{"record":{"id":"a1fe0b3cc6ece2a1","repo":"Tencent/tinker","slug":"map-is-unsorted-at-previous-section","errorCode":null,"errorMessage":"Map is unsorted at ${previous}, ${section}","messagePattern":"Map is unsorted at (.+?), (.+?)","errorType":"exception","errorClass":"DexException","httpStatus":null,"severity":"error","filePath":"third-party/aosp-dexutils/src/main/java/com/tencent/tinker/android/dex/TableOfContents.java","lineNumber":225,"sourceCode":"        int mapSize = in.readInt();\n        Section previous = null;\n        for (int i = 0; i < mapSize; i++) {\n            short type = in.readShort();\n            in.readShort(); // unused\n            Section section = getSection(type);\n            int size = in.readInt();\n            int offset = in.readInt();\n\n            if ((section.size != 0 && section.size != size)\n                    || (section.off != Section.UNDEF_OFFSET && section.off != offset)) {\n                throw new DexException(\"Unexpected map value for 0x\" + Integer.toHexString(type));\n            }\n\n            section.size = size;\n            section.off = offset;\n\n            if (previous != null && previous.off > section.off) {\n                throw new DexException(\"Map is unsorted at \" + previous + \", \" + section);\n            }\n\n            previous = section;\n        }\n\n        header.off = 0;\n\n        Arrays.sort(sections);\n\n        // Skip header section, since its offset must be zero.\n        for (int i = 1; i < sections.length; ++i) {\n            if (sections[i].off == Section.UNDEF_OFFSET) {\n                sections[i].off = sections[i - 1].off;\n            }\n        }\n    }\n\n    public void computeSizesFromOffsets() {","sourceCodeStart":207,"sourceCodeEnd":243,"githubUrl":"https://github.com/Tencent/tinker/blob/1b7ea02c239840f563ea64fb5bd286eb98d4011e/third-party/aosp-dexutils/src/main/java/com/tencent/tinker/android/dex/TableOfContents.java#L207-L243","documentation":"Thrown by TableOfContents.readMap when consecutive map_list entries have descending file offsets — the map must list sections in ascending offset order (the spec requires it, and the sort/byteCount computation later relies on it). The message names the offending previous and current section.","triggerScenarios":"A map list whose entries were reordered or whose offsets were edited without re-sorting; duplicate sections with stale offsets; corrupted map data after binary edits.","commonSituations":"Custom dex rewriters that grow one section in place and push others around but forget to re-emit the map in order; toolchains with off-by-one offset math producing overlapping/out-of-order sections.","solutions":["Rebuild the dex with a conformant toolchain rather than repairing the map in place.","If you write dexes, emit sections in offset order and generate the map from the final layout, never incrementally.","Use `dexdump` on the input to confirm the ordering failure and identify the two sections named in the message."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"catch (DexException e) with 'Map is unsorted' -> fail fast with both section names from the message; do not reorder the map yourself","preventionTips":["Generate map lists from the final layout in one pass; never edit individual map entries.","Add a structural validator (sections ascending by offset) to your dex-writing test suite."],"tags":["dex","map-list","ordering","corruption","tinker"],"backgroundTag":null,"analyzedSha":"1b7ea02c239840f563ea64fb5bd286eb98d4011e","analyzedAt":"2026-08-14T15:16:52.110Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}