fix: bound aggregate nested property sets

This commit is contained in:
2026-07-22 20:15:46 +02:00
parent 6a87ef6510
commit edb19bfcc8
2 changed files with 92 additions and 7 deletions

View File

@@ -71,4 +71,63 @@ describe('bounded OneStore primitives', () => {
value: Uint8Array.from([0xaa, 0xbb, 0xcc]),
});
});
it('enforces one aggregate budget across nested PropertySet arrays', () => {
const bytes = objectPropertySetWithNestedArrays(16);
const reference = {
offset: 0,
size: bytes.length,
nil: false,
zero: false,
};
expect(() =>
parseObjectPropSet(
bytes,
reference,
// Every array contains one set, but the property set contains 16.
resolveParserLimits({ maxObjectReferences: 15 })
)
).toThrowError(
expect.objectContaining({
code: 'LIMIT_EXCEEDED',
structure: 'Nested PropertySets',
})
);
const parsed = parseObjectPropSet(
bytes,
reference,
resolveParserLimits({ maxObjectReferences: 16 })
);
expect(parsed.properties.entries).toHaveLength(16);
});
});
function objectPropertySetWithNestedArrays(count: number): Uint8Array {
const propertyIds = Array.from({ length: count }, (_, index) =>
u32((0x10 << 26) | index)
).flat();
const values = Array.from({ length: count }, (_, index) => [
...u32(1), // One nested PropertySet in this array.
...u32(index),
0x00,
0x00, // Empty nested PropertySet.
]).flat();
return Uint8Array.from([
...u32(0x8000_0000), // Zero OIDs; OSID stream absent.
count & 0xff,
count >>> 8,
...propertyIds,
...values,
]);
}
function u32(value: number): number[] {
return [
value & 0xff,
(value >>> 8) & 0xff,
(value >>> 16) & 0xff,
value >>> 24,
];
}