@ai-ecoverse/slicc-kernel 1.173.0 → 1.173.2

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.
@@ -7513,7 +7513,7 @@ var init_version = __esm({
7513
7513
  "src/version.ts"() {
7514
7514
  "use strict";
7515
7515
  init_captured_globals();
7516
- KERNEL_VERSION = true ? "1.173.0" : "0.0.0-dev";
7516
+ KERNEL_VERSION = true ? "1.173.2" : "0.0.0-dev";
7517
7517
  OS_RELEASE = "6.0.0-slicc";
7518
7518
  }
7519
7519
  });
@@ -7512,7 +7512,7 @@ var init_version = __esm({
7512
7512
  "src/version.ts"() {
7513
7513
  "use strict";
7514
7514
  init_captured_globals();
7515
- KERNEL_VERSION = true ? "1.173.0" : "0.0.0-dev";
7515
+ KERNEL_VERSION = true ? "1.173.2" : "0.0.0-dev";
7516
7516
  OS_RELEASE = "6.0.0-slicc";
7517
7517
  }
7518
7518
  });
package/dist/node.js CHANGED
@@ -3702,7 +3702,7 @@ function satisfies(version, range2) {
3702
3702
  }
3703
3703
 
3704
3704
  // src/version.ts
3705
- var KERNEL_VERSION = true ? "1.173.0" : "0.0.0-dev";
3705
+ var KERNEL_VERSION = true ? "1.173.2" : "0.0.0-dev";
3706
3706
  var OS_RELEASE = "6.0.0-slicc";
