musubix2 0.5.37 → 0.5.38

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.
@@ -1 +1 @@
1
- {"generator":"musubix2","version":"0.5.37","timestamp":"2026-07-09T23:55:01.391Z"}
1
+ {"generator":"musubix2","version":"0.5.38","timestamp":"2026-07-10T00:04:27.184Z"}
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "version": "1.0",
3
- "generatedAt": "2026-07-09T23:55:01.426Z",
3
+ "generatedAt": "2026-07-10T00:04:27.214Z",
4
4
  "entries": [
5
5
  {
6
6
  "platform": "copilot",
package/dist/cli.js CHANGED
@@ -8699,7 +8699,7 @@ var init_dist5 = __esm({
8699
8699
  return runPatterns(this.patterns, blankNonCode(code, hashComments), filePath, code);
8700
8700
  }
8701
8701
  };
8702
- TaintDataflowAnalyzer = class {
8702
+ TaintDataflowAnalyzer = class _TaintDataflowAnalyzer {
8703
8703
  sinks = [
8704
8704
  {
8705
8705
  re: /\b(?:execute|executemany|query|raw|prepare)\s*\(\s*(\$?\w+)\s*[,)]/g,
@@ -8742,9 +8742,17 @@ var init_dist5 = __esm({
8742
8742
  suggestion: "Never eval built strings; use a safe parser/dispatch table."
8743
8743
  }
8744
8744
  ];
8745
+ /**
8746
+ * Known escaping / quoting / casting helpers. When the dynamic part of a
8747
+ * built string passes through one of these, the value is treated as
8748
+ * sanitized and not tainted (e.g. `"ls " + shlex.quote(x)`, `"…%d" % int(n)`).
8749
+ */
8750
+ static SANITIZERS = /\b(?:shlex\.quote|pipes\.quote|escapeshellarg|escapeshellcmd|mysqli_real_escape_string|real_escape_string|pg_escape_(?:string|literal|identifier)|quote_ident(?:ifier)?|re\.escape|html\.escape|htmlspecialchars|htmlentities|int|float|Number|parseInt|parseFloat|Integer\.parseInt)\s*\(/;
8745
8751
  isDynamicRhs(rhs) {
8746
8752
  if (/^\s*\[/.test(rhs))
8747
8753
  return false;
8754
+ if (_TaintDataflowAnalyzer.SANITIZERS.test(rhs))
8755
+ return false;
8748
8756
  return /\.\s*format\s*\(/.test(rhs) || // "…".format(x)
8749
8757
  /\bf['"]/.test(rhs) || // f-string
8750
8758
  /['"]\s*%\s*[\w([]/.test(rhs) || // "…" % x
@@ -8768,7 +8776,7 @@ var init_dist5 = __esm({
8768
8776
  if (tainted.has(name))
8769
8777
  return;
8770
8778
  let taint = this.isDynamicRhs(rhs);
8771
- if (!taint) {
8779
+ if (!taint && !_TaintDataflowAnalyzer.SANITIZERS.test(rhs)) {
8772
8780
  for (const t of tainted.keys()) {
8773
8781
  if (t !== name && new RegExp(`(?<![\\w$])${escapeRe(t)}(?![\\w])`).test(rhs) && /[+%]|\.\s*format|f['"]/.test(rhs)) {
8774
8782
  taint = true;
package/dist/index.js CHANGED
@@ -8699,7 +8699,7 @@ var init_dist5 = __esm({
8699
8699
  return runPatterns(this.patterns, blankNonCode(code, hashComments), filePath, code);
8700
8700
  }
8701
8701
  };
8702
- TaintDataflowAnalyzer = class {
8702
+ TaintDataflowAnalyzer = class _TaintDataflowAnalyzer {
8703
8703
  sinks = [
8704
8704
  {
8705
8705
  re: /\b(?:execute|executemany|query|raw|prepare)\s*\(\s*(\$?\w+)\s*[,)]/g,
@@ -8742,9 +8742,17 @@ var init_dist5 = __esm({
8742
8742
  suggestion: "Never eval built strings; use a safe parser/dispatch table."
8743
8743
  }
8744
8744
  ];
8745
+ /**
8746
+ * Known escaping / quoting / casting helpers. When the dynamic part of a
8747
+ * built string passes through one of these, the value is treated as
8748
+ * sanitized and not tainted (e.g. `"ls " + shlex.quote(x)`, `"…%d" % int(n)`).
8749
+ */
8750
+ static SANITIZERS = /\b(?:shlex\.quote|pipes\.quote|escapeshellarg|escapeshellcmd|mysqli_real_escape_string|real_escape_string|pg_escape_(?:string|literal|identifier)|quote_ident(?:ifier)?|re\.escape|html\.escape|htmlspecialchars|htmlentities|int|float|Number|parseInt|parseFloat|Integer\.parseInt)\s*\(/;
8745
8751
  isDynamicRhs(rhs) {
8746
8752
  if (/^\s*\[/.test(rhs))
8747
8753
  return false;
8754
+ if (_TaintDataflowAnalyzer.SANITIZERS.test(rhs))
8755
+ return false;
8748
8756
  return /\.\s*format\s*\(/.test(rhs) || // "…".format(x)
8749
8757
  /\bf['"]/.test(rhs) || // f-string
8750
8758
  /['"]\s*%\s*[\w([]/.test(rhs) || // "…" % x
@@ -8768,7 +8776,7 @@ var init_dist5 = __esm({
8768
8776
  if (tainted.has(name))
8769
8777
  return;
8770
8778
  let taint = this.isDynamicRhs(rhs);
8771
- if (!taint) {
8779
+ if (!taint && !_TaintDataflowAnalyzer.SANITIZERS.test(rhs)) {
8772
8780
  for (const t of tainted.keys()) {
8773
8781
  if (t !== name && new RegExp(`(?<![\\w$])${escapeRe(t)}(?![\\w])`).test(rhs) && /[+%]|\.\s*format|f['"]/.test(rhs)) {
8774
8782
  taint = true;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "musubix2",
3
- "version": "0.5.37",
3
+ "version": "0.5.38",
4
4
  "description": "MUSUBIX2 — Specification Driven Development System",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",