diff options
| author | Agando <roduccomm@gmail.com> | 2026-10-23 18:25:52 +0200 |
|---|---|---|
| committer | Agando <roduccomm@gmail.com> | 2026-10-23 18:25:52 +0200 |
| commit | 7a40846766f3e4dad7c7f72f285e43e06010b218 (patch) | |
| tree | e3b9c78adee9846e32b1d7866848c774c3ad7c69 /modules/core | |
| parent | 5d9fb104317f800dff9f01920c3a34fdd4fd9911 (diff) | |
fix(newos4): an invalid grep pattern returns a message, not an exception (v4.6.64)
Packet 8. `new RegExp(pattern)` sat unguarded in the terminal grep handler and in
VFS find()/grep(), so a bad pattern threw out of the command handler into the error
ledger -- the same ledger packet 2 had to stop trusting.
- module-fs.js grep: compile in try/catch, print
"grep: invalid pattern: <pattern> (<engine message>)" as a warning and return
- virtual-fs.js find()/grep(): same guard, return [] and stash the message on
_lastPatternError instead of throwing into the module error wrapper
Verified live on v4.6.64 with the packet's own repro: `grep "/\bug_id\" file` prints
the message, the error counter stays 0 (was: one ledger entry per call), a valid
pattern still matches, and fs.grep('[') returns [] instead of throwing.
Diffstat (limited to 'modules/core')
| -rw-r--r-- | modules/core/core-bundle.js | 21 | ||||
| -rw-r--r-- | modules/core/module-fs.js | 11 | ||||
| -rw-r--r-- | modules/core/module-loader.js | 2 | ||||
| -rw-r--r-- | modules/core/virtual-fs.js | 10 |
4 files changed, 37 insertions, 7 deletions
diff --git a/modules/core/core-bundle.js b/modules/core/core-bundle.js index df4563d..a5e9a79 100644 --- a/modules/core/core-bundle.js +++ b/modules/core/core-bundle.js @@ -824,7 +824,10 @@ class VirtualFileSystem { dir = resolved.dir; } const results = []; - const regex = new RegExp(pattern, 'i'); + // v4.6.64: an invalid pattern must not throw into the error ledger (packet §8). + let regex; + try { regex = new RegExp(pattern, 'i'); } + catch (e) { this._lastPatternError = e.message; return []; } for (const name of Object.keys(dir.content)) { const fullPath = path ? path + '/' + name : name; if (regex.test(name)) { @@ -838,7 +841,10 @@ class VirtualFileSystem { } grep(pattern, path = '') { const results = []; - const regex = new RegExp(pattern, 'i'); + // v4.6.64: see find() above — a bad pattern is a result, not an exception. + let regex; + try { regex = new RegExp(pattern, 'i'); } + catch (e) { this._lastPatternError = e.message; return []; } const files = this.find('.', path).filter(e => e.type === 'file'); for (const file of files) { const content = this.readFile(file.path); @@ -6636,7 +6642,16 @@ class FileSystemModule { } const pattern = args[ai]; const target = args[ai + 1]; if (!pattern) return this.terminal.print('Usage: grep [-n] [-i] [-c] [-l] <pattern> [filename]', 'warning'); - const re = new RegExp(pattern, opt.ignoreCase ? 'i' : ''); + // v4.6.64: an invalid pattern is user input, not a system fault. It used to throw + // out of the command handler into the error ledger, polluting the counter that + // packet §2 says nobody can trust (packet §8). + let re; + try { + re = new RegExp(pattern, opt.ignoreCase ? 'i' : ''); + } catch (e) { + this.terminal.print('grep: invalid pattern: ' + pattern + ' (' + e.message + ')', 'warning'); + return; + } const hits = (line) => (opt.invert ? !re.test(line) : re.test(line)); if (target) { const c = this.terminal.fs.readFile(target); diff --git a/modules/core/module-fs.js b/modules/core/module-fs.js index fd1dfc1..415bd92 100644 --- a/modules/core/module-fs.js +++ b/modules/core/module-fs.js @@ -238,7 +238,16 @@ class FileSystemModule { } const pattern = args[ai]; const target = args[ai + 1]; if (!pattern) return this.terminal.print('Usage: grep [-n] [-i] [-c] [-l] <pattern> [filename]', 'warning'); - const re = new RegExp(pattern, opt.ignoreCase ? 'i' : ''); + // v4.6.64: an invalid pattern is user input, not a system fault. It used to throw + // out of the command handler into the error ledger, polluting the counter that + // packet §2 says nobody can trust (packet §8). + let re; + try { + re = new RegExp(pattern, opt.ignoreCase ? 'i' : ''); + } catch (e) { + this.terminal.print('grep: invalid pattern: ' + pattern + ' (' + e.message + ')', 'warning'); + return; + } const hits = (line) => (opt.invert ? !re.test(line) : re.test(line)); if (target) { const c = this.terminal.fs.readFile(target); diff --git a/modules/core/module-loader.js b/modules/core/module-loader.js index 5bf2a4c..abc1a86 100644 --- a/modules/core/module-loader.js +++ b/modules/core/module-loader.js @@ -4,7 +4,7 @@ // Core module bundle loaded synchronously in main.html. // This loader only handles version cache-busting, splash, terminal init, and optional ext modules. - const LATEST_VER = 'v4.6.63'; + const LATEST_VER = 'v4.6.64'; const CACHE = '?v=' + LATEST_VER; const stored = localStorage.getItem('webx11_cache_ver'); if (stored !== LATEST_VER) { diff --git a/modules/core/virtual-fs.js b/modules/core/virtual-fs.js index c9eb7a3..a52a393 100644 --- a/modules/core/virtual-fs.js +++ b/modules/core/virtual-fs.js @@ -822,7 +822,10 @@ class VirtualFileSystem { dir = resolved.dir; } const results = []; - const regex = new RegExp(pattern, 'i'); + // v4.6.64: an invalid pattern must not throw into the error ledger (packet §8). + let regex; + try { regex = new RegExp(pattern, 'i'); } + catch (e) { this._lastPatternError = e.message; return []; } for (const name of Object.keys(dir.content)) { const fullPath = path ? path + '/' + name : name; if (regex.test(name)) { @@ -836,7 +839,10 @@ class VirtualFileSystem { } grep(pattern, path = '') { const results = []; - const regex = new RegExp(pattern, 'i'); + // v4.6.64: see find() above — a bad pattern is a result, not an exception. + let regex; + try { regex = new RegExp(pattern, 'i'); } + catch (e) { this._lastPatternError = e.message; return []; } const files = this.find('.', path).filter(e => e.type === 'file'); for (const file of files) { const content = this.readFile(file.path); |