Merge pull request 'fix: limit the prompt template to 1,000 characters' (#12) from fix/template-length-limit into develop

Reviewed-on: https://git.zavage.net/Zavage-Software/search-with-chatgpt-powered-by-openai-extension/pulls/12
This commit is contained in:
zavage
2026-10-18 02:26:43 -06:00
5 changed files with 38 additions and 5 deletions
+27 -1
View File
@@ -1,7 +1,9 @@
import test from "node:test";
import assert from "node:assert/strict";
import { DEFAULT_SETTINGS } from "../lib/defaults.js";
import { readFileSync } from "node:fs";
import { DEFAULT_SETTINGS, MAX_TEMPLATE_CHARS } from "../lib/defaults.js";
import { mergeSettings } from "../lib/settings.js";
test("empty object yields the defaults", () => {
@@ -67,6 +69,30 @@ test("wrong types fall back to the default", () => {
assert.equal(merged.promptTemplate, DEFAULT_SETTINGS.promptTemplate);
});
test("a prompt template over the length limit falls back to the default", () => {
assert.equal(typeof MAX_TEMPLATE_CHARS, "number");
const atLimit = "x".repeat(MAX_TEMPLATE_CHARS);
assert.equal(mergeSettings({ promptTemplate: atLimit }).promptTemplate, atLimit);
assert.equal(mergeSettings({ promptTemplate: `${atLimit}x` }).promptTemplate,
DEFAULT_SETTINGS.promptTemplate);
});
// storage.sync rejects any item over 8192 bytes (key plus JSON value), and the
// options page writes every field in one set(), so one oversized template would
// make every later save fail. The worst character is a pasted control
// character, which JSON escapes to six bytes.
test("a template at the limit fits storage.sync's per-item quota in the worst case", () => {
const worst = "\u0001".repeat(MAX_TEMPLATE_CHARS);
const bytes = new TextEncoder().encode("promptTemplate" + JSON.stringify(worst)).length;
assert.ok(bytes <= 8192, `${bytes} bytes`);
});
test("the options page enforces the same template limit", () => {
const html = readFileSync(new URL("../options/options.html", import.meta.url), "utf8");
const input = html.match(/<input[^>]*id="promptTemplate"[^>]*>/)?.[0] ?? "";
assert.equal(input.match(/maxlength="(\d+)"/)?.[1], String(MAX_TEMPLATE_CHARS));
});
test("an out-of-range openIn falls back to the default", () => {
assert.equal(mergeSettings({ openIn: "teleport" }).openIn, DEFAULT_SETTINGS.openIn);
assert.equal(mergeSettings({ openIn: "" }).openIn, DEFAULT_SETTINGS.openIn);