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

  1. Ensure old dex at apply time exactly matches the one used at diff time (signature check)
  2. Upgrade Tinker to a release with a newer bundled dexlib2
  3. 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

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


AI-assisted analysis of Tencent/tinker@1b7ea02c23 (2026-08-14). Data as JSON: /api/errors/66e41d47f237bf93. Report an issue: GitHub.