entrygraph 0.1.32__tar.gz → 0.1.34__tar.gz

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.
Files changed (198) hide show
  1. {entrygraph-0.1.32 → entrygraph-0.1.34}/PKG-INFO +1 -1
  2. {entrygraph-0.1.32 → entrygraph-0.1.34}/src/entrygraph/_version.py +2 -2
  3. {entrygraph-0.1.32 → entrygraph-0.1.34}/src/entrygraph/api.py +31 -2
  4. {entrygraph-0.1.32 → entrygraph-0.1.34}/src/entrygraph/detect/entrypoints/javascript.py +4 -0
  5. {entrygraph-0.1.32 → entrygraph-0.1.34}/src/entrygraph/pipeline/scanner.py +16 -4
  6. {entrygraph-0.1.32 → entrygraph-0.1.34}/tests/test_reachability.py +49 -0
  7. {entrygraph-0.1.32 → entrygraph-0.1.34}/.github/workflows/ci.yml +0 -0
  8. {entrygraph-0.1.32 → entrygraph-0.1.34}/.github/workflows/release.yml +0 -0
  9. {entrygraph-0.1.32 → entrygraph-0.1.34}/.gitignore +0 -0
  10. {entrygraph-0.1.32 → entrygraph-0.1.34}/LICENSE +0 -0
  11. {entrygraph-0.1.32 → entrygraph-0.1.34}/README.md +0 -0
  12. {entrygraph-0.1.32 → entrygraph-0.1.34}/RELEASING.md +0 -0
  13. {entrygraph-0.1.32 → entrygraph-0.1.34}/pyproject.toml +0 -0
  14. {entrygraph-0.1.32 → entrygraph-0.1.34}/src/entrygraph/__init__.py +0 -0
  15. {entrygraph-0.1.32 → entrygraph-0.1.34}/src/entrygraph/__main__.py +0 -0
  16. {entrygraph-0.1.32 → entrygraph-0.1.34}/src/entrygraph/cli/__init__.py +0 -0
  17. {entrygraph-0.1.32 → entrygraph-0.1.34}/src/entrygraph/cli/main.py +0 -0
  18. {entrygraph-0.1.32 → entrygraph-0.1.34}/src/entrygraph/cli/render.py +0 -0
  19. {entrygraph-0.1.32 → entrygraph-0.1.34}/src/entrygraph/data/sinks/csharp.toml +0 -0
  20. {entrygraph-0.1.32 → entrygraph-0.1.34}/src/entrygraph/data/sinks/go.toml +0 -0
  21. {entrygraph-0.1.32 → entrygraph-0.1.34}/src/entrygraph/data/sinks/java.toml +0 -0
  22. {entrygraph-0.1.32 → entrygraph-0.1.34}/src/entrygraph/data/sinks/javascript.toml +0 -0
  23. {entrygraph-0.1.32 → entrygraph-0.1.34}/src/entrygraph/data/sinks/lib_javascript.toml +0 -0
  24. {entrygraph-0.1.32 → entrygraph-0.1.34}/src/entrygraph/data/sinks/lib_python.toml +0 -0
  25. {entrygraph-0.1.32 → entrygraph-0.1.34}/src/entrygraph/data/sinks/php.toml +0 -0
  26. {entrygraph-0.1.32 → entrygraph-0.1.34}/src/entrygraph/data/sinks/python.toml +0 -0
  27. {entrygraph-0.1.32 → entrygraph-0.1.34}/src/entrygraph/data/sinks/ruby.toml +0 -0
  28. {entrygraph-0.1.32 → entrygraph-0.1.34}/src/entrygraph/data/sinks/rust.toml +0 -0
  29. {entrygraph-0.1.32 → entrygraph-0.1.34}/src/entrygraph/db/__init__.py +0 -0
  30. {entrygraph-0.1.32 → entrygraph-0.1.34}/src/entrygraph/db/engine.py +0 -0
  31. {entrygraph-0.1.32 → entrygraph-0.1.34}/src/entrygraph/db/meta.py +0 -0
  32. {entrygraph-0.1.32 → entrygraph-0.1.34}/src/entrygraph/db/models.py +0 -0
  33. {entrygraph-0.1.32 → entrygraph-0.1.34}/src/entrygraph/db/queries.py +0 -0
  34. {entrygraph-0.1.32 → entrygraph-0.1.34}/src/entrygraph/detect/__init__.py +0 -0
  35. {entrygraph-0.1.32 → entrygraph-0.1.34}/src/entrygraph/detect/entrypoints/__init__.py +0 -0
  36. {entrygraph-0.1.32 → entrygraph-0.1.34}/src/entrygraph/detect/entrypoints/base.py +0 -0
  37. {entrygraph-0.1.32 → entrygraph-0.1.34}/src/entrygraph/detect/entrypoints/configs.py +0 -0
  38. {entrygraph-0.1.32 → entrygraph-0.1.34}/src/entrygraph/detect/entrypoints/csharp.py +0 -0
  39. {entrygraph-0.1.32 → entrygraph-0.1.34}/src/entrygraph/detect/entrypoints/golang.py +0 -0
  40. {entrygraph-0.1.32 → entrygraph-0.1.34}/src/entrygraph/detect/entrypoints/java.py +0 -0
  41. {entrygraph-0.1.32 → entrygraph-0.1.34}/src/entrygraph/detect/entrypoints/php.py +0 -0
  42. {entrygraph-0.1.32 → entrygraph-0.1.34}/src/entrygraph/detect/entrypoints/python.py +0 -0
  43. {entrygraph-0.1.32 → entrygraph-0.1.34}/src/entrygraph/detect/entrypoints/ruby.py +0 -0
  44. {entrygraph-0.1.32 → entrygraph-0.1.34}/src/entrygraph/detect/entrypoints/rust.py +0 -0
  45. {entrygraph-0.1.32 → entrygraph-0.1.34}/src/entrygraph/detect/frameworks.py +0 -0
  46. {entrygraph-0.1.32 → entrygraph-0.1.34}/src/entrygraph/detect/manifests.py +0 -0
  47. {entrygraph-0.1.32 → entrygraph-0.1.34}/src/entrygraph/detect/taint.py +0 -0
  48. {entrygraph-0.1.32 → entrygraph-0.1.34}/src/entrygraph/errors.py +0 -0
  49. {entrygraph-0.1.32 → entrygraph-0.1.34}/src/entrygraph/extract/__init__.py +0 -0
  50. {entrygraph-0.1.32 → entrygraph-0.1.34}/src/entrygraph/extract/base.py +0 -0
  51. {entrygraph-0.1.32 → entrygraph-0.1.34}/src/entrygraph/extract/csharp.py +0 -0
  52. {entrygraph-0.1.32 → entrygraph-0.1.34}/src/entrygraph/extract/golang.py +0 -0
  53. {entrygraph-0.1.32 → entrygraph-0.1.34}/src/entrygraph/extract/ir.py +0 -0
  54. {entrygraph-0.1.32 → entrygraph-0.1.34}/src/entrygraph/extract/java.py +0 -0
  55. {entrygraph-0.1.32 → entrygraph-0.1.34}/src/entrygraph/extract/javascript.py +0 -0
  56. {entrygraph-0.1.32 → entrygraph-0.1.34}/src/entrygraph/extract/php.py +0 -0
  57. {entrygraph-0.1.32 → entrygraph-0.1.34}/src/entrygraph/extract/python.py +0 -0
  58. {entrygraph-0.1.32 → entrygraph-0.1.34}/src/entrygraph/extract/registry.py +0 -0
  59. {entrygraph-0.1.32 → entrygraph-0.1.34}/src/entrygraph/extract/ruby.py +0 -0
  60. {entrygraph-0.1.32 → entrygraph-0.1.34}/src/entrygraph/extract/rust.py +0 -0
  61. {entrygraph-0.1.32 → entrygraph-0.1.34}/src/entrygraph/fs/__init__.py +0 -0
  62. {entrygraph-0.1.32 → entrygraph-0.1.34}/src/entrygraph/fs/hashing.py +0 -0
  63. {entrygraph-0.1.32 → entrygraph-0.1.34}/src/entrygraph/fs/lang.py +0 -0
  64. {entrygraph-0.1.32 → entrygraph-0.1.34}/src/entrygraph/fs/walker.py +0 -0
  65. {entrygraph-0.1.32 → entrygraph-0.1.34}/src/entrygraph/graph/__init__.py +0 -0
  66. {entrygraph-0.1.32 → entrygraph-0.1.34}/src/entrygraph/graph/adjacency.py +0 -0
  67. {entrygraph-0.1.32 → entrygraph-0.1.34}/src/entrygraph/graph/cte.py +0 -0
  68. {entrygraph-0.1.32 → entrygraph-0.1.34}/src/entrygraph/graph/scoring.py +0 -0
  69. {entrygraph-0.1.32 → entrygraph-0.1.34}/src/entrygraph/kinds.py +0 -0
  70. {entrygraph-0.1.32 → entrygraph-0.1.34}/src/entrygraph/parsing/__init__.py +0 -0
  71. {entrygraph-0.1.32 → entrygraph-0.1.34}/src/entrygraph/parsing/parsers.py +0 -0
  72. {entrygraph-0.1.32 → entrygraph-0.1.34}/src/entrygraph/parsing/queries.py +0 -0
  73. {entrygraph-0.1.32 → entrygraph-0.1.34}/src/entrygraph/pipeline/__init__.py +0 -0
  74. {entrygraph-0.1.32 → entrygraph-0.1.34}/src/entrygraph/pipeline/worker.py +0 -0
  75. {entrygraph-0.1.32 → entrygraph-0.1.34}/src/entrygraph/pipeline/writer.py +0 -0
  76. {entrygraph-0.1.32 → entrygraph-0.1.34}/src/entrygraph/py.typed +0 -0
  77. {entrygraph-0.1.32 → entrygraph-0.1.34}/src/entrygraph/queries/csharp/calls.scm +0 -0
  78. {entrygraph-0.1.32 → entrygraph-0.1.34}/src/entrygraph/queries/csharp/definitions.scm +0 -0
  79. {entrygraph-0.1.32 → entrygraph-0.1.34}/src/entrygraph/queries/csharp/imports.scm +0 -0
  80. {entrygraph-0.1.32 → entrygraph-0.1.34}/src/entrygraph/queries/go/calls.scm +0 -0
  81. {entrygraph-0.1.32 → entrygraph-0.1.34}/src/entrygraph/queries/go/definitions.scm +0 -0
  82. {entrygraph-0.1.32 → entrygraph-0.1.34}/src/entrygraph/queries/go/imports.scm +0 -0
  83. {entrygraph-0.1.32 → entrygraph-0.1.34}/src/entrygraph/queries/java/calls.scm +0 -0
  84. {entrygraph-0.1.32 → entrygraph-0.1.34}/src/entrygraph/queries/java/definitions.scm +0 -0
  85. {entrygraph-0.1.32 → entrygraph-0.1.34}/src/entrygraph/queries/java/imports.scm +0 -0
  86. {entrygraph-0.1.32 → entrygraph-0.1.34}/src/entrygraph/queries/javascript/calls.scm +0 -0
  87. {entrygraph-0.1.32 → entrygraph-0.1.34}/src/entrygraph/queries/javascript/definitions.scm +0 -0
  88. {entrygraph-0.1.32 → entrygraph-0.1.34}/src/entrygraph/queries/javascript/imports.scm +0 -0
  89. {entrygraph-0.1.32 → entrygraph-0.1.34}/src/entrygraph/queries/php/calls.scm +0 -0
  90. {entrygraph-0.1.32 → entrygraph-0.1.34}/src/entrygraph/queries/php/definitions.scm +0 -0
  91. {entrygraph-0.1.32 → entrygraph-0.1.34}/src/entrygraph/queries/php/imports.scm +0 -0
  92. {entrygraph-0.1.32 → entrygraph-0.1.34}/src/entrygraph/queries/python/calls.scm +0 -0
  93. {entrygraph-0.1.32 → entrygraph-0.1.34}/src/entrygraph/queries/python/definitions.scm +0 -0
  94. {entrygraph-0.1.32 → entrygraph-0.1.34}/src/entrygraph/queries/python/imports.scm +0 -0
  95. {entrygraph-0.1.32 → entrygraph-0.1.34}/src/entrygraph/queries/ruby/calls.scm +0 -0
  96. {entrygraph-0.1.32 → entrygraph-0.1.34}/src/entrygraph/queries/ruby/definitions.scm +0 -0
  97. {entrygraph-0.1.32 → entrygraph-0.1.34}/src/entrygraph/queries/ruby/imports.scm +0 -0
  98. {entrygraph-0.1.32 → entrygraph-0.1.34}/src/entrygraph/queries/rust/calls.scm +0 -0
  99. {entrygraph-0.1.32 → entrygraph-0.1.34}/src/entrygraph/queries/rust/definitions.scm +0 -0
  100. {entrygraph-0.1.32 → entrygraph-0.1.34}/src/entrygraph/queries/rust/imports.scm +0 -0
  101. {entrygraph-0.1.32 → entrygraph-0.1.34}/src/entrygraph/resolve/__init__.py +0 -0
  102. {entrygraph-0.1.32 → entrygraph-0.1.34}/src/entrygraph/resolve/externals.py +0 -0
  103. {entrygraph-0.1.32 → entrygraph-0.1.34}/src/entrygraph/resolve/hierarchy.py +0 -0
  104. {entrygraph-0.1.32 → entrygraph-0.1.34}/src/entrygraph/resolve/resolver.py +0 -0
  105. {entrygraph-0.1.32 → entrygraph-0.1.34}/src/entrygraph/resolve/symbol_table.py +0 -0
  106. {entrygraph-0.1.32 → entrygraph-0.1.34}/src/entrygraph/results.py +0 -0
  107. {entrygraph-0.1.32 → entrygraph-0.1.34}/tests/conftest.py +0 -0
  108. {entrygraph-0.1.32 → entrygraph-0.1.34}/tests/fixtures/csharp/aspnet_app/Controllers/ReportsController.cs +0 -0
  109. {entrygraph-0.1.32 → entrygraph-0.1.34}/tests/fixtures/csharp/aspnet_app/Program.cs +0 -0
  110. {entrygraph-0.1.32 → entrygraph-0.1.34}/tests/fixtures/csharp/aspnet_app/Services/ReportService.cs +0 -0
  111. {entrygraph-0.1.32 → entrygraph-0.1.34}/tests/fixtures/csharp/aspnet_app/app.csproj +0 -0
  112. {entrygraph-0.1.32 → entrygraph-0.1.34}/tests/fixtures/csharp/minimalapi_app/Program.cs +0 -0
  113. {entrygraph-0.1.32 → entrygraph-0.1.34}/tests/fixtures/csharp/minimalapi_app/app.csproj +0 -0
  114. {entrygraph-0.1.32 → entrygraph-0.1.34}/tests/fixtures/go/gin_app/go.mod +0 -0
  115. {entrygraph-0.1.32 → entrygraph-0.1.34}/tests/fixtures/go/gin_app/main.go +0 -0
  116. {entrygraph-0.1.32 → entrygraph-0.1.34}/tests/fixtures/go/gin_app/service.go +0 -0
  117. {entrygraph-0.1.32 → entrygraph-0.1.34}/tests/fixtures/go/nethttp_app/go.mod +0 -0
  118. {entrygraph-0.1.32 → entrygraph-0.1.34}/tests/fixtures/go/nethttp_app/main.go +0 -0
  119. {entrygraph-0.1.32 → entrygraph-0.1.34}/tests/fixtures/java/methodref_app/pom.xml +0 -0
  120. {entrygraph-0.1.32 → entrygraph-0.1.34}/tests/fixtures/java/methodref_app/src/main/java/com/example/App.java +0 -0
  121. {entrygraph-0.1.32 → entrygraph-0.1.34}/tests/fixtures/java/spring_app/pom.xml +0 -0
  122. {entrygraph-0.1.32 → entrygraph-0.1.34}/tests/fixtures/java/spring_app/src/main/java/com/example/Application.java +0 -0
  123. {entrygraph-0.1.32 → entrygraph-0.1.34}/tests/fixtures/java/spring_app/src/main/java/com/example/ReportRunner.java +0 -0
  124. {entrygraph-0.1.32 → entrygraph-0.1.34}/tests/fixtures/java/spring_app/src/main/java/com/example/ReportService.java +0 -0
  125. {entrygraph-0.1.32 → entrygraph-0.1.34}/tests/fixtures/java/spring_app/src/main/java/com/example/UserController.java +0 -0
  126. {entrygraph-0.1.32 → entrygraph-0.1.34}/tests/fixtures/javascript/commonjs_app/server.js +0 -0
  127. {entrygraph-0.1.32 → entrygraph-0.1.34}/tests/fixtures/javascript/express_app/package.json +0 -0
  128. {entrygraph-0.1.32 → entrygraph-0.1.34}/tests/fixtures/javascript/express_app/src/routes.js +0 -0
  129. {entrygraph-0.1.32 → entrygraph-0.1.34}/tests/fixtures/javascript/express_app/src/services.js +0 -0
  130. {entrygraph-0.1.32 → entrygraph-0.1.34}/tests/fixtures/php/laravel_app/app/Http/Controllers/ReportController.php +0 -0
  131. {entrygraph-0.1.32 → entrygraph-0.1.34}/tests/fixtures/php/laravel_app/artisan +0 -0
  132. {entrygraph-0.1.32 → entrygraph-0.1.34}/tests/fixtures/php/laravel_app/composer.json +0 -0
  133. {entrygraph-0.1.32 → entrygraph-0.1.34}/tests/fixtures/php/laravel_app/routes/web.php +0 -0
  134. {entrygraph-0.1.32 → entrygraph-0.1.34}/tests/fixtures/python/chained_sinks/app.py +0 -0
  135. {entrygraph-0.1.32 → entrygraph-0.1.34}/tests/fixtures/python/flask_app/app/__init__.py +0 -0
  136. {entrygraph-0.1.32 → entrygraph-0.1.34}/tests/fixtures/python/flask_app/app/db.py +0 -0
  137. {entrygraph-0.1.32 → entrygraph-0.1.34}/tests/fixtures/python/flask_app/app/routes.py +0 -0
  138. {entrygraph-0.1.32 → entrygraph-0.1.34}/tests/fixtures/python/flask_app/app/services.py +0 -0
  139. {entrygraph-0.1.32 → entrygraph-0.1.34}/tests/fixtures/python/flask_app/cli.py +0 -0
  140. {entrygraph-0.1.32 → entrygraph-0.1.34}/tests/fixtures/python/flask_app/requirements.txt +0 -0
  141. {entrygraph-0.1.32 → entrygraph-0.1.34}/tests/fixtures/python/fuzzy_sink/app.py +0 -0
  142. {entrygraph-0.1.32 → entrygraph-0.1.34}/tests/fixtures/python/heal_fidelity/caller.py +0 -0
  143. {entrygraph-0.1.32 → entrygraph-0.1.34}/tests/fixtures/python/heal_fidelity/worker.py +0 -0
  144. {entrygraph-0.1.32 → entrygraph-0.1.34}/tests/fixtures/python/may_continue/app.py +0 -0
  145. {entrygraph-0.1.32 → entrygraph-0.1.34}/tests/fixtures/python/sanitizer/app.py +0 -0
  146. {entrygraph-0.1.32 → entrygraph-0.1.34}/tests/fixtures/python/taint_source/handler.py +0 -0
  147. {entrygraph-0.1.32 → entrygraph-0.1.34}/tests/fixtures/ruby/sinatra_app/Gemfile +0 -0
  148. {entrygraph-0.1.32 → entrygraph-0.1.34}/tests/fixtures/ruby/sinatra_app/app.rb +0 -0
  149. {entrygraph-0.1.32 → entrygraph-0.1.34}/tests/fixtures/ruby/sinatra_app/services/runner.rb +0 -0
  150. {entrygraph-0.1.32 → entrygraph-0.1.34}/tests/fixtures/rust/axum_app/Cargo.toml +0 -0
  151. {entrygraph-0.1.32 → entrygraph-0.1.34}/tests/fixtures/rust/axum_app/src/handlers.rs +0 -0
  152. {entrygraph-0.1.32 → entrygraph-0.1.34}/tests/fixtures/rust/axum_app/src/main.rs +0 -0
  153. {entrygraph-0.1.32 → entrygraph-0.1.34}/tests/fixtures/rust/axum_callback_app/Cargo.toml +0 -0
  154. {entrygraph-0.1.32 → entrygraph-0.1.34}/tests/fixtures/rust/axum_callback_app/src/main.rs +0 -0
  155. {entrygraph-0.1.32 → entrygraph-0.1.34}/tests/fixtures/rust/scoped_sink_app/Cargo.toml +0 -0
  156. {entrygraph-0.1.32 → entrygraph-0.1.34}/tests/fixtures/rust/scoped_sink_app/src/main.rs +0 -0
  157. {entrygraph-0.1.32 → entrygraph-0.1.34}/tests/test_api.py +0 -0
  158. {entrygraph-0.1.32 → entrygraph-0.1.34}/tests/test_cli.py +0 -0
  159. {entrygraph-0.1.32 → entrygraph-0.1.34}/tests/test_commonjs.py +0 -0
  160. {entrygraph-0.1.32 → entrygraph-0.1.34}/tests/test_csharp_callbacks.py +0 -0
  161. {entrygraph-0.1.32 → entrygraph-0.1.34}/tests/test_cte_bounds.py +0 -0
  162. {entrygraph-0.1.32 → entrygraph-0.1.34}/tests/test_engine_pragmas.py +0 -0
  163. {entrygraph-0.1.32 → entrygraph-0.1.34}/tests/test_entrypoint_expansion.py +0 -0
  164. {entrygraph-0.1.32 → entrygraph-0.1.34}/tests/test_entrypoints.py +0 -0
  165. {entrygraph-0.1.32 → entrygraph-0.1.34}/tests/test_extract_csharp.py +0 -0
  166. {entrygraph-0.1.32 → entrygraph-0.1.34}/tests/test_extract_go.py +0 -0
  167. {entrygraph-0.1.32 → entrygraph-0.1.34}/tests/test_extract_java.py +0 -0
  168. {entrygraph-0.1.32 → entrygraph-0.1.34}/tests/test_extract_javascript.py +0 -0
  169. {entrygraph-0.1.32 → entrygraph-0.1.34}/tests/test_extract_php.py +0 -0
  170. {entrygraph-0.1.32 → entrygraph-0.1.34}/tests/test_extract_python.py +0 -0
  171. {entrygraph-0.1.32 → entrygraph-0.1.34}/tests/test_extract_ruby.py +0 -0
  172. {entrygraph-0.1.32 → entrygraph-0.1.34}/tests/test_extract_rust.py +0 -0
  173. {entrygraph-0.1.32 → entrygraph-0.1.34}/tests/test_frameworks.py +0 -0
  174. {entrygraph-0.1.32 → entrygraph-0.1.34}/tests/test_fuzzy_sink.py +0 -0
  175. {entrygraph-0.1.32 → entrygraph-0.1.34}/tests/test_go_callbacks.py +0 -0
  176. {entrygraph-0.1.32 → entrygraph-0.1.34}/tests/test_hardening.py +0 -0
  177. {entrygraph-0.1.32 → entrygraph-0.1.34}/tests/test_heal_fidelity.py +0 -0
  178. {entrygraph-0.1.32 → entrygraph-0.1.34}/tests/test_incremental.py +0 -0
  179. {entrygraph-0.1.32 → entrygraph-0.1.34}/tests/test_indexer.py +0 -0
  180. {entrygraph-0.1.32 → entrygraph-0.1.34}/tests/test_java_callbacks.py +0 -0
  181. {entrygraph-0.1.32 → entrygraph-0.1.34}/tests/test_lang.py +0 -0
  182. {entrygraph-0.1.32 → entrygraph-0.1.34}/tests/test_manifests.py +0 -0
  183. {entrygraph-0.1.32 → entrygraph-0.1.34}/tests/test_may_continue.py +0 -0
  184. {entrygraph-0.1.32 → entrygraph-0.1.34}/tests/test_models.py +0 -0
  185. {entrygraph-0.1.32 → entrygraph-0.1.34}/tests/test_pool.py +0 -0
  186. {entrygraph-0.1.32 → entrygraph-0.1.34}/tests/test_registry_cache.py +0 -0
  187. {entrygraph-0.1.32 → entrygraph-0.1.34}/tests/test_render.py +0 -0
  188. {entrygraph-0.1.32 → entrygraph-0.1.34}/tests/test_resolver.py +0 -0
  189. {entrygraph-0.1.32 → entrygraph-0.1.34}/tests/test_rust_callbacks.py +0 -0
  190. {entrygraph-0.1.32 → entrygraph-0.1.34}/tests/test_rust_scoped_sinks.py +0 -0
  191. {entrygraph-0.1.32 → entrygraph-0.1.34}/tests/test_sanitizer_languages.py +0 -0
  192. {entrygraph-0.1.32 → entrygraph-0.1.34}/tests/test_scoring.py +0 -0
  193. {entrygraph-0.1.32 → entrygraph-0.1.34}/tests/test_sink_catalog.py +0 -0
  194. {entrygraph-0.1.32 → entrygraph-0.1.34}/tests/test_taint.py +0 -0
  195. {entrygraph-0.1.32 → entrygraph-0.1.34}/tests/test_taint_sanitizers.py +0 -0
  196. {entrygraph-0.1.32 → entrygraph-0.1.34}/tests/test_taint_sources.py +0 -0
  197. {entrygraph-0.1.32 → entrygraph-0.1.34}/tests/test_walker.py +0 -0
  198. {entrygraph-0.1.32 → entrygraph-0.1.34}/uv.lock +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: entrygraph
