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.
- {entrygraph-0.1.32 → entrygraph-0.1.34}/PKG-INFO +1 -1
- {entrygraph-0.1.32 → entrygraph-0.1.34}/src/entrygraph/_version.py +2 -2
- {entrygraph-0.1.32 → entrygraph-0.1.34}/src/entrygraph/api.py +31 -2
- {entrygraph-0.1.32 → entrygraph-0.1.34}/src/entrygraph/detect/entrypoints/javascript.py +4 -0
- {entrygraph-0.1.32 → entrygraph-0.1.34}/src/entrygraph/pipeline/scanner.py +16 -4
- {entrygraph-0.1.32 → entrygraph-0.1.34}/tests/test_reachability.py +49 -0
- {entrygraph-0.1.32 → entrygraph-0.1.34}/.github/workflows/ci.yml +0 -0
- {entrygraph-0.1.32 → entrygraph-0.1.34}/.github/workflows/release.yml +0 -0
- {entrygraph-0.1.32 → entrygraph-0.1.34}/.gitignore +0 -0
- {entrygraph-0.1.32 → entrygraph-0.1.34}/LICENSE +0 -0
- {entrygraph-0.1.32 → entrygraph-0.1.34}/README.md +0 -0
- {entrygraph-0.1.32 → entrygraph-0.1.34}/RELEASING.md +0 -0
- {entrygraph-0.1.32 → entrygraph-0.1.34}/pyproject.toml +0 -0
- {entrygraph-0.1.32 → entrygraph-0.1.34}/src/entrygraph/__init__.py +0 -0
- {entrygraph-0.1.32 → entrygraph-0.1.34}/src/entrygraph/__main__.py +0 -0
- {entrygraph-0.1.32 → entrygraph-0.1.34}/src/entrygraph/cli/__init__.py +0 -0
- {entrygraph-0.1.32 → entrygraph-0.1.34}/src/entrygraph/cli/main.py +0 -0
- {entrygraph-0.1.32 → entrygraph-0.1.34}/src/entrygraph/cli/render.py +0 -0
- {entrygraph-0.1.32 → entrygraph-0.1.34}/src/entrygraph/data/sinks/csharp.toml +0 -0
- {entrygraph-0.1.32 → entrygraph-0.1.34}/src/entrygraph/data/sinks/go.toml +0 -0
- {entrygraph-0.1.32 → entrygraph-0.1.34}/src/entrygraph/data/sinks/java.toml +0 -0
- {entrygraph-0.1.32 → entrygraph-0.1.34}/src/entrygraph/data/sinks/javascript.toml +0 -0
- {entrygraph-0.1.32 → entrygraph-0.1.34}/src/entrygraph/data/sinks/lib_javascript.toml +0 -0
- {entrygraph-0.1.32 → entrygraph-0.1.34}/src/entrygraph/data/sinks/lib_python.toml +0 -0
- {entrygraph-0.1.32 → entrygraph-0.1.34}/src/entrygraph/data/sinks/php.toml +0 -0
- {entrygraph-0.1.32 → entrygraph-0.1.34}/src/entrygraph/data/sinks/python.toml +0 -0
- {entrygraph-0.1.32 → entrygraph-0.1.34}/src/entrygraph/data/sinks/ruby.toml +0 -0
- {entrygraph-0.1.32 → entrygraph-0.1.34}/src/entrygraph/data/sinks/rust.toml +0 -0
- {entrygraph-0.1.32 → entrygraph-0.1.34}/src/entrygraph/db/__init__.py +0 -0
- {entrygraph-0.1.32 → entrygraph-0.1.34}/src/entrygraph/db/engine.py +0 -0
- {entrygraph-0.1.32 → entrygraph-0.1.34}/src/entrygraph/db/meta.py +0 -0
- {entrygraph-0.1.32 → entrygraph-0.1.34}/src/entrygraph/db/models.py +0 -0
- {entrygraph-0.1.32 → entrygraph-0.1.34}/src/entrygraph/db/queries.py +0 -0
- {entrygraph-0.1.32 → entrygraph-0.1.34}/src/entrygraph/detect/__init__.py +0 -0
- {entrygraph-0.1.32 → entrygraph-0.1.34}/src/entrygraph/detect/entrypoints/__init__.py +0 -0
- {entrygraph-0.1.32 → entrygraph-0.1.34}/src/entrygraph/detect/entrypoints/base.py +0 -0
- {entrygraph-0.1.32 → entrygraph-0.1.34}/src/entrygraph/detect/entrypoints/configs.py +0 -0
- {entrygraph-0.1.32 → entrygraph-0.1.34}/src/entrygraph/detect/entrypoints/csharp.py +0 -0
- {entrygraph-0.1.32 → entrygraph-0.1.34}/src/entrygraph/detect/entrypoints/golang.py +0 -0
- {entrygraph-0.1.32 → entrygraph-0.1.34}/src/entrygraph/detect/entrypoints/java.py +0 -0
- {entrygraph-0.1.32 → entrygraph-0.1.34}/src/entrygraph/detect/entrypoints/php.py +0 -0
- {entrygraph-0.1.32 → entrygraph-0.1.34}/src/entrygraph/detect/entrypoints/python.py +0 -0
- {entrygraph-0.1.32 → entrygraph-0.1.34}/src/entrygraph/detect/entrypoints/ruby.py +0 -0
- {entrygraph-0.1.32 → entrygraph-0.1.34}/src/entrygraph/detect/entrypoints/rust.py +0 -0
- {entrygraph-0.1.32 → entrygraph-0.1.34}/src/entrygraph/detect/frameworks.py +0 -0
- {entrygraph-0.1.32 → entrygraph-0.1.34}/src/entrygraph/detect/manifests.py +0 -0
- {entrygraph-0.1.32 → entrygraph-0.1.34}/src/entrygraph/detect/taint.py +0 -0
- {entrygraph-0.1.32 → entrygraph-0.1.34}/src/entrygraph/errors.py +0 -0
- {entrygraph-0.1.32 → entrygraph-0.1.34}/src/entrygraph/extract/__init__.py +0 -0
- {entrygraph-0.1.32 → entrygraph-0.1.34}/src/entrygraph/extract/base.py +0 -0
- {entrygraph-0.1.32 → entrygraph-0.1.34}/src/entrygraph/extract/csharp.py +0 -0
- {entrygraph-0.1.32 → entrygraph-0.1.34}/src/entrygraph/extract/golang.py +0 -0
- {entrygraph-0.1.32 → entrygraph-0.1.34}/src/entrygraph/extract/ir.py +0 -0
- {entrygraph-0.1.32 → entrygraph-0.1.34}/src/entrygraph/extract/java.py +0 -0
- {entrygraph-0.1.32 → entrygraph-0.1.34}/src/entrygraph/extract/javascript.py +0 -0
- {entrygraph-0.1.32 → entrygraph-0.1.34}/src/entrygraph/extract/php.py +0 -0
- {entrygraph-0.1.32 → entrygraph-0.1.34}/src/entrygraph/extract/python.py +0 -0
- {entrygraph-0.1.32 → entrygraph-0.1.34}/src/entrygraph/extract/registry.py +0 -0
- {entrygraph-0.1.32 → entrygraph-0.1.34}/src/entrygraph/extract/ruby.py +0 -0
- {entrygraph-0.1.32 → entrygraph-0.1.34}/src/entrygraph/extract/rust.py +0 -0
- {entrygraph-0.1.32 → entrygraph-0.1.34}/src/entrygraph/fs/__init__.py +0 -0
- {entrygraph-0.1.32 → entrygraph-0.1.34}/src/entrygraph/fs/hashing.py +0 -0
- {entrygraph-0.1.32 → entrygraph-0.1.34}/src/entrygraph/fs/lang.py +0 -0
- {entrygraph-0.1.32 → entrygraph-0.1.34}/src/entrygraph/fs/walker.py +0 -0
- {entrygraph-0.1.32 → entrygraph-0.1.34}/src/entrygraph/graph/__init__.py +0 -0
- {entrygraph-0.1.32 → entrygraph-0.1.34}/src/entrygraph/graph/adjacency.py +0 -0
- {entrygraph-0.1.32 → entrygraph-0.1.34}/src/entrygraph/graph/cte.py +0 -0
- {entrygraph-0.1.32 → entrygraph-0.1.34}/src/entrygraph/graph/scoring.py +0 -0
- {entrygraph-0.1.32 → entrygraph-0.1.34}/src/entrygraph/kinds.py +0 -0
- {entrygraph-0.1.32 → entrygraph-0.1.34}/src/entrygraph/parsing/__init__.py +0 -0
- {entrygraph-0.1.32 → entrygraph-0.1.34}/src/entrygraph/parsing/parsers.py +0 -0
- {entrygraph-0.1.32 → entrygraph-0.1.34}/src/entrygraph/parsing/queries.py +0 -0
- {entrygraph-0.1.32 → entrygraph-0.1.34}/src/entrygraph/pipeline/__init__.py +0 -0
- {entrygraph-0.1.32 → entrygraph-0.1.34}/src/entrygraph/pipeline/worker.py +0 -0
- {entrygraph-0.1.32 → entrygraph-0.1.34}/src/entrygraph/pipeline/writer.py +0 -0
- {entrygraph-0.1.32 → entrygraph-0.1.34}/src/entrygraph/py.typed +0 -0
- {entrygraph-0.1.32 → entrygraph-0.1.34}/src/entrygraph/queries/csharp/calls.scm +0 -0
- {entrygraph-0.1.32 → entrygraph-0.1.34}/src/entrygraph/queries/csharp/definitions.scm +0 -0
- {entrygraph-0.1.32 → entrygraph-0.1.34}/src/entrygraph/queries/csharp/imports.scm +0 -0
- {entrygraph-0.1.32 → entrygraph-0.1.34}/src/entrygraph/queries/go/calls.scm +0 -0
- {entrygraph-0.1.32 → entrygraph-0.1.34}/src/entrygraph/queries/go/definitions.scm +0 -0
- {entrygraph-0.1.32 → entrygraph-0.1.34}/src/entrygraph/queries/go/imports.scm +0 -0
- {entrygraph-0.1.32 → entrygraph-0.1.34}/src/entrygraph/queries/java/calls.scm +0 -0
- {entrygraph-0.1.32 → entrygraph-0.1.34}/src/entrygraph/queries/java/definitions.scm +0 -0
- {entrygraph-0.1.32 → entrygraph-0.1.34}/src/entrygraph/queries/java/imports.scm +0 -0
- {entrygraph-0.1.32 → entrygraph-0.1.34}/src/entrygraph/queries/javascript/calls.scm +0 -0
- {entrygraph-0.1.32 → entrygraph-0.1.34}/src/entrygraph/queries/javascript/definitions.scm +0 -0
- {entrygraph-0.1.32 → entrygraph-0.1.34}/src/entrygraph/queries/javascript/imports.scm +0 -0
- {entrygraph-0.1.32 → entrygraph-0.1.34}/src/entrygraph/queries/php/calls.scm +0 -0
- {entrygraph-0.1.32 → entrygraph-0.1.34}/src/entrygraph/queries/php/definitions.scm +0 -0
- {entrygraph-0.1.32 → entrygraph-0.1.34}/src/entrygraph/queries/php/imports.scm +0 -0
- {entrygraph-0.1.32 → entrygraph-0.1.34}/src/entrygraph/queries/python/calls.scm +0 -0
- {entrygraph-0.1.32 → entrygraph-0.1.34}/src/entrygraph/queries/python/definitions.scm +0 -0
- {entrygraph-0.1.32 → entrygraph-0.1.34}/src/entrygraph/queries/python/imports.scm +0 -0
- {entrygraph-0.1.32 → entrygraph-0.1.34}/src/entrygraph/queries/ruby/calls.scm +0 -0
- {entrygraph-0.1.32 → entrygraph-0.1.34}/src/entrygraph/queries/ruby/definitions.scm +0 -0
- {entrygraph-0.1.32 → entrygraph-0.1.34}/src/entrygraph/queries/ruby/imports.scm +0 -0
- {entrygraph-0.1.32 → entrygraph-0.1.34}/src/entrygraph/queries/rust/calls.scm +0 -0
- {entrygraph-0.1.32 → entrygraph-0.1.34}/src/entrygraph/queries/rust/definitions.scm +0 -0
- {entrygraph-0.1.32 → entrygraph-0.1.34}/src/entrygraph/queries/rust/imports.scm +0 -0
- {entrygraph-0.1.32 → entrygraph-0.1.34}/src/entrygraph/resolve/__init__.py +0 -0
- {entrygraph-0.1.32 → entrygraph-0.1.34}/src/entrygraph/resolve/externals.py +0 -0
- {entrygraph-0.1.32 → entrygraph-0.1.34}/src/entrygraph/resolve/hierarchy.py +0 -0
- {entrygraph-0.1.32 → entrygraph-0.1.34}/src/entrygraph/resolve/resolver.py +0 -0
- {entrygraph-0.1.32 → entrygraph-0.1.34}/src/entrygraph/resolve/symbol_table.py +0 -0
- {entrygraph-0.1.32 → entrygraph-0.1.34}/src/entrygraph/results.py +0 -0
- {entrygraph-0.1.32 → entrygraph-0.1.34}/tests/conftest.py +0 -0
- {entrygraph-0.1.32 → entrygraph-0.1.34}/tests/fixtures/csharp/aspnet_app/Controllers/ReportsController.cs +0 -0
- {entrygraph-0.1.32 → entrygraph-0.1.34}/tests/fixtures/csharp/aspnet_app/Program.cs +0 -0
- {entrygraph-0.1.32 → entrygraph-0.1.34}/tests/fixtures/csharp/aspnet_app/Services/ReportService.cs +0 -0
- {entrygraph-0.1.32 → entrygraph-0.1.34}/tests/fixtures/csharp/aspnet_app/app.csproj +0 -0
- {entrygraph-0.1.32 → entrygraph-0.1.34}/tests/fixtures/csharp/minimalapi_app/Program.cs +0 -0
- {entrygraph-0.1.32 → entrygraph-0.1.34}/tests/fixtures/csharp/minimalapi_app/app.csproj +0 -0
- {entrygraph-0.1.32 → entrygraph-0.1.34}/tests/fixtures/go/gin_app/go.mod +0 -0
- {entrygraph-0.1.32 → entrygraph-0.1.34}/tests/fixtures/go/gin_app/main.go +0 -0
- {entrygraph-0.1.32 → entrygraph-0.1.34}/tests/fixtures/go/gin_app/service.go +0 -0
- {entrygraph-0.1.32 → entrygraph-0.1.34}/tests/fixtures/go/nethttp_app/go.mod +0 -0
- {entrygraph-0.1.32 → entrygraph-0.1.34}/tests/fixtures/go/nethttp_app/main.go +0 -0
- {entrygraph-0.1.32 → entrygraph-0.1.34}/tests/fixtures/java/methodref_app/pom.xml +0 -0
- {entrygraph-0.1.32 → entrygraph-0.1.34}/tests/fixtures/java/methodref_app/src/main/java/com/example/App.java +0 -0
- {entrygraph-0.1.32 → entrygraph-0.1.34}/tests/fixtures/java/spring_app/pom.xml +0 -0
- {entrygraph-0.1.32 → entrygraph-0.1.34}/tests/fixtures/java/spring_app/src/main/java/com/example/Application.java +0 -0
- {entrygraph-0.1.32 → entrygraph-0.1.34}/tests/fixtures/java/spring_app/src/main/java/com/example/ReportRunner.java +0 -0
- {entrygraph-0.1.32 → entrygraph-0.1.34}/tests/fixtures/java/spring_app/src/main/java/com/example/ReportService.java +0 -0
- {entrygraph-0.1.32 → entrygraph-0.1.34}/tests/fixtures/java/spring_app/src/main/java/com/example/UserController.java +0 -0
- {entrygraph-0.1.32 → entrygraph-0.1.34}/tests/fixtures/javascript/commonjs_app/server.js +0 -0
- {entrygraph-0.1.32 → entrygraph-0.1.34}/tests/fixtures/javascript/express_app/package.json +0 -0
- {entrygraph-0.1.32 → entrygraph-0.1.34}/tests/fixtures/javascript/express_app/src/routes.js +0 -0
- {entrygraph-0.1.32 → entrygraph-0.1.34}/tests/fixtures/javascript/express_app/src/services.js +0 -0
- {entrygraph-0.1.32 → entrygraph-0.1.34}/tests/fixtures/php/laravel_app/app/Http/Controllers/ReportController.php +0 -0
- {entrygraph-0.1.32 → entrygraph-0.1.34}/tests/fixtures/php/laravel_app/artisan +0 -0
- {entrygraph-0.1.32 → entrygraph-0.1.34}/tests/fixtures/php/laravel_app/composer.json +0 -0
- {entrygraph-0.1.32 → entrygraph-0.1.34}/tests/fixtures/php/laravel_app/routes/web.php +0 -0
- {entrygraph-0.1.32 → entrygraph-0.1.34}/tests/fixtures/python/chained_sinks/app.py +0 -0
- {entrygraph-0.1.32 → entrygraph-0.1.34}/tests/fixtures/python/flask_app/app/__init__.py +0 -0
- {entrygraph-0.1.32 → entrygraph-0.1.34}/tests/fixtures/python/flask_app/app/db.py +0 -0
- {entrygraph-0.1.32 → entrygraph-0.1.34}/tests/fixtures/python/flask_app/app/routes.py +0 -0
- {entrygraph-0.1.32 → entrygraph-0.1.34}/tests/fixtures/python/flask_app/app/services.py +0 -0
- {entrygraph-0.1.32 → entrygraph-0.1.34}/tests/fixtures/python/flask_app/cli.py +0 -0
- {entrygraph-0.1.32 → entrygraph-0.1.34}/tests/fixtures/python/flask_app/requirements.txt +0 -0
- {entrygraph-0.1.32 → entrygraph-0.1.34}/tests/fixtures/python/fuzzy_sink/app.py +0 -0
- {entrygraph-0.1.32 → entrygraph-0.1.34}/tests/fixtures/python/heal_fidelity/caller.py +0 -0
- {entrygraph-0.1.32 → entrygraph-0.1.34}/tests/fixtures/python/heal_fidelity/worker.py +0 -0
- {entrygraph-0.1.32 → entrygraph-0.1.34}/tests/fixtures/python/may_continue/app.py +0 -0
- {entrygraph-0.1.32 → entrygraph-0.1.34}/tests/fixtures/python/sanitizer/app.py +0 -0
- {entrygraph-0.1.32 → entrygraph-0.1.34}/tests/fixtures/python/taint_source/handler.py +0 -0
- {entrygraph-0.1.32 → entrygraph-0.1.34}/tests/fixtures/ruby/sinatra_app/Gemfile +0 -0
- {entrygraph-0.1.32 → entrygraph-0.1.34}/tests/fixtures/ruby/sinatra_app/app.rb +0 -0
- {entrygraph-0.1.32 → entrygraph-0.1.34}/tests/fixtures/ruby/sinatra_app/services/runner.rb +0 -0
- {entrygraph-0.1.32 → entrygraph-0.1.34}/tests/fixtures/rust/axum_app/Cargo.toml +0 -0
- {entrygraph-0.1.32 → entrygraph-0.1.34}/tests/fixtures/rust/axum_app/src/handlers.rs +0 -0
- {entrygraph-0.1.32 → entrygraph-0.1.34}/tests/fixtures/rust/axum_app/src/main.rs +0 -0
- {entrygraph-0.1.32 → entrygraph-0.1.34}/tests/fixtures/rust/axum_callback_app/Cargo.toml +0 -0
- {entrygraph-0.1.32 → entrygraph-0.1.34}/tests/fixtures/rust/axum_callback_app/src/main.rs +0 -0
- {entrygraph-0.1.32 → entrygraph-0.1.34}/tests/fixtures/rust/scoped_sink_app/Cargo.toml +0 -0
- {entrygraph-0.1.32 → entrygraph-0.1.34}/tests/fixtures/rust/scoped_sink_app/src/main.rs +0 -0
- {entrygraph-0.1.32 → entrygraph-0.1.34}/tests/test_api.py +0 -0
- {entrygraph-0.1.32 → entrygraph-0.1.34}/tests/test_cli.py +0 -0
- {entrygraph-0.1.32 → entrygraph-0.1.34}/tests/test_commonjs.py +0 -0
- {entrygraph-0.1.32 → entrygraph-0.1.34}/tests/test_csharp_callbacks.py +0 -0
- {entrygraph-0.1.32 → entrygraph-0.1.34}/tests/test_cte_bounds.py +0 -0
- {entrygraph-0.1.32 → entrygraph-0.1.34}/tests/test_engine_pragmas.py +0 -0
- {entrygraph-0.1.32 → entrygraph-0.1.34}/tests/test_entrypoint_expansion.py +0 -0
- {entrygraph-0.1.32 → entrygraph-0.1.34}/tests/test_entrypoints.py +0 -0
- {entrygraph-0.1.32 → entrygraph-0.1.34}/tests/test_extract_csharp.py +0 -0
- {entrygraph-0.1.32 → entrygraph-0.1.34}/tests/test_extract_go.py +0 -0
- {entrygraph-0.1.32 → entrygraph-0.1.34}/tests/test_extract_java.py +0 -0
- {entrygraph-0.1.32 → entrygraph-0.1.34}/tests/test_extract_javascript.py +0 -0
- {entrygraph-0.1.32 → entrygraph-0.1.34}/tests/test_extract_php.py +0 -0
- {entrygraph-0.1.32 → entrygraph-0.1.34}/tests/test_extract_python.py +0 -0
- {entrygraph-0.1.32 → entrygraph-0.1.34}/tests/test_extract_ruby.py +0 -0
- {entrygraph-0.1.32 → entrygraph-0.1.34}/tests/test_extract_rust.py +0 -0
- {entrygraph-0.1.32 → entrygraph-0.1.34}/tests/test_frameworks.py +0 -0
- {entrygraph-0.1.32 → entrygraph-0.1.34}/tests/test_fuzzy_sink.py +0 -0
- {entrygraph-0.1.32 → entrygraph-0.1.34}/tests/test_go_callbacks.py +0 -0
- {entrygraph-0.1.32 → entrygraph-0.1.34}/tests/test_hardening.py +0 -0
- {entrygraph-0.1.32 → entrygraph-0.1.34}/tests/test_heal_fidelity.py +0 -0
- {entrygraph-0.1.32 → entrygraph-0.1.34}/tests/test_incremental.py +0 -0
- {entrygraph-0.1.32 → entrygraph-0.1.34}/tests/test_indexer.py +0 -0
- {entrygraph-0.1.32 → entrygraph-0.1.34}/tests/test_java_callbacks.py +0 -0
- {entrygraph-0.1.32 → entrygraph-0.1.34}/tests/test_lang.py +0 -0
- {entrygraph-0.1.32 → entrygraph-0.1.34}/tests/test_manifests.py +0 -0
- {entrygraph-0.1.32 → entrygraph-0.1.34}/tests/test_may_continue.py +0 -0
- {entrygraph-0.1.32 → entrygraph-0.1.34}/tests/test_models.py +0 -0
- {entrygraph-0.1.32 → entrygraph-0.1.34}/tests/test_pool.py +0 -0
- {entrygraph-0.1.32 → entrygraph-0.1.34}/tests/test_registry_cache.py +0 -0
- {entrygraph-0.1.32 → entrygraph-0.1.34}/tests/test_render.py +0 -0
- {entrygraph-0.1.32 → entrygraph-0.1.34}/tests/test_resolver.py +0 -0
- {entrygraph-0.1.32 → entrygraph-0.1.34}/tests/test_rust_callbacks.py +0 -0
- {entrygraph-0.1.32 → entrygraph-0.1.34}/tests/test_rust_scoped_sinks.py +0 -0
- {entrygraph-0.1.32 → entrygraph-0.1.34}/tests/test_sanitizer_languages.py +0 -0
- {entrygraph-0.1.32 → entrygraph-0.1.34}/tests/test_scoring.py +0 -0
- {entrygraph-0.1.32 → entrygraph-0.1.34}/tests/test_sink_catalog.py +0 -0
- {entrygraph-0.1.32 → entrygraph-0.1.34}/tests/test_taint.py +0 -0
- {entrygraph-0.1.32 → entrygraph-0.1.34}/tests/test_taint_sanitizers.py +0 -0
- {entrygraph-0.1.32 → entrygraph-0.1.34}/tests/test_taint_sources.py +0 -0
- {entrygraph-0.1.32 → entrygraph-0.1.34}/tests/test_walker.py +0 -0
- {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.
|
|
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.
|
|
22
|
-
__version_tuple__ = version_tuple = (0, 1,
|
|
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 =
|
|
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 =
|
|
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
|
|
583
|
-
symbol_id = (
|
|
584
|
-
|
|
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
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{entrygraph-0.1.32 → entrygraph-0.1.34}/tests/fixtures/csharp/aspnet_app/Services/ReportService.cs
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{entrygraph-0.1.32 → entrygraph-0.1.34}/tests/fixtures/javascript/express_app/src/services.js
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|