aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarc Miltenberger <Marc.Miltenberger@sit.fraunhofer.de>2021-12-22 22:26:26 +0100
committerBen Gruver <bgruv@google.com>2022-03-08 13:00:17 -0600
commit11f71ae481d0f38dcf8c4198c34135e047dc98c8 (patch)
treea7755c9dcd04a035418ac23e9bab88ef014cebf9
parentec5ae2288883374890f91f7437cedc44873dc10b (diff)
downloadgoogle-smali-11f71ae481d0f38dcf8c4198c34135e047dc98c8.tar.gz
Fix range check for character arrays with elements over 32767
-rw-r--r--dexlib2/src/main/java/org/jf/dexlib2/util/Preconditions.java21
-rw-r--r--dexlib2/src/test/java/org/jf/util/PreconditionsTest.java8
2 files changed, 25 insertions, 4 deletions
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 extends List<? extends Number>> 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);