fix: append large parser collections safely
This commit is contained in:
9
src/onenote/model/append.ts
Normal file
9
src/onenote/model/append.ts
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
// This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
// License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||||
|
// You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||||
|
// SPDX-License-Identifier: MPL-2.0
|
||||||
|
|
||||||
|
/** Append a bounded collection without relying on the engine's argument cap. */
|
||||||
|
export function appendItems<T>(target: T[], items: readonly T[]): void {
|
||||||
|
for (const item of items) target.push(item);
|
||||||
|
}
|
||||||
@@ -11,6 +11,7 @@
|
|||||||
|
|
||||||
import { BinaryReader } from '../binary/BinaryReader.js';
|
import { BinaryReader } from '../binary/BinaryReader.js';
|
||||||
import { filetimeToIso, oneNoteTimeToIso } from '../binary/time.js';
|
import { filetimeToIso, oneNoteTimeToIso } from '../binary/time.js';
|
||||||
|
import { appendItems } from '../model/append.js';
|
||||||
import type { ParserDiagnostic } from '../model/diagnostics.js';
|
import type { ParserDiagnostic } from '../model/diagnostics.js';
|
||||||
import type { OneNotePageSummaryDto, OneNoteSectionDto } from '../model/dto.js';
|
import type { OneNotePageSummaryDto, OneNoteSectionDto } from '../model/dto.js';
|
||||||
import type { OneNoteParserLimits } from '../parser/limits.js';
|
import type { OneNoteParserLimits } from '../parser/limits.js';
|
||||||
@@ -341,7 +342,10 @@ function traverseReferences(
|
|||||||
): string[] {
|
): string[] {
|
||||||
const result: string[] = [];
|
const result: string[] = [];
|
||||||
for (const id of ids) {
|
for (const id of ids) {
|
||||||
result.push(...extractGraphText(context, space, id, active, depth + 1));
|
appendItems(
|
||||||
|
result,
|
||||||
|
extractGraphText(context, space, id, active, depth + 1)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,6 +4,7 @@
|
|||||||
|
|
||||||
import { BinaryReader } from '../binary/BinaryReader.js';
|
import { BinaryReader } from '../binary/BinaryReader.js';
|
||||||
import { readGuid } from '../binary/guid.js';
|
import { readGuid } from '../binary/guid.js';
|
||||||
|
import { appendItems } from '../model/append.js';
|
||||||
import type { ParserDiagnostic } from '../model/diagnostics.js';
|
import type { ParserDiagnostic } from '../model/diagnostics.js';
|
||||||
import { parseDesktopOneNoteTableOfContentsStore } from '../onestore/desktop-store.js';
|
import { parseDesktopOneNoteTableOfContentsStore } from '../onestore/desktop-store.js';
|
||||||
import type { DesktopOneStore } from '../onestore/desktop-store.js';
|
import type { DesktopOneStore } from '../onestore/desktop-store.js';
|
||||||
@@ -171,7 +172,7 @@ function parseChildren(
|
|||||||
color: optionalColor(child),
|
color: optionalColor(child),
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
result.push(...parseChildren(context, child, depth + 1));
|
appendItems(result, parseChildren(context, child, depth + 1));
|
||||||
}
|
}
|
||||||
} finally {
|
} finally {
|
||||||
context.active.delete(key);
|
context.active.delete(key);
|
||||||
|
|||||||
21
tests/append.test.ts
Normal file
21
tests/append.test.ts
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
// This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
// License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||||
|
// You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||||
|
// SPDX-License-Identifier: MPL-2.0
|
||||||
|
|
||||||
|
import { describe, expect, it } from 'vitest';
|
||||||
|
|
||||||
|
import { appendItems } from '../src/onenote/model/append.js';
|
||||||
|
|
||||||
|
describe('bounded collection append', () => {
|
||||||
|
it('does not use a variadic call for argument-limit-sized collections', () => {
|
||||||
|
const source = Array.from({ length: 200_000 }, (_, index) => index);
|
||||||
|
const target = [-1];
|
||||||
|
|
||||||
|
appendItems(target, source);
|
||||||
|
|
||||||
|
expect(target).toHaveLength(200_001);
|
||||||
|
expect(target[0]).toBe(-1);
|
||||||
|
expect(target.at(-1)).toBe(199_999);
|
||||||
|
});
|
||||||
|
});
|
||||||
Reference in New Issue
Block a user