3
- Version: 0.1.32
3
+ Version: 0.1.34
4
4
  Summary: Language-agnostic code graph: query symbols, entrypoints, and source-to-sink call paths from a SQLite index
5
5
  Project-URL: Repository, https://github.com/brettbergin/entrygraph
6
6
  Author-email: Brett Bergin <brettberginbc@yahoo.com>
@@ -18,7 +18,7 @@ version_tuple: tuple[int | str, ...]
18
18
  commit_id: str | None
19
19
  __commit_id__: str | None
20
20
 
21
- __version__ = version = '0.1.32'
22
- __version_tuple__ = version_tuple = (0, 1, 32)
21
+ __version__ = version = '0.1.34'
22
+ __version_tuple__ = version_tuple = (0, 1, 34)
23
23
 
24
24
  __commit_id__ = commit_id = None
@@ -331,11 +331,28 @@ class CodeGraph:
331
331
  return PathResults()
332
332
  traverser = self._traverser(session, engine, kinds, floor, include_cha)
333
333
  raw_paths = traverser.paths(sources, sinks, max_depth=max_depth, max_paths=max_paths)
334
+ truncated = bool(getattr(raw_paths, "truncated", False))
335
+ if sink_category is not None:
336
+ # A category sink is tagged per-EDGE (with arg hints), but traversal
337
+ # stops at the sink SYMBOL. A path reaching that symbol via an
338
+ # untagged sibling edge — createHash('sha256') vs the md5 edge that
339
+ # tagged the shared createHash symbol — is a false positive. Keep a
340
+ # path only if its terminal edge is a category sink (or its terminal
341
+ # node is an explicit --sink symbol). This also drops degenerate
342
+ # length-1 `--source '*'` self-matches, which have no terminal edge.
343
+ explicit_ids = self._spec_to_ids(session, sink) if sink is not None else set()
344
+ sink_edges = self._category_sink_edge_ids(session, sink_category)
345
+ raw_paths = [
346
+ p
347
+ for p in raw_paths
348
+ if p[-1][0] in explicit_ids
349
+ or (p[-1][1] is not None and p[-1][1].edge_id in sink_edges)
350
+ ]
334
351
  if not raw_paths:
335
352
  # 0 paths may mean the visit budget was spent before any sink was
336
353
  # reached — propagate the flag so this isn't mistaken for "safe".
337
354
  empty = PathResults()
338
- empty.truncated = bool(getattr(raw_paths, "truncated", False))
355
+ empty.truncated = truncated
339
356
  return empty
340
357
  all_ids = {node for path in raw_paths for node, _ in path}
341
358
  symbol_map = q.symbols_by_ids(session, all_ids)
@@ -366,7 +383,7 @@ class CodeGraph:
366
383
  # Truncating after the risk rank (not during DFS) is what makes the widen
367
384
  # flags monotonic — a wider edge set can only add candidates to rank.
368
385
  out = PathResults(results[:max_paths])
369
- out.truncated = bool(getattr(raw_paths, "truncated", False))
386
+ out.truncated = truncated
370
387
  return out
371
388
 
372
389
  def reachable(
@@ -522,6 +539,18 @@ class CodeGraph:
522
539
  ids |= set(ep_rows)
523
540
  return ids
524
541
 
542
+ def _category_sink_edge_ids(self, session: Session, sink_category: str) -> set[int]:
543
+ """Edge ids tagged as a sink of `sink_category` — used to require that a
544
+ path terminates at a sink EDGE, not merely a shared sink symbol."""
545
+ registry = self._registry(session)
546
+ sink_ids = registry.ids_for_category(sink_category)
547
+ if not sink_ids:
548
+ return set()
549
+ rows = session.execute(
550
+ select(models.Edge.id).where(models.Edge.sink_id.in_(sink_ids))
551
+ ).scalars()
552
+ return set(rows)
553
+
525
554
  def _sink_ids(self, session: Session, sink, sink_category: str | None) -> set[int]:
526
555
  ids = self._spec_to_ids(session, sink) if sink is not None else set()
527
556
  if sink_category is not None:
@@ -75,6 +75,10 @@ def _router_routes(framework: str):
75
75
  route=route,
76
76
  http_methods=[ref.callee_name.upper()],
77
77
  framework=framework,
78
+ # registration line, so the scanner can bind a
79
+ # handler-passed-by-reference (router.get('/x', ctrl.fn))
80
+ # to the callback edge emitted at the same site.
81
+ span=ref.span,
78
82
  )
79
83
  )
80
84
  return hints
@@ -554,10 +554,17 @@ def _write_edges_and_entrypoints(
554
554
  local_symbol_ids=handler_ids_by_path.get(path, {}),
555
555
  )
556
556
  file_id = file_id_by_path[path]
557
+ # registration line -> handler symbol, for routes whose handler is passed by
558
+ # reference (router.get('/x', ctrl.fn)): the resolver emits a callback edge
559
+ # at the same line, and the entrypoint below binds to it instead of falling
560
+ # back to the module symbol.
561
+ callback_handler_by_line: dict[int, int] = {}
557
562
  for edge in resolver.resolve():
558
563
  is_call = edge.kind is EdgeKind.CALLS
559
564
  sink_id = sink_registry.match(edge.dst_qname, edge.arg_preview) if is_call else None
560
565
  source_id = sink_registry.match_source(edge.dst_qname) if is_call else None
566
+ if edge.kind is EdgeKind.PASSED_AS_CALLBACK and edge.dst_symbol_id is not None:
567
+ callback_handler_by_line.setdefault(edge.line, edge.dst_symbol_id)
561
568
  edge_writer.add(
562
569
  {
563
570
  "id": alloc.take(Edge),
@@ -579,10 +586,15 @@ def _write_edges_and_entrypoints(
579
586
  handler_q = hint.handler_qualified_name or ""
580
587
  # Bind to the handler defined in this file first (so same-package
581
588
  # collisions like per-file `func init()` each keep their own row),
582
- # then the global map, then the file's module symbol as a last resort.
583
- symbol_id = (
584
- per_file.get(handler_q) or symbol_id_by_qname.get(handler_q) or module_ids[path]
585
- )
589
+ # then the global map.
590
+ symbol_id = per_file.get(handler_q) or symbol_id_by_qname.get(handler_q)
591
+ # Route handler passed by reference (router.get('/x', ctrl.fn)) the
592
+ # name isn't a symbol in scope, but the resolver bound the callback at
593
+ # the registration line. Bind the route to that real handler instead of
594
+ # the module, so it (not the whole module) is the http_input source.
595
+ if symbol_id is None and hint.span is not None:
596
+ symbol_id = callback_handler_by_line.get(hint.span.start_line)
597
+ symbol_id = symbol_id or module_ids[path]
586
598
  entrypoint_writer.add(
587
599
  {
588
600
  "id": alloc.take(Entrypoint),
@@ -170,3 +170,52 @@ def test_http_route_handler_is_an_http_input_source(tmp_path):
170
170
  graph.close()
171
171
  chains = [[s.qname for s in p.symbols] for p in paths]
172
172
  assert ["app.runReport", "js:child_process.exec"] in chains
173
+
174
+
175
+ def test_category_path_requires_a_sink_tagged_terminal_edge(tmp_path):
176
+ # createHash('md5') is weak_crypto; createHash('sha256') is not. Both call the
177
+ # same crypto.createHash symbol, so a path must end at the *tagged* edge — the
178
+ # sha256 call must not be reported as weak_crypto (#34 / F-H15).
179
+ (tmp_path / "a.js").write_text(
180
+ 'const crypto = require("crypto");\n'
181
+ 'function weak(x) { return crypto.createHash("md5").update(x).digest("hex"); }\n'
182
+ 'function strong(x) { return crypto.createHash("sha256").update(x).digest("hex"); }\n'
183
+ )
184
+ graph = CodeGraph.index(tmp_path, db=tmp_path / "g.db")
185
+ paths = graph.paths(source="*", sink_category="weak_crypto")
186
+ graph.close()
187
+ chains = [[s.qname for s in p.symbols] for p in paths]
188
+ assert ["a.weak", "js:crypto.createHash"] in chains # md5 kept
189
+ assert all("a.strong" not in c for c in chains) # sha256 dropped
190
+ assert all(len(c) >= 2 for c in chains) # no degenerate single-node paths
191
+
192
+
193
+ def test_route_handler_passed_by_reference_binds_to_the_handler(tmp_path):
194
+ # router.get('/x', ctrl.fn) binds to the module, but the resolver emits a
195
+ # callback edge at the registration line — the route must bind to that real
196
+ # handler so ctrl.fn (not the whole module) is the http_input source, and the
197
+ # taint path resolves WITHOUT --include-callbacks (#34, call-based binding).
198
+ src = tmp_path / "src"
199
+ src.mkdir(parents=True)
200
+ (tmp_path / "package.json").write_text('{"name":"app","dependencies":{"express":"^4"}}')
201
+ (src / "controller.js").write_text(
202
+ 'const { exec } = require("child_process");\n'
203
+ "function getUser(req, res) { exec('lookup ' + req.body.id); }\n"
204
+ "module.exports = { getUser };\n"
205
+ )
206
+ (src / "routes.js").write_text(
207
+ 'const { Router } = require("express");\n'
208
+ 'const ctrl = require("./controller");\n'
209
+ "const router = Router();\n"
210
+ 'router.get("/user", ctrl.getUser);\n'
211
+ "module.exports = router;\n"
212
+ )
213
+ graph = CodeGraph.index(tmp_path, db=tmp_path / "g.db")
214
+ # the route binds to the handler function, not the routes module
215
+ eps = graph.entrypoints(kind="http_route")
216
+ assert eps and eps[0].symbol.qname == "controller.getUser"
217
+ # and the taint path resolves by default (no include_callbacks)
218
+ paths = graph.paths(source_category="http_input", sink_category="command_exec")
219
+ graph.close()
220
+ chains = [[s.qname for s in p.symbols] for p in paths]
221
+ assert ["controller.getUser", "js:child_process.exec"] in chains
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes