refactor: simplify pass (trekexecute)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Kjell Tore Guttormsen 2026-11-02 10:58:35 +01:00
commit cc277c476c
Signed by: ktg
SSH key fingerprint: SHA256:JakMjO6FTBBzN0Bhfj9saOoEjaFxlSdYuZQQpM/lF9Q
2 changed files with 15 additions and 12 deletions

View file

@ -365,13 +365,13 @@ function blockArgs(unquoted, unreadable) {
process.exit(2); process.exit(2);
} }
// The quote state at `to` of `text` read from `from` for quotes only: 'none' // The quote state at `to` of `text` read from its start for quotes only: 'none'
// (outside every quote), 'open' (inside '...' or "...", or inside an earlier // (outside every quote), 'open' (inside '...' or "...", or inside an earlier
// heredoc's body) or 'unknown' (the scan cannot follow the shell here). // heredoc's body) or 'unknown' (the scan cannot follow the shell here).
// `state`, when given, lets the calls on one text resume where the last stopped. // `state` lets the calls on one text resume where the last stopped; a call
function argsQuoteScan(text, from, to, openers, state) { // before that point starts over from the start of the text.
const fresh = (pos) => ({ pos, mode: 'none', pending: null, bodyEnd: -1 }); function argsQuoteScan(text, to, openers, state) {
const st = state ? (state.pos <= to ? state : fresh(0)) : fresh(from); const st = state.pos <= to ? state : { pos: 0, mode: 'none', pending: null, bodyEnd: -1 };
let p = st.pos; let p = st.pos;
let mode = st.mode; let mode = st.mode;
let pending = st.pending; let pending = st.pending;
@ -418,7 +418,6 @@ function argsQuoteScan(text, from, to, openers, state) {
if (c === '\\') { if (c === '\\') {
// The scan never decides a backslash without the character it escapes. // The scan never decides a backslash without the character it escapes.
if (p + 1 >= to) return unknown(); if (p + 1 >= to) return unknown();
if (mode === 'double' && d === '\n') return unknown();
if (d === '\n') return unknown(); // scan: a continuation cannot be followed if (d === '\n') return unknown(); // scan: a continuation cannot be followed
p += 2; p += 2;
continue; continue;
@ -495,7 +494,7 @@ function argsEscapedLt(text, i, lim, openers) {
let b = 0; let b = 0;
while (i - 1 - b >= 0 && text[i - 1 - b] === '\\') b += 1; while (i - 1 - b >= 0 && text[i - 1 - b] === '\\') b += 1;
const s = i - b; const s = i - b;
return b % 2 === 1 && argsQuoteScan(text, 0, s, openers, lim.state) === 'none'; return b % 2 === 1 && argsQuoteScan(text, s, openers, lim.state) === 'none';
} }
// An opener whose raw span holds a backslash-newline. The regex reading cannot // An opener whose raw span holds a backslash-newline. The regex reading cannot

View file

@ -26,6 +26,7 @@ import { dirname, join } from 'node:path';
import { fileURLToPath, pathToFileURL } from 'node:url'; import { fileURLToPath, pathToFileURL } from 'node:url';
import { runHook, runHookWithEnv } from '../helpers/hook-helper.mjs'; import { runHook, runHookWithEnv } from '../helpers/hook-helper.mjs';
import { tmp, pluginCopy } from './guard-helpers.mjs'; import { tmp, pluginCopy } from './guard-helpers.mjs';
import { fastestWithin } from '../helpers/timing.mjs';
const HERE = dirname(fileURLToPath(import.meta.url)); const HERE = dirname(fileURLToPath(import.meta.url));
const ROOT = join(HERE, '..', '..'); const ROOT = join(HERE, '..', '..');
@ -305,9 +306,12 @@ test('part-A scan: a long command with many escaped < is read in linear time', a
// scan resumes where its last call stopped, so the text is read once. // scan resumes where its last call stopped, so the text is read once.
const many = ('\\<' + 'x'.repeat(40) + ' ').repeat(20000); const many = ('\\<' + 'x'.repeat(40) + ' ').repeat(20000);
const command = `echo ${many}<<'${D}'\nbrief.md\n${D}`; const command = `echo ${many}<<'${D}'\nbrief.md\n${D}`;
const started = Date.now(); let last = { code: null, stderr: '' };
const { code, stderr } = await runHook(PRE_BASH, bashInput(command)); const timing = await fastestWithin(15000, async () => {
const elapsed = Date.now() - started; const started = Date.now();
assert.strictEqual(code, 0, `the guard did not pass the long command (exit ${code}): ${stderr.slice(0, 300)}`); last = await runHook(PRE_BASH, bashInput(command));
assert.ok(elapsed < 15000, `the guard took ${elapsed} ms on ${command.length} characters (limit 15000 ms)`); return Date.now() - started;
});
assert.strictEqual(last.code, 0, `the guard did not pass the long command (exit ${last.code}): ${last.stderr.slice(0, 300)}`);
assert.ok(timing.ok, `the guard took ${timing.fastest} ms at best (runs ${timing.runs.join(', ')}) on ${command.length} characters (limit 15000 ms)`);
}); });