Skip to content

Commit a659fe7

Browse files
committed
test(audit): pin every control-suffix spelling of a secret name
The name pre-filter strips all of C0 plus DEL before re-testing, but only the trailing-LF spelling was covered. Reading the class was no help while it was written with literal bytes, so the behaviour was effectively unpinned in both directions. Each boundary spelling now has a case — LF, CR, DEL, NUL — and narrowing the strip to LF alone turns the CR and DEL cases red, so the class cannot be quietly narrowed again.
1 parent 2683a39 commit a659fe7

1 file changed

Lines changed: 16 additions & 8 deletions

File tree

packages/cli/src/commands/audit/lib/files-plan.test.ts

Lines changed: 16 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1119,21 +1119,29 @@ describe('the never-content-read and never-walk invariants', () => {
11191119
expect(collection.subjects.map((f) => f.path)).toContain('src/scanner.ts');
11201120
});
11211121

1122-
it('records a secret-shaped name carrying a trailing newline', () => {
1122+
it.each([
1123+
['a trailing LF', '.env\n'],
1124+
['a trailing CR', '.env\r'],
1125+
['a trailing DEL', '.npmrc\x7f'],
1126+
['a trailing NUL', 'app.key\x00'],
1127+
])('records a secret-shaped name carrying %s', (_label, name) => {
11231128
// Filesystem names are byte strings, and every name clause is
1124-
// `$`-anchored: a trailing CR/LF slips the lot and the file becomes a
1125-
// content-read audit subject.
1126-
const weird = join(dir, '.env\n');
1129+
// `$`-anchored: a trailing control character slips the lot and the file
1130+
// becomes a content-read audit subject. The strip covers all of C0 plus
1131+
// DEL, so each boundary spelling is pinned here rather than just the
1132+
// newline one — the class is written with escapes precisely so a reader
1133+
// can check that claim (literal bytes made the whole module undiffable).
1134+
const weird = join(dir, name);
11271135
try {
11281136
writeFileSync(weird, 'API_KEY=x\n');
11291137
} catch {
11301138
return; // the platform refuses the name; nothing to guard
11311139
}
11321140
const collection = collectAuditFiles(dir);
1133-
expect(collection.subjects.map((f) => f.path)).not.toContain('.env\n');
1134-
expect(collection.uncoverable.map((u) => u.reason)).toContain(
1135-
'secret-shaped',
1136-
);
1141+
expect(collection.subjects.map((f) => f.path)).not.toContain(name);
1142+
expect(collection.uncoverable.find((u) => u.path === name)).toMatchObject({
1143+
reason: 'secret-shaped',
1144+
});
11371145
});
11381146

11391147
it('names the newly covered credential shapes', () => {

0 commit comments

Comments
 (0)