fix: bound actual table references
This commit is contained in:
@@ -46,7 +46,7 @@ describe('content table allocation safety', () => {
|
|||||||
expect.objectContaining({
|
expect.objectContaining({
|
||||||
code: 'CONTENT_PARSE_FAILED',
|
code: 'CONTENT_PARSE_FAILED',
|
||||||
message: expect.stringContaining(
|
message: expect.stringContaining(
|
||||||
'Declared table column count exceeds 1000000'
|
`Declared table column count exceeds ${DEFAULT_ONENOTE_PARSER_LIMITS.maxTableCells}`
|
||||||
),
|
),
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
@@ -77,7 +77,43 @@ describe('content table allocation safety', () => {
|
|||||||
})
|
})
|
||||||
).toEqual([]);
|
).toEqual([]);
|
||||||
expect(diagnostics[0]?.message).toContain(
|
expect(diagnostics[0]?.message).toContain(
|
||||||
'Declared table cell count exceeds 1000000'
|
`Declared table cell count exceeds ${DEFAULT_ONENOTE_PARSER_LIMITS.maxTableCells}`
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('rejects actual row references before mapping an oversized array', () => {
|
||||||
|
const tableId: ExGuid = { guid: GUID, value: 3 };
|
||||||
|
const firstRowId: ExGuid = { guid: GUID, value: 4 };
|
||||||
|
const secondRowId: ExGuid = { guid: GUID, value: 5 };
|
||||||
|
const table = object(
|
||||||
|
tableId,
|
||||||
|
JCID.TableNode,
|
||||||
|
props(referenceEntry(PROPERTY.ElementChildNodes, 2))
|
||||||
|
);
|
||||||
|
table.resolvedObjectIds = [firstRowId, secondRowId];
|
||||||
|
const firstRow = object(firstRowId, JCID.TableRowNode, props());
|
||||||
|
const secondRow = object(secondRowId, JCID.TableRowNode, props());
|
||||||
|
const diagnostics: ParserDiagnostic[] = [];
|
||||||
|
|
||||||
|
expect(
|
||||||
|
parseContentObjects([tableId], {
|
||||||
|
space: {
|
||||||
|
id: { guid: GUID, value: 0 },
|
||||||
|
roots: new Map(),
|
||||||
|
objects: new Map(
|
||||||
|
[table, firstRow, secondRow].map((value) => [
|
||||||
|
exGuidKey(value.id),
|
||||||
|
value,
|
||||||
|
])
|
||||||
|
),
|
||||||
|
},
|
||||||
|
limits: { ...DEFAULT_ONENOTE_PARSER_LIMITS, maxTableCells: 1 },
|
||||||
|
diagnostics,
|
||||||
|
resources: new Map(),
|
||||||
|
})
|
||||||
|
).toEqual([]);
|
||||||
|
expect(diagnostics[0]?.message).toContain(
|
||||||
|
'Table row reference count exceeds 1'
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@@ -122,3 +158,12 @@ function bytesEntry(rawId: number, value: Uint8Array): PropertyEntry {
|
|||||||
value: { kind: 'bytes', value },
|
value: { kind: 'bytes', value },
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function referenceEntry(rawId: number, count: number): PropertyEntry {
|
||||||
|
return {
|
||||||
|
rawId,
|
||||||
|
id: rawId & 0x03ff_ffff,
|
||||||
|
type: 0x9,
|
||||||
|
value: { kind: 'objectIds', count },
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|||||||
@@ -540,6 +540,11 @@ function parseTable(
|
|||||||
context.limits.maxTableCells
|
context.limits.maxTableCells
|
||||||
);
|
);
|
||||||
const rowIds = objectReferences(object, PROPERTY.ElementChildNodes);
|
const rowIds = objectReferences(object, PROPERTY.ElementChildNodes);
|
||||||
|
if (rowIds.length > context.limits.maxTableCells) {
|
||||||
|
throw new Error(
|
||||||
|
`Table row reference count exceeds ${context.limits.maxTableCells}`
|
||||||
|
);
|
||||||
|
}
|
||||||
if (declaredRowCount !== undefined && declaredRowCount !== rowIds.length) {
|
if (declaredRowCount !== undefined && declaredRowCount !== rowIds.length) {
|
||||||
addDiagnostic(
|
addDiagnostic(
|
||||||
context,
|
context,
|
||||||
@@ -553,6 +558,14 @@ function parseTable(
|
|||||||
const row = getObject(context.space, rowId, 'table row');
|
const row = getObject(context.space, rowId, 'table row');
|
||||||
assertJcid(row, JCID.TableRowNode, 'TableRowNode');
|
assertJcid(row, JCID.TableRowNode, 'TableRowNode');
|
||||||
const cellIds = objectReferences(row, PROPERTY.ElementChildNodes);
|
const cellIds = objectReferences(row, PROPERTY.ElementChildNodes);
|
||||||
|
if (
|
||||||
|
cellIds.length >
|
||||||
|
context.limits.maxTableCells - context.budget.tableCells
|
||||||
|
) {
|
||||||
|
throw new Error(
|
||||||
|
`Table cell reference count exceeds ${context.limits.maxTableCells}`
|
||||||
|
);
|
||||||
|
}
|
||||||
if (
|
if (
|
||||||
declaredColumnCount !== undefined &&
|
declaredColumnCount !== undefined &&
|
||||||
cellIds.length !== declaredColumnCount
|
cellIds.length !== declaredColumnCount
|
||||||
|
|||||||
Reference in New Issue
Block a user