Merge "Add partial support for dex containers (DEX v41)." into main am: 12595bf3a2

Original change: https://android-review.googlesource.com/c/platform/external/smali/+/2756247

Change-Id: I8de22e8374609252da6a69a4a9dd5d88e8bb595b
Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
diff --git a/dexlib2/src/main/java/org/jf/dexlib2/VersionMap.java b/dexlib2/src/main/java/org/jf/dexlib2/VersionMap.java
index 791fffa..13a9fea 100644
--- a/dexlib2/src/main/java/org/jf/dexlib2/VersionMap.java
+++ b/dexlib2/src/main/java/org/jf/dexlib2/VersionMap.java
@@ -44,22 +44,39 @@
                 return 27;
             case 39:
                 return 28;
+            case 40:
+                return 34;
+            case 41:
+                return 35;
             default:
                 return NO_VERSION;
         }
     }
 
     public static int mapApiToDexVersion(int api) {
-        if (api <= 23) {
+        if (api <= 23) {  // Android M/6
             return 35;
         }
-        if (api <= 25) {
-            return 37;
+        switch (api) {
+            case 24:  // Android N/7
+            case 25:  // Android N/7.1
+                return 37;
+            case 26:  // Android O/8
+            case 27:  // Android O/8.1
+                return 38;
+            case 28:  // Android P/9
+                return 39;
+            case 29:  // Android Q/10
+            case 30:  // Android R/11
+            case 31:  // Android S/12
+            case 32:  // Android S/12.1
+            case 33:  // Android T/13
+            case 34:  // Android U/14
+                return 40;
+            case 35:  // Android V/15
+                return 41;
         }
-        if (api <= 27) {
-            return 38;
-        }
-        return 39;
+        return NO_VERSION;
     }
 
     public static int mapArtVersionToApi(int artVersion) {
diff --git a/dexlib2/src/main/java/org/jf/dexlib2/dexbacked/DexBackedDexFile.java b/dexlib2/src/main/java/org/jf/dexlib2/dexbacked/DexBackedDexFile.java
index 664428b..210552c 100644
--- a/dexlib2/src/main/java/org/jf/dexlib2/dexbacked/DexBackedDexFile.java
+++ b/dexlib2/src/main/java/org/jf/dexlib2/dexbacked/DexBackedDexFile.java
@@ -100,6 +100,16 @@
         classCount = readSmallUint(HeaderItem.CLASS_COUNT_OFFSET);
         classStartOffset = readSmallUint(HeaderItem.CLASS_START_OFFSET);
         mapOffset = readSmallUint(HeaderItem.MAP_OFFSET);
+
+        if (dexVersion >= 41) {
+          // Reject non-trivial dex container (i.e. multiples dex files in the same physical file).
+          int container_off = readSmallUint(HeaderItem.CONTAINER_OFF_OFFSET);
+          int container_size = readSmallUint(HeaderItem.CONTAINER_SIZE_OFFSET);
+          int file_size = readSmallUint(HeaderItem.FILE_SIZE_OFFSET);
+          if (container_off != 0 || container_size != file_size) {
+            throw new DexUtil.UnsupportedFile(String.format("Dex container is not supported"));
+          }
+        }
     }
 
     public DexBackedDexFile(@Nullable Opcodes opcodes, @Nonnull BaseDexBuffer buf) {
diff --git a/dexlib2/src/main/java/org/jf/dexlib2/dexbacked/raw/HeaderItem.java b/dexlib2/src/main/java/org/jf/dexlib2/dexbacked/raw/HeaderItem.java
index 619357a..e6859b4 100644
--- a/dexlib2/src/main/java/org/jf/dexlib2/dexbacked/raw/HeaderItem.java
+++ b/dexlib2/src/main/java/org/jf/dexlib2/dexbacked/raw/HeaderItem.java
@@ -83,6 +83,9 @@
     public static final int CLASS_COUNT_OFFSET = 96;
     public static final int CLASS_START_OFFSET = 100;
 
+    public static final int CONTAINER_SIZE_OFFSET = 112;
+    public static final int CONTAINER_OFF_OFFSET = 116;
+
     @Nonnull private RawDexFile dexFile;
 
     public HeaderItem(@Nonnull RawDexFile dexFile) {