- extension/src/{port,platform,codepage} -> src/; native_render -> src/host
(+ dxt, shaders/); libgr2 -> src/gr2; extension/third_party -> third_party
- extension/tests -> tests/port, libgr2/tests -> tests/gr2
- android-native -> android (build.sh, push-client.sh moved in)
- script -> scripts; tools/40250 -> tools/server; oracle -> tools/granny-oracle;
perf tools -> tools/perf
- all build trees under build/ (native, release, android, port-gate)
- xrender:: CMake aliases -> mt::; port-map ledger impl paths rewritten
No code changes. ctest 15/15, port_gate macos+android PASS, port_map check 0 errors.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
64 lines
2.1 KiB
JavaScript
Executable File
64 lines
2.1 KiB
JavaScript
Executable File
#!/usr/bin/env node
|
|
/* Copy stdin to stdout line by line, replacing the test credentials before any
|
|
* byte reaches disk. Secrets come only from MT_ACCOUNT / MT_PASSWORD in the
|
|
* environment and are never printed, logged or passed as arguments.
|
|
*
|
|
* node scripts/redact_stream.mjs <fifo >client.log
|
|
*
|
|
* Uses blocking reads on fd 0: async stdin on a macOS FIFO does not reliably
|
|
* report EOF, which would leave the runner waiting for the redactor. */
|
|
import fs from 'node:fs';
|
|
import { fileURLToPath } from 'node:url';
|
|
|
|
const MIN_LENGTH = 2;
|
|
|
|
export function secretLiterals(env = process.env) {
|
|
return ['MT_PASSWORD', 'MT_ACCOUNT']
|
|
.map((name) => env[name] || '')
|
|
.filter((value) => value.length >= MIN_LENGTH)
|
|
// Longest first so an account contained in a password is not half-replaced.
|
|
.sort((a, b) => b.length - a.length);
|
|
}
|
|
|
|
export function redact(line, literals = secretLiterals()) {
|
|
let out = line;
|
|
for (const literal of literals) out = out.split(literal).join('[redacted]');
|
|
return out;
|
|
}
|
|
|
|
function pump() {
|
|
const literals = secretLiterals();
|
|
const buffer = Buffer.alloc(64 * 1024);
|
|
let pending = '';
|
|
const write = (text) => {
|
|
const bytes = Buffer.from(text);
|
|
let offset = 0;
|
|
while (offset < bytes.length) offset += fs.writeSync(1, bytes, offset);
|
|
};
|
|
for (;;) {
|
|
let count;
|
|
try {
|
|
count = fs.readSync(0, buffer, 0, buffer.length, null);
|
|
} catch (error) {
|
|
if (error.code === 'EAGAIN') continue;
|
|
if (error.code === 'EOF') break;
|
|
throw error;
|
|
}
|
|
if (count === 0) break;
|
|
pending += buffer.toString('utf8', 0, count);
|
|
const lines = pending.split('\n');
|
|
pending = lines.pop();
|
|
if (lines.length > 0) write(lines.map((line) => `${redact(line, literals)}\n`).join(''));
|
|
}
|
|
// A trailing partial line is still redacted as a whole.
|
|
if (pending !== '') write(`${redact(pending, literals)}\n`);
|
|
}
|
|
|
|
if (process.argv[1] && fileURLToPath(import.meta.url) === fs.realpathSync(process.argv[1])) {
|
|
if (process.argv.includes('--help')) {
|
|
console.log('usage: node scripts/redact_stream.mjs < INPUT > OUTPUT (reads MT_ACCOUNT/MT_PASSWORD from env)');
|
|
} else {
|
|
pump();
|
|
}
|
|
}
|