[Automatic Import] Fix chunking of samples in ecs mapping (#214702)

This commit is contained in:
Bharat Pasupula 2025-03-17 13:52:37 +01:00 committed by GitHub
parent 59e606cdc4
commit 059e7e7c52
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 52 additions and 22 deletions

View file

@ -17,4 +17,31 @@ describe('test chunks', () => {
JSON.stringify({ c: { d: 3 }, e: 4 }, null, 2),
]);
});
it('handles empty objects', () => {
const objects = ['{}', '{}'];
const chunkSize = 2;
const result = mergeAndChunkSamples(objects, chunkSize);
expect(result).toStrictEqual([]);
});
it('handles large objects with custom chunk size', () => {
const objects = ['{"a": 1, "b": 2, "c": 3, "d": 4}', '{"e": 5, "f": 6, "g": 7, "h": 8}'];
const chunkSize = 3;
const result = mergeAndChunkSamples(objects, chunkSize);
expect(result).toStrictEqual([
JSON.stringify({ a: 1, b: 2, c: 3 }, null, 2),
JSON.stringify({ d: 4, e: 5, f: 6 }, null, 2),
JSON.stringify({ g: 7, h: 8 }, null, 2),
]);
});
it('safely handles prototype pollution attempts', () => {
const objects = [
'{"a": 1, "__proto__": {"polluted": true}, "constructor": {"ignored": true}}',
'{"b": 2, "prototype": {"unsafe": true}, "constructor": {"bad": true}}',
];
const chunkSize = 2;
const result = mergeAndChunkSamples(objects, chunkSize);
expect(result).toStrictEqual([JSON.stringify({ a: 1, b: 2 }, null, 2)]);
});
});

View file

@ -6,7 +6,7 @@
*/
/* eslint-disable @typescript-eslint/no-explicit-any */
import { merge } from '../../util/samples';
import { isUnsafeProperty, merge } from '../../util/samples';
interface NestedObject {
[key: string]: any;
@ -40,32 +40,35 @@ function generateChunks(mergedSamples: NestedObject, chunkSize: number): NestedO
function traverse(current: NestedObject, path: string[] = []) {
for (const [key, value] of Object.entries(current)) {
const newPath = [...path, key];
if (!isUnsafeProperty(key, current)) {
const newPath = [...path, key];
// If the value is a nested object, recurse into it
if (typeof value === 'object' && value !== null && !Array.isArray(value)) {
traverse(value, newPath);
} else {
// For non-object values, add them to the current chunk
let target = currentChunk;
// If the value is a nested object, recurse into it
if (typeof value === 'object' && value !== null && !Array.isArray(value)) {
traverse(value, newPath);
} else {
// For non-object values, add them to the current chunk
let target = currentChunk;
// Recreate the nested structure in the current chunk
for (let i = 0; i < newPath.length - 1; i++) {
if (!(newPath[i] in target)) {
target[newPath[i]] = {};
// Recreate the nested structure in the current chunk
for (let i = 0; i < newPath.length - 1; i++) {
const pathSegment = newPath[i];
if (isUnsafeProperty(pathSegment, target) || !(pathSegment in target)) {
target[pathSegment] = {};
}
target = target[newPath[i]];
}
target = target[newPath[i]];
}
// Add the value to the deepest level of the structure
target[newPath[newPath.length - 1]] = value;
currentSize++;
// Add the value to the deepest level of the structure
target[newPath[newPath.length - 1]] = value;
currentSize++;
// If the chunk is full, add it to the chunks and start a new chunk
if (currentSize === chunkSize) {
chunks.push(currentChunk);
currentChunk = {};
currentSize = 0;
// If the chunk is full, add it to the chunks and start a new chunk
if (currentSize === chunkSize) {
chunks.push(currentChunk);
currentChunk = {};
currentSize = 0;
}
}
}
}