attocode-code-intel 0.1.0__py3-none-any.whl
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.
- attocode_code_intel-0.1.0.dist-info/METADATA +221 -0
- attocode_code_intel-0.1.0.dist-info/RECORD +345 -0
- attocode_code_intel-0.1.0.dist-info/WHEEL +4 -0
- attocode_code_intel-0.1.0.dist-info/entry_points.txt +2 -0
- attocode_code_intel-0.1.0.dist-info/licenses/LICENSE +21 -0
- attocode_intel/GUIDELINES.md +432 -0
- attocode_intel/__init__.py +52 -0
- attocode_intel/_internal/__init__.py +1 -0
- attocode_intel/_internal/errors/__init__.py +126 -0
- attocode_intel/_internal/integrations/__init__.py +1 -0
- attocode_intel/_internal/integrations/context/__init__.py +1 -0
- attocode_intel/_internal/integrations/context/architecture_drift.py +354 -0
- attocode_intel/_internal/integrations/context/ast_chunker.py +202 -0
- attocode_intel/_internal/integrations/context/ast_service.py +1483 -0
- attocode_intel/_internal/integrations/context/blob_oid.py +423 -0
- attocode_intel/_internal/integrations/context/cache_manifest.py +221 -0
- attocode_intel/_internal/integrations/context/cas.py +466 -0
- attocode_intel/_internal/integrations/context/code_analyzer.py +528 -0
- attocode_intel/_internal/integrations/context/codebase_ast.py +1461 -0
- attocode_intel/_internal/integrations/context/codebase_context.py +1736 -0
- attocode_intel/_internal/integrations/context/cross_mode.py +263 -0
- attocode_intel/_internal/integrations/context/cross_references.py +616 -0
- attocode_intel/_internal/integrations/context/embedding_rotation.py +597 -0
- attocode_intel/_internal/integrations/context/embeddings.py +282 -0
- attocode_intel/_internal/integrations/context/frecency.py +427 -0
- attocode_intel/_internal/integrations/context/fuzzy.py +320 -0
- attocode_intel/_internal/integrations/context/hierarchical_explorer.py +331 -0
- attocode_intel/_internal/integrations/context/hydration.py +90 -0
- attocode_intel/_internal/integrations/context/index_repair.py +87 -0
- attocode_intel/_internal/integrations/context/index_store.py +586 -0
- attocode_intel/_internal/integrations/context/memory_store.py +602 -0
- attocode_intel/_internal/integrations/context/module_resolution.py +52 -0
- attocode_intel/_internal/integrations/context/query_constraints.py +361 -0
- attocode_intel/_internal/integrations/context/query_history.py +417 -0
- attocode_intel/_internal/integrations/context/reranker.py +351 -0
- attocode_intel/_internal/integrations/context/semantic_search.py +2931 -0
- attocode_intel/_internal/integrations/context/syntax_evidence.py +94 -0
- attocode_intel/_internal/integrations/context/systemone_ranker.py +245 -0
- attocode_intel/_internal/integrations/context/temporal_coupling.py +411 -0
- attocode_intel/_internal/integrations/context/trigram_index.py +820 -0
- attocode_intel/_internal/integrations/context/trigram_regex.py +171 -0
- attocode_intel/_internal/integrations/context/ts_parser.py +2199 -0
- attocode_intel/_internal/integrations/context/vector_store.py +795 -0
- attocode_intel/_internal/integrations/feature_flags/__init__.py +357 -0
- attocode_intel/_internal/integrations/lsp/__init__.py +1 -0
- attocode_intel/_internal/integrations/lsp/client.py +1140 -0
- attocode_intel/_internal/integrations/mcp/__init__.py +1 -0
- attocode_intel/_internal/integrations/mcp/client.py +253 -0
- attocode_intel/_internal/integrations/security/__init__.py +1 -0
- attocode_intel/_internal/integrations/security/custom_rules.py +176 -0
- attocode_intel/_internal/integrations/security/dataflow.py +522 -0
- attocode_intel/_internal/integrations/security/dependency_audit.py +303 -0
- attocode_intel/_internal/integrations/security/matcher.py +44 -0
- attocode_intel/_internal/integrations/security/patterns.py +724 -0
- attocode_intel/_internal/integrations/security/scanner.py +351 -0
- attocode_intel/_internal/integrations/utilities/__init__.py +1 -0
- attocode_intel/_internal/integrations/utilities/ignore.py +64 -0
- attocode_intel/_internal/integrations/utilities/token_estimate.py +51 -0
- attocode_intel/_internal/tricks/__init__.py +1 -0
- attocode_intel/_internal/tricks/recursive_context.py +357 -0
- attocode_intel/_internal/types/__init__.py +1 -0
- attocode_intel/_internal/types/events.py +289 -0
- attocode_intel/_internal/types/severity.py +15 -0
- attocode_intel/_shared.py +341 -0
- attocode_intel/analysis_coverage.py +56 -0
- attocode_intel/api/__init__.py +1 -0
- attocode_intel/api/access.py +32 -0
- attocode_intel/api/app.py +247 -0
- attocode_intel/api/auth/__init__.py +128 -0
- attocode_intel/api/auth/api_keys.py +61 -0
- attocode_intel/api/auth/context.py +34 -0
- attocode_intel/api/auth/jwt.py +66 -0
- attocode_intel/api/auth/oauth.py +146 -0
- attocode_intel/api/auth/passwords.py +15 -0
- attocode_intel/api/deps.py +351 -0
- attocode_intel/api/knowledge_bridge.py +13 -0
- attocode_intel/api/mcp_transport.py +51 -0
- attocode_intel/api/middleware.py +411 -0
- attocode_intel/api/models.py +698 -0
- attocode_intel/api/providers/__init__.py +1 -0
- attocode_intel/api/providers/db_provider.py +1106 -0
- attocode_intel/api/providers/local_provider.py +476 -0
- attocode_intel/api/providers/remote_provider.py +740 -0
- attocode_intel/api/repository_source.py +21 -0
- attocode_intel/api/routes/__init__.py +1 -0
- attocode_intel/api/routes/_pin_helper.py +158 -0
- attocode_intel/api/routes/activity.py +148 -0
- attocode_intel/api/routes/adr.py +102 -0
- attocode_intel/api/routes/analysis.py +515 -0
- attocode_intel/api/routes/api_keys.py +170 -0
- attocode_intel/api/routes/auth.py +428 -0
- attocode_intel/api/routes/branches.py +262 -0
- attocode_intel/api/routes/cross_repo_search.py +198 -0
- attocode_intel/api/routes/embeddings.py +386 -0
- attocode_intel/api/routes/files.py +132 -0
- attocode_intel/api/routes/files_v2.py +388 -0
- attocode_intel/api/routes/gc.py +322 -0
- attocode_intel/api/routes/git_v2.py +433 -0
- attocode_intel/api/routes/graph.py +174 -0
- attocode_intel/api/routes/graph_viz.py +160 -0
- attocode_intel/api/routes/health.py +62 -0
- attocode_intel/api/routes/history.py +175 -0
- attocode_intel/api/routes/jobs.py +84 -0
- attocode_intel/api/routes/learning.py +205 -0
- attocode_intel/api/routes/lsp.py +272 -0
- attocode_intel/api/routes/notify.py +623 -0
- attocode_intel/api/routes/operations.py +27 -0
- attocode_intel/api/routes/orgs.py +924 -0
- attocode_intel/api/routes/preferences.py +100 -0
- attocode_intel/api/routes/presence.py +42 -0
- attocode_intel/api/routes/projects.py +116 -0
- attocode_intel/api/routes/repos.py +47 -0
- attocode_intel/api/routes/search.py +180 -0
- attocode_intel/api/routes/snapshots.py +614 -0
- attocode_intel/api/routes/webhooks.py +313 -0
- attocode_intel/api/routes/websocket.py +116 -0
- attocode_intel/api/static/graph.html +239 -0
- attocode_intel/api/utils.py +96 -0
- attocode_intel/artifacts/__init__.py +45 -0
- attocode_intel/artifacts/hashing.py +230 -0
- attocode_intel/artifacts/provenance.py +190 -0
- attocode_intel/artifacts/retrieval_pin.py +159 -0
- attocode_intel/audit.py +59 -0
- attocode_intel/bug_finder.py +206 -0
- attocode_intel/bundle.py +80 -0
- attocode_intel/catalog.py +242 -0
- attocode_intel/change_review.py +75 -0
- attocode_intel/cli.py +3062 -0
- attocode_intel/community.py +63 -0
- attocode_intel/confidence/__init__.py +144 -0
- attocode_intel/confidence/jev.py +234 -0
- attocode_intel/confidence/llm.py +330 -0
- attocode_intel/confidence/redact.py +44 -0
- attocode_intel/confidence/settings.py +74 -0
- attocode_intel/config.py +256 -0
- attocode_intel/crypto.py +31 -0
- attocode_intel/db/__init__.py +7 -0
- attocode_intel/db/base.py +33 -0
- attocode_intel/db/engine.py +61 -0
- attocode_intel/db/models.py +529 -0
- attocode_intel/entrypoint.py +185 -0
- attocode_intel/focused_evidence.py +130 -0
- attocode_intel/freshness.py +154 -0
- attocode_intel/gateway.py +734 -0
- attocode_intel/git/__init__.py +7 -0
- attocode_intel/git/credentials.py +75 -0
- attocode_intel/git/manager.py +493 -0
- attocode_intel/git/models.py +96 -0
- attocode_intel/git/storage.py +98 -0
- attocode_intel/graph_query_parser.py +761 -0
- attocode_intel/helpers.py +712 -0
- attocode_intel/indexing/__init__.py +29 -0
- attocode_intel/indexing/debouncer.py +136 -0
- attocode_intel/indexing/delta_indexer.py +151 -0
- attocode_intel/indexing/full_indexer.py +323 -0
- attocode_intel/indexing/incremental.py +240 -0
- attocode_intel/indexing/parser.py +403 -0
- attocode_intel/indexing/summarizer.py +264 -0
- attocode_intel/installer.py +1896 -0
- attocode_intel/knowledge.py +269 -0
- attocode_intel/local_knowledge.py +77 -0
- attocode_intel/migrations/alembic.ini +36 -0
- attocode_intel/migrations/env.py +71 -0
- attocode_intel/migrations/script.py.mako +27 -0
- attocode_intel/migrations/versions/001_initial_schema.py +219 -0
- attocode_intel/migrations/versions/002_branch_version_and_embeddings.py +61 -0
- attocode_intel/migrations/versions/003_embedding_uniqueness_and_cascade.py +51 -0
- attocode_intel/migrations/versions/004_audit_events.py +38 -0
- attocode_intel/migrations/versions/005_user_preferences.py +30 -0
- attocode_intel/migrations/versions/006_google_oauth.py +27 -0
- attocode_intel/migrations/versions/007_pgvector_embeddings.py +28 -0
- attocode_intel/migrations/versions/008_symbol_references.py +37 -0
- attocode_intel/migrations/versions/009_webhook_secret_encryption.py +25 -0
- attocode_intel/migrations/versions/010_add_commits_table.py +40 -0
- attocode_intel/migrations/versions/011_commit_changed_files.py +25 -0
- attocode_intel/migrations/versions/012_branch_merged_at.py +25 -0
- attocode_intel/migrations/versions/013_revoked_tokens.py +32 -0
- attocode_intel/migrations/versions/014_blame_hunks.py +40 -0
- attocode_intel/migrations/versions/015_commit_file_stats.py +40 -0
- attocode_intel/migrations/versions/016_embedding_provenance_columns.py +179 -0
- attocode_intel/migrations/versions/017_provenance_table.py +102 -0
- attocode_intel/migrations/versions/018_repo_snapshots.py +178 -0
- attocode_intel/migrations/versions/019_symref_caller.py +42 -0
- attocode_intel/migrations/versions/020_shared_knowledge.py +29 -0
- attocode_intel/onboarding.py +258 -0
- attocode_intel/output.py +178 -0
- attocode_intel/precision.py +133 -0
- attocode_intel/presence.py +160 -0
- attocode_intel/probe.py +110 -0
- attocode_intel/project_dir.py +97 -0
- attocode_intel/pubsub.py +113 -0
- attocode_intel/query_ranking.py +242 -0
- attocode_intel/readiness.py +972 -0
- attocode_intel/redis.py +51 -0
- attocode_intel/reference_pages.py +60 -0
- attocode_intel/remote.py +131 -0
- attocode_intel/repo_ranker.py +246 -0
- attocode_intel/request_context.py +82 -0
- attocode_intel/rules/__init__.py +28 -0
- attocode_intel/rules/ci.py +320 -0
- attocode_intel/rules/combinators.py +293 -0
- attocode_intel/rules/enricher.py +127 -0
- attocode_intel/rules/evolution.py +452 -0
- attocode_intel/rules/executor.py +531 -0
- attocode_intel/rules/filters/__init__.py +5 -0
- attocode_intel/rules/filters/pipeline.py +151 -0
- attocode_intel/rules/formatter.py +198 -0
- attocode_intel/rules/hygiene.py +242 -0
- attocode_intel/rules/importers/__init__.py +1 -0
- attocode_intel/rules/importers/semgrep.py +382 -0
- attocode_intel/rules/loader.py +292 -0
- attocode_intel/rules/marketplace.py +375 -0
- attocode_intel/rules/metavar.py +181 -0
- attocode_intel/rules/model.py +317 -0
- attocode_intel/rules/packs/__init__.py +1 -0
- attocode_intel/rules/packs/community/_license_templates/Apache-2.0.txt +176 -0
- attocode_intel/rules/packs/community/_license_templates/MIT.txt +21 -0
- attocode_intel/rules/packs/community/bandit-python/LICENSE +176 -0
- attocode_intel/rules/packs/community/bandit-python/NOTICE +13 -0
- attocode_intel/rules/packs/community/bandit-python/PORTING.md +23 -0
- attocode_intel/rules/packs/community/bandit-python/manifest.yaml +14 -0
- attocode_intel/rules/packs/community/bandit-python/rules/B105-hardcoded-password.yaml +23 -0
- attocode_intel/rules/packs/community/bandit-python/rules/B303-weak-md5.yaml +21 -0
- attocode_intel/rules/packs/community/bandit-python/rules/B304-weak-des.yaml +20 -0
- attocode_intel/rules/packs/community/bandit-python/rules/B307-use-of-eval.yaml +22 -0
- attocode_intel/rules/packs/community/bandit-python/rules/B324-weak-sha1.yaml +21 -0
- attocode_intel/rules/packs/community/bandit-python/rules/B501-no-cert-validation.yaml +23 -0
- attocode_intel/rules/packs/community/bandit-python/rules/B602-shell-true.yaml +22 -0
- attocode_intel/rules/packs/community/bandit-python/rules/B608-sqli.yaml +22 -0
- attocode_intel/rules/packs/community/eslint-typescript/LICENSE +21 -0
- attocode_intel/rules/packs/community/eslint-typescript/NOTICE +13 -0
- attocode_intel/rules/packs/community/eslint-typescript/PORTING.md +23 -0
- attocode_intel/rules/packs/community/eslint-typescript/manifest.yaml +14 -0
- attocode_intel/rules/packs/community/eslint-typescript/rules/eqeqeq.yaml +20 -0
- attocode_intel/rules/packs/community/eslint-typescript/rules/no-eval.yaml +22 -0
- attocode_intel/rules/packs/community/eslint-typescript/rules/no-implied-eval.yaml +20 -0
- attocode_intel/rules/packs/community/eslint-typescript/rules/no-new-func.yaml +21 -0
- attocode_intel/rules/packs/community/eslint-typescript/rules/no-throw-literal.yaml +19 -0
- attocode_intel/rules/packs/community/eslint-typescript/rules/no-var.yaml +20 -0
- attocode_intel/rules/packs/community/eslint-typescript/rules/no-with.yaml +18 -0
- attocode_intel/rules/packs/community/gosec-go/LICENSE +176 -0
- attocode_intel/rules/packs/community/gosec-go/NOTICE +13 -0
- attocode_intel/rules/packs/community/gosec-go/PORTING.md +23 -0
- attocode_intel/rules/packs/community/gosec-go/manifest.yaml +14 -0
- attocode_intel/rules/packs/community/gosec-go/rules/G101-hardcoded-credentials.yaml +22 -0
- attocode_intel/rules/packs/community/gosec-go/rules/G102-bind-all-interfaces.yaml +21 -0
- attocode_intel/rules/packs/community/gosec-go/rules/G103-unsafe-block.yaml +21 -0
- attocode_intel/rules/packs/community/gosec-go/rules/G201-sql-format.yaml +21 -0
- attocode_intel/rules/packs/community/gosec-go/rules/G304-file-inclusion.yaml +23 -0
- attocode_intel/rules/packs/community/gosec-go/rules/G401-weak-cipher.yaml +20 -0
- attocode_intel/rules/packs/community/gosec-go/rules/G402-tls-min-version.yaml +20 -0
- attocode_intel/rules/packs/community/gosec-go/rules/G501-md5-import.yaml +21 -0
- attocode_intel/rules/packs/examples/cpp/manifest.yaml +4 -0
- attocode_intel/rules/packs/examples/cpp/rules/security.yaml +90 -0
- attocode_intel/rules/packs/examples/cpp/rules/structural.yaml +42 -0
- attocode_intel/rules/packs/examples/csharp/manifest.yaml +4 -0
- attocode_intel/rules/packs/examples/csharp/rules/security.yaml +69 -0
- attocode_intel/rules/packs/examples/csharp/rules/structural.yaml +42 -0
- attocode_intel/rules/packs/examples/go/manifest.yaml +4 -0
- attocode_intel/rules/packs/examples/go/rules/performance.yaml +136 -0
- attocode_intel/rules/packs/examples/go/rules/security.yaml +48 -0
- attocode_intel/rules/packs/examples/go/rules/structural.yaml +58 -0
- attocode_intel/rules/packs/examples/go/taint/sanitizers.yaml +24 -0
- attocode_intel/rules/packs/examples/go/taint/sinks.yaml +51 -0
- attocode_intel/rules/packs/examples/go/taint/sources.yaml +26 -0
- attocode_intel/rules/packs/examples/java/manifest.yaml +4 -0
- attocode_intel/rules/packs/examples/java/rules/correctness.yaml +55 -0
- attocode_intel/rules/packs/examples/java/rules/structural.yaml +48 -0
- attocode_intel/rules/packs/examples/java/taint/sinks.yaml +37 -0
- attocode_intel/rules/packs/examples/java/taint/sources.yaml +21 -0
- attocode_intel/rules/packs/examples/kotlin/manifest.yaml +4 -0
- attocode_intel/rules/packs/examples/kotlin/rules/correctness.yaml +50 -0
- attocode_intel/rules/packs/examples/kotlin/rules/structural.yaml +38 -0
- attocode_intel/rules/packs/examples/php/manifest.yaml +4 -0
- attocode_intel/rules/packs/examples/php/rules/security.yaml +66 -0
- attocode_intel/rules/packs/examples/php/rules/structural.yaml +41 -0
- attocode_intel/rules/packs/examples/python/manifest.yaml +4 -0
- attocode_intel/rules/packs/examples/python/rules/performance.yaml +90 -0
- attocode_intel/rules/packs/examples/python/rules/structural.yaml +55 -0
- attocode_intel/rules/packs/examples/ruby/manifest.yaml +4 -0
- attocode_intel/rules/packs/examples/ruby/rules/security.yaml +73 -0
- attocode_intel/rules/packs/examples/ruby/rules/structural.yaml +41 -0
- attocode_intel/rules/packs/examples/rust/manifest.yaml +4 -0
- attocode_intel/rules/packs/examples/rust/rules/correctness.yaml +51 -0
- attocode_intel/rules/packs/examples/rust/rules/structural.yaml +49 -0
- attocode_intel/rules/packs/examples/typescript/manifest.yaml +4 -0
- attocode_intel/rules/packs/examples/typescript/rules/performance.yaml +70 -0
- attocode_intel/rules/packs/examples/typescript/rules/structural.yaml +48 -0
- attocode_intel/rules/packs/pack_loader.py +244 -0
- attocode_intel/rules/plugins/__init__.py +1 -0
- attocode_intel/rules/plugins/plugin_loader.py +132 -0
- attocode_intel/rules/profiling.py +332 -0
- attocode_intel/rules/registry.py +213 -0
- attocode_intel/rules/sarif.py +187 -0
- attocode_intel/rules/synthesis.py +420 -0
- attocode_intel/rules/testing.py +326 -0
- attocode_intel/server.py +734 -0
- attocode_intel/service.py +3416 -0
- attocode_intel/sharing.py +57 -0
- attocode_intel/storage/__init__.py +6 -0
- attocode_intel/storage/branch_overlay.py +352 -0
- attocode_intel/storage/content_store.py +220 -0
- attocode_intel/storage/dependency_store.py +143 -0
- attocode_intel/storage/diff_engine.py +187 -0
- attocode_intel/storage/embedding_store.py +594 -0
- attocode_intel/storage/provenance_store.py +137 -0
- attocode_intel/storage/security_scanner_db.py +164 -0
- attocode_intel/storage/symbol_store.py +160 -0
- attocode_intel/structural_evidence.py +144 -0
- attocode_intel/symbol_inspection.py +141 -0
- attocode_intel/symbol_links.py +167 -0
- attocode_intel/telemetry.py +42 -0
- attocode_intel/test_ranking.py +73 -0
- attocode_intel/testing/__init__.py +43 -0
- attocode_intel/testing/fixtures.py +122 -0
- attocode_intel/testing/helpers.py +75 -0
- attocode_intel/testing/mocks.py +99 -0
- attocode_intel/tools/__init__.py +2 -0
- attocode_intel/tools/adr_tools.py +628 -0
- attocode_intel/tools/analysis_tools.py +382 -0
- attocode_intel/tools/composite_tools.py +695 -0
- attocode_intel/tools/cross_mode_tools.py +173 -0
- attocode_intel/tools/dead_code_tools.py +582 -0
- attocode_intel/tools/distill_tools.py +353 -0
- attocode_intel/tools/frecency_tools.py +220 -0
- attocode_intel/tools/fuzzy_tools.py +255 -0
- attocode_intel/tools/history_tools.py +486 -0
- attocode_intel/tools/learning_tools.py +222 -0
- attocode_intel/tools/lsp_tools.py +218 -0
- attocode_intel/tools/maintenance_tools.py +1662 -0
- attocode_intel/tools/navigation_tools.py +220 -0
- attocode_intel/tools/overlay_tools.py +540 -0
- attocode_intel/tools/pin_store.py +432 -0
- attocode_intel/tools/pin_tools.py +266 -0
- attocode_intel/tools/query_constraints_tools.py +262 -0
- attocode_intel/tools/query_history_tools.py +158 -0
- attocode_intel/tools/readiness_tools.py +44 -0
- attocode_intel/tools/rule_tools.py +992 -0
- attocode_intel/tools/search_tools.py +770 -0
- attocode_intel/tools/snapshot_tools.py +624 -0
- attocode_intel/workers/__init__.py +1 -0
- attocode_intel/workers/job_utils.py +111 -0
- attocode_intel/workers/jobs.py +573 -0
- attocode_intel/workers/run.py +30 -0
- attocode_intel/workers/settings.py +61 -0
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
# Go performance antipatterns — inspired by Uber PerfInsights
|
|
2
|
+
# These target patterns that cause measurable CPU/memory overhead
|
|
3
|
+
# in production Go services.
|
|
4
|
+
|
|
5
|
+
- id: go-sprintf-allocation
|
|
6
|
+
name: fmt.Sprintf string allocation
|
|
7
|
+
pattern: 'fmt\.Sprintf\s*\('
|
|
8
|
+
message: "fmt.Sprintf allocates a new string per call — consider alternatives in hot paths"
|
|
9
|
+
severity: low
|
|
10
|
+
category: performance
|
|
11
|
+
languages: [go]
|
|
12
|
+
confidence: 0.5
|
|
13
|
+
explanation: >
|
|
14
|
+
fmt.Sprintf parses the format string and allocates a new string on every
|
|
15
|
+
invocation. In hot loops, this creates N allocations that pressure the GC.
|
|
16
|
+
Not every Sprintf is a problem — only flag this in performance-sensitive paths.
|
|
17
|
+
recommendation: "For hot paths, use strings.Builder, strconv.Itoa + concatenation, or pre-allocate"
|
|
18
|
+
examples:
|
|
19
|
+
- bad: 'key := fmt.Sprintf("cache:%s:%d", prefix, id)'
|
|
20
|
+
good: 'key := "cache:" + prefix + ":" + strconv.Itoa(id)'
|
|
21
|
+
explanation: "String concatenation avoids format parsing overhead"
|
|
22
|
+
- bad: 'msg := fmt.Sprintf("error: %s", err.Error())'
|
|
23
|
+
good: 'msg := "error: " + err.Error()'
|
|
24
|
+
explanation: "Direct concatenation for simple cases"
|
|
25
|
+
|
|
26
|
+
- id: go-string-tolower-compare
|
|
27
|
+
name: strings.ToLower for comparison
|
|
28
|
+
pattern: 'strings\.To(?:Lower|Upper)\s*\([^)]+\)\s*[!=]='
|
|
29
|
+
message: "strings.ToLower() allocates a new string for comparison — use EqualFold"
|
|
30
|
+
severity: medium
|
|
31
|
+
category: performance
|
|
32
|
+
languages: [go]
|
|
33
|
+
confidence: 0.85
|
|
34
|
+
explanation: >
|
|
35
|
+
strings.ToLower() creates a new lowercase copy of the string just to
|
|
36
|
+
compare it. strings.EqualFold() compares case-insensitively without
|
|
37
|
+
any allocation.
|
|
38
|
+
recommendation: "Use strings.EqualFold(a, b) for case-insensitive comparison"
|
|
39
|
+
examples:
|
|
40
|
+
- bad: 'if strings.ToLower(name) == "admin" {'
|
|
41
|
+
good: 'if strings.EqualFold(name, "admin") {'
|
|
42
|
+
explanation: "EqualFold is allocation-free"
|
|
43
|
+
|
|
44
|
+
- id: go-append-no-prealloc
|
|
45
|
+
name: append without pre-allocation
|
|
46
|
+
pattern: 'var\s+\w+\s+\[\]\w+\s*\n(?:.*\n){0,5}.*\bappend\('
|
|
47
|
+
message: "Slice append in loop without pre-allocation causes repeated re-allocation"
|
|
48
|
+
severity: low
|
|
49
|
+
category: performance
|
|
50
|
+
languages: [go]
|
|
51
|
+
confidence: 0.5
|
|
52
|
+
explanation: >
|
|
53
|
+
When the final size is known or estimatable, pre-allocating with
|
|
54
|
+
make([]T, 0, n) avoids the geometric growth and copying that
|
|
55
|
+
append performs behind the scenes.
|
|
56
|
+
recommendation: "Use make([]T, 0, expectedLen) when the size is known"
|
|
57
|
+
examples:
|
|
58
|
+
- bad: "var results []string\nfor _, item := range items {\n results = append(results, item.Name)\n}"
|
|
59
|
+
good: "results := make([]string, 0, len(items))\nfor _, item := range items {\n results = append(results, item.Name)\n}"
|
|
60
|
+
explanation: "Pre-allocation avoids re-allocation during growth"
|
|
61
|
+
|
|
62
|
+
- id: go-json-marshal-hot
|
|
63
|
+
name: json.Marshal without reusable encoder
|
|
64
|
+
pattern: 'json\.(?:Marshal|MarshalIndent|Unmarshal)\s*\('
|
|
65
|
+
message: "json.Marshal/Unmarshal in hot path — consider json.NewEncoder for reuse"
|
|
66
|
+
severity: low
|
|
67
|
+
category: performance
|
|
68
|
+
languages: [go]
|
|
69
|
+
confidence: 0.5
|
|
70
|
+
explanation: >
|
|
71
|
+
json.Marshal creates a new encoder internally each time. For high-throughput
|
|
72
|
+
paths, reusing json.NewEncoder with a bytes.Buffer pool reduces allocations.
|
|
73
|
+
recommendation: "For hot paths, use json.NewEncoder(buf) with sync.Pool for buffers"
|
|
74
|
+
|
|
75
|
+
- id: go-mutex-lock
|
|
76
|
+
name: sync.Mutex Lock call
|
|
77
|
+
pattern: '\.Lock\(\)'
|
|
78
|
+
message: "Mutex lock — verify no I/O (network, file, HTTP) happens before Unlock"
|
|
79
|
+
severity: info
|
|
80
|
+
category: suspicious
|
|
81
|
+
languages: [go]
|
|
82
|
+
confidence: 0.3
|
|
83
|
+
explanation: >
|
|
84
|
+
Holding a mutex across I/O blocks all waiting goroutines. This flags
|
|
85
|
+
Lock() calls for review — check that no network calls, file operations,
|
|
86
|
+
or HTTP requests occur before the corresponding Unlock().
|
|
87
|
+
recommendation: "Verify no I/O between Lock() and Unlock(). If there is, restructure."
|
|
88
|
+
|
|
89
|
+
- id: go-reflect-in-loop
|
|
90
|
+
name: Reflection in tight loop
|
|
91
|
+
pattern: 'reflect\.(?:ValueOf|TypeOf)\s*\('
|
|
92
|
+
message: "reflect.ValueOf/TypeOf in potential hot path — reflection is slow"
|
|
93
|
+
severity: low
|
|
94
|
+
category: performance
|
|
95
|
+
languages: [go]
|
|
96
|
+
confidence: 0.45
|
|
97
|
+
explanation: >
|
|
98
|
+
Reflection in Go is significantly slower than direct type access due to
|
|
99
|
+
interface boxing and type introspection. In tight loops, this overhead
|
|
100
|
+
compounds.
|
|
101
|
+
recommendation: "Use type switches, generics, or code generation instead of reflection"
|
|
102
|
+
|
|
103
|
+
- id: go-error-string-compare
|
|
104
|
+
name: Error string comparison
|
|
105
|
+
pattern: 'err\.Error\(\)\s*[!=]='
|
|
106
|
+
message: "Comparing error strings is fragile — use errors.Is or errors.As"
|
|
107
|
+
severity: medium
|
|
108
|
+
category: correctness
|
|
109
|
+
languages: [go]
|
|
110
|
+
confidence: 0.9
|
|
111
|
+
explanation: >
|
|
112
|
+
Error messages can change between library versions. errors.Is() and
|
|
113
|
+
errors.As() check the error chain properly and are stable across versions.
|
|
114
|
+
recommendation: "Use errors.Is(err, targetErr) or errors.As(err, &targetType)"
|
|
115
|
+
examples:
|
|
116
|
+
- bad: 'if err.Error() == "not found" {'
|
|
117
|
+
good: 'if errors.Is(err, ErrNotFound) {'
|
|
118
|
+
explanation: "errors.Is checks the entire error chain"
|
|
119
|
+
|
|
120
|
+
- id: go-defer-statement
|
|
121
|
+
name: defer statement (check if inside loop)
|
|
122
|
+
pattern: '^\s+defer\s'
|
|
123
|
+
message: "defer call — if inside a loop, defers accumulate until function returns"
|
|
124
|
+
severity: low
|
|
125
|
+
category: correctness
|
|
126
|
+
languages: [go]
|
|
127
|
+
confidence: 0.35
|
|
128
|
+
explanation: >
|
|
129
|
+
If this defer is inside a for/range loop, deferred calls stack up until
|
|
130
|
+
the function returns — causing resource leaks. Check surrounding code
|
|
131
|
+
for a loop. If inside a loop, wrap in a closure or close explicitly.
|
|
132
|
+
recommendation: "If inside a loop: wrap in func() { defer f.Close() }()"
|
|
133
|
+
examples:
|
|
134
|
+
- bad: "for _, f := range files {\n fd, _ := os.Open(f)\n defer fd.Close()\n}"
|
|
135
|
+
good: "for _, f := range files {\n func() {\n fd, _ := os.Open(f)\n defer fd.Close()\n }()\n}"
|
|
136
|
+
explanation: "Closure ensures defer runs each iteration"
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
# Go security patterns
|
|
2
|
+
|
|
3
|
+
- id: go-sql-string-concat
|
|
4
|
+
name: SQL string concatenation
|
|
5
|
+
pattern: '(?:db|tx|conn)\.(?:Query|QueryRow|QueryContext|QueryRowContext|Exec|ExecContext|Prepare)\s*\([^,)]*\+'
|
|
6
|
+
message: "SQL query built with string concatenation — SQL injection risk"
|
|
7
|
+
severity: high
|
|
8
|
+
category: security
|
|
9
|
+
languages: [go]
|
|
10
|
+
cwe: CWE-89
|
|
11
|
+
confidence: 0.8
|
|
12
|
+
recommendation: "Use parameterized queries with ? placeholders"
|
|
13
|
+
examples:
|
|
14
|
+
- bad: 'db.Query("SELECT * FROM users WHERE id=" + id)'
|
|
15
|
+
good: 'db.Query("SELECT * FROM users WHERE id=?", id)'
|
|
16
|
+
|
|
17
|
+
- id: go-exec-command-var
|
|
18
|
+
name: Variable in exec.Command
|
|
19
|
+
pattern: 'exec\.Command\s*\([^"'']'
|
|
20
|
+
message: "exec.Command with variable argument — command injection risk"
|
|
21
|
+
severity: high
|
|
22
|
+
category: security
|
|
23
|
+
languages: [go]
|
|
24
|
+
cwe: CWE-78
|
|
25
|
+
confidence: 0.7
|
|
26
|
+
recommendation: "Validate and sanitize command arguments; avoid user input in commands"
|
|
27
|
+
|
|
28
|
+
- id: go-template-html-unescaped
|
|
29
|
+
name: template.HTML with user input
|
|
30
|
+
pattern: 'template\.HTML\s*\('
|
|
31
|
+
message: "template.HTML bypasses Go's auto-escaping — XSS risk"
|
|
32
|
+
severity: medium
|
|
33
|
+
category: security
|
|
34
|
+
languages: [go]
|
|
35
|
+
cwe: CWE-79
|
|
36
|
+
confidence: 0.7
|
|
37
|
+
recommendation: "Use text/template auto-escaping; only use template.HTML for trusted content"
|
|
38
|
+
|
|
39
|
+
- id: go-tls-insecure
|
|
40
|
+
name: TLS InsecureSkipVerify
|
|
41
|
+
pattern: 'InsecureSkipVerify\s*:\s*true'
|
|
42
|
+
message: "TLS certificate verification disabled — MITM risk"
|
|
43
|
+
severity: high
|
|
44
|
+
category: security
|
|
45
|
+
languages: [go]
|
|
46
|
+
cwe: CWE-295
|
|
47
|
+
confidence: 0.95
|
|
48
|
+
recommendation: "Enable TLS verification; use custom CA bundle if needed"
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
# Go structural patterns (ast-grep, Tier 2).
|
|
2
|
+
#
|
|
3
|
+
# Many Go ``pkg.Func(arg)`` patterns are parsed by tree-sitter as
|
|
4
|
+
# ``type_conversion_expression`` (treating ``pkg.Func`` as a qualified
|
|
5
|
+
# type) rather than ``call_expression``. We disambiguate via
|
|
6
|
+
# ``structural_context`` + ``structural_selector`` so the matcher binds
|
|
7
|
+
# to the actual call.
|
|
8
|
+
|
|
9
|
+
- id: go-debug-fmt-println
|
|
10
|
+
name: Debug fmt.Println left in source
|
|
11
|
+
structural_pattern: 'fmt.Println($X)'
|
|
12
|
+
structural_context: 'func _() { fmt.Println($X) }'
|
|
13
|
+
structural_selector: call_expression
|
|
14
|
+
message: "fmt.Println($X) left in source — switch to log.Printf or remove"
|
|
15
|
+
severity: low
|
|
16
|
+
category: style
|
|
17
|
+
languages: [go]
|
|
18
|
+
confidence: 0.35
|
|
19
|
+
tags: [debug]
|
|
20
|
+
explanation: >
|
|
21
|
+
``fmt.Println`` writes straight to stdout with no level filtering or
|
|
22
|
+
structure. In services, prefer ``log`` / ``slog`` so output can be
|
|
23
|
+
routed and silenced.
|
|
24
|
+
recommendation: "Use log.Printf, slog.Info, or remove if it was a debug aid."
|
|
25
|
+
examples:
|
|
26
|
+
- bad: "fmt.Println(\"got request\", req)"
|
|
27
|
+
good: "slog.Info(\"got request\", \"req\", req)"
|
|
28
|
+
explanation: "Structured logging keeps fields queryable and respects levels."
|
|
29
|
+
|
|
30
|
+
- id: go-production-panic
|
|
31
|
+
name: panic() in production code
|
|
32
|
+
structural_pattern: 'panic($X)'
|
|
33
|
+
message: "panic($X) — production code should return errors instead of crashing"
|
|
34
|
+
severity: medium
|
|
35
|
+
category: correctness
|
|
36
|
+
languages: [go]
|
|
37
|
+
confidence: 0.55
|
|
38
|
+
explanation: >
|
|
39
|
+
Go convention is to return ``error`` and let callers decide what to
|
|
40
|
+
do. ``panic`` is reserved for truly unrecoverable invariants (init
|
|
41
|
+
failures, programmer errors).
|
|
42
|
+
recommendation: "Return an error from the function and let the caller handle it."
|
|
43
|
+
|
|
44
|
+
- id: go-blocking-sleep
|
|
45
|
+
name: Blocking time.Sleep call
|
|
46
|
+
structural_pattern: 'time.Sleep($X)'
|
|
47
|
+
structural_context: 'func _() { time.Sleep($X) }'
|
|
48
|
+
structural_selector: call_expression
|
|
49
|
+
message: "time.Sleep($X) blocks the goroutine — usually a workaround for a missing sync primitive"
|
|
50
|
+
severity: low
|
|
51
|
+
category: suspicious
|
|
52
|
+
languages: [go]
|
|
53
|
+
confidence: 0.45
|
|
54
|
+
explanation: >
|
|
55
|
+
Hardcoded sleeps are flaky in tests and waste latency in production.
|
|
56
|
+
Replace with channel/select waits, context deadlines, or proper
|
|
57
|
+
backoff with a ticker.
|
|
58
|
+
recommendation: "Use a ticker, context.WithTimeout, or a synchronization channel."
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
sanitizers:
|
|
2
|
+
- name: parameterized_query
|
|
3
|
+
patterns:
|
|
4
|
+
- 'db\.Query(?:Row|Context)?\(\s*(?:["`]|`)[^)]*\?\s*(?:["`]|`)\s*,'
|
|
5
|
+
- 'db\.Exec(?:Context)?\(\s*(?:["`]|`)[^)]*\?\s*(?:["`]|`)\s*,'
|
|
6
|
+
language: go
|
|
7
|
+
|
|
8
|
+
- name: html_escape
|
|
9
|
+
patterns:
|
|
10
|
+
- 'html\.EscapeString\('
|
|
11
|
+
- 'template\.HTMLEscapeString\('
|
|
12
|
+
language: go
|
|
13
|
+
|
|
14
|
+
- name: filepath_clean
|
|
15
|
+
patterns:
|
|
16
|
+
- 'filepath\.Clean\('
|
|
17
|
+
- 'filepath\.Base\('
|
|
18
|
+
language: go
|
|
19
|
+
|
|
20
|
+
- name: url_escape
|
|
21
|
+
patterns:
|
|
22
|
+
- 'url\.PathEscape\('
|
|
23
|
+
- 'url\.QueryEscape\('
|
|
24
|
+
language: go
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
sinks:
|
|
2
|
+
- name: sql_query
|
|
3
|
+
patterns:
|
|
4
|
+
- 'db\.Query\('
|
|
5
|
+
- 'db\.QueryRow\('
|
|
6
|
+
- 'db\.QueryContext\('
|
|
7
|
+
- 'db\.QueryRowContext\('
|
|
8
|
+
- 'db\.Exec\('
|
|
9
|
+
- 'db\.ExecContext\('
|
|
10
|
+
- 'tx\.Query\('
|
|
11
|
+
- 'tx\.QueryContext\('
|
|
12
|
+
- 'tx\.Exec\('
|
|
13
|
+
- 'tx\.ExecContext\('
|
|
14
|
+
cwe: CWE-89
|
|
15
|
+
message: "SQL injection: tainted data reaches database query"
|
|
16
|
+
language: go
|
|
17
|
+
|
|
18
|
+
- name: exec_command
|
|
19
|
+
patterns:
|
|
20
|
+
- 'exec\.Command\('
|
|
21
|
+
- 'exec\.CommandContext\('
|
|
22
|
+
cwe: CWE-78
|
|
23
|
+
message: "Command injection: tainted data reaches shell execution"
|
|
24
|
+
language: go
|
|
25
|
+
|
|
26
|
+
- name: template_html
|
|
27
|
+
patterns:
|
|
28
|
+
- 'template\.HTML\('
|
|
29
|
+
- 'template\.JS\('
|
|
30
|
+
- 'template\.URL\('
|
|
31
|
+
cwe: CWE-79
|
|
32
|
+
message: "XSS: tainted data passed to template.HTML (bypasses escaping)"
|
|
33
|
+
language: go
|
|
34
|
+
|
|
35
|
+
- name: file_access
|
|
36
|
+
patterns:
|
|
37
|
+
- 'os\.Open\('
|
|
38
|
+
- 'os\.Create\('
|
|
39
|
+
- 'os\.ReadFile\('
|
|
40
|
+
- 'os\.WriteFile\('
|
|
41
|
+
- 'filepath\.Join\('
|
|
42
|
+
cwe: CWE-22
|
|
43
|
+
message: "Path traversal: tainted data used in file path"
|
|
44
|
+
language: go
|
|
45
|
+
|
|
46
|
+
- name: http_redirect
|
|
47
|
+
patterns:
|
|
48
|
+
- 'http\.Redirect\('
|
|
49
|
+
cwe: CWE-601
|
|
50
|
+
message: "Open redirect: tainted data in redirect URL"
|
|
51
|
+
language: go
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
sources:
|
|
2
|
+
- name: http_request
|
|
3
|
+
patterns:
|
|
4
|
+
- 'r\.URL\.Query\(\)'
|
|
5
|
+
- 'r\.FormValue\('
|
|
6
|
+
- 'r\.Body'
|
|
7
|
+
- 'r\.Header\.Get\('
|
|
8
|
+
- 'r\.PostFormValue\('
|
|
9
|
+
- 'r\.URL\.Path'
|
|
10
|
+
- 'r\.URL\.RawQuery'
|
|
11
|
+
- 'r\.Host'
|
|
12
|
+
- 'r\.Cookies?\('
|
|
13
|
+
- 'req\.(?:Body|URL|Header|Form|PostForm)'
|
|
14
|
+
language: go
|
|
15
|
+
|
|
16
|
+
- name: os_args
|
|
17
|
+
patterns:
|
|
18
|
+
- 'os\.Args'
|
|
19
|
+
- 'flag\.(?:String|Int|Bool|Float64|Duration|Var)\('
|
|
20
|
+
language: go
|
|
21
|
+
|
|
22
|
+
- name: env_var
|
|
23
|
+
patterns:
|
|
24
|
+
- 'os\.Getenv\('
|
|
25
|
+
- 'os\.LookupEnv\('
|
|
26
|
+
language: go
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
# Java/Kotlin correctness and performance patterns
|
|
2
|
+
|
|
3
|
+
- id: java-string-concat-loop
|
|
4
|
+
name: String concatenation in loop
|
|
5
|
+
pattern: '\w+\s*\+=\s*"'
|
|
6
|
+
message: "String concatenation in loop — O(N^2) due to immutable strings"
|
|
7
|
+
severity: medium
|
|
8
|
+
category: performance
|
|
9
|
+
languages: [java, kotlin]
|
|
10
|
+
confidence: 0.6
|
|
11
|
+
recommendation: "Use StringBuilder for loop concatenation"
|
|
12
|
+
examples:
|
|
13
|
+
- bad: 'String result = "";\nfor (String s : items) result += s;'
|
|
14
|
+
good: "StringBuilder sb = new StringBuilder();\nfor (String s : items) sb.append(s);"
|
|
15
|
+
|
|
16
|
+
- id: java-catch-exception
|
|
17
|
+
name: Catch generic Exception
|
|
18
|
+
pattern: 'catch\s*\(\s*(?:Exception\s|\w+\s*:\s*Exception)'
|
|
19
|
+
message: "Catching generic Exception — too broad, may mask bugs"
|
|
20
|
+
severity: medium
|
|
21
|
+
category: correctness
|
|
22
|
+
languages: [java, kotlin]
|
|
23
|
+
confidence: 0.7
|
|
24
|
+
recommendation: "Catch specific exception types"
|
|
25
|
+
|
|
26
|
+
- id: java-synchronized-block
|
|
27
|
+
name: Synchronized block (check for I/O inside)
|
|
28
|
+
pattern: 'synchronized\s*\('
|
|
29
|
+
message: "Synchronized block — verify no I/O (streams, sockets, HTTP) inside"
|
|
30
|
+
severity: info
|
|
31
|
+
category: performance
|
|
32
|
+
languages: [java]
|
|
33
|
+
confidence: 0.35
|
|
34
|
+
recommendation: "If I/O occurs inside, move it outside the synchronized block"
|
|
35
|
+
|
|
36
|
+
- id: java-null-return
|
|
37
|
+
name: Returning null from collection method
|
|
38
|
+
pattern: 'return\s+null\s*;'
|
|
39
|
+
message: "Returning null — consider Optional or empty collection"
|
|
40
|
+
severity: low
|
|
41
|
+
category: style
|
|
42
|
+
languages: [java]
|
|
43
|
+
confidence: 0.4
|
|
44
|
+
recommendation: "Use Optional<T>, Collections.emptyList(), or throw an exception"
|
|
45
|
+
|
|
46
|
+
- id: java-sql-concat
|
|
47
|
+
name: SQL string concatenation
|
|
48
|
+
pattern: '(?:createQuery|prepareStatement|executeQuery)\s*\([^)]*\+'
|
|
49
|
+
message: "SQL query built with concatenation — SQL injection risk"
|
|
50
|
+
severity: high
|
|
51
|
+
category: security
|
|
52
|
+
languages: [java, kotlin]
|
|
53
|
+
cwe: CWE-89
|
|
54
|
+
confidence: 0.8
|
|
55
|
+
recommendation: "Use PreparedStatement with parameterized queries"
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
# Java structural patterns (ast-grep, Tier 2).
|
|
2
|
+
|
|
3
|
+
- id: java-system-out-println
|
|
4
|
+
name: System.out.println left in source
|
|
5
|
+
structural_pattern: 'System.out.println($X)'
|
|
6
|
+
message: "System.out.println($X) — use a logger framework instead"
|
|
7
|
+
severity: low
|
|
8
|
+
category: style
|
|
9
|
+
languages: [java]
|
|
10
|
+
confidence: 0.35
|
|
11
|
+
tags: [debug]
|
|
12
|
+
explanation: >
|
|
13
|
+
Direct ``System.out`` writes bypass the logging pipeline (SLF4J,
|
|
14
|
+
Log4j, JUL). They aren't filterable by level or routable to log
|
|
15
|
+
aggregators.
|
|
16
|
+
recommendation: "Use SLF4J: logger.info(\"…\", arg) — or remove if it was debug output."
|
|
17
|
+
|
|
18
|
+
- id: java-print-stack-trace
|
|
19
|
+
name: Throwable.printStackTrace() called
|
|
20
|
+
structural_pattern: '$E.printStackTrace()'
|
|
21
|
+
message: "$E.printStackTrace() — log the exception via your logger instead"
|
|
22
|
+
severity: medium
|
|
23
|
+
category: correctness
|
|
24
|
+
languages: [java]
|
|
25
|
+
confidence: 0.7
|
|
26
|
+
explanation: >
|
|
27
|
+
``printStackTrace()`` writes to ``System.err`` with no metadata or
|
|
28
|
+
context. Logging frameworks attach timestamps, levels, MDC, and
|
|
29
|
+
can ship the trace alongside structured fields.
|
|
30
|
+
recommendation: "logger.error(\"context\", e) — passes the exception so the framework formats it."
|
|
31
|
+
examples:
|
|
32
|
+
- bad: "} catch (IOException e) {\n e.printStackTrace();\n}"
|
|
33
|
+
good: "} catch (IOException e) {\n logger.error(\"failed to read file\", e);\n}"
|
|
34
|
+
explanation: "The logger captures the full stack trace plus your message."
|
|
35
|
+
|
|
36
|
+
- id: java-thread-sleep
|
|
37
|
+
name: Thread.sleep call
|
|
38
|
+
structural_pattern: 'Thread.sleep($X)'
|
|
39
|
+
message: "Thread.sleep($X) blocks the thread — usually a workaround for missing sync"
|
|
40
|
+
severity: low
|
|
41
|
+
category: suspicious
|
|
42
|
+
languages: [java]
|
|
43
|
+
confidence: 0.4
|
|
44
|
+
explanation: >
|
|
45
|
+
Hardcoded sleeps are flaky in tests and waste latency in services.
|
|
46
|
+
Prefer ``CompletableFuture``, ``CountDownLatch``, or scheduled
|
|
47
|
+
executors with proper retry/backoff.
|
|
48
|
+
recommendation: "Use CompletableFuture/CountDownLatch or a ScheduledExecutorService with backoff."
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
sinks:
|
|
2
|
+
- name: sql_query
|
|
3
|
+
patterns:
|
|
4
|
+
- 'createQuery\('
|
|
5
|
+
- 'prepareStatement\('
|
|
6
|
+
- 'executeQuery\('
|
|
7
|
+
- 'createNativeQuery\('
|
|
8
|
+
cwe: CWE-89
|
|
9
|
+
message: "SQL injection: tainted data reaches database query"
|
|
10
|
+
language: java
|
|
11
|
+
|
|
12
|
+
- name: runtime_exec
|
|
13
|
+
patterns:
|
|
14
|
+
- 'Runtime\.getRuntime\(\)\.exec\('
|
|
15
|
+
- 'ProcessBuilder\('
|
|
16
|
+
cwe: CWE-78
|
|
17
|
+
message: "Command injection: tainted data reaches process execution"
|
|
18
|
+
language: java
|
|
19
|
+
|
|
20
|
+
- name: file_access
|
|
21
|
+
patterns:
|
|
22
|
+
- 'new\s+File\('
|
|
23
|
+
- 'new\s+FileInputStream\('
|
|
24
|
+
- 'new\s+FileOutputStream\('
|
|
25
|
+
- 'Paths\.get\('
|
|
26
|
+
- 'Files\.readAllBytes\('
|
|
27
|
+
cwe: CWE-22
|
|
28
|
+
message: "Path traversal: tainted data used in file path"
|
|
29
|
+
language: java
|
|
30
|
+
|
|
31
|
+
- name: response_write
|
|
32
|
+
patterns:
|
|
33
|
+
- 'response\.getWriter\(\)\.(?:print|write)\('
|
|
34
|
+
- 'response\.getOutputStream\('
|
|
35
|
+
cwe: CWE-79
|
|
36
|
+
message: "XSS: tainted data written directly to HTTP response"
|
|
37
|
+
language: java
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
sources:
|
|
2
|
+
- name: http_request
|
|
3
|
+
patterns:
|
|
4
|
+
- 'request\.getParameter\('
|
|
5
|
+
- 'request\.getHeader\('
|
|
6
|
+
- 'request\.getCookies\('
|
|
7
|
+
- 'request\.getQueryString\('
|
|
8
|
+
- 'request\.getPathInfo\('
|
|
9
|
+
- 'request\.getInputStream\('
|
|
10
|
+
- '@RequestParam'
|
|
11
|
+
- '@PathVariable'
|
|
12
|
+
- '@RequestBody'
|
|
13
|
+
- '@RequestHeader'
|
|
14
|
+
language: java
|
|
15
|
+
|
|
16
|
+
- name: system_input
|
|
17
|
+
patterns:
|
|
18
|
+
- 'System\.getenv\('
|
|
19
|
+
- 'System\.getProperty\('
|
|
20
|
+
- 'Scanner\(System\.in\)'
|
|
21
|
+
language: java
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
# Kotlin correctness rules (Tier 1 regex).
|
|
2
|
+
|
|
3
|
+
- id: kotlin-not-null-assertion
|
|
4
|
+
name: Non-null assertion operator (!!)
|
|
5
|
+
pattern: '\w+!!'
|
|
6
|
+
message: "!! throws NPE if null — use safe call (?.) or explicit check"
|
|
7
|
+
severity: medium
|
|
8
|
+
category: correctness
|
|
9
|
+
languages: [kotlin]
|
|
10
|
+
cwe: CWE-476
|
|
11
|
+
confidence: 0.5
|
|
12
|
+
explanation: >
|
|
13
|
+
The ``!!`` operator turns a nullable into a non-null at the cost
|
|
14
|
+
of a NullPointerException at runtime. Defeats Kotlin's null safety.
|
|
15
|
+
Acceptable only after a confirmed invariant (with a comment).
|
|
16
|
+
recommendation: "Use ?.let { ... }, ?: throw IllegalStateException(\"why\"), or pattern-match the nullable."
|
|
17
|
+
|
|
18
|
+
- id: kotlin-runtime-exception-throw
|
|
19
|
+
name: throw RuntimeException — too generic
|
|
20
|
+
pattern: 'throw\s+RuntimeException\s*\('
|
|
21
|
+
message: "throw RuntimeException — use a more specific exception type"
|
|
22
|
+
severity: medium
|
|
23
|
+
category: correctness
|
|
24
|
+
languages: [kotlin]
|
|
25
|
+
confidence: 0.7
|
|
26
|
+
recommendation: "Throw IllegalStateException, IllegalArgumentException, or a domain-specific subclass."
|
|
27
|
+
|
|
28
|
+
- id: kotlin-runblocking-in-coroutine
|
|
29
|
+
name: runBlocking inside a coroutine
|
|
30
|
+
pattern: '\brunBlocking\s*[\{\(]'
|
|
31
|
+
message: "runBlocking inside a coroutine blocks the dispatcher — usually a mistake"
|
|
32
|
+
severity: medium
|
|
33
|
+
category: correctness
|
|
34
|
+
languages: [kotlin]
|
|
35
|
+
confidence: 0.4
|
|
36
|
+
explanation: >
|
|
37
|
+
``runBlocking`` blocks the current thread until the coroutine
|
|
38
|
+
completes. Inside another coroutine you usually want to ``await``
|
|
39
|
+
or ``async``-launch instead.
|
|
40
|
+
recommendation: "Use coroutineScope { ... } or async { ... }.await() inside coroutines."
|
|
41
|
+
|
|
42
|
+
- id: kotlin-print-debug
|
|
43
|
+
name: println debug leftover
|
|
44
|
+
pattern: '\bprintln\s*\('
|
|
45
|
+
message: "println — debug leftover, route through Timber/SLF4J"
|
|
46
|
+
severity: low
|
|
47
|
+
category: style
|
|
48
|
+
languages: [kotlin]
|
|
49
|
+
confidence: 0.5
|
|
50
|
+
recommendation: "Use Timber.d(\"...\") on Android or your project's logger."
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
# Kotlin structural patterns (ast-grep, Tier 2).
|
|
2
|
+
|
|
3
|
+
- id: kotlin-todo-call
|
|
4
|
+
name: TODO() call left in code
|
|
5
|
+
structural_pattern: 'TODO()'
|
|
6
|
+
message: "TODO() — throws NotImplementedError at runtime; finish the implementation"
|
|
7
|
+
severity: high
|
|
8
|
+
category: correctness
|
|
9
|
+
languages: [kotlin]
|
|
10
|
+
confidence: 0.9
|
|
11
|
+
explanation: >
|
|
12
|
+
``TODO()`` is the placeholder for unfinished code; it throws
|
|
13
|
+
``NotImplementedError`` when reached. Useful during scaffolding,
|
|
14
|
+
should not survive into mainline.
|
|
15
|
+
recommendation: "Implement the function or open a tracking issue and gate the path."
|
|
16
|
+
|
|
17
|
+
- id: kotlin-system-out-println
|
|
18
|
+
name: System.out.println left in source
|
|
19
|
+
structural_pattern: 'System.out.println($X)'
|
|
20
|
+
message: "System.out.println($X) — use Timber/SLF4J or remove"
|
|
21
|
+
severity: low
|
|
22
|
+
category: style
|
|
23
|
+
languages: [kotlin]
|
|
24
|
+
confidence: 0.35
|
|
25
|
+
tags: [debug]
|
|
26
|
+
recommendation: "Use Timber.i(\"...\") on Android or the project's logger."
|
|
27
|
+
|
|
28
|
+
- id: kotlin-empty-catch
|
|
29
|
+
name: Empty catch swallows exception
|
|
30
|
+
structural_pattern: 'catch ($E: $T) {}'
|
|
31
|
+
structural_context: 'fun _f() { try {} catch ($E: $T) {} }'
|
|
32
|
+
structural_selector: catch_block
|
|
33
|
+
message: "Empty catch block silently swallows exceptions — log or rethrow"
|
|
34
|
+
severity: medium
|
|
35
|
+
category: correctness
|
|
36
|
+
languages: [kotlin]
|
|
37
|
+
confidence: 0.85
|
|
38
|
+
recommendation: "Log via Timber.e(e, \"context\") or rethrow as a more meaningful exception."
|