fix: cap huge selections before shortening
The shortcut and toolbar read window.getSelection() without a limit, so a select-all on a very large page handed prepareAction millions of characters. Every binary-search probe re-encoded the whole candidate prefix: about 1.1 s for 5M characters, paid again by the dialog. Each code point adds at least one character to the URL, so nothing past the first MAX_URL_CHARS can fit. Cap there before any encoding. A capped source never takes the ready path: renderPrompt trims, so a prefix of mostly whitespace could fit and silently drop the rest without consent. Output is unchanged: 2,000 random cases matched develop exactly. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
+14
-3
@@ -25,12 +25,23 @@ export function prepareAction(request) {
|
||||
}
|
||||
const resolved = { ...request, language };
|
||||
const serialize = text => serializePrompt(request.settings, renderPrompt(resolved, text));
|
||||
const url = serialize(source);
|
||||
if (url.length <= MAX_URL_CHARS) return { kind: 'ready', url };
|
||||
// Each code point adds at least one URL character, so none past the first
|
||||
// MAX_URL_CHARS can fit. Capping first keeps a select-all on a huge page from
|
||||
// costing seconds of re-encoding. A capped source is never sent as ready: its
|
||||
// kept prefix may trim down to something that fits and silently drop the rest.
|
||||
const points = [];
|
||||
let capped = false;
|
||||
for (const point of source) {
|
||||
if (points.length === MAX_URL_CHARS) { capped = true; break; }
|
||||
points.push(point);
|
||||
}
|
||||
if (!capped) {
|
||||
const url = serialize(source);
|
||||
if (url.length <= MAX_URL_CHARS) return { kind: 'ready', url };
|
||||
}
|
||||
if (isUrl) return error('This URL is too long to send intact. No part of it has been sent.');
|
||||
const marker = '\n[Selected text shortened]';
|
||||
if (serialize(marker).length >= MAX_URL_CHARS) return error('The prompt instructions are too long. Shorten your prompt template and try again.');
|
||||
const points = Array.from(source);
|
||||
let low = 0, high = points.length;
|
||||
while (low < high) {
|
||||
const mid = Math.ceil((low + high) / 2);
|
||||
|
||||
Reference in New Issue
Block a user