diff --git a/dexlib2/src/main/java/org/jf/dexlib2/util/Preconditions.java b/dexlib2/src/main/java/org/jf/dexlib2/util/Preconditions.java index 990986b9..4a18afa0 100644 --- a/dexlib2/src/main/java/org/jf/dexlib2/util/Preconditions.java +++ b/dexlib2/src/main/java/org/jf/dexlib2/util/Preconditions.java @@ -220,9 +220,24 @@ public class Preconditions { } public static > L checkArrayPayloadElements(int elementWidth, L elements) { - long maxValue = (1L << ((8 * elementWidth) - 1)) - 1; - long minValue = -maxValue - 1; - + long maxValue; + long minValue; + if (elementWidth == 2) { + //Could be a short or character. + //Characters are unsigned, Shorts are signed. + //Short.MAX_VALUE = 32767 + //Short.MIN_VALUE = -32768 + //(int) Character.MAX_VALUE = 65535 + //(int) Character.MIN_VALUE = 0 + //See https://docs.oracle.com/javase/specs/jvms/se6/html/Overview.doc.html for details + //As such, we use the combined interval range of both. + maxValue = (int) Character.MAX_VALUE; + minValue = Short.MIN_VALUE; + } else { + //Two's complement. + maxValue = (1L << ((8 * elementWidth) - 1)) - 1; + minValue = -maxValue - 1; + } for (Number element : elements) { if (element.longValue() < minValue || element.longValue() > maxValue) { throw new IllegalArgumentException( diff --git a/dexlib2/src/test/java/org/jf/util/PreconditionsTest.java b/dexlib2/src/test/java/org/jf/util/PreconditionsTest.java index ba3b6fde..4c9718be 100644 --- a/dexlib2/src/test/java/org/jf/util/PreconditionsTest.java +++ b/dexlib2/src/test/java/org/jf/util/PreconditionsTest.java @@ -28,12 +28,18 @@ public class PreconditionsTest { verifyArrayPayloadElementIsValid(4, Integer.MIN_VALUE); verifyArrayPayloadElementIsValid(2, Short.MAX_VALUE); verifyArrayPayloadElementIsValid(2, Short.MIN_VALUE); + verifyArrayPayloadElementIsValid(2, Character.MAX_VALUE); + verifyArrayPayloadElementIsValid(2, Character.MIN_VALUE); verifyArrayPayloadElementIsValid(1, Byte.MAX_VALUE); verifyArrayPayloadElementIsValid(1, Byte.MIN_VALUE); verifyArrayPayloadElementIsInvalid(4, ((long) Integer.MAX_VALUE) + 1); verifyArrayPayloadElementIsInvalid(4, ((long) Integer.MIN_VALUE) - 1); - verifyArrayPayloadElementIsInvalid(2, ((long) Short.MAX_VALUE) + 1); + verifyArrayPayloadElementIsInvalid(2, ((long) Short.MIN_VALUE) - 1); + //Since short and character have the same size, but different ranges + // and cannot be distinguished here, the valid interval is + //[Short.MIN_VALUE, Character.MAX_VALUE], i.e. [-32768, 65535] + verifyArrayPayloadElementIsInvalid(2, ((long) Character.MAX_VALUE) + 1); verifyArrayPayloadElementIsInvalid(2, ((long) Short.MIN_VALUE) - 1); verifyArrayPayloadElementIsInvalid(1, ((long) Byte.MAX_VALUE) + 1); verifyArrayPayloadElementIsInvalid(1, ((long) Byte.MIN_VALUE) - 1);