circle-ir 3.27.1 → 3.29.0

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.
@@ -3997,6 +3997,7 @@ var parserInitialized = false;
3997
3997
  var parserInitializing = null;
3998
3998
  var loadedLanguages = /* @__PURE__ */ new Map();
3999
3999
  var loadingLanguages = /* @__PURE__ */ new Map();
4000
+ var cachedParsers = /* @__PURE__ */ new Map();
4000
4001
  var configuredLanguagePaths = {};
4001
4002
  var configuredLanguageModules = {};
4002
4003
  async function initParser(options = {}) {
@@ -4066,9 +4067,14 @@ async function loadLanguage(language, wasmPath) {
4066
4067
  return loadPromise;
4067
4068
  }
4068
4069
  async function createParser(language) {
4070
+ const cached = cachedParsers.get(language);
4071
+ if (cached) {
4072
+ return cached;
4073
+ }
4069
4074
  const lang = await loadLanguage(language);
4070
4075
  const parser = new Parser();
4071
4076
  parser.setLanguage(lang);
4077
+ cachedParsers.set(language, parser);
4072
4078
  return parser;
4073
4079
  }
4074
4080
  async function parse(code, language) {
@@ -4165,9 +4171,19 @@ function isLanguageLoaded(language) {
4165
4171
  return loadedLanguages.has(language);
4166
4172
  }
4167
4173
  function resetParser() {
4168
- parserInitialized = false;
4174
+ for (const parser of cachedParsers.values()) {
4175
+ try {
4176
+ parser.delete();
4177
+ } catch {
4178
+ }
4179
+ }
4180
+ cachedParsers.clear();
4169
4181
  loadedLanguages.clear();
4182
+ loadingLanguages.clear();
4170
4183
  configuredLanguagePaths = {};
4184
+ configuredLanguageModules = {};
4185
+ parserInitialized = false;
4186
+ parserInitializing = null;
4171
4187
  }
4172
4188
 
4173
4189
  // src/core/extractors/meta.ts
@@ -10033,7 +10049,9 @@ var DEFAULT_SINKS = [
10033
10049
  { method: "ProcessBuilder", class: "constructor", type: "command_injection", cwe: "CWE-78", severity: "critical", arg_positions: [0] },
10034
10050
  { method: "command", class: "ProcessBuilder", type: "command_injection", cwe: "CWE-78", severity: "critical", arg_positions: [0] },
10035
10051
  // Commons Exec
10036
- { method: "execute", class: "Executor", type: "command_injection", cwe: "CWE-78", severity: "critical", arg_positions: [0] },
10052
+ // Note: bare class 'Executor' removed it collided with java.util.concurrent.Executor
10053
+ // (Executor.execute(Runnable) is not command injection). Apache Commons Exec users
10054
+ // typically declare DefaultExecutor explicitly, so we match that instead. See issue #14.
10037
10055
  { method: "execute", class: "DefaultExecutor", type: "command_injection", cwe: "CWE-78", severity: "critical", arg_positions: [0] },
10038
10056
  { method: "CommandLine", class: "constructor", type: "command_injection", cwe: "CWE-78", severity: "critical", arg_positions: [0] },
10039
10057
  { method: "parse", class: "CommandLine", type: "command_injection", cwe: "CWE-78", severity: "critical", arg_positions: [0] },
@@ -10101,8 +10119,8 @@ var DEFAULT_SINKS = [
10101
10119
  { method: "popen", type: "command_injection", cwe: "CWE-78", severity: "critical", arg_positions: [0] },
10102
10120
  { method: "system", type: "command_injection", cwe: "CWE-78", severity: "critical", arg_positions: [0] },
10103
10121
  // Apache Commons Exec
10104
- { method: "execute", class: "Executor", type: "command_injection", cwe: "CWE-78", severity: "critical", arg_positions: [0] },
10105
- { method: "setCommandline", class: "Executor", type: "command_injection", cwe: "CWE-78", severity: "critical", arg_positions: [0] },
10122
+ // Note: bare class 'Executor' removed (see comment above) DefaultExecutor matched explicitly.
10123
+ { method: "setCommandline", class: "DefaultExecutor", type: "command_injection", cwe: "CWE-78", severity: "critical", arg_positions: [0] },
10106
10124
  { method: "parse", class: "CommandLine", type: "command_injection", cwe: "CWE-78", severity: "critical", arg_positions: [0] },
10107
10125
  { method: "addArgument", class: "CommandLine", type: "command_injection", cwe: "CWE-78", severity: "critical", arg_positions: [0] },
10108
10126
  // Process-related utilities
@@ -10111,7 +10129,10 @@ var DEFAULT_SINKS = [
10111
10129
  { method: "redirectOutput", class: "ProcessBuilder", type: "command_injection", cwe: "CWE-78", severity: "medium", arg_positions: [0] },
10112
10130
  { method: "redirectInput", class: "ProcessBuilder", type: "command_injection", cwe: "CWE-78", severity: "medium", arg_positions: [0] },
10113
10131
  // Path Traversal (CWE-22)
10114
- { method: "File", class: "constructor", type: "path_traversal", cwe: "CWE-22", severity: "high", arg_positions: [0] },
10132
+ // File: covers both File(String pathname) and File(parent, child). The 2-arg
10133
+ // overload's child argument carries CVE-2018-8041 (Camel mail Content-Disposition
10134
+ // filename written to disk).
10135
+ { method: "File", class: "constructor", type: "path_traversal", cwe: "CWE-22", severity: "high", arg_positions: [0, 1] },
10115
10136
  { method: "FileInputStream", class: "constructor", type: "path_traversal", cwe: "CWE-22", severity: "high", arg_positions: [0] },
10116
10137
  { method: "FileOutputStream", class: "constructor", type: "path_traversal", cwe: "CWE-22", severity: "high", arg_positions: [0] },
10117
10138
  { method: "FileReader", class: "constructor", type: "path_traversal", cwe: "CWE-22", severity: "high", arg_positions: [0] },
@@ -10724,11 +10745,14 @@ var DEFAULT_SINKS = [
10724
10745
  { method: "spawn", class: "child_process", type: "command_injection", cwe: "CWE-78", severity: "critical", arg_positions: [0] },
10725
10746
  { method: "spawnSync", class: "child_process", type: "command_injection", cwe: "CWE-78", severity: "critical", arg_positions: [0] },
10726
10747
  // Also match without receiver (destructured imports: const { exec } = require('child_process'))
10748
+ // `exec` is intentionally classless: catches Node.js child_process.exec AND
10749
+ // Java Runtime.exec (via `r.exec()` where heuristic can't resolve r → Runtime).
10727
10750
  { method: "exec", type: "command_injection", cwe: "CWE-78", severity: "high", arg_positions: [0] },
10728
- { method: "execSync", type: "command_injection", cwe: "CWE-78", severity: "high", arg_positions: [0] },
10729
- { method: "spawn", type: "command_injection", cwe: "CWE-78", severity: "high", arg_positions: [0] },
10730
- { method: "spawnSync", type: "command_injection", cwe: "CWE-78", severity: "high", arg_positions: [0] },
10731
- { method: "execFile", type: "command_injection", cwe: "CWE-78", severity: "high", arg_positions: [0] },
10751
+ // `execSync`/`spawn`/`spawnSync`/`execFile` are Node-specific language-scope them.
10752
+ { method: "execSync", type: "command_injection", cwe: "CWE-78", severity: "high", arg_positions: [0], languages: ["javascript", "typescript"] },
10753
+ { method: "spawn", type: "command_injection", cwe: "CWE-78", severity: "high", arg_positions: [0], languages: ["javascript", "typescript"] },
10754
+ { method: "spawnSync", type: "command_injection", cwe: "CWE-78", severity: "high", arg_positions: [0], languages: ["javascript", "typescript"] },
10755
+ { method: "execFile", type: "command_injection", cwe: "CWE-78", severity: "high", arg_positions: [0], languages: ["javascript", "typescript"] },
10732
10756
  // Node.js File System (path traversal)
10733
10757
  { method: "readFile", class: "fs", type: "path_traversal", cwe: "CWE-22", severity: "critical", arg_positions: [0] },
10734
10758
  { method: "readFileSync", class: "fs", type: "path_traversal", cwe: "CWE-22", severity: "critical", arg_positions: [0] },
@@ -10741,12 +10765,15 @@ var DEFAULT_SINKS = [
10741
10765
  { method: "createReadStream", class: "fs", type: "path_traversal", cwe: "CWE-22", severity: "critical", arg_positions: [0] },
10742
10766
  { method: "createWriteStream", class: "fs", type: "path_traversal", cwe: "CWE-22", severity: "critical", arg_positions: [0] },
10743
10767
  // Node.js SQL (mysql, pg, sqlite, etc.)
10744
- { method: "query", class: "Connection", type: "sql_injection", cwe: "CWE-89", severity: "critical", arg_positions: [0] },
10745
- { method: "query", class: "Pool", type: "sql_injection", cwe: "CWE-89", severity: "critical", arg_positions: [0] },
10746
- { method: "query", class: "Client", type: "sql_injection", cwe: "CWE-89", severity: "critical", arg_positions: [0] },
10768
+ // Language-scoped: generic class names `Pool`/`Connection`/`Client` substring-match
10769
+ // unrelated Java identifiers like `cachedThreadPool`, `dbConnection`. See issue #14.
10770
+ { method: "query", class: "Connection", type: "sql_injection", cwe: "CWE-89", severity: "critical", arg_positions: [0], languages: ["javascript", "typescript"] },
10771
+ { method: "query", class: "Pool", type: "sql_injection", cwe: "CWE-89", severity: "critical", arg_positions: [0], languages: ["javascript", "typescript"] },
10772
+ { method: "query", class: "Client", type: "sql_injection", cwe: "CWE-89", severity: "critical", arg_positions: [0], languages: ["javascript", "typescript"] },
10747
10773
  // Note: classless { method: 'query' } removed — too many FPs (UriComponentsBuilder.query(), etc.)
10748
10774
  // SQL query calls are covered by class-specific patterns above (Connection, Pool, Client, JdbcTemplate)
10749
- { method: "raw", type: "sql_injection", cwe: "CWE-89", severity: "high", arg_positions: [0] },
10775
+ // Note: `raw` is shared with Python (Django ORM) scoped to JS+TS to avoid leaking.
10776
+ { method: "raw", type: "sql_injection", cwe: "CWE-89", severity: "high", arg_positions: [0], languages: ["javascript", "typescript"] },
10750
10777
  // Browser DOM XSS sinks
10751
10778
  { method: "setAttribute", type: "xss", cwe: "CWE-79", severity: "high", arg_positions: [1] },
10752
10779
  // Express.js XSS (response methods)
@@ -10756,7 +10783,7 @@ var DEFAULT_SINKS = [
10756
10783
  { method: "html", class: "Response", type: "xss", cwe: "CWE-79", severity: "high", arg_positions: [0] },
10757
10784
  { method: "render", class: "Response", type: "xss", cwe: "CWE-79", severity: "medium", arg_positions: [1] },
10758
10785
  // Node.js Code Injection (eval, vm, etc.)
10759
- { method: "eval", type: "code_injection", cwe: "CWE-94", severity: "critical", arg_positions: [0] },
10786
+ { method: "eval", type: "code_injection", cwe: "CWE-94", severity: "critical", arg_positions: [0], languages: ["javascript", "typescript"] },
10760
10787
  { method: "Function", class: "constructor", type: "code_injection", cwe: "CWE-94", severity: "critical", arg_positions: [0] },
10761
10788
  { method: "runInContext", class: "vm", type: "code_injection", cwe: "CWE-94", severity: "critical", arg_positions: [0] },
10762
10789
  { method: "runInNewContext", class: "vm", type: "code_injection", cwe: "CWE-94", severity: "critical", arg_positions: [0] },
@@ -10772,7 +10799,7 @@ var DEFAULT_SINKS = [
10772
10799
  { method: "get", class: "axios", type: "ssrf", cwe: "CWE-918", severity: "high", arg_positions: [0] },
10773
10800
  { method: "post", class: "axios", type: "ssrf", cwe: "CWE-918", severity: "high", arg_positions: [0] },
10774
10801
  { method: "request", class: "axios", type: "ssrf", cwe: "CWE-918", severity: "high", arg_positions: [0] },
10775
- { method: "fetch", type: "ssrf", cwe: "CWE-918", severity: "high", arg_positions: [0] },
10802
+ { method: "fetch", type: "ssrf", cwe: "CWE-918", severity: "high", arg_positions: [0], languages: ["javascript", "typescript"] },
10776
10803
  { method: "request", class: "http", type: "ssrf", cwe: "CWE-918", severity: "high", arg_positions: [0] },
10777
10804
  { method: "get", class: "http", type: "ssrf", cwe: "CWE-918", severity: "high", arg_positions: [0] },
10778
10805
  { method: "request", class: "https", type: "ssrf", cwe: "CWE-918", severity: "high", arg_positions: [0] },
@@ -10801,10 +10828,12 @@ var DEFAULT_SINKS = [
10801
10828
  { method: "check_call", class: "subprocess", type: "command_injection", cwe: "CWE-78", severity: "critical", arg_positions: [0] },
10802
10829
  { method: "Popen", class: "subprocess", type: "command_injection", cwe: "CWE-78", severity: "critical", arg_positions: [0] },
10803
10830
  // Python Code Injection
10804
- { method: "eval", type: "code_injection", cwe: "CWE-94", severity: "critical", arg_positions: [0] },
10805
- { method: "exec", type: "code_injection", cwe: "CWE-94", severity: "critical", arg_positions: [0] },
10806
- { method: "compile", type: "code_injection", cwe: "CWE-94", severity: "high", arg_positions: [0] },
10807
- { method: "__import__", type: "code_injection", cwe: "CWE-94", severity: "high", arg_positions: [0] },
10831
+ // Language-scoped: classless `exec`/`eval`/`compile` collide with Java/JS builtins
10832
+ // and Java util.concurrent (e.g. Executor.execute / future.compile).
10833
+ { method: "eval", type: "code_injection", cwe: "CWE-94", severity: "critical", arg_positions: [0], languages: ["python"] },
10834
+ { method: "exec", type: "code_injection", cwe: "CWE-94", severity: "critical", arg_positions: [0], languages: ["python"] },
10835
+ { method: "compile", type: "code_injection", cwe: "CWE-94", severity: "high", arg_positions: [0], languages: ["python"] },
10836
+ { method: "__import__", type: "code_injection", cwe: "CWE-94", severity: "high", arg_positions: [0], languages: ["python"] },
10808
10837
  // Python Deserialization
10809
10838
  { method: "loads", class: "pickle", type: "deserialization", cwe: "CWE-502", severity: "critical", arg_positions: [0] },
10810
10839
  { method: "load", class: "pickle", type: "deserialization", cwe: "CWE-502", severity: "critical", arg_positions: [0] },
@@ -10812,36 +10841,39 @@ var DEFAULT_SINKS = [
10812
10841
  { method: "load", class: "yaml", type: "deserialization", cwe: "CWE-502", severity: "critical", arg_positions: [0] },
10813
10842
  { method: "loads", class: "yaml", type: "deserialization", cwe: "CWE-502", severity: "critical", arg_positions: [0] },
10814
10843
  // Python SQL Injection
10815
- { method: "execute", type: "sql_injection", cwe: "CWE-89", severity: "critical", arg_positions: [0] },
10816
- { method: "executemany", type: "sql_injection", cwe: "CWE-89", severity: "critical", arg_positions: [0] },
10817
- { method: "raw", type: "sql_injection", cwe: "CWE-89", severity: "critical", arg_positions: [0] },
10818
- { method: "extra", type: "sql_injection", cwe: "CWE-89", severity: "high", arg_positions: [0] },
10844
+ // Language-scoped: classless `execute`/`raw` collide with Java util.concurrent
10845
+ // (Executor.execute, ThreadPool.execute) and other languages. See issue #14.
10846
+ { method: "execute", type: "sql_injection", cwe: "CWE-89", severity: "critical", arg_positions: [0], languages: ["python"] },
10847
+ { method: "executemany", type: "sql_injection", cwe: "CWE-89", severity: "critical", arg_positions: [0], languages: ["python"] },
10848
+ { method: "raw", type: "sql_injection", cwe: "CWE-89", severity: "critical", arg_positions: [0], languages: ["python"] },
10849
+ { method: "extra", type: "sql_injection", cwe: "CWE-89", severity: "high", arg_positions: [0], languages: ["python"] },
10819
10850
  // Python Path Traversal
10820
- { method: "open", type: "path_traversal", cwe: "CWE-22", severity: "high", arg_positions: [0] },
10851
+ // Language-scoped: classless `open` collides with Java I/O / JS DOM.
10852
+ { method: "open", type: "path_traversal", cwe: "CWE-22", severity: "high", arg_positions: [0], languages: ["python"] },
10821
10853
  { method: "remove", class: "os", type: "path_traversal", cwe: "CWE-22", severity: "high", arg_positions: [0] },
10822
10854
  { method: "unlink", class: "os", type: "path_traversal", cwe: "CWE-22", severity: "high", arg_positions: [0] },
10823
10855
  { method: "rmdir", class: "os", type: "path_traversal", cwe: "CWE-22", severity: "high", arg_positions: [0] },
10824
10856
  { method: "rmtree", class: "shutil", type: "path_traversal", cwe: "CWE-22", severity: "critical", arg_positions: [0] },
10825
- { method: "send_file", type: "path_traversal", cwe: "CWE-22", severity: "high", arg_positions: [0] },
10857
+ { method: "send_file", type: "path_traversal", cwe: "CWE-22", severity: "high", arg_positions: [0], languages: ["python"] },
10826
10858
  // Python XSS / SSTI
10827
- { method: "render_template_string", type: "xss", cwe: "CWE-79", severity: "high", arg_positions: [0] },
10828
- { method: "Markup", type: "xss", cwe: "CWE-79", severity: "high", arg_positions: [0] },
10829
- { method: "mark_safe", type: "xss", cwe: "CWE-79", severity: "high", arg_positions: [0] },
10859
+ { method: "render_template_string", type: "xss", cwe: "CWE-79", severity: "high", arg_positions: [0], languages: ["python"] },
10860
+ { method: "Markup", type: "xss", cwe: "CWE-79", severity: "high", arg_positions: [0], languages: ["python"] },
10861
+ { method: "mark_safe", type: "xss", cwe: "CWE-79", severity: "high", arg_positions: [0], languages: ["python"] },
10830
10862
  // Python SSRF
10831
10863
  { method: "get", class: "requests", type: "ssrf", cwe: "CWE-918", severity: "high", arg_positions: [0] },
10832
10864
  { method: "post", class: "requests", type: "ssrf", cwe: "CWE-918", severity: "high", arg_positions: [0] },
10833
10865
  { method: "urlopen", class: "urllib.request", type: "ssrf", cwe: "CWE-918", severity: "high", arg_positions: [0] },
10834
10866
  // Python Open Redirect
10835
- { method: "redirect", type: "open_redirect", cwe: "CWE-601", severity: "medium", arg_positions: [0] },
10867
+ { method: "redirect", type: "open_redirect", cwe: "CWE-601", severity: "medium", arg_positions: [0], languages: ["python"] },
10836
10868
  // Python XPath Injection
10837
- { method: "xpath", type: "xpath_injection", cwe: "CWE-643", severity: "high", arg_positions: [0] },
10869
+ { method: "xpath", type: "xpath_injection", cwe: "CWE-643", severity: "high", arg_positions: [0], languages: ["python"] },
10838
10870
  { method: "find", class: "etree", type: "xpath_injection", cwe: "CWE-643", severity: "high", arg_positions: [0] },
10839
10871
  { method: "findall", class: "etree", type: "xpath_injection", cwe: "CWE-643", severity: "high", arg_positions: [0] },
10840
10872
  { method: "iterfind", class: "etree", type: "xpath_injection", cwe: "CWE-643", severity: "high", arg_positions: [0] },
10841
10873
  { method: "XPath", class: "lxml", type: "xpath_injection", cwe: "CWE-643", severity: "high", arg_positions: [0] },
10842
10874
  // elementpath library (XPath 2.0/3.0)
10843
10875
  { method: "select", class: "elementpath", type: "xpath_injection", cwe: "CWE-643", severity: "high", arg_positions: [1] },
10844
- { method: "select", type: "xpath_injection", cwe: "CWE-643", severity: "high", arg_positions: [0] },
10876
+ { method: "select", type: "xpath_injection", cwe: "CWE-643", severity: "high", arg_positions: [0], languages: ["python"] },
10845
10877
  { method: "iter_select", class: "elementpath", type: "xpath_injection", cwe: "CWE-643", severity: "high", arg_positions: [1] },
10846
10878
  { method: "Selector", class: "elementpath", type: "xpath_injection", cwe: "CWE-643", severity: "high", arg_positions: [0] },
10847
10879
  // Python XXE
@@ -10933,36 +10965,42 @@ var DEFAULT_SINKS = [
10933
10965
  { method: "arg", class: "Command", type: "command_injection", cwe: "CWE-78", severity: "critical", arg_positions: [0] },
10934
10966
  { method: "args", class: "Command", type: "command_injection", cwe: "CWE-78", severity: "critical", arg_positions: [0] },
10935
10967
  // Rust SQL Injection (sqlx, diesel, rusqlite, tokio-postgres)
10936
- { method: "query", class: "Client", type: "sql_injection", cwe: "CWE-89", severity: "critical", arg_positions: [0] },
10937
- { method: "execute", class: "Client", type: "sql_injection", cwe: "CWE-89", severity: "critical", arg_positions: [0] },
10938
- { method: "query", class: "Pool", type: "sql_injection", cwe: "CWE-89", severity: "critical", arg_positions: [0] },
10939
- { method: "execute", class: "Pool", type: "sql_injection", cwe: "CWE-89", severity: "critical", arg_positions: [0] },
10940
- { method: "sql_query", type: "sql_injection", cwe: "CWE-89", severity: "critical", arg_positions: [0] },
10941
- { method: "raw_sql", type: "sql_injection", cwe: "CWE-89", severity: "critical", arg_positions: [0] },
10942
- { method: "execute", class: "Connection", type: "sql_injection", cwe: "CWE-89", severity: "critical", arg_positions: [0] },
10943
- { method: "query_row", class: "Connection", type: "sql_injection", cwe: "CWE-89", severity: "critical", arg_positions: [0] },
10944
- { method: "prepare", class: "Connection", type: "sql_injection", cwe: "CWE-89", severity: "critical", arg_positions: [0] },
10968
+ // Language-scoped: generic class names `Pool`/`Connection`/`Client` substring-match
10969
+ // unrelated Java identifiers (cachedThreadPool, dbConnection). See issue #14.
10970
+ { method: "query", class: "Client", type: "sql_injection", cwe: "CWE-89", severity: "critical", arg_positions: [0], languages: ["rust"] },
10971
+ { method: "execute", class: "Client", type: "sql_injection", cwe: "CWE-89", severity: "critical", arg_positions: [0], languages: ["rust"] },
10972
+ { method: "query", class: "Pool", type: "sql_injection", cwe: "CWE-89", severity: "critical", arg_positions: [0], languages: ["rust"] },
10973
+ { method: "execute", class: "Pool", type: "sql_injection", cwe: "CWE-89", severity: "critical", arg_positions: [0], languages: ["rust"] },
10974
+ { method: "sql_query", type: "sql_injection", cwe: "CWE-89", severity: "critical", arg_positions: [0], languages: ["rust"] },
10975
+ { method: "raw_sql", type: "sql_injection", cwe: "CWE-89", severity: "critical", arg_positions: [0], languages: ["rust"] },
10976
+ { method: "execute", class: "Connection", type: "sql_injection", cwe: "CWE-89", severity: "critical", arg_positions: [0], languages: ["rust"] },
10977
+ { method: "query_row", class: "Connection", type: "sql_injection", cwe: "CWE-89", severity: "critical", arg_positions: [0], languages: ["rust"] },
10978
+ { method: "prepare", class: "Connection", type: "sql_injection", cwe: "CWE-89", severity: "critical", arg_positions: [0], languages: ["rust"] },
10945
10979
  // sqlx::query macro — use class-specific pattern
10946
10980
  { method: "query", class: "sqlx", type: "sql_injection", cwe: "CWE-89", severity: "critical", arg_positions: [0] },
10947
10981
  // rusqlite specific
10948
- { method: "prepare", type: "sql_injection", cwe: "CWE-89", severity: "critical", arg_positions: [0] },
10949
- { method: "execute", type: "sql_injection", cwe: "CWE-89", severity: "critical", arg_positions: [0] },
10950
- { method: "query_map", type: "sql_injection", cwe: "CWE-89", severity: "critical", arg_positions: [0] },
10982
+ // Language-scoped: classless `execute`/`prepare`/`query_map` collide with
10983
+ // Java util.concurrent (Executor.execute, ExecutorService) and other languages.
10984
+ { method: "prepare", type: "sql_injection", cwe: "CWE-89", severity: "critical", arg_positions: [0], languages: ["rust"] },
10985
+ { method: "execute", type: "sql_injection", cwe: "CWE-89", severity: "critical", arg_positions: [0], languages: ["rust"] },
10986
+ { method: "query_map", type: "sql_injection", cwe: "CWE-89", severity: "critical", arg_positions: [0], languages: ["rust"] },
10951
10987
  // Rust Path Traversal
10952
10988
  { method: "open", class: "File", type: "path_traversal", cwe: "CWE-22", severity: "high", arg_positions: [0] },
10953
10989
  { method: "create", class: "File", type: "path_traversal", cwe: "CWE-22", severity: "high", arg_positions: [0] },
10954
- { method: "read_dir", type: "path_traversal", cwe: "CWE-22", severity: "high", arg_positions: [0] },
10955
- { method: "remove_file", type: "path_traversal", cwe: "CWE-22", severity: "high", arg_positions: [0] },
10956
- { method: "remove_dir", type: "path_traversal", cwe: "CWE-22", severity: "high", arg_positions: [0] },
10957
- { method: "remove_dir_all", type: "path_traversal", cwe: "CWE-22", severity: "critical", arg_positions: [0] },
10958
- { method: "copy", type: "path_traversal", cwe: "CWE-22", severity: "high", arg_positions: [0, 1] },
10959
- { method: "rename", type: "path_traversal", cwe: "CWE-22", severity: "high", arg_positions: [0, 1] },
10960
- { method: "write", type: "path_traversal", cwe: "CWE-22", severity: "high", arg_positions: [0] },
10961
- { method: "read_to_string", type: "path_traversal", cwe: "CWE-22", severity: "high", arg_positions: [0] },
10962
- { method: "create_dir", type: "path_traversal", cwe: "CWE-22", severity: "high", arg_positions: [0] },
10963
- { method: "create_dir_all", type: "path_traversal", cwe: "CWE-22", severity: "high", arg_positions: [0] },
10964
- { method: "metadata", type: "path_traversal", cwe: "CWE-22", severity: "medium", arg_positions: [0] },
10965
- { method: "symlink_metadata", type: "path_traversal", cwe: "CWE-22", severity: "medium", arg_positions: [0] },
10990
+ // Language-scoped: classless std::fs helpers collide with Java/JS method names
10991
+ // (write, copy, rename, metadata, etc.) See issue #14.
10992
+ { method: "read_dir", type: "path_traversal", cwe: "CWE-22", severity: "high", arg_positions: [0], languages: ["rust"] },
10993
+ { method: "remove_file", type: "path_traversal", cwe: "CWE-22", severity: "high", arg_positions: [0], languages: ["rust"] },
10994
+ { method: "remove_dir", type: "path_traversal", cwe: "CWE-22", severity: "high", arg_positions: [0], languages: ["rust"] },
10995
+ { method: "remove_dir_all", type: "path_traversal", cwe: "CWE-22", severity: "critical", arg_positions: [0], languages: ["rust"] },
10996
+ { method: "copy", type: "path_traversal", cwe: "CWE-22", severity: "high", arg_positions: [0, 1], languages: ["rust"] },
10997
+ { method: "rename", type: "path_traversal", cwe: "CWE-22", severity: "high", arg_positions: [0, 1], languages: ["rust"] },
10998
+ { method: "write", type: "path_traversal", cwe: "CWE-22", severity: "high", arg_positions: [0], languages: ["rust"] },
10999
+ { method: "read_to_string", type: "path_traversal", cwe: "CWE-22", severity: "high", arg_positions: [0], languages: ["rust"] },
11000
+ { method: "create_dir", type: "path_traversal", cwe: "CWE-22", severity: "high", arg_positions: [0], languages: ["rust"] },
11001
+ { method: "create_dir_all", type: "path_traversal", cwe: "CWE-22", severity: "high", arg_positions: [0], languages: ["rust"] },
11002
+ { method: "metadata", type: "path_traversal", cwe: "CWE-22", severity: "medium", arg_positions: [0], languages: ["rust"] },
11003
+ { method: "symlink_metadata", type: "path_traversal", cwe: "CWE-22", severity: "medium", arg_positions: [0], languages: ["rust"] },
10966
11004
  // Tokio async fs
10967
11005
  { method: "read_to_string", class: "fs", type: "path_traversal", cwe: "CWE-22", severity: "high", arg_positions: [0] },
10968
11006
  { method: "write", class: "fs", type: "path_traversal", cwe: "CWE-22", severity: "high", arg_positions: [0] },
@@ -11240,9 +11278,9 @@ var PYTHON_TAINTED_PATTERNS = [
11240
11278
  { pattern: /\brequest\.query_params\b/, sourceType: "http_param" },
11241
11279
  { pattern: /\brequest\.path_params\b/, sourceType: "http_param" }
11242
11280
  ];
11243
- function analyzeTaint(calls, types, config = getDefaultConfig(), typeHierarchy) {
11281
+ function analyzeTaint(calls, types, config = getDefaultConfig(), typeHierarchy, language) {
11244
11282
  const sources = findSources(calls, types, config.sources);
11245
- const sinks = findSinks(calls, config.sinks, typeHierarchy);
11283
+ const sinks = findSinks(calls, config.sinks, typeHierarchy, language);
11246
11284
  const sanitizers = findSanitizers(calls, types, config.sanitizers);
11247
11285
  return { sources, sinks, sanitizers };
11248
11286
  }
@@ -11496,11 +11534,11 @@ function isParameterizedQueryCall(call, pattern) {
11496
11534
  }
11497
11535
  return false;
11498
11536
  }
11499
- function findSinks(calls, patterns, typeHierarchy) {
11537
+ function findSinks(calls, patterns, typeHierarchy, language) {
11500
11538
  const sinkMap = /* @__PURE__ */ new Map();
11501
11539
  for (const call of calls) {
11502
11540
  for (const pattern of patterns) {
11503
- if (matchesSinkPattern(call, pattern, typeHierarchy)) {
11541
+ if (matchesSinkPattern(call, pattern, typeHierarchy, language)) {
11504
11542
  if (isParameterizedQueryCall(call, pattern)) {
11505
11543
  continue;
11506
11544
  }
@@ -11753,7 +11791,12 @@ function isKnownSafeReceiverForMethod(receiver, method, sinkType) {
11753
11791
  }
11754
11792
  return false;
11755
11793
  }
11756
- function matchesSinkPattern(call, pattern, typeHierarchy) {
11794
+ function matchesSinkPattern(call, pattern, typeHierarchy, language) {
11795
+ if (pattern.languages && pattern.languages.length > 0 && language !== void 0) {
11796
+ if (!pattern.languages.includes(language)) {
11797
+ return false;
11798
+ }
11799
+ }
11757
11800
  const callMethodName = call.method_name;
11758
11801
  const patternMethod = pattern.method;
11759
11802
  let methodMatches = callMethodName === patternMethod;
@@ -11857,17 +11900,29 @@ function receiverMightBeClass(receiver, className) {
11857
11900
  }
11858
11901
  }
11859
11902
  }
11860
- if (lowerReceiver.length >= 3 && lowerClass.includes(lowerReceiver)) {
11903
+ const ambiguousIdentifiers = /* @__PURE__ */ new Set([
11904
+ "executor",
11905
+ "pool",
11906
+ "connection",
11907
+ "manager",
11908
+ "handler",
11909
+ "controller",
11910
+ "task",
11911
+ "thread",
11912
+ "job"
11913
+ ]);
11914
+ const isAmbiguous = ambiguousIdentifiers.has(lowerReceiver);
11915
+ if (!isAmbiguous && lowerReceiver.length >= 3 && lowerClass.includes(lowerReceiver)) {
11861
11916
  if (lowerReceiver.length >= 5 || lowerReceiver.length / lowerClass.length >= 0.4) {
11862
11917
  return true;
11863
11918
  }
11864
11919
  }
11865
- if (lowerReceiver.length >= 2) {
11920
+ if (!isAmbiguous && lowerReceiver.length >= 2) {
11866
11921
  if (lowerClass.startsWith(lowerReceiver) || lowerClass.endsWith(lowerReceiver)) {
11867
11922
  return true;
11868
11923
  }
11869
11924
  }
11870
- if (lowerReceiver.length >= 3) {
11925
+ if (!isAmbiguous && lowerReceiver.length >= 3) {
11871
11926
  const words = className.replace(/([a-z])([A-Z])/g, "$1\0$2").toLowerCase().split("\0");
11872
11927
  for (const word of words) {
11873
11928
  if (word.startsWith(lowerReceiver) && lowerReceiver.length / word.length >= 0.4) {
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * Core module index - re-exports parser and extractors
3
3
  */
4
- export { initParser, loadLanguage, createParser, parse, walkTree, findNodes, findAncestor, getNodeText, collectAllNodes, getNodesFromCache, isInitialized, isLanguageLoaded, resetParser, type SupportedLanguage, type SyntaxNode, type Node, type NodeCache, type Language, type Tree, } from './parser.js';
4
+ export { initParser, loadLanguage, createParser, createFreshParser, parse, disposeTree, walkTree, findNodes, findAncestor, getNodeText, collectAllNodes, getNodesFromCache, isInitialized, isLanguageLoaded, resetParser, type SupportedLanguage, type SyntaxNode, type Node, type NodeCache, type Language, type Tree, } from './parser.js';
5
5
  export { extractMeta, extractTypes, extractCalls, extractImports, extractExports, buildCFG, buildDFG, } from './extractors/index.js';
6
6
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/core/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAGH,OAAO,EACL,UAAU,EACV,YAAY,EACZ,YAAY,EACZ,KAAK,EACL,QAAQ,EACR,SAAS,EACT,YAAY,EACZ,WAAW,EACX,eAAe,EACf,iBAAiB,EACjB,aAAa,EACb,gBAAgB,EAChB,WAAW,EACX,KAAK,iBAAiB,EACtB,KAAK,UAAU,EACf,KAAK,IAAI,EACT,KAAK,SAAS,EACd,KAAK,QAAQ,EACb,KAAK,IAAI,GACV,MAAM,aAAa,CAAC;AAGrB,OAAO,EACL,WAAW,EACX,YAAY,EACZ,YAAY,EACZ,cAAc,EACd,cAAc,EACd,QAAQ,EACR,QAAQ,GACT,MAAM,uBAAuB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/core/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAGH,OAAO,EACL,UAAU,EACV,YAAY,EACZ,YAAY,EACZ,iBAAiB,EACjB,KAAK,EACL,WAAW,EACX,QAAQ,EACR,SAAS,EACT,YAAY,EACZ,WAAW,EACX,eAAe,EACf,iBAAiB,EACjB,aAAa,EACb,gBAAgB,EAChB,WAAW,EACX,KAAK,iBAAiB,EACtB,KAAK,UAAU,EACf,KAAK,IAAI,EACT,KAAK,SAAS,EACd,KAAK,QAAQ,EACb,KAAK,IAAI,GACV,MAAM,aAAa,CAAC;AAGrB,OAAO,EACL,WAAW,EACX,YAAY,EACZ,YAAY,EACZ,cAAc,EACd,cAAc,EACd,QAAQ,EACR,QAAQ,GACT,MAAM,uBAAuB,CAAC"}
@@ -2,7 +2,7 @@
2
2
  * Core module index - re-exports parser and extractors
3
3
  */
4
4
  // Parser
5
- export { initParser, loadLanguage, createParser, parse, walkTree, findNodes, findAncestor, getNodeText, collectAllNodes, getNodesFromCache, isInitialized, isLanguageLoaded, resetParser, } from './parser.js';
5
+ export { initParser, loadLanguage, createParser, createFreshParser, parse, disposeTree, walkTree, findNodes, findAncestor, getNodeText, collectAllNodes, getNodesFromCache, isInitialized, isLanguageLoaded, resetParser, } from './parser.js';
6
6
  // Extractors
7
7
  export { extractMeta, extractTypes, extractCalls, extractImports, extractExports, buildCFG, buildDFG, } from './extractors/index.js';
8
8
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/core/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,SAAS;AACT,OAAO,EACL,UAAU,EACV,YAAY,EACZ,YAAY,EACZ,KAAK,EACL,QAAQ,EACR,SAAS,EACT,YAAY,EACZ,WAAW,EACX,eAAe,EACf,iBAAiB,EACjB,aAAa,EACb,gBAAgB,EAChB,WAAW,GAOZ,MAAM,aAAa,CAAC;AAErB,aAAa;AACb,OAAO,EACL,WAAW,EACX,YAAY,EACZ,YAAY,EACZ,cAAc,EACd,cAAc,EACd,QAAQ,EACR,QAAQ,GACT,MAAM,uBAAuB,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/core/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,SAAS;AACT,OAAO,EACL,UAAU,EACV,YAAY,EACZ,YAAY,EACZ,iBAAiB,EACjB,KAAK,EACL,WAAW,EACX,QAAQ,EACR,SAAS,EACT,YAAY,EACZ,WAAW,EACX,eAAe,EACf,iBAAiB,EACjB,aAAa,EACb,gBAAgB,EAChB,WAAW,GAOZ,MAAM,aAAa,CAAC;AAErB,aAAa;AACb,OAAO,EACL,WAAW,EACX,YAAY,EACZ,YAAY,EACZ,cAAc,EACd,cAAc,EACd,QAAQ,EACR,QAAQ,GACT,MAAM,uBAAuB,CAAC"}
@@ -45,13 +45,28 @@ export declare function initParser(options?: ParserOptions): Promise<void>;
45
45
  */
46
46
  export declare function loadLanguage(language: SupportedLanguage, wasmPath?: string): Promise<Language>;
47
47
  /**
48
- * Create a new parser instance configured for the specified language.
48
+ * Get a parser instance configured for the specified language. The Parser is
49
+ * cached per-language and reused across calls — see `cachedParsers` above.
50
+ * Use `createFreshParser()` if you need a non-shared instance.
49
51
  */
50
52
  export declare function createParser(language: SupportedLanguage): Promise<Parser>;
53
+ /**
54
+ * Create a non-cached parser. Caller is responsible for `parser.delete()` when
55
+ * done. Prefer `createParser` unless isolation is required.
56
+ */
57
+ export declare function createFreshParser(language: SupportedLanguage): Promise<Parser>;
51
58
  /**
52
59
  * Parse source code and return the syntax tree.
60
+ *
61
+ * IMPORTANT: The returned Tree holds memory in the tree-sitter WASM heap. Call
62
+ * `disposeTree(tree)` once you no longer need its nodes to free that memory.
63
+ * Failing to dispose causes unbounded WASM heap growth at scale (#16).
53
64
  */
54
65
  export declare function parse(code: string, language: SupportedLanguage): Promise<Tree>;
66
+ /**
67
+ * Free the WASM memory backing a parsed Tree. Safe to call multiple times.
68
+ */
69
+ export declare function disposeTree(tree: Tree | null | undefined): void;
55
70
  /**
56
71
  * Walk the syntax tree and call the visitor for each node.
57
72
  */
@@ -92,6 +107,9 @@ export declare function isInitialized(): boolean;
92
107
  export declare function isLanguageLoaded(language: SupportedLanguage): boolean;
93
108
  /**
94
109
  * Reset the parser state (mainly for testing).
110
+ *
111
+ * Disposes any cached Parser instances and clears the language cache so the
112
+ * next `initParser()` call starts with a clean WASM heap.
95
113
  */
96
114
  export declare function resetParser(): void;
97
115
  //# sourceMappingURL=parser.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"parser.d.ts","sourceRoot":"","sources":["../../src/core/parser.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,iBAAiB,CAAC;AAoD/D,OAAO,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC;AAC1B,YAAY,EAAE,IAAI,EAAE,CAAC;AAErB,MAAM,MAAM,UAAU,GAAG,IAAI,CAAC;AAE9B,MAAM,MAAM,iBAAiB,GAAG,MAAM,GAAG,GAAG,GAAG,KAAK,GAAG,YAAY,GAAG,YAAY,GAAG,QAAQ,GAAG,MAAM,GAAG,MAAM,GAAG,MAAM,GAAG,IAAI,CAAC;AAEhI,UAAU,aAAa;IACrB;;;;OAIG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;IAElB;;;;OAIG;IACH,UAAU,CAAC,EAAE,WAAW,CAAC,MAAM,CAAC;IAEhC;;;OAGG;IACH,aAAa,CAAC,EAAE,OAAO,CAAC,MAAM,CAAC,iBAAiB,EAAE,MAAM,CAAC,CAAC,CAAC;IAE3D;;;;OAIG;IACH,eAAe,CAAC,EAAE,OAAO,CAAC,MAAM,CAAC,iBAAiB,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC,CAAC;CAC1E;AASD;;;;GAIG;AACH,wBAAsB,UAAU,CAAC,OAAO,GAAE,aAAkB,GAAG,OAAO,CAAC,IAAI,CAAC,CA4C3E;AAED;;;GAGG;AACH,wBAAsB,YAAY,CAChC,QAAQ,EAAE,iBAAiB,EAC3B,QAAQ,CAAC,EAAE,MAAM,GAChB,OAAO,CAAC,QAAQ,CAAC,CA6CnB;AAED;;GAEG;AACH,wBAAsB,YAAY,CAAC,QAAQ,EAAE,iBAAiB,GAAG,OAAO,CAAC,MAAM,CAAC,CAK/E;AAED;;GAEG;AACH,wBAAsB,KAAK,CACzB,IAAI,EAAE,MAAM,EACZ,QAAQ,EAAE,iBAAiB,GAC1B,OAAO,CAAC,IAAI,CAAC,CAOf;AAED;;GAEG;AACH,wBAAgB,QAAQ,CACtB,IAAI,EAAE,IAAI,EACV,OAAO,EAAE,CAAC,IAAI,EAAE,IAAI,KAAK,IAAI,GAC5B,IAAI,CAQN;AAED;;GAEG;AACH,wBAAgB,SAAS,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,GAAG,IAAI,EAAE,CAQ1D;AAED;;;GAGG;AACH,MAAM,MAAM,SAAS,GAAG,GAAG,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC;AAE5C;;;GAGG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,GAAG,CAAC,MAAM,CAAC,GAAG,SAAS,CAazE;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,SAAS,GAAG,IAAI,EAAE,CAKrF;AAED;;GAEG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,GAAG,IAAI,GAAG,IAAI,CASlE;AAED;;GAEG;AACH,wBAAgB,WAAW,CAAC,IAAI,EAAE,IAAI,GAAG,MAAM,CAE9C;AA4DD;;GAEG;AACH,wBAAgB,aAAa,IAAI,OAAO,CAEvC;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,iBAAiB,GAAG,OAAO,CAErE;AAED;;GAEG;AACH,wBAAgB,WAAW,IAAI,IAAI,CAIlC"}
1
+ {"version":3,"file":"parser.d.ts","sourceRoot":"","sources":["../../src/core/parser.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,iBAAiB,CAAC;AAoD/D,OAAO,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC;AAC1B,YAAY,EAAE,IAAI,EAAE,CAAC;AAErB,MAAM,MAAM,UAAU,GAAG,IAAI,CAAC;AAE9B,MAAM,MAAM,iBAAiB,GAAG,MAAM,GAAG,GAAG,GAAG,KAAK,GAAG,YAAY,GAAG,YAAY,GAAG,QAAQ,GAAG,MAAM,GAAG,MAAM,GAAG,MAAM,GAAG,IAAI,CAAC;AAEhI,UAAU,aAAa;IACrB;;;;OAIG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;IAElB;;;;OAIG;IACH,UAAU,CAAC,EAAE,WAAW,CAAC,MAAM,CAAC;IAEhC;;;OAGG;IACH,aAAa,CAAC,EAAE,OAAO,CAAC,MAAM,CAAC,iBAAiB,EAAE,MAAM,CAAC,CAAC,CAAC;IAE3D;;;;OAIG;IACH,eAAe,CAAC,EAAE,OAAO,CAAC,MAAM,CAAC,iBAAiB,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC,CAAC;CAC1E;AAaD;;;;GAIG;AACH,wBAAsB,UAAU,CAAC,OAAO,GAAE,aAAkB,GAAG,OAAO,CAAC,IAAI,CAAC,CA4C3E;AAED;;;GAGG;AACH,wBAAsB,YAAY,CAChC,QAAQ,EAAE,iBAAiB,EAC3B,QAAQ,CAAC,EAAE,MAAM,GAChB,OAAO,CAAC,QAAQ,CAAC,CA6CnB;AAED;;;;GAIG;AACH,wBAAsB,YAAY,CAAC,QAAQ,EAAE,iBAAiB,GAAG,OAAO,CAAC,MAAM,CAAC,CAU/E;AAED;;;GAGG;AACH,wBAAsB,iBAAiB,CAAC,QAAQ,EAAE,iBAAiB,GAAG,OAAO,CAAC,MAAM,CAAC,CAKpF;AAED;;;;;;GAMG;AACH,wBAAsB,KAAK,CACzB,IAAI,EAAE,MAAM,EACZ,QAAQ,EAAE,iBAAiB,GAC1B,OAAO,CAAC,IAAI,CAAC,CAOf;AAED;;GAEG;AACH,wBAAgB,WAAW,CAAC,IAAI,EAAE,IAAI,GAAG,IAAI,GAAG,SAAS,GAAG,IAAI,CAO/D;AAED;;GAEG;AACH,wBAAgB,QAAQ,CACtB,IAAI,EAAE,IAAI,EACV,OAAO,EAAE,CAAC,IAAI,EAAE,IAAI,KAAK,IAAI,GAC5B,IAAI,CAQN;AAED;;GAEG;AACH,wBAAgB,SAAS,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,GAAG,IAAI,EAAE,CAQ1D;AAED;;;GAGG;AACH,MAAM,MAAM,SAAS,GAAG,GAAG,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC;AAE5C;;;GAGG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,GAAG,CAAC,MAAM,CAAC,GAAG,SAAS,CAazE;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,SAAS,GAAG,IAAI,EAAE,CAKrF;AAED;;GAEG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,GAAG,IAAI,GAAG,IAAI,CASlE;AAED;;GAEG;AACH,wBAAgB,WAAW,CAAC,IAAI,EAAE,IAAI,GAAG,MAAM,CAE9C;AA4DD;;GAEG;AACH,wBAAgB,aAAa,IAAI,OAAO,CAEvC;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,iBAAiB,GAAG,OAAO,CAErE;AAED;;;;;GAKG;AACH,wBAAgB,WAAW,IAAI,IAAI,CAWlC"}
@@ -52,6 +52,10 @@ let parserInitialized = false;
52
52
  let parserInitializing = null;
53
53
  const loadedLanguages = new Map();
54
54
  const loadingLanguages = new Map();
55
+ // One reusable Parser per language. `new Parser()` allocates a struct in the
56
+ // tree-sitter WASM heap; reusing the instance avoids unbounded heap growth
57
+ // when many files are parsed in a single process (see issue #16).
58
+ const cachedParsers = new Map();
55
59
  let configuredLanguagePaths = {};
56
60
  let configuredLanguageModules = {};
57
61
  /**
@@ -144,9 +148,26 @@ export async function loadLanguage(language, wasmPath) {
144
148
  return loadPromise;
145
149
  }
146
150
  /**
147
- * Create a new parser instance configured for the specified language.
151
+ * Get a parser instance configured for the specified language. The Parser is
152
+ * cached per-language and reused across calls — see `cachedParsers` above.
153
+ * Use `createFreshParser()` if you need a non-shared instance.
148
154
  */
149
155
  export async function createParser(language) {
156
+ const cached = cachedParsers.get(language);
157
+ if (cached) {
158
+ return cached;
159
+ }
160
+ const lang = await loadLanguage(language);
161
+ const parser = new Parser();
162
+ parser.setLanguage(lang);
163
+ cachedParsers.set(language, parser);
164
+ return parser;
165
+ }
166
+ /**
167
+ * Create a non-cached parser. Caller is responsible for `parser.delete()` when
168
+ * done. Prefer `createParser` unless isolation is required.
169
+ */
170
+ export async function createFreshParser(language) {
150
171
  const lang = await loadLanguage(language);
151
172
  const parser = new Parser();
152
173
  parser.setLanguage(lang);
@@ -154,6 +175,10 @@ export async function createParser(language) {
154
175
  }
155
176
  /**
156
177
  * Parse source code and return the syntax tree.
178
+ *
179
+ * IMPORTANT: The returned Tree holds memory in the tree-sitter WASM heap. Call
180
+ * `disposeTree(tree)` once you no longer need its nodes to free that memory.
181
+ * Failing to dispose causes unbounded WASM heap growth at scale (#16).
157
182
  */
158
183
  export async function parse(code, language) {
159
184
  const parser = await createParser(language);
@@ -163,6 +188,19 @@ export async function parse(code, language) {
163
188
  }
164
189
  return tree;
165
190
  }
191
+ /**
192
+ * Free the WASM memory backing a parsed Tree. Safe to call multiple times.
193
+ */
194
+ export function disposeTree(tree) {
195
+ if (!tree)
196
+ return;
197
+ try {
198
+ tree.delete();
199
+ }
200
+ catch {
201
+ // Already deleted or invalid handle — ignore.
202
+ }
203
+ }
166
204
  /**
167
205
  * Walk the syntax tree and call the visitor for each node.
168
206
  */
@@ -293,10 +331,23 @@ export function isLanguageLoaded(language) {
293
331
  }
294
332
  /**
295
333
  * Reset the parser state (mainly for testing).
334
+ *
335
+ * Disposes any cached Parser instances and clears the language cache so the
336
+ * next `initParser()` call starts with a clean WASM heap.
296
337
  */
297
338
  export function resetParser() {
298
- parserInitialized = false;
339
+ for (const parser of cachedParsers.values()) {
340
+ try {
341
+ parser.delete();
342
+ }
343
+ catch { /* ignore */ }
344
+ }
345
+ cachedParsers.clear();
299
346
  loadedLanguages.clear();
347
+ loadingLanguages.clear();
300
348
  configuredLanguagePaths = {};
349
+ configuredLanguageModules = {};
350
+ parserInitialized = false;
351
+ parserInitializing = null;
301
352
  }
302
353
  //# sourceMappingURL=parser.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"parser.js","sourceRoot":"","sources":["../../src/core/parser.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,IAAI,EAAQ,MAAM,iBAAiB,CAAC;AAE/D,uDAAuD;AACvD,+DAA+D;AAC/D,IAAI,WAAW,GAKJ,IAAI,CAAC;AAEhB,IAAI,SAAS,GAAkB,IAAI,CAAC;AAEpC;;GAEG;AACH,KAAK,UAAU,cAAc;IAC3B,IAAI,WAAW;QAAE,OAAO,WAAW,CAAC;IAEpC,IAAI,CAAC;QACH,wEAAwE;QACxE,yEAAyE;QACzE,8BAA8B;QAC9B,EAAE;QACF,sEAAsE;QACtE,uEAAuE;QACvE,sDAAsD;QACtD,sEAAsE;QACtE,sEAAsE;QACtE,gDAAgD;QAChD,MAAM,aAAa,GAAG,IAAI,QAAQ,CAAC,GAAG,EAAE,kBAAkB,CAAC,CAAC;QAC5D,MAAM,CAAC,MAAM,EAAE,OAAO,EAAE,KAAK,CAAC,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC;YACjD,aAAa,CAAC,KAAK,CAAC;YACpB,aAAa,CAAC,MAAM,CAAC;YACrB,aAAa,CAAC,IAAI,CAAC;SACpB,CAAC,CAAC;QACH,WAAW,GAAG;YACZ,aAAa,EAAE,MAAM,CAAC,aAAa;YACnC,OAAO,EAAE,OAAO,CAAC,OAAO;YACxB,IAAI,EAAE,OAAO,CAAC,IAAI;YAClB,UAAU,EAAE,KAAK,CAAC,UAAU;SAC7B,CAAC;QACF,6BAA6B;QAC7B,SAAS,GAAG,WAAW,CAAC,OAAO,CAAC,WAAW,CAAC,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;QAC5E,OAAO,WAAW,CAAC;IACrB,CAAC;IAAC,MAAM,CAAC;QACP,iEAAiE;QACjE,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED,0CAA0C;AAC1C,OAAO,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC;AAoC1B,IAAI,iBAAiB,GAAG,KAAK,CAAC;AAC9B,IAAI,kBAAkB,GAAyB,IAAI,CAAC;AACpD,MAAM,eAAe,GAAG,IAAI,GAAG,EAA+B,CAAC;AAC/D,MAAM,gBAAgB,GAAG,IAAI,GAAG,EAAwC,CAAC;AACzE,IAAI,uBAAuB,GAA+C,EAAE,CAAC;AAC7E,IAAI,yBAAyB,GAA2D,EAAE,CAAC;AAE3F;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,UAAU,CAAC,UAAyB,EAAE;IAC1D,IAAI,iBAAiB,EAAE,CAAC;QACtB,OAAO;IACT,CAAC;IAED,qDAAqD;IACrD,IAAI,kBAAkB,EAAE,CAAC;QACvB,OAAO,kBAAkB,CAAC;IAC5B,CAAC;IAED,6DAA6D;IAC7D,IAAI,OAAO,CAAC,aAAa,EAAE,CAAC;QAC1B,uBAAuB,GAAG,OAAO,CAAC,aAAa,CAAC;IAClD,CAAC;IACD,IAAI,OAAO,CAAC,eAAe,EAAE,CAAC;QAC5B,yBAAyB,GAAG,OAAO,CAAC,eAAe,CAAC;IACtD,CAAC;IAED,6CAA6C;IAC7C,kBAAkB,GAAG,CAAC,KAAK,IAAI,EAAE;QAC/B,IAAI,OAAO,CAAC,UAAU,EAAE,CAAC;YACvB,6FAA6F;YAC7F,oFAAoF;YACpF,MAAM,MAAM,CAAC,IAAI,CAAC;gBAChB,UAAU,EAAE,GAAG,EAAE,CAAC,sBAAsB;gBACxC,eAAe,CAAC,OAA4B,EAAE,QAA+E;oBAC3H,MAAM,QAAQ,GAAG,IAAI,WAAW,CAAC,QAAQ,CAAC,OAAO,CAAC,UAAW,EAAE,OAAO,CAAC,CAAC;oBACxE,gFAAgF;oBAChF,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC,UAAW,CAAC,CAAC;oBACxC,OAAO,QAAQ,CAAC,OAAO,CAAC;gBAC1B,CAAC;aACF,CAAC,CAAC;QAEL,CAAC;aAAM,CAAC;YACN,MAAM,QAAQ,GAAG,OAAO,CAAC,QAAQ,IAAI,MAAM,kBAAkB,EAAE,CAAC;YAChE,MAAM,MAAM,CAAC,IAAI,CAAC;gBAChB,UAAU,EAAE,GAAG,EAAE,CAAC,QAAQ;aAC3B,CAAC,CAAC;QACL,CAAC;QACD,iBAAiB,GAAG,IAAI,CAAC;QACzB,kBAAkB,GAAG,IAAI,CAAC;IAC5B,CAAC,CAAC,EAAE,CAAC;IAEL,OAAO,kBAAkB,CAAC;AAC5B,CAAC;AAED;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,YAAY,CAChC,QAA2B,EAC3B,QAAiB;IAEjB,IAAI,CAAC,iBAAiB,EAAE,CAAC;QACvB,MAAM,IAAI,KAAK,CAAC,kDAAkD,CAAC,CAAC;IACtE,CAAC;IAED,oBAAoB;IACpB,MAAM,MAAM,GAAG,eAAe,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;IAC7C,IAAI,MAAM,EAAE,CAAC;QACX,OAAO,MAAM,CAAC;IAChB,CAAC;IAED,8DAA8D;IAC9D,MAAM,OAAO,GAAG,gBAAgB,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;IAC/C,IAAI,OAAO,EAAE,CAAC;QACZ,OAAO,OAAO,CAAC;IACjB,CAAC;IAED,2DAA2D;IAC3D,MAAM,UAAU,GAAG,yBAAyB,CAAC,QAAQ,CAAC,CAAC;IACvD,IAAI,UAAU,EAAE,CAAC;QACf,MAAM,WAAW,GAAG,CAAC,KAAK,IAAI,EAAE;YAC9B,qEAAqE;YACrE,gEAAgE;YAChE,MAAM,IAAI,GAAG,MAAM,QAAQ,CAAC,IAAI,CAAC,UAAmC,CAAC,CAAC;YACtE,eAAe,CAAC,GAAG,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC;YACpC,OAAO,IAAI,CAAC;QACd,CAAC,CAAC,EAAE,CAAC;QACL,gBAAgB,CAAC,GAAG,CAAC,QAAQ,EAAE,WAAW,CAAC,CAAC;QAC5C,OAAO,WAAW,CAAC;IACrB,CAAC;IAED,8DAA8D;IAC9D,MAAM,IAAI,GAAG,QAAQ,IAAI,uBAAuB,CAAC,QAAQ,CAAC,IAAI,MAAM,sBAAsB,CAAC,QAAQ,CAAC,CAAC;IAErG,sCAAsC;IACtC,MAAM,WAAW,GAAG,CAAC,KAAK,IAAI,EAAE;QAC9B,MAAM,IAAI,GAAG,MAAM,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACvC,eAAe,CAAC,GAAG,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC;QACpC,gBAAgB,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;QAClC,OAAO,IAAI,CAAC;IACd,CAAC,CAAC,EAAE,CAAC;IAEL,gBAAgB,CAAC,GAAG,CAAC,QAAQ,EAAE,WAAW,CAAC,CAAC;IAE5C,OAAO,WAAW,CAAC;AACrB,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,YAAY,CAAC,QAA2B;IAC5D,MAAM,IAAI,GAAG,MAAM,YAAY,CAAC,QAAQ,CAAC,CAAC;IAC1C,MAAM,MAAM,GAAG,IAAI,MAAM,EAAE,CAAC;IAC5B,MAAM,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC;IACzB,OAAO,MAAM,CAAC;AAChB,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,KAAK,CACzB,IAAY,EACZ,QAA2B;IAE3B,MAAM,MAAM,GAAG,MAAM,YAAY,CAAC,QAAQ,CAAC,CAAC;IAC5C,MAAM,IAAI,GAAG,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IAChC,IAAI,CAAC,IAAI,EAAE,CAAC;QACV,MAAM,IAAI,KAAK,CAAC,sBAAsB,CAAC,CAAC;IAC1C,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,QAAQ,CACtB,IAAU,EACV,OAA6B;IAE7B,OAAO,CAAC,IAAI,CAAC,CAAC;IACd,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,UAAU,EAAE,CAAC,EAAE,EAAE,CAAC;QACzC,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;QAC5B,IAAI,KAAK,EAAE,CAAC;YACV,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC;QAC3B,CAAC;IACH,CAAC;AACH,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,SAAS,CAAC,IAAU,EAAE,IAAY;IAChD,MAAM,OAAO,GAAW,EAAE,CAAC;IAC3B,QAAQ,CAAC,IAAI,EAAE,CAAC,CAAC,EAAE,EAAE;QACnB,IAAI,CAAC,CAAC,IAAI,KAAK,IAAI,EAAE,CAAC;YACpB,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;IACH,CAAC,CAAC,CAAC;IACH,OAAO,OAAO,CAAC;AACjB,CAAC;AAQD;;;GAGG;AACH,MAAM,UAAU,eAAe,CAAC,IAAU,EAAE,KAAkB;IAC5D,MAAM,KAAK,GAAc,IAAI,GAAG,EAAE,CAAC;IACnC,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,KAAK,CAAC,GAAG,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;IACtB,CAAC;IAED,QAAQ,CAAC,IAAI,EAAE,CAAC,CAAC,EAAE,EAAE;QACnB,IAAI,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC;YACtB,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAE,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAC7B,CAAC;IACH,CAAC,CAAC,CAAC;IAEH,OAAO,KAAK,CAAC;AACf,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,iBAAiB,CAAC,IAAU,EAAE,IAAY,EAAE,KAAiB;IAC3E,IAAI,KAAK,EAAE,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC;QACrB,OAAO,KAAK,CAAC,GAAG,CAAC,IAAI,CAAE,CAAC;IAC1B,CAAC;IACD,OAAO,SAAS,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;AAC/B,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,YAAY,CAAC,IAAU,EAAE,IAAY;IACnD,IAAI,OAAO,GAAG,IAAI,CAAC,MAAM,CAAC;IAC1B,OAAO,OAAO,EAAE,CAAC;QACf,IAAI,OAAO,CAAC,IAAI,KAAK,IAAI,EAAE,CAAC;YAC1B,OAAO,OAAO,CAAC;QACjB,CAAC;QACD,OAAO,GAAG,OAAO,CAAC,MAAM,CAAC;IAC3B,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,WAAW,CAAC,IAAU;IACpC,OAAO,IAAI,CAAC,IAAI,CAAC;AACnB,CAAC;AAED;;;GAGG;AACH,KAAK,UAAU,kBAAkB;IAC/B,MAAM,IAAI,GAAG,MAAM,cAAc,EAAE,CAAC;IAEpC,IAAI,IAAI,IAAI,SAAS,EAAE,CAAC;QACtB,yDAAyD;QACzD,qEAAqE;QACrE,MAAM,WAAW,GAAG,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC;QAErD,gFAAgF;QAChF,kFAAkF;QAClF,8DAA8D;QAC9D,MAAM,YAAY,GAAG,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,MAAM,EAAE,MAAM,EAAE,sBAAsB,CAAC,CAAC;QACpF,IAAI,IAAI,CAAC,UAAU,CAAC,YAAY,CAAC,EAAE,CAAC;YAClC,OAAO,YAAY,CAAC;QACtB,CAAC;QAED,0DAA0D;QAC1D,MAAM,sBAAsB,GAAG,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,cAAc,EAAE,iBAAiB,EAAE,sBAAsB,CAAC,CAAC;QACjH,IAAI,IAAI,CAAC,UAAU,CAAC,sBAAsB,CAAC,EAAE,CAAC;YAC5C,OAAO,sBAAsB,CAAC;QAChC,CAAC;IACH,CAAC;IAED,wDAAwD;IACxD,OAAO,mDAAmD,CAAC;AAC7D,CAAC;AAED;;GAEG;AACH,KAAK,UAAU,sBAAsB,CAAC,QAA2B;IAC/D,MAAM,IAAI,GAAG,MAAM,cAAc,EAAE,CAAC;IAEpC,IAAI,IAAI,IAAI,SAAS,EAAE,CAAC;QACtB,yDAAyD;QACzD,MAAM,WAAW,GAAG,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC;QAErD,iFAAiF;QACjF,MAAM,YAAY,GAAG,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,MAAM,EAAE,MAAM,EAAE,eAAe,QAAQ,OAAO,CAAC,CAAC;QAC5F,IAAI,IAAI,CAAC,UAAU,CAAC,YAAY,CAAC,EAAE,CAAC;YAClC,OAAO,YAAY,CAAC;QACtB,CAAC;QAED,oDAAoD;QACpD,MAAM,eAAe,GAAG,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,MAAM,EAAE,eAAe,QAAQ,OAAO,CAAC,CAAC;QACvF,IAAI,IAAI,CAAC,UAAU,CAAC,eAAe,CAAC,EAAE,CAAC;YACrC,OAAO,eAAe,CAAC;QACzB,CAAC;IACH,CAAC;IAED,qDAAqD;IACrD,OAAO,oBAAoB,QAAQ,OAAO,CAAC;AAC7C,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,aAAa;IAC3B,OAAO,iBAAiB,CAAC;AAC3B,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,gBAAgB,CAAC,QAA2B;IAC1D,OAAO,eAAe,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;AACvC,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,WAAW;IACzB,iBAAiB,GAAG,KAAK,CAAC;IAC1B,eAAe,CAAC,KAAK,EAAE,CAAC;IACxB,uBAAuB,GAAG,EAAE,CAAC;AAC/B,CAAC"}
1
+ {"version":3,"file":"parser.js","sourceRoot":"","sources":["../../src/core/parser.ts"],"names":[],"mappings":"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"}
@@ -1,7 +1,7 @@
1
1
  /**
2
2
  * Types for YAML configuration files (configs/sources/, configs/sinks/)
3
3
  */
4
- import type { SarifLevel, Severity, SinkType, SourceType } from './index.js';
4
+ import type { SarifLevel, Severity, SinkType, SourceType, SupportedLanguage } from './index.js';
5
5
  export interface SourceConfig {
6
6
  sources: SourcePattern[];
7
7
  }
@@ -30,6 +30,13 @@ export interface SinkPattern {
30
30
  cwe: string;
31
31
  severity: Severity;
32
32
  arg_positions: number[];
33
+ /**
34
+ * Restrict the pattern to specific source languages. When omitted, the
35
+ * pattern matches calls regardless of language. Use this for sinks whose
36
+ * method name collides across language ecosystems (e.g. Python/Rust
37
+ * `cursor.execute()` vs Java `Executor.execute()`).
38
+ */
39
+ languages?: SupportedLanguage[];
33
40
  note?: string;
34
41
  }
35
42
  export interface SanitizerPattern {