blob: b6a37fbbd7e726eb541aa2d259021675212835d1 [file]
import assert from 'node:assert/strict';
import { describe, test } from 'node:test';
import { BashTailBuffer } from '../bash-tail-buffer.js';
describe('BashTailBuffer', () => {
test('returns everything when under the cap', () => {
const buf = new BashTailBuffer(100);
buf.push('hello\n');
buf.push('world');
assert.equal(buf.value(), 'hello\nworld');
});
test('bounds retained output to the cap and keeps whole tail lines', () => {
const buf = new BashTailBuffer(20);
for (let i = 0; i < 100; i++) buf.push(`line${i}\n`);
const value = buf.value();
assert.ok(value.length <= 20);
assert.ok(value.endsWith('line99\n')); // tail preserved
assert.ok(value.startsWith('line')); // starts at a line boundary, not mid-line
});
test('drops the partial leading line so a sliced secret prefix cannot survive', () => {
// The first line would be cut mid-secret; the buffer must drop it whole so a
// later redaction pass never sees a secret with its prefix sliced off.
const buf = new BashTailBuffer(10);
buf.push('SECRETXYZ\n');
buf.push('KEEP1\nKEEP2\n');
const value = buf.value();
assert.equal(value, 'KEEP2\n');
assert.ok(!value.includes('SECRET'));
});
test('drops a single oversized line with no newline (no safe redaction boundary)', () => {
// A single line larger than the cap has no line boundary to cut on; keeping
// a byte-slice could hand redaction a secret with its prefix sliced off, so
// it is dropped entirely. Pathological case — the common single line is
// under the cap and never sliced.
const buf = new BashTailBuffer(5);
buf.push('Authorization: Bearer sk-live-secret-token-value'); // one giant line
assert.equal(buf.value(), '');
// It also flags the unsafe drop so callers can mark the empty result.
assert.equal(buf.hasDroppedUnsafe(), true);
});
test('does not flag a safe drop (partial leading line trimmed at a newline)', () => {
const buf = new BashTailBuffer(8);
buf.push('aaaa\nbbbb\ncccc\n'); // sliced at a newline boundary — safe, not unsafe
assert.ok(buf.value().length <= 8);
assert.equal(buf.hasDroppedUnsafe(), false);
});
test('keeps discarding continuation chunks of a dropped oversized line until a newline', () => {
// The oversized line arrives across multiple chunks (stdout does not split on
// line boundaries). After the prefix is dropped, the suffix chunk must stay
// discarded — otherwise redaction would later see a secret with no prefix.
const buf = new BashTailBuffer(20);
buf.push('Authorization: Bearer sk-live-' + 'A'.repeat(30)); // oversized prefix dropped
buf.push('secret_tail'); // continuation of the SAME line
assert.equal(buf.value(), '');
buf.push(' more\nKEEP\n'); // newline terminates the compromised line; resume after it
assert.equal(buf.value(), 'KEEP\n');
});
});