{"record":{"id":"6343541dd0c6f4ea","repo":"Tencent/tinker","slug":"failed-to-compute-old-dex-s-signature","errorCode":null,"errorMessage":"failed to compute old dex's signature.","messagePattern":"failed to compute old dex's signature\\.","errorType":"exception","errorClass":"IOException","httpStatus":null,"severity":"critical","filePath":"tinker-commons/src/main/java/com/tencent/tinker/commons/dexpatcher/DexPatchApplier.java","lineNumber":131,"sourceCode":"    }\n\n    public void executeAndSaveTo(OutputStream out) throws IOException {\n        // Before executing, we should check if this patch can be applied to\n        // old dex we passed in.\n        if (this.patchFile == null) {\n            throw new IllegalArgumentException(\"patch file is null.\");\n        }\n        if (this.patchFile.getVersion() > DexPatchFile.VERSION_02) {\n            final int oldDexAPI = this.oldDex.getTableOfContents().api;\n            final int expectedOldDexAPI = this.patchFile.getOldDexAPI();\n            if (oldDexAPI != expectedOldDexAPI) {\n                throw new IOException(\"old dex version mismatch! expetced: \"\n                        + expectedOldDexAPI + \", actual: \" + oldDexAPI);\n            }\n        }\n        byte[] oldDexSign = this.oldDex.computeSignature(false);\n        if (oldDexSign == null) {\n            throw new IOException(\"failed to compute old dex's signature.\");\n        }\n        byte[] oldDexSignInPatchFile = this.patchFile.getOldDexSignature();\n        if (CompareUtils.uArrCompare(oldDexSign, oldDexSignInPatchFile) != 0) {\n            throw new IOException(\n                    String.format(\n                            \"old dex signature mismatch! expected: %s, actual: %s\",\n                            Arrays.toString(oldDexSign),\n                            Arrays.toString(oldDexSignInPatchFile)\n                    )\n            );\n        }\n\n        // Firstly, set sections' offset after patched, sort according to their offset so that\n        // the dex lib of aosp can calculate section size.\n        TableOfContents patchedToc = this.patchedDex.getTableOfContents();\n\n        patchedToc.api = patchFile.getPatchedDexAPI();\n        patchedToc.header.off = 0;","sourceCodeStart":113,"sourceCodeEnd":149,"githubUrl":"https://github.com/Tencent/tinker/blob/1b7ea02c239840f563ea64fb5bd286eb98d4011e/tinker-commons/src/main/java/com/tencent/tinker/commons/dexpatcher/DexPatchApplier.java#L113-L149","documentation":"IOException from DexPatchApplier.executeAndSaveTo: Dex.computeSignature returned null, so the applier cannot verify the old dex matches the patch's expected signature. computeSignature fails when the dex is too short or its map section cannot be read — i.e., the old dex input is not a usable dex.","triggerScenarios":"Passing a truncated, empty, or non-dex buffer as oldDex to DexPatchApplier; the dex was corrupted before patch application began.","commonSituations":"Reading the old dex from a bad odex/vdex extraction path, a partially written file, or a decompressed stream that failed; on-device patch applying where the base dex could not be fully loaded.","solutions":["Log and inspect the old dex bytes (length, header magic 'dex\\n035') before applying","Fix the extraction path so the full original dex (not odex/vdex artifacts) is fed in","Re-download or restore the base dex/apk if corrupted"],"exampleFix":"// before\nbyte[] oldDexBuf = loadMaybeCorruptedDex();\nnew DexPatchApplier(new Dex(oldDexBuf), patchFile).executeAndSaveTo(out);\n\n// after\nbyte[] oldDexBuf = loadMaybeCorruptedDex();\nif (oldDexBuf == null || oldDexBuf.length < 112 || !oldDexBuf[0]=='d') throw new IOException(\"bad old dex\");\nnew DexPatchApplier(new Dex(oldDexBuf), patchFile).executeAndSaveTo(out);","handlingStrategy":"validation","validationCode":"byte[] buf = readAll(oldDexStream);\nif (buf.length < 112\n        || buf[0] != 'd' || buf[1] != 'e' || buf[2] != 'x' || buf[3] != '\\n') {\n    throw new IOException(\"old dex unreadable (len=\" + buf.length + \")\");\n}\nnew DexPatchApplier(new Dex(buf), patchFile).executeAndSaveTo(out);","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Validate dex header magic, file length, and checksum before patch application","Extract the original dex (not odex/vdex) with a tested code path"],"tags":["dexpatcher","corrupted-dex","signature","patch-apply"],"backgroundTag":null,"analyzedSha":"1b7ea02c239840f563ea64fb5bd286eb98d4011e","analyzedAt":"2026-08-14T15:16:52.110Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}