Repository navigation
fix: resolve a Binary length of 0 or NaN from the value - #1817
cheenamalhotra wants to merge 7 commits into
Conversation
Since tediousjs#1774, an explicit Binary length of 0 or NaN was sent as a zero TYPE_INFO length while the declaration still said binary(n), so the server rejected the request. Treat a falsy length as unspecified, as Binary did before 20.3.0 and as its declaration does. Fixes tediousjs#1812 Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
An empty Binary value now declares binary(1) instead of a zero length, which the server rejects. A declared length larger than the value now writes the value's actual byte count, so the stream is not corrupted; the server pads the value. Both match Microsoft.Data.SqlClient's wire format. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Covers tediousjs#1812 (a length of 0 or NaN), padding, truncation and an empty value. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## master #1817 +/- ##
==========================================
- Coverage 84.76% 83.72% -1.04%
==========================================
Files 96 96
Lines 4720 4726 +6
Branches 884 886 +2
==========================================
- Hits 4001 3957 -44
- Misses 455 514 +59
+ Partials 264 255 -9 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
…ry-explicit-length
…ry-explicit-length
|
Thanks @cheenamalhotra, this is a good find. I'm happy with the direction: treating a For context, I ran the same cases against SQL Server 2025 with tedious 14.7.0 through 20.3.5 and with this branch, covering request parameters, bulk load and TVPs:
Must fix:
|
Since 20.3.0, a
Binaryparameter with an explicitlength: 0orNaNis rejected by the server (#1812).Fixes #1812
Cause
#1774 moved length resolution into
resolveParameter(), which keeps any explicit length (!= null), including0. Before, a falsy length fell back toresolveLength().Binary.resolveLength()ignoresparameter.length, soBinarywas the one type whose wire bytes changed: TYPE_INFO said length 0 whiledeclaration()(still truthiness-based) saidbinary(2).Changes
8fe62f40):Binarygets a nativeresolve()that treats a falsy length as unspecified, matching itsdeclaration()and pre-20.3.0 behavior.bb5e34c9, also broken in 20.2.x):binary(1)declaration.writeValuenow writes the actual byte count, and the server pads the value. Truncation is unchanged.08d28dd0): unit contract tests plus integration tests for length 0/NaN, padding, truncation, and an empty value.Notes for review
writeValueis also used by TVP and bulk load, so abinary(n)cell shorter thannno longer corrupts those requests either. This is whybb5e34c9is a separate commit; it can be split out if preferred.Binarynow treatslength: 0as unset, whileVarBinary/NVarCharkeep an explicit 0. This is deliberate: it matchesBinary's own declaration, andNaNcurrently selects max/PLP for those types, so changing them would be a separate behavior change.Charwithlength: 0has a similar problem but predates 20.3.0. It is left for a follow-up.Verification
0x4A50, length 4 returns0x4A500000, length 1 returns0x4A, and an empty value returns0x00. Null values still use TYPE_INFO 8000, which the server accepts.npm test(609 passing),npm run lint, andnpm run buildpass.cc @saurabh500 @David-Engel @arthurschreiber