From 4fc8af11705604402a158f1c8fac1f129df4c9a0 Mon Sep 17 00:00:00 2001 From: jay23606 <4602056+jay23606@users.noreply.github.com> Date: Wed, 21 Oct 2026 05:23:53 -0400 Subject: [PATCH 1/3] Handle unknown encoding values cleanly Co-Authored-By: Claude Haiku 5.5 Signed-off-by: jay23606 <4602056+jay23606@users.noreply.github.com> --- src/cli.ts | 1 + src/engine.ts | 7 +++++++ test/js/encoding.test.js | 15 ++++++--------- 3 files changed, 14 insertions(+), 9 deletions(-) diff --git a/src/cli.ts b/src/cli.ts index 46c7661a..da37082c 100644 --- a/src/cli.ts +++ b/src/cli.ts @@ -395,6 +395,7 @@ function unescapeString(str = '') { }); outputConfig(config); + rexreplace.validateEncoding(config.encoding); let pipeInUse = false; let pipeData = ''; diff --git a/src/engine.ts b/src/engine.ts index 6cb51667..7bf01f49 100644 --- a/src/engine.ts +++ b/src/engine.ts @@ -26,9 +26,16 @@ export {version} from '../package.json'; const runtime = process.versions.bun ? 'Bun' : 'Node'; const runtimeEngine = process.versions.bun ? 'JSC' : 'V8'; +export function validateEncoding(encoding = 'utf8') { + if (!Buffer.isEncoding(encoding)) { + die('Unknown encoding:', encoding); + } +} + // Returns a promise that resolves when all files are done export async function engine(config: any = {engine: 'default'}) { outputConfig(config); + validateEncoding(config.encoding); step('Displaying steps for:'); step(config); diff --git a/test/js/encoding.test.js b/test/js/encoding.test.js index 8d7d665f..0b506bf4 100644 --- a/test/js/encoding.test.js +++ b/test/js/encoding.test.js @@ -49,15 +49,12 @@ describe('--encoding', () => { ); }); - test.todo( - 'BUG #690: an unknown encoding gives an error message instead of crashing', - async () => { - fs.writeFileSync('my.file', 'foobar'); - const result = await rr('o', 'x', {includeGlob: ['my.file'], encoding: 'nope'}); - expect(result.exit).toBe(1); - expect(result.err).toContain('nope'); - } - ); + test('BUG #690: an unknown encoding gives an error message instead of crashing', async () => { + fs.writeFileSync('my.file', 'foobar'); + const result = await rr('o', 'x', {includeGlob: ['my.file'], encoding: 'nope'}); + expect(result.exit).toBe(1); + expect(result.err).toContain('nope'); + }); describe('combined', () => { test.each([ From 74833a021cf01798f3d114bd0b86adb2566ac773 Mon Sep 17 00:00:00 2001 From: Mathias Wulff Date: Thu, 22 Oct 2026 01:55:56 +1100 Subject: [PATCH 2/3] Test the full result of an unknown encoding, also for piped data and in the CLI --- test/cli/run.sh | 10 ++++++++++ test/js/encoding.test.js | 22 ++++++++++++++++++---- 2 files changed, 28 insertions(+), 4 deletions(-) diff --git a/test/cli/run.sh b/test/cli/run.sh index 3454688c..0852e1d7 100644 --- a/test/cli/run.sh +++ b/test/cli/run.sh @@ -130,6 +130,16 @@ else fi +# -e +# An unknown encoding stops the run with an error, both for files and for piped data (#690) +reset +assert_failure "rexreplace o x my.file -e nope" +assert "cat my.file" 'foobar' +assert_failure "printf foo | rexreplace o x -e nope" +assert "printf foo | rexreplace o x -e nope 2>&1 | grep -v 'exited with code'" ' ❌ Unknown encoding: nope' +assert "printf foo | rexreplace o x -e LATIN1" 'fxx' + + # -b reset rexreplace o x my.file --keep-backup diff --git a/test/js/encoding.test.js b/test/js/encoding.test.js index 0b506bf4..60561781 100644 --- a/test/js/encoding.test.js +++ b/test/js/encoding.test.js @@ -49,11 +49,25 @@ describe('--encoding', () => { ); }); - test('BUG #690: an unknown encoding gives an error message instead of crashing', async () => { + // The error message, and not the stack trace from deep inside node, when an encoding is unknown (#690) + const unknownEncoding = {out: '', err: ' ❌ Unknown encoding: nope\n\n', exit: 1}; + + test('stops the run with an error if it is unknown (#690)', async () => { fs.writeFileSync('my.file', 'foobar'); - const result = await rr('o', 'x', {includeGlob: ['my.file'], encoding: 'nope'}); - expect(result.exit).toBe(1); - expect(result.err).toContain('nope'); + expect(await rr('o', 'x', {includeGlob: ['my.file'], encoding: 'nope'})).toEqual( + unknownEncoding + ); + expect(fs.readFileSync('my.file', 'utf8')).toBe('foobar'); + }); + + test('stops the run with an error if it is unknown, also for piped data (#690)', async () => { + expect(await rr('o', 'x', {pipedData: 'foo', encoding: 'nope'})).toEqual(unknownEncoding); + }); + + test('is known in any case', async () => { + fs.writeFileSync('my.file', latin1()); + await rr('æ', 'ø', {includeGlob: ['my.file'], encoding: 'LATIN1'}); + expect(fs.readFileSync('my.file')).toEqual(Buffer.from([0x66, 0xf8, 0x6f])); }); describe('combined', () => { From 46bd57d122d891909e413f957499c8ece27721bc Mon Sep 17 00:00:00 2001 From: Mathias Wulff Date: Thu, 22 Oct 2026 02:17:02 +1100 Subject: [PATCH 3/3] Check the encoding in the input parser of the CLI --- src/cli.ts | 3 ++- src/engine.ts | 2 +- test/cli/run.sh | 2 +- 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/src/cli.ts b/src/cli.ts index da37082c..5e48d256 100644 --- a/src/cli.ts +++ b/src/cli.ts @@ -93,6 +93,8 @@ const yargs = require('yargs') .default('e', 'utf8') .alias('e', 'encoding') .describe('e', 'Encoding of files/piped data.') + // Not .choices() as node takes the name of an encoding in any case, like `UTF8` + .check((argv) => Buffer.isEncoding(argv.encoding) || `Unknown encoding: ${argv.encoding}`) .alias('E', 'engine') .describe( @@ -395,7 +397,6 @@ function unescapeString(str = '') { }); outputConfig(config); - rexreplace.validateEncoding(config.encoding); let pipeInUse = false; let pipeData = ''; diff --git a/src/engine.ts b/src/engine.ts index 7bf01f49..da504e35 100644 --- a/src/engine.ts +++ b/src/engine.ts @@ -26,7 +26,7 @@ export {version} from '../package.json'; const runtime = process.versions.bun ? 'Bun' : 'Node'; const runtimeEngine = process.versions.bun ? 'JSC' : 'V8'; -export function validateEncoding(encoding = 'utf8') { +function validateEncoding(encoding = 'utf8') { if (!Buffer.isEncoding(encoding)) { die('Unknown encoding:', encoding); } diff --git a/test/cli/run.sh b/test/cli/run.sh index 0852e1d7..593f634c 100644 --- a/test/cli/run.sh +++ b/test/cli/run.sh @@ -136,7 +136,7 @@ reset assert_failure "rexreplace o x my.file -e nope" assert "cat my.file" 'foobar' assert_failure "printf foo | rexreplace o x -e nope" -assert "printf foo | rexreplace o x -e nope 2>&1 | grep -v 'exited with code'" ' ❌ Unknown encoding: nope' +assert "printf foo | rexreplace o x -e nope 2>&1 | grep -v 'exited with code' | tail -1" 'Unknown encoding: nope' assert "printf foo | rexreplace o x -e LATIN1" 'fxx'