mirror of
https://github.com/affaan-m/everything-claude-code.git
synced 2026-03-30 13:43:26 +08:00
test: add 3 tests for nested backtick context truncation, newline args injection, alias 128-char boundary
Round 111: Tests for parseSessionMetadata context regex truncation at nested triple backticks (lazy [\s\S]*? stops early), getExecCommand accepting newline/tab/CR in args via \s in SAFE_ARGS_REGEX, and setAlias accepting exactly 128-character alias (off-by-one boundary). 893 tests total.
This commit is contained in:
@@ -1536,6 +1536,33 @@ function runTests() {
|
||||
}
|
||||
})) passed++; else failed++;
|
||||
|
||||
// ── Round 111: getExecCommand with newline in args — SAFE_ARGS_REGEX \s includes \n ──
|
||||
console.log('\nRound 111: getExecCommand (newline in args — SAFE_ARGS_REGEX \\s matches \\n):');
|
||||
if (test('getExecCommand accepts newline in args because SAFE_ARGS_REGEX \\s includes \\n', () => {
|
||||
// SAFE_ARGS_REGEX = /^[@a-zA-Z0-9\s_.\/:=,'"*+-]+$/
|
||||
// \s matches [\t\n\v\f\r ] — includes newline!
|
||||
// This means "file.js\nmalicious" passes the regex.
|
||||
const originalEnv = process.env.CLAUDE_PACKAGE_MANAGER;
|
||||
try {
|
||||
process.env.CLAUDE_PACKAGE_MANAGER = 'npm';
|
||||
// Newline in args should pass SAFE_ARGS_REGEX because \s matches \n
|
||||
const cmd = pm.getExecCommand('prettier', 'file.js\necho injected');
|
||||
assert.strictEqual(cmd, 'npx prettier file.js\necho injected',
|
||||
'Newline passes SAFE_ARGS_REGEX (\\s includes \\n) — potential command injection vector');
|
||||
// Tab also passes
|
||||
const cmd2 = pm.getExecCommand('eslint', 'file.js\t--fix');
|
||||
assert.strictEqual(cmd2, 'npx eslint file.js\t--fix',
|
||||
'Tab also passes SAFE_ARGS_REGEX via \\s');
|
||||
// Carriage return also passes
|
||||
const cmd3 = pm.getExecCommand('tsc', 'src\r--strict');
|
||||
assert.strictEqual(cmd3, 'npx tsc src\r--strict',
|
||||
'Carriage return passes via \\s');
|
||||
} finally {
|
||||
if (originalEnv !== undefined) process.env.CLAUDE_PACKAGE_MANAGER = originalEnv;
|
||||
else delete process.env.CLAUDE_PACKAGE_MANAGER;
|
||||
}
|
||||
})) passed++; else failed++;
|
||||
|
||||
// Summary
|
||||
console.log('\n=== Test Results ===');
|
||||
console.log(`Passed: ${passed}`);
|
||||
|
||||
@@ -1395,6 +1395,29 @@ function runTests() {
|
||||
'Whitespace title persists in JSON as-is');
|
||||
})) passed++; else failed++;
|
||||
|
||||
// ── Round 111: setAlias with exactly 128-character alias — off-by-one boundary ──
|
||||
console.log('\nRound 111: setAlias (128-char alias — exact boundary of > 128 check):');
|
||||
if (test('setAlias accepts alias of exactly 128 characters (128 is NOT > 128)', () => {
|
||||
// session-aliases.js line 199: if (alias.length > 128)
|
||||
// 128 is NOT > 128, so exactly 128 chars is ACCEPTED.
|
||||
// Existing test only checks 129 (rejected).
|
||||
resetAliases();
|
||||
const alias128 = 'a'.repeat(128);
|
||||
const result = aliases.setAlias(alias128, '/path/to/session');
|
||||
assert.strictEqual(result.success, true,
|
||||
'128-char alias should be accepted (128 is NOT > 128)');
|
||||
assert.strictEqual(result.isNew, true);
|
||||
// Verify it can be resolved
|
||||
const resolved = aliases.resolveAlias(alias128);
|
||||
assert.notStrictEqual(resolved, null, '128-char alias should be resolvable');
|
||||
assert.strictEqual(resolved.sessionPath, '/path/to/session');
|
||||
// Confirm 129 is rejected (boundary)
|
||||
const result129 = aliases.setAlias('b'.repeat(129), '/path');
|
||||
assert.strictEqual(result129.success, false, '129-char alias should be rejected');
|
||||
assert.ok(result129.error.includes('128'),
|
||||
'Error message should mention 128-char limit');
|
||||
})) passed++; else failed++;
|
||||
|
||||
// Summary
|
||||
console.log(`\nResults: Passed: ${passed}, Failed: ${failed}`);
|
||||
process.exit(failed > 0 ? 1 : 0);
|
||||
|
||||
@@ -1891,6 +1891,45 @@ file.ts
|
||||
assert.strictEqual(lowerResult.shortId, 'abcd1234');
|
||||
})) passed++; else failed++;
|
||||
|
||||
// ── Round 111: parseSessionMetadata context with nested triple backticks — lazy regex truncation ──
|
||||
console.log('\nRound 111: parseSessionMetadata (nested ``` in context — lazy \\S*? stops at first ```):");');
|
||||
if (test('parseSessionMetadata context capture truncated by nested triple backticks', () => {
|
||||
// The regex: /### Context to Load\s*\n```\n([\s\S]*?)```/
|
||||
// The lazy [\s\S]*? matches as few chars as possible, so it stops at the
|
||||
// FIRST ``` it encounters — even if that's inside the code block content.
|
||||
const content = [
|
||||
'# Session',
|
||||
'',
|
||||
'### Context to Load',
|
||||
'```',
|
||||
'const x = 1;',
|
||||
'```nested code block```', // Inner ``` causes premature match end
|
||||
'const y = 2;',
|
||||
'```'
|
||||
].join('\n');
|
||||
const meta = sessionManager.parseSessionMetadata(content);
|
||||
// Lazy regex stops at the inner ```, so context only captures "const x = 1;\n"
|
||||
assert.ok(meta.context.includes('const x = 1'),
|
||||
'Context should contain text before the inner backticks');
|
||||
assert.ok(!meta.context.includes('const y = 2'),
|
||||
'Context should NOT contain text after inner ``` (lazy regex stops early)');
|
||||
// Without nested backticks, full content is captured
|
||||
const cleanContent = [
|
||||
'# Session',
|
||||
'',
|
||||
'### Context to Load',
|
||||
'```',
|
||||
'const x = 1;',
|
||||
'const y = 2;',
|
||||
'```'
|
||||
].join('\n');
|
||||
const cleanMeta = sessionManager.parseSessionMetadata(cleanContent);
|
||||
assert.ok(cleanMeta.context.includes('const x = 1'),
|
||||
'Clean context should have first line');
|
||||
assert.ok(cleanMeta.context.includes('const y = 2'),
|
||||
'Clean context should have second line');
|
||||
})) passed++; else failed++;
|
||||
|
||||
// Summary
|
||||
console.log(`\nResults: Passed: ${passed}, Failed: ${failed}`);
|
||||
process.exit(failed > 0 ? 1 : 0);
|
||||
|
||||
Reference in New Issue
Block a user