Repository navigation
fix: refuse text for a binary parameter - #40
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
There was a problem hiding this comment.
ℹ️ No critical issues. Two small suggestions: a hint in the error message and a docs gap.
Reviewed changes
I reviewed the new run-time check that refuses any value other than a Uint8Array for a binary parameter, and its tests.
checkBinaryinstatement(): a scalar parameter whose engine type is exactlybyteaorblob, or an element of an array of one, must be aUint8Array. Otherwise.run()throws aParameterErrorbefore the statement runs. This matches whatrenderParamTypealready gives as the TS type, and the check a structured parameter's binary member already had insrc/rows.ts.- Scope checked against the engine: an unnarrowed MySQL
BITcontext is typedbool|bytea(param_typeinengine/mysql/src/mysql.rs). The match is on the exact name, so it isn't checked, andBIT(1)columns keep taking truth values. On SQLite, an untyped column or aSTRICTANYcolumn isunknown, notblob, so it isn't affected either. - Tests:
node --test tests/execute.test.tspasses (46/46) at687c06a.
ℹ️ The docs don't mention the new refusal
The "Binary parameters" rules say only that a binary parameter "takes a Uint8Array, a Buffer or not, on every driver". The Postgres parameter bullets list each refusal .run() makes before the statement runs: text without a zone, a Date, a NULL array element. This one isn't there, so a reader still can't tell that base64 or hex text is now refused rather than stored.
Technical details
# Document that `.run()` refuses a non-Uint8Array binary parameter
## Affected sites
- site/content/docs/postgres.mdx:443-445 — "Binary parameters" rule; also the parameter bullets at ~L741-748
- site/content/docs/sqlite.mdx:429-431 — "Binary parameters" rule
- site/content/docs/mysql.mdx:414+ — "Binary" section (BINARY, VARBINARY, BLOB, BIT wider than 1)
## Required outcome
- Each dialect's docs say that a binary parameter refuses any other value, base64 or hex text included, before the statement runs, and say to decode the text into a `Uint8Array` first.claude-opus-5-5 | 𝕏
There was a problem hiding this comment.
✅ No new issues found. Both points from the last review are addressed.
Reviewed changes
I reviewed the two commits pushed since the last review: one changes the refusal message, the other updates the docs.
ArrayBufferhint: when the value is anArrayBuffer,checkBinarynow ends its message with "Wrap an ArrayBuffer in one: new Uint8Array(buffer)." instead of the base64 or hex hint. The test now checks the whole message.- Docs: the binary parameter rule in
postgres.mdx,mysql.mdxandsqlite.mdxnow says that any other value, base64 or hex text included, is refused before the statement runs, and says to decode the text first. The Postgres parameter list has a matchingbyteabullet. - Tests:
node --test tests/execute.test.tspasses (46/46) at7d448bd.
claude-opus-5-5 | 𝕏
A binary parameter is typed Uint8Array, but run passed any other value to the driver as it was. A string then meant something different on each database, and base64 text was stored as its own letters. A structured parameter's binary member already refused it.
7d448bd to
3913d4b
Compare
There was a problem hiding this comment.
✅ No new issues found. The rebase leaves the check as it was and moves the docs into
main's rewritten pages.
Reviewed changes
Since the last review, the branch was rebased onto main, where the database docs pages had been rewritten. src/execute.ts, src/rows.ts and the test are unchanged apart from context lines.
- Docs moved into "What a parameter takes": the old "Binary parameters" sections are gone from
main, so the refusal is now one line on each page.postgres.mdxandmysql.mdxhave it as a bullet beside the date and JSON rules.sqlite.mdxhas it as a sentence under the type table, because that section has no list. Each one says a binary parameter takes only aUint8Array, gives the per‑database reason, and says to decode the text first. - Tests:
node --test tests/execute.test.tspasses (46/46) at3913d4b.
claude-opus-5-5 | 𝕏

A binary parameter (
byteaon Postgres,BINARY,VARBINARYandBLOBon MySQL,BLOBon SQLite) is typedUint8Array, but.run()passed any other value to the driver unchanged. A string then means something different on each database: Postgres reads it as bytea's hex or escape text, MySQL stores the bytes of its UTF-8, and SQLite stores it as TEXT, which comes back a string where the column's type saysUint8Array. Base64 text, for one, was stored as its own letters..run()now refuses anything but aUint8Array(aBufferis one) for a binary parameter, and for each element of a binary array, before the statement runs, the way a structured parameter's binary member already did:src/execute.ts:checkBinary, beside the date and time checks.src/rows.ts: exportsdescribefor the message.tests/execute.test.ts: the refusal on all three dialects, for a scalar and an array element, and that aBuffer, aUint8Arrayand null still bind.nub run typecheckandnub run testpass locally (the server-backed tests run in CI).