Skip to content

Commit

Permalink
Merge pull request apache#1616, fix hessian1 serialized short, byte i…
Browse files Browse the repository at this point in the history
…s converted to int.
  • Loading branch information
zonghaishang authored and chickenlj committed May 10, 2018
1 parent ebc0508 commit 23070d8
Show file tree
Hide file tree
Showing 3 changed files with 318 additions and 12 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;

/**
* Input stream for Hessian requests.
Expand Down Expand Up @@ -999,7 +1000,15 @@ private HashMap readFault()
@Override
public Object readObject(Class cl)
throws IOException {
if (cl == null || cl == Object.class)
return readObject(cl, null, null);
}

/**
* Reads an object from the input stream with an expected type.
*/
public Object readObject(Class expectedClass, Class<?>... expectedTypes)
throws IOException {
if (expectedClass == null || expectedClass == Object.class)
return readObject();

int tag = read();
Expand All @@ -1011,17 +1020,23 @@ public Object readObject(Class cl)
case 'M': {
String type = readType();

boolean keyValuePair = expectedTypes != null && expectedTypes.length == 2;

// hessian/3386
if ("".equals(type)) {
Deserializer reader;
reader = _serializerFactory.getDeserializer(cl);
reader = _serializerFactory.getDeserializer(expectedClass);

return reader.readMap(this);
return reader.readMap(this
, keyValuePair ? expectedTypes[0] : null
, keyValuePair ? expectedTypes[1] : null);
} else {
Deserializer reader;
reader = _serializerFactory.getObjectDeserializer(type, cl);
reader = _serializerFactory.getObjectDeserializer(type, expectedClass);

return reader.readMap(this);
return reader.readMap(this
, keyValuePair ? expectedTypes[0] : null
, keyValuePair ? expectedTypes[1] : null);
}
}

Expand All @@ -1032,12 +1047,14 @@ public Object readObject(Class cl)
Deserializer reader;
reader = _serializerFactory.getObjectDeserializer(type);

if (cl != reader.getType() && cl.isAssignableFrom(reader.getType()))
return reader.readList(this, length);
boolean valueType = expectedTypes != null && expectedTypes.length == 1;

if (expectedClass != reader.getType() && expectedClass.isAssignableFrom(reader.getType()))
return reader.readList(this, length, valueType ? expectedTypes[0] : null);

reader = _serializerFactory.getDeserializer(cl);
reader = _serializerFactory.getDeserializer(expectedClass);

Object v = reader.readList(this, length);
Object v = reader.readList(this, length, valueType ? expectedTypes[0] : null);

return v;
}
Expand All @@ -1061,7 +1078,7 @@ public Object readObject(Class cl)
// hessian/332i vs hessian/3406
//return readObject();

Object value = _serializerFactory.getDeserializer(cl).readObject(this);
Object value = _serializerFactory.getDeserializer(expectedClass).readObject(this);

return value;
}
Expand All @@ -1073,6 +1090,15 @@ public Object readObject(Class cl)
@Override
public Object readObject()
throws IOException {
return readObject((List<Class<?>>) null);
}

