You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@johnzon.apache.org by st...@apache.org on 2018/07/18 19:54:31 UTC
johnzon git commit: JOHNZON-177 blow up if java type range is exceeded
Repository: johnzon
Updated Branches:
refs/heads/master f784faf2c -> 50b8fc3e8
JOHNZON-177 blow up if java type range is exceeded
thanks to Markus Bruckner for the report!
Project: http://git-wip-us.apache.org/repos/asf/johnzon/repo
Commit: http://git-wip-us.apache.org/repos/asf/johnzon/commit/50b8fc3e
Tree: http://git-wip-us.apache.org/repos/asf/johnzon/tree/50b8fc3e
Diff: http://git-wip-us.apache.org/repos/asf/johnzon/diff/50b8fc3e
Branch: refs/heads/master
Commit: 50b8fc3e84678d0266530e47c1c3372255cfc469
Parents: f784faf
Author: Mark Struberg <st...@apache.org>
Authored: Wed Jul 18 21:50:05 2018 +0200
Committer: Mark Struberg <st...@apache.org>
Committed: Wed Jul 18 21:53:51 2018 +0200
----------------------------------------------------------------------
.../org/apache/johnzon/core/JsonLongImpl.java | 6 +-
.../johnzon/mapper/MappingParserImpl.java | 36 +++---
.../org/apache/johnzon/mapper/MapperTest.java | 115 ++++++++++++++-----
3 files changed, 113 insertions(+), 44 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/johnzon/blob/50b8fc3e/johnzon-core/src/main/java/org/apache/johnzon/core/JsonLongImpl.java
----------------------------------------------------------------------
diff --git a/johnzon-core/src/main/java/org/apache/johnzon/core/JsonLongImpl.java b/johnzon-core/src/main/java/org/apache/johnzon/core/JsonLongImpl.java
index 5428a87..7637512 100644
--- a/johnzon-core/src/main/java/org/apache/johnzon/core/JsonLongImpl.java
+++ b/johnzon-core/src/main/java/org/apache/johnzon/core/JsonLongImpl.java
@@ -48,7 +48,11 @@ public final class JsonLongImpl implements JsonNumber, Serializable {
@Override
public int intValueExact() {
- return intValue();
+ int intVal = intValue();
+ if (intVal != value) {
+ throw new java.lang.ArithmeticException("Overflow");
+ }
+ return intVal;
}
@Override
http://git-wip-us.apache.org/repos/asf/johnzon/blob/50b8fc3e/johnzon-mapper/src/main/java/org/apache/johnzon/mapper/MappingParserImpl.java
----------------------------------------------------------------------
diff --git a/johnzon-mapper/src/main/java/org/apache/johnzon/mapper/MappingParserImpl.java b/johnzon-mapper/src/main/java/org/apache/johnzon/mapper/MappingParserImpl.java
index c16ce92..3dbc337 100644
--- a/johnzon-mapper/src/main/java/org/apache/johnzon/mapper/MappingParserImpl.java
+++ b/johnzon-mapper/src/main/java/org/apache/johnzon/mapper/MappingParserImpl.java
@@ -523,20 +523,8 @@ public class MappingParserImpl implements MappingParser {
final JsonNumber number = JsonNumber.class.cast(jsonValue);
- if (type == Integer.class || type == int.class) {
- return number.intValue();
- }
-
if (type == Long.class || type == long.class) {
- return number.longValue();
- }
-
- if (type == Short.class || type == short.class) {
- return (short) number.intValue();
- }
-
- if (type == Byte.class || type == byte.class) {
- return (byte) number.intValue();
+ return number.longValueExact();
}
if (type == Float.class || type == float.class) {
@@ -554,6 +542,28 @@ public class MappingParserImpl implements MappingParser {
if (type == BigDecimal.class) {
return number.bigDecimalValue();
}
+
+ int intValue = number.intValueExact();
+ if (type == Integer.class || type == int.class) {
+ return intValue;
+ }
+
+ if (type == Short.class || type == short.class) {
+ short shortVal = (short) intValue;
+ if (intValue != shortVal) {
+ throw new java.lang.ArithmeticException("Overflow");
+ }
+ return shortVal;
+ }
+
+ if (type == Byte.class || type == byte.class) {
+ byte byteVal = (byte) intValue;
+ if (intValue != byteVal) {
+ throw new java.lang.ArithmeticException("Overflow");
+ }
+ return byteVal;
+ }
+
} else if (JsonString.class.isInstance(jsonValue)) {
if (JsonString.class == type) {
return jsonValue;
http://git-wip-us.apache.org/repos/asf/johnzon/blob/50b8fc3e/johnzon-mapper/src/test/java/org/apache/johnzon/mapper/MapperTest.java
----------------------------------------------------------------------
diff --git a/johnzon-mapper/src/test/java/org/apache/johnzon/mapper/MapperTest.java b/johnzon-mapper/src/test/java/org/apache/johnzon/mapper/MapperTest.java
index 8c8c4ce..dc06ea7 100644
--- a/johnzon-mapper/src/test/java/org/apache/johnzon/mapper/MapperTest.java
+++ b/johnzon-mapper/src/test/java/org/apache/johnzon/mapper/MapperTest.java
@@ -21,6 +21,7 @@ package org.apache.johnzon.mapper;
import org.apache.johnzon.mapper.access.FieldAccessMode;
import org.apache.johnzon.mapper.reflection.JohnzonCollectionType;
import org.apache.johnzon.mapper.reflection.JohnzonParameterizedType;
+import org.junit.Assert;
import org.junit.Test;
import java.beans.ConstructorProperties;
@@ -29,6 +30,7 @@ import java.io.ByteArrayOutputStream;
import java.io.StringReader;
import java.io.StringWriter;
import java.lang.reflect.ParameterizedType;
+import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
@@ -52,11 +54,11 @@ import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
public class MapperTest {
- private static final String BIG_OBJECT_STR = "{" + "\"name\":\"the string\"," + "\"integer\":56," + "\"longnumber\":118,"
- + "\"bool\":true," + "\"nested\":{" + "\"name\":\"another value\"," + "\"integer\":97," + "\"longnumber\":34" + "},"
- + "\"array\":[" + "{" + "\"name\":\"a1\"," + "\"integer\":1," + "\"longnumber\":2" + "}," + "{" + "\"name\":\"a2\","
- + "\"integer\":3," + "\"longnumber\":4" + "}" + "]," + "\"list\":[" + "{" + "\"name\":\"a3\"," + "\"integer\":5,"
- + "\"longnumber\":6" + "}," + "{" + "\"name\":\"a4\"," + "\"integer\":7," + "\"longnumber\":8" + "}" + "],"
+ private static final String BIG_OBJECT_STR = "{" + "\"name\":\"the string\"," + "\"intVal\":56," + "\"longnumber\":118,"
+ + "\"bool\":true," + "\"nested\":{" + "\"name\":\"another value\"," + "\"intVal\":97," + "\"longnumber\":34" + "},"
+ + "\"array\":[" + "{" + "\"name\":\"a1\"," + "\"intVal\":1," + "\"longnumber\":2" + "}," + "{" + "\"name\":\"a2\","
+ + "\"intVal\":3," + "\"longnumber\":4" + "}" + "]," + "\"list\":[" + "{" + "\"name\":\"a3\"," + "\"intVal\":5,"
+ + "\"longnumber\":6" + "}," + "{" + "\"name\":\"a4\"," + "\"intVal\":7," + "\"longnumber\":8" + "}" + "],"
+ "\"primitives\":[1,2,3,4,5]," + "\"collectionWrapper\":[1,2,3,4,5]," + "\"map\":{\"uno\":true,\"duos\":false}" + "}";
@Test
@@ -405,23 +407,58 @@ public class MapperTest {
mapper.writeObject(bsr, writer);
assertEquals(expectedJson, writer.toString());
}
-
+
+ /**
+ * Verify that assigning a short or byte number
+ * which is too big to fit into the java field
+ * does raise a MapperException.
+ */
+ @Test
+ public void tooLongShortAndByte() {
+ Mapper mapper = new MapperBuilder().build();
+ expectMapperException(() -> mapper.readObject("{\"numShort\":123456}", ByteShort.class));
+ expectMapperException(() -> mapper.readObject("{\"numShort\":-123456}", ByteShort.class));
+ expectMapperException(() -> mapper.readObject("{\"shortW\":123456}", ByteShort.class));
+ expectMapperException(() -> mapper.readObject("{\"shortW\":-123456}", ByteShort.class));
+ expectMapperException(() -> mapper.readObject("{\"numByte\":123456}", ByteShort.class));
+ expectMapperException(() -> mapper.readObject("{\"numByte\":-123456}", ByteShort.class));
+ expectMapperException(() -> mapper.readObject("{\"byteW\":123456}", ByteShort.class));
+ expectMapperException(() -> mapper.readObject("{\"byteW\":-123456}", ByteShort.class));
+ }
+
+ /**
+ * Verify that assigning a long or int number
+ * which is too big to fit into the java field
+ * does raise a MapperException.
+ */
+ @Test
+ public void tooLongIntAndLong() {
+ Mapper mapper = new MapperBuilder().build();
+ String intCap = new BigDecimal(Integer.MAX_VALUE).add(new BigDecimal(2L)).toString();
+ String longCap = new BigDecimal(Long.MAX_VALUE).add(new BigDecimal(2L)).toString();
+ expectMapperException(() -> mapper.readObject("{\"intVal\":" + intCap + "}", TheObject.class));
+ expectMapperException(() -> mapper.readObject("{\"intVal\":-" + intCap + "}", TheObject.class));
+ expectMapperException(() -> mapper.readObject("{\"longnumber\":" + longCap + "}", TheObject.class));
+ expectMapperException(() -> mapper.readObject("{\"longnumber\":-" + longCap + "}", TheObject.class));
+ }
+
+
/*@Test
public void byteArrayBase64Converter() {
-
+
Mapper mapper = new MapperBuilder().setTreatByteArrayAsBase64(false).build();
-
+
ByteArray ba = new ByteArray();
ba.setByteArray(new byte[]{(byte) 1,(byte) 1,(byte) 1 });
-
+
final String expectedJson = "{\"shortW\":22,\"shortWA\":[7,-2],\"byteW\":7,\"numShortA\":[4,-2],\"numByteA\":\"Af8C\",\"byteWA\":[4,-12,2],\"numByte\":6,\"numShort\":-1}";
-
+
StringWriter writer = new StringWriter();
mapper.writeObject(ba, writer);
assertEquals(expectedJson, writer.toString());
-
+
ByteShort bsr = mapper.readObject(new StringReader(expectedJson), ByteArray.class);
-
+
writer = new StringWriter();
mapper.writeObject(bsr, writer);
assertEquals(expectedJson, writer.toString());
@@ -538,26 +575,26 @@ public class MapperTest {
assertNotNull(object);
assertEquals("the string", object.name);
- assertEquals(56, object.integer);
+ assertEquals(56, object.intVal);
assertEquals(118, object.longnumber);
assertTrue(object.bool);
assertEquals("another value", object.nested.name);
- assertEquals(97, object.nested.integer);
+ assertEquals(97, object.nested.intVal);
assertEquals(34, object.nested.longnumber);
assertFalse(object.nested.bool);
assertNotNull(object.array);
assertEquals(2, object.array.length);
assertEquals("a1", object.array[0].name);
- assertEquals(1, object.array[0].integer);
+ assertEquals(1, object.array[0].intVal);
assertEquals(2, object.array[0].longnumber);
assertEquals("a2", object.array[1].name);
- assertEquals(3, object.array[1].integer);
+ assertEquals(3, object.array[1].intVal);
assertEquals(4, object.array[1].longnumber);
assertEquals("a3", object.list.get(0).name);
- assertEquals(5, object.list.get(0).integer);
+ assertEquals(5, object.list.get(0).intVal);
assertEquals(6, object.list.get(0).longnumber);
assertEquals("a4", object.list.get(1).name);
- assertEquals(7, object.list.get(1).integer);
+ assertEquals(7, object.list.get(1).intVal);
assertEquals(8, object.list.get(1).longnumber);
assertEquals(5, object.primitives.length);
for (int i = 0; i < object.primitives.length; i++) {
@@ -579,15 +616,15 @@ public class MapperTest {
@Test
public void readArray() {
final TheObject[] object = new MapperBuilder().build().readArray(
- new ByteArrayInputStream(("[" + "{" + "\"name\":\"a3\"," + "\"integer\":5," + "\"longnumber\":6" + "}," + "{"
- + "\"name\":\"a4\"," + "\"integer\":7," + "\"longnumber\":8" + "}" + "]").getBytes()), TheObject.class);
+ new ByteArrayInputStream(("[" + "{" + "\"name\":\"a3\"," + "\"intVal\":5," + "\"longnumber\":6" + "}," + "{"
+ + "\"name\":\"a4\"," + "\"intVal\":7," + "\"longnumber\":8" + "}" + "]").getBytes()), TheObject.class);
assertNotNull(object);
assertEquals(2, object.length);
assertEquals("a3", object[0].name);
- assertEquals(5, object[0].integer);
+ assertEquals(5, object[0].intVal);
assertEquals(6, object[0].longnumber);
assertEquals("a4", object[1].name);
- assertEquals(7, object[1].integer);
+ assertEquals(7, object[1].intVal);
assertEquals(8, object[1].longnumber);
}
@@ -702,6 +739,15 @@ public class MapperTest {
assertNotEquals(utf8, latin); // means encoding was considered, we don't need more here
}
+ private void expectMapperException(Runnable runnable) {
+ try {
+ runnable.run();
+ Assert.fail("MapperException expected!");
+ } catch (MapperException me) {
+ // all fine!
+ }
+ }
+
public static class NanHolder {
private Double nan = Double.NaN;
@@ -716,7 +762,8 @@ public class MapperTest {
public static class TheObject {
private String name;
- private int integer;
+ private int intVal;
+ private Integer integerVal;
private long longnumber;
private boolean bool;
private TheObject nested;
@@ -734,12 +781,20 @@ public class MapperTest {
this.name = name;
}
- public int getInteger() {
- return integer;
+ public int getIntVal() {
+ return intVal;
+ }
+
+ public void setIntVal(final int intVal) {
+ this.intVal = intVal;
+ }
+
+ public Integer getIntegerVal() {
+ return integerVal;
}
- public void setInteger(final int integer) {
- this.integer = integer;
+ public void setIntegerVal(Integer integerVal) {
+ this.integerVal = integerVal;
}
public long getLongnumber() {
@@ -808,7 +863,7 @@ public class MapperTest {
@Override
public String toString() {
- return "TheObject [name=" + name + ", integer=" + integer + ", longnumber=" + longnumber + ", bool=" + bool + ", nested="
+ return "TheObject [name=" + name + ", integer=" + intVal + ", longnumber=" + longnumber + ", bool=" + bool + ", nested="
+ nested + ", array=" + Arrays.toString(array) + ", list=" + list + ", primitives=" + Arrays.toString(primitives)
+ ", collectionWrapper=" + collectionWrapper + ", map=" + map + "]";
}
@@ -820,7 +875,7 @@ public class MapperTest {
result = prime * result + Arrays.hashCode(array);
result = prime * result + (bool ? 1231 : 1237);
result = prime * result + ((collectionWrapper == null) ? 0 : collectionWrapper.hashCode());
- result = prime * result + integer;
+ result = prime * result + intVal;
result = prime * result + ((list == null) ? 0 : list.hashCode());
result = prime * result + (int) (longnumber ^ (longnumber >>> 32));
result = prime * result + ((map == null) ? 0 : map.hashCode());
@@ -855,7 +910,7 @@ public class MapperTest {
} else if (!collectionWrapper.equals(other.collectionWrapper)) {
return false;
}
- if (integer != other.integer) {
+ if (intVal != other.intVal) {
return false;
}
if (list == null) {