Skip to content

fix(protocol): read 3-byte length-encoded ints without panicking - #200

Open
AntonPates wants to merge 1 commit into
maxpert:masterfrom
AntonPates:fix/length-encoded-int-0xfd
Open

AntonPates wants to merge 1 commit into
maxpert:masterfrom
AntonPates:fix/length-encoded-int-0xfd

Conversation

@AntonPates

@AntonPates AntonPates commented Oct 13, 2026 •

Copy link
Copy Markdown

Fixes #199.

Problem

readLengthEncodedInt decoded the 0xFD prefix (a 3-byte little-endian length) with binary.LittleEndian.Uint32(b[1:4]). Uint32 needs 4 bytes, so this always panicked. Clients send every string/BLOB parameter of 64 KiB..16 MiB in COM_STMT_EXECUTE with that prefix, so one such INSERT crashed the whole server process (index out of range [3] with length 3).

Change

  • protocol/server.go: decode the three bytes explicitly: uint64(b[1]) | uint64(b[2])<<8 | uint64(b[3])<<16.
  • protocol/length_encoded_int_test.go:
    • a table test for readLengthEncodedInt covering every prefix, including the 0xFD boundaries (65,536 and 16,777,215), an exact 4-byte slice and truncated input;
    • parseParamValue with a 70,000-byte BLOB.

Testing

  • New tests fail on master with the same panic as in production, and pass with the fix.
  • go test ./protocol/ passes.
  • I built a node from this branch and ran it standalone. A go-sql-driver client then inserted 100 KB and 2 MB BLOBs as ordinary prepared-statement parameters, and both read back byte for byte. On v2.10.0-beta the 100 KB insert makes the process exit with status 2.

🤖 Generated with Claude Code

https://claude.ai/code/session_01UToh6jDBmKGsVgdjX2Cbq8

readLengthEncodedInt decoded the 0xFD prefix with
binary.LittleEndian.Uint32(b[1:4]), which needs 4 bytes but gets 3 and
always panics. Clients send every string/BLOB parameter of 64 KiB..16 MiB
in COM_STMT_EXECUTE with that prefix, so one such INSERT crashed the
whole server process (index out of range [3] with length 3).

Decode the three bytes explicitly and add tests for every prefix and for
parseParamValue with a 70000-byte BLOB.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UToh6jDBmKGsVgdjX2Cbq8

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

MySQL server panics and exits on prepared-statement parameters of 64 KiB or more

1 participant