@agentxm/extension-content 0.30.2 → 0.31.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
|
@@ -5,6 +5,7 @@ import { enforceArchiveContentType, enforceArchiveSizeLimit, } from "./ingest-li
|
|
|
5
5
|
import { resolveManifest, validateDeclaredManifestAlignment, } from "./manifest-policy.js";
|
|
6
6
|
import { FilteredPackageError, validateFilteredPackage } from "./filtered-package-validation.js";
|
|
7
7
|
const LOCAL_FILE_HEADER_SIZE = 30;
|
|
8
|
+
const INFLATE_CHUNK_SIZE = 16 * 1024;
|
|
8
9
|
export const defaultReadEntry = (archiveBytes, entry) => Effect.gen(function* () {
|
|
9
10
|
const { localHeaderOffset, compressedSize, compressionMethod, fileName } = entry;
|
|
10
11
|
if (localHeaderOffset + LOCAL_FILE_HEADER_SIZE > archiveBytes.length) {
|
|
@@ -38,11 +39,19 @@ export const defaultReadEntry = (archiveBytes, entry) => Effect.gen(function* ()
|
|
|
38
39
|
return compressedData;
|
|
39
40
|
}
|
|
40
41
|
if (compressionMethod === 8) {
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
42
|
+
const expansionFailure = () => new ArchiveGuardrailError({
|
|
43
|
+
code: "decompression_limit_exceeded",
|
|
44
|
+
message: `Entry "${fileName}" decompresses beyond its declared size of ${entry.uncompressedSize} bytes.`,
|
|
45
|
+
entry: fileName,
|
|
46
|
+
});
|
|
47
|
+
// workerd grows its bounded zlib buffer by whole chunks, including the
|
|
48
|
+
// final partial chunk. Reserve one chunk of codec headroom, then enforce
|
|
49
|
+
// the exact declared size below. Expansion remains bounded during decode.
|
|
44
50
|
const result = yield* Effect.try({
|
|
45
|
-
try: () => inflateRawSync(compressedData, {
|
|
51
|
+
try: () => inflateRawSync(compressedData, {
|
|
52
|
+
chunkSize: INFLATE_CHUNK_SIZE,
|
|
53
|
+
maxOutputLength: entry.uncompressedSize + INFLATE_CHUNK_SIZE,
|
|
54
|
+
}),
|
|
46
55
|
catch: (error) => {
|
|
47
56
|
const errorCode = typeof error === "object" &&
|
|
48
57
|
error !== null &&
|
|
@@ -50,12 +59,9 @@ export const defaultReadEntry = (archiveBytes, entry) => Effect.gen(function* ()
|
|
|
50
59
|
typeof error.code === "string"
|
|
51
60
|
? error.code
|
|
52
61
|
: "";
|
|
53
|
-
return errorCode === "ERR_BUFFER_TOO_LARGE"
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
message: `Entry "${fileName}" decompresses beyond its declared size of ${entry.uncompressedSize} bytes.`,
|
|
57
|
-
entry: fileName,
|
|
58
|
-
})
|
|
62
|
+
return errorCode === "ERR_BUFFER_TOO_LARGE" ||
|
|
63
|
+
(error instanceof RangeError && error.message === "Memory limit exceeded")
|
|
64
|
+
? expansionFailure()
|
|
59
65
|
: new ArchiveGuardrailError({
|
|
60
66
|
code: "malformed_archive",
|
|
61
67
|
message: `Failed to decompress entry "${fileName}".`,
|
|
@@ -63,6 +69,8 @@ export const defaultReadEntry = (archiveBytes, entry) => Effect.gen(function* ()
|
|
|
63
69
|
});
|
|
64
70
|
},
|
|
65
71
|
});
|
|
72
|
+
if (result.byteLength > entry.uncompressedSize)
|
|
73
|
+
return yield* expansionFailure();
|
|
66
74
|
return new Uint8Array(result.buffer, result.byteOffset, result.byteLength);
|
|
67
75
|
}
|
|
68
76
|
return yield* new ArchiveGuardrailError({
|
package/package.json
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
"url": "https://github.com/agentxm/axm/issues"
|
|
5
5
|
},
|
|
6
6
|
"dependencies": {
|
|
7
|
-
"@agentxm/extension-model": "^0.
|
|
7
|
+
"@agentxm/extension-model": "^0.31.0",
|
|
8
8
|
"effect": "4.0.0-rc.115",
|
|
9
9
|
"yaml": "^2.9.0"
|
|
10
10
|
},
|
|
@@ -58,5 +58,5 @@
|
|
|
58
58
|
},
|
|
59
59
|
"sideEffects": false,
|
|
60
60
|
"type": "module",
|
|
61
|
-
"version": "0.
|
|
61
|
+
"version": "0.31.0"
|
|
62
62
|
}
|