kritya 0.8.6-beta → 0.8.8-beta
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/dist/tools/document/xlsx.js +36 -0
- package/package.json +13 -4
|
@@ -1,6 +1,30 @@
|
|
|
1
1
|
import ExcelJS from "exceljs";
|
|
2
|
+
import JSZip from "jszip";
|
|
2
3
|
const CELL_REF_RE = /^[A-Za-z]{1,3}[1-9][0-9]*$/;
|
|
4
|
+
// exceljs's xlsx loader decompresses every entry of the .xlsx zip with no
|
|
5
|
+
// size limit (CVE-2026-78206, unpatched upstream as of this writing) — a
|
|
6
|
+
// small file whose declared uncompressed size is huge can exhaust memory
|
|
7
|
+
// before exceljs itself ever runs. JSZip.loadAsync only reads the central
|
|
8
|
+
// directory (cheap, no inflation), so summing each entry's *declared*
|
|
9
|
+
// uncompressed size here rejects a bomb before handing the buffer to exceljs.
|
|
10
|
+
const MAX_XLSX_UNCOMPRESSED_BYTES = 200 * 1024 * 1024;
|
|
11
|
+
async function assertSafeXlsxSize(buf) {
|
|
12
|
+
const zip = await JSZip.loadAsync(buf);
|
|
13
|
+
let total = 0;
|
|
14
|
+
for (const entry of Object.values(zip.files)) {
|
|
15
|
+
// `_data` is JSZip's internal CompressedObject; there is no public API
|
|
16
|
+
// for a zip entry's declared (pre-inflation) uncompressed size.
|
|
17
|
+
total +=
|
|
18
|
+
entry._data?.uncompressedSize ?? 0;
|
|
19
|
+
if (total > MAX_XLSX_UNCOMPRESSED_BYTES) {
|
|
20
|
+
throw new Error(`This .xlsx file's declared uncompressed size exceeds ` +
|
|
21
|
+
`${MAX_XLSX_UNCOMPRESSED_BYTES / (1024 * 1024)}MB and was refused ` +
|
|
22
|
+
`as a likely decompression bomb rather than risk exhausting memory.`);
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
}
|
|
3
26
|
export async function readXlsx(buf) {
|
|
27
|
+
await assertSafeXlsxSize(buf);
|
|
4
28
|
const workbook = new ExcelJS.Workbook();
|
|
5
29
|
// exceljs's bundled types pin an older @types/node Buffer shape; the
|
|
6
30
|
// runtime accepts any Node Buffer.
|
|
@@ -43,12 +67,18 @@ function toCellValue(value) {
|
|
|
43
67
|
}
|
|
44
68
|
return value;
|
|
45
69
|
}
|
|
70
|
+
// If CSV export via exceljs's `workbook.csv.write()`/`writeBuffer()`/
|
|
71
|
+
// `writeFile()` is ever added, string values starting with =, +, -, @, tab,
|
|
72
|
+
// or CR must be prefixed with a leading `'` before export (CVE-2026-78209) —
|
|
73
|
+
// exceljs does not do this itself, and cell content here can come from
|
|
74
|
+
// LLM-generated or user-supplied text, not just trusted input.
|
|
46
75
|
/**
|
|
47
76
|
* Change specific cells of an existing workbook in place, preserving every
|
|
48
77
|
* other cell, formula, and sheet. Returns the new file bytes and a record of
|
|
49
78
|
* what changed (old -> new) for the permission preview and result message.
|
|
50
79
|
*/
|
|
51
80
|
export async function editXlsx(buf, edits) {
|
|
81
|
+
await assertSafeXlsxSize(buf);
|
|
52
82
|
const workbook = new ExcelJS.Workbook();
|
|
53
83
|
await workbook.xlsx.load(buf);
|
|
54
84
|
const applied = [];
|
|
@@ -74,6 +104,12 @@ export async function editXlsx(buf, edits) {
|
|
|
74
104
|
const arrayBuffer = await workbook.xlsx.writeBuffer();
|
|
75
105
|
return { buf: Buffer.from(arrayBuffer), applied };
|
|
76
106
|
}
|
|
107
|
+
// If image embedding is ever added here via exceljs's `Workbook.addImage()`,
|
|
108
|
+
// never pass a model/user-supplied path straight into `addImage({filename})`
|
|
109
|
+
// — resolve it first and verify it stays inside the workspace, the same way
|
|
110
|
+
// `resolveSafe` guards file-write paths elsewhere. An unchecked filename lets
|
|
111
|
+
// addImage() read and embed an arbitrary file the process can see
|
|
112
|
+
// (CVE-2026-78208).
|
|
77
113
|
export async function writeXlsx(sheets) {
|
|
78
114
|
const workbook = new ExcelJS.Workbook();
|
|
79
115
|
for (const sheet of sheets) {
|
package/package.json
CHANGED
|
@@ -1,8 +1,17 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "kritya",
|
|
3
|
-
"version": "0.8.
|
|
3
|
+
"version": "0.8.8-beta",
|
|
4
4
|
"description": "Kritya — a lean, provider-agnostic terminal coding agent (NVIDIA, OpenAI, OpenRouter, Groq, Ollama, and more)",
|
|
5
5
|
"type": "module",
|
|
6
|
+
"repository": {
|
|
7
|
+
"type": "git",
|
|
8
|
+
"url": "git+https://github.com/GenAICloudDevOps/Kritya.git"
|
|
9
|
+
},
|
|
10
|
+
"homepage": "https://github.com/GenAICloudDevOps/Kritya#readme",
|
|
11
|
+
"bugs": {
|
|
12
|
+
"url": "https://github.com/GenAICloudDevOps/Kritya/issues"
|
|
13
|
+
},
|
|
14
|
+
"author": "Venkata Ramanand",
|
|
6
15
|
"bin": {
|
|
7
16
|
"kritya": "dist/index.js"
|
|
8
17
|
},
|
|
@@ -45,12 +54,12 @@
|
|
|
45
54
|
"dependencies": {
|
|
46
55
|
"docx": "^9.7.1",
|
|
47
56
|
"exceljs": "^4.4.0",
|
|
48
|
-
"fast-glob": "^3.3.
|
|
57
|
+
"fast-glob": "^3.3.3",
|
|
49
58
|
"ink": "^7.1.1",
|
|
50
59
|
"ink-text-input": "^6.0.0",
|
|
51
60
|
"jszip": "^3.10.1",
|
|
52
|
-
"mammoth": "^1.12.
|
|
53
|
-
"openai": "^7.
|
|
61
|
+
"mammoth": "^1.12.1",
|
|
62
|
+
"openai": "^7.5.0",
|
|
54
63
|
"pdf-lib": "^1.17.1",
|
|
55
64
|
"pdfjs-dist": "^6.1.200",
|
|
56
65
|
"pptxgenjs": "^4.0.1",
|