mirror of
https://git.zavage.net/Zavage-Software/search-with-chatgpt-powered-by-openai-extension.git
synced 2026-08-10 13:40:29 -06:00
fix: stop $ sequences in selected text corrupting the prompt
This commit is contained in:
parent
1106f4e315
commit
d7821e3dc7
@ -21,7 +21,12 @@ function applyTemplate(template, query) {
|
|||||||
}
|
}
|
||||||
const tpl = typeof template === "string" ? template : "";
|
const tpl = typeof template === "string" ? template : "";
|
||||||
if (tpl.includes("{query}")) {
|
if (tpl.includes("{query}")) {
|
||||||
return tpl.replaceAll("{query}", query);
|
// Replacer function, not a replacement string: String.prototype.replaceAll
|
||||||
|
// gives $&, $`, $', and $$ special meaning in a replacement STRING, and
|
||||||
|
// `query` is arbitrary page-selected text that can contain any of those
|
||||||
|
// (shell one-liners routinely do). The function form disables that
|
||||||
|
// interpretation entirely. Do not "simplify" this back to the string form.
|
||||||
|
return tpl.replaceAll("{query}", () => query);
|
||||||
}
|
}
|
||||||
const trimmed = tpl.trim();
|
const trimmed = tpl.trim();
|
||||||
return trimmed === "" ? query : `${trimmed} ${query}`;
|
return trimmed === "" ? query : `${trimmed} ${query}`;
|
||||||
|
|||||||
@ -133,3 +133,43 @@ test("a query needing no truncation is left byte-identical", () => {
|
|||||||
const raw = "a modest question about thermodynamics";
|
const raw = "a modest question about thermodynamics";
|
||||||
assert.equal(queryOf(buildChatGptUrl(DEFAULT_SETTINGS, raw)), raw);
|
assert.equal(queryOf(buildChatGptUrl(DEFAULT_SETTINGS, raw)), raw);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// String.prototype.replaceAll gives $&, $`, $', and $$ special meaning in the
|
||||||
|
// REPLACEMENT string, and `query` (arbitrary page-selected text) is exactly
|
||||||
|
// that argument. These selections are ordinary shell one-liners, not
|
||||||
|
// adversarial input, and must round-trip byte-identically into `q`.
|
||||||
|
test("a selection containing $& survives the default {query} template byte-identically", () => {
|
||||||
|
const raw = "awk print $& here";
|
||||||
|
const url = buildChatGptUrl(DEFAULT_SETTINGS, raw);
|
||||||
|
assert.equal(queryOf(url), raw);
|
||||||
|
});
|
||||||
|
|
||||||
|
test("a selection containing $& survives a prefix template byte-identically", () => {
|
||||||
|
const raw = "awk print $& here";
|
||||||
|
const url = buildChatGptUrl(withSettings({ promptTemplate: "Explain: {query}" }), raw);
|
||||||
|
assert.equal(queryOf(url), `Explain: ${raw}`);
|
||||||
|
});
|
||||||
|
|
||||||
|
test("a selection containing $` and $' survives the default {query} template byte-identically", () => {
|
||||||
|
const raw = "shell $` and $' here";
|
||||||
|
const url = buildChatGptUrl(DEFAULT_SETTINGS, raw);
|
||||||
|
assert.equal(queryOf(url), raw);
|
||||||
|
});
|
||||||
|
|
||||||
|
test("a selection containing $` and $' survives a prefix template byte-identically", () => {
|
||||||
|
const raw = "shell $` and $' here";
|
||||||
|
const url = buildChatGptUrl(withSettings({ promptTemplate: "Explain: {query}" }), raw);
|
||||||
|
assert.equal(queryOf(url), `Explain: ${raw}`);
|
||||||
|
});
|
||||||
|
|
||||||
|
test("a selection containing $$ survives the default {query} template byte-identically", () => {
|
||||||
|
const raw = "PID is $$ in bash";
|
||||||
|
const url = buildChatGptUrl(DEFAULT_SETTINGS, raw);
|
||||||
|
assert.equal(queryOf(url), raw);
|
||||||
|
});
|
||||||
|
|
||||||
|
test("a selection containing $$ survives a prefix template byte-identically", () => {
|
||||||
|
const raw = "PID is $$ in bash";
|
||||||
|
const url = buildChatGptUrl(withSettings({ promptTemplate: "Explain: {query}" }), raw);
|
||||||
|
assert.equal(queryOf(url), `Explain: ${raw}`);
|
||||||
|
});
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user