fixed nota encoding/decoding bug with arrays longer than 126 elements

This commit is contained in:
2025-02-23 17:16:00 -06:00
parent f728a217c9
commit 5254b84704
3 changed files with 44 additions and 12 deletions

View File

@@ -77,16 +77,24 @@ char *nota_skip(char *nota)
char *nota_read_num(long long *n, char *nota)
{
if (!n)
return nota_skip(nota);
*n = 0;
*n |= (*nota) & NOTA_HEAD_DATA;
while (CONTINUE(*(nota++)))
*n = (((*n<<7) | *nota) & NOTA_DATA);
if (!n) {
return nota_skip(nota);
}
return nota;
// Start by reading the first byte
unsigned char b = *nota;
int result = b & NOTA_HEAD_DATA; // lower bits
nota++;
// While the top bit is set, read more 7-bit chunks
while (CONTINUE(b)) {
b = *nota;
nota++;
result = (result << 7) | (b & NOTA_DATA);
}
*n = result;
return nota;
}
// Given a number n, and bits used in the first char sb, how many bits are needed

View File

@@ -117,13 +117,21 @@ char *js_do_nota_encode(JSContext *js, JSValue v, char *nota)
return nota_write_blob(bloblen*8, blob, nota);
if (JS_IsArray(js, v)) {
JSValue lengthVal = JS_GetPropertyStr(js, v, "length");
int n;
JS_ToInt32(js, &n, JS_GetPropertyStr(js, v, "length"));
JS_ToInt32(js, &n, lengthVal);
JS_FreeValue(js, lengthVal);
nota = nota_write_array(n, nota);
for (int i = 0; i < n; i++)
nota = js_do_nota_encode(js, JS_GetPropertyUint32(js, v, i), nota);
for (int i = 0; i < n; i++) {
JSValue elemVal = JS_GetPropertyUint32(js, v, i);
nota = js_do_nota_encode(js, elemVal, nota);
JS_FreeValue(js, elemVal);
}
return nota;
}
JS_GetOwnPropertyNames(js, &ptab, &plen, v, JS_GPN_ENUM_ONLY | JS_GPN_STRING_MASK);
nota = nota_write_record(plen, nota);

View File

@@ -96,6 +96,13 @@ function deepCompare(expected, actual, path = '') {
}
// Extended test cases covering all Nota types from documentation
var testarr = []
var hex = "a374"
for (var i = 0; i < 500; i++) {
testarr.push(1)
hex += "61"
}
var testCases = [
// Integer tests
{ input: 0, expectedHex: "60" },
@@ -130,6 +137,8 @@ var testCases = [
{ input: new Uint8Array([0b11110000, 0b11100011, 0b00100000, 0b10000000]).buffer,
expectedHex: "8019f0e32080" }, // 25 bits example padded to 32 bits
{ input: testarr, expectedHex: hex },
// Array tests
{ input: [], expectedHex: "20" },
{ input: [1, 2, 3], expectedHex: "23616263" },
@@ -156,6 +165,13 @@ var testCases = [
{ input: { system: { msg: "hello" } },
expectedHex: "3179216d73671568656c6c6f" },
{ input: [ { system: {msg: "hello" } }, {
num: 42,
arr: [1, -1, 2.5],
str: "test",
obj: { x: true }
} ], expectedHex: "223179216d73671568656c6c6f34216e756d622a2173747214746573742161727223616965235840216f626a21117873" },
// Additional edge cases
{ input: new Uint8Array([]).buffer, expectedHex: "00" }, // Empty blob
{ input: [[]], expectedHex: "2120" }, // Nested empty array