3707
3707
  function procVersion() {
3708
3708
  return `Linux version ${OS_RELEASE} (slicc-kernel ${KERNEL_VERSION}) #1 SMP PREEMPT_DYNAMIC
@@ -30649,7 +30649,20 @@ var RULE = new RegExp(
30649
30649
  );
30650
30650
  var TERM = /^[A-Za-z0-9._+-]+$/;
30651
30651
  var PLAIN3 = /^[A-Za-z0-9_@%+=:,./-]+$/;
30652
+ var CONTROL = /[\0-\x1f\x7f]/;
30652
30653
  var USAGE = "usage: sudo [-n] [-u user] [--] command [args...]\n sudo -l";
30654
+ function hasControl(text) {
30655
+ return CONTROL.test(text);
30656
+ }
30657
+ function withoutControl(text) {
30658
+ return text.replace(CONTROL, (ch) => {
30659
+ const n = ch.charCodeAt(0);
30660
+ if (n === 9) return "\\t";
30661
+ if (n === 10) return "\\n";
30662
+ if (n === 13) return "\\r";
30663
+ return `\\x${n.toString(16).padStart(2, "0")}`;
30664
+ });
30665
+ }
30653
30666
  function failed3(errno3, error) {
30654
30667
  return { error, errno: errno3 };
30655
30668
  }
@@ -30675,7 +30688,106 @@ function splitWords(text) {
30675
30688
  return words2;
30676
30689
  }
30677
30690
  function quoteWord(word) {
30678
- return PLAIN3.test(word) ? word : `'${word.replaceAll("'", `'\\''`)}'`;
30691
+ const text = hasControl(word) ? withoutControl(word) : word;
30692
+ return PLAIN3.test(text) ? text : `'${text.replaceAll("'", `'\\''`)}'`;
30693
+ }
30694
+ function addPart(word, part) {
30695
+ const last = word.length - 1;
30696
+ if (part === null) {
30697
+ if (word[last] !== null) word.push(null);
30698
+ } else if (typeof word[last] === "string") word[last] += part;
30699
+ else word.push(part);
30700
+ }
30701
+ function addPlain(word, plain3) {
30702
+ for (const [i, part] of plain3.split("*").entries()) {
30703
+ if (i > 0) addPart(word, null);
30704
+ if (part !== "") addPart(word, part);
30705
+ }
30706
+ }
30707
+ function splitPatterns(text) {
30708
+ const piece = /'([^']*)'|"((?:[^"\\]|\\[\s\S])*)"|\\([\s\S])|([^\s'"\\]+)|(\s+)/y;
30709
+ const words2 = [];
30710
+ let word;
30711
+ while (piece.lastIndex < text.length) {
30712
+ const m = piece.exec(text);
30713
+ if (!m) return void 0;
30714
+ const [, single, double, escaped, plain3, space] = m;
30715
+ if (space !== void 0) {
30716
+ if (word !== void 0) words2.push(word);
30717
+ word = void 0;
30718
+ continue;
30719
+ }
30720
+ word ??= [];
30721
+ if (plain3 !== void 0) addPlain(word, plain3);
30722
+ else addPart(word, single ?? (double !== void 0 ? unescaped(double) : escaped));
30723
+ }
30724
+ if (word !== void 0) words2.push(word);
30725
+ return words2;
30726
+ }
30727
+ var literal2 = (pattern) => pattern.map((p) => p ?? "*").join("");
30728
+ var isAny = (pattern) => pattern?.length === 1 && pattern[0] === null;
30729
+ function literalWord(word) {
30730
+ if (!word.includes("*")) return quoteWord(word);
30731
+ const bare = word.replaceAll("*", "");
30732
+ return bare === "" || PLAIN3.test(bare) ? word.replaceAll("*", "\\*") : quoteWord(word);
30733
+ }
30734
+ function patternWord(pattern) {
30735
+ if (pattern.length === 1 && typeof pattern[0] === "string") return literalWord(pattern[0]);
30736
+ return pattern.map((p) => p === null ? "*" : literalWord(p)).join("");
30737
+ }
30738
+ function globMatch(items, subjects, star, one) {
30739
+ let i = 0;
30740
+ let j = 0;
30741
+ let back = -1;
30742
+ let from = 0;
30743
+ while (j < subjects) {
30744
+ if (i < items && star(i)) {
30745
+ back = i++;
30746
+ from = j;
30747
+ } else if (i < items && one(i, j)) {
30748
+ i++;
30749
+ j++;
30750
+ } else if (back >= 0) {
30751
+ i = back + 1;
30752
+ j = ++from;
30753
+ } else return false;
30754
+ }
30755
+ while (i < items && star(i)) i++;
30756
+ return i === items;
30757
+ }
30758
+ function wordMatch(pattern, arg) {
30759
+ if (pattern.every((p) => p !== null)) return literal2(pattern) === arg;
30760
+ const chars = pattern.flatMap((p) => p === null ? [null] : [...p]);
30761
+ const subject = [...arg];
30762
+ return globMatch(
30763
+ chars.length,
30764
+ subject.length,
30765
+ (i) => chars[i] === null,
30766
+ (i, j) => chars[i] === subject[j]
30767
+ );
30768
+ }
30769
+ function commandMatches(cmnd, argv) {
30770
+ if (cmnd === "*") return true;
30771
+ const [path, ...args] = argv;
30772
+ if (path !== cmnd.path) return false;
30773
+ const want = cmnd.args;
30774
+ if (want === void 0) return true;
30775
+ return globMatch(
30776
+ want.length,
30777
+ args.length,
30778
+ (i) => isAny(want[i]),
30779
+ (i, j) => wordMatch(want[i], args[j])
30780
+ );
30781
+ }
30782
+ function commandText(cmnd) {
30783
+ const path = quoteWord(cmnd.path);
30784
+ if (cmnd.args === void 0) return path;
30785
+ if (cmnd.args.length === 0) return `${path} ""`;
30786
+ return [path, ...cmnd.args.map(patternWord)].join(" ");
30787
+ }
30788
+ function recordedCommand(argv) {
30789
+ const [path = "", ...args] = argv;
30790
+ return commandText({ path, args: args.map((a) => [a]) });
30679
30791
  }
30680
30792
  function validWho(who) {
30681
30793
  if (who === "ALL") return true;
@@ -30697,9 +30809,23 @@ function parseRule(line) {
30697
30809
  if (cwd === "") return void 0;
30698
30810
  const rule = { nopasswd: !!nopasswd, who, target, ...cwd !== void 0 ? { cwd } : {} };
30699
30811
  if (rest2.trim() === "*") return { ...rule, cmnd: "*" };
30700
- const cmnd = splitWords(rest2);
30701
- if (!cmnd?.[0]?.startsWith("/")) return void 0;
30702
- return { ...rule, cmnd };
30812
+ const words2 = splitPatterns(rest2);
30813
+ const [first, ...args] = words2 ?? [];
30814
+ const path = first ? literal2(first) : "";
30815
+ if (!path.startsWith("/")) return void 0;
30816
+ const only = args.length === 1 && args[0]?.length === 1 && args[0][0] === "";
30817
+ if (only && /\s""$/.test(rest2.trim())) return { ...rule, cmnd: { path, args: [] } };
30818
+ return { ...rule, cmnd: args.length === 0 ? { path } : { path, args } };
30819
+ }
30820
+ function recordedBare(line, file, rule) {
30821
+ if (rule.cmnd === "*" || rule.cmnd.args !== void 0 || !rule.nopasswd) return false;
30822
+ if (file !== `${SUDOERS_D}/${rule.who}` || !NAME3.test(rule.who) || !NAME3.test(rule.target)) {
30823
+ return false;
30824
+ }
30825
+ const head = `NOPASSWD ${rule.who} (${rule.target}) `;
30826
+ const cmnd = `Cmnd ${quoteWord(rule.cmnd.path)}`;
30827
+ const cwd = rule.cwd === void 0 ? "" : `Cwd ${quoteWord(rule.cwd)} `;
30828
+ return line.trimEnd() === `${head}${cwd}${cmnd}`;
30703
30829
  }
30704
30830
  function flags(parsed2, arg, next3) {
30705
30831
  for (let j = 1; j < arg.length; j++) {
@@ -30737,7 +30863,7 @@ function parseArgs(args) {
30737
30863
  return parsed2;
30738
30864
  }
30739
30865
  function described(rule) {
30740
- const cmnd = rule.cmnd === "*" ? "ALL" : rule.cmnd.map(quoteWord).join(" ");
30866
+ const cmnd = rule.cmnd === "*" ? "ALL" : commandText(rule.cmnd);
30741
30867
  const cwd = rule.cwd === void 0 ? "" : `CWD=${quoteWord(rule.cwd)} `;
30742
30868
  return ` (${rule.target}) ${cwd}${rule.nopasswd ? "NOPASSWD: " : ""}${cmnd}`;
30743
30869
  }
@@ -30783,7 +30909,9 @@ var Sudo = class {
30783
30909
  const rules = [];
30784
30910
  for (const [n, line] of text.split("\n").entries()) {
30785
30911
  const rule = parseRule(line);
30786
- if (rule) rules.push(rule);
30912
+ if (rule && recordedBare(line, path, rule) && rule.cmnd !== "*") {
30913
+ rules.push({ ...rule, cmnd: { path: rule.cmnd.path, args: [] } });
30914
+ } else if (rule) rules.push(rule);
30787
30915
  else if (rule === void 0) this.warn(`sudo: ${path}:${n + 1}: bad line skipped: ${line}`);
30788
30916
  }
30789
30917
  return rules;
@@ -30879,7 +31007,7 @@ var Sudo = class {
30879
31007
  if (untrusted2) return untrusted2;
30880
31008
  const argv = [path, ...args];
30881
31009
  const matching = rules.filter(
30882
- (rule) => applies(rule) && (rule.target === "ALL" || rule.target === target.name) && (rule.cwd === void 0 || rule.cwd === cwd) && (rule.cmnd === "*" || rule.cmnd.length === argv.length && rule.cmnd.every((w, i) => w === argv[i]))
31010
+ (rule) => applies(rule) && (rule.target === "ALL" || rule.target === target.name) && (rule.cwd === void 0 || rule.cwd === cwd) && commandMatches(rule.cmnd, argv)
30883
31011
  );
30884
31012
  const grant = () => this.grant(self, target, cred, parsed2.command, path, cwd, call.term);
30885
31013
  if (root || matching.some((rule) => rule.nopasswd)) return grant();
@@ -30970,13 +31098,14 @@ ${lines2}
30970
31098
  const { fs } = this.o;
30971
31099
  const path = `${SUDOERS_D}/${self.name}`;
30972
31100
  if (!NAME3.test(self.name)) return false;
31101
+ if (hasControl(cwd) || argv.some(hasControl)) return false;
30973
31102
  try {
30974
31103
  await this.provision();
30975
31104
  if (!await this.trusted(SUDOERS_D)) return false;
30976
31105
  const st = await fs.lstat(path).catch(() => void 0);
30977
31106
  if (st && !await this.trusted(path)) return false;
30978
31107
  const old = st ? await fs.readFile(path) : "";
30979
- const words2 = argv.map(quoteWord).join(" ");
31108
+ const words2 = recordedCommand(argv);
30980
31109
  const line = `NOPASSWD ${self.name} (${target.name}) Cwd ${quoteWord(cwd)} Cmnd ${words2}
30981
31110
  `;
30982
31111
  const text = old === "" || old.endsWith("\n") ? `${old}${line}` : `${old}