From 9abc47ea51c30884b1095c3cbcaf9ab919b3cd5e Mon Sep 17 00:00:00 2001 From: Codex Date: Wed, 30 Sep 2026 16:55:42 +0800 Subject: [PATCH] fix: bound large schematic NBT imports --- docs/issue-128-large-schematic-import.md | 37 +++ packages/importer-schem/src/index.ts | 238 +++++++++++++++++- .../test/fixtures/probe-b-512.schem | Bin 0 -> 107799 bytes packages/importer-schem/test/importer.test.ts | 136 ++++++++++ scripts/bench-probe-b-512.mjs | 54 ++++ 5 files changed, 463 insertions(+), 2 deletions(-) create mode 100644 docs/issue-128-large-schematic-import.md create mode 100644 packages/importer-schem/test/fixtures/probe-b-512.schem create mode 100644 scripts/bench-probe-b-512.mjs diff --git a/docs/issue-128-large-schematic-import.md b/docs/issue-128-large-schematic-import.md new file mode 100644 index 0000000..83653f9 --- /dev/null +++ b/docs/issue-128-large-schematic-import.md @@ -0,0 +1,37 @@ +# Issue #128: bounded large schematic import evidence + +## Root cause + +MinePilot Probe B's Sponge schematic is 512×64×512 with 997,632 occupied blocks. Its gzip file is 107,799 bytes and its NBT `BlockData` byte array is exactly 16,777,216 bytes. `prismarine-nbt@2.8.0` delegates to `protodef@1.19.0`, whose default array reader rejects counts above `0xffffff` (16,777,215). The default parser rejection is covered by the importer regression test. + +## Safety boundary + +The importer now bounds work before using Prismarine's supported `parseUncompressed(data, "big", { noArraySizeCheck: true })` option: + +- compressed schematic input: at most 16 MiB; +- uncompressed NBT: at most 32 MiB, enforced by `gunzipSync({ maxOutputLength })`; +- dimensions: positive and at most 16,777,216 total cells; +- root `BlockData`: at most 24 MiB and at least one encoded byte per cell; +- all other NBT lists and arrays: at most 1,000,000 elements total, no more than 100,000 tags, and at most 64 levels deep; +- large-array imports: at most 1,000,000 decoded non-air blocks. + +A no-allocation NBT preflight validates tag structure, declared collection lengths, dimensions, and the single permitted large array before the large-array parser option is enabled. The parser option is only used when the top-level `BlockData` exceeds the default `0xffffff` limit and the preflight passes. These limits intentionally bound the supported large-schematic envelope to the measured Probe B case and nearby inputs; larger volumes, larger BlockData, or over one million occupied blocks remain rejected. + +## Probe B result + +Exact MinePilot artifact: `packages/importer-schem/test/fixtures/probe-b-512.schem`. + +| Dimensions | Bounding volume | Occupied | BlockData bytes | Compressed bytes | Import | Peak RSS after import | Exact position check | +| --- | ---: | ---: | ---: | ---: | ---: | ---: | --- | +| 512×64×512 | 16,777,216 | 997,632 | 16,777,216 | 107,799 | 540.9 ms | 902,381,568 B (860.6 MiB) | Pass; all occupied coordinates and block names match the deterministic source geometry | + +The separate exact-position verification took 17.0 ms and did not raise the process high-water mark beyond 902,381,568 B (860.6 MiB). This is a successful but memory-heavy import (`PASS_HEAVY`), not a comfortable-scale claim. + +Environment: macOS 27.0 arm64, Node.js v22.22.3, pnpm 8.15.0. Reproduce after building the workspace: + +```sh +pnpm build +node scripts/bench-probe-b-512.mjs +``` + +The benchmark script checks dimensions, occupied count, every occupied position, and material against the deterministic MinePilot Probe B generator formula without allocating a second million-position set. diff --git a/packages/importer-schem/src/index.ts b/packages/importer-schem/src/index.ts index 709fe57..f4ceb18 100644 --- a/packages/importer-schem/src/index.ts +++ b/packages/importer-schem/src/index.ts @@ -14,6 +14,204 @@ interface SchematicData { blockIds: number[]; } +// Probe B establishes a concrete supported large-schematic envelope. Keep +// the larger parser path bounded to that volume and a modest NBT payload. +const MAX_COMPRESSED_SCHEMATIC_BYTES = 16 * 1024 * 1024; +const MAX_UNCOMPRESSED_NBT_BYTES = 32 * 1024 * 1024; +const MAX_SCHEMATIC_VOLUME = 16_777_216; +const MAX_BLOCK_DATA_BYTES = 24 * 1024 * 1024; +const MAX_OTHER_COLLECTION_ITEMS = 1_000_000; +const MAX_TOTAL_COLLECTION_ITEMS = 1_000_000; +const MAX_NBT_TAGS = 100_000; +const MAX_NBT_DEPTH = 64; +const MAX_LARGE_IMPORT_OCCUPIED_BLOCKS = 1_000_000; + +interface SchematicPreflight { + width: number; + height: number; + length: number; + blockDataLength: number; +} + +/** + * Walk NBT tag headers and lengths without allocating tag arrays. This runs + * before opting out of ProtoDef's array guard, so only the bounded root + * BlockData byte array may exceed the ordinary collection limits. + */ +function preflightSchematic(uncompressed: Buffer): SchematicPreflight { + let offset = 0; + let tagCount = 0; + let collectionItems = 0; + let width: number | undefined; + let height: number | undefined; + let length: number | undefined; + let blockDataLength: number | undefined; + + function requireBytes(count: number, description: string): void { + if (!Number.isSafeInteger(count) || count < 0 || offset + count > uncompressed.length) { + throw new Error(`Invalid schematic NBT: truncated ${description}`); + } + } + + function readByte(description: string): number { + requireBytes(1, description); + return uncompressed.readUInt8(offset++); + } + + function readShort(description: string): number { + requireBytes(2, description); + const value = uncompressed.readInt16BE(offset); + offset += 2; + return value; + } + + function readInt(description: string): number { + requireBytes(4, description); + const value = uncompressed.readInt32BE(offset); + offset += 4; + return value; + } + + function readName(): string { + const byteLength = readUnsignedShort("tag name length"); + requireBytes(byteLength, "tag name"); + const name = uncompressed.toString("utf8", offset, offset + byteLength); + offset += byteLength; + return name; + } + + function readUnsignedShort(description: string): number { + requireBytes(2, description); + const value = uncompressed.readUInt16BE(offset); + offset += 2; + return value; + } + + function consumeItems(count: number, description: string): void { + if (count < 0 || count > MAX_OTHER_COLLECTION_ITEMS) { + throw new Error(`Schematic safety limit exceeded: ${description} exceeds ${MAX_OTHER_COLLECTION_ITEMS} items`); + } + collectionItems += count; + if (collectionItems > MAX_TOTAL_COLLECTION_ITEMS) { + throw new Error(`Schematic safety limit exceeded: NBT collections exceed ${MAX_TOTAL_COLLECTION_ITEMS} total items`); + } + } + + function scanPayload(type: number, name: string | undefined, isRootTag: boolean, depth: number): void { + if (depth > MAX_NBT_DEPTH) { + throw new Error(`Schematic safety limit exceeded: NBT nesting exceeds ${MAX_NBT_DEPTH}`); + } + + switch (type) { + case 1: // byte + requireBytes(1, "byte tag"); + offset += 1; + return; + case 2: { // short + const value = readShort("short tag"); + if (isRootTag && name === "Width") width = value; + if (isRootTag && name === "Height") height = value; + if (isRootTag && name === "Length") length = value; + return; + } + case 3: // int + case 5: // float + requireBytes(4, "32-bit tag"); + offset += 4; + return; + case 4: // long + case 6: // double + requireBytes(8, "64-bit tag"); + offset += 8; + return; + case 7: { // byte array + const count = readInt("byte-array length"); + if (count < 0) throw new Error("Invalid schematic NBT: negative byte-array length"); + if (isRootTag && name === "BlockData") { + if (blockDataLength !== undefined) throw new Error("Invalid schematic NBT: duplicate BlockData tag"); + if (count > MAX_BLOCK_DATA_BYTES) { + throw new Error(`Schematic safety limit exceeded: BlockData exceeds ${MAX_BLOCK_DATA_BYTES} bytes`); + } + blockDataLength = count; + } else { + consumeItems(count, "non-BlockData byte array"); + } + requireBytes(count, "byte-array payload"); + offset += count; + return; + } + case 8: { // string + const byteLength = readUnsignedShort("string length"); + requireBytes(byteLength, "string payload"); + offset += byteLength; + return; + } + case 9: { // list + const elementType = readByte("list element type"); + const count = readInt("list length"); + consumeItems(count, "NBT list"); + if (elementType < 0 || elementType > 12 || (elementType === 0 && count > 0)) { + throw new Error("Invalid schematic NBT: invalid list element type or length"); + } + for (let i = 0; i < count; i++) scanPayload(elementType, undefined, false, depth + 1); + return; + } + case 10: { // compound + for (;;) { + const childType = readByte("compound tag type"); + if (childType === 0) return; + if (childType < 1 || childType > 12) throw new Error("Invalid schematic NBT: unknown tag type"); + const childName = readName(); + tagCount += 1; + if (tagCount > MAX_NBT_TAGS) { + throw new Error(`Schematic safety limit exceeded: NBT contains more than ${MAX_NBT_TAGS} tags`); + } + scanPayload(childType, childName, false, depth + 1); + } + } + case 11: // int array + case 12: { // long array + const count = readInt("numeric-array length"); + consumeItems(count, "NBT numeric array"); + const elementBytes = type === 11 ? 4 : 8; + const byteLength = count * elementBytes; + requireBytes(byteLength, "numeric-array payload"); + offset += byteLength; + return; + } + default: + throw new Error(`Invalid schematic NBT: unsupported tag type ${type}`); + } + } + + if (readByte("root tag type") !== 10) throw new Error("Invalid schematic NBT: root tag must be a compound"); + readName(); + for (;;) { + const type = readByte("root tag type"); + if (type === 0) break; + if (type < 1 || type > 12) throw new Error("Invalid schematic NBT: unknown root tag type"); + const name = readName(); + tagCount += 1; + if (tagCount > MAX_NBT_TAGS) { + throw new Error(`Schematic safety limit exceeded: NBT contains more than ${MAX_NBT_TAGS} tags`); + } + scanPayload(type, name, true, 1); + } + + if (offset !== uncompressed.length) throw new Error("Invalid schematic NBT: unexpected trailing bytes"); + if (!Number.isInteger(width) || !Number.isInteger(height) || !Number.isInteger(length) || width! <= 0 || height! <= 0 || length! <= 0) { + throw new Error("Invalid schematic: Width, Height, and Length must be positive short values"); + } + const volume = width! * height! * length!; + if (volume > MAX_SCHEMATIC_VOLUME) { + throw new Error(`Schematic safety limit exceeded: volume ${volume} exceeds ${MAX_SCHEMATIC_VOLUME} cells`); + } + if (blockDataLength === undefined) throw new Error("Invalid schematic NBT: missing BlockData byte array"); + if (blockDataLength < volume) throw new Error(`Invalid schematic: BlockData has ${blockDataLength} bytes for ${volume} cells`); + + return { width: width!, height: height!, length: length!, blockDataLength }; +} + function parseBlockState(str: string): BlockState { const bracketIdx = str.indexOf("["); if (bracketIdx === -1) return { name: str }; @@ -28,8 +226,31 @@ function parseBlockState(str: string): BlockState { } function parseSchematic(buffer: Buffer): SchematicData { - const uncompressed = zlib.gunzipSync(buffer); - const parsed = nbt.parseUncompressed(uncompressed); + if (buffer.byteLength > MAX_COMPRESSED_SCHEMATIC_BYTES) { + throw new Error(`Schematic safety limit exceeded: compressed input exceeds ${MAX_COMPRESSED_SCHEMATIC_BYTES} bytes`); + } + + let uncompressed: Buffer; + try { + uncompressed = zlib.gunzipSync(buffer, { maxOutputLength: MAX_UNCOMPRESSED_NBT_BYTES }); + } catch (error) { + if ((error as NodeJS.ErrnoException).code === "ERR_BUFFER_TOO_LARGE") { + throw new Error(`Schematic safety limit exceeded: uncompressed NBT exceeds ${MAX_UNCOMPRESSED_NBT_BYTES} bytes`); + } + throw error; + } + const preflight = preflightSchematic(uncompressed); + const oversizedBlockData = preflight.blockDataLength > 0xffffff; + let parsed: ReturnType; + if (oversizedBlockData) { + try { + parsed = nbt.parseUncompressed(uncompressed, "big", { noArraySizeCheck: true }); + } catch (error) { + throw new Error(`Unable to parse bounded large schematic NBT: ${(error as Error).message}`); + } + } else { + parsed = nbt.parseUncompressed(uncompressed); + } const root = (parsed as any).value; const version = root.Version?.value ?? 2; @@ -49,6 +270,7 @@ function parseSchematic(buffer: Buffer): SchematicData { const blockDataBytes: number[] = root.BlockData?.value ?? []; const blockIds: number[] = []; + let occupiedBlockCount = 0; let i = 0; while (i < blockDataBytes.length) { let value = 0; @@ -60,6 +282,18 @@ function parseSchematic(buffer: Buffer): SchematicData { shift += 7; } while ((byte & 0x80) !== 0 && i < blockDataBytes.length); blockIds.push(value); + const blockState = palette.get(value); + if (oversizedBlockData && blockState && blockState.name !== "minecraft:air") { + occupiedBlockCount += 1; + if (occupiedBlockCount > MAX_LARGE_IMPORT_OCCUPIED_BLOCKS) { + throw new Error(`Schematic safety limit exceeded: large imports may contain at most ${MAX_LARGE_IMPORT_OCCUPIED_BLOCKS} occupied blocks`); + } + } + } + + const expectedCells = width * height * length; + if (blockIds.length !== expectedCells) { + throw new Error(`Invalid schematic: BlockData decoded to ${blockIds.length} cells; expected ${expectedCells}`); } return { version, dataVersion, width, height, length, offset, paletteMax, palette, blockIds }; diff --git a/packages/importer-schem/test/fixtures/probe-b-512.schem b/packages/importer-schem/test/fixtures/probe-b-512.schem new file mode 100644 index 0000000000000000000000000000000000000000..79fd685461ac14f43e51224c61041971f184735d GIT binary patch literal 107799 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 3, 0x45d9f3b) ^ Math.imul(z >> 3, 0x119de1f3) ^ 0x5f3759df) >>> 0; + n = Math.imul(n ^ (n >>> 16), 0x45d9f3b) >>> 0; + n = Math.imul(n ^ (n >>> 16), 0x45d9f3b) >>> 0; + return (n ^ (n >>> 16)) >>> 0; +} + +function probeBExpectedBlock(x: number, y: number, z: number): string | undefined { + const hash = probeBHash2(x, z); + const landHeight = 5 + ((hash >>> 8) % 28); + const layerCount = 3 + (hash % probeBColumns < probeBExtraColumns ? 1 : 0); + const layer = y - (landHeight - layerCount); + if (layer < 0 || layer >= layerCount) return undefined; + if (layer === layerCount - 1) return landHeight > 23 ? "minecraft:stone" : "minecraft:grass_block"; + if (layer === layerCount - 2) return "minecraft:dirt"; + return "minecraft:stone"; +} + +function expectedProbeBOccupiedCount(): number { + let count = 0; + for (let z = 0; z < 512; z++) { + for (let x = 0; x < 512; x++) { + const hash = probeBHash2(x, z); + count += 3 + (hash % probeBColumns < probeBExtraColumns ? 1 : 0); + } + } + return count; +} + +function makeSchematic(size: [number, number, number], blockData: number[] = [0], withEmptyBlockEntitiesList = false): Buffer { + const [width, height, length] = size; + const raw = nbt.writeUncompressed({ + type: "compound", + name: "Schematic", + value: { + Version: { type: "int", value: 2 }, + DataVersion: { type: "int", value: 3463 }, + Width: { type: "short", value: width }, + Height: { type: "short", value: height }, + Length: { type: "short", value: length }, + Offset: { type: "intArray", value: [0, 0, 0] }, + PaletteMax: { type: "int", value: 1 }, + Palette: { type: "compound", value: { "minecraft:air": { type: "int", value: 0 } } }, + BlockData: { type: "byteArray", value: blockData }, + ...(withEmptyBlockEntitiesList ? { BlockEntities: { type: "list", value: { type: "compound", value: [] } } } : {}), + }, + } as any); + return zlib.gzipSync(raw); +} + describe("Schematic Importer metadata", () => { it("reports the current package version", () => { expect(importerVersion).toBe("0.2.5"); @@ -79,4 +137,82 @@ describe("schematic importer", () => { expect(imported.blocks.length).toBe(0); expect(imported.size).toEqual([4, 4, 4]); }); + + it("reproduces the prismarine-nbt default 0xffffff array guard on the Probe B fixture", () => { + const uncompressed = zlib.gunzipSync(probeB512Fixture); + expect(() => nbt.parseUncompressed(uncompressed)).toThrow(/array size is abnormally large.*16777216/); + }); + + it("imports and exactly matches the Probe B 512×64×512 occupied coordinates", () => { + const imported = importFromSchematic(probeB512Fixture, { name: "Probe B 512" }); + expect(imported.size).toEqual([512, 64, 512]); + expect(imported.blocks).toHaveLength(997_632); + expect(imported.blocks).toHaveLength(expectedProbeBOccupiedCount()); + + // The importer emits each voxel position at most once from the full grid. + // Matching every output position/material plus the expected count proves + // the exact expected occupied set without keeping a second million-key Set. + for (const block of imported.blocks) { + const expectedBlock = probeBExpectedBlock(...block.pos); + if (expectedBlock !== block.block.name) { + throw new Error(`unexpected block ${block.block.name} at ${block.pos}; expected ${expectedBlock ?? "air"}`); + } + } + }, 120_000); + + it("rejects a schematic volume above the measured safety bound", () => { + const tooLarge = makeSchematic([512, 64, 513]); + expect(() => importFromSchematic(tooLarge)).toThrow(/volume .* exceeds 16777216 cells/); + }); + + it("rejects compressed schematics above the input safety bound before gunzip", () => { + const tooLarge = Buffer.alloc(16 * 1024 * 1024 + 1); + expect(() => importFromSchematic(tooLarge)).toThrow(/compressed input exceeds 16777216 bytes/); + }); + + it("rejects uncompressed NBT above the gunzip safety bound", () => { + const tooLarge = zlib.gzipSync(Buffer.alloc(32 * 1024 * 1024 + 1)); + expect(() => importFromSchematic(tooLarge)).toThrow(/uncompressed NBT exceeds 33554432 bytes/); + }); + + it("rejects oversized BlockData even when the compressed payload is small", () => { + const uncompressed = zlib.gunzipSync(probeB512Fixture); + const blockDataName = Buffer.from("BlockData"); + const nameIndex = uncompressed.indexOf(blockDataName); + expect(nameIndex).toBeGreaterThan(0); + uncompressed.writeInt32BE(24 * 1024 * 1024 + 1, nameIndex + blockDataName.length); + const malformed = zlib.gzipSync(uncompressed); + expect(() => importFromSchematic(malformed)).toThrow(/BlockData exceeds 25165824 bytes/); + }); + + it("does not lift the normal list bound when allowing large BlockData", () => { + const uncompressed = zlib.gunzipSync(makeSchematic([1, 1, 1], [0], true)); + const listName = Buffer.from("BlockEntities"); + const nameIndex = uncompressed.indexOf(listName); + expect(nameIndex).toBeGreaterThan(0); + // NBT list layout is element type byte followed by signed 32-bit length. + uncompressed.writeInt32BE(1_000_001, nameIndex + listName.length + 1); + const malformed = zlib.gzipSync(uncompressed); + expect(() => importFromSchematic(malformed)).toThrow(/NBT list exceeds 1000000 items/); + }); + + it("rejects large schematics whose decoded occupied count exceeds the safety bound", () => { + const uncompressed = zlib.gunzipSync(probeB512Fixture); + const blockDataName = Buffer.from("BlockData"); + const blockDataNameIndex = uncompressed.indexOf(blockDataName); + const blockDataLength = uncompressed.readInt32BE(blockDataNameIndex + blockDataName.length); + const payloadOffset = blockDataNameIndex + blockDataName.length + 4; + let changed = 0; + const additionalBlocks = 1_000_001 - 997_632; + for (let i = payloadOffset; i < payloadOffset + blockDataLength && changed < additionalBlocks; i++) { + if (uncompressed[i] === 0) { + uncompressed[i] = 1; + changed += 1; + } + } + expect(changed).toBe(additionalBlocks); + const overOccupiedLimit = zlib.gzipSync(uncompressed); + expect(() => importFromSchematic(overOccupiedLimit)).toThrow(/at most 1000000 occupied blocks/); + }, 120_000); + }); diff --git a/scripts/bench-probe-b-512.mjs b/scripts/bench-probe-b-512.mjs new file mode 100644 index 0000000..b54a772 --- /dev/null +++ b/scripts/bench-probe-b-512.mjs @@ -0,0 +1,54 @@ +import { readFile } from "node:fs/promises"; +import { performance } from "node:perf_hooks"; +import { importFromSchematic } from "../packages/importer-schem/dist/index.js"; + +const fixturePath = new URL("../packages/importer-schem/test/fixtures/probe-b-512.schem", import.meta.url); +const fixture = await readFile(fixturePath); + +function hash2(x, z) { + let n = (Math.imul(x >> 3, 0x45d9f3b) ^ Math.imul(z >> 3, 0x119de1f3) ^ 0x5f3759df) >>> 0; + n = Math.imul(n ^ (n >>> 16), 0x45d9f3b) >>> 0; + n = Math.imul(n ^ (n >>> 16), 0x45d9f3b) >>> 0; + return (n ^ (n >>> 16)) >>> 0; +} + +function expectedBlock(x, y, z) { + const hash = hash2(x, z); + const landHeight = 5 + ((hash >>> 8) % 28); + const columns = 512 * 512; + const extraColumns = 1_000_000 % columns; + const layers = 3 + (hash % columns < extraColumns ? 1 : 0); + const layer = y - (landHeight - layers); + if (layer < 0 || layer >= layers) return undefined; + if (layer === layers - 1) return landHeight > 23 ? "minecraft:stone" : "minecraft:grass_block"; + if (layer === layers - 2) return "minecraft:dirt"; + return "minecraft:stone"; +} + +const importStart = performance.now(); +const plan = importFromSchematic(fixture, { name: "Probe B deterministic wide landscape 512" }); +const importMs = performance.now() - importStart; +const peakRssBytesAfterImport = process.resourceUsage().maxRSS * 1024; + +if (JSON.stringify(plan.size) !== JSON.stringify([512, 64, 512])) throw new Error(`unexpected dimensions: ${plan.size}`); +if (plan.blocks.length !== 997_632) throw new Error(`unexpected occupied count: ${plan.blocks.length}`); + +const validationStart = performance.now(); +for (const block of plan.blocks) { + const expected = expectedBlock(...block.pos); + if (expected !== block.block.name) { + throw new Error(`unexpected block ${block.block.name} at ${block.pos}; expected ${expected ?? "air"}`); + } +} +const exactPositionValidationMs = performance.now() - validationStart; + +console.log(JSON.stringify({ + fixtureBytes: fixture.byteLength, + dimensions: plan.size, + occupiedBlocks: plan.blocks.length, + exactPositionAndMaterialMatch: true, + importMs, + exactPositionValidationMs, + peakRssBytesAfterImport, + peakRssBytesAfterValidation: process.resourceUsage().maxRSS * 1024, +}));