Tencent/tinker · critical · IndexOutOfBoundsException
codeAddress %d out of bounds
Error message
codeAddress %d out of bounds
What it means
IndexOutOfBoundsException from BuilderMutableMethodImplementation.newLabelForAddress(int): the requested code address is negative or beyond the last instruction's code address in the method. Called when dexlib2 materializes labels for offset-based references (switch/branch targets) during dex-to-builder conversion.
Source
Thrown at tinker-build/tinker-patch-lib/src/main/java/org/jf/dexlib2/builder/BuilderMutableMethodImplementation.java:623
if (guessedLocation.codeAddress == codeAddress) {
return index;
} else if (guessedLocation.codeAddress > codeAddress) {
do {
index--;
} while (instructionList.get(index).codeAddress > codeAddress);
return index;
} else {
do {
index++;
} while (index < instructionList.size() && instructionList.get(index).codeAddress <= codeAddress);
return index - 1;
}
}
@Nonnull
public Label newLabelForAddress(int codeAddress) {
if (codeAddress < 0 || codeAddress > instructionList.get(instructionList.size() - 1).codeAddress) {
throw new IndexOutOfBoundsException(String.format("codeAddress %d out of bounds", codeAddress));
}
MethodLocation referent = instructionList.get(mapCodeAddressToIndex(codeAddress));
return referent.addNewLabel();
}
@Nonnull
public Label newLabelForIndex(int instructionIndex) {
if (instructionIndex < 0 || instructionIndex >= instructionList.size()) {
throw new IndexOutOfBoundsException(String.format("instruction index %d out of bounds", instructionIndex));
}
MethodLocation referent = instructionList.get(instructionIndex);
return referent.addNewLabel();
}
@Nonnull
private Label newLabel(@Nonnull int[] codeAddressToIndex, int codeAddress) {
MethodLocation referent = instructionList.get(mapCodeAddressToIndex(codeAddressToIndex, codeAddress));
return referent.addNewLabel();View on GitHub (pinned to 1b7ea02c23)
Solutions
- Ensure old dex at apply time exactly matches the one used at diff time (signature check)
- Upgrade Tinker to a release with a newer bundled dexlib2
- Rebuild the base apk without exotic obfuscation and regenerate the patch
Defensive patterns
Strategy: validation
Validate before calling
// if driving the builder API directly
int lastAddr = impl.getInstructions().get(impl.getInstructions().size() - 1).getCodeAddress();
if (codeAddress < 0 || codeAddress > lastAddr) throw new IllegalArgumentException("bad codeAddress " + codeAddress);
Label l = impl.newLabelForAddress(codeAddress); Try / catch
try { impl.newLabelForAddress(addr); } catch (IndexOutOfBoundsException e) { /* reject input dex */ } Prevention
- Bounds-check any externally derived offset before passing it into builder APIs
- Keep generator and applier Tinker versions identical
When it happens
Trigger: An instruction offset (e.g., a switch payload code offset from a DexBacked dex) computes a codeAddress outside [0, last codeAddress]; typical for malformed branch targets or desynchronized codeAddress-to-index maps after instruction rewrites.
Common situations: Corrupted or non-standard dex; patches applied to a different old dex than they were generated from; older Tinker versions encountering newer dex layouts.
Related errors
- instruction index %d out of bounds
- Switch instruction at address/index 0x%x/%d does not refer t
- Switch instruction at address/index 0x%x/%d refers to the wr
- Unexpected header: 0x${headerSize}
- Unexpected endian tag: 0x${endianTag}
AI-assisted analysis of Tencent/tinker@1b7ea02c23 (2026-08-14).
Data as JSON: /api/errors/66e41d47f237bf93.
Report an issue: GitHub.