/**
* Reads an arbitrary object from the input stream when the type
* is unknown.
*/
public Object readObject(List<Class<?>> expectedTypes)
throws IOException {
int tag = read();

switch (tag) {
Expand Down Expand Up @@ -1137,13 +1163,29 @@ public Object readObject()
String type = readType();
int length = readLength();

return _serializerFactory.readList(this, length, type);
Deserializer reader;
reader = _serializerFactory.getObjectDeserializer(type);

boolean valueType = expectedTypes != null && expectedTypes.size() == 1;

if (List.class != reader.getType() && List.class.isAssignableFrom(reader.getType()))
return reader.readList(this, length, valueType ? expectedTypes.get(0) : null);

reader = _serializerFactory.getDeserializer(List.class);

Object v = reader.readList(this, length, valueType ? expectedTypes.get(0) : null);

return v;
}

case 'M': {
String type = readType();

return _serializerFactory.readMap(this, type);
boolean keyValuePair = expectedTypes != null && expectedTypes.size() == 2;

return _serializerFactory.readMap(this, type
, keyValuePair ? expectedTypes.get(0) : null
, keyValuePair ? expectedTypes.get(1) : null);
}

case 'R': {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,210 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.alibaba.com.caucho.hessian.io;

import com.alibaba.com.caucho.hessian.io.base.SerializeTestBase;
import com.alibaba.com.caucho.hessian.io.beans.Hessian2StringShortType;
import com.alibaba.com.caucho.hessian.io.beans.PersonType;

import org.junit.Test;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import static junit.framework.TestCase.assertEquals;
import static junit.framework.TestCase.assertTrue;

public class Hessian1StringShortTest extends SerializeTestBase {

@Test
public void serialize_string_short_map_then_deserialize() throws Exception {

Hessian2StringShortType stringShort = new Hessian2StringShortType();
Map<String, Short> stringShortMap = new HashMap<String, Short>();
stringShortMap.put("first", (short)0);
stringShortMap.put("last", (short)60);
stringShort.stringShortMap = stringShortMap;

Hessian2StringShortType deserialize = baseHessionSerialize(stringShort);
assertTrue(deserialize.stringShortMap != null);
assertTrue(deserialize.stringShortMap.size() == 2);
assertTrue(deserialize.stringShortMap.get("last") instanceof Short);
assertEquals(Short.valueOf((short)0), deserialize.stringShortMap.get("first"));
assertEquals(Short.valueOf((short)60), deserialize.stringShortMap.get("last"));
}

@Test
public void serialize_string_byte_map_then_deserialize() throws Exception {

Hessian2StringShortType stringShort = new Hessian2StringShortType();
Map<String, Byte> stringByteMap = new HashMap<String, Byte>();
stringByteMap.put("first", (byte)0);
stringByteMap.put("last", (byte)60);
stringShort.stringByteMap = stringByteMap;

Hessian2StringShortType deserialize = baseHessionSerialize(stringShort);
assertTrue(deserialize.stringByteMap != null);
assertTrue(deserialize.stringByteMap.size() == 2);
assertTrue(deserialize.stringByteMap.get("last") instanceof Byte);
assertEquals(Byte.valueOf((byte)0), deserialize.stringByteMap.get("first"));
assertEquals(Byte.valueOf((byte) 60), deserialize.stringByteMap.get("last"));
}

@Test
public void serialize_map_then_deserialize() throws Exception {

Map<String, Short> stringShortMap = new HashMap<String, Short>();
stringShortMap.put("first", (short)0);
stringShortMap.put("last", (short)60);

ByteArrayOutputStream bout = new ByteArrayOutputStream();
HessianOutput out = new HessianOutput(bout);

out.writeObject(stringShortMap);
out.flush();

ByteArrayInputStream bin = new ByteArrayInputStream(bout.toByteArray());
HessianInput input = new HessianInput(bin);
Map deserialize = (Map) input.readObject(HashMap.class, String.class, Short.class);
assertTrue(deserialize != null);
assertTrue(deserialize.size() == 2);
assertTrue(deserialize.get("last") instanceof Short);
assertEquals(Short.valueOf((short)0), deserialize.get("first"));
assertEquals(Short.valueOf((short)60), deserialize.get("last"));
}

@Test
public void serialize_map_then_deserialize0() throws Exception {

Map<String, Short> stringShortMap = new HashMap<String, Short>();
stringShortMap.put("first", (short)0);
stringShortMap.put("last", (short)60);

ByteArrayOutputStream bout = new ByteArrayOutputStream();
HessianOutput out = new HessianOutput(bout);

out.writeObject(stringShortMap);
out.flush();

ByteArrayInputStream bin = new ByteArrayInputStream(bout.toByteArray());
HessianInput input = new HessianInput(bin);
List<Class<?>> keyValueType = new ArrayList<Class<?>>();
keyValueType.add(String.class);
keyValueType.add(short.class);

Map deserialize = (Map) input.readObject(keyValueType);
assertTrue(deserialize != null);
assertTrue(deserialize.size() == 2);
assertTrue(deserialize.get("last") instanceof Short);
assertEquals(Short.valueOf((short)0), deserialize.get("first"));
assertEquals(Short.valueOf((short)60), deserialize.get("last"));
}

@Test
public void serialize_string_person_map_then_deserialize() throws Exception {

Hessian2StringShortType stringShort = new Hessian2StringShortType();
Map<String, PersonType> stringPersonTypeMap = new HashMap<String, PersonType>();
stringPersonTypeMap.put("first", new PersonType(
"jason.shang", 26, (double) 0.1, (short)1, (byte)2, Arrays.asList((short)1,(short)1)
));
stringPersonTypeMap.put("last", new PersonType(
"jason.shang2", 52, (double) 0.2, (short)2, (byte)4, Arrays.asList((short)2,(short)2)
));
stringShort.stringPersonTypeMap = stringPersonTypeMap;

ByteArrayOutputStream bout = new ByteArrayOutputStream();
HessianOutput out = new HessianOutput(bout);

out.writeObject(stringShort);
out.flush();

ByteArrayInputStream bin = new ByteArrayInputStream(bout.toByteArray());
HessianInput input = new HessianInput(bin);

Hessian2StringShortType deserialize = (Hessian2StringShortType) input.readObject();
assertTrue(deserialize.stringPersonTypeMap != null);
assertTrue(deserialize.stringPersonTypeMap.size() == 2);
assertTrue(deserialize.stringPersonTypeMap.get("last") instanceof PersonType);


assertEquals(new PersonType(
"jason.shang", 26, (double) 0.1, (short)1, (byte)2, Arrays.asList((short)1,(short)1)
), deserialize.stringPersonTypeMap.get("first"));

assertEquals(new PersonType(
"jason.shang2", 52, (double) 0.2, (short)2, (byte)4, Arrays.asList((short)2,(short)2)
), deserialize.stringPersonTypeMap.get("last"));

}

@Test
public void serialize_list_then_deserialize() throws Exception {

List<Short> shortList = new ArrayList<Short>();
shortList.add((short)0);
shortList.add((short)60);

ByteArrayOutputStream bout = new ByteArrayOutputStream();
HessianOutput out = new HessianOutput(bout);

out.writeObject(shortList);
out.flush();

ByteArrayInputStream bin = new ByteArrayInputStream(bout.toByteArray());
HessianInput input = new HessianInput(bin);
List<Short> deserialize = (List) input.readObject(ArrayList.class, Short.class);
assertTrue(deserialize != null);
assertTrue(deserialize.size() == 2);
assertTrue(deserialize.get(1) instanceof Short);
assertEquals(Short.valueOf((short)0), deserialize.get(0));
assertEquals(Short.valueOf((short)60), deserialize.get(1));
}

@Test
public void serialize_list_then_deserialize0() throws Exception {

List<Short> shortList = new ArrayList<Short>();
shortList.add((short)0);
shortList.add((short)60);

ByteArrayOutputStream bout = new ByteArrayOutputStream();
HessianOutput out = new HessianOutput(bout);

out.writeObject(shortList);
out.flush();

ByteArrayInputStream bin = new ByteArrayInputStream(bout.toByteArray());
HessianInput input = new HessianInput(bin);

List<Class<?>> valueType = new ArrayList<Class<?>>();
valueType.add(short.class);

List<Short> deserialize = (List) input.readObject(valueType);
assertTrue(deserialize != null);
assertTrue(deserialize.size() == 2);
assertTrue(deserialize.get(1) instanceof Short);
assertEquals(Short.valueOf((short)0), deserialize.get(0));
assertEquals(Short.valueOf((short)60), deserialize.get(1));
}

}
Loading

0 comments on commit 23070d8

Please sign in to comment.