Skip to content

refactor(rust): replace the hand-rolled base64 and hex codecs with crates - #1132

Merged
thekevinscott merged 3 commits into
mainfrom
claude/1130-codec-crates
Sep 18, 2026
Merged

thekevinscott merged 3 commits into
mainfrom
claude/1130-codec-crates

Conversation

@thekevinbot

Copy link
Copy Markdown
Collaborator

Fixes #1130.

Deletes the hand-rolled binary codecs in the core and replaces them with the crates that cover them.

  • packages/rust/src/functions.rs: BASE64_ALPHABET, base64_encode, base64_decode (~58 lines) → base64::engine::general_purpose::STANDARD. The #[expect(clippy::cast_possible_truncation)] the decoder's shifts needed goes with them.
  • packages/rust/src/cli/serialize.rs: hex_encode (7 lines) → hex::encode. Taken rather than left alone: seven lines of format!("{b:02x}") in a loop is the same hand-rolled-infrastructure shape as the base64, and hex is zero-dependency and CLI-gated, so a library consumer never sees it.

Net −90 lines in packages/rust/src.

Dependencies

base64 = "0.22" is unconditional — functions.rs is core, reachable by a library consumer through the function-worker path, not the CLI. It is zero-dependency, no_std-capable, and was already in Cargo.lock transitively, so the lockfile gains exactly one new entry (hex). hex = "0.4" is optional = true behind the cli feature.

Byte-identical output

STANDARD is the standard alphabet with required padding and no line wrapping, which is what docs/reference/config.md documents for {"$bytes": "<base64>"} and what the embeddings plugin's stdlib base64 decodes. hex::encode is lowercase, two chars per byte, no separator.

Decoder strictness is preserved on every path the deleted tests covered. Verified with a throwaway probe against parse_response (removed before committing) — each of "abc" (length not a multiple of 4), "a!==" (byte outside the alphabet), "ab=c", "ab==cd==" and "a===" (padding outside the close of the final chunk) still fails the query with "$bytes" is not valid base64, and "AQI=" still decodes to [1, 2].

One input is now rejected that the old decoder accepted: a final character carrying non-canonical trailing bits, e.g. "AQJ=". No conforming encoder emits it, no test covered it, and the old behavior (silently dropping the stray bits) was not a documented promise. Called out here rather than configured away, because decode_allow_trailing_bits is the laxer setting and matching a hand-rolled quirk is not worth carrying.

Tests

The colocated tests for the deleted functions are deleted with them (base64_round_trips_every_padding_length, base64_known_vectors, base64_decode_rejects_malformed_input, hex_encode_matches_lowercase_spec) — a test for a function that no longer exists is not a test. The protocol-level tests (request_line_encodes_every_scalar_shape, meta_does_not_change_the_decoded_value, response_defects_are_named, blob_cell_becomes_hex_string) are unchanged and pass.

blob_cell_becomes_hex_string picks up the hex_encode_matches_lowercase_spec vector (00 0f ff → 000fff) at the public seam, so the zero-padding assertion survives the deletion rather than being dropped.

No new tests restating crate behavior. unit mutation on the changed lines: 2 mutants, 0 survivors.

Coverage

No floor re-pinned. cargo +nightly llvm-cov --lib --features cli --branch, same command on both sides:

main (12a73dd) this branch floor
lines 94.53 94.49 92
regions 93.67 93.62 91
functions 93.17 93.11 91
branch 80.06 79.49 72

The deletion removes 18 fully-covered branches and no uncovered ones, so branch dips a little while missed-branch count is identical (128 both sides). Everything stays well clear of [rust.coverage], so the floors are untouched.

Manual exercise

Built the CLI (cargo build --features cli --bin dirsql) and round-tripped real BLOBs through a [[dirsql.function]] worker that prints the request line it receives.

$ dirsql -c /tmp/.../dirsql.config.toml "SELECT hex(echo_bytes(x'00deadbeeff0')) AS round_tripped" --format json
WORKER SAW: {"$bytes": "AN6tvu/w"}
WORKER DECODED: b'\x00\xde\xad\xbe\xef\xf0'
[{"round_tripped":"00DEADBEEFF0"}]

$ dirsql -c ... "SELECT quote(echo_bytes(x'666f6f62')) AS padded" --format json
WORKER SAW: {"$bytes": "Zm9vYg=="}
WORKER DECODED: b'foob'
[{"padded":"X'666F6F62'"}]

$ dirsql -c ... "SELECT bad_bytes(1)" --format json     # worker answers {"$bytes": "ab=c"}
dirsql query: SQLite error: function `bad_bytes` worker sent an invalid response ("$bytes" is not valid base64): {"ok": {"$bytes": "ab=c"}}

AN6tvu/w carries a /, confirming the standard (not URL-safe) alphabet; Zm9vYg== is verbatim the vector the deleted base64_known_vectors asserted. The worker is a Python script decoding with stdlib base64.b64decode(..., validate=True), i.e. the same decoder the embeddings plugin uses, and it accepted the payload.

Hex, through the HTTP API (the path cli/serialize.rs serves):

$ dirsql server --port 8791 &
$ curl -s -X POST localhost:8791/query -H 'content-type: application/json' -d '{"sql":"SELECT x'"'"'000fffdead'"'"' AS b"}'
[{"b":"000fffdead"}]

000fffdead is verbatim the vector the deleted hex_encode_matches_lowercase_spec asserted.

Parity

No public API change — both functions were private. PARITY.md is untouched.

E2E Verification

  • Ran e2e suites locally for every affected SDK
  • Python SDK e2e: pass (37 passed)
  • TypeScript SDK e2e: pass (17 passed, 5 files)
  • Rust core e2e (if applicable): pass (cargo test --features cli --tests, all suites green)
  • packages/python/e2e-attestations/<branch>.json receipt written if packages/python changed (just e2e-attest-python)
  • packages/ts/e2e-attestations/<branch>.json receipt written if packages/ts changed (just e2e-attest-ts)
  • Command(s) run: just e2e-attest-python; just e2e-attest-ts; cargo test --manifest-path packages/rust/Cargo.toml --features cli --tests; cargo test --lib --features cli; just preflight
  • Result summary: python 37/37, ts 17/17, rust 882 unit + all integration suites green, just preflight 0 failing pairs / 3 skipped.

Changelog / Migrations

  • Changelog fragment added under <root>/<pkg>/changelog.d/ for each changed package (packages/rust/changelog.d/2026-09-18-codec-crates.md, Changed)
  • Migration fragment added under <root>/<pkg>/migrations.d/ (or: not required -- additive/bugfix only) — not required, behavior-preserving refactor

`functions.rs` hand-rolled a standard-alphabet base64 encoder and a strict
decoder (~58 lines, including a `clippy::cast_possible_truncation` opt-out
for its shifts) and `cli/serialize.rs` hand-rolled hex. Both are replaced by
the crates that cover them: `base64`'s `general_purpose::STANDARD` engine,
which is byte-for-byte the configuration the `{"$bytes": "<base64>"}` wire
format documents, and `hex::encode`.

`base64` is an unconditional dependency because the function-worker path is
core, not CLI; `hex` sits behind the `cli` feature. Both are zero-dependency
and `base64` was already in the lockfile transitively.

The colocated tests for the deleted functions go with them. The protocol
tests one level up are untouched and still pass, including the malformed
inputs the old decoder rejected.
@thekevinscott
thekevinscott merged commit 922cfda into main Sep 18, 2026
77 checks passed
@thekevinscott
thekevinscott deleted the claude/1130-codec-crates branch September 18, 2026 16:39
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.

core: replace the hand-rolled base64 and hex codecs with the crates that cover them

2 participants