relic-mcp 0.14.3 → 0.15.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.
- package/.claude-plugin/marketplace.json +2 -2
- package/.claude-plugin/plugin.json +1 -1
- package/README.md +4 -3
- package/dist/cover/cover.js +178 -27
- package/dist/cover/frame.html +83 -4
- package/dist/cover/pdf.worker.mjs +73 -3
- package/dist/cover/styles.css +181 -4
- package/dist/relic-mcp.js +735 -407
- package/mcp-servers.json +2 -2
- package/package.json +1 -1
- package/prebuilds/darwin-arm64/build-info.json +1 -1
- package/prebuilds/darwin-x64/build-info.json +1 -1
- package/prebuilds/linux-arm64-gnu/build-info.json +1 -1
- package/prebuilds/linux-x64-gnu/build-info.json +1 -1
- package/src/cover/inputs.ts +25 -1
- package/src/cover/render.ts +9 -0
- package/src/files.ts +2 -1
- package/src/index.ts +2 -0
- package/src/inventory.ts +1 -1
- package/src/otio-bundle.ts +24 -10
- package/src/publish.ts +77 -25
- package/src/republish.ts +11 -4
- package/src/resolve-anchor.ts +9 -6
- package/src/upload.ts +140 -0
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
{
|
|
11
11
|
"name": "relic",
|
|
12
12
|
"description": "Publish a file from your machine as an encrypted, shareable link. The agent encrypts locally, uploads only ciphertext, and hands back a URL whose fragment holds the key, so the service stores something it cannot read.",
|
|
13
|
-
"version": "0.
|
|
13
|
+
"version": "0.15.0",
|
|
14
14
|
"source": "./",
|
|
15
15
|
"author": {
|
|
16
16
|
"name": "The Bushido Collective",
|
|
@@ -21,6 +21,6 @@
|
|
|
21
21
|
}
|
|
22
22
|
],
|
|
23
23
|
"metadata": {
|
|
24
|
-
"version": "0.
|
|
24
|
+
"version": "0.15.0"
|
|
25
25
|
}
|
|
26
26
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "relic",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.15.0",
|
|
4
4
|
"description": "Publish a file from your machine as an encrypted, shareable link. The agent encrypts locally, uploads only ciphertext, and hands back a URL whose fragment holds the key, so the service stores something it cannot read.",
|
|
5
5
|
"mcpServers": "./mcp-servers.json",
|
|
6
6
|
"author": {
|
package/README.md
CHANGED
|
@@ -32,9 +32,9 @@ For any client that takes a JSON config:
|
|
|
32
32
|
3. Encrypts locally with AES-128-GCM under RFC 8188 `aes128gcm` framing.
|
|
33
33
|
4. Uploads **only ciphertext**, straight to object storage under a signed URL.
|
|
34
34
|
It does not pass through the Relic service.
|
|
35
|
-
5. Tells the service four things: a coarse renderer class from
|
|
36
|
-
list (`markdown`, `code`, `html`, `jsx`, `image`, `pdf`, `
|
|
37
|
-
`binary`, `otio`), this client's name, the ciphertext's byte length, and the
|
|
35
|
+
5. Tells the service four things: a coarse renderer class from an eleven-value
|
|
36
|
+
list (`markdown`, `code`, `html`, `jsx`, `image`, `pdf`, `model`, `media`,
|
|
37
|
+
`archive`, `binary`, `otio`), this client's name, the ciphertext's byte length, and the
|
|
38
38
|
title, which defaults to the filename and is stored in the clear. By default,
|
|
39
39
|
it also renders a 1200x630 cover image of the file's first screen in local
|
|
40
40
|
headless Chrome and uploads it unencrypted via `POST /api/relics/{id}/cover`
|
|
@@ -42,6 +42,7 @@ For any client that takes a JSON config:
|
|
|
42
42
|
timeline relics (`otio`) skip unencrypted first-screen media rendering by
|
|
43
43
|
default, using a generic card carrying the title and format label to protect
|
|
44
44
|
private timeline cuts and media from leaking into unencrypted link previews.
|
|
45
|
+
STL and OBJ models also use a generic card instead of a geometry preview.
|
|
45
46
|
Not the mimetype, not the contents.
|
|
46
47
|
6. Records the relic's id, key, and publish token locally, in a 0600 file
|
|
47
48
|
under your user config directory, so the relic can be republished from
|
package/dist/cover/cover.js
CHANGED
|
@@ -1202,6 +1202,68 @@ var require_build = __commonJS(function(exports) {
|
|
|
1202
1202
|
exports.default = LinesAndColumns;
|
|
1203
1203
|
});
|
|
1204
1204
|
|
|
1205
|
+
// ../relic-viewer/src/content.ts
|
|
1206
|
+
var CONTENT_BATCH_BYTES = 8 * 1024 * 1024;
|
|
1207
|
+
var CONTENT_HEAD_BYTES = 65536;
|
|
1208
|
+
var CONTENT_TAIL_BYTES = 65557;
|
|
1209
|
+
var MAX_CONTENT_READ_BYTES = 16 * 1024 * 1024;
|
|
1210
|
+
var DOCUMENT_RENDER_LIMIT_BYTES = 100 * 1024 * 1024;
|
|
1211
|
+
|
|
1212
|
+
class ContentStoreError extends Error {
|
|
1213
|
+
constructor(cause) {
|
|
1214
|
+
super("The browser could not hold the decrypted content.", { cause });
|
|
1215
|
+
this.name = "ContentStoreError";
|
|
1216
|
+
}
|
|
1217
|
+
}
|
|
1218
|
+
function sliceBlob(blob, start, end, type) {
|
|
1219
|
+
try {
|
|
1220
|
+
return blob.slice(start, end, type);
|
|
1221
|
+
} catch (cause) {
|
|
1222
|
+
throw new ContentStoreError(cause);
|
|
1223
|
+
}
|
|
1224
|
+
}
|
|
1225
|
+
async function readBlob(blob) {
|
|
1226
|
+
try {
|
|
1227
|
+
const bytes = new Uint8Array(await blob.arrayBuffer());
|
|
1228
|
+
if (bytes.length !== blob.size)
|
|
1229
|
+
throw new Error("short Blob read");
|
|
1230
|
+
return bytes;
|
|
1231
|
+
} catch (cause) {
|
|
1232
|
+
throw new ContentStoreError(cause);
|
|
1233
|
+
}
|
|
1234
|
+
}
|
|
1235
|
+
function contentFromParts(base, head, tail) {
|
|
1236
|
+
return {
|
|
1237
|
+
size: base.size,
|
|
1238
|
+
head,
|
|
1239
|
+
tail,
|
|
1240
|
+
blob(type) {
|
|
1241
|
+
return sliceBlob(base, 0, base.size, type);
|
|
1242
|
+
},
|
|
1243
|
+
async read(start, end) {
|
|
1244
|
+
if (!Number.isSafeInteger(start) || !Number.isSafeInteger(end) || start < 0 || end < start || end > base.size || end - start > MAX_CONTENT_READ_BYTES) {
|
|
1245
|
+
throw new RangeError("Invalid or oversized content read");
|
|
1246
|
+
}
|
|
1247
|
+
return readBlob(sliceBlob(base, start, end));
|
|
1248
|
+
},
|
|
1249
|
+
async readWhole(limit) {
|
|
1250
|
+
if (!Number.isSafeInteger(limit) || limit < 0 || limit > DOCUMENT_RENDER_LIMIT_BYTES) {
|
|
1251
|
+
throw new RangeError("Invalid whole-content read limit");
|
|
1252
|
+
}
|
|
1253
|
+
if (base.size > limit)
|
|
1254
|
+
return;
|
|
1255
|
+
return readBlob(base);
|
|
1256
|
+
}
|
|
1257
|
+
};
|
|
1258
|
+
}
|
|
1259
|
+
async function contentFromBlob(blob) {
|
|
1260
|
+
const [head, tail] = await Promise.all([
|
|
1261
|
+
readBlob(sliceBlob(blob, 0, Math.min(blob.size, CONTENT_HEAD_BYTES))),
|
|
1262
|
+
readBlob(sliceBlob(blob, Math.max(0, blob.size - CONTENT_TAIL_BYTES), blob.size))
|
|
1263
|
+
]);
|
|
1264
|
+
return contentFromParts(blob, head, tail);
|
|
1265
|
+
}
|
|
1266
|
+
|
|
1205
1267
|
// ../relic-viewer/src/markdown.ts
|
|
1206
1268
|
function escapeHtml(value) {
|
|
1207
1269
|
return value.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """).replace(/'/g, "'");
|
|
@@ -1300,8 +1362,15 @@ function renderMarkdown(source) {
|
|
|
1300
1362
|
flushParagraph();
|
|
1301
1363
|
const ordered = /^\s*\d+\./.test(line);
|
|
1302
1364
|
const items = [];
|
|
1303
|
-
while (index < lines.length
|
|
1304
|
-
|
|
1365
|
+
while (index < lines.length) {
|
|
1366
|
+
const current = lines[index];
|
|
1367
|
+
if (/^\s*([-*+]|\d+\.)\s+/.test(current)) {
|
|
1368
|
+
items.push(current.replace(/^\s*([-*+]|\d+\.)\s+/, ""));
|
|
1369
|
+
} else if (/^\s+\S/.test(current) && !/^\s*(>|```)/.test(current)) {
|
|
1370
|
+
items[items.length - 1] += ` ${current.trim()}`;
|
|
1371
|
+
} else {
|
|
1372
|
+
break;
|
|
1373
|
+
}
|
|
1305
1374
|
index++;
|
|
1306
1375
|
}
|
|
1307
1376
|
const tag = ordered ? "ol" : "ul";
|
|
@@ -44719,6 +44788,81 @@ globalThis.pdfjsLib = {
|
|
|
44719
44788
|
XfaLayer
|
|
44720
44789
|
};
|
|
44721
44790
|
|
|
44791
|
+
// ../relic-viewer/src/pdf.ts
|
|
44792
|
+
var PDF_INITIAL_BYTES = 1024 * 1024;
|
|
44793
|
+
var PDF_RANGE_CHUNK_SIZE = 65536;
|
|
44794
|
+
|
|
44795
|
+
class RelicPdfRangeTransport extends PDFDataRangeTransport {
|
|
44796
|
+
content;
|
|
44797
|
+
onError;
|
|
44798
|
+
aborted = false;
|
|
44799
|
+
failed = false;
|
|
44800
|
+
constructor(content, initialData, onError) {
|
|
44801
|
+
super(content.size, initialData);
|
|
44802
|
+
this.content = content;
|
|
44803
|
+
this.onError = onError;
|
|
44804
|
+
}
|
|
44805
|
+
requestDataRange(begin, end) {
|
|
44806
|
+
if (this.aborted || this.failed)
|
|
44807
|
+
return;
|
|
44808
|
+
this.readRange(begin, end).then((bytes) => {
|
|
44809
|
+
if (!this.aborted && !this.failed)
|
|
44810
|
+
this.onDataRange(begin, bytes);
|
|
44811
|
+
}).catch((error) => {
|
|
44812
|
+
if (this.aborted || this.failed)
|
|
44813
|
+
return;
|
|
44814
|
+
this.failed = true;
|
|
44815
|
+
this.onError(error);
|
|
44816
|
+
});
|
|
44817
|
+
}
|
|
44818
|
+
abort() {
|
|
44819
|
+
this.aborted = true;
|
|
44820
|
+
}
|
|
44821
|
+
async readRange(begin, end) {
|
|
44822
|
+
if (!Number.isSafeInteger(begin) || !Number.isSafeInteger(end) || begin < 0 || end < begin || end > this.content.size) {
|
|
44823
|
+
throw new RangeError("Invalid PDF range");
|
|
44824
|
+
}
|
|
44825
|
+
const length = end - begin;
|
|
44826
|
+
if (length <= MAX_CONTENT_READ_BYTES) {
|
|
44827
|
+
const bytes = await this.content.read(begin, end);
|
|
44828
|
+
if (bytes.byteLength !== length)
|
|
44829
|
+
throw new Error("Short PDF range read");
|
|
44830
|
+
return bytes;
|
|
44831
|
+
}
|
|
44832
|
+
const bytes = new Uint8Array(length);
|
|
44833
|
+
for (let start = begin;start < end; start += MAX_CONTENT_READ_BYTES) {
|
|
44834
|
+
if (this.aborted)
|
|
44835
|
+
return new Uint8Array(0);
|
|
44836
|
+
const stop = Math.min(start + MAX_CONTENT_READ_BYTES, end);
|
|
44837
|
+
const chunk = await this.content.read(start, stop);
|
|
44838
|
+
if (chunk.byteLength !== stop - start)
|
|
44839
|
+
throw new Error("Short PDF range read");
|
|
44840
|
+
bytes.set(chunk, start - begin);
|
|
44841
|
+
}
|
|
44842
|
+
return bytes;
|
|
44843
|
+
}
|
|
44844
|
+
}
|
|
44845
|
+
async function createPdfLoadingTask(content, signal) {
|
|
44846
|
+
const initialData = await content.read(0, Math.min(content.size, PDF_INITIAL_BYTES));
|
|
44847
|
+
if (signal?.aborted)
|
|
44848
|
+
throw new Error("PDF loading cancelled");
|
|
44849
|
+
if (initialData.byteLength !== Math.min(content.size, PDF_INITIAL_BYTES))
|
|
44850
|
+
throw new Error("Short PDF initial read");
|
|
44851
|
+
const { promise: failure, reject: rejectFailure } = Promise.withResolvers();
|
|
44852
|
+
failure.catch(() => {
|
|
44853
|
+
return;
|
|
44854
|
+
});
|
|
44855
|
+
const range = new RelicPdfRangeTransport(content, initialData, rejectFailure);
|
|
44856
|
+
const task = getDocument({
|
|
44857
|
+
range,
|
|
44858
|
+
length: content.size,
|
|
44859
|
+
rangeChunkSize: PDF_RANGE_CHUNK_SIZE,
|
|
44860
|
+
disableAutoFetch: true,
|
|
44861
|
+
disableStream: true
|
|
44862
|
+
});
|
|
44863
|
+
return { task, failure };
|
|
44864
|
+
}
|
|
44865
|
+
|
|
44722
44866
|
// ../relic-viewer/src/cover/pdf-trim.ts
|
|
44723
44867
|
var PDF_GUTTER_PX = 20;
|
|
44724
44868
|
var PDF_CANVAS_WIDTH = 600;
|
|
@@ -44771,21 +44915,21 @@ function trimPdfPage(ink, pageWidth) {
|
|
|
44771
44915
|
// ../relic-viewer/src/cover/pdf.ts
|
|
44772
44916
|
var PDF_CANVAS_HEIGHT = 315;
|
|
44773
44917
|
var PDF_DEVICE_SCALE = 2;
|
|
44774
|
-
var workerInitialized = false;
|
|
44775
44918
|
function ensurePdfWorker() {
|
|
44776
|
-
|
|
44777
|
-
GlobalWorkerOptions.workerPort = new Worker("/pdf.worker.mjs", {
|
|
44778
|
-
type: "module"
|
|
44779
|
-
});
|
|
44780
|
-
workerInitialized = true;
|
|
44781
|
-
}
|
|
44919
|
+
GlobalWorkerOptions.workerSrc = "/pdf.worker.mjs";
|
|
44782
44920
|
}
|
|
44783
|
-
async function renderPdfCover(
|
|
44921
|
+
async function renderPdfCover(content, root) {
|
|
44784
44922
|
ensurePdfWorker();
|
|
44785
|
-
let pdfDoc;
|
|
44786
44923
|
try {
|
|
44787
|
-
const
|
|
44788
|
-
|
|
44924
|
+
const { task, failure } = await createPdfLoadingTask(content);
|
|
44925
|
+
try {
|
|
44926
|
+
const pdfDoc = await Promise.race([task.promise, failure]);
|
|
44927
|
+
return await renderPdfCoverDocument(pdfDoc, root, failure);
|
|
44928
|
+
} finally {
|
|
44929
|
+
await task.destroy().catch(() => {
|
|
44930
|
+
return;
|
|
44931
|
+
});
|
|
44932
|
+
}
|
|
44789
44933
|
} catch (err) {
|
|
44790
44934
|
return {
|
|
44791
44935
|
ok: false,
|
|
@@ -44793,9 +44937,11 @@ async function renderPdfCover(bytes, root) {
|
|
|
44793
44937
|
detail: err instanceof Error ? err.message : String(err)
|
|
44794
44938
|
};
|
|
44795
44939
|
}
|
|
44940
|
+
}
|
|
44941
|
+
async function renderPdfCoverDocument(pdfDoc, root, failure) {
|
|
44796
44942
|
let page;
|
|
44797
44943
|
try {
|
|
44798
|
-
page = await pdfDoc.getPage(1);
|
|
44944
|
+
page = await Promise.race([pdfDoc.getPage(1), failure]);
|
|
44799
44945
|
} catch (err) {
|
|
44800
44946
|
return {
|
|
44801
44947
|
ok: false,
|
|
@@ -44820,11 +44966,14 @@ async function renderPdfCover(bytes, root) {
|
|
|
44820
44966
|
};
|
|
44821
44967
|
}
|
|
44822
44968
|
try {
|
|
44823
|
-
await
|
|
44824
|
-
|
|
44825
|
-
|
|
44826
|
-
|
|
44827
|
-
|
|
44969
|
+
await Promise.race([
|
|
44970
|
+
page.render({
|
|
44971
|
+
canvasContext: measureCtx,
|
|
44972
|
+
viewport: refViewport,
|
|
44973
|
+
canvas: measureCanvas
|
|
44974
|
+
}).promise,
|
|
44975
|
+
failure
|
|
44976
|
+
]);
|
|
44828
44977
|
} catch (err) {
|
|
44829
44978
|
return {
|
|
44830
44979
|
ok: false,
|
|
@@ -44857,11 +45006,14 @@ async function renderPdfCover(bytes, root) {
|
|
|
44857
45006
|
};
|
|
44858
45007
|
}
|
|
44859
45008
|
try {
|
|
44860
|
-
await
|
|
44861
|
-
|
|
44862
|
-
|
|
44863
|
-
|
|
44864
|
-
|
|
45009
|
+
await Promise.race([
|
|
45010
|
+
page.render({
|
|
45011
|
+
canvasContext: renderCtx,
|
|
45012
|
+
viewport: finalViewport,
|
|
45013
|
+
canvas: renderCanvas
|
|
45014
|
+
}).promise,
|
|
45015
|
+
failure
|
|
45016
|
+
]);
|
|
44865
45017
|
} catch (err) {
|
|
44866
45018
|
return {
|
|
44867
45019
|
ok: false,
|
|
@@ -44889,7 +45041,7 @@ async function fetchInputBlob(input) {
|
|
|
44889
45041
|
if (!res.ok) {
|
|
44890
45042
|
throw new Error(`Failed to fetch input part ${i}: ${res.status}`);
|
|
44891
45043
|
}
|
|
44892
|
-
parts.push(await res.
|
|
45044
|
+
parts.push(await res.blob());
|
|
44893
45045
|
}
|
|
44894
45046
|
return new Blob(parts, { type: input.mimetype });
|
|
44895
45047
|
}
|
|
@@ -45077,8 +45229,7 @@ async function renderKind(request, root) {
|
|
|
45077
45229
|
}
|
|
45078
45230
|
}
|
|
45079
45231
|
case "pdf": {
|
|
45080
|
-
|
|
45081
|
-
return renderPdfCover(new Uint8Array(arrayBuffer), root);
|
|
45232
|
+
return renderPdfCover(await contentFromBlob(blob), root);
|
|
45082
45233
|
}
|
|
45083
45234
|
}
|
|
45084
45235
|
}
|
package/dist/cover/frame.html
CHANGED
|
@@ -11390,15 +11390,91 @@ var MAX_HEADER_BYTES = 2 + (2 + MAX_FILENAME_BYTES + 2 + MAX_MIMETYPE_BYTES + 8
|
|
|
11390
11390
|
var encoder = new TextEncoder;
|
|
11391
11391
|
var decoder = new TextDecoder("utf-8", { fatal: false });
|
|
11392
11392
|
|
|
11393
|
+
// ../relic-format/src/limits.ts
|
|
11394
|
+
var PLAINTEXT_CAP_BYTES = 500 * 1024 * 1024;
|
|
11395
|
+
|
|
11393
11396
|
// ../relic-format/src/rfc8188.ts
|
|
11394
11397
|
var TAG_BYTES = 16;
|
|
11395
11398
|
var DELIMITER_BYTES = 1;
|
|
11396
11399
|
var RECORD_OVERHEAD = TAG_BYTES + DELIMITER_BYTES;
|
|
11397
11400
|
var CEK_INFO = new TextEncoder().encode("Content-Encoding: aes128gcm\x00");
|
|
11398
11401
|
var NONCE_INFO = new TextEncoder().encode("Content-Encoding: nonce\x00");
|
|
11399
|
-
|
|
11400
|
-
|
|
11401
|
-
|
|
11402
|
+
// ../relic-format/src/crc32c.ts
|
|
11403
|
+
var CRC32C_TABLE = new Uint32Array(256);
|
|
11404
|
+
for (let index = 0;index < 256; index++) {
|
|
11405
|
+
let value = index;
|
|
11406
|
+
for (let bit = 0;bit < 8; bit++) {
|
|
11407
|
+
value = value & 1 ? value >>> 1 ^ 2197175160 : value >>> 1;
|
|
11408
|
+
}
|
|
11409
|
+
CRC32C_TABLE[index] = value >>> 0;
|
|
11410
|
+
}
|
|
11411
|
+
// ../relic-format/src/sha256.ts
|
|
11412
|
+
var K = new Uint32Array([
|
|
11413
|
+
1116352408,
|
|
11414
|
+
1899447441,
|
|
11415
|
+
3049323471,
|
|
11416
|
+
3921009573,
|
|
11417
|
+
961987163,
|
|
11418
|
+
1508970993,
|
|
11419
|
+
2453635748,
|
|
11420
|
+
2870763221,
|
|
11421
|
+
3624381080,
|
|
11422
|
+
310598401,
|
|
11423
|
+
607225278,
|
|
11424
|
+
1426881987,
|
|
11425
|
+
1925078388,
|
|
11426
|
+
2162078206,
|
|
11427
|
+
2614888103,
|
|
11428
|
+
3248222580,
|
|
11429
|
+
3835390401,
|
|
11430
|
+
4022224774,
|
|
11431
|
+
264347078,
|
|
11432
|
+
604807628,
|
|
11433
|
+
770255983,
|
|
11434
|
+
1249150122,
|
|
11435
|
+
1555081692,
|
|
11436
|
+
1996064986,
|
|
11437
|
+
2554220882,
|
|
11438
|
+
2821834349,
|
|
11439
|
+
2952996808,
|
|
11440
|
+
3210313671,
|
|
11441
|
+
3336571891,
|
|
11442
|
+
3584528711,
|
|
11443
|
+
113926993,
|
|
11444
|
+
338241895,
|
|
11445
|
+
666307205,
|
|
11446
|
+
773529912,
|
|
11447
|
+
1294757372,
|
|
11448
|
+
1396182291,
|
|
11449
|
+
1695183700,
|
|
11450
|
+
1986661051,
|
|
11451
|
+
2177026350,
|
|
11452
|
+
2456956037,
|
|
11453
|
+
2730485921,
|
|
11454
|
+
2820302411,
|
|
11455
|
+
3259730800,
|
|
11456
|
+
3345764771,
|
|
11457
|
+
3516065817,
|
|
11458
|
+
3600352804,
|
|
11459
|
+
4094571909,
|
|
11460
|
+
275423344,
|
|
11461
|
+
430227734,
|
|
11462
|
+
506948616,
|
|
11463
|
+
659060556,
|
|
11464
|
+
883997877,
|
|
11465
|
+
958139571,
|
|
11466
|
+
1322822218,
|
|
11467
|
+
1537002063,
|
|
11468
|
+
1747873779,
|
|
11469
|
+
1955562222,
|
|
11470
|
+
2024104815,
|
|
11471
|
+
2227730452,
|
|
11472
|
+
2361852424,
|
|
11473
|
+
2428436474,
|
|
11474
|
+
2756734187,
|
|
11475
|
+
3204031479,
|
|
11476
|
+
3329325298
|
|
11477
|
+
]);
|
|
11402
11478
|
// ../relic-format/src/id.ts
|
|
11403
11479
|
var RESERVED_SEGMENTS = [
|
|
11404
11480
|
"abuse",
|
|
@@ -11431,7 +11507,10 @@ function foldAliases(lowered) {
|
|
|
11431
11507
|
return out;
|
|
11432
11508
|
}
|
|
11433
11509
|
// ../relic-format/src/otio-zip.ts
|
|
11434
|
-
var
|
|
11510
|
+
var MAX_INFLATED_ZIP_BYTES = 100 * 1024 * 1024;
|
|
11511
|
+
var OTIO_DOCUMENT_MAX_BYTES = 100 * 1024 * 1024;
|
|
11512
|
+
var MAX_ZIP_DIRECTORY_BYTES = 16 * 1024 * 1024;
|
|
11513
|
+
var ZIP_READ_CHUNK_BYTES = 8 * 1024 * 1024;
|
|
11435
11514
|
var MAX_OTIO_BUNDLE_MEDIA_ENTRIES = 65535 - 3;
|
|
11436
11515
|
var CRC_TABLE = new Uint32Array(256);
|
|
11437
11516
|
for (let i = 0;i < 256; i++) {
|
|
@@ -20,6 +20,11 @@
|
|
|
20
20
|
* JavaScript code in this page
|
|
21
21
|
*/
|
|
22
22
|
|
|
23
|
+
/**
|
|
24
|
+
* Modified by The Bushido Collective: stop indirect-object lookahead at endobj
|
|
25
|
+
* to avoid scanning the following whitespace in range-loaded PDFs.
|
|
26
|
+
*/
|
|
27
|
+
|
|
23
28
|
/**
|
|
24
29
|
* pdfjsVersion = 5.4.149
|
|
25
30
|
* pdfjsBuild = 9e2e9e209
|
|
@@ -11481,6 +11486,71 @@ class Lexer {
|
|
|
11481
11486
|
}
|
|
11482
11487
|
}
|
|
11483
11488
|
}
|
|
11489
|
+
class IndirectObjectLexer extends Lexer {
|
|
11490
|
+
// Stop before lookahead reads beyond an indirect object's top-level endobj.
|
|
11491
|
+
// Dictionary entries alternate between names and values; a closer in value
|
|
11492
|
+
// position is a value, and a mismatched closer never closes a container.
|
|
11493
|
+
#openers = [];
|
|
11494
|
+
#ended = false;
|
|
11495
|
+
#tracking = true;
|
|
11496
|
+
getObj() {
|
|
11497
|
+
if (this.#ended) {
|
|
11498
|
+
return EOF;
|
|
11499
|
+
}
|
|
11500
|
+
const obj = super.getObj();
|
|
11501
|
+
if (!this.#tracking) {
|
|
11502
|
+
return obj;
|
|
11503
|
+
}
|
|
11504
|
+
// Inline images have their own parser and delimiter rules.
|
|
11505
|
+
if (obj instanceof Cmd && obj.cmd === "BI") {
|
|
11506
|
+
this.#openers.length = 0;
|
|
11507
|
+
this.#tracking = false;
|
|
11508
|
+
return obj;
|
|
11509
|
+
}
|
|
11510
|
+
const top = this.#openers.at(-1);
|
|
11511
|
+
if (top === "<<") {
|
|
11512
|
+
if (obj instanceof Name) {
|
|
11513
|
+
this.#openers[this.#openers.length - 1] = "<<value";
|
|
11514
|
+
}
|
|
11515
|
+
if (!(obj instanceof Cmd) || obj.cmd !== ">>") {
|
|
11516
|
+
return obj;
|
|
11517
|
+
}
|
|
11518
|
+
} else if (top === "<<value") {
|
|
11519
|
+
this.#openers[this.#openers.length - 1] = "<<";
|
|
11520
|
+
if (obj instanceof Cmd && (obj.cmd === ">>" || obj.cmd === "]")) {
|
|
11521
|
+
return obj;
|
|
11522
|
+
}
|
|
11523
|
+
}
|
|
11524
|
+
if (obj instanceof Cmd) {
|
|
11525
|
+
switch (obj.cmd) {
|
|
11526
|
+
case "<<":
|
|
11527
|
+
case "[":
|
|
11528
|
+
// Fall back to the original lexer on excessive nesting.
|
|
11529
|
+
if (this.#openers.length === 1024) {
|
|
11530
|
+
this.#openers.length = 0;
|
|
11531
|
+
this.#tracking = false;
|
|
11532
|
+
} else {
|
|
11533
|
+
this.#openers.push(obj.cmd);
|
|
11534
|
+
}
|
|
11535
|
+
break;
|
|
11536
|
+
case ">>":
|
|
11537
|
+
if (top === "<<") {
|
|
11538
|
+
this.#openers.pop();
|
|
11539
|
+
}
|
|
11540
|
+
break;
|
|
11541
|
+
case "]":
|
|
11542
|
+
if (top === "[") {
|
|
11543
|
+
this.#openers.pop();
|
|
11544
|
+
}
|
|
11545
|
+
break;
|
|
11546
|
+
case "endobj":
|
|
11547
|
+
this.#ended = this.#openers.length === 0;
|
|
11548
|
+
break;
|
|
11549
|
+
}
|
|
11550
|
+
}
|
|
11551
|
+
return obj;
|
|
11552
|
+
}
|
|
11553
|
+
}
|
|
11484
11554
|
class Linearization {
|
|
11485
11555
|
static create(stream) {
|
|
11486
11556
|
function getInt(linDict, name, allowZeroValue = false) {
|
|
@@ -11505,7 +11575,7 @@ class Linearization {
|
|
|
11505
11575
|
throw new Error("Hint array in the linearization dictionary is invalid.");
|
|
11506
11576
|
}
|
|
11507
11577
|
const parser = new Parser({
|
|
11508
|
-
lexer: new
|
|
11578
|
+
lexer: new IndirectObjectLexer(stream),
|
|
11509
11579
|
xref: null
|
|
11510
11580
|
});
|
|
11511
11581
|
const obj1 = parser.getObj();
|
|
@@ -54884,7 +54954,7 @@ class XRef {
|
|
|
54884
54954
|
startXRefParsedCache.add(startXRef);
|
|
54885
54955
|
stream.pos = startXRef + stream.start;
|
|
54886
54956
|
const parser = new Parser({
|
|
54887
|
-
lexer: new
|
|
54957
|
+
lexer: new IndirectObjectLexer(stream),
|
|
54888
54958
|
xref: this,
|
|
54889
54959
|
allowStreams: true
|
|
54890
54960
|
});
|
|
@@ -55002,7 +55072,7 @@ class XRef {
|
|
|
55002
55072
|
}
|
|
55003
55073
|
const stream = this.stream.makeSubStream(xrefEntry.offset + this.stream.start);
|
|
55004
55074
|
const parser = new Parser({
|
|
55005
|
-
lexer: new
|
|
55075
|
+
lexer: new IndirectObjectLexer(stream),
|
|
55006
55076
|
xref: this,
|
|
55007
55077
|
allowStreams: true
|
|
55008
55078
|
});
|