@ngockhoale/ukit 3.4.18 → 3.4.19
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,13 @@
|
|
|
2
2
|
|
|
3
3
|
All notable changes to UKit are documented here.
|
|
4
4
|
|
|
5
|
+
## 3.4.19 - 2026-10-06
|
|
6
|
+
|
|
7
|
+
**Create-scope guard: more read-only shell false positives removed (found by replaying 4vn's real blocked commands).**
|
|
8
|
+
`2>/dev/null;` / `2>/dev/null|` (operator glued to the redirect target) was read as a write to a file
|
|
9
|
+
named `/dev/null;`; commands after shell keywords (`for ...; do jq ...`, `then`, `else`, `while`) skipped the
|
|
10
|
+
read-only interpreter mask. Real writes (`>src/a.js;`, write APIs) still block. Test 14 in createScopeGuard.
|
|
11
|
+
|
|
5
12
|
## 3.4.18 - 2026-10-06
|
|
6
13
|
|
|
7
14
|
**Stops the token-burning respawn loop at its source.**
|
package/package.json
CHANGED
|
@@ -407,7 +407,7 @@ const SCRIPT_WRITE_API = new RegExp([
|
|
|
407
407
|
function firstWord(text) {
|
|
408
408
|
const words = text.trim().split(/\s+/);
|
|
409
409
|
let i = 0;
|
|
410
|
-
while (i < words.length && (/^[A-Za-z_]\w*=/.test(words[i]) || /^(?:sudo|time|nohup|command|exec)$/.test(words[i]))) i += 1;
|
|
410
|
+
while (i < words.length && (/^[A-Za-z_]\w*=/.test(words[i]) || /^(?:sudo|time|nohup|command|exec|do|then|else|elif|if|while|until|!|\{|\()$/.test(words[i]))) i += 1;
|
|
411
411
|
return (words[i] || '').replace(/^.*\//, '');
|
|
412
412
|
}
|
|
413
413
|
function splitShellSegments(command) {
|
|
@@ -488,7 +488,8 @@ function shellWriteHit(rawCommand) {
|
|
|
488
488
|
// Redirect (optionally fd-numbered: `1>f`, `3>f`, `&>f`, `>&f`) to anything but /dev/null.
|
|
489
489
|
// fd duplication (`2>&1`, `>&2`, `>&-`) is excluded by the `(?!&)` target shape.
|
|
490
490
|
for (const m of command.matchAll(/(^|[^>])&?>{1,2}\s*(?:&(?![0-9-]))?((?!&)\S+)/g)) {
|
|
491
|
-
|
|
491
|
+
// `2>/dev/null;` / `2>/dev/null|` / `2>/dev/null)` glue the shell operator onto the target token.
|
|
492
|
+
if (!['/dev/null', '/dev/stdout', '/dev/stderr'].includes(m[2].replace(/[;&|)]+$/, ''))) return true;
|
|
492
493
|
}
|
|
493
494
|
return SHELL_WRITE_PATTERNS.some((re) => re.test(command));
|
|
494
495
|
}
|