fix(waproto): normalize high to int32 + tighten roundtrip test
Addresses 2 review comments on PR #385: 1. CodeRabbit Major — longToString/longToNumber checked `value.high < 0` on the raw input. When a Long-like object carries high as an unsigned 32-bit value (e.g. raw {low, high} from JSON deserialization, not constructed via Long.fromBits/fromValue which normalize via `| 0`), the sign-bit detection fails and the value is interpreted as unsigned. Example: {low: 0, high: 0xFFFFFFFF} signed should be -4294967296 but returned 18446744069414584320. Fix: `const high = value.high | 0` before the sign check. Applied to both helpers in WAProto/index.js (generated artifact) and WAProto/fix-imports.js (template). Diverges from upstream Baileys PR #2333 which has the same latent bug. Added 2 test cases in bigint-validation.test.ts for the raw {low, high} scenario (Long.fromBits would mask the bug because it normalizes internally). 2. CodeRabbit Nitpick — the encode/decode roundtrip test in proto-tojson-long.test.ts used safe integers (1700000000 and 123456789), which would silently pass even if longToString fell back to Number(value). Switched to uint64 values above MAX_SAFE_INTEGER (max uint64 and 9999999999999999999) so the roundtrip actually exercises the BigInt fast path. Test suite: 789/789 passing (+2 cases for the unsigned-high scenario). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -21,10 +21,13 @@ try {
|
||||
'\t// Fast path: convert Long {low, high} directly via native BigInt\n' +
|
||||
'\t// BigInt.toString() is a native C++ operation, much faster than Long\'s pure JS division loops\n' +
|
||||
'\tif (value && typeof value.low === "number" && typeof value.high === "number") {\n' +
|
||||
'\t\t// Normalize high to signed int32 so the sign-bit check works for inputs\n' +
|
||||
'\t\t// where high is stored unsigned (e.g. raw {low, high} JSON).\n' +
|
||||
'\t\tconst high = value.high | 0;\n' +
|
||||
'\t\tconst lo = BigInt(value.low >>> 0);\n' +
|
||||
'\t\tconst hi = BigInt(value.high >>> 0);\n' +
|
||||
'\t\tconst combined = (hi << 32n) | lo;\n' +
|
||||
'\t\tif (!unsigned && value.high < 0) {\n' +
|
||||
'\t\tif (!unsigned && high < 0) {\n' +
|
||||
'\t\t\treturn (combined - (1n << 64n)).toString();\n' +
|
||||
'\t\t}\n' +
|
||||
'\t\treturn combined.toString();\n' +
|
||||
@@ -41,10 +44,11 @@ try {
|
||||
'\t}\n' +
|
||||
'\t// Fast path: convert Long {low, high} directly via native BigInt\n' +
|
||||
'\tif (value && typeof value.low === "number" && typeof value.high === "number") {\n' +
|
||||
'\t\tconst high = value.high | 0;\n' +
|
||||
'\t\tconst lo = BigInt(value.low >>> 0);\n' +
|
||||
'\t\tconst hi = BigInt(value.high >>> 0);\n' +
|
||||
'\t\tconst combined = (hi << 32n) | lo;\n' +
|
||||
'\t\tif (!unsigned && value.high < 0) {\n' +
|
||||
'\t\tif (!unsigned && high < 0) {\n' +
|
||||
'\t\t\treturn Number(combined - (1n << 64n));\n' +
|
||||
'\t\t}\n' +
|
||||
'\t\treturn Number(combined);\n' +
|
||||
|
||||
Reference in New Issue
Block a user