From c0871ee360e11cb1594d9bba2627c09f7feca797 Mon Sep 17 00:00:00 2001 From: Arielwyy <1558351025@qq.com> Date: Tue, 7 Apr 2026 17:21:58 +0800 Subject: [PATCH] sync: update src/resource/test and config files --- .eslintrc.js | 11 + .gitignore | 5 +- README.md | 91 +- build.sh | 91 +- check-requires.js | 237 ++ install_deps.sh | 5 +- package.json | 17 +- resource/checker/checker-config.json | 34 +- resource/checker/checker-pack-config.json | 32 +- .../lib-arg-to-this-sid-blacklist.json | 0 .../example-rule-config/rule_config_go.json | 9 - .../rule_config_python.json | 7 +- .../java/class-hierarchy-and-modeling.json | 34 +- resource/python/python-default-rule.json | 14 +- .../lib-arg-to-this-sid-blacklist.json | 28 + .../lib-func-tag-propagation-rule.json | 32 +- src/checker/antql/rules/antql-getbaseclass.ts | 6 +- .../antql/rules/antql-getdefinition.ts | 7 +- src/checker/antql/rules/antql-hasflow.ts | 26 +- .../antql/rules/antql-hasfunctioncall.ts | 25 +- src/checker/antql/rules/antql-hasproperty.ts | 25 +- src/checker/antql/util/entrypoint-util.ts | 2 +- src/checker/antql/util/qid-unify-util.ts | 147 - src/checker/callchain/callchain-checker.ts | 342 +++ .../callchain/go/go-callchain-checker.ts | 232 ++ .../callchain/java/java-callchain-checker.ts | 307 ++ .../callchain/js/js-callchain-checker.ts | 288 ++ .../python/python-callchain-checker.ts | 256 ++ src/checker/callgraph/callgraph-checker.ts | 101 +- .../common/full-callgraph-file-entrypoint.ts | 268 +- .../output/callchain-output-strategy.ts | 140 + .../output/callgraph-output-strategy.ts | 156 +- .../common/output/taint-output-strategy.ts | 101 +- .../common/ql-uast-convert/converter.ts | 34 +- src/checker/common/rules-basic-handler.ts | 179 +- src/checker/sanitizer/sanitizer-checker.ts | 129 +- src/checker/sdk/get-file-ast-checker.ts | 33 +- .../taint/common-kit/entry-points-util.ts | 22 +- src/checker/taint/common-kit/sink-util.ts | 95 +- src/checker/taint/common-kit/source-util.ts | 186 +- .../taint-entrypoint-util.ts} | 16 +- .../taint/common-kit/taint-finding-util.ts | 12 +- .../taint/common-kit/taint-trace-output.ts | 63 + .../go/beego-entrypoint-collect-checker.ts | 104 +- src/checker/taint/go/cobra-command-checker.ts | 38 +- .../go/echo-entrypoint-collect-checker.ts | 439 --- .../go/gRpc-entrypoint-collect-checker.ts | 16 +- .../taint/go/gin-default-taint-checker.ts | 51 +- src/checker/taint/go/gin-taint-checker.ts | 49 +- .../taint/go/go-default-taint-checker.ts | 51 +- .../gorilla-mux-entrypoint-collect-checker.ts | 16 +- .../go/main-entrypoint-collect-checker.ts | 6 +- .../go/restful-entrypoint-collect-checker.ts | 43 +- src/checker/taint/go/sync-once-do-checker.ts | 17 +- src/checker/taint/go/urfave-cli-checker.ts | 23 +- .../taint/java/java-default-taint-checker.ts | 31 +- .../taint/java/java-taint-abstract-checker.ts | 349 ++- src/checker/taint/java/java-taint-checker.ts | 24 +- src/checker/taint/js/egg-taint-checker.ts | 73 +- .../taint/js/express/express-taint-checker.ts | 66 +- src/checker/taint/js/js-taint-checker.ts | 77 +- src/checker/taint/js/source-util-for-egg.ts | 16 +- .../taint/python/django-taint-checker.ts | 43 +- .../python/python-default-taint-checker.ts | 70 +- .../python/python-taint-abstract-checker.ts | 133 +- .../taint/python/python-taint-checker.ts | 65 +- .../taint/python/script-taint-checker.ts | 81 + .../taint/python/tornado-taint-checker.ts | 43 +- src/checker/taint/taint-checker.ts | 9 +- src/checker/taint/test-taint-checker.ts | 27 +- src/client.ts | 2 +- src/config.ts | 24 +- .../analyzer/common/analysis-context.ts | 14 + src/engine/analyzer/common/analyzer-cache.ts | 1832 ++++++++++++ src/engine/analyzer/common/analyzer.ts | 2604 ++++++++++++----- src/engine/analyzer/common/ast-manager.ts | 107 + src/engine/analyzer/common/ast-visitor.ts | 16 + src/engine/analyzer/common/base-analyzer.ts | 137 + src/engine/analyzer/common/call-args.ts | 95 + src/engine/analyzer/common/checker-manager.ts | 144 +- src/engine/analyzer/common/entrypoint.ts | 4 +- src/engine/analyzer/common/initializer.ts | 48 +- src/engine/analyzer/common/memSpace.ts | 434 ++- src/engine/analyzer/common/memState.ts | 98 +- src/engine/analyzer/common/memStateBVT.ts | 153 +- src/engine/analyzer/common/native-resolver.ts | 298 +- src/engine/analyzer/common/sarif.ts | 33 +- src/engine/analyzer/common/scope.ts | 217 +- src/engine/analyzer/common/source-line.ts | 592 ++-- src/engine/analyzer/common/sym-address.ts | 58 +- .../analyzer/common/symbol-table-interface.ts | 58 + .../analyzer/common/symbol-table-manager.ts | 144 + .../analyzer/common/value/ast-binding.ts | 103 + .../analyzer/common/value/ast-ref-list.ts | 118 + src/engine/analyzer/common/value/ast-ref.ts | 63 + .../analyzer/common/value/binary-expr.ts | 76 + src/engine/analyzer/common/value/bvt.ts | 252 +- src/engine/analyzer/common/value/call-expr.ts | 96 + src/engine/analyzer/common/value/class.ts | 58 + .../analyzer/common/value/constructor.ts | 81 - .../analyzer/common/value/data-value.ts | 68 + .../analyzer/common/value/entity-value.ts | 121 + .../analyzer/common/value/expr-value.ts | 49 + src/engine/analyzer/common/value/function.ts | 99 +- .../analyzer/common/value/identifier-ref.ts | 55 + .../analyzer/common/value/member-expr.ts | 73 + src/engine/analyzer/common/value/object.ts | 103 +- src/engine/analyzer/common/value/package.ts | 83 +- src/engine/analyzer/common/value/primitive.ts | 82 +- src/engine/analyzer/common/value/scope-ctx.ts | 80 + src/engine/analyzer/common/value/scoped.ts | 93 +- .../analyzer/common/value/sentinel-value.ts | 31 + src/engine/analyzer/common/value/spread.ts | 28 + src/engine/analyzer/common/value/symbolic.ts | 97 +- src/engine/analyzer/common/value/symbols.ts | 5 + .../analyzer/common/value/taint-record.ts | 308 ++ src/engine/analyzer/common/value/tainted.ts | 31 + src/engine/analyzer/common/value/typed.ts | 29 + .../analyzer/common/value/unary-expr.ts | 61 + src/engine/analyzer/common/value/undefine.ts | 40 +- src/engine/analyzer/common/value/uninit.ts | 50 +- src/engine/analyzer/common/value/union.ts | 412 ++- src/engine/analyzer/common/value/unit.js | 327 --- src/engine/analyzer/common/value/unit.ts | 585 ++++ src/engine/analyzer/common/value/unkown.ts | 37 +- .../analyzer/common/value/value-base.ts | 261 ++ .../analyzer/common/value/value-ref-list.ts | 440 +++ .../analyzer/common/value/value-ref-map.ts | 238 ++ src/engine/analyzer/common/value/value-ref.ts | 83 + src/engine/analyzer/common/value/valueUtil.ts | 75 - src/engine/analyzer/common/value/void.ts | 24 + .../go-default-entrypoint.ts | 4 +- .../analyzer/golang/common/go-analyzer.ts | 480 +-- .../gin-default-entrypoint.ts | 15 +- .../builtins/abstractwrapper-builtins.ts | 243 ++ .../java/common/builtins/arrays-builtins.ts | 52 + .../builtins/atomicreference-builtins.ts | 23 +- .../analyzer/java/common/builtins/buffer.ts | 11 +- .../java/common/builtins/class-builtins.ts | 96 + .../common/builtins/collection-builtins.ts | 43 + .../builtins/completablefuture-builtins.ts | 98 +- .../java/common/builtins/executor-builtins.ts | 12 +- .../builtins/executorservice-builtins.ts | 112 + .../java/common/builtins/hashset-builtins.ts | 2 +- .../builtins/lambdaquerywrapper-builtins.ts | 12 + .../java/common/builtins/list-builtins.ts | 92 +- .../analyzer/java/common/builtins/lombok.ts | 45 +- .../java/common/builtins/map-builtins.ts | 198 +- .../java/common/builtins/object-builtins.ts | 44 + .../analyzer/java/common/builtins/object.ts | 44 + .../common/builtins/querywrapper-builtins.ts | 34 + .../java/common/builtins/queue-builtins.ts | 18 +- .../java/common/builtins/set-builtins.ts | 52 +- .../java/common/builtins/stack-builtins.ts | 8 +- .../java/common/builtins/stream-builtins.ts | 641 ++++ .../common/builtins/stringbuffer-builtins.ts | 2 +- .../common/builtins/stringbuilder-builtins.ts | 2 +- .../java/common/builtins/timer-builtins.ts | 5 +- .../java-default-entrypoint.ts | 48 +- .../analyzer/java/common/java-analyzer.ts | 2183 +++++++++----- .../analyzer/java/common/java-initializer.ts | 262 +- .../spring-default-entrypoint.ts | 78 +- .../analyzer/java/spring/spring-analyzer.ts | 776 +++-- .../java/spring/spring-initializer.ts | 24 +- .../common/builtins/array-builtins.ts | 4 +- .../javascript/common/builtins/function.ts | 19 +- .../common/builtins/map-builtins.ts | 64 +- .../common/builtins/operator-builtins.ts | 59 +- .../javascript/common/builtins/promise.ts | 32 +- .../common/builtins/reflect-builtins.ts | 16 +- .../common/builtins/set-builtins.ts | 13 +- .../analyzer/javascript/common/js-analyzer.ts | 515 ++-- .../javascript/common/js-initializer.ts | 81 +- .../analyzer/javascript/egg/egg-analyzer.ts | 115 +- .../javascript/egg/egg-initializer.ts | 60 +- .../egg/entrypoint-collector/egg-http.ts | 14 +- .../entrypoint-collector/python-entrypoint.ts | 105 +- .../analyzer/python/common/python-analyzer.ts | 1022 ++++--- .../python/common/python-import-resolver.ts | 493 +++- .../fastapi-entrypoint.ts | 1 + .../flask-default-entrypoint.ts | 163 +- src/engine/parser/golang/go-ast-builder.ts | 149 +- src/engine/parser/java/java-ast-builder.ts | 106 +- .../parser/javascript/js-ast-builder.ts | 109 +- src/engine/parser/parser-core.ts | 537 ++++ src/engine/parser/parser-worker.ts | 113 + src/engine/parser/parser.ts | 1392 +++++++++ src/engine/parser/parsing.ts | 439 --- .../parser/python/python-ast-builder.ts | 188 +- src/engine/parser/uast-sanity.ts | 2 +- src/engine/util/type-util.ts | 118 - src/engine/util/value-util.ts | 243 +- src/interface/starter.ts | 198 +- src/main.ts | 6 +- src/report/report.sarif | 1 - .../common/type-related-info-resolver.ts | 331 ++- .../go/go-type-related-info-resolver.ts | 2 +- .../java/java-type-related-info-resolver.ts | 104 +- src/types/analyzer.ts | 84 + src/types/uast.ts | 134 + src/types/value.ts | 198 ++ src/util/ast-util.ts | 334 ++- src/util/clone-util.ts | 363 ++- src/util/common-util.ts | 103 +- src/util/constant.ts | 38 + src/util/diagnostics-log-util.ts | 443 ++- src/util/error-code.ts | 2 +- src/util/file-util.ts | 720 +++-- src/util/finding-util.ts | 10 +- src/util/format-util.ts | 2 +- src/util/framework-util.ts | 28 +- src/util/global-registry.ts | 28 + src/util/graph.ts | 30 +- src/util/logger.ts | 10 +- src/util/performance-tracker.ts | 425 +-- src/util/qid-unify-util.ts | 241 ++ src/util/value-formatter.ts | 457 --- src/util/variable-util.ts | 38 +- test/callargs/test-callargs.ts | 482 +++ .../callchain/expect/callchain-go-expect.json | 591 ++++ .../expect/callchain-java-expect.json | 116 + .../callchain/expect/callchain-js-expect.json | 495 ++++ .../expect/callchain-python-expect.json | 222 ++ test/callchain/go/test_callchain.go | 34 + test/callchain/java/TestCallchain.java | 33 + test/callchain/js/test_callchain.js | 53 + test/callchain/python/test_callchain.py | 38 + test/callchain/rule_config_callchain_go.json | 52 + .../callchain/rule_config_callchain_java.json | 48 + test/callchain/rule_config_callchain_js.json | 41 + .../rule_config_callchain_python.json | 35 + test/callchain/test-all-callchain.ts | 127 + test/callchain/test-callchain-benchmark.ts | 216 ++ test/callchain/test-callchain-go.ts | 52 + test/callchain/test-callchain-java.ts | 51 + test/callchain/test-callchain-js.ts | 50 + test/callchain/test-callchain-python.ts | 52 + test/go/expect/gobenchmark-expect.json | 2 +- test/go/test-go-benchmark.ts | 2 +- test/java/expect/sast-java-expect.result | 1651 +++++------ test/java/rule_config_xast_java.json | 7 +- test/java/test-java-benchmark.ts | 70 +- test/java/test-java-real-project.ts | 189 ++ .../javascript/expect/jsbenchmark-expect.json | 2 +- test/javascript/prepare-js-benchmark.ts | 3 +- test/javascript/test-js-benchmark.ts | 160 +- .../expect/pythonbenchmark-expect.result | 1152 ++++---- test/python/test-python-benchmark.ts | 4 +- tsconfig.json | 2 + 249 files changed, 29227 insertions(+), 10898 deletions(-) mode change 100644 => 100755 build.sh create mode 100755 check-requires.js rename test.js => resource/checker/lib-arg-to-this-sid-blacklist.json (100%) create mode 100644 resource/tag-propagation/lib-arg-to-this-sid-blacklist.json delete mode 100644 src/checker/antql/util/qid-unify-util.ts create mode 100644 src/checker/callchain/callchain-checker.ts create mode 100644 src/checker/callchain/go/go-callchain-checker.ts create mode 100644 src/checker/callchain/java/java-callchain-checker.ts create mode 100644 src/checker/callchain/js/js-callchain-checker.ts create mode 100644 src/checker/callchain/python/python-callchain-checker.ts create mode 100644 src/checker/common/output/callchain-output-strategy.ts rename src/checker/taint/{go/util.ts => common-kit/taint-entrypoint-util.ts} (75%) create mode 100644 src/checker/taint/common-kit/taint-trace-output.ts delete mode 100644 src/checker/taint/go/echo-entrypoint-collect-checker.ts create mode 100644 src/checker/taint/python/script-taint-checker.ts create mode 100644 src/engine/analyzer/common/analysis-context.ts create mode 100644 src/engine/analyzer/common/analyzer-cache.ts create mode 100644 src/engine/analyzer/common/ast-manager.ts create mode 100644 src/engine/analyzer/common/ast-visitor.ts create mode 100644 src/engine/analyzer/common/base-analyzer.ts create mode 100644 src/engine/analyzer/common/call-args.ts create mode 100644 src/engine/analyzer/common/symbol-table-interface.ts create mode 100644 src/engine/analyzer/common/symbol-table-manager.ts create mode 100644 src/engine/analyzer/common/value/ast-binding.ts create mode 100644 src/engine/analyzer/common/value/ast-ref-list.ts create mode 100644 src/engine/analyzer/common/value/ast-ref.ts create mode 100644 src/engine/analyzer/common/value/binary-expr.ts create mode 100644 src/engine/analyzer/common/value/call-expr.ts create mode 100644 src/engine/analyzer/common/value/class.ts delete mode 100644 src/engine/analyzer/common/value/constructor.ts create mode 100644 src/engine/analyzer/common/value/data-value.ts create mode 100644 src/engine/analyzer/common/value/entity-value.ts create mode 100644 src/engine/analyzer/common/value/expr-value.ts create mode 100644 src/engine/analyzer/common/value/identifier-ref.ts create mode 100644 src/engine/analyzer/common/value/member-expr.ts create mode 100644 src/engine/analyzer/common/value/scope-ctx.ts create mode 100644 src/engine/analyzer/common/value/sentinel-value.ts create mode 100644 src/engine/analyzer/common/value/spread.ts create mode 100644 src/engine/analyzer/common/value/symbols.ts create mode 100644 src/engine/analyzer/common/value/taint-record.ts create mode 100644 src/engine/analyzer/common/value/tainted.ts create mode 100644 src/engine/analyzer/common/value/typed.ts create mode 100644 src/engine/analyzer/common/value/unary-expr.ts delete mode 100644 src/engine/analyzer/common/value/unit.js create mode 100644 src/engine/analyzer/common/value/unit.ts create mode 100644 src/engine/analyzer/common/value/value-base.ts create mode 100644 src/engine/analyzer/common/value/value-ref-list.ts create mode 100644 src/engine/analyzer/common/value/value-ref-map.ts create mode 100644 src/engine/analyzer/common/value/value-ref.ts delete mode 100644 src/engine/analyzer/common/value/valueUtil.ts create mode 100644 src/engine/analyzer/common/value/void.ts create mode 100644 src/engine/analyzer/java/common/builtins/abstractwrapper-builtins.ts create mode 100644 src/engine/analyzer/java/common/builtins/arrays-builtins.ts create mode 100644 src/engine/analyzer/java/common/builtins/class-builtins.ts create mode 100644 src/engine/analyzer/java/common/builtins/executorservice-builtins.ts create mode 100644 src/engine/analyzer/java/common/builtins/lambdaquerywrapper-builtins.ts create mode 100644 src/engine/analyzer/java/common/builtins/object-builtins.ts create mode 100644 src/engine/analyzer/java/common/builtins/object.ts create mode 100644 src/engine/analyzer/java/common/builtins/querywrapper-builtins.ts create mode 100644 src/engine/analyzer/java/common/builtins/stream-builtins.ts create mode 100644 src/engine/parser/parser-core.ts create mode 100644 src/engine/parser/parser-worker.ts create mode 100644 src/engine/parser/parser.ts delete mode 100644 src/engine/util/type-util.ts delete mode 100644 src/report/report.sarif create mode 100644 src/types/analyzer.ts create mode 100644 src/types/uast.ts create mode 100644 src/types/value.ts create mode 100644 src/util/global-registry.ts create mode 100644 src/util/qid-unify-util.ts delete mode 100644 src/util/value-formatter.ts create mode 100644 test/callargs/test-callargs.ts create mode 100644 test/callchain/expect/callchain-go-expect.json create mode 100644 test/callchain/expect/callchain-java-expect.json create mode 100644 test/callchain/expect/callchain-js-expect.json create mode 100644 test/callchain/expect/callchain-python-expect.json create mode 100644 test/callchain/go/test_callchain.go create mode 100644 test/callchain/java/TestCallchain.java create mode 100644 test/callchain/js/test_callchain.js create mode 100644 test/callchain/python/test_callchain.py create mode 100644 test/callchain/rule_config_callchain_go.json create mode 100644 test/callchain/rule_config_callchain_java.json create mode 100644 test/callchain/rule_config_callchain_js.json create mode 100644 test/callchain/rule_config_callchain_python.json create mode 100644 test/callchain/test-all-callchain.ts create mode 100644 test/callchain/test-callchain-benchmark.ts create mode 100644 test/callchain/test-callchain-go.ts create mode 100644 test/callchain/test-callchain-java.ts create mode 100644 test/callchain/test-callchain-js.ts create mode 100644 test/callchain/test-callchain-python.ts create mode 100644 test/java/test-java-real-project.ts diff --git a/.eslintrc.js b/.eslintrc.js index 57152f3b..859a558c 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -85,5 +85,16 @@ module.exports = { 'no-undef': 'off', // TypeScript 已处理变量未定义检查 }, }, + { + files: ['check-requires.js'], // 编译检查工具,不参与 dist 生成 + parserOptions: { + project: null, // 不使用 TypeScript 项目配置 + ecmaVersion: 'latest', + sourceType: 'script', // 使用 script 模式(因为文件开头有 #!) + }, + rules: { + 'filenames/match-regex': 'off', // 允许工具文件使用不同的命名 + }, + }, ], } diff --git a/.gitignore b/.gitignore index e4b64010..8d27ac29 100644 --- a/.gitignore +++ b/.gitignore @@ -47,4 +47,7 @@ deps/uast4python /workspace/ deps/uast4py src/uast -src/report \ No newline at end of file +deps-runtime/ +.cursorrules +test/javascript/test-report +deps diff --git a/README.md b/README.md index 3bd2feed..71b09688 100644 --- a/README.md +++ b/README.md @@ -1,78 +1,31 @@ - +# 项目简介 +统一多语言程序分析是一个面向工业界大规模落地的静态程序分析工具。它为多语言定义了统一的抽象语法树(UAST)中间表示,基于UAST和模拟执行技术,实现了高精度的数据流、指针分析和污点分析,并同时提供了命令式和声明式两种规则扩展能力供用户灵活、低成本使用,可广泛应用于代码安全等场景。 -#### [简体中文](README_ZH.md) / [English](README.md) +# 核心功能 ++ 定义了统一的多语言的抽象语法树(UAST)中间表示,并提供了各语言向UAST转换的工具 ++ 高精度的数据流、指针分析和污点分析 ++ 可扩展的规则定制化能力,包括命令式规则和声明式查询语言 ++ 内置常见的安全检测规则,面向安全检测场景可开箱即用 -**YASA** (**Y**et **A**nother **S**tatic **A**nalyzer, pronounced “**YA-sa**”) is an open-source static program analysis project. Its core innovation lies in a unified intermediate representation called the **U**nified **A**bstract **S**yntax **T**ree (UAST), designed to support multiple programming languages. Built on top of UAST, YASA provides a highly accurate static analysis framework. Users can extend its capabilities by writing custom checkers to perform various program analysis tasks—such as AST queries, data flow analysis, and function call graph analysis—and expose functionality through SDK, declarative query language (QL), or MCP. +# 项目架构 +![](https://intranetproxy.alipay.com/skylark/lark/0/2025/png/178787/1743992792193-33a83234-5229-481d-a4b6-e99a796a2fc0.png) -As a project originally developed within a security team, YASA also comes with built-in taint analysis capabilities, implemented as a checker, to detect security vulnerabilities. +**QL**:Query Language -## Components - +**UAST**:Unify Abstract Syntax Tree **统一抽象语法树** -### YASA-UAST: Unified Abstract Syntax Tree -[YASA-UAST](https://github.com/antgroup/YASA-UAST) is an intermediate representation structure for multi-language program analysis. The UAST-Parser parses code from different programming languages into a unified abstract syntax format. Through UAST, source code in different languages can be converted into a standardized tree structure, enabling unified analysis and processing across multiple languages. +**YASA** :Yet Another Static Analyzer -### YASA-Engine: Unified multi-language Analysis Engine -The unified multi-language analysis engine is the core component of a modern program analysis platform. It aims to achieve efficient and precise analysis of multiple programming languages through a unified analysis framework and methodology. Also, with the help of AI capabilities, it addresses issues such as broken chains in traditional program analysis and high adaptation costs for new scenarios. (The AI part is not open-sourced yet.) +# 技术优势 ++ 【统一】统一多语言抽象语法树(UAST)中间表示,可低成本支持新语言,便于跨语言的分析 ++ 【高精度】多语言程序模拟执行技术,还原了真实的程序运行上下文,可提供更高的分析精度 ++ 【工业界落地】经过蚂蚁内部大规模落地和业界首个程序分析评价体系开源项目[xast](https://xastbenchmark.github.io/)的“双重认证”,多语言场景下的分析完整度、准确度和性能都有较高保障 ++ 【低使用成本】命令式程序分析combine声明式查询语句 + - 兼容[Github codeql](https://github.com/github/codeql)的语法和规则,用户使用门槛低 + - 提供了灵活的规则定制能力 -### YASA-UQL: Unified Declarative Rule Query Language -Supports declarative unified query rule writing for multiple languages, compatible with CodeQL syntax, lowering the barrier to rule writing while unifying rule sets across languages. +# 支持的语言 +Java、JS、Go、Python...... -### YASA-MCP: Unified multi-language Program Analysis MCP -Provides atomic analysis APIs for LLM, offering program analysis services that are LLM-friendly. +其他语言的支持为开源社区共建“留白” -### YASA-SDK: Unified multi-language Program Analysis SDK -Provides SDK packages supporting multiple programming languages for traditional applications. It provides a variety of granular program analysis APIs, making integration easier and enabling efficient and user-friendly program analysis services within applications. - -### xAST -[xAST](https://github.com/alipay/ant-application-security-testing-benchmark) is an open-source evaluation system for SAST/IAST/DAST tool capabilities. In YASA-Engine, it serves as the regression target for post-change testing, and during the process of multi-language adaptation, it provides positive guidance on language syntax support. - -## Technical Advantages -### Low Cost for New Language Support -- YASA is directly modeled and analyzed based on UAST. When adapting to a new language, once it is parsed into UAST, the general-layer analyzer's capabilities can be used. After supporting the new language's package structure, the new language's analysis is already supported. - - - - -### High Analysis Accuracy, Measurable, and Unified Multi-Languages -- YASA is based on unified multi-language symbolic interpretation capabilities, offering high precision and scalability in static code analysis. It naturally supports field-sensitive, context-sensitive, object-sensitive, path-sensitive, and flow-sensitive capabilities in the field of static analysis. - -- During YASA's development, we used [xAST](https://github.com/alipay/ant-application-security-testing-benchmark) to evaluate and verify our capabilities, achieving "measurable capabilities." We compared YASA's performance with other open-source program analysis tools under the xAST evaluation system: - - - -### Open and Friendly -- Introduced the unified declarative rule query language YASA-UQL, compatible with CodeQL syntax, and pioneered a unified QL rule library for multiple languages, making program analysis more engineer-friendly. - -- Launched YASA MCP (LLM-friendly) and SDK (App development-friendly). - -## Quick Start - -[Getting Started](https://www.yuque.com/u22090306/bebf6g/evyf4chw26deq8xq) - -[Installation and Deployment](https://www.yuque.com/u22090306/bebf6g/gm7b32tcn9vosgll) - -## Join Us -Welcome to submit issues if you encounter any problems! - -For code contributions, please refer to [CONTRIBUTION](CONTRIBUTION.md) - -## Resource Links -[Official Documentation](https://www.yuque.com/u22090306/bebf6g) - -[Learning Resources](https://www.yuque.com/u22090306/bebf6g/sr0y5fqg0kcua5nf) - -[Community Activities](https://www.yuque.com/u22090306/bebf6g/fn1rauxwtp7z0l1u) - -## Open Source License -Apache License 2.0 - Details in LICENSE Apache-2.0. - -## Acknowledgments -Thanks to all developers who have contributed to the YASA project! Special thanks to the open-source community for their support and feedback, enabling us to jointly advance the development of program analysis technology. - -YASA - Making code analysis more precise, easier, and smarter. - -## Contact Us -[Official Website](https://cybersec.antgroup.com/station) - - diff --git a/build.sh b/build.sh old mode 100644 new mode 100755 index b5d6d689..242d4725 --- a/build.sh +++ b/build.sh @@ -27,43 +27,99 @@ info() { info "开始构建流程..." +# 步骤 0: 清理历史结果 +info "步骤 0/8: 清理历史结果 (rm -rf dist)" +if ! rm -rf dist > /dev/null; then + alert "清理历史结果失败" +fi +success "清理历史结果完成" + # 步骤 1: 安装依赖 -info "步骤 1/6: 安装依赖 (npm install)" -if ! npm install; then +info "步骤 1/8: 安装依赖 (npm install --package-lock=false)" +if ! npm install --package-lock=false > /dev/null; then alert "npm install 失败" fi success "依赖安装完成" # 步骤 2: 类型检查 -info "步骤 2/6: 类型检查 (npx tsc --noEmit)" -if ! npx tsc --noEmit; then +info "步骤 2/8: 类型检查 (npx tsc --noEmit)" +# 只重定向 stdout,保留 stderr 以便显示错误信息 +set +e +npx tsc --noEmit > /dev/null +TSC_CHECK_EXIT_CODE=$? +set -e +if [ $TSC_CHECK_EXIT_CODE -ne 0 ]; then alert "类型检查失败,请修复 TypeScript 错误" fi success "类型检查通过" -# 步骤 3: 运行所有测试 -info "步骤 3/6: 运行所有测试 (npm run test-all)" -if ! npm run test-all; then +# 步骤 3: 检查 require() 调用 +info "步骤 3/8: 检查 require() 调用 (node check-requires.js)" +if ! node check-requires.js > /dev/null; then + alert "require() 检查失败,请修复模块引用错误" +fi +success "require() 检查通过" + +# 步骤 4: 运行所有测试 +info "步骤 4/8: 运行所有测试 (npm run test-all)" +if ! npm run test-all > /dev/null; then alert "测试失败,请修复测试错误" fi success "所有测试通过" -# 步骤 4: 编译 TypeScript -info "步骤 4/6: 编译 TypeScript (npx tsc)" -if ! npx tsc; then - alert "TypeScript 编译失败" +# 步骤 5: 生成构建版本信息 +info "步骤 5/8: 生成构建版本信息" +BUILD_DATE=$(date +%Y%m%d) +COMMIT_HASH=$(git rev-parse --short HEAD 2>/dev/null || echo "unknown") + +# 创建 dist 目录(如果不存在) +mkdir -p dist + +# 生成版本信息文件(编译后代码会读取此文件) +cat > dist/build-version.json < /dev/null +TSC_EXIT_CODE=$? +set -e +if [ $TSC_EXIT_CODE -ne 0 ]; then + alert "TypeScript 编译失败,请查看上方的错误信息" fi success "TypeScript 编译完成" -# 步骤 5: 打包二进制 -info "步骤 5/6: 打包二进制 (npx pkg)" -if ! npx pkg . --options max-old-space-size=13312; then - alert "打包失败" +# 确保版本文件在编译后仍然存在(因为 tsc 可能会清理 dist) +mkdir -p dist +cat > dist/build-version.json < /dev/null +PKG_EXIT_CODE=$? +set -e +if [ $PKG_EXIT_CODE -ne 0 ]; then + alert "打包失败 (退出码: $PKG_EXIT_CODE),请查看上方的错误信息" fi success "打包完成" -# 步骤 6: 删除 dist 文件 -info "步骤 6/6: 删除 dist 文件" +# 步骤 8: 删除 dist 文件 +info "步骤 8/8: 删除 dist 文件" if [ -d "dist" ]; then rm -rf dist success "dist 文件已删除" @@ -72,4 +128,3 @@ else fi info "构建流程全部完成!" - diff --git a/check-requires.js b/check-requires.js new file mode 100755 index 00000000..799ff911 --- /dev/null +++ b/check-requires.js @@ -0,0 +1,237 @@ +#!/usr/bin/env node + +const fs = require('fs') +const path = require('path') +const { globSync } = require('fast-glob') + +/** + * 检查 require() 调用是否有效 + * 只检查 TypeScript 会编译的文件(根据 tsconfig.json 配置) + */ + +// 配置 +const PROJECT_ROOT = __dirname +const TSCONFIG_PATH = path.join(PROJECT_ROOT, 'tsconfig.json') + +/** + * 使用 TypeScript 编译器获取实际会编译的文件列表 + */ +function getTypeScriptFiles() { + const { execSync } = require('child_process') + + try { + // 使用 tsc --listFiles 获取实际编译的文件列表 + const output = execSync('npx tsc --listFiles --noEmit', { + cwd: PROJECT_ROOT, + encoding: 'utf-8', + stdio: ['pipe', 'pipe', 'pipe'], + }) + + // 解析输出,提取文件路径 + const files = output + .split('\n') + .map(line => line.trim()) + .filter(line => line && !line.startsWith('TS') && !line.includes('node_modules')) + .filter(line => { + // 只保留源文件,排除 .d.ts 和输出文件 + return line.endsWith('.ts') || line.endsWith('.js') + }) + .map(line => { + // 转换为绝对路径 + if (path.isAbsolute(line)) { + return line + } + return path.resolve(PROJECT_ROOT, line) + }) + .filter(file => { + // 排除输出目录中的文件 + return !file.includes('/dist/') && !file.includes('\\dist\\') + }) + + return [...new Set(files)] // 去重 + } catch (error) { + // 如果 tsc 执行失败,回退到使用 tsconfig.json + const tsconfigContent = fs.readFileSync(TSCONFIG_PATH, 'utf-8') + const tsconfig = JSON.parse(tsconfigContent) + const include = tsconfig.include || ['src/**/*.ts', 'src/**/*.js'] + const exclude = tsconfig.exclude || ['node_modules', 'test/**/*', 'dist'] + + // 使用 globSync 查找文件(同步方式) + return globSync(include, { + cwd: PROJECT_ROOT, + ignore: exclude, + absolute: true, + }) + } +} + +// 统计 +let totalFiles = 0 +let totalRequires = 0 +let invalidRequires = 0 +const invalidList = [] + +/** + * 解析 require 语句,提取模块路径 + */ +function extractRequires(content, filePath) { + const requires = [] + + // 匹配 require('xxx') 或 require("xxx") + const requireRegex = /require\s*\(\s*['"]([^'"]+)['"]\s*\)/g + let match + + while ((match = requireRegex.exec(content)) !== null) { + const modulePath = match[1] + const lineNumber = content.substring(0, match.index).split('\n').length + + requires.push({ + module: modulePath, + line: lineNumber, + column: match.index - content.lastIndexOf('\n', match.index) - 1, + }) + } + + return requires +} + +/** + * 检查模块是否存在 + */ +function checkModuleExists(modulePath, currentFile) { + // 相对路径 + if (modulePath.startsWith('.')) { + const currentDir = path.dirname(currentFile) + const resolvedPath = path.resolve(currentDir, modulePath) + + // 检查 .js, .ts, .json, 或目录下的 index.js/index.ts + const extensions = ['.js', '.ts', '.json', ''] + for (const ext of extensions) { + const fullPath = resolvedPath + ext + if (fs.existsSync(fullPath) && fs.statSync(fullPath).isFile()) { + return { exists: true, path: fullPath } + } + } + + // 检查目录下的 index 文件 + if (fs.existsSync(resolvedPath) && fs.statSync(resolvedPath).isDirectory()) { + for (const ext of ['.js', '.ts', '.json']) { + const indexPath = path.join(resolvedPath, 'index' + ext) + if (fs.existsSync(indexPath)) { + return { exists: true, path: indexPath } + } + } + // 目录存在但没有 index 文件,也算存在(可能是 package.json 的 main) + return { exists: true, path: resolvedPath, note: 'directory without index' } + } + + return { exists: false, path: resolvedPath } + } + + // node_modules 中的模块 + // 检查是否是内置模块 + const builtinModules = require('module').builtinModules + if (builtinModules.includes(modulePath)) { + return { exists: true, path: 'builtin', note: 'Node.js builtin module' } + } + + // 检查 node_modules + let checkPath = currentFile + while (checkPath !== path.dirname(checkPath)) { + const nodeModulesPath = path.join(checkPath, 'node_modules', modulePath) + if (fs.existsSync(nodeModulesPath)) { + return { exists: true, path: nodeModulesPath } + } + checkPath = path.dirname(checkPath) + } + + // 检查项目根目录的 node_modules + const rootNodeModules = path.join(PROJECT_ROOT, 'node_modules', modulePath) + if (fs.existsSync(rootNodeModules)) { + return { exists: true, path: rootNodeModules } + } + + return { exists: false, path: modulePath } +} + +/** + * 检查单个文件 + */ +function checkFile(filePath) { + try { + const content = fs.readFileSync(filePath, 'utf-8') + const requires = extractRequires(content, filePath) + + if (requires.length === 0) { + return + } + + totalFiles++ + totalRequires += requires.length + + for (const req of requires) { + const checkResult = checkModuleExists(req.module, filePath) + + if (!checkResult.exists) { + invalidRequires++ + invalidList.push({ + file: path.relative(PROJECT_ROOT, filePath), + line: req.line, + column: req.column, + module: req.module, + resolved: checkResult.path, + }) + } + } + } catch (error) { + console.error(`Error reading file ${filePath}:`, error.message) + } +} + +/** + * 主函数 + */ +function main() { + // 使用 TypeScript 编译器获取实际会编译的文件 + const files = getTypeScriptFiles() + + // 检查每个文件 + for (const file of files) { + checkFile(file) + } + + // 输出结果(简化版,类似编译器错误输出) + if (invalidRequires > 0) { + // 按文件分组 + const grouped = {} + for (const item of invalidList) { + if (!grouped[item.file]) { + grouped[item.file] = [] + } + grouped[item.file].push(item) + } + + // 输出错误,格式类似 TypeScript 编译器 + for (const [file, items] of Object.entries(grouped).sort()) { + for (const item of items) { + console.error(`${file}(${item.line},${item.column + 1}): error: Cannot find module '${item.module}'`) + } + } + + console.error(`\nFound ${invalidRequires} error(s).`) + process.exit(1) + } + + // 成功时输出简要信息 + console.log(`Checked ${totalRequires} require() call(s) in ${totalFiles} file(s). All valid.`) + process.exit(0) +} + +// 运行 +try { + main() +} catch (error) { + console.error('执行出错:', error) + process.exit(1) +} + diff --git a/install_deps.sh b/install_deps.sh index b3efd94c..292384dc 100644 --- a/install_deps.sh +++ b/install_deps.sh @@ -4,7 +4,7 @@ detect_platform() { OS=$(uname -s | tr '[:upper:]' '[:lower:]') ARCH=$(uname -m) - + case "$OS" in linux) case "$ARCH" in @@ -37,7 +37,6 @@ check_directory() { # Download binary files download_binaries() { PLATFORM=$1 - echo "[INFO] Downloading latest release binaries for platform: $PLATFORM..." # Create target directories @@ -91,4 +90,4 @@ main() { echo "[INFO] Build completed successfully." } -main "$@" \ No newline at end of file +main "$@" diff --git a/package.json b/package.json index be1f393d..e629d26a 100644 --- a/package.json +++ b/package.json @@ -5,8 +5,8 @@ "main": "./dist/main.js", "bin": "./dist/main.js", "dependencies": { - "@ant-yasa/uast-parser-java-js": "^0.1.49", - "@ant-yasa/uast-spec": "^0.1.26", + "@ant-yasa/uast-parser-java-js": "^0.2.9", + "@ant-yasa/uast-spec": "^0.2.9", "@babel/core": "^7.14.6", "@babel/parser": "^7.16.4", "@babel/plugin-proposal-decorators": "^7.14.5", @@ -33,7 +33,7 @@ "node-uuid": "^1.4.8", "semver": "^7.3.8", "tmp": "^0.2.3", - "tsx": "^4.20.6", + "tsx": "^4.21.0", "underscore": "^1.9.1", "xml2js": "^0.6.2" }, @@ -49,6 +49,7 @@ "@typescript-eslint/parser": "^5.62.0", "async": "^3.2.0", "babel-preset-es2015": "^6.24.1", + "baseline-browser-mapping": "^2.9.11", "chai": "^4.2.0", "eslint": "^8.57.1", "eslint-config-airbnb-base": "^15.0.0", @@ -67,7 +68,7 @@ "gulp-rename": "^2.0.0", "gulp-uglify": "^3.0.2", "gulp-uglify-es": "^3.0.0", - "javascript-obfuscator": "^2.19.0", + "javascript-obfuscator": "^4.1.0", "jscpd": "^4.0.5", "jsdoc": "^4.0.2", "mocha": "^8.4.0", @@ -86,7 +87,9 @@ "test-java": "npx mocha --require tsx/cjs test/java/test-java-benchmark.ts", "test-go": "npx mocha --require tsx/cjs test/go/test-go-benchmark.ts", "test-python": "npx mocha --require tsx/cjs test/python/test-python-benchmark.ts", - "test-all": "npm run test-js && npm run test-java && npm run test-go && npm run test-python", + "test-callchain": "npx mocha --require tsx/cjs test/callchain/test-callchain-benchmark.ts", + "test-callargs": "npx mocha --require tsx/cjs test/callargs/test-callargs.ts", + "test-all": "npm run test-callargs && npm run test-js && npm run test-java && npm run test-go && npm run test-python && npm run test-callchain", "build": "bash build.sh", "lint": "eslint .", "lint:duplicates": "jscpd .", @@ -168,7 +171,9 @@ ], "assets": [ "dist/**/*", - "resource/**/*" + "resource/**/*", + "deps/uast4go/uast4go", + "deps/uast4py/uast4py" ], "targets": [ "node18-macos-arm64", diff --git a/resource/checker/checker-config.json b/resource/checker/checker-config.json index 90519bfa..2638516a 100644 --- a/resource/checker/checker-config.json +++ b/resource/checker/checker-config.json @@ -140,6 +140,11 @@ "checkerPath": "checker/taint/python/tornado-taint-checker.ts", "description": "python Tornado框架 entrypoint采集以及框架source添加" }, + { + "checkerId": "taint_flow_python_script_input", + "checkerPath": "checker/taint/python/script-taint-checker.ts", + "description": "Python脚本命令行参数source添加,支持argparse/sys.argv/input/os.environ/getopt等" + }, { "checkerId": "taint_flow_test", "checkerPath": "checker/taint/test-taint-checker.ts", @@ -151,11 +156,6 @@ "checkerPath": "checker/taint/go/restful-entrypoint-collect-checker.ts", "description": "go-restful entrypoint采集以及框架source添加" }, - { - "checkerId": "echo-entrypoint-collect-checker", - "checkerPath": "checker/taint/go/echo-entrypoint-collect-checker.ts", - "description": "echo entrypoint采集以及框架source添加" - }, { "checkerId": "beego-entrypoint-collect-checker", "checkerPath": "checker/taint/go/beego-entrypoint-collect-checker.ts", @@ -170,5 +170,29 @@ "checkerId": "get_ast_source_code", "checkerPath": "checker/sdk/get-ast-source-code-checker.ts", "description": "获取AST对应的源码" + }, + { + "checkerId": "callchain_java", + "checkerPath": "checker/callchain/java/java-callchain-checker.ts", + "description": "Java callchain checker,只检测sink匹配并输出调用链路", + "demoRuleConfigPath": "resource/example-rule-config/rule_config_java.json" + }, + { + "checkerId": "callchain_go", + "checkerPath": "checker/callchain/go/go-callchain-checker.ts", + "description": "Go callchain checker,只检测sink匹配并输出调用链路", + "demoRuleConfigPath": "resource/example-rule-config/rule_config_go.json" + }, + { + "checkerId": "callchain_js", + "checkerPath": "checker/callchain/js/js-callchain-checker.ts", + "description": "JavaScript callchain checker,只检测sink匹配并输出调用链路", + "demoRuleConfigPath": "resource/example-rule-config/rule_config_js.json" + }, + { + "checkerId": "callchain_python", + "checkerPath": "checker/callchain/python/python-callchain-checker.ts", + "description": "Python callchain checker,只检测sink匹配并输出调用链路", + "demoRuleConfigPath": "resource/example-rule-config/rule_config_python.json" } ] diff --git a/resource/checker/checker-pack-config.json b/resource/checker/checker-pack-config.json index 3d7b95fb..21387ea4 100644 --- a/resource/checker/checker-pack-config.json +++ b/resource/checker/checker-pack-config.json @@ -6,7 +6,6 @@ "taint_flow_go_input", "cobra.Command-builtIn", "go-restful-entryPoints-collect-checker", - "echo-entrypoint-collect-checker", "beego-entrypoint-collect-checker", "gorilla-mux-entrypoint-collect-checker", "gRpc-entryPoint-collect-checker", @@ -24,6 +23,7 @@ "taint_flow_gin_input_inner", "cobra.Command-builtIn", "go-restful-entryPoints-collect-checker", + "beego-entrypoint-collect-checker", "gorilla-mux-entrypoint-collect-checker", "gRpc-entryPoint-collect-checker", "go-main-entryPoints-collection", @@ -125,7 +125,33 @@ "callgraph" ], "description": "java的sdk-蚂蚁内部使用的规则包" + }, + { + "checkerPackId": "callchain-java", + "checkerIds": [ + "callchain_java" + ], + "description": "Java callchain checker - 只检测sink匹配" + }, + { + "checkerPackId": "callchain-go", + "checkerIds": [ + "callchain_go" + ], + "description": "Go callchain checker - 只检测sink匹配" + }, + { + "checkerPackId": "callchain-js", + "checkerIds": [ + "callchain_js" + ], + "description": "JavaScript callchain checker - 只检测sink匹配" + }, + { + "checkerPackId": "callchain-python", + "checkerIds": [ + "callchain_python" + ], + "description": "Python callchain checker - 只检测sink匹配" } - - ] diff --git a/test.js b/resource/checker/lib-arg-to-this-sid-blacklist.json similarity index 100% rename from test.js rename to resource/checker/lib-arg-to-this-sid-blacklist.json diff --git a/resource/example-rule-config/rule_config_go.json b/resource/example-rule-config/rule_config_go.json index 71dde301..2770fc3d 100644 --- a/resource/example-rule-config/rule_config_go.json +++ b/resource/example-rule-config/rule_config_go.json @@ -468,15 +468,6 @@ } ], "FuncCallArgTaintSource": [ - { - "args": [ - "0" - ], - "calleeType": "echo.Context", - "fsig": "Bind", - "scopeFile": "all", - "scopeFunc": "all" - }, { "args": [ "0" diff --git a/resource/example-rule-config/rule_config_python.json b/resource/example-rule-config/rule_config_python.json index 1b866057..93de362d 100644 --- a/resource/example-rule-config/rule_config_python.json +++ b/resource/example-rule-config/rule_config_python.json @@ -1,11 +1,6 @@ [ { - "checkerIds": [ - "taint_flow_python_input", - "taint_flow_python_input_inner", - "taint_flow_python_django_input", - "taint_flow_python_tornado_input" - ], + "checkerIds": ["taint_flow_python_input", "taint_flow_python_input_inner", "taint_flow_python_django_input"], "sources": { "FuncCallReturnValueTaintSource": [ { diff --git a/resource/java/class-hierarchy-and-modeling.json b/resource/java/class-hierarchy-and-modeling.json index 102068b7..6124f838 100644 --- a/resource/java/class-hierarchy-and-modeling.json +++ b/resource/java/class-hierarchy-and-modeling.json @@ -157,15 +157,17 @@ "sun.net.www.http.KeepAliveCache" ] }, - "java.util.concurrent.Executor": { - "modelingFilePath": "./builtins/executor-builtins", + "java.util.concurrent.ExecutorService": { + "modelingFilePath": "./builtins/executorservice-builtins", "subTypeList": [ "java.util.concurrent.AbstractExecutorService", - "java.util.concurrent.ExecutorService", "java.util.concurrent.ForkJoinPool", "java.util.concurrent.ScheduledExecutorService", "java.util.concurrent.ScheduledThreadPoolExecutor", - "java.util.concurrent.ThreadPoolExecutor" + "java.util.concurrent.ThreadPoolExecutor", + "com.alipay.sofa.common.thread.SofaScheduledThreadPoolExecutor", + "com.alipay.sofa.common.thread.SofaThreadPoolExecutor", + "com.alipay.sofa.common.thread.SofaThreadPoolTaskExecutor" ] }, "java.util.Timer": { @@ -183,5 +185,29 @@ "java.util.concurrent.atomic.AtomicReference": { "modelingFilePath": "./builtins/atomicreference-builtins", "subTypeList": [] + }, + "java.lang.Class": { + "modelingFilePath": "./builtins/class-builtins", + "subTypeList": [] + }, + "java.lang.Object": { + "modelingFilePath": "./builtins/object-builtins", + "subTypeList": [] + }, + "java.util.stream.Stream": { + "modelingFilePath": "./builtins/stream-builtins", + "subTypeList": [] + }, + "com.baomidou.mybatisplus.core.conditions.query.QueryWrapper": { + "modelingFilePath": "./builtins/querywrapper-builtins", + "subTypeList": [] + }, + "com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper": { + "modelingFilePath": "./builtins/lambdaquerywrapper-builtins", + "subTypeList": [] + }, + "java.util.Arrays": { + "modelingFilePath": "./builtins/arrays-builtins", + "subTypeList": [] } } diff --git a/resource/python/python-default-rule.json b/resource/python/python-default-rule.json index 9b8d13fc..69bd25b1 100644 --- a/resource/python/python-default-rule.json +++ b/resource/python/python-default-rule.json @@ -1,15 +1,17 @@ [ { - "checkerIds": [ - "taint_flow_python_input", - "taint_flow_python_input_inner" - ], + "checkerIds": ["taint_flow_python_input", "taint_flow_python_input_inner"], "sources": { "TaintSource": [ { "path": "flask.request", "scopeFile": "all", "scopeFunc": "all" + }, + { + "path": "request", + "scopeFile": "all", + "scopeFunc": "all" } ] }, @@ -17,9 +19,7 @@ "FuncCallTaintSink": [ { "fsig": "os.system", - "args": [ - 0 - ] + "args": [0] } ] } diff --git a/resource/tag-propagation/lib-arg-to-this-sid-blacklist.json b/resource/tag-propagation/lib-arg-to-this-sid-blacklist.json new file mode 100644 index 00000000..ca47f165 --- /dev/null +++ b/resource/tag-propagation/lib-arg-to-this-sid-blacklist.json @@ -0,0 +1,28 @@ +{ + "sidKeywords": [ + "log", + "logger", + "logging", + "console", + "print", + "println", + "printf", + "debug", + "trace", + "info", + "warn", + "error", + "fatal", + "format", + "formatter", + "stringify", + "serialize", + "dump", + "inspect", + "metric", + "metrics", + "telemetry", + "audit", + "report" + ] +} diff --git a/resource/tag-propagation/lib-func-tag-propagation-rule.json b/resource/tag-propagation/lib-func-tag-propagation-rule.json index d645142f..e8a44f2b 100644 --- a/resource/tag-propagation/lib-func-tag-propagation-rule.json +++ b/resource/tag-propagation/lib-func-tag-propagation-rule.json @@ -19,29 +19,45 @@ }, { "func": { - "calleeType": "CompilerConfiguration", - "fsig": "addCompilationCustomizers" + "calleeType": "BeanUtils", + "fsig": "copyProperties", + "argNum": 2 }, "source": { - "type": "ARG" + "type": "ARG", + "index": 0 }, "target": { - "type": "THIS" + "type": "ARG", + "index": 1 } }, { "func": { - "calleeType": "BeanUtils", - "fsig": "copyProperties", - "argNum": 2 + "calleeType": "ProcessBuilder", + "fsig": "redirectError", + "argNum": 1 }, "source": { + "type": "THIS" + }, + "target": { "type": "ARG", "index": 0 + } + }, + { + "func": { + "calleeType": "ProcessBuilder", + "fsig": "redirectOutput", + "argNum": 1 + }, + "source": { + "type": "THIS" }, "target": { "type": "ARG", - "index": 1 + "index": 0 } } ] diff --git a/src/checker/antql/rules/antql-getbaseclass.ts b/src/checker/antql/rules/antql-getbaseclass.ts index 88cfa487..85055637 100644 --- a/src/checker/antql/rules/antql-getbaseclass.ts +++ b/src/checker/antql/rules/antql-getbaseclass.ts @@ -1,7 +1,7 @@ import type { Finding } from '../../../engine/analyzer/common/common-types' const LocationUtil = require('../util/location-util') -const QidUnifyUtil = require('../util/qid-unify-util') +const QidUnifyUtil = require('../../../util/qid-unify-util') const Config = require('../../../config') const Checker = require('../../common/checker') const InteractiveOutputStrategy = require('../../common/output/interactive-output-strategy') @@ -86,8 +86,8 @@ class AntqlGetBaseClass extends Checker { // 获取基类 const superSymbol = info?.val?.super if (superSymbol && (superSymbol?.vtype === 'object' || superSymbol?.vtype === 'class')) { - const superClassId = QidUnifyUtil.unify(superSymbol) - const classId = QidUnifyUtil.unify(info?.val) + const superClassId = QidUnifyUtil.qidUnifyForQL(superSymbol) + const classId = QidUnifyUtil.qidUnifyForQL(info?.val) const nodeLoc = LocationUtil.convertUastLocationToString(node.loc, Config.prefixPath) diff --git a/src/checker/antql/rules/antql-getdefinition.ts b/src/checker/antql/rules/antql-getdefinition.ts index 2fdd17e4..122d2471 100644 --- a/src/checker/antql/rules/antql-getdefinition.ts +++ b/src/checker/antql/rules/antql-getdefinition.ts @@ -3,7 +3,7 @@ import type { Finding } from '../../../engine/analyzer/common/common-types' const LocationUtil = require('../util/location-util') const EntrypointUtil = require('../util/entrypoint-util') const Config = require('../../../config') -const QidUnifyUtil = require('../util/qid-unify-util') +const QidUnifyUtil = require('../../../util/qid-unify-util') const logger = require('../../../util/logger')(__filename) const Checker = require('../../common/checker') const InteractiveOutputStrategy = require('../../common/output/interactive-output-strategy') @@ -85,7 +85,8 @@ class AntQLGetDefinition extends Checker { const fullCallGraphEntrypoint = fullCallGraphFileEntryPoint.getEntryPointsUsingCallGraphByLoc( LocationUtil.convertQLLocationStringListToUastLocation([this.input], Config.prefixPath), analyzer.ainfo?.callgraph, - analyzer.fileManager + analyzer.fileManager, + analyzer ) const uniqueEntries = EntrypointUtil.mergeEntryPoints(fullCallGraphEntrypoint, analyzer.entryPoints) analyzer.entryPoints = Array.from(uniqueEntries.values()) @@ -107,7 +108,7 @@ class AntQLGetDefinition extends Checker { const qlLocationString = LocationUtil.findUastLocationInList(node?.loc, [this.input], Config.prefixPath) if (qlLocationString) { const finding: Finding = { - output: QidUnifyUtil.unify(info.val), + output: QidUnifyUtil.qidUnifyForQL(info.val), } this.resultManager.newFinding(finding, InteractiveOutputStrategy.outputStrategyId) } diff --git a/src/checker/antql/rules/antql-hasflow.ts b/src/checker/antql/rules/antql-hasflow.ts index ed61469c..84fdf94c 100644 --- a/src/checker/antql/rules/antql-hasflow.ts +++ b/src/checker/antql/rules/antql-hasflow.ts @@ -111,10 +111,7 @@ class AntQLHasFlow extends TaintChecker { for (const sourceLoc in this.sourceSymbol) { const symbol = this.sourceSymbol[sourceLoc] if (symbol !== '') { - symbol._has_tags = undefined - symbol.hasTagRec = undefined - symbol._tags = undefined - symbol.trace = undefined + symbol.taint.clear() symbol.value = {} // symbol.misc_ = {} } @@ -152,7 +149,8 @@ class AntQLHasFlow extends TaintChecker { const fullCallGraphEntrypoint = fullCallGraphFileEntryPoint.getEntryPointsUsingCallGraphByLoc( LocationUtil.convertQLLocationStringListToUastLocation(this.sourceLocs, Config.prefixPath), analyzer.ainfo?.callgraph, - analyzer.fileManager + analyzer.fileManager, + analyzer ) const uniqueEntries = EntrypointUtil.mergeEntryPoints(fullCallGraphEntrypoint, analyzer.entryPoints) analyzer.entryPoints = Array.from(uniqueEntries.values()) @@ -184,13 +182,14 @@ class AntQLHasFlow extends TaintChecker { */ markTaintSource(unit: any, { node, kind }: { node: any; kind: string }): void { SourceUtil.setTaint(unit, kind) + const existingTrace = unit.taint.getFirstTrace() if ( - unit.trace && - Array.isArray(unit.trace) && - (unit.trace[0]?.tag !== 'SOURCE: ' || - (typeof unit.trace[0]?.str === 'string' && !unit.trace[0].str.includes('SOURCE: '))) + existingTrace && + Array.isArray(existingTrace) && + (existingTrace[0]?.tag !== 'SOURCE: ' || + (typeof existingTrace[0]?.str === 'string' && !existingTrace[0].str.includes('SOURCE: '))) ) { - unit.trace = undefined + unit.taint.clearTrace() } else { const startLine = node?.loc?.start?.line const endLine = node?.loc?.end?.line @@ -203,10 +202,7 @@ class AntQLHasFlow extends TaintChecker { affectedNodeName: AstUtil.prettyPrint(node), } - if (!unit.trace) { - unit.trace = [] - } - unit.trace.push(trace) + unit.taint.addTraceToAllTags(trace) } } @@ -289,7 +285,7 @@ class AntQLHasFlow extends TaintChecker { ): any { const finding = BasicRuleHandler.getFinding(this.getCheckerId(), this.desc, currentNode) // const finding = this.mng.newFinding(this.getCheckerId(), currentNode, currentNode.loc, sourceNode, fclos.id) - if (finding && sourceNode.hasTagRec) { + if (finding && sourceNode.taint?.isTaintedRec) { const sourceTrace = FindingUtil.getTrace(sourceNode, tag) if (sourceTrace.length > 0) { let flag = false diff --git a/src/checker/antql/rules/antql-hasfunctioncall.ts b/src/checker/antql/rules/antql-hasfunctioncall.ts index b99961ca..4254c794 100644 --- a/src/checker/antql/rules/antql-hasfunctioncall.ts +++ b/src/checker/antql/rules/antql-hasfunctioncall.ts @@ -5,7 +5,7 @@ const LocationUtil = require('../util/location-util') const EntrypointUtil = require('../util/entrypoint-util') const Config = require('../../../config') const SymbolUtil = require('../util/symbol-util') -const QidUnifyUtil = require('../util/qid-unify-util') +const QidUnifyUtil = require('../../../util/qid-unify-util') const Checker = require('../../common/checker') const InteractiveOutputStrategy = require('../../common/output/interactive-output-strategy') @@ -21,7 +21,7 @@ class AntQLHasFunctionCall extends Checker { output: string[] - symbolMap: Map + antQLSymbolMap: Map input!: string @@ -37,7 +37,7 @@ class AntQLHasFunctionCall extends Checker { this.kit = mng.kit this.status = false this.output = [] - this.symbolMap = new Map() + this.antQLSymbolMap = new Map() } /** @@ -77,19 +77,19 @@ class AntQLHasFunctionCall extends Checker { } if (this.input.includes('*') || this.input.includes('**')) { - const qidList = Array.from(this.symbolMap.keys()) + const qidList = Array.from(this.antQLSymbolMap.keys()) const output: string[] = [] for (const qid of qidList) { if (SymbolUtil.matchPattern(qid, this.input)) { - const locations = this.symbolMap.get(qid) + const locations = this.antQLSymbolMap.get(qid) if (locations) { output.push(...locations) } } } finding.output = output.join(',') - } else if (this.symbolMap.has(this.input)) { - const locations = this.symbolMap.get(this.input) + } else if (this.antQLSymbolMap.has(this.input)) { + const locations = this.antQLSymbolMap.get(this.input) finding.output = locations ? locations.join(',') : '' } this.resultManager.newFinding(finding, InteractiveOutputStrategy.outputStrategyId) @@ -116,7 +116,8 @@ class AntQLHasFunctionCall extends Checker { const fullCallGraphEntrypoint = fullCallGraphFileEntryPoint.getEntryPointsUsingCallGraphByKeyWords( [keyword], analyzer.ainfo?.callgraph, - analyzer.fileManager + analyzer.fileManager, + analyzer ) const uniqueEntries = EntrypointUtil.mergeEntryPoints(fullCallGraphEntrypoint, analyzer.entryPoints) const prepareEntryPoints: EntryPoint[] = [] @@ -143,14 +144,14 @@ class AntQLHasFunctionCall extends Checker { */ triggerAtFunctionCallBefore(analyzer: any, scope: any, node: any, state: any, info: any): void { const { fclos } = info - const checkQid = QidUnifyUtil.unify(fclos) + const checkQid = QidUnifyUtil.qidUnifyForQL(fclos) if (checkQid) { const nodeLoc = LocationUtil.convertUastLocationToString(node.loc, Config.prefixPath) - if (!this.symbolMap.has(checkQid)) { - this.symbolMap.set(checkQid, []) + if (!this.antQLSymbolMap.has(checkQid)) { + this.antQLSymbolMap.set(checkQid, []) } - const locations = this.symbolMap.get(checkQid) + const locations = this.antQLSymbolMap.get(checkQid) if (locations && !locations.includes(nodeLoc)) { locations.push(nodeLoc) } diff --git a/src/checker/antql/rules/antql-hasproperty.ts b/src/checker/antql/rules/antql-hasproperty.ts index 325ddd02..a3d42260 100644 --- a/src/checker/antql/rules/antql-hasproperty.ts +++ b/src/checker/antql/rules/antql-hasproperty.ts @@ -3,7 +3,7 @@ import type { EntryPoint } from '../../../engine/analyzer/common/entrypoint' const LocationUtil = require('../util/location-util') const EntrypointUtil = require('../util/entrypoint-util') -const QidUnifyUtil = require('../util/qid-unify-util') +const QidUnifyUtil = require('../../../util/qid-unify-util') const Config = require('../../../config') const SymbolUtil = require('../util/symbol-util') const logger = require('../../../util/logger')(__filename) @@ -22,7 +22,7 @@ class AntQLHasProperty extends Checker { output: string[] - symbolMap: Map + antQLSymbolMap: Map alreadyExecutedEntries: Map @@ -38,7 +38,7 @@ class AntQLHasProperty extends Checker { this.kit = mng.kit this.status = false this.output = [] - this.symbolMap = new Map() + this.antQLSymbolMap = new Map() this.alreadyExecutedEntries = new Map() } @@ -72,18 +72,18 @@ class AntQLHasProperty extends Checker { } if (this.input.includes('*') || this.input.includes('**')) { const output: string[] = [] - const qidList = Array.from(this.symbolMap.keys()) + const qidList = Array.from(this.antQLSymbolMap.keys()) for (const qid of qidList) { if (SymbolUtil.matchPattern(qid, this.input)) { - const locations = this.symbolMap.get(qid) + const locations = this.antQLSymbolMap.get(qid) if (locations) { output.push(...locations) } } } finding.output = output.join(',') - } else if (this.symbolMap.has(this.input)) { - const locations = this.symbolMap.get(this.input) + } else if (this.antQLSymbolMap.has(this.input)) { + const locations = this.antQLSymbolMap.get(this.input) finding.output = locations ? locations.join(',') : '' } this.status = false @@ -111,7 +111,8 @@ class AntQLHasProperty extends Checker { const fullCallGraphEntrypoint = fullCallGraphFileEntryPoint.getEntryPointsUsingCallGraphByKeyWords( [keyword], analyzer.ainfo?.callgraph, - analyzer.fileManager + analyzer.fileManager, + analyzer ) const uniqueEntries = EntrypointUtil.mergeEntryPoints(fullCallGraphEntrypoint, analyzer.entryPoints) // analyzer.entryPoints = Array.from(uniqueEntries.values()) @@ -152,13 +153,13 @@ class AntQLHasProperty extends Checker { * @param info */ private checkIsIdentifier(node: any, res: any, scope: any, info: any): void { - const checkQid = QidUnifyUtil.unify(res) + const checkQid = QidUnifyUtil.qidUnifyForQL(res) if (checkQid) { const nodeLoc = LocationUtil.convertUastLocationToString(node.loc, Config.prefixPath) - if (!this.symbolMap.has(checkQid)) { - this.symbolMap.set(checkQid, []) + if (!this.antQLSymbolMap.has(checkQid)) { + this.antQLSymbolMap.set(checkQid, []) } - const locations = this.symbolMap.get(checkQid) + const locations = this.antQLSymbolMap.get(checkQid) if (locations && !locations.includes(nodeLoc)) { locations.push(nodeLoc) } diff --git a/src/checker/antql/util/entrypoint-util.ts b/src/checker/antql/util/entrypoint-util.ts index f8606b1e..369d39d9 100644 --- a/src/checker/antql/util/entrypoint-util.ts +++ b/src/checker/antql/util/entrypoint-util.ts @@ -28,7 +28,7 @@ function mergeEntryPoints(entryPoints: EntryPoint[], analyzerEntryPoints: EntryP * @param entryPoint */ function getEntryPointUniqueKey(entryPoint: EntryPoint): string { - const loc = entryPoint?.entryPointSymVal?.ast?.loc + const loc = entryPoint?.entryPointSymVal?.ast?.node?.loc if (loc) { return `${loc?.sourcefile}:${loc?.start?.line}:${loc?.start?.column}:${loc?.end?.line}:${loc?.end?.column}` } diff --git a/src/checker/antql/util/qid-unify-util.ts b/src/checker/antql/util/qid-unify-util.ts deleted file mode 100644 index 6ac4f6a4..00000000 --- a/src/checker/antql/util/qid-unify-util.ts +++ /dev/null @@ -1,147 +0,0 @@ -interface SymbolLike { - qid?: string - vtype?: string - sid?: string - [key: string]: any -} - -/** - * 统一各语言的qid - */ -class QidUnifyUtil { - symbol: SymbolLike | undefined - - value: string - - /** - * 需要传符号值 - * @param symbol - */ - constructor(symbol?: SymbolLike) { - this.symbol = symbol - this.value = symbol?.qid || '' - } - - /** - * 统一路径形式,将开头的"/"去掉,并将每一层目录替换成".", 即 /tp/2.func ==> tp.2.func - */ - removePath(): QidUnifyUtil { - this.value = this.value?.replace(/^\//, '').replace(/\//g, '.') - return this - } - - /** - * python中找不到import时,会以"syslib_from."开头 - */ - removeSyslibFrom(): QidUnifyUtil { - if (this.value.startsWith('syslib_from.')) { - this.value = this.value.replace('syslib_from.', '') - } - return this - } - - /** - * js-chair框架会将agg替换成Egg.Application,将ctx替换成Egg.Context,替换回来 - */ - removeChair(): QidUnifyUtil { - this.value = this.value.replace('Egg.Application', 'app') - this.value = this.value.replace('Egg.Context', 'ctx') - return this - } - - /** - * 去除所有的括号及括号内内容(包括嵌套)——更通用的情况 - */ - removeParentheses(): QidUnifyUtil { - let result = '' - let level = 0 - for (const char of this.value) { - if (char === '(') { - level++ - } else if (char === ')') { - if (level > 0) level-- - } else if (level === 0) { - result += char - } - } - this.value = result - return this - } - - /** - * remove *_scope.写法,即1.calculate.calculate_scope..process ==> 1.calculate.process - */ - removeBlock(): QidUnifyUtil { - if (!this.value.includes(' 0 ? temp[i - 1] : 'NaN' - if (curStr === `${preStr}_scope`) { - continue - } - // 移除掉多余的 - if (curStr.startsWith('.,去掉 - */ - removeInstance(): QidUnifyUtil { - this.value = this.value.replace('', '') - return this - } - - /** - * 统一去掉 - */ - removeGlobal(): QidUnifyUtil { - this.value = this.value.replace('.', '') - return this - } - - /** - * 获取当前的值 - */ - get(): string { - return this.value - } - - /** - * 静态方法,用于调用上面所有的方法,一步到位统一符号值qid - * @param symbol - */ - static unify(symbol?: SymbolLike): string { - let unifyID = symbol?.qid || '' - if (symbol?.vtype !== 'primitive' && symbol?.vtype !== 'uninitialized') { - unifyID = new QidUnifyUtil(symbol) - .removePath() - .removeSyslibFrom() - .removeChair() - .removeParentheses() - .removeBlock() - .removeInstance() - .removeGlobal() - .get() - } - return unifyID - } -} - -module.exports = QidUnifyUtil diff --git a/src/checker/callchain/callchain-checker.ts b/src/checker/callchain/callchain-checker.ts new file mode 100644 index 00000000..78b1c357 --- /dev/null +++ b/src/checker/callchain/callchain-checker.ts @@ -0,0 +1,342 @@ +import type { CallInfo } from '../../engine/analyzer/common/call-args' + +const _ = require('lodash') +const Checker = require('../common/checker') +const AstUtil = require('../../util/ast-util') +const SourceLine = require('../../engine/analyzer/common/source-line') +const entryPointConfig = require('../../engine/analyzer/common/current-entrypoint') +const RulesBasicHandler = require('../common/rules-basic-handler') +const Config = require('../../config') +const QidUnifyUtil = require('../../util/qid-unify-util') +const CallchainOutputStrategy = require('../common/output/callchain-output-strategy') + +/** + * basic class for callchain checker + * This checker only detects sink matches and outputs call chains, + * without checking for taint flow + */ +class CallchainChecker extends Checker { + /** + * constructor of CallchainChecker + * @param resultManager + * @param checkerId + */ + constructor(resultManager: any, checkerId: any) { + super(resultManager, checkerId) + this.sinkRuleArray = undefined + this.matchSinkRuleResultMap = new Map() + } + + /** + * 从 fclos 中提取文件路径(相对路径) + * @param fclos + */ + extractFilePath(fclos: any): string { + const sourcefile = fclos?.ast?.node?.loc?.sourcefile || fclos?.loc?.sourcefile + if (!sourcefile) return '' + return this.toRelativePath(sourcefile) + } + + /** + * 从 state.callstack 中构建调用链信息 + * 每个元素包含 CallstackElement 的内容(type, nodeHash, funcDef, fullName) + * 以及额外的可读信息(function, file, line, column) + * 最后追加 sink 调用点(CallExpression node)的信息 + * @param callstack + * @param sinkNode + * @param sinkFclos + */ + buildCallstackInfo(callstack: any[], sinkNode: any, sinkFclos: any): any[] { + const result: any[] = [] + + // 1. 记录从 entrypoint 到 sink 的函数调用链(与 sarif CallstackElement 统一) + if (callstack && callstack.length > 0) { + for (const fclos of callstack) { + if (!fclos) continue + + const astNode = fclos.ast?.node + const loc = astNode?.loc + const sourcefile = this.extractFilePath(fclos) + const funcName = astNode?.id?.name || fclos.name || fclos.sid || '' + const qid = fclos.qid || '' + + const entry: any = { + // CallstackElement 标准字段 + type: 0, + nodeHash: astNode?._meta?.nodehash || null, + fullName: qid ? QidUnifyUtil.qidUnifyByRemoveAngleAndPrefix(qid) : null, + // 额外可读信息 + function: funcName, + file: sourcefile, + line: loc?.start?.line, + column: loc?.start?.column, + } + + if (loc?.start?.column) { + entry.column = loc.start.column + } + + result.push(entry) + } + } + + // 2. 记录 sink 调用点(CallExpression node)的信息 + if (sinkNode) { + let sourcefile = '' + let srcNode = sinkNode + while (srcNode && !srcNode?.loc?.sourcefile) { + srcNode = srcNode.parent + } + if (srcNode?.loc?.sourcefile) { + sourcefile = this.toRelativePath(srcNode.loc.sourcefile) + } else if (sinkFclos) { + sourcefile = this.extractFilePath(sinkFclos) + } + const funcName = sinkNode?.id?.name || sinkFclos.name || sinkFclos.sid || '' + result.push({ + // CallstackElement 标准字段 + type: 1, + nodeHash: sinkNode?._meta?.nodehash || null, + // sink 调用点信息 + fullName: QidUnifyUtil.qidUnifyByRemoveAngleAndPrefix(sinkFclos.qid) || null, + function: funcName, + file: sourcefile, + line: sinkNode.loc?.start?.line, + column: sinkNode.loc?.start?.column, + }) + } + + return result + } + + /** + * 将绝对路径转换为相对路径 + * @param sourcefile + */ + toRelativePath(sourcefile: string): string { + if (!sourcefile) return '' + if (Config.maindirPrefix && sourcefile.startsWith(Config.maindirPrefix)) { + return sourcefile.substring(Config.maindirPrefix.length) + } + if (Config.maindir && sourcefile.startsWith(Config.maindir)) { + return sourcefile.substring(Config.maindir.length) + } + return sourcefile + } + + /** + * 从 sink 调用节点 (CallExpression node) 中提取调用点信息 + * @param node + * @param fclos + */ + buildSinkCallSiteInfo(node: any, fclos: any): any { + if (!node) return {} + + const { loc } = node + // 获取 sourcefile,优先从 node 自身获取,再从 fclos 获取 + let sourcefile = '' + let srcNode = node + while (srcNode && !srcNode?.loc?.sourcefile) { + srcNode = srcNode.parent + } + if (srcNode?.loc?.sourcefile) { + sourcefile = this.toRelativePath(srcNode.loc.sourcefile) + } else { + sourcefile = this.extractFilePath(fclos) + } + + const callExpr = AstUtil.getRawCode(node.callee || node).slice(0, 100) + + return { + code: callExpr, + file: sourcefile, + line: loc?.start?.line, + column: loc?.start?.column, + } + } + + /** + * 将 state.callsites 转换为可读的调用点信息(路径转为相对路径) + * callsites 中每个元素结构为 { code, nodehash, loc } + * @param callsites + * @param sinkNode + */ + buildCallsitesInfo(callsites: any[], sinkNode: any): any[] { + if (!callsites || callsites.length === 0) { + return [] + } + const result = callsites.map((site: any) => { + let sourcefile = '' + if (site?.loc?.sourcefile) { + sourcefile = this.toRelativePath(site.loc.sourcefile) + } else { + sourcefile = this.extractFilePath(site) + } + + return { + code: site.code, + nodeHash: site.nodeHash, + file: sourcefile, + line: site.loc.start.line, + column: site.loc.start.column, + } + }) + // 2. 记录 sink 调用点(CallExpression node)的信息 + if (sinkNode) { + let sourcefile = '' + if (sinkNode?.loc?.sourcefile) { + sourcefile = this.toRelativePath(sinkNode.loc.sourcefile) + } else { + sourcefile = this.extractFilePath(sinkNode) + } + result.push({ + code: AstUtil.getRawCode(sinkNode).slice(0, 100), + nodeHash: sinkNode._meta?.nodehash, + file: sourcefile, + line: sinkNode.loc.start.line, + column: sinkNode.loc.start.column, + }) + } + return result + } + + /** + * construct callchain finding detail info + * @param finding + */ + buildCallchainFindingDetail(finding: any): any { + const callNode = finding.node + const sinkRule = finding.ruleName + const { fclos, callstack, callsites } = finding + if (finding && callNode) { + const trace = SourceLine.getNodeTrace(fclos, callNode) + trace.tag = 'SINK: ' + trace.affectedNodeName = AstUtil.getRawCode(callNode?.callee || callNode).slice(0, 100) + + const arr = sinkRule.split('\nSINK Attribute: ') + if (arr.length === 1) { + finding.sinkRule = arr[0] + } else if (arr.length === 2) { + finding.sinkRule = arr[0] + finding.sinkAttribute = arr[1] + } + + finding.sinkInfo = { + sinkRule: finding.sinkRule, + sinkAttribute: finding.sinkAttribute, + callSite: this.buildSinkCallSiteInfo(callNode, fclos), + } + + finding.entrypoint = _.pickBy( + _.clone(entryPointConfig.getCurrentEntryPoint()), + (value: any) => !_.isObject(value) + ) + + finding.trace = [trace] + finding.callstackInfo = this.buildCallstackInfo(callstack, callNode, fclos) + finding.callsitesInfo = this.buildCallsitesInfo(callsites, callNode) + finding.callstack = callstack + finding.callsites = callsites + } + if ( + finding.callsites && + finding.callstack && + finding.callsites.length > 0 && + finding.callstack.length > 0 && + finding.callstack.length === finding.callsites.length + ) { + return finding + } + + return null + } + + /** + * construct callchain finding object with detail info + * @param checkerId + * @param checkerDesc + * @param node + * @param fclos + * @param ruleName + * @param callstack + * @param callsites + */ + buildCallchainFinding( + checkerId: any, + checkerDesc: any, + node: any, + fclos: any, + ruleName: any, + callstack: any, + callsites: any + ): any { + const callchainFinding = this.buildCallchainFindingObject( + checkerId, + checkerDesc, + node, + fclos, + ruleName, + callstack, + callsites + ) + return this.buildCallchainFindingDetail(callchainFinding) + } + + /** + * construct callchain finding object + * @param checkerId + * @param checkerDesc + * @param node + * @param fclos + * @param ruleName + * @param callstack + * @param callsites + */ + buildCallchainFindingObject( + checkerId: any, + checkerDesc: any, + node: any, + fclos: any, + ruleName: any, + callstack: any, + callsites: any + ): any { + const callchainFinding = RulesBasicHandler.getFinding(checkerId, checkerDesc, node) + callchainFinding.node = node + callchainFinding.fclos = fclos + callchainFinding.ruleName = ruleName + callchainFinding.callstack = callstack + callchainFinding.callsites = callsites + return callchainFinding + } + + /** + * + * @param node + * @param callInfo + * @param fclos + * @param rule + * @param state + */ + findArgsAndAddNewFinding(node: any, callInfo: CallInfo | undefined, fclos: any, rule: any, state: any) { + let ruleName = (rule as any).fsig + if (typeof (rule as any).attribute !== 'undefined') { + ruleName += `\nSINK Attribute: ${(rule as any).attribute}` + } + const callchainFinding = this.buildCallchainFinding( + this.getCheckerId(), + this.desc, + node, + fclos, + ruleName, + state?.callstack, + state?.callsites + ) + + if (!CallchainOutputStrategy.isNewFinding(this.resultManager, callchainFinding)) return + this.resultManager.newFinding(callchainFinding, CallchainOutputStrategy.outputStrategyId) + return true + } +} + +module.exports = CallchainChecker diff --git a/src/checker/callchain/go/go-callchain-checker.ts b/src/checker/callchain/go/go-callchain-checker.ts new file mode 100644 index 00000000..7da7a2c2 --- /dev/null +++ b/src/checker/callchain/go/go-callchain-checker.ts @@ -0,0 +1,232 @@ +import type { CallInfo } from '../../../engine/analyzer/common/call-args' + +const _ = require('lodash') +const CallchainChecker = require('../callchain-checker') +const { matchSinkAtFuncCallWithCalleeType } = require('../../taint/common-kit/sink-util') +const GoEntryPoint = require('../../../engine/analyzer/golang/common/entrypoint-collector/go-default-entrypoint') +const FullCallGraphFileEntryPoint = require('../../common/full-callgraph-file-entrypoint') +const completeEntryPoint = require('../../taint/common-kit/entry-points-util') +const AstUtil = require('../../../util/ast-util') +const FileUtil = require('../../../util/file-util') + +/** + * Go callchain checker + * Only detects sink matches and outputs call chains without checking for taint + */ +class GoCallchainChecker extends CallchainChecker { + entryPoints: any[] + + /** + * constructor + * @param resultManager + */ + constructor(resultManager: any) { + super(resultManager, 'callchain_go') + this.entryPoints = [] + } + + /** + * starter trigger + * @param analyzer + * @param scope + * @param node + * @param state + * @param info + */ + triggerAtStartOfAnalyze(analyzer: any, scope: any, node: any, state: any, info: any) { + const { topScope } = analyzer + const Config = require('../../../config') + const EntryPoint = require('../../../engine/analyzer/common/entrypoint') + const Constant = require('../../../util/constant') + const logger = require('../../../util/logger')(__filename) + + try { + logger.info('[GoCallchainChecker] triggerAtStartOfAnalyze called') + + // 直接从 analyzer.checkerManager.Rules 获取规则配置 + const BasicRuleHandler = analyzer.getCheckerManager().Rules + if (BasicRuleHandler && BasicRuleHandler.getRules) { + const allRules = BasicRuleHandler.getRules() + if (Array.isArray(allRules) && allRules.length > 0) { + for (const rule of allRules) { + if (rule.checkerIds && rule.checkerIds.includes(this.getCheckerId())) { + _.merge(this.checkerRuleConfigContent, rule) + break + } + } + } + } + + // 完整复制 GoDefaultTaintChecker 的 prepareEntryPoints 逻辑 + // 1. 添加 main 入口点(如果不是 ONLY_CUSTOM 模式) + if (Config.entryPointMode !== 'ONLY_CUSTOM') { + // 添加 main 入口 + let mainEntryPoints = GoEntryPoint.getMainEntryPoints(topScope.context.packages) + if (!_.isEmpty(mainEntryPoints)) { + if (Array.isArray(mainEntryPoints)) { + mainEntryPoints = _.uniqBy(mainEntryPoints, (value: any) => value.ast?.fdef) + } else { + mainEntryPoints = [mainEntryPoints] + } + mainEntryPoints.forEach((main: any) => { + if (main) { + const entryPoint = completeEntryPoint(main) + this.entryPoints.push(entryPoint) + } + }) + } + + // 使用 callGraph 边界作为 entrypoint + if (Config.cgAlgo === 'CHA' && analyzer.typeResolver) { + FullCallGraphFileEntryPoint.makeFullCallGraphByType(analyzer, analyzer.typeResolver) + } else { + FullCallGraphFileEntryPoint.makeFullCallGraph(analyzer) + } + const fullCallGraphEntrypoint = FullCallGraphFileEntryPoint.getAllEntryPointsUsingCallGraph( + analyzer.ainfo?.callgraph, + analyzer + ) + this.entryPoints.push(...fullCallGraphEntrypoint) + } + } catch (err: any) { + logger.error(`[GoCallchainChecker] Error in entrypoint collection: ${err.message}`) + logger.error(`[GoCallchainChecker] Stack: ${err.stack}`) + } + + // 2. 使用用户规则中指定的 entrypoint + const { entrypoints: ruleConfigEntryPoints } = this.checkerRuleConfigContent + if (!_.isEmpty(ruleConfigEntryPoints) && Config.entryPointMode !== 'SELF_COLLECT') { + logger.info(`[GoCallchainChecker] Processing ${ruleConfigEntryPoints.length} custom entrypoints`) + for (const entrypoint of ruleConfigEntryPoints) { + logger.info(`[GoCallchainChecker] Looking for: ${entrypoint.filePath}#${entrypoint.functionName}`) + let entryPointSymVal + if (entrypoint.funcReceiverType) { + entryPointSymVal = AstUtil.satisfy( + topScope.context.packages, + (n: any) => + n.vtype === 'fclos' && + FileUtil.extractAfterSubstring(n?.ast?.node?.loc?.sourcefile, Config.maindirPrefix) === entrypoint.filePath && + n?.parent?.ast?.node?.type === 'ClassDefinition' && + n?.parent?.ast?.node?.id?.name === entrypoint.funcReceiverType && + n?.ast?.node?.id?.name === entrypoint.functionName, + (node: any, prop: any) => prop === '_field', + null, + false + ) + } else { + // 尝试多种路径匹配方式 + entryPointSymVal = AstUtil.satisfy( + topScope.context.packages, + (n: any) => { + const sourcefile = n?.ast?.node?.loc?.sourcefile + const extracted = FileUtil.extractAfterSubstring(sourcefile, Config.maindirPrefix) + const matches = + n.vtype === 'fclos' && + (extracted === entrypoint.filePath || + sourcefile?.endsWith(entrypoint.filePath) || + sourcefile?.includes(`/${entrypoint.filePath}`)) && + n?.ast?.node?.id?.name === entrypoint.functionName + + if (matches) { + logger.info(`[GoCallchainChecker] Found match: ${sourcefile} -> ${n?.ast?.node?.id?.name}`) + } + return matches + }, + (node: any, prop: any) => prop === '_field', + null, + false + ) + } + + if (_.isEmpty(entryPointSymVal)) { + logger.warn( + `[GoCallchainChecker] match entryPoint fail for ${entrypoint.filePath}#${entrypoint.functionName}` + ) + continue + } + + logger.info( + `[GoCallchainChecker] Found ${Array.isArray(entryPointSymVal) ? entryPointSymVal.length : 1} match(es)` + ) + const symValArray = Array.isArray(entryPointSymVal) + ? _.uniqBy(entryPointSymVal, (value: any) => value.ast?.fdef) + : [entryPointSymVal] + for (const main of symValArray) { + if (main) { + const entryPoint = new EntryPoint(Constant.ENGIN_START_FUNCALL) + entryPoint.scopeVal = main.parent + entryPoint.argValues = [] + entryPoint.entryPointSymVal = main + entryPoint.filePath = entrypoint.filePath + entryPoint.functionName = entrypoint.functionName + entryPoint.attribute = entrypoint.attribute + entryPoint.funcReceiverType = main.funcReceiverType + this.entryPoints.push(entryPoint) + } + } + } + } + + logger.info(`[GoCallchainChecker] Total entryPoints: ${this.entryPoints.length}`) + analyzer.mainEntryPoints = this.entryPoints + } + + /** + * FunctionCall trigger + * @param analyzer + * @param scope + * @param node + * @param state + * @param info + */ + triggerAtFunctionCallBefore(analyzer: any, scope: any, node: any, state: any, info: any) { + const { fclos, callInfo } = info + this.checkSinkMatch(node, fclos, callInfo, scope, state) + } + + /** + * check if sink matches by name and class + * @param node + * @param fclos + * @param callInfo + * @param scope + * @param state + */ + checkSinkMatch(node: any, fclos: any, callInfo: CallInfo | undefined, scope: any, state: any) { + if (fclos === undefined) { + return + } + const rules = this.checkerRuleConfigContent.sinks?.FuncCallTaintSink + + if (!rules || !callInfo) return + + const nodeCallee = node.callee || node + + let rule = matchSinkAtFuncCallWithCalleeType(node, fclos, rules, scope, callInfo) + rule = rule.length > 0 ? rule[0] : null + + // 如果没有匹配到,尝试基于 AST node 的匹配(用于处理类型信息缺失的情况) + if (!rule && nodeCallee?.type === 'MemberAccess') { + const objectName = nodeCallee.object?.name + const propertyName = nodeCallee.property?.name + + if (objectName && propertyName) { + for (const tspec of rules) { + // 尝试匹配:如果 fsig 是方法名,检查是否匹配 + if (tspec.fsig === propertyName || tspec.fsig === `${objectName}.${propertyName}`) { + // 对于 callchain checker,当类型信息缺失时,忽略 calleeType 检查 + // 因为我们只关心 sink 匹配,不需要严格的类型检查 + rule = tspec + break + } + } + } + } + + if (rule) { + this.findArgsAndAddNewFinding(node, callInfo, fclos, rule, state) + } + } +} + +module.exports = GoCallchainChecker diff --git a/src/checker/callchain/java/java-callchain-checker.ts b/src/checker/callchain/java/java-callchain-checker.ts new file mode 100644 index 00000000..a2ff0a37 --- /dev/null +++ b/src/checker/callchain/java/java-callchain-checker.ts @@ -0,0 +1,307 @@ +import type { CallInfo } from '../../../engine/analyzer/common/call-args' +import type { Invocation } from '../../../resolver/common/value/invocation' + +const _ = require('lodash') +const CallchainChecker = require('../callchain-checker') +const RulesBasicHandler = require('../../common/rules-basic-handler') +const CallchainOutputStrategy = require('../../common/output/callchain-output-strategy') +const { matchSinkAtFuncCallWithCalleeType, checkInvocationMatchSink } = require('../../taint/common-kit/sink-util') +const SpringEntryPoint = require('../../../engine/analyzer/java/spring/entrypoint-collector/spring-default-entrypoint') +const Loader = require('../../../util/loader') +const CommonUtil = require('../../../util/common-util') +const Constant = require('../../../util/constant') +const { + valueUtil: { + ValueUtil: { Scoped }, + }, +} = require('../../../engine/analyzer/common') + +/** + * Java callchain checker + * Only detects sink matches and outputs call chains without checking for taint + */ +class JavaCallchainChecker extends CallchainChecker { + entryPoints: any[] + + /** + * constructor + * @param resultManager + */ + constructor(resultManager: any) { + super(resultManager, 'callchain_java') + this.entryPoints = [] + } + + /** + * starter trigger + * @param analyzer + * @param scope + * @param node + * @param state + * @param info + */ + triggerAtStartOfAnalyze(analyzer: any, scope: any, node: any, state: any, info: any) { + const { topScope } = analyzer + const AstUtil = require('../../../util/ast-util') + const Config = require('../../../config') + const EntryPoint = require('../../../engine/analyzer/common/entrypoint') + const logger = require('../../../util/logger')(__filename) + + // 直接从 analyzer.checkerManager.Rules 获取规则配置 + const BasicRuleHandler = analyzer.getCheckerManager().Rules + if (BasicRuleHandler && BasicRuleHandler.getRules) { + const allRules = BasicRuleHandler.getRules() + if (Array.isArray(allRules) && allRules.length > 0) { + for (const rule of allRules) { + if (rule.checkerIds && rule.checkerIds.includes(this.getCheckerId())) { + _.merge(this.checkerRuleConfigContent, rule) + break + } + } + } + } + + // 准备 entrypoints - 完整复制 JavaTaintChecker 的逻辑 + const { entrypoints: ruleConfigEntryPoints } = this.checkerRuleConfigContent + + // 1. 自动采集 Spring entrypoints(如果不是 ONLY_CUSTOM 模式) + if (Config.entryPointMode !== 'ONLY_CUSTOM') { + logger.info('YASA will collect Entrypoint and Source for callchain') + const { selfCollectSpringEntryPoints } = SpringEntryPoint.getSpringEntryPointAndSource(topScope.context.packages) + + if (!_.isEmpty(selfCollectSpringEntryPoints)) { + selfCollectSpringEntryPoints.forEach((main: any) => { + if (main) { + const entryPoint = new EntryPoint(Constant.ENGIN_START_FUNCALL) + entryPoint.scopeVal = main.parent + entryPoint.argValues = [] + entryPoint.entryPointSymVal = main + entryPoint.filePath = main.filePath + entryPoint.functionName = main.functionName + entryPoint.attribute = main.attribute + entryPoint.funcReceiverType = main.funcReceiverType + this.entryPoints.push(entryPoint) + } + }) + } + } + + // 2. 处理 rule config 中的自定义 entrypoints(如果不是 SELF_COLLECT 模式) + if (!_.isEmpty(ruleConfigEntryPoints) && Config.entryPointMode !== 'SELF_COLLECT') { + for (const entrypoint of ruleConfigEntryPoints) { + // 先尝试使用 packageName 查找(原始逻辑) + if (entrypoint.packageName) { + let targetPackage = entrypoint.packageName + targetPackage = targetPackage.startsWith('.') ? targetPackage.slice(1) : targetPackage + const arr = Loader.getPackageNameProperties(targetPackage) + let packageManagerT = topScope.context.packages + arr.forEach((path: any) => { + packageManagerT = packageManagerT?.members?.get(path) + }) + + if (packageManagerT && packageManagerT.vtype !== 'undefine') { + const func = entrypoint.functionName + const entryPointSymVal = CommonUtil.getFclosFromScope(packageManagerT, func) + if (entryPointSymVal?.vtype === 'fclos') { + const scopeVal = Scoped('', { + vtype: 'scope', + sid: 'mock', + qid: 'mock', + field: {}, + parent: null, + }) + + const entryPoint = new EntryPoint(Constant.ENGIN_START_FUNCALL) + entryPoint.scopeVal = scopeVal + entryPoint.argValues = [] + entryPoint.functionName = entrypoint.functionName + entryPoint.filePath = entrypoint.filePath + entryPoint.attribute = entrypoint.attribute + entryPoint.packageName = entrypoint.packageName + entryPoint.entryPointSymVal = entryPointSymVal + this.entryPoints.push(entryPoint) + continue + } + } + } + + // 如果 packageName 查找失败,使用 filePath 查找(备选方案) + const entryPointSymVal = AstUtil.satisfy( + topScope.context.packages, + (n: any) => + n.vtype === 'fclos' && + (n?.ast?.node?.loc?.sourcefile?.endsWith(entrypoint.filePath) || + n?.ast?.node?.loc?.sourcefile?.includes(entrypoint.filePath)) && + n?.ast?.node?.id?.name === entrypoint.functionName, + (node: any, prop: any) => prop === '_field', + null, + false + ) + + if (!_.isEmpty(entryPointSymVal)) { + const symVal = Array.isArray(entryPointSymVal) ? entryPointSymVal[0] : entryPointSymVal + const entryPoint = new EntryPoint(Constant.ENGIN_START_FUNCALL) + entryPoint.scopeVal = symVal.parent + entryPoint.argValues = [] + entryPoint.functionName = entrypoint.functionName + entryPoint.filePath = entrypoint.filePath + entryPoint.attribute = entrypoint.attribute || 'HTTP' + entryPoint.packageName = entrypoint.packageName + entryPoint.entryPointSymVal = symVal + this.entryPoints.push(entryPoint) + } + } + } + + analyzer.entryPoints = this.entryPoints + } + + /** + * FunctionCall trigger + * @param analyzer + * @param scope + * @param node + * @param state + * @param info + */ + triggerAtFunctionCallBefore(analyzer: any, scope: any, node: any, state: any, info: any) { + const { fclos, callInfo } = info + this.checkSinkMatch(node, fclos, callInfo, scope, state, info, analyzer) + } + + /** + * check if sink matches by name and class + * @param node + * @param fclos + * @param callInfo + * @param scope + * @param state + * @param info + * @param analyzer + */ + checkSinkMatch(node: any, fclos: any, callInfo: CallInfo | undefined, scope: any, state: any, info: any, analyzer: any) { + let sinkRules + if (RulesBasicHandler.getPreprocessReady()) { + if (!this.sinkRuleArray) { + this.sinkRuleArray = this.assembleFunctionCallSinkRule() + this.sinkArray = analyzer?.loadAllSink() + } + sinkRules = this.sinkRuleArray + } else { + sinkRules = this.assembleFunctionCallSinkRule() + } + + let rules + if (RulesBasicHandler.getPreprocessReady()) { + if (node?._meta?.nodehash) { + if (this.matchSinkRuleResultMap.has(node._meta.nodehash)) { + rules = this.matchSinkRuleResultMap.get(node._meta.nodehash) + } else { + rules = matchSinkAtFuncCallWithCalleeType(node, fclos, sinkRules, scope, callInfo) + this.appendCgRules(rules, node, scope, sinkRules, analyzer) + this.matchSinkRuleResultMap.set(node._meta.nodehash, rules) + } + } else { + rules = matchSinkAtFuncCallWithCalleeType(node, fclos, sinkRules, scope, callInfo) + this.appendCgRules(rules, node, scope, sinkRules, analyzer) + } + } else { + rules = matchSinkAtFuncCallWithCalleeType(node, fclos, sinkRules, scope, callInfo) + this.appendCgRules(rules, node, scope, sinkRules, analyzer) + } + + for (const rule of rules) { + let ruleName = rule.fsig + if (typeof rule.attribute !== 'undefined') { + ruleName += `\nSINK Attribute: ${rule.attribute}` + } + const callchainFinding = this.buildCallchainFinding( + this.getCheckerId(), + this.desc, + node, + fclos, + ruleName, + state.callstack, + state.callsites + ) + if (!CallchainOutputStrategy.isNewFinding(this.resultManager, callchainFinding)) continue + this.resultManager.newFinding(callchainFinding, CallchainOutputStrategy.outputStrategyId) + } + + return true + } + + /** + * append matched rules find by callgraph + * @param rules + * @param node + * @param scope + * @param sinkRules + * @param analyzer + */ + appendCgRules(rules: any[], node: any, scope: any, sinkRules: any[], analyzer: any) { + if (rules.length > 0) { + return + } + const cgRules = this.findMatchedRuleByCallGraph(node, scope, sinkRules, analyzer) + for (const cgRule of cgRules) { + rules.push(cgRule) + } + } + + /** + * find matched rule by CallGraph + * @param node + * @param scope + * @param analyzer + * @param sinkRules + */ + findMatchedRuleByCallGraph(node: any, scope: any, sinkRules: any[], analyzer: any) { + const resultArray: any[] = [] + + if (!node || !scope || !sinkRules || !analyzer || !analyzer.findNodeInvocations) { + return resultArray + } + + const invocations: Invocation[] = analyzer.findNodeInvocations(scope, node) + if (!invocations) { + return resultArray + } + + for (const invocation of invocations) { + for (const sink of sinkRules) { + const matchSink: boolean = checkInvocationMatchSink(invocation, sink, analyzer.typeResolver) + if (matchSink) { + resultArray.push(sink) + } + } + } + + return resultArray + } + + /** + * assemble function call sink rule + */ + assembleFunctionCallSinkRule() { + const sinkRules: any[] = [] + const funcCallTaintSinkRules = this.checkerRuleConfigContent.sinks?.FuncCallTaintSink + if (Array.isArray(funcCallTaintSinkRules)) { + for (const funcCallTaintSinkRule of funcCallTaintSinkRules) { + funcCallTaintSinkRule._sinkType = 'FuncCallTaintSink' + } + sinkRules.push(...funcCallTaintSinkRules) + } + const objectTaintFuncCallSinkRules = this.checkerRuleConfigContent.sinks?.ObjectTaintFuncCallSink + if (Array.isArray(objectTaintFuncCallSinkRules)) { + for (const objectTaintFuncCallSinkRule of objectTaintFuncCallSinkRules) { + objectTaintFuncCallSinkRule._sinkType = 'ObjectTaintFuncCallSink' + } + sinkRules.push(...objectTaintFuncCallSinkRules) + } + + return sinkRules + } +} + +module.exports = JavaCallchainChecker diff --git a/src/checker/callchain/js/js-callchain-checker.ts b/src/checker/callchain/js/js-callchain-checker.ts new file mode 100644 index 00000000..dd8b41b9 --- /dev/null +++ b/src/checker/callchain/js/js-callchain-checker.ts @@ -0,0 +1,288 @@ +import type { CallInfo } from '../../../engine/analyzer/common/call-args' + +const _ = require('lodash') +const CallchainChecker = require('../callchain-checker') +const { matchSinkAtFuncCall } = require('../../taint/common-kit/sink-util') +const config = require('../../../config') +const QidUnifyUtil = require('../../../util/qid-unify-util') +const Config = require('../../../config') + +/** + * JavaScript callchain checker + * Only detects sink matches and outputs call chains without checking for taint + */ +class JsCallchainChecker extends CallchainChecker { + entryPoints: any[] + + /** + * constructor + * @param resultManager + */ + constructor(resultManager: any) { + super(resultManager, 'callchain_js') + this.entryPoints = [] + } + + /** + * starter trigger + * @param analyzer + * @param scope + * @param node + * @param state + * @param info + */ + triggerAtStartOfAnalyze(analyzer: any, scope: any, node: any, state: any, info: any) { + const { topScope, fileManager } = analyzer + const loader = require('../../../util/loader') + const commonUtil = require('../../../util/common-util') + const EntryPoint = require('../../../engine/analyzer/common/entrypoint') + const constValue = require('../../../util/constant') + const { handleException } = require('../../../engine/analyzer/common/exception-handler') + + // 直接从 analyzer.checkerManager.Rules 获取规则配置 + const BasicRuleHandler = analyzer.getCheckerManager().Rules + if (BasicRuleHandler && BasicRuleHandler.getRules) { + const allRules = BasicRuleHandler.getRules() + if (Array.isArray(allRules) && allRules.length > 0) { + for (const rule of allRules) { + if (rule.checkerIds && rule.checkerIds.includes(this.getCheckerId())) { + _.merge(this.checkerRuleConfigContent, rule) + break + } + } + } + } + + // 完整复制 JsTaintChecker 的 prepareEntryPoints 逻辑 + const { entrypoints: ruleConfigEntryPoints } = this.checkerRuleConfigContent + if (config.entryPointMode !== 'SELF_COLLECT') { + // 自定义 source 入口方式,并根据入口自主加载 source + const prepareEntryPointList = [] + if (!_.isEmpty(ruleConfigEntryPoints)) { + prepareEntryPointList.push(...ruleConfigEntryPoints) + } + if (!_.isEmpty(prepareEntryPointList)) { + for (const entrypoint of prepareEntryPointList) { + try { + let filepath = entrypoint.filePath + filepath = filepath.startsWith('/') ? filepath.slice(1) : filepath + const arr = loader.getFilePathProperties(filepath, { caseStyle: 'lower' }) + let fieldT = topScope + arr.forEach((path: any) => { + fieldT = fieldT?.members?.get(path) + }) + if (!fieldT || fieldT.vtype === 'undefine') { + for (const [mod, modVal] of topScope.context.modules.members.entries()) { + if ( + mod.includes(entrypoint.filePath) && + modVal.ast?.node?.type === 'CompileUnit' + ) { + fieldT = modVal + break + } + } + } + + if (entrypoint.functionName) { + const func = entrypoint.functionName + const valExport = fieldT + const entryPointSymVal = commonUtil.getFclosFromScope(valExport, func) + if (entryPointSymVal?.vtype !== 'fclos') { + continue + } + + const entryPoint = new EntryPoint(constValue.ENGIN_START_FUNCALL) + entryPoint.scopeVal = entryPointSymVal.parent + entryPoint.functionName = entrypoint.functionName + entryPoint.filePath = entrypoint.filePath + entryPoint.attribute = entrypoint.attribute + entryPoint.entryPointSymVal = entryPointSymVal + this.entryPoints.push(entryPoint) + } else { + if (!fieldT.ast?.node || fieldT.ast.node.type !== 'CompileUnit') continue + const entryPoint = new EntryPoint(constValue.ENGIN_START_FILE_BEGIN) + entryPoint.scopeVal = fieldT + entryPoint.argValues = undefined + entryPoint.functionName = undefined + entryPoint.filePath = fieldT?.ast?.node?.loc?.sourcefile + entryPoint.attribute = entrypoint.attribute + entryPoint.packageName = undefined + entryPoint.entryPointSymVal = fieldT + this.entryPoints.push(entryPoint) + } + } catch (e: any) { + handleException( + e, + '[js-callchain-checker]An Error Occurred in custom entrypoint', + '[js-callchain-checker]An Error Occurred in custom entrypoint' + ) + } + } + } + } + + // 使用 callgraph 边界 + file 作为 entrypoint + if (config.entryPointMode !== 'ONLY_CUSTOM') { + const fullCallGraphFileEntryPoint = require('../../common/full-callgraph-file-entrypoint') + fullCallGraphFileEntryPoint.makeFullCallGraph(analyzer) + const fullCallGraphEntrypoint = fullCallGraphFileEntryPoint.getAllEntryPointsUsingCallGraph( + analyzer.ainfo?.callgraph, + analyzer + ) + const fullFileEntrypoint = fullCallGraphFileEntryPoint.getAllFileEntryPointsUsingFileManager(analyzer) + this.entryPoints.push(...fullCallGraphEntrypoint) + this.entryPoints.push(...fullFileEntrypoint) + } + + analyzer.entryPoints.push(...this.entryPoints) + } + + /** + * FunctionCall trigger + * @param analyzer + * @param scope + * @param node + * @param state + * @param info + */ + triggerAtFunctionCallBefore(analyzer: any, scope: any, node: any, state: any, info: any) { + const { fclos, callInfo } = info + this.checkSinkMatch(node, fclos, callInfo, state) + this.checkByFieldMatch(node, fclos, callInfo, state) + } + + /** + * check if sink matches by name + * @param node + * @param fclos + * @param callInfo + * @param state + */ + checkSinkMatch(node: any, fclos: any, callInfo: CallInfo | undefined, state: any) { + if (fclos === undefined) { + return + } + const rules = this.checkerRuleConfigContent.sinks?.FuncCallTaintSink + + if (!rules || !callInfo) return + const nodeCallee = node.callee || node + + let rule = matchSinkAtFuncCall(node, fclos, rules, callInfo) + rule = rule.length > 0 ? rule[0] : null + + // 如果没有匹配到,尝试基于函数名的匹配(用于处理解构导入等情况) + if (!rule) { + const functionName = fclos?.name || fclos?.ast?.node?.id?.name || nodeCallee?.name + + if (functionName) { + for (const tspec of rules) { + // 尝试匹配:如果 fsig 包含函数名(例如 child_process.exec 匹配 exec) + if (tspec.fsig && (tspec.fsig === functionName || tspec.fsig.endsWith(`.${functionName}`))) { + rule = tspec + break + } + } + } + } + + if (rule) { + this.findArgsAndAddNewFinding(node, callInfo, fclos, rule, state) + } + } + + /** + * + * @param node + * @param fclos + * @param callInfo + * @param state + */ + checkByFieldMatch(node: any, fclos: any, callInfo: CallInfo | undefined, state: any) { + const rules = this.checkerRuleConfigContent.sinks?.FuncCallTaintSink + if (_.isEmpty(rules)) { + return + } + + rules.some((rule: any) => { + if (typeof rule.fsig !== 'string') { + return false + } + const paths = rule.fsig.split('.') + const lastIndex = rule.fsig.lastIndexOf('.') + let RuleObj = rule.fsig.substring(0, lastIndex) + if (lastIndex === -1) { + RuleObj = rule.fsig + } + const ruleCallName = paths[paths.length - 1] + let callName + const { callee } = node + if (!callee) return false + if (callee.type === 'MemberAccess') { + callName = callee.property.name + } else { + // Identifier + callName = callee.name + } + const CallFull = this.getObj(fclos) + if (typeof CallFull === 'undefined') { + return false + } + const lastIndexofCall = CallFull.lastIndexOf('.') + if (ruleCallName !== '*' && ruleCallName !== callName) { + if (lastIndexofCall >= 0) { + // 补偿获取一次callName + callName = CallFull.substring(lastIndexofCall + 1) + if (ruleCallName !== callName && rule.fsig.includes('.')) { + return false + } + } + } + + let CallObj = CallFull + if (lastIndexofCall >= 0) { + CallObj = CallFull.substring(0, lastIndexofCall) + } + if (CallObj !== RuleObj) { + const idx = CallObj.lastIndexOf('(') + const result = idx !== -1 ? CallObj.slice(0, idx) : CallObj + if (result !== RuleObj) { + if (!result.endsWith(`.${RuleObj}`) && !result.startsWith(`${RuleObj}.`)) { + return false + } + } + } + this.findArgsAndAddNewFinding(node, callInfo, fclos, rule, state) + }) + } + + /** + * + * @param fclos + */ + getObj(fclos: any): any { + if (typeof fclos?.qid === 'undefined' && typeof fclos?._this === 'undefined') { + return QidUnifyUtil.qidUnifyByRemoveAngleAndPrefix(fclos.sid) + } + if (typeof fclos?.qid !== 'undefined') { + let qid = fclos?.qid?.replace('Egg.Context', 'this.ctx') + qid = qid?.replace('Egg.Application', 'this.app') + qid = qid?.replace('this.app.service', 'this.ctx.service') + qid = qid?.replace('Egg.Request', 'this.ctx.request') + if (fclos.ast?.node?.loc?.sourcefile && fclos.ast?.node?.loc?.sourcefile.startsWith(Config.maindirPrefix)) { + const prefix = fclos.ast.node.loc.sourcefile.substring(Config.maindirPrefix.length) + const lastDotIndex = prefix.lastIndexOf('.') + const result = lastDotIndex >= 0 ? prefix.substring(0, lastDotIndex) : prefix + if (result) { + qid = qid?.substring(prefix.length + 1) + } + } + return QidUnifyUtil.qidUnifyByRemoveAngleAndPrefix(qid) + } + if (!(fclos === fclos?._this)) { + return this.getObj(fclos._this) + } + return QidUnifyUtil.qidUnifyByRemoveAngleAndPrefix(fclos.sid) + } +} + +module.exports = JsCallchainChecker diff --git a/src/checker/callchain/python/python-callchain-checker.ts b/src/checker/callchain/python/python-callchain-checker.ts new file mode 100644 index 00000000..37805d6f --- /dev/null +++ b/src/checker/callchain/python/python-callchain-checker.ts @@ -0,0 +1,256 @@ +import type { CallInfo } from '../../../engine/analyzer/common/call-args' + +const _ = require('lodash') +const QidUnifyUtil = require('../../../util/qid-unify-util') +const CallchainChecker = require('../callchain-checker') +const { matchSinkAtFuncCall, matchRegex } = require('../../taint/common-kit/sink-util') +const { + findPythonFcEntryPointAndSource, + buildFclosIndex, + lookupFclos, +} = require('../../../engine/analyzer/python/common/entrypoint-collector/python-entrypoint') +const Constant = require('../../../util/constant') +const EntryPoint = require('../../../engine/analyzer/common/entrypoint') +const Config = require('../../../config') +const { extractRelativePath } = require('../../../util/file-util') +const logger = require('../../../util/logger')(__filename) +const { loadPythonDefaultRule } = require('../../taint/python/python-taint-abstract-checker') + +/** + * Python callchain checker + * Only detects sink matches and outputs call chains without checking for taint + */ +class PythonCallchainChecker extends CallchainChecker { + entryPoints: any[] + + /** + * constructor + * @param resultManager + */ + constructor(resultManager: any) { + super(resultManager, 'callchain_python') + this.entryPoints = [] + } + + /** + * starter trigger - 完全复制 PythonTaintChecker 的实现 + * @param analyzer + * @param scope + * @param node + * @param state + * @param info + */ + triggerAtStartOfAnalyze(analyzer: any, scope: any, node: any, state: any, info: any) { + const moduleManager = analyzer.topScope.context.modules + const fileManager = analyzer.topScope.context.files + this.prepareEntryPoints(analyzer, Config.maindir, moduleManager, fileManager) + analyzer.entryPoints.push(...this.entryPoints) + } + + /** + * prepare entrypoint - 完全复制 PythonTaintChecker 的逻辑 + * @param analyzer + * @param dir + * @param moduleManager + * @param fileManager + */ + prepareEntryPoints(analyzer: any, dir: any, moduleManager: any, fileManager: any) { + const funCallEntryPoints: any[] = [] + const fileEntryPoints: any[] = [] + const { entrypoints: ruleConfigEntryPoints } = this.checkerRuleConfigContent + + if (Config.entryPointMode !== 'ONLY_CUSTOM') { + const pythonDefaultRule = loadPythonDefaultRule() + if (pythonDefaultRule[0].checkerIds.includes(this.getCheckerId())) { + this.checkerRuleConfigContent.sources = this.checkerRuleConfigContent.sources || {} + this.checkerRuleConfigContent.sources.TaintSource = this.checkerRuleConfigContent.sources.TaintSource || [] + this.checkerRuleConfigContent.sources.TaintSource = Array.isArray( + this.checkerRuleConfigContent.sources.TaintSource + ) + ? this.checkerRuleConfigContent.sources.TaintSource + : [this.checkerRuleConfigContent.sources.TaintSource] + this.checkerRuleConfigContent.sources.TaintSource.push(...pythonDefaultRule[0].sources.TaintSource) + } + const { pyFcEntryPointArray, pyFcEntryPointSourceArray } = findPythonFcEntryPointAndSource( + dir, + fileManager, + analyzer + ) + if (pyFcEntryPointArray) { + funCallEntryPoints.push(...pyFcEntryPointArray) + } + if (pyFcEntryPointSourceArray) { + this.checkerRuleConfigContent.sources = this.checkerRuleConfigContent.sources || {} + this.checkerRuleConfigContent.sources.TaintSource = this.checkerRuleConfigContent.sources.TaintSource || [] + this.checkerRuleConfigContent.sources.TaintSource = Array.isArray( + this.checkerRuleConfigContent.sources.TaintSource + ) + ? this.checkerRuleConfigContent.sources.TaintSource + : [this.checkerRuleConfigContent.sources.TaintSource] + this.checkerRuleConfigContent.sources.TaintSource.push(...pyFcEntryPointSourceArray) + } + } + if (Config.entryPointMode !== 'SELF_COLLECT' && !_.isEmpty(ruleConfigEntryPoints)) { + for (const entrypoint of ruleConfigEntryPoints) { + if (entrypoint.functionName) { + const entryPoint = new EntryPoint(Constant.ENGIN_START_FUNCALL) + entryPoint.filePath = entrypoint.filePath + entryPoint.functionName = entrypoint.functionName + entryPoint.attribute = entrypoint.attribute + funCallEntryPoints.push(entryPoint) + } else { + const entryPoint = new EntryPoint(Constant.ENGIN_START_FILE_BEGIN) + entryPoint.filePath = entrypoint.filePath + entryPoint.attribute = entrypoint.attribute + fileEntryPoints.push(entryPoint) + } + } + } + + // 构建 fclos 索引,一次遍历替代多次查找 + const fclosIndex = buildFclosIndex(moduleManager, dir, extractRelativePath) + + for (const funCallEntryPoint of funCallEntryPoints) { + // 使用索引查找,O(1) 操作 + let valFuncs = lookupFclos(fclosIndex, funCallEntryPoint.filePath, funCallEntryPoint.functionName) + + if (_.isEmpty(valFuncs)) { + logger.info('match entryPoint fail') + continue + } + + // 去重 + valFuncs = _.uniqBy(valFuncs, (value: any) => value.ast?.fdef) + + for (const valFunc of valFuncs) { + const entryPoint = new EntryPoint(Constant.ENGIN_START_FUNCALL) + entryPoint.filePath = funCallEntryPoint.filePath + entryPoint.functionName = funCallEntryPoint.functionName + entryPoint.attribute = funCallEntryPoint.attribute + entryPoint.entryPointSymVal = valFunc + this.entryPoints.push(entryPoint) + } + } + + for (const fileEntryPoint of fileEntryPoints) { + const fullFilePath = `${Config.maindir}${fileEntryPoint.filePath}`.replace('//', '/') + const fileUuid = fileManager[fullFilePath] + const file = analyzer.symbolTable.get(fileUuid) + if (file?.ast?.node?.type === 'CompileUnit') { + const entryPoint = new EntryPoint(Constant.ENGIN_START_FILE_BEGIN) + entryPoint.scopeVal = file + entryPoint.argValues = undefined + entryPoint.functionName = undefined + entryPoint.filePath = file?.ast?.node?.loc?.sourcefile + entryPoint.attribute = fileEntryPoint.attribute + entryPoint.packageName = undefined + entryPoint.entryPointSymVal = file + this.entryPoints.push(entryPoint) + } + } + } + + /** + * FunctionCall trigger + * @param analyzer + * @param scope + * @param node + * @param state + * @param info + */ + triggerAtFunctionCallBefore(analyzer: any, scope: any, node: any, state: any, info: any) { + const { fclos, callInfo } = info + this.checkByNameMatch(node, fclos, callInfo, state) + this.checkByFieldMatch(node, fclos, callInfo, state) + } + + /** + * check if sink matches by name + * @param node + * @param fclos + * @param callInfo + * @param state + */ + checkByNameMatch(node: any, fclos: any, callInfo: CallInfo | undefined, state: any) { + if (fclos === undefined) { + return + } + const rules = this.checkerRuleConfigContent.sinks?.FuncCallTaintSink + + if (!rules || !callInfo) return + let rule = matchSinkAtFuncCall(node, fclos, rules, callInfo) + rule = rule.length > 0 ? rule[0] : null + + if (rule) { + this.findArgsAndAddNewFinding(node, callInfo, fclos, rule, state) + } + } + + /** + * + * @param node + * @param fclos + * @param callInfo + * @param scope + * @param state + */ + checkByFieldMatch(node: any, fclos: any, callInfo: CallInfo | undefined, state: any) { + const rules = this.checkerRuleConfigContent.sinks?.FuncCallTaintSink + if (_.isEmpty(rules)) { + return + } + rules.some((rule: any): boolean => { + if (typeof rule.fsig !== 'string') { + return false + } + const callFull = this.getObj(fclos) + if (typeof callFull === 'undefined') { + return false + } + if (rule.fsig) { + if (rule.fsig === callFull) { + this.findArgsAndAddNewFinding(node, callInfo, fclos, rule, state) + return true + } + } else { + if (!rule.fregex) { + return false + } + if (callFull.type === 'MemberAccess' && matchRegex(rule.fregex, fclos.qid)) { + this.findArgsAndAddNewFinding(node, callInfo, fclos, rule, state) + return true + } + } + return false + }) + } + + /** + * get obj + * @param fclos + */ + getObj(fclos: any): any { + if (typeof fclos?.sid !== 'undefined' && typeof fclos?.qid === 'undefined' && typeof fclos?._this === 'undefined') { + const index = fclos?.sid.indexOf('>.') + return index !== -1 ? fclos?.sid.substring(index + 2) : fclos?.sid + } + if (typeof fclos?.qid !== 'undefined' && typeof fclos.qid === 'string') { + const index = fclos.qid.indexOf('>.') + const result = index !== -1 ? fclos?.qid.substring(index + 2) : fclos?.qid + return QidUnifyUtil.qidUnifyByRemoveAngleAndPrefix(result) + } + if (!(fclos === fclos?._this)) { + return this.getObj(fclos._this) + } + if (typeof fclos?.sid === 'string') { + const index = fclos?.sid.indexOf('>.') + const result = index !== -1 ? fclos?.sid.substring(index + 2) : fclos?.sid + if (result) { + return QidUnifyUtil.qidUnifyByRemoveAngleAndPrefix(result) + } + } + } + +} + +module.exports = PythonCallchainChecker diff --git a/src/checker/callgraph/callgraph-checker.ts b/src/checker/callgraph/callgraph-checker.ts index 5cac34ae..2867b3a0 100644 --- a/src/checker/callgraph/callgraph-checker.ts +++ b/src/checker/callgraph/callgraph-checker.ts @@ -1,5 +1,4 @@ // used for dump call graph -import type { IConfig } from '../../config' import type TypeRelatedInfoResolver from '../../resolver/common/type-related-info-resolver' const _ = require('lodash') @@ -8,9 +7,6 @@ const kitCallgraph = require('../common/checker-kit') const configCallgraph = require('../../config') const CheckerCallgraph = require('../common/checker') const CallgraphOutputStrategyCallgraph = require('../common/output/callgraph-output-strategy') - -let ConfigCallgraph: IConfig -let loggerCallgraph: any /** * CallgraphChecker represents calling relationships between procedures. * CallgraphChecker has nodes and edges. @@ -37,8 +33,6 @@ class CallgraphChecker extends CheckerCallgraph { super(mng, 'callgraph') this.mng = mng this.kit = kitCallgraph - loggerCallgraph = kitCallgraph.logger(__filename) - ConfigCallgraph = this.kit.Config } /** @@ -82,28 +76,47 @@ class CallgraphChecker extends CheckerCallgraph { * @param info */ triggerAtFunctionCallBefore(analyzer: any, scope: any, node: any, state: any, info: any): void { - const { fclos, argvalues, ainfo } = info - const fdecl = fclos.fdef - if (fclos === undefined || fdecl?.type !== 'FunctionDefinition') { + const { fclos, ainfo } = info + if (!fclos) { + return + } + const fdecl = fclos.ast?.fdef + if (fdecl && fdecl.type !== 'FunctionDefinition') { return } const stack = state.callstack + if (!stack) { + return + } const to = fclos - const toAST = fclos && fclos.fdef - const call_site_node = node + const toAST = fclos.ast?.fdef + const callSiteNode = node const from = stack[stack.length - 1] || { name: '<__entry_point__>', sid: '<__entry_point__>', vtype: 'fclos' } - const fromAST = from.fdef + const fromAST = from.ast?.fdef if (fromAST && fromAST.type !== 'FunctionDefinition' && from.vtype !== 'fclos') { return } const callgraph = (ainfo.callgraph = ainfo.callgraph || new this.kit.Graph()) - const fromNode = callgraph.addNode(this.prettyPrint(from, fromAST, call_site_node), { - funcDef: fromAST, - funcSymbol: from, + + // 获取 AST 的 nodehash 和符号值的 UUID + const fromASTNodehash = fromAST?._meta?.nodehash || null + const fromFuncSymbolUuid = from?.uuid || null + const toASTNodehash = toAST?._meta?.nodehash || null + const toFuncSymbolUuid = to?.uuid || null + + const fromNode = callgraph.addNode(this.prettyPrint(from, fromAST, callSiteNode), { + funcDefNodehash: fromASTNodehash, + funcSymbolUuid: fromFuncSymbolUuid, + }) + + // 存储 callSite 的 nodehash + const callSiteNodehash = callSiteNode?._meta?.nodehash || null + const toNode = callgraph.addNode(this.prettyPrint(to, toAST, callSiteNode), { + funcDefNodehash: toASTNodehash, + funcSymbolUuid: toFuncSymbolUuid, }) - const toNode = callgraph.addNode(this.prettyPrint(to, toAST, call_site_node), { funcDef: toAST, funcSymbol: to }) - callgraph.addEdge(fromNode, toNode, { callSite: call_site_node }) + callgraph.addEdge(fromNode, toNode, { callSiteNodehash }) } /** @@ -116,8 +129,13 @@ class CallgraphChecker extends CheckerCallgraph { */ triggerAtEndOfAnalyze(analyzer: any, scope: any, node: any, state: any, info: any): void { const finding = analyzer.ainfo.callgraph - finding.type = this.getCheckerId() - this.mng.newFinding(finding, CallgraphOutputStrategyCallgraph.outputStrategyId) + if (finding) { + finding.type = this.getCheckerId() + // 在 finding 中存储 astManager 和 symbolTable 的引用,供 dumpGraph 使用 + ;(finding as any).astManager = analyzer.astManager + ;(finding as any).symbolTable = analyzer.symbolTable + this.mng.newFinding(finding, CallgraphOutputStrategyCallgraph.outputStrategyId) + } } /** @@ -129,33 +147,32 @@ class CallgraphChecker extends CheckerCallgraph { prettyPrint(fclos: any, fdef: any, callSiteNode: any): string { let ret: string = '' let name: string - if (!fdef || !fdef.name || fdef.name === '') { + // 临时补丁,防止stc 漏洞uk变化 + if (!fdef || !fdef.name || fdef.name.includes(' f.id) - if (fclos) { - ret = fclos.id - } + let fclosArray = fclos.value + if (fclosArray && !Array.isArray(fclosArray)) { + fclosArray = Object.entries(fclosArray) + } + const f = _.find(fclosArray, (f1: any) => f1.sid) + if (f) { + ret = f.sid } } else if (fclos.vtype && fclos.type !== 'MemberAccess') { // 针对[]byte(xx)场景,fclos是一个symbol value,且fclos.qid是ArrayType这个identifier节点,而非string,因此这里if条件需做限定 if (fclos.name) { ret = fclos.name - } else if ( - (typeof fclos.id !== 'string' && fclos.id?.name) || - (typeof fclos.sid !== 'string' && fclos.sid?.name) - ) { - ret = fclos.id?.name || fclos.sid?.name + } else if (typeof fclos.sid !== 'string' && fclos.sid?.name) { + ret = fclos.sid?.name } let { parent } = fclos while (parent) { if (['object', 'modScope', 'fclos', 'symbol'].indexOf(parent.vtype) === -1) break - name = parent.id || parent.name || parent.sid + name = parent.name || parent.sid if (!name) break ret = `${name}.${ret}` parent = parent.parent @@ -174,15 +191,19 @@ class CallgraphChecker extends CheckerCallgraph { } } else { // pretty print fdef - name = fdef.name || '' + name = + fdef.name || + `` // try to attach namespace - if (fclos && fclos.__proto__.constructor.name !== 'BVT') { + if (fclos && fclos.__proto__.constructor.name !== 'BVTValue') { if (fclos.vtype === 'class') { // e.g. javascript function class name = `new ${name}` - } else if (fclos.parent?.vtype === 'class' || fclos.parent?.fdef?.type === 'ClassDefinition') { - const nsDef = fclos.parent.fdef - const nsName = nsDef?.name || '' + } else if (fclos.parent?.vtype === 'class' || fclos.parent?.ast.fdef?.type === 'ClassDefinition') { + const nsDef = fclos.parent.ast.fdef + const nsName = + nsDef?.name || + `` if (name === '_CTOR_') { name = `new ${nsName}` } else { @@ -202,7 +223,7 @@ class CallgraphChecker extends CheckerCallgraph { ret = `${ret.slice(0, 500)}...` } // attach loc - if (fdef) { + if (fdef && fdef?.loc) { ret += this.printLoc(fdef) } return ret @@ -219,8 +240,8 @@ class CallgraphChecker extends CheckerCallgraph { const splits = sourcefile.split('/') sourcefile = splits[splits.length - 1] } - const startLine = ast && ast.loc.start.line - const endLine = ast && ast.loc.end.line + const startLine = ast && ast?.loc?.start?.line + const endLine = ast && ast?.loc?.end?.line return ` \\n[${sourcefile} : ${startLine}_${endLine}]` } diff --git a/src/checker/common/full-callgraph-file-entrypoint.ts b/src/checker/common/full-callgraph-file-entrypoint.ts index 5b40902b..36748110 100644 --- a/src/checker/common/full-callgraph-file-entrypoint.ts +++ b/src/checker/common/full-callgraph-file-entrypoint.ts @@ -11,6 +11,7 @@ const options = require('../../config') const { Graph } = require('../../util/graph') const logger = require('../../util/logger')(__filename) const sourceLine = require('../../engine/analyzer/common/source-line') +const { performanceTracker } = require('../../util/performance-tracker') /** * @@ -23,8 +24,8 @@ function printLoc(ast: any): string { const splits = sourcefile.split('/') sourcefile = splits[splits.length - 1] } - const startLine = ast && ast.loc.start.line - const endLine = ast && ast.loc.end.line + const startLine = ast && ast?.loc?.start.line + const endLine = ast && ast?.loc?.end.line return ` \\n[${sourcefile} : ${startLine}_${endLine}]` } @@ -60,13 +61,16 @@ function prettyPrint( // pretty print fdef name = fdef.name || '' // try to attach namespace - if (fclos && fclos.__proto__.constructor.name !== 'BVT') { + if (fclos && fclos.__proto__.constructor.name !== 'BVTValue') { if (fclos.vtype === 'class') { // e.g. javascript function class name = `new ${name}` - } else if (fclos.parent?.vtype === 'class' || fclos.parent?.fdef?.type === 'ClassDefinition') { - const nsDef = fclos.parent.fdef - const nsName = nsDef?.name || '' + } else if (fclos.parent?.vtype === 'class' || fclos.parent?.ast.fdef?.type === 'ClassDefinition') { + const nsDef = fclos.parent.ast.fdef + let nsName = nsDef?.name || '' + if (fclos.parent.qid) { + nsName = fclos.parent.qid + } if (name === '_CTOR_') { name = `new ${nsName}` } else { @@ -86,18 +90,33 @@ function prettyPrint( ret = `${ret.slice(0, 500)}...` } // attach loc - if (fdef) { + if (fdef && fdef?.loc) { ret += printLoc(fdef) } return ret } +/** + * 从 nodehash 和 UUID 还原 funcDef 和 funcSymbol + * @param node callgraph 节点 + * @param astManager AST 管理器 + * @param symbolTable 符号表管理器 + * @returns 包含 funcDef 和 funcSymbol 的对象 + */ +function restoreNodeFromReferences(node: any, astManager?: any, symbolTable?: any): { funcDef: any; funcSymbol: any } { + const funcDef = + node.opts?.funcDefNodehash && astManager ? astManager.get(node.opts.funcDefNodehash) : node.opts?.funcDef + const funcSymbol = + node.opts?.funcSymbolUuid && symbolTable ? symbolTable.get(node.opts.funcSymbolUuid) : node.opts?.funcSymbol + return { funcDef, funcSymbol } +} + /** * generate full callGraph by funcSymbolTable * @param analyzer */ function makeFullCallGraph(analyzer: any): void { - analyzer.performanceTracker.start(`makeFullCallGraph(BySymbolInterpret)`) + performanceTracker.start(`startAnalyze.makeFullCallGraph(BySymbolInterpret)`) config.loadDefaultRule = false config.loadExternalRule = false config.makeAllCG = true @@ -108,20 +127,24 @@ function makeFullCallGraph(analyzer: any): void { const backupCheckerManager = analyzer.checkerManager analyzer.checkerManager = newCheckerManager analyzer.ainfo.callgraph = analyzer.ainfo.callgraph || new Graph() - if (analyzer.ainfo.callgraph && Object.keys(analyzer.funcSymbolTable).length > 0) { + if (analyzer.ainfo.callgraph && Object.keys(analyzer.topScope.context.funcs).length > 0) { const alreadyCheckList: any[] = [] // 分析过的callnode一定会出现在nodes中 for (const node of analyzer.ainfo.callgraph.nodes.values()) { - if (node.opts?.funcSymbol) { - alreadyCheckList.push(node.opts?.funcSymbol) + // 从 UUID 还原 funcSymbol + if (node.opts?.funcSymbolUuid) { + const funcSymbol = analyzer.symbolTable.get(node.opts.funcSymbolUuid) + if (funcSymbol) { + alreadyCheckList.push(funcSymbol) + } } } let totalCount = 0 - Object.entries(analyzer.funcSymbolTable).forEach(([key, funcSymbol]) => { + Object.entries(analyzer.topScope.context.funcs).forEach(([key, funcSymbol]) => { const funcSymbolAny = funcSymbol as any if ( !alreadyCheckList.includes(funcSymbolAny) && - funcSymbolAny.fdef && - funcSymbolAny.fdef.type === 'FunctionDefinition' + funcSymbolAny.ast.fdef && + funcSymbolAny.ast.fdef.type === 'FunctionDefinition' ) { totalCount += 1 } @@ -131,7 +154,7 @@ function makeFullCallGraph(analyzer: any): void { let already30Percent = false let already70Percent = false logger.info('makeAllCG-start') - Object.entries(analyzer.funcSymbolTable).forEach(([key, funcSymbol]) => { + Object.entries(analyzer.topScope.context.funcs).forEach(([key, funcSymbol]) => { analyzedCount += 1 if (analyzedCount > totalCount * 0.1 && !already10Percent) { logger.info('\tmakeAllCG-10%') @@ -149,15 +172,13 @@ function makeFullCallGraph(analyzer: any): void { const funcSymbolAny2 = funcSymbol as any if ( !alreadyCheckList.includes(funcSymbolAny2) && - funcSymbolAny2.fdef && - funcSymbolAny2.fdef.type === 'FunctionDefinition' + funcSymbolAny2.ast.fdef && + funcSymbolAny2.ast.fdef.type === 'FunctionDefinition' ) { alreadyCheckList.push(funcSymbolAny2) - const argValues: any[] = [] analyzer.executeCall( - funcSymbolAny2.fdef, + funcSymbolAny2.ast.fdef, funcSymbolAny2, - argValues, analyzer.initState(funcSymbolAny2.parent), funcSymbolAny2.parent ) @@ -167,7 +188,7 @@ function makeFullCallGraph(analyzer: any): void { } analyzer.checkerManager = backupCheckerManager config.makeAllCG = false - analyzer.performanceTracker.end(`makeFullCallGraph(BySymbolInterpret)`) + performanceTracker.end(`startAnalyze.makeFullCallGraph(BySymbolInterpret)`) } /** @@ -176,16 +197,34 @@ function makeFullCallGraph(analyzer: any): void { * @param resolver */ function makeFullCallGraphByType(analyzer: any, resolver: TypeRelatedInfoResolver) { - if (!resolver) { + if (!resolver || (resolver.resolveFinish && analyzer?.ainfo?.callgraph)) { return } - analyzer.performanceTracker.start('makeFullCallGraphByType') + performanceTracker.start('startAnalyze.makeFullCallGraphByType') if (!resolver.resolveFinish) { resolver.resolve(analyzer) } + // Helper function to extract only location and name from AST to reduce memory usage + const extractFuncDefInfo = (ast: any): { loc?: any; name?: any; id?: any } | null => { + if (!ast) return null + return { + loc: ast.loc, + name: ast.name, + id: ast.id, // Store id for functionName access + } + } + + // Helper function to extract only location from callSite AST to reduce memory usage + const extractCallSiteInfo = (callSite: any): { loc?: any } | null => { + if (!callSite) return null + return { + loc: callSite.loc, + } + } + const graph = new Graph() Object.entries(analyzer.funcSymbolTable).forEach(([, funcSymbol]) => { const funcSymbolAny = funcSymbol as any @@ -201,7 +240,10 @@ function makeFullCallGraphByType(analyzer: any, resolver: TypeRelatedInfoResolve invocation.calleeType, invocation.fsig ), - { funcDef: invocation.fromScopeAst, funcSymbol: invocation.fromScope } + { + funcDef: extractFuncDefInfo(invocation.fromScopeAst), + funcSymbol: invocation.fromScope, + } ) const toNode = graph.addNode( prettyPrint( @@ -213,31 +255,45 @@ function makeFullCallGraphByType(analyzer: any, resolver: TypeRelatedInfoResolve invocation.fsig ), { - funcDef: invocation.toScopeAst, + funcDef: extractFuncDefInfo(invocation.toScopeAst), funcSymbol: invocation.toScope, } ) - graph.addEdge(fromNode, toNode, { callSite: invocation.callSite }) + graph.addEdge(fromNode, toNode, { callSite: extractCallSiteInfo(invocation.callSite) }) } } } }) analyzer.ainfo.callgraph = graph - analyzer.performanceTracker.end('makeFullCallGraphByType') + performanceTracker.end('startAnalyze.makeFullCallGraphByType') } /** * 从CallGraph中拿取边界作为全func类型的Entrypoint * @param callGraph + * @param analyzer */ -function getAllEntryPointsUsingCallGraph(callGraph: any): any[] { +function getAllEntryPointsUsingCallGraph(callGraph: any, analyzer?: any): any[] { const entryPoints = { fclosEntryPoints: new Map(), } + const astManager = analyzer?.astManager + const symbolTable = analyzer?.symbolTable + for (const f of callGraph.nodes.keys()) { const thisNode = callGraph.nodes.get(f) - if (!thisNode.opts?.funcDef) { + // 从 nodehash 和 UUID 还原 funcDef 和 funcSymbol + const thisNodeFuncDef = + thisNode.opts?.funcDefNodehash && astManager + ? astManager.get(thisNode.opts.funcDefNodehash) + : thisNode.opts?.funcDef + const thisNodeFuncSymbol = + thisNode.opts?.funcSymbolUuid && symbolTable + ? symbolTable.get(thisNode.opts.funcSymbolUuid) + : thisNode.opts?.funcSymbol + + if (!thisNodeFuncDef) { continue } let hasCalled = false @@ -245,21 +301,27 @@ function getAllEntryPointsUsingCallGraph(callGraph: any): any[] { // 需要准确比较ast上的loc,因为函数符号值由于有new等问题不一定是同一个 const targetNode = callGraph.nodes.get(callGraph.edges.get(ek).targetNodeId) if (thisNode && targetNode && !callGraph.edges.get(ek)?.sourceNodeId.includes('entry_point')) { + // 从 nodehash 还原 targetNode 的 funcDef + const targetNodeFuncDef = + targetNode.opts?.funcDefNodehash && astManager + ? astManager.get(targetNode.opts.funcDefNodehash) + : targetNode.opts?.funcDef + if ( - targetNode.opts?.funcDef?.loc?.sourcefile && - targetNode.opts?.funcDef?.loc?.start?.line && - targetNode.opts?.funcDef?.loc?.end?.line && - targetNode.opts?.funcDef?.loc?.sourcefile === thisNode.opts?.funcDef?.loc?.sourcefile && - targetNode.opts?.funcDef?.loc?.start?.line === thisNode.opts?.funcDef?.loc?.start?.line && - targetNode.opts?.funcDef?.loc?.end?.line === thisNode.opts?.funcDef?.loc?.end?.line + targetNodeFuncDef?.loc?.sourcefile && + targetNodeFuncDef?.loc?.start?.line && + targetNodeFuncDef?.loc?.end?.line && + targetNodeFuncDef?.loc?.sourcefile === thisNodeFuncDef?.loc?.sourcefile && + targetNodeFuncDef?.loc?.start?.line === thisNodeFuncDef?.loc?.start?.line && + targetNodeFuncDef?.loc?.end?.line === thisNodeFuncDef?.loc?.end?.line ) { hasCalled = true break } } } - if (!hasCalled) { - entryPoints.fclosEntryPoints.set(thisNode.id, thisNode.opts.funcSymbol) + if (!hasCalled && thisNodeFuncSymbol) { + entryPoints.fclosEntryPoints.set(thisNode.id, thisNodeFuncSymbol) } } const newEntryPointList: any[] = [] @@ -267,10 +329,10 @@ function getAllEntryPointsUsingCallGraph(callGraph: any): any[] { const entryPoint = new EntryPoint(constValue.ENGIN_START_FUNCALL) entryPoint.scopeVal = entry.parent entryPoint.argValues = [] - entryPoint.functionName = entry.fdef?.id?.name - entryPoint.filePath = entry.fdef?.loc?.sourcefile?.startsWith(config.maindirPrefix) - ? entry.fdef?.loc?.sourcefile?.substring(config.maindirPrefix.length) - : entry.fdef?.loc?.sourcefile + entryPoint.functionName = entry.ast.fdef?.id?.name + entryPoint.filePath = entry.ast.fdef?.loc?.sourcefile?.startsWith(config.maindirPrefix) + ? entry.ast.fdef?.loc?.sourcefile?.substring(config.maindirPrefix.length) + : entry.ast.fdef?.loc?.sourcefile entryPoint.attribute = 'fullCallGraphMade' entryPoint.packageName = undefined entryPoint.entryPointSymVal = entry @@ -281,19 +343,20 @@ function getAllEntryPointsUsingCallGraph(callGraph: any): any[] { /** * 若为弱类型脚本语言,则加入所有文件作为EntryPoint - * @param fileManager + * @param analyzer */ -function getAllFileEntryPointsUsingFileManager(fileManager: any): any[] { +function getAllFileEntryPointsUsingFileManager(analyzer: any): any[] { const entryPoints: any[] = [] if (options.language === 'python' || options.language === 'javascript') { - if (fileManager) { - Object.values(fileManager).forEach((file: any) => { - if (!file.ast || file.ast.type !== 'CompileUnit') return + if (analyzer?.fileManager) { + Object.values(analyzer?.fileManager).forEach((fileUUid: any) => { + const file = analyzer.symbolTable.get(fileUUid) + if (!file.ast.node || file.ast.node.type !== 'CompileUnit') return const entryPoint = new EntryPoint(constValue.ENGIN_START_FILE_BEGIN) entryPoint.scopeVal = file entryPoint.argValues = undefined entryPoint.functionName = undefined - entryPoint.filePath = file?.ast?.loc?.sourcefile + entryPoint.filePath = file?.ast?.node?.loc?.sourcefile entryPoint.attribute = 'fullfileManagerMade' entryPoint.packageName = undefined entryPoint.entryPointSymVal = file @@ -309,30 +372,45 @@ function getAllFileEntryPointsUsingFileManager(fileManager: any): any[] { * @param keywords need an array * @param callGraph * @param fileManager + * @param analyzer */ -function getEntryPointsUsingCallGraphByKeyWords(keywords: string[], callGraph: any, fileManager: any): any[] { +function getEntryPointsUsingCallGraphByKeyWords( + keywords: string[], + callGraph: any, + fileManager: any, + analyzer?: any +): any[] { const newEntryPointList: any[] = [] if (!callGraph || !keywords || !Array.isArray(keywords)) { return newEntryPointList } + const astManager = analyzer?.astManager + const symbolTable = analyzer?.symbolTable for (const keyword of keywords) { const alreadyCalculate: any[] = [] - const nodes = getNodeInCallGraphByKeyword(keyword, callGraph.nodes) + const nodes = getNodeInCallGraphByKeyword(keyword, callGraph.nodes, astManager) for (const node of nodes) { // const node = getNodeInCallGraphByKeyword(keyword, callGraph.nodes) if (node) { - const fclosNodes = getFclosEntryPointsUsingCallGraphByTargetNode(node.id, callGraph, alreadyCalculate) + const fclosNodes = getFclosEntryPointsUsingCallGraphByTargetNode( + node.id, + callGraph, + alreadyCalculate, + astManager, + symbolTable + ) if (fclosNodes && Array.isArray(fclosNodes) && fclosNodes.length > 0) { for (const f of fclosNodes) { - const entry = f.opts.funcSymbol + const { funcSymbol: entry } = restoreNodeFromReferences(f, astManager, symbolTable) + if (!entry) continue const entryPoint = new EntryPoint(constValue.ENGIN_START_FUNCALL) entryPoint.scopeVal = entry.parent entryPoint.argValues = [] - entryPoint.functionName = entry.fdef?.id?.name - entryPoint.filePath = entry.fdef?.loc?.sourcefile?.startsWith(config.maindirPrefix) - ? entry.fdef?.loc?.sourcefile?.substring(config.maindirPrefix.length) - : entry.fdef?.loc?.sourcefile + entryPoint.functionName = entry.ast.fdef?.id?.name + entryPoint.filePath = entry.ast.fdef?.loc?.sourcefile?.startsWith(config.maindirPrefix) + ? entry.ast.fdef?.loc?.sourcefile?.substring(config.maindirPrefix.length) + : entry.ast.fdef?.loc?.sourcefile entryPoint.attribute = 'FuncEntryPointByLoc' entryPoint.packageName = undefined entryPoint.entryPointSymVal = entry @@ -344,13 +422,13 @@ function getEntryPointsUsingCallGraphByKeyWords(keywords: string[], callGraph: a for (const file of Object.values(fileManager)) { // const file = fileManager[loc.sourcefile] - const content = sourceLine.getCodeBySourceFile((file as any)?.ast?.loc?.sourcefile) + const content = sourceLine.getCodeBySourceFile((file as any)?.ast?.node?.loc?.sourcefile) if (file && content.includes(keyword)) { const entryPoint = new EntryPoint(constValue.ENGIN_START_FILE_BEGIN) entryPoint.scopeVal = file entryPoint.argValues = undefined entryPoint.functionName = undefined - entryPoint.filePath = (file as any)?.ast?.sourcefile || (file as any)?.ast?.loc?.sourcefile + entryPoint.filePath = (file as any)?.ast?.node?.sourcefile || (file as any)?.ast?.node?.loc?.sourcefile entryPoint.attribute = 'FileEntryPointByLoc' entryPoint.packageName = undefined entryPoint.entryPointSymVal = file @@ -366,30 +444,41 @@ function getEntryPointsUsingCallGraphByKeyWords(keywords: string[], callGraph: a * @param locs need an array * @param callGraph * @param fileManager + * @param analyzer */ -function getEntryPointsUsingCallGraphByLoc(locs: any[], callGraph: any, fileManager: any): any[] { +function getEntryPointsUsingCallGraphByLoc(locs: any[], callGraph: any, fileManager: any, analyzer?: any): any[] { const newEntryPointList: any[] = [] if (!callGraph || !locs || !Array.isArray(locs)) { return newEntryPointList } + const astManager = analyzer?.astManager + const symbolTable = analyzer?.symbolTable + for (const loc of locs) { - if (!loc.sourcefile || !loc.start?.line || !loc.end.line) { + if (!loc.sourcefile || !loc.start?.line || !loc.end?.line) { continue } const alreadyCalculate: any[] = [] - const node = getNodeInCallGraphByLoc(loc, callGraph.nodes) + const node = getNodeInCallGraphByLoc(loc, callGraph.nodes, astManager) if (node) { - const fclosNodes = getFclosEntryPointsUsingCallGraphByTargetNode(node.id, callGraph, alreadyCalculate) + const fclosNodes = getFclosEntryPointsUsingCallGraphByTargetNode( + node.id, + callGraph, + alreadyCalculate, + astManager, + symbolTable + ) if (fclosNodes && Array.isArray(fclosNodes) && fclosNodes.length > 0) { for (const f of fclosNodes) { - const entry = f.opts.funcSymbol + const { funcSymbol: entry } = restoreNodeFromReferences(f, astManager, symbolTable) + if (!entry) continue const entryPoint = new EntryPoint(constValue.ENGIN_START_FUNCALL) entryPoint.scopeVal = entry.parent entryPoint.argValues = [] - entryPoint.functionName = entry.fdef?.id?.name - entryPoint.filePath = entry.fdef?.loc?.sourcefile?.startsWith(config.maindirPrefix) - ? entry.fdef?.loc?.sourcefile?.substring(config.maindirPrefix.length) - : entry.fdef?.loc?.sourcefile + entryPoint.functionName = entry.ast.fdef?.id?.name + entryPoint.filePath = entry.ast.fdef?.loc?.sourcefile?.startsWith(config.maindirPrefix) + ? entry.ast.fdef?.loc?.sourcefile?.substring(config.maindirPrefix.length) + : entry.ast.fdef?.loc?.sourcefile entryPoint.attribute = 'FuncEntryPointByLoc' entryPoint.packageName = undefined entryPoint.entryPointSymVal = entry @@ -403,7 +492,7 @@ function getEntryPointsUsingCallGraphByLoc(locs: any[], callGraph: any, fileMana entryPoint.scopeVal = file entryPoint.argValues = undefined entryPoint.functionName = undefined - entryPoint.filePath = (file as any)?.ast?.sourcefile || (file as any)?.ast?.loc?.sourcefile + entryPoint.filePath = (file as any)?.ast?.node?.sourcefile || (file as any)?.ast?.node?.loc?.sourcefile entryPoint.attribute = 'FileEntryPointByLoc' entryPoint.packageName = undefined entryPoint.entryPointSymVal = file @@ -419,11 +508,15 @@ function getEntryPointsUsingCallGraphByLoc(locs: any[], callGraph: any, fileMana * @param key * @param callGraph * @param alreadyCalculate + * @param astManager + * @param symbolTable */ function getFclosEntryPointsUsingCallGraphByTargetNode( key: any, callGraph: any, - alreadyCalculate: any[] + alreadyCalculate: any[], + astManager?: any, + symbolTable?: any ): any[] | null { if ( !key || @@ -444,8 +537,10 @@ function getFclosEntryPointsUsingCallGraphByTargetNode( continue } if (circularDetected.includes(n)) { - if (callGraph.nodes.get(n)?.opts?.funcDef) { - res.push(callGraph.nodes.get(n)) + const node = callGraph.nodes.get(n) + const { funcDef } = restoreNodeFromReferences(node, astManager, symbolTable) + if (funcDef) { + res.push(node) } continue } @@ -454,8 +549,10 @@ function getFclosEntryPointsUsingCallGraphByTargetNode( let hasFind = false for (const ek of callGraph.edges.keys()) { // 需要准确比较ast上的loc,因为函数符号值由于有new等问题不一定是同一个 - const targetNodeAST = callGraph.nodes.get(callGraph.edges.get(ek).targetNodeId).opts?.funcDef - const thisNodeAST = callGraph.nodes.get(n).opts?.funcDef + const targetNode = callGraph.nodes.get(callGraph.edges.get(ek).targetNodeId) + const thisNode = callGraph.nodes.get(n) + const { funcDef: targetNodeAST } = restoreNodeFromReferences(targetNode, astManager, symbolTable) + const { funcDef: thisNodeAST } = restoreNodeFromReferences(thisNode, astManager, symbolTable) if ( thisNodeAST && targetNodeAST && @@ -473,8 +570,10 @@ function getFclosEntryPointsUsingCallGraphByTargetNode( } } if (!hasFind) { - if (callGraph.nodes.get(n)?.opts?.funcDef) { - res.push(callGraph.nodes.get(n)) + const node = callGraph.nodes.get(n) + const { funcDef } = restoreNodeFromReferences(node, astManager, symbolTable) + if (funcDef) { + res.push(node) } } } @@ -485,8 +584,9 @@ function getFclosEntryPointsUsingCallGraphByTargetNode( * * @param loc * @param nodes + * @param astManager */ -function getNodeInCallGraphByLoc(loc: any, nodes: any): any { +function getNodeInCallGraphByLoc(loc: any, nodes: any, astManager?: any): any { let tempStartLine = -1 let tempEndLine = Number.MAX_VALUE let tempKey @@ -495,10 +595,12 @@ function getNodeInCallGraphByLoc(loc: any, nodes: any): any { } for (const key of nodes.keys()) { if (key.includes('\\n[')) { - const filename = nodes.get(key)?.opts?.funcDef?.loc?.sourcefile - const startLine = nodes.get(key)?.opts?.funcDef?.loc?.start?.line - const endLine = nodes.get(key)?.opts?.funcDef?.loc?.end?.line - if (loc.sourcefile === filename && loc.start.line >= startLine && loc.end.line <= endLine) { + const node = nodes.get(key) + const { funcDef } = restoreNodeFromReferences(node, astManager) + const filename = funcDef?.loc?.sourcefile + const startLine = funcDef?.loc?.start?.line + const endLine = funcDef?.loc?.end?.line + if (loc.sourcefile === filename && loc.start?.line >= startLine && loc.end?.line <= endLine) { if (startLine > tempStartLine && endLine < tempEndLine) { tempStartLine = startLine tempEndLine = endLine @@ -515,19 +617,21 @@ function getNodeInCallGraphByLoc(loc: any, nodes: any): any { * 判断函数中是否包含关键字 * @param keyword * @param nodes + * @param astManager */ -function getNodeInCallGraphByKeyword(keyword: string, nodes: any): any[] { +function getNodeInCallGraphByKeyword(keyword: string, nodes: any, astManager?: any): any[] { const result: any[] = [] if (keyword === '') { return result } for (const key of nodes.keys()) { if (key.includes('\\n[')) { - const funcDef = nodes.get(key)?.opts?.funcDef + const node = nodes.get(key) + const { funcDef } = restoreNodeFromReferences(node, astManager) if (funcDef) { const content = sourceLine.getCodeByLocation(funcDef?.loc) if (content.includes(keyword)) { - result.push(nodes.get(key)) + result.push(node) } } } diff --git a/src/checker/common/output/callchain-output-strategy.ts b/src/checker/common/output/callchain-output-strategy.ts new file mode 100644 index 00000000..f1da9d4c --- /dev/null +++ b/src/checker/common/output/callchain-output-strategy.ts @@ -0,0 +1,140 @@ +import type { IResultManager } from '../../../engine/analyzer/common/result-manager' +import type { IConfig } from '../../../config' + +const _ = require('lodash') +const path = require('path') +const OutputStrategy = require('../../../engine/analyzer/common/output-strategy') +const Config = require('../../../config') +const FileUtil = require('../../../util/file-util') +const logger = require('../../../util/logger')(__filename) +const { handleException } = require('../../../engine/analyzer/common/exception-handler') + +/** + * Output strategy for callchain checker + * Outputs findings as JSON with entrypoint, sinkInfo, and callstack + */ +class CallchainOutputStrategy extends OutputStrategy { + static outputStrategyId = 'callchain' + + /** + * constructor + */ + constructor() { + super() + this.outputFilePath = 'callchain-report.json' + } + + /** + * output findings + * @param resultManager + * @param outputFilePath + * @param config + * @param printf + */ + outputFindings(resultManager: IResultManager, outputFilePath: string, config: IConfig, printf: any): void { + let reportFilePath + if (resultManager) { + const allFindings = resultManager.getFindings() + const callchainFindings = allFindings[CallchainOutputStrategy.outputStrategyId] + if (callchainFindings) { + // if (printf) { + // this.outputCallchainResultToConsole(callchainFindings, printf) + // } + const results = this.buildCallchainJSON(callchainFindings) + reportFilePath = path.join(Config.reportDir, outputFilePath) + FileUtil.writeJSONfile(reportFilePath, results) + logger.info(`callchain report is written to ${reportFilePath}`) + } + } + } + + /** + * output callchain result to console + * @param callchainFindings + * @param printf + */ + outputCallchainResultToConsole(callchainFindings: any[], printf: any): void { + if (!callchainFindings || callchainFindings.length === 0) { + printf('No callchain findings detected.') + return + } + printf(`\nTotal callchain findings: ${callchainFindings.length}\n`) + callchainFindings.forEach((finding: any, index: number) => { + printf(`\n[${index + 1}] Sink matched: ${finding.sinkRule}`) + if (finding.sinkAttribute) { + printf(` Attribute: ${finding.sinkAttribute}`) + } + printf(` Entry point: ${finding.entrypoint?.functionName || 'N/A'}`) + printf(` Location: ${finding.sourcefile}:${finding.line}`) + if (finding.callstackInfo && finding.callstackInfo.length > 0) { + printf(` Call stack depth: ${finding.callstackInfo.length}`) + finding.callstackInfo.forEach((frame: any, i: number) => { + printf(` [${i}] ${frame.function || 'anonymous'} at ${frame.file || '?'}:${frame.line || '?'}`) + }) + } + }) + } + + /** + * check whether callchain finding is new or not + * @param resultManager + * @param finding + */ + static isNewFinding(resultManager: IResultManager, finding: any): boolean { + try { + if (!finding) { + return false + } + const category = resultManager?.findings[CallchainOutputStrategy.outputStrategyId] + if (!category) return true + for (const issue of category) { + if ( + issue.line === finding.line && + issue.node === finding.node && + issue.issuecause === finding.issuecause && + issue.entry_fclos === finding.entry_fclos && + issue.entrypoint?.attribute === finding.entrypoint?.attribute && + issue.entrypoint?.filePath === finding.entrypoint?.filePath && + issue.entrypoint?.functionName === finding.entrypoint?.functionName && + issue.sinkRule === finding.sinkRule + ) { + return false + } + } + } catch (e) { + handleException( + e, + 'Error: an error occurred in CallchainOutputStrategy.isNewFinding', + 'Error: an error occurred in CallchainOutputStrategy.isNewFinding' + ) + } + return true + } + + /** + * Build JSON output with entrypoint, sinkInfo, callstack, and callsites + * @param callchainFindings + */ + buildCallchainJSON(callchainFindings: any[]): any { + const findings: any[] = [] + + _.values(callchainFindings).forEach((finding: any) => { + const entry: any = { + entrypoint: finding.entrypoint || {}, + sinkInfo: finding.sinkInfo || {}, + callstack: finding.callstackInfo || [], + callsites: finding.callsitesInfo || [], + } + + findings.push(entry) + }) + + return { + version: '1.0', + totalFindings: findings.length, + findings, + } + } +} + +module.exports = CallchainOutputStrategy diff --git a/src/checker/common/output/callgraph-output-strategy.ts b/src/checker/common/output/callgraph-output-strategy.ts index 8165bed8..d1533618 100644 --- a/src/checker/common/output/callgraph-output-strategy.ts +++ b/src/checker/common/output/callgraph-output-strategy.ts @@ -2,7 +2,6 @@ import type { IResultManager } from '../../../engine/analyzer/common/result-mana import type { IConfig } from '../../../config' const path = require('path') -const fs = require('fs-extra') const OutputStrategy = require('../../../engine/analyzer/common/output-strategy') const logger = require('../../../util/logger')(__filename) const { createWriteStream } = require('fs') @@ -23,105 +22,101 @@ class CallgraphOutputStrategy extends OutputStrategy { /** * 流式写入 CG 内容到文件,避免内存溢出 - * @param cgContent - * @param filePath + * 使用原生 JSON.stringify 配合 replacer 提升性能,同时保持流式写入 + * @param cgContent - 调用图内容,包含 nodes 和 edges + * @param filePath - 输出文件路径 */ - private writeCgContentToStream(cgContent: { nodes: Record; edges: Record }, filePath: string): void { - const writeStream = createWriteStream(filePath, { encoding: 'utf8' }) - - // 流式序列化单个值到流中(应用过滤器:排除 parent,将 undefined 转为 '') - const writeValue = (value: any): void => { - if (value === undefined) { - writeStream.write('""') - return - } - if (value === null) { - writeStream.write('null') - return - } - if (typeof value === 'string') { - writeStream.write(JSON.stringify(value)) - return + private writeCgContentToStream( + cgContent: { nodes: Record; edges: Record }, + filePath: string + ): void { + const writeStream = createWriteStream(filePath, { encoding: 'utf8', highWaterMark: 64 * 1024 }) + const bufferSize = 1024 * 1024 // 1MB 缓冲区 + const chunks: string[] = [] + let currentSize = 0 + + // 批量写入缓冲区,减少系统调用 + const flush = (): void => { + if (chunks.length > 0) { + writeStream.write(chunks.join('')) + chunks.length = 0 + currentSize = 0 } - if (typeof value === 'number' || typeof value === 'boolean') { - writeStream.write(String(value)) - return + } + + const append = (str: string): void => { + chunks.push(str) + currentSize += str.length + if (currentSize >= bufferSize) { + flush() } - if (Array.isArray(value)) { - writeStream.write('[') - value.forEach((item, index) => { - if (index > 0) { - writeStream.write(',') - } - writeValue(item) - }) - writeStream.write(']') - return + } + + // JSON.stringify 的 replacer:排除 parent 属性,将 undefined 转为空字符串 + const replacer = (key: string, value: any): any => { + // 排除 parent 属性 + if (key === 'parent') { + return undefined } - if (typeof value === 'object') { - writeStream.write('{') - let first = true - for (const [key, val] of Object.entries(value)) { - // 排除 parent 属性 - if (key === 'parent') { - continue - } - if (!first) { - writeStream.write(',') - } - first = false - writeStream.write(JSON.stringify(key)) - writeStream.write(':') - // 将 undefined 转为 '' - writeValue(val === undefined ? '' : val) - } - writeStream.write('}') - return + // 将 undefined 转为空字符串 + if (value === undefined) { + return '' } - writeStream.write('""') + return value } // 写入开始 - writeStream.write('{') + append('{') - // 写入 nodes - writeStream.write('"nodes":{') + // 写入 nodes:使用原生 JSON.stringify 序列化每个节点,利用 V8 优化 + append('"nodes":{') const nodeKeys = Object.keys(cgContent.nodes) - nodeKeys.forEach((key, index) => { - if (index > 0) { - writeStream.write(',') + if (nodeKeys.length > 0) { + for (let i = 0; i < nodeKeys.length; i++) { + if (i > 0) { + append(',') + } + const key = nodeKeys[i] + const nodeValue = cgContent.nodes[key] + // 使用原生 JSON.stringify,利用 V8 的原生优化 + const serializedNode = JSON.stringify(nodeValue, replacer) + append(`${JSON.stringify(key)}:${serializedNode}`) } - writeStream.write(JSON.stringify(key)) - writeStream.write(':') - writeValue(cgContent.nodes[key]) - }) - writeStream.write('}') + } + append('}') - // 写入 edges - writeStream.write(',"edges":{') + // 写入 edges:使用原生 JSON.stringify 序列化每条边 + append(',"edges":{') const edgeKeys = Object.keys(cgContent.edges) - edgeKeys.forEach((key, index) => { - if (index > 0) { - writeStream.write(',') + if (edgeKeys.length > 0) { + for (let i = 0; i < edgeKeys.length; i++) { + if (i > 0) { + append(',') + } + const key = edgeKeys[i] + const edgeValue = cgContent.edges[key] + // 使用原生 JSON.stringify,利用 V8 的原生优化 + const serializedEdge = JSON.stringify(edgeValue, replacer) + append(`${JSON.stringify(key)}:${serializedEdge}`) } - writeStream.write(JSON.stringify(key)) - writeStream.write(':') - writeValue(cgContent.edges[key]) - }) - writeStream.write('}') + } + append('}') // 写入结束 - writeStream.write('}') + append('}') + + // 刷新剩余缓冲区并关闭流 + flush() writeStream.end() } /** * output callgraph findings * - * @param resultManager - * @param outputFilePath - * @param config - * @param printf + * @param resultManager - 结果管理器 + * @param outputFilePath - 输出文件路径 + * @param config - 配置对象 + * @param printf - 打印函数(未使用) */ outputFindings(resultManager: IResultManager, outputFilePath: string, config: IConfig, printf: any): void { const allFindings = resultManager.getFindings() @@ -132,7 +127,10 @@ class CallgraphOutputStrategy extends OutputStrategy { if (config.dumpCG || config.dumpAllCG) { const callgraph = findings if (Array.isArray(callgraph) && callgraph.length > 0) { - const cgContent = callgraph[0].dumpGraph() + // 从 finding 中获取 astManager 和 symbolTable(在 triggerAtEndOfAnalyze 中已设置) + const astManager = (callgraph[0] as any).astManager + const symbolTable = (callgraph[0] as any).symbolTable + const cgContent = callgraph[0].dumpGraph(astManager, symbolTable) if (cgContent) { const cgFilePath = path.join(config.reportDir, outputFilePath) diff --git a/src/checker/common/output/taint-output-strategy.ts b/src/checker/common/output/taint-output-strategy.ts index 3e95de66..4666327b 100644 --- a/src/checker/common/output/taint-output-strategy.ts +++ b/src/checker/common/output/taint-output-strategy.ts @@ -9,6 +9,7 @@ const OutputStrategy = require('../../../engine/analyzer/common/output-strategy' const Config = require('../../../config') const FileUtil = require('../../../util/file-util') const TaintFindingUtil = require('../../taint/common-kit/taint-finding-util') +const { getOutputTrace } = require('../../taint/common-kit/taint-trace-output') const SourceLine = require('../../../engine/analyzer/common/source-line') const FindingUtil = require('../../../util/finding-util') const logger = require('../../../util/logger')(__filename) @@ -23,6 +24,42 @@ const { const AstUtil = require('../../../util/ast-util') const { handleException } = require('../../../engine/analyzer/common/exception-handler') +/** + * 比较单个 trace item 是否相等(file、line、tag、affectedNodeName) + */ +function isTraceItemEqual(item1: any, item2: any): boolean { + if (item1?.file !== item2?.file) return false + const line1 = item1?.line + const line2 = item2?.line + if (Array.isArray(line1) && Array.isArray(line2)) { + if (!_.isEqual(line1, line2)) return false + } else if (line1 !== line2) { + return false + } + if (item1?.tag !== item2?.tag) return false + if (item1?.affectedNodeName !== item2?.affectedNodeName) return false + return true +} + +/** + * 比较两个 trace 数组是否相等 + * 如果大小一样,且每一项的 file、line、tag、affectedNodeName 都一样,则返回 true + * @param trace1 + * @param trace2 + */ +function isTraceEqual(trace1: any[] | undefined, trace2: any[] | undefined): boolean { + if (!Array.isArray(trace1) || !Array.isArray(trace2)) { + return false + } + if (trace1.length !== trace2.length) { + return false + } + for (let i = 0; i < trace1.length; i++) { + if (!isTraceItemEqual(trace1[i], trace2[i])) return false + } + return true +} + /** * */ @@ -51,7 +88,9 @@ class TaintOutputStrategy extends OutputStrategy { const taintFindings = allFindings[TaintOutputStrategy.outputStrategyId] let callgraphFindings if (taintFindings) { - TaintFindingUtil.outputCheckerResultToConsole(taintFindings, printf) + if (printf) { + TaintFindingUtil.outputCheckerResultToConsole(taintFindings, printf) + } callgraphFindings = allFindings[CallgraphOutputStrategy.outputStrategyId] const results = this.getTaintFlowAsSarif(taintFindings, callgraphFindings) reportFilePath = path.join(Config.reportDir, outputFilePath) @@ -80,10 +119,25 @@ class TaintOutputStrategy extends OutputStrategy { issue.entrypoint.attribute === finding.entrypoint.attribute ) { if (issue.argNode && finding.argNode) { - if (_.isEqual(issue.argNode.trace, finding.argNode.trace)) { + if (isTraceEqual(issue.argNode.taint.getFirstTrace(), finding.argNode.taint.getFirstTrace())) { return false } - } else if (_.isEqual(issue.trace, finding.trace)) { + } else if (isTraceEqual(issue.trace, finding.trace)) { + return false + } else if (isTraceEqual(getOutputTrace(issue), getOutputTrace(finding))) { + // callstack-only output may collapse distinct internal traces into the same + // user-visible chain; suppress duplicate visible findings in that mode. + return false + } else if ( + finding.trace && finding.trace.length === 2 && + finding.trace[0]?.tag === 'SOURCE: ' && finding.trace[1]?.tag === 'SINK: ' && + issue.trace && issue.trace.length > 2 && + issue.trace[0]?.tag === 'SOURCE: ' && + isTraceItemEqual(finding.trace[0], issue.trace[0]) && + isTraceItemEqual(finding.trace[1], issue.trace[issue.trace.length - 1]) + ) { + // TaintRecord._clone 拷贝 trace 数组导致部分 finding 的 trace 退化为仅 SOURCE+SINK(len=2), + // 当已有同 SOURCE 且同 SINK 的更长 trace finding 时,跳过退化 finding。 return false } } @@ -106,9 +160,10 @@ class TaintOutputStrategy extends OutputStrategy { getTaintFlowAsSarif(taintFindings: TaintFinding[], callgraphFindings: any): any { const results: any[] = [] _.values(taintFindings).forEach((finding: TaintFinding) => { + const outputTrace = getOutputTrace(finding) // prepare trace const locations: any[] = [] - finding.trace?.forEach((item: any) => { + outputTrace?.forEach((item: any) => { const affectedNodeName = item?.affectedNodeName if (item.node) { const snippetText = SourceLine.formatSingleTrace(item) @@ -147,7 +202,7 @@ class TaintOutputStrategy extends OutputStrategy { finding.node?._meta?.nodehash ) - const callstackElements = prepareCallstackElements(finding.callstack) + const callstackElements = prepareCallstackElements(finding.callstack, finding.node) results.push( prepareResult( @@ -185,16 +240,18 @@ class TaintOutputStrategy extends OutputStrategy { const res: any = {} const { id, opts } = node res.id = id - const funcDef = opts?.funcDef + // 从 nodehash 还原 funcDef + let funcDef = opts?.funcDef + if (opts?.funcDefNodehash && (callgraph as any).astManager) { + funcDef = (callgraph as any).astManager.get(opts.funcDefNodehash) + } if (funcDef) { res.location = prepareLocation( - funcDef.loc.start.line, - funcDef.loc.start.column, - funcDef.loc.end.line, - funcDef.loc.end.column, - funcDef.loc.sourcefile, - '', - funcDef._meta?.nodehash || '' + funcDef.loc.start?.line, + funcDef.loc.start?.column, + funcDef.loc.end?.line, + funcDef.loc.end?.column, + funcDef.loc.sourcefile ) } return res @@ -202,16 +259,18 @@ class TaintOutputStrategy extends OutputStrategy { edges: callgraph.getEdgesAsArray().map((node: any) => { const res: any = {} const { id, sourceNodeId, targetNodeId, opts } = node - const callSite = opts?.callSite + // 从 callSiteNodehash 还原 callSite + let callSite = opts?.callSite + if (opts?.callSiteNodehash && (callgraph as any).astManager) { + callSite = (callgraph as any).astManager.get(opts.callSiteNodehash) + } if (callSite?.loc) { res.location = prepareLocation( - callSite.loc.start.line, - callSite.loc.start.column, - callSite.loc.end.line, - callSite.loc.end.column, - callSite.loc.sourcefile, - '', - callSite._meta?.nodehash || '' + callSite.loc.start?.line, + callSite.loc.start?.column, + callSite.loc.end?.line, + callSite.loc.end?.column, + callSite.loc.sourcefile ) } res.id = id diff --git a/src/checker/common/ql-uast-convert/converter.ts b/src/checker/common/ql-uast-convert/converter.ts index 42bb445c..1d617745 100644 --- a/src/checker/common/ql-uast-convert/converter.ts +++ b/src/checker/common/ql-uast-convert/converter.ts @@ -106,7 +106,7 @@ function traverseAndCollectNodes( ): void { if (!node) return const currentNodePath = buildPath(node) - if (node.loc && node.loc.start.line <= targetEndLine && node.loc.end.line >= targetStartLine) { + if (node.loc && node.loc.start?.line <= targetEndLine && node.loc.end?.line >= targetStartLine) { collectedNodes.push({ node, level, path: currentNodePath }) } for (const key in node) { @@ -119,7 +119,6 @@ function traverseAndCollectNodes( 'type', 'ast', 'loc', - 'sort', '_tags', 'uninit', 'callnode', @@ -163,8 +162,8 @@ function isDirectParent(childPath: any[], potentialParentPath: any[]): boolean { * @param flag */ function findClosestNode(ast: any, loc: any, flag: string): any { - const targetStartLine = loc.start.line - const targetEndLine = loc.end.line + const targetStartLine = loc.start?.line + const targetEndLine = loc.end?.line let closestNode: any = null let closestNodeLevel = -1 const collectedNodes: any[] = [] @@ -177,8 +176,8 @@ function findClosestNode(ast: any, loc: any, flag: string): any { !collectedNodes.some( ({ node: otherNode, path: otherPath }) => otherNode !== node && - otherNode.loc.start.line <= targetEndLine && - otherNode.loc.end.line >= targetStartLine && + otherNode.loc.start?.line <= targetEndLine && + otherNode.loc.end?.line >= targetStartLine && isDirectParent(otherPath, path) )) ) { @@ -188,10 +187,10 @@ function findClosestNode(ast: any, loc: any, flag: string): any { }) if (flag === 'source') { closestNode._meta.isSource = true - closestNode._meta.sourcePos = `${loc.filename}:${loc.start.line}:${loc.start.column}:${loc.end.line}:${loc.end.column}` + closestNode._meta.sourcePos = `${loc.filename}:${loc.start?.line}:${loc.start?.column}:${loc.end?.line}:${loc.end?.column}` } else if (flag === 'sink') { closestNode._meta.isSink = true - closestNode._meta.sinkPos = `${loc.filename}:${loc.start.line}:${loc.start.column}:${loc.end.line}:${loc.end.column}` + closestNode._meta.sinkPos = `${loc.filename}:${loc.start?.line}:${loc.start?.column}:${loc.end?.line}:${loc.end?.column}` } return closestNode } @@ -258,7 +257,7 @@ function introduceFlowConfig(options: any, ast: any, filename: string): void { } } -// filemanager = {filename : scope(filescope) } +// filemanager = {filename : scope(filescope).uuid } // 从source的文件出发 /** * @@ -274,10 +273,11 @@ function calcEntryPointAndRun(options: any, fileManager: any, analyzer: any): vo for (const filename in fileManager) { for (const sourcefile in options.FlowConfig.sourcefiles) { if (filename.endsWith(sourcefile)) { - const filescope = fileManager[filename] + const fileUuid = fileManager[filename] + const filescope = analyzer.symbolTable.get(fileUuid) let entryPoints = AstUtilConverter.satisfy( filescope, - (n: any) => n.vtype === 'fclos' && n.ast, + (n: any) => n.vtype === 'fclos' && n.ast.node, null, null, true @@ -287,20 +287,20 @@ function calcEntryPointAndRun(options: any, fileManager: any, analyzer: any): vo return } if (Array.isArray(entryPoints)) { - entryPoints = _.uniqBy(entryPoints, (value: any) => value.fdef) + entryPoints = _.uniqBy(entryPoints, (value: any) => value.ast.fdef) } else { entryPoints = [entryPoints] } const state = analyzer.initState(filescope) entryPoints.forEach((main: any) => { - const nd = AstUtilConverter.satisfy(main.ast, (n: any) => n?._meta?.isSource === true) + const nd = AstUtilConverter.satisfy(main.ast?.node, (n: any) => n?._meta?.isSource === true) if (nd) { const argValues: any[] = [] - for (const key in main?.ast?.parameters) { - argValues.push(analyzer.processInstruction(filescope, main.ast.parameters[key], state)) + for (const key in main?.ast?.node?.parameters) { + argValues.push(analyzer.processInstruction(filescope, main.ast.node.parameters[key], state)) } - logger.info(`entryPoint ${main?.ast?.loc?.sourcefile}:${main.id}`) - analyzer.executeCall(main.ast, main, argValues, state, filescope) + logger.info(`entryPoint ${main?.ast?.node?.loc?.sourcefile}:${main.id}`) + analyzer.executeCall(main.ast?.node, main, state, filescope, { callArgs: { args: argValues.map((v, i) => ({ index: i, value: v, kind: 'positional' as const })) } }) } }) } diff --git a/src/checker/common/rules-basic-handler.ts b/src/checker/common/rules-basic-handler.ts index 86d3d69c..a0ae42e7 100644 --- a/src/checker/common/rules-basic-handler.ts +++ b/src/checker/common/rules-basic-handler.ts @@ -1,4 +1,10 @@ import type { TaintFinding } from '../../engine/analyzer/common/common-types' +import { + getLegacyArgValues, + getCallArgsFromInfo, + getBoundCallFromInfo, + type CallInfo, +} from '../../engine/analyzer/common/call-args' const _ = require('lodash') const config = require('../../config') @@ -7,13 +13,71 @@ const { handleException } = require('../../engine/analyzer/common/exception-hand const logger = require('../../util/logger')(__filename) interface Rule { + selectors?: Array<{ type?: string; index?: number | '*'; name?: string }> args?: (string | number)[] + positions?: (string | number)[] + paramNames?: string[] + keywordNames?: string[] + includeReceiver?: boolean [key: string]: any } +/** + * 将 rule 中的多种选择器格式统一为 { type, index?, name? } 数组 + */ +function normalizeSelectors( + rule: Rule +): Array<{ type: 'position' | 'keyword' | 'all'; index?: number; name?: string }> { + const selectors: Array<{ type: 'position' | 'keyword' | 'all'; index?: number; name?: string }> = [] + + if (Array.isArray(rule.selectors)) { + for (const selector of rule.selectors) { + if (selector?.type === 'position' && selector.index === '*') { + selectors.push({ type: 'all' }) + } else if (selector?.type === 'position' && Number.isInteger(selector.index)) { + selectors.push({ type: 'position', index: selector.index as number }) + } else if (selector?.type === 'keyword' && typeof selector.name === 'string' && selector.name !== '') { + selectors.push({ type: 'keyword', name: selector.name }) + } + } + } + + const positions = Array.isArray(rule.positions) ? rule.positions : Array.isArray(rule.args) ? rule.args : [] + for (const item of positions) { + if (item === '*') { + selectors.push({ type: 'all' }) + continue + } + const parsed = parseInt(String(item), 10) + if (!Number.isNaN(parsed)) { + selectors.push({ type: 'position', index: parsed }) + } + } + + if (Array.isArray(rule.keywordNames)) { + for (const item of rule.keywordNames) { + if (typeof item === 'string' && item !== '') { + selectors.push({ type: 'keyword', name: item }) + } + } + } + + if (rule.includeReceiver === true) { + selectors.push({ type: 'position', index: -1 }) + } + + return selectors +} + let rules: any[] let preprocessReady: boolean = false +function normalizeTraceStrategy(strategy: any): string | undefined { + if (strategy === 'folded') return 'callstack-only' + if (strategy === 'callstack-only' || strategy === 'full') return strategy + return undefined +} + /** * * @param ruleConfigPath @@ -43,42 +107,108 @@ function getRules(ruleConfigPath: string): any[] { /** * - * @param argvalues + * @param callInfo * @param fclos * @param rule */ -function prepareArgs(argvalues: any[], fclos: any, rule: Rule): any[] { - let { args } = rule - let res = argvalues.concat() - args = (args || []).map((item: string | number) => { - if (item !== '*') { - return parseInt(String(item)) - } - return item - }) - if (!args.some((v: string | number) => v === '*')) { - args = args.filter((v: string | number) => typeof v === 'number') - res = argvalues.filter((value: any, index: number) => { - return (args as number[]).indexOf(index) !== -1 - }) - } - - // check whether receiver is tainted - if (args.some((v: string | number) => v === -1)) { - res.push(fclos.getThis()) +function prepareArgs(callInfo: CallInfo | undefined, fclos: any, rule: Rule): any[] { + const res: any[] = [] + const callArgs = getCallArgsFromInfo(callInfo) + const boundCall = getBoundCallFromInfo(callInfo) + const legacyArgvalues = getLegacyArgValues(callInfo) + const selectors = normalizeSelectors(rule) + const paramNames = Array.isArray(rule.paramNames) ? rule.paramNames.filter((item: string) => typeof item === 'string') : [] + const explicitArgs = + callArgs?.args && Array.isArray(callArgs.args) + ? callArgs.args + : legacyArgvalues.map((value: any, index: number) => ({ index, value })) + + const appendResult = (value: any) => { + if (typeof value === 'undefined') return + if (!res.includes(value)) { + res.push(value) + } + } + + for (const selector of selectors) { + if (selector.type === 'all') { + explicitArgs.forEach((arg: any) => appendResult(arg.value)) + continue + } + if (selector.type === 'position') { + if (selector.index === -1) { + appendResult(callArgs?.receiver || fclos?.getThisObj?.()) + } else if (typeof selector.index === 'number' && selector.index >= 0) { + explicitArgs.filter((arg: any) => arg.index === selector.index).forEach((arg: any) => appendResult(arg.value)) + } + continue + } + if (selector.type === 'keyword') { + explicitArgs + .filter((arg: any) => arg.name && arg.name === selector.name) + .forEach((arg: any) => appendResult(arg.value)) + } } + + // 兼容路径:通过形参名匹配 + if (paramNames.length > 0 && boundCall?.params?.length) { + boundCall.params + .filter((param: any) => paramNames.includes(param.name) && param.provided) + .forEach((param: any) => appendResult(param.value)) + } + + if (paramNames.includes('self') || paramNames.includes('cls')) { + appendResult(callArgs?.receiver || fclos?.getThisObj?.()) + } + return res } +/** + * prepare args by type + * @param callInfo + * @param fclos + * @param rule + */ +function prepareArgsByType(callInfo: CallInfo | undefined, fclos: any, rule: Rule): any[] { + const resultArray: any[] = [] + const argvalues = getLegacyArgValues(callInfo) + + if (!Array.isArray(argvalues) || !rule || !Array.isArray(rule.argTypes)) { + return resultArray + } + const { argTypes } = rule + for (const argvalue of argvalues) { + if (!argvalue.rtype || !argvalue.rtype.definiteType || argvalue.rtype.vagueType) { + continue + } + for (const argType of argTypes) { + if (argvalue.rtype.definiteType.name === argType || argvalue.rtype.definiteType.name.endsWith(`.${argType}`)) { + resultArray.push(argvalue) + break + } + } + } + + return resultArray +} + /** * */ function initRules(): void { - const configPath = require.resolve('../../config') - logger.info(`rules-basic-handler [CONFIG] Loaded from: ${configPath}`) - if (config.ruleConfigFile && config.ruleConfigFile !== '') { rules = FileUtil.loadJSONfile(FileUtil.getAbsolutePath(config.ruleConfigFile)) + // Extract taint trace output strategy from ruleConfig + if (Array.isArray(rules)) { + for (const rule of rules) { + const traceStrategy = normalizeTraceStrategy(rule.outputAtTaint?.traceStrategy) + if (traceStrategy) { + config.taintTraceOutputStrategy = traceStrategy + break + } + } + } } else { logger.info('Attention: no ruleConfig found') } @@ -181,7 +311,7 @@ function getFinding(type: string, description: string, node: any, argNode?: any) type, desc: description, node, - line: node.loc.start.line, + line: node.loc.start?.line, } if (argNode) { finding.argNode = argNode @@ -200,6 +330,7 @@ module.exports = { setPreprocessReady, getPreprocessReady, prepareArgs, + prepareArgsByType, matchPackageValueSink, getFinding, } diff --git a/src/checker/sanitizer/sanitizer-checker.ts b/src/checker/sanitizer/sanitizer-checker.ts index 226f446a..35805fae 100644 --- a/src/checker/sanitizer/sanitizer-checker.ts +++ b/src/checker/sanitizer/sanitizer-checker.ts @@ -1,3 +1,5 @@ +import type { CallInfo } from '../../engine/analyzer/common/call-args' + const _ = require('lodash') const BasicRuleHandler = require('../common/rules-basic-handler') const SanitizerTag = require('../common/value/sanitizer-tag') @@ -32,6 +34,10 @@ const callstackSanitizers = new Set() * */ class SanitizerChecker extends Checker { + static sanitizerMap: Map | undefined = undefined + + static matchSanitizerResultMap = new Map() + /** * * @param mng @@ -71,7 +77,7 @@ class SanitizerChecker extends Checker { * @param info */ triggerAtFunctionCallAfter(analyzer: any, scope: any, node: any, state: any, info: any): void { - const { fclos, ret, argvalues } = info + const { fclos, ret, callInfo } = info const sanitizers = SanitizerChecker.findAllSanitizers() if (sanitizers) { SanitizerChecker.checkAddOrDeleteFunctionCallSanitizer( @@ -79,7 +85,7 @@ class SanitizerChecker extends Checker { node, fclos, ret, - argvalues, + callInfo, scope, info?.callstack ) @@ -96,7 +102,7 @@ class SanitizerChecker extends Checker { * @param info */ triggerAtNewExprAfter(analyzer: any, scope: any, node: any, state: any, info: any): void { - const { fclos, ret, argvalues } = info + const { fclos, ret, callInfo } = info const sanitizers = SanitizerChecker.findAllSanitizers() if (sanitizers) { SanitizerChecker.checkAddOrDeleteFunctionCallSanitizer( @@ -104,7 +110,7 @@ class SanitizerChecker extends Checker { node, fclos, ret, - argvalues, + callInfo, scope, info?.callstack ) @@ -140,7 +146,7 @@ class SanitizerChecker extends Checker { * @param node * @param fclos * @param ret - * @param argvalues + * @param callInfo * @param scope * @param callstack */ @@ -149,7 +155,7 @@ class SanitizerChecker extends Checker { node: any, fclos: any, ret: any, - argvalues: any[], + callInfo: CallInfo, scope: any, callstack: any ): void { @@ -157,7 +163,7 @@ class SanitizerChecker extends Checker { return } - const matchedSanitizers = SanitizerChecker.findMatchedSanitizerOfFunctionCall(sanitizers, node, fclos, scope) + const matchedSanitizers = SanitizerChecker.findMatchedSanitizerOfFunctionCall(sanitizers, node, fclos, scope, callInfo) if (!matchedSanitizers) { return } @@ -173,7 +179,7 @@ class SanitizerChecker extends Checker { } break case SANITIZER.SANITIZER_SCENARIO.VALIDATE_BY_FUNCTIONCALL: - const args = BasicRuleHandler.prepareArgs(argvalues, fclos, matchedSanitizer) + const args = BasicRuleHandler.prepareArgs(callInfo, fclos, matchedSanitizer) if (args) { for (const arg of args) { SanitizerChecker.addSanitizerInSymbolValue(matchedSanitizer, node, arg, callstack) @@ -296,19 +302,36 @@ class SanitizerChecker extends Checker { } /** - * find all sanitizers from rule - * @returns {*} + * load and store all sanitizers from rule */ - static findAllSanitizers(): any[] { - const sanitizers: any[] = [] + static loadAndStoreAllSanitizersFromRule() { + if (!BasicRuleHandler.getPreprocessReady() || SanitizerChecker.sanitizerMap) { + return + } + SanitizerChecker.sanitizerMap = new Map() if (Array.isArray(BasicRuleHandler.getRules()) && BasicRuleHandler.getRules().length > 0) { for (const rule of BasicRuleHandler.getRules()) { if (Array.isArray(rule.sanitizers)) { - sanitizers.push(...rule.sanitizers) + for (const sanitizer of rule.sanitizers) { + SanitizerChecker.sanitizerMap.set(sanitizer.id, sanitizer) + } } } } - return sanitizers + } + + /** + * find all sanitizers from rule + * @returns {*} + */ + static findAllSanitizers(): any[] { + if (!SanitizerChecker.sanitizerMap) { + SanitizerChecker.loadAndStoreAllSanitizersFromRule() + } + if (!SanitizerChecker.sanitizerMap) { + return [] + } + return Array.from(SanitizerChecker.sanitizerMap.values()) } /** @@ -322,17 +345,19 @@ class SanitizerChecker extends Checker { return result } - if (Array.isArray(BasicRuleHandler.getRules()) && BasicRuleHandler.getRules().length > 0) { - for (const rule of BasicRuleHandler.getRules()) { - if (Array.isArray(rule.sanitizers)) { - for (const sanitizer of rule.sanitizers) { - if (sanitizerIds.includes(sanitizer.id)) { - result.push(sanitizer) - } - } - } + if (!SanitizerChecker.sanitizerMap) { + SanitizerChecker.loadAndStoreAllSanitizersFromRule() + } + if (!SanitizerChecker.sanitizerMap) { + return [] + } + + for (const sanitizerId of sanitizerIds) { + if (SanitizerChecker.sanitizerMap.has(sanitizerId)) { + result.push(SanitizerChecker.sanitizerMap.get(sanitizerId)) } } + return result } @@ -374,23 +399,23 @@ class SanitizerChecker extends Checker { for (const obj of sanitizerTag.callstack) { const callstackElement = new SanitizerCallstackElement() callstackElement.id = index - if (obj.ast?.loc?.sourcefile) { - callstackElement.fileName = shortenSourceFile(obj.ast?.loc?.sourcefile, Config.maindir_prefix) + if (obj.ast?.node?.loc?.sourcefile) { + callstackElement.fileName = shortenSourceFile(obj.ast?.node?.loc?.sourcefile, Config.maindir_prefix) } - if (obj.ast?.loc?.start?.line) { - callstackElement.beginLine = obj.ast?.loc?.start?.line + if (obj.ast?.node?.loc?.start?.line) { + callstackElement.beginLine = obj.ast?.node?.loc?.start?.line } - if (obj.ast?.loc?.end?.line) { - callstackElement.endLine = obj.ast?.loc?.end?.line + if (obj.ast?.node?.loc?.end?.line) { + callstackElement.endLine = obj.ast?.node?.loc?.end?.line } - if (obj.ast?.loc?.start?.column) { - callstackElement.beginColumn = obj.ast?.loc?.start?.column + if (obj.ast?.node?.loc?.start?.column) { + callstackElement.beginColumn = obj.ast?.node?.loc?.start?.column } - if (obj.ast?.loc?.end?.column) { - callstackElement.endColumn = obj.ast?.loc?.end?.column + if (obj.ast?.node?.loc?.end?.column) { + callstackElement.endColumn = obj.ast?.node?.loc?.end?.column } - if (obj.ast) { - callstackElement.codeSnippet = prettyPrint(obj.fdef ? obj.fdef : obj.ast) + if (obj.ast.node) { + callstackElement.codeSnippet = prettyPrint(obj.ast.fdef ? obj.ast.fdef : obj.ast.node) } callstackElements.push(callstackElement) index += 1 @@ -412,7 +437,15 @@ class SanitizerChecker extends Checker { * @param scope * @returns {*[]} */ - static findMatchedSanitizerOfFunctionCall(sanitizers: any[], node: any, fclos: any, scope: any): any[] { + static findMatchedSanitizerOfFunctionCall(sanitizers: any[], node: any, fclos: any, scope: any, callInfo: CallInfo): any[] { + if (!BasicRuleHandler.getPreprocessReady()) { + return [] + } + + if (node?._meta?.nodehash && SanitizerChecker.matchSanitizerResultMap.has(node._meta.nodehash)) { + return SanitizerChecker.matchSanitizerResultMap.get(node._meta.nodehash) + } + const matchedSanitizers: any[] = [] const sanitizersWithoutCalleeType = sanitizers.filter( @@ -420,7 +453,7 @@ class SanitizerChecker extends Checker { sanitizer.sanitizerType === SANITIZER.SANITIZER_TYPE.FUNCTION_CALL_SANITIZER && (!sanitizer.calleeType || sanitizer.calleeType.length === 0) ) - const matchedSanitizersWithoutCalleeType = matchSinkAtFuncCall(node, fclos, sanitizersWithoutCalleeType) + const matchedSanitizersWithoutCalleeType = matchSinkAtFuncCall(node, fclos, sanitizersWithoutCalleeType, callInfo) if (matchedSanitizersWithoutCalleeType) { matchedSanitizers.push(...matchedSanitizersWithoutCalleeType) } @@ -435,12 +468,17 @@ class SanitizerChecker extends Checker { node, fclos, sanitizersWithCalleeType, - scope + scope, + callInfo ) if (matchedSanitizersWithCalleeType) { matchedSanitizers.push(...matchedSanitizersWithCalleeType) } + if (node?._meta?.nodehash) { + SanitizerChecker.matchSanitizerResultMap.set(node._meta.nodehash, matchedSanitizers) + } + return matchedSanitizers } @@ -502,7 +540,7 @@ class SanitizerChecker extends Checker { if (!sanitizer || !sanitizer.id || !val) { return } - if (this.checkSanitizerTagExist(val._tags, sanitizer, node)) { + if (this.checkSanitizerTagExist(val.taint.getTags(), sanitizer, node)) { return } @@ -558,7 +596,7 @@ class SanitizerChecker extends Checker { (sanitizer: any) => sanitizer.sanitizerScenario === SANITIZER.SANITIZER_SCENARIO.CONFIG_BY_FUNCTIONCALL ) const fConfig = (nd: any) => { - const tags = nd?._tags + const tags = nd?.taint ? nd.taint.getTags() : undefined return tags && SanitizerChecker.findMatchedSanitizerTag(Configs, tags)?.length > 0 } @@ -566,13 +604,13 @@ class SanitizerChecker extends Checker { if (sanitizerNd) { if (Array.isArray(sanitizerNd)) { for (const n of sanitizerNd) { - const matchedConfigSanitizerTags = SanitizerChecker.findMatchedSanitizerTag(sanitizers, n._tags) + const matchedConfigSanitizerTags = SanitizerChecker.findMatchedSanitizerTag(sanitizers, n.taint ? n.taint.getTags() : undefined) if (matchedConfigSanitizerTags) { matchedSanitizerTagsForAllTrace.push(...matchedConfigSanitizerTags) } } } else { - const matchedConfigSanitizerTags = SanitizerChecker.findMatchedSanitizerTag(sanitizers, sanitizerNd._tags) + const matchedConfigSanitizerTags = SanitizerChecker.findMatchedSanitizerTag(sanitizers, sanitizerNd.taint ? sanitizerNd.taint.getTags() : undefined) if (matchedConfigSanitizerTags) { matchedSanitizerTagsForAllTrace.push(...matchedConfigSanitizerTags) } @@ -586,8 +624,9 @@ class SanitizerChecker extends Checker { sanitizer.sanitizerScenario === SANITIZER.SANITIZER_SCENARIO.VALIDATE_BY_BINARYOPERATION ) const fFlow = (nd: any) => { - const tags = nd?._tags - return _.isFunction(tags?.has) && tags.has(attribute) + const tagTraceMap = nd?.taint ? nd.taint.getTagTracesMap() : undefined + if (!tagTraceMap) return false + return tagTraceMap.has(attribute) } const filter = defaultFilter const satisfyCallback = (nd: any, from: any, parentMap: any) => { @@ -610,7 +649,7 @@ class SanitizerChecker extends Checker { } while (currentNd) } for (const parentNd of parentNdList) { - const matchedFlowSanitizerTags = SanitizerChecker.findMatchedSanitizerTag(flowSanitizers, parentNd._tags) + const matchedFlowSanitizerTags = SanitizerChecker.findMatchedSanitizerTag(flowSanitizers, parentNd.taint ? parentNd.taint.getTags() : undefined) if (matchedFlowSanitizerTags) { matchedSanitizerTags.push(...matchedFlowSanitizerTags) } diff --git a/src/checker/sdk/get-file-ast-checker.ts b/src/checker/sdk/get-file-ast-checker.ts index e4b53b2e..89c895be 100644 --- a/src/checker/sdk/get-file-ast-checker.ts +++ b/src/checker/sdk/get-file-ast-checker.ts @@ -16,6 +16,8 @@ class GetFileAstChecker extends Checker { fileManager: Record + symbolTable: any + /** * * @param mng @@ -56,18 +58,24 @@ class GetFileAstChecker extends Checker { const finding: Finding = { output: '', } - if (this.fileManager[this.input]) { - finding.output = JSON.stringify(this.fileManager[this.input].ast, (key: string, value: any) => { - // 如果属性名是 'parent',则返回 undefined 表示排除 - if (key === 'parent') { - return undefined - } - if (value === undefined) { - return '' - } - return value - }) - this.resultManager.newFinding(finding, InteractiveOutputStrategy.outputStrategyId) + let fileValue = this.fileManager[this.input] + if (fileValue) { + if (typeof fileValue === 'string' && fileValue.startsWith('symuuid_')) { + fileValue = this.symbolTable.get(this.fileManager[this.input]) + } + if (fileValue?.ast?.node) { + finding.output = JSON.stringify(fileValue.ast?.node, (key: string, value: any) => { + // 如果属性名是 'parent',则返回 undefined 表示排除 + if (key === 'parent') { + return undefined + } + if (value === undefined) { + return '' + } + return value + }) + this.resultManager.newFinding(finding, InteractiveOutputStrategy.outputStrategyId) + } } this.status = false } @@ -82,6 +90,7 @@ class GetFileAstChecker extends Checker { */ triggerAtStartOfAnalyze(analyzer: any, scope: any, node: any, state: any, info: any): void { this.fileManager = analyzer.fileManager + this.symbolTable = analyzer.symbolTable } } module.exports = GetFileAstChecker diff --git a/src/checker/taint/common-kit/entry-points-util.ts b/src/checker/taint/common-kit/entry-points-util.ts index bec25dd4..42861775 100644 --- a/src/checker/taint/common-kit/entry-points-util.ts +++ b/src/checker/taint/common-kit/entry-points-util.ts @@ -11,11 +11,13 @@ interface EntryPointConfig { interface MainFunction { parent?: any ast?: { - loc?: { - sourcefile?: string - } - id?: { - name?: string + node?: { + loc?: { + sourcefile?: string + } + id?: { + name?: string + } } } filePath?: string @@ -35,19 +37,23 @@ if (Array.isArray(Rules.getRules()) && Rules.getRules().length > 0) { /** * 填充entryPoint信息 * @param main + * @param isPreProcess 是否是为了模拟服务上下文而必须执行的操作,并非真实的api * @returns {EntryPoint} */ -function completeEntryPoint(main: MainFunction): typeof EntryPoint { +function completeEntryPoint(main: MainFunction, isPreProcess = false): typeof EntryPoint { const entryPoint = new EntryPoint(constValue.ENGIN_START_FUNCALL) entryPoint.scopeVal = main.parent entryPoint.argValues = [] entryPoint.entryPointSymVal = main - entryPoint.filePath = main.filePath || main.ast?.loc?.sourcefile?.substring(config.maindirPrefix.length) - entryPoint.functionName = main.functionName || main.ast?.id?.name + entryPoint.filePath = main.filePath || (config.maindirPrefix + ? main.ast?.node?.loc?.sourcefile?.substring(config.maindirPrefix.length) + : main.ast?.node?.loc?.sourcefile) + entryPoint.functionName = main.functionName || main.ast?.node?.id?.name entryPoint.attribute = 'HTTP' entryPoint.parent ??= main.parent // TODO entryPoint.funcReceiverType = main.funcReceiverType + entryPoint.isPreProcess = isPreProcess return entryPoint } diff --git a/src/checker/taint/common-kit/sink-util.ts b/src/checker/taint/common-kit/sink-util.ts index 98a80b22..b0a98893 100644 --- a/src/checker/taint/common-kit/sink-util.ts +++ b/src/checker/taint/common-kit/sink-util.ts @@ -1,8 +1,24 @@ +import { Invocation } from '../../../resolver/common/value/invocation' +import TypeRelatedInfoResolver from '../../../resolver/common/type-related-info-resolver' +import type { ClassHierarchy } from '../../../resolver/common/value/class-hierarchy' +import { getExplicitArgCount, type CallInfo } from '../../../engine/analyzer/common/call-args' + const _ = require('lodash') const { matchField: matchFieldSinkUtil } = require('../../common/rules-basic-handler') const AstUtilSinkUtil = require('../../../util/ast-util') const { handleException: handleExceptionSinkUtil } = require('../../../engine/analyzer/common/exception-handler') +// 全局统计:实际匹配的 sink 数量 +let matchedSinkCount = 0 + +function getMatchedSinkCount(): number { + return matchedSinkCount +} + +function resetMatchedSinkCount(): void { + matchedSinkCount = 0 +} + interface SinkRule { argNum?: number fsig?: string @@ -16,15 +32,16 @@ interface SinkRule { * @param node * @param fclos * @param sinks - * @param argvalues + * @param callInfo * @returns {Array} */ -function matchSinkAtFuncCall(node: any, fclos: any, sinks: SinkRule[], argvalues: any[]): SinkRule[] { +function matchSinkAtFuncCall(node: any, fclos: any, sinks: SinkRule[], callInfo: CallInfo): SinkRule[] { + const argCount = getExplicitArgCount(callInfo) const callExpr = node.callee || node const res: SinkRule[] = [] if (sinks && sinks.length > 0) { for (const tspec of sinks) { - if (tspec.argNum !== undefined && tspec.argNum >= 0 && argvalues && tspec.argNum !== argvalues.length) { + if (tspec.argNum !== undefined && tspec.argNum >= 0 && tspec.argNum !== argCount) { continue } @@ -32,10 +49,12 @@ function matchSinkAtFuncCall(node: any, fclos: any, sinks: SinkRule[], argvalues const marray = tspec.fsig.split('.') if (matchFieldSinkUtil(callExpr, marray, marray.length - 1)) { res.push(tspec) + matchedSinkCount++ // 统计实际匹配的 sink } } else if (tspec.fregex) { - if (callExpr.type === 'MemberAccess' && matchRegex(tspec.fregex, fclos._qid)) { + if (callExpr.type === 'MemberAccess' && matchRegex(tspec.fregex, fclos.qid)) { res.push(tspec) + matchedSinkCount++ // 统计实际匹配的 sink } } } @@ -56,19 +75,20 @@ function matchSinkAtFuncCallWithCalleeType( fclos: any, rules: SinkRule[], scope: any, - argvalues: any[] + callInfo: CallInfo ): SinkRule[] { + const argCount = getExplicitArgCount(callInfo) const callExpr = node.callee || node const res: SinkRule[] = [] if (rules && rules.length > 0) { - if (fclos.vtype === 'union' && !_.isEmpty(fclos.field)) { - fclos.field.forEach((subFClos: any) => { - res.push(...matchSinkAtFuncCallWithCalleeType(node, subFClos, rules, scope, argvalues)) + if (fclos.vtype === 'union' && !_.isEmpty(fclos.value)) { + fclos.value.forEach((subFClos: any) => { + res.push(...matchSinkAtFuncCallWithCalleeType(node, subFClos, rules, scope, callInfo)) }) return res } for (const tspec of rules) { - if (tspec.argNum !== undefined && tspec.argNum >= 0 && argvalues && tspec.argNum !== argvalues.length) { + if (tspec.argNum !== undefined && tspec.argNum >= 0 && tspec.argNum !== argCount) { continue } @@ -91,7 +111,7 @@ function matchSinkAtFuncCallWithCalleeType( AstUtilSinkUtil.prettyPrint(fclos.rtype?.definiteType).endsWith(`.${tspec.calleeType}`) || tspec.calleeType === '*') && (AstUtilSinkUtil.prettyPrint(fclos.rtype?.vagueType).replace(/"/g, '') === tspec.fsig || - fclos._sid === tspec.fsig) + fclos.sid === tspec.fsig) ) { // import cn.hutool.http.HttpRequest; HttpRequest.post res.push(tspec) @@ -112,7 +132,7 @@ function matchSinkAtFuncCallWithCalleeType( AstUtilSinkUtil.prettyPrint(fclos.rtype?.definiteType) === tspec.calleeType || AstUtilSinkUtil.prettyPrint(fclos.rtype?.definiteType).endsWith(`.${tspec.calleeType}`) || tspec.calleeType === '*') && - AstUtilSinkUtil.prettyPrint(fclos.ast) === tspec.fsig + AstUtilSinkUtil.prettyPrint(fclos.ast?.node) === tspec.fsig ) { res.push(tspec) } @@ -121,7 +141,7 @@ function matchSinkAtFuncCallWithCalleeType( // 用于匹配形如 squirrel.Delete(*).Where形式的sink点,*为通配符 callExpr.type === 'MemberAccess' && tspec.calleeType === '' && - matchRegex(tspec.fregex, fclos._qid) + matchRegex(tspec.fregex, fclos.qid) ) { res.push(tspec) } @@ -149,8 +169,59 @@ function matchRegex(pattern: string, testStr: string): boolean { } } +/** + * check if invocation match sink + * @param invocation + * @param sink + * @param typeResolver + */ +function checkInvocationMatchSink(invocation: Invocation, sink: SinkRule, typeResolver: TypeRelatedInfoResolver): boolean { + if (!invocation || !sink) { + return false + } + + if (!sink.fsig || sink.fsig === '') { + return false + } + if (!sink.calleeType || sink.calleeType === '') { + if (invocation.callSiteLiteral === sink.fsig || invocation.fsig === sink.fsig) { + return true + } + } else { + if (invocation.fsig === sink.fsig && invocation.calleeType && invocation.calleeType !== '') { + if (invocation.calleeType === sink.calleeType || invocation.calleeType.endsWith(`.${sink.calleeType}`)) { + return true + } else if (typeResolver) { + const classHierarchy: ClassHierarchy | undefined = typeResolver.classHierarchyMap.get(invocation.calleeType) + if (classHierarchy) { + const baseTypes: string[] = typeResolver.findBaseTypes(classHierarchy) + for (const baseType of baseTypes) { + if (baseType === sink.calleeType || baseType?.endsWith(`.${sink.calleeType}`)) { + return true + } + } + const subTypes: string[] = typeResolver.findSubTypes(classHierarchy) + for (const subType of subTypes) { + if (subType === sink.calleeType || subType?.endsWith(`.${sink.calleeType}`)) { + return true + } + } + } + } + } + if (invocation.callSiteLiteral === `${sink.calleeType}.${sink.fsig}` || invocation.callSiteLiteral?.endsWith(`.${sink.calleeType}.${sink.fsig}`)) { + return true + } + } + + return false +} + module.exports = { matchSinkAtFuncCall, matchSinkAtFuncCallWithCalleeType, matchRegex, + checkInvocationMatchSink, + getMatchedSinkCount, + resetMatchedSinkCount, } diff --git a/src/checker/taint/common-kit/source-util.ts b/src/checker/taint/common-kit/source-util.ts index 1eb2fa15..653abba1 100644 --- a/src/checker/taint/common-kit/source-util.ts +++ b/src/checker/taint/common-kit/source-util.ts @@ -1,10 +1,31 @@ +import { buildNewValueInstance } from '../../../util/clone-util' +import { getLegacyArgValues, type CallInfo } from '../../../engine/analyzer/common/call-args' + const _ = require('lodash') const AstUtil = require('../../../util/ast-util') const { prepareArgs, matchField } = require('../../common/rules-basic-handler') const BasicRuleHandler = require('../../common/rules-basic-handler') const { Scope } = require('../../../engine/analyzer/common') -const ValueUtil = require('../../../engine/analyzer/common/value/valueUtil') -const varUtil = require('../../../util/variable-util') +const QidUnifyUtil = require('../../../util/qid-unify-util') + +import { SymbolValue } from '../../../engine/analyzer/common/value/symbolic' + +// 全局统计:实际标记的 source 数量 +let markedSourceCount = 0 + +/** + * + */ +function getMarkedSourceCount(): number { + return markedSourceCount +} + +/** + * + */ +function resetMarkedSourceCount(): void { + markedSourceCount = 0 +} /** * @@ -12,15 +33,14 @@ const varUtil = require('../../../util/variable-util') * @param tagType */ function setTaint(res: any, tagType: any): void { - res._tags = res._tags || new Set() + // taint 在 Unit 构造函数中已创建 if (Array.isArray(tagType)) { for (const item of tagType) { - res._tags.add(item) + res.taint.addTag(item) } } else if (tagType) { - res._tags.add(tagType) + res.taint.addTag(tagType) } - res.hasTagRec = true } /** @@ -35,22 +55,24 @@ function markTaintSource(unit: any, { path, kind }: { path: any; kind: any }): v return } setTaint(unit, kind) - if (unit.trace && Array.isArray(unit.trace) && unit.trace[0]?.tag !== 'SOURCE: ') { - unit.trace = undefined + markedSourceCount++ // 统计实际标记的 source + // 如果已有 trace 但首项不是 SOURCE,清空 trace + const existingTrace = unit.taint.getFirstTrace() + if (existingTrace && Array.isArray(existingTrace) && existingTrace[0]?.tag !== 'SOURCE: ') { + unit.taint.clearTrace() } - if (!unit.trace) { + if (!unit.taint.hasTraces()) { const start_line = path?.loc?.start?.line const end_line = path?.loc?.end?.line const tline = start_line === end_line ? start_line : _.range(start_line, end_line + 1) - unit.trace = [ - { - file: path?.loc?.sourcefile, - line: tline, - node: path, - tag: 'SOURCE: ', - affectedNodeName: AstUtil.prettyPrint(path), - }, - ] + const traceItem = { + file: path?.loc?.sourcefile, + line: tline, + node: path, + tag: 'SOURCE: ', + affectedNodeName: AstUtil.prettyPrint(path), + } + unit.taint.setAllTraces([traceItem]) } } @@ -102,33 +124,34 @@ function introduceTaintAtFuncCallReturnValue( * * @param scope * @param node - * @param res + * @param callInfo * @param funcCallArgTaintSource */ -function introduceFuncArgTaintByRuleConfig(scope: any, node: any, res: any, funcCallArgTaintSource: any): void { +function introduceFuncArgTaintByRuleConfig(scope: any, node: any, callInfo: CallInfo | undefined, funcCallArgTaintSource: any): void { if (!BasicRuleHandler.getPreprocessReady()) { return } + const argvalues = getLegacyArgValues(callInfo) const rules = funcCallArgTaintSource if (rules && Array.isArray(rules) && rules.length > 0) { const call = node for (const tspec of rules) { if (tspec.fsig) { const marray = tspec.fsig.split('.') - if (call.callee?.type === 'MemberAccess' && _.isArray(res)) { + if (call.callee?.type === 'MemberAccess' && _.isArray(argvalues)) { if ( (matchField(call.callee?.property, marray, marray.length - 1) || matchField(call.callee, marray, marray.length - 1)) && (AstUtil.prettyPrint(scope?.rtype) === tspec.calleeType || tspec.calleeType === '*') ) { - const args = prepareArgs(res, undefined, tspec) + const args = prepareArgs(callInfo, undefined, tspec) for (let i = 0; i < args.length; i++) { markTaintSource(args[i], { path: node, kind: tspec.kind }) } } } else if (call.callee?.type === 'Identifier') { if (call.callee.name === tspec.fsig) { - const args = prepareArgs(res, undefined, tspec) + const args = prepareArgs(callInfo, undefined, tspec) for (let i = 0; i < args.length; i++) { markTaintSource(args[i], { path: node, kind: tspec.kind }) } @@ -142,43 +165,74 @@ function introduceFuncArgTaintByRuleConfig(scope: any, node: any, res: any, func /** * + * @param analyzer + * @param scope * @param node * @param res * @param sourceScopeVal */ -function introduceTaintAtIdentifier(node: any, res: any, sourceScopeVal: any): any { +function introduceTaintAtIdentifier(analyzer: any, scope: any, node: any, res: any, sourceScopeVal: any): any { if (!BasicRuleHandler.getPreprocessReady()) { - return + return res } - if (varUtil.isEmpty(res._tags)) { - // source定义方式,增加文件域和函数域的匹配,主要用于形参场景。identifier的source添加基本都用于插件-->形参场景 - const nodeStart = node.loc?.start?.line - const nodeEnd = node.loc?.end?.line - if (sourceScopeVal && sourceScopeVal.length > 0) { - for (const val of sourceScopeVal) { - const paths = val.path - if (res._sid === paths || res._qid === paths || node.name === paths) { - const valStart = val.locStart - const valEnd = val.locEnd - if (typeof valStart === 'undefined' || typeof valEnd === 'undefined') { + const nodeStart = node.loc?.start?.line + const nodeEnd = node.loc?.end?.line + + const alreadyTainted = res.taint?.hasTags() + let target = res + + if (sourceScopeVal && sourceScopeVal.length > 0) { + for (const val of sourceScopeVal) { + const paths = val.path + if ( + res.sid === paths || + res.qid === paths || + QidUnifyUtil.qidUnifyByRemoveAngleAndPrefix(res.qid) === paths || + node.name === paths + ) { + const valStart = val.locStart + const valEnd = val.locEnd + if (typeof valStart === 'undefined' || typeof valEnd === 'undefined') { + continue + } + let shouldMark = false + if (valStart === 'all' && valEnd === 'all' && val.scopeFile === 'all' && val.scopeFunc === 'all') { + shouldMark = true + } else if (valStart === 'all' && valEnd === 'all' && val.scopeFile !== 'all' && val.scopeFunc === 'all') { + if (typeof node.loc.sourcefile === 'string' && node.loc.sourcefile.includes(val.scopeFile)) { + shouldMark = true + } + } else if (node.loc.sourcefile.includes(val.scopeFile) && nodeStart >= valStart && nodeEnd <= valEnd) { + shouldMark = true + } + + if (shouldMark) { + // 只有全局标识符 source(如 request)才需要拷贝。 + // 路由函数参数等局部 source(locStart/locEnd 为具体行号)不需要拷贝。 + const isGlobalIdentifierSource = valStart === 'all' && valEnd === 'all' + // 局部 source:子值已持有该 kind 的 tag 时跳过,避免 φ 合并后重复标记 + const kinds = Array.isArray(val.kind) ? val.kind : [val.kind] + if (!isGlobalIdentifierSource && kinds.some((k: string) => target.taint?.containsTag(k))) { continue } - if (valStart === 'all' && valEnd === 'all' && val.scopeFile === 'all' && val.scopeFunc === 'all') { - markTaintSource(res, { path: node, kind: val.kind }) - } else if (valStart === 'all' && valEnd === 'all' && val.scopeFile !== 'all' && val.scopeFunc === 'all') { - if (typeof node.loc.sourcefile === 'string') { - if (node.loc.sourcefile.includes(val.scopeFile)) { - markTaintSource(res, { path: node, kind: val.kind }) - } - } - } else if (node.loc.sourcefile.includes(val.scopeFile) && nodeStart >= valStart && nodeEnd <= valEnd) { - markTaintSource(res, { path: node, kind: val.kind }) + if (alreadyTainted && target === res && isGlobalIdentifierSource) { + target = buildNewValueInstance( + analyzer, + res, + node, + scope, + () => false, + () => false, + 1, + { skipTagTraceMap: true } + ) } + markTaintSource(target, { path: node, kind: val.kind }) } } } } - return res + return target } /** @@ -219,34 +273,38 @@ function matchAndMark(paths: any, scp: any, rule: any, mark_cb: any, createIfNot const path = paths.shift() if (path === '*') { - for (const i in scp.field) { - const u = scp.field[i] - matchAndMark(paths, u, rule, mark_cb, createIfNotExists) + if (scp.members) { + for (const i of scp.members.keys()) { + const u = scp.members.get(i) + matchAndMark(paths, u, rule, mark_cb, createIfNotExists) + } } } else if (path === '**') { mark_cb(scp, rule) - for (const i in scp.field) { - const u = scp.field[i] - matchAndMark(['**'], u, rule, mark_cb, createIfNotExists) + if (scp.members) { + for (const i of scp.members.keys()) { + const u = scp.members.get(i) + matchAndMark(['**'], u, rule, mark_cb, createIfNotExists) + } } } else if (path === 'this') { - const val = scp.getThis() + const val = scp.getThisObj() if (!val) return matchAndMark(paths, val, rule, mark_cb, createIfNotExists) } else { const scpBackup = scp - scp = Scope.getDefScope(scp, ValueUtil.SymbolValue({ type: 'Identifier', name: path })) + scp = Scope.getDefScope(scp, new SymbolValue(scp.qid || '', { sid: path, type: 'Identifier', name: path })) if (!scp) { scp = scpBackup } let val = scp?.getFieldValue(path, createIfNotExists) if (!val) { - if (scp._sid !== '') { + if (scp.sid !== '') { while (scp.hasOwnProperty('parent') && scp.parent) { scp = scp.parent } - if (scp?._sid === '') { - scp = scp.moduleManager + if (scp?.sid === '') { + scp = scp.context.modules } // 确保scp的值不是undefined if (scp && typeof scp.getFieldValue === 'function') { @@ -265,18 +323,20 @@ function matchAndMark(paths: any, scp: any, rule: any, mark_cb: any, createIfNot /** * introduce identifier taint globally, no limitation for file and function, usually for benchmark testing + * @param analyzer + * @param scope * @param node * @param res * @param sourceScopeVal */ -function introduceTaintAtIdentifierDirect(node: any, res: any, sourceScopeVal: any): void { +function introduceTaintAtIdentifierDirect(analyzer: any, scope: any, node: any, res: any, sourceScopeVal: any): any { if (!BasicRuleHandler.getPreprocessReady()) { - return + return res } if (sourceScopeVal) { for (const rule of sourceScopeVal) { const paths = rule.path - if (res._sid === paths) { + if (res.sid === paths) { markTaintSource(res, { path: node, kind: rule.kind }) } } @@ -345,7 +405,7 @@ function introduceFuncArgTaintBySelfCollection( rule: any, sourceKind: any ): void { - const parameters = entryPoint.fdef?.parameters + const parameters = entryPoint.ast.fdef?.parameters const interestedParas = getArrayElementsByRule(parameters, rule) interestedParas.forEach((para) => { const argv = analyzer.processInstruction(entryPoint, para, state) @@ -363,4 +423,6 @@ module.exports = { introduceFuncArgTaintBySelfCollection, introduceFuncArgTaintByRuleConfig, setTaint, + getMarkedSourceCount, + resetMarkedSourceCount, } diff --git a/src/checker/taint/go/util.ts b/src/checker/taint/common-kit/taint-entrypoint-util.ts similarity index 75% rename from src/checker/taint/go/util.ts rename to src/checker/taint/common-kit/taint-entrypoint-util.ts index a1c64881..bee036f2 100644 --- a/src/checker/taint/go/util.ts +++ b/src/checker/taint/common-kit/taint-entrypoint-util.ts @@ -1,14 +1,14 @@ import type Unit from '../../../engine/analyzer/common/value/unit' -const IntroduceTaint = require('../common-kit/source-util') -const completeEntryPoint = require('../common-kit/entry-points-util') +const IntroduceTaint = require('./source-util') +const completeEntryPoint = require('./entry-points-util') /** * * @param list */ export function flattenUnionValues(list: Array): Array { - return list.flatMap((unit) => { + return list.filter(Boolean).flatMap((unit) => { switch (unit.vtype) { case 'union': return flattenUnionValues(unit.value) @@ -30,22 +30,24 @@ export function flattenUnionValues(list: Array): Array { * @param processedRouteRegistry * @param entryPointUnitValue * @param source + * @param taintKind */ export function processEntryPointAndTaintSource( analyzer: any, state: any, processedRouteRegistry: Set, entryPointUnitValue: Unit, - source: string + source: string, + taintKind: string ) { flattenUnionValues([entryPointUnitValue]) .filter((val) => val.vtype === 'fclos') .forEach((entryPointFuncValue) => { - if (entryPointFuncValue?.ast.loc) { - const hash = JSON.stringify(entryPointFuncValue.ast.loc) + if (entryPointFuncValue?.ast?.node?.loc) { + const hash = JSON.stringify(entryPointFuncValue.ast.node.loc) if (!processedRouteRegistry.has(hash)) { processedRouteRegistry.add(hash) - IntroduceTaint.introduceFuncArgTaintBySelfCollection(entryPointFuncValue, state, analyzer, source, 'GO_INPUT') + IntroduceTaint.introduceFuncArgTaintBySelfCollection(entryPointFuncValue, state, analyzer, source, taintKind) const entryPoint = completeEntryPoint(entryPointFuncValue) analyzer.entryPoints.push(entryPoint) } diff --git a/src/checker/taint/common-kit/taint-finding-util.ts b/src/checker/taint/common-kit/taint-finding-util.ts index 90a14cfa..dfde9109 100644 --- a/src/checker/taint/common-kit/taint-finding-util.ts +++ b/src/checker/taint/common-kit/taint-finding-util.ts @@ -9,6 +9,7 @@ const Statistics = require('../../../util/statistics').default const { shortenSourceFile } = require('../../../util/finding-util') const Config = require('../../../config') const logger = require('../../../util/logger')(__filename) +const { getOutputTrace } = require('./taint-trace-output') /** * output taint flow result to console @@ -111,21 +112,22 @@ function formatTaintFinding(finding: TaintFinding): Record { // the line of the issue if (finding.node) { const { loc } = finding.node - const line_str = loc.start.line == loc.end.line ? loc.start.line : `[${loc.start.line}, ${loc.end.line}]` + const line_str = loc.start?.line == loc.end?.line ? loc.start?.line : `[${loc.start?.line}, ${loc.end?.line}]` let code = AstUtil.prettyPrint(finding.node) if (code.startsWith('{\n "type')) // non-pretty-printed ast - code = SourceLine.formatTraces([{ file: finding.sourcefile, line: loc.start.line }]) + code = SourceLine.formatTraces([{ file: finding.sourcefile, line: loc.start?.line }]) res.line = `Line ${line_str}: ${code}` } else { logger.warn('finding.node is null') } // the trace of the origin of the issue - if (finding.trace) { - for (const item of finding.trace) { + const outputTrace = getOutputTrace(finding) + if (outputTrace) { + for (const item of outputTrace) { if (item.file) item.shortfile = shortenSourceFile(item.file) } - const trace = SourceLine.formatTraces(finding.trace) + const trace = SourceLine.formatTraces(outputTrace) res.trace = trace } // the trace of an example attack diff --git a/src/checker/taint/common-kit/taint-trace-output.ts b/src/checker/taint/common-kit/taint-trace-output.ts new file mode 100644 index 00000000..0d6a3ab2 --- /dev/null +++ b/src/checker/taint/common-kit/taint-trace-output.ts @@ -0,0 +1,63 @@ +import type { TaintFinding } from '../../../engine/analyzer/common/common-types' + +const Config = require('../../../config') +function normalizeTraceStrategy(strategy: string | undefined): string { + if (strategy === 'folded') return 'callstack-only' + return strategy || 'callstack-only' +} + +function isLineInScope(line: any, scope: { startLine: number; endLine: number }): boolean { + if (Array.isArray(line)) { + return line.some( + (singleLine) => typeof singleLine === 'number' && singleLine >= scope.startLine && singleLine <= scope.endLine + ) + } + return typeof line === 'number' && line >= scope.startLine && line <= scope.endLine +} + +function getOutputTrace(finding: TaintFinding): any[] | undefined { + const strategy = normalizeTraceStrategy(Config.taintTraceOutputStrategy) + const rawTrace = finding.trace + if (!Array.isArray(rawTrace)) return rawTrace + if (strategy !== 'callstack-only') return rawTrace + if (rawTrace.length === 0) return rawTrace + + const scopes: Array<{ file: string; startLine: number; endLine: number }> = [] + + if (Array.isArray(finding.callstack)) { + for (const fclos of finding.callstack) { + const loc = fclos?.ast?.node?.loc + if (loc?.sourcefile && loc.start?.line != null && loc.end?.line != null) { + scopes.push({ + file: loc.sourcefile, + startLine: loc.start.line, + endLine: loc.end.line, + }) + } + } + } + + const entryLoc = finding.entrypointLoc + if (entryLoc?.sourcefile && entryLoc.start?.line != null && entryLoc.end?.line != null) { + scopes.push({ + file: entryLoc.sourcefile, + startLine: entryLoc.start.line, + endLine: entryLoc.end.line, + }) + } + + if (scopes.length === 0) return rawTrace + + const filtered = rawTrace.filter((step: any) => { + if (step?.tag === 'SOURCE: ' || step?.tag === 'SINK: ') return true + const stepFile = step?.loc?.sourcefile || step?.file + const stepLine = step?.loc?.start?.line ?? step?.line + return scopes.some( + (scope) => stepFile === scope.file && isLineInScope(stepLine, scope) + ) + }) + + return filtered.length > 0 ? filtered : rawTrace +} + +export { getOutputTrace } diff --git a/src/checker/taint/go/beego-entrypoint-collect-checker.ts b/src/checker/taint/go/beego-entrypoint-collect-checker.ts index 6e97f315..1ea87a7e 100644 --- a/src/checker/taint/go/beego-entrypoint-collect-checker.ts +++ b/src/checker/taint/go/beego-entrypoint-collect-checker.ts @@ -1,5 +1,6 @@ import type Unit from '../../../engine/analyzer/common/value/unit' -import { flattenUnionValues, processEntryPointAndTaintSource } from './util' +import { getLegacyArgValues } from '../../../engine/analyzer/common/call-args' +import { flattenUnionValues, processEntryPointAndTaintSource } from '../common-kit/taint-entrypoint-util' const config = require('../../../config') @@ -46,33 +47,32 @@ class BeegoEntrypointCollectChecker extends Checker { * @param node * @param state * @param info - * @param info.fclos - * @param info.argvalues */ triggerAtFunctionCallBefore(analyzer: any, scope: any, node: any, state: any, info: any) { - const { fclos, argvalues } = info + const { fclos, callInfo } = info + const argvalues = getLegacyArgValues(callInfo) if (config.entryPointMode === 'ONLY_CUSTOM') return if (fclos.vtype === 'symbol') { if (fclos.type === 'Identifier') { - if (fclos._qid.startsWith('github.com/beego/beego/v2/server/web/filter/apiauth.APISecretAuth')) { - processEntryPointAndTaintSource(analyzer, state, processedRouteRegistry, argvalues[0], '0') - } else if (fclos._qid.startsWith('github.com/beego/beego/v2/server/web/filter/auth.NewBasicAuthenticator')) { - processEntryPointAndTaintSource(analyzer, state, processedRouteRegistry, argvalues[0], '0, 1') - } else if (fclos._qid.startsWith('github.com/beego/beego/v2/server/web')) { + if (fclos._qid.includes('github.com/beego/beego/v2/server/web/filter/apiauth.APISecretAuth')) { + processEntryPointAndTaintSource(analyzer, state, processedRouteRegistry, argvalues[0], '0', 'GO_INPUT') + } else if (fclos._qid.includes('github.com/beego/beego/v2/server/web/filter/auth.NewBasicAuthenticator')) { + processEntryPointAndTaintSource(analyzer, state, processedRouteRegistry, argvalues[0], '0, 1', 'GO_INPUT') + } else if (fclos._qid.includes('github.com/beego/beego/v2/server/web')) { this.handleHttpServerMethod(analyzer, scope, state, fclos.name, argvalues) } } else if (fclos.type === 'MemberAccess') { if (controllerQids.has(fclos.object._qid) && fclos.property.name === 'Mapping') { const controllerMethodVal = argvalues[1] - if (controllerMethodVal?.ast.loc) { - const hash = JSON.stringify(controllerMethodVal.ast.loc) + if (controllerMethodVal?.ast?.node?.loc) { + const hash = JSON.stringify(controllerMethodVal.ast.node.loc) if (!processedRouteRegistry.has(hash)) { processedRouteRegistry.add(hash) const entryPoint = completeEntryPoint(controllerMethodVal) analyzer.entryPoints.push(entryPoint) } } - } else if (fclos._qid.startsWith('github.com/beego/beego/v2/server/web.NewNamespace')) { + } else if (fclos._qid.includes('github.com/beego/beego/v2/server/web.NewNamespace')) { this.handleNamespaceMethod(analyzer, scope, state, fclos.property.name, argvalues) } } @@ -88,7 +88,8 @@ class BeegoEntrypointCollectChecker extends Checker { * @param info */ triggerAtFunctionCallAfter(analyzer: any, scope: any, node: any, state: any, info: any) { - const { fclos, argvalues, ret } = info + const { fclos, ret, callInfo } = info + const argvalues = getLegacyArgValues(callInfo) if (config.entryPointMode === 'ONLY_CUSTOM') return if (fclos.vtype === 'symbol' && fclos.type === 'MemberAccess') { if (controllerQids.has(fclos.object._qid)) { @@ -138,10 +139,10 @@ class BeegoEntrypointCollectChecker extends Checker { const { rvalue } = info const { left } = node if ( - analyzer.processInstruction(scope, left.object, state)?._qid === 'github.com/beego/beego/v2/server/web.BConfig' && + analyzer.processInstruction(scope, left.object, state)?._qid?.includes('github.com/beego/beego/v2/server/web.BConfig') && left.property?.name === 'RecoverFunc' ) { - processEntryPointAndTaintSource(analyzer, state, processedRouteRegistry, rvalue, '0') + processEntryPointAndTaintSource(analyzer, state, processedRouteRegistry, rvalue, '0', 'GO_INPUT') } } @@ -166,8 +167,10 @@ class BeegoEntrypointCollectChecker extends Checker { isControllerMethod(name: string, value: any): boolean { if (!name[0] || name[0] < 'A' || name[0] > 'Z') return false if (!value || value.vtype !== 'fclos') return false - if (value.fdef.returnType.type !== 'VoidType') return false - return value.fdef.parameters.length === 0 + const fdef = value.ast?.fdef || value.ast?.node + if (!fdef) return false + if (fdef.returnType?.type !== 'VoidType') return false + return fdef.parameters?.length === 0 } /** @@ -183,38 +186,39 @@ class BeegoEntrypointCollectChecker extends Checker { switch (name) { case 'AutoRouter': case 'NSAutoRouter': - this.handleAutoControllerArgVal(analyzer, argvalues[0]) + if (argvalues[0]) this.handleAutoControllerArgVal(analyzer, argvalues[0]) break case 'AutoPrefix': case 'NSAutoPrefix': - this.handleAutoControllerArgVal(analyzer, argvalues[1]) + if (argvalues[1]) this.handleAutoControllerArgVal(analyzer, argvalues[1]) break case 'InsertFilter': - processEntryPointAndTaintSource(analyzer, state, processedRouteRegistry, argvalues[2], '0') + processEntryPointAndTaintSource(analyzer, state, processedRouteRegistry, argvalues[2], '0', 'GO_INPUT') break case 'InsertFilterChain': flattenUnionValues([argvalues[1]]) .filter((unit) => unit.vtype === 'fclos') .forEach((fclos) => { - const retVal = analyzer.processAndCallFuncDef(scope, (fclos as any).fdef, fclos, state) - processEntryPointAndTaintSource(analyzer, state, processedRouteRegistry, retVal, '0') + const fdef = (fclos as any).ast?.fdef || (fclos as any).ast?.node + const retVal = analyzer.processAndCallFuncDef(scope, fdef, fclos, state) + processEntryPointAndTaintSource(analyzer, state, processedRouteRegistry, retVal, '0', 'GO_INPUT') }) break case 'Handler': flattenUnionValues([argvalues[1]]).forEach((handlerVal) => { - const serveHttp = handlerVal.field?.ServeHTTP + const serveHttp = handlerVal.value?.ServeHTTP if (serveHttp) { - processEntryPointAndTaintSource(analyzer, state, processedRouteRegistry, serveHttp, '1') + processEntryPointAndTaintSource(analyzer, state, processedRouteRegistry, serveHttp, '1', 'GO_INPUT') } }) break case 'Include': case 'NSInclude': flattenUnionValues(argvalues).forEach((mappingController) => { - const urlMapping = mappingController.field?.URLMapping + const urlMapping = mappingController.value?.URLMapping if (urlMapping) { controllerQids.add(mappingController._qid) - analyzer.processAndCallFuncDef(scope, urlMapping.fdef, urlMapping, state) + analyzer.processAndCallFuncDef(scope, urlMapping.ast?.fdef || urlMapping.ast?.node, urlMapping, state) } }) break @@ -237,20 +241,22 @@ class BeegoEntrypointCollectChecker extends Checker { flattenUnionValues([argvalues[1]]) .filter((unit) => unit.vtype === 'fclos') .forEach((unboundMethodVal: any) => { + const thisVal = unboundMethodVal._this const instance = analyzer.buildNewObject( - unboundMethodVal.__this.cdef, + thisVal?.cdef || thisVal?.ast?.cdef, [], - unboundMethodVal.__this, + thisVal, state, null, scope ) - const boundMethodVal = instance.field?.[unboundMethodVal.fdef.id.name] - if (boundMethodVal?.ast.loc) { - const hash = JSON.stringify(boundMethodVal.ast.loc) + const fdef = unboundMethodVal.ast?.fdef || unboundMethodVal.ast?.node + const boundMethodVal = instance.value?.[fdef?.id?.name] + if (boundMethodVal?.ast?.node?.loc) { + const hash = JSON.stringify(boundMethodVal.ast.node.loc) if (!processedRouteRegistry.has(hash)) { processedRouteRegistry.add(hash) - controllerQids.add(boundMethodVal.__this._qid) + controllerQids.add(boundMethodVal._this?._qid) const entryPoint = completeEntryPoint(boundMethodVal) analyzer.entryPoints.push(entryPoint) } @@ -264,12 +270,12 @@ class BeegoEntrypointCollectChecker extends Checker { .forEach((stringVal) => { const methodName = stringVal.value.slice(1, -1).split(':')[1] flattenUnionValues([argvalues[1]]).forEach((controllerVal) => { - const controllerMethodVal = controllerVal.field?.[methodName] - if (controllerMethodVal?.ast.loc) { - const hash = JSON.stringify(controllerMethodVal.ast.loc) + const controllerMethodVal = controllerVal.value?.[methodName] + if (controllerMethodVal?.ast?.node?.loc) { + const hash = JSON.stringify(controllerMethodVal.ast.node.loc) if (!processedRouteRegistry.has(hash)) { processedRouteRegistry.add(hash) - controllerQids.add(controllerMethodVal.__this._qid) + if (controllerMethodVal._this?._qid) controllerQids.add(controllerMethodVal._this._qid) const entryPoint = completeEntryPoint(controllerMethodVal) analyzer.entryPoints.push(entryPoint) } @@ -293,14 +299,14 @@ class BeegoEntrypointCollectChecker extends Checker { case 'NSOptions': case 'NSPatch': case 'NSPut': - processEntryPointAndTaintSource(analyzer, state, processedRouteRegistry, argvalues[1], '0') + processEntryPointAndTaintSource(analyzer, state, processedRouteRegistry, argvalues[1], '0', 'GO_INPUT') break case 'NSCond': - processEntryPointAndTaintSource(analyzer, state, processedRouteRegistry, argvalues[0], '0') + processEntryPointAndTaintSource(analyzer, state, processedRouteRegistry, argvalues[0], '0', 'GO_INPUT') break case 'NSBefore': case 'NSAfter': - argvalues.forEach((val) => processEntryPointAndTaintSource(analyzer, state, processedRouteRegistry, val, '0')) + argvalues.forEach((val) => processEntryPointAndTaintSource(analyzer, state, processedRouteRegistry, val, '0', 'GO_INPUT')) break case 'ErrorController': this.handleErrorControllerArgVal(analyzer, argvalues[0]) @@ -323,10 +329,10 @@ class BeegoEntrypointCollectChecker extends Checker { case 'Filter': argvalues .slice(1) - .forEach((val) => processEntryPointAndTaintSource(analyzer, state, processedRouteRegistry, val, '0')) + .forEach((val) => processEntryPointAndTaintSource(analyzer, state, processedRouteRegistry, val, '0', 'GO_INPUT')) break case 'Cond': - processEntryPointAndTaintSource(analyzer, state, processedRouteRegistry, argvalues[0], '0') + processEntryPointAndTaintSource(analyzer, state, processedRouteRegistry, argvalues[0], '0', 'GO_INPUT') break default: break @@ -340,15 +346,15 @@ class BeegoEntrypointCollectChecker extends Checker { */ handleErrorControllerArgVal(analyzer: any, controllerArgVal: Unit) { flattenUnionValues([controllerArgVal]) - .flatMap((v) => Object.entries(v.field)) + .flatMap((v) => Object.entries(v.value)) .filter(([fieldName, fieldVal]) => this.isControllerMethod(fieldName, fieldVal) && fieldName.startsWith('Error')) .map(([, controllerMethodVal]) => controllerMethodVal as Unit) .forEach((controllerMethodVal) => { - if (controllerMethodVal?.ast.loc) { - const hash = JSON.stringify(controllerMethodVal.ast.loc) + if (controllerMethodVal?.ast?.node?.loc) { + const hash = JSON.stringify(controllerMethodVal.ast.node.loc) if (!processedRouteRegistry.has(hash)) { processedRouteRegistry.add(hash) - controllerQids.add(controllerMethodVal.__this._qid) + if (controllerMethodVal._this?._qid) controllerQids.add(controllerMethodVal._this._qid) const entryPoint = completeEntryPoint(controllerMethodVal) analyzer.entryPoints.push(entryPoint) } @@ -363,15 +369,15 @@ class BeegoEntrypointCollectChecker extends Checker { */ handleAutoControllerArgVal(analyzer: any, controllerArgVal: Unit) { flattenUnionValues([controllerArgVal]) - .flatMap((v) => Object.entries(v.field)) + .flatMap((v) => Object.entries(v.value)) .filter(([fieldName, fieldVal]) => this.isControllerMethod(fieldName, fieldVal)) .map(([, controllerMethodVal]) => controllerMethodVal as Unit) .forEach((controllerMethodVal) => { - if (controllerMethodVal?.ast.loc) { - const hash = JSON.stringify(controllerMethodVal.ast.loc) + if (controllerMethodVal?.ast?.node?.loc) { + const hash = JSON.stringify(controllerMethodVal.ast.node.loc) if (!processedRouteRegistry.has(hash)) { processedRouteRegistry.add(hash) - controllerQids.add(controllerMethodVal.__this._qid) + if (controllerMethodVal._this?._qid) controllerQids.add(controllerMethodVal._this._qid) const entryPoint = completeEntryPoint(controllerMethodVal) analyzer.entryPoints.push(entryPoint) } diff --git a/src/checker/taint/go/cobra-command-checker.ts b/src/checker/taint/go/cobra-command-checker.ts index 996dbaea..4342ae51 100644 --- a/src/checker/taint/go/cobra-command-checker.ts +++ b/src/checker/taint/go/cobra-command-checker.ts @@ -2,11 +2,11 @@ import type { EntryPoint } from '../../../engine/analyzer/common/entrypoint' const _ = require('lodash') const completeEntryPoint = require('../common-kit/entry-points-util') -const configCobra = require('../../../config') -const CheckerCobra = require('../../common/checker') +const config = require('../../../config') +const Checker = require('../../common/checker') const processedBuiltInRegistry = new Set() -const cobraCommandQid = 'github.com/spf13/cobra.Command' +const cobraCommandQid = /github\.com\/spf13\/cobra\.Command/ const preAction: string[] = ['PreRun', 'PreRunE'] const postAction: string[] = ['RunE', 'Run'] @@ -14,7 +14,7 @@ const postAction: string[] = ['RunE', 'Run'] * cobra.Command bulitIn checker * 为第三方库方法cobra.command做建模,添加entryPoints */ -class cobraCommandChecker extends CheckerCobra { +class cobraCommandChecker extends Checker { /** * constructor * @param resultManager @@ -34,9 +34,9 @@ class cobraCommandChecker extends CheckerCobra { * @param fClos */ ifIgnoreEntryPoint(fClos: any): boolean { - if (!fClos.fdef?.loc) return true + if (!fClos.ast.fdef?.loc) return true // todo:this.func{call this.f1()},this.f1依赖于this的符号值,但注册this.func时,目前的hash无法反映不同this符号值的区别,如alarm_center/pkg/app/app.go的#173行 - const hash = JSON.stringify(fClos.fdef.loc) + const hash = JSON.stringify(fClos.ast.fdef.loc) if (processedBuiltInRegistry.has(hash)) return true processedBuiltInRegistry.add(hash) return false @@ -52,9 +52,9 @@ class cobraCommandChecker extends CheckerCobra { */ triggerAtVariableDeclaration(analyzer: any, scope: any, node: any, state: any, info: any): void { const { initVal } = info - if (configCobra.entryPointMode === 'ONLY_CUSTOM') return - if (initVal?._qid !== cobraCommandQid || _.isEmpty(initVal.field)) return - const initField = initVal.field + if (config.entryPointMode === 'ONLY_CUSTOM') return + if (!cobraCommandQid.test(initVal?.qid) || !initVal.members || initVal.members.size === 0) return + const initField = initVal.value const preEntryPoints: EntryPoint[] = [] const postEntryPoints: EntryPoint[] = [] @@ -64,7 +64,7 @@ class cobraCommandChecker extends CheckerCobra { if (initField.hasOwnProperty(action) && initField[action]?.vtype === 'fclos') { const ep = initField[action] if (this.ifIgnoreEntryPoint(ep)) return - targetEntryPoints.push(completeEntryPoint(ep)) + targetEntryPoints.push(completeEntryPoint(ep, true)) } }) } @@ -83,11 +83,19 @@ class cobraCommandChecker extends CheckerCobra { */ triggerAtAssignment(analyzer: any, scope: any, node: any, state: any, info: any): void { const { lvalue, rvalue } = info - if (configCobra.entryPointMode === 'ONLY_CUSTOM') return // 不路由自采集 - if (!lvalue?._qid || rvalue?.vtype !== 'fclos') return - if (!lvalue._qid.startsWith(cobraCommandQid) || ![...preAction, ...postAction].includes(lvalue._sid)) return - if (this.ifIgnoreEntryPoint(rvalue)) return - analyzer.entryPoints.push(completeEntryPoint(rvalue)) + if (config.entryPointMode === 'ONLY_CUSTOM') { + return // 不路由自采集 + } + if (!lvalue?.qid || rvalue?.vtype !== 'fclos') { + return + } + if (!cobraCommandQid.test(lvalue.qid) || ![...preAction, ...postAction].includes(lvalue.sid)) { + return + } + if (this.ifIgnoreEntryPoint(rvalue)) { + return + } + analyzer.entryPoints.push(completeEntryPoint(rvalue, true)) } /** diff --git a/src/checker/taint/go/echo-entrypoint-collect-checker.ts b/src/checker/taint/go/echo-entrypoint-collect-checker.ts deleted file mode 100644 index 042bd93c..00000000 --- a/src/checker/taint/go/echo-entrypoint-collect-checker.ts +++ /dev/null @@ -1,439 +0,0 @@ -import type Unit from '../../../engine/analyzer/common/value/unit' -import { flattenUnionValues, processEntryPointAndTaintSource } from './util' - -const config = require('../../../config') -const GoAnalyzer = require('../../../engine/analyzer/golang/common/go-analyzer') - -const KnownPackageName = { - 'github.com/labstack/echo/v4': 'echo', - 'github.com/labstack/echo-jwt/v4': 'echojwt', -} - -const RouteRegistryObject = ['github.com/labstack/echo/v4.New()'] - -const MiddlewareHandlerRegistryObject = [ - 'github.com/labstack/echo/v4/middleware', - 'github.com/labstack/echo-contrib/casbin', - 'github.com/labstack/echo-jwt/v4', - 'github.com/labstack/echo-contrib/echoprometheus', - 'github.com/labstack/echo-contrib/session', -] - -const ConfigObjectCollectionTable = new Map>([ - [ - 'BasicAuthWithConfig', - [ - { name: 'Skipper', source: '0' }, - { name: 'Validator', source: '0, 1, 2' }, - ], - ], - [ - 'BodyDumpWithConfig', - [ - { name: 'Skipper', source: '0' }, - { name: 'Handler', source: '0, 1, 2' }, - ], - ], - ['BodyLimitWithConfig', [{ name: 'Skipper', source: '0' }]], - [ - 'MiddlewareWithConfig', - [ - { name: 'Skipper', source: '0' }, - { name: 'EnforceHandler', source: '0, 1' }, - { name: 'UserGetter', source: '0' }, - { name: 'ErrorHandler', source: '0, 1' }, - ], - ], - [ - 'ContextTimeoutWithConfig', - [ - { name: 'Skipper', source: '0' }, - { name: 'ErrorHandler', source: '0, 1' }, - ], - ], - [ - 'CORSWithConfig', - [ - { name: 'Skipper', source: '0' }, - { name: 'AllowOriginFunc', source: '0' }, - ], - ], - [ - 'CSRFWithConfig', - [ - { name: 'Skipper', source: '0' }, - { name: 'ErrorHandler', source: '0, 1' }, - ], - ], - ['DecompressWithConfig', [{ name: 'Skipper', source: '0' }]], - ['GzipWithConfig', [{ name: 'Skipper', source: '0' }]], - [ - 'WithConfig', - [ - { name: 'Skipper', source: '0' }, - { name: 'BeforeFunc', source: '0' }, - { name: 'SuccessHandler', source: '0' }, - { name: 'ErrorHandler', source: '0, 1' }, - { name: 'KeyFunc', source: '0' }, - { name: 'ParseTokenFunc', source: '0' }, - { name: 'NewClaimsFunc', source: '0' }, - ], - ], - [ - 'KeyAuthWithConfig', - [ - { name: 'Skipper', source: '0' }, - { name: 'Validator', source: '0, 1' }, - { name: 'ErrorHandler', source: '0, 1' }, - ], - ], - [ - 'LoggerWithConfig', - [ - { name: 'Skipper', source: '0' }, - { name: 'CustomTagFunc', source: '0' }, - ], - ], - [ - 'RequestLoggerWithConfig', - [ - { name: 'Skipper', source: '0' }, - { name: 'BeforeNextFunc', source: '0' }, - { name: 'LogValuesFunc', source: '0, 1' }, - ], - ], - [ - 'MethodOverrideWithConfig', - [ - { name: 'Skipper', source: '0' }, - { name: 'Getter', source: '0' }, - ], - ], - [ - 'NewMiddlewareWithConfig', - [ - { name: 'Skipper', source: '0' }, - { name: 'BeforeNext', source: '0' }, - { name: 'AfterNext', source: '0, 1' }, - { name: 'StatusCodeResolver', source: '0, 1' }, - ], - ], - ['Proxy', [{ name: 'Next', source: '0' }]], - [ - 'ProxyWithConfig', - [ - { name: 'Skipper', source: '0' }, - { name: 'RetryFilter', source: '0, 1' }, - { name: 'ErrorHandler', source: '0, 1' }, - { name: 'ModifyResponse', source: '0' }, - ], - ], - ['RateLimiter', [{ name: 'Allow', source: '0' }]], - [ - 'RateLimiterWithConfig', - [ - { name: 'Skipper', source: '0' }, - { name: 'BeforeFunc', source: '0' }, - { name: 'IdentifierExtractor', source: '0' }, - { name: 'ErrorHandler', source: '0, 1' }, - { name: 'DenyHandler', source: '0, 1, 2' }, - ], - ], - [ - 'RecoverWithConfig', - [ - { name: 'Skipper', source: '0' }, - { name: 'LogErrorFunc', source: '0, 1' }, - ], - ], - ['HTTPSRedirectWithConfig', [{ name: 'Skipper', source: '0' }]], - [ - 'RequestIDWithConfig', - [ - { name: 'Skipper', source: '0' }, - { name: 'RequestIDHandler', source: '0, 1' }, - ], - ], - ['RewriteWithConfig', [{ name: 'Skipper', source: '0' }]], - ['SecureWithConfig', [{ name: 'Skipper', source: '0' }]], - [ - 'Middleware', - [ - { name: 'Get', source: '0' }, - { name: 'New', source: '0' }, - { name: 'Save', source: '0' }, - ], - ], - ['StaticWithConfig', [{ name: 'Skipper', source: '0' }]], - ['AddTrailingSlashWithConfig', [{ name: 'Skipper', source: '0' }]], - ['RemoveTrailingSlashWithConfig', [{ name: 'Skipper', source: '0' }]], -]) - -const Checker = require('../../common/checker') - -const processedRouteRegistry = new Set() - -/** - * - */ -class EchoEntrypointCollectChecker extends Checker { - /** - * - * @param resultManager - */ - constructor(resultManager: any) { - super(resultManager, 'echo-entrypoint-collect-checker') - GoAnalyzer.registerKnownPackageNames(KnownPackageName) - } - - /** - * - * @param analyzer - * @param scope - * @param node - * @param state - * @param info - */ - triggerAtFunctionCallBefore(analyzer: any, scope: any, node: any, state: any, info: any) { - const { fclos, argvalues } = info - if (config.entryPointMode === 'ONLY_CUSTOM') return - if (!(fclos && fclos.object && fclos.property)) return - const { object, property } = fclos - if (!object._qid || !property.name) return - if (!RouteRegistryObject.some((obj) => object._qid.includes(obj))) return - switch (property.name) { - case 'Use': - case 'Pre': - this.handleMiddlewareArgs(analyzer, scope, state, argvalues) - break - case 'CONNECT': - case 'DELETE': - case 'GET': - case 'HEAD': - case 'OPTIONS': - case 'PATCH': - case 'POST': - case 'PUT': - case 'TRACE': - case 'RouteNotFound': - case 'Any': - processEntryPointAndTaintSource(analyzer, state, processedRouteRegistry, argvalues[1], '0') - this.handleMiddlewareArgs(analyzer, scope, state, argvalues.slice(2)) - break - case 'Match': - case 'Add': - processEntryPointAndTaintSource(analyzer, state, processedRouteRegistry, argvalues[2], '0') - this.handleMiddlewareArgs(analyzer, scope, state, argvalues.slice(3)) - break - case 'File': - this.handleMiddlewareArgs(analyzer, scope, state, argvalues.slice(2)) - break - case 'FileFS': - flattenUnionValues([argvalues[2]]).forEach((fs) => { - processEntryPointAndTaintSource(analyzer, state, processedRouteRegistry, fs.field.Open, '0') - }) - this.handleMiddlewareArgs(analyzer, scope, state, argvalues.slice(3)) - break - case 'Host': - case 'Group': - this.handleMiddlewareArgs(analyzer, scope, state, argvalues.slice(1)) - break - default: - break - } - } - - /** - * - * @param analyzer - * @param scope - * @param node - * @param state - * @param info - */ - triggerAtSymbolInterpretOfEntryPointAfter(analyzer: any, scope: any, node: any, state: any, info: any) { - if (info?.entryPoint.functionName === 'main') processedRouteRegistry.clear() - } - - /** - * - * @param analyzer - * @param scope - * @param node - * @param state - * @param info - */ - triggerAtAssignment(analyzer: any, scope: any, node: any, state: any, info: any) { - if (config.entryPointMode === 'ONLY_CUSTOM') return - const { lvalue, rvalue } = info - if (!(lvalue.object && lvalue.property)) return - const { object, property } = lvalue - if (!object._qid || !property.name) return - if (!RouteRegistryObject.some((obj) => object._qid.includes(obj))) return - const rvalueObjs = flattenUnionValues([rvalue]) - switch (property.name) { - case 'HTTPErrorHandler': - rvalueObjs.forEach((obj) => - processEntryPointAndTaintSource(analyzer, state, processedRouteRegistry, obj, '0, 1') - ) - break - case 'Binder': - rvalueObjs.forEach((obj) => - processEntryPointAndTaintSource(analyzer, state, processedRouteRegistry, obj.field.Bind, '1') - ) - break - case 'Renderer': - rvalueObjs.forEach((obj) => - processEntryPointAndTaintSource(analyzer, state, processedRouteRegistry, obj.field.Render, '3') - ) - break - case 'Filesystem': - rvalueObjs.forEach((obj) => - processEntryPointAndTaintSource(analyzer, state, processedRouteRegistry, obj.field.Open, '0') - ) - break - default: - break - } - } - - /** - * - * @param analyzer - * @param state - * @param symbol - */ - handleConfigObjectCollection(analyzer: any, state: any, symbol: any) { - const rules = ConfigObjectCollectionTable.get(symbol.expression?.name) - if (!rules) return - flattenUnionValues([symbol.arguments[0]]).forEach((middlewareConfig) => { - rules.forEach((rule) => { - const fieldValue = middlewareConfig.field[rule.name] - if (!fieldValue) return - processEntryPointAndTaintSource(analyzer, state, processedRouteRegistry, fieldValue, rule.source) - }) - }) - } - - /** - * - * @param analyzer - * @param state - * @param symbol - */ - handleKnownEchoMiddlewares(analyzer: any, state: any, symbol: any) { - if (symbol.type !== 'CallExpression') return - const objectQid = symbol.expression?._qid - if (!(objectQid && MiddlewareHandlerRegistryObject.some((obj) => objectQid.startsWith(obj)))) return - - switch (symbol.expression.name) { - case 'BasicAuth': - processEntryPointAndTaintSource(analyzer, state, processedRouteRegistry, symbol.arguments[0], '0, 1, 2') - break - case 'BodyDump': - processEntryPointAndTaintSource(analyzer, state, processedRouteRegistry, symbol.arguments[0], '0, 1, 2') - break - case 'KeyAuth': - processEntryPointAndTaintSource(analyzer, state, processedRouteRegistry, symbol.arguments[0], '0, 1') - break - case 'WithConfig': - flattenUnionValues([symbol.arguments[0]]).forEach((middlewareConfig) => { - const tokenLookupFuncs = middlewareConfig.field.TokenLookupFuncs - if (!tokenLookupFuncs) return - Object.values(tokenLookupFuncs.value).forEach((v) => { - processEntryPointAndTaintSource(analyzer, state, processedRouteRegistry, v as Unit, '0') - }) - }) - this.handleConfigObjectCollection(analyzer, state, symbol) - break - case 'NewMiddlewareWithConfig': - flattenUnionValues([symbol.arguments[0]]).forEach((middlewareConfig) => { - const labelFuncs = middlewareConfig.field.LabelFuncs - if (!labelFuncs) return - Object.values(labelFuncs.value).forEach((v) => { - processEntryPointAndTaintSource(analyzer, state, processedRouteRegistry, v as Unit, '0, 1') - }) - }) - this.handleConfigObjectCollection(analyzer, state, symbol) - break - case 'ProxyWithConfig': - flattenUnionValues([symbol.arguments[0]]).forEach((middlewareConfig) => { - const balancerNext = middlewareConfig.field?.Balancer?.field?.Next - if (balancerNext) { - processEntryPointAndTaintSource(analyzer, state, processedRouteRegistry, balancerNext, '0') - } - const transportRoundTrip = middlewareConfig.field?.Transport?.field?.RoundTrip - if (transportRoundTrip) { - processEntryPointAndTaintSource(analyzer, state, processedRouteRegistry, transportRoundTrip, '0') - } - }) - this.handleConfigObjectCollection(analyzer, state, symbol) - break - case 'RateLimiterWithConfig': - flattenUnionValues([symbol.arguments[0]]).forEach((middlewareConfig) => { - const allow = middlewareConfig.field?.Store?.field?.Allow - if (allow) { - processEntryPointAndTaintSource(analyzer, state, processedRouteRegistry, allow, '0') - } - }) - this.handleConfigObjectCollection(analyzer, state, symbol) - break - case 'MiddlewareWithConfig': - flattenUnionValues([symbol.arguments[0]]).forEach((middlewareConfig) => { - const store = middlewareConfig.field.Store - if (!store) return - ;[store.field.Get, store.field.New, store.field.Save] - .filter((v) => v) - .forEach((v) => { - processEntryPointAndTaintSource(analyzer, state, processedRouteRegistry, v, '0') - }) - }) - this.handleConfigObjectCollection(analyzer, state, symbol) - break - case 'StaticWithConfig': - flattenUnionValues([symbol.arguments[0]]).forEach((middlewareConfig) => { - const open = middlewareConfig.field?.Filesystem?.field?.Open - if (open) { - processEntryPointAndTaintSource(analyzer, state, processedRouteRegistry, open, '0') - } - }) - this.handleConfigObjectCollection(analyzer, state, symbol) - break - default: - this.handleConfigObjectCollection(analyzer, state, symbol) - break - } - } - - /** - * - * @param analyzer - * @param scope - * @param state - * @param middlewareFunctionValue - */ - handleCustomMiddleware(analyzer: any, scope: any, state: any, middlewareFunctionValue: any) { - const retVal = analyzer.processAndCallFuncDef(scope, middlewareFunctionValue.fdef, middlewareFunctionValue, state) - processEntryPointAndTaintSource(analyzer, state, processedRouteRegistry, retVal, '0') - } - - /** - * - * @param analyzer - * @param scope - * @param state - * @param list - */ - handleMiddlewareArgs(analyzer: any, scope: any, state: any, list: Array) { - const flattened = flattenUnionValues(list) - flattened.forEach((unit) => { - if (unit.vtype === 'symbol') { - this.handleKnownEchoMiddlewares(analyzer, state, unit) - } else if (unit.vtype === 'fclos') { - this.handleCustomMiddleware(analyzer, scope, state, unit) - } - }) - } -} - -module.exports = EchoEntrypointCollectChecker diff --git a/src/checker/taint/go/gRpc-entrypoint-collect-checker.ts b/src/checker/taint/go/gRpc-entrypoint-collect-checker.ts index d42024a1..a7fbcd0d 100644 --- a/src/checker/taint/go/gRpc-entrypoint-collect-checker.ts +++ b/src/checker/taint/go/gRpc-entrypoint-collect-checker.ts @@ -1,4 +1,5 @@ import type { EntryPoint } from '../../../engine/analyzer/common/entrypoint' +import { getLegacyArgValues } from '../../../engine/analyzer/common/call-args' const completeEntryPoint = require('../common-kit/entry-points-util') const AstUtil = require('../../../util/ast-util') @@ -68,7 +69,7 @@ class GRpcEntrypointCollectChecker extends Checker { if (match) { const serverName = match[1] const fClos = analyzer.processFunctionDefinition(scope, exp, state) - if (fClos?._qid) registerServerPoints[fClos._qid] = serverName + if (fClos?.qid) registerServerPoints[fClos.qid] = serverName } break @@ -111,11 +112,12 @@ class GRpcEntrypointCollectChecker extends Checker { * @param info */ triggerAtFunctionCallBefore(analyzer: any, scope: any, node: any, state: any, info: any): void { - const { fclos, argvalues } = info + const { fclos, callInfo } = info if (config.entryPointMode === 'ONLY_CUSTOM') return // 不路由自采集 - if (!(fclos._qid in registerServerPoints)) return // 处理Register_xxx_Server函数,即实现类注册点 + if (!(fclos.qid in registerServerPoints)) return // 处理Register_xxx_Server函数,即实现类注册点 + const argvalues = getLegacyArgValues(callInfo) if (!Array.isArray(argvalues) || argvalues.length < 1) return - const serverName = registerServerPoints[fclos._qid] + const serverName = registerServerPoints[fclos.qid] const implServer = argvalues[1] this.searchServiceEntryPoints(serverName, implServer, fclos, state, analyzer) } @@ -135,14 +137,14 @@ class GRpcEntrypointCollectChecker extends Checker { interfaceEntryPoints.forEach((entryPointName: string) => { const ep = AstUtil.satisfy( implServer, - (n: any) => n.vtype === 'fclos' && n?.ast?.id.name === entryPointName, - (node: any, prop: any) => prop === 'field', + (n: any) => n.vtype === 'fclos' && n?.ast?.node?.id.name === entryPointName, + (node: any, prop: any) => prop === '_field', null, false ) if (ep) { - const hash = JSON.stringify(ep.ast.loc) + const hash = JSON.stringify(ep.ast.node.loc) if (!hash || processedRegisterEntryPoints.has(hash)) return processedRegisterEntryPoints.add(hash) this.introduceGrpcTaint(ep, state, analyzer) diff --git a/src/checker/taint/go/gin-default-taint-checker.ts b/src/checker/taint/go/gin-default-taint-checker.ts index 330af726..77149d75 100644 --- a/src/checker/taint/go/gin-default-taint-checker.ts +++ b/src/checker/taint/go/gin-default-taint-checker.ts @@ -1,3 +1,5 @@ +import { getLegacyArgValues, type CallInfo } from '../../../engine/analyzer/common/call-args' + const _ = require('lodash') const BasicRuleHandler = require('../../common/rules-basic-handler') const FileUtil = require('../../../util/file-util') @@ -66,13 +68,13 @@ class GinDefaultTaintChecker extends TaintChecker { * @param topScope */ prepareEntryPoints(analyzer: any, topScope: any) { - const { entrypoints: ruleConfigEntryPoints, sources: ruleConfigSources } = this.checkerRuleConfigContent + const { entrypoints: ruleConfigEntryPoints, sources: ruleConfigSources } = this.checkerRuleConfigContent || {} const { TaintSource: TaintSourceRules, FuncCallArgTaintSource: FuncCallArgTaintSourceRules, FuncCallReturnValueTaintSource: FuncCallReturnValueTaintSourceRules, - } = ruleConfigSources + } = ruleConfigSources || {} if (Config.entryPointMode !== 'SELF_COLLECT') { // 添加rule_config中的route入口 @@ -81,25 +83,25 @@ class GinDefaultTaintChecker extends TaintChecker { let entryPointSymVal if (entrypoint.funcReceiverType) { entryPointSymVal = AstUtil.satisfy( - topScope.packageManager, + topScope.context.packages, (n: any) => n.vtype === 'fclos' && - FileUtil.extractAfterSubstring(n?.ast?.loc?.sourcefile, Config.maindirPrefix) === entrypoint.filePath && - n?.parent?.ast?.type === 'ClassDefinition' && - n?.parent?.ast?.id?.name === entrypoint.funcReceiverType && - n?.ast?.id.name === entrypoint.functionName, - (node: any, prop: any) => prop === 'field', + FileUtil.extractAfterSubstring(n?.ast?.node?.loc?.sourcefile, Config.maindirPrefix) === entrypoint.filePath && + n?.parent?.ast?.node?.type === 'ClassDefinition' && + n?.parent?.ast?.node?.id?.name === entrypoint.funcReceiverType && + n?.ast?.node?.id.name === entrypoint.functionName, + (node: any, prop: any) => prop === '_field', null, false ) } else { entryPointSymVal = AstUtil.satisfy( - topScope.packageManager, + topScope.context.packages, (n: any) => n.vtype === 'fclos' && - FileUtil.extractAfterSubstring(n?.ast?.loc?.sourcefile, Config.maindirPrefix) === entrypoint.filePath && - n?.ast?.id.name === entrypoint.functionName, - (node: any, prop: any) => prop === 'field', + FileUtil.extractAfterSubstring(n?.ast?.node?.loc?.sourcefile, Config.maindirPrefix) === entrypoint.filePath && + n?.ast?.node?.id.name === entrypoint.functionName, + (node: any, prop: any) => prop === '_field', null, false ) @@ -108,7 +110,7 @@ class GinDefaultTaintChecker extends TaintChecker { continue } if (Array.isArray(entryPointSymVal)) { - entryPointSymVal = _.uniqBy(entryPointSymVal, (value: any) => value.fdef) + entryPointSymVal = _.uniqBy(entryPointSymVal, (value: any) => value.ast.fdef) } else { entryPointSymVal = [entryPointSymVal] } @@ -126,12 +128,12 @@ class GinDefaultTaintChecker extends TaintChecker { } } if (Config.entryPointMode !== 'ONLY_CUSTOM') { - const ginDefaultEntrypoint = GinEntryPoint.getGinDefaultEntrypoint(topScope.packageManager) + const ginDefaultEntrypoint = GinEntryPoint.getGinDefaultEntrypoint(topScope.context.packages) analyzer.ruleEntrypoints.push(...ginDefaultEntrypoint) // 添加source const { TaintSource, FuncCallArgTaintSource, FuncCallReturnValueTaintSource } = - GinEntryPoint.getGinEntryPointAndSource(topScope.packageManager) + GinEntryPoint.getGinEntryPointAndSource(topScope.context.packages) if ( _.isEmpty(TaintSource) && @@ -201,13 +203,14 @@ class GinDefaultTaintChecker extends TaintChecker { * @param info */ triggerAtFunctionCallBefore(analyzer: any, scope: any, node: any, state: any, info: any) { - const { fclos, argvalues } = info + const { fclos, callInfo } = info const calleeObject = fclos.object - this.checkByNameAndClassMatch(node, fclos, argvalues, scope) + this.checkByNameAndClassMatch(node, fclos, callInfo, scope, state) const funcCallArgTaintSource = this.checkerRuleConfigContent.sources?.FuncCallArgTaintSource - IntroduceTaint.introduceFuncArgTaintByRuleConfig(calleeObject, node, argvalues, funcCallArgTaintSource) + IntroduceTaint.introduceFuncArgTaintByRuleConfig(calleeObject, node, callInfo, funcCallArgTaintSource) if (Config.entryPointMode === 'ONLY_CUSTOM') return + const argvalues = getLegacyArgValues(callInfo) this.collectRouteRegistry(node, calleeObject, argvalues, scope, analyzer) } @@ -271,18 +274,19 @@ class GinDefaultTaintChecker extends TaintChecker { * @param fclos * @param argvalues * @param scope + * @param state */ - checkByNameAndClassMatch(node: any, fclos: any, argvalues: any, scope: any) { + checkByNameAndClassMatch(node: any, fclos: any, callInfo: CallInfo | undefined, scope: any, state?: any) { if (fclos === undefined) { return } const rules = this.checkerRuleConfigContent.sinks?.FuncCallTaintSink - if (!rules || !argvalues) return - let rule = matchSinkAtFuncCallWithCalleeType(node, fclos, rules, scope) + if (!rules || !callInfo) return + let rule = matchSinkAtFuncCallWithCalleeType(node, fclos, rules, scope, callInfo) rule = rule.length > 0 ? rule[0] : null if (rule) { - const args = BasicRuleHandler.prepareArgs(argvalues, fclos, rule) + const args = BasicRuleHandler.prepareArgs(callInfo, fclos, rule) const sanitizers = SanitizerChecker.findSanitizerByIds(rule.sanitizerIds) const ndResultWithMatchedSanitizerTagsArray = SanitizerChecker.findTagAndMatchedSanitizer( node, @@ -309,7 +313,8 @@ class GinDefaultTaintChecker extends TaintChecker { fclos, TAINT_TAG_NAME_GIN_DEFAULT, ruleName, - matchedSanitizerTags + matchedSanitizerTags, + state?.callstack ) if (!TaintOutputStrategyGinDefault.isNewFinding(this.resultManager, taintFlowFinding)) continue this.resultManager.newFinding(taintFlowFinding, TaintOutputStrategyGinDefault.outputStrategyId) diff --git a/src/checker/taint/go/gin-taint-checker.ts b/src/checker/taint/go/gin-taint-checker.ts index 2b7982c5..f0829b31 100644 --- a/src/checker/taint/go/gin-taint-checker.ts +++ b/src/checker/taint/go/gin-taint-checker.ts @@ -1,3 +1,5 @@ +import { getLegacyArgValues, type CallInfo } from '../../../engine/analyzer/common/call-args' + const _ = require('lodash') const BasicRuleHandler = require('../../common/rules-basic-handler') const FileUtil = require('../../../util/file-util') @@ -66,13 +68,13 @@ class GinTaintChecker extends TaintChecker { * @param topScope */ prepareEntryPoints(analyzer: any, topScope: any) { - const { entrypoints: ruleConfigEntryPoints, sources: ruleConfigSources } = this.checkerRuleConfigContent + const { entrypoints: ruleConfigEntryPoints, sources: ruleConfigSources } = this.checkerRuleConfigContent || {} const { TaintSource: TaintSourceRules, FuncCallArgTaintSource: FuncCallArgTaintSourceRules, FuncCallReturnValueTaintSource: FuncCallReturnValueTaintSourceRules, - } = ruleConfigSources + } = ruleConfigSources || {} // 添加rule_config中的route入口 if (!_.isEmpty(ruleConfigEntryPoints) && Config.entryPointMode !== 'SELF_COLLECT') { @@ -80,25 +82,25 @@ class GinTaintChecker extends TaintChecker { let entryPointSymVal if (entrypoint.funcReceiverType) { entryPointSymVal = AstUtil.satisfy( - topScope.packageManager, + topScope.context.packages, (n: any) => n.vtype === 'fclos' && - FileUtil.extractAfterSubstring(n?.ast?.loc?.sourcefile, Config.maindirPrefix) === entrypoint.filePath && - n?.parent?.ast?.type === 'ClassDefinition' && - n?.parent?.ast?.id?.name === entrypoint.funcReceiverType && - n?.ast?.id.name === entrypoint.functionName, - (node: any, prop: any) => prop === 'field', + FileUtil.extractAfterSubstring(n?.ast?.node?.loc?.sourcefile, Config.maindirPrefix) === entrypoint.filePath && + n?.parent?.ast?.node?.type === 'ClassDefinition' && + n?.parent?.ast?.node?.id?.name === entrypoint.funcReceiverType && + n?.ast?.node?.id.name === entrypoint.functionName, + (node: any, prop: any) => prop === '_field', null, false ) } else { entryPointSymVal = AstUtil.satisfy( - topScope.packageManager, + topScope.context.packages, (n: any) => n.vtype === 'fclos' && - FileUtil.extractAfterSubstring(n?.ast?.loc?.sourcefile, Config.maindirPrefix) === entrypoint.filePath && - n?.ast?.id.name === entrypoint.functionName, - (node: any, prop: any) => prop === 'field', + FileUtil.extractAfterSubstring(n?.ast?.node?.loc?.sourcefile, Config.maindirPrefix) === entrypoint.filePath && + n?.ast?.node?.id.name === entrypoint.functionName, + (node: any, prop: any) => prop === '_field', null, false ) @@ -107,7 +109,7 @@ class GinTaintChecker extends TaintChecker { continue } if (Array.isArray(entryPointSymVal)) { - entryPointSymVal = _.uniqBy(entryPointSymVal, (value: any) => value.fdef) + entryPointSymVal = _.uniqBy(entryPointSymVal, (value: any) => value.ast.fdef) } else { entryPointSymVal = [entryPointSymVal] } @@ -127,7 +129,7 @@ class GinTaintChecker extends TaintChecker { // 添加source if (Config.entryPointMode !== 'ONLY_CUSTOM') { const { TaintSource, FuncCallArgTaintSource, FuncCallReturnValueTaintSource } = - GinEntryPoint.getGinEntryPointAndSource(topScope.packageManager) + GinEntryPoint.getGinEntryPointAndSource(topScope.context.packages) if ( _.isEmpty(TaintSource) && @@ -197,13 +199,14 @@ class GinTaintChecker extends TaintChecker { * @param info */ triggerAtFunctionCallBefore(analyzer: any, scope: any, node: any, state: any, info: any) { - const { fclos, argvalues } = info + const { fclos, callInfo } = info const calleeObject = fclos.object - this.checkByNameAndClassMatch(node, fclos, argvalues, scope) + this.checkByNameAndClassMatch(node, fclos, callInfo, scope, state) const funcCallArgTaintSource = this.checkerRuleConfigContent.sources?.FuncCallArgTaintSource - IntroduceTaint.introduceFuncArgTaintByRuleConfig(calleeObject, node, argvalues, funcCallArgTaintSource) + IntroduceTaint.introduceFuncArgTaintByRuleConfig(calleeObject, node, callInfo, funcCallArgTaintSource) if (Config.entryPointMode === 'ONLY_CUSTOM') return + const argvalues = getLegacyArgValues(callInfo) this.collectRouteRegistry(node, calleeObject, argvalues, scope, analyzer) } @@ -268,19 +271,20 @@ class GinTaintChecker extends TaintChecker { * @param fclos * @param argvalues * @param scope + * @param state */ - checkByNameAndClassMatch(node: any, fclos: any, argvalues: any, scope: any) { + checkByNameAndClassMatch(node: any, fclos: any, callInfo: CallInfo | undefined, scope: any, state?: any) { if (fclos === undefined) { return } const rules = this.checkerRuleConfigContent.sinks?.FuncCallTaintSink - if (!rules || !argvalues) return - let rule = matchSinkAtFuncCallWithCalleeType(node, fclos, rules, scope) + if (!rules || !callInfo) return + let rule = matchSinkAtFuncCallWithCalleeType(node, fclos, rules, scope, callInfo) rule = rule.length > 0 ? rule[0] : null if (rule) { - const args = BasicRuleHandler.prepareArgs(argvalues, fclos, rule) + const args = BasicRuleHandler.prepareArgs(callInfo, fclos, rule) const sanitizers = SanitizerChecker.findSanitizerByIds(rule.sanitizerIds) const ndResultWithMatchedSanitizerTagsArray = SanitizerChecker.findTagAndMatchedSanitizer( node, @@ -307,7 +311,8 @@ class GinTaintChecker extends TaintChecker { fclos, TAINT_TAG_NAME_GIN, ruleName, - matchedSanitizerTags + matchedSanitizerTags, + state?.callstack ) if (!TaintOutputStrategy.isNewFinding(this.resultManager, taintFlowFinding)) continue this.resultManager.newFinding(taintFlowFinding, TaintOutputStrategy.outputStrategyId) diff --git a/src/checker/taint/go/go-default-taint-checker.ts b/src/checker/taint/go/go-default-taint-checker.ts index f13036b8..c31b5cc9 100644 --- a/src/checker/taint/go/go-default-taint-checker.ts +++ b/src/checker/taint/go/go-default-taint-checker.ts @@ -1,3 +1,5 @@ +import type { CallInfo } from '../../../engine/analyzer/common/call-args' + const _ = require('lodash') const GoEntryPoint = require('../../../engine/analyzer/golang/common/entrypoint-collector/go-default-entrypoint') const completeEntryPoint = require('../common-kit/entry-points-util') @@ -55,13 +57,13 @@ class GoDefaultTaintChecker extends TaintChecker { prepareEntryPoints(topScope: any, analyzer: any) { if (Config.entryPointMode === 'ONLY_CUSTOM') return // 添加main入口 - let mainEntryPoints = GoEntryPoint.getMainEntryPoints(topScope.packageManager) + let mainEntryPoints = GoEntryPoint.getMainEntryPoints(topScope.context.packages) if (_.isEmpty(mainEntryPoints)) { logger.info('[go-default-taint-checker]EntryPoints are not found') return } if (Array.isArray(mainEntryPoints)) { - mainEntryPoints = _.uniqBy(mainEntryPoints, (value: any) => value.fdef) + mainEntryPoints = _.uniqBy(mainEntryPoints, (value: any) => value.ast.fdef) } else { mainEntryPoints = [mainEntryPoints] } @@ -80,7 +82,8 @@ class GoDefaultTaintChecker extends TaintChecker { FullCallGraphFileEntryPoint.makeFullCallGraph(analyzer) } const fullCallGraphEntrypoint = FullCallGraphFileEntryPoint.getAllEntryPointsUsingCallGraph( - analyzer.ainfo?.callgraph + analyzer.ainfo?.callgraph, + analyzer ) this.entryPoints.push(...fullCallGraphEntrypoint) } @@ -93,25 +96,25 @@ class GoDefaultTaintChecker extends TaintChecker { let entryPointSymVal if (entrypoint.funcReceiverType) { entryPointSymVal = AstUtil.satisfy( - topScope.packageManager, + topScope.context.packages, (n: any) => n.vtype === 'fclos' && - FileUtil.extractAfterSubstring(n?.ast?.loc?.sourcefile, Config.maindirPrefix) === entrypoint.filePath && - n?.parent?.ast?.type === 'ClassDefinition' && - n?.parent?.ast?.id?.name === entrypoint.funcReceiverType && - n?.ast?.id.name === entrypoint.functionName, - (node: any, prop: any) => prop === 'field', + FileUtil.extractAfterSubstring(n?.ast?.node?.loc?.sourcefile, Config.maindirPrefix) === entrypoint.filePath && + n?.parent?.ast?.node?.type === 'ClassDefinition' && + n?.parent?.ast?.node?.id?.name === entrypoint.funcReceiverType && + n?.ast?.node?.id.name === entrypoint.functionName, + (node: any, prop: any) => prop === '_field', null, false ) } else { entryPointSymVal = AstUtil.satisfy( - topScope.packageManager, + topScope.context.packages, (n: any) => n.vtype === 'fclos' && - FileUtil.extractAfterSubstring(n?.ast?.loc?.sourcefile, Config.maindirPrefix) === entrypoint.filePath && - n?.ast?.id.name === entrypoint.functionName, - (node: any, prop: any) => prop === 'field', + FileUtil.extractAfterSubstring(n?.ast?.node?.loc?.sourcefile, Config.maindirPrefix) === entrypoint.filePath && + n?.ast?.node?.id.name === entrypoint.functionName, + (node: any, prop: any) => prop === '_field', null, false ) @@ -120,7 +123,7 @@ class GoDefaultTaintChecker extends TaintChecker { continue } if (Array.isArray(entryPointSymVal)) { - entryPointSymVal = _.uniqBy(entryPointSymVal, (value: any) => value.fdef) + entryPointSymVal = _.uniqBy(entryPointSymVal, (value: any) => value.ast.fdef) } else { entryPointSymVal = [entryPointSymVal] } @@ -160,11 +163,11 @@ class GoDefaultTaintChecker extends TaintChecker { * @param info */ triggerAtFunctionCallBefore(analyzer: any, scope: any, node: any, state: any, info: any) { - const { fclos, argvalues } = info + const { fclos, callInfo } = info const calleeObject = fclos?.object - this.checkByNameAndClassMatch(node, fclos, argvalues, scope) + this.checkByNameAndClassMatch(node, fclos, callInfo, scope, state) const funcCallArgTaintSource = this.checkerRuleConfigContent.sources?.FuncCallArgTaintSource - IntroduceTaint.introduceFuncArgTaintByRuleConfig(calleeObject, node, argvalues, funcCallArgTaintSource) + IntroduceTaint.introduceFuncArgTaintByRuleConfig(calleeObject, node, callInfo, funcCallArgTaintSource) } /** @@ -188,19 +191,20 @@ class GoDefaultTaintChecker extends TaintChecker { * @param fclos * @param argvalues * @param scope + * @param state */ - checkByNameAndClassMatch(node: any, fclos: any, argvalues: any, scope: any) { + checkByNameAndClassMatch(node: any, fclos: any, callInfo: CallInfo | undefined, scope: any, state?: any) { if (fclos === undefined) { return } const rules = this.checkerRuleConfigContent.sinks?.FuncCallTaintSink - if (!rules || !argvalues) return - let rule = matchSinkAtFuncCallWithCalleeType(node, fclos, rules, scope, argvalues) + if (!rules || !callInfo) return + let rule = matchSinkAtFuncCallWithCalleeType(node, fclos, rules, scope, callInfo) rule = rule.length > 0 ? rule[0] : null if (rule) { - const args = BasicRuleHandler.prepareArgs(argvalues, fclos, rule) + const args = BasicRuleHandler.prepareArgs(callInfo, fclos, rule) const sanitizers = SanitizerChecker.findSanitizerByIds((rule as any).sanitizerIds) const ndResultWithMatchedSanitizerTagsArray = SanitizerChecker.findTagAndMatchedSanitizer( node, @@ -227,7 +231,8 @@ class GoDefaultTaintChecker extends TaintChecker { fclos, TAINT_TAG_NAME, ruleName, - matchedSanitizerTags + matchedSanitizerTags, + state?.callstack ) if (!TaintOutputStrategy.isNewFinding(this.resultManager, taintFlowFinding)) continue @@ -247,7 +252,7 @@ class GoDefaultTaintChecker extends TaintChecker { * @param info */ triggerAtIdentifier(analyzer: any, scope: any, node: any, state: any, info: any) { - IntroduceTaint.introduceTaintAtIdentifierDirect(node, info.res, this.sourceScope.value) + IntroduceTaint.introduceTaintAtIdentifierDirect(analyzer, scope, node, info.res, this.sourceScope.value) } } diff --git a/src/checker/taint/go/gorilla-mux-entrypoint-collect-checker.ts b/src/checker/taint/go/gorilla-mux-entrypoint-collect-checker.ts index 50fb4ba7..2771a684 100644 --- a/src/checker/taint/go/gorilla-mux-entrypoint-collect-checker.ts +++ b/src/checker/taint/go/gorilla-mux-entrypoint-collect-checker.ts @@ -1,8 +1,10 @@ +import { getLegacyArgValues } from '../../../engine/analyzer/common/call-args' + const completeEntryPoint = require('../common-kit/entry-points-util') const Config = require('../../../config') const RouteRegistryProperty = ['HandleFunc', 'Handle', 'Handler'] -const RouteRegistryObject = ['github.com/gorilla/mux.NewRouter()'] +const RouteRegistryObject = ['.packageManager.github.com/gorilla/mux.NewRouter()'] const IntroduceTaint = require('../common-kit/source-util') const Checker = require('../../common/checker') @@ -30,8 +32,8 @@ class MuxEntryPointCollectChecker extends Checker { * @param info */ triggerAtFunctionCallBefore(analyzer: any, scope: any, node: any, state: any, info: any) { - const { fclos, argvalues } = info - + const { fclos, callInfo } = info + const argvalues = getLegacyArgValues(callInfo) this.collectRouteRegistry(node, fclos, argvalues, scope, info) } @@ -60,16 +62,16 @@ class MuxEntryPointCollectChecker extends Checker { if (Config.entryPointMode === 'ONLY_CUSTOM') return // 不路由自采集 if (!(calleeFClos && calleeFClos.object && calleeFClos.property)) return const { object, property } = calleeFClos - if (!object._qid || !property.name) return - const objectQid = object._qid + if (!object.qid || !property.name) return + const objectQid = object.qid const propertyName = property.name if ( RouteRegistryObject.some((muxPrefix: any) => objectQid.startsWith(muxPrefix)) && RouteRegistryProperty.includes(propertyName) ) { for (const arg of argValues) { - if (arg?.vtype === 'fclos' && arg?.ast.loc) { - const hash = JSON.stringify(arg.ast.loc) + if (arg?.vtype === 'fclos' && arg?.ast.node.loc) { + const hash = JSON.stringify(arg.ast.node.loc) if (!processedRouteRegistry.has(hash)) { processedRouteRegistry.add(hash) IntroduceTaint.introduceFuncArgTaintBySelfCollection(arg, state, analyzer, '1:', 'GO_INPUT') diff --git a/src/checker/taint/go/main-entrypoint-collect-checker.ts b/src/checker/taint/go/main-entrypoint-collect-checker.ts index fc2e8254..d8193671 100644 --- a/src/checker/taint/go/main-entrypoint-collect-checker.ts +++ b/src/checker/taint/go/main-entrypoint-collect-checker.ts @@ -42,18 +42,18 @@ class MainEntrypointCollectChecker extends Checker { prepareEntryPoints(topScope: any): void { if (Config.entryPointMode === 'ONLY_CUSTOM') return // 添加main入口 - let mainEntryPoints = GoEntryPoint.getMainEntryPoints(topScope.packageManager) + let mainEntryPoints = GoEntryPoint.getMainEntryPoints(topScope.context.packages) if (_.isEmpty(mainEntryPoints)) { return } if (Array.isArray(mainEntryPoints)) { - mainEntryPoints = _.uniqBy(mainEntryPoints, (value: EntryPoint) => value.fdef) + mainEntryPoints = _.uniqBy(mainEntryPoints, (value: EntryPoint) => value.ast.fdef) } else { mainEntryPoints = [mainEntryPoints] } mainEntryPoints.forEach((main: EntryPoint) => { if (main) { - const entryPoint = completeEntryPoint(main) + const entryPoint = completeEntryPoint(main, true) this.entryPoints.push(entryPoint) } }) diff --git a/src/checker/taint/go/restful-entrypoint-collect-checker.ts b/src/checker/taint/go/restful-entrypoint-collect-checker.ts index 6fca9f0c..867d90ba 100644 --- a/src/checker/taint/go/restful-entrypoint-collect-checker.ts +++ b/src/checker/taint/go/restful-entrypoint-collect-checker.ts @@ -1,20 +1,17 @@ -import { processEntryPointAndTaintSource } from './util' +import { getLegacyArgValues } from '../../../engine/analyzer/common/call-args' const config = require('../../../config') -const GoAnalyzer = require('../../../engine/analyzer/golang/common/go-analyzer') const RouteRegistryProperty = ['Filter', 'To', 'If'] -const KnownPackageName = { - 'github.com/emicklei/go-restful': 'restful', - 'github.com/emicklei/go-restful/v3': 'restful', -} const RouteRegistryObject = [ - 'github.com/emicklei/go-restful.WebService', - 'github.com/emicklei/go-restful/v3.WebService', + /github\.com\/emicklei\/go-restful\/v3\.WebService/, + /github\.com\/emicklei\/go-restful\.WebService/, ] +const IntroduceTaint = require('../common-kit/source-util') const Checker = require('../../common/checker') +const completeEntryPoint = require('../common-kit/entry-points-util') -const processedRouteRegistry = new Set() +const processedRouteRegistry = new Set() /** * @@ -26,7 +23,6 @@ class RestfulEntrypointCollectChecker extends Checker { */ constructor(resultManager: any) { super(resultManager, 'go-restful-entryPoints-collect-checker') - GoAnalyzer.registerKnownPackageNames(KnownPackageName) } /** @@ -38,8 +34,8 @@ class RestfulEntrypointCollectChecker extends Checker { * @param info */ triggerAtFunctionCallBefore(analyzer: any, scope: any, node: any, state: any, info: any) { - const { fclos, argvalues } = info - + const { fclos, callInfo } = info + const argvalues = getLegacyArgValues(callInfo) this.collectRouteRegistry(node, fclos, argvalues, scope, info) } @@ -68,15 +64,22 @@ class RestfulEntrypointCollectChecker extends Checker { if (config.entryPointMode === 'ONLY_CUSTOM') return if (!(calleeFClos && calleeFClos.object && calleeFClos.property)) return const { object, property } = calleeFClos - if (!object._qid || !property.name) return - const objectQid = object._qid + if (!object.qid || !property.name) return + const objectQid = object.qid const propertyName = property.name - if ( - RouteRegistryObject.some((prefix) => objectQid.startsWith(prefix)) && - RouteRegistryProperty.includes(propertyName) && - argValues[0] - ) { - processEntryPointAndTaintSource(analyzer, state, processedRouteRegistry, argValues[0], '0') + if (RouteRegistryObject.some((prefix) => prefix.test(objectQid)) && RouteRegistryProperty.includes(propertyName)) { + if (argValues.length < 1) return + const arg0 = argValues[0] + + if (arg0?.vtype === 'fclos' && arg0?.ast.node.loc) { + const hash = JSON.stringify(arg0.ast.node.loc) + if (!processedRouteRegistry.has(hash)) { + processedRouteRegistry.add(hash) + IntroduceTaint.introduceFuncArgTaintBySelfCollection(arg0, state, analyzer, '0', 'GO_INPUT') + const entryPoint = completeEntryPoint(arg0) + analyzer.entryPoints.push(entryPoint) + } + } } } } diff --git a/src/checker/taint/go/sync-once-do-checker.ts b/src/checker/taint/go/sync-once-do-checker.ts index 654dad57..831efa87 100644 --- a/src/checker/taint/go/sync-once-do-checker.ts +++ b/src/checker/taint/go/sync-once-do-checker.ts @@ -1,11 +1,13 @@ -const CheckerSyncOnceDo = require('../../common/checker') +import { getLegacyArgValues, type CallInfo } from '../../../engine/analyzer/common/call-args' + +const Checker = require('../../common/checker') const done: Set = new Set() -const syncOnceDoQid: string = 'sync.Once.Do' +const syncOnceDoQidRegex: RegExp = /sync\.Once\.Do/ interface TriggerInfo { fclos: any - argvalues: any[] + callInfo: CallInfo | undefined [key: string]: any } @@ -13,7 +15,7 @@ interface TriggerInfo { * sync.Once.Do bulitIn checker * 为Go内置库方法sync.Once.Do做建模,执行且只执行一次传给Do方法的funcDef */ -class syncOnceDoChecker extends CheckerSyncOnceDo { +class syncOnceDoChecker extends Checker { /** * constructor * @param resultManager @@ -31,12 +33,13 @@ class syncOnceDoChecker extends CheckerSyncOnceDo { * @param info */ triggerAtFunctionCallBefore(analyzer: any, scope: any, node: any, state: any, info: TriggerInfo): void { - const { fclos, argvalues } = info - if (fclos._qid !== syncOnceDoQid) return + const { fclos, callInfo } = info + if (!syncOnceDoQidRegex.test(fclos.qid)) return const hash: string = JSON.stringify(node.loc) if (done.has(hash)) return done.add(hash) - if (argvalues.length !== 1 && argvalues[0].vtype !== 'fclos') return + const argvalues = getLegacyArgValues(callInfo) + if (argvalues.length !== 1 || argvalues[0].vtype !== 'fclos') return const fDef = node.arguments[0] const fClos = argvalues[0] diff --git a/src/checker/taint/go/urfave-cli-checker.ts b/src/checker/taint/go/urfave-cli-checker.ts index 4e5801d8..a35aeb56 100644 --- a/src/checker/taint/go/urfave-cli-checker.ts +++ b/src/checker/taint/go/urfave-cli-checker.ts @@ -1,16 +1,16 @@ const completeEntryPoint = require('../common-kit/entry-points-util') -const configUrfaveCli = require('../../../config') -const CheckerUrfaveCli = require('../../common/checker') +const config = require('../../../config') +const Checker = require('../../common/checker') -const processedBuiltInRegistryUrfaveCli = new Set() -const builtInOnjectListUrfaveCli = ['github.com/urfave/cli.NewApp()'] -const builtInPropertyListUrfaveCli = ['Action'] +const processedBuiltInRegistry = new Set() +const builtInObjectList = ['github.com/urfave/cli.NewApp()'] +const builtInPropertyList = ['Action'] /** * urfave.cli bulitIn checker * 为第三方库方法urfave.cli做建模,添加entryPoints */ -class urfaveCliChecker extends CheckerUrfaveCli { +class urfaveCliChecker extends Checker { /** * constructor * @param resultManager @@ -29,16 +29,15 @@ class urfaveCliChecker extends CheckerUrfaveCli { */ triggerAtAssignment(analyzer: any, scope: any, node: any, state: any, info: any): void { const { lvalue, rvalue } = info - if (configUrfaveCli.entryPointMode === 'ONLY_CUSTOM') return // 不路由自采集 + if (config.entryPointMode === 'ONLY_CUSTOM') return // 不路由自采集 if (!lvalue || !rvalue || rvalue.vtype !== 'fclos') return const { object, property } = lvalue if (!object || !property) return - if (!builtInOnjectListUrfaveCli.includes(object._qid) || !builtInPropertyListUrfaveCli.includes(property.name)) - return + if (!builtInObjectList.includes(object.qid) || !builtInPropertyList.includes(property.name)) return const hash = JSON.stringify(node.right.loc) - if (processedBuiltInRegistryUrfaveCli.has(hash)) return - processedBuiltInRegistryUrfaveCli.add(hash) - analyzer.entryPoints.push(completeEntryPoint(rvalue)) + if (processedBuiltInRegistry.has(hash)) return + processedBuiltInRegistry.add(hash) + analyzer.entryPoints.push(completeEntryPoint(rvalue, true)) } } diff --git a/src/checker/taint/java/java-default-taint-checker.ts b/src/checker/taint/java/java-default-taint-checker.ts index 46d11a54..a617bbcf 100644 --- a/src/checker/taint/java/java-default-taint-checker.ts +++ b/src/checker/taint/java/java-default-taint-checker.ts @@ -41,13 +41,13 @@ class JavaDefaultTaintChecker extends JavaTaintAbstractChecker { const selfCollectEntryPoints: any[] = [] const selfCollectTaintSource: any[] = [] const { selfCollectMainEntryPoints, selfCollectMainTaintSource } = MainEntryPoint.getJavaMainEntryPointAndSource( - topScope.packageManager + topScope.context.packages ) selfCollectEntryPoints.push(...selfCollectMainEntryPoints) selfCollectTaintSource.push(...selfCollectMainTaintSource) const { selfCollectSpringEntryPoints, selfCollectSpringTaintSource } = - springEntryPoint.getSpringEntryPointAndSource(topScope.packageManager) + springEntryPoint.getSpringEntryPointAndSource(topScope.context.packages) selfCollectEntryPoints.push(...selfCollectSpringEntryPoints) selfCollectTaintSource.push(...selfCollectSpringTaintSource) @@ -87,9 +87,10 @@ class JavaDefaultTaintChecker extends JavaTaintAbstractChecker { FullCallGraphFileEntryPoint.makeFullCallGraph(analyzer) } const fullCallGraphEntrypoint = FullCallGraphFileEntryPoint.getAllEntryPointsUsingCallGraph( - analyzer.ainfo?.callgraph + analyzer.ainfo?.callgraph, + analyzer ) - const fullFileEntrypoint = FullCallGraphFileEntryPoint.getAllFileEntryPointsUsingFileManager(analyzer.fileManager) + const fullFileEntrypoint = FullCallGraphFileEntryPoint.getAllFileEntryPointsUsingFileManager(analyzer) this.entryPoints.push(...fullCallGraphEntrypoint) this.entryPoints.push(...fullFileEntrypoint) } @@ -102,9 +103,9 @@ class JavaDefaultTaintChecker extends JavaTaintAbstractChecker { } targetPackage = targetPackage.startsWith('.') ? targetPackage.slice(1) : targetPackage const arr = Loader.getPackageNameProperties(targetPackage) - let packageManagerT = topScope.packageManager + let packageManagerT = topScope.context.packages arr.forEach((path: any) => { - packageManagerT = packageManagerT?.field[path] + packageManagerT = packageManagerT?.members?.get(path) }) if (!packageManagerT || packageManagerT.vtype === 'undefine') { continue @@ -117,23 +118,7 @@ class JavaDefaultTaintChecker extends JavaTaintAbstractChecker { continue } - const scopeVal = Scoped({ - vtype: 'scope', - _sid: 'mock', - _id: 'mock', - field: {}, - parent: null, - }) - - const entryPoint = new EntryPoint(Constant.ENGIN_START_FUNCALL) - entryPoint.scopeVal = scopeVal - entryPoint.argValues = [] - entryPoint.functionName = entrypoint.functionName - entryPoint.filePath = entrypoint.filePath - entryPoint.attribute = entrypoint.attribute - entryPoint.packageName = entrypoint.packageName - entryPoint.entryPointSymVal = entryPointSymVal - this.entryPoints.push(entryPoint) + this.resolveAndPushEntryPoint(entryPointSymVal, entrypoint, func, analyzer, Scoped, EntryPoint, Constant) } } } diff --git a/src/checker/taint/java/java-taint-abstract-checker.ts b/src/checker/taint/java/java-taint-abstract-checker.ts index fd4811db..d9e5deae 100644 --- a/src/checker/taint/java/java-taint-abstract-checker.ts +++ b/src/checker/taint/java/java-taint-abstract-checker.ts @@ -1,17 +1,223 @@ +import type { CallInfo } from '../../../engine/analyzer/common/call-args' +import type { Invocation } from '../../../resolver/common/value/invocation' + +const QidUnifyUtil = require('../../../util/qid-unify-util') const TaintCheckerJava = require('../taint-checker') const IntroduceTaintJava = require('../common-kit/source-util') const commonUtilJavaAbstract = require('../../../util/common-util') -const { matchSinkAtFuncCallWithCalleeType: matchSinkAtFuncCallWithCalleeTypeJava } = require('../common-kit/sink-util') +const { + matchSinkAtFuncCallWithCalleeType: matchSinkAtFuncCallWithCalleeTypeJava, + checkInvocationMatchSink, +} = require('../common-kit/sink-util') const RulesJava = require('../../common/rules-basic-handler') const SanitizerCheckerJava = require('../../sanitizer/sanitizer-checker') const TaintOutputStrategyJava = require('../../common/output/taint-output-strategy') +const Config = require('../../../config') +const logger = require('../../../util/logger')(__filename) + const TAINT_TAG_NAME_JAVA = 'JAVA_INPUT' /** * java taint base checker */ class JavaTaintAbstractChecker extends TaintCheckerJava { + /** + * When the entrypoint resolves to an interface/abstract method with no body, + * find implementation classes and return their overriding methods instead. + * @param entryPointSymVal - the resolved entrypoint function closure + * @param funcName - the function name to look for + * @param analyzer - the analyzer instance with classMap and symbolTable + * @returns array of resolved function closures (may contain multiple implementations) + */ + resolveInterfaceEntryPoint(entryPointSymVal: any, funcName: string, analyzer: any): any[] { + const parentScope = entryPointSymVal?.parent + const isInterface = parentScope?.ast?.node?._meta?.isInterface + const isAbstract = parentScope?.ast?.node?._meta?.isAbstract + + if (!(isInterface || isAbstract) || !analyzer?.classMap) { + return [entryPointSymVal] + } + + const parentQid = parentScope?.qid + + const implSymVals: any[] = [] + for (const [, classRef] of analyzer.classMap) { + const classVal = analyzer.symbolTable?.get(classRef) ?? classRef + if (!classVal || typeof classVal !== 'object' || classVal === parentScope) { + continue + } + + // Check all supers (both extends and implements) via the AST supers array, + // because classVal.super only holds the last resolved super reference. + const fdefSupers = classVal.ast?.fdef?.supers + let isImpl = false + if (Array.isArray(fdefSupers)) { + for (const superId of fdefSupers) { + if (!superId) continue + const superName = superId.name ?? superId.id?.name + if (superName && parentScope?.sid && superName === parentScope.sid) { + isImpl = true + break + } + if (parentQid && (superId.qid === parentQid || superId.logicalQid === parentQid)) { + isImpl = true + break + } + } + } + // Fallback: also check the runtime super chain for cases already resolved + if (!isImpl) { + let superRef = classVal.super + while (superRef) { + if (superRef === parentScope || (parentQid && superRef.qid === parentQid)) { + isImpl = true + break + } + superRef = superRef.super + } + } + if (!isImpl) continue + + const implMethod = classVal.members?.get(funcName) ?? classVal.value?.[funcName] + if (implMethod?.vtype === 'fclos' && !implMethod.inherited) { + implSymVals.push(implMethod) + logger.info( + 'Resolved interface entrypoint [%s.%s] to implementation [%s.%s]', + parentScope?.sid, + funcName, + classVal?.sid, + funcName + ) + } + } + + return implSymVals.length > 0 ? implSymVals : [entryPointSymVal] + } + + /** + * When entrypoint is resolved from interface to implementation, augment TaintSource + * entries so that sources configured for the interface file also apply to the + * implementation class file. + * @param interfaceSymVal - the original interface method fclos + * @param implSymVals - the resolved implementation method fclos array + * @param funcName - the function name + */ + augmentSourcesForInterfaceResolution(interfaceSymVal: any, implSymVals: any[], funcName: string): void { + const taintSources = this.checkerRuleConfigContent.sources?.TaintSource + if (!Array.isArray(taintSources) || taintSources.length === 0) return + + const interfacePath = this.normalizeAstSourceFilePath(interfaceSymVal?.ast?.node?.loc?.sourcefile) + if (!interfacePath) return + + // Track full source identity so repeated interface resolution does not append the + // same implementation source twice, while still allowing multiple distinct sources + // inside the same function. + const buildSourceKey = (source: any): string => + `${source.scopeFile}::${source.scopeFunc}::${source.path}::${source.kind}::${source.attribute || ''}` + const existingKeys = new Set(taintSources.map((s: any) => buildSourceKey(s))) + + for (const implSymVal of implSymVals) { + const implPath = this.normalizeAstSourceFilePath(implSymVal?.ast?.node?.loc?.sourcefile) + if (!implPath || implPath === interfacePath) continue + + const implAstNode = implSymVal?.ast?.node + // locStart: use the first parameter's start line when available so that the + // source scope covers the parameter list rather than the method keyword itself. + // This matches how initSourceScopeByTaintSourceWithLoc computes effective ranges. + const locStart = implAstNode?.parameters?.length > 0 + ? implAstNode.parameters[0].loc?.start?.line + : implAstNode?.loc?.start?.line + const locEnd = implAstNode?.loc?.end?.line + + const newSources: any[] = [] + for (const source of taintSources) { + if (source.scopeFile === interfacePath && source.scopeFunc === funcName) { + const key = buildSourceKey({ ...source, scopeFile: implPath }) + if (!existingKeys.has(key)) { + newSources.push({ ...source, scopeFile: implPath }) + existingKeys.add(key) + } + } + } + + if (newSources.length > 0) { + taintSources.push(...newSources) + for (const ns of newSources) { + const scopeEntry = { + path: ns.path, + kind: ns.kind, + scopeFile: ns.scopeFile, + scopeFunc: ns.scopeFunc, + attribute: ns.attribute, + locStart, + locEnd, + } + this.sourceScope.value.push(scopeEntry) + this.sourceScope.fillLineValues.push(scopeEntry) + } + logger.info( + 'Augmented TaintSource for implementation [%s] (loc %s-%s) from interface [%s.%s]', + implPath, + locStart, + locEnd, + interfacePath, + funcName + ) + } + } + } + + /** + * 将接口/抽象类 entrypoint 解析为实现类,并推入 this.entryPoints。 + * 两个子类(JavaTaintChecker / JavaDefaultTaintChecker)的 prepareEntryPoints + * 共用此方法,避免重复代码。 + */ + resolveAndPushEntryPoint(entryPointSymVal: any, entrypoint: any, func: string, analyzer: any, Scoped: any, EntryPoint: any, Constant: any): void { + const resolvedSymVals = this.resolveInterfaceEntryPoint(entryPointSymVal, func, analyzer) + if (resolvedSymVals.length > 0 && resolvedSymVals[0] !== entryPointSymVal) { + this.augmentSourcesForInterfaceResolution(entryPointSymVal, resolvedSymVals, func) + } + for (const resolvedSymVal of resolvedSymVals) { + const scopeVal = new Scoped('', { + vtype: 'scope', + sid: 'mock', + qid: 'mock', + field: {}, + parent: null, + }) + const entryPoint = new EntryPoint(Constant.ENGIN_START_FUNCALL) + entryPoint.scopeVal = scopeVal + entryPoint.argValues = [] + entryPoint.functionName = entrypoint.functionName + entryPoint.filePath = entrypoint.filePath + entryPoint.attribute = entrypoint.attribute + entryPoint.packageName = entrypoint.packageName + entryPoint.entryPointSymVal = resolvedSymVal + this.entryPoints.push(entryPoint) + } + } + + /** + * Normalize an AST sourcefile path to the format used by ruleconfig scopeFile. + * @param astPath - the full path from ast.loc.sourcefile + * @returns normalized relative path (e.g. "/app/biz/.../Foo.java") or null + */ + normalizeAstSourceFilePath(astPath: string | undefined): string | null { + if (!astPath) return null + try { + const prefixIdx = astPath.indexOf(Config.maindirPrefix) + if (prefixIdx === -1) return null + let relativePath = astPath.substring(prefixIdx + Config.maindirPrefix.length) + const slashIdx = relativePath.indexOf('/') + if (slashIdx === -1) return null + relativePath = relativePath.substring(slashIdx) + return relativePath + } catch { + return null + } + } + /** * starter trigger * @param analyzer @@ -37,7 +243,7 @@ class JavaTaintAbstractChecker extends TaintCheckerJava { * @param info */ triggerAtIdentifier(analyzer: any, scope: any, node: any, state: any, info: any) { - IntroduceTaintJava.introduceTaintAtIdentifier(node, info.res, this.sourceScope.value) + IntroduceTaintJava.introduceTaintAtIdentifier(analyzer, scope, node, info.res, this.sourceScope.value) } /** @@ -61,11 +267,11 @@ class JavaTaintAbstractChecker extends TaintCheckerJava { * @param info */ triggerAtFunctionCallBefore(analyzer: any, scope: any, node: any, state: any, info: any) { - const { fclos, argvalues } = info + const { fclos, callInfo } = info const funcCallArgTaintSource = this.checkerRuleConfigContent.sources?.FuncCallArgTaintSource - IntroduceTaintJava.introduceFuncArgTaintByRuleConfig(fclos?.object, node, argvalues, funcCallArgTaintSource) - this.checkByNameAndClassMatch(node, fclos, argvalues, scope, state, info) - this.checkByFieldMatch(node, fclos, argvalues, scope, state, info) + IntroduceTaintJava.introduceFuncArgTaintByRuleConfig(fclos?.object, node, callInfo, funcCallArgTaintSource) + this.checkByNameAndClassMatch(node, fclos, callInfo, scope, state, info, analyzer) + // this.checkByFieldMatch(node, fclos, callInfo, scope, state, info) } /** @@ -91,17 +297,49 @@ class JavaTaintAbstractChecker extends TaintCheckerJava { * @param scope * @param state * @param info + * @param analyzer */ - checkByNameAndClassMatch(node: any, fclos: any, argvalues: any, scope: any, state: any, info: any) { - const sinkRules = this.assembleFunctionCallSinkRule() + checkByNameAndClassMatch(node: any, fclos: any, callInfo: CallInfo | undefined, scope: any, state: any, info: any, analyzer: any) { + let sinkRules + if (RulesJava.getPreprocessReady()) { + if (!this.sinkRuleArray) { + this.sinkRuleArray = this.assembleFunctionCallSinkRule() + this.sinkArray = analyzer?.loadAllSink() + } + sinkRules = this.sinkRuleArray + } else { + sinkRules = this.assembleFunctionCallSinkRule() + } + + let rules + if (RulesJava.getPreprocessReady()) { + if (node?._meta?.nodehash) { + if (this.matchSinkRuleResultMap.has(node._meta.nodehash)) { + rules = this.matchSinkRuleResultMap.get(node._meta.nodehash) + } else { + rules = matchSinkAtFuncCallWithCalleeTypeJava(node, fclos, sinkRules, scope) + this.appendCgRules(rules, node, scope, sinkRules, analyzer) + this.matchSinkRuleResultMap.set(node._meta.nodehash, rules) + } + } else { + rules = matchSinkAtFuncCallWithCalleeTypeJava(node, fclos, sinkRules, scope) + this.appendCgRules(rules, node, scope, sinkRules, analyzer) + } + } else { + rules = matchSinkAtFuncCallWithCalleeTypeJava(node, fclos, sinkRules, scope) + this.appendCgRules(rules, node, scope, sinkRules, analyzer) + } - const rules = matchSinkAtFuncCallWithCalleeTypeJava(node, fclos, sinkRules, scope) for (const rule of rules) { let args if (rule._sinkType === 'FuncCallTaintSink') { - args = RulesJava.prepareArgs(argvalues, fclos, rule) + if (rule.args) { + args = RulesJava.prepareArgs(callInfo, fclos, rule) + } else if (rule.argTypes) { + args = RulesJava.prepareArgsByType(callInfo, fclos, rule) + } } else if (rule._sinkType === 'ObjectTaintFuncCallSink') { - args = fclos.getThis() + args = fclos.getThisObj() } if (!args) { continue @@ -145,6 +383,55 @@ class JavaTaintAbstractChecker extends TaintCheckerJava { return true } + /** + * append matched rules find by callgraph + * @param rules + * @param node + * @param scope + * @param sinkRules + * @param analyzer + */ + appendCgRules(rules: any[], node: any, scope: any, sinkRules: any[], analyzer: any) { + if (rules.length > 0) { + return + } + const cgRules = this.findMatchedRuleByCallGraph(node, scope, sinkRules, analyzer) + for (const cgRule of cgRules) { + rules.push(cgRule) + } + } + + /** + * find matched rule by CallGraph + * @param node + * @param scope + * @param analyzer + * @param sinkRules + */ + findMatchedRuleByCallGraph(node: any, scope: any, sinkRules: any[], analyzer: any) { + const resultArray: any[] = [] + + if (!node || !scope || !sinkRules || !analyzer || !analyzer.findNodeInvocations) { + return resultArray + } + + const invocations: Invocation[] = analyzer.findNodeInvocations(scope, node) + if (!invocations) { + return resultArray + } + + for (const invocation of invocations) { + for (const sink of sinkRules) { + const matchSink: boolean = checkInvocationMatchSink(invocation, sink, analyzer.typeResolver) + if (matchSink) { + resultArray.push(sink) + } + } + } + + return resultArray + } + /** * check if sink or not by obj value * @param node @@ -154,8 +441,16 @@ class JavaTaintAbstractChecker extends TaintCheckerJava { * @param state * @param info */ - checkByFieldMatch(node: any, fclos: any, argvalues: any, scope: any, state: any, info: any) { - const rules = this.checkerRuleConfigContent.sinks?.FuncCallTaintSink + checkByFieldMatch(node: any, fclos: any, callInfo: CallInfo | undefined, scope: any, state: any, info: any) { + let rules + if (RulesJava.getPreprocessReady()) { + if (!this.sinkRuleArray) { + this.sinkRuleArray = this.assembleFunctionCallSinkRule() + } + rules = this.sinkRuleArray + } else { + rules = this.assembleFunctionCallSinkRule() + } if (!rules) return let matched = false @@ -223,7 +518,7 @@ class JavaTaintAbstractChecker extends TaintCheckerJava { create ) if (matched) { - const args = RulesJava.prepareArgs(argvalues, fclos, rule) + const args = RulesJava.prepareArgs(callInfo, fclos, rule) const sanitizers = SanitizerCheckerJava.findSanitizerByIds(rule.sanitizerIds) const ndResultWithMatchedSanitizerTagsArray = SanitizerCheckerJava.findTagAndMatchedSanitizer( node, @@ -269,27 +564,23 @@ class JavaTaintAbstractChecker extends TaintCheckerJava { * @param fclos */ getObj(fclos: any): any { - if ( - typeof fclos?._sid !== 'undefined' && - typeof fclos?._qid === 'undefined' && - typeof fclos?._this === 'undefined' - ) { - const index = fclos?._sid.indexOf('>.') - const result = index !== -1 ? fclos?._sid.substring(index + 2) : fclos?._sid - return result.replace('', '') + if (typeof fclos?.sid !== 'undefined' && typeof fclos?.qid === 'undefined' && typeof fclos?._this === 'undefined') { + const index = fclos?.sid.indexOf('>.') + const result = index !== -1 ? fclos?.sid.substring(index + 2) : fclos?.sid + return QidUnifyUtil.qidUnifyByRemoveAngleAndPrefix(result) } - if (typeof fclos?._qid !== 'undefined') { - const index = fclos._qid.indexOf('>.') - const result = index !== -1 ? fclos?._qid.substring(index + 2) : fclos?._qid - return result.replace('', '') + if (typeof fclos?.qid !== 'undefined') { + const index = fclos.qid.indexOf('>.') + const result = index !== -1 ? fclos?.qid.substring(index + 2) : fclos?.qid + return QidUnifyUtil.qidUnifyByRemoveAngleAndPrefix(result) } if (!(fclos === fclos?._this)) { return this.getObj(fclos._this) } - const index = fclos?._sid.indexOf('>.') - const result = index !== -1 ? fclos?._sid.substring(index + 2) : fclos?._sid + const index = fclos?.sid.indexOf('>.') + const result = index !== -1 ? fclos?.sid.substring(index + 2) : fclos?.sid if (result) { - return result.replace('', '') + return QidUnifyUtil.qidUnifyByRemoveAngleAndPrefix(result) } } diff --git a/src/checker/taint/java/java-taint-checker.ts b/src/checker/taint/java/java-taint-checker.ts index ff0dc25d..97c71b2e 100644 --- a/src/checker/taint/java/java-taint-checker.ts +++ b/src/checker/taint/java/java-taint-checker.ts @@ -36,7 +36,7 @@ class JavaTaintChecker extends JavaTaintAbstractChecker { if (Config.entryPointMode !== 'ONLY_CUSTOM') { logger.info('YASA will collect Entrypoint and Source') const { selfCollectSpringEntryPoints, selfCollectSpringTaintSource } = - SpringEntryPoint.getSpringEntryPointAndSource(topScope.packageManager) + SpringEntryPoint.getSpringEntryPointAndSource(topScope.context.packages) if (!_.isEmpty(selfCollectSpringTaintSource)) { this.checkerRuleConfigContent.sources = this.checkerRuleConfigContent.sources || {} @@ -77,9 +77,9 @@ class JavaTaintChecker extends JavaTaintAbstractChecker { } targetPackage = targetPackage.startsWith('.') ? targetPackage.slice(1) : targetPackage const arr = Loader.getPackageNameProperties(targetPackage) - let packageManagerT = topScope.packageManager + let packageManagerT = topScope.context.packages arr.forEach((path: any) => { - packageManagerT = packageManagerT?.field[path] + packageManagerT = packageManagerT?.members?.get(path) }) if (!packageManagerT || packageManagerT.vtype === 'undefine') { continue @@ -92,23 +92,7 @@ class JavaTaintChecker extends JavaTaintAbstractChecker { continue } - const scopeVal = Scoped({ - vtype: 'scope', - _sid: 'mock', - _id: 'mock', - field: {}, - parent: null, - }) - - const entryPoint = new EntryPoint(Constant.ENGIN_START_FUNCALL) - entryPoint.scopeVal = scopeVal - entryPoint.argValues = [] - entryPoint.functionName = entrypoint.functionName - entryPoint.filePath = entrypoint.filePath - entryPoint.attribute = entrypoint.attribute - entryPoint.packageName = entrypoint.packageName - entryPoint.entryPointSymVal = entryPointSymVal - this.entryPoints.push(entryPoint) + this.resolveAndPushEntryPoint(entryPointSymVal, entrypoint, func, analyzer, Scoped, EntryPoint, Constant) } } } diff --git a/src/checker/taint/js/egg-taint-checker.ts b/src/checker/taint/js/egg-taint-checker.ts index df55287f..63445f27 100644 --- a/src/checker/taint/js/egg-taint-checker.ts +++ b/src/checker/taint/js/egg-taint-checker.ts @@ -1,3 +1,5 @@ +import type { CallInfo } from '../../../engine/analyzer/common/call-args' + const _ = require('lodash') const BasicRuleHandler = require('../../common/rules-basic-handler') const IntroduceTaint = require('../common-kit/source-util') @@ -7,11 +9,6 @@ const Constant = require('../../../util/constant') const CommonUtil = require('../../../util/common-util') const Loader = require('../../../util/loader') const { matchSinkAtFuncCall } = require('../common-kit/sink-util') -const { - valueUtil: { - ValueUtil: { Scoped }, - }, -} = require('../../../engine/analyzer/common') const Config = require('../../../config') const eggHttpEgg = require('../../../engine/analyzer/javascript/egg/entrypoint-collector/egg-http') const SanitizerCheckerEgg = require('../../sanitizer/sanitizer-checker') @@ -19,6 +16,7 @@ const { handleException: handleExceptionEgg } = require('../../../engine/analyze const logger = require('../../../util/logger')(__filename) const TaintCheckerEgg = require('../taint-checker') const TaintOutputStrategyEgg = require('../../common/output/taint-output-strategy') +const QidUnifyUtil = require('../../../util/qid-unify-util') const TAINT_TAG_NAME_EGG = 'EGG_INPUT' @@ -67,7 +65,7 @@ class EggTaintChecker extends TaintCheckerEgg { return } try { - IntroduceTaint.introduceTaintAtIdentifier(node, info.res, this.sourceScope.value) + IntroduceTaint.introduceTaintAtIdentifier(analyzer, scope, node, info.res, this.sourceScope.value) } catch (e: any) { handleExceptionEgg( e, @@ -105,7 +103,8 @@ class EggTaintChecker extends TaintCheckerEgg { logger.info('YASA collecting egg source and entrypoint...') // eslint-disable-next-line prefer-const let { selfCollectEntryPoints, selfCollectTaintSource } = eggHttpEgg.getEggHttpEntryPointsAndSources( - topScope.fileManager + analyzer.fileManager, + analyzer ) if (_.isEmpty(selfCollectEntryPoints) && _.isEmpty(ruleConfigEntryPoints)) { @@ -156,12 +155,12 @@ class EggTaintChecker extends TaintCheckerEgg { // const arr = filepath.split("/").filter(str => str !== "").map(str => str.split(".").shift()); let fieldT = topScope arr.forEach((path: any) => { - fieldT = fieldT?.field[path] + fieldT = fieldT?.members?.get(path) }) if (!fieldT || fieldT.vtype === 'undefine') { - for (const mod in topScope.moduleManager.field) { - if (mod.includes(entrypoint.filePath) && topScope.moduleManager.field[mod].ast?.type === 'CompileUnit') { - fieldT = topScope.moduleManager.field[mod] + for (const mod of topScope.context.modules.members.keys()) { + if (mod.includes(entrypoint.filePath) && topScope.context.modules.members.get(mod)?.ast?.node?.type === 'CompileUnit') { + fieldT = topScope.context.modules.members.get(mod) break } } @@ -187,12 +186,12 @@ class EggTaintChecker extends TaintCheckerEgg { entryPoint.entryPointSymVal = entryPointSymVal this.entryPoints.push(entryPoint) } else { - if (!fieldT.ast || fieldT.ast.type !== 'CompileUnit') continue + if (!fieldT.ast.node || fieldT.ast.node.type !== 'CompileUnit') continue const entryPoint = new EntryPoint(Constant.ENGIN_START_FILE_BEGIN) entryPoint.scopeVal = fieldT entryPoint.argValues = undefined entryPoint.functionName = undefined - entryPoint.filePath = fieldT?.ast?.loc?.sourcefile + entryPoint.filePath = fieldT?.ast?.node?.loc?.sourcefile entryPoint.attribute = entrypoint.attribute entryPoint.packageName = undefined entryPoint.entryPointSymVal = fieldT @@ -221,11 +220,11 @@ class EggTaintChecker extends TaintCheckerEgg { if (Config.analyzer !== 'EggAnalyzer') { return } - const { fclos, argvalues } = info + const { fclos, callInfo } = info const funcCallArgTaintSource = this.checkerRuleConfigContent.sources?.FuncCallArgTaintSource - IntroduceTaint.introduceFuncArgTaintByRuleConfig(fclos?.object, node, argvalues, funcCallArgTaintSource) - this.checkSinkAtFunctionCall(node, fclos, argvalues) - this.checkByFieldMatch(node, fclos, argvalues, scope) + IntroduceTaint.introduceFuncArgTaintByRuleConfig(fclos?.object, node, callInfo, funcCallArgTaintSource) + this.checkSinkAtFunctionCall(node, fclos, callInfo, state) + this.checkByFieldMatch(node, fclos, callInfo, scope, state) } /** @@ -265,19 +264,20 @@ class EggTaintChecker extends TaintCheckerEgg { * * @param node * @param fclos - * @param argvalues + * @param callInfo + * @param state */ - checkSinkAtFunctionCall(node: any, fclos: any, argvalues: any) { + checkSinkAtFunctionCall(node: any, fclos: any, callInfo: CallInfo | undefined, state?: any) { const rules = this.checkerRuleConfigContent.sinks?.FuncCallTaintSink if (_.isEmpty(rules)) { return } - let rule = matchSinkAtFuncCall(node, fclos, rules) + let rule = matchSinkAtFuncCall(node, fclos, rules, callInfo) rule = rule.length > 0 ? rule[0] : null if (rule) { - const args = BasicRuleHandler.prepareArgs(argvalues, fclos, rule) + const args = BasicRuleHandler.prepareArgs(callInfo, fclos, rule) const sanitizers = SanitizerCheckerEgg.findSanitizerByIds(rule.sanitizerIds) const ndResultWithMatchedSanitizerTagsArray = SanitizerCheckerEgg.findTagAndMatchedSanitizer( node, @@ -304,7 +304,8 @@ class EggTaintChecker extends TaintCheckerEgg { fclos, TAINT_TAG_NAME_EGG, ruleName, - matchedSanitizerTags + matchedSanitizerTags, + state?.callstack ) if (!TaintOutputStrategyEgg.isNewFinding(this.resultManager, taintFlowFinding)) continue this.resultManager.newFinding(taintFlowFinding, TaintOutputStrategyEgg.outputStrategyId) @@ -319,8 +320,9 @@ class EggTaintChecker extends TaintCheckerEgg { * @param fclos * @param argvalues * @param scope + * @param state */ - checkByFieldMatch(node: any, fclos: any, argvalues: any, scope: any) { + checkByFieldMatch(node: any, fclos: any, callInfo: CallInfo | undefined, scope: any, state?: any) { const rules = this.checkerRuleConfigContent.sinks?.FuncCallTaintSink if (_.isEmpty(rules)) { return @@ -388,7 +390,7 @@ class EggTaintChecker extends TaintCheckerEgg { create ) if (matched) { - const args = BasicRuleHandler.prepareArgs(argvalues, fclos, rule) + const args = BasicRuleHandler.prepareArgs(callInfo, fclos, rule) const sanitizers = SanitizerCheckerEgg.findSanitizerByIds(rule.sanitizerIds) const ndResultWithMatchedSanitizerTagsArray = SanitizerCheckerEgg.findTagAndMatchedSanitizer( node, @@ -415,7 +417,8 @@ class EggTaintChecker extends TaintCheckerEgg { fclos, TAINT_TAG_NAME_EGG, ruleName, - matchedSanitizerTags + matchedSanitizerTags, + state?.callstack ) if (!TaintOutputStrategyEgg.isNewFinding(this.resultManager, taintFlowFinding)) continue @@ -432,26 +435,28 @@ class EggTaintChecker extends TaintCheckerEgg { * @param fclos */ getObj(fclos: any): any { - if (typeof fclos?._qid === 'undefined' && typeof fclos?._this === 'undefined') { - return fclos._sid?.replace('', '') + if (typeof fclos?.qid === 'undefined' && typeof fclos?._this === 'undefined') { + return QidUnifyUtil.qidUnifyByRemoveAngleAndPrefix(fclos.sid) } - if (typeof fclos?._qid !== 'undefined') { - let qid = fclos?._qid?.replace('Egg.Context', 'this.ctx') + if (typeof fclos?.qid !== 'undefined') { + let qid = fclos?.qid?.replace('Egg.Context', 'this.ctx') qid = qid?.replace('Egg.Application', 'this.app') qid = qid?.replace('this.app.service', 'this.ctx.service') qid = qid?.replace('Egg.Request', 'this.ctx.request') - if (fclos.ast?.loc?.sourcefile && fclos.ast?.loc?.sourcefile.startsWith(Config.maindirPrefix)) { - const prefix = fclos.ast.loc.sourcefile.substring(Config.maindirPrefix.length).split('.')[0] - if (prefix) { + if (fclos.ast?.node?.loc?.sourcefile && fclos.ast?.node?.loc?.sourcefile.startsWith(Config.maindirPrefix)) { + const prefix = fclos.ast.node.loc.sourcefile.substring(Config.maindirPrefix.length) + const lastDotIndex = prefix.lastIndexOf('.') + const result = lastDotIndex >= 0 ? prefix.substring(0, lastDotIndex) : prefix + if (result) { qid = qid?.substring(prefix.length + 1) } } - return qid?.replace('', '') + return QidUnifyUtil.qidUnifyByRemoveAngleAndPrefix(qid) } if (!(fclos === fclos?._this)) { return this.getObj(fclos._this) } - return fclos._sid?.replace('', '') + return QidUnifyUtil.qidUnifyByRemoveAngleAndPrefix(fclos.sid) } } diff --git a/src/checker/taint/js/express/express-taint-checker.ts b/src/checker/taint/js/express/express-taint-checker.ts index f24fb717..b80f9b93 100644 --- a/src/checker/taint/js/express/express-taint-checker.ts +++ b/src/checker/taint/js/express/express-taint-checker.ts @@ -1,3 +1,5 @@ +import type { CallInfo } from '../../../../engine/analyzer/common/call-args' + // checker加载逻辑重构后可打开,让stc不要用 const _ = require('lodash') const Rules = require('../../../common/rules-basic-handler') @@ -14,6 +16,7 @@ const SanitizerChecker = require('../../../sanitizer/sanitizer-checker') const TaintOutputStrategy = require('../../../common/output/taint-output-strategy') const { handleException } = require('../../../../engine/analyzer/common/exception-handler') const logger = require('../../../../util/logger')(__filename) +const QidUnifyUtil = require('../../../../util/qid-unify-util') const TAINT_TAG_NAME = 'EXPRESS_INPUT' @@ -63,7 +66,7 @@ class ExpressTaintChecker extends TaintChecker { if (config.analyzer !== 'JavaScriptAnalyzer') { return } - IntroduceTaint.introduceTaintAtIdentifier(node, info.res, this.sourceScope.value) + IntroduceTaint.introduceTaintAtIdentifier(analyzer, scope, node, info.res, this.sourceScope.value) } /** @@ -108,12 +111,12 @@ class ExpressTaintChecker extends TaintChecker { const arr = loader.getFilePathProperties(filepath, { caseStyle: 'lower' }) let fieldT = topScope arr.forEach((path: any) => { - fieldT = fieldT?.field[path] + fieldT = fieldT?.members?.get(path) }) if (!fieldT || fieldT.vtype === 'undefine') { - for (const mod in topScope.moduleManager.field) { - if (mod.includes(entrypoint.filePath) && topScope.moduleManager.field[mod].ast?.type === 'CompileUnit') { - fieldT = topScope.moduleManager.field[mod] + for (const mod of topScope.context.modules.members.keys()) { + if (mod.includes(entrypoint.filePath) && topScope.context.modules.members.get(mod)?.ast?.node?.type === 'CompileUnit') { + fieldT = topScope.context.modules.members.get(mod) break } } @@ -137,12 +140,12 @@ class ExpressTaintChecker extends TaintChecker { entryPoint.entryPointSymVal = entryPointSymVal this.entryPoints.push(entryPoint) } else { - if (!fieldT.ast || fieldT.ast.type !== 'CompileUnit') continue + if (!fieldT.ast.node || fieldT.ast.node.type !== 'CompileUnit') continue const entryPoint = new EntryPoint(constValue.ENGIN_START_FILE_BEGIN) entryPoint.scopeVal = fieldT entryPoint.argValues = undefined entryPoint.functionName = undefined - entryPoint.filePath = fieldT?.ast?.loc?.sourcefile + entryPoint.filePath = fieldT?.ast?.node?.loc?.sourcefile entryPoint.attribute = entrypoint.attribute entryPoint.packageName = undefined entryPoint.entryPointSymVal = fieldT @@ -173,12 +176,12 @@ class ExpressTaintChecker extends TaintChecker { return } - const { fclos, argvalues } = info + const { fclos, callInfo } = info const funcCallArgTaintSource = this.checkerRuleConfigContent.sources?.FuncCallArgTaintSource - IntroduceTaint.introduceFuncArgTaintByRuleConfig(fclos?.object, node, argvalues, funcCallArgTaintSource) - this.checkSinkAtFunctionCall(node, fclos, argvalues) - this.checkByFieldMatch(node, fclos, argvalues, scope) + IntroduceTaint.introduceFuncArgTaintByRuleConfig(fclos?.object, node, callInfo, funcCallArgTaintSource) + this.checkSinkAtFunctionCall(node, fclos, callInfo, state) + this.checkByFieldMatch(node, fclos, callInfo, scope, state) } /** @@ -219,18 +222,19 @@ class ExpressTaintChecker extends TaintChecker { * @param node * @param fclos * @param argvalues + * @param state */ - checkSinkAtFunctionCall(node: any, fclos: any, argvalues: any) { + checkSinkAtFunctionCall(node: any, fclos: any, callInfo: CallInfo | undefined, state?: any) { const rules = this.checkerRuleConfigContent.sinks?.FuncCallTaintSink if (_.isEmpty(rules)) { return } - let rule = matchSinkAtFuncCall(node, fclos, rules) + let rule = matchSinkAtFuncCall(node, fclos, rules, callInfo) rule = rule.length > 0 ? rule[0] : null if (rule) { - const args = Rules.prepareArgs(argvalues, fclos, rule) + const args = Rules.prepareArgs(callInfo, fclos, rule) const sanitizers = SanitizerChecker.findSanitizerByIds(rule.sanitizerIds) const ndResultWithMatchedSanitizerTagsArray = SanitizerChecker.findTagAndMatchedSanitizer( node, @@ -257,7 +261,8 @@ class ExpressTaintChecker extends TaintChecker { fclos, TAINT_TAG_NAME, ruleName, - matchedSanitizerTags + matchedSanitizerTags, + state?.callstack ) if (!TaintOutputStrategy.isNewFinding(this.resultManager, taintFlowFinding)) continue this.resultManager.newFinding(taintFlowFinding, TaintOutputStrategy.outputStrategyId) @@ -272,8 +277,9 @@ class ExpressTaintChecker extends TaintChecker { * @param fclos * @param argvalues * @param scope + * @param state */ - checkByFieldMatch(node: any, fclos: any, argvalues: any, scope: any) { + checkByFieldMatch(node: any, fclos: any, callInfo: CallInfo | undefined, scope: any, state?: any) { let rules = this.checkerRuleConfigContent.sinks?.FuncCallTaintSink if (_.isEmpty(rules)) { return @@ -342,7 +348,7 @@ class ExpressTaintChecker extends TaintChecker { create ) if (matched) { - const args = Rules.prepareArgs(argvalues, fclos, rule) + const args = Rules.prepareArgs(callInfo, fclos, rule) const sanitizers = SanitizerChecker.findSanitizerByIds(rule.sanitizerIds) const ndResultWithMatchedSanitizerTagsArray = SanitizerChecker.findTagAndMatchedSanitizer( node, @@ -369,7 +375,8 @@ class ExpressTaintChecker extends TaintChecker { fclos, TAINT_TAG_NAME, ruleName, - matchedSanitizerTags + matchedSanitizerTags, + state?.callstack ) if (!TaintOutputStrategy.isNewFinding(this.resultManager, taintFlowFinding)) continue @@ -386,26 +393,25 @@ class ExpressTaintChecker extends TaintChecker { * @param fclos */ getObj(fclos: any): any { - if (typeof fclos?._qid === 'undefined' && typeof fclos?._this === 'undefined') { - return fclos._sid?.replace('', '') + if (typeof fclos?.qid === 'undefined' && typeof fclos?._this === 'undefined') { + return QidUnifyUtil.qidUnifyByRemoveAngleAndPrefix(fclos.sid) } - if (typeof fclos?._qid !== 'undefined') { - let qid = fclos._qid?.replace('Egg.Context', 'this.ctx') - qid = qid?.replace('Egg.Application', 'this.app') - qid = qid?.replace('this.app.service', 'this.ctx.service') - qid = qid?.replace('Egg.Request', 'this.ctx.request') - if (fclos.ast?.loc?.sourcefile && fclos.ast?.loc?.sourcefile.startsWith(config.maindirPrefix)) { - const prefix = fclos.ast.loc.sourcefile.substring(config.maindirPrefix.length).split('.')[0] - if (prefix) { + if (typeof fclos?.qid !== 'undefined') { + let { qid } = fclos + if (fclos.ast?.node?.loc?.sourcefile && fclos.ast?.node?.loc?.sourcefile.startsWith(config.maindirPrefix)) { + const prefix = fclos.ast.node.loc.sourcefile.substring(config.maindirPrefix.length) + const lastDotIndex = prefix.lastIndexOf('.') + const result = lastDotIndex >= 0 ? prefix.substring(0, lastDotIndex) : prefix + if (result) { qid = qid?.substring(prefix.length + 1) } } - return qid?.replace('', '') + return QidUnifyUtil.qidUnifyByRemoveAngleAndPrefix(qid) } if (!(fclos === fclos?._this)) { return this.getObj(fclos._this) } - return fclos._sid?.replace('', '') + return QidUnifyUtil.qidUnifyByRemoveAngleAndPrefix(fclos.sid) } } diff --git a/src/checker/taint/js/js-taint-checker.ts b/src/checker/taint/js/js-taint-checker.ts index 230fea7a..face6f97 100644 --- a/src/checker/taint/js/js-taint-checker.ts +++ b/src/checker/taint/js/js-taint-checker.ts @@ -1,3 +1,5 @@ +import type { CallInfo } from '../../../engine/analyzer/common/call-args' + // checker加载逻辑重构后可打开,让stc不要用 const _ = require('lodash') const Rules = require('../../common/rules-basic-handler') @@ -8,12 +10,8 @@ const constValue = require('../../../util/constant') const commonUtil = require('../../../util/common-util') const loader = require('../../../util/loader') const { matchSinkAtFuncCall } = require('../common-kit/sink-util') +const QidUnifyUtil = require('../../../util/qid-unify-util') const TaintChecker = require('../taint-checker') -const { - valueUtil: { - ValueUtil: { Scoped }, - }, -} = require('../../../engine/analyzer/common') const config = require('../../../config') const SanitizerChecker = require('../../sanitizer/sanitizer-checker') const TaintOutputStrategy = require('../../common/output/taint-output-strategy') @@ -65,7 +63,7 @@ class JsTaintChecker extends TaintChecker { if (config.analyzer !== 'JavaScriptAnalyzer') { return } - IntroduceTaint.introduceTaintAtIdentifier(node, info.res, this.sourceScope.value) + IntroduceTaint.introduceTaintAtIdentifier(analyzer, scope, node, info.res, this.sourceScope.value) } /** @@ -106,15 +104,15 @@ class JsTaintChecker extends TaintChecker { // const arr = filepath.split("/").filter(str => str !== "").map(str => str.split(".").shift()); let fieldT = topScope arr.forEach((path: any) => { - fieldT = fieldT?.field[path] + fieldT = fieldT?.members?.get(path) }) if (!fieldT || fieldT.vtype === 'undefine') { - for (const mod in topScope.moduleManager.field) { + for (const mod of topScope.context.modules.members.keys()) { if ( mod.includes(entrypoint.filePath) && - topScope.moduleManager.field[mod].ast?.type === 'CompileUnit' + topScope.context.modules.members.get(mod)?.ast?.node?.type === 'CompileUnit' ) { - fieldT = topScope.moduleManager.field[mod] + fieldT = topScope.context.modules.members.get(mod) break } } @@ -138,12 +136,12 @@ class JsTaintChecker extends TaintChecker { entryPoint.entryPointSymVal = entryPointSymVal this.entryPoints.push(entryPoint) } else { - if (!fieldT.ast || fieldT.ast.type !== 'CompileUnit') continue + if (!fieldT.ast.node || fieldT.ast.node.type !== 'CompileUnit') continue const entryPoint = new EntryPoint(constValue.ENGIN_START_FILE_BEGIN) entryPoint.scopeVal = fieldT entryPoint.argValues = undefined entryPoint.functionName = undefined - entryPoint.filePath = fieldT?.ast?.loc?.sourcefile + entryPoint.filePath = fieldT?.ast?.node?.loc?.sourcefile entryPoint.attribute = entrypoint.attribute entryPoint.packageName = undefined entryPoint.entryPointSymVal = fieldT @@ -165,9 +163,10 @@ class JsTaintChecker extends TaintChecker { const fullCallGraphFileEntryPoint = require('../../common/full-callgraph-file-entrypoint') fullCallGraphFileEntryPoint.makeFullCallGraph(analyzer) const fullCallGraphEntrypoint = fullCallGraphFileEntryPoint.getAllEntryPointsUsingCallGraph( - analyzer.ainfo?.callgraph + analyzer.ainfo?.callgraph, + analyzer ) - const fullFileEntrypoint = fullCallGraphFileEntryPoint.getAllFileEntryPointsUsingFileManager(analyzer.fileManager) + const fullFileEntrypoint = fullCallGraphFileEntryPoint.getAllFileEntryPointsUsingFileManager(analyzer) this.entryPoints.push(...fullCallGraphEntrypoint) this.entryPoints.push(...fullFileEntrypoint) } @@ -186,11 +185,11 @@ class JsTaintChecker extends TaintChecker { if (config.analyzer !== 'JavaScriptAnalyzer') { return } - const { fclos, argvalues } = info + const { fclos, callInfo } = info const funcCallArgTaintSource = this.checkerRuleConfigContent.sources?.FuncCallArgTaintSource - IntroduceTaint.introduceFuncArgTaintByRuleConfig(fclos?.object, node, argvalues, funcCallArgTaintSource) - this.checkSinkAtFunctionCall(node, fclos, argvalues) - this.checkByFieldMatch(node, fclos, argvalues, scope) + IntroduceTaint.introduceFuncArgTaintByRuleConfig(fclos?.object, node, callInfo, funcCallArgTaintSource) + this.checkSinkAtFunctionCall(node, fclos, callInfo, state) + this.checkByFieldMatch(node, fclos, callInfo, scope, state) } /** @@ -230,19 +229,20 @@ class JsTaintChecker extends TaintChecker { * * @param node * @param fclos - * @param argvalues + * @param callInfo + * @param state */ - checkSinkAtFunctionCall(node: any, fclos: any, argvalues: any) { + checkSinkAtFunctionCall(node: any, fclos: any, callInfo: CallInfo | undefined, state?: any) { const rules = this.checkerRuleConfigContent.sinks?.FuncCallTaintSink if (_.isEmpty(rules)) { return } - let rule = matchSinkAtFuncCall(node, fclos, rules) + let rule = matchSinkAtFuncCall(node, fclos, rules, callInfo) rule = rule.length > 0 ? rule[0] : null if (rule) { - const args = Rules.prepareArgs(argvalues, fclos, rule) + const args = Rules.prepareArgs(callInfo, fclos, rule) const sanitizers = SanitizerChecker.findSanitizerByIds(rule.sanitizerIds) const ndResultWithMatchedSanitizerTagsArray = SanitizerChecker.findTagAndMatchedSanitizer( node, @@ -269,7 +269,8 @@ class JsTaintChecker extends TaintChecker { fclos, TAINT_TAG_NAME_JS_TAINT, ruleName, - matchedSanitizerTags + matchedSanitizerTags, + state?.callstack ) if (!TaintOutputStrategy.isNewFinding(this.resultManager, taintFlowFinding)) continue this.resultManager.newFinding(taintFlowFinding, TaintOutputStrategy.outputStrategyId) @@ -282,10 +283,11 @@ class JsTaintChecker extends TaintChecker { * * @param node * @param fclos - * @param argvalues + * @param callInfo * @param scope + * @param state */ - checkByFieldMatch(node: any, fclos: any, argvalues: any, scope: any) { + checkByFieldMatch(node: any, fclos: any, callInfo: CallInfo | undefined, scope: any, state?: any) { const rules = this.checkerRuleConfigContent.sinks?.FuncCallTaintSink if (_.isEmpty(rules)) { return @@ -353,7 +355,7 @@ class JsTaintChecker extends TaintChecker { create ) if (matched) { - const args = Rules.prepareArgs(argvalues, fclos, rule) + const args = Rules.prepareArgs(callInfo, fclos, rule) const sanitizers = SanitizerChecker.findSanitizerByIds(rule.sanitizerIds) const ndResultWithMatchedSanitizerTagsArray = SanitizerChecker.findTagAndMatchedSanitizer( node, @@ -380,7 +382,8 @@ class JsTaintChecker extends TaintChecker { fclos, TAINT_TAG_NAME_JS_TAINT, ruleName, - matchedSanitizerTags + matchedSanitizerTags, + state?.callstack ) if (!TaintOutputStrategy.isNewFinding(this.resultManager, taintFlowFinding)) continue @@ -397,23 +400,25 @@ class JsTaintChecker extends TaintChecker { * @param fclos */ getObj(fclos: any): any { - if (typeof fclos?._qid === 'undefined' && typeof fclos?._this === 'undefined') { - return fclos._sid?.replace('', '') + if (typeof fclos?.qid === 'undefined' && typeof fclos?._this === 'undefined') { + return QidUnifyUtil.qidUnifyByRemoveAngleAndPrefix(fclos.sid) } - if (typeof fclos?._qid !== 'undefined') { - let qid = fclos?._qid - if (fclos.ast?.loc?.sourcefile && fclos.ast?.loc?.sourcefile.startsWith(config.maindirPrefix)) { - const prefix = fclos.ast.loc.sourcefile.substring(config.maindirPrefix.length).split('.')[0] - if (prefix) { + if (typeof fclos?.qid !== 'undefined') { + let qid = fclos?.qid + if (fclos.ast?.node?.loc?.sourcefile && fclos.ast?.node?.loc?.sourcefile.startsWith(config.maindirPrefix)) { + const prefix = fclos.ast.node.loc.sourcefile.substring(config.maindirPrefix.length) + const lastDotIndex = prefix.lastIndexOf('.') + const result = lastDotIndex >= 0 ? prefix.substring(0, lastDotIndex) : prefix + if (result) { qid = qid?.substring(prefix.length + 1) } } - return qid?.replace('', '') + return QidUnifyUtil.qidUnifyByRemoveAngleAndPrefix(qid) } if (!(fclos === fclos?._this)) { return this.getObj(fclos._this) } - return fclos._sid?.replace('', '') + return QidUnifyUtil.qidUnifyByRemoveAngleAndPrefix(fclos.sid) } } diff --git a/src/checker/taint/js/source-util-for-egg.ts b/src/checker/taint/js/source-util-for-egg.ts index d61e829e..05f1c16d 100644 --- a/src/checker/taint/js/source-util-for-egg.ts +++ b/src/checker/taint/js/source-util-for-egg.ts @@ -1,3 +1,4 @@ +const QidUnifyUtil = require('../../../util/qid-unify-util') const { markTaintSource } = require('../common-kit/source-util') const BasicRuleHandler = require('../../common/rules-basic-handler') @@ -25,7 +26,7 @@ function _introduceTaintAtMemberAccess(res: any, sourceScopeVal: any, node: any) if (!BasicRuleHandler.getPreprocessReady()) { return } - if (typeof res._qid === 'undefined' || typeof res._qid !== 'string') { + if (typeof res.qid === 'undefined' || typeof res.qid !== 'string') { return res } if (markTaintAtMemberAccess(res, sourceScopeVal, node)) { @@ -41,15 +42,15 @@ function _introduceTaintAtMemberAccess(res: any, sourceScopeVal: any, node: any) * @param node */ function markTaintAtMemberAccess(res: any, sourceScopeVal: any, node: any): boolean { - if (typeof res._qid !== 'undefined') { - let qid = res._qid + if (typeof res.qid !== 'undefined') { + let { qid } = res if (typeof qid !== 'string') { return false } + qid = QidUnifyUtil.qidUnifyByRemoveAngleAndPrefix(qid) qid = qid?.replace('Egg.Context', 'this.ctx') qid = qid?.replace('Egg.Application', 'this.app') qid = qid?.replace('Egg.Request', 'this.ctx.request') - qid = qid?.replace('\', '') // 适配ctx=this const sourceFile = node.loc?.sourcefile @@ -63,9 +64,10 @@ function markTaintAtMemberAccess(res: any, sourceScopeVal: any, node: any): bool qid = qid.charAt(0).toLowerCase() + qid.slice(1) className = className.charAt(0).toLowerCase() + className.slice(1) qid = qid.replace(className, 'this.ctx') - } else if (qid.startsWith('module.exports')) { - // module.exports场景 - qid = qid.replace('module.exports', 'this.ctx') + } + if (qid.includes('module.exports')) { + // module.exports场景,去掉module.exports前面的所有部分 + qid = qid.replace(/.*module\.exports/, 'this.ctx') } } } diff --git a/src/checker/taint/python/django-taint-checker.ts b/src/checker/taint/python/django-taint-checker.ts index 3853d7d8..cebf58c2 100644 --- a/src/checker/taint/python/django-taint-checker.ts +++ b/src/checker/taint/python/django-taint-checker.ts @@ -1,4 +1,4 @@ -const PythonTaintAbstractChecker = require('./python-taint-abstract-checker') +const { PythonTaintAbstractChecker } = require('./python-taint-abstract-checker') const completeEntryPoint = require('../common-kit/entry-points-util') const { extractRelativePath } = require('../../../util/file-util') @@ -64,6 +64,7 @@ class DjangoTaintChecker extends PythonTaintAbstractChecker { if (registerFile.size === 0 || !registerFile.has(fileName)) { return } + if (node.left.name === 'urlpatterns') { const { right } = node this.collectDjangoEntrypointAndSource(analyzer, scope, state, right) @@ -131,19 +132,31 @@ class DjangoTaintChecker extends PythonTaintAbstractChecker { analyzer.entryPoints.push(completeEntryPoint(ep)) if (targetSrcName.length > 0) { const targetName = targetSrcName[0] - for (const param of ep.fdef.parameters) { + for (const param of ep.ast.fdef.parameters) { if (param.id.name === targetName) { this.sourceScope.value.push({ path: param.id.name, kind: 'PYTHON_INPUT', scopeFile: extractRelativePath(param?.loc?.sourcefile, Config.maindir), - scopeFunc: ep.fdef?.id?.name, - locStart: param.loc.start.line, - locEnd: param.loc.end.line, + scopeFunc: ep.ast.fdef?.id?.name, + locStart: param.loc.start?.line, + locEnd: param.loc.end?.line, }) } } } + for (const param of ep.ast.fdef.parameters) { + if (param.id.name === 'request') { + this.sourceScope.value.push({ + path: param.id.name, + kind: 'PYTHON_INPUT', + scopeFile: extractRelativePath(param?.loc?.sourcefile, Config.maindir), + scopeFunc: ep.ast.fdef?.id?.name, + locStart: param.loc.start.line, + locEnd: param.loc.end.line, + }) + } + } } } @@ -172,15 +185,15 @@ class DjangoTaintChecker extends PythonTaintAbstractChecker { if (targetSrcName.length > 0) { const targetName = targetSrcName[0] for (const ep of entrypoints as any[]) { - for (const param of ep.fdef.parameters) { + for (const param of ep.ast.fdef.parameters) { if (param.id.name === targetName) { this.sourceScope.value.push({ path: param.id.name, kind: 'PYTHON_INPUT', scopeFile: extractRelativePath(param?.loc?.sourcefile, Config.maindir), - scopeFunc: ep.fdef?.id?.name, - locStart: param.loc.start.line, - locEnd: param.loc.end.line, + scopeFunc: ep.ast.fdef?.id?.name, + locStart: param.loc.start?.line, + locEnd: param.loc.end?.line, }) } } @@ -188,6 +201,18 @@ class DjangoTaintChecker extends PythonTaintAbstractChecker { } } else { for (const ep of entrypoints as any[]) { + for (const param of ep.ast.fdef.parameters) { + if (param.id.name === 'request') { + this.sourceScope.value.push({ + path: param.id.name, + kind: 'PYTHON_INPUT', + scopeFile: extractRelativePath(param?.loc?.sourcefile, Config.maindir), + scopeFunc: ep.ast.fdef?.id?.name, + locStart: param.loc.start.line, + locEnd: param.loc.end.line, + }) + } + } analyzer.entryPoints.push(completeEntryPoint(ep)) } } diff --git a/src/checker/taint/python/python-default-taint-checker.ts b/src/checker/taint/python/python-default-taint-checker.ts index 4e0225bc..6ff8ca84 100644 --- a/src/checker/taint/python/python-default-taint-checker.ts +++ b/src/checker/taint/python/python-default-taint-checker.ts @@ -1,20 +1,19 @@ -import { handleException } from '../../../engine/analyzer/common/exception-handler' - const _ = require('lodash') -const PythonTaintAbstractChecker = require('./python-taint-abstract-checker') +const { PythonTaintAbstractChecker } = require('./python-taint-abstract-checker') const CommonUtil = require('../../../util/common-util') const { findPythonFcEntryPointAndSource, + buildFclosIndex, + lookupFclos, } = require('../../../engine/analyzer/python/common/entrypoint-collector/python-entrypoint') const Constant = require('../../../util/constant') const EntryPoint = require('../../../engine/analyzer/common/entrypoint') -const AstUtil = require('../../../util/ast-util') const Config = require('../../../config') -const FileUtil = require('../../../util/file-util') const { extractRelativePath } = require('../../../util/file-util') const logger = require('../../../util/logger')(__filename) +const { loadPythonDefaultRule } = require('./python-taint-abstract-checker') const TAINT_TAG_NAME_PYTHON_DEFAULT = 'PYTHON_INPUT' @@ -40,7 +39,8 @@ class PythonDefaultTaintChecker extends PythonTaintAbstractChecker { * @param info */ triggerAtStartOfAnalyze(analyzer: any, scope: any, node: any, state: any, info: any) { - const { moduleManager, fileManager } = analyzer + const moduleManager = analyzer.topScope.context.modules + const fileManager = analyzer.topScope.context.files this.prepareEntryPoints(analyzer, Config.maindir, moduleManager, fileManager) analyzer.entryPoints.push(...this.entryPoints) this.addSourceTagForSourceScope(TAINT_TAG_NAME_PYTHON_DEFAULT, this.sourceScope.value) @@ -60,7 +60,7 @@ class PythonDefaultTaintChecker extends PythonTaintAbstractChecker { const { entrypoints: ruleConfigEntryPoints } = this.checkerRuleConfigContent if (Config.entryPointMode !== 'ONLY_CUSTOM') { - const pythonDefaultRule = this.loadPythonDefaultRule() + const pythonDefaultRule = loadPythonDefaultRule() if (pythonDefaultRule[0].checkerIds.includes(this.getCheckerId())) { this.checkerRuleConfigContent.sources = this.checkerRuleConfigContent.sources || {} this.checkerRuleConfigContent.sources.TaintSource = this.checkerRuleConfigContent.sources.TaintSource || [] @@ -71,7 +71,11 @@ class PythonDefaultTaintChecker extends PythonTaintAbstractChecker { : [this.checkerRuleConfigContent.sources.TaintSource] this.checkerRuleConfigContent.sources.TaintSource.push(...pythonDefaultRule[0].sources.TaintSource) } - const { pyFcEntryPointArray, pyFcEntryPointSourceArray } = findPythonFcEntryPointAndSource(dir, fileManager) + const { pyFcEntryPointArray, pyFcEntryPointSourceArray } = findPythonFcEntryPointAndSource( + dir, + fileManager, + analyzer + ) if (pyFcEntryPointArray) { funCallEntryPoints.push(...pyFcEntryPointArray) } @@ -104,26 +108,20 @@ class PythonDefaultTaintChecker extends PythonTaintAbstractChecker { } } + // 构建 fclos 索引,一次遍历替代多次查找 + const fclosIndex = buildFclosIndex(moduleManager, dir, extractRelativePath) + for (const funCallEntryPoint of funCallEntryPoints) { - let valFuncs = AstUtil.satisfy( - moduleManager, - (n: any) => - n.vtype === 'fclos' && - extractRelativePath(n?.ast?.loc?.sourcefile, dir) === funCallEntryPoint.filePath && - n?.ast?.id?.name === funCallEntryPoint.functionName, - (node: any, prop: any) => prop === 'field', - null, - true - ) + // 使用索引查找,O(1) 操作 + let valFuncs = lookupFclos(fclosIndex, funCallEntryPoint.filePath, funCallEntryPoint.functionName) + if (_.isEmpty(valFuncs)) { logger.info('match entryPoint fail') continue } - if (Array.isArray(valFuncs)) { - valFuncs = _.uniqBy(valFuncs, (value: any) => value.fdef) - } else { - valFuncs = [valFuncs] - } + + // 去重 + valFuncs = _.uniqBy(valFuncs, (value: any) => value.ast.fdef) for (const valFunc of valFuncs) { const entryPoint = new EntryPoint(Constant.ENGIN_START_FUNCALL) @@ -138,13 +136,14 @@ class PythonDefaultTaintChecker extends PythonTaintAbstractChecker { for (const fileEntryPoint of fileEntryPoints) { const fullFilePath = `${Config.maindir}${fileEntryPoint.filePath}`.replace('//', '/') - const file = fileManager[fullFilePath] - if (file?.ast?.type === 'CompileUnit') { + const fileUuid = fileManager[fullFilePath] + const file = analyzer.symbolTable.get(fileUuid) + if (file?.ast?.node?.type === 'CompileUnit') { const entryPoint = new EntryPoint(Constant.ENGIN_START_FILE_BEGIN) entryPoint.scopeVal = file entryPoint.argValues = undefined entryPoint.functionName = undefined - entryPoint.filePath = file?.ast?.sourcefile || file?.ast?.loc?.sourcefile + entryPoint.filePath = file?.ast?.node?.sourcefile || file?.ast?.node?.loc?.sourcefile entryPoint.attribute = fileEntryPoint.attribute entryPoint.packageName = undefined entryPoint.entryPointSymVal = file @@ -157,29 +156,16 @@ class PythonDefaultTaintChecker extends PythonTaintAbstractChecker { if (Config.entryPointMode !== 'ONLY_CUSTOM') { fullCallGraphFileEntryPoint.makeFullCallGraph(analyzer) const fullCallGraphEntrypoint = fullCallGraphFileEntryPoint.getAllEntryPointsUsingCallGraph( - analyzer.ainfo?.callgraph + analyzer.ainfo?.callgraph, + analyzer ) - const fullFileEntrypoint = fullCallGraphFileEntryPoint.getAllFileEntryPointsUsingFileManager(analyzer.fileManager) + const fullFileEntrypoint = fullCallGraphFileEntryPoint.getAllFileEntryPointsUsingFileManager(analyzer) this.entryPoints.push(...fullCallGraphEntrypoint) this.entryPoints.push(...fullFileEntrypoint) } CommonUtil.initSourceScopeByTaintSourceWithLoc(this.sourceScope, this.checkerRuleConfigContent.sources?.TaintSource) } - - /** - * load python default rule - */ - loadPythonDefaultRule() { - let pythonDefaultRule - try { - const rulePath = FileUtil.getAbsolutePath('./resource/python/python-default-rule.json') - pythonDefaultRule = FileUtil.loadJSONfile(rulePath) - } catch (e) { - handleException(e, 'Error occurred in load python default rule', 'Error occurred in load python default rule') - } - return pythonDefaultRule - } } module.exports = PythonDefaultTaintChecker diff --git a/src/checker/taint/python/python-taint-abstract-checker.ts b/src/checker/taint/python/python-taint-abstract-checker.ts index f4ac5fa1..9ea5da23 100644 --- a/src/checker/taint/python/python-taint-abstract-checker.ts +++ b/src/checker/taint/python/python-taint-abstract-checker.ts @@ -1,10 +1,18 @@ +import type { CallInfo } from '../../../engine/analyzer/common/call-args' + const _ = require('lodash') +const commonUtil = require('../../../util/common-util') +const config = require('../../../config') +const { handleException } = require('../../../engine/analyzer/common/exception-handler') + const IntroduceTaint = require('../common-kit/source-util') const BasicRuleHandler = require('../../common/rules-basic-handler') const SanitizerChecker = require('../../sanitizer/sanitizer-checker') const { matchSinkAtFuncCall, matchRegex } = require('../common-kit/sink-util') const TaintChecker = require('../taint-checker') const TaintOutputStrategy = require('../../common/output/taint-output-strategy') +const QidUnifyUtil = require('../../../util/qid-unify-util') +const FileUtil = require('../../../util/file-util') const TAINT_TAG_NAME_PYTHON = 'PYTHON_INPUT' @@ -21,7 +29,25 @@ class PythonTaintAbstractChecker extends TaintChecker { * @param info */ triggerAtIdentifier(analyzer: any, scope: any, node: any, state: any, info: any) { - IntroduceTaint.introduceTaintAtIdentifier(node, info.res, this.sourceScope.value) + const result = IntroduceTaint.introduceTaintAtIdentifier(analyzer, scope, node, info.res, this.sourceScope.value) + if (result !== undefined) { + info.res = result + } + } + + /** + * + * @param analyzer + * @param scope + * @param node + * @param state + * @param info + */ + triggerAtFunctionDefinition(analyzer: any, scope: any, node: any, state: any, info: any) { + if (config.analyzer !== 'PythonAnalyzer') { + return + } + commonUtil.fillSourceScope(info.fclos, this.sourceScope) } /** @@ -33,11 +59,11 @@ class PythonTaintAbstractChecker extends TaintChecker { * @param info */ triggerAtFunctionCallBefore(analyzer: any, scope: any, node: any, state: any, info: any) { - const { fclos, argvalues } = info + const { fclos, callInfo } = info const funcCallArgTaintSource = this.checkerRuleConfigContent.sources?.FuncCallArgTaintSource - IntroduceTaint.introduceFuncArgTaintByRuleConfig(fclos?.object, node, argvalues, funcCallArgTaintSource) - this.checkByNameMatch(node, fclos, argvalues) - this.checkByFieldMatch(node, fclos, argvalues) + IntroduceTaint.introduceFuncArgTaintByRuleConfig(fclos?.object, node, callInfo, funcCallArgTaintSource) + this.checkByNameMatch(node, fclos, callInfo, state) + this.checkByFieldMatch(node, fclos, callInfo, state) } /** @@ -60,18 +86,20 @@ class PythonTaintAbstractChecker extends TaintChecker { * @param node * @param fclos * @param argvalues + * @param callInfo + * @param state * @returns {boolean} */ - checkByNameMatch(node: any, fclos: any, argvalues: any) { + checkByNameMatch(node: any, fclos: any, callInfo: CallInfo | undefined, state?: any) { const rules = this.checkerRuleConfigContent.sinks?.FuncCallTaintSink if (_.isEmpty(rules)) { return } - let rule = matchSinkAtFuncCall(node, fclos, rules) + let rule = matchSinkAtFuncCall(node, fclos, rules, callInfo) rule = rule.length > 0 ? rule[0] : null if (rule) { - this.findArgsAndAddNewFinding(node, argvalues, fclos, rule) + this.findArgsAndAddNewFinding(node, callInfo, fclos, rule, state) } } @@ -80,9 +108,28 @@ class PythonTaintAbstractChecker extends TaintChecker { * @param node * @param fclos * @param argvalues - * @param scope + * @param state + * @param qid */ - checkByFieldMatch(node: any, fclos: any, argvalues: any) { + // 去除 qid 中每个 `.` 分隔段的调用参数元数据,如 connect(with(config)) → connect + stripCallMetadata(qid: string): string { + return qid + .split('.') + .map((seg) => { + const parenIdx = seg.indexOf('(') + return parenIdx >= 0 ? seg.substring(0, parenIdx) : seg + }) + .join('.') + } + + /** + * + * @param node + * @param fclos + * @param callInfo + * @param state + */ + checkByFieldMatch(node: any, fclos: any, callInfo: CallInfo | undefined, state?: any) { const rules = this.checkerRuleConfigContent.sinks?.FuncCallTaintSink if (_.isEmpty(rules)) { return @@ -97,15 +144,21 @@ class PythonTaintAbstractChecker extends TaintChecker { } if (rule.fsig) { if (rule.fsig === callFull) { - this.findArgsAndAddNewFinding(node, argvalues, fclos, rule) + this.findArgsAndAddNewFinding(node, callInfo, fclos, rule, state) + return true + } + // 去除参数元数据后做后缀匹配 + const stripped = this.stripCallMetadata(callFull) + if (stripped.endsWith(rule.fsig)) { + this.findArgsAndAddNewFinding(node, callInfo, fclos, rule, state) return true } } else { if (!rule.fregex) { return false } - if (callFull.type === 'MemberAccess' && matchRegex(rule.fregex, fclos._qid)) { - this.findArgsAndAddNewFinding(node, argvalues, fclos, rule) + if (callFull.type === 'MemberAccess' && matchRegex(rule.fregex, fclos.qid)) { + this.findArgsAndAddNewFinding(node, callInfo, fclos, rule, state) return true } } @@ -118,27 +171,24 @@ class PythonTaintAbstractChecker extends TaintChecker { * @param fclos */ getObj(fclos: any): any { - if ( - typeof fclos?._sid !== 'undefined' && - typeof fclos?._qid === 'undefined' && - typeof fclos?._this === 'undefined' - ) { - const index = fclos?._sid.indexOf('>.') - const result = index !== -1 ? fclos?._sid.substring(index + 2) : fclos?._sid - return result.replace('', '').replace('()', '') + if (typeof fclos?.sid !== 'undefined' && typeof fclos?.qid === 'undefined' && typeof fclos?._this === 'undefined') { + const index = fclos?.sid.indexOf('>.') + return index !== -1 ? fclos?.sid.substring(index + 2) : fclos?.sid } - if (typeof fclos?._qid !== 'undefined') { - const index = fclos._qid.indexOf('>.') - const result = index !== -1 ? fclos?._qid.substring(index + 2) : fclos?._qid - return result.replace('', '').replace('()', '') + if (typeof fclos?.qid !== 'undefined' && typeof fclos.qid === 'string') { + const index = fclos.qid.indexOf('>.') + const result = index !== -1 ? fclos?.qid.substring(index + 2) : fclos?.qid + return QidUnifyUtil.qidUnifyByRemoveAngleAndPrefix(result) } if (!(fclos === fclos?._this)) { return this.getObj(fclos._this) } - const index = fclos?._sid.indexOf('>.') - const result = index !== -1 ? fclos?._sid.substring(index + 2) : fclos?._sid - if (result) { - return result.replace('', '').replace('()', '') + if (typeof fclos?.sid === 'string') { + const index = fclos?.sid.indexOf('>.') + const result = index !== -1 ? fclos?.sid.substring(index + 2) : fclos?.sid + if (result) { + return QidUnifyUtil.qidUnifyByRemoveAngleAndPrefix(result) + } } } @@ -146,11 +196,13 @@ class PythonTaintAbstractChecker extends TaintChecker { * * @param node * @param argvalues + * @param callInfo * @param fclos * @param rule + * @param state */ - findArgsAndAddNewFinding(node: any, argvalues: any, fclos: any, rule: any) { - const args = BasicRuleHandler.prepareArgs(argvalues, fclos, rule) + findArgsAndAddNewFinding(node: any, callInfo: CallInfo | undefined, fclos: any, rule: any, state?: any) { + const args = BasicRuleHandler.prepareArgs(callInfo, fclos, rule) const sanitizers = SanitizerChecker.findSanitizerByIds(rule.sanitizerIds) const ndResultWithMatchedSanitizerTagsArray = SanitizerChecker.findTagAndMatchedSanitizer( node, @@ -177,7 +229,8 @@ class PythonTaintAbstractChecker extends TaintChecker { fclos, TAINT_TAG_NAME_PYTHON, ruleName, - matchedSanitizerTags + matchedSanitizerTags, + state?.callstack ) if (!TaintOutputStrategy.isNewFinding(this.resultManager, taintFlowFinding)) continue this.resultManager.newFinding(taintFlowFinding, TaintOutputStrategy.outputStrategyId) @@ -187,4 +240,18 @@ class PythonTaintAbstractChecker extends TaintChecker { } } -module.exports = PythonTaintAbstractChecker +/** + * + */ +function loadPythonDefaultRule() { + let pythonDefaultRule + try { + const rulePath = FileUtil.getAbsolutePath('./resource/python/python-default-rule.json') + pythonDefaultRule = FileUtil.loadJSONfile(rulePath) + } catch (e) { + handleException(e, 'Error occurred in load python default rule', 'Error occurred in load python default rule') + } + return pythonDefaultRule +} + +module.exports = { PythonTaintAbstractChecker, loadPythonDefaultRule } diff --git a/src/checker/taint/python/python-taint-checker.ts b/src/checker/taint/python/python-taint-checker.ts index 966d09fd..299cd480 100644 --- a/src/checker/taint/python/python-taint-checker.ts +++ b/src/checker/taint/python/python-taint-checker.ts @@ -1,18 +1,17 @@ -import { handleException } from '../../../engine/analyzer/common/exception-handler' - const _ = require('lodash') -const PythonTaintAbstractChecker = require('./python-taint-abstract-checker') +const { PythonTaintAbstractChecker } = require('./python-taint-abstract-checker') const CommonUtil = require('../../../util/common-util') const { findPythonFcEntryPointAndSource, + buildFclosIndex, + lookupFclos, } = require('../../../engine/analyzer/python/common/entrypoint-collector/python-entrypoint') const Constant = require('../../../util/constant') const EntryPoint = require('../../../engine/analyzer/common/entrypoint') -const AstUtil = require('../../../util/ast-util') const Config = require('../../../config') -const FileUtil = require('../../../util/file-util') const { extractRelativePath } = require('../../../util/file-util') const logger = require('../../../util/logger')(__filename) +const { loadPythonDefaultRule } = require('./python-taint-abstract-checker') const TAINT_TAG_NAME_PYTHON = 'PYTHON_INPUT' @@ -38,7 +37,8 @@ class PythonTaintChecker extends PythonTaintAbstractChecker { * @param info */ triggerAtStartOfAnalyze(analyzer: any, scope: any, node: any, state: any, info: any) { - const { moduleManager, fileManager } = analyzer + const moduleManager = analyzer.topScope.context.modules + const fileManager = analyzer.topScope.context.files this.prepareEntryPoints(analyzer, Config.maindir, moduleManager, fileManager) analyzer.entryPoints.push(...this.entryPoints) this.addSourceTagForSourceScope(TAINT_TAG_NAME_PYTHON, this.sourceScope.value) @@ -58,7 +58,7 @@ class PythonTaintChecker extends PythonTaintAbstractChecker { const { entrypoints: ruleConfigEntryPoints } = this.checkerRuleConfigContent if (Config.entryPointMode !== 'ONLY_CUSTOM') { - const pythonDefaultRule = this.loadPythonDefaultRule() + const pythonDefaultRule = loadPythonDefaultRule() if (pythonDefaultRule[0].checkerIds.includes(this.getCheckerId())) { this.checkerRuleConfigContent.sources = this.checkerRuleConfigContent.sources || {} this.checkerRuleConfigContent.sources.TaintSource = this.checkerRuleConfigContent.sources.TaintSource || [] @@ -69,7 +69,11 @@ class PythonTaintChecker extends PythonTaintAbstractChecker { : [this.checkerRuleConfigContent.sources.TaintSource] this.checkerRuleConfigContent.sources.TaintSource.push(...pythonDefaultRule[0].sources.TaintSource) } - const { pyFcEntryPointArray, pyFcEntryPointSourceArray } = findPythonFcEntryPointAndSource(dir, fileManager) + const { pyFcEntryPointArray, pyFcEntryPointSourceArray } = findPythonFcEntryPointAndSource( + dir, + fileManager, + analyzer + ) if (pyFcEntryPointArray) { funCallEntryPoints.push(...pyFcEntryPointArray) } @@ -101,26 +105,20 @@ class PythonTaintChecker extends PythonTaintAbstractChecker { } } + // 构建 fclos 索引,一次遍历替代多次查找 + const fclosIndex = buildFclosIndex(moduleManager, dir, extractRelativePath) + for (const funCallEntryPoint of funCallEntryPoints) { - let valFuncs = AstUtil.satisfy( - moduleManager, - (n: any) => - n.vtype === 'fclos' && - extractRelativePath(n?.ast?.loc?.sourcefile, dir) === funCallEntryPoint.filePath && - n?.ast?.id?.name === funCallEntryPoint.functionName, - (node: any, prop: any) => prop === 'field', - null, - true - ) + // 使用索引查找,O(1) 操作 + let valFuncs = lookupFclos(fclosIndex, funCallEntryPoint.filePath, funCallEntryPoint.functionName) + if (_.isEmpty(valFuncs)) { logger.info('match entryPoint fail') continue } - if (Array.isArray(valFuncs)) { - valFuncs = _.uniqBy(valFuncs, (value: any) => value.fdef) - } else { - valFuncs = [valFuncs] - } + + // 去重 + valFuncs = _.uniqBy(valFuncs, (value: any) => value.ast.fdef) for (const valFunc of valFuncs) { const entryPoint = new EntryPoint(Constant.ENGIN_START_FUNCALL) @@ -134,13 +132,14 @@ class PythonTaintChecker extends PythonTaintAbstractChecker { for (const fileEntryPoint of fileEntryPoints) { const fullFilePath = `${Config.maindir}${fileEntryPoint.filePath}`.replace('//', '/') - const file = fileManager[fullFilePath] - if (file?.ast?.type === 'CompileUnit') { + const fileUuid = fileManager[fullFilePath] + const file = analyzer.symbolTable.get(fileUuid) + if (file?.ast?.node?.type === 'CompileUnit') { const entryPoint = new EntryPoint(Constant.ENGIN_START_FILE_BEGIN) entryPoint.scopeVal = file entryPoint.argValues = undefined entryPoint.functionName = undefined - entryPoint.filePath = file?.ast?.loc?.sourcefile + entryPoint.filePath = file?.ast?.node?.loc?.sourcefile entryPoint.attribute = fileEntryPoint.attribute entryPoint.packageName = undefined entryPoint.entryPointSymVal = file @@ -150,20 +149,6 @@ class PythonTaintChecker extends PythonTaintAbstractChecker { CommonUtil.initSourceScopeByTaintSourceWithLoc(this.sourceScope, this.checkerRuleConfigContent.sources?.TaintSource) } - - /** - * - */ - loadPythonDefaultRule() { - let pythonDefaultRule - try { - const rulePath = FileUtil.getAbsolutePath('./resource/python/python-default-rule.json') - pythonDefaultRule = FileUtil.loadJSONfile(rulePath) - } catch (e) { - handleException(e, 'Error occurred in load python default rule', 'Error occurred in load python default rule') - } - return pythonDefaultRule - } } module.exports = PythonTaintChecker diff --git a/src/checker/taint/python/script-taint-checker.ts b/src/checker/taint/python/script-taint-checker.ts new file mode 100644 index 00000000..e0e3c2a3 --- /dev/null +++ b/src/checker/taint/python/script-taint-checker.ts @@ -0,0 +1,81 @@ +const { PythonTaintAbstractChecker } = require('./python-taint-abstract-checker') +const Config = require('../../../config') +const { markTaintSource } = require('../common-kit/source-util') +const AstUtil = require('../../../util/ast-util') + +// fclos.qid 匹配规则 +const ARGPARSE_QID_PATTERN = /\.argparse\.ArgumentParser\(.*\)\.(parse_args|parse_known_args)$/ +const OPTPARSE_QID_PATTERN = /\.optparse\.OptionParser\(.*\)\.(parse_args|parse_known_args)$/ +const INPUT_QID_PATTERN = /\.(input|raw_input)$/ +const GETOPT_QID_PATTERN = /\.getopt\.(getopt|gnu_getopt)$/ +const OS_GETENV_QID_PATTERN = /\.os\.getenv$/ +const OS_ENVIRON_GET_QID_PATTERN = /\.os\.environ\.get$/ +const SYS_STDIN_QID_PATTERN = /\.sys\.stdin\.(read|readline|readlines)$/ + +// 文件 I/O source:open() / io.open() / codecs.open() 返回文件句柄,携带本地文件内容 +const FILE_OPEN_QID_PATTERN = /\.(open|io\.open|codecs\.open)$/ +// pathlib 文件读取 +const PATHLIB_READ_QID_PATTERN = /\.Path.*\.(read_text|read_bytes|read)$/ + +const SCRIPT_SOURCE_QID_PATTERNS = [ + ARGPARSE_QID_PATTERN, + OPTPARSE_QID_PATTERN, + INPUT_QID_PATTERN, + GETOPT_QID_PATTERN, + OS_GETENV_QID_PATTERN, + OS_ENVIRON_GET_QID_PATTERN, + SYS_STDIN_QID_PATTERN, + FILE_OPEN_QID_PATTERN, + PATHLIB_READ_QID_PATTERN, +] + +/** + * Python 脚本污点追踪 checker + * Source: argparse.parse_args(), sys.argv, input(), os.environ, getopt, open() 等 + * Entrypoint: 文件级入口(脚本从文件头开始执行) + */ +class ScriptTaintChecker extends PythonTaintAbstractChecker { + constructor(resultManager: any) { + super(resultManager, 'taint_flow_python_script_input') + } + + triggerAtStartOfAnalyze(analyzer: any, scope: any, node: any, state: any, info: any): void { + this.addSourceTagForcheckerRuleConfigContent('PYTHON_INPUT', this.checkerRuleConfigContent) + if (Config.entryPointMode === 'ONLY_CUSTOM') return + const fullCallGraphFileEntryPoint = require('../../common/full-callgraph-file-entrypoint') + const fullFileEntrypoint = fullCallGraphFileEntryPoint.getAllFileEntryPointsUsingFileManager(analyzer) + analyzer.entryPoints.push(...fullFileEntrypoint) + } + + triggerAtFunctionCallAfter(analyzer: any, scope: any, node: any, state: any, info: any): void { + super.triggerAtFunctionCallAfter(analyzer, scope, node, state, info) + const { fclos, ret } = info + if (Config.entryPointMode === 'ONLY_CUSTOM' || !fclos || !ret) return + + const { qid } = fclos + if (typeof qid !== 'string') return + + for (const pattern of SCRIPT_SOURCE_QID_PATTERNS) { + if (pattern.test(qid)) { + markTaintSource(ret, { path: node, kind: 'PYTHON_INPUT' }) + return + } + } + } + + triggerAtMemberAccess(analyzer: any, scope: any, node: any, state: any, info: any): void { + if (Config.entryPointMode === 'ONLY_CUSTOM') return + + // sys.argv + if (AstUtil.prettyPrintAST(node) === 'sys.argv') { + markTaintSource(info.res, { path: node, kind: 'PYTHON_INPUT' }) + } + + // os.environ + if (AstUtil.prettyPrintAST(node) === 'os.environ') { + markTaintSource(info.res, { path: node, kind: 'PYTHON_INPUT' }) + } + } +} + +module.exports = ScriptTaintChecker diff --git a/src/checker/taint/python/tornado-taint-checker.ts b/src/checker/taint/python/tornado-taint-checker.ts index 24cf5dac..f3e96c6b 100644 --- a/src/checker/taint/python/tornado-taint-checker.ts +++ b/src/checker/taint/python/tornado-taint-checker.ts @@ -1,4 +1,6 @@ -const PythonTaintAbstractChecker = require('./python-taint-abstract-checker') +import { getLegacyArgValues } from '../../../engine/analyzer/common/call-args' + +const { PythonTaintAbstractChecker } = require('./python-taint-abstract-checker') const Config = require('../../../config') const completeEntryPoint = require('../common-kit/entry-points-util') const { markTaintSource } = require('../common-kit/source-util') @@ -43,7 +45,8 @@ class TornadoTaintChecker extends PythonTaintAbstractChecker { */ triggerAtFunctionCallBefore(analyzer: any, scope: any, node: any, state: any, info: any): void { super.triggerAtFunctionCallBefore(analyzer, scope, node, state, info) - const { fclos, argvalues } = info + const { fclos, callInfo } = info + const argvalues = getLegacyArgValues(callInfo) if (Config.entryPointMode === 'ONLY_CUSTOM' || !fclos || !argvalues) return const isApp = isTornadoCall(node, 'Application') const isRouter = isTornadoCall(node, 'RuleRouter') @@ -93,7 +96,7 @@ class TornadoTaintChecker extends PythonTaintAbstractChecker { const handler = val.value['1'] if (handler) { const pathArg = val.value['0'] - const path = pathArg?.value || pathArg?.ast?.value + const path = pathArg?.value || pathArg?.ast?.node?.value if (typeof path === 'string') { this.finishRoute(analyzer, scope, state, handler) return @@ -134,15 +137,15 @@ class TornadoTaintChecker extends PythonTaintAbstractChecker { } // 2. Handle Class Definition (Handler classes) let cls = h - if (cls.vtype !== 'class' && cls.ast?.type === 'ClassDefinition') { + if (cls.vtype !== 'class' && cls.ast?.node?.type === 'ClassDefinition') { try { - cls = analyzer.processInstruction(scope, cls.ast, state) || this.buildClassSymbol(cls.ast) + cls = analyzer.processInstruction(scope, cls.ast.node, state) || this.buildClassSymbol(cls.ast.node) } catch (e) { - cls = this.buildClassSymbol(cls.ast) + cls = this.buildClassSymbol(cls.ast.node) } - } else if (cls.vtype === 'symbol' && cls.cdef) { + } else if (cls.vtype === 'symbol' && cls.ast?.cdef) { // If it's an instance symbol, get its class definition - cls = cls.cdef + cls = cls.ast.cdef } if (cls && (cls.vtype === 'class' || cls.vtype === 'symbol')) { this.registerEntryPoints(analyzer, cls) @@ -156,14 +159,23 @@ class TornadoTaintChecker extends PythonTaintAbstractChecker { */ private registerEntryPoints(analyzer: any, cls: any) { const methods = ['get', 'post', 'put', 'delete', 'patch'] - // Look for methods in cls.value, cls.field, or cls.value.field (Python specificity) - const classValue = cls.value?.field || cls.field || cls.value || {} + // 在 cls.value 或 cls.value.value 中查找方法(Python 类结构) + const classValue = cls.value?.value || cls.value || {} Object.entries(classValue).forEach(([name, fclos]: [string, any]) => { if (methods.includes(name)) { const ep = completeEntryPoint(fclos) if (ep) { - analyzer.entryPoints.push(ep) - const actualParams = (fclos.fdef?.parameters || fclos.ast?.parameters || []) as any[] + ep.funcReceiverType = cls.ast?.node?.id?.name || cls.sid || 'Unknown' + const isDuplicate = analyzer.entryPoints.some( + (existing: any) => + existing.functionName === ep.functionName && + existing.filePath === ep.filePath && + existing.funcReceiverType === ep.funcReceiverType + ) + if (!isDuplicate) { + analyzer.entryPoints.push(ep) + } + const actualParams = (fclos.ast?.fdef?.parameters || fclos.ast?.node?.parameters || []) as any[] actualParams.forEach((p: any) => { const pName = p.id?.name || p.name if (pName === 'self') return @@ -171,7 +183,7 @@ class TornadoTaintChecker extends PythonTaintAbstractChecker { this.sourceScope.value.push({ path: pName, kind: 'PYTHON_INPUT', - scopeFile: extractRelativePath(fclos?.ast?.loc?.sourcefile || ep.filePath, Config.maindir), + scopeFile: extractRelativePath(fclos?.ast?.node?.loc?.sourcefile || ep.filePath, Config.maindir), scopeFunc: ep.functionName, locStart: p.loc?.start?.line, locEnd: p.loc?.end?.line, @@ -213,7 +225,8 @@ class TornadoTaintChecker extends PythonTaintAbstractChecker { */ triggerAtFunctionCallAfter(analyzer: any, scope: any, node: any, state: any, info: any): void { super.triggerAtFunctionCallAfter(analyzer, scope, node, state, info) - const { fclos, ret, argvalues } = info + const { fclos, ret, callInfo } = info + const argvalues = getLegacyArgValues(callInfo) if (Config.entryPointMode === 'ONLY_CUSTOM' || !fclos || !ret) return const name = node.callee?.property?.name || node.callee?.name // 1. Record route info for Rule, URLSpec, url (Recording phase) @@ -259,4 +272,4 @@ class TornadoTaintChecker extends PythonTaintAbstractChecker { } } -export = TornadoTaintChecker +module.exports = TornadoTaintChecker diff --git a/src/checker/taint/taint-checker.ts b/src/checker/taint/taint-checker.ts index 2a7a7886..ab7800dd 100644 --- a/src/checker/taint/taint-checker.ts +++ b/src/checker/taint/taint-checker.ts @@ -23,8 +23,11 @@ class TaintChecker extends Checker { this.sourceScope = { complete: false, value: [], + fillLineValues: [], } taintCheckerCommonUtil.initSourceScope(this.sourceScope, this.checkerRuleConfigContent.sources?.TaintSource) + this.sinkRuleArray = undefined + this.matchSinkRuleResultMap = new Map() } /** @@ -37,7 +40,7 @@ class TaintChecker extends Checker { const callNode = finding.node const sinkRule = finding.ruleName const { fclos, matchedSanitizerTags, callstack } = finding - if (finding && argNode && argNode.hasTagRec) { + if (finding && argNode && argNode.taint?.isTaintedRec) { let traceStack = TaintCheckerFindingUtil.getTrace(argNode, tagName) const trace = TaintCheckerSourceLine.getNodeTrace(fclos, callNode) // 暂时统一去掉Field,不然展示出来的链路会重复 @@ -61,8 +64,10 @@ class TaintChecker extends Checker { sinkRule: finding.sinkRule, sinkAttribute: finding.sinkAttribute, } + const currentEntryPoint = entryPointConfig.getCurrentEntryPoint() + finding.entrypointLoc = currentEntryPoint?.entryPointSymVal?.ast?.node?.loc finding.entrypoint = _.pickBy( - _.clone(entryPointConfig.getCurrentEntryPoint()), + _.clone(currentEntryPoint), (value: any) => !_.isObject(value) ) finding.trace.push(trace) diff --git a/src/checker/taint/test-taint-checker.ts b/src/checker/taint/test-taint-checker.ts index 7edd372b..d544e72b 100644 --- a/src/checker/taint/test-taint-checker.ts +++ b/src/checker/taint/test-taint-checker.ts @@ -1,3 +1,5 @@ +import type { CallInfo } from '../../engine/analyzer/common/call-args' + const BasicRuleHandler = require('../common/rules-basic-handler') const IntroduceTaint = require('./common-kit/source-util') const SanitizerChecker = require('../sanitizer/sanitizer-checker') @@ -53,8 +55,8 @@ class TestTaintChecker extends TaintChecker { * @param info */ triggerAtFunctionCallBefore(analyzer: any, scope: any, node: any, state: any, info: any) { - const { fclos, argvalues } = info - this.checkSinkAtFunctionCall(node, fclos, argvalues) + const { fclos, callInfo } = info + this.checkSinkAtFunctionCall(node, fclos, callInfo, state) } /** @@ -76,7 +78,7 @@ class TestTaintChecker extends TaintChecker { * @param info */ triggerAtIdentifier(analyzer: any, scope: any, node: any, state: any, info: any) { - IntroduceTaint.introduceTaintAtIdentifierDirect(node, info.res, this.sourceScope.value) + IntroduceTaint.introduceTaintAtIdentifierDirect(analyzer, scope, node, info.res, this.sourceScope.value) } /** @@ -123,7 +125,7 @@ class TestTaintChecker extends TaintChecker { /** * - + * @param analyzer * @param scope * @param node @@ -144,7 +146,7 @@ class TestTaintChecker extends TaintChecker { /** * - + * @param analyzer * @param scope * @param node @@ -183,10 +185,11 @@ class TestTaintChecker extends TaintChecker { // 使用callgraph边界作为entrypoint fullCallGraphFileEntryPoint.makeFullCallGraph(analyzer) const fullCallGraphEntrypoint = fullCallGraphFileEntryPoint.getAllEntryPointsUsingCallGraph( - analyzer.ainfo?.callgraph + analyzer.ainfo?.callgraph, + analyzer ) // 使用file作为entrypoint - const fullFileEntrypoint = fullCallGraphFileEntryPoint.getAllFileEntryPointsUsingFileManager(analyzer.fileManager) + const fullFileEntrypoint = fullCallGraphFileEntryPoint.getAllFileEntryPointsUsingFileManager(analyzer) this.entryPoints.push(...fullFileEntrypoint) this.entryPoints.push(...fullCallGraphEntrypoint) } @@ -197,17 +200,18 @@ class TestTaintChecker extends TaintChecker { * @param node * @param fclos * @param argValues + * @param state */ - checkSinkAtFunctionCall(node: any, fclos: any, argValues: any) { + checkSinkAtFunctionCall(node: any, fclos: any, callInfo: CallInfo | undefined, state?: any) { if (!fclos) { return } const rules = this.checkerRuleConfigContent.sinks?.FuncCallTaintSink - let rule = matchSinkAtFuncCall(node, fclos, rules) + let rule = matchSinkAtFuncCall(node, fclos, rules, callInfo) rule = rule.length > 0 ? rule[0] : null if (rule) { - const args = BasicRuleHandler.prepareArgs(argValues, fclos, rule) + const args = BasicRuleHandler.prepareArgs(callInfo, fclos, rule) const sanitizers = SanitizerChecker.findSanitizerByIds(rule.sanitizerIds) const ndResultWithMatchedSanitizerTagsArray = SanitizerChecker.findTagAndMatchedSanitizer( node, @@ -234,7 +238,8 @@ class TestTaintChecker extends TaintChecker { fclos, TAINT_TAG_NAME_TEST_TAINT, ruleName, - matchedSanitizerTags + matchedSanitizerTags, + state?.callstack ) if (!TaintOutputStrategy.isNewFinding(this.resultManager, taintFlowFinding)) continue this.resultManager.newFinding(taintFlowFinding, TaintOutputStrategy.outputStrategyId) diff --git a/src/client.ts b/src/client.ts index eb1a5889..981646d4 100644 --- a/src/client.ts +++ b/src/client.ts @@ -131,7 +131,7 @@ async function main(): Promise { console.log(`arguments: ${args.join(' ')}`) if (!args.includes('--singleCommand')) { const analyzer = await initAnalyzer(null, args) - analyzer.preProcess(Config.maindir) + await analyzer.preProcess(Config.maindir) const fullCallGraphFileEntryPoint = require('./checker/common/full-callgraph-file-entrypoint') fullCallGraphFileEntryPoint.makeFullCallGraph(analyzer) BasicRuleHandler.setPreprocessReady(true) diff --git a/src/config.ts b/src/config.ts index f85c39ab..87e3f23c 100644 --- a/src/config.ts +++ b/src/config.ts @@ -33,6 +33,7 @@ export interface IConfig { invokeCallbackOnUnknownFunction?: number maxIterationTime?: number shareSourceLineSet?: boolean + workerCount?: number // Worker数量:0表示自动计算,>0表示使用设置的worker数量 // Analysis stateUnionLevel?: number @@ -53,6 +54,7 @@ export interface IConfig { entryPointAndSourceAtSameTime?: boolean entryPointMode?: string cgAlgo: string + taintTraceOutputStrategy?: string // Allow additional properties [key: string]: any @@ -69,8 +71,12 @@ const configObject: IConfig = { dumpAST: false, // dump ast to json format dumpAllAST: false, // dump all ast to json format - intermediateDir: '', // 中间文件缓存目录路径(默认使用 reportDir/ast-output) + intermediateDir: '', // 增量扫描缓存目录路径(默认使用 reportDir/ast-output) incremental: false, // 增量分析模式(默认禁用,需要显式配置) + saveContextEnvironment: false, // 保存上下文缓存模式 + miniSaveContextEnvironment: false, // 极简保存上下文缓存模式 + loadContextEnvironment: false, // 加载上下文缓存模式 + contextEnvironmentDir: '', // 上下文缓存文件目录 //* ***************************** path and so on *************************** @@ -104,6 +110,9 @@ const configObject: IConfig = { // multiple objects with the same source may share the same source line trace shareSourceLineSet: false, + // Worker数量:0表示自动计算,>0表示使用设置的worker数量 + workerCount: 0, + //* ***************************** analysis *************************** stateUnionLevel: 2, @@ -122,8 +131,21 @@ const configObject: IConfig = { entryPointAndSourceAtSameTime: true, entryPointMode: 'BOTH', // BOTH or ONLY_CUSTOM or SELF_COLLECT + // Taint trace output strategy: 'full' | 'callstack-only' (legacy alias: 'folded') + taintTraceOutputStrategy: 'callstack-only', + // CallGraph cgAlgo: 'DEFAULT', + + // Pruning + minEntryPointToEnablePrune: 200, + + // Timeout + entryPointTimeoutMs: 300000, + entryPointTimeoutQuickMs: 120000, + + // Prune parameters for aggressive prune mode + maxCallstackDepth: 12, // max callstack depth in aggressive prune mode } module.exports = configObject diff --git a/src/engine/analyzer/common/analysis-context.ts b/src/engine/analyzer/common/analysis-context.ts new file mode 100644 index 00000000..d25fda63 --- /dev/null +++ b/src/engine/analyzer/common/analysis-context.ts @@ -0,0 +1,14 @@ +/** + * AnalysisContext - 项目级分析上下文 + * + * 仅 topScope 持有,Analyzer 共享引用。 + * 统一归组项目级分析数据,替代 topScope 上散落的 manager 属性。 + */ +export class AnalysisContext { + ast: any = null + symbols: any = null + modules: any = null + packages: any = null + files: Record | null = null + funcs: Record | null = null +} diff --git a/src/engine/analyzer/common/analyzer-cache.ts b/src/engine/analyzer/common/analyzer-cache.ts new file mode 100644 index 00000000..5ec1d97a --- /dev/null +++ b/src/engine/analyzer/common/analyzer-cache.ts @@ -0,0 +1,1832 @@ +import { RAW_TARGET, IS_UNION_ARRAY } from './value/symbols' +import { yasaLog, yasaWarning, yasaError } from '../../../util/format-util' +import { AnalysisContext } from './analysis-context' +import { Scoped } from './value/scoped' +import { ObjectValue } from './value/object' +import { PrimitiveValue } from './value/primitive' +import { SymbolValue } from './value/symbolic' +import { PackageValue } from './value/package' +import { UnionValue } from './value/union' +import { UnknownValue } from './value/unkown' +import { UndefinedValue } from './value/undefine' +import { UninitializedValue } from './value/uninit' +import { FunctionValue } from './value/function' +import { BVTValue } from './value/bvt' +import type { RType } from './value/data-value' + +const fs = require('fs') +const path = require('path') +const jsonfile = require('jsonfile') +const util = require('util') +const Config = require('../../../config') +const { writeJSONfile } = require('../../../util/file-util') +const { shallowCopyValue } = require('../../../util/clone-util') +const { Graph } = require('../../../util/graph') + +const names: string[] = [] + +/** + * 获取缓存目录路径 + */ +function getCacheDir(): string { + const outputDir = Config.contextEnvironmentDir + if (!outputDir) { + yasaError( + '[CACHE]Config.intermediateDir is not set. Please set Config.intermediateDir before using cache functionality.' + ) + throw new Error( + 'Config.intermediateDir is not set. Please set Config.intermediateDir before using cache functionality.' + ) + } + + let cacheDir: string + if (!path.isAbsolute(outputDir)) { + cacheDir = path.resolve(process.cwd(), outputDir) + } else { + cacheDir = outputDir + } + return cacheDir +} + +/** + * 序列化对象,处理 astManager 时跳过 parent 属性 + * @param obj 要序列化的对象 + * @param skipParent 是否跳过 parent 属性(用于 astManager) + * @param maxDepth 最大深度,防止无限递归 + * @param currentDepth 当前深度 + * @param visited 已访问的对象集合,用于检测循环引用 + * @param parentRelations + * @returns 序列化后的对象 + */ +function serializeObject( + obj: any, + skipParent: boolean = false, + maxDepth: number = 100, + currentDepth: number = 0, + visited: WeakSet = new WeakSet(), + parentRelations?: Map // 用于记录 parent 关系:nodehash -> parent nodehash +): any { + if (currentDepth > maxDepth) { + return '[Max Depth Reached]' + } + + if (obj == null) { + return obj + } + + // 处理基本类型 + if (typeof obj !== 'object') { + return obj + } + + // 检测循环引用 + if (visited.has(obj)) { + return '[Circular Reference]' + } + + // 处理 Map 类型 + if (obj instanceof Map) { + visited.add(obj) + const result: any = {} + const constructorNames: any = {} // 用于记录每个 unit 的构造函数名称 + for (const [key, value] of obj.entries()) { + // 检查是否是 topScope 对象(通过 sid 和 qid 判断) + if (value && typeof value === 'object' && value.sid === '' && value.qid === '') { + // 用特殊标记替换 topScope + result[key] = { __yasaTopScopeMarker: true } + } else if (value != null && typeof value === 'object') { + // 如果是 Unit 对象(有 vtype 属性),记录其构造函数名称 + if (value.vtype && value.constructor?.name) { + constructorNames[key] = value.constructor.name + } + result[key] = serializeObject(value, skipParent, maxDepth, currentDepth + 1, visited, parentRelations) + } else { + result[key] = value + } + } + // 如果有构造函数名称记录,将其添加到结果中 + if (Object.keys(constructorNames).length > 0) { + result.__yasaConstructorNames = constructorNames + } + visited.delete(obj) + return result + } + + // 处理 Set 类型 + if (obj instanceof Set) { + visited.add(obj) + const result: any[] = [] + for (const item of obj.values()) { + if (item != null && typeof item === 'object') { + result.push(serializeObject(item, skipParent, maxDepth, currentDepth + 1, visited, parentRelations)) + } else { + result.push(item) + } + } + visited.delete(obj) + return result + } + + // 处理数组 + if (Array.isArray(obj)) { + visited.add(obj) + const result = obj.map((item, index) => { + if (item != null && typeof item === 'object') { + return serializeObject(item, skipParent, maxDepth, currentDepth + 1, visited, parentRelations) + } + return item + }) + visited.delete(obj) + return result + } + + // 处理对象 + visited.add(obj) + + // 检测是否是 Proxy,如果是则获取原始对象 + let targetObj = obj + if (util.types.isProxy && util.types.isProxy(obj)) { + // 尝试获取 Proxy 的原始对象 + if ((obj as any)[RAW_TARGET]) { + targetObj = (obj as any)[RAW_TARGET] + } else if ((obj as any)[IS_UNION_ARRAY]) { + targetObj = (obj as any)[IS_UNION_ARRAY] + } + } + + const result: any = {} + + // 使用 Reflect.ownKeys 获取所有属性(包括不可枚举的) + // 对于 Unit 对象,我们需要同时检查 targetObj 和 obj,因为某些属性(如 astNodehash)可能在原对象上 + // 使用 targetObj 而不是 obj,避免触发 Proxy 的 get trap + const allKeys = Reflect.ownKeys(targetObj) + // 对于 Unit 对象,也检查原对象上的属性(如果 targetObj 和 obj 不同) + const allKeysFromObj = targetObj !== obj ? Reflect.ownKeys(obj) : [] + // 合并两个键集合,确保所有属性都被序列化 + const allKeysSet = new Set([...allKeys, ...allKeysFromObj]) + + for (const key of allKeysSet) { + if (typeof key === 'symbol') { + continue + } + + const keyStr = key as string + + // 跳过内部属性和不可序列化的 ValueRefMap/ValueRefList 影子属性 + if (keyStr.startsWith('__yasa') || keyStr === 'elements' || keyStr === '_children' || keyStr === 'set') { + if (!names.includes(keyStr)) { + names.push(keyStr) + } + continue + } + + try { + // 直接访问 targetObj 的属性,避免触发 Proxy 的 get trap + // 如果 targetObj 上没有该属性,尝试从原对象获取(对于某些属性如 astNodehash) + let value = Reflect.get(targetObj, keyStr) + if (value === undefined && targetObj !== obj) { + // 如果 targetObj 上没有该属性,尝试从原对象获取 + const descriptor = Object.getOwnPropertyDescriptor(obj, keyStr) + if (descriptor && 'value' in descriptor) { + value = descriptor.value + } + } + + // 处理 parent 属性:记录 parent 的 nodehash 关系 + if (keyStr === 'parent' && value && typeof value === 'object' && value.type) { + // 这是一个 AST 节点的 parent + const currentNodehash = targetObj._meta?.nodehash + const parentNodehash = value._meta?.nodehash + if (currentNodehash && parentNodehash && parentRelations) { + // 记录 parent 关系 + parentRelations.set(currentNodehash, parentNodehash) + } + // 如果 skipParent 为 true,跳过序列化 parent 对象本身 + if (skipParent) { + continue + } + // 否则继续序列化 parent(但会记录关系) + } + + // 如果 skipParent 为 true 且是 parent 属性,跳过(但上面已经处理了) + if (skipParent && keyStr === 'parent') { + continue + } + + // 对于 decls 和 overloaded,它们可能是 Proxy,需要访问内部存储 + if (keyStr === 'decls' && util.types.isProxy && util.types.isProxy(value)) { + // 优先从 _ast._declsMap 读取(AstBinding),回退到 _declsNodehashMap + const astBinding = Reflect.get(targetObj, '_ast') + const declsMap = astBinding?._declsMap ?? Reflect.get(targetObj, '_declsNodehashMap') + if (declsMap instanceof Map) { + const declsData: any = {} + for (const [name, entry] of declsMap.entries()) { + // AstRef 对象取 .hash,裸字符串直接用 + declsData[name] = entry?.hash ?? entry + } + result[keyStr] = declsData + } else { + result[keyStr] = serializeObject(value, skipParent, maxDepth, currentDepth + 1, visited, parentRelations) + } + continue + } + + if (keyStr === 'overloaded') { + const overloadedList = Reflect.get(targetObj, 'overloaded') + if (overloadedList && overloadedList._refs) { + result[keyStr] = overloadedList._refs.map((ref: any) => ref.hash) + } + continue + } + + // 检查是否是 topScope 对象(通过 sid 和 qid 判断) + if (value && typeof value === 'object' && value.sid === '' && value.qid === '') { + // 用特殊标记替换 topScope + result[keyStr] = { __yasaTopScopeMarker: true } + } else if (value != null && typeof value === 'object') { + result[keyStr] = serializeObject(value, skipParent, maxDepth, currentDepth + 1, visited, parentRelations) + } else { + // 对于基本类型(字符串、数字、布尔值、null、undefined),直接赋值 + // 注意:JSON.stringify 会忽略 undefined,但会保留 null + // 为了确保 astNodehash 等属性被正确序列化,即使值是 undefined,我们也应该包含它 + // 但 JSON 不支持 undefined,所以如果值是 undefined,我们将其序列化为 null + // 不过,为了保持一致性,我们直接赋值,让 JSON.stringify 处理 + result[keyStr] = value + } + } catch (e) { + // 忽略访问器错误 + yasaWarning(`Failed to serialize property ${keyStr}: ${e}`) + } + } + + visited.delete(obj) + return result +} + +/** + * 将大对象分割成多个文件 + * @param data 要分割的数据 + * @param basePath 基础路径 + * @param chunkSize 每个文件的最大条目数(对于 Map,默认 1000) + * @param isMapData 是否是 Map 数据(序列化后的对象) + * @returns 保存的文件路径列表 + */ +function splitAndSave(data: any, basePath: string, chunkSize: number = 1000, isMapData: boolean = false): string[] { + const savedFiles: string[] = [] + + if (Array.isArray(data)) { + // 如果是数组,按 chunkSize 分割 + for (let i = 0; i < data.length; i += chunkSize) { + const chunk = data.slice(i, i + chunkSize) + const chunkPath = `${basePath}.part${Math.floor(i / chunkSize)}.json` + writeJSONfile(chunkPath, chunk) + savedFiles.push(chunkPath) + } + } else if (typeof data === 'object' && data !== null) { + const keys = Object.keys(data) + const mapChunkSize = 1000 // Map 数据使用 1000 作为 chunkSize + + if (isMapData) { + // Map 数据:无论条目数多少都使用子文件夹结构 + const baseDir = path.dirname(basePath) + const baseName = path.basename(basePath) + const mapDir = path.join(baseDir, baseName) + + // 确保目录存在 + if (!fs.existsSync(mapDir)) { + fs.mkdirSync(mapDir, { recursive: true }) + } + + const mapInfo = { + totalEntries: keys.length, + chunkSize: mapChunkSize, + numChunks: Math.ceil(keys.length / mapChunkSize), + } + writeJSONfile(path.join(mapDir, 'info.json'), mapInfo) + savedFiles.push(path.join(mapDir, 'info.json')) + + // 按 chunkSize 分割,使用文件夹名字作为前缀 + const prefix = baseName // 使用 baseName 作为前缀(如 astMap, symbolMap) + for (let i = 0; i < keys.length; i += mapChunkSize) { + const chunkKeys = keys.slice(i, i + mapChunkSize) + const chunk: any = {} + for (const key of chunkKeys) { + chunk[key] = data[key] + } + const chunkIndex = Math.floor(i / mapChunkSize) + const chunkPath = path.join(mapDir, `${prefix}-chunk${chunkIndex}.json`) + writeJSONfile(chunkPath, chunk) + savedFiles.push(chunkPath) + } + } else { + // 如果键数量很多,按键分割 + for (let i = 0; i < keys.length; i += chunkSize) { + const chunkKeys = keys.slice(i, i + chunkSize) + const chunk: any = {} + for (const key of chunkKeys) { + chunk[key] = data[key] + } + const chunkPath = `${basePath}.part${Math.floor(i / chunkSize)}.json` + writeJSONfile(chunkPath, chunk) + savedFiles.push(chunkPath) + } + } + } else { + // 其他类型直接保存 + writeJSONfile(`${basePath}.json`, data) + savedFiles.push(`${basePath}.json`) + } + + return savedFiles +} + +/** + * 反序列化对象,将 JSON 中的对象转换回 Map 和 Set + * @param obj 要反序列化的对象 + * @param topScopeRef topScope 对象的引用(用于恢复特殊标记) + * @param skipParentForAST + * @returns 反序列化后的对象 + */ +function deserializeObject(obj: any, topScopeRef?: any, skipParentForAST?: boolean): any { + if (obj == null || typeof obj !== 'object') { + return obj + } + + // 检查是否是 topScope 特殊标记 + if (obj && typeof obj === 'object' && obj.__yasaTopScopeMarker === true) { + return topScopeRef || obj + } + + // 处理数组 + if (Array.isArray(obj)) { + return obj.map((item) => deserializeObject(item, topScopeRef, skipParentForAST)) + } + + // 检查是否是 Map 的序列化格式(普通对象,但需要特殊处理) + // 对于 symbolTable,我们需要检查特定的属性名来判断是否需要转换为 Map + const result: any = {} + + for (const key in obj) { + if (!Object.prototype.hasOwnProperty.call(obj, key)) { + continue + } + + const value = obj[key] + + // 对于 symbolTable 的特殊属性,需要转换为 Map 或 Set + if (key === 'symbolMap') { + if (value && typeof value === 'object' && !Array.isArray(value)) { + // 转换为 Map + const map = new Map() + // 检查是否有构造函数名称记录(仅对 symbolMap) + const constructorNames = key === 'symbolMap' ? value.__yasaConstructorNames : null + for (const mapKey in value) { + if (Object.prototype.hasOwnProperty.call(value, mapKey)) { + // 跳过构造函数名称记录 + if (mapKey === '__yasaConstructorNames') { + continue + } + const mapValue = value[mapKey] + // 检查是否是 topScope 特殊标记 + if (mapValue && typeof mapValue === 'object' && mapValue.__yasaTopScopeMarker === true) { + map.set(mapKey, topScopeRef || mapValue) + } else if (key === 'symbolMap' && constructorNames && constructorNames[mapKey]) { + // 对于 symbolMap 中的 Unit 对象,根据构造函数名称创建实例,然后复制所有属性 + // 先反序列化对象(获取所有属性) + const deserializedUnit = deserializeObject(mapValue, topScopeRef, skipParentForAST) + const constructorName = constructorNames[mapKey] + + // 根据构造函数名称创建新实例(使用最小参数,保持正确的原型链) + let recreatedUnit: any + const minimalOpts = { + sid: deserializedUnit.sid || deserializedUnit._sid || '', + qid: deserializedUnit.qid || deserializedUnit._qid || '', + parent: deserializedUnit.parent || null, + } + + switch (constructorName) { + case 'Scoped': + recreatedUnit = Scoped.fromOpts('', minimalOpts) + break + case 'ObjectValue': + recreatedUnit = ObjectValue.fromOpts('', minimalOpts) + break + case 'PrimitiveValue': + recreatedUnit = PrimitiveValue.fromOpts('', minimalOpts) + break + case 'SymbolValue': + recreatedUnit = SymbolValue.fromOpts('', minimalOpts) + break + case 'PackageValue': + recreatedUnit = PackageValue.fromOpts('', minimalOpts) + break + case 'UnionValue': + recreatedUnit = UnionValue.fromOpts('', minimalOpts) + break + case 'UnknownValue': + recreatedUnit = UnknownValue.fromOpts('', minimalOpts) + break + case 'UndefinedValue': + recreatedUnit = UndefinedValue.fromOpts('', minimalOpts) + break + case 'UninitializedValue': + recreatedUnit = UninitializedValue.fromOpts('', minimalOpts) + break + case 'FunctionValue': + recreatedUnit = FunctionValue.fromOpts('', minimalOpts) + break + case 'BVTValue': + recreatedUnit = BVTValue.fromOpts('', minimalOpts) + break + default: + // 如果不知道构造函数,直接使用反序列化的对象 + recreatedUnit = deserializedUnit + map.set(mapKey, recreatedUnit) + continue + } + + // 将所有属性从反序列化的对象复制到新实例上(使用 Reflect.ownKeys 确保所有属性都被复制) + const allKeys = Reflect.ownKeys(deserializedUnit) + for (const propKey of allKeys) { + if (typeof propKey === 'symbol') { + continue + } + const propKeyStr = propKey as string + // 跳过一些不应该直接复制的属性(这些属性会在构造函数中设置) + if (propKeyStr === 'constructor' || propKeyStr === '__proto__') { + continue + } + try { + const descriptor = Object.getOwnPropertyDescriptor(deserializedUnit, propKeyStr) + if (descriptor) { + if ('value' in descriptor) { + // 直接设置属性值 + ;(recreatedUnit as any)[propKeyStr] = descriptor.value + } else if ('get' in descriptor || 'set' in descriptor) { + // 对于 getter/setter,尝试复制描述符 + try { + Object.defineProperty(recreatedUnit, propKeyStr, descriptor) + } catch (e) { + // 如果无法复制描述符,尝试直接访问值 + try { + ;(recreatedUnit as any)[propKeyStr] = (deserializedUnit as any)[propKeyStr] + } catch (e2) { + // 忽略错误 + } + } + } + } else { + // 如果没有描述符,尝试直接复制 + try { + ;(recreatedUnit as any)[propKeyStr] = (deserializedUnit as any)[propKeyStr] + } catch (e) { + // 忽略错误 + } + } + } catch (e) { + // 忽略复制错误 + yasaWarning(`Failed to copy property ${propKeyStr} to recreated unit: ${e}`) + } + } + + map.set(mapKey, recreatedUnit) + } else { + // 递归反序列化 Unit 对象,确保所有属性(包括 astNodehash)都被正确恢复 + map.set(mapKey, deserializeObject(mapValue, topScopeRef, skipParentForAST)) + } + } + } + result[key] = map + } else { + result[key] = deserializeObject(value, topScopeRef, skipParentForAST) + } + } else if (key === 'astMap') { + // astManager 的 astMap 需要转换为 Map + // 注意:在反序列化 AST 节点时,需要先跳过 parent 属性,后续再统一设置 + if (value && typeof value === 'object' && !Array.isArray(value)) { + const map = new Map() + for (const mapKey in value) { + if (Object.prototype.hasOwnProperty.call(value, mapKey)) { + const mapValue = value[mapKey] + // 递归反序列化 AST 节点(跳过 parent,后续统一设置) + const astNode = deserializeObject(mapValue, topScopeRef, true) // 第三个参数表示跳过 parent + // 先删除可能存在的 parent 引用(避免指向错误的对象) + if (astNode && typeof astNode === 'object') { + delete astNode.parent + } + map.set(mapKey, astNode) + } + } + result[key] = map + } else { + result[key] = deserializeObject(value, topScopeRef) + } + } else { + // 对于其他属性,递归反序列化 + // 这包括 Unit 对象的所有属性(如 astNodehash、declsNodehash、uuid、parent_uuid 等) + // 如果是 AST 节点的 parent 属性且 skipParentForAST 为 true,跳过它 + if (skipParentForAST && key === 'parent') { + // 跳过 parent 属性,后续统一设置 + continue + } + result[key] = deserializeObject(value, topScopeRef, skipParentForAST) + } + } + + return result +} + +/** + * 从分割的文件中加载数据 + * @param basePath 基础路径 + * @returns 加载的数据 + */ +function loadFromSplit(basePath: string): any { + const baseDir = path.dirname(basePath) + const baseName = path.basename(basePath) + const mapDir = path.join(baseDir, baseName) + + // 检查是否存在子文件夹结构(Map 数据) + if (fs.existsSync(mapDir) && fs.statSync(mapDir).isDirectory()) { + // 检查是否存在 info.json(表示是分 chunk 的大 Map) + const mapInfoPath = path.join(mapDir, 'info.json') + if (fs.existsSync(mapInfoPath)) { + // 大 Map:从多个 chunk 文件加载 + const mapInfo = jsonfile.readFileSync(mapInfoPath) + const numChunks = mapInfo.numChunks || 0 + + // 加载所有 chunk 并合并,使用文件夹名字作为前缀查找 + const result: any = {} + const prefix = baseName // 使用 baseName 作为前缀(如 astMap, symbolMap) + for (let i = 0; i < numChunks; i++) { + const chunkPath = path.join(mapDir, `${prefix}-chunk${i}.json`) + if (fs.existsSync(chunkPath)) { + const chunkData = jsonfile.readFileSync(chunkPath) + Object.assign(result, chunkData) + } + } + + return result + } + // 小 Map:从单个文件加载 + const singleFilePath = path.join(mapDir, `${baseName}.json`) + if (fs.existsSync(singleFilePath)) { + return jsonfile.readFileSync(singleFilePath) + } + // 如果文件夹存在但文件不存在,返回 null + return null + } + + // 查找所有分割文件(part 文件) + const files: string[] = [] + let partIndex = 0 + + // 查找所有分割文件 + while (true) { + const partPath = `${basePath}.part${partIndex}.json` + if (fs.existsSync(partPath)) { + files.push(partPath) + partIndex++ + } else { + break + } + } + + // 如果没有分割文件,尝试加载单个文件 + if (files.length === 0) { + const singlePath = `${basePath}.json` + if (fs.existsSync(singlePath)) { + return jsonfile.readFileSync(singlePath) + } + return null + } + + // 加载所有分割文件并合并 + const allData: any[] = [] + for (const file of files) { + try { + const data = jsonfile.readFileSync(file) + if (Array.isArray(data)) { + allData.push(...data) + } else if (typeof data === 'object' && data !== null) { + allData.push(data) + } + } catch (err: any) { + yasaWarning(`Failed to load cache file ${file}: ${err.message}`) + } + } + + if (allData.length === 0) { + return null + } + + // 判断原始数据类型 + const firstFile = jsonfile.readFileSync(files[0]) + if (Array.isArray(firstFile)) { + return allData + } + if (typeof firstFile === 'object' && firstFile !== null) { + // 合并对象 + const result: any = {} + for (const obj of allData) { + Object.assign(result, obj) + } + return result + } + + return allData +} + +/** + * 保存分析器缓存 + * @param analyzer 分析器实例 + * @param cacheId 缓存 ID(用于区分不同的缓存,如基于源路径的哈希) + */ +export function saveAnalyzerCache(analyzer: any, cacheId?: string): void { + try { + const cacheDir = getCacheDir() + if (!fs.existsSync(cacheDir)) { + fs.mkdirSync(cacheDir, { recursive: true }) + } + + // 如果没有提供 cacheId,使用默认值 + const id = cacheId || 'default' + // 创建以 cacheId 命名的文件夹 + const cacheFolder = path.join(cacheDir, id) + if (!fs.existsSync(cacheFolder)) { + fs.mkdirSync(cacheFolder, { recursive: true }) + } + const cacheBasePath = cacheFolder + + yasaLog(`[SAVE CACHE]Saving analyzer cache to ${cacheBasePath}...`) + + // 获取 topScope 的原始对象(绕过 Proxy) + const topScopeTarget = (analyzer.topScope as any)[RAW_TARGET] || analyzer.topScope + + // a. fileManager + if (!Config.miniSaveContextEnvironment) { + if (analyzer.fileManager) { + const fileManagerData = serializeObject(analyzer.fileManager) + splitAndSave(fileManagerData, path.join(cacheBasePath, 'fileManager'), 1000, true) + yasaLog('[SAVE CACHE]Saved fileManager') + } + } + + // b. symbolTable + if (analyzer.symbolTable) { + const symbolTable = analyzer.symbolTable // 特殊处理 symbolMap:根据 Config.miniSaveContextEnvironment 决定是否简化 + const symbolMap = symbolTable.getMap() + if (symbolMap instanceof Map) { + if (Config.miniSaveContextEnvironment) { + // 简化模式:根据节点类型过滤属性 + const astManager = analyzer.astManager + const astMap = astManager.getMap() + if (astMap instanceof Map) { + const keysToDelete: string[] = [] + for (const [nodehash, node] of astMap.entries()) { + if (node && typeof node === 'object' && node.type) { + if (node.type === 'VariableDeclaration') { + // 只保留 type、id、varType 属性 + const allowedProps = ['type', 'id', 'varType', '_meta'] + const allKeys = Reflect.ownKeys(node) + for (const prop of allKeys) { + if (typeof prop === 'string' && !allowedProps.includes(prop)) { + try { + delete (node as any)[prop] + } catch (e) { + // 忽略删除错误 + } + } + } + } else if (node.type === 'FunctionDefinition') { + // 只保留 type、id、parameters、returnType 属性 + const allowedProps = ['type', 'id', 'parameters', 'returnType', '_meta'] + const allKeys = Reflect.ownKeys(node) + for (const prop of allKeys) { + if (typeof prop === 'string' && !allowedProps.includes(prop)) { + try { + delete (node as any)[prop] + } catch (e) { + // 忽略删除错误 + } + } + } + } else { + // 其他类型,直接从 astMap 删除 + keysToDelete.push(nodehash) + } + } + } + // 删除其他类型的节点 + for (const nodehash of keysToDelete) { + astManager.astMap.delete(nodehash) + } + } + + // 简化模式:只保留指定的属性 + const allowedProps = [ + 'vtype', + '_field', + '_sid', + '_qid', + 'uuid', + '_ast', + '_parentRef', + '_thisRef', + '_superRef', + '_packageScopeRef', + 'overloaded', + '_scopeCtx', + 'rtype', + ] + + // 直接遍历 symbolMap,在原对象上删除不需要的属性 + for (const [key, value] of symbolTable.symbolMap.entries()) { + if (value && typeof value === 'object' && value._ast?._nodeRef) { + const hash = value._ast._nodeRef.hash + if (astManager && astManager.astMap instanceof Map) { + if (!astManager.astMap.has(hash)) { + value.ast = null + } + } else { + value.ast = null + } + } + // 检查是否是 topScope 对象(通过 sid 和 qid 判断) + if (value != null && typeof value === 'object' && value.sid !== '' && value.qid !== '') { + // 获取所有属性键 + const allKeys = Reflect.ownKeys(value) + // 删除不在允许列表中的属性 + for (const prop of allKeys) { + if (typeof prop === 'string' && !allowedProps.includes(prop)) { + try { + delete (value as any)[prop] + } catch (e) { + // 忽略删除错误(可能是不可配置的属性) + } + } + if (prop === 'rtype') { + // 只保留 rtype 下的 type 和 name 字段,其他字段去掉 + const rtype = (value as { rtype?: RType }).rtype + if (rtype && typeof rtype === 'object') { + const filteredRtype: Partial = {} + if ('type' in rtype) { + filteredRtype.type = rtype.type + } + if ('definiteType' in rtype) { + filteredRtype.definiteType = { type: rtype.definiteType?.type, name: rtype.definiteType?.name } + } + if ('vagueType' in rtype) { + filteredRtype.vagueType = rtype.vagueType + } + ;(value as { rtype: RType }).rtype = filteredRtype as RType + } + } + } + } + } + } else { + for (const [key, value] of symbolTable.symbolMap.entries()) { + // 检查是否是 topScope 对象(通过 sid 和 qid 判断) + if (value != null && typeof value === 'object' && value.sid !== '' && value.qid !== '') { + // 获取所有属性键 + const allKeys = Reflect.ownKeys(value) + // 删除不在允许列表中的属性 + for (const prop of allKeys) { + if (prop === 'rtype') { + // 只保留 rtype 下的 type 和 name 字段,其他字段去掉 + const rtype = (value as { rtype?: RType }).rtype + if (rtype && typeof rtype === 'object') { + const filteredRtype: Partial = {} + if ('type' in rtype) { + filteredRtype.type = rtype.type + } + if ('definiteType' in rtype) { + filteredRtype.definiteType = { type: rtype.definiteType?.type, name: rtype.definiteType?.name } + } + if ('vagueType' in rtype) { + filteredRtype.vagueType = rtype.vagueType + } + ;(value as { rtype: RType }).rtype = filteredRtype as RType + } + } + } + } + } + } + } + + const symbolTableData = serializeObject(analyzer.symbolTable) + + // 创建 symbolTable 文件夹 + const symbolTableDir = path.join(cacheBasePath, 'symbolTable') + if (!fs.existsSync(symbolTableDir)) { + fs.mkdirSync(symbolTableDir, { recursive: true }) + } + // 特殊处理各个 Map 属性:按每 1000 个条目分割,使用子文件夹结构 + for (const key in symbolTableData) { + if (Config.miniSaveContextEnvironment && key.includes('funcSymbolTable')) { + continue + } + if (key === '__yasaConstructorNames') { + continue + } + const value = symbolTableData[key] + if (value && typeof value === 'object') { + splitAndSave(value, path.join(symbolTableDir, key), 1000, true) + } else if (typeof value !== 'function') { + // 基本类型:直接保存 + writeJSONfile(path.join(symbolTableDir, `${key}.json`), value) + } + } + + yasaLog('[SAVE CACHE]Saved symbolTable') + } + + // c. astManager (记录 parent 关系,但不序列化 parent 对象本身) + if (analyzer.astManager) { + // 创建 parent 关系映射 + const parentRelations = new Map() + const astManagerData = serializeObject(analyzer.astManager, true, 100, 0, new WeakSet(), parentRelations) // skipParent = true, 但会记录关系 + + // 创建 astManager 文件夹 + const astManagerDir = path.join(cacheBasePath, 'astManager') + if (!fs.existsSync(astManagerDir)) { + fs.mkdirSync(astManagerDir, { recursive: true }) + } + + // 特殊处理 astMap:按每 1000 个条目分割,使用子文件夹结构 + if (astManagerData.astMap && typeof astManagerData.astMap === 'object') { + splitAndSave(astManagerData.astMap, path.join(astManagerDir, 'astMap'), 1000, true) + yasaLog(`[SAVE CACHE]Saved astManager.astMap (${Object.keys(astManagerData.astMap).length} entries)`) + } + + // 保存 astManager 的其他属性(除了 astMap) + for (const key in astManagerData) { + if (key !== 'astMap' && key !== '__yasaConstructorNames') { + const value = astManagerData[key] + if (value != null) { + splitAndSave(value, path.join(astManagerDir, key)) + } + } + } + + // 保存 parent 关系映射 + if (!Config.miniSaveContextEnvironment) { + if (parentRelations.size > 0) { + const parentRelationsObj: any = {} + for (const [nodehash, parentNodehash] of parentRelations.entries()) { + parentRelationsObj[nodehash] = parentNodehash + } + splitAndSave(parentRelationsObj, path.join(astManagerDir, 'parentRelations')) + yasaLog(`[SAVE CACHE]Saved astManager parent relations (${parentRelations.size} relations)`) + } + } + yasaLog('[SAVE CACHE]Saved astManager (parent relations recorded)') + } + + // d. funcSymbolTable + if (!Config.miniSaveContextEnvironment) { + if (analyzer.funcSymbolTable) { + // 重要:funcSymbolTable 是一个 Proxy,需要绕过 Proxy 直接访问原始对象(target) + // 从 symbolTable 获取 funcSymbolTableTarget,这样可以直接获取 UUID 而不是符号值对象 + const { funcSymbolTableTarget } = analyzer.symbolTable as any + if (funcSymbolTableTarget) { + // 直接序列化原始对象,其中存储的是 UUID + const funcSymbolTableData = serializeObject(funcSymbolTableTarget) + splitAndSave(funcSymbolTableData, path.join(cacheBasePath, 'funcSymbolTable'), 1000, true) + yasaLog('[SAVE CACHE]Saved funcSymbolTable') + } else { + // 如果没有 funcSymbolTableTarget,尝试直接序列化(可能不是 Proxy) + const funcSymbolTableData = serializeObject(analyzer.funcSymbolTable) + splitAndSave(funcSymbolTableData, path.join(cacheBasePath, 'funcSymbolTable'), 1000, true) + yasaLog('[SAVE CACHE]Saved funcSymbolTable') + } + } + } + + // e. statistics + if (!Config.miniSaveContextEnvironment) { + if (analyzer.statistics) { + writeJSONfile(path.join(cacheBasePath, 'statistics.json'), analyzer.statistics) + yasaLog('[SAVE CACHE]Saved statistics') + } + } + + // f. ainfo + if (!Config.miniSaveContextEnvironment) { + if (analyzer.ainfo) { + // 在序列化前,记录 callgraph 是否为 Graph 实例 + const ainfoData = serializeObject(analyzer.ainfo) + // 如果 callgraph 是 Graph 实例,记录其类型 + if (analyzer.ainfo.callgraph && analyzer.ainfo.callgraph.constructor?.name === 'GraphClass') { + ainfoData.__yasaCallgraphIsGraph = true + } + splitAndSave(ainfoData, path.join(cacheBasePath, 'ainfo'), 1000, true) + yasaLog('[SAVE CACHE]Saved ainfo') + } + } + + // g. sourceCodeCache + if (!Config.miniSaveContextEnvironment) { + if (analyzer.sourceCodeCache) { + const sourceCodeCacheData = serializeObject(analyzer.sourceCodeCache) + splitAndSave(sourceCodeCacheData, path.join(cacheBasePath, 'sourceCodeCache'), 1000, true) + yasaLog('[SAVE CACHE]Saved sourceCodeCache') + } + } + + // h. classMap + if (analyzer.classMap) { + const classMapData = serializeObject(analyzer.classMap) + splitAndSave(classMapData, path.join(cacheBasePath, 'classMap'), 1000, true) + yasaLog('[SAVE CACHE]Saved classMap') + } + + // 创建 topScope 文件夹 + const topScopeDir = path.join(cacheBasePath, 'topScope') + if (!fs.existsSync(topScopeDir)) { + fs.mkdirSync(topScopeDir, { recursive: true }) + } + + // i. topScope.context.modules (UUID for backward compatibility) + const modulesUuid = analyzer.topScope.context?.modules?.uuid + if (modulesUuid !== undefined) { + writeJSONfile(path.join(topScopeDir, 'moduleManagerUuid.json'), { + __moduleManagerUuid: modulesUuid, + }) + yasaLog('[SAVE CACHE]Saved topScope.context.modules (moduleManagerUuid)') + } + + // j. topScope.context.packages (UUID for backward compatibility) + const packagesUuid = analyzer.topScope.context?.packages?.uuid + if (packagesUuid !== undefined) { + writeJSONfile(path.join(topScopeDir, 'packageManagerUuid.json'), { + __packageManagerUuid: packagesUuid, + }) + yasaLog('[SAVE CACHE]Saved topScope.context.packages (packageManagerUuid)') + } + + // k. topScope.value(通过 getter 访问,EntityValue 返回 _members.getProxy()) + const topScopeField = topScopeTarget.value + if (topScopeField !== undefined) { + const fieldData = serializeObject(topScopeField) + writeJSONfile(path.join(topScopeDir, 'field.json'), { _field: fieldData }) + yasaLog('[SAVE CACHE]Saved topScope.value') + } + + // l. topScope.uuid + if (topScopeTarget.uuid !== undefined) { + writeJSONfile(path.join(topScopeDir, 'uuid.json'), { uuid: topScopeTarget.uuid }) + yasaLog('[SAVE CACHE]Saved topScope.uuid') + } + + // m. topScope 的其他所有属性 + // 获取 topScope 的所有属性,排除已经单独保存的属性 + const excludedProps = new Set([ + 'context', + '_field', + 'uuid', + 'funcSymbolTable', + 'symbolTable', + 'parent', + ]) + const topScopeOtherProps: any = {} + const topScopePropTypes: any = {} // 记录每个属性的类型 + const allTopScopeKeys = Reflect.ownKeys(topScopeTarget) + for (const key of allTopScopeKeys) { + if (typeof key === 'symbol') { + continue + } + const keyStr = key as string + // 跳过内部属性和已单独保存的属性 + if (keyStr.startsWith('__yasa')) { + if (!names.includes(keyStr)) { + names.push(keyStr) + } + continue + } + if (excludedProps.has(keyStr)) { + continue + } + try { + const value = Reflect.get(topScopeTarget, keyStr) + // 记录属性类型 + if (value instanceof Map) { + topScopePropTypes[keyStr] = 'Map' + } else if (value instanceof Set) { + topScopePropTypes[keyStr] = 'Set' + } else if (Array.isArray(value)) { + topScopePropTypes[keyStr] = 'Array' + } else if (value && typeof value === 'object' && value.constructor?.name) { + // 记录其他对象类型的构造函数名称 + topScopePropTypes[keyStr] = value.constructor.name + } + // 序列化属性值 + topScopeOtherProps[keyStr] = serializeObject(value) + } catch (e) { + yasaWarning(`Failed to serialize topScope property ${keyStr}: ${e}`) + } + } + // 如果有其他属性,保存它们 + if (Object.keys(topScopeOtherProps).length > 0) { + // 将类型信息添加到数据中 + topScopeOtherProps.__yasaPropTypes = topScopePropTypes + splitAndSave(topScopeOtherProps, path.join(topScopeDir, 'otherProps')) + yasaLog(`[SAVE CACHE]Saved topScope other properties (${Object.keys(topScopeOtherProps).length - 1} properties)`) + } + + // 保存 checkerManager.registered_checkers 中每个 checker 的 sourceScope + if (analyzer.checkerManager && analyzer.checkerManager.registered_checkers) { + const checkerSourceScopes: any = {} + for (const checkerName in analyzer.checkerManager.registered_checkers) { + if (Object.prototype.hasOwnProperty.call(analyzer.checkerManager.registered_checkers, checkerName)) { + const checker = analyzer.checkerManager.registered_checkers[checkerName] + if (checker && checker.sourceScope) { + // 序列化 sourceScope + checkerSourceScopes[checkerName] = serializeObject(checker.sourceScope) + } + } + } + if (Object.keys(checkerSourceScopes).length > 0) { + writeJSONfile(path.join(cacheBasePath, 'checkerSourceScopes.json'), checkerSourceScopes) + yasaLog(`[SAVE CACHE]Saved checker sourceScopes (${Object.keys(checkerSourceScopes).length} checkers)`) + } + } + + // 保存缓存元数据 + const metadata = { + cacheId: id, + timestamp: new Date().toISOString(), + version: '1.0', + } + writeJSONfile(path.join(cacheBasePath, 'metadata.json'), metadata) + yasaLog(`[SAVE CACHE]Analyzer cache saved successfully to ${cacheBasePath}`) + } catch (err: any) { + yasaError(`[SAVE CACHE]Failed to save analyzer cache: ${err.message}`) + throw err + } +} + +/** + * 加载分析器缓存 + * @param analyzer 分析器实例 + * @param cacheId 缓存 ID + * @param sourcePath + * @returns 是否成功加载 + */ +export function loadAnalyzerCache(analyzer: any, cacheId?: string, sourcePath?: string): boolean { + try { + const cacheDir = getCacheDir() + let cacheFolder: string | null = null + + if (cacheId) { + // 如果提供了 cacheId,直接使用 + cacheFolder = path.join(cacheDir, cacheId) + if (!fs.existsSync(cacheFolder) || !fs.statSync(cacheFolder).isDirectory()) { + yasaLog(`[LOAD CACHE]Cache folder not found at ${cacheFolder}`) + cacheFolder = null + } + } + + // 如果 cacheId 未提供或未找到,且提供了 sourcePath,则根据 repoName 和 hashPrefix 查找 + if (!cacheFolder && sourcePath) { + cacheFolder = findCacheFolder(sourcePath) + if (cacheFolder) { + yasaLog(`[LOAD CACHE]Found cache folder by sourcePath: ${cacheFolder}`) + } + } + + // 如果仍未找到,使用默认值 + if (!cacheFolder) { + cacheFolder = path.join(cacheDir, 'default') + } + + // 检查文件夹是否存在 + if (!fs.existsSync(cacheFolder) || !fs.statSync(cacheFolder).isDirectory()) { + yasaLog(`[LOAD CACHE]Cache folder not found at ${cacheFolder}`) + return false + } + + const cacheBasePath = cacheFolder + + // 检查元数据文件是否存在 + const metadataPath = path.join(cacheBasePath, 'metadata.json') + if (!fs.existsSync(metadataPath)) { + yasaLog(`[LOAD CACHE]Cache metadata not found at ${metadataPath}`) + return false + } + + yasaLog(`[LOAD CACHE]Loading analyzer cache from ${cacheBasePath}...`) + + // 获取 topScope 的原始对象(绕过 Proxy) + const topScopeTarget = (analyzer.topScope as any)[RAW_TARGET] || analyzer.topScope + + // a. fileManager + const fileManagerData = loadFromSplit(path.join(cacheBasePath, 'fileManager')) + if (fileManagerData) { + analyzer.fileManager = fileManagerData + yasaLog('[LOAD CACHE]Loaded fileManager') + } + + // b. symbolTable + // 检查是否存在子文件夹结构 + const symbolTableDir = path.join(cacheBasePath, 'symbolTable') + let symbolTableData: any = null + + if (fs.existsSync(symbolTableDir) && fs.statSync(symbolTableDir).isDirectory()) { + // 从子文件夹结构加载 + symbolTableData = {} + const files = fs.readdirSync(symbolTableDir) + for (const file of files) { + // 跳过 info.json + if (file === 'info.json') { + continue + } + const filePath = path.join(symbolTableDir, file) + const stat = fs.statSync(filePath) + + if (stat.isDirectory()) { + // 是文件夹,说明是 Map 数据,使用 loadFromSplit 加载 + const propName = file + const propData = loadFromSplit(filePath) + if (propData !== null) { + symbolTableData[propName] = propData + } + } else if (file.endsWith('.json')) { + // 是 JSON 文件,直接加载 + const propName = file.replace(/\.json$/, '').replace(/\.part\d+$/, '') + try { + const propData = jsonfile.readFileSync(filePath) + symbolTableData[propName] = propData + } catch (err: any) { + yasaWarning(`Failed to load symbolTable property ${propName}: ${err.message}`) + } + } + } + } else { + // 使用原来的方式加载 + symbolTableData = loadFromSplit(path.join(cacheBasePath, 'symbolTable')) + } + + if (symbolTableData && Object.keys(symbolTableData).length > 0) { + // 反序列化 Map 和 Set,传递 topScope 引用以便恢复特殊标记 + const deserializedData = deserializeObject(symbolTableData, analyzer.topScope) + // 需要恢复 symbolTable 的方法和状态 + // 先恢复 Map 类型的属性 + if (deserializedData.symbolMap instanceof Map) { + const { symbolMap } = deserializedData + // 遍历 symbolMap,将 topScope 特殊标记替换为实际引用 + // 同时确保所有 Unit 对象的属性都被正确恢复(包括 astNodehash) + for (const [key, value] of symbolMap.entries()) { + if (value && typeof value === 'object' && (value as any).__yasaTopScopeMarker === true) { + symbolMap.set(key, analyzer.topScope) + } else if (value && typeof value === 'object' && value.vtype) { + // 这是一个 Unit 对象,确保所有属性都被正确恢复 + // deserializeObject 已经创建了新的对象,但我们需要确保所有属性都被正确赋值 + // 这里 value 已经是反序列化后的对象,应该包含所有属性(包括 astNodehash) + // 不需要额外操作,因为 deserializeObject 已经处理了所有属性 + } + } + ;(analyzer.symbolTable as any).symbolMap = symbolMap + } + + // 恢复其他属性 + for (const key in deserializedData) { + if (key !== 'symbolMap' && Object.prototype.hasOwnProperty.call(deserializedData, key)) { + ;(analyzer.symbolTable as any)[key] = deserializedData[key] + } + } + yasaLog('[LOAD CACHE]Loaded symbolTable') + } + + // c. astManager + // 检查是否存在子文件夹结构 + const astManagerDir = path.join(cacheBasePath, 'astManager') + let astManagerData: any = null + + if (fs.existsSync(astManagerDir) && fs.statSync(astManagerDir).isDirectory()) { + // 从子文件夹结构加载 + astManagerData = {} + const files = fs.readdirSync(astManagerDir) + for (const file of files) { + // 跳过 info.json + if (file === 'info.json') { + continue + } + const filePath = path.join(astManagerDir, file) + const stat = fs.statSync(filePath) + + if (stat.isDirectory()) { + // 是文件夹,说明是 Map 数据(如 astMap),使用 loadFromSplit 加载 + const propName = file + const propData = loadFromSplit(filePath) + if (propData !== null) { + astManagerData[propName] = propData + } + } else if (file.endsWith('.json')) { + // 是 JSON 文件,直接加载 + const propName = file.replace(/\.json$/, '').replace(/\.part\d+$/, '') + try { + const propData = jsonfile.readFileSync(filePath) + astManagerData[propName] = propData + } catch (err: any) { + yasaWarning(`Failed to load astManager property ${propName}: ${err.message}`) + } + } + } + } else { + // 使用原来的方式加载 + astManagerData = loadFromSplit(path.join(cacheBasePath, 'astManager')) + } + + if (astManagerData) { + // 先反序列化 astManagerData,将 astMap 从普通对象转换为 Map + // 注意:在反序列化 AST 节点时跳过 parent 属性,后续统一设置 + const deserializedAstManager = deserializeObject(astManagerData, analyzer.topScope, true) // skipParentForAST = true + Object.assign(analyzer.astManager, deserializedAstManager) + + const { astMap } = analyzer.astManager as any + if (astMap instanceof Map) { + // 第一步:替换所有子节点为 astMap 中的对象 + // 递归函数:替换节点及其所有子节点为 astMap 中的对象 + const replaceChildrenWithAstMapNodes = (node: any, visited: WeakSet = new WeakSet()): void => { + if (!node || typeof node !== 'object' || visited.has(node)) { + return + } + visited.add(node) + + // 遍历节点的所有属性 + for (const key in node) { + if (Object.prototype.hasOwnProperty.call(node, key)) { + // 跳过 parent 属性(后续统一设置) + if (key === 'parent') { + continue + } + + const value = node[key] + + // 如果是数组,递归处理每个元素 + if (Array.isArray(value)) { + for (let i = 0; i < value.length; i++) { + const item = value[i] + if (item && typeof item === 'object' && item.type && item._meta?.nodehash) { + // 如果子节点有 nodehash,从 astMap 中获取对应的对象 + const { nodehash } = item._meta + const astMapNode = astMap.get(nodehash) + if (astMapNode && astMapNode !== item) { + // 替换为 astMap 中的对象 + value[i] = astMapNode + // 继续递归处理替换后的节点 + replaceChildrenWithAstMapNodes(astMapNode, visited) + } else if (astMapNode === item) { + // 已经是同一个对象,继续递归处理 + replaceChildrenWithAstMapNodes(item, visited) + } else { + // 不在 astMap 中,继续递归处理(可能是新节点) + replaceChildrenWithAstMapNodes(item, visited) + } + } else if (item && typeof item === 'object' && item.type) { + // 没有 nodehash,但可能是 AST 节点,继续递归处理 + replaceChildrenWithAstMapNodes(item, visited) + } + } + } else if (value && typeof value === 'object' && value.type && value._meta?.nodehash) { + // 如果子节点有 nodehash,从 astMap 中获取对应的对象 + const { nodehash } = value._meta + const astMapNode = astMap.get(nodehash) + if (astMapNode && astMapNode !== value) { + // 替换为 astMap 中的对象 + node[key] = astMapNode + // 继续递归处理替换后的节点 + replaceChildrenWithAstMapNodes(astMapNode, visited) + } else if (astMapNode === value) { + // 已经是同一个对象,继续递归处理 + replaceChildrenWithAstMapNodes(value, visited) + } else { + // 不在 astMap 中,继续递归处理(可能是新节点) + replaceChildrenWithAstMapNodes(value, visited) + } + } else if (value && typeof value === 'object' && value.type) { + // 没有 nodehash,但可能是 AST 节点,继续递归处理 + replaceChildrenWithAstMapNodes(value, visited) + } + } + } + } + + // 遍历所有节点,替换子节点为 astMap 中的对象 + for (const [nodehash, astNode] of astMap.entries()) { + if (astNode && typeof astNode === 'object' && astNode.type) { + replaceChildrenWithAstMapNodes(astNode) + } + } + + // 第二步:清理所有节点的 parent 引用 + const cleanupParent = (node: any, visited: WeakSet = new WeakSet()): void => { + if (!node || typeof node !== 'object' || visited.has(node)) { + return + } + visited.add(node) + + // 如果节点有 parent,先删除它(后续统一设置) + if (node.parent) { + delete node.parent + } + + // 递归处理所有属性(可能是数组或对象) + for (const key in node) { + if (Object.prototype.hasOwnProperty.call(node, key)) { + const value = node[key] + if (Array.isArray(value)) { + for (const item of value) { + if (item && typeof item === 'object' && item.type) { + cleanupParent(item, visited) + } + } + } else if (value && typeof value === 'object' && value.type) { + cleanupParent(value, visited) + } + } + } + } + + for (const [nodehash, astNode] of astMap.entries()) { + if (astNode && typeof astNode === 'object' && astNode.type) { + cleanupParent(astNode) + } + } + + // 第三步:根据 parentRelations 统一设置 parent + const parentRelationsData = loadFromSplit(path.join(astManagerDir, 'parentRelations')) + if (parentRelationsData) { + let restoredCount = 0 + let missingNodeCount = 0 + let missingParentCount = 0 + for (const nodehash in parentRelationsData) { + if (Object.prototype.hasOwnProperty.call(parentRelationsData, nodehash)) { + const parentNodehash = parentRelationsData[nodehash] + const astNode = astMap.get(nodehash) + const parentNode = astMap.get(parentNodehash) + if (!astNode) { + missingNodeCount++ + // yasaWarning(`Node with nodehash ${nodehash} not found in astMap`) + continue + } + if (!parentNode) { + missingParentCount++ + continue + } + // 确保 parent 指向 astMap 中的对象 + astNode.parent = parentNode + restoredCount++ + } + } + yasaLog( + `[LOAD CACHE]Restored ${restoredCount} parent relations in astManager (missing nodes: ${missingNodeCount}, missing parents: ${missingParentCount})` + ) + } else { + yasaWarning('[LOAD CACHE]parentRelationsData not found') + } + } else { + yasaWarning('[LOAD CACHE]astManager.astMap is not a Map instance') + } + + yasaLog('[LOAD CACHE]Loaded astManager') + } + + // d. funcSymbolTable + const funcSymbolTableData = loadFromSplit(path.join(cacheBasePath, 'funcSymbolTable')) + if (funcSymbolTableData) { + // funcSymbolTable 的原始对象(target) + const funcSymbolTableTarget = funcSymbolTableData + // 重新创建 Proxy,自动处理 UUID 和对象的转换 + analyzer.funcSymbolTable = new Proxy(funcSymbolTableTarget, { + get: (target, prop: string | symbol) => { + // 如果访问的是 Symbol 属性(如 Symbol.iterator),直接返回 + if (typeof prop === 'symbol') { + return (target as any)[prop] + } + // 如果访问的是对象自身的方法或属性(如 toString, valueOf 等),直接返回 + if (prop === 'toString' || prop === 'valueOf' || prop === 'constructor') { + return (target as any)[prop] + } + const value = target[prop] + // 如果是 UUID,从符号表中获取对象 + if (value && typeof value === 'string' && value.startsWith('symuuid_')) { + const unit = analyzer.symbolTable.get(value) + // 如果从符号表获取到了对象,返回对象;否则返回 null + return unit || null + } + // 如果不是 UUID,直接返回原值(可能是 undefined、null 或其他值) + return value + }, + set: (target, prop: string, value: any) => { + // 如果新值是符号值对象,转换为 UUID 存储 + if (value && typeof value === 'object' && value.vtype && value.qid) { + const uuid = analyzer.symbolTable.register(value) + target[prop] = uuid + // 记录引用关系 + ;(analyzer.symbolTable as any).addFuncSymbolTableRef?.(uuid, prop) + } else { + target[prop] = value + } + return true + }, + deleteProperty: (target, prop: string) => { + delete target[prop] + return true + }, + ownKeys: (target) => { + return Reflect.ownKeys(target) + }, + has: (target, prop) => { + return prop in target + }, + }) as Record + yasaLog('[LOAD CACHE]Loaded funcSymbolTable (Proxy restored)') + } + + // e. statistics + const statisticsPath = path.join(cacheBasePath, 'statistics.json') + if (fs.existsSync(statisticsPath)) { + const statisticsData = jsonfile.readFileSync(statisticsPath) + analyzer.statistics = statisticsData + yasaLog('[LOAD CACHE]Loaded statistics') + } + + // f. ainfo + const ainfoData = loadFromSplit(path.join(cacheBasePath, 'ainfo')) + if (ainfoData) { + // 检查是否需要恢复 callgraph 为 Graph 实例 + if (ainfoData.__yasaCallgraphIsGraph && ainfoData.callgraph) { + // 创建新的 Graph 实例 + const callgraph = new Graph() + // 恢复 nodes Map + if (ainfoData.callgraph.nodes && typeof ainfoData.callgraph.nodes === 'object') { + const nodesMap = new Map() + for (const key in ainfoData.callgraph.nodes) { + if (Object.prototype.hasOwnProperty.call(ainfoData.callgraph.nodes, key)) { + nodesMap.set(key, ainfoData.callgraph.nodes[key]) + } + } + callgraph.nodes = nodesMap + } + // 恢复 edges Map + if (ainfoData.callgraph.edges && typeof ainfoData.callgraph.edges === 'object') { + const edgesMap = new Map() + for (const key in ainfoData.callgraph.edges) { + if (Object.prototype.hasOwnProperty.call(ainfoData.callgraph.edges, key)) { + edgesMap.set(key, ainfoData.callgraph.edges[key]) + } + } + callgraph.edges = edgesMap + } + // 将 callgraph 设置为 Graph 实例 + ainfoData.callgraph = callgraph + // 删除标记 + delete ainfoData.__yasaCallgraphIsGraph + } + analyzer.ainfo = ainfoData + yasaLog('[LOAD CACHE]Loaded ainfo (callgraph restored as Graph instance)') + } + + // g. sourceCodeCache + const sourceCodeCacheData = loadFromSplit(path.join(cacheBasePath, 'sourceCodeCache')) + if (sourceCodeCacheData) { + // 将反序列化的对象转换为 Map + if (sourceCodeCacheData && typeof sourceCodeCacheData === 'object' && !Array.isArray(sourceCodeCacheData)) { + const map = new Map() + for (const key in sourceCodeCacheData) { + if (Object.prototype.hasOwnProperty.call(sourceCodeCacheData, key)) { + const value = sourceCodeCacheData[key] + // 确保值是字符串 + map.set(key, value) + } + } + analyzer.sourceCodeCache = map + } else { + analyzer.sourceCodeCache = new Map() + } + // 更新全局 analyzer 引用 + const SourceLine = require('./source-line') + SourceLine.setGlobalAnalyzer(analyzer) + yasaLog('[LOAD CACHE]Loaded sourceCodeCache') + } + + // h. classMap + const classMapData = loadFromSplit(path.join(cacheBasePath, 'classMap')) + if (classMapData) { + // 将反序列化的对象转换为 Map + if (classMapData && typeof classMapData === 'object' && !Array.isArray(classMapData)) { + const map = new Map() + for (const key in classMapData) { + if (Object.prototype.hasOwnProperty.call(classMapData, key)) { + const value = classMapData[key] + map.set(key, value) + } + } + analyzer.classMap = map + } else { + analyzer.classMap = new Map() + } + yasaLog('[LOAD CACHE]Loaded classMap') + } + + // i. topScope.context.modules (resolve UUID from symbolTable) + const moduleManagerUuidPath = path.join(cacheBasePath, 'topScope', 'moduleManagerUuid.json') + if (fs.existsSync(moduleManagerUuidPath)) { + const moduleManagerUuidData = jsonfile.readFileSync(moduleManagerUuidPath) + if (moduleManagerUuidData.__moduleManagerUuid !== undefined) { + if (!analyzer.topScope.context) { + analyzer.topScope.context = new AnalysisContext() + } + analyzer.topScope.context.modules = analyzer.symbolTable.get(moduleManagerUuidData.__moduleManagerUuid) + yasaLog('[LOAD CACHE]Loaded topScope.context.modules') + } + } + + // j. topScope.context.packages (resolve UUID from symbolTable) + const packageManagerUuidPath = path.join(cacheBasePath, 'topScope', 'packageManagerUuid.json') + if (fs.existsSync(packageManagerUuidPath)) { + const packageManagerUuidData = jsonfile.readFileSync(packageManagerUuidPath) + if (packageManagerUuidData.__packageManagerUuid !== undefined) { + if (!analyzer.topScope.context) { + analyzer.topScope.context = new AnalysisContext() + } + analyzer.topScope.context.packages = analyzer.symbolTable.get(packageManagerUuidData.__packageManagerUuid) + yasaLog('[LOAD CACHE]Loaded topScope.context.packages') + } + } + + // j. topScope.value(从缓存恢复,JSON key 为 _field 保持向后兼容) + const fieldPath = path.join(cacheBasePath, 'topScope', 'field.json') + if (fs.existsSync(fieldPath)) { + const fieldData = jsonfile.readFileSync(fieldPath) + if (fieldData._field !== undefined) { + topScopeTarget.value = fieldData._field + yasaLog('[LOAD CACHE]Loaded topScope.value') + } + } + + // k. topScope.uuid + const uuidPath = path.join(cacheBasePath, 'topScope', 'uuid.json') + if (fs.existsSync(uuidPath)) { + const uuidData = jsonfile.readFileSync(uuidPath) + if (uuidData.uuid !== undefined) { + topScopeTarget.uuid = uuidData.uuid + yasaLog('[LOAD CACHE]Loaded topScope.uuid') + } + } + + // l. topScope 的其他所有属性 + const topScopeOtherPropsData = loadFromSplit(path.join(cacheBasePath, 'topScope', 'otherProps')) + if (topScopeOtherPropsData) { + // 获取类型信息 + const propTypes = topScopeOtherPropsData.__yasaPropTypes || {} + // 先根据类型信息还原 Map 和 Set,然后再反序列化其他嵌套对象 + const processedProps: any = {} + for (const key in topScopeOtherPropsData) { + if (Object.prototype.hasOwnProperty.call(topScopeOtherPropsData, key)) { + // 跳过类型信息标记 + if (key === '__yasaPropTypes') { + continue + } + const propType = propTypes[key] + const value = topScopeOtherPropsData[key] + + // 根据类型信息还原对象类型(在反序列化之前) + if (propType === 'Map') { + // 将普通对象转换为 Map(包括空对象) + const map = new Map() + if (value && typeof value === 'object' && !Array.isArray(value)) { + for (const mapKey in value) { + if (Object.prototype.hasOwnProperty.call(value, mapKey)) { + // 递归反序列化 Map 的值 + map.set(mapKey, deserializeObject(value[mapKey], analyzer.topScope)) + } + } + } + // 即使 value 是 null/undefined 或空对象,也创建空 Map + processedProps[key] = map + } else if (propType === 'Set') { + // 将数组转换为 Set(包括空数组) + const set = new Set() + if (Array.isArray(value)) { + for (const item of value) { + // 递归反序列化 Set 的元素 + set.add(deserializeObject(item, analyzer.topScope)) + } + } + // 即使 value 是 null/undefined 或空数组,也创建空 Set + processedProps[key] = set + } else { + // 对于其他类型,先反序列化,然后再处理特殊类型 + processedProps[key] = deserializeObject(value, analyzer.topScope) + } + } + } + + // 现在处理其他对象类型的还原(需要在反序列化之后) + for (const key in processedProps) { + if (Object.prototype.hasOwnProperty.call(processedProps, key)) { + try { + const propType = propTypes[key] + let value = processedProps[key] + + // 检查是否是 topScope 特殊标记 + if (value && typeof value === 'object' && value.__yasaTopScopeMarker === true) { + value = analyzer.topScope + } + + // 对于其他对象类型(非 Map、Set、Array),使用 shallowCopyValue 恢复 + if ( + propType && + propType !== 'Map' && + propType !== 'Set' && + propType !== 'Array' && + propType !== 'Object' && + value && + typeof value === 'object' + ) { + // 使用 shallowCopyValue 恢复 + const objWithConstructor = { ...value } + Object.defineProperty(objWithConstructor, 'constructor', { + value: { name: propType }, + writable: true, + enumerable: false, + configurable: true, + }) + value = shallowCopyValue(objWithConstructor) + } + + topScopeTarget[key] = value + } catch (e) { + yasaWarning(`Failed to restore topScope property ${key}: ${e}`) + } + } + } + const propCount = Object.keys(processedProps).length + yasaLog(`[LOAD CACHE]Loaded topScope other properties (${propCount} properties)`) + } + + // 更新 topScope 的引用(确保 topScope.context 与 analyzer 中的引用一致) + if (analyzer.topScope) { + if (!analyzer.topScope.context) { + analyzer.topScope.context = new AnalysisContext() + } + analyzer.topScope.context.files = analyzer.fileManager + analyzer.topScope.context.ast = analyzer.astManager + analyzer.topScope.context.symbols = analyzer.symbolTable + analyzer.topScope.context.funcs = analyzer.funcSymbolTable + analyzer.context = analyzer.topScope.context + } + + // 恢复 checkerManager.registered_checkers 中每个 checker 的 sourceScope + if (analyzer.checkerManager && analyzer.checkerManager.registered_checkers) { + const checkerSourceScopesPath = path.join(cacheBasePath, 'checkerSourceScopes.json') + if (fs.existsSync(checkerSourceScopesPath)) { + try { + const checkerSourceScopes = jsonfile.readFileSync(checkerSourceScopesPath) + let restoredCheckerCount = 0 + for (const checkerName in checkerSourceScopes) { + if (Object.prototype.hasOwnProperty.call(checkerSourceScopes, checkerName)) { + // 检查 analyzer.checkerManager.registered_checkers 中是否有相同的 checker + if (Object.prototype.hasOwnProperty.call(analyzer.checkerManager.registered_checkers, checkerName)) { + const checker = analyzer.checkerManager.registered_checkers[checkerName] + if (checker) { + // 反序列化 sourceScope + const sourceScopeData = checkerSourceScopes[checkerName] + if (sourceScopeData) { + const restoredSourceScope = deserializeObject(sourceScopeData, analyzer.topScope) + // 覆盖 checker 的 sourceScope + checker.sourceScope = restoredSourceScope + restoredCheckerCount++ + } + } + } + } + } + if (restoredCheckerCount > 0) { + yasaLog(`[LOAD CACHE]Restored sourceScope for ${restoredCheckerCount} checkers`) + } + } catch (err: any) { + yasaWarning(`[LOAD CACHE]Failed to load checker sourceScopes: ${err.message}`) + } + } + } + + // 恢复所有 Unit 对象的 Proxy 结构(_field, decls, overloaded) + if (analyzer.symbolTable && (analyzer.symbolTable as any).symbolMap instanceof Map) { + const { symbolMap } = analyzer.symbolTable as any + for (const [uuid, unit] of symbolMap.entries()) { + if (unit && typeof unit === 'object' && unit.vtype) { + // 这是一个 Unit 对象,需要恢复其 Proxy + try { + // 在恢复 Proxy 之前,确保所有属性(包括 astNodehash)都已经被正确恢复 + // deserializeObject 应该已经恢复了所有属性,但我们需要确保它们没有被覆盖 + + let fieldTarget = unit.value + if (fieldTarget && util.types.isProxy(fieldTarget)) { + fieldTarget = (fieldTarget as any)[RAW_TARGET] || fieldTarget + } + if (fieldTarget === undefined || fieldTarget === null || typeof fieldTarget !== 'object') { + fieldTarget = {} + } + + if (unit.vtype === 'union' && typeof unit._syncElements === 'function') { + const arr = Array.isArray(fieldTarget) ? fieldTarget : Object.values(fieldTarget) + unit._syncElements(arr) + } else { + unit.value = fieldTarget + } + } catch (e) { + yasaWarning(`Failed to restore Proxy for Unit ${uuid}: ${e}`) + } + } + } + } + + yasaLog(`[LOAD CACHE]Analyzer cache loaded successfully from ${cacheBasePath}`) + return true + } catch (err: any) { + yasaError(`[LOAD CACHE]Failed to load analyzer cache: ${err.message}`) + return false + } +} + +/** + * 生成缓存 ID(基于源路径、日期和 MD5 哈希) + * @param sourcePath 源路径 + * @returns 缓存 ID,格式:代码库名字_日期_MD5哈希(前8位) + */ +export function generateCacheId(sourcePath: string): string { + const crypto = require('crypto') + + // 从路径中提取代码库名字(路径的最后一部分) + const normalizedPath = path.normalize(sourcePath) + const pathParts = normalizedPath.split(path.sep).filter((part: string) => part.length > 0) + const repoName = pathParts.length > 0 ? pathParts[pathParts.length - 1] : 'default' + // 清理代码库名字,移除特殊字符,只保留字母、数字、下划线和连字符 + const cleanRepoName = repoName.replace(/[^a-zA-Z0-9_-]/g, '_') + + // 获取当前日期(格式:YYYYMMDD) + const now = new Date() + const year = now.getFullYear() + const month = String(now.getMonth() + 1).padStart(2, '0') + const day = String(now.getDate()).padStart(2, '0') + const dateStr = `${year}${month}${day}` + + // 使用源路径生成 MD5 哈希(保证幂等性) + const hash = crypto.createHash('md5').update(sourcePath).digest('hex') + const hashPrefix = hash.substring(0, 8) // 取前8位 + + // 组合:代码库名字_MD5哈希前缀_日期 + return `${cleanRepoName}_${hashPrefix}_${dateStr}` +} + +/** + * 根据 repoName 和 hashPrefix 查找缓存文件夹 + * @param sourcePath 源路径 + * @returns 缓存文件夹路径,如果不存在则返回 null + */ +export function findCacheFolder(sourcePath: string): string | null { + const crypto = require('crypto') + + // 从路径中提取代码库名字(路径的最后一部分) + const normalizedPath = path.normalize(sourcePath) + const pathParts = normalizedPath.split(path.sep).filter((part: string) => part.length > 0) + const repoName = pathParts.length > 0 ? pathParts[pathParts.length - 1] : 'default' + // 清理代码库名字,移除特殊字符,只保留字母、数字、下划线和连字符 + const cleanRepoName = repoName.replace(/[^a-zA-Z0-9_-]/g, '_') + + // 使用源路径生成 MD5 哈希(保证幂等性) + const hash = crypto.createHash('md5').update(sourcePath).digest('hex') + const hashPrefix = hash.substring(0, 8) // 取前8位 + + // 查找匹配的缓存文件夹:repoName_hashPrefix_* + const cacheDir = getCacheDir() + if (!fs.existsSync(cacheDir)) { + return null + } + + const prefix = `${cleanRepoName}_${hashPrefix}_` + const files = fs.readdirSync(cacheDir) + + // 查找以 prefix 开头的文件夹 + for (const file of files) { + if (file.startsWith(prefix)) { + const folderPath = path.join(cacheDir, file) + const stat = fs.statSync(folderPath) + if (stat.isDirectory()) { + // 检查是否有 metadata.json 文件 + const metadataPath = path.join(folderPath, 'metadata.json') + if (fs.existsSync(metadataPath)) { + return folderPath + } + } + } + } + + return null +} diff --git a/src/engine/analyzer/common/analyzer.ts b/src/engine/analyzer/common/analyzer.ts index 924607dd..f92ed184 100644 --- a/src/engine/analyzer/common/analyzer.ts +++ b/src/engine/analyzer/common/analyzer.ts @@ -1,38 +1,294 @@ +import { primitiveToString } from '../../../util/variable-util' +import type { ISymbolTableManager } from './symbol-table-interface' +import type { Invocation } from '../../../resolver/common/value/invocation' +import type { + BaseNode, + Node, + Identifier, + Literal, + CompileUnit, + IfStatement, + SwitchStatement, + ForStatement, + WhileStatement, + RangeStatement, + ReturnStatement, + BreakStatement, + ContinueStatement, + ThrowStatement, + TryStatement, + ExpressionStatement, + ScopedStatement, + BinaryExpression, + UnaryExpression, + AssignmentExpression, + ConditionalExpression, + SuperExpression, + ThisExpression, + MemberAccess, + SliceExpression, + TupleExpression, + ObjectExpression, + CallExpression, + CastExpression, + NewExpression, + FunctionDefinition, + ClassDefinition, + VariableDeclaration, + ImportExpression, + SpreadElement, + YieldExpression, + ExportStatement, +} from '../../../types/uast' +import type { + Scope as ScopeType, + State, + Value, + SymbolValue as SymbolValueType, + VoidValue as VoidValueType, + SpreadValue as SpreadValueType, +} from '../../../types/analyzer' +import { BaseAnalyzer } from './base-analyzer' +import { BinaryExprValue } from './value/binary-expr' +import { UnaryExprValue } from './value/unary-expr' +import { CallExprValue } from './value/call-expr' +import { AnalysisContext } from './analysis-context' + const _ = require('lodash') const Uuid = require('node-uuid') -const chalk = require('chalk') const logger = require('../../../util/logger')(__filename) const Config = require('../../../config') const Initializer = require('./initializer') -const MemSpace = require('./memSpace') const NativeResolver = require('./native-resolver') +import type { CallArg, CallArgs, CallInfo, BoundParam, BoundCall } from './call-args' +import { getLegacyArgValues, INTERNAL_CALL } from './call-args' const MemState = require('./memState') const Scope = require('./scope') const SourceLine = require('./source-line') const AstUtil = require('../../../util/ast-util') -const ValueFormatter = require('../../../util/value-formatter') const StateUtil = require('../../util/state-util') const SymAddress = require('./sym-address') const { unionAllValues } = require('./memStateBVT') -const { cloneWithDepth } = require('../../../util/clone-util') +const { shallowCopyValue, buildNewValueInstance, lodashCloneWithTag } = require('../../../util/clone-util') const { handleException } = require('./exception-handler') const { - ValueUtil: { ObjectValue, Scoped, PrimitiveValue, UndefinedValue, UnionValue, SymbolValue, PackageValue }, + ValueUtil: { + ObjectValue, + Scoped, + PrimitiveValue, + UndefinedValue, + UnionValue, + SymbolValue, + PackageValue, + VoidValue, + SpreadValue, + }, } = require('../../util/value-util') const { filterDataFromScope, shallowEqual } = require('../../../util/common-util') const Rules = require('../../../checker/common/rules-basic-handler') const { getAbsolutePath, loadJSONfile } = require('../../../util/file-util') +const { saveAnalyzerCache, loadAnalyzerCache, generateCacheId } = require('./analyzer-cache') const { matchSinkAtFuncCallWithCalleeType } = require('../../../checker/taint/common-kit/sink-util') -const { moveExistElementsToBuffer } = require('../java/common/builtins/buffer') -const { PerformanceTracker } = require('../../../util/performance-tracker') +const { moveExistElementsToBuffer, addElementToBuffer } = require('../java/common/builtins/buffer') +const { performanceTracker } = require('../../../util/performance-tracker') +const { checkInvocationMatchSink } = require('../../../checker/taint/common-kit/sink-util') +const OutputStrategyAutoRegister = require('./output-strategy-auto-register') + +const ASTManager = require('./ast-manager') +const SymbolTableManager = require('./symbol-table-manager') +const { setGlobalASTManager, setGlobalSymbolTable, getGlobalSymbolTable } = require('../../../util/global-registry') +const { prettyPrint } = require('../../../util/ast-util') + +/** + * 临时符号表管理器:包装原始符号表,在执行 symbolInterpretFn 期间自动拷贝符号值 + * 实现 ISymbolTableManager 接口,与 SymbolTableManager 具有相同的接口 + */ +class TemporarySymbolTableManager { + private originalSymbolTable: InstanceType // SymbolTableManager 实例 + + private tmpSymbolTableManager: InstanceType // SymbolTableManager 实例,其 symbolMap 作为临时符号表存储,同时提供 UUID 引用管理功能 + + private copiedUnits: Map // 记录已拷贝的 Unit 对象,避免重复拷贝 + + /** + * + * @param originalSymbolTable SymbolTableManager 实例 + */ + constructor(originalSymbolTable: InstanceType) { + this.originalSymbolTable = originalSymbolTable + // 使用 tmpSymbolTableManager 的 symbolMap 作为临时符号表存储,同时使用其 UUID 引用管理功能 + this.tmpSymbolTableManager = new SymbolTableManager() + this.copiedUnits = new Map() + } + + /** + * 获取临时符号表的 symbolMap(直接访问私有属性) + * @private + */ + private getTmpSymbolMap(): Map { + // 通过反射访问私有属性 symbolMap + return (this.tmpSymbolTableManager as any).symbolMap + } + + /** + * 拷贝 Unit 对象(按需拷贝,只拷贝当前对象,不递归拷贝 parent 和 field 中的引用) + * _parentRef 和 field 中的 uuid 保持原样,当真正访问时再按需拷贝 + * 直接复制内存中的属性值,不触发 getter/setter,避免循环调用 + * @param unit + */ + private tmpTableCopyUnit(unit: any): any { + if (!unit || typeof unit !== 'object') { + return unit + } + + // 如果已经拷贝过,直接返回 + if (unit.uuid && this.copiedUnits.has(unit.uuid)) { + return this.copiedUnits.get(unit.uuid) + } + + // 创建新对象,保持原型链 + const copiedUnit = shallowCopyValue(unit) + + // 确保 _parentRef 被正确拷贝(ValueRef 不可变,可安全共享引用) + const originalParentRef = unit._parentRef + if (originalParentRef && !copiedUnit._parentRef) { + copiedUnit._parentRef = originalParentRef + } + + // 注册到临时符号表(直接存储到 tmpSymbolTableManager 的 symbolMap) + if (copiedUnit.uuid) { + this.getTmpSymbolMap().set(copiedUnit.uuid, copiedUnit) + this.copiedUnits.set(copiedUnit.uuid, copiedUnit) + } + + return copiedUnit + } + + /** + * 获取 Unit 对象:如果存在于临时符号表,直接返回;否则从原始符号表获取并拷贝 + * 如果临时符号表中的符号值没有 parent,但从原始符号表查有 parent,则重新完整拷贝 + * @param uuid + */ + get(uuid: string | null | undefined): any { + if (!uuid) { + return null + } + + // 先检查临时符号表(使用 tmpSymbolTableManager 的 symbolMap) + const tmpUnit = this.getTmpSymbolMap().get(uuid) || null + if (tmpUnit) { + // 检查临时符号表中的符号值是否有 parent(通过 _parentRef 判断) + if (!tmpUnit._parentRef) { + // 临时符号表中没有 parent,检查原始符号表中是否有 + const originalUnit = this.originalSymbolTable.get(uuid) + if (originalUnit?._parentRef) { + // 从临时符号表中删除旧的拷贝 + this.getTmpSymbolMap().delete(uuid) + this.copiedUnits.delete(uuid) + // 重新完整拷贝(包括 _parentRef) + return this.tmpTableCopyUnit(originalUnit) + } + } + return tmpUnit + } + + // 从原始符号表获取 + const originalUnit = this.originalSymbolTable.get(uuid) + if (!originalUnit) { + return null + } + + // 深拷贝并注册到临时符号表 + return this.tmpTableCopyUnit(originalUnit) + } + + /** + * 注册 Unit 对象到临时符号表 + * 当 UUID 变化时,自动更新所有引用该 UUID 的地方 + * @param unit + */ + register(unit: any): string | null { + if (!unit || typeof unit !== 'object') { + return null + } + + // 使用临时符号表管理器计算 UUID + const uuid = this.tmpSymbolTableManager.calculateUUID(unit) + if (!uuid) { + return null + } + + // 设置 UUID + unit.uuid = uuid + + // 直接存储到 tmpSymbolTableManager 的 symbolMap(而不是调用 register,因为 register 会重新计算 UUID) + if (uuid) { + this.getTmpSymbolMap().set(uuid, unit) + } + + return uuid + } + + /** + * 检查 UUID 是否存在 + * @param uuid + */ + has(uuid: string | null | undefined): boolean { + if (!uuid) { + return false + } + return this.getTmpSymbolMap().has(uuid) || this.originalSymbolTable.has(uuid) + } + + /** + * 计算 UUID + * @param unit + * @param qidSuffix + */ + calculateUUID(unit: any, qidSuffix?: any): string | null { + return this.tmpSymbolTableManager.calculateUUID(unit, qidSuffix) + } + + /** + * 删除 Unit 对象 + * @param uuid + */ + delete(uuid: string | null | undefined): void { + if (uuid) { + this.getTmpSymbolMap().delete(uuid) + } + } + + /** + * 清空临时符号表 + */ + clear(): void { + this.getTmpSymbolMap().clear() + this.copiedUnits.clear() + } + + /** + * 获取临时符号表大小 + */ + size(): number { + return this.getTmpSymbolMap().size + } + + /** + * 获取临时符号表 + */ + getMap(): Map { + return this.tmpSymbolTableManager.getMap() + } +} /** * The main AST analyzer with checker invoking * @param checker * @constructor */ -class Analyzer extends MemSpace { +class Analyzer extends BaseAnalyzer { options: any checkerManager: any @@ -41,17 +297,17 @@ class Analyzer extends MemSpace { lastReturnValue: any - thisFClos: any + _thisFClos: any // 内部存储,通过 getter/setter 访问 - entry_fclos: any + _entry_fclos: any // 内部存储,通过 getter/setter 访问 inRange: boolean ainfo: Record - sourceCodeCache: Record + sourceCodeCache: Map - lastProcessedNode: any + _lastProcessedNode: any // 内部存储,通过 getter/setter 访问 thisIterationTime: number @@ -63,9 +319,9 @@ class Analyzer extends MemSpace { libFuncTagPropagationRuleArray: any[] - moduleManager: any + context!: AnalysisContext - packageManager: any + libArgToThisSidBlacklistKeywords: string[] fileManager!: Record @@ -73,10 +329,21 @@ class Analyzer extends MemSpace { topScope: any + astManager: any + + // 操作符号表:基于analyzer中使用this.symbolTable,基于符号值使用getSymbolTable() + symbolTable!: ISymbolTableManager + preprocessState: boolean | undefined performanceTracker: import('../../../util/performance-tracker').IPerformanceTracker + backUpSymbolTable: any + + tmpSymbolTable: any + + isTmpSymbolTableOpen: boolean + /** * * @param checkerManager @@ -85,18 +352,21 @@ class Analyzer extends MemSpace { constructor(checkerManager: any, options?: any) { super() this.options = options || {} + this.isTmpSymbolTableOpen = false this.checkerManager = checkerManager // 关联的检查器管理器 - this.performanceTracker = new PerformanceTracker() + this.performanceTracker = performanceTracker // 使用单例 this.enablePerformanceLogging = this.options.enablePerformanceLogging || false // 默认关闭 // 启用详细指令统计(如果启用了性能日志,输出 top 信息) this.performanceTracker.setEnableDetailedInstructionStats(this.enablePerformanceLogging) this.lastReturnValue = null // 记录最后一次函数调用的返回值 - this.thisFClos = null // 当前分析函数的闭包 - this.entry_fclos = null // 最外层函数的闭包 + this._thisFClos = null // 当前分析函数的闭包(存储 UUID) + this._entry_fclos = null // 最外层函数的闭包(存储 UUID) this.inRange = false // 范围语句标志 this.ainfo = {} // 整个分析过程中的信息 - this.sourceCodeCache = {} // 缓存的源代码 - this.lastProcessedNode = null + this.sourceCodeCache = new Map() // 缓存的源代码(文件路径 -> 代码行数组) + // 设置全局 analyzer 引用,使 source-line.ts 可以访问 sourceCodeCache + SourceLine.setGlobalAnalyzer(this) + this._lastProcessedNode = null // 最后处理的节点(存储 UUID 或 AST 节点) // 超时控制 this.thisIterationTime = 0 this.prevIterationTime = 0 @@ -107,6 +377,113 @@ class Analyzer extends MemSpace { this.initValTreeStruct() this.entryPoints = [] this.libFuncTagPropagationRuleArray = this.loadLibFuncTagPropagationRule() + this.libArgToThisSidBlacklistKeywords = this.loadLibArgToThisSidBlacklistKeywords() + } + + /** + * thisFClos getter: 如果存储的是 UUID,从符号表中获取对象 + */ + get thisFClos() { + if (this._thisFClos === null || this._thisFClos === undefined) { + return null + } + // 如果是 UUID,从符号表中获取对象 + if (typeof this._thisFClos === 'string' && this._thisFClos.startsWith('symuuid_')) { + const unit = this.symbolTable.get(this._thisFClos) + return unit || null + } + // 如果不是 UUID,直接返回(向后兼容) + return this._thisFClos + } + + /** + * thisFClos setter: 如果值是符号值对象,转换为 UUID 存储 + */ + set thisFClos(val) { + if (val === null || val === undefined) { + this._thisFClos = null + return + } + // 如果是符号值对象,转换为 UUID 存储 + if (val && typeof val === 'object' && val.vtype && val.qid) { + const uuid = this.symbolTable.register(val) + this._thisFClos = uuid + } else { + // 如果不是符号值对象,直接存储(向后兼容) + this._thisFClos = val + } + } + + /** + * entry_fclos getter: 如果存储的是 UUID,从符号表中获取对象 + */ + get entry_fclos() { + if (this._entry_fclos === null || this._entry_fclos === undefined) { + return null + } + // 如果是 UUID,从符号表中获取对象 + if (typeof this._entry_fclos === 'string' && this._entry_fclos.startsWith('symuuid_')) { + const unit = this.symbolTable.get(this._entry_fclos) + return unit || null + } + // 如果不是 UUID,直接返回(向后兼容) + return this._entry_fclos + } + + /** + * entry_fclos setter: 如果值是符号值对象,转换为 UUID 存储 + */ + set entry_fclos(val) { + if (val === null || val === undefined) { + this._entry_fclos = null + return + } + // 如果是符号值对象,转换为 UUID 存储 + if (val && typeof val === 'object' && val.vtype && val.qid) { + const uuid = this.symbolTable.register(val) + this._entry_fclos = uuid + } else { + // 如果不是符号值对象,直接存储(向后兼容) + this._entry_fclos = val + } + } + + /** + * lastProcessedNode getter: 如果存储的是 nodehash,从 AST 管理器中获取 AST 节点 + */ + get lastProcessedNode() { + if (this._lastProcessedNode === null || this._lastProcessedNode === undefined) { + return null + } + // 如果是字符串,尝试从 AST 管理器中获取 AST 节点(可能是 nodehash) + if (typeof this._lastProcessedNode === 'string') { + const astNode = this.astManager?.get(this._lastProcessedNode) + if (astNode) { + return astNode + } + // 如果获取不到,可能是其他字符串,直接返回(向后兼容) + return this._lastProcessedNode + } + // 如果不是字符串,直接返回(向后兼容) + return this._lastProcessedNode + } + + /** + * lastProcessedNode setter: 如果值是 AST 节点,转换为 nodehash 存储 + */ + set lastProcessedNode(val) { + if (val === null || val === undefined) { + this._lastProcessedNode = null + return + } + // 如果是 AST 节点(有 type 属性),注册并存储 nodehash + if (val && typeof val === 'object' && val.type && this.astManager) { + const nodehash = this.astManager.register(val) + this._lastProcessedNode = nodehash + } else { + // 如果不是 AST 节点,直接存储(向后兼容) + this._lastProcessedNode = val + } } /** @@ -154,91 +531,140 @@ class Analyzer extends MemSpace { * 初始化符号值树 */ initValTreeStruct() { - this.moduleManager = Scoped({ - parent: null, // will set to topScope right away + this.astManager = new ASTManager() + this.symbolTable = new SymbolTableManager() + setGlobalASTManager(this.astManager) + setGlobalSymbolTable(this.symbolTable) + + const moduleManager = new Scoped('', { sid: 'moduleManager', - }) // cache of imported module + }) - this.packageManager = PackageValue({ - parent: null, // will set to topScope right away - sid: '', - id: '', + const packageManager = new PackageValue('', { + parent: null, + sid: 'packageManager', name: 'packageManager', - }) // cache of imported module + }) this.fileManager = {} - this.funcSymbolTable = {} // 函数符号值集合,可快速搜索全局函数,向QL/断点粘连提供快速检索能力 - this.topScope = Scoped({ - id: '', + + const funcSymbolTableTarget: Record = {} + const { symbolTable } = this + this.funcSymbolTable = new Proxy(funcSymbolTableTarget, { + get: (target, prop: string | symbol) => { + if (typeof prop === 'symbol') { + return (target as any)[prop] + } + if (prop === 'toString' || prop === 'valueOf' || prop === 'constructor') { + return (target as any)[prop] + } + const value = target[prop] + if (value && typeof value === 'string' && value.startsWith('symuuid_')) { + const unit = symbolTable.get(value) + return unit || null + } + return value + }, + set: (target, prop: string, value: any) => { + if (value && typeof value === 'object' && value.vtype && value.qid) { + const uuid = symbolTable.register(value) + target[prop] = uuid + ;(symbolTable as any).addFuncSymbolTableRef?.(uuid, prop) + } else { + target[prop] = value + } + return true + }, + deleteProperty: (target, prop: string) => { + delete target[prop] + return true + }, + ownKeys: (target) => { + return Reflect.ownKeys(target) + }, + has: (target, prop) => { + return prop in target + }, + }) as Record + + this.topScope = new Scoped('', { sid: '', - moduleManager: this.moduleManager, - packageManager: this.packageManager, - fileManager: this.fileManager, - funcSymbolTable: this.funcSymbolTable, + qid: '', parent: null, }) - this.funcSymbolTable.parent = this.topScope - this.fileManager.parent = this.topScope - this.moduleManager.parent = this.topScope - this.packageManager.parent = this.topScope - this.fileManager.parent = this.topScope + + this.context = new AnalysisContext() + this.context.ast = this.astManager + this.context.symbols = this.symbolTable + this.context.modules = moduleManager + this.context.packages = packageManager + this.context.files = this.fileManager + this.context.funcs = this.funcSymbolTable + this.topScope.context = this.context + + moduleManager.parent = this.topScope + packageManager.parent = this.topScope this.thisFClos = this.topScope } /** - * 执行分析流程的通用方法,统一处理性能追踪(同步版本) - * - * **重要说明:** - * - 此方法仅用于同步 preProcess 场景,preProcessFn 必须返回 void(不能返回 Promise) - * - 如果 preProcessFn 可能返回 Promise,请使用 executeAnalysisPipelineAsync 方法 - * - * @param preProcessFn - 执行同步 preProcess 的函数(必须返回 void,不能返回 Promise) - * @param symbolInterpretFn - 执行 symbolInterpret 的函数 + * 切换到临时符号表,在执行 symbolInterpretFn 期间自动拷贝符号值 */ - private executeAnalysisPipeline(preProcessFn: () => void, symbolInterpretFn: () => void): void { - // 开始整体性能追踪 - this.performanceTracker.start() - this.performanceTracker.start('preProcess') - - Rules.setPreprocessReady(false) - // 启用指令级别的性能监控(如果已启用性能日志) - this.performanceTracker.startInstructionMonitor() - - // 执行同步 preProcess - preProcessFn() - - this.performanceTracker.end('preProcess') - this.performanceTracker.start('startAnalyze') - - this.startAnalyze() - - this.performanceTracker.end('startAnalyze') - Rules.setPreprocessReady(true) - - this.performanceTracker.start('symbolInterpret') + protected switchToTemporarySymbolTable(): void { + // 确保当前 symbolTable 是 SymbolTableManager,不是 TemporarySymbolTableManager + // 如果已经是 TemporarySymbolTableManager,说明存在嵌套调用,这是不支持的 + if (this.symbolTable instanceof TemporarySymbolTableManager) { + throw new Error( + 'Nested TemporarySymbolTableManager is not supported. symbolInterpretFn should not be called recursively.' + ) + } - symbolInterpretFn() + // 创建临时符号表,在执行 symbolInterpretFn 期间自动拷贝符号值 + const tmpSymbolTable = new TemporarySymbolTableManager(this.symbolTable as InstanceType) + const originalGlobalSymbolTable = getGlobalSymbolTable() + const originalAnalyzerSymbolTable = this.symbolTable + const originalTopScopeSymbolTable = (this.topScope?.context?.symbols as ISymbolTableManager | null) || null - this.performanceTracker.end('symbolInterpret') - this.endAnalyze() + setGlobalSymbolTable(tmpSymbolTable) + this.symbolTable = tmpSymbolTable + if (this.topScope?.context) { + this.topScope.context.symbols = tmpSymbolTable + } + this.isTmpSymbolTableOpen = true + this.tmpSymbolTable = tmpSymbolTable + this.backUpSymbolTable = { + originalGlobalSymbolTable, + originalAnalyzerSymbolTable, + originalTopScopeSymbolTable, + } + } - // 记录性能数据并输出摘要(会自动输出指令统计) - this.performanceTracker.logPerformance(this) + /** + * 恢复原始符号表引用,并清理临时符号表 + */ + protected restoreSymbolTable(): void { + // 恢复所有符号表引用 + setGlobalSymbolTable(this.backUpSymbolTable.originalGlobalSymbolTable) + this.symbolTable = this.backUpSymbolTable.originalAnalyzerSymbolTable + if (this.topScope?.context) { + this.topScope.context.symbols = this.backUpSymbolTable.originalTopScopeSymbolTable + } + this.isTmpSymbolTableOpen = false + // 清理临时符号表 + this.tmpSymbolTable.clear() } /** - * 执行分析流程的通用方法(异步版本),统一处理性能追踪 - * - * 用于处理异步 preProcess 场景,避免 analyzeProjectAsync 中的代码重复。 - * - * @param preProcessFn - 执行异步 preProcess 的函数 - * @param symbolInterpretFn - 执行 symbolInterpret 的函数 + * 执行分析流程的通用方法,统一处理性能追踪 + * @param initAfterUsingCache + * @param preProcessFn - 执行同步 preProcess 的函数(必须返回 void,不能返回 Promise) + * @returns {Promise} 分析结果 */ - private async executeAnalysisPipelineAsync( - preProcessFn: () => Promise, - symbolInterpretFn: () => void - ): Promise { + private async executeAnalysisPipeline( + initAfterUsingCache: () => void, + preProcessFn: () => void | Promise + ): Promise { // 开始整体性能追踪 this.performanceTracker.start() this.performanceTracker.start('preProcess') @@ -247,10 +673,59 @@ class Analyzer extends MemSpace { // 启用指令级别的性能监控(如果已启用性能日志) this.performanceTracker.startInstructionMonitor() - // 执行异步 preProcess - await preProcessFn() + // 尝试加载缓存 + let cacheLoaded = false + let shouldPreProcess = true + if (Config.loadContextEnvironment) { + shouldPreProcess = false + this.performanceTracker.start('loadContextEnvironment') + try { + // 根据源路径查找缓存文件夹(基于 repoName 和 hashPrefix) + const sourcePath = this.options?.maindir || Config.prefixPath || process.cwd() + cacheLoaded = loadAnalyzerCache(this, Config.loadContextEnvironmentId, sourcePath) + if (cacheLoaded) { + logger.info('Analyzer cache loaded successfully') + } + if (cacheLoaded && Config.maindirPrefix) { + const name = Config.maindirPrefix.split('/').pop() || Config.maindirPrefix + if (!Config.loadContextEnvironmentId || !Config.loadContextEnvironmentId.startsWith(`${name}_`)) { + shouldPreProcess = true + } + } + if (!shouldPreProcess && typeof initAfterUsingCache === 'function') { + initAfterUsingCache() + } + } catch (err: any) { + logger.warn(`Failed to load analyzer cache: ${err.message}`) + } + this.performanceTracker.end('loadContextEnvironment') + } + + if (shouldPreProcess) { + const result = preProcessFn() + if (result instanceof Promise) { + await result + } + } this.performanceTracker.end('preProcess') + + // 保存缓存(在 startAnalyze 之前) + if (Config.saveContextEnvironment || Config.miniSaveContextEnvironment) { + try { + this.performanceTracker.start('saveContextEnvironment') + const sourcePath = this.options?.maindir + const cacheId = generateCacheId(sourcePath) + saveAnalyzerCache(this, cacheId) + logger.info('Analyzer cache saved successfully') + // 保存完成后结束分析 + this.performanceTracker.end('saveContextEnvironment') + return + } catch (err: any) { + logger.warn(`Failed to save analyzer cache: ${err.message}`) + } + } + this.performanceTracker.start('startAnalyze') this.startAnalyze() @@ -260,86 +735,76 @@ class Analyzer extends MemSpace { this.performanceTracker.start('symbolInterpret') - symbolInterpretFn() + // 切换到临时符号表 + this.switchToTemporarySymbolTable() + try { + this.symbolInterpret() + } finally { + // 恢复原始符号表 + this.restoreSymbolTable() + } this.performanceTracker.end('symbolInterpret') this.endAnalyze() // 记录性能数据并输出摘要(会自动输出指令统计) - this.performanceTracker.logPerformance(this) + performanceTracker.collectAnalysisData(this) + + return this.recordCheckerFindings() } /** * 分析单个文件 - * - * 性能追踪逻辑已统一到 executeAnalysisPipeline 方法,避免代码重复。 - * * @param source - 源代码内容 * @param fileName - 文件名 * @returns 分析结果 */ - analyzeSingleFile(source: any, fileName: any) { + async analyzeSingleFile(source: any, fileName: any) { try { + // 单文件就不要用缓存了 + Config.loadContextEnvironment = false + Config.saveContextEnvironment = false + Config.miniSaveContextEnvironment = false if (typeof this.preProcess4SingleFile === 'function' && typeof this.symbolInterpret === 'function') { - this.executeAnalysisPipeline( - () => this.preProcess4SingleFile(source, fileName), - () => this.symbolInterpret() + return await this.executeAnalysisPipeline( + () => {}, + () => this.preProcess4SingleFile(source, fileName) ) - } else { - logger.info(`this analyzer has not support analyzeSingleFile yet`) } + logger.info(`this analyzer has not support analyzeSingleFile yet`) return this.recordCheckerFindings() } catch (e) { handleException(e, 'Error occurred in analyzer analyzeSingleFile', 'Error occurred in analyzer analyzeSingleFile') + return false } } /** - * 异步分析项目 - * - * 用于处理支持异步 preProcess 的分析器(如 Go Analyzer、Python Analyzer)。 - * + * 分析项目 * @param processingDir - 要分析的项目目录 * @returns 分析结果 */ - async analyzeProjectAsync(processingDir: any) { + async analyzeProject(processingDir: any) { try { if (typeof this.preProcess === 'function' && typeof this.symbolInterpret === 'function') { - await this.executeAnalysisPipelineAsync( - () => this.preProcess(processingDir), - () => this.symbolInterpret() + if (typeof this.initAfterUsingCache !== 'function') { + this.initAfterUsingCache = () => {} + } + return await this.executeAnalysisPipeline( + () => this.initAfterUsingCache(), + () => this.preProcess(processingDir) ) } return this.recordCheckerFindings() - } catch (e) { + } catch (e: any) { + const errorMsg = e?.message || String(e) + const errorStack = e?.stack || '' handleException( e, - 'Error occurred in analyzer analyzeProjectAsync', - 'Error occurred in analyzer analyzeProjectAsync' + `Error occurred in analyzer analyzeProject: ${errorMsg}\n${errorStack}`, + `Error occurred in analyzer analyzeProject: ${errorMsg}` ) - } - } - - /** - * 同步分析项目 - * - * 用于处理同步 preProcess 的分析器(如 Java Analyzer、JavaScript Analyzer)。 - * 性能追踪逻辑已统一到 executeAnalysisPipeline 方法,避免代码重复。 - * - * @param processingDir - 要分析的项目目录 - * @returns 分析结果 - */ - analyzeProject(processingDir: any) { - try { - if (typeof this.preProcess === 'function' && typeof this.symbolInterpret === 'function') { - this.executeAnalysisPipeline( - () => this.preProcess(processingDir), - () => this.symbolInterpret() - ) - } - return this.recordCheckerFindings() - } catch (e) { - handleException(e, 'Error occurred in analyzer analyzeProject', 'Error occurred in analyzer analyzeProject') + return false } } @@ -359,13 +824,6 @@ class Analyzer extends MemSpace { */ initTopScope() {} - /** - * - * @param source - * @param filename - */ - parseUast(source: any, filename: any) {} - /** * * @param uast @@ -391,68 +849,6 @@ class Analyzer extends MemSpace { } } - /** - * - * @param target - * @param topScopeTemp - */ - findValInTree(target: any, topScopeTemp: any): any { - const passVals: any[] = [] - let current = target - while (current) { - if (current.sid === '') { - break - } - passVals.push(current) - current = current.parent - } - passVals.reverse() - let scope = topScopeTemp - for (const val of passVals) { - let hasFind = false - for (const s of Object.values(scope) as any[]) { - if ( - s && - val.vtype === s.vtype && - val.id === s.id && - val.sid === s.sid && - val.qid === s.qid && - val.sort === s.sort && - val.name === s.name && - val.ast === s.ast && - val.parent?.vtype === s.parent?.vtype - ) { - scope = s - hasFind = true - break // 提前退出循环 - } - } - if (!hasFind && scope.field) { - for (const s of Object.values(scope.field) as any[]) { - if ( - s && - val.vtype === s.vtype && - val.id === s.id && - val.sid === s.sid && - val.qid === s.qid && - val.sort === s.sort && - val.name === s.name && - val.ast === s.ast && - val.parent?.vtype === s.parent?.vtype - ) { - scope = s - hasFind = true - break // 提前退出循环 - } - } - } - if (!hasFind) { - return null - } - } - return scope - } - /** * * @param instructionType @@ -476,47 +872,6 @@ class Analyzer extends MemSpace { return load(this) } - /** - * - * @param node - */ - debugInstruction(node: any) { - if (!Array.isArray(node)) { - const code = this.sourceCodeCache[node?.loc?.sourcefile] - - if (code) { - const { start, end } = node.loc - const showLine = getLine(code, node.loc.start.line) - const startColumn = start.column - let endColumn = end.column - if (start.line !== end.line) { - endColumn = start.column - } - const msg = `${start.line} ${showLine.substring(0, startColumn)}${chalk.blue( - showLine.substring(startColumn, endColumn) - )}${showLine.substring(endColumn, showLine.length)}` - logger.debug(msg) - } - } - - /** - * - * @param code - * @param n - */ - function getLine(code: any, n: any) { - // 将代码分割成行数组 - const lines = code.split('\n') - - // 检查行数是否在有效范围内 - if (n > 0 && n <= lines.length) { - // 获取第N行的内容 - return lines[n - 1] - } - return null // 行数无效,返回null或其他适当的值 - } - } - // prePostFlag /** * @@ -527,7 +882,7 @@ class Analyzer extends MemSpace { */ processInstruction(scope: any, node: any, state: any, prePostFlag?: any): any { if (!node || !scope) { - return UndefinedValue() + return new UndefinedValue() } if (node.vtype) { return node @@ -535,7 +890,12 @@ class Analyzer extends MemSpace { this.lastProcessedNode = node if (scope.vtype === 'union') { - const res = UnionValue() + const res = new UnionValue( + undefined, + undefined, + `${scope.qid}.`, + node + ) for (const scp of scope.value) { const val = this.processInstruction(scp, node, state, prePostFlag) res.appendValue(val) @@ -553,7 +913,10 @@ class Analyzer extends MemSpace { const action = prePostFlag ? `${prePostFlag}Process` : 'process' const inst = this.loadInstruction(action + node.type) if (!inst) { - return SymbolValue(node) + if (Config.saveContextEnvironment || Config.miniSaveContextEnvironment) { + return new SymbolValue(scope.qid, { sid: '' }) + } + return new SymbolValue(scope.qid, { ...node, sid: '' }) } // TODO 添加判断,后续指令是否是跟在return或throw后且在同一个scope内无法执行的指令 4+ this.statistics.numProcessedInstructions++ @@ -565,12 +928,11 @@ class Analyzer extends MemSpace { try { val = inst.call(this, scope, node, state) } catch (e) { - handleException( - e, - '', - `process${node.type} error! loc is${node.loc.sourcefile}::${node.loc.start.line}_${node.loc.end.line}` - ) - val = UndefinedValue() + const locInfo = node.loc + ? `${node.loc.sourcefile}::${node.loc.start?.line}_${node.loc.end?.line}` + : '' + handleException(e, '', `process${node.type} error! loc is${locInfo}`) + val = new UndefinedValue() } // 性能追踪:结束指令执行并更新统计(内部会检查是否启用) @@ -594,10 +956,10 @@ class Analyzer extends MemSpace { processPre(val: any, state: any) { switch (val?.vtype) { case 'class': - this.processClassDefinition(val.parent, val.cdef, state) + this.processClassDefinition(val.parent, val.ast.cdef, state) break case 'fclos': - this.processFunctionDefinition(val.parent, val.fdef, state) + this.processFunctionDefinition(val.parent, val.ast.fdef, state) break } } @@ -609,7 +971,7 @@ class Analyzer extends MemSpace { * @param state */ processNoop(scope: any, node: any, state: any) { - return UndefinedValue() + return new UndefinedValue() } /** @@ -618,8 +980,16 @@ class Analyzer extends MemSpace { * @param node * @param state */ - processLiteral(scope: any, node: any, state: any) { - return PrimitiveValue({ ...node, ast: node, qid: node.value, sid: node.value, id: node.value }) + processLiteral(scope: ScopeType, node: Literal, state: State): SymbolValueType { + return new PrimitiveValue( + scope.qid, + primitiveToString(node.value), + node.value, + node.literalType, + node.type, + node.loc, + node + ) } /** @@ -628,19 +998,25 @@ class Analyzer extends MemSpace { * @param node * @param state */ - processIdentifier(scope: any, node: any, state: any) { - if (node.name === 'undefined') return PrimitiveValue({ type: 'Literal', value: undefined }) - const res = this.getMemberValue(scope, node, state) + processIdentifier(scope: ScopeType, node: Identifier, state: State): SymbolValueType { + if (node.name === 'undefined') { + return new PrimitiveValue(scope.qid, 'undefined', undefined, null, 'Literal') + } + let res + if (state?.findIdInCurScope) { + res = this.getMemberValueInCurrentScope(scope, node, state) + } else { + res = this.getMemberValue(scope, node, state) + } if (res.vtype === 'fclos') { res._this = this.topScope } if (res.vtype === 'undefine' || res.vtype === 'uninitialized' || res.vtype === 'symbol') { - res.vtype = 'symbol' - res._id = node.name - res._sid = node.name + res.sid = node.name } - this.checkerManager.checkAtIdentifier(this, scope, node, state, { res }) - return res + const info = { res } + this.checkerManager.checkAtIdentifier(this, scope, node, state, info) + return info.res } /** @@ -649,7 +1025,7 @@ class Analyzer extends MemSpace { * @param node * @param state */ - processCompileUnit(scope: any, node: any, state: any) { + processCompileUnit(scope: ScopeType, node: CompileUnit, state: State): Value { if (this.checkerManager && this.checkerManager.checkAtCompileUnit) { this.checkerManager.checkAtCompileUnit(this, scope, node, state, { pcond: state.pcond, @@ -667,6 +1043,7 @@ class Analyzer extends MemSpace { // node.body.filter(n => needCompileFirst(n.type)).forEach(n => this.processInstruction(scope, n, state)); // process Compile First twice in order to handle elements which can't be correctly compiled once first node.body.forEach((n: any) => this.processInstruction(scope, n, state)) + return new VoidValue() } /** @@ -675,7 +1052,7 @@ class Analyzer extends MemSpace { * @param node * @param state */ - processExportStatement(scope: any, node: any, state: any) { + processExportStatement(scope: ScopeType, node: ExportStatement, state: State): VoidValueType { // locate exports const exports = this.getExportsScope(scope) const val = this.processInstruction(scope, node.argument, state) @@ -684,6 +1061,7 @@ class Analyzer extends MemSpace { } else if (exports) { this.saveVarInCurrentScope(exports, node.alias, val, state) } + return new VoidValue() } /** @@ -711,7 +1089,7 @@ class Analyzer extends MemSpace { * @param node * @param state */ - processIfStatement(scope: any, node: any, state: any) { + processIfStatement(scope: ScopeType, node: IfStatement, state: State): VoidValueType { /* { test, consequent, @@ -727,7 +1105,13 @@ class Analyzer extends MemSpace { }) } - const b: string = 'U' // abstraction.evaluate(test, state.pcond); + let b: string = 'U' // abstraction.evaluate(test, state.pcond); + if (test?.type === 'Literal' && test.value === true) { + b = 'T' + } else if (test?.type === 'Literal' && test.value === false) { + b = 'F' + } + switch (b) { case 'T': this.processInstruction(scope, node.consequent, state) @@ -770,6 +1154,7 @@ class Analyzer extends MemSpace { } } } + return new VoidValue() } /** @@ -778,19 +1163,20 @@ class Analyzer extends MemSpace { * @param node * @param state */ - processSwitchStatement(scope: any, node: any, state: any) { + processSwitchStatement(scope: ScopeType, node: SwitchStatement, state: State): VoidValueType { // cases: [ SwitchCase ] const test = this.processInstruction(scope, node.discriminant, state) if (test && test.type === 'Literal') { + const testValue = (test as any as Literal).value for (const caseClause of node.cases) { if ( !caseClause.test || // FIXME - caseClause.test.value === test.value + (caseClause.test.type === 'Literal' && (caseClause.test as any as Literal).value === testValue) ) { return this.processInstruction(scope, caseClause.body, state) } } - return UndefinedValue() + return new UndefinedValue() } const scopes = [] @@ -804,7 +1190,7 @@ class Analyzer extends MemSpace { this.processInstruction(scope1, caseClause.body, st) } MemState.unionValues(scopes, substates, state.brs) - return UndefinedValue() + return new UndefinedValue() } /** @@ -813,7 +1199,7 @@ class Analyzer extends MemSpace { * @param node * @param state */ - processForStatement(scope: any, node: any, state: any) { + processForStatement(scope: ScopeType, node: ForStatement, state: State): VoidValueType { StateUtil.pushLoopInfo(state, node) if (node.init) { this.processInstruction(scope, node.init, state) @@ -836,7 +1222,7 @@ class Analyzer extends MemSpace { } else this.processInstruction(scope, node.body, state) StateUtil.popLoopInfo(state) - return UndefinedValue() + return new UndefinedValue() } /** @@ -845,7 +1231,7 @@ class Analyzer extends MemSpace { * @param node * @param state */ - processWhileStatement(scope: any, node: any, state: any) { + processWhileStatement(scope: ScopeType, node: WhileStatement, state: State): VoidValueType { /* { test, body, @@ -869,7 +1255,7 @@ class Analyzer extends MemSpace { // // fixed-point on values (with scopes) for data-flow calculation // scope.value = MemState.computeValueFixedPoint(scope).value; - return UndefinedValue() + return new UndefinedValue() } /** @@ -878,9 +1264,9 @@ class Analyzer extends MemSpace { * @param node * @param state */ - processRangeStatement(scope: any, node: any, state: any) { + processRangeStatement(scope: ScopeType, node: RangeStatement, state: State): any { const { key, value, right, body } = node - scope = Analyzer.createSubScope( + scope = Scope.createSubScope( ``, scope ) @@ -889,7 +1275,7 @@ class Analyzer extends MemSpace { !Array.isArray(rightVal) && (this.inRange || rightVal?.vtype === 'primitive' || - Object.keys(rightVal.getRawValue()).length === 0 || + Object.keys(rightVal.getRawValue()).filter((key) => !key.startsWith('__yasa')).length === 0 || rightVal?.vtype === 'union') ) { if (value) { @@ -897,6 +1283,7 @@ class Analyzer extends MemSpace { this.saveVarInCurrentScope(scope, value.id, rightVal, state) } else if (value.type === 'TupleExpression') { for (const ele of value.elements) { + // Runtime may have 'name' property even if not in type definition this.saveVarInCurrentScope(scope, ele.name, rightVal, state) } } else { @@ -912,7 +1299,7 @@ class Analyzer extends MemSpace { this.inRange = true if (this.isNullLiteral(rightVal)) { this.inRange = false - return + return undefined as any // 保持历史行为(25282dbd) } const itr = this.getValueIterator(rightVal, filterDataFromScope) let countLimit = 30 @@ -928,13 +1315,18 @@ class Analyzer extends MemSpace { } else { // 如果是string,将其构造出符号值再存储 // TODO 250731 将符号的字面量(而非符号值)作为key存储是否合适,有待商榷。 - if (_.isString(k)) k = PrimitiveValue({ ...key, value: k, ast: key, qid: k, sid: k, id: k }) + if (_.isString(k)) k = new PrimitiveValue(scope.qid, k, k, null, key.type, key.loc, key) this.saveVarInScope(scope, key, k, state) } } if (value) { if (value.type === 'VariableDeclaration') { this.saveVarInCurrentScope(scope, value.id, v, state) + } else if (value.type === 'TupleExpression') { + for (let i = 0; i < value.elements.length; i++) { + const eleVal = v?.members?.get(String(i)) ?? v + this.saveVarInCurrentScope(scope, value.elements[i].name, eleVal, state) + } } else { this.saveVarInScope(scope, value, v, state) } @@ -943,6 +1335,7 @@ class Analyzer extends MemSpace { } this.inRange = false } + return new VoidValue() } /** @@ -951,25 +1344,36 @@ class Analyzer extends MemSpace { * @param node * @param state */ - processReturnStatement(scope: any, node: any, state: any) { + processReturnStatement(scope: ScopeType, node: ReturnStatement, state: State): VoidValueType { // { expression } // lastReturnValue should be treated as union since there are multi return points in one func if (node.argument) { - const return_value = this.processInstruction(scope, node.argument, state) + const returnValue = this.processInstruction(scope, node.argument, state) if (!node.isYield) { if (!this.lastReturnValue) { - this.lastReturnValue = return_value + this.lastReturnValue = returnValue } else if (this.lastReturnValue.vtype === 'union') { - if (return_value === this.lastReturnValue || return_value.value === this.lastReturnValue.value) { - const new_return_value = cloneWithDepth(return_value, 2) - this.lastReturnValue.appendValue(new_return_value, false) + if (returnValue === this.lastReturnValue || returnValue.value === this.lastReturnValue.value) { + const newReturnValue = buildNewValueInstance( + this, + returnValue, + node, + scope, + () => { + return false + }, + (v: any) => { + return !v + } + ) + this.lastReturnValue.appendValue(newReturnValue, false) } else { - this.lastReturnValue.appendValue(return_value, false) + this.lastReturnValue.appendValue(returnValue, false) } } else { - const tmp = UnionValue() + const tmp = new UnionValue(undefined, undefined, `${scope.qid}.`, node) tmp.appendValue(this.lastReturnValue) - tmp.appendValue(return_value) + tmp.appendValue(returnValue) this.lastReturnValue = tmp } if (node.loc && this.lastReturnValue) @@ -981,9 +1385,9 @@ class Analyzer extends MemSpace { '[return value]' ) } - return return_value + return returnValue } - return PrimitiveValue({ type: 'Literal', value: null, loc: node.loc }) + return new PrimitiveValue(scope.qid, 'undefined', null, null, 'Literal', node.loc) } // TODO break statement @@ -993,8 +1397,8 @@ class Analyzer extends MemSpace { * @param node * @param state */ - processBreakStatement(scope: any, node: any, state: any) { - return UndefinedValue() + processBreakStatement(scope: ScopeType, node: BreakStatement, state: State): VoidValueType { + return new UndefinedValue() } // TODO continue statement @@ -1004,8 +1408,8 @@ class Analyzer extends MemSpace { * @param node * @param state */ - processContinueStatement(scope: any, node: any, state: any) { - return UndefinedValue() + processContinueStatement(scope: ScopeType, node: ContinueStatement, state: State): VoidValueType { + return new UndefinedValue() } // TODO throw @@ -1015,7 +1419,7 @@ class Analyzer extends MemSpace { * @param node * @param state */ - processThrowStatement(scope: any, node: any, state: any) { + processThrowStatement(scope: ScopeType, node: ThrowStatement, state: State): VoidValueType { // 原本是注释的,打开了,throw和return 还是有很大区别的 // throw会沿着调用栈传递,return 只会传到调用层 没处理就结束了 // const ret = this.processReturnStatement(scope, node, state); @@ -1030,15 +1434,25 @@ class Analyzer extends MemSpace { node, node.loc && node.loc.sourcefile, 'Throw Pass: ', - node.argument.name + (node.argument.type === 'Identifier' ? node.argument.name : null) || + AstUtil.prettyPrintAST(node.argument).slice(0, 50) ) // 没有被try处理的异常 state.throwstack = state.throwstack ?? [] state.throwstack.push(throw_value) return throw_value } + state.throwstackScopeAndState = state.throwstackScopeAndState ?? [] + state.throwstackScopeAndState.push({ scope, state }) } - return PrimitiveValue({ type: 'Literal', value: node.argument, loc: node.loc }) + return new PrimitiveValue( + scope.qid, + ``, + node.argument, + null, + 'Literal', + node.loc + ) } /** @@ -1047,13 +1461,14 @@ class Analyzer extends MemSpace { * @param node * @param state */ - processTryStatement(scope: any, node: any, state: any) { + processTryStatement(scope: ScopeType, node: TryStatement, state: State): VoidValueType { // 此处processInstruction的返回值是undefine 因此无法拿到try里面是否抛出异常的信息 this.processInstruction(scope, node.body, state) const { handlers } = node if (handlers) { for (const clause of handlers) { - scope = Analyzer.createSubScope( + if (!clause) continue + scope = Scope.createSubScope( ``, scope ) @@ -1062,7 +1477,7 @@ class Analyzer extends MemSpace { } } if (node.finalizer) this.processInstruction(scope, node.finalizer, state) - return UndefinedValue() + return new UndefinedValue() } /** @@ -1071,7 +1486,7 @@ class Analyzer extends MemSpace { * @param node * @param state */ - processExpressionStatement(scope: any, node: any, state: any) { + processExpressionStatement(scope: ScopeType, node: ExpressionStatement, state: State): VoidValueType { // { expression } return this.processInstruction(scope, node.expression, state) } @@ -1082,17 +1497,17 @@ class Analyzer extends MemSpace { * @param node * @param state */ - processScopedStatement(scope: any, node: any, state: any) { + processScopedStatement(scope: ScopeType, node: ScopedStatement, state: State): any { /* { statements } */ const { loc } = node let scopeName if (loc) { - if (!scope._qid) { - const relateFileName = loc.sourcefile.startsWith(Config.maindirPrefix) - ? loc.sourcefile?.substring(Config.maindirPrefix.length).split('.')[0] - : loc.sourcefile.split('.')[0] + if (!scope.qid) { + const prefix = loc.sourcefile?.substring(Config.maindirPrefix.length) + const lastDotIndex = prefix?.lastIndexOf('.') ?? -1 + const relateFileName = lastDotIndex >= 0 ? prefix?.substring(0, lastDotIndex) : prefix scopeName = `${relateFileName}` } else { scopeName = `` @@ -1112,6 +1527,7 @@ class Analyzer extends MemSpace { if (this.checkerManager && this.checkerManager.checkAtEndOfBlock) { this.checkerManager.checkAtEndOfBlock(this, scope, node, state, {}) } + return new VoidValue() } /** @@ -1120,27 +1536,22 @@ class Analyzer extends MemSpace { * @param node * @param state */ - processBinaryExpression(scope: any, node: any, state: any) { - /* - { operator, - left, - right - } - */ - const new_node = _.clone(node) - new_node.ast = node - const new_left = (new_node.left = this.processInstruction(scope, node.left, state)) - const new_right = (new_node.right = this.processInstruction(scope, node.right, state)) + processBinaryExpression(scope: ScopeType, node: BinaryExpression, state: State): BinaryExprValue { + const new_left = this.processInstruction(scope, node.left, state) + const new_right = this.processInstruction(scope, node.right, state) - const has_tag = (new_left && new_left.hasTagRec) || (new_right && new_right.hasTagRec) - if (has_tag) { - new_node.hasTagRec = has_tag - } + const has_tag = (new_left && new_left.taint?.isTaintedRec) || (new_right && new_right.taint?.isTaintedRec) + // checkerManager 需要 newNode 兼容对象 + const newNode: any = { ...node, ast: node, left: new_left, right: new_right, isTainted: has_tag || null } if (this.checkerManager && this.checkerManager.checkAtBinaryOperation) - this.checkerManager.checkAtBinaryOperation(this, scope, node, state, { newNode: new_node }) + this.checkerManager.checkAtBinaryOperation(this, scope, node, state, { newNode }) - return SymbolValue(new_node) + const result = new BinaryExprValue(scope.qid, node.operator, new_left, new_right, node, node.loc) + if (has_tag) { + result.taint?.mergeFrom([new_left, new_right]) + } + return result } /** @@ -1149,14 +1560,12 @@ class Analyzer extends MemSpace { * @param node * @param state */ - processUnaryExpression(scope: any, node: any, state: any) { - const new_node = SymbolValue(_.clone(node)) - new_node.ast = node - new_node.argument = this.processInstruction(scope, node.argument, state) - // return nativeResolver.simplifyUnaryExpression(new_node); - const hasTags = new_node.argument && new_node.argument.hasTagRec - if (hasTags) new_node.hasTagRec = hasTags - return new_node + processUnaryExpression(scope: ScopeType, node: UnaryExpression, state: State): UnaryExprValue { + const unaryArg = this.processInstruction(scope, node.argument, state) + const result = new UnaryExprValue(scope.qid, node.operator, unaryArg, node, node.loc, node.isSuffix) + const hasTags = unaryArg && unaryArg.taint?.isTaintedRec + if (hasTags) result.taint?.mergeFrom([unaryArg]) + return result } /** @@ -1165,7 +1574,7 @@ class Analyzer extends MemSpace { * @param node * @param state */ - processAssignmentExpression(scope: any, node: any, state: any) { + processAssignmentExpression(scope: ScopeType, node: AssignmentExpression, state: State): any { /* { operator, left, @@ -1178,17 +1587,15 @@ class Analyzer extends MemSpace { const { left } = node const { right } = node let tmpVal = this.processInstruction(scope, right, state) - if (node.cloned && !tmpVal?.refCount) { - tmpVal = _.clone(tmpVal) - tmpVal.value = _.clone(tmpVal.value) - } const oldVal = this.processInstruction(scope, left, state) // TODO: clean the following up if (left.type === 'TupleExpression') { for (let k = 0; k < left.elements.length; k++) { const x = left.elements[k] - if (!x || x.name === '_') continue + if (!x) continue + const xName = x.type === 'Identifier' ? x.name : undefined + if (xName === '_') continue let val = tmpVal && tmpVal.type === 'TupleExpression' ? tmpVal.elements[k] : tmpVal const oldV = oldVal && oldVal.type === 'TupleExpression' ? oldVal.elements[k] : oldVal @@ -1212,11 +1619,20 @@ class Analyzer extends MemSpace { } } } else { - if (!tmpVal) - // explicit null value - tmpVal = PrimitiveValue({ type: 'Literal', value: null, loc: right.loc }) + if (!tmpVal) { + tmpVal = new PrimitiveValue(scope.qid, 'undefined', null, null, 'Literal', right.loc) + } + if (typeof tmpVal !== 'object') { + tmpVal = new PrimitiveValue(scope.qid, ``, tmpVal, null, 'Literal', right.loc) + } const sid = SymAddress.toStringID(node.left) - tmpVal.sid = !tmpVal.id || tmpVal.id === '' ? sid : tmpVal.id + if ( + tmpVal.sid === undefined || + tmpVal.sid === null || + (typeof tmpVal.sid === 'string' && tmpVal.sid.includes('`, + node + ) res.appendValue(this.processInstruction(scope, node.consequent, lstate)) res.appendValue(this.processInstruction(rscope, node.alternative, rstate)) return res @@ -1339,7 +1771,7 @@ class Analyzer extends MemSpace { * @param node * @param state */ - processSuperExpression(scope: any, node: any, state: any) { + processSuperExpression(scope: ScopeType, node: SuperExpression, state: State): SymbolValueType { return this.getMemberValue(scope, node, state) } @@ -1349,7 +1781,7 @@ class Analyzer extends MemSpace { * @param node * @param state */ - processThisExpression(scope: any, node: any, state: any) { + processThisExpression(scope: ScopeType, node: ThisExpression, state: State): SymbolValueType { return this.thisFClos } @@ -1359,7 +1791,7 @@ class Analyzer extends MemSpace { * @param node * @param state */ - processMemberAccess(scope: any, node: any, state: any) { + processMemberAccess(scope: ScopeType, node: MemberAccess, state: State): SymbolValueType { /** object, property, @@ -1378,115 +1810,414 @@ class Analyzer extends MemSpace { resolved_prop = this.processInstruction(scope, prop, state) } } - const res = this.getMemberValue(defscope, resolved_prop, state) - if (this.checkerManager && this.checkerManager.checkAtMemberAccess) { - this.checkerManager.checkAtMemberAccess(this, defscope, node, state, { res }) + const res = this.getMemberValue(defscope, resolved_prop, state) + if (node.object.type !== 'SuperExpression' && (res.vtype !== 'union' || !Array.isArray(res.value))) { + res._this = defscope + } + if (this.checkerManager && this.checkerManager.checkAtMemberAccess) { + this.checkerManager.checkAtMemberAccess(this, defscope, node, state, { res }) + } + return res + } + + // TODO slice + /** + * + * @param scope + * @param node + * @param state + */ + processSliceExpression(scope: ScopeType, node: SliceExpression, state: State): SymbolValueType { + // 返回 undefined 保持历史行为(25282dbd) + return undefined as any // TODO: 实现 SliceExpression 处理 + } + + // TODO tuple + /** + * + * @param scope + * @param node + * @param state + */ + processTupleExpression(scope: ScopeType, node: TupleExpression, state: State): SymbolValueType { + const values = node.elements.map((ele: any) => { + return this.processInstruction(scope, ele, state) + }) + return unionAllValues(values, state) + } + + /** + * + * @param scope + * @param node + * @param state + */ + processObjectExpression(scope: ScopeType, node: ObjectExpression, state: State): SymbolValueType { + // FIXME + const objSid = `` + let res = new Scoped(scope.qid, { + sid: objSid, + parent: scope, + ast: node, + _skipRegister: true, + }) + if (node.properties) { + for (const property of node.properties) { + let name + let fvalue + // ObjectMethod may exist in runtime but not in UAST type definition + const propertyType = (property as any).type + switch (propertyType) { + case 'ObjectMethod': { + // ObjectMethod is not in UAST definition, but may exist in runtime + const objectMethod = property as any + name = objectMethod.key?.name + fvalue = this.createFuncScope(objectMethod, scope) + fvalue.ast.fdef = _.clone(fvalue.ast.fdef) + if (fvalue.ast.fdef) { + fvalue.ast.fdef.type = 'FunctionDefinition' + } + if (fvalue.ast?.node) { + fvalue.ast.node.type = 'FunctionDefinition' + } + break + } + case 'SpreadElement': { + this.processInstruction(res, property, state) + continue + } + case 'ObjectProperty': + default: { + if (property.type !== 'ObjectProperty') continue + let { key } = property + switch (key.type) { + // FIXME process ObjectMethod + case 'Literal': + name = key.value + break + case 'Identifier': + name = key.name + break + default: + key = this.processInstruction(res, key, state) + name = key.type === 'Literal' ? key.value : key.type === 'Identifier' ? key.name : undefined + break + } + fvalue = this.processInstruction(res, property.value, state) + if (fvalue?.taint?.isTaintedRec) res.taint?.propagateFrom(fvalue) + // FunctionDefinition is both Decl and Expr (double inheritance) + if (property.value && property.value.type === 'FunctionDefinition') fvalue.parent = res + break + } + } + res.value[name] = fvalue + // // call-back + // if (expressionCallBack) { + // expressionCallBack(node, [name, fvalue], this.currentFunction); + // } + // if (triggers) + // //triggers.checkObjectValue(node, property, fvalue, this.currentFunction.sourcefile); + // triggers.checkExpression(property, fvalue); + } + res.length = node.properties.length + } + res = new ObjectValue(scope.qid, { ...res, sid: objSid }) + res.vtype = 'object' + res._this = res + return res + } + + // ==================== CallArgs methods (Step 2) ==================== + + /** + * Build CallArgs from evaluated argvalues and call-site AST node. + * Base implementation: all args are positional, keyword determined by node.names. + * Language-specific analyzers can override (e.g. Python buildPythonCallArgs). + */ + buildCallArgs(node: any, argvalues: any[], fclos: any): CallArgs { + const args: CallArg[] = [] + for (let i = 0; i < argvalues.length; i++) { + const name = this.getCallArgName(node, i) + args.push({ + index: i, + value: argvalues[i], + node: node.arguments?.[i], + name, + kind: name ? 'keyword' : 'positional', + }) + } + const receiver = this.getCallReceiver(fclos, node) + return { receiver, args } + } + + /** + * Get the keyword name for argument at given index from node.names. + */ + getCallArgName(node: any, index: number): string | undefined { + if (node.names && Array.isArray(node.names) && index < node.names.length) { + const name = node.names[index] + if (name && typeof name === 'string') return name + } + return undefined + } + + /** + * Get the receiver (this/self) from fclos for MemberAccess calls. + */ + getCallReceiver(fclos: any, node: any): any { + if (node?.callee?.type === 'MemberAccess') { + return fclos?._this || fclos?.getThisObj?.() + } + return undefined + } + + /** + * 确保 callInfo 有效:缺失时创建空对象,callArgs 缺失时构建空 callArgs。 + */ + ensureCallInfo(node: any, fclos: any, callInfo?: CallInfo): CallInfo { + const activeCallInfo: CallInfo = callInfo || ({ callArgs: { args: [] } } as CallInfo) + if (!activeCallInfo.callArgs) { + activeCallInfo.callArgs = this.buildCallArgs(node, [], fclos) + } + return activeCallInfo + } + + /** + * Bind CallArgs to function parameters, producing BoundCall. + * 核心绑定逻辑:将 CallArgs 中的实参绑定到 BoundCall 的形参上。 + * 替代旧的 for-loop + node.names.indexOf 方式。 + */ + bindCallArgs(node: any, fclos: any, fdecl: any, callInfo: CallInfo): BoundCall { + const callArgs = callInfo.callArgs + const params = fdecl?.parameters + const boundCall: BoundCall = { + receiver: callArgs?.receiver, + params: [], + } + if (!params || !callArgs) return boundCall + + const paramList: any[] = Array.isArray(params) ? params : params.parameters || [] + for (let i = 0; i < paramList.length; i++) { + const param = paramList[i] + boundCall.params.push({ + index: i, + name: param.name || param.id?.name || `_${i}`, + value: undefined, + provided: false, + argIndexes: [], + }) + } + + const startIndex = this.bindReceiverParam(boundCall, paramList, callArgs, node) + this.bindPositionalArgs(boundCall, paramList, callArgs, startIndex) + this.bindKeywordArgs(boundCall, paramList, callArgs) + + return boundCall + } + + /** + * 判定形参类型:vararg(*args/rest)、varkw(**kwargs)、keyword_only、positional_only 或普通 + */ + getParamKind(param: any): string { + if (param?._meta?.parameterKind) { + return param._meta.parameterKind + } + if (param?._meta?.positional_only) { + return 'positional_only' + } + if (param?._meta?.keyword_only) { + return 'keyword_only' + } + if (param?._meta?.varkw) { + return 'varkw' + } + // isRestElement: JS parser; varType._meta.varargs: Java/Go parser + if (param?._meta?.isRestElement || param?.varType?._meta?.varargs) { + return 'vararg' + } + return 'positional_or_keyword' + } + + /** + * 统一赋值:普通参数直接赋值,vararg 收集为数组,varkw 收集为对象 + */ + private assignParamValue(boundCall: BoundCall, params: any[], paramIndex: number, value: any, argIndex: number): void { + if (paramIndex < 0 || paramIndex >= boundCall.params.length) return + const target = boundCall.params[paramIndex] + const paramKind = this.getParamKind(params[paramIndex]) + if (paramKind === 'vararg') { + if (!target.provided || !Array.isArray(target.value)) { + target.value = [] + target.provided = true + } + target.value.push(value) + target.argIndexes.push(argIndex) + return + } + if (paramKind === 'varkw') { + if (!target.provided || !target.value || typeof target.value !== 'object' || Array.isArray(target.value)) { + target.value = {} + target.provided = true + } + } + target.value = value + target.provided = true + target.argIndexes.push(argIndex) + } + + /** + * 展开 *args spread 值为数组 + */ + resolveSpreadValues(value: any): any[] { + if (Array.isArray(value)) { + return value + } + if (value?._field && Array.isArray(value._field)) { + return value._field + } + if (value?.members && value.members.size > 0) { + const numericKeys = [...value.members.keys()] + .filter((key: string) => /^\d+$/.test(key)) + .sort((a: string, b: string) => Number(a) - Number(b)) + if (numericKeys.length > 0) { + return numericKeys.map((key: string) => value.members.get(key)) + } + } + if (value?._field && typeof value._field === 'object') { + const numericKeys = Object.keys(value._field) + .filter((key: string) => /^\d+$/.test(key)) + .sort((a: string, b: string) => Number(a) - Number(b)) + if (numericKeys.length > 0) { + return numericKeys.map((key: string) => value._field[key]) + } } - return res + return [value] } - // TODO slice /** - * - * @param scope - * @param node - * @param state + * 展开 **kwargs kwspread 值为 [name, value] 对 */ - processSliceExpression(scope: any, node: any, state: any) {} + resolveKwSpreadEntries(value: any): Array<[string, any]> { + if (!value) return [] + const entries: Array<[string, any]> = [] + if (value.members && value.members.size > 0) { + for (const key of value.members.keys()) { + entries.push([key, value.members.get(key)]) + } + } else { + const source = value._field && typeof value._field === 'object' ? value._field : value + if (source && typeof source === 'object') { + for (const [key, val] of Object.entries(source)) { + if (typeof key === 'string') { + entries.push([key, val]) + } + } + } + } + return entries + } - // TODO tuple /** - * - * @param scope - * @param node - * @param state + * receiver(self/cls/this)绑定到第一个形参,返回 positional 绑定的起始索引 */ - processTupleExpression(scope: any, node: any, state: any) { - return unionAllValues( - node.elements.map((ele: any) => { - return this.processInstruction(scope, ele, state) - }), - state - ) + bindReceiverParam(boundCall: BoundCall, params: any[], callArgs: CallArgs, node: any): number { + if (!callArgs.receiver || params.length === 0) return 0 + const firstParam = params[0] + const firstName = firstParam.name || firstParam.id?.name || '' + if (['self', 'cls', 'this'].includes(firstName)) { + const bp = boundCall.params[0] + if (bp) { + bp.value = callArgs.receiver + bp.provided = true + } + return 1 + } + return 0 } /** - * - * @param scope - * @param node - * @param state + * positional/spread 实参绑定到形参,溢出部分收集到 vararg */ - processObjectExpression(scope: any, node: any, state: any) { - // FIXME - let res = Scoped({ parent: scope, ast: node }) - if (node.properties) { - for (const property of node.properties) { - let name - let fvalue - switch (property.type) { - case 'ObjectMethod': { - name = property.key.name - fvalue = this.createFuncScope(property, scope) - fvalue.fdef = _.clone(fvalue.fdef) - if (fvalue.fdef) { - fvalue.fdef.type = 'FunctionDefinition' - } - fvalue.ast = _.clone(fvalue.ast) - if (fvalue.ast) { - fvalue.ast.type = 'FunctionDefinition' - } - break - } - case 'SpreadElement': { - this.processInstruction(res, property, state) - continue + bindPositionalArgs(boundCall: BoundCall, params: any[], callArgs: CallArgs, startIndex: number): void { + let nextPositionalIndex = startIndex + const findNext = (): number => { + while (nextPositionalIndex < params.length) { + const kind = this.getParamKind(params[nextPositionalIndex]) + if (kind === 'keyword_only' || kind === 'varkw') { + nextPositionalIndex++ + continue + } + return nextPositionalIndex + } + return -1 + } + + for (const arg of callArgs?.args || []) { + if (arg.kind === 'keyword' || arg.kind === 'kwspread') continue + const values = arg.kind === 'spread' ? this.resolveSpreadValues(arg.value) : [arg.value] + for (const value of values) { + const paramIndex = findNext() + if (paramIndex === -1) { + // 溢出:收集到 vararg 形参 + const varargIndex = params.findIndex((p: any) => this.getParamKind(p) === 'vararg') + if (varargIndex !== -1) { + this.assignParamValue(boundCall, params, varargIndex, value, arg.index) } - case 'ObjectProperty': - default: { - let { key } = property - switch (key.type) { - // FIXME process ObjectMethod - case 'Literal': - name = key.value - break - case 'Identifier': - name = key.name - break - default: - key = this.processInstruction(res, key, state) - name = key.type === 'Literal' ? key.value : key.name - break - } - fvalue = this.processInstruction(res, property.value, state) - res.hasTagRec = res.hasTagRec || fvalue?.hasTagRec - if (property.value && property.value.type === 'FunctionDefinition') fvalue.parent = res - break + continue + } + this.assignParamValue(boundCall, params, paramIndex, value, arg.index) + if (this.getParamKind(params[paramIndex]) !== 'vararg') { + nextPositionalIndex = paramIndex + 1 + } + } + } + } + + /** + * keyword/kwspread 实参按名称匹配形参,未匹配的收集到 varkw(**kwargs) + */ + bindKeywordArgs(boundCall: BoundCall, params: any[], callArgs: CallArgs): void { + const keywordEntries: Array<{ name: string; value: any; argIndex: number }> = [] + for (const arg of callArgs?.args || []) { + if (arg.kind === 'keyword' && arg.name) { + keywordEntries.push({ name: arg.name, value: arg.value, argIndex: arg.index }) + } else if (arg.kind === 'kwspread') { + for (const [name, value] of this.resolveKwSpreadEntries(arg.value)) { + keywordEntries.push({ name, value, argIndex: arg.index }) + } + } + } + + const varkwIndex = params.findIndex((p: any) => this.getParamKind(p) === 'varkw') + for (const entry of keywordEntries) { + const paramIndex = params.findIndex((p: any) => (p?.id?.name || p?.name) === entry.name) + if (paramIndex === -1) { + // 未匹配的 keyword → **kwargs + if (varkwIndex !== -1) { + const target = boundCall.params[varkwIndex] + if (!target.provided || !target.value || typeof target.value !== 'object' || Array.isArray(target.value)) { + target.value = {} + target.provided = true } + target.value[entry.name] = entry.value + target.argIndexes.push(entry.argIndex) } - res.value[name] = fvalue - // // call-back - // if (expressionCallBack) { - // expressionCallBack(node, [name, fvalue], this.currentFunction); - // } - // if (triggers) - // //triggers.checkObjectValue(node, property, fvalue, this.currentFunction.sourcefile); - // triggers.checkExpression(property, fvalue); + continue } + if (this.getParamKind(params[paramIndex]) === 'positional_only') continue + this.assignParamValue(boundCall, params, paramIndex, entry.value, entry.argIndex) } - res = ObjectValue(res) - res.vtype = 'object' - res._this = res - return res } + // ==================== End CallArgs methods ==================== + /** * * @param scope * @param node * @param state - * @param cachedFclos */ - processCallExpression(scope: any, node: any, state: any, cachedFclos?: any) { + processCallExpression(scope: ScopeType, node: CallExpression, state: State): any { /* { callee, arguments, } @@ -1497,11 +2228,8 @@ class Analyzer extends MemSpace { einfo: state.einfo, }) - const fclos = cachedFclos ?? this.processInstruction(scope, node.callee, state) - if (!fclos) return UndefinedValue() - if (node?.callee?.type === 'MemberAccess' && fclos.fdef && node.callee?.object?.type !== 'SuperExpression') { - fclos._this = this.processInstruction(scope, node.callee.object, state) - } + const fclos = this.processInstruction(scope, node.callee, state) + if (!fclos) return new UndefinedValue() // prepare the function arguments let argvalues = [] @@ -1511,9 +2239,12 @@ class Analyzer extends MemSpace { // 处理参数是 箭头函数或匿名函数 // 参数类型必须是函数定义,且fclos找不到定义或未建模适配 // 如果参数适配建模,则会进入相应的逻辑模拟执行,例如array.push - if (arg?.type === 'FunctionDefinition' && arg?.name === '' && !fclos?.fdef && !fclos?.execute) { - // let subscope = Scope.createSubScope(argv.sid + '_scope', scope,'scope') - argv = this.processAndCallFuncDef(scope, arg, argv, state) + if (arg.type === 'FunctionDefinition' && !fclos?.ast.fdef && !fclos?.runtime?.execute) { + const funcDef = arg as FunctionDefinition & { name?: string } + if (funcDef.name?.includes(' 0) { + initVal = SourceLine.addSrcLineInfo(initVal, id, id.loc && id.loc.sourcefile, 'Var Pass: ', idName || '') + } else if (node?.parent?.type === 'CatchClause' && node?._meta?.isCatchParam && (state?.throwstack?.length ?? 0) > 0) { // 处理throw传递到catch的情况 initVal = state?.throwstack && state?.throwstack.shift() - initVal = SourceLine.addSrcLineInfo(initVal, node, node.loc && node.loc.sourcefile, 'Var Pass: ', id.name) + initVal = SourceLine.addSrcLineInfo(initVal, node, node.loc && node.loc.sourcefile, 'Var Pass: ', idName || '') delete node._meta.isCatchParm } else { initVal = this.processInstruction(scope, initialNode, state) @@ -1759,7 +2501,7 @@ class Analyzer extends MemSpace { initVal = this.processInstruction(scope, initialNode, state) } } - initVal = SourceLine.addSrcLineInfo(initVal, node, node.loc && node.loc.sourcefile, 'Var Pass: ', id.name) + initVal = SourceLine.addSrcLineInfo(initVal, node, node.loc && node.loc.sourcefile, 'Var Pass: ', idName || '') } if (this.checkerManager && this.checkerManager.checkAtPreDeclaration) @@ -1774,16 +2516,13 @@ class Analyzer extends MemSpace { this.saveVarInCurrentScope(scope, id, initVal, state) // set alias name if val itself has no identifier - if ( - initVal && - !Array.isArray(initVal) && - !(initVal.name || (initVal.id && initVal.id !== '') || initVal.sid) - ) { - initVal.sid = id.name - delete initVal.id + if (initVal && !Array.isArray(initVal) && !(initVal.name || initVal.sid) && idName) { + initVal.sid = idName } - scope.decls[id.name] = id + if (idName) { + scope.ast.setDecl(idName, id) + } const typeQualifiedName = AstUtil.typeToQualifiedName(node.varType) let declTypeVal @@ -1791,9 +2530,6 @@ class Analyzer extends MemSpace { declTypeVal = this.getMemberValueNoCreate(scope, typeQualifiedName, state) } - if (initVal && declTypeVal) { - initVal.sort = declTypeVal.sort - } return initVal } @@ -1806,10 +2542,10 @@ class Analyzer extends MemSpace { */ processDereferenceExpression(scope: any, node: any, state: any) { const ret = this.processInstruction(scope, node.argument, state) - if (ret && ret.refCount) { - ret.refCount-- - if (ret.refCount === 0) { - delete ret.refCount + if (ret && ret.runtime?.refCount) { + ret.runtime.refCount-- + if (ret.runtime.refCount === 0) { + delete ret.runtime.refCount } } return ret @@ -1825,8 +2561,9 @@ class Analyzer extends MemSpace { processReferenceExpression(scope: any, node: any, state: any) { const val = this.processInstruction(scope, node.argument, state) if (val) { - val.refCount = val.refCount || 0 - val.refCount++ + if (!val.runtime) val.runtime = {} + val.runtime.refCount = val.runtime.refCount || 0 + val.runtime.refCount++ } return val } @@ -1837,7 +2574,7 @@ class Analyzer extends MemSpace { * @param node * @param state */ - processImportExpression(scope: any, node: any, state: any) { + processImportExpression(scope: ScopeType, node: ImportExpression, state: State): SymbolValueType { /* { from, local, @@ -1857,14 +2594,14 @@ class Analyzer extends MemSpace { * @param node * @param state */ - processSpreadElement(scope: any, node: any, state: any) { + processSpreadElement(scope: ScopeType, node: SpreadElement, state: State): SpreadValueType { const val = this.processInstruction(scope, node.argument, state) if (!val) { return val } const res = new Set() const self = this - const fields = Array.isArray(val) ? val : val.exports ? val.exports.getRawValue() : val.getRawValue() + const fields = Array.isArray(val) ? val : val.scope.exports ? val.scope.exports.getRawValue() : val.getRawValue() if (Array.isArray(fields)) { for (const f of fields) { handler(f) @@ -1893,8 +2630,8 @@ class Analyzer extends MemSpace { // eg arr1= [1,2,3] arr2=[10,...arr1,...arr1] // 第一个...arr1应该加上的偏移量是1,第二个arr1应该加上的偏移量是4 // TODO 未来数组表达式的ast从ObjectExpression换成ArrayExpression 在这里需要做相应修改 - const offset = Object.keys(scope.field).length - const isArray = node.parent?._meta?.isArray + const offset = scope.members.size + const isArray = (node.parent as any)?._meta?.isArray for (let fname in flds) { const fVal = flds[fname] // 解构变量field中undefine的值不应该被保存到scope的field中,会清除有污点的变量 @@ -1912,7 +2649,15 @@ class Analyzer extends MemSpace { } } - return Array.from(res) + // 创建 SpreadValue - 返回增强数组(保持向后兼容) + // 注意:不预先计算 isTainted,让后续逻辑(如 js-analyzer)按需处理 + const spreadValue: any = Array.from(res) + spreadValue.vtype = 'spread' + spreadValue.elements = spreadValue // elements 指向自身(因为本身就是数组) + spreadValue.sid = '' + spreadValue.qid = '' + + return spreadValue as SpreadValueType } // TODO YieldExpression @@ -1922,42 +2667,14 @@ class Analyzer extends MemSpace { * @param node * @param state */ - processYieldExpression(scope: any, node: any, state: any) { - node.expression = node.argument - return this.processReturnStatement(scope, node, state) - } - - /** - * - * @param node - */ - traceNodeInfo(node: any) { - const loc = node?.loc - if (!loc) return - - const sourcefile = (() => { - let n = node - while (n) { - if (n?.loc?.sourcefile) { - return n.loc.sourcefile - } - n = n.parent - } - return null - })() - - if (!sourcefile) return - const source_code = this.sourceCodeCache[sourcefile] - if (!source_code) return - const lines = source_code.split('\n') - - const snippet = lines[loc.start.line - 1] - const start = loc.start.column - const end = loc.end.line === loc.start.line ? loc.end.column : snippet.length - 1 - - const prefix = `${sourcefile}:${loc.start.line}:[${node.type}] ${snippet.substring(0, start)}` - const highlight = source_code.substring(loc.start.index, loc.end.index).substring(0, 100).replace(/\n/g, ' ') - return prefix + chalk.blue(highlight) + processYieldExpression(scope: ScopeType, node: YieldExpression, state: State): VoidValueType { + // 保持历史行为(25282dbd):转换为 ReturnStatement 处理 + // YieldExpression has 'argument' field, not 'expression' + const returnLike = { + ...node, + expression: node.argument, + } as any as ReturnStatement + return this.processReturnStatement(scope, returnLike, state) } /** @@ -2021,18 +2738,28 @@ class Analyzer extends MemSpace { * @param scope * @returns {*} */ - executeCall(node: any, fclos: any, argvalues: any, state: any, scope: any): any { - if (Config.makeAllCG && fclos?.fdef?.type === 'FunctionDefinition' && this.ainfo?.callgraph?.nodes) { + executeCall(node: any, fclos: any, state: State, scope: any, callInfo: CallInfo): any { + callInfo = this.ensureCallInfo(node, fclos, callInfo) + const argvalues = getLegacyArgValues(callInfo) + if (Config.miniSaveContextEnvironment) { + return new CallExprValue(scope.qid, fclos, argvalues, node, node.loc, fclos) + } + if (Config.makeAllCG && fclos?.ast.fdef?.type === 'FunctionDefinition' && this.ainfo?.callgraph?.nodes) { for (const callgraphnode of this.ainfo?.callgraph?.nodes.values()) { + // 从 nodehash 还原 funcDef + let callgraphFuncDef = callgraphnode.opts?.funcDef + if (callgraphnode.opts?.funcDefNodehash && this.astManager) { + callgraphFuncDef = this.astManager.get(callgraphnode.opts.funcDefNodehash) + } if ( - callgraphnode.opts?.funcDef?.loc?.start?.line && - callgraphnode.opts?.funcDef?.loc?.end?.line && - callgraphnode.opts?.funcDef?.loc?.sourcefile === fclos.fdef?.loc?.sourcefile && - callgraphnode.opts?.funcDef?.loc?.start?.line === fclos.fdef?.loc?.start?.line && - callgraphnode.opts?.funcDef?.loc?.end?.line === fclos.fdef?.loc?.end?.line + callgraphFuncDef?.loc?.start?.line && + callgraphFuncDef?.loc?.end?.line && + callgraphFuncDef?.loc?.sourcefile === fclos.ast.fdef?.loc?.sourcefile && + callgraphFuncDef?.loc?.start?.line === fclos.ast.fdef?.loc?.start?.line && + callgraphFuncDef?.loc?.end?.line === fclos.ast.fdef?.loc?.end?.line ) { this.checkerManager.checkAtFunctionCallBefore(this, scope, node, state, { - argvalues, + callInfo, fclos, pcond: state.pcond, entry_fclos: this.entry_fclos, @@ -2041,43 +2768,44 @@ class Analyzer extends MemSpace { analyzer: this, ainfo: this.ainfo, }) - return SymbolValue({ - type: 'FunctionCall', - expression: fclos, - arguments: argvalues, - ast: node, - }) + return new CallExprValue(scope.qid, fclos, argvalues, node, node.loc, fclos) } } } // process the function body - if (fclos.fdef || fclos.execute) { + if (fclos.ast.fdef || fclos.runtime?.execute) { const { decorators } = fclos // const decorators = fclos.ast && fclos.ast.decorators; if (decorators && decorators.length > 0) { - return this.executeCallWithDecorators(_.clone(decorators), fclos, argvalues, state, node, scope) + return this.executeCallWithDecorators(_.clone(decorators), fclos, state, node, scope, callInfo) } - return this.executeSingleCall(fclos, argvalues, state, node, scope) + return this.executeSingleCall(fclos, state, node, scope, callInfo) } if (fclos.vtype === 'union') { const res: any[] = [] for (const f of fclos.value) { if (!f) continue - node = node || f.ast - const v = this.executeCall(node, f, argvalues, state, scope) + node = node || f.ast?.node + const v = this.executeCall(node, f, state, scope, callInfo) if (v) res.push(v) } const len = res.length if (len === 0) { } else if (len === 1) return res[0] - else return UnionValue({ value: res }) + else + return new UnionValue( + res, + undefined, + `${scope.qid}.`, + node + ) } // now for the function without body if (this.checkerManager) { this.checkerManager.checkAtFunctionCallBefore(this, scope, node, state, { - argvalues, + callInfo, fclos, pcond: state.pcond, entry_fclos: this.entry_fclos, @@ -2091,10 +2819,14 @@ class Analyzer extends MemSpace { const native = NativeResolver.processNativeFunction.call(this, node, fclos, argvalues, state) if (native) return native - const libFuncTagPropagationRuleFound = this.processLibFuncTagPropagation(node, fclos, argvalues, scope, state) + const libFuncTagPropagationRuleFound = this.processLibFuncTagPropagation(node, fclos, callInfo, scope, state) if (!libFuncTagPropagationRuleFound) { // 没有配置的库函数,采用默认处理方式:arg->ret - return this.processLibArgToRet(node, fclos, argvalues, scope, state) + const res = this.processLibArgToRet(node, fclos, argvalues, scope, state, callInfo) + if (this.enableLibArgToThis) { + this.processLibArgToThis(node, fclos, argvalues, -1, scope, state) + } + return res } } @@ -2106,57 +2838,72 @@ class Analyzer extends MemSpace { * @param scope * @param state */ - processLibArgToRet(node: any, fclos: any, argvalues: any, scope: any, state: any) { + processLibArgToRet(node: any, fclos: any, argvalues: any, scope: any, state: any, callInfo: CallInfo) { // the case without function body, still process the call, e.g. perform taint propagation let res = _.clone(node) res.expression = fclos res.arguments = argvalues res.ast = node const argsSignature = AstUtil.prettyPrintAST(node.arguments) - res.id = `${fclos?.id}(${argsSignature})` res.sid = `${fclos?.sid}(${argsSignature})` res.qid = `${fclos?.qid}(${argsSignature})` // res.field = {} - if (fclos.hasTagRec) { - res.hasTagRec = true + let isTainted = false + if (fclos.taint?.isTaintedRec) { + isTainted = true } - // attach taint information if any - // var taint; + // 检查参数是否携带污点 for (const arg of argvalues) { if (arg) { - if (arg.hasTagRec) { - res.hasTagRec = true + if (arg.taint?.isTaintedRec) { + isTainted = true break } - const hasTag = AstUtil.hasTag(arg, '') - if (hasTag) { - res.hasTagRec = true - } } } - // e.g. XXInterface token = XXInterface(id) where id is ctor_init + // e.g. XXInterface token = XXInterface(id) where id is ctorInit for (const arg of argvalues) { - if (arg && arg.ctor_init && node.expression && node.expression.value) { + if (arg && arg.runtime?.ctorInit && node.expression && node.expression.value) { let top_scope = scope while (top_scope.parent) { top_scope = top_scope.parent } if (top_scope.value && top_scope.value[node.expression.value]) { - res.ctor_init = true + if (!res.runtime) res.runtime = {} + res.runtime.ctorInit = true } } } if (node.callee.type === 'MemberAccess') { - if (fclos?.object?.hasTagRec) { - res.hasTagRec = true + if (fclos?.object?.taint?.isTaintedRec) { + isTainted = true + } else { + /* + first invoke: JSONObject.toJSONString(); + second invoke: JSONObject obj = new JSONObject(); obj.toJSONString(); + */ + const thisVal = fclos.getThisObj() + if ( + thisVal && + ['symbol', 'object'].includes(thisVal.vtype) && + res.expression && + !res.expression.object && + thisVal.taint?.isTaintedRec + ) { + res.expression.object = thisVal + isTainted = true + } } } // return { type : 'FunctionCall', expression: fclos, arguments: argvalues, // ast: node }; - res = SymbolValue(res) // esp. for member getter function + res = new SymbolValue('', { sid: res.sid, qid: res.qid, ...res }) // esp. for member getter function + if (isTainted) { + res.taint?.markSource() + } // save pass-in arguments for later use if (argvalues.length > 0) { @@ -2173,12 +2920,15 @@ class Analyzer extends MemSpace { * @param scope * @param state */ - processLibFuncTagPropagation(node: any, fclos: any, argvalues: any, scope: any, state: any) { + processLibFuncTagPropagation(node: any, fclos: any, callInfo: CallInfo | undefined, scope: any, state: any) { + const argvalues = getLegacyArgValues(callInfo) let matchRuleFound = false const libFuncTagPropagationRuleArray = this.loadLibFuncTagPropagationRule() for (const libFuncTagPropagationRule of libFuncTagPropagationRuleArray) { if ( - matchSinkAtFuncCallWithCalleeType(node, fclos, [libFuncTagPropagationRule.func], scope, argvalues)?.length > 0 + matchSinkAtFuncCallWithCalleeType(node, fclos, [libFuncTagPropagationRule.func], scope, callInfo)?.length > + 0 || + this.findMatchedRuleByCallGraph(node, scope, [libFuncTagPropagationRule.func])?.length > 0 ) { const sourceType = libFuncTagPropagationRule.source?.type const targetType = libFuncTagPropagationRule.target?.type @@ -2232,28 +2982,25 @@ class Analyzer extends MemSpace { if (!argvalues || argvalues.length < 2 || !targetIndex || targetIndex >= argvalues.length) { return } - const res = argvalues[targetIndex] + let res = argvalues[targetIndex] res.setMisc('precise', false) moveExistElementsToBuffer(res) - const passIn = res.getMisc('pass-in') || [] + const passIn = res.getMisc('buffer') || [] for (const argIndex in argvalues) { if (sourceIndex >= 0 && sourceIndex !== Number(argIndex)) { continue } const arg = argvalues[argIndex] passIn.push(arg) - if (arg.hasTagRec) { - res.hasTagRec = true - } - const hasTag = AstUtil.hasTag(arg, '') - if (hasTag) { - res.hasTagRec = true + if (arg.taint?.isTaintedRec) { + res.taint?.markSource() + res = SourceLine.addSrcLineInfo(res, node, node.loc && node.loc.sourcefile, 'Var Pass: ', res.sid) } } - res.setMisc('pass-in', passIn) + res.setMisc('buffer', passIn) } /** @@ -2266,37 +3013,46 @@ class Analyzer extends MemSpace { * @param state */ processLibArgToThis(node: any, fclos: any, argvalues: any, sourceIndex: any, scope: any, state: any) { - const _this = fclos.getThis() - if (!argvalues || !_this) { + let thisVal = fclos.getThisObj() + if ( + !argvalues || + argvalues.length === 0 || + !thisVal || + !['symbol', 'object'].includes(thisVal.vtype) || + !_.isFunction(thisVal.setMisc) || + this.shouldSkipLibArgToThisPropagation(thisVal) || + thisVal.injected || + thisVal?.parent?.vtype === 'class' || + thisVal?.parent?._isConstructor || + thisVal?._this?.vtype === 'class' || + thisVal?._this?._isConstructor || + thisVal.qid?.startsWith('.syslib_from') + ) { return } - _this.setMisc('precise', false) - moveExistElementsToBuffer(_this) + thisVal.setMisc('precise', false) + moveExistElementsToBuffer(thisVal) switch (node.callee.type) { case 'MemberAccess': - const thisVal = this.processInstruction(scope, node.callee.object, state) for (const argIndex in argvalues) { if (sourceIndex >= 0 && sourceIndex !== Number(argIndex)) { continue } const arg = argvalues[argIndex] - if (arg.hasTagRec) { - thisVal.setFieldValue( - arg.id, - ObjectValue({ - sid: arg.sid, - qid: arg.qid, - parent: thisVal, - value: arg, - }) - ) - thisVal.hasTagRec = true - } - const hasTag = AstUtil.hasTag(arg, '') - if (hasTag) { - thisVal.hasTagRec = true + addElementToBuffer(thisVal, arg) + if (arg.taint?.isTaintedRec) { + thisVal.taint?.markSource() + if (node?.parent?.type !== 'AssignmentExpression') { + thisVal = SourceLine.addSrcLineInfo( + thisVal, + node, + node.loc && node.loc.sourcefile, + 'Var Pass: ', + node?.callee?.object ? prettyPrint(node.callee.object) : thisVal.sid + ) + } } } break @@ -2307,6 +3063,28 @@ class Analyzer extends MemSpace { } } + /** + * Check whether lib arg->this propagation should be skipped. + * @param thisVal + */ + shouldSkipLibArgToThisPropagation(thisVal: any) { + if (!thisVal || typeof thisVal.sid !== 'string') { + return false + } + const sid = thisVal.sid.toLowerCase() + const keywords = this.loadLibArgToThisSidBlacklistKeywords() + if (!Array.isArray(keywords) || keywords.length === 0) { + return false + } + return keywords.some((keyword) => { + if (typeof keyword !== 'string') { + return false + } + const normalizedKeyword = keyword.trim().toLowerCase() + return normalizedKeyword.length > 0 && sid.includes(normalizedKeyword) + }) + } + /** * process lib this to arg * @param node @@ -2328,22 +3106,22 @@ class Analyzer extends MemSpace { if (targetIndex >= 0 && targetIndex !== Number(argIndex)) { continue } - const arg = argvalues[argIndex] + let arg = argvalues[argIndex] arg.setMisc('precise', false) moveExistElementsToBuffer(arg) - if (thisVal && thisVal.hasTagRec) { + if (thisVal && thisVal.taint?.isTaintedRec) { arg.setFieldValue( - thisVal.id, - ObjectValue({ + thisVal.sid, + new ObjectValue(arg.qid, { sid: thisVal.sid, - qid: thisVal.qid, parent: arg, value: thisVal, }) ) - arg.hasTagRec = true + arg.taint?.markSource() + arg = SourceLine.addSrcLineInfo(arg, node, node.loc && node.loc.sourcefile, 'Var Pass: ', arg.sid) } } break @@ -2364,9 +3142,9 @@ class Analyzer extends MemSpace { * @param node * @param scope */ - executeCallWithDecorators(decorators: any, fclos: any, argvalues: any, state: any, node: any, scope: any) { + executeCallWithDecorators(decorators: any, fclos: any, state: any, node: any, scope: any, callInfo: CallInfo) { if (!decorators || decorators.length === 0) { - return this.executeSingleCall(fclos, argvalues, state, node, scope) + return this.executeSingleCall(fclos, state, node, scope, callInfo) } // The decorator expressions get called top to bottom, and produce decorators, @@ -2374,11 +3152,11 @@ class Analyzer extends MemSpace { let decorator = decorators.pop() let descriptor_fclos = fclos - const class_obj = fclos.getThis() // fclos represents class method, the parent of it is class object + const class_obj = fclos.getThisObj() // fclos represents class method, the parent of it is class object while (decorator) { - let descriptor = ObjectValue({ sid: 'descriptor' }) - descriptor.value.value = _.clone(descriptor_fclos) + let descriptor = new ObjectValue(descriptor_fclos.qid, { sid: 'descriptor' }) + descriptor.value.value = lodashCloneWithTag(descriptor_fclos) const { name } = decorator // both function decl and identifier have name const target = decorator decorator._this = class_obj @@ -2388,8 +3166,9 @@ class Analyzer extends MemSpace { // if decorator is not found, just skip it // TODO decorators that can't be found should be summary analyzed - if (decorator_clos?.vtype === 'fclos' && !shallowEqual(decorator_clos.ast, decorator)) { - descriptor_res = this.executeCall(node, decorator, [target, name, descriptor], state, scope) + if (decorator_clos?.vtype === 'fclos' && !shallowEqual(decorator_clos.ast?.node, decorator)) { + const decoratorCallInfo: CallInfo = { callArgs: this.buildCallArgs(node, [target, name, descriptor], decorator) } + descriptor_res = this.executeCall(node, decorator, state, scope, decoratorCallInfo) } else { descriptor_res = null } @@ -2400,17 +3179,14 @@ class Analyzer extends MemSpace { descriptor_fclos = this.getMemberValue( descriptor, - PrimitiveValue({ - type: 'Literal', - value: 'value', - }), + new PrimitiveValue(scope.qid, '', 'value', null, 'Literal'), state ) // descriptor_fclos runs with class object as it's [this], which can be located from parent of class method descriptor_fclos._this = class_obj decorator = decorators.pop() } - return this.executeSingleCall(descriptor_fclos, argvalues, state, descriptor_fclos.ast, scope) + return this.executeSingleCall(descriptor_fclos, state, descriptor_fclos.ast?.node, scope, callInfo) } /** @@ -2423,114 +3199,221 @@ class Analyzer extends MemSpace { * @param scope * @returns {undefined|*} */ - executeSingleCall(fclos: any, argvalues: any, state: any, node: any, scope: any) { - let fdecl = fclos.fdef + executeSingleCall(fclos: any, state: State, node: any, scope: any, callInfo: CallInfo) { + const argvalues = getLegacyArgValues(callInfo) + let fdecl = fclos.ast.fdef let fname // name of the function if (fclos && fclos.vtype === 'union') { - const res = UnionValue() + const res = new UnionValue( + undefined, + undefined, + `${scope.qid}.`, + node + ) for (const fc of fclos.value) { - node = node || fc.ast - res.appendValue(this.executeSingleCall(fc, argvalues, state, node, scope)) + node = node || fc.ast?.node + res.appendValue(this.executeSingleCall(fc, state, node, scope, callInfo)) } return res } let execute_builtin = false if (!fdecl) { - if (!fclos.execute) { - return { type: 'FunctionCall', callee: fclos, arguments: argvalues, loc: node.loc } + if (!fclos.runtime?.execute) { + return new CallExprValue(scope.qid, fclos, argvalues, node, node.loc) } // execute prepared builtins function execute_builtin = true } else { fname = fdecl.name if (fdecl.type === 'StructDefinition') { - return this.buildNewObject(fdecl, argvalues, fclos, state, node, scope) + return this.buildNewObject(fdecl, fclos, state, node, scope, callInfo) } if (fdecl.type === 'ClassDefinition' && fclos.value?._CTOR_ && fclos.value?._CTOR_.vtype === 'fclos') { - fdecl = fclos?.value?._CTOR_?.fdef + fdecl = fclos?.value?._CTOR_?.ast.fdef } if (fdecl.type !== 'FunctionDefinition') { - return UndefinedValue() + return new UndefinedValue() } } + fname = fname || fclos.sid || '' + if (fname.includes(' 1) { + let extraFuncDefs = [] + const overloadedNodes = fclos.overloaded.filter(() => true) + if (overloadedNodes.length > 1) { // overloaded functions let hasFind = false - for (const f of fclos.overloaded) { + let maxMatchNum = 0 + let maxMatchFdef + for (const f of overloadedNodes) { + let matchNum = 0 let paramLength = 0 - const param = f.parameters - if (param) { - paramLength = Array.isArray(param) ? param.length : param.parameters.length + const params = f.parameters + if (params) { + paramLength = Array.isArray(params) ? params.length : params.parameters.length } + const literalTypeList = ['String', 'string', 'int', 'Integer', 'Double', 'double', 'float', 'Float'] + let typeMatch = false if (paramLength === argvalues.length) { - let typeMatch = true - const literalTypeList = ['String', 'string', 'int', 'Integer', 'Double', 'double', 'float', 'Float'] + typeMatch = true for (let i = 0; i < paramLength; i++) { + const param = params[i] if ( - param[i].varType?.id?.name === argvalues[i].rtype?.definiteType?.name || - argvalues[i].rtype?.definiteType?.name?.endsWith(`.${param[i].varType?.id?.name}`) || - (argvalues[i].vtype === 'primitive' && literalTypeList.includes(param[i].varType?.id?.name)) + param.varType?.id?.name === argvalues[i].rtype?.definiteType?.name || + argvalues[i].rtype?.definiteType?.name?.endsWith(`.${param.varType?.id?.name}`) || + (argvalues[i].vtype === 'primitive' && literalTypeList.includes(param.varType?.id?.name)) ) { + matchNum++ continue } typeMatch = false } - if (typeMatch) { - hasFind = true - fclos = _.clone(fclos) - fclos.ast = fclos.fdef = fdecl = f // adjust to the right function definition - break + if (matchNum > maxMatchNum) { + maxMatchNum = matchNum + maxMatchFdef = f + extraFuncDefs = [] + } else if (matchNum === maxMatchNum) { + extraFuncDefs.push(f) + } + } else if ( + paramLength < argvalues.length && + paramLength > 0 && + params[paramLength - 1]?.varType?._meta?.varargs + ) { + typeMatch = true + for (let i = 0; i < argvalues.length; i++) { + const param = i < paramLength ? params[i] : params[paramLength - 1] + if ( + param.varType?.id?.name === argvalues[i].rtype?.definiteType?.name || + argvalues[i].rtype?.definiteType?.name?.endsWith(`.${param.varType?.id?.name}`) || + (argvalues[i].vtype === 'primitive' && literalTypeList.includes(param.varType?.id?.name)) + ) { + matchNum++ + continue + } + typeMatch = false } + if (matchNum > maxMatchNum) { + maxMatchNum = matchNum + maxMatchFdef = f + extraFuncDefs = [] + } else if (matchNum === maxMatchNum) { + extraFuncDefs.push(f) + } + } + if (typeMatch) { + hasFind = true + fclos = lodashCloneWithTag(fclos) + fdecl = f // adjust to the right function definition + fclos.ast = fdecl + fclos.ast.fdef = fdecl } } // 兜底,假设类型完全没匹配到(类型检测没适配好),就走长度匹配 if (!hasFind) { - for (const f of fclos.overloaded) { - let paramLength = 0 - const param = f.parameters - if (param) { - paramLength = Array.isArray(param) ? param.length : param.parameters.length - } - if (paramLength === argvalues.length) { - fclos = _.clone(fclos) - fclos.ast = fclos.fdef = fdecl = f // adjust to the right function definition - break + if (maxMatchFdef) { + fclos = lodashCloneWithTag(fclos) + fclos.ast = maxMatchFdef + fclos.ast.fdef = maxMatchFdef + fdecl = maxMatchFdef + } else { + for (const f of overloadedNodes) { + let paramLength = 0 + const params = f.parameters + if (params) { + paramLength = Array.isArray(params) ? params.length : params.parameters.length + } + if ( + paramLength === argvalues.length || + (paramLength < argvalues.length && paramLength > 0 && params[paramLength - 1]?.varType?._meta?.varargs) + ) { + fclos = lodashCloneWithTag(fclos) + fclos.ast = f + fclos.ast.fdef = f + fdecl = f // adjust to the right function definition + break + } } } } } + // 在进入 executeFdeclOrExecute 前,预计算形参绑定 + if (callInfo) { + const boundCall = this.bindCallArgs(node, fclos, fdecl, callInfo) + callInfo.boundCall = boundCall + } + const return_value = this.executeFdeclOrExecute(fclos, state, node, scope, fdecl, fname, execute_builtin, callInfo) + extraFuncDefs = extraFuncDefs.filter((extraFuncDef) => extraFuncDef !== fclos.ast?.node) + if (extraFuncDefs.length === 0) { + return return_value + } + const union_return_value = new UnionValue( + undefined, + undefined, + `${scope.qid}.`, + node + ) + union_return_value.appendValue(return_value) + for (const extraFuncDef of extraFuncDefs) { + fclos = lodashCloneWithTag(fclos) + fdecl = extraFuncDef + fclos.ast = extraFuncDef + fclos.ast.fdef = extraFuncDef + // 每个 overload 需要独立绑定 + const extraCallInfo: CallInfo = { callArgs: callInfo?.callArgs } + const extraBoundCall = this.bindCallArgs(node, fclos, fdecl, extraCallInfo) + extraCallInfo.boundCall = extraBoundCall + const extraReturnValue = this.executeFdeclOrExecute(fclos, state, node, scope, fdecl, fname, false, extraCallInfo) + union_return_value.appendValue(extraReturnValue) + } + return union_return_value + } + + /** + * + * @param fclos + * @param argvalues + * @param state + * @param node + * @param scope + * @param fdecl + * @param fname + * @param execute_builtin + */ + executeFdeclOrExecute( + fclos: any, + state: State, + node: any, + scope: any, + fdecl: any, + fname: any, + execute_builtin: any, + callInfo: CallInfo + ) { + const argvalues = getLegacyArgValues(callInfo) if (logger.isTraceEnabled()) logger.trace(`\nprocessCall: function: ${this.formatScope(fdecl?.id?.name)}`) // avoid infinite loops,the re-entry should only less than 3 if ( fdecl && state.callstack.reduce((previousValue: any, currentValue: any) => { - return currentValue.fdef === fdecl ? previousValue + 1 : previousValue + return currentValue.ast.fdef === fdecl ? previousValue + 1 : previousValue }, 0) > 0 ) { - return SymbolValue({ - type: 'FunctionCall', - expression: fclos, - arguments: argvalues, - ast: node, - }) + return new CallExprValue(scope.qid, fclos, argvalues, node, node.loc, fclos) } // pre-call processing const oldThisFClos = this.thisFClos - this.thisFClos = fclos.getThis() - - fname = fname || fclos.id || fclos.sid || '' - if (fname === '') { - fname = fclos.id - } + this.thisFClos = fclos.getThisObj() let fscope = Scope.createSubScope(`${fname}_scope`, fclos) // this is actually named "activation record" in computer science fscope._this = fclos._this - if (fclos.vtype === 'class') { + if (fclos.vtype === 'class' || fclos._isConstructor) { // for javascript class ctor function fscope = fclos } @@ -2539,13 +3422,28 @@ class Analyzer extends MemSpace { const new_state = _.clone(state) new_state.parent = state new_state.callstack = state.callstack ? state.callstack.concat([fclos]) : [fclos] + new_state.callsites = state.callsites + ? state.callsites.concat([ + { + code: AstUtil.getRawCode(node).slice(0, 100), + nodeHash: node._meta?.nodehash, + loc: node.loc, + }, + ]) + : [ + { + code: AstUtil.getRawCode(node).slice(0, 100), + nodeHash: node._meta?.nodehash, + loc: node.loc, + }, + ] new_state.brs = '' // this.recordFunctionDefinitions(fscope, fdecl.body, new_state); let return_value if (execute_builtin) { this?.checkerManager.checkAtFunctionCallBefore(this, scope, node, state, { - argvalues, + callInfo, fclos, pcond: state.pcond, entry_fclos: this.entry_fclos, @@ -2555,16 +3453,16 @@ class Analyzer extends MemSpace { ainfo: this.ainfo, }) - // this.lastReturnValue = fclos.execute.call(this, fclos, argvalues, new_state, node, scope); + // this.lastReturnValue = fclos.runtime.execute.call(this, fclos, argvalues, new_state, node, scope); this.lastReturnValue = null for (let i = 0; i < argvalues.length; i++) { argvalues[i] = SourceLine.addSrcLineInfo(argvalues[i], node, node.loc && node.loc.sourcefile, 'CALL: ', fname) } - return_value = fclos.execute.call(this, fclos, argvalues, new_state, node, scope) + return_value = fclos.runtime!.execute!.call(this, fclos, argvalues, new_state, node, scope) } else { // now go into the function body this?.checkerManager.checkAtFunctionCallBefore(this, scope, node, state, { - argvalues, + callInfo, fclos, pcond: state.pcond, entry_fclos: this.entry_fclos, @@ -2574,60 +3472,59 @@ class Analyzer extends MemSpace { ainfo: this.ainfo, }) + // 基于 boundCall 绑定形参(替代旧的 argvalues[i] + node.names.indexOf 逻辑) + const activeBoundCall = callInfo?.boundCall + if (!activeBoundCall) { + logger.warn('executeFdeclOrExecute: boundCall missing from callInfo') + } + // process function arguments if (!fdecl.parameters) { - // Errors.UnexpectedNode(`warning: processCall: function parameters not found: ${fdecl}`) - return UndefinedValue() + return new UndefinedValue() } const params = fdecl.parameters - // // make sure all parameters in fclos are defined + // 先执行形参声明(确保 scope 中有位置) params?.forEach((param: any) => { this.processInstruction(fscope, param, new_state) }) - const size = Math.min(argvalues.length, params.length) - let hasVariadicElement = false - if ( - argvalues.length > size && - ((Config.language !== 'js' && Config.language !== 'javascript') || - params[params.length - 1]?._meta.isRestElement) - ) { - hasVariadicElement = true - } - for (let i = 0; i < size; i++) { - const param = params[i] - let val - const paramName = param.id?.name - if (i === size - 1 && hasVariadicElement) { - // variadic parameter processing - const rest_argvalues = argvalues.slice(i) - const rest_val: any = {} - rest_argvalues.forEach((element: any, index: any) => { - rest_val[index.toString()] = element + // 遍历 boundCall.params 绑定实参到形参 + for (const boundParam of activeBoundCall?.params || []) { + if (!boundParam?.provided) continue + const param = params[boundParam.index] + const paramName = param?.id?.name + if (!paramName) continue + let val = boundParam.value + + // vararg(*args / rest parameter)→ 收集为 ObjectValue + if (Array.isArray(val) && this.getParamKind(param) === 'vararg') { + const restVal: any = {} + val.forEach((element: any, index: number) => { + restVal[index.toString()] = element }) - - val = ObjectValue({ - id: paramName, - field: rest_val, + val = new ObjectValue(fscope.qid, { + sid: paramName, + field: restVal, + }) + } else if ( + val && + !Array.isArray(val) && + this.getParamKind(param) === 'varkw' && + typeof val === 'object' && + !val.vtype + ) { + // varkw(**kwargs)→ 收集为 ObjectValue + val = new ObjectValue(fscope.qid, { + sid: paramName, + field: val, }) - } else { - if (!paramName) continue // unused parameters - - let index = i - if (node.names && node.names.length > 0) { - // handle named argument values like "f({value: 2, key: 3})" - const k = node.names.indexOf(param.name) - if (k !== -1) index = k - } - // if (DEBUG) logger.info('write arg:' + formatNode(param) + ' = ' + formatNode(argvalues[i])); - val = argvalues[index] } - // add source line information + // SourceLine 信息 if (param.loc && oldThisFClos && node.type !== 'FunctionDefinition') { val = SourceLine.addSrcLineInfo(val, node, node.loc && node.loc.sourcefile, 'CALL: ', fname) const fdeclParam = Array.isArray(fdecl.parameters) ? fdecl.parameters[0] : fdecl.parameters - if (fdeclParam.loc.end.line === param.loc.end.line) + if (fdeclParam.loc.end?.line === param.loc.end?.line) val = SourceLine.addSrcLineInfo(val, fdeclParam, fdeclParam.loc.sourcefile, 'ARG PASS: ', paramName) else val = SourceLine.addSrcLineInfo(val, param, param.loc && param.loc.sourcefile, 'ARG PASS: ', paramName) } @@ -2642,15 +3539,14 @@ class Analyzer extends MemSpace { }) } - // argument passing this.saveVarInCurrentScope(fscope, param, val, new_state) } - // make sure all parameters in fclos are defined + // 未绑定的形参初始化为 UndefinedValue params?.forEach((param: any) => { const val = this._getMemberValueDirect(fscope, param.id, state, false, 0, new Set()) if (!val) { - this.saveVarInCurrentScope(fscope, param.id, UndefinedValue(), state) + this.saveVarInCurrentScope(fscope, param.id, new UndefinedValue(), state) } }) @@ -2663,13 +3559,13 @@ class Analyzer extends MemSpace { node.callee.object, node.callee.object.loc.sourcefile, 'ARG PASS: ', - node.callee.object.name + node.callee.object.name || AstUtil.prettyPrintAST(node.callee.object).slice(0, 50) ) } // return parameters if (fdecl.returnParameters) { - const val_0 = PrimitiveValue({ type: 'Literal', value: 0, loc: fdecl.returnParameters.loc }) + const val_0 = new PrimitiveValue(scope.qid, '', 0, null, 'Literal', fdecl.returnParameters.loc) const paras = Array.isArray(fdecl.returnParameters) ? fdecl.returnParameters : fdecl.returnParameters.parameters if (paras) { for (const param of paras) { @@ -2684,12 +3580,25 @@ class Analyzer extends MemSpace { const oldReturnValue = this.lastReturnValue this.lastReturnValue = undefined this.processInstruction(fscope, fdecl.body, new_state) - // if (this.lastReturnValue) { // for the source line trace - // const dataflow = 'RETURN:'; // size ? 'RETURN: ' : null; - // this.lastReturnValue = SourceLine.addSrcLineInfo(this.lastReturnValue, node, node.loc && node.loc.sourcefile, dataflow); - // } - // return_value = return_value || UndefinedValue(); - return_value = this.lastReturnValue || UndefinedValue() + + // Java lambda 表达式体隐式返回值:匿名函数的 ScopedStatement 无 ReturnStatement 时,取最后一个表达式的值 + if ( + !this.lastReturnValue && + Config.language === 'java' && + fdecl.body?.type === 'ScopedStatement' && + fname?.includes(' 0) { + const lastStmt = stmts[stmts.length - 1] + const hasReturn = stmts.some((s: any) => s.type === 'ReturnStatement') + if (!hasReturn && lastStmt.type !== 'ReturnStatement') { + this.lastReturnValue = this.processInstruction(fscope, lastStmt, new_state) + } + } + } + + return_value = this.lastReturnValue || new UndefinedValue() this.lastReturnValue = oldReturnValue const tag = 'CALL RETURN:' // size ? 'RETURN: ' : null; @@ -2697,7 +3606,7 @@ class Analyzer extends MemSpace { } // post-call processing - delete fclos.value[fscope.id] + delete fclos.value[fscope.sid] // this.setCurrentFunction(old_function); this.thisFClos = oldThisFClos @@ -2734,15 +3643,16 @@ class Analyzer extends MemSpace { if (same_args) argvalues = call.arguments } - const { fdef } = fclos + const { fdef } = fclos.ast // if (analysisutil.isInCallStack(fdef, state.callstack)) return; - const obj = this.buildNewObject(fdef, argvalues, fclos, state, node, scope) + const newCallInfo: CallInfo = { callArgs: this.buildCallArgs(node, argvalues, fclos) } + const obj = this.buildNewObject(fdef, fclos, state, node, scope, newCallInfo) if (logger.isTraceEnabled()) logger.trace(`new expression: ${this.formatScope(obj)}`) if (obj && this.checkerManager?.checkAtNewExprAfter) { this.checkerManager.checkAtNewExprAfter(this, scope, node, state, { - argvalues, + callInfo: newCallInfo, fclos, ret: obj, pcond: state.pcond, @@ -2764,44 +3674,35 @@ class Analyzer extends MemSpace { * @param scope * @returns {*} */ - buildNewObject(fdef: any, argvalues: any, fclos: any, state: any, node: any, scope: any) { - let obj - // clone the basic class object - obj = ObjectValue(fclos) - obj.reset() - obj.vtype = 'object' - obj.value = {} - obj.id = `${obj.sid}` - obj.qid += '' - obj._this = obj - if (obj.parent?.sid === '') { - obj.parent = scope - } - if (typeof fclos.value === 'object') { - for (const x in fclos.value) { - const v = fclos.value[x] - if (!v) continue - const v_copy = cloneWithDepth(v) - obj.value[x] = v_copy - // if (v.vtype !== 'fclos') { // can reuse function definitions - // } - if (typeof v_copy === 'object') { - v_copy._this = obj - v_copy.parent = obj - } - } + buildNewObject(fdef: any, fclos: any, state: State, node: any, scope: any, callInfo: CallInfo) { + const argvalues = getLegacyArgValues(callInfo) + if (Config.miniSaveContextEnvironment) { + return new UndefinedValue() } - if (_.isFunction(fclos.execute)) { - fclos.execute.call(this, obj, argvalues, state, node, scope) + const obj = buildNewValueInstance( + this, + fclos, + node, + scope, + () => { + return false + }, + (v: any) => { + return !v + }, + 1, + '', + 'object' + ) + + if (_.isFunction(fclos.runtime?.execute)) { + fclos.runtime!.execute!.call(this, obj, argvalues, state, node, scope) } if (!argvalues) return obj if (!fdef) { - if (logger.isTraceEnabled()) - logger.trace(`processNewObject: definition not found: ${ValueFormatter.formatNode(fclos)}`) - // function definition not found, examine possible call-back functions in the arguments if (Config.invokeCallbackOnUnknownFunction) { this.executeFunctionInArguments(scope, fclos, node, argvalues, state) @@ -2823,7 +3724,7 @@ class Analyzer extends MemSpace { body = fdef.properties break case 'FunctionDefinition': - fclos.vtype = 'class' + fclos._isConstructor = true // fall through case 'ClassDefinition': default: @@ -2839,7 +3740,9 @@ class Analyzer extends MemSpace { let ctorClos switch (fdef.type) { case 'StructDefinition': - paras = fdef.members.map((x: any) => SymbolValue({ type: 'Parameter', name: x.name, loc: x.loc })) + paras = fdef.members.map( + (x: any) => new SymbolValue(obj.qid, { sid: x.name, type: 'Parameter', name: x.name, loc: x.loc }) + ) break // for javascript, ctor is itself case 'FunctionDefinition': @@ -2874,7 +3777,13 @@ class Analyzer extends MemSpace { let val = argvalues[index] // add source line information if (param.loc) { - val = SourceLine.addSrcLineInfo(val, node, param.loc.sourcefile, 'CTOR ARG PASS: ', param.name) + val = SourceLine.addSrcLineInfo( + val, + node, + param.loc.sourcefile, + 'CTOR ARG PASS: ', + param.name || AstUtil.prettyPrint(param).slice(0, 50) + ) } if (fdef.type === 'StructDefinition') { @@ -2886,7 +3795,7 @@ class Analyzer extends MemSpace { if (ctorClos) { if (this.checkerManager && this.checkerManager.checkAtNewObject) { this.checkerManager.checkAtNewObject(this, scope, fdef, state, { - argvalues, + callInfo, state, fclos: ctorClos, ainfo: this.ainfo, @@ -2895,7 +3804,7 @@ class Analyzer extends MemSpace { const oldThisFClos = this.thisFClos this.thisFClos = obj ctorClos._this = obj - this.executeCall(node, ctorClos, argvalues, state, scope) + this.executeCall(node, ctorClos, state, scope, callInfo) this.thisFClos = oldThisFClos } @@ -2916,16 +3825,31 @@ class Analyzer extends MemSpace { */ executeFunctionInArguments(scope: any, caller: any, callsite_node: any, argvalues: any, state: any) { const needInvoke = Config.invokeCallbackOnUnknownFunction - if (needInvoke !== 1 && needInvoke !== 2) return UndefinedValue() + if (needInvoke !== 1 && needInvoke !== 2) return new UndefinedValue() for (let i = 0; i < argvalues.length; i++) { const arg = argvalues[i] if (arg && arg.vtype === 'fclos') { - const fclos = _.clone(arg) + const fclos = lodashCloneWithTag(arg) const new_state = _.clone(state) new_state.parent = state new_state.callstack = state.callstack ? state.callstack.concat([caller]) : [caller] - this.executeCall(callsite_node, fclos, [], new_state, scope) + new_state.callsites = state.callsites + ? state.callsites.concat([ + { + code: AstUtil.getRawCode(callsite_node).slice(0, 100), + nodeHash: callsite_node._meta?.nodehash, + loc: callsite_node.loc, + }, + ]) + : [ + { + code: AstUtil.getRawCode(callsite_node).slice(0, 100), + nodeHash: callsite_node._meta?.nodehash, + loc: callsite_node.loc, + }, + ] + this.executeCall(callsite_node, fclos, new_state, scope, INTERNAL_CALL) } } } @@ -2983,7 +3907,7 @@ class Analyzer extends MemSpace { // }; resolveClassInheritance(fclos: any, state: any) { - const { fdef } = fclos + const { fdef } = fclos.ast const { supers } = fdef if (!supers || supers.length === 0) return @@ -3001,13 +3925,13 @@ class Analyzer extends MemSpace { * @param superId */ function _resolveClassInheritance(this: any, fclos: any, superId: any) { - if (fclos?.id === superId?.name) { + if (fclos?.sid === superId?.name) { // to avoid self-referencing return } const superClos = this.processInstruction(scope, superId, state) // const superClos = this.getMemberValue(scope, superId, state); - if (!superClos) return UndefinedValue() + if (!superClos) return new UndefinedValue() fclos.super = superClos // inherit definitions @@ -3018,28 +3942,32 @@ class Analyzer extends MemSpace { for (const fieldName in superClos.value) { if (fieldName === 'super') continue const v = superClos.value[fieldName] - if (v.readonly) continue - const v_copy = _.clone(v) - v_copy.inherited = true - v_copy._this = fclos - v_copy._base = superClos - fclos.value[fieldName] = v_copy - - superValue.value[fieldName] = v_copy - // super fclos should fill its fdef with ctor definition - if (fieldName === '_CTOR_') { - superValue.fdef = v_copy.fdef - superValue.overloaded = superValue.overloaded || [] - superValue.overloaded.push(fdef) + if (v.runtime?.readonly) continue + // const v_copy = _.clone(v) + const v_copy = lodashCloneWithTag(v) + if (v_copy) { + if (!v_copy.func) v_copy.func = {} + v_copy.func.inherited = true + v_copy._this = fclos + v_copy._base = superClos + fclos.value[fieldName] = v_copy + + superValue.value[fieldName] = v_copy + if (fieldName === '_CTOR_') { + superValue.ast.node = v_copy.ast.fdef + superValue.ast.fdef = v_copy.ast.fdef + superValue.overloaded = superValue.overloaded || [] + superValue.overloaded.push(fdef) + } } // v_copy.parent = fclos; // Important! } // inherit declarations - for (const x in superClos.decls) { - const v = superClos.decls[x] - fclos.decls[x] = v + for (const x of superClos.ast.declKeys) { + const v = superClos.ast.getDecl(x) + fclos.ast.setDecl(x, v) } // inherit modifiers for (const x in superClos.modifier) { @@ -3088,6 +4016,9 @@ class Analyzer extends MemSpace { const fields = rightVal.getRawValue() for (const key in fields) { // 过滤原型链 + if (typeof key === 'string' && key.includes('__yasa')) { + continue + } if (typeof fields.hasOwnProperty === 'function' && fields.hasOwnProperty(key)) { if (!filter) yield { k: key, v: fields[key] } else if (filter(fields[key])) yield { k: key, v: fields[key] } @@ -3124,6 +4055,80 @@ class Analyzer extends MemSpace { } return ruleArray } + + /** + * load lib arg to this sid blacklist keywords + */ + loadLibArgToThisSidBlacklistKeywords() { + if (Array.isArray(this.libArgToThisSidBlacklistKeywords)) { + return this.libArgToThisSidBlacklistKeywords + } + + let sidKeywordArray: any[] = [] + try { + const rulePath = getAbsolutePath('resource/tag-propagation/lib-arg-to-this-sid-blacklist.json') + const ruleData = loadJSONfile(rulePath) + if (Array.isArray(ruleData?.sidKeywords)) { + sidKeywordArray = ruleData.sidKeywords + } else if (Array.isArray(ruleData?.keywords)) { + sidKeywordArray = ruleData.keywords + } + } catch (e) { + return [] + } + + return sidKeywordArray.filter((item) => typeof item === 'string' && item.trim().length > 0) + } + + /** + * find matched rule by CallGraph + * @param node + * @param scope + * @param sinkRules + */ + findMatchedRuleByCallGraph(node: any, scope: any, sinkRules: any[]) { + const resultArray: any[] = [] + + if (!node || !scope || !sinkRules || !this.findNodeInvocations) { + return resultArray + } + + const invocations: Invocation[] = this.findNodeInvocations(scope, node) + if (!invocations) { + return resultArray + } + + for (const invocation of invocations) { + for (const sink of sinkRules) { + const matchSink: boolean = checkInvocationMatchSink(invocation, sink, this.typeResolver) + if (matchSink) { + resultArray.push(sink) + } + } + } + + return resultArray + } + + /** + * output all the findings of all registered checker + * @param {any} printf - Print function for output + */ + async outputAnalyzerExistResult(printf?: any) { + let allFindings = null + const { resultManager } = this.getCheckerManager() + if (resultManager && Config.reportDir) { + const outputStrategyAutoRegister = new OutputStrategyAutoRegister() + outputStrategyAutoRegister.autoRegisterAllStrategies() + allFindings = resultManager.getFindings() + for (const outputStrategyId in allFindings) { + const strategy = outputStrategyAutoRegister.getStrategy(outputStrategyId) + if (strategy && typeof strategy.outputFindings === 'function') { + strategy.outputFindings(resultManager, strategy.getOutputFilePath(), Config, printf) + } + } + } + } } /** @@ -3137,3 +4142,4 @@ function needCompileFirst(type: any) { //* ******************************************* module.exports = Analyzer +export { Analyzer } diff --git a/src/engine/analyzer/common/ast-manager.ts b/src/engine/analyzer/common/ast-manager.ts new file mode 100644 index 00000000..26bb403e --- /dev/null +++ b/src/engine/analyzer/common/ast-manager.ts @@ -0,0 +1,107 @@ +const UastSpec = require('@ant-yasa/uast-spec') + +/** + * AST 管理器:使用 nodehash 作为 key 管理 AST 对象,避免重复存储 + * 用于降低内存占用,Unit 对象中只存储 AST 的 nodehash,而不是完整的 AST 对象 + */ +class ASTManager { + private astMap: Map + + /** + * + */ + constructor() { + this.astMap = new Map() + } + + /** + * 注册 AST 节点并返回其 nodehash + * 如果 AST 节点已有 nodehash,则直接返回;否则生成一个 Mock nodehash + * @param ast AST 节点对象 + * @returns AST 节点的 nodehash + */ + register(ast: any): string | null { + if (!ast) { + return null + } + if (typeof ast === 'string') { + ast = UastSpec.identifier(ast) + } + // 确保 _meta 对象存在 + if (!ast._meta) { + ast._meta = {} + } + + // 获取 nodehash + let { nodehash } = ast._meta + if (!nodehash) { + // 如果没有 nodehash,生成一个 Mock nodehash + const random = Math.random().toString(36).substring(2, 15) + Math.random().toString(36).substring(2, 15) + nodehash = `` + ast._meta.nodehash = nodehash + } + + // 注册到 Map(如果已存在则覆盖,确保使用最新的 AST 对象) + this.astMap.set(nodehash, ast) + + return nodehash + } + + /** + * 根据 nodehash 获取 AST 节点 + * @param nodehash AST 节点的 nodehash + * @returns AST 节点对象,如果不存在则返回 null + */ + get(nodehash: string | null | undefined): any { + if (!nodehash) { + return null + } + return this.astMap.get(nodehash) || null + } + + /** + * 检查 nodehash 是否存在 + * @param nodehash AST 节点的 nodehash + * @returns 是否存在 + */ + has(nodehash: string | null | undefined): boolean { + if (!nodehash) { + return false + } + return this.astMap.has(nodehash) + } + + /** + * 删除 AST 节点(通常不需要,但提供清理功能) + * @param nodehash AST 节点的 nodehash + */ + delete(nodehash: string | null | undefined): void { + if (nodehash) { + this.astMap.delete(nodehash) + } + } + + /** + * 清空所有 AST 节点 + */ + clear(): void { + this.astMap.clear() + } + + /** + * 获取已注册的 AST 节点数量 + * @returns 节点数量 + */ + size(): number { + return this.astMap.size + } + + /** + * 获取 astMap + */ + getMap(): Map { + return this.astMap + } +} + +module.exports = ASTManager diff --git a/src/engine/analyzer/common/ast-visitor.ts b/src/engine/analyzer/common/ast-visitor.ts new file mode 100644 index 00000000..e2fbfbf3 --- /dev/null +++ b/src/engine/analyzer/common/ast-visitor.ts @@ -0,0 +1,16 @@ +/** + * find inner FunctionDefinition + */ +export class InnerFuncDefVisitor { + matchFuncDefCount = 0 + + /** + * visit FunctionDefinition + * @param node + * @constructor + */ + FunctionDefinition(node: any) { + this.matchFuncDefCount += 1 + return this.matchFuncDefCount <= 1 + } +} diff --git a/src/engine/analyzer/common/base-analyzer.ts b/src/engine/analyzer/common/base-analyzer.ts new file mode 100644 index 00000000..25f1ac0b --- /dev/null +++ b/src/engine/analyzer/common/base-analyzer.ts @@ -0,0 +1,137 @@ +/** + * BaseAnalyzer 抽象类 + * + * 定义所有 Analyzer 必须实现的核心方法签名 + * 所有语言特定的 Analyzer (JsAnalyzer, JavaAnalyzer, PythonAnalyzer, GoAnalyzer) 必须继承此类 + * + * 方法分类: + * - 核心方法 (2个): processInstruction, processCompileUnit + * - Expr 方法 (21个): 处理所有表达式节点 + * - Stmt 方法 (14个): 处理所有语句节点 + * - Decl 方法 (3个): 处理所有声明节点 + * + * @see .cursor/rules/analyzer-architecture.mdc + */ + +import type { + Node, + // 6大分类 + Stmt, + Expr, + Decl, + // CompileUnit + CompileUnit, + // Expr 节点 (21个) + Literal, + Identifier, + BinaryExpression, + UnaryExpression, + AssignmentExpression, + ConditionalExpression, + CallExpression, + NewExpression, + MemberAccess, + SliceExpression, + CastExpression, + ImportExpression, + YieldExpression, + TupleExpression, + ObjectExpression, + SpreadElement, + Sequence, + DereferenceExpression, + ReferenceExpression, + ThisExpression, + SuperExpression, + // Stmt 节点 (14个) + Noop, + IfStatement, + SwitchStatement, + ForStatement, + WhileStatement, + RangeStatement, + BreakStatement, + ContinueStatement, + ReturnStatement, + ThrowStatement, + ScopedStatement, + TryStatement, + ExpressionStatement, + ExportStatement, + // Decl 节点 (3个) + FunctionDefinition, + ClassDefinition, + VariableDeclaration, +} from '../../../types/uast' + +import type { Scope, State, Value, SymbolValue, VoidValue, SpreadValue, BinaryExprValue, UnaryExprValue } from '../../../types/analyzer' + +const MemSpace = require('./memSpace') + +/** + * BaseAnalyzer 抽象基类 + * + * 定义所有 Analyzer 必须实现的方法签名 + * 每个方法接收 (scope, node, state) 三个参数,返回 Value + */ +export abstract class BaseAnalyzer extends MemSpace { + // ===== 核心方法 (2个) ===== + + /** + * 处理任意指令节点 (Stmt | Expr | Decl) + * 根据节点类型分发到对应的 process 方法 + */ + abstract processInstruction(scope: Scope, node: Stmt | Expr | Decl, state: State): Value + + /** + * 处理编译单元(程序入口) + */ + abstract processCompileUnit(scope: Scope, node: CompileUnit, state: State): Value + + // ===== Expr 方法 (21个) ===== + + abstract processLiteral(scope: Scope, node: Literal, state: State): SymbolValue + abstract processIdentifier(scope: Scope, node: Identifier, state: State): SymbolValue + abstract processBinaryExpression(scope: Scope, node: BinaryExpression, state: State): BinaryExprValue + abstract processUnaryExpression(scope: Scope, node: UnaryExpression, state: State): UnaryExprValue + abstract processAssignmentExpression(scope: Scope, node: AssignmentExpression, state: State): SymbolValue + abstract processConditionalExpression(scope: Scope, node: ConditionalExpression, state: State): SymbolValue + abstract processCallExpression(scope: Scope, node: CallExpression, state: State): SymbolValue + abstract processNewExpression(scope: Scope, node: NewExpression, state: State): SymbolValue + abstract processMemberAccess(scope: Scope, node: MemberAccess, state: State): SymbolValue + abstract processSliceExpression(scope: Scope, node: SliceExpression, state: State): SymbolValue + abstract processCastExpression(scope: Scope, node: CastExpression, state: State): SymbolValue + abstract processImportExpression(scope: Scope, node: ImportExpression, state: State): SymbolValue + abstract processYieldExpression(scope: Scope, node: YieldExpression, state: State): VoidValue + abstract processTupleExpression(scope: Scope, node: TupleExpression, state: State): SymbolValue + abstract processObjectExpression(scope: Scope, node: ObjectExpression, state: State): SymbolValue + abstract processSpreadElement(scope: Scope, node: SpreadElement, state: State): SpreadValue + abstract processSequence(scope: Scope, node: Sequence, state: State): SymbolValue + abstract processDereferenceExpression(scope: Scope, node: DereferenceExpression, state: State): SymbolValue + abstract processReferenceExpression(scope: Scope, node: ReferenceExpression, state: State): SymbolValue + abstract processThisExpression(scope: Scope, node: ThisExpression, state: State): SymbolValue + abstract processSuperExpression(scope: Scope, node: SuperExpression, state: State): SymbolValue + + // ===== Stmt 方法 (14个) - 返回 VoidValue(预期无返回值) ===== + + abstract processNoop(scope: Scope, node: Noop, state: State): VoidValue + abstract processIfStatement(scope: Scope, node: IfStatement, state: State): VoidValue + abstract processSwitchStatement(scope: Scope, node: SwitchStatement, state: State): VoidValue + abstract processForStatement(scope: Scope, node: ForStatement, state: State): VoidValue + abstract processWhileStatement(scope: Scope, node: WhileStatement, state: State): VoidValue + abstract processRangeStatement(scope: Scope, node: RangeStatement, state: State): VoidValue + abstract processBreakStatement(scope: Scope, node: BreakStatement, state: State): VoidValue + abstract processContinueStatement(scope: Scope, node: ContinueStatement, state: State): VoidValue + abstract processReturnStatement(scope: Scope, node: ReturnStatement, state: State): VoidValue + abstract processThrowStatement(scope: Scope, node: ThrowStatement, state: State): VoidValue + abstract processScopedStatement(scope: Scope, node: ScopedStatement, state: State): VoidValue + abstract processTryStatement(scope: Scope, node: TryStatement, state: State): VoidValue + abstract processExpressionStatement(scope: Scope, node: ExpressionStatement, state: State): VoidValue + abstract processExportStatement(scope: Scope, node: ExportStatement, state: State): VoidValue + + // ===== Decl 方法 (3个) ===== + + abstract processFunctionDefinition(scope: Scope, node: FunctionDefinition, state: State): SymbolValue + abstract processClassDefinition(scope: Scope, node: ClassDefinition, state: State): SymbolValue + abstract processVariableDeclaration(scope: Scope, node: VariableDeclaration, state: State): SymbolValue +} diff --git a/src/engine/analyzer/common/call-args.ts b/src/engine/analyzer/common/call-args.ts new file mode 100644 index 00000000..2707174c --- /dev/null +++ b/src/engine/analyzer/common/call-args.ts @@ -0,0 +1,95 @@ +/** + * Call argument types and utility functions for structured call info. + * + * CallArgs: call-site view — records each argument's kind/name/value + * BoundCall: declaration-side view — binds arguments to parameters + * CallInfo: container passed through the call chain + */ + +export type CallArgKind = 'positional' | 'keyword' | 'spread' | 'kwspread' + +export interface CallArg { + index: number // original position in node.arguments + value: any // evaluated result + node?: any // AST node (for SourceLine) + name?: string // keyword name (keyword/kwspread only) + kind: CallArgKind +} + +export interface CallArgs { + receiver?: any // MemberAccess thisObj + args: CallArg[] +} + +export interface BoundParam { + index: number + name: string + value?: any + provided: boolean + argIndexes: number[] +} + +export interface BoundCall { + receiver?: any + params: BoundParam[] +} + +export interface CallInfo { + callArgs?: CallArgs + boundCall?: BoundCall +} + +/** + * Info object passed from analyzer to checkers via checkAtFunctionCallBefore/After. + * Unifies the `info: any` parameter in all triggerAtFunctionCall* methods. + */ +export interface FunctionCallInfo { + callInfo: CallInfo | undefined + fclos: any + ret?: any + pcond?: any[] + entry_fclos?: any + einfo?: any + ainfo?: any + [key: string]: any +} + +/** analyzer 主动触发的函数执行(无真实调用方、无参数) */ +export const INTERNAL_CALL: CallInfo = { callArgs: { args: [] } } + +/** + * Extract legacy argvalues array from callInfo for backward compatibility. + * Returns the values of all call args, or an empty array if callInfo is undefined. + */ +export function getLegacyArgValues(callInfo: CallInfo | undefined): any[] { + if (!callInfo) return [] + const callArgs = callInfo.callArgs + if (!callArgs) return [] + return callArgs.args.map((a: CallArg) => a.value) +} + +/** + * Get the count of explicit (non-spread) arguments. + */ +export function getExplicitArgCount(callInfo: CallInfo | undefined): number { + if (!callInfo) return 0 + const callArgs = callInfo.callArgs + if (!callArgs) return 0 + return callArgs.args.filter((a: CallArg) => a.kind !== 'spread' && a.kind !== 'kwspread').length +} + +/** + * Extract CallArgs from a CallInfo object. + */ +export function getCallArgsFromInfo(callInfo: CallInfo | undefined): CallArgs | undefined { + if (!callInfo) return undefined + return callInfo.callArgs +} + +/** + * Extract BoundCall from a CallInfo object. + */ +export function getBoundCallFromInfo(callInfo: CallInfo | undefined): BoundCall | undefined { + if (!callInfo) return undefined + return callInfo.boundCall +} diff --git a/src/engine/analyzer/common/checker-manager.ts b/src/engine/analyzer/common/checker-manager.ts index 2d8d98ac..80fde6b3 100644 --- a/src/engine/analyzer/common/checker-manager.ts +++ b/src/engine/analyzer/common/checker-manager.ts @@ -1,11 +1,12 @@ const fs = require('fs') const path = require('path') const logger = require('../../../util/logger')(__filename) -const statistics = require('../../../util/statistics') +const statistics: { numChecks: number; checkFiringTime: number } = require('../../../util/statistics') const checkerKit = require('../../../checker/common/checker-kit') const ResultManager = require('./result-manager') const { getAbsolutePath, loadJSONfile, isPkgEnv } = require('../../../util/file-util') const { handleException } = require('./exception-handler') +const { yasaLog } = require('../../../util/format-util') /** * Smart checker path resolution: prioritize src/.ts, then dist/.js @@ -28,8 +29,6 @@ function resolveCheckerPath(checkerPath: string): string { } } - logger.info(`resolveCheckerPath projectRoot : ${projectRoot}`) - // 优先加载dist/.js const distJsPath = path.join(projectRoot, 'dist', checkerPath.replace(/\.ts$/, '.js')) if (fs.existsSync(distJsPath)) { @@ -111,7 +110,6 @@ class CheckerManager { if (!this.options) return const { yasaSeparator } = require('../../../util/format-util') - yasaSeparator('Register rules') try { this.kit = checkerKit this.resultManager = resultManager || new ResultManager() @@ -145,9 +143,10 @@ class CheckerManager { } } for (let i = 0; i < targetCheckerPaths.length; i++) { + const checkerId = targetCheckerIds[i] let targetCheckerPath = targetCheckerPaths[i] targetCheckerPath = resolveCheckerPath(targetCheckerPath) - logger.info(`Resolved checker path :${targetCheckerPath}`) + yasaLog(`Loading checker: ${checkerId} from ${targetCheckerPath}`, 'init') const targetCheckerDesc = targetCheckerDescs[i] const checkerNames = this.registerAllCheckers(this, targetCheckerPath, targetCheckerDesc, this.resultManager) if (checkerNames) { @@ -158,12 +157,11 @@ class CheckerManager { } } } - logger.info('load checkers:', loadCheckerNames) + const checkerCount = loadCheckerNames.length + yasaLog(`Successfully loaded ${checkerCount} checker(s): [${loadCheckerNames.join(', ')}]`, 'init') } catch (e) { handleException(e, 'Error occurred in CheckerManager_ctor', 'Error occurred in CheckerManager_ctor') } - - yasaSeparator('') } /** @@ -195,11 +193,11 @@ class CheckerManager { `Error occured in:${check_at_start_analyze[i].getCheckerId()}.triggerAtStartOfAnalyze! Stack detail has been logged in error log!` ) } - ;(statistics as any).numChecks++ + statistics.numChecks++ } } - const end_time = (new Date() as any).getTime() as number - ;(statistics as any).checkFiringTime += end_time - start_time + const end_time = new Date().getTime() + statistics.checkFiringTime += end_time - start_time } /** @@ -225,12 +223,12 @@ class CheckerManager { `Error occured in:${check_at_end_analyze[i].getCheckerId()}.triggerAtEndOfAnalyze! Stack detail has been logged in error log!` ) } - ;(statistics as any).numChecks++ + statistics.numChecks++ } } - const end_time = (new Date() as any).getTime() as number - ;(statistics as any).checkFiringTime += end_time - start_time + const end_time = new Date().getTime() + statistics.checkFiringTime += end_time - start_time } /** @@ -257,11 +255,11 @@ class CheckerManager { `Error occured in:${check_at_compile_unit[i].getCheckerId()}.triggerAtCompileUnit! Stack detail has been logged in error log!` ) } - ;(statistics as any).numChecks++ + statistics.numChecks++ } } - const end_time = (new Date() as any).getTime() as number - ;(statistics as any).checkFiringTime += end_time - start_time + const end_time = new Date().getTime() + statistics.checkFiringTime += end_time - start_time return interruptFlag } @@ -287,11 +285,11 @@ class CheckerManager { `Error occured in:${check_at_end_compileunit[i].getCheckerId()}.triggerAtEndOfCompileUnit! Stack detail has been logged in error log!` ) } - ;(statistics as any).numChecks++ + statistics.numChecks++ } } - const end_time = (new Date() as any).getTime() as number - ;(statistics as any).checkFiringTime += end_time - start_time + const end_time = new Date().getTime() + statistics.checkFiringTime += end_time - start_time } /** @@ -316,11 +314,11 @@ class CheckerManager { `Error occured in:${check_at_binary_operation[i].getCheckerId()}.checkAtBinaryOperation! Stack detail has been logged in error log!` ) } - ;(statistics as any).numChecks++ + statistics.numChecks++ } } - const end_time = (new Date() as any).getTime() as number - ;(statistics as any).checkFiringTime += end_time - start_time + const end_time = new Date().getTime() + statistics.checkFiringTime += end_time - start_time } /** @@ -346,11 +344,11 @@ class CheckerManager { `Error occured in:${check_at_pre_declaration[i].getCheckerId()}.triggerAtPreDeclaration! Stack detail has been logged in error log!` ) } - ;(statistics as any).numChecks++ + statistics.numChecks++ } } - const end_time = (new Date() as any).getTime() as number - ;(statistics as any).checkFiringTime += end_time - start_time + const end_time = new Date().getTime() + statistics.checkFiringTime += end_time - start_time } /** @@ -376,12 +374,12 @@ class CheckerManager { `Error occured in:${check_at_funccall_syntax[i].getCheckerId()}.triggerAtFuncCallSyntax! Stack detail has been logged in error log!` ) } - ;(statistics as any).numChecks++ + statistics.numChecks++ } } - const end_time = (new Date() as any).getTime() as number - ;(statistics as any).checkFiringTime += end_time - start_time + const end_time = new Date().getTime() + statistics.checkFiringTime += end_time - start_time } /** @@ -418,12 +416,12 @@ class CheckerManager { `Error occured in:${check_at_function_call_before[i].getCheckerId()}.triggerAtFunctionCallBefore! Stack detail has been logged in error log!` ) } - ;(statistics as any).numChecks++ + statistics.numChecks++ } } - const end_time = (new Date() as any).getTime() as number - ;(statistics as any).checkFiringTime += end_time - start_time + const end_time = new Date().getTime() + statistics.checkFiringTime += end_time - start_time } /** @@ -450,12 +448,12 @@ class CheckerManager { `Error occured in:${check_at_function_call_after[i].getCheckerId()}.triggerAtFunctionCallAfter! Stack detail has been logged in error log!` ) } - ;(statistics as any).numChecks++ + statistics.numChecks++ } } - const end_time = (new Date() as any).getTime() as number - ;(statistics as any).checkFiringTime += end_time - start_time + const end_time = new Date().getTime() + statistics.checkFiringTime += end_time - start_time } /** @@ -481,12 +479,12 @@ class CheckerManager { `Error occured in:${check_new_expr[i].getCheckerId()}.triggerAtNewExpr! Stack detail has been logged in error log!` ) } - ;(statistics as any).numChecks++ + statistics.numChecks++ } } - const end_time = (new Date() as any).getTime() as number - ;(statistics as any).checkFiringTime += end_time - start_time + const end_time = new Date().getTime() + statistics.checkFiringTime += end_time - start_time } /** @@ -511,11 +509,11 @@ class CheckerManager { `Error occured in:${check_at_new_object[i].getCheckerId()}.triggerAtNewObject! Stack detail has been logged in error log!` ) } - ;(statistics as any).numChecks++ + statistics.numChecks++ } } - const end_time = (new Date() as any).getTime() as number - ;(statistics as any).checkFiringTime += end_time - start_time + const end_time = new Date().getTime() + statistics.checkFiringTime += end_time - start_time } /** @@ -541,12 +539,12 @@ class CheckerManager { `Error occured in:${check_new_expr_after[i].getCheckerId()}.triggerAtNewExprAfter! Stack detail has been logged in error log!` ) } - ;(statistics as any).numChecks++ + statistics.numChecks++ } } - const end_time = (new Date() as any).getTime() as number - ;(statistics as any).checkFiringTime += end_time - start_time + const end_time = new Date().getTime() + statistics.checkFiringTime += end_time - start_time } /** @@ -572,12 +570,12 @@ class CheckerManager { `Error occured in:${check_at_ifcondition[i].getCheckerId()}.triggerAtIfCondition! Stack detail has been logged in error log!` ) } - ;(statistics as any).numChecks++ + statistics.numChecks++ } } - const end_time = (new Date() as any).getTime() as number - ;(statistics as any).checkFiringTime += end_time - start_time + const end_time = new Date().getTime() + statistics.checkFiringTime += end_time - start_time } /** @@ -606,12 +604,12 @@ class CheckerManager { `Error occured in:${check_at_assignment[i].getCheckerId()}.triggerAtAssignment! Stack detail has been logged in error log!` ) } - ;(statistics as any).numChecks++ + statistics.numChecks++ } } - const end_time = (new Date() as any).getTime() as number - ;(statistics as any).checkFiringTime += end_time - start_time + const end_time = new Date().getTime() + statistics.checkFiringTime += end_time - start_time } /** @@ -638,12 +636,12 @@ class CheckerManager { `Error occured in:${check_at_end_block[i].getCheckerId()}.triggerAtEndOfBlock! Stack detail has been logged in error log!` ) } - ;(statistics as any).numChecks++ + statistics.numChecks++ } } - const end_time = (new Date() as any).getTime() as number - ;(statistics as any).checkFiringTime += end_time - start_time + const end_time = new Date().getTime() + statistics.checkFiringTime += end_time - start_time } /** @@ -669,12 +667,12 @@ class CheckerManager { `Error occured in:${check_at_identifier[i].getCheckerId()}.triggerAtIdentifier! Stack detail has been logged in error log!` ) } - ;(statistics as any).numChecks++ + statistics.numChecks++ } } - const end_time = (new Date() as any).getTime() as number - ;(statistics as any).checkFiringTime += end_time - start_time + const end_time = new Date().getTime() + statistics.checkFiringTime += end_time - start_time } /** @@ -700,12 +698,12 @@ class CheckerManager { `Error occured in:${check_at_member_access[i].getCheckerId()}.triggerAtMemberAccess! Stack detail has been logged in error log!` ) } - ;(statistics as any).numChecks++ + statistics.numChecks++ } } - const end_time = (new Date() as any).getTime() as number - ;(statistics as any).checkFiringTime += end_time - start_time + const end_time = new Date().getTime() + statistics.checkFiringTime += end_time - start_time } /** @@ -731,12 +729,12 @@ class CheckerManager { `Error occured in:${check_at_function_definition[i].getCheckerId()}.triggerAtFunctionDefinition! Stack detail has been logged in error log!` ) } - ;(statistics as any).numChecks++ + statistics.numChecks++ } } - const end_time = (new Date() as any).getTime() as number - ;(statistics as any).checkFiringTime += end_time - start_time + const end_time = new Date().getTime() + statistics.checkFiringTime += end_time - start_time } /** @@ -768,12 +766,12 @@ class CheckerManager { `Error occured in:${check_at_symbol_execute_of_entrypoint_before[i].getCheckerId()}.triggerAtSymbolInterpretOfEntryPointBefore! Stack detail has been logged in error log!` ) } - ;(statistics as any).numChecks++ + statistics.numChecks++ } } - const end_time = (new Date() as any).getTime() as number - ;(statistics as any).checkFiringTime += end_time - start_time + const end_time = new Date().getTime() + statistics.checkFiringTime += end_time - start_time } /** @@ -805,12 +803,12 @@ class CheckerManager { `Error occured in:${check_at_symbol_execute_of_entrypoint_after[i].getCheckerId()}.triggerAtSymbolInterpretOfEntryPointAfter! Stack detail has been logged in error log!` ) } - ;(statistics as any).numChecks++ + statistics.numChecks++ } } - const end_time = (new Date() as any).getTime() as number - ;(statistics as any).checkFiringTime += end_time - start_time + const end_time = new Date().getTime() + statistics.checkFiringTime += end_time - start_time } /** @@ -838,8 +836,8 @@ class CheckerManager { } } - const end_time = (new Date() as any).getTime() as number - ;(statistics as any).checkFiringTime += end_time - start_time + const end_time = new Date().getTime() + statistics.checkFiringTime += end_time - start_time } /** @@ -865,12 +863,12 @@ class CheckerManager { `Error occured in:${check_at_end_of_node[i].getCheckerId()}.triggerAtEndOfNode! Stack detail has been logged in error log!` ) } - ;(statistics as any).numChecks++ + statistics.numChecks++ } } - const end_time = (new Date() as any).getTime() as number - ;(statistics as any).checkFiringTime += end_time - start_time + const end_time = new Date().getTime() + statistics.checkFiringTime += end_time - start_time } /** diff --git a/src/engine/analyzer/common/entrypoint.ts b/src/engine/analyzer/common/entrypoint.ts index 03a7efa1..99d4f242 100644 --- a/src/engine/analyzer/common/entrypoint.ts +++ b/src/engine/analyzer/common/entrypoint.ts @@ -9,7 +9,9 @@ export interface EntryPoint { argValues?: any[] entryPointSymVal?: { ast?: { - loc?: any + node?: { + loc?: any + } } [key: string]: any } diff --git a/src/engine/analyzer/common/initializer.ts b/src/engine/analyzer/common/initializer.ts index 6d9fc874..71a155fe 100644 --- a/src/engine/analyzer/common/initializer.ts +++ b/src/engine/analyzer/common/initializer.ts @@ -1,9 +1,11 @@ +import { shallowCopyValue } from '../../../util/clone-util' +import type Unit from './value/unit' + const _ = require('lodash') const Scope = require('./scope') const { ValueUtil: { ObjectValue, PrimitiveValue }, } = require('../../util/value-util') -const { cloneWithDepth } = require('../../../util/clone-util') /** * get the constructor function @@ -18,7 +20,6 @@ function getConstructor(fbody: any, fname: string): any { * @param obj */ function isIterable(obj: any): boolean { - // checks for null and undefined if (obj == null) { return false } @@ -47,10 +48,10 @@ function getConstructor(fbody: any, fname: string): any { * @param res * @param scope */ -function resetInitVariables(scope: any): void { +function resetInitVariables(scope: Unit): void { for (const field of Object.keys(scope.value)) { const v = scope.value[field] - if (v.trace) delete v.trace + if (v.taint) v.taint.clearTrace() } } @@ -62,7 +63,7 @@ function resetInitVariables(scope: any): void { * @param source_fdef * @returns {{vtype: string, id: *, value: {}, ast: null, parent: *}} */ -function initVarScope(scope: any, node: any, should_taint: boolean, source_fdef: any): any { +function initVarScope(scope: Unit, node: any, should_taint: boolean, source_fdef: any): Unit | undefined { if (!node) return switch (node.type) { @@ -85,9 +86,9 @@ function initVarScope(scope: any, node: any, should_taint: boolean, source_fdef: if (!obj || !_.isObject(obj)) obj = Scope.createIdentifierFieldValue(node, scope) if (should_taint) { - obj.taint = new Set() - obj.taint.add('TOD') - obj.hasTagRec = true + obj.taint.clear() + obj.taint.addTag('TOD') + obj.taint?.markSource() if (!obj.hasOwnProperty('source_fdef')) { obj.source_fdef = new Set() } @@ -95,7 +96,10 @@ function initVarScope(scope: any, node: any, should_taint: boolean, source_fdef: if (obj.source_fdef.size < 10) // be defensive obj.source_fdef.add(source_fdef) - if (node.loc) obj.trace = [{ line: node.loc.start.line, node }] + if (node.loc) { + const traceItem = { line: node.loc.start?.line, node } + obj.taint.setAllTraces([traceItem]) + } } return obj } @@ -107,7 +111,7 @@ function initVarScope(scope: any, node: any, should_taint: boolean, source_fdef: * Specifically, delete the existing values * @param scope */ -function havocSharedVariables(scope: any): void { +function havocSharedVariables(scope: Unit): void { const { writes } = scope.fdata if (!writes) return for (const entry of writes.entries()) { @@ -141,12 +145,13 @@ function havocSharedVariables(scope: any): void { * process class inheritance * @param fclos */ -function resolveClassInheritance(fclos: any): void { +function resolveClassInheritance(fclos: Unit): void { const { fdef } = fclos const { supers } = fdef if (!supers || supers.length === 0) return - const scope = fclos.parent + if (!fclos.parent) return + const scope: Unit = fclos.parent for (const i in supers) { if (supers[i]) { @@ -159,7 +164,7 @@ function resolveClassInheritance(fclos: any): void { * @param fclos * @param base_name */ - function _resolveClassInheritance(fclos: any, base_name: any): void { + function _resolveClassInheritance(fclos: Unit, base_name: string): void { const base_fclos = scope.value[base_name] if (!base_fclos) return fclos.super = base_fclos @@ -172,17 +177,18 @@ function resolveClassInheritance(fclos: any): void { for (const fieldName in base_fclos.value) { if (fieldName === 'super') continue const v = base_fclos.value[fieldName] - if (v.readonly) continue - const v_copy = cloneWithDepth(v) - v_copy.inherited = true + if (v.runtime?.readonly) continue + const v_copy = shallowCopyValue(v) + if (!v_copy.func) v_copy.func = {} + v_copy.func.inherited = true v_copy._this = fclos fclos.value[fieldName] = v_copy superValue.value[fieldName] = v_copy // super fclos should fill its fdef with ctor definition if (fieldName === '_CTOR_') { - superValue.fdef = v_copy.fdef - superValue.overloaded = superValue.overloaded || [] + superValue.ast.node = v_copy.ast?.node + superValue.ast.fdef = v_copy.ast.fdef superValue.overloaded.push(fdef) } @@ -190,9 +196,9 @@ function resolveClassInheritance(fclos: any): void { } // inherit declarations - for (const x in base_fclos.decls) { - const v = base_fclos.decls[x] - fclos.decls[x] = v + for (const x of base_fclos.ast.declKeys) { + const v = base_fclos.ast.getDecl(x) + fclos.ast.setDecl(x, v) } // inherit modifiers for (const x in base_fclos.modifier) { diff --git a/src/engine/analyzer/common/memSpace.ts b/src/engine/analyzer/common/memSpace.ts index a801f479..cd1348e7 100644 --- a/src/engine/analyzer/common/memSpace.ts +++ b/src/engine/analyzer/common/memSpace.ts @@ -1,26 +1,19 @@ const _ = require('lodash') const logger = require('../../../util/logger')(__filename) -const typeUtil = require('../../util/type-util') const memState = require('./memState') const Scope = require('./scope') -const nativeResolver = require('./native-resolver') const symAddress = require('./sym-address') -const valueFormatter = require('../../../util/value-formatter') -const { Errors: MemSpaceErrors } = require('../../../util/error-code') +const { Errors } = require('../../../util/error-code') const { - ValueUtil: { - UndefinedValue: MemSpaceUndefinedValue, - ObjectValue: MemSpaceObjectValue, - PrimitiveValue: MemSpacePrimitiveValue, - UnionValue: MemSpaceUnionValue, - SymbolValue: MemSpaceSymbolValue, - }, - Unit: MemSpaceUnit, - ValueUtil: MemSpaceValueUtil, + ValueUtil: { UndefinedValue, ObjectValue, PrimitiveValue, UnionValue, SymbolValue, MemberExprValue, IdentifierRefValue }, + Unit, } = require('../../util/value-util') -const MemSpaceAstUtil = require('../../../util/ast-util') -const memSpaceVarUtil = require('../../../util/variable-util') -const { handleException: memSpaceHandleException } = require('./exception-handler') +const AstUtil = require('../../../util/ast-util') +const varUtil = require('../../../util/variable-util') +const { handleException } = require('./exception-handler') + +import type UnitType from './value/unit' +type FilterFn = ((scope: UnitType) => boolean) | null // *** /** @@ -33,13 +26,13 @@ class MemSpace extends Scope { * @param ids * @param createIfNotExists */ - getFieldValue(unit: any, ids: any, createIfNotExists?: boolean): any { + getFieldValue(unit: any, ids: any, createIfNotExists?: boolean): UnitType | null { if (!unit) { return null } - if (!(unit instanceof MemSpaceUnit)) { - unit = MemSpaceValueUtil.ObjectValue(unit) + if (!(unit instanceof Unit)) { + unit = new ObjectValue('', { sid: '', ...unit }) } return unit.getFieldValue(ids, createIfNotExists) @@ -50,7 +43,7 @@ class MemSpace extends Scope { * @param unit * @param ids */ - getFieldValueIfNotExists(unit: any, ids: any): any { + getFieldValueIfNotExists(unit: any, ids: any): UnitType | null { return this.getFieldValue(unit, ids, true) } @@ -63,14 +56,14 @@ class MemSpace extends Scope { * @param state * @returns {*} */ - resolveIndices(scope: any, node: any, state: any): any { + resolveIndices(scope: UnitType, node: any, state: any): any { if (!node) return node // 针对error类型特别适配 if (node?.rtype?.type === 'Identifier' && node?.rtype?.name === 'error') { return node } - if (typeof node === 'string') node = MemSpaceSymbolValue({ type: 'Identifier', name: node }) + if (typeof node === 'string') node = new IdentifierRefValue(scope.qid, node, null, null) if (node.type === 'MemberAccess') { let index: any @@ -82,42 +75,58 @@ class MemSpace extends Scope { } else { const prop = node.property index = this.processInstruction(scope, prop, state) - // if (!index || !(index.type === 'Literal' || index.type === 'Identifier' || index.vtype === 'union')) { - // index = prop; - // } - if (!index) index = MemSpaceSymbolValue(prop) + if (!index) index = new SymbolValue(scope.qid, { sid: ``, ...prop }) } const object = this.resolveIndices(scope, node.object, state) if (object === node.object && index === prop) return node - return MemSpaceSymbolValue({ - type: 'MemberAccess', - object, - property: index, + return new MemberExprValue(object.qid, object, index, node.computed, node, node.loc) + } + if (node.type === 'Identifier' || node.type === 'Parameter') { + return new SymbolValue(scope.qid, { sid: ``, ...node }) + } + if (node.type === 'Literal') { + return new SymbolValue(scope.qid, { sid: ``, ...node }) + } + if (node.type === 'ThisExpression') { + return new SymbolValue(scope.qid, { + sid: ``, + ...node, }) } - if ( - node.type === 'Identifier' || - node.type === 'Literal' || - node.type === 'ThisExpression' || - node.type === 'Parameter' || - node.type === 'SuperExpression' - ) { - return MemSpaceSymbolValue(node) + if (node.type === 'SuperExpression') { + return new SymbolValue(scope.qid, { + sid: ``, + ...node, + }) } if (node.vtype === 'union') { - const res: any[] = [] - for (const el of node.value) { - const v = this.resolveIndices(scope, el, state) - if (v) res.push(v) + const res: UnitType[] = [] + let values = node.value + if (values && !Array.isArray(values)) { + values = Object.values(values) + } + if (Array.isArray(values)) { + for (const el of values) { + const v = this.resolveIndices(scope, el, state) + if (v) res.push(v) + } } - return MemSpaceUnionValue({ value: res }) + return new UnionValue(res, undefined, `${scope.qid}.`, node.ast?.node) } // for Parameter and Return Parameter if (node.type === 'VariableDeclaration') { - return MemSpaceSymbolValue({ type: 'Parameter', name: node.id?.name, ast: node }) + return new SymbolValue(scope.qid, { + sid: ``, + type: 'Parameter', + name: node.id?.name, + ast: node, + }) } if (node.type === 'DereferenceExpression') { - return MemSpaceSymbolValue(node.argument) + return new SymbolValue(scope.qid, { + sid: ``, + ...node.argument, + }) } return this.processInstruction(scope, node, state) } @@ -131,8 +140,8 @@ class MemSpace extends Scope { * @param filter specify the scope to skip * @returns {{type, object, property}|*} */ - getMemberValue(scope: any, node: any, state: any, filter: any = null): any { - return this._getMemberValue(scope, node, state, true, undefined, filter) + getMemberValue(scope: UnitType, node: any, state: any, filter: FilterFn = null): any { + return this._getMemberValue(scope, node, state, true, undefined, filter, false) } /** @@ -144,8 +153,21 @@ class MemSpace extends Scope { * @param limit * @returns {{type, object, property}|*} */ - getMemberValueNoCreate(scope: any, node: any, state: any, limit?: number): any { - return this._getMemberValue(scope, node, state, false, limit) + getMemberValueNoCreate(scope: UnitType, node: any, state: any, limit?: number): any { + return this._getMemberValue(scope, node, state, false, limit, undefined, false) + } + + /** + * read the value of a variable from the current scope only + * value will be created if not existing + * @param scope + * @param node + * @param state + * @param filter + * @returns {{type, object, property}|*} + */ + getMemberValueInCurrentScope(scope: UnitType, node: any, state: any, filter: FilterFn = null): any { + return this._getMemberValue(scope, node, state, true, undefined, filter, true) } /** @@ -157,23 +179,37 @@ class MemSpace extends Scope { * @param limit * @param filter */ - _getMemberValue(scope: any, node: any, state: any, createIfNotExists: boolean, limit?: number, filter?: any): any { + _getMemberValue( + scope: any, + node: any, + state: any, + createIfNotExists: boolean, + limit?: number, + filter?: FilterFn, + currentScopeOnly?: boolean + ): any { if (typeof node === 'string') { return this._getMemberValue( scope, - MemSpaceAstUtil.qualifiedNameToMemberAccess(node), + AstUtil.qualifiedNameToMemberAccess(node), state, createIfNotExists, - limit + limit, + filter, + currentScopeOnly ) } - if (filter && filter(scope)) return MemSpaceUndefinedValue() + if (filter && filter(scope)) return new UndefinedValue() let defscope = scope if (scope.vtype === 'union') { if (!limit) limit = 30 - const res = MemSpaceUnionValue() - for (const scp of scope.value) { + const res = new UnionValue(undefined, undefined, `${scope.qid}.`, node) + let values = scope.value + if (values && !Array.isArray(scope.value)) { + values = Object.values(scope.value) + } + for (const scp of values) { if (scp && limit > 0) { res.appendValue(this._getMemberValue(scp, node, state, createIfNotExists, limit--, filter)) } @@ -181,20 +217,20 @@ class MemSpace extends Scope { return res } // 如果scope.vtype是object 则传入的scope就是当前obj的defscope 直接从scope中取值即可 - if (!['object', 'symbol', 'undefine'].includes(scope.vtype)) { + if (!['object', 'symbol', 'undefine', 'uninitialized'].includes(scope.vtype)) { // find the scope defining this object (e.g. for obj.x) - defscope = this.getDefScope(scope, node) + if (!currentScopeOnly) { + defscope = this.getDefScope(scope, node) + } } if (state?.brs) state.br_index = 0 const res = this._getMemberValueRec(defscope, node, state, createIfNotExists) - if (res && !res?.sort) { - res.sort = res.qid - } if (res && res.type === 'MemberAccess') { if (res.object) { - const { hasTagRec } = res.object // the property is usually tainted (e.g. user-controlled) - if (hasTagRec) res.hasTagRec = hasTagRec + // res.object 可能非 Unit,先检查 taint 存在 + const isTainted = res.object.taint ? res.object.taint.isTainted : false + if (isTainted) res.taint?.propagateFrom(res.object) } } return res @@ -215,7 +251,7 @@ class MemSpace extends Scope { if (node.vtype === 'union') { // value union - const res = MemSpaceUnionValue() + const res = new UnionValue(undefined, undefined, `${scope.qid}.`, node.ast?.node) for (const el of node.value) { const val = this._getMemberValueRec(scope, el, state, createIfNotExists) if (val) res.appendValue(val) @@ -281,20 +317,11 @@ class MemSpace extends Scope { * @param oldVal * @returns {*} */ - saveVarInScope(scope: any, node: any, value: any, state: any, oldVal: any = null): any { + saveVarInScope(scope: UnitType, node: any, value: UnitType, state: any, oldVal: UnitType | null = null): any { if (!value.rtype && oldVal && oldVal.rtype) value.rtype = oldVal.rtype const resolvedNode = this.resolveIndices(scope, node, state) - // find the scope defining this object (e.g. for obj.x) const defscope = this.getDefScope(scope, node) - // // use the top scope if not found - // if (!defscope) { - // defscope = scope; - // let limit = 20; // control circular pointers - // while (defscope.parent && defscope.parent.id !== 'top' && (limit--)) { - // defscope = defscope.parent; - // } - // } if (state && state.brs) state.br_index = 0 return this.saveVarInCurrentScope(defscope, resolvedNode, value, state) @@ -308,7 +335,7 @@ class MemSpace extends Scope { * @param state * @returns {*} */ - saveVarInCurrentScope(scope: any, node: any, value: any, state: any): any { + saveVarInCurrentScope(scope: UnitType, node: any, value: UnitType, state: any): any { const resolvedNode = this.resolveIndices(scope, node, state) if (value && resolvedNode?.rtype && !value?.rtype) { value.rtype = resolvedNode.rtype @@ -342,7 +369,7 @@ class MemSpace extends Scope { return } - if (typeof node === 'string') node = MemSpaceSymbolValue({ type: 'Identifier', name: node }) + if (typeof node === 'string') node = new IdentifierRefValue(scope.qid, node, null, null) switch (node.type) { case 'MemberAccess': { @@ -424,12 +451,12 @@ class MemSpace extends Scope { // a short-cut from the identity to the value if (scope.value) { const sid = symAddress.toStringID(node) - let u_sid = sid - if (node.trans_dep && state.tid) { - u_sid = `${sid}~${state.tid}` + let usid = sid + if (node.runtime?.transDep && state.tid) { + usid = `${sid}~${state.tid}` } - if (sid) scope.value[u_sid] = value + if (sid) scope.value[usid] = value } } @@ -443,14 +470,14 @@ class MemSpace extends Scope { if (!scope) return // FIXME if (scope.vtype === 'union') { - const res: any[] = [] - scope.value.forEach((s: any) => { + const res: UnitType[] = [] + scope.value.forEach((s: UnitType) => { res.push(this._removeMemberValueDirect(s, node, state)) }) if (res.length === 0) return undefined if (res.length === 1) return res[0] - return MemSpaceUnionValue({ value: res }) + return new UnionValue(res, undefined, `${scope.qid}.`, node) } if (scope.vtype === 'BVT') { scope = memState.loadForkedValue(scope, state) @@ -479,15 +506,6 @@ class MemSpace extends Scope { const isArray = Array.isArray(scope) const fields = isArray ? scope : scope.value - const scopeId = scope.getQualifiedId() - const qid = Scope.joinQualifiedName(scopeId, index) - const sid = index - if (isArray) { - // interpret native members - const native = nativeResolver.simplifyArrayExpression(scope, index) - if (native) return native - } - // if (fields && fields.hasOwnProperty(index)) { if (fields && _.has(fields, index)) { delete fields[index] @@ -512,7 +530,7 @@ class MemSpace extends Scope { state: any, createIfNotExists: boolean, stack: number, - visited: Set + visited: Set ): any { if (!scope) return // FIXME visited = visited || new Set() @@ -524,14 +542,14 @@ class MemSpace extends Scope { } visited.add(scope) if (scope.vtype === 'union') { - const res: any[] = [] - scope.value.forEach((s: any) => { + const res: UnitType[] = [] + scope.value.forEach((s: UnitType) => { res.push(this._getMemberValueDirect(s, node, state, createIfNotExists, stack, visited)) }) if (res.length === 0) return undefined if (res.length === 1) return res[0] - return MemSpaceUnionValue({ value: res }) + return new UnionValue(res, undefined, `${scope.qid}.`, node) } if (scope.vtype === 'BVT') { scope = memState.loadForkedValue(scope, state) @@ -568,26 +586,21 @@ class MemSpace extends Scope { } const qid = Scope.joinQualifiedName(scopeId, index) const sid = index?.toString() - if (isArray) { - // interpret native members - const native = nativeResolver.simplifyArrayExpression(scope, index) - if (native) return native - } let val: any if (fields && _.has(fields, index)) { // todo 还需要判断当前的val 是否state匹配 val = fields[index] - if (Object.prototype.hasOwnProperty.call(val, 'jumpLocate')) { - const targetVal = val.jumpLocate(val, qid, scope) + if (val.func?.jumpLocate) { + const targetVal = val.func.jumpLocate(val, qid, scope) if (targetVal) { val = targetVal } } - } else if (!createIfNotExists && !scope.hasTagRec) { + } else if (!createIfNotExists && !scope.taint?.isTaintedRec) { // notice that if scope has taint, sub field will always be created - return MemSpaceUndefinedValue({ - index, - qid: index, + return new UndefinedValue({ + sid: index, + qid: scope.qid + index, parent: scope, // refer to the parent scope }) } else if (fields && (!!fields.prototype || index === '__proto__' || index === 'prototype')) { @@ -599,10 +612,8 @@ class MemSpace extends Scope { if (!fields.prototype) { scope.setFieldValue( 'prototype', - MemSpaceObjectValue({ - id: 'prototype', + new ObjectValue(scope.qid, { sid: 'prototype', - qid: 'prototype', parent: scope, }) ) @@ -613,7 +624,6 @@ class MemSpace extends Scope { // 先在field找,如果没有,则看field是否有prototype的符号值 prototype如果有index则返回prototype中的index // prototype中如果没有,但prototype中还有prototype则递归从原型符号链查找 val = this.getPropertyFromPrototype(fields.prototype, index) - // val = _.has(fields['prototype'].field ,index) ? fields['prototype'].field[index] : MemSpaceSymbolValue({ type: 'MemberAccess', object: scope, property: node, ast: node.ast, sid, qid,}) } } if (!val) { @@ -621,112 +631,103 @@ class MemSpace extends Scope { // otherwise possibly symbolic access if (isArray || scope.type === 'MemberAccess' || scope.vtype === 'object' || scope.vtype === 'symbol') { // do not create a value, instead return the "scope.index" expression - val = MemSpaceSymbolValue({ - type: 'MemberAccess', - object: scope, - property: node, - ast: node.ast, - sid, - qid, - }) + val = new MemberExprValue('', scope, node, false, node.ast?.node, node.loc) + val._sid = sid + val._qid = qid if (scope.value && typeof scope.value === 'object') { scope.value[index] = val } - if (scope.hasTagRec) { - val.hasTagRec = scope.hasTagRec + if (scope.taint?.isTaintedRec && val.taint) { + val.taint?.propagateFrom(scope) } - if (memSpaceVarUtil.isNotEmpty(scope._tags)) { - val._tags = _.clone(scope._tags) + if (scope.taint?.hasTags() && val.taint) { + for (const t of scope.taint.getTags()) val.taint.addTag(t) } - if (scope.trace) { - val.trace = _.clone(scope.trace) + if (scope.taint.hasTraces() && val.taint) { + val.taint.inheritTracesFrom(scope.taint) } } else if (scope.value && scope.type !== 'Literal') { try { val = this.createIdentifierFieldValue(node, scope) val.sid = sid - val.qid = qid + val._qid = qid + val.uuid = null + val.calculateAndRegisterUUID() } catch (e) { - memSpaceHandleException(e, '', 'Error occurred in Memspace.getValueDirect') + handleException(e, '', 'Error occurred in Memspace.getValueDirect') } } } if (val) { - if (typeof val === 'string' || typeof val === 'number') { - return MemSpacePrimitiveValue({ value: val, type: 'Literal' }) + if (typeof val === 'string') { + return new PrimitiveValue('', val, val, null, 'Literal') + } + if (typeof val === 'number') { + return new PrimitiveValue('', ``, val, null, 'Literal') + } + if (typeof val === 'boolean') { + return new PrimitiveValue('', ``, val, null, 'Literal') } - if (!val.hasTagRec && scope.hasTagRec) { - val.hasTagRec = scope.hasTagRec + if (val.taint && !val.taint?.isTaintedRec && scope.taint?.isTaintedRec) { + val.taint?.propagateFrom(scope) } - if (memSpaceVarUtil.isEmpty(val._tags) && memSpaceVarUtil.isNotEmpty(scope._tags)) { - val._tags = _.clone(scope._tags) + if (val.taint && !val.taint?.hasTags() && scope.taint?.hasTags()) { + for (const t of scope.taint.getTags()) val.taint.addTag(t) } - if (!val.trace && scope.trace) { - val.trace = _.clone(scope.trace) + if (val.taint && !val.taint.hasTraces() && scope.taint.hasTraces()) { + val.taint.inheritTracesFrom(scope.taint) } val = memState.loadForkedValue(val, state) // may need to resolve branch-dependent values if (!val) { // val = Scope.createSubScope(index, scope); - val = MemSpaceUndefinedValue({ - index, - qid: index, + val = new UndefinedValue({ + sid: index, + qid: `${scope.qid}.${index}`, parent: scope, // refer to the parent scope }) return val } // if (typeof val === 'string' || typeof val === 'number') { - // return MemSpacePrimitiveValue({ value: val, type: 'Literal' }) + // return PrimitiveValue({ value: val, type: 'Literal' }) // } if (val && typeof val === 'string') { - val = MemSpacePrimitiveValue({ type: 'Literal', value: val }) - } - if (!val.sort) val.sort = typeUtil.inferType({ type: 'MemberAccess', expression: scope, property: val }) - - if (!val.sort && val.type === 'Literal') { - val.sort = typeUtil.inferType(val) + val = new PrimitiveValue('', val, val, null, 'Literal') } // set the "this" pointer for objects if (val.vtype === 'fclos') { - val._this = scope.getThis() + val._this = scope.getThisObj() } - if (node.hasTagRec) { - // 一般情况下 对象的key的符号值是不会存储到field里的,field只用来存储value的符号值 - // 当污点在key上时,key的符号值会被转换成普通字符串,并且不会存储到field中 此时污点信息taint和trace丢失发生断链 - // 为了解决上述问题 若key携带污点,则将key的符号值存储到misc里 只要后续worklist能遍历到misc 这条污点链路即可建立起来 + if (node.taint && node.taint?.isTaintedRec) { + // 当 key 携带污点,存储到 misc 避免断链 scope.setMisc(sid, node) } return val } + const memberExpr = new MemberExprValue('', scope, node, false, node.ast?.node, node.loc) + memberExpr._sid = sid + memberExpr._qid = qid const res = scope.vtype === 'scope' ? node - : MemSpaceSymbolValue({ - type: 'MemberAccess', - object: scope, - property: node, - ast: node.ast, - sid, - qid, - }) - res.sort = typeUtil.inferType(res) + : memberExpr if (scope.vtype === 'primitive') { - if (!res.hasTagRec && scope.hasTagRec) { - res.hasTagRec = scope.hasTagRec + if (res.taint && !res.taint?.isTaintedRec && scope.taint?.isTaintedRec) { + res.taint?.propagateFrom(scope) } - if (memSpaceVarUtil.isEmpty(res._tags) && memSpaceVarUtil.isNotEmpty(scope._tags)) { - res._tags = _.clone(scope._tags) + if (res.taint && !res.taint?.hasTags() && scope.taint?.hasTags()) { + for (const t of scope.taint.getTags()) res.taint.addTag(t) } - if (!res.trace && scope.trace) { - res.trace = _.clone(scope.trace) + if (res.taint && !res.taint.hasTraces() && scope.taint.hasTraces()) { + res.taint.mergeTracesFrom(scope.taint) } } return res } case 'ThisExpression': { - return scope.getThis() + return scope.getThisObj() } case 'UnaryOperation': { switch (node.operator) { @@ -741,7 +742,7 @@ class MemSpace extends Scope { node = node.subExpression break default: - MemSpaceErrors.UnsupportedOperator(`unsupported operator:${node.operator}`) + Errors.UnsupportedOperator(`unsupported operator:${node.operator}`) } } } @@ -751,7 +752,7 @@ class MemSpace extends Scope { const { updates } = scope if (updates) { // if node is transaction related, don't get from updates - if (!node.trans_dep) { + if (!node.runtime?.transDep) { const v = updates.get(node) if (v) return v } @@ -760,44 +761,37 @@ class MemSpace extends Scope { if (scope.value) { const sid = symAddress.toStringID(node) if (sid) { - let u_sid = sid - if (node.trans_dep && state.tid) { - u_sid = `${sid}~${state.tid}` + let usid = sid + if (node.runtime?.transDep && state.tid) { + usid = `${sid}~${state.tid}` } - // if (scope.value.hasOwnProperty(u_sid)) - if (Object.prototype.hasOwnProperty.call(scope.value, u_sid)) return scope.value[u_sid] + // if (scope.value.hasOwnProperty(usid)) + if (Object.prototype.hasOwnProperty.call(scope.value, usid)) return scope.value[usid] // const val = Scope.createIdentifierScope({type: 'Literal', value: sid}, // scope); - // val.sort = typeUtil.inferType({type: 'MemberAccess', expression: scope, property: node}); + const memberExpr3 = new MemberExprValue('', scope, node, false, node.ast?.node, node.loc) + memberExpr3._sid = sid + memberExpr3._qid = sid const val = scope.vtype === 'scope' && node.vtype ? node - : MemSpaceSymbolValue({ - type: 'MemberAccess', - object: scope, - property: node, - sid, - qid: sid, - }) - if (node.hasTagRec) { - // 一般情况下 对象的key的符号值是不会存储到field里的,field只用来存储value的符号值 - // 当污点在key上时,key的符号值会被转换成普通字符串,并且不会存储到field中 此时污点信息taint和trace丢失发生断链 - // 为了解决上述问题 若key携带污点,则将key的符号值存储到misc里 只要后续worklist能遍历到misc 这条污点链路即可建立起来 - scope.setMisc(u_sid, node) + : memberExpr3 + if (node.taint && node.taint?.isTaintedRec) { + // 当 key 携带污点,存储到 misc 避免断链 + scope.setMisc(usid, node) } if (scope.type !== 'Literal' && typeof scope.value !== 'string') { - scope.value[u_sid] = val + scope.value[usid] = val } - val.sort = typeUtil.inferType(val) return val } } // other cases, e.g. unknown value - const res = - scope.vtype === 'scope' ? node : MemSpaceSymbolValue({ type: 'MemberAccess', object: scope, property: node }) - res.sort = typeUtil.inferType(res) - return res + if (scope.vtype === 'scope') return node + const fallbackMember = new MemberExprValue(scope.qid, scope, node, false, node.ast?.node, node.loc) + fallbackMember._sid = AstUtil.prettyPrint(node) + return fallbackMember } /** @@ -810,57 +804,11 @@ class MemSpace extends Scope { * @param node * @param sid */ - getPropertyFromPrototype(proto: any, index: any): any { - if (proto && proto.field && _.has(proto.field, index)) { - return proto.field[index] - } - return proto?.field.prototype != null ? this.getPropertyFromPrototype(proto?.field.prototype, index) : undefined - } - - /** - * for declaration/definition hoisting; consider only one block (and not the sub blocks) - * @param scope - * @param node - * @param state - */ - recordFunctionDefinitions(scope: any, node: any, state: any): void { - if (logger.isTraceEnabled()) logger.trace(`recordFunctionDefinition: ${valueFormatter.formatNode(node)}\n`) - if (!node) return - - if (Array.isArray(node)) { - for (const statement of node) { - this.recordFunctionDefinitions(scope, statement, state) - } - return - } - - switch (node.type) { - case 'FunctionDefinition': { - // let clos = Scope.createFunctionClosure(scope, node); - // analysisUtil.saveOverloadedFunctionInScope(scope, node.id, clos); - break - } - case 'BlockStatement': { - this.recordFunctionDefinitions(scope, node.body, state) - break - } - case 'ClassDeclaration': { - if (logger.isTraceEnabled()) logger.trace(`allocate class members: ${valueFormatter.formatNode(node)}`) - const clos = this.createClassClosure(scope, node) - if (logger.isTraceEnabled()) logger.trace(`node.id = ${valueFormatter.formatNode(node.id)}`) - const id = node.id.type ? node.id : { type: 'Literal', value: node.id } - this.saveVarInCurrentScope(scope, id, clos, state) - break - } - case 'VariableDeclaration': { - this.recordFunctionDefinitions(scope, node.declarations, state) - break - } - case 'ExpressionStatement': { - this.recordFunctionDefinitions(scope, node.expression, state) - break - } - } // end switch + getPropertyFromPrototype(proto: UnitType | undefined, index: string): UnitType | undefined { + if (!proto?.members) return undefined + if (proto.members.has(index)) return proto.members.get(index) + const nextProto = proto.members.get('prototype') + return nextProto != null ? this.getPropertyFromPrototype(nextProto, index) : undefined } } @@ -872,7 +820,7 @@ class MemSpace extends Scope { * @param value * @param state */ -function saveVarInScopeDirect(scope: any, id: any, value: any, state: any): void { +function saveVarInScopeDirect(scope: any, id: string | number, value: UnitType, state: any): void { let fields = Array.isArray(scope) ? scope : scope.value if (!fields) fields = scope.value = {} // fields[id] = value; diff --git a/src/engine/analyzer/common/memState.ts b/src/engine/analyzer/common/memState.ts index 86dbf582..7c9c4867 100644 --- a/src/engine/analyzer/common/memState.ts +++ b/src/engine/analyzer/common/memState.ts @@ -2,8 +2,9 @@ const _ = require('lodash') const Config = require('../../../config') const StateBVT = require('./memStateBVT') +const { lodashCloneWithTag } = require('../../../util/clone-util') const { - ValueUtil: { ObjectValue, Scoped, PrimitiveValue, UndefinedValue, UnionValue, SymbolValue }, + ValueUtil: { UnionValue }, } = require('../../util/value-util') /** ********************* analysis state management ********************** */ @@ -36,7 +37,7 @@ const options = { //* ***************************** Interface ******************************************** /** - * deep object cloning + * 待删除,新增逻辑不要再用了 * @param object * @param state: e.g. side effects * @param state @@ -93,9 +94,6 @@ function forkStates(state: any, n: number = 2): any[] { rstate.brs = `${state.brs}R` lstate.parent = state rstate.parent = state - - // lstate.pcond = _.clone(state.pcond); - // rstate.pcond = _.clone(state.pcond); return pair } if (n === 1) { @@ -135,47 +133,6 @@ function forkStates(state: any, n: number = 2): any[] { //* ***************************** Utility ******************************************** -/** - * simplify the union expression - * @param v1 - * @param v2 - * @param reuse - * @returns {*} - */ -function mk_union(v1: any, v2: any, reuse: any): any { - if (!v1) return v2 - if (!v2) return v1 - if (v1.vtype === 'union') { - if (v2.vtype === 'union') { - if (reuse) { - for (const el of v2.value) { - if (!v1.value.some((x: any) => isEqValue(x, el))) v1.value.push(el) - } - return v1 - } - return UnionValue({ value: v1.value.concat(v2.value) }) - } - if (v1.value.some((x: any) => isEqValue(x, v2))) return v1 - - if (reuse) { - v1.value.push(v2) - return v1 - } - return UnionValue({ value: v1.value.concat([v2]) }) - } - if (v2.vtype === 'union') { - if (v2.value.some((x: any) => isEqValue(x, v1))) return v2 - - if (reuse) { - v2.value.push(v1) - return v2 - } - return UnionValue({ value: v2.value.concat([v1]) }) - } - if (isEqValue(v1, v2)) return v1 - return UnionValue({ value: [v1, v2] }) -} - /** * * @param v1 @@ -235,48 +192,14 @@ function writeValueMemState(fields: any, id: any, value: any, state: any, scope: * @param scope */ function simpleObjectClone(scope: any): any { - if (scope.readonly) return scope + if (scope.runtime?.readonly) return scope - const clone = _.clone(scope) + const clone = lodashCloneWithTag(scope) switch (clone.vtype) { case 'object': case 'fclos': case 'scope': - clone.value = _.clone(scope.value) - } - return clone -} - -/** - * deep scope of a scope with meta-information sharing - * @param scope - * @param filter - * @param visited - */ -function deepScopeClone(scope: any, filter: any, visited: Map): any { - if (scope.readonly) return scope - if (!filter(scope)) return scope - - const old = visited.get(scope) - if (old) return old - const clone = _.clone(scope) - visited.set(scope, clone) - - switch (clone.vtype) { - case 'object': - case 'fclos': - case 'scope': { - const res: any = {} - for (const field of Object.keys(clone.value)) { - const val = clone.value[field] - const v1 = deepScopeClone(val, filter, visited) - res[field] = v1 - // if (val.parent === scope) // adjust the parent pointer to the clone - if (v1 !== clone) v1.parent = clone // Important!!! - // v1.parent === visited.get(val.parent); // Important!!!: adjust the parent pointer to the clone - } - clone.value = res - } + clone.value = lodashCloneWithTag(scope.value) } return clone } @@ -341,7 +264,7 @@ function unionPrimitiveValuesMemState(v1: any, v2: any): any { } } else if (!res.includes(v2)) res.push(v2) if (v1.vtype === 'union') { - return UnionValue({ value: res }) + return new UnionValue(res, undefined, `${v1.qid}.`, v1.ast?.node) } return { vtype: v1.vtype, value: res } } @@ -350,20 +273,17 @@ function unionPrimitiveValuesMemState(v1: any, v2: any): any { if (!res.includes(v1)) res.push(v1) if (res.length >= options.unionValueLimit) return v2 if (v2.vtype === 'union') { - return UnionValue({ value: res }) + return new UnionValue(res, undefined, `${v2.qid}.`, v2.ast?.node) } return { vtype: v2.vtype, value: res } } - return UnionValue({ value: [v1, v2] }) + return new UnionValue([v1, v2], undefined, `${v1.qid}.`, v1.ast?.node) } //* ***************************** exports *************************************** module.exports = { cloneScope: cloneObject, - deepScopeClone: (scope: any, filter: any) => { - return deepScopeClone(scope, filter, new Map()) - }, loadForkedValue, writeValue: writeValueMemState, unionValues: unionValuesMemState, diff --git a/src/engine/analyzer/common/memStateBVT.ts b/src/engine/analyzer/common/memStateBVT.ts index 2e45b808..926fa976 100644 --- a/src/engine/analyzer/common/memStateBVT.ts +++ b/src/engine/analyzer/common/memStateBVT.ts @@ -1,5 +1,5 @@ const { - ValueUtil: { BVT, UnionValue, Scoped, SymbolValue, UndefinedValue }, + ValueUtil: { BVTValue, UnionValue, Scoped, SymbolValue, UndefinedValue }, } = require('../../util/value-util') /** ************************************************************ @@ -27,19 +27,23 @@ function writeValueBVT(fields: any, index: any, value: any, br: any, br_index: a * @param parent * @param pname */ - function write(tree: any, br: any, i: number, parent: any, pname: any): void { + function write(tree: any, br: any, i: number, parentBvt: any, pname: any): void { if (!tree || tree.vtype !== 'BVT') { - // create a sub-tree for the new appeared branch - tree = BVT({ value: tree }) - parent[pname] = tree + const oldTree = tree + tree = new BVTValue('', ``, {}) + tree.raw_value = oldTree + parentBvt.setChild(pname, tree) } if (i < br.length - 1) { const c = br[i] - const { children } = tree - write(children[c], br, i + 1, children, c) + write(tree.getChild(c), br, i + 1, tree, c) } else { const c = br[br.length - 1] - tree.children[c] = value + const oldVal = tree.getChild(c) + if (oldVal) { + tree.setChild(`${c}_`, oldVal) + } + tree.setChild(c, value) } } @@ -47,13 +51,15 @@ function writeValueBVT(fields: any, index: any, value: any, br: any, br_index: a // initialize the BVT root node let old_value = fields[index] if (!old_value) { - old_value = BVT({ value: old_value }) + const oldValue = old_value + old_value = new BVTValue(scope.qid, ``, {}) + old_value.raw_value = oldValue // 直接设置 raw_value,不通过 setter } else if (old_value.vtype !== 'BVT') { - old_value = createBVT(br, old_value) + old_value = createBVT(scope.qid, br, old_value, value.ast?.node) } fields[index] = old_value write(old_value, br, br_index, old_value, index) - } else if (scope.misc_.pointer_reference) { + } else if (scope.pointerReference) { // overwrite directly Object.assign(fields[index], value) } else { @@ -63,18 +69,25 @@ function writeValueBVT(fields: any, index: any, value: any, br: any, br_index: a /** * + * @param qidPrefix * @param br * @param old_value + * @param node */ -function createBVT(br: any, old_value: any): any { +function createBVT(qidPrefix: string, br: any, old_value: any, node: any): any { if (!br || br.length === 0) { return old_value } const currentChar = br[0] - const nestedBVT = createBVT(br.slice(1), old_value) - return BVT({ children: { [currentChar]: nestedBVT } }) + const nestedBVT = createBVT(qidPrefix, br.slice(1), old_value, node) + let sig = '' + if (node?.loc?.sourcefile && typeof node?.loc?.sourcefile === 'string') { + sig = `${node.loc?.sourcefile.substring((node.loc?.sourcefile.lastIndexOf('/') || 0) + 1, node.loc?.sourcefile.lastIndexOf('.'))}_${node.loc?.start?.line}_${node.loc?.start?.column}_${node.loc?.end?.line}_${node.loc?.end?.column}` + } + + return new BVTValue(qidPrefix, ``, { [currentChar]: nestedBVT }) } /** @@ -109,7 +122,11 @@ function readValue(value: any, br: any, br_index: any): any { if (value.vtype) { return value } - return SymbolValue({ field: value }) + return new SymbolValue('', { + sid: `${tree.sid}`, + qid: `${tree.qid}`, + field: value, + }) } return read(children[c], br, i + 1) } @@ -129,7 +146,11 @@ function readValue(value: any, br: any, br_index: any): any { if (pval.vtype) { return pval } - return SymbolValue({ field: pval }) + return new SymbolValue('', { + sid: `${tree.sid}`, + qid: `${tree.qid}`, + field: pval, + }) } if (!value) return value @@ -146,10 +167,10 @@ function readValue(value: any, br: any, br_index: any): any { * @param v */ function wrapValue(v: any): any { - if (!v) return UndefinedValue() + if (!v) return new UndefinedValue() if (v.vtype) return v - return SymbolValue({ field: v }) + return new SymbolValue('', { sid: '', qid: '', field: v }) } /** @@ -171,7 +192,7 @@ function unionValue(v1: any, v2: any): any { if (v1.vtype === 'union') { if (v2.vtype === 'union') { const vs = v1.value.concat(v2.value) - return vs.length === 1 ? vs[0] : UnionValue({ value: vs }) + return vs.length === 1 ? vs[0] : new UnionValue(vs, undefined, `${v1.qid}.`, v1.ast?.node) } const vs = v1.value.slice() if ( @@ -180,55 +201,10 @@ function unionValue(v1: any, v2: any): any { }) ) vs.push(v2) - return vs.length === 1 ? vs[0] : UnionValue({ value: vs }) + return vs.length === 1 ? vs[0] : new UnionValue(vs, undefined, `${v1.qid}.`, v1.ast?.node) } if (v1 === v2) return v1 - return UnionValue({ value: [v1, v2] }) -} - -/** - * reduce a Branch Value Tree by merging the given branches - * @param value - * @param brs - * @returns {*} - */ -function mergeBVT(value: any, brs: any): any { - /** - * - * @param tree - * @param br - * @param i - * @param parent - * @param extra - */ - function merge(tree: any, br: any, i: number, parent: any, extra?: any): any { - if (i < br.length - 1) { - const c = br[i] - const { children } = tree - return merge(children[c], br, i + 1, tree, null) - } - if (tree) { - const c = br[i] - let vs: any - let numChildren = 0 - for (const field in tree.children) { - const val = tree.children[field] - vs = unionValue(vs, val) - numChildren++ - } - if (numChildren < 2 && tree.value) vs = unionValue(vs, tree.value) - if (parent) { - parent.children[c] = vs - } else return vs - } - } - - if (!value) return value - if (value.vtype === 'BVT') { - const res = merge(value, brs[0], 0, null) - return res || value - } - return value + return new UnionValue([v1, v2], undefined, `${v1.qid}.`, v1.ast?.node) } /** @@ -242,7 +218,7 @@ function mergeBVT(value: any, brs: any): any { * @returns {*} */ function mergeLeafValues(scope: any, brs: any, br_index: any, parent: any, visited: Set): any { - if (typeof scope !== 'object') return scope + if (typeof scope !== 'object' || scope === null) return scope if (scope.type) return scope // expressions visited.add(scope) @@ -261,7 +237,7 @@ function mergeLeafValues(scope: any, brs: any, br_index: any, parent: any, visit } if (numChildren < 2 && scope.value) vs = unionValue(vs, scope.value) if (parent) { - parent.children[brs[br_index - 1]] = vs + parent.setChild(brs[br_index - 1], vs) return parent } return vs // scope; @@ -340,8 +316,9 @@ function unionBVTScope(scope1: any, scope2: any, visited: Map): any { if (scope1.type === 'Literal' && scope2.type.type == 'Literal' && scope1.value === scope2.value) { return scope1 } - - const result = Scoped({ parent: scope1.parent }) + const bvtQid = `` + const bvtSid = `` + const result = new Scoped('', { sid: bvtSid, qid: bvtQid, parent: scope1.parent }) const vvalue1 = scope1.value const vvalue2 = scope2.value const rvalue = result.value @@ -351,23 +328,21 @@ function unionBVTScope(scope1: any, scope2: any, visited: Map): any { if (v2) { const prev_v = visited.get(field) if (prev_v) return prev_v - const new_v = BVT({ children: { L: v1, R: v2 } }) + const bvtSid = `` + const new_v = new BVTValue('', bvtSid, { L: v1, R: v2 }) rvalue[field] = new_v visited.set(field, new_v) - } else rvalue[field] = BVT({ children: { L: v1 } }) + } else { + const bvtSid = `` + rvalue[field] = new BVTValue(scope1.qid, bvtSid, { L: v1 }) + } } for (const field in vvalue2) { const v2 = vvalue2[field] - if (!vvalue1 || !vvalue1[field]) rvalue[field] = BVT({ children: { R: v2 } }) + const bvtSid = `` + if (!vvalue1 || !vvalue1[field]) rvalue[field] = new BVTValue(scope2.qid, bvtSid, { R: v2 }) } - // if (scope1.ast) { - // if (scope2.ast) - // result.ast = unionPrimitiveValues(scope1.ast, scope2.ast); - // else - // result.ast = scope1.ast; - // } - // else if (scope2.ast) - // result.ast = scope2.ast; + return result } @@ -394,10 +369,10 @@ function reduceBVTScope(scope: any, visited: Set): any { const r = reduceBVTScope(rchild, visited) return unionBVTScope(l, r, new Map()) } - scope.children.L = l + scope.setChild('L', l) } else if (rchild) { const r = reduceBVTScope(rchild, visited) - scope.children.R = r + scope.setChild('R', r) } } else if (scope.vtype === 'object' || scope.vtype === 'fclos' || scope.vtype === 'scope') { for (const field in scope.value) { @@ -448,16 +423,8 @@ function cloneScope(scope: any, state: any): any { */ function unionAllValues(scopes: any, state: any): any { const res = scopes[0] - const tmp = UnionValue() - tmp.appendValue(res) - for (let i = 1; i < scopes.length; i++) { - if (scopes[i].vtype === 'union') { - tmp._pushValue(scopes[i]) - } else { - tmp.appendValue(scopes[i]) - } - } - return tmp + const validScopes = scopes.filter((s: any) => s != null) + return new UnionValue(validScopes, undefined, `${res?.qid || ''}.`, res?.ast?.node) } //* ***************************** exports ******************************************** diff --git a/src/engine/analyzer/common/native-resolver.ts b/src/engine/analyzer/common/native-resolver.ts index 0003557f..f14170a2 100644 --- a/src/engine/analyzer/common/native-resolver.ts +++ b/src/engine/analyzer/common/native-resolver.ts @@ -1,9 +1,9 @@ const util = require('util') -const _ = require('lodash') const logger = require('../../../util/logger')(__filename) const { ValueUtil: { PrimitiveValue }, } = require('../../util/value-util') +const ASTUtil = require('../../../util/ast-util') const { handleException } = require('./exception-handler') /** @@ -25,284 +25,12 @@ function mkLiteral(v: any, parent: any): any { res = { ast: v, parent } break default: - res = PrimitiveValue({ type: 'Literal', value: v }) + res = new PrimitiveValue(parent.qid, ASTUtil.prettyPrint(v), v, null, 'Literal') + res.parent = parent } return res } -//* ***************************** value simplifcation ************************************** - -/** - * "-" | "+" | "!" | "~" | "typeof" | "void" | "delete" - * @param exp - * @returns {*} - */ -function simplifyUnaryExpression(exp: any): any { - const argument = exp.subExpression - if (!argument) return exp - - if (Array.isArray(argument)) { - switch (exp.operator) { - case '!': { - const newval = argument.length === 0 - return PrimitiveValue({ type: 'Literal', value: newval }) - } - } - return exp - } - if (exp.operator === '#') { - // handle escaping - switch (argument.type) { - case 'Literal': - return argument.value - // should handle only literals; otherwise #id is resolved to a constant rather than an expression - // case 'Identifier': - // return argument.name; - } - } else if (argument.type === 'Literal') { - const val = argument.value - let newval - switch (exp.operator) { - case '--': { - newval = val - 1 - break - } - case '++': { - newval = val + 1 - break - } - case '-': { - newval = -val - break - } - case '+': { - newval = +val - break - } - case '!': { - newval = !val - break - } - case '~': { - newval = ~val - break - } - default: - return PrimitiveValue(exp) - } - if (val && val.hasTagRec) newval.hasTagRec = val.hasTagRec - return PrimitiveValue({ type: 'Literal', value: newval }) - } else if (argument.vtype === 'object') { - switch (exp.operator) { - case '!': { - const newval = _.isEmpty(argument.value) - return PrimitiveValue({ type: 'Literal', value: newval }) - } - } - return exp - } - return exp -} - -/** - * - * "==" | "!=" | "===" | "!==" | "<" | "<=" | ">" | ">=" | "<<" | ">>" | ">>>" | - * "+" | "-" | "*" | "/" | "%" | "|" | "^" | "&" | - * "&&" | "||" - * @param exp - * @returns {*} - */ -function simplifyBinaryExpression(exp: any): any { - // onsole.log("simplify: " + formatNode(exp)); - const { left } = exp - const { right } = exp - if (!left || !right || left.type !== 'Literal' || right.type !== 'Literal') return exp - const lval = left.value - const rval = right.value - let newval - switch (exp.operator) { - case '+': - case '+=': { - newval = lval + rval - break - } - case '-': - case '-=': { - newval = lval - rval - break - } - case '*': - case '*=': { - newval = lval * rval - break - } - case '/': - case '/=': { - newval = lval / rval - break - } - case '%': - case '%=': { - newval = lval % rval - break - } - case '|': - case '|=': { - newval = lval | rval - break - } - case '^': - case '^=': { - newval = lval ^ rval - break - } - case '&': - case '&=': { - newval = lval & rval - break - } - - case '<': { - newval = lval < rval - break - } - case '<=': { - newval = lval <= rval - break - } - case '>': { - newval = lval > rval - break - } - case '>=': { - newval = lval >= rval - break - } - case '<<': - case '<<=': { - newval = lval << rval - break - } - case '>>': - case '>>=': { - newval = lval >> rval - break - } - case '>>>': - case '>>>=': { - newval = lval >>> rval - break - } - - case '&&': - case '&&=': { - newval = lval && rval - break - } - case '||': - case '||=': { - newval = lval || rval - break - } - - case '<': { - newval = lval < rval - break - } - case '<=': { - newval = lval <= rval - break - } - case '>=': { - newval = lval >= rval - break - } - case '>': { - newval = lval > rval - break - } - case '==': { - newval = lval == rval - break - } - case '!=': { - newval = lval != rval - break - } - case '&&': - case '&&=': { - newval = lval && rval - break - } - case '||': - case '||=': { - newval = lval || rval - break - } - - default: - return exp - } - - return PrimitiveValue({ type: 'Literal', value: newval }) -} - -/** - * c ? b1 : b2 - * @param exp - * @returns {*} - */ -function simplifyConditionalExpression(exp: any): any { - // onsole.log("simplify: " + formatNode(exp)); - const { test } = exp - if (!test || test.type !== 'Literal') return exp - return test.value ? PrimitiveValue(exp.trueExpression) : PrimitiveValue(exp.falseExpression) -} - -// *** - -/** - * e.g. accessing members in concrete objects - * @param obj - * @param index - * @returns {{type: string, value: *}|*} - */ -function simplifyMemberAccess(obj: any, index: any): any { - switch (obj.type) { - case 'Literal': { - // let res = obj.raw[index]; - if (!obj.value) return // {type: "Literal", value: null}; - const res = obj.value[index] - if (res) return mkLiteral(res, obj) - break - } - } -} - -/** - * e.g. accessing members in concrete arrays - * @param obj - * @param index - * @returns {*} - */ -function simplifyArrayExpression(obj: any, index: any): any { - try { - switch (index) { - case 'length': { - const len = obj.length - return PrimitiveValue({ type: 'Literal', value: len, raw: len }) - } - } - const res = obj[index] // return the value - if (res) { - if (typeof res === 'function') { - return { ast: res, parent: obj } - } - return res - } - } catch (e) {} -} - //* ***************************** native calls ************************************** /** @@ -383,18 +111,18 @@ function nativeCall(obj: any, f: any, argvalues: any[]): any { * @returns {*} */ function processNativeFunction(this: any, node: any, fclos: any, argvalues: any[], state: any): any { - if (!fclos.id) return + if (!fclos.sid) return const { parent } = fclos if (!parent) return // array related native functions try { - const res = nativeCall(parent, fclos.ast, argvalues) + const res = nativeCall(parent, fclos.ast?.node, argvalues) if (res) return res } catch (e) {} - switch (fclos.id) { + switch (fclos.sid) { case '__delete__': { const cval = argvalues[0] // container value const key: any = argvalues[1] // key @@ -405,18 +133,18 @@ function processNativeFunction(this: any, node: any, fclos: any, argvalues: any[ } // other native functions, e.g. global functions - switch (parent.id) { + switch (parent.sid) { case 'Array': { - switch (fclos.id) { + switch (fclos.sid) { case 'isArray': { const val = argvalues.length == 0 ? false : Array.isArray(argvalues[0]) - return PrimitiveValue({ type: 'Literal', value: val, raw: val }) + return new PrimitiveValue(parent.qid, '', val, null, 'Literal') } } break } case '__': { - const fid = fclos.id + const fid = fclos.sid if (!fid) break switch (fid) { case 'log': @@ -450,11 +178,5 @@ function processNativeFunction(this: any, node: any, fclos: any, argvalues: any[ // *** module.exports = { - simplifyUnaryExpression, - simplifyBinaryExpression, - simplifyMemberAccess, - simplifyArrayExpression, - simplifyConditionalExpression, - processNativeFunction, } diff --git a/src/engine/analyzer/common/sarif.ts b/src/engine/analyzer/common/sarif.ts index 5ea18fb6..8188aedf 100644 --- a/src/engine/analyzer/common/sarif.ts +++ b/src/engine/analyzer/common/sarif.ts @@ -100,7 +100,8 @@ function prepareLocation( nodeHash, }, } - if (affectedNodeName) { + // TODO: 排查为什么会不是string + if (affectedNodeName && typeof affectedNodeName === 'string') { res.physicalLocation!.region.snippet.affectedNodeName = affectedNodeName } return res @@ -157,24 +158,36 @@ function prepareSarifFormat(results: SarifResult[], graphs: any): Record scope.vtype === vtype)) { @@ -124,30 +95,24 @@ class Scope { return defScope ?? scope } - /** - * - * @param scope - * @param node - */ - getDefScope(scope: any, node: any): any { + getDefScope(scope: Unit, node: any): Unit | undefined { const res = Scope.getDefScope(scope, node) return res ?? scope } - /** - * create a field value for an unknown variable - * @param identifier - * @param scope - * @returns {{vtype: string, id: *, value: {}, ast: null, parent: *}} - */ - createIdentifierFieldValue(identifier: any, scope: any): any { - const index = - identifier.type === 'Identifier' || identifier.type === 'SuperExpression' - ? identifier.name - : identifier.value.toString() + createIdentifierFieldValue(identifier: any, scope: Unit): Unit { + let index + if (identifier.type === 'Identifier') { + index = identifier.name + } else if (identifier.type === 'SuperExpression') { + index = 'super' + } else { + index = identifier.value.toString() + } + const scopeId = scope.getQualifiedId() const qid = Scope.joinQualifiedName(scopeId, index) - let subscope = SymbolValue({ + let subscope = new SymbolValue('', { sid: index, qid, ast: identifier, @@ -164,88 +129,77 @@ class Scope { // subscope.parent = scope; // // record type information // type.recordType(identifier, subscope, scope); - if (scope.hasTagRec) { - subscope.hasTagRec = true - subscope._tags = scope._tags - if (scope.trace) { - subscope.trace = _.clone(scope.trace) + if (scope._taint?.isTaintedRec) { + subscope.taint?.markSource() + subscope._taint = scope._taint._clone(subscope) + if (scope._taint.hasTraces()) { subscope = addSrcLineInfo(subscope, identifier, identifier.loc?.sourcefile, 'Field: ', index) } } - // link to the parent scope - scope.field[index] = subscope + if (scope.members) { + scope.members.set(index, subscope) + } return subscope } - /** - * - * @param decl - * @param scope - * @returns {{vtype: string, id: *, value: {}, ast: null, parent: *}} - */ - createVarDeclarationScope(decl: any, scope: any): any { + createVarDeclarationScope(decl: any, scope: Unit): Unit { const id = decl.name - const subscope = UninitializedValue({ - id, - qid: id, - ast: decl, - sort: decl.typeName, - parent: scope, // refer to the parent scope - }) + const sid = typeof id === 'string' ? id : ASTUtil.prettyPrint(id) + const subscope = new UninitializedValue(scope.qid, sid, decl) + subscope.parent = scope // refer to the parent scope // link to the parent scope scope.value[id] = subscope return subscope } - /** - * create a function closure - * @param node - * @param scope - * @returns {{vtype: string, fdef: *, id: (*|string), value: {}, decls: {}, parent: *}} - */ - createFuncScope(node: any, scope: any): any { + createFuncScope(node: any, scope: Unit): Unit { // new version uses keyword 'constructor' to refer to ctor, this will cause node.name being null // so tweak name to _CTOR_ to facilitate following evaluating - let funcName = node.id?.name || `` // for anonymous function + let funcName = + node.id?.name || + `` // for anonymous function if (node._meta.isConstructor) { funcName = '_CTOR_' } - let fclos = Object.prototype.hasOwnProperty.call(scope.value, funcName) ? scope.value[funcName] : undefined + let fclos = + Object.prototype.hasOwnProperty.call(scope.value, funcName) && scope.value[funcName]?.vtype === 'fclos' + ? scope.value[funcName] + : undefined // do not override ctor if (fclos && node.parameters) { // overloaded functions // if fclos is from the super, override it - let cdef = fclos.fdef && fclos.fdef.parent + let cdef = fclos.ast.fdef && fclos.ast.fdef.parent while (cdef) { if (cdef.type === 'ClassDefinition') { break } cdef = cdef.parent } - if (cdef && cdef.name !== scope.id) { - const targetQid = scope.qid ? `${scope.qid}.${funcName}` : undefined - fclos = FunctionValue({ - fdef: node, // record the function definition including its type and prototype information + if (cdef && cdef.name !== scope.sid) { + const targetQid = `${scope.qid}.${funcName}` + fclos = new FunctionValue('', { overloaded: [node], sid: funcName, qid: targetQid, decls: {}, - superDef: fclos.fdef, + func: { superDef: fclos.ast.fdef }, parent: scope, ast: node, }) + fclos.ast.fdef = node scope.value[funcName] = fclos if (targetQid) { - let current = scope + let current: Unit | null = scope while (current) { if (current.sid === '') { break } current = current.parent } - current.funcSymbolTable[targetQid] = fclos + if (current) current.context.funcs[QidUnifyUtil.qidUnifyByRemoveAngleAndPrefix(targetQid)] = fclos } return fclos } @@ -253,17 +207,17 @@ class Scope { const len = Array.isArray(node.parameters) ? node.parameters.length : node.parameters.parameters.length const parametersType = this.getParameterType(node) let matched = false - if (!fclos.overloaded) fclos.overloaded = [] - if (funcName === '_CTOR_') { fclos.overloaded.push(node) return fclos } for (let k = 0; k < fclos.overloaded.length; k++) { - const param = fclos.overloaded[k].parameters + const resolved = fclos.overloaded.get(k) + if (!resolved) continue + const param = resolved.parameters const overloadedLen = Array.isArray(param) ? param.length : param.parameters.length - const overloadedParametersType = this.getParameterType(fclos.overloaded[k]) + const overloadedParametersType = this.getParameterType(resolved) if (overloadedLen === len) { let typeMatch = true for (let i = 0; i < overloadedLen; i++) { @@ -273,7 +227,7 @@ class Scope { } } if (typeMatch) { - fclos.overloaded[k] = node + fclos.overloaded.set(k, node) matched = true break } @@ -282,23 +236,26 @@ class Scope { if (!matched) { fclos.overloaded.push(node) } - fclos = _.clone(fclos) - fclos.fdef = node + fclos = lodashCloneWithTag(fclos) fclos.ast = node + fclos.ast.fdef = node fclos.vtype = 'fclos' } else { - const targetQid = scope.qid && funcName ? `${scope.qid}.${funcName}` : undefined - fclos = FunctionValue({ - fdef: node, // record the function definition including its type and prototype information + const sid = + funcName || + `` + const targetQid = `${scope.qid}.${sid}` + fclos = new FunctionValue('', { overloaded: [node], - sid: funcName || '', + sid, qid: targetQid, decls: {}, parent: scope, ast: node, }) + fclos.ast.fdef = node if (targetQid && (this as any).funcSymbolTable && typeof (this as any).funcSymbolTable === 'object') { - ;(this as any).funcSymbolTable[targetQid] = fclos + ;(this as any).funcSymbolTable[QidUnifyUtil.qidUnifyByRemoveAngleAndPrefix(targetQid)] = fclos } // 检查 scope 和 scope.value 的有效性 if (typeof scope === 'object') { @@ -331,15 +288,9 @@ class Scope { return parametersType } - /** - * for debugging - * @param scope - * @param delimit - * @returns {string} - */ - formatScope(scope: any, delimit: any): string { + formatScope(scope: Unit, delimit: number): string { // return JSON.stringify(scope, JSON_scope_replacer_scope, 2); - return (cache = []), JSON.stringify(scope, JSON_scope_replacer_scope, delimit) + return ((cache = []), JSON.stringify(scope, JSON_scope_replacer_scope, delimit)) } /** diff --git a/src/engine/analyzer/common/source-line.ts b/src/engine/analyzer/common/source-line.ts index d86d5238..11f536b9 100644 --- a/src/engine/analyzer/common/source-line.ts +++ b/src/engine/analyzer/common/source-line.ts @@ -2,12 +2,63 @@ export {} const _ = require('lodash') const Config = require('../../../config') const { prettyPrint } = require('../../../util/ast-util') -const { cloneWithDepth } = require('../../../util/clone-util') +const { buildNewCopiedWithTag } = require('../../../util/clone-util') +const QidUnifyUtil = require('../../../util/qid-unify-util') const VariableUtil = require('../../../util/variable-util') /** **************** source code line management *********************** */ -const codeCache = new Map() +// 全局 analyzer 引用,用于访问 sourceCodeCache +let globalAnalyzer: any = null + +/** + * 设置全局 analyzer 实例 + * @param analyzer analyzer 实例 + */ +function setGlobalAnalyzer(analyzer: any) { + globalAnalyzer = analyzer +} + +/** + * 获取全局 analyzer 实例 + * @returns analyzer 实例 + */ +function getGlobalAnalyzer() { + return globalAnalyzer +} + +/** + * 获取 sourceCodeCache(统一使用 analyzer.sourceCodeCache) + * @returns sourceCodeCache Map,存储文件的行数组 + */ +function getSourceCodeCache(): Map { + if (globalAnalyzer && globalAnalyzer.sourceCodeCache instanceof Map) { + return globalAnalyzer.sourceCodeCache + } + // 如果没有全局 analyzer,返回一个临时的 Map(向后兼容) + if (!globalAnalyzer) { + return new Map() + } + // 如果 sourceCodeCache 不是 Map,转换为 Map + if ( + globalAnalyzer.sourceCodeCache && + typeof globalAnalyzer.sourceCodeCache === 'object' && + !Array.isArray(globalAnalyzer.sourceCodeCache) + ) { + const map = new Map() + for (const key in globalAnalyzer.sourceCodeCache) { + if (Object.prototype.hasOwnProperty.call(globalAnalyzer.sourceCodeCache, key)) { + const value = globalAnalyzer.sourceCodeCache[key] + // 兼容处理:如果是字符串,转换为数组 + map.set(key, typeof value === 'string' ? value.split(/\n/) : value) + } + } + globalAnalyzer.sourceCodeCache = map + return map + } + return new Map() +} + /** * @@ -19,10 +70,14 @@ const codeCache = new Map() */ function addSrcLineInfo(val: any, node: any, sourcefile: any, tag: any, affectedNodeName: any) { if (!val) return val + let sig = '' + if (node.loc?.sourcefile && typeof node.loc?.sourcefile === 'string') { + sig = `${node.loc?.sourcefile.substring((node.loc?.sourcefile.lastIndexOf('/') || 0) + 1, node.loc?.sourcefile.lastIndexOf('.'))}_${node.loc?.start?.line}_${node.loc?.start?.column}_${node.loc?.end?.line}_${node.loc?.end?.column}` + } if (Array.isArray(val)) { let arrayHasTag = false for (const eachVal of val) { - if ((eachVal as any).hasTagRec) { + if ((eachVal as any).taint?.isTaintedRec) { arrayHasTag = true break } @@ -30,75 +85,55 @@ function addSrcLineInfo(val: any, node: any, sourcefile: any, tag: any, affected if (!arrayHasTag) { return val } - const new_val = _.clone(val) - for (const eachVal of new_val) { - if (eachVal.trace) { - const { trace } = eachVal - if (trace.length > 0) { - const last_line = trace[trace.length - 1] - if (last_line.file === sourcefile && last_line.line === node.loc.start?.line && last_line.tag === tag) - trace.pop() - } - const start_line = node.loc.start?.line - const end_line = node.loc.end?.line - const tline = start_line === end_line ? start_line : _.range(start_line, end_line + 1) - eachVal.trace.push({ file: sourcefile, line: tline, node, tag, affectedNodeName }) - } else { - const start_line = node.loc.start?.line - const end_line = node.loc.end?.line - const tline = start_line === end_line ? start_line : _.range(start_line, end_line + 1) - eachVal.trace = [ - { - file: sourcefile, - line: tline, - node, - tag, - affectedNodeName, - }, - ] - } - processFieldAndArguments(eachVal, eachVal, 0, []) + // 添加copied主要是为了生成新的符号值,避免覆盖原有的表项,这个跟符号值树使用内存维护有区别 + const newVal = buildNewCopiedWithTag(globalAnalyzer, val, sig) + // @ts-ignore + newVal.value = val.value + for (const eachVal of newVal) { + const start_line = node.loc.start?.line + const end_line = node.loc.end?.line + const tline = start_line === end_line ? start_line : _.range(start_line, end_line + 1) + const traceItem = { file: sourcefile, line: tline, node, tag, affectedNodeName } + + eachVal.taint.dedupLastTrace(sourcefile, node.loc.start?.line, tag) + + // Pass traceItem to processFieldAndArguments for delayed addition + processFieldAndArguments(eachVal, eachVal, 0, [], node, traceItem) } - return new_val + return newVal } - if (!val.hasTagRec || !sourcefile) return val + if (!val.taint?.isTaintedRec || !sourcefile) return val - const { trace } = val - if (trace) { - if (trace.length > 0) { - const last_line = trace[trace.length - 1] - if (last_line.file === sourcefile && last_line.line === node.loc.start?.line && last_line.tag === tag) trace.pop() - } + const start_line = node.loc.start?.line + const end_line = node.loc.end?.line + const tline = start_line === end_line ? start_line : _.range(start_line, end_line + 1) + const traceItem = { file: sourcefile, line: tline, node, tag, affectedNodeName } + + if (val.taint.hasTraces()) { + val.taint.dedupLastTrace(sourcefile, node.loc.start?.line, tag) - let new_val + let newVal if (Config.shareSourceLineSet) { - new_val = val + newVal = val } else { - new_val = _.clone(val) - new_val.trace = _.clone(val.trace) + newVal = buildNewCopiedWithTag(globalAnalyzer, val, sig) + newVal.value = val.value } - const start_line = node.loc.start?.line - const end_line = node.loc.end?.line - const tline = start_line === end_line ? start_line : _.range(start_line, end_line + 1) - new_val.trace.push({ file: sourcefile, line: tline, node, tag, affectedNodeName }) - processFieldAndArguments(new_val, new_val, 0, []) - return new_val + // CRITICAL: If traceItem exists and val has tags, add it to val FIRST + // This handles the case where val itself has tags (first call where val === res) + if (traceItem && newVal.taint?.hasTags()) { + newVal.taint.addTraceToAllTags(traceItem) + } + // Pass traceItem to processFieldAndArguments for delayed addition + processFieldAndArguments(newVal, newVal, 0, [], node, traceItem) + return newVal } - const new_val = _.clone(val) - const start_line = node.loc.start?.line - const end_line = node.loc.end?.line - const tline = start_line === end_line ? start_line : _.range(start_line, end_line + 1) - new_val.trace = [ - { - file: sourcefile, - line: tline, - node, - tag, - affectedNodeName, - }, - ] - processFieldAndArguments(new_val, new_val, 0, []) - return new_val + const newVal = buildNewCopiedWithTag(globalAnalyzer, val, sig) + newVal.value = val.value + + // Pass traceItem to processFieldAndArguments for delayed addition + processFieldAndArguments(newVal, newVal, 0, [], node, traceItem) + return newVal } /** @@ -107,22 +142,25 @@ function addSrcLineInfo(val: any, node: any, sourcefile: any, tag: any, affected * @param res * @param stack * @param visited + * @param node + * @param traceItem - The trace item to be added during recursion */ -function processFieldAndArguments(val: any, res: any, stack: any, visited: any[]) { +function processFieldAndArguments(val: any, res: any, stack: any, visited: any[], node: any, traceItem?: any) { if (visited.includes(val)) { return } + const sig = `${node.loc?.sourcefile.substring((node.loc?.sourcefile.lastIndexOf('/') || 0) + 1, node.loc?.sourcefile.lastIndexOf('.'))}_${node.loc?.start?.line}_${node.loc?.start?.column}_${node.loc?.end?.line}_${node.loc?.end?.column}` + for (const a of visited) { if ( a.vtype !== 'union' && a.vtype !== 'BVT' && a.vtype === val.vtype && - a._sid === val._sid && - a._qid === val._qid && - a._id === val._id && - a.ast === val.ast && + a.sid === val.sid && + a.logicalQid === val.logicalQid && + a.ast?.node === val.ast?.node && a.type === val.type && - a.hasTagRec === val.hasTagRec + a.taint?.isTaintedRec === val.taint?.isTaintedRec ) { return } @@ -131,293 +169,153 @@ function processFieldAndArguments(val: any, res: any, stack: any, visited: any[] if (stack >= 20) { return } - if (!Array.isArray(res.trace)) { + + // Check if val needs processing + if (!val.taint?.isTaintedRec) { return } - if (typeof val.hasTagRec !== 'undefined' && !val.hasTagRec) { + + // Check if there's anything to propagate: res has traces OR traceItem exists + // Don't return early just because res has no traces - traceItem might need to propagate to children + if (!res.taint.hasTraces() && !traceItem) { return } - if ( - typeof val?.field !== 'undefined' && - (Array.isArray(val?.field) || Object.getOwnPropertyNames(val?.field).length !== 0) && - val.hasTagRec + if (val.taint?.isTaintedRec && val.vtype === 'BVT') { + const childKeys = Object.keys(val.value) + for (const key of childKeys) { + const arg = val.getChild(key) + if (arg == null) continue + if (arg.taint?.isTaintedRec) { + let hasChange = false + if (arg.taint?.hasTags()) { + const argCopy = buildNewCopiedWithTag(globalAnalyzer, arg, sig) + argCopy.taint.propagateTraceFrom(res.taint, traceItem) + val.setChild(key, argCopy) + hasChange = true + } + if (hasChange) { + processFieldAndArguments(val.getChild(key), res, stack + 1, visited, node, traceItem) + } else { + processFieldAndArguments(arg, res, stack + 1, visited, node, traceItem) + } + } + } + } else if ( + typeof val?._field !== 'undefined' && + (Array.isArray(val?._field) || Object.getOwnPropertyNames(val?._field).length !== 0) && + val.taint?.isTaintedRec ) { - if (Array.isArray(val.field)) { - for (const argI in val.field) { - const arg = val.field[argI] - if (arg.hasTagRec) { + if (Array.isArray(val._field)) { + for (const argI in val._field) { + const arg = val.getFieldValue(argI) + if (arg?.taint?.isTaintedRec) { let hasChange = false - if (Array.isArray(arg.trace) && VariableUtil.isNotEmpty(arg._tags)) { - const arg_copy = cloneWithDepth(arg, 2) - for (const argT in res.trace) { - let flag = 1 - for (const tt in arg_copy.trace) { - if ( - arg_copy.trace[tt].file === res.trace[argT].file && - arg_copy.trace[tt].tag === res.trace[argT].tag && - JSON.stringify(arg_copy.trace[tt].line) === JSON.stringify(res.trace[argT].line) - ) { - if ( - arg_copy.trace[tt]?.affectedNodeName?.includes('__tmp') && - !res.trace[argT]?.affectedNodeName?.includes('__tmp') - ) { - arg_copy.trace[tt].affectedNodeName = res.trace[argT]?.affectedNodeName - } - flag = 0 - break - } - } - if (flag) { - arg_copy.trace.push(res.trace[argT]) - } - } - val.field[argI] = arg_copy + if (arg.taint?.hasTags()) { + const argCopy = buildNewCopiedWithTag(globalAnalyzer, arg, sig) + argCopy.taint.propagateTraceFrom(res.taint, traceItem) + val.setFieldValue(argI, argCopy) hasChange = true } if (hasChange) { - processFieldAndArguments(val.field[argI], res, stack + 1, visited) + processFieldAndArguments(val.getFieldValue(argI), res, stack + 1, visited, node, traceItem) } else { - processFieldAndArguments(arg, res, stack + 1, visited) + processFieldAndArguments(arg, res, stack + 1, visited, node, traceItem) } } } - } else { - for (const key in val.field) { - if (Object.prototype.hasOwnProperty.call(val.field, key)) { - const arg = val.field[key] - if (typeof arg === 'undefined') { - continue + } else if (val.members) { + for (const key of val.members.keys()) { + const arg = val.members.get(key) + if (typeof arg === 'undefined' || arg === null || !arg.taint) { + continue + } + if (arg.taint?.isTaintedRec) { + let hasChange = false + if (arg.taint?.hasTags()) { + const argCopy = buildNewCopiedWithTag(globalAnalyzer, arg, sig) + argCopy.taint.propagateTraceFrom(res.taint, traceItem) + val.members.set(key, argCopy) + hasChange = true } - if (arg.hasTagRec) { - let hasChange = false - if (Array.isArray(arg.trace) && VariableUtil.isNotEmpty(arg._tags)) { - const arg_copy = cloneWithDepth(arg, 2) - for (const argT in res.trace) { - let flag = 1 - for (const tt in arg_copy.trace) { - if ( - arg_copy.trace[tt].file === res.trace[argT].file && - arg_copy.trace[tt].tag === res.trace[argT].tag && - JSON.stringify(arg_copy.trace[tt].line) === JSON.stringify(res.trace[argT].line) - ) { - if ( - arg_copy.trace[tt]?.affectedNodeName?.includes('__tmp') && - !res.trace[argT]?.affectedNodeName?.includes('__tmp') - ) { - arg_copy.trace[tt].affectedNodeName = res.trace[argT].affectedNodeName - } - flag = 0 - break - } - } - if (flag) { - arg_copy.trace.push(res.trace[argT]) - } - } - if (val.vtype === 'BVT') { - val.value = { [key]: arg_copy } - } else { - val.field[key] = arg_copy - } - hasChange = true - } - if (hasChange) { - processFieldAndArguments(val.field[key], res, stack + 1, visited) - } else { - processFieldAndArguments(arg, res, stack + 1, visited) - } + if (hasChange) { + processFieldAndArguments(val.members.get(key), res, stack + 1, visited, node, traceItem) + } else { + processFieldAndArguments(arg, res, stack + 1, visited, node, traceItem) } } } } } - if (val?.hasTagRec && Array.isArray(val?.arguments)) { - for (const argJ in val.arguments) { - const arg = val.arguments[argJ] + if (val?.taint?.isTaintedRec && Array.isArray(val?.arguments)) { + const argsSnapshot = val.arguments + for (let argIdx = 0; argIdx < argsSnapshot.length; argIdx++) { + const arg = argsSnapshot[argIdx] if (typeof arg === 'undefined' || arg === null) { continue } try { - if (arg.hasTagRec) { + if (arg.taint?.isTaintedRec) { let hasChange = false - if (Array.isArray(arg.trace) && VariableUtil.isNotEmpty(arg._tags)) { - const arg_copy = cloneWithDepth(arg, 2) - for (const argT in res.trace) { - let flag = 1 - for (const tt in arg_copy.trace) { - if ( - arg_copy.trace[tt].file === res.trace[argT].file && - arg_copy.trace[tt].tag === res.trace[argT].tag && - JSON.stringify(arg_copy.trace[tt].line) === JSON.stringify(res.trace[argT].line) - ) { - if ( - arg_copy.trace[tt]?.affectedNodeName?.includes('__tmp') && - !res.trace[argT]?.affectedNodeName?.includes('__tmp') - ) { - arg_copy.trace[tt].affectedNodeName = res.trace[argT].affectedNodeName - } - flag = 0 - break - } - } - if (flag) { - arg_copy.trace.push(res.trace[argT]) - } - } - val.arguments[argJ] = arg_copy + if (arg.taint?.hasTags()) { + const argCopy = buildNewCopiedWithTag(globalAnalyzer, arg, sig) + argCopy.taint.propagateTraceFrom(res.taint, traceItem) + const currentArgs = val.arguments + currentArgs[argIdx] = argCopy + val.arguments = currentArgs hasChange = true } if (hasChange) { - processFieldAndArguments(val.arguments[argJ], res, stack + 1, visited) + processFieldAndArguments(val.arguments[argIdx], res, stack + 1, visited, node, traceItem) } else { - processFieldAndArguments(arg, res, stack + 1, visited) + processFieldAndArguments(arg, res, stack + 1, visited, node, traceItem) } } } catch (e) {} } } - if (val?.left?.hasTagRec) { - if ( - VariableUtil.isNotEmpty(val.left._tags) && - typeof val.left.trace !== 'undefined' && - Array.isArray(val.left.trace) - ) { - const arg = val.left - const left_copy = cloneWithDepth(arg, 2) - for (const argT in res.trace) { - let flag = 1 - for (const tt in left_copy.trace) { - if ( - left_copy.trace[tt].file === res.trace[argT].file && - left_copy.trace[tt].tag === res.trace[argT].tag && - JSON.stringify(left_copy.trace[tt].line) === JSON.stringify(res.trace[argT].line) - ) { - if ( - left_copy?.trace[tt]?.affectedNodeName?.includes('__tmp') && - !res.trace[argT]?.affectedNodeName?.includes('__tmp') - ) { - left_copy.trace[tt].affectedNodeName = res.trace[argT].affectedNodeName - } - flag = 0 - break - } - } - if (flag) { - left_copy.trace.push(res.trace[argT]) - } - } - val.left = left_copy + if (val?.left?.taint?.isTaintedRec) { + if (val.left.taint?.hasTags()) { + const leftCopy = buildNewCopiedWithTag(globalAnalyzer, val.left, sig) + leftCopy.taint.propagateTraceFrom(res.taint, traceItem) + val.left = leftCopy } - processFieldAndArguments(val.left, res, stack + 1, visited) + processFieldAndArguments(val.left, res, stack + 1, visited, node, traceItem) } - if (val?.right?.hasTagRec) { - if ( - VariableUtil.isNotEmpty(val.right._tags) && - typeof val.right.trace !== 'undefined' && - Array.isArray(val.right.trace) - ) { - const arg = val.right - const right_copy = cloneWithDepth(arg, 2) - for (const argT in res.trace) { - let flag = 1 - for (const tt in right_copy.trace) { - if ( - right_copy.trace[tt].file === res.trace[argT].file && - right_copy.trace[tt].tag === res.trace[argT].tag && - JSON.stringify(right_copy.trace[tt].line) === JSON.stringify(res.trace[argT].line) - ) { - if ( - right_copy?.trace[tt]?.affectedNodeName?.includes('__tmp') && - !res.trace[argT]?.affectedNodeName?.includes('__tmp') - ) { - right_copy.trace[tt].affectedNodeName = res.trace[argT]?.affectedNodeName - } - flag = 0 - break - } - } - if (flag) { - right_copy.trace.push(res.trace[argT]) - } - } - val.right = right_copy + if (val?.right?.taint?.isTaintedRec) { + if (val.right.taint?.hasTags()) { + const rightCopy = buildNewCopiedWithTag(globalAnalyzer, val.right, sig) + rightCopy.taint.propagateTraceFrom(res.taint, traceItem) + val.right = rightCopy } - processFieldAndArguments(val.right, res, stack + 1, visited) + processFieldAndArguments(val.right, res, stack + 1, visited, node, traceItem) } - if (val?.expression?.hasTagRec) { - if ( - VariableUtil.isNotEmpty(val.expression._tags) && - typeof val.expression.trace !== 'undefined' && - Array.isArray(val.expression.trace) - ) { - const arg = val.expression - const expression_copy = cloneWithDepth(arg, 2) - for (const argT in res.trace) { - let flag = 1 - for (const tt in expression_copy.trace) { - if ( - expression_copy.trace[tt].file === res.trace[argT].file && - expression_copy.trace[tt].tag === res.trace[argT].tag && - JSON.stringify(expression_copy.trace[tt].line) === JSON.stringify(res.trace[argT].line) - ) { - if ( - expression_copy.trace[tt]?.affectedNodeName?.includes('__tmp') && - !res.trace[argT]?.affectedNodeName?.includes('__tmp') - ) { - expression_copy.trace[tt].affectedNodeName = res.trace[argT]?.affectedNodeName - } - flag = 0 - break - } - } - if (flag) { - expression_copy.trace.push(res.trace[argT]) - } - } - val.expression = expression_copy + if (val?.expression?.taint?.isTaintedRec) { + if (val.expression.taint?.hasTags()) { + const expressionCopy = buildNewCopiedWithTag(globalAnalyzer, val.expression, sig) + expressionCopy.taint.propagateTraceFrom(res.taint, traceItem) + val.expression = expressionCopy } - processFieldAndArguments(val.expression, res, stack + 1, visited) + processFieldAndArguments(val.expression, res, stack + 1, visited, node, traceItem) } - if (val?.children) { + if (val?.children && val.vtype !== 'BVT') { for (const key in val.children) { if (Object.prototype.hasOwnProperty.call(val.children, key)) { const children = val.children[key] if (typeof children === 'undefined') { continue } - if (children.hasTagRec) { + if (children.taint?.isTaintedRec) { let hasChange = false - if (Array.isArray(children.trace) && VariableUtil.isNotEmpty(children._tags)) { - const children_copy = cloneWithDepth(children, 2) - for (const argT in res.trace) { - let flag = 1 - for (const tt in children_copy.trace) { - if ( - children_copy.trace[tt].file === res.trace[argT].file && - children_copy.trace[tt].tag === res.trace[argT].tag && - JSON.stringify(children_copy.trace[tt].line) === JSON.stringify(res.trace[argT].line) - ) { - if ( - children_copy.trace[tt]?.affectedNodeName?.includes('__tmp') && - !res.trace[argT]?.affectedNodeName?.includes('__tmp') - ) { - children_copy.trace[tt].affectedNodeName = res.trace[argT].affectedNodeName - } - flag = 0 - break - } - } - if (flag) { - children_copy.trace.push(res.trace[argT]) - } - } - val.field[key] = children_copy + if (children.taint?.hasTags()) { + const childrenCopy = buildNewCopiedWithTag(globalAnalyzer, children, sig) + childrenCopy.taint.propagateTraceFrom(res.taint, traceItem) + val.children[key] = childrenCopy hasChange = true } if (hasChange) { - processFieldAndArguments(val.field[key], res, stack + 1, visited) + processFieldAndArguments(val.children[key], res, stack + 1, visited, node, traceItem) } else { - processFieldAndArguments(children, res, stack + 1, visited) + processFieldAndArguments(children, res, stack + 1, visited, node, traceItem) } } } @@ -426,50 +324,53 @@ function processFieldAndArguments(val: any, res: any, stack: any, visited: any[] if (val.vtype === 'symbol') { const processMemberAccess = (target: any) => { - const targetRef = val[target] + const targetRef = target === 'object' ? val.object : val.property - if (targetRef.object && targetRef?.object?._sid && targetRef?.object?._sid?.includes('__tmp')) { + if (targetRef.object && targetRef?.object?.sid && targetRef?.object?.sid?.includes('__tmp')) { return } - if (Array.isArray(targetRef.trace) && VariableUtil.isNotEmpty(targetRef._tags)) { - const target_copy = cloneWithDepth(targetRef, 2) - for (const argT in res.trace) { - let flag = 1 - for (const tt in target_copy.trace) { - if ( - target_copy.trace[tt].file === res.trace[argT].file && - target_copy.trace[tt].tag === res.trace[argT].tag && - JSON.stringify(target_copy.trace[tt].line) === JSON.stringify(res.trace[argT].line) - ) { - if ( - target_copy.trace[tt]?.affectedNodeName?.includes('__tmp') && - !res.trace[argT]?.affectedNodeName?.includes('__tmp') - ) { - target_copy.trace[tt].affectedNodeName = res.trace[argT].affectedNodeName - } - flag = 0 - break - } - } - if (flag) { - target_copy.trace.push(res.trace[argT]) - } + if (targetRef.taint?.hasTags()) { + const targetCopy = buildNewCopiedWithTag(globalAnalyzer, targetRef, sig) + targetCopy.taint.propagateTraceFrom(res.taint, traceItem) + if (target === 'object') { + val.object = targetCopy + } else { + val.property = targetCopy } - val[target] = target_copy } - processFieldAndArguments(val[target], res, stack + 1, visited) + const nextTarget = target === 'object' ? val.object : val.property + processFieldAndArguments(nextTarget, res, stack + 1, visited, node, traceItem) } - if (val.object?.hasTagRec) { + if (val.object?.taint && val.object.taint?.isTaintedRec) { processMemberAccess('object') } - if (val.property?.hasTagRec) { + if (val.property?.taint && val.property.taint?.isTaintedRec) { processMemberAccess('property') } } + if (val?.misc_?.buffer && Array.isArray(val.misc_.buffer)) { + for (const bufferI in val.misc_.buffer) { + const buffer = val.misc_.buffer[bufferI] + if (buffer.taint?.isTaintedRec) { + let hasChange = false + if (buffer.taint?.hasTags()) { + const buffer_copy = buildNewCopiedWithTag(globalAnalyzer, buffer, sig) + buffer_copy.taint.propagateTraceFrom(res.taint, traceItem) + val.misc_.buffer[bufferI] = buffer_copy + hasChange = true + } + if (hasChange) { + processFieldAndArguments(val.misc_.buffer[bufferI], res, stack + 1, visited, node, traceItem) + } else { + processFieldAndArguments(buffer, res, stack + 1, visited, node, traceItem) + } + } + } + } } /** @@ -491,7 +392,7 @@ function getNodeTrace(fdef: any, node: any) { sourcefile = src_node?.loc?.sourcefile } - const line = loc.start.line === loc.end.line ? loc.start.line : _.range(loc.start.line, loc.end.line + 1) + const line = loc.start?.line === loc.end?.line ? loc.start?.line : _.range(loc.start?.line, loc.end?.line + 1) if (sourcefile === undefined) { sourcefile = node?.loc?.sourcefile } @@ -504,9 +405,14 @@ function getNodeTrace(fdef: any, node: any) { * @param code */ function storeCode(sourcefile: string, code: string) { + const codeCache = getSourceCodeCache() const fname = sourcefile ? sourcefile.toString() : `_f_${codeCache.size}` const lines = (code as string).split(/\n/) codeCache.set(fname, lines) + // 同时更新 analyzer.sourceCodeCache(如果存在) + if (globalAnalyzer) { + globalAnalyzer.sourceCodeCache = codeCache + } return fname } @@ -551,6 +457,7 @@ function formatSingleTrace(item: any) { } let code if (fname) { + const codeCache = getSourceCodeCache() const flines = codeCache.get(fname) const lines = Array.isArray(item.line) ? item.line : [item.line] for (let i = 0; i < lines.length; i++) { @@ -598,6 +505,7 @@ function getCodeByLocation(loc: any) { const endLine = loc?.end?.line if (sourcefile && startLine && endLine) { + const codeCache = getSourceCodeCache() const lines = codeCache.get(sourcefile) if (lines) { const startIdx = startLine - 1 @@ -615,10 +523,12 @@ function getCodeByLocation(loc: any) { * @param sourcefile */ function getCodeBySourceFile(sourcefile: string) { + const codeCache = getSourceCodeCache() if (sourcefile && codeCache.has(sourcefile)) { - const lines = codeCache.get(sourcefile) as string[] - if (lines.length === 0) return '' - return lines.join('\n') + const lines = codeCache.get(sourcefile) + if (lines && lines.length > 0) { + return lines.join('\n') + } } return '' } @@ -631,4 +541,6 @@ module.exports = { formatSingleTrace, getCodeByLocation, getCodeBySourceFile, + setGlobalAnalyzer, + getGlobalAnalyzer, } diff --git a/src/engine/analyzer/common/sym-address.ts b/src/engine/analyzer/common/sym-address.ts index 674b2ece..3a6c9418 100644 --- a/src/engine/analyzer/common/sym-address.ts +++ b/src/engine/analyzer/common/sym-address.ts @@ -14,9 +14,8 @@ function toStringIDCached(node: any, visited: VisitedMap): string | undefined { visited.set(node, '__') // place holder: unknown id = toStringID(node, visited) - if (id && id.length > 36) id = id.substring(id.length - 36) + if (id && id.length > 100) id = id.substring(id.length - 100) visited.set(node, id || '__') // replace the unknown - node.sid = id return id } @@ -28,8 +27,6 @@ function toStringIDCached(node: any, visited: VisitedMap): string | undefined { function toStringID(node: any, visited: VisitedMap): string | undefined { if (!node) return - if (node.sid) return node.sid - if (Array.isArray(node)) { const sub_ids = node.map((x: any) => toStringIDCached(x, visited)) return sub_ids.join(',') @@ -47,11 +44,11 @@ function toStringID(node: any, visited: VisitedMap): string | undefined { case 'MemberAccess': if (!node.object || node.object.vtype === 'scope') return toStringIDCached(node.property, visited) if (node.computed) return `${toStringIDCached(node.object, visited)}[${toStringIDCached(node.property, visited)}]` - return `[${toStringIDCached(node.object, visited)}.${toStringIDCached(node.property, visited)}]` + return `${toStringIDCached(node.object, visited)}.${toStringIDCached(node.property, visited)}` case 'Noop': { return 'Noop' } - case 'BinaryOperation': { + case 'BinaryExpression': { const left = toStringIDCached(node.left, visited) || '' const right = toStringIDCached(node.right, visited) || '' switch (node.operator) { @@ -94,13 +91,13 @@ function toStringID(node: any, visited: VisitedMap): string | undefined { switch (node.vtype) { case 'object': { let { parent } = node - let { id } = node + let { sid } = node while (parent && parent.vtype !== 'scope' && parent.vtype !== 'fclos' && !parent.type) { - id = `${toStringIDCached(parent, visited)}.${id}` + sid = `${toStringIDCached(parent, visited)}.${sid}` parent = parent.parent } - if (parent && parent.vtype === 'fclos') id = `${parent.id}.${id}` - return id + if (parent && parent.vtype === 'fclos') sid = `${parent.sid}.${sid}` + return sid } case 'union': { let id = '{' @@ -125,49 +122,10 @@ function toStringID(node: any, visited: VisitedMap): string | undefined { } } -/** - * whether two values, e.g. two symbolic expressions, are equivalent - * @param val1 - * @param val2 - * @returns {*} - * TODO - */ -function isSameValueSymAddress(val1: any, val2: any): any { - if (val1 === val2) return true - if (!val1 || !val2) return false - - switch (val1.type) { - case 'MemberAccess': - return ( - isSameValueSymAddress(val1.expression, val2.expression) && isSameValueSymAddress(val1.property, val2.property) - ) - case 'Identifier': - case 'Parameter': - if (val2.type) return val1.name === val2.name - case 'Literal': - return val1.value === val2.value - default: - return false - } - switch (val1.vtype) { - case 'object': - if (val1.id !== val2.id) return false - return isSameValueSymAddress(val1.parent, val2.parent) - case 'scope': - return val1.id === val2.id - } - return false -} - // *** -const symAddress = { +export = { toStringID(node: any) { return toStringIDCached(node, new Map()) }, - - isSameValue: isSameValueSymAddress, } - -module.exports = symAddress -export default symAddress diff --git a/src/engine/analyzer/common/symbol-table-interface.ts b/src/engine/analyzer/common/symbol-table-interface.ts new file mode 100644 index 00000000..02600567 --- /dev/null +++ b/src/engine/analyzer/common/symbol-table-interface.ts @@ -0,0 +1,58 @@ +/** + * 符号表管理器接口:定义符号表管理器的统一接口 + * SymbolTableManager 和 TemporarySymbolTableManager 都应该实现此接口 + */ +export interface ISymbolTableManager { + /** + * 计算 Unit 的 UUID + * @param unit Unit 对象 + * @param qidSuffix 方便计算qid修改时新的uuid + * @returns UUID,如果无法计算则返回 null + */ + calculateUUID(unit: any, qidSuffix?: string): string | null + + /** + * 注册 Unit 对象并返回其 UUID + * @param unit Unit 对象 + * @param needUpdate 是否需要更新引用(可选) + * @returns Unit 对象的 UUID + */ + register(unit: any, needUpdate?: boolean): string | null + + /** + * 根据 UUID 获取 Unit 对象 + * @param uuid Unit 对象的 UUID + * @returns Unit 对象,如果不存在则返回 null + */ + get(uuid: string | null | undefined): any + + /** + * 检查 UUID 是否存在 + * @param uuid Unit 对象的 UUID + * @returns 是否存在 + */ + has(uuid: string | null | undefined): boolean + + /** + * 删除 Unit 对象 + * @param uuid Unit 对象的 UUID + */ + delete(uuid: string | null | undefined): void + + /** + * 清空所有 Unit 对象 + */ + clear(): void + + /** + * 获取已注册的 Unit 对象数量 + * @returns 对象数量 + */ + size(): number + + /** + * 获取符号表的 Map 对象 + * @returns 符号表的 Map + */ + getMap(): Map +} diff --git a/src/engine/analyzer/common/symbol-table-manager.ts b/src/engine/analyzer/common/symbol-table-manager.ts new file mode 100644 index 00000000..0dfca14e --- /dev/null +++ b/src/engine/analyzer/common/symbol-table-manager.ts @@ -0,0 +1,144 @@ +import { yasaError } from "../../../util/format-util" + +const { md5 } = require('../../../util/hash-util') +const { yasaWarning } = require('../../../util/format-util') +/** + * 符号表管理器:管理符号表,负责计算 UUID、注册 Unit 对象等操作 + * 用于降低内存占用,parent 和 field 中只存储 UUID,而不是完整的 Unit 对象 + * 实现 ISymbolTableManager 接口 + */ +class SymbolTableManager { + private symbolMap: Map // 符号表:使用 UUID 作为 key 存储 Unit 对象 + + /** + * 构造函数 + */ + constructor() { + this.symbolMap = new Map() + } + + /** + * 计算 Unit 的 UUID + * UUID = md5(astNodehash + valueType + qid) + * valueType 使用 constructor.name(如 FunctionValue/SymbolValue),比 vtype 更精确 + * @param unit Unit 对象 + * @param qidSuffix + * @returns UUID,如果无法计算则返回 null + */ + calculateUUID(unit: any, qidSuffix?: string): string | null { + if (!unit) { + return null + } + + const parts: string[] = [] + + const astNodehash = unit.ast?.node?._meta?.nodehash || '' + parts.push(astNodehash) + + // Value 类型名(constructor.name),比 vtype 更精确地区分不同 Value 子类 + const valueType = unit.constructor?.name || '' + parts.push(valueType) + + // qid + let qid = unit.qid || '' + if (qidSuffix && qidSuffix !== '') { + qid += qidSuffix + } + parts.push(qid) + + const joined = parts.join('_') + const md5Id = md5(joined) + return `symuuid_${md5Id}` + } + + /** + * 注册 Unit 对象并返回其 UUID + * @param unit Unit 对象 + * @returns Unit 对象的 UUID + */ + register(unit: any): string | null { + if (!unit || typeof unit !== 'object') { + return null + } + + // 计算 UUID + const uuid = this.calculateUUID(unit) + if (!uuid) { + return null + } + + // 碰撞检测:同 uuid 不同对象且不同类型 → 警告 + const existing = this.symbolMap.get(uuid) + if (existing && existing !== unit) { + if (existing.vtype !== unit.vtype || existing.constructor?.name !== unit.constructor?.name) { + yasaError(`UUID cross-type collision: ${uuid} (qid=${unit.qid}, vtype=${unit.vtype}, ctor=${unit.constructor?.name}) overwrites (vtype=${existing.vtype}, ctor=${existing.constructor?.name})`) + } + } + + // 设置 UUID + unit.uuid = uuid + + // 注册到符号表 + this.symbolMap.set(uuid, unit) + + return uuid + } + + /** + * 根据 UUID 获取 Unit 对象 + * @param uuid Unit 对象的 UUID + * @returns Unit 对象,如果不存在则返回 null + */ + get(uuid: string | null | undefined): any { + if (!uuid) { + return null + } + return this.symbolMap.get(uuid) || null + } + + /** + * 检查 UUID 是否存在 + * @param uuid Unit 对象的 UUID + * @returns 是否存在 + */ + has(uuid: string | null | undefined): boolean { + if (!uuid) { + return false + } + return this.symbolMap.has(uuid) + } + + /** + * 删除 Unit 对象(通常不需要,但提供清理功能) + * @param uuid Unit 对象的 UUID + */ + delete(uuid: string | null | undefined): void { + if (uuid) { + this.symbolMap.delete(uuid) + } + } + + /** + * 清空所有 Unit 对象 + */ + clear(): void { + this.symbolMap.clear() + } + + /** + * 获取已注册的 Unit 对象数量 + * @returns 对象数量 + */ + size(): number { + return this.symbolMap.size + } + + /** + * 获取symbolmap + */ + getMap(): Map { + return this.symbolMap + } +} + +module.exports = SymbolTableManager diff --git a/src/engine/analyzer/common/value/ast-binding.ts b/src/engine/analyzer/common/value/ast-binding.ts new file mode 100644 index 00000000..50093690 --- /dev/null +++ b/src/engine/analyzer/common/value/ast-binding.ts @@ -0,0 +1,103 @@ +import { AstRef } from './ast-ref' +import type { AstNodeManager } from './ast-ref' +import type { BaseNode } from '../../../../types/uast' + +/** + * AstBinding - AST 绑定属性组(RefGroup) + * + * 拥有 node/fdef/cdef/decls 的 AstRef 存储, + * getter 自动通过 ASTManager resolve 为 AST 节点对象, + * setter 自动提取 nodehash 创建 AstRef。 + */ +export class AstBinding { + private _nodeRef: AstRef | null = null + private _fdefRef: AstRef | null = null + private _cdefRef: AstRef | null = null + private _declsMap: Map = new Map() + private _owner: { getASTManager(): AstNodeManager | null } + + constructor(owner: { getASTManager(): AstNodeManager | null }) { + this._owner = owner + } + + private _resolve(ref: AstRef | null): BaseNode | null { + if (!ref) return null + const mgr = this._owner.getASTManager() + if (!mgr) return null + try { return mgr.get(ref.hash) ?? null } catch { return null } + } + + private _toRef(astNode: BaseNode | null | undefined): AstRef | null { + if (!astNode) return null + const hash = astNode._meta?.nodehash + if (!hash) { + const mgr = this._owner.getASTManager() + if (!mgr) return null + const registered = mgr.register(astNode) + return registered ? new AstRef(registered) : null + } + const mgr = this._owner.getASTManager() + if (mgr && !mgr.has(hash)) { + mgr.register(astNode) + } + return new AstRef(hash) + } + + get node(): BaseNode | null { return this._resolve(this._nodeRef) } + set node(astNode: BaseNode | null | undefined) { this._nodeRef = this._toRef(astNode ?? null) } + + get fdef(): BaseNode | null { return this._resolve(this._fdefRef) } + set fdef(astNode: BaseNode | null | undefined) { this._fdefRef = this._toRef(astNode ?? null) } + + get cdef(): BaseNode | null { return this._resolve(this._cdefRef) } + set cdef(astNode: BaseNode | null | undefined) { this._cdefRef = this._toRef(astNode ?? null) } + + getDecl(key: string): BaseNode | null { + return this._resolve(this._declsMap.get(key) ?? null) + } + + setDecl(key: string, astNode: BaseNode | null | undefined): void { + if (!astNode) { this._declsMap.delete(key); return } + const ref = this._toRef(astNode) + if (ref) this._declsMap.set(key, ref) + } + + hasDecl(key: string): boolean { + return this._declsMap.has(key) + } + + deleteDecl(key: string): void { + this._declsMap.delete(key) + } + + get declKeys(): string[] { + return Array.from(this._declsMap.keys()) + } + + initDecls(declsObj: Record | null | undefined): void { + if (!declsObj || typeof declsObj !== 'object' || Array.isArray(declsObj)) return + const keys = Object.keys(declsObj) + for (let i = 0; i < keys.length; i++) { + const key = keys[i] + const uastNode = declsObj[key] + let hash: string | null = null + if (typeof uastNode === 'string') { + hash = uastNode + } else if (uastNode && typeof uastNode === 'object') { + hash = uastNode._meta?.nodehash ?? null + } + if (hash) { + this._declsMap.set(key, new AstRef(hash)) + } + } + } + + _clone(newOwner: { getASTManager(): AstNodeManager | null }): AstBinding { + const c = new AstBinding(newOwner) + c._nodeRef = this._nodeRef + c._fdefRef = this._fdefRef + c._cdefRef = this._cdefRef + c._declsMap = new Map(this._declsMap) + return c + } +} diff --git a/src/engine/analyzer/common/value/ast-ref-list.ts b/src/engine/analyzer/common/value/ast-ref-list.ts new file mode 100644 index 00000000..b2a2f937 --- /dev/null +++ b/src/engine/analyzer/common/value/ast-ref-list.ts @@ -0,0 +1,118 @@ +import { AstRef } from './ast-ref' +import type { AstNodeStore } from './ast-ref' +import type { BaseNode } from '../../../../types/uast' + +/** + * AstRefList — 内部存 AstRef[],对外表现像 AST node[] + * + * push/set 自动将 AST node 转为 AstRef 存储 + * get/遍历/length 自动 resolve 为 AST node + * 序列化时通过 _refs 访问内部 AstRef[] + */ +export class AstRefList { + _refs: AstRef[] = [] + private _getASTManager: () => AstNodeStore | null + + constructor(getASTManager: () => AstNodeStore | null) { + this._getASTManager = getASTManager + } + + get length(): number { + return this._refs.length + } + + set length(val: number) { + this._refs.length = val + } + + get(index: number): BaseNode | undefined { + const ref = this._refs[index] + if (!ref) return undefined + const am = this._getASTManager() + return am ? ref.resolve(am) ?? undefined : undefined + } + + push(...nodes: (BaseNode | AstRef)[]): number { + for (const node of nodes) { + if (node instanceof AstRef) { + this._refs.push(node) + } else { + const ref = AstRef.fromNode(node) + if (ref) this._refs.push(ref) + } + } + return this._refs.length + } + + set(index: number, node: BaseNode | AstRef): void { + const ref = node instanceof AstRef ? node : AstRef.fromNode(node) + if (ref && index >= 0 && index < this._refs.length) { + this._refs[index] = ref + } + } + + [Symbol.iterator](): Iterator { + const am = this._getASTManager() + const refs = this._refs + let i = 0 + return { + next(): IteratorResult { + while (i < refs.length) { + const node = am ? refs[i].resolve(am) : null + i++ + if (node) return { value: node, done: false } + } + return { value: undefined as unknown as BaseNode, done: true } + }, + } + } + + map(fn: (node: BaseNode, index: number) => T): T[] { + const am = this._getASTManager() + const result: T[] = [] + for (let i = 0; i < this._refs.length; i++) { + const node = am ? this._refs[i].resolve(am) : null + if (node) result.push(fn(node, i)) + } + return result + } + + filter(fn: (node: BaseNode, index: number) => boolean): BaseNode[] { + const am = this._getASTManager() + const result: BaseNode[] = [] + for (let i = 0; i < this._refs.length; i++) { + const node = am ? this._refs[i].resolve(am) : null + if (node && fn(node, i)) result.push(node) + } + return result + } + + forEach(fn: (node: BaseNode, index: number) => void): void { + const am = this._getASTManager() + for (let i = 0; i < this._refs.length; i++) { + const node = am ? this._refs[i].resolve(am) : null + if (node) fn(node, i) + } + } + + static from(items: (BaseNode | AstRef | string)[], getASTManager: () => AstNodeStore | null): AstRefList { + const list = new AstRefList(getASTManager) + for (const item of items) { + if (item instanceof AstRef) { + list._refs.push(item) + } else if (typeof item === 'string') { + list._refs.push(new AstRef(item)) + } else { + const ref = AstRef.fromNode(item) + if (ref) list._refs.push(ref) + } + } + return list + } + + _clone(getASTManager: () => AstNodeStore | null): AstRefList { + const copy = new AstRefList(getASTManager) + copy._refs = this._refs.slice() + return copy + } +} diff --git a/src/engine/analyzer/common/value/ast-ref.ts b/src/engine/analyzer/common/value/ast-ref.ts new file mode 100644 index 00000000..69b50348 --- /dev/null +++ b/src/engine/analyzer/common/value/ast-ref.ts @@ -0,0 +1,63 @@ +/** + * AstRef - AST 节点间接引用 + * + * 封装 nodehash 字符串,提供类型安全的 AST 节点引用。 + * resolve() 首次从 ASTManager 获取后缓存。AST 不可变 → 缓存永不失效。 + */ + +import type { BaseNode } from '../../../../types/uast' + +export interface AstNodeStore { + get(hash: string): BaseNode | null | undefined +} + +export interface AstNodeManager extends AstNodeStore { + has(hash: string): boolean + register(ast: BaseNode): string | null +} + +export class AstRef { + readonly hash: string + private _cached: BaseNode | null = null + + constructor(hash: string) { + if (typeof hash !== 'string' || hash.length === 0) { + throw new Error(`[AstRef] Invalid hash: ${hash}`) + } + this.hash = hash + } + + resolve(astManager: AstNodeStore): BaseNode | null { + if (this._cached) return this._cached + if (!astManager) return null + const node = astManager.get(this.hash) ?? null + if (node) this._cached = node + return node + } + + static isAstRef(obj: unknown): obj is AstRef { + return obj instanceof AstRef + } + + static from(hashOrRef: string | AstRef): AstRef { + if (hashOrRef instanceof AstRef) { + return hashOrRef + } + return new AstRef(hashOrRef) + } + + static fromNode(astNode: BaseNode | null | undefined): AstRef | null { + if (!astNode || typeof astNode !== 'object') { + return null + } + const nodehash = (astNode as any)._meta?.nodehash + if (typeof nodehash !== 'string' || nodehash.length === 0) { + return null + } + return new AstRef(nodehash) + } + + toString(): string { + return `AstRef(${this.hash.substring(0, 12)}...)` + } +} diff --git a/src/engine/analyzer/common/value/binary-expr.ts b/src/engine/analyzer/common/value/binary-expr.ts new file mode 100644 index 00000000..a81f8f1f --- /dev/null +++ b/src/engine/analyzer/common/value/binary-expr.ts @@ -0,0 +1,76 @@ +import { ExprValue } from './expr-value' +import { ValueRef } from './value-ref' +import type Unit from './unit' + +interface BinaryExprOptions { + operator?: string + left?: Unit | null + right?: Unit | null + ast?: any + loc?: any + arithAssign?: boolean +} + +/** + * BinaryExprValue - 二元运算表达式(a + b, a > b, ...) + * + * left/right 通过 instance-level own enumerable accessor properties 实现: + * - 内部走 _leftRef/_rightRef (ValueRef) 存储 + * - hasOwnProperty('left') 返回 true(satisfy() 遍历兼容) + * - for...in 可枚举(enumerable: true) + */ +export class BinaryExprValue extends ExprValue { + _leftRef!: ValueRef | null + _rightRef!: ValueRef | null + declare left: Unit | null + declare right: Unit | null + operator: string + arithAssign: boolean + + constructor(upperQid: string, operator: string, left: Unit | null, right: Unit | null, ast: any, loc: any, arithAssign: boolean = false) { + const sid = `` + super(upperQid, { + sid, + exprKind: 'binary', + type: 'BinaryExpression', + ast, + loc, + }) + this.operator = operator + this.arithAssign = arithAssign + Object.defineProperty(this, '_leftRef', { value: this._makeValueRefDirect(left), writable: true, enumerable: false, configurable: true }) + Object.defineProperty(this, '_rightRef', { value: this._makeValueRefDirect(right), writable: true, enumerable: false, configurable: true }) + Object.defineProperty(this, 'left', { + get(this: BinaryExprValue) { return this._leftRef?.resolve(this.getSymbolTable()) ?? null }, + set(this: BinaryExprValue, val: Unit | null) { this._leftRef = val != null ? this._makeValueRefDirect(val) : null }, + enumerable: true, + configurable: true, + }) + Object.defineProperty(this, 'right', { + get(this: BinaryExprValue) { return this._rightRef?.resolve(this.getSymbolTable()) ?? null }, + set(this: BinaryExprValue, val: Unit | null) { this._rightRef = val != null ? this._makeValueRefDirect(val) : null }, + enumerable: true, + configurable: true, + }) + } + + static fromOpts(upperQid: string, opts: BinaryExprOptions): BinaryExprValue { + const o = opts || {} + return new BinaryExprValue( + upperQid, + o.operator || '', + o.left ?? null, + o.right ?? null, + o.ast?.node ?? o.ast, + o.loc, + o.arithAssign || false, + ) + } + + get operands(): (Unit | null)[] { + const ops: (Unit | null)[] = [] + if (this._leftRef) ops.push(this.left) + if (this._rightRef) ops.push(this.right) + return ops + } +} diff --git a/src/engine/analyzer/common/value/bvt.ts b/src/engine/analyzer/common/value/bvt.ts index 4ed6c170..aea9d98b 100644 --- a/src/engine/analyzer/common/value/bvt.ts +++ b/src/engine/analyzer/common/value/bvt.ts @@ -1,101 +1,233 @@ const _ = require('lodash') -const Unit = require('./unit') +import { DataValue } from './data-value' +import { ValueRefMap } from './value-ref-map' +import { ValueRef } from './value-ref' const astUtil = require('../../../../util/ast-util') +const { TaintRecord, NULL_TAINT } = require('./taint-record') + +export interface BVTValueOptions { + sid?: string + qid?: string + children?: Record + parent?: any +} /** - * BVT (Basic Value Type) class + * BVTValue (Branch Value Tree) class + * + * 路径敏感分析的条件分支值 */ -class BVT extends Unit { - children!: Record +export class BVTValue extends DataValue { + private _children!: ValueRefMap + private _cachedChildren: Record | null = null + declare children: Record + + constructor(upperQid: string, sid: string, childrenData: Record) { + const opts: { sid: string; qid?: string } = { sid } + + const childQids: string[] = [] + for (const key in childrenData) { + if (childrenData.hasOwnProperty(key)) { + const child = childrenData[key] + if (child && child.hasOwnProperty('qid') && child.qid) { + childQids.push(child.qid) + } + } + } + if (childQids.length > 0) { + opts.sid = `${sid}.` + opts.qid = `` + } + + super('BVT', upperQid || '', opts) + if (this.taint === NULL_TAINT) this.taint = new TaintRecord(this) + this.taint.markRecursive() + + this._initChildren(childrenData) + } /** - * Constructor for BVT - * @param opts - Options for constructing BVT + * 初始化 _children 和 children 自有访问器属性 + * children 必须是 own enumerable accessor,保证 spread、for...in、Object.keys 兼容 */ - constructor(opts: any) { - super({ - vtype: 'BVT', - ...opts, + _initChildren(source?: Record): void { + Object.defineProperty(this, '_children', { + value: new ValueRefMap(() => this.getSymbolTable()), + writable: true, + enumerable: false, + configurable: true, }) - if (!opts.children) { - this.children = {} + + Object.defineProperty(this, 'children', { + get: () => this._resolveChildren(), + set: (obj: Record) => { + Object.defineProperty(this, '_children', { + value: new ValueRefMap(() => this.getSymbolTable()), + writable: true, + enumerable: false, + configurable: true, + }) + this._cachedChildren = null + if (obj && typeof obj === 'object') { + for (const key in obj) { + if (obj.hasOwnProperty(key)) { + this._children.set(key, obj[key]) + } + } + } + }, + enumerable: true, + configurable: true, + }) + + if (source && typeof source === 'object') { + for (const key in source) { + if (source.hasOwnProperty(key)) { + this._children.set(key, source[key]) + } + } } } - /** - * Get raw value from children - */ - getRawValue(): any[] { - const { children } = this - const tmpArry = Object.values(children).filter((val) => !!val) - return _.uniqWith(tmpArry, _.isEqual) + private _resolveChildren(): Record { + if (!this._children) return {} + if (this._cachedChildren) return this._cachedChildren + const st = this.getSymbolTable() + const result: Record = {} + for (const [key, ref] of this._children._map) { + const resolved = ref.resolve(st) + if (resolved) { + result[key] = resolved + } else if (ref.uuid) { + result[key] = ref.uuid + } else { + result[key] = undefined + } + } + this._cachedChildren = result + return result } - /** - * Check if any child value has a tag recursively - */ - get hasTagRec(): boolean | null { - const values = Object.values(this.value) - return _.isFunction(values?.some) ? values.some((v: any) => v?.hasTagRec) : null + getChild(key: string): any { + return this._children.get(key) } - /** - * Set hasTagRec (uses hasTag utility) - */ - set hasTagRec(value: boolean | null) { - astUtil.hasTag(this, null) + setChild(key: string, value: any): void { + this._children.set(key, value) + this._cachedChildren = null } - /** - * Get the value (children) - */ - get value(): Record { - return this.children + + + static fromOpts(upperQid: string, opts: BVTValueOptions): BVTValue { + const finalOpts = opts || {} + const childrenData = finalOpts.children || {} + const sid = finalOpts.sid || '' + const qid = finalOpts.qid + const bvt = new BVTValue(upperQid, sid, childrenData) + if (qid) { + bvt._qid = qid + } + return bvt } - /** - * Set the value (children) - */ - set value(val: Record) { - this.children = val + override clone(): this { + const copy = super.clone() + if (this._children && typeof this._children._clone === 'function') { + Object.defineProperty(copy, '_children', { + value: this._children._clone(() => copy.getSymbolTable()), + writable: true, + enumerable: false, + configurable: true, + }) + copy._cachedChildren = null + Object.defineProperty(copy, 'children', { + get: () => copy._resolveChildren(), + set: (obj: Record) => { copy.value = obj }, + enumerable: true, + configurable: true, + }) + } + return copy } - /** - * Get trace by tag - * @param tag - Tag to search for - */ - getTrace(tag: any): any { + override cloneAlias(): this { + const copy = super.cloneAlias() + if (this._children && typeof this._children._clone === 'function') { + Object.defineProperty(copy, '_children', { + value: this._children._clone(() => copy.getSymbolTable()), + writable: true, + enumerable: false, + configurable: true, + }) + copy._cachedChildren = null + Object.defineProperty(copy, 'children', { + get: () => copy._resolveChildren(), + set: (obj: Record) => { copy.value = obj }, + enumerable: true, + configurable: true, + }) + } + return copy + } + + override getRawValue(): any[] { + const childrenValues = this._children.entries().map(([_, val]) => val) + const tmpArry = childrenValues.filter((val) => !!val) + return _.uniqWith(tmpArry, _.isEqual) + } + + override get value(): Record { + return this._resolveChildren() + } + + override set value(obj: Record) { + Object.defineProperty(this, '_children', { + value: new ValueRefMap(() => this.getSymbolTable()), + writable: true, + enumerable: false, + configurable: true, + }) + this._cachedChildren = null + Object.defineProperty(this, 'children', { + get: () => this._resolveChildren(), + set: (newObj: Record) => { + this.value = newObj + }, + enumerable: true, + configurable: true, + }) + if (obj && typeof obj === 'object') { + for (const key in obj) { + if (obj.hasOwnProperty(key)) { + this._children.set(key, obj[key]) + } + } + } + } + + override getTrace(tag: any): any { return _.find(this.value, (v: any) => { - if (_.isFunction(v?._tags?.has) && v._tags.has(tag)) { - return v.trace + if (v?.taint.containsTag(tag)) { + return v.taint.getTrace(tag) } }) } - /** - * Get taint info by tag - * @param tag - Tag to search for - */ getTaintInfo(tag: any): { value: any; trace: any } | undefined { const value = _.find(this.value, (v: any) => { - return _.isFunction(v?._tags?.has) && v._tags.has(tag) + return v?.taint.containsTag(tag) }) if (value) { return { value, - trace: value.trace, + trace: value.taint.getTrace(tag), } } } - /** - * Get miscellaneous data by key - * @param key - Key to get misc data - */ - getMisc(key: string): any[] { + override getMisc(key: string): any[] { const values = this.getRawValue() return values.map((val: any) => val.getMisc(key)) } } - -module.exports = BVT diff --git a/src/engine/analyzer/common/value/call-expr.ts b/src/engine/analyzer/common/value/call-expr.ts new file mode 100644 index 00000000..4b3a0c8f --- /dev/null +++ b/src/engine/analyzer/common/value/call-expr.ts @@ -0,0 +1,96 @@ +import { ExprValue } from './expr-value' +import { ValueRef } from './value-ref' +import type Unit from './unit' + +interface CallExprOptions { + callee?: Unit | null + arguments?: (Unit | null)[] + ast?: any + loc?: any + expression?: Unit | null +} + +/** + * CallExprValue - 函数调用表达式(f(a, b)) + * + * callee/arguments/expression: instance-level own enumerable accessor + ValueRef 存储 + * arguments getter 返回 resolved 数组,setter 整体替换 _argumentRefs + */ +export class CallExprValue extends ExprValue { + _calleeRef!: ValueRef | null + _argumentRefs!: (ValueRef | null)[] + _expressionRef!: ValueRef | null + declare callee: Unit | null + declare arguments: (Unit | null)[] + declare expression: Unit | null + + constructor(upperQid: string, callee: Unit | null, args: (Unit | null)[], ast: any, loc: any, expression?: Unit | null) { + const sid = `` + super(upperQid, { + sid, + exprKind: 'call', + type: 'FunctionCall', + ast, + loc, + }) + Object.defineProperty(this, '_calleeRef', { value: this._makeValueRefDirect(callee), writable: true, enumerable: false, configurable: true }) + Object.defineProperty(this, '_argumentRefs', { value: (args || []).map((v: Unit | null) => this._makeValueRefDirect(v)), writable: true, enumerable: false, configurable: true }) + + Object.defineProperty(this, 'callee', { + get(this: CallExprValue) { return this._calleeRef?.resolve(this.getSymbolTable()) ?? null }, + set(this: CallExprValue, val: Unit | null) { this._calleeRef = val != null ? this._makeValueRefDirect(val) : null }, + enumerable: true, + configurable: true, + }) + + Object.defineProperty(this, 'arguments', { + get(this: CallExprValue) { + if (!this._argumentRefs) return [] + return this._argumentRefs.map((ref: ValueRef | null) => ref?.resolve(this.getSymbolTable()) ?? null) + }, + set(this: CallExprValue, val: (Unit | null)[]) { + this._argumentRefs = Array.isArray(val) + ? val.map((v: Unit | null) => v != null ? this._makeValueRefDirect(v) : null) + : [] + }, + enumerable: true, + configurable: true, + }) + + if (expression !== undefined) { + Object.defineProperty(this, '_expressionRef', { value: this._makeValueRefDirect(expression), writable: true, enumerable: false, configurable: true }) + Object.defineProperty(this, 'expression', { + get(this: CallExprValue) { return this._expressionRef?.resolve(this.getSymbolTable()) ?? null }, + set(this: CallExprValue, val: Unit | null) { this._expressionRef = val != null ? this._makeValueRefDirect(val) : null }, + enumerable: true, + configurable: true, + }) + } + } + + static fromOpts(upperQid: string, opts: CallExprOptions): CallExprValue { + const o = opts || {} + return new CallExprValue( + upperQid, + o.callee ?? null, + o.arguments || [], + o.ast?.node ?? o.ast, + o.loc, + o.expression ?? null, + ) + } + + get operands(): (Unit | null)[] { + const ops: (Unit | null)[] = [] + if (this._calleeRef) ops.push(this.callee) + if (this._argumentRefs) { + for (const ref of this._argumentRefs) { + if (ref) { + const val = ref.resolve(this.getSymbolTable()) + if (val !== undefined) ops.push(val) + } + } + } + return ops + } +} diff --git a/src/engine/analyzer/common/value/class.ts b/src/engine/analyzer/common/value/class.ts new file mode 100644 index 00000000..8cbdf4ba --- /dev/null +++ b/src/engine/analyzer/common/value/class.ts @@ -0,0 +1,58 @@ +import { Scoped } from './scoped' + +interface ClassValueOptions { + sid?: string + parent?: any + decls?: Record + name?: string + ast?: any + value?: any + field?: any + annotations?: any + modifier?: any + inits?: any +} + +/** + * ClassValue - 类定义 + * + * 继承 ScopeValue(类体是作用域),固定 vtype='class' + */ +export class ClassValue extends Scoped { + // 注意:super 在 Unit 中是 accessor(通过 UUID 查符号表),不能在此重新声明为类属性 + // 注意:annotations/modifier/inits 不能声明为类属性(会覆盖 Unit 构造函数中的赋值) + declare isInterface: boolean + + constructor(upperQid: string, sid: string, parent: any, decls?: Record) { + super(upperQid, { + sid, + vtype: 'class', + parent, + decls: decls || {}, + }) + } + + /** + * 从序列化的 opts 对象恢复(仅用于反序列化) + */ + static override fromOpts(upperQid: string, opts: ClassValueOptions): ClassValue { + const o = opts || {} + const cv = new ClassValue(upperQid, o.sid || '', o.parent, o.decls) + // 恢复其他属性(通过赋值而非构造函数,因为这些是 Unit 的 accessor) + if (o.name !== undefined) cv.name = o.name + if (o.ast !== undefined) cv.ast = o.ast?.node ?? o.ast + if (o.value !== undefined) cv.value = o.value + if (o.field !== undefined) cv.value = o.field + if (o.annotations !== undefined) cv.annotations = o.annotations + if (o.modifier !== undefined) cv.modifier = o.modifier + if (o.inits !== undefined) cv.inits = o.inits + return cv + } + + /** + * 从 SymbolValue (vtype='class') 创建 ClassValue,复制所有属性 + */ + static fromSymbolValue(symbolValue: ClassValueOptions & { qid?: string }): ClassValue { + return ClassValue.fromOpts(symbolValue.qid || '', symbolValue) + } +} diff --git a/src/engine/analyzer/common/value/constructor.ts b/src/engine/analyzer/common/value/constructor.ts deleted file mode 100644 index 1b499d12..00000000 --- a/src/engine/analyzer/common/value/constructor.ts +++ /dev/null @@ -1,81 +0,0 @@ -import * as _ from 'lodash' - -const UnknownValue = require('./unkown') -const ObjectValue = require('./object') -const Scoped = require('./scoped') -const FunctionValue = require('./function') -const UndefinedValue = require('./undefine') -const UninitializedValue = require('./uninit') -const UnionValue = require('./union') -const SymbolValue = require('./symbolic') -const PrimitiveValue = require('./primitive') -const BVT = require('./bvt') -const PackageValue = require('./package') - -const Constructor = { - UnknownValue(opts: Record) { - opts = prepareOpts(opts) - return new UnknownValue(opts) - }, - - ObjectValue(opts: Record) { - opts = prepareOpts(opts) - return new ObjectValue(opts) - }, - - Scoped(opts: Record) { - opts = prepareOpts(opts) - return new Scoped(opts) - }, - - FunctionValue(opts: Record) { - opts = prepareOpts(opts) - return new FunctionValue(opts) - }, - - PackageValue(opts: Record) { - opts = prepareOpts(opts) - return new PackageValue(opts) - }, - - UndefinedValue(opts: Record) { - opts = prepareOpts(opts) - return new UndefinedValue(opts) - }, - - UninitializedValue(opts: Record) { - opts = prepareOpts(opts) - return new UninitializedValue(opts) - }, - - UnionValue(opts: Record) { - opts = prepareOpts(opts) - return new UnionValue(opts) - }, - - SymbolValue(opts: Record) { - opts = prepareOpts(opts) - opts.parent = opts.parent || null - return new SymbolValue(opts) - }, - - PrimitiveValue(opts: Record) { - opts = prepareOpts(opts) - return new PrimitiveValue(opts) - }, - - BVT(opts: Record) { - opts = prepareOpts(opts) - return new BVT(opts) - }, -} - -/** - * Prepare options for constructor - * @param opts - Options to prepare - */ -function prepareOpts(opts: Record): any { - return opts || {} -} - -module.exports = Constructor diff --git a/src/engine/analyzer/common/value/data-value.ts b/src/engine/analyzer/common/value/data-value.ts new file mode 100644 index 00000000..91fbc275 --- /dev/null +++ b/src/engine/analyzer/common/value/data-value.ts @@ -0,0 +1,68 @@ +import { ValueBase } from './value-base' + +/** + * 运行时类型信息接口 + * + * 用于 Java/Go 等静态类型语言的类型推断和传播 + */ +export interface RType { + /** + * 类型名称(如 "PointerType") + */ + type?: string + + /** + * 确定类型:AST Identifier node 或类型字符串 + * + * 通常由 UastSpec.identifier() 生成或直接使用 node.varType.id + */ + definiteType?: any + + /** + * 模糊类型路径(如 "com.example.Foo.bar") + * + * 用于成员访问时的类型路径追踪 + */ + vagueType?: string + + /** + * 指针类型的元素类型(Go 特有) + */ + element?: any +} + +/** + * DataValue - 有确定类型的计算结果 + * + * 表示具有明确类型和值的数据(与 SentinelValue 的占位符、ExprValue 的未求值相对) + * + * 子类: + * - PrimitiveValue: 基本类型字面量 + * - BVTValue: 分支值树 + * - UnionValue: 联合值 + * - TypedValue: 仅有类型信息 + * - TaintedValue: 携带污点标记 + * - SpreadValue: 展开运算结果 + */ +export abstract class DataValue extends ValueBase { + /** + * AST 节点类型(DataValue 必需) + */ + declare type: string + + /** + * 运行时类型信息(DataValue 必需) + */ + declare rtype: RType + + constructor(vtype: string, upperQidOrOpts?: string | any, opts?: any) { + // 抽象基类构造函数:支持两种调用方式 + // 1. super(vtype, upperQid, opts) - 子类常用 + // 2. super(vtype, opts) - 可选 + if (typeof upperQidOrOpts === 'string') { + super(vtype, upperQidOrOpts, opts) + } else { + super(vtype, upperQidOrOpts) + } + } +} diff --git a/src/engine/analyzer/common/value/entity-value.ts b/src/engine/analyzer/common/value/entity-value.ts new file mode 100644 index 00000000..2e51e155 --- /dev/null +++ b/src/engine/analyzer/common/value/entity-value.ts @@ -0,0 +1,121 @@ +import { ValueBase, SpringCtx, RuntimeState } from './value-base' +import { ValueRefMap } from './value-ref-map' +import { RAW_TARGET } from './symbols' + +export abstract class EntityValue extends ValueBase { + declare name?: string + declare type?: string + declare rtype?: any + declare spring?: SpringCtx + declare runtime?: RuntimeState + + // 内部属性声明(通过 Object.defineProperty 定义) + protected _members!: ValueRefMap + + constructor(vtype: string, opts?: any) + constructor(vtype: string, upperQid: string, opts: any) + constructor(vtype: string, upperQidOrOpts?: string | any, opts?: any) { + if (typeof upperQidOrOpts === 'string') { + super(vtype, upperQidOrOpts, opts) + } else { + super(vtype, upperQidOrOpts) + } + const finalOpts: any = typeof upperQidOrOpts === 'string' ? (opts || {}) : (upperQidOrOpts || {}) + + const members = new ValueRefMap(() => this.getSymbolTable()) + + // 从 Unit 构造函数设置的 _field 迁移数据到 _members + const unitField = this._field + if (unitField && typeof unitField === 'object') { + const raw = (unitField as any)[RAW_TARGET] || unitField + if (raw && typeof raw === 'object') { + for (const key of Object.keys(raw)) { + const val = raw[key] + if (val != null) members.set(key, val) + } + } + } + + Object.defineProperty(this, '_members', { + value: members, + writable: true, + enumerable: false, + configurable: true, + }) + + // 保持 _field 与 _members Proxy 同步(source-line taint 传播等通过 _field 遍历成员) + this._field = members.getProxy() + + if ('runtime' in finalOpts) this.runtime = finalOpts.runtime + if ('field' in finalOpts) { + const val = finalOpts.field + if (val && typeof val === 'object') { + const raw = val[RAW_TARGET] || val + for (const key of Object.keys(raw)) { + if (raw[key] != null) members.set(key, raw[key]) + } + } + } + if ('fdata' in finalOpts) this.fdata = finalOpts.fdata + if ('id' in finalOpts) this.id = finalOpts.id + } + + get members(): ValueRefMap { + return this._members + } + + override get value(): any { + if (Object.prototype.hasOwnProperty.call(this, 'raw_value')) { + return this.raw_value + } + if (!this._members) { + // 构造阶段或异常路径,回退到基类 _field + return this._field + } + return this._members.getProxy() + } + + override set value(val: any) { + const members = this._members + if (!members) { + // 构造阶段 _members 尚未初始化 + this.raw_value = val + return + } + if (val === members.getProxy()) return + const newOwner = val && typeof val === 'object' && val._owner + if (newOwner && newOwner instanceof ValueRefMap) { + this._members = newOwner + this._field = newOwner.getProxy() + return + } + if (val && typeof val === 'object') { + members.clear() + const raw = val[RAW_TARGET] || val + if (typeof raw === 'object') { + for (const key of Object.keys(raw)) { + if (raw[key] != null) members.set(key, raw[key]) + } + } + } else { + this.raw_value = val + } + } + + protected override _cloneField(copy: any, _fieldValue: any): void { + const originalMembers = this._members + if (originalMembers) { + const clonedMembers = originalMembers._clone(() => copy.getSymbolTable()) + Object.defineProperty(copy, '_members', { + value: clonedMembers, + writable: true, + enumerable: false, + configurable: true, + }) + // _field 保持与 _members Proxy 同步 + copy._field = clonedMembers.getProxy() + } else { + super._cloneField(copy, _fieldValue) + } + } +} diff --git a/src/engine/analyzer/common/value/expr-value.ts b/src/engine/analyzer/common/value/expr-value.ts new file mode 100644 index 00000000..59e3c13b --- /dev/null +++ b/src/engine/analyzer/common/value/expr-value.ts @@ -0,0 +1,49 @@ +import { ValueBase } from './value-base' +import { ValueRef } from './value-ref' +import type Unit from './unit' + +interface ExprValueOptions { + sid?: string + name?: string + type?: string + exprKind?: string + rst?: Unit | null + ast?: any + loc?: any +} + +/** + * ExprValue - 未求值的表达式(延迟计算) + * + * operand 属性通过 getter/setter + ValueRef 存储, + * 外部访问透明 resolve,内部存 UUID,序列化/clone 安全。 + */ +export abstract class ExprValue extends ValueBase { + exprKind: string | undefined + _rstRef!: ValueRef | null + + constructor(upperQidOrOpts?: string | ExprValueOptions, opts?: ExprValueOptions) { + const finalOpts = typeof upperQidOrOpts === 'string' ? (opts || {}) : (upperQidOrOpts || {}) + + if (typeof upperQidOrOpts === 'string') { + super('symbol', upperQidOrOpts, finalOpts) + } else { + super('symbol', finalOpts) + } + + this._rstRef = null + if (finalOpts.exprKind !== undefined) this.exprKind = finalOpts.exprKind + if (finalOpts.rst !== undefined) this.rst = finalOpts.rst + } + + get rst(): Unit | null { + if (!this._rstRef) return null + return this._rstRef.resolve(this.getSymbolTable()) + } + + set rst(val: Unit | null) { + this._rstRef = val != null ? this._makeValueRefDirect(val) : null + } + + abstract get operands(): (Unit | null)[] +} diff --git a/src/engine/analyzer/common/value/function.ts b/src/engine/analyzer/common/value/function.ts index 9181b5ee..15be8677 100644 --- a/src/engine/analyzer/common/value/function.ts +++ b/src/engine/analyzer/common/value/function.ts @@ -1,21 +1,98 @@ -const Scoped = require('./scoped') +import { Scoped } from './scoped' +import type Unit from './unit' +import type { FuncMeta } from './value-base' -interface FunctionValueOptions { - [key: string]: any +export interface FunctionValueOptions { + sid?: string + qid?: string + name?: string + parent?: Unit | null + _this?: Unit | null + exports?: any + ast?: any + fdef?: any + overloaded?: any[] + decls?: Record + execute?: ((...args: any[]) => any) | null + func?: FuncMeta + loc?: any + value?: any + field?: any + _meta?: any + + arguments?: any[] + functionName?: string + decorators?: any[] + id?: any + attribute?: string + filePath?: string + receiverType?: string + params?: any + results?: any + + superDef?: any + jumpLocate?: ((val: any, qid: any, scope: any) => any) | null + inherited?: boolean + typeArguments?: any + typeParams?: any } /** * FunctionValue class */ -module.exports = class FunctionValue extends Scoped { +export class FunctionValue extends Scoped { + declare func?: FuncMeta + declare _isConstructor: boolean + + declare arguments?: any[] + declare functionName?: string + declare decorators?: any[] + declare id?: any + declare attribute?: string + declare filePath?: string + declare receiverType?: string + declare params?: any + declare results?: any + + constructor(upperQidOrOpts?: string | FunctionValueOptions, opts?: FunctionValueOptions) { + const finalOpts = typeof upperQidOrOpts === 'string' ? (opts || {}) : (upperQidOrOpts || {}) + + // Override vtype for FunctionValue + const optsWithVtype = { ...finalOpts, vtype: 'fclos' } + + if (typeof upperQidOrOpts === 'string') { + super(upperQidOrOpts, optsWithVtype) + } else { + super(optsWithVtype) + } + this._isConstructor = false + + // FunctionValue-specific properties + if ('func' in finalOpts) this.func = finalOpts.func + if ('receiverType' in finalOpts) this.receiverType = finalOpts.receiverType + if ('filePath' in finalOpts) this.filePath = finalOpts.filePath + if ('superDef' in finalOpts) this.superDef = finalOpts.superDef + if ('jumpLocate' in finalOpts) this.jumpLocate = finalOpts.jumpLocate + if ('inherited' in finalOpts) this.inherited = finalOpts.inherited + if ('attribute' in finalOpts) this.attribute = finalOpts.attribute + if ('params' in finalOpts) this.params = finalOpts.params + if ('results' in finalOpts) this.results = finalOpts.results + if ('typeArguments' in finalOpts) this.typeArguments = finalOpts.typeArguments + if ('typeParams' in finalOpts) this.typeParams = finalOpts.typeParams + } + /** - * Constructor for FunctionValue - * @param opts - Options for constructing FunctionValue + * 从序列化的 opts 对象恢复 FunctionValue(仅用于反序列化) */ - constructor(opts?: FunctionValueOptions) { - super({ - vtype: 'fclos', - ...opts, - }) + static override fromOpts(upperQid: string, opts: FunctionValueOptions): FunctionValue { + const functionValue = new FunctionValue(upperQid, opts) + // 反序列化时恢复原始 qid + if (opts?.qid) { + functionValue._qid = opts.qid + } + if (opts?.parent) { + functionValue.parent = opts.parent + } + return functionValue } } diff --git a/src/engine/analyzer/common/value/identifier-ref.ts b/src/engine/analyzer/common/value/identifier-ref.ts new file mode 100644 index 00000000..05c83526 --- /dev/null +++ b/src/engine/analyzer/common/value/identifier-ref.ts @@ -0,0 +1,55 @@ +import { ExprValue } from './expr-value' +import type Unit from './unit' + +export interface IdentifierRefOptions { + nameRef?: string + name?: string + sid?: string + ast?: any + loc?: any + refKind?: string + qid?: string + parent?: any +} + +/** + * IdentifierRefValue - 标识符引用(变量名/类型名/标签名) + * 表示无法 resolve 的标识符引用 + */ +export class IdentifierRefValue extends ExprValue { + nameRef: string + refKind?: string + + constructor(upperQid: string, nameRef: string, ast: any, loc: any, refKind?: string) { + super(upperQid, { + sid: nameRef, + exprKind: 'identifier', + type: 'Identifier', + name: nameRef, // 必须通过 opts 传入,Unit 会设置为 own property + ast, + loc, + }) + this.nameRef = nameRef + if (refKind !== undefined) { + this.refKind = refKind + } + } + + /** + * 从序列化的 opts 对象恢复(仅用于反序列化) + */ + static fromOpts(upperQid: string, opts: IdentifierRefOptions): IdentifierRefValue { + const o = opts || {} + return new IdentifierRefValue( + upperQid, + o.nameRef || o.name || o.sid || '', + o.ast?.node ?? o.ast, + o.loc, + o.refKind, + ) + } + + get operands(): (Unit | null)[] { + return [] + } +} diff --git a/src/engine/analyzer/common/value/member-expr.ts b/src/engine/analyzer/common/value/member-expr.ts new file mode 100644 index 00000000..10847d9b --- /dev/null +++ b/src/engine/analyzer/common/value/member-expr.ts @@ -0,0 +1,73 @@ +import { ExprValue } from './expr-value' +import { ValueRef } from './value-ref' +import type Unit from './unit' + +interface MemberExprOptions { + object?: Unit | null + property?: Unit | null + computed?: boolean + ast?: any + loc?: any +} + +/** + * MemberExprValue - 成员访问表达式(a.b, a[b]) + * + * object/property 通过 instance-level own enumerable accessor properties 实现: + * - 内部走 _objectRef/_propertyRef (ValueRef) 存储 + * - hasOwnProperty('object') 返回 true(satisfy() 遍历兼容) + * - for...in 可枚举(enumerable: true) + */ +export class MemberExprValue extends ExprValue { + _objectRef!: ValueRef | null + _propertyRef!: ValueRef | null + declare object: Unit | null + declare property: Unit | null + computed: boolean + + constructor(upperQid: string, object: Unit | null, property: Unit | null, computed: boolean, ast: any, loc: any) { + const propStr = computed ? '[...]' : `.${property?.name || property?.sid || '?'}` + const sid = `` + super(upperQid, { + sid, + exprKind: 'member', + type: 'MemberAccess', + ast, + loc, + }) + this.computed = computed + Object.defineProperty(this, '_objectRef', { value: this._makeValueRefDirect(object), writable: true, enumerable: false, configurable: true }) + Object.defineProperty(this, '_propertyRef', { value: this._makeValueRefDirect(property), writable: true, enumerable: false, configurable: true }) + Object.defineProperty(this, 'object', { + get(this: MemberExprValue) { return this._objectRef?.resolve(this.getSymbolTable()) ?? null }, + set(this: MemberExprValue, val: Unit | null) { this._objectRef = val != null ? this._makeValueRefDirect(val) : null }, + enumerable: true, + configurable: true, + }) + Object.defineProperty(this, 'property', { + get(this: MemberExprValue) { return this._propertyRef?.resolve(this.getSymbolTable()) ?? null }, + set(this: MemberExprValue, val: Unit | null) { this._propertyRef = val != null ? this._makeValueRefDirect(val) : null }, + enumerable: true, + configurable: true, + }) + } + + static fromOpts(upperQid: string, opts: MemberExprOptions): MemberExprValue { + const o = opts || {} + return new MemberExprValue( + upperQid, + o.object ?? null, + o.property ?? null, + o.computed || false, + o.ast?.node ?? o.ast, + o.loc, + ) + } + + get operands(): (Unit | null)[] { + const ops: (Unit | null)[] = [] + if (this._objectRef) ops.push(this.object) + if (this._propertyRef) ops.push(this.property) + return ops + } +} diff --git a/src/engine/analyzer/common/value/object.ts b/src/engine/analyzer/common/value/object.ts index f90289ee..13d710f2 100644 --- a/src/engine/analyzer/common/value/object.ts +++ b/src/engine/analyzer/common/value/object.ts @@ -1,46 +1,89 @@ -const Unit = require('./unit') +import { EntityValue } from './entity-value' +import type Unit from './unit' const astUtil = require('../../../../util/ast-util') +const { TaintRecord, NULL_TAINT } = require('./taint-record') -interface ObjectValueOptions { +export interface ObjectValueOptions { + sid?: string + qid?: string + name?: string _meta?: { type?: any [key: string]: any } - [key: string]: any + parent?: Unit | null + _this?: Unit | null + loc?: any + ast?: any + value?: any + field?: any + + injected?: boolean + keyType?: string + valueType?: string + size?: number + element?: Unit | null + length?: number + node_module?: boolean + + uninit?: boolean + definiteType?: string + vagueType?: string + literalType?: string } /** * ObjectValue class */ -module.exports = class ObjectValue extends Unit { - rtype: any - - _has_tags: boolean | undefined - - /** - * Constructor for ObjectValue - * @param opts - Options for constructing ObjectValue - */ - constructor(opts?: ObjectValueOptions) { - super({ - vtype: 'object', - ...opts, - }) - this.rtype = opts?._meta?.type - } +export class ObjectValue extends EntityValue { + declare injected?: boolean + declare keyType?: string + declare valueType?: string + declare size?: number + declare element?: Unit | null + declare length?: number + declare node_module?: boolean + + constructor(upperQidOrOpts?: string | ObjectValueOptions, opts?: ObjectValueOptions) { + const finalOpts = typeof upperQidOrOpts === 'string' ? (opts || {}) : (upperQidOrOpts || {}) + + if (typeof upperQidOrOpts === 'string') { + super('object', upperQidOrOpts, finalOpts) + } else { + super('object', finalOpts) + } + + this.rtype = finalOpts._meta?.type + // 递归类型必须有独立 TaintRecord(isTaintedRec 需要 _owner) + if (this.taint === NULL_TAINT) this.taint = new TaintRecord(this) + this.taint.markRecursive() - /** - * Check if this object has a tag recursively - */ - get hasTagRec(): boolean { - return astUtil.hasTag(this, null) + // ObjectValue-specific properties + if ('element' in finalOpts) this.element = finalOpts.element + if ('uninit' in finalOpts) this.uninit = finalOpts.uninit + if ('definiteType' in finalOpts) this.definiteType = finalOpts.definiteType + if ('keyType' in finalOpts) this.keyType = finalOpts.keyType + if ('node_module' in finalOpts) this.node_module = finalOpts.node_module + if ('injected' in finalOpts) this.injected = finalOpts.injected + if ('vagueType' in finalOpts) this.vagueType = finalOpts.vagueType + if ('valueType' in finalOpts) this.valueType = finalOpts.valueType + if ('size' in finalOpts) this.size = finalOpts.size + if ('length' in finalOpts) this.length = finalOpts.length + if ('literalType' in finalOpts) this.literalType = finalOpts.literalType } - /** - * Set hasTagRec - * @param val - Value to set - */ - set hasTagRec(val: boolean) { - this._has_tags = val + + + static fromOpts(upperQid: string, opts: ObjectValueOptions): ObjectValue { + const objectValue = new ObjectValue(upperQid, opts) + // 反序列化时恢复原始 qid + if (opts?.qid) { + objectValue._qid = opts.qid + } + if (opts?.parent) { + objectValue.parent = opts.parent + } + return objectValue } + } diff --git a/src/engine/analyzer/common/value/package.ts b/src/engine/analyzer/common/value/package.ts index 5dfcdd61..d22b5ef9 100644 --- a/src/engine/analyzer/common/value/package.ts +++ b/src/engine/analyzer/common/value/package.ts @@ -1,16 +1,53 @@ -const Scoped = require('./scoped') +import { Scoped } from './scoped' +import type Unit from './unit' const { Errors } = require('../../../../util/error-code') -module.exports = class PackageValue extends Scoped { +export interface PackageValueOptions { + sid?: string + qid?: string + name?: string + vtype?: string + parent?: Unit | null + _this?: Unit | null + loc?: any + ast?: any + value?: any + field?: any + _meta?: any +} + +/** + * PackageValue class + */ +export class PackageValue extends Scoped { + declare packageProcessed?: boolean + + constructor(upperQidOrOpts: string | PackageValueOptions, opts?: PackageValueOptions) { + const finalOpts = typeof upperQidOrOpts === 'string' ? (opts || {}) : (upperQidOrOpts || {}) + + // Override vtype for PackageValue + const optsWithVtype = { ...finalOpts, vtype: 'package' } + + if (typeof upperQidOrOpts === 'string') { + super(upperQidOrOpts, optsWithVtype) + } else { + super(optsWithVtype) + } + } + /** - * - * @param opts + * 从序列化的 opts 对象恢复 PackageValue(仅用于反序列化) */ - constructor(opts: any) { - super({ - vtype: 'package', - ...opts, - }) + static override fromOpts(upperQid: string, opts: PackageValueOptions): PackageValue { + const packageValue = new PackageValue(upperQid, opts) + // 反序列化时恢复原始 qid + if (opts?.qid) { + packageValue._qid = opts.qid + } + if (opts?.parent) { + packageValue.parent = opts.parent + } + return packageValue } /** @@ -24,9 +61,7 @@ module.exports = class PackageValue extends Scoped { try { Errors.IllegalUse('getSubPackage ids should not be empty') } catch (e) {} - return new PackageValue({ - vtype: 'unknown', - }) + return undefined } if (!Array.isArray(ids)) { @@ -36,24 +71,24 @@ module.exports = class PackageValue extends Scoped { let fval: any = this for (let i = 0; i < ids.length; i++) { const fname = ids[i] - let sub_fval: any - if (Object.prototype.hasOwnProperty.call(fval.field, fname)) { - sub_fval = fval.field[fname] - } + let sub_fval = fval.members?.get(fname) ?? fval.getMemberValue?.(fname) if (!sub_fval) { if (createIfNotExists) { - sub_fval = new PackageValue({ + sub_fval = new PackageValue(`${fval.qid}.${fname}`, { vtype: 'package', sid: fname, - qid: fval.qid ? `${fval.qid}.${fname}` : fname, - exports: new Scoped({ - sid: 'exports', - id: 'exports', - parent: null, - }), + qid: `${fval.qid}.${fname}`, parent: this, }) - fval.field[fname] = sub_fval + sub_fval.scope.exports = new Scoped(`${fval.qid}.${fname}.exports`, { + sid: 'exports', + parent: null, + }) + if (fval.members) { + fval.members.set(fname, sub_fval) + } else { + fval.setFieldValue(fname, sub_fval) + } } else { // Errors.UnexpectedValue(`getFieldValue: ${i} is not in ${sub_fval.sid}`, {no_throw: true}); return diff --git a/src/engine/analyzer/common/value/primitive.ts b/src/engine/analyzer/common/value/primitive.ts index e9efe5fe..cfb61a18 100644 --- a/src/engine/analyzer/common/value/primitive.ts +++ b/src/engine/analyzer/common/value/primitive.ts @@ -1,23 +1,81 @@ -const Unit = require('./unit') +import { DataValue } from './data-value' -interface PrimitiveValueOptions { +export interface PrimitiveValueOptions { + sid?: string + qid?: string + parent?: any value?: any - field?: any - [key: string]: any + literalType?: 'string' | 'number' | 'boolean' | 'null' | null + type?: string + loc?: any + ast?: any } /** - * PrimitiveValue class + * PrimitiveValue - 基本类型字面量 + * + * 固定构造函数:具名参数,不使用 opts 对象 + * sid 必须由调用者提供(因为它依赖上下文语义) */ -module.exports = class PrimitiveValue extends Unit { +export class PrimitiveValue extends DataValue { + literalType: 'string' | 'number' | 'boolean' | 'null' | null + /** - * Constructor for PrimitiveValue - * @param opts - Options for constructing PrimitiveValue + * @param upperQid - 父作用域 qid + * @param sid - 符号 ID(必须由调用者提供) + * @param value - 字面量值 + * @param literalType - 字面量类型(可选,自动推断) + * @param type - AST 节点类型(可选,默认 'Literal') + * @param loc - 源码位置(可选) + * @param ast - AST 节点(可选) */ - constructor(opts: PrimitiveValueOptions) { - super({ - vtype: 'primitive', - ...opts, + constructor( + upperQid: string, + sid: string, + value: any, + literalType?: 'string' | 'number' | 'boolean' | 'null' | null, + type?: string, + loc?: any, + ast?: any + ) { + // 不自动推断 literalType,保持调用者传入的值(可以是 null/undefined) + const finalLiteralType = literalType ?? null + + super('primitive', upperQid, { + sid, + value, + type: type || 'Literal', + literalType: finalLiteralType, + loc, + ast: ast || null, }) + + this.literalType = finalLiteralType + this.type = type || 'Literal' + this.rtype = {} + } + + /** + * 从序列化的 opts 对象恢复(仅用于反序列化) + */ + static fromOpts(upperQid: string, opts: PrimitiveValueOptions): PrimitiveValue { + const sid = opts?.sid || 'undefined' + const value = opts?.value + const literalType = opts?.literalType + const type = opts?.type || 'Literal' + const loc = opts?.loc + const ast = opts?.ast + + const primitive = new PrimitiveValue(upperQid, sid, value, literalType, type, loc, ast) + + // 反序列化时恢复原始 qid + if (opts?.qid) { + primitive._qid = opts.qid + } + if (opts?.parent) { + primitive.parent = opts.parent + } + + return primitive } } diff --git a/src/engine/analyzer/common/value/scope-ctx.ts b/src/engine/analyzer/common/value/scope-ctx.ts new file mode 100644 index 00000000..f345776d --- /dev/null +++ b/src/engine/analyzer/common/value/scope-ctx.ts @@ -0,0 +1,80 @@ +/** + * ScopeCtx - 作用域上下文属性组(RefGroup) + * + * 管理 fileScope/exports 的 UUID 存储和 SymbolTable resolve, + * 以及 declarationMap 的直接存储。 + * getter 自动通过 SymbolTable resolve UUID 为 Value 对象, + * setter 自动提取 UUID 存储。 + */ +export class ScopeCtx { + private _fileScopeUuid: string | null = null + private _exportsUuid: string | null = null + private _declarationMap: Map | null = null + private _owner: { getSymbolTable(): any } + + constructor(owner: { getSymbolTable(): any }) { + this._owner = owner + } + + // --- fileScope --- + + get fileScope(): any { + if (!this._fileScopeUuid) return null + const st = this._owner.getSymbolTable() + return st ? st.get(this._fileScopeUuid) : null + } + + set fileScope(unit: any) { + if (!unit) { this._fileScopeUuid = null; return } + const st = this._owner.getSymbolTable() + if (unit.uuid !== this._fileScopeUuid) { + if (unit.uuid) { + this._fileScopeUuid = unit.uuid + } else if (st) { + this._fileScopeUuid = st.register(unit) + } else { + this._fileScopeUuid = unit.uuid || null + } + } + } + + // --- exports --- + + get exports(): any { + if (!this._exportsUuid) return null + const st = this._owner.getSymbolTable() + return st ? st.get(this._exportsUuid) : null + } + + set exports(unit: any) { + if (!unit) { this._exportsUuid = null; return } + const st = this._owner.getSymbolTable() + if (unit.uuid !== this._exportsUuid) { + if (unit.uuid) { + this._exportsUuid = unit.uuid + } else if (st) { + this._exportsUuid = st.register(unit) + } + } + } + + // --- declarationMap --- + + get declarationMap(): Map | null { + return this._declarationMap + } + + set declarationMap(map: Map | null) { + this._declarationMap = map + } + + // --- _clone --- + + _clone(newOwner: { getSymbolTable(): any }): ScopeCtx { + const c = new ScopeCtx(newOwner) + c._fileScopeUuid = this._fileScopeUuid + c._exportsUuid = this._exportsUuid + c._declarationMap = this._declarationMap ? new Map(this._declarationMap) : null + return c + } +} diff --git a/src/engine/analyzer/common/value/scoped.ts b/src/engine/analyzer/common/value/scoped.ts index 9bc3ceb3..57ee0cad 100644 --- a/src/engine/analyzer/common/value/scoped.ts +++ b/src/engine/analyzer/common/value/scoped.ts @@ -1,30 +1,87 @@ -const Unit = require('./unit') +import { handleException } from '../exception-handler' +import { EntityValue } from './entity-value' +import type Unit from './unit' const logger = require('../../../../util/logger')(__filename) -interface ScopedOptions { - parent?: any +export interface ScopedOptions { + sid?: string + qid?: string name?: string - [key: string]: any + vtype?: string + + parent?: Unit | null + _this?: Unit | null + + decls?: Record + + loc?: any + ast?: any + value?: any + field?: any + _meta?: any + + declarationMap?: any + context?: any + spring?: any + beanMap?: any + springReferenceMap?: any + springServiceMap?: any } -module.exports = class Scoped extends Unit { - parent: any // the parent of the scope +/** + * Scoped class + */ +export class Scoped extends EntityValue { + override name: string | undefined + + declare symbolTable?: any + declare funcSymbolTable?: any + declare invocationMap?: any + declare isProcessed?: boolean + declare updates?: any + declare context?: any + declare pointerReference?: boolean + + constructor(upperQidOrOpts?: string | ScopedOptions, opts?: ScopedOptions) { + const finalOpts: any = typeof upperQidOrOpts === 'string' ? (opts || {}) : (upperQidOrOpts || {}) + + if (typeof upperQidOrOpts === 'string') { + super('scope', upperQidOrOpts, finalOpts) + } else { + super('scope', finalOpts) + } + + this.name = finalOpts.name + + // Scoped-specific properties + if ('declarationMap' in finalOpts) this.declarationMap = finalOpts.declarationMap + if ('context' in finalOpts) this.context = finalOpts.context + if ('spring' in finalOpts) this.spring = finalOpts.spring + if ('beanMap' in finalOpts) this.beanMap = finalOpts.beanMap + if ('springReferenceMap' in finalOpts) this.springReferenceMap = finalOpts.springReferenceMap + if ('springServiceMap' in finalOpts) this.springServiceMap = finalOpts.springServiceMap - name: string | undefined + if (this.parent === undefined) { + handleException( + null, + 'parent is not set when creating scope value', + 'parent is not set when creating scope value' + ) + } + } /** - * - * @param opts + * 从序列化的 opts 对象恢复 Scoped(仅用于反序列化) */ - constructor(opts?: ScopedOptions) { - super({ - vtype: 'scope', - ...opts, - }) - this.parent = opts?.parent - this.name = opts?.name - if (this.parent === undefined) { - logger.warn('parent is not set when creating scope value') + static fromOpts(upperQid: string, opts: ScopedOptions): Scoped { + const scoped = new Scoped(upperQid, opts) + // 反序列化时恢复原始 qid + if (opts?.qid) { + scoped._qid = opts.qid + } + if (opts?.parent) { + scoped.parent = opts.parent } + return scoped } } diff --git a/src/engine/analyzer/common/value/sentinel-value.ts b/src/engine/analyzer/common/value/sentinel-value.ts new file mode 100644 index 00000000..7f7195a8 --- /dev/null +++ b/src/engine/analyzer/common/value/sentinel-value.ts @@ -0,0 +1,31 @@ +import { ValueBase } from './value-base' + +/** + * SentinelValue - 占位符值基类 + * + * 表示特殊状态的值(void/undefined/uninitialized/unknown) + * 不表示具体的计算结果,仅作为控制流和状态标记 + * + * 子类: + * - VoidValue: 函数无返回值 + * - UndefinedValue: 变量未定义 + * - UninitializedValue: 变量已声明但未赋值 + * - UnknownValue: 无法推断的值 + */ +export abstract class SentinelValue extends ValueBase { + /** + * 是否为未初始化状态(仅 UninitializedValue 使用) + */ + uninit?: boolean + + constructor(vtype: string, upperQidOrOpts?: string | Record, opts?: Record) { + // 抽象基类构造函数:支持两种调用方式 + // 1. super(vtype, upperQid, opts) - 子类常用 + // 2. super(vtype, opts) - 可选 + if (typeof upperQidOrOpts === 'string') { + super(vtype, upperQidOrOpts, opts) + } else { + super(vtype, upperQidOrOpts) + } + } +} diff --git a/src/engine/analyzer/common/value/spread.ts b/src/engine/analyzer/common/value/spread.ts new file mode 100644 index 00000000..eeb654c3 --- /dev/null +++ b/src/engine/analyzer/common/value/spread.ts @@ -0,0 +1,28 @@ +import { DataValue } from './data-value' +import type { Value } from '../../../../types/value' + +/** + * SpreadValue - 展开运算结果 + * + * 固定构造函数:具名参数,不使用 opts 对象 + */ +export class SpreadValue extends DataValue { + elements: Value[] + + /** + * @param elements - 展开后的元素列表(必需) + * @param isTainted - 污点标记(必需) + * @param sid - 符号 ID(可选) + * @param qid - 限定 ID(可选) + */ + constructor( + elements: Value[], + isTainted: boolean, + sid?: string, + qid?: string + ) { + super('spread', { sid, qid }) + this.elements = elements + if (isTainted) this.taint?.markSource() + } +} diff --git a/src/engine/analyzer/common/value/symbolic.ts b/src/engine/analyzer/common/value/symbolic.ts index 618ed72c..be241a0b 100644 --- a/src/engine/analyzer/common/value/symbolic.ts +++ b/src/engine/analyzer/common/value/symbolic.ts @@ -1,34 +1,91 @@ -const ObjectValue = require('./object') +import { ObjectValue } from './object' +import type Unit from './unit' -interface SymbolicValueOptions { +export interface SymbolicValueOptions { + sid?: string + qid?: string + name?: string vtype?: string - parent?: any + type?: string + + object?: Unit | null + property?: any + annotations?: any[] + argument?: Unit | null + left?: Unit | null + right?: Unit | null + operator?: string + expression?: Unit | null + arguments?: any[] + + parent?: Unit | null + _this?: Unit | null + + loc?: any + ast?: any + value?: any + field?: any + _meta?: any [key: string]: any } /** * SymbolValue class */ -class SymbolValue extends ObjectValue { - parent: any +export class SymbolValue extends ObjectValue { + object?: Unit | null + property?: any + annotations?: any[] + argument?: Unit | null + left?: Unit | null + right?: Unit | null + operator?: string + expression?: Unit | null + arguments?: any[] + + constructor(upperQidOrOpts?: string | SymbolicValueOptions, opts?: SymbolicValueOptions) { + const finalOpts = typeof upperQidOrOpts === 'string' ? (opts || {}) : (upperQidOrOpts || {}) + + // Ensure parent is set + finalOpts.parent = finalOpts.parent || null + + // Override vtype for SymbolValue + const optsWithVtype = { ...finalOpts, vtype: 'symbol' } + + if (typeof upperQidOrOpts === 'string') { + super(upperQidOrOpts, optsWithVtype) + } else { + super(optsWithVtype) + } + + if (finalOpts.object !== undefined) this.object = finalOpts.object + if (finalOpts.property !== undefined) this.property = finalOpts.property + if (finalOpts.annotations !== undefined) this.annotations = finalOpts.annotations + if (finalOpts.argument !== undefined) this.argument = finalOpts.argument + if (finalOpts.left !== undefined) this.left = finalOpts.left + if (finalOpts.right !== undefined) this.right = finalOpts.right + if (finalOpts.operator !== undefined) this.operator = finalOpts.operator + if (finalOpts.expression !== undefined) this.expression = finalOpts.expression + if (finalOpts.arguments !== undefined) this.arguments = finalOpts.arguments - /** - * Constructor for SymbolValue - * @param opts - Options for constructing SymbolValue - */ - constructor(opts?: SymbolicValueOptions) { - super({ - vtype: 'symbol', - ...opts, - }) // remove parent if it is assigned from ast than value if (!this.parent?.vtype) { - delete this.parent + this.parent = null } - // if (!opts.value) { - // try{ Errors.UnexpectedValue('symbol value should have value init when being created'); }catch (e) {} - // } } -} -module.exports = SymbolValue + /** + * 从序列化的 opts 对象恢复 SymbolValue(仅用于反序列化) + */ + static override fromOpts(upperQid: string, opts: SymbolicValueOptions): SymbolValue { + const symbolValue = new SymbolValue(upperQid, opts) + // 反序列化时恢复原始 qid + if (opts?.qid) { + symbolValue._qid = opts.qid + } + if (opts?.parent) { + symbolValue.parent = opts.parent + } + return symbolValue + } +} diff --git a/src/engine/analyzer/common/value/symbols.ts b/src/engine/analyzer/common/value/symbols.ts new file mode 100644 index 00000000..860b55d1 --- /dev/null +++ b/src/engine/analyzer/common/value/symbols.ts @@ -0,0 +1,5 @@ +/** Proxy → 原始对象。用于序列化/clone 时穿透 Proxy 访问底层数据 */ +export const RAW_TARGET: unique symbol = Symbol('rawTarget') + +/** 标记 UnionValue 的 field 数组 Proxy */ +export const IS_UNION_ARRAY: unique symbol = Symbol('isUnionArray') diff --git a/src/engine/analyzer/common/value/taint-record.ts b/src/engine/analyzer/common/value/taint-record.ts new file mode 100644 index 00000000..209cf941 --- /dev/null +++ b/src/engine/analyzer/common/value/taint-record.ts @@ -0,0 +1,308 @@ +/** + * TaintRecord - 污点追踪属性组 + * + * 内存优化: + * - 大部分 Unit 从不使用 taint(95%+),用全局 NULL_TAINT 单例避免对象分配 + * - NULL_TAINT 不持有 _owner,所有查询返回 false/empty + * - 任何写操作自动将 owner.taint 升级为独立实例(写时复制语义) + * - tagTraces 懒分配,仅在首次 addTag 时创建 Map + * + * ObjectValue/UnionValue/BVTValue 构造时调 markRecursive(), + * 会触发升级为独立实例(因为 isTaintedRec 需要 _owner 做递归检查)。 + */ + +// 懒加载 ast-util.hasTag(避免循环依赖) +let _astUtilHasTag: ((val: any) => boolean) | null = null +function getAstUtilHasTag(): (val: any) => boolean { + if (!_astUtilHasTag) { + _astUtilHasTag = require('../../../../util/ast-util').hasTag + } + return _astUtilHasTag! +} + +export class TaintRecord { + _owner: any + private hasTag: boolean | null = null + private tagTraces: Map | null = null + /** 标记 owner 是否需要递归污点检查(ObjectValue/UnionValue/BVTValue) */ + private _recursiveHasTag: boolean = false + + constructor(owner: any) { + this._owner = owner + } + + private ensureTagTraces(): Map { + if (!this.tagTraces) this.tagTraces = new Map() + return this.tagTraces + } + + /** 标记为需要递归污点检查(ObjectValue/UnionValue/BVTValue 构造时调用) */ + markRecursive(): void { + this._recursiveHasTag = true + } + + /** Re-bind to a new owner (e.g. when taint is transferred via {...unit} spread) */ + rebindOwner(newOwner: any): void { + this._owner = newOwner + } + + + // --- 查询 --- + + /** 非递归:当前 Unit 自身是否被标记为污点 */ + get isTainted(): boolean { + return !!this.hasTag + } + + /** 递归:仅对需要递归检查的类型委托 astUtil.hasTag 深度检查 */ + get isTaintedRec(): boolean { + if (this._recursiveHasTag) { + return getAstUtilHasTag()(this._owner) + } + return !!this.hasTag + } + + getTrace(tag: string): any[] | null { + return this.tagTraces?.get(tag) || null + } + + getTags(): string[] { + return this.tagTraces ? Array.from(this.tagTraces.keys()) : [] + } + + containsTag(tag: string, visited?: Set): boolean { + if (this.tagTraces?.has(tag)) return true + // 递归类型(Union/BVT/Object):检查子值是否持有该 tag + if (this._recursiveHasTag && this._owner) { + if (!visited) visited = new Set() + if (visited.has(this)) return false + visited.add(this) + const owner = this._owner + if (owner.vtype === 'union' && Array.isArray(owner.value)) { + return owner.value.some((child: any) => child?._taint?.containsTag(tag, visited)) + } + if (owner.vtype === 'BVT' && owner.value) { + return Object.values(owner.value).some((child: any) => (child as any)?._taint?.containsTag(tag, visited)) + } + } + return false + } + + hasTraces(): boolean { + if (!this.tagTraces) return false + for (const [_, traces] of this.tagTraces) { + if (traces.length > 0) return true + } + return false + } + + getFirstTrace(): any[] | null { + if (!this.tagTraces) return null + for (const [_, traces] of this.tagTraces) { + return traces + } + return null + } + + // --- 修改 --- + + addTag(tag: string): void { + const map = this.ensureTagTraces() + if (!map.has(tag)) { + map.set(tag, []) + } + this.hasTag = true + } + + addTraceToTag(tag: string, item: any): void { + const map = this.ensureTagTraces() + if (!map.has(tag)) { + map.set(tag, []) + } + map.get(tag)!.push(item) + this.hasTag = true + } + + addTraceToAllTags(item: any): void { + if (!this.tagTraces) return + for (const [_, traces] of this.tagTraces) { + traces.push(item) + } + } + + popFromAllTraces(): void { + if (!this.tagTraces) return + for (const [_, traces] of this.tagTraces) { + traces.pop() + } + } + + /** 清空所有 tag 的 trace(保留 tag 本身) */ + clearTrace(): void { + if (!this.tagTraces) return + for (const [tag] of this.tagTraces) { + this.tagTraces.set(tag, []) + } + } + + /** 从 source 复制 tags + trace + hasTag(收口 memSpace 手工复制) */ + copyFrom(source: TaintRecord): void { + this.hasTag = source.hasTag + if (source.tagTraces) { + const map = this.ensureTagTraces() + map.clear() + for (const [k, v] of source.tagTraces) { + map.set(k, [...v]) + } + } else { + this.tagTraces = null + } + } + + clear(): void { + this.hasTag = null + this.tagTraces = null + } + + // --- 传播接口 --- + + /** 标记当前为污点源 */ + markSource(): void { + this.hasTag = true + } + + /** 从单个源传播污点状态(source 必须是 Unit,调用方负责类型检查) */ + propagateFrom(source: any): void { + // 用 _taint 避免触发 getter 创建空 TaintRecord + this.hasTag = source?._taint?.isTaintedRec ?? null + } + + /** 从多个源合并污点状态(sources 元素必须是 Unit,调用方负责类型检查) */ + mergeFrom(sources: (any)[]): void { + this.hasTag = sources.some((s: any) => s?._taint?.isTaintedRec) || null + } + + /** 清除污点状态 */ + sanitize(): void { + this.hasTag = null + } + + // --- 外部访问接口 --- + + /** tagTraces 是否有 tag(等价于 tagTraces.size > 0) */ + hasTags(): boolean { + return this.tagTraces ? this.tagTraces.size > 0 : false + } + + /** 为所有现有 tag 设置相同 trace;若无 tag 则创建 __default__ 并标记 hasTag */ + setAllTraces(traceVal: any[]): void { + if (this.tagTraces && this.tagTraces.size > 0) { + for (const [tag] of this.tagTraces) { + this.tagTraces.set(tag, traceVal) + } + } else { + this.ensureTagTraces().set('__default__', traceVal) + this.hasTag = true + } + } + + /** 从 source 继承 trace(所有 tag 共享同一数组引用,用于父→子成员传播) */ + inheritTracesFrom(source: TaintRecord): void { + const srcTrace = source.getFirstTrace() + if (!srcTrace || srcTrace.length === 0) return + if (!this.tagTraces) return + const shared = [...srcTrace] + for (const [tag] of this.tagTraces) { + this.tagTraces.set(tag, shared) + } + } + + /** 从 source 复制 traces 到 this(逐 tag 深拷贝,不影响 hasTag) */ + mergeTracesFrom(source: TaintRecord): void { + if (!source.tagTraces) return + const map = this.ensureTagTraces() + for (const [tag, trace] of source.tagTraces) { + map.set(tag, [...trace]) + } + } + + /** 从 source 合并 traces,带三维去重(file + tag + JSON.stringify(line)) */ + mergeTracesDedup(source: TaintRecord): void { + if (!source.tagTraces) return + const map = this.ensureTagTraces() + for (const [tag, resTrace] of source.tagTraces) { + const childTrace = map.get(tag) + if (!childTrace) { + map.set(tag, [...resTrace]) + continue + } + + for (const resTraceItem of resTrace) { + let isDuplicate = false + for (const childTraceItem of childTrace) { + if ( + childTraceItem.file === resTraceItem.file && + childTraceItem.tag === resTraceItem.tag && + JSON.stringify(childTraceItem.line) === JSON.stringify(resTraceItem.line) + ) { + // __tmp 名称覆盖规则 + if (childTraceItem.affectedNodeName?.includes('__tmp') && !resTraceItem.affectedNodeName?.includes('__tmp')) { + childTraceItem.affectedNodeName = resTraceItem.affectedNodeName + } + isDuplicate = true + break + } + } + if (!isDuplicate) { + childTrace.push(resTraceItem) + } + } + } + } + + /** 从 resTaint 传播 trace 到当前值(收口 source-line processFieldAndArguments 重复模式) */ + propagateTraceFrom(resTaint: TaintRecord, traceItem?: any): void { + if (traceItem && !resTaint.hasTraces() && this.hasTags()) { + this.addTraceToAllTags(traceItem) + } + this.mergeTracesDedup(resTaint) + } + + /** 去重:若最后一条 trace 与参数匹配则弹出 */ + dedupLastTrace(file: string, line: number, tag: string): void { + const firstTrace = this.getFirstTrace() + if (firstTrace && firstTrace.length > 0) { + const last = firstTrace[firstTrace.length - 1] + if (last.file === file && last.line === line && last.tag === tag) { + this.popFromAllTraces() + } + } + } + + /** 返回 tagTraces 的只读引用(给 source-line 等需要直接遍历 Map 的场景) */ + getTagTracesMap(): ReadonlyMap { + return this.tagTraces ?? new Map() + } + + // --- 克隆 --- + + _clone(newOwner: any): TaintRecord { + const copy = new TaintRecord(newOwner) + copy.hasTag = this.hasTag + copy._recursiveHasTag = this._recursiveHasTag + if (this.tagTraces) { + const map = copy.ensureTagTraces() + for (const [k, v] of this.tagTraces) { + map.set(k, [...v]) + } + } + return copy + } +} + +/** + * 全局共享的空 TaintRecord 单例。 + * 所有查询返回 false/empty,所有写操作无副作用(因为没有真实 owner 可以升级)。 + * Unit 构造时默认使用此实例,只在确实需要 taint 时才 new TaintRecord(this)。 + */ +export const NULL_TAINT = new TaintRecord(null) diff --git a/src/engine/analyzer/common/value/tainted.ts b/src/engine/analyzer/common/value/tainted.ts new file mode 100644 index 00000000..6ea8f5fb --- /dev/null +++ b/src/engine/analyzer/common/value/tainted.ts @@ -0,0 +1,31 @@ +import { DataValue } from './data-value' + +/** + * TaintedValue - 携带污点标记的值 + * + * 固定构造函数:具名参数,不使用 opts 对象 + */ +export class TaintedValue extends DataValue { + annotations?: Array<{ + type: string + value?: any + [key: string]: any + }> + + /** + * @param isTainted - 污点标记(必需) + * @param sid - 符号 ID(可选) + * @param qid - 限定 ID(可选) + * @param annotations - 污点注解(可选) + */ + constructor( + isTainted: boolean, + sid?: string, + qid?: string, + annotations?: Array<{ type: string; value?: any; [key: string]: any }> + ) { + super('tainted', { sid, qid }) + if (isTainted) this.taint?.markSource() + this.annotations = annotations + } +} diff --git a/src/engine/analyzer/common/value/typed.ts b/src/engine/analyzer/common/value/typed.ts new file mode 100644 index 00000000..df862fe2 --- /dev/null +++ b/src/engine/analyzer/common/value/typed.ts @@ -0,0 +1,29 @@ +import { DataValue, RType } from './data-value' + +/** + * TypedValue - 仅有类型信息的值 + * + * 用于:Java/Go 等静态类型语言中需要类型推断的场景 + * + * 固定构造函数:具名参数,不使用 opts 对象 + */ +export class TypedValue extends DataValue { + override rtype: RType + + /** + * @param rtype - 类型信息(必需) + * @param sid - 符号 ID(可选) + * @param qid - 限定 ID(可选) + */ + constructor( + rtype: RType, + sid?: string, + qid?: string + ) { + super('typed', { + sid, + qid, + }) + this.rtype = rtype + } +} diff --git a/src/engine/analyzer/common/value/unary-expr.ts b/src/engine/analyzer/common/value/unary-expr.ts new file mode 100644 index 00000000..d2e94547 --- /dev/null +++ b/src/engine/analyzer/common/value/unary-expr.ts @@ -0,0 +1,61 @@ +import { ExprValue } from './expr-value' +import { ValueRef } from './value-ref' +import type Unit from './unit' + +interface UnaryExprOptions { + operator?: string + argument?: Unit | null + ast?: any + loc?: any + isSuffix?: boolean +} + +/** + * UnaryExprValue - 一元运算表达式(++i, -x, !flag, ...) + * + * argument 通过 instance-level own enumerable accessor 实现: + * - 内部走 _argumentRef (ValueRef) 存储 + * - hasOwnProperty('argument') 返回 true(satisfy() 遍历兼容) + */ +export class UnaryExprValue extends ExprValue { + _argumentRef!: ValueRef | null + declare argument: Unit | null + operator: string + isSuffix: boolean + + constructor(upperQid: string, operator: string, argument: Unit | null, ast: any, loc: any, isSuffix: boolean = true) { + const sid = `` + super(upperQid, { + sid, + exprKind: 'unary', + type: 'UnaryExpression', + ast, + loc, + }) + this.operator = operator + this.isSuffix = isSuffix + Object.defineProperty(this, '_argumentRef', { value: this._makeValueRefDirect(argument), writable: true, enumerable: false, configurable: true }) + Object.defineProperty(this, 'argument', { + get(this: UnaryExprValue) { return this._argumentRef?.resolve(this.getSymbolTable()) ?? null }, + set(this: UnaryExprValue, val: Unit | null) { this._argumentRef = val != null ? this._makeValueRefDirect(val) : null }, + enumerable: true, + configurable: true, + }) + } + + static fromOpts(upperQid: string, opts: UnaryExprOptions): UnaryExprValue { + const o = opts || {} + return new UnaryExprValue( + upperQid, + o.operator || '', + o.argument ?? null, + o.ast?.node ?? o.ast, + o.loc, + o.isSuffix !== undefined ? o.isSuffix : true, + ) + } + + get operands(): (Unit | null)[] { + return this._argumentRef ? [this.argument] : [] + } +} diff --git a/src/engine/analyzer/common/value/undefine.ts b/src/engine/analyzer/common/value/undefine.ts index 16b7d153..cd9f9276 100644 --- a/src/engine/analyzer/common/value/undefine.ts +++ b/src/engine/analyzer/common/value/undefine.ts @@ -1,21 +1,41 @@ -const Unit = require('./unit') +import { SentinelValue } from './sentinel-value' interface UndefinedValueOptions { - [key: string]: any + sid?: string + qid?: string + parent?: any } /** * UndefinedValue class + * + * BVT 模式:固定构造函数签名 */ -module.exports = class UndefinedValue extends Unit { +export class UndefinedValue extends SentinelValue { /** - * Constructor for UndefinedValue - * @param opts - Options for constructing UndefinedValue + * 创建 UndefinedValue + * @param upperQid - 父作用域的 qid(可选,默认 '') + * @param sid - 符号 ID(可选,默认 '') */ - constructor(opts?: UndefinedValueOptions) { - super({ - vtype: 'undefine', - ...opts, - }) + constructor(upperQid: string = '', sid: string = '') { + super('undefine', upperQid, { sid }) + } + + /** + * 从序列化的 opts 对象恢复 UndefinedValue(仅用于反序列化) + */ + static fromOpts(upperQid: string, opts: UndefinedValueOptions): UndefinedValue { + const sid = opts?.sid || '' + const qid = opts?.qid + const parent = opts?.parent + const undefinedValue = new UndefinedValue(upperQid, sid) + // 反序列化时恢复原始属性 + if (qid) { + undefinedValue._qid = qid + } + if (parent) { + undefinedValue.parent = parent + } + return undefinedValue } } diff --git a/src/engine/analyzer/common/value/uninit.ts b/src/engine/analyzer/common/value/uninit.ts index e956f796..8d864799 100644 --- a/src/engine/analyzer/common/value/uninit.ts +++ b/src/engine/analyzer/common/value/uninit.ts @@ -1,18 +1,48 @@ -const Unit = require('./unit') +import { SentinelValue } from './sentinel-value' interface UninitializedValueOptions { - [key: string]: any + sid?: string + qid?: string + ast?: any + parent?: any } -module.exports = class UninitializedValue extends Unit { +/** + * UninitializedValue - 未初始化的值 + * + * BVT 模式:固定构造函数签名 + */ +export class UninitializedValue extends SentinelValue { /** - * - * @param opts + * 创建 UninitializedValue + * @param upperQid - 父作用域的 qid(可选,默认 '') + * @param sid - 符号 ID(可选,默认 '') + * @param ast - AST 节点(可选) */ - constructor(opts?: UninitializedValueOptions) { - super({ - vtype: 'uninitialized', - ...opts, - }) + constructor(upperQid: string = '', sid: string = '', ast?: any) { + super('uninitialized', upperQid, { sid }) + // ast 通过基类的 accessor 赋值(不重新声明) + if (ast !== undefined) { + this.ast = ast + } + } + + /** + * 从序列化的 opts 对象恢复 UninitializedValue(仅用于反序列化) + */ + static fromOpts(upperQid: string, opts: UninitializedValueOptions): UninitializedValue { + const sid = opts?.sid || '' + const ast = opts?.ast + const qid = opts?.qid + const parent = opts?.parent + const uninitializedValue = new UninitializedValue(upperQid, sid, ast) + // 反序列化时恢复原始属性 + if (qid) { + uninitializedValue._qid = qid + } + if (parent) { + uninitializedValue.parent = parent + } + return uninitializedValue } } diff --git a/src/engine/analyzer/common/value/union.ts b/src/engine/analyzer/common/value/union.ts index f3b9a808..13959a01 100644 --- a/src/engine/analyzer/common/value/union.ts +++ b/src/engine/analyzer/common/value/union.ts @@ -1,112 +1,185 @@ const _ = require('lodash') -const Unit = require('./unit') +import { DataValue } from './data-value' +import Unit = require('./unit') +import { ValueRefList } from './value-ref-list' +import { ValueRef } from './value-ref' +const { TaintRecord, NULL_TAINT } = require('./taint-record') +import { RAW_TARGET, IS_UNION_ARRAY } from './symbols' const astUtil = require('../../../../util/ast-util') -interface UnionValueOptions { - value?: any[] | Record - raw_value?: any[] | Record - [key: string]: any -} - /** - * UnionValue class + * UnionValue - 联合值 + * + * 固定构造函数:具名参数,不使用 opts 对象 + * AST-based UUID:union 只用 AST,不用序号 */ -class UnionValue extends Unit { - set: WeakSet - - field!: any[] - - raw_value: any +export class UnionValue extends DataValue { + set: WeakSet + elements!: ValueRefList - _has_tags: boolean | undefined + raw_value: unknown /** - * Constructor for UnionValue - * @param opts - Options for constructing UnionValue + * @param value - Union 元素数组(可选,默认空数组) + * @param sid - 符号 ID(可选,默认 '') + * @param qid - 限定 ID(可选,默认 '') + * @param astNode - 创建点的 AST 节点(用于 UUID 稳定性) */ - constructor(opts?: UnionValueOptions) { - super({ - vtype: 'union', - ...opts, - }) + constructor(value?: Unit[], sid?: string, qid?: string, astNode?: object | null) { + const opts: Record = { + sid: sid || '', + qid: qid || '', + } + if (astNode) opts.ast = astNode + + super('union', opts) + if (this.taint === NULL_TAINT) this.taint = new TaintRecord(this) + this.taint.markRecursive() this.set = new WeakSet() + Object.defineProperty(this, 'elements', { + value: new ValueRefList(() => this.getSymbolTable()), + writable: true, + enumerable: false, + configurable: true, + }) + + // 通过 value setter 设置(触发 wrapFieldArray,匹配旧行为) + this.value = (value && Array.isArray(value)) ? value : [] + } + + static fromOpts(upperQid: string, opts: any): UnionValue { const value = opts?.value - // 确保value为数组 - if (!value) { - this.value = [] + const sid = opts?.sid + const qid = opts?.qid + + const unionValue = new UnionValue(undefined, sid, qid) + + // 恢复 value + if (value) { + if (Array.isArray(value)) { + unionValue._field = value + } else { + unionValue._field = Object.values(value) + } } - let oldValue: any[] = [] - let { raw_value } = this - if (raw_value) { + + // 处理 raw_value 合并(反序列化专用) + const rawValue = opts?.raw_value + if (rawValue) { + let oldValue: any[] = [] if (!_.isArray(value)) { - oldValue = Object.values(value || {}) as any[] + oldValue = Object.values(value || {}) } - // 确保raw_value为数组 - if (!_.isArray(this.raw_value)) { - raw_value = Object.values(this.raw_value) + let rawArr = rawValue + if (!_.isArray(rawArr)) { + rawArr = Object.values(rawArr) } + rawArr.forEach((element: any) => oldValue.push(element)) + unionValue._field = oldValue + } - raw_value.forEach((element: any) => oldValue.push(element)) - - this.value = oldValue + const rawField = Array.isArray(unionValue._field) ? [...unionValue._field] : Object.values(unionValue._field || {}) + unionValue.wrapFieldArray() + unionValue._syncElements(rawField) - if (Array.isArray(this.raw_value)) { - this.raw_value.length = 0 - } else if (typeof this.raw_value === 'object' && this.raw_value !== undefined && this.raw_value !== null) { - for (const key in this.raw_value) { - if (this.raw_value.hasOwnProperty(key)) { - delete this.raw_value[key] - } - } - } + // 恢复原始 qid + if (opts?.qid) { + unionValue._qid = opts.qid } + if (opts?.parent) { + unionValue.parent = opts.parent + } + if (opts?._this) { + unionValue._this = opts._this + } + if (opts?.name) { + unionValue.name = opts.name + } + + return unionValue } /** - * Get value + * Clone _field for UnionValue: extract raw array from double Proxy, re-wrap. */ - get value(): any[] { - // if (Object.prototype.hasOwnProperty.call(this, 'raw_value')) { - // return this.raw_value - // } - return this.field + protected override _cloneField(copy: UnionValue, fieldValue: any): void { + if (!fieldValue || typeof fieldValue !== 'object') { + copy._field = fieldValue + return + } + const desc = Object.getOwnPropertyDescriptor(fieldValue, RAW_TARGET) + const raw = desc?.value + if (Array.isArray(raw)) { + copy._field = [...raw] + } else if (Array.isArray(fieldValue)) { + copy._field = [...fieldValue] + } else { + copy._field = fieldValue + } + copy.wrapFieldArray() } - /** - * Set value - * @param v - New value - */ - set value(v: any[]) { - this.field = v - this.set = new WeakSet() + override clone(): this { + const copy = super.clone() + copy.set = new WeakSet() + if (this.elements && typeof this.elements._clone === 'function') { + Object.defineProperty(copy, 'elements', { + value: this.elements._clone(() => copy.getSymbolTable()), + writable: true, + enumerable: false, + configurable: true, + }) + } + return copy + } + + override cloneAlias(): this { + const copy = super.cloneAlias() + copy.set = new WeakSet() + if (this.elements && typeof this.elements._clone === 'function') { + Object.defineProperty(copy, 'elements', { + value: this.elements._clone(() => copy.getSymbolTable()), + writable: true, + enumerable: false, + configurable: true, + }) + } + return copy } /** - * Check if has tag recursively + * Get value */ - get hasTagRec(): boolean { - return astUtil.hasTag(this, null) + override get value(): any[] { + if (!Array.isArray(this._field)) { + this._field = Object.values(this._field) + this.wrapFieldArray() + } + return this._field as any[] } /** - * Set hasTagRec - * @param value - Tag value + * Set value + * @param v - New value */ - set hasTagRec(value: boolean) { - this._has_tags = value + override set value(v: any[]) { + this._field = v + this.set = new WeakSet() + this.wrapFieldArray() + this._syncElements(v) } /** - * Get trace by tag + * Get trace by tag — delegate to children's TaintBinding * @param tag - Tag to search for */ - getTrace(tag: string): any { - return _.find(this.value, (v: any) => { - if (_.isFunction(v?._tags?.has) && v._tags.has(tag)) { - return v.trace + override getTrace(tag: string): any { + return _.find(this.value, (v: Unit) => { + if (v?.taint.containsTag(tag)) { + return v.taint.getTrace(tag) } }) } @@ -115,14 +188,14 @@ class UnionValue extends Unit { * Get taint info by tag * @param tag - Tag to search for */ - getTaintInfo(tag: string): { value: any; trace: any } | undefined { - const value = _.find(this.value, (v: any) => { - return _.isFunction(v?._tags?.has) && v._tags.has(tag) + getTaintInfo(tag: string): { value: Unit; trace: unknown } | undefined { + const value = _.find(this.value, (v: Unit) => { + return v?.taint.containsTag(tag) }) if (value) { return { value, - trace: value.trace, + trace: value.taint.getTrace(tag), } } } @@ -130,31 +203,31 @@ class UnionValue extends Unit { /** * Get this instance */ - getThis(): UnionValue { - return new UnionValue({ value: this.value.map((v: any) => v.getThis()) }) + override getThisObj(): UnionValue { + return new UnionValue(this.value.map((v: Unit) => v.getThisObj()), this.sid, this.qid, this.ast?.node) } /** * Append value to union * @param val - Value to append * @param uniqueFlag - Whether to deduplicate + * @param flatten - Whether to flatten inner UnionValues (false preserves tuple position structure) */ - appendValue(val: any, uniqueFlag: boolean = true): void { + appendValue(val: Unit | Unit[], uniqueFlag: boolean = true, flatten: boolean = true): void { if (!val) return if (Array.isArray(val)) { - val.forEach((v: any) => { + val.forEach((v: Unit) => { this._pushValue(v, uniqueFlag) }) return } - if (val instanceof UnionValue) { + if (flatten && val instanceof UnionValue) { for (const v of val.value) { - this.appendValue(v, uniqueFlag) + this.appendValue(v, uniqueFlag, flatten) } } else if (val instanceof Unit) { - // other type of Value this._pushValue(val, uniqueFlag) } } @@ -164,28 +237,183 @@ class UnionValue extends Unit { * @param val - Value to push * @param uniqueFlag - Whether to deduplicate */ - private _pushValue(val: any, uniqueFlag: boolean = true): void { - if (this === val) return - if (this.isUnionInBVT(this, val)) return - if (this.set.has(val) && uniqueFlag) return - const isEqual = this.value.some((ele: any) => { + private _pushValue(val: Unit, uniqueFlag: boolean = true): void { + if (this === val) { + return + } + if (this.uuid === val.uuid) { + return + } + if (this.isUnionInBVT(this, val)) { + return + } + if (this.set.has(val) && uniqueFlag) { + return + } + const isEqual = this.value.some((ele: Unit) => { return ( _.isEqual(ele, val) || (val.vtype === ele.vtype && val.vtype === 'symbol' && ele.hasOwnProperty('loc') && _.isEqual(ele.loc, val.loc)) ) }) - if (isEqual && uniqueFlag) return - this.value.push(val) + if (isEqual && uniqueFlag) { + return + } + + const valueToPush = val.uuid + + this.value.push(valueToPush) this.set.add(val) + this.elements.push(val) + } + + /** + * 包装 field 数组为 Proxy,拦截所有数组操作,自动更新 UUID + */ + _syncElements(source?: unknown[]): void { + Object.defineProperty(this, 'elements', { + value: new ValueRefList(() => this.getSymbolTable()), + writable: true, + enumerable: false, + configurable: true, + }) + if (!source) return + for (let i = 0; i < source.length; i++) { + const val = source[i] + if (typeof val === 'string' && val.startsWith('symuuid_')) { + this.elements._refs.push(new ValueRef(val)) + } else if (val && typeof val === 'object' && 'uuid' in val && typeof (val as Unit).uuid === 'string') { + this.elements._refs.push(new ValueRef((val as Unit).uuid)) + } + } + } + + private wrapFieldArray(): void { + if (!Array.isArray(this._field)) { + return + } + + if ((this._field as any)[IS_UNION_ARRAY]) { + return + } + + const self = this + const rawArray = this._field + const arrayMethods = ['push', 'pop', 'shift', 'unshift', 'splice', 'sort', 'reverse'] + let hasUnionArrayProxy = false + + const fieldProxy = new Proxy(rawArray, { + get(target, prop) { + const value = (target as any)[prop] + + // 拦截数组修改方法 + if (typeof prop === 'string' && arrayMethods.includes(prop) && typeof value === 'function') { + return function (...args: any[]) { + const result = value.apply(target, args) + return result + } + } + + // 拦截 length 属性的设置(通过直接赋值 length = n) + if (prop === 'length' && typeof value === 'number') { + return value + } + + // 如果是数组索引访问(如 array[0], array[1]),需要检查值是否是 UUID + if (typeof prop === 'string' && !isNaN(Number(prop))) { + // 如果值是 UUID,从符号表中查找对应的符号值对象 + if (typeof value === 'string' && value.startsWith('symuuid_')) { + const symbolTable = self.getSymbolTable() + if (symbolTable && symbolTable.has(value)) { + return symbolTable.get(value) + } + } + } + + // 如果不是数组索引或不是 UUID,返回原始值 + return value + }, + set(target, prop, value) { + // 拦截直接赋值操作(如 array[0] = value, array.length = n) + const symbolTable = self.getSymbolTable() + + // 如果是数组索引赋值(如 array[0] = value),需要处理 UUID 引用关系 + if (typeof prop === 'string' && !isNaN(Number(prop))) { + if (value instanceof Unit || (value && typeof value === 'object' && value.vtype && value.qid)) { + if (symbolTable) { + const uuid = symbolTable.register(value) + ;(target as any)[prop] = uuid + return true + } + } + } + + ;(target as any)[prop] = value + + return true + }, + + ownKeys(target) { + // 获取所有自有属性键 + const keys: (string | symbol)[] = Reflect.ownKeys(target).filter((key) => typeof key === 'string') + if (hasUnionArrayProxy) { + keys.push(IS_UNION_ARRAY, RAW_TARGET) + } + return keys + }, + + getOwnPropertyDescriptor(target, prop) { + if (prop === IS_UNION_ARRAY && hasUnionArrayProxy) { + return { + value: true, + writable: false, + enumerable: false, + configurable: false, + } + } + return Object.getOwnPropertyDescriptor(target, prop) + }, + }) + + if ( + !Object.prototype.hasOwnProperty.call(fieldProxy, IS_UNION_ARRAY) && + Object.getOwnPropertyDescriptor(fieldProxy, IS_UNION_ARRAY) === undefined + ) { + Object.defineProperty(fieldProxy, IS_UNION_ARRAY, { + value: true, + writable: false, + enumerable: false, + configurable: false, + }) + hasUnionArrayProxy = true + } + + Object.defineProperty(fieldProxy, RAW_TARGET, { + value: rawArray, + writable: false, + enumerable: false, + configurable: false, + }) + + this._field = fieldProxy } + /** + * 已废弃:uuid 不再随 field 变化重算 + */ + updateUUID(): void {} + /** * Check if union is in BVT to prevent infinite loops * @param targetUnion - Target union * @param baseBVT - Base BVT */ - private isUnionInBVT(targetUnion: UnionValue, baseBVT: any): boolean { + private isUnionInBVT(targetUnion: UnionValue, baseBVT: Unit, visited?: Set): boolean { if (!targetUnion || !baseBVT) return false + if (!visited) visited = new Set() + if (visited.has(baseBVT)) return false + visited.add(baseBVT) + if (baseBVT.vtype === 'BVT') { // 如果存在 children 属性,则递归检查每个子对象 if (baseBVT.children && typeof baseBVT.children === 'object') { @@ -194,14 +422,14 @@ class UnionValue extends Unit { // 如果子对象的 vtype 为 "union",检查其值是否为 "this" if (child.vtype === 'union') { - if (child.field === targetUnion.field) { + if (child._field === targetUnion._field) { return true } } // 如果子对象的 vtype 为 "BVT",递归检查它 else if (child.vtype === 'BVT') { - if (this.isUnionInBVT(targetUnion, child)) { - return true // 如果递归检查失败,返回 false + if (this.isUnionInBVT(targetUnion, child, visited)) { + return true } } } @@ -214,5 +442,3 @@ class UnionValue extends Unit { return false } } - -module.exports = UnionValue diff --git a/src/engine/analyzer/common/value/unit.js b/src/engine/analyzer/common/value/unit.js deleted file mode 100644 index 7baf1de8..00000000 --- a/src/engine/analyzer/common/value/unit.js +++ /dev/null @@ -1,327 +0,0 @@ -const _ = require('lodash') -const { Errors } = require('../../../../util/error-code') - -/** - * - */ -class Unit { - vtype // value type - - field // indicates the fields of the value, TODO rename to [field] when backward compatibility is take out - - // value has different meaning in different type of Value - // in most cases value is the ref of field - // value and field are different in few scenes, e.g. - // string type in javascript, 'hello' is value, and field has toString, toUpperCase, etc in it, - // representing the member access of it - // value; - // raw_value; - _sid // symbolic id - - _id - - _qid // qualified sid - - sort // type of the value, in order to tell apart from type of the node, we use sort here - - ast // uast node where the value be retrieved - - decl // uast node where the value be declared - - trace - - misc_ // misc information - - _has_tags - - _tags - - /** - * - * @param root0 - * @param root0.vtype - * @param root0.field - * @param root0.value - */ - constructor({ vtype, field, value, ...opts }) { - this.vtype = vtype - if (value !== undefined) { - this.raw_value = value - } - - this.field = field || createField() - - this.misc_ = new Object() - // this._tags = new Set() - - this.decls = this.decls || {} - this.id = this.id || this.sid - - for (const key of Object.keys(opts)) { - if (key === 'parent' && !opts[key]?.vtype && opts[key]?.type) { - continue - } - this[key] = opts[key] - } - } - - /** - * - */ - get qid() { - return this._qid || this._sid || this._id - } - - /** - * - */ - set qid(id) { - this._qid = id - } - - /** - * - */ - get id() { - return this._id || this._sid || this._qid - } - - /** - * - */ - set id(id) { - this._id = id - } - - /** - * - */ - get sid() { - return this._sid || this._id || this._qid - } - - /** - * - */ - set sid(id) { - this._sid = id - } - - /** - * - */ - get value() { - if (Object.prototype.hasOwnProperty.call(this, 'raw_value')) { - return this.raw_value - } - return this.field - } - - /** - * - */ - set value(val) { - // this. - this.field = val - } - - /** - * - * @param tag - */ - getTrace(tag) { - if (!this._has_tags) return null - if (this._tags.has(tag)) { - return this.trace - } - } - - /** - * - * @param ids - * @param createIfNotExists - */ - getFieldValue(ids, createIfNotExists) { - if (!ids) { - // error should not be thrown out - try { - Errors.IllegalUse('getFieldValue ids should not be empty') - } catch (e) {} - return new Unit({ - vtype: 'unknown', - }) - } - - if (!Array.isArray(ids)) { - ids = ids.split('.') - } - - let fval = this - for (let i = 0; i < ids.length; i++) { - const fname = ids[i] - let sub_fval - if (Object.prototype.hasOwnProperty.call(fval.field, fname)) { - sub_fval = fval.field[fname] - } - if (!sub_fval) { - if (createIfNotExists) { - sub_fval = new Unit({ - vtype: 'object', - sid: fname, - qid: `${this.sid}.${fname}`, - }) - - if (this._has_tags) { - sub_fval.hasTagRec = this._has_tags - } - if (typeof this._tags !== 'undefined') { - sub_fval._tags = _.clone(this._tags) - } - if (this.trace) { - sub_fval.trace = _.clone(this.trace) - } - - fval.field[fname] = sub_fval - } else { - // Errors.UnexpectedValue(`getFieldValue: ${i} is not in ${sub_fval.sid}`, {no_throw: true}); - return - } - } - fval = sub_fval - } - - return fval - } - - /** - * - * @param fieldName - */ - getFieldValueIfNotExists(fieldName) { - return this.getFieldValue(fieldName, true) - } - - /** - * set the id's value in this; the id "x.y.z" is of format [x, y, z] or 'x.y.z' - * @param ids: 'x.y.z' or ['x', 'y', 'z'] - * @param value: the value to be assigned - * @param ids - * @param value - */ - setFieldValue(ids, value) { - let scp = this - ids = Array.isArray(ids) ? ids : ids.toString().split('.') - - for (let i = 0; i < ids.length - 1; i++) { - const fname = ids[i] - const scp1 = scp.field[fname] - if (!scp1) { - scp.field[fname] = new Unit({ - vtype: 'object', - }) - } else { - scp1.parent = scp - } - scp = scp.field[fname] - } - scp.value[ids[ids.length - 1]] = value - } - - /** - * - */ - getRawValue() { - return this.value - } - - /** - * - */ - getQualifiedId() { - return this.qid - } - - /** - * - */ - get _this() { - return this.__this - } - - /** - * - */ - set _this(value) { - this.__this = value - } - - /** - * - */ - getThis() { - let scp = this - let _this - while (scp) { - _this = scp._this - if (_this) { - return _this - } - if (this.vtype === 'object') { - return this - } - scp = scp.parent - } - return this - } - - /** - * - * @param key - * @param value - */ - setMisc(key, value) { - this.misc_[key] = value - } - - /** - * - * @param key - */ - getMisc(key) { - return this.misc_[key] - } - - /** - * - */ - reset() { - this.misc_ = new Object() - // TODO taint reset - } - - /** - * - */ - get hasTagRec() { - return this._has_tags - } - - /** - * - * @param value - */ - set hasTagRec(value) { - this._has_tags = value - } -} - -// TODO return new Map() instead of {} when backward compatibility is take out -/** - * - */ -function createField() { - return {} - // return new Map(); -} - -module.exports = Unit diff --git a/src/engine/analyzer/common/value/unit.ts b/src/engine/analyzer/common/value/unit.ts new file mode 100644 index 00000000..d6fbfdbc --- /dev/null +++ b/src/engine/analyzer/common/value/unit.ts @@ -0,0 +1,585 @@ +import { AstBinding } from './ast-binding' +import { ValueRef } from './value-ref' +import { ScopeCtx } from './scope-ctx' +import { AstRefList } from './ast-ref-list' +import { TaintRecord } from './taint-record' + +const _ = require('lodash') +const { Errors } = require('../../../../util/error-code') +const { getGlobalSymbolTable, getGlobalASTManager } = require('../../../../util/global-registry') +const { yasaWarning } = require('../../../../util/format-util') +const QidUnifyUtil = require('../../../../util/qid-unify-util') + +class Unit { + // Allows subclass properties assigned via constructor opts + [key: string]: any + + // ===== Public fields ===== + vtype: string = '' + uuid: string = '' + declsNodehash: any = undefined + _taint: TaintRecord | null = null + misc_: Record = {} + + // ===== Private fields ===== + _sid: string = '' + _qid: string = '' + _field: Record = {} + _ast: AstBinding | undefined = undefined + _scopeCtx: ScopeCtx | undefined = undefined + overloaded: AstRefList | undefined = undefined + _parentRef: ValueRef | null = null + _thisRef: ValueRef | null = null + _superRef: ValueRef | null = null + _packageScopeRef: ValueRef | null = null + _isConstructing: boolean = false + + constructor(opts: Record) { + const { vtype, _field, value } = opts + if (opts.qid === undefined || opts.sid === undefined) { + if (opts._qid === undefined || opts._sid === undefined) { + const _caller = new Error().stack?.split('\n').slice(1, 5).map((l: string) => l.trim()).join(' <- ') + yasaWarning(`Missing qid/sid in ${vtype} Value (type: ${opts.type}, name: ${opts.name}, sid: ${opts.sid}, qid: ${opts.qid}) | ${_caller}`) + opts.sid = opts.name || opts.type || '' + opts.qid = opts.sid + } + } + this.vtype = vtype + if (value !== undefined) { + this.raw_value = value + } + + this._field = _field ?? {} + + this.misc_ = new Object() + + this._ast = new AstBinding(this) + const oldDecls = opts.decls + if (oldDecls && typeof oldDecls === 'object' && !Array.isArray(oldDecls)) { + this._ast.initDecls(oldDecls) + } + + this._scopeCtx = new ScopeCtx(this) + + const getAM = () => this.getASTManager() + const oldOverloaded = opts.overloaded + this.overloaded = oldOverloaded && Array.isArray(oldOverloaded) + ? AstRefList.from(oldOverloaded, getAM) + : new AstRefList(getAM) + + if (opts.parent !== undefined) this.parent = opts.parent + + if (opts.parent_uuid !== undefined) { + this._parentRef = opts.parent_uuid ? new ValueRef(opts.parent_uuid) : null + } + if (opts.__this !== undefined) { + this._thisRef = opts.__this ? new ValueRef(opts.__this) : null + } + if (opts.__superUuid !== undefined) { + this._superRef = opts.__superUuid ? new ValueRef(opts.__superUuid) : null + } + if (opts.__packageScopeUuid !== undefined) { + this._packageScopeRef = opts.__packageScopeUuid ? new ValueRef(opts.__packageScopeUuid) : null + } + + if (opts.ast !== undefined) this.ast = opts.ast + + if (opts.exports !== undefined) this._scopeCtx.exports = opts.exports + + this._isConstructing = true + + // --- Unit/ValueBase layer property assignments --- + + // Identity + if ('sid' in opts) this.sid = opts.sid + if ('qid' in opts) this.qid = opts.qid + if ('_sid' in opts) this._sid = opts._sid + if ('_qid' in opts) this._qid = opts._qid + if ('name' in opts) this.name = opts.name + + // Value + if ('raw_value' in opts) this.raw_value = opts.raw_value + if ('values' in opts) this.values = opts.values + + // References (via setter → ValueRef) + if ('_this' in opts) this._this = opts._this + if ('super' in opts) this.super = opts.super + if ('packageScope' in opts) this.packageScope = opts.packageScope + + // AST / Type (cross-layer) + if ('loc' in opts) this.loc = opts.loc + if ('declsNodehash' in opts) this.declsNodehash = opts.declsNodehash + if ('type' in opts) this.type = opts.type + if ('rtype' in opts) this.rtype = opts.rtype + + // Taint(懒分配:默认 _taint=null,getter 按需创建) + // 来源 1:clone/显式传入 taint(data property) + // 来源 2:{...unit} spread 传入 _taint(因 taint 是 getter 不被 spread 复制) + const srcTaint = ('taint' in opts && opts.taint instanceof TaintRecord) ? opts.taint + : ('_taint' in opts && opts._taint instanceof TaintRecord) ? opts._taint + : null + if (srcTaint) { + this._taint = new TaintRecord(this) + this._taint.copyFrom(srcTaint) + } + + // Misc + if ('misc_' in opts) this.misc_ = opts.misc_ + + // Internal (via {...unit} spread / clone) + if ('_ast' in opts) this._ast = opts._ast + if ('_parentRef' in opts) this._parentRef = opts._parentRef + if ('_thisRef' in opts) this._thisRef = opts._thisRef + if ('_superRef' in opts) this._superRef = opts._superRef + if ('_packageScopeRef' in opts) this._packageScopeRef = opts._packageScopeRef + if ('_meta' in opts) this._meta = opts._meta + if ('_declsNodehashMap' in opts) this._declsNodehashMap = opts._declsNodehashMap + if ('_logicalQid' in opts) this._logicalQid = opts._logicalQid + if ('_scopeCtx' in opts) this._scopeCtx = opts._scopeCtx + if ('_dedup' in opts) this._dedup = opts._dedup + if ('_isConstructor' in opts) this._isConstructor = opts._isConstructor + + // Control + if ('_skipRegister' in opts) this._skipRegister = opts._skipRegister + + this._isConstructing = false + + if (!opts._skipRegister) { + this.calculateAndRegisterUUID() + } + } + + get sid(): string { + return this._sid + } + + set sid(value: string) { + this._sid = value + } + + setAlias(name: string): void { + this._sid = name + } + + get qid(): string { + return this._qid + } + + get logicalQid(): string { + if (this._logicalQid === undefined) { + this._logicalQid = QidUnifyUtil.qidUnifyByRemoveAngleAndPrefix(this) + } + return this._logicalQid + } + + set qid(value: string) { + const oldValue = this._qid + this._qid = value + if (oldValue !== value && !this._isConstructing) { + if (oldValue !== undefined && oldValue !== null) { + const _caller = new Error().stack?.split('\n').slice(1, 3).map((l: string) => l.trim()).join(' <- ') + yasaWarning(`qid mutation after construction: "${oldValue}" → "${value}" (vtype=${this.vtype}) | ${_caller}`) + } + } + } + + get value(): any { + if (Object.prototype.hasOwnProperty.call(this, 'raw_value')) { + return this.raw_value + } + return this._field + } + + set value(val: any) { + this._field = val ?? {} + } + + getTrace(tag: string): any[] | null { + return this.taint.getTrace(tag) ?? null + } + + getMemberValue(fieldName: string): Unit | null { + if (this.members) { + const val = this.members.get(fieldName) + if (val != null) return val + // 回退:members 无此 key,继续查 _field + } + if (!Object.prototype.hasOwnProperty.call(this._field, fieldName)) { + return null + } + const fieldValue = this._field[fieldName] + if (typeof fieldValue === 'string' && fieldValue.startsWith('symuuid_')) { + const symbolTable = this.getSymbolTable() + if (symbolTable) { + const resolved = symbolTable.get(fieldValue) + if (resolved) { + return resolved + } + } + } + return fieldValue + } + + setMemberValue(fieldName: string, value: any): void { + if (this.members) { this.members.set(fieldName, value); return } + if (!value) { + delete this._field[fieldName] + return + } + + if (value instanceof Unit || (value.vtype && value.qid)) { + if (value.uuid) { + this._field[fieldName] = value.uuid + } else { + const symbolTable = this.getSymbolTable() + if (symbolTable) { + const uuid = symbolTable.register(value) + this._field[fieldName] = uuid + } else { + this._field[fieldName] = value + } + } + } else { + this._field[fieldName] = value + } + } + + getFieldValue(ids: string | string[], createIfNotExists?: boolean): Unit | undefined { + if (!ids) { + try { + Errors.IllegalUse('getFieldValue ids should not be empty') + } catch (e) {} + return new Unit({ + vtype: 'unknown', + sid: '', + qid: '', + }) + } + + if (!Array.isArray(ids)) { + ids = ids.split('.') + } + + let fval: Unit = this + for (let i = 0; i < ids.length; i++) { + const fname = ids[i] + let sub_fval = fval.getMemberValue(fname) + if (!sub_fval) { + if (createIfNotExists) { + sub_fval = new Unit({ + vtype: 'object', + sid: fname, + qid: `${fval.sid}.${fname}`, + parent: fval, + }) + + if (fval._taint) sub_fval._taint = fval._taint._clone(sub_fval) + + fval.setMemberValue(fname, sub_fval) + } else { + return + } + } + fval = sub_fval + } + + return fval + } + + getFieldValueIfNotExists(fieldName: string): Unit | undefined { + return this.getFieldValue(fieldName, true) + } + + setFieldValue(ids: string | string[], value: Unit | null): void { + let scp: Unit = this + ids = Array.isArray(ids) ? ids : ids.toString().split('.') + + for (let i = 0; i < ids.length - 1; i++) { + const fname = ids[i] + let scp1 = scp.getMemberValue(fname) + if (!scp1) { + scp1 = new Unit({ + vtype: 'object', + sid: '', + qid: '', + parent: scp, + }) + scp.setMemberValue(fname, scp1) + } else { + scp1.parent = scp + } + scp = scp1 + } + scp.setMemberValue(ids[ids.length - 1], value) + } + + getRawValue(): any { + return this.value + } + + getQualifiedId(): string { + return this.qid + } + + get _this(): Unit | null { return this._resolveValueRef(this._thisRef) } + set _this(unit: Unit | null) { this._thisRef = this._makeValueRef(unit) } + + getThisObj(): Unit { + let scp: Unit | null = this + let _this: Unit | null + let depth = 0 + const maxDepth = 100 + while (scp && depth < maxDepth) { + _this = scp._this + if (_this) { + return _this + } + if (this.vtype === 'object') { + return this + } + scp = scp.parent + depth++ + } + return this + } + + setMisc(key: string, value: any): void { + this.misc_[key] = value + } + + getMisc(key: string): any { + return this.misc_[key] + } + + reset(): void { + this.misc_ = new Object() + this.taint.clear() + } + + + + + getASTManager(): any { + const globalASTManager = getGlobalASTManager() + if (globalASTManager) { + return globalASTManager + } + return null + } + + getSymbolTable(): any { + const globalSymbolTable = getGlobalSymbolTable() + if (globalSymbolTable) { + return globalSymbolTable + } + return null + } + + _resolveValueRef(ref: ValueRef | null): Unit | null { + if (!ref) return null + const st = this.getSymbolTable() + return st ? st.get(ref.uuid) : null + } + + _makeValueRef(unit: Unit | null): ValueRef | null { + if (!unit) return null + if (unit.uuid) return new ValueRef(unit.uuid) + const st = this.getSymbolTable() + if (st) { + const uuid = st.register(unit) + return new ValueRef(uuid) + } + return null + } + + _makeValueRefDirect(unit: Unit | string | null | undefined): ValueRef | null { + if (unit == null) return null + if (typeof unit === 'string' && unit.startsWith('symuuid')) { + return new ValueRef(unit) + } + const uuid = (typeof unit === 'object' && unit.uuid) ? unit.uuid : '' + return new ValueRef(uuid, unit) + } + + calculateAndRegisterUUID(): void { + const symbolTable = this.getSymbolTable() + if (!symbolTable) { + return + } + symbolTable.register(this) + } + + get taint(): TaintRecord { + if (!this._taint) this._taint = new TaintRecord(this) + return this._taint + } + + set taint(val: TaintRecord) { + this._taint = val + } + + get ast(): AstBinding { + return this._ast! + } + + set ast(astNode: any) { + if (this._ast) this._ast.node = astNode + } + + get scope(): ScopeCtx { + return this._scopeCtx! + } + + get parent(): Unit | null { return this._resolveValueRef(this._parentRef) } + set parent(unit: Unit | null) { this._parentRef = this._makeValueRef(unit) } + + get packageScope(): Unit | null { return this._resolveValueRef(this._packageScopeRef) } + set packageScope(unit: Unit | null) { this._packageScopeRef = this._makeValueRef(unit) } + + get super(): Unit | null { return this._resolveValueRef(this._superRef) } + set super(unit: Unit | null) { this._superRef = this._makeValueRef(unit) } + + clone(): this { + const copy: this = Object.create(Object.getPrototypeOf(this)) + const keys = Object.keys(this) + for (let i = 0; i < keys.length; i++) { + const key = keys[i] + const desc = Object.getOwnPropertyDescriptor(this, key) + if (!desc || !('value' in desc)) continue + if (key === '_field') { + // 跳过 _field,clone 完成后通过 field setter 处理 + } else { + copy[key] = desc.value + } + } + // 克隆 _field:浅拷贝 plain object,保留 UUID 字符串 + const fieldValue = this._field + if (fieldValue && typeof fieldValue === 'object') { + const fieldCopy: Record = {} + for (const fk in fieldValue) { + if (!Object.prototype.hasOwnProperty.call(fieldValue, fk)) continue + const fd = Object.getOwnPropertyDescriptor(fieldValue, fk) + if (fd && 'value' in fd && typeof fd.value === 'string' && fd.value.startsWith('symuuid')) { + fieldCopy[fk] = fd.value + } else { + fieldCopy[fk] = fieldValue[fk] + } + } + copy._field = fieldCopy + } else { + copy._field = fieldValue + } + if (copy._taint) copy._taint = copy._taint._clone(copy) + if (copy._ast && typeof copy._ast._clone === 'function') { + copy._ast = copy._ast._clone(copy) + } + if (copy._scopeCtx && typeof copy._scopeCtx._clone === 'function') { + copy._scopeCtx = copy._scopeCtx._clone(copy) + } + copy._skipRegister = true + return copy + } + + /** + * Shallow copy that shares _field Proxy (alias semantics). + * Multiple Values reference the same field storage. + * Property groups (taint/runtime/func/_ast/_scopeCtx) get independent shallow copies. + */ + cloneAlias(): this { + const copy: this = Object.create(Object.getPrototypeOf(this)) + const keys = Object.keys(this) + for (let i = 0; i < keys.length; i++) { + const key = keys[i] + const desc = Object.getOwnPropertyDescriptor(this, key) + if (!desc || !('value' in desc)) continue + copy[key] = desc.value + } + const exprRefKeys = ['_objectRef', '_propertyRef', '_leftRef', '_rightRef', '_calleeRef', '_argumentRefs', '_expressionRef', '_argumentRef'] + for (let i = 0; i < exprRefKeys.length; i++) { + const key = exprRefKeys[i] + if (!Object.prototype.hasOwnProperty.call(this, key)) continue + const sourceDesc = Object.getOwnPropertyDescriptor(this, key) + if (!sourceDesc || !('value' in sourceDesc)) continue + Object.defineProperty(copy, key, { + value: sourceDesc.value, + writable: sourceDesc.writable ?? true, + enumerable: false, + configurable: sourceDesc.configurable ?? true, + }) + } + // Rebuild own enumerable accessors for getter-based operands so that + // satisfy() (for...in + hasOwnProperty) can traverse them on the clone. + const exprPropPairs: [string, string][] = [ + ['_leftRef', 'left'], + ['_rightRef', 'right'], + ['_objectRef', 'object'], + ['_propertyRef', 'property'], + ['_calleeRef', 'callee'], + ['_argumentRef', 'argument'], + ] + for (let i = 0; i < exprPropPairs.length; i++) { + const [refKey, propKey] = exprPropPairs[i] + if (!Object.prototype.hasOwnProperty.call(this, refKey)) continue + const propVal = (this as any)[propKey] + if (propVal !== undefined) { + Object.defineProperty(copy, propKey, { + value: propVal, + writable: true, + enumerable: true, + configurable: true, + }) + } + } + // Rebuild arguments accessor for CallExprValue clones + if (Object.prototype.hasOwnProperty.call(this, '_argumentRefs')) { + Object.defineProperty(copy, 'arguments', { + get(this: any) { + if (!this._argumentRefs) return [] + return this._argumentRefs.map((ref: any) => ref?.resolve(this.getSymbolTable()) ?? undefined) + }, + set(this: any, val: any) { + this._argumentRefs = Array.isArray(val) + ? val.map((v: any) => v != null ? this._makeValueRefDirect(v) : null) + : [] + }, + enumerable: true, + configurable: true, + }) + } + // Rebuild expression accessor for CallExprValue clones + if (Object.prototype.hasOwnProperty.call(this, '_expressionRef')) { + Object.defineProperty(copy, 'expression', { + get(this: any) { return this._expressionRef?.resolve(this.getSymbolTable()) ?? undefined }, + set(this: any, val: any) { this._expressionRef = val != null ? this._makeValueRefDirect(val) : null }, + enumerable: true, + configurable: true, + }) + } + if (copy._taint) copy._taint = copy._taint._clone(copy) + if (copy.runtime && typeof copy.runtime === 'object') { + copy.runtime = { ...copy.runtime } + } + if (copy.func && typeof copy.func === 'object') { + copy.func = { ...copy.func } + } + if (copy._ast && typeof copy._ast._clone === 'function') { + copy._ast = copy._ast._clone(copy) + } + if (copy._scopeCtx && typeof copy._scopeCtx._clone === 'function') { + copy._scopeCtx = copy._scopeCtx._clone(copy) + } + // Share _members for EntityValue aliases (non-enumerable, not copied by Object.keys) + if ((this as any)._members) { + Object.defineProperty(copy, '_members', { + value: (this as any)._members, + writable: true, + enumerable: false, + configurable: true, + }) + } + copy._skipRegister = true + return copy + } +} + +export = Unit diff --git a/src/engine/analyzer/common/value/unkown.ts b/src/engine/analyzer/common/value/unkown.ts index 142e5bca..8b4ef073 100644 --- a/src/engine/analyzer/common/value/unkown.ts +++ b/src/engine/analyzer/common/value/unkown.ts @@ -1,23 +1,36 @@ -const Unit = require('./unit') +import { SentinelValue } from './sentinel-value' interface UnknownValueOptions { - [key: string]: any + sid?: string + qid?: string } /** + * UnknownValue - 未知类型的值 * + * BVT 模式:固定构造函数签名 */ -class UnknownValue extends Unit { +export class UnknownValue extends SentinelValue { /** - * - * @param opts + * 创建 UnknownValue + * @param upperQid - 父作用域的 qid(可选,默认 '') + * @param sid - 符号 ID(可选,默认 '') */ - constructor(opts?: UnknownValueOptions) { - super({ - vtype: 'unknown', - ...opts, - }) + constructor(upperQid: string = '', sid: string = '') { + super('unknown', upperQid, { sid }) } -} -module.exports = UnknownValue + /** + * 从序列化的 opts 对象恢复 UnknownValue(仅用于反序列化) + */ + static fromOpts(upperQid: string, opts: UnknownValueOptions): UnknownValue { + const sid = opts?.sid || '' + const qid = opts?.qid + const unknownValue = new UnknownValue(upperQid, sid) + // 反序列化时恢复原始 qid + if (qid) { + unknownValue._qid = qid + } + return unknownValue + } +} diff --git a/src/engine/analyzer/common/value/value-base.ts b/src/engine/analyzer/common/value/value-base.ts new file mode 100644 index 00000000..97fd2afd --- /dev/null +++ b/src/engine/analyzer/common/value/value-base.ts @@ -0,0 +1,261 @@ +import Unit = require('./unit') +import { TaintRecord } from './taint-record' + +/** + * AstBinding - AST 绑定属性组(EntityValue 特有) + * + * 将 node/fdef/cdef/decls/id 聚合为一个属性组 + * 底层通过 AstRef 存储 nodehash,getter 自动通过 ASTManager resolve + */ +export interface AstBinding { + node: any // AST 节点(对应原 ast 属性) + fdef: any // 函数定义 AST 节点 + cdef: any // 类定义 AST 节点 + decls: any // 声明映射(Proxy,name → AST node) + id: any // 标识符 AST 节点 +} + +/** + * SpringCtx - Spring 框架上下文(仅 Spring 项目使用) + */ +export interface SpringCtx { + beanMap: Map + springReferenceMap: Map + springServiceMap: Map +} + +/** + * FuncMeta - 函数元信息(FunctionValue 特有) + * + * 注意:attribute/filePath 属于 EntryPoint,不在此处 + */ +export interface FuncMeta { + inherited?: boolean // 是否继承自父类 + superDef?: any // 父类方法定义(AST node) + jumpLocate?: ((val: any, qid: any, scope: any) => any) | null // 跳转位置回调 +} + +/** + * RuntimeState - 运行时状态属性组 + * + * 聚合 execute/readonly/refCount/ctorInit/transDep + * opts 中直接传入 runtime: { execute: fn } 形式 + */ +export interface RuntimeState { + refCount?: number // 引用计数(指针语义,Go) + readonly?: boolean // 是否只读 + execute?: Function | null // 内建执行函数(替代 AST 解释执行) + ctorInit?: boolean // 构造函数初始化标记 + transDep?: any // 传递依赖 +} + +/** + * ValueBase - 所有 Value 类的基类 + * + * 职责: + * - 处理构造函数重载(支持 opts 或 upperQid+opts 两种调用方式) + * - 统一处理 sid/qid 生成和拼接 + * - 简化子类实现(子类只需传递 vtype) + * - 提供 clone() 基础实现(子类 override 处理特有成员) + */ +export class ValueBase extends Unit { + declare _taint: TaintRecord | null + /** + * Constructor with options only + * @param vtype - Value type + * @param opts - Options + */ + constructor(vtype: string, opts?: any) + /** + * Constructor with upperQid and options + * @param vtype - Value type + * @param upperQid - Parent qualified ID + * @param opts - Options + */ + constructor(vtype: string, upperQid: string, opts: any) + constructor(vtype: string, upperQidOrOpts?: string | any, opts?: any) { + let upperQid: string = '' + let finalOpts: any + + // 处理构造函数重载 + if (typeof upperQidOrOpts === 'string') { + // Called as: new XxxValue(upperQid, opts) + upperQid = upperQidOrOpts + finalOpts = opts || {} + } else { + // Called as: new XxxValue(opts) + upperQid = '' + finalOpts = upperQidOrOpts || {} + } + + // 统一处理 sid/qid 生成和拼接 + const preparedOpts = ValueBase.prepareOpts(upperQid, finalOpts) + + // 调用 Unit 构造函数 + super({ + vtype, + ...preparedOpts, + }) + } + + /** + * Prepare options for Value constructor + * Handles sid/qid generation and concatenation + * + * @param upperQid - Parent qualified ID + * @param opts - Options to prepare + * @returns Prepared options with sid/qid + */ + protected static prepareOpts(upperQid: string, opts: Record): any { + // Generate sid if not provided + if (opts.sid === undefined && opts._sid === undefined) { + if (opts.name !== undefined && typeof opts.name === 'string') { + opts.sid = opts.name + } else if (opts.value !== undefined && typeof opts.value === 'string') { + opts.sid = opts.value + } + } + + // Generate qid from sid if not provided + if (opts.qid === undefined && opts.sid !== undefined) { + opts.qid = opts.sid + } + + // Concatenate with parent qid if needed + if (upperQid && upperQid !== '' && opts.qid && !opts.qid.startsWith(upperQid)) { + opts.qid = `${upperQid}.${opts.qid}` + } + + return opts || {} + } + + /** + * Clone this value: same prototype, own properties copied, property groups deep-copied. + * Subclasses override for type-specific members (e.g. UnionValue resets WeakSet). + */ + override clone(): this { + const copy: any = Object.create(Object.getPrototypeOf(this)) + + // Copy enumerable own data properties only (matches old for...in + hasOwnProperty) + const keys = Object.keys(this as any) + for (let i = 0; i < keys.length; i++) { + const key = keys[i] + const desc = Object.getOwnPropertyDescriptor(this, key) + if (!desc || !('value' in desc)) continue + + if (key === '_field') { + this._cloneField(copy, desc.value) + } else { + copy[key] = desc.value + } + } + + const exprRefKeys = ['_objectRef', '_propertyRef', '_leftRef', '_rightRef', '_calleeRef', '_argumentRefs', '_expressionRef', '_argumentRef'] + for (let i = 0; i < exprRefKeys.length; i++) { + const key = exprRefKeys[i] + if (!Object.prototype.hasOwnProperty.call(this, key)) continue + const sourceDesc = Object.getOwnPropertyDescriptor(this, key) + if (!sourceDesc || !('value' in sourceDesc)) continue + Object.defineProperty(copy, key, { + value: sourceDesc.value, + writable: sourceDesc.writable ?? true, + enumerable: false, + configurable: sourceDesc.configurable ?? true, + }) + } + + // Rebuild own enumerable accessors for getter-based operands so that + // satisfy() (for...in + hasOwnProperty) can traverse them on the clone. + const exprPropPairs: [string, string][] = [ + ['_leftRef', 'left'], + ['_rightRef', 'right'], + ['_objectRef', 'object'], + ['_propertyRef', 'property'], + ['_calleeRef', 'callee'], + ['_argumentRef', 'argument'], + ] + for (let i = 0; i < exprPropPairs.length; i++) { + const [refKey, propKey] = exprPropPairs[i] + if (!Object.prototype.hasOwnProperty.call(this, refKey)) continue + const propVal = (this as any)[propKey] + if (propVal !== undefined) { + Object.defineProperty(copy, propKey, { + value: propVal, + writable: true, + enumerable: true, + configurable: true, + }) + } + } + // Rebuild arguments accessor for CallExprValue clones + if (Object.prototype.hasOwnProperty.call(this, '_argumentRefs')) { + Object.defineProperty(copy, 'arguments', { + get(this: any) { + if (!this._argumentRefs) return [] + return this._argumentRefs.map((ref: any) => ref?.resolve(this.getSymbolTable()) ?? undefined) + }, + set(this: any, val: any) { + this._argumentRefs = Array.isArray(val) + ? val.map((v: any) => v != null ? this._makeValueRefDirect(v) : null) + : [] + }, + enumerable: true, + configurable: true, + }) + } + // Rebuild expression accessor for CallExprValue clones + if (Object.prototype.hasOwnProperty.call(this, '_expressionRef')) { + Object.defineProperty(copy, 'expression', { + get(this: any) { return this._expressionRef?.resolve(this.getSymbolTable()) ?? undefined }, + set(this: any, val: any) { this._expressionRef = val != null ? this._makeValueRefDirect(val) : null }, + enumerable: true, + configurable: true, + }) + } + + // Deep-copy taint via TaintRecord._clone(跳过未初始化的) + if (copy._taint) { + copy._taint = copy._taint._clone(copy) + } + // Deep-copy runtime + if (copy.runtime && typeof copy.runtime === 'object') { + copy.runtime = { ...copy.runtime } + } + // func: reference copy only (matches old shallowCopyValue behavior) + + // Clone RefGroups and rebind to new owner + if (copy._ast && typeof copy._ast._clone === 'function') { + copy._ast = copy._ast._clone(copy) + } + if (copy._scopeCtx && typeof copy._scopeCtx._clone === 'function') { + copy._scopeCtx = copy._scopeCtx._clone(copy) + } + + copy._skipRegister = true + return copy as this + } + + /** + * Clone _field storage. Iterates _field Proxy entries, preserving UUID strings + * and shallow-copying non-UUID values to match legacy shallowCopyValue semantics. + * Subclasses override for different field types (e.g. UnionValue array). + */ + protected _cloneField(copy: any, fieldValue: any): void { + if (!fieldValue || typeof fieldValue !== 'object') { + copy._field = fieldValue + return + } + + const fieldCopy: Record = {} + for (const key in fieldValue) { + if (!Object.prototype.hasOwnProperty.call(fieldValue, key)) continue + const desc = Object.getOwnPropertyDescriptor(fieldValue, key) + if (desc && 'value' in desc && typeof desc.value === 'string' && desc.value.startsWith('symuuid')) { + fieldCopy[key] = desc.value + } else { + fieldCopy[key] = fieldValue[key] + } + } + copy._field = fieldCopy + } +} diff --git a/src/engine/analyzer/common/value/value-ref-list.ts b/src/engine/analyzer/common/value/value-ref-list.ts new file mode 100644 index 00000000..73f47522 --- /dev/null +++ b/src/engine/analyzer/common/value/value-ref-list.ts @@ -0,0 +1,440 @@ +import { ValueRef } from './value-ref' +import type Unit from './unit' +import type { ValueRegistry } from './value-ref-map' +import { RAW_TARGET, IS_UNION_ARRAY } from './symbols' + +/** + * ValueRefList — 内部存 ValueRef[],通过 Proxy 对外模拟原生 Array + * + * proxy[i] → resolve ValueRef → 返回 Value(走缓存) + * proxy[i] = val → 转 ValueRef 存储 + * proxy.push() → 拦截,存 ValueRef + * proxy.length → _refs.length + * Array.isArray(proxy) → true(target 是真数组) + * for...of → 自动 resolve 每个元素 + */ +export class ValueRefList { + _refs: ValueRef[] = [] + private _getSymbolTable: () => ValueRegistry | null + private _proxy: any + private _onMutate: (() => void) | null = null + + constructor(getSymbolTable: () => ValueRegistry | null, onMutate?: () => void) { + this._getSymbolTable = getSymbolTable + this._onMutate = onMutate || null + this._proxy = this._createProxy() + } + + private _resolve(ref: ValueRef): any { + if (!ref) return undefined + const st = this._getSymbolTable() + if (st) { + const value = ref.resolve(st) + if (value) return value + } + return ref.uuid + } + + getProxy(): any { + return this._proxy + } + + get length(): number { + return this._refs.length + } + + set length(val: number) { + this._refs.length = val + } + + push(...values: (Unit | ValueRef | string)[]): number { + for (const value of values) { + if (value instanceof ValueRef) { + this._refs.push(value) + } else if (typeof value === 'string') { + if (value.startsWith('symuuid_')) { + this._refs.push(new ValueRef(value)) + } + } else { + const uuid = value.uuid + if (uuid) { + this._refs.push(new ValueRef(uuid)) + } + } + } + return this._refs.length + } + + set(index: number, value: Unit | ValueRef | string | null | undefined): void { + if (value === null || value === undefined) { + if (index >= 0 && index < this._refs.length) { + this._refs.splice(index, 1) + } + return + } + let ref: ValueRef + if (value instanceof ValueRef) { + ref = value + } else if (typeof value === 'string') { + ref = new ValueRef(value) + } else { + const st = this._getSymbolTable() + if (st) { + const newUuid = st.register(value) + if (newUuid) { + ref = new ValueRef(newUuid) + } else { + return + } + } else { + const uuid = value.uuid + if (uuid) { + ref = new ValueRef(uuid) + } else { + return + } + } + } + if (index >= 0) { + this._refs[index] = ref + } + } + + toArray(): any[] { + return this._refs.map(ref => this._resolve(ref)) + } + + some(fn: (value: any, index: number) => boolean): boolean { + for (let i = 0; i < this._refs.length; i++) { + if (fn(this._resolve(this._refs[i]), i)) return true + } + return false + } + + find(fn: (value: any, index: number) => boolean): any { + for (let i = 0; i < this._refs.length; i++) { + const v = this._resolve(this._refs[i]) + if (fn(v, i)) return v + } + return undefined + } + + forEach(fn: (value: any, index: number) => void): void { + for (let i = 0; i < this._refs.length; i++) { + fn(this._resolve(this._refs[i]), i) + } + } + + map(fn: (value: any, index: number) => T): T[] { + const result: T[] = [] + for (let i = 0; i < this._refs.length; i++) { + result.push(fn(this._resolve(this._refs[i]), i)) + } + return result + } + + [Symbol.iterator](): Iterator { + const refs = this._refs + const resolve = (ref: ValueRef) => this._resolve(ref) + let index = 0 + return { + next(): IteratorResult { + if (index < refs.length) { + return { value: resolve(refs[index++]), done: false } + } + return { value: undefined, done: true } + }, + } + } + + has(value: Unit | ValueRef | string): boolean { + const uuid = value instanceof ValueRef ? value.uuid + : typeof value === 'string' ? value + : value?.uuid + if (!uuid) return false + return this._refs.some(r => r.uuid === uuid) + } + + private _createProxy(): any { + const self = this + return new Proxy([] as any[], { + get(_target, prop, receiver) { + if (typeof prop === 'string' && /^\d+$/.test(prop)) { + const ref = self._refs[Number(prop)] + return ref ? self._resolve(ref) : undefined + } + + switch (prop) { + case 'length': + return self._refs.length + case '_refs': + return self._refs + case '_owner': + return self + case Symbol.iterator: + return function* () { + for (let i = 0; i < self._refs.length; i++) { + yield self._resolve(self._refs[i]) + } + } + case 'push': + return (...args: any[]) => self.push(...args) + case 'pop': + return () => { + const ref = self._refs.pop() + return ref ? self._resolve(ref) : undefined + } + case 'shift': + return () => { + const ref = self._refs.shift() + return ref ? self._resolve(ref) : undefined + } + case 'unshift': + return (...args: any[]) => { + const refs = args.map((v: any) => { + if (v instanceof ValueRef) return v + const uuid = typeof v === 'string' ? v : v?.uuid + return uuid ? new ValueRef(uuid) : null + }).filter(Boolean) as ValueRef[] + self._refs.unshift(...refs) + return self._refs.length + } + case 'splice': + return (start: number, deleteCount?: number, ...items: any[]) => { + const newRefs = items.map((v: any) => { + if (v instanceof ValueRef) return v + const uuid = typeof v === 'string' ? v : v?.uuid + return uuid ? new ValueRef(uuid) : null + }).filter(Boolean) as ValueRef[] + const removed = deleteCount !== undefined + ? self._refs.splice(start, deleteCount, ...newRefs) + : self._refs.splice(start) + return removed.map(r => self._resolve(r)) + } + case 'slice': + return (start?: number, end?: number) => { + const sliced = self._refs.slice(start, end) + return sliced.map(r => self._resolve(r)) + } + case 'concat': + return (...args: any[]) => { + const result: any[] = [] + for (const ref of self._refs) { + result.push(self._resolve(ref)) + } + for (const arg of args) { + if (Array.isArray(arg)) { + result.push(...arg) + } else { + result.push(arg) + } + } + return result + } + case 'indexOf': + return (searchVal: any, fromIndex?: number) => { + const start = fromIndex ?? 0 + for (let i = start; i < self._refs.length; i++) { + if (self._resolve(self._refs[i]) === searchVal) return i + } + return -1 + } + case 'includes': + return (searchVal: any, fromIndex?: number) => { + const start = fromIndex ?? 0 + for (let i = start; i < self._refs.length; i++) { + if (self._resolve(self._refs[i]) === searchVal) return true + } + return false + } + case 'forEach': + return (fn: any) => { + for (let i = 0; i < self._refs.length; i++) { + fn(self._resolve(self._refs[i]), i, receiver) + } + } + case 'map': + return (fn: any) => { + const result: any[] = [] + for (let i = 0; i < self._refs.length; i++) { + result.push(fn(self._resolve(self._refs[i]), i, receiver)) + } + return result + } + case 'filter': + return (fn: any) => { + const result: any[] = [] + for (let i = 0; i < self._refs.length; i++) { + const v = self._resolve(self._refs[i]) + if (fn(v, i, receiver)) result.push(v) + } + return result + } + case 'some': + return (fn: any) => { + for (let i = 0; i < self._refs.length; i++) { + if (fn(self._resolve(self._refs[i]), i, receiver)) return true + } + return false + } + case 'every': + return (fn: any) => { + for (let i = 0; i < self._refs.length; i++) { + if (!fn(self._resolve(self._refs[i]), i, receiver)) return false + } + return true + } + case 'find': + return (fn: any) => { + for (let i = 0; i < self._refs.length; i++) { + const v = self._resolve(self._refs[i]) + if (fn(v, i, receiver)) return v + } + return undefined + } + case 'findIndex': + return (fn: any) => { + for (let i = 0; i < self._refs.length; i++) { + if (fn(self._resolve(self._refs[i]), i, receiver)) return i + } + return -1 + } + case 'reduce': + return (fn: any, initial?: any) => { + let acc = initial + let startIdx = 0 + if (acc === undefined) { + acc = self._refs.length > 0 ? self._resolve(self._refs[0]) : undefined + startIdx = 1 + } + for (let i = startIdx; i < self._refs.length; i++) { + acc = fn(acc, self._resolve(self._refs[i]), i, receiver) + } + return acc + } + case 'join': + return (sep?: string) => { + const arr: any[] = [] + for (const ref of self._refs) arr.push(self._resolve(ref)) + return arr.join(sep) + } + case 'sort': + return (fn?: any) => { + const resolved = self._refs.map((r, i) => ({ ref: r, val: self._resolve(r), i })) + if (fn) { + resolved.sort((a, b) => fn(a.val, b.val)) + } else { + resolved.sort((a, b) => String(a.val) < String(b.val) ? -1 : 1) + } + self._refs = resolved.map(x => x.ref) + self._onMutate?.() + return receiver + } + case 'reverse': + return () => { + self._refs.reverse() + self._onMutate?.() + return receiver + } + case 'flat': + case 'flatMap': + case 'keys': + case 'values': + case 'entries': + case 'at': + case 'toString': + case 'toLocaleString': + case 'constructor': + return (Array.prototype as any)[prop]?.bind( + self._refs.map(r => self._resolve(r)) + ) + default: + if (prop === IS_UNION_ARRAY) return true + if (prop === RAW_TARGET) return self._refs.map(r => r.uuid) + return undefined + } + }, + + set(_target, prop, value) { + if (typeof prop === 'string' && /^\d+$/.test(prop)) { + self.set(Number(prop), value) + self._onMutate?.() + return true + } + if (prop === 'length') { + self._refs.length = value + self._onMutate?.() + return true + } + return true + }, + + has(_target, prop) { + if (typeof prop === 'string' && /^\d+$/.test(prop)) { + return Number(prop) < self._refs.length + } + if (prop === 'length') return true + if (prop === Symbol.iterator) return true + return prop in Array.prototype + }, + + ownKeys() { + const keys: string[] = [] + for (let i = 0; i < self._refs.length; i++) { + keys.push(String(i)) + } + keys.push('length') + return keys + }, + + getOwnPropertyDescriptor(_target, prop) { + if (typeof prop === 'string' && /^\d+$/.test(prop)) { + const idx = Number(prop) + if (idx < self._refs.length) { + return { + value: self._refs[idx].uuid, + writable: true, + enumerable: true, + configurable: true, + } + } + } + if (prop === 'length') { + return { + value: self._refs.length, + writable: true, + enumerable: false, + configurable: false, + } + } + return undefined + }, + }) + } + + static from( + data: (string | ValueRef | Unit)[], + getSymbolTable: () => ValueRegistry | null, + ): ValueRefList { + const list = new ValueRefList(getSymbolTable) + for (const item of data) { + if (item instanceof ValueRef) { + list._refs.push(item) + } else if (typeof item === 'string') { + list._refs.push(new ValueRef(item)) + } else { + const uuid = item?.uuid + if (uuid) { + list._refs.push(new ValueRef(uuid)) + } + } + } + return list + } + + _clone(getSymbolTable: () => ValueRegistry | null, onMutate?: () => void): ValueRefList { + const copy = new ValueRefList(getSymbolTable, onMutate || this._onMutate || undefined) + copy._refs = this._refs.slice() + return copy + } +} diff --git a/src/engine/analyzer/common/value/value-ref-map.ts b/src/engine/analyzer/common/value/value-ref-map.ts new file mode 100644 index 00000000..eb364df5 --- /dev/null +++ b/src/engine/analyzer/common/value/value-ref-map.ts @@ -0,0 +1,238 @@ +import { ValueRef } from './value-ref' +import type Unit from './unit' +import { RAW_TARGET } from './symbols' + +/** + * ValueStore — 符号表只读接口 + */ +export interface ValueStore { + get(uuid: string): Unit | null | undefined +} + +/** + * ValueRegistry — 符号表读写接口 + */ +export interface ValueRegistry extends ValueStore { + register(value: Unit): string | null +} + +/** + * ValueRefMap — 内部存 Map,通过 Proxy 对外模拟 Record + * + * 设计原则:_members 是数据所有者,ValueRef 同时持有 uuid + _direct。 + * 有 UUID → 优先从符号表 resolve(匹配旧 createFieldProxy 行为),_direct 做 fallback。 + * 无 UUID → 直返 _direct(非 Unit 值或注册失败时)。 + * + * proxy[key] → resolve ValueRef → 返回 Value + * proxy[key] = val → 转 ValueRef 存储(uuid + direct) + * delete proxy[key] → 删除 + * Object.keys(proxy) → _map.keys() + * for...in → 遍历 keys + */ +export class ValueRefMap { + _map: Map = new Map() + private _getSymbolTable: () => ValueRegistry | null + private _proxy: any + private _proxyTarget: Record = {} + + constructor(getSymbolTable: () => ValueRegistry | null) { + this._getSymbolTable = getSymbolTable + this._proxy = this._createProxy() + Object.defineProperty(this._proxy, RAW_TARGET, { + value: this._proxyTarget, + writable: false, + enumerable: false, + configurable: false, + }) + } + + get size(): number { + return this._map.size + } + + getProxy(): any { + return this._proxy + } + + get(key: string): any { + const ref = this._map.get(key) + if (!ref) return null + const st = this._getSymbolTable() + const resolved = ref.resolve(st) + if (resolved) return resolved + if (ref.uuid) return ref.uuid + return null + } + + has(key: string): boolean { + return this._map.has(key) + } + + set(key: string, value: Unit | ValueRef | null | undefined): void { + if (value == null) { + this._map.delete(key) + delete this._proxyTarget[key] + return + } + if (value instanceof ValueRef) { + this._map.set(key, value) + this._proxyTarget[key] = value.uuid || value._direct + return + } + // UUID string → pure reference (no direct object available) + if (typeof value === 'string' && (value as any).startsWith('symuuid')) { + this._map.set(key, new ValueRef(value as any)) + this._proxyTarget[key] = value + return + } + // Register Unit values in ST, store UUID-only ref (no _direct). + // Matches old createFieldProxy: SET stores UUID string, GET resolves via ST. + if (value && typeof value === 'object' && (value as any).vtype && (value as any).qid) { + const st = this._getSymbolTable() + if (st) { + const uuid = st.register(value as Unit) + if (uuid) { + this._map.set(key, new ValueRef(uuid)) + this._proxyTarget[key] = uuid + return + } + } + } + // Non-Unit values or ST unavailable: store with whatever UUID is available + const uuid = value?.uuid || '' + if (uuid) { + this._map.set(key, new ValueRef(uuid)) + this._proxyTarget[key] = uuid + } else { + this._map.set(key, new ValueRef('', value)) + this._proxyTarget[key] = value + } + } + + delete(key: string): boolean { + delete this._proxyTarget[key] + return this._map.delete(key) + } + + clear(): void { + this._map.clear() + for (const k of Object.keys(this._proxyTarget)) { + delete this._proxyTarget[k] + } + } + + keys(): IterableIterator { + return this._map.keys() + } + + forEach(fn: (value: any, key: string) => void): void { + const st = this._getSymbolTable() + for (const [key, ref] of this._map) { + const value = ref.resolve(st) + if (value) fn(value, key) + } + } + + entries(): [string, any][] { + const st = this._getSymbolTable() + const result: [string, any][] = [] + for (const [key, ref] of this._map) { + const value = ref.resolve(st) + if (value) result.push([key, value]) + } + return result + } + + private _createProxy(): any { + const self = this + return new Proxy(this._proxyTarget, { + get(_target, prop) { + if (typeof prop === 'symbol') return (_target as any)[prop] + if (typeof prop === 'string') { + if (prop === '_map') return self._map + if (prop === '_owner') return self + if (prop === 'hasOwnProperty') return (key: string) => self._map.has(key) + const ref = self._map.get(prop) + if (!ref) return _target[prop] + const st = self._getSymbolTable() + const resolved = ref.resolve(st) + if (resolved) return resolved + if (ref.uuid) return ref.uuid + return undefined + } + return undefined + }, + + set(_target, prop, value) { + if (typeof prop === 'string') { + self.set(prop, value) + return true + } + return true + }, + + deleteProperty(_target, prop) { + if (typeof prop === 'string') { + self._map.delete(prop) + delete _target[prop] + return true + } + return false + }, + + has(_target, prop) { + if (typeof prop === 'string') { + return self._map.has(prop) + } + return false + }, + + ownKeys(_target) { + const keys: (string | symbol)[] = Array.from(self._map.keys()) + if (Object.prototype.hasOwnProperty.call(_target, RAW_TARGET)) { + keys.push(RAW_TARGET) + } + return keys + }, + + getOwnPropertyDescriptor(_target, prop) { + if (typeof prop === 'string' && self._map.has(prop)) { + return { + value: _target[prop], + writable: true, + enumerable: true, + configurable: true, + } + } + return Object.getOwnPropertyDescriptor(_target, prop) + }, + }) + } + + static from( + data: Record | Map, + getSymbolTable: () => ValueRegistry | null, + ): ValueRefMap { + const map = new ValueRefMap(getSymbolTable) + const entries = data instanceof Map ? data.entries() : Object.entries(data) + for (const [key, value] of entries) { + if (value instanceof ValueRef) { + map._map.set(key, value) + map._proxyTarget[key] = value.uuid || value._direct + } else if (typeof value === 'string') { + map._map.set(key, new ValueRef(value)) + map._proxyTarget[key] = value + } + } + return map + } + + _clone(getSymbolTable: () => ValueRegistry | null): ValueRefMap { + const copy = new ValueRefMap(getSymbolTable) + copy._map = new Map(this._map) + for (const [key, ref] of copy._map) { + copy._proxyTarget[key] = ref.uuid || ref._direct + } + return copy + } +} diff --git a/src/engine/analyzer/common/value/value-ref.ts b/src/engine/analyzer/common/value/value-ref.ts new file mode 100644 index 00000000..41069902 --- /dev/null +++ b/src/engine/analyzer/common/value/value-ref.ts @@ -0,0 +1,83 @@ +/** + * ValueRef - Value 间接引用 + * + * 封装 UUID 字符串,提供类型安全的 Value 引用。 + * resolve() 首次从符号表获取后缓存,后续直接返回缓存引用。 + * UUID readonly + 缓存同一 JS 对象引用 → 属性修改自动可见,缓存永不失效。 + */ + +export class ValueRef { + readonly uuid: string + private _cached: any = null + private _directWeak: WeakRef | null = null + private _directStrong: any = null + + constructor(uuid: string, direct?: any) { + if (!direct && (typeof uuid !== 'string' || uuid.length === 0)) { + throw new Error(`[ValueRef] Invalid uuid: ${uuid}`) + } + this.uuid = uuid || '' + if (direct != null) { + if (typeof direct === 'object') { + this._directWeak = new WeakRef(direct) + } else { + this._directStrong = direct + } + } + } + + get _direct(): any { + if (this._directStrong != null) return this._directStrong + return this._directWeak?.deref() ?? null + } + + set _direct(val: any) { + if (val == null) { + this._directWeak = null + this._directStrong = null + } else if (typeof val === 'object') { + this._directWeak = new WeakRef(val) + this._directStrong = null + } else { + this._directStrong = val + this._directWeak = null + } + } + + resolve(symbolTable: any): any | null { + const direct = this._direct + if (direct) return direct + + if (!this.uuid) return null + if (!symbolTable || typeof symbolTable.get !== 'function') { + return null + } + return symbolTable.get(this.uuid) ?? null + } + + /** + * UUID 注册成功后调用:清除 _direct 强引用。 + * 有 uuid → 后续 resolve() 仍优先走 WeakRef(保持 identity),GC 回收后走 ST。 + * 无 uuid → 保留 _direct(非 Unit 值场景)。 + */ + markRegistered(): void { + if (this.uuid) { + this._directStrong = null + } + } + + static isValueRef(obj: any): obj is ValueRef { + return obj instanceof ValueRef + } + + static from(uuidOrRef: string | ValueRef): ValueRef { + if (uuidOrRef instanceof ValueRef) { + return uuidOrRef + } + return new ValueRef(uuidOrRef) + } + + toString(): string { + return `ValueRef(${this.uuid.substring(0, 12)}...)` + } +} diff --git a/src/engine/analyzer/common/value/valueUtil.ts b/src/engine/analyzer/common/value/valueUtil.ts deleted file mode 100644 index 88c1554b..00000000 --- a/src/engine/analyzer/common/value/valueUtil.ts +++ /dev/null @@ -1,75 +0,0 @@ -const Unknown = require('./unkown') -const ObjectClass = require('./object') -const Scoped = require('./scoped') -const FunctionClass = require('./function') -const Undefined = require('./undefine') -const Uninitialized = require('./uninit') -const Union = require('./union') -const SymbolClass = require('./symbolic') -const Primitive = require('./primitive') -const BVT = require('./bvt') -const Package = require('./package') - -const ValueUtil = { - UnknownValue(opts: any) { - opts = prepareOpts(opts) - return new Unknown(opts) - }, - - ObjectValue(opts: any) { - opts = prepareOpts(opts) - return new ObjectClass(opts) - }, - - Scoped(opts: any) { - opts = prepareOpts(opts) - return new Scoped(opts) - }, - - FunctionValue(opts: any) { - opts = prepareOpts(opts) - return new FunctionClass(opts) - }, - PackageValue(opts: any) { - opts = prepareOpts(opts) - return new Package(opts) - }, - UndefinedValue(opts: any) { - opts = prepareOpts(opts) - return new Undefined(opts) - }, - UninitializedValue(opts: any) { - opts = prepareOpts(opts) - return new Uninitialized(opts) - }, - UnionValue(opts: any) { - opts = prepareOpts(opts) - return new Union(opts) - }, - - SymbolValue(opts: any) { - opts = prepareOpts(opts) - opts.parent = opts.parent || null - return new SymbolClass(opts) - }, - - PrimitiveValue(opts: any) { - opts = prepareOpts(opts) - return new Primitive(opts) - }, - - BVT(opts: any) { - opts = prepareOpts(opts) - return new BVT(opts) - }, -} - -/** - * - * @param opts - */ -function prepareOpts(opts: any): any { - return opts || {} -} - -module.exports = ValueUtil diff --git a/src/engine/analyzer/common/value/void.ts b/src/engine/analyzer/common/value/void.ts new file mode 100644 index 00000000..95ffc83c --- /dev/null +++ b/src/engine/analyzer/common/value/void.ts @@ -0,0 +1,24 @@ +import { SentinelValue } from './sentinel-value' + +/** + * VoidValue - 无返回值 + * + * 用于:Statement 的预期无返回值(区别于 UndefinedValue) + * 语义:表示操作成功完成但无返回值 + * + * 固定属性: + * - vtype: 'void' + * - sid/qid: 标识符(默认 '') + */ +export class VoidValue extends SentinelValue { + /** + * Constructor for VoidValue + * 无参数,sid/qid 固定为 '' + */ + constructor() { + super('void', { + sid: '', + qid: '', + }) + } +} diff --git a/src/engine/analyzer/golang/common/entrypoint-collector/go-default-entrypoint.ts b/src/engine/analyzer/golang/common/entrypoint-collector/go-default-entrypoint.ts index 8322456a..d0c00e33 100644 --- a/src/engine/analyzer/golang/common/entrypoint-collector/go-default-entrypoint.ts +++ b/src/engine/analyzer/golang/common/entrypoint-collector/go-default-entrypoint.ts @@ -11,8 +11,8 @@ function getMainEntryPoints(packageManager: any) { const entryPoints: any[] = [] const mainEntryPoints = AstUtil.satisfy( packageManager, - (n: any) => n.ast?.id?.name === 'main' && n.vtype === 'fclos', - (node: any, prop: any) => prop === 'field', + (n: any) => n.ast?.node?.id?.name === 'main' && n.vtype === 'fclos', + (node: any, prop: any) => prop === '_field', null, true ) diff --git a/src/engine/analyzer/golang/common/go-analyzer.ts b/src/engine/analyzer/golang/common/go-analyzer.ts index e6a72039..67cf49bf 100644 --- a/src/engine/analyzer/golang/common/go-analyzer.ts +++ b/src/engine/analyzer/golang/common/go-analyzer.ts @@ -1,32 +1,39 @@ import GoTypeRelatedInfoResolver from '../../../../resolver/go/go-type-related-info-resolver' +import { buildNewCopiedWithTag } from '../../../../util/clone-util' +import { BinaryExprValue } from '../../common/value/binary-expr' +import type { Scope, State, Value, SymbolValue as SymbolValueType } from '../../../../types/analyzer' +import type { CallExpression, VariableDeclaration, NewExpression, ThisExpression, CompileUnit, BinaryExpression, MemberAccess, Identifier, TupleExpression } from '../../../../types/uast' + +const path = require('path') +const _ = require('lodash') +const QidUnifyUtil = require('../../../../util/qid-unify-util') const logger = require('../../../../util/logger')(__filename) -const Scope = require('../../common/scope') -const { Analyzer } = require('../../common') +const ScopeClass = require('../../common/scope') +const Analyzer: typeof import('../../common/analyzer').Analyzer = require('../../common/analyzer') const BasicRuleHandler = require('../../../../checker/common/rules-basic-handler') -const _ = require('lodash') -const GoParser = require('../../../parser/golang/go-ast-builder') -const { cloneWithDepth } = require('../../../../util/clone-util') +const Parser = require('../../../parser/parser') const { ValueUtil: { FunctionValue }, } = require('../../../util/value-util') +const { shallowCopyValue, buildNewValueInstance, lodashCloneWithTag } = require('../../../../util/clone-util') const { valueUtil: { ValueUtil: { Scoped, PackageValue, PrimitiveValue, UndefinedValue, SymbolValue, UnionValue }, }, } = require('../../common') +import type { CallInfo } from '../../common/call-args' +import { INTERNAL_CALL } from '../../common/call-args' +const { getLegacyArgValues } = require('../../common/call-args') const Config = require('../../../../config') const SourceLine = require('../../common/source-line') const FileUtil = require('../../../../util/file-util') -const { Errors } = require('../../../../util/error-code') const AstUtil = require('../../../../util/ast-util') const MemState = require('../../common/memState') const CheckerManager = require('../../common/checker-manager') const entryPointConfig = require('../../common/current-entrypoint') const { unionAllValues } = require('../../common/memStateBVT') -const path = require('path') -const { floor } = require('lodash') const constValue = require('../../../../util/constant') const { handleException } = require('../../common/exception-handler') @@ -34,28 +41,6 @@ const { handleException } = require('../../common/exception-handler') * */ class GoAnalyzer extends Analyzer { - options: any - - mainEntryPoints: any[] - - ruleEntrypoints: any[] - - moduleManager: any - - fileManager: Record = {} - - entry_fclos: any - - thisFClos: any - - entryPoints!: any[] - - topScope: any - - packageManager: any - - ainfo: any - /** * * @param options @@ -90,9 +75,6 @@ class GoAnalyzer extends Analyzer { ) process.exit(1) } - for (const mod of modules) { - SourceLine.storeCode(mod.file, mod.content) - } } /** @@ -108,21 +90,31 @@ class GoAnalyzer extends Analyzer { let parseCodeEnded = false try { this.scanModules(dir) - this.moduleManager = await GoParser.parsePackage(dir, this.options) - const { numOfGoMod } = this.moduleManager + this.topScope.context.modules = await Parser.parseProject(dir, this.options, this.sourceCodeCache) + + // 防御性检查:确保 moduleManager 不为 null + if (!this.topScope.context.modules) { + handleException( + null, + '[go-analyzer] parseProject returned null, Go AST parsing failed', + '[go-analyzer] parseProject returned null, Go AST parsing failed' + ) + return + } + const { numOfGoMod } = this.topScope.context.modules if (numOfGoMod > 1) { logger.info(`[go-analyzer] found more than one go.mod files. The num of go.mod files is ${numOfGoMod}`) } - this.makeGoFileManager(this.moduleManager) - const { packageInfo, moduleName } = this.moduleManager + this.makeGoFileManager(this.topScope.context.modules) + const { packageInfo, moduleName } = this.topScope.context.modules if (Object.entries(packageInfo.files).length === 0 && Object.entries(packageInfo.subs).length === 0) { // 提前返回:没有文件需要处理,在 finally 中结束 parseCode return } - let { goModPath } = this.moduleManager + let { goModPath } = this.topScope.context.modules if (!goModPath) goModPath = '' // TODO 如果模块名叫code.alipay.com/antjail/antdpa,进去会截断 - const modulePackageManager = defaultScope || this.packageManager.getSubPackage(moduleName, true) + const modulePackageManager = defaultScope || this.topScope.context.packages.getSubPackage(moduleName, true) // 计算项目模块根路径(go.mod所在目录) const moduleRootPath = this.getModuleRootPath(goModPath, Config.maindir) @@ -134,8 +126,8 @@ class GoAnalyzer extends Analyzer { rootDir = rootDir.subs[dirName] } } - this.moduleManager.rootDir = rootDir - this.moduleManager.rootDirName = dirName + this.topScope.context.modules.rootDir = rootDir + this.topScope.context.modules.rootDirName = dirName // 正常流程:结束 parseCode 阶段 this.performanceTracker.end('preProcess.parseCode') @@ -305,12 +297,12 @@ class GoAnalyzer extends Analyzer { * @param node * @param state */ - processCallExpression(scope: any, node: any, state: any) { + override processCallExpression(scope: Scope, node: CallExpression, state: State): SymbolValueType { if (node._meta.defer) { const encloseFclos = this.getEncloseFclos(scope) if (encloseFclos) { encloseFclos._defers = encloseFclos._defers || [] - const deferNode = _.clone(node) // 浅拷贝即可 + const deferNode = _.clone(node) delete deferNode._meta.defer encloseFclos._defers.push(deferNode) } @@ -319,11 +311,7 @@ class GoAnalyzer extends Analyzer { const fclos = this.processInstruction(scope, node.callee, state) let ret if (fclos?.vtype === 'class' && node.arguments.length === 1) { - const val = this.processInstruction(scope, node.arguments[0], state) - if (val) { - val.sort = fclos.id - } - ret = val + ret = this.processInstruction(scope, node.arguments[0], state) } else { const argvalues = [] for (const arg of node.arguments) { @@ -348,7 +336,7 @@ class GoAnalyzer extends Analyzer { ainfo: this.ainfo, }) } - ret = super.processCallExpression(scope, node, state, fclos) + ret = super.processCallExpression(scope, node, state) if (ret && this.checkerManager) { this.checkerManager.checkAtFunctionCallAfter(this, scope, node, state, { fclos, @@ -387,8 +375,8 @@ class GoAnalyzer extends Analyzer { if (globalScope.sid === '') break globalScope = globalScope.parent } - if (Object.prototype.hasOwnProperty.call(globalScope.funcSymbolTable, targetQid)) { - return globalScope.funcSymbolTable[targetQid] + if (Object.prototype.hasOwnProperty.call(globalScope.context.funcs, targetQid)) { + return globalScope.context.funcs[QidUnifyUtil.qidUnifyByRemoveAngleAndPrefix(targetQid)] } let initFunctionValue = Object.prototype.hasOwnProperty.call(scope.value, 'init') ? scope.value.init : undefined @@ -397,15 +385,15 @@ class GoAnalyzer extends Analyzer { scope.value.init = initFunctionValue } - const fclos = FunctionValue({ - fdef: node, // record the function definition including its type and prototype information + const fclos = new FunctionValue('', { sid: 'init', qid: targetQid, decls: {}, parent: scope, ast: node, }) - globalScope.funcSymbolTable[targetQid] = fclos + fclos.ast.fdef = node + globalScope.context.funcs[QidUnifyUtil.qidUnifyByRemoveAngleAndPrefix(targetQid)] = fclos if (Array.isArray(initFunctionValue)) { initFunctionValue.push(fclos) @@ -423,37 +411,40 @@ class GoAnalyzer extends Analyzer { * @param state */ processImportDirect(scope: any, node: any, state: any) { - const { moduleName } = this.moduleManager - const { rootDirName } = this.moduleManager + const { moduleName } = this.topScope.context.modules + const { rootDirName } = this.topScope.context.modules const fromPath = node?.from?.value?.replace(/"/g, '') // 外部包返回空packageValue if (!fromPath.startsWith(`${moduleName}/`)) { - return PackageValue({ + const packageVal = new PackageValue(this.topScope.context.packages.qid, { vtype: 'package', sid: fromPath, - qid: fromPath, - exports: Scoped({ - sid: 'exports', - id: 'exports', - parent: null, - }), - parent: this.packageManager, + parent: this.topScope.context.packages, + }) + const exports = new Scoped(`${this.topScope.context.packages.qid}.${fromPath}`, { + sid: 'exports', + parent: packageVal, }) + packageVal.scope.exports = exports + return packageVal } const relativeFromPath = fromPath.slice(`${moduleName}/`.length) const dirs = relativeFromPath.split('/') - // 取该项目根目录的PackageValue:rootPackageValue(顶层Scope,即go.mod所在目录的packageValue) - const modulePackageValue = this.packageManager.getSubPackage(moduleName, false) + // 取该项目根目录的PackageValue:rootnew PackageValue(顶层Scope,即go.mod所在目录的packageValue) + const modulePackageValue = this.topScope.context.packages.getSubPackage(moduleName, false) const rootPackageValue = modulePackageValue.getSubPackage(`%dir_${rootDirName}`, false) let parentScope = modulePackageValue // packageManager按照import路径(即目录结构)存储。每个目录(不管是否是包)都视作一个PackageValue,其下可能有PackageValue、ClassScope、FuncScope等。 for (const dir of dirs) { + const targetQid = ScopeClass.joinQualifiedName(parentScope.qid, dir) const currentScope = parentScope.getSubPackage(`%dir_${dir}`, true) - parentScope.exports.value[dir] = currentScope - currentScope.sort = currentScope.qid = Scope.joinQualifiedName(parentScope.qid, dir) + parentScope.scope.exports.value[dir] = currentScope + currentScope._qid = targetQid + currentScope.uuid = null + currentScope.calculateAndRegisterUUID() parentScope = currentScope } const targetScope = parentScope @@ -472,7 +463,7 @@ class GoAnalyzer extends Analyzer { * @param state */ addFdef(targetScope: any, dirs: any, state: any) { - const { rootDir } = this.moduleManager + const { rootDir } = this.topScope.context.modules if (!rootDir) { return } @@ -507,36 +498,26 @@ class GoAnalyzer extends Analyzer { const initFCloses = AstUtil.satisfy( ImportedScope, - (n: any) => n.ast?.id?.name === 'init' && n.vtype === 'fclos', + (n: any) => n.ast?.node?.id?.name === 'init' && n.vtype === 'fclos', (node: any, prop: any, from: any) => node === from, // 只找当前包下的field null, true ) || [] for (const initFClos of initFCloses) { - this.executeCall(initFClos.ast, initFClos, [], state, ImportedScope) + this.executeCall(initFClos.ast?.node, initFClos, state, ImportedScope, INTERNAL_CALL) } } - private static knownPackageName: Record = {} - - /** - * Register known module name to package name mapping for default import variable name fix - * @param knownPackageName A map from module name to known package name - */ - static registerKnownPackageNames(knownPackageName: Record) { - GoAnalyzer.knownPackageName = { ...GoAnalyzer.knownPackageName, ...knownPackageName } - } - /** * * @param scope * @param node * @param state */ - processVariableDeclaration(scope: any, node: any, state: any) { + override processVariableDeclaration(scope: Scope, node: VariableDeclaration, state: State): SymbolValueType { const initialNode = node.init - const { id } = node - if (!id || id?.name === '_') return UndefinedValue() // e.g. in Go + const id = node.id // LVal: Identifier | MemberAccess | TupleExpression + if (!id || (id.type === 'Identifier' && id.name === '_')) return new UndefinedValue() // e.g. in Go let initVal if (!initialNode) { @@ -545,18 +526,24 @@ class GoAnalyzer extends Analyzer { cscope = this.processInstruction(scope, node.varType, state) // if (cscope && cscope.vtype !== 'undefine') if (cscope) { - initVal = this.buildNewObject(cscope?.fdef, undefined, cscope, state, node, scope) + initVal = this.buildNewObject(cscope?.ast.fdef, cscope, state, node, scope, INTERNAL_CALL) } else { initVal = this.createVarDeclarationScope(id, scope) } } initVal.uninit = !initialNode - initVal = SourceLine.addSrcLineInfo(initVal, id, id.loc && id.loc.sourcefile, 'Var Pass: ', id.name) + initVal = SourceLine.addSrcLineInfo( + initVal, + id, + id.loc && id.loc.sourcefile, + 'Var Pass: ', + id.type === 'Identifier' ? id.name : undefined + ) } else { initVal = this.processInstruction(scope, initialNode, state) - if (node.cloned && !initVal?.refCount) { - initVal = cloneWithDepth(initVal) - initVal.value = cloneWithDepth(initVal.value) + if (node.cloned && !initVal?.runtime?.refCount) { + initVal = shallowCopyValue(initVal) + initVal.value = shallowCopyValue(initVal.value) } if (initVal?.rtype && initVal.rtype !== 'DynamicType') { const cscope = this.processInstruction(scope, initVal.rtype, state) @@ -564,7 +551,13 @@ class GoAnalyzer extends Analyzer { initVal = this.buildTypeObject(initVal, cscope) } } - initVal = SourceLine.addSrcLineInfo(initVal, node, node.loc && node.loc.sourcefile, 'Var Pass: ', id.name) + initVal = SourceLine.addSrcLineInfo( + initVal, + node, + node.loc && node.loc.sourcefile, + 'Var Pass: ', + id.type === 'Identifier' ? id.name : undefined + ) } if (this.checkerManager && this.checkerManager.checkAtPreDeclaration) @@ -577,64 +570,54 @@ class GoAnalyzer extends Analyzer { }) if (id.type === 'TupleExpression') { // 解构Tuple赋值,分别分发到Tuple里的每个元素 + const tupleId = id as TupleExpression if (initVal.vtype === 'union') { const substates = MemState.forkStates(state, 1) - const pairs = floor(initVal.field.length / id.elements.length) - const scopes = new Array(id.elements.length) - for (let i = 0; i < id.elements.length; i++) { + const pairs = _.floor(initVal.value.length / tupleId.elements.length) + const scopes = new Array(tupleId.elements.length) + for (let i = 0; i < tupleId.elements.length; i++) { scopes[i] = new Array(pairs) } for (let i = 0; i < pairs; i++) { - for (let j = 0; j < id.elements.length; j++) { - scopes[j][i] = initVal.field[i * id.elements.length + j] + for (let j = 0; j < tupleId.elements.length; j++) { + scopes[j][i] = initVal.getFieldValue(String(i * tupleId.elements.length + j)) } } - for (let i = 0; i < id.elements.length; i++) { + for (let i = 0; i < tupleId.elements.length; i++) { const union = unionAllValues(scopes[i], state) - this.saveVarInCurrentScope(scope, id.elements[i], union, state) + this.saveVarInCurrentScope(scope, tupleId.elements[i], union, state) } - } else if (Array.isArray(initVal.field) && initVal.field.length >= 1) { - const minLen = Math.min(id.elements.length, initVal.field.length) + } else if (Array.isArray(initVal.value) && initVal.value.length >= 1) { + const minLen = Math.min(tupleId.elements.length, initVal.value.length) for (let i = 0; i < minLen; i++) { - this.saveVarInCurrentScope(scope, id.elements[i], initVal.field[i], state) + this.saveVarInCurrentScope(scope, tupleId.elements[i], initVal.getFieldValue(String(i)), state) } } else { - for (const i in id.elements) { - this.saveVarInCurrentScope(scope, id.elements[i], initVal, state) + for (const i in tupleId.elements) { + this.saveVarInCurrentScope(scope, tupleId.elements[i], initVal, state) } } } else { - if (initialNode?.type === 'ImportExpression') { - // 处理 default import 情况 - if (node._meta?.isDefaultImport === true && GoAnalyzer.knownPackageName[initialNode.from?.value]) { - id.name = GoAnalyzer.knownPackageName[initialNode.from?.value] - } - // 如果是import,则定义真正的包名而非目录名 - if (initVal?.vtype === 'package' && initVal.name && id.name === initialNode.from?.value?.split('/').at(-1)) { - id.name = initVal.name - } + // 如果是import,则定义真正的包名而非目录名 + if ( + initialNode?.type === 'ImportExpression' && + initVal?.vtype === 'package' && + initVal.name && + id.type === 'Identifier' && + id.name === (initialNode as any).from?.value?.split('/').at(-1) + ) { + id.name = initVal.name } this.saveVarInCurrentScope(scope, id, initVal, state) } // set alias name if val itself has no identifier - if (initVal && !(initVal.name || (initVal.id && initVal.id !== '') || initVal.sid)) { - initVal.sid = id.name - delete initVal.id + if (initVal && !(initVal.name || initVal.sid)) { + initVal.sid = id.type === 'Identifier' ? id.name : '' } - scope.decls[id.name] = id - - const typeQualifiedName = AstUtil.typeToQualifiedName(node.varType) - let declTypeVal - if (typeQualifiedName) { - declTypeVal = this.getMemberValue(scope, typeQualifiedName, state) - } - - if (initVal && declTypeVal) { - // initVal.sort = (!id.typeName || id.typeName.name === 'var') ? - // TypeUtil.inferType(initVal) : id.typeName; - initVal.sort = declTypeVal.sort + if (id.type === 'Identifier') { + scope.ast.setDecl(id.name, id) } if (this.checkerManager && this.checkerManager.checkAtVariableDeclaration) { @@ -650,7 +633,7 @@ class GoAnalyzer extends Analyzer { * @param node * @param state */ - processNewExpression(scope: any, node: any, state: any) { + override processNewExpression(scope: Scope, node: NewExpression, state: State): SymbolValueType { return this.processNewObject(scope, node, state) } @@ -661,7 +644,7 @@ class GoAnalyzer extends Analyzer { * @param state * @returns {*} */ - processNewObject(scope: any, node: any, state: any) { + override processNewObject(scope: any, node: any, state: any) { // if (DEBUG) logger.info("processInstruction: NewExpression " + formatNode(node)); const call = node @@ -690,7 +673,7 @@ class GoAnalyzer extends Analyzer { const { fdef } = fclos // if (analysisutil.isInCallStack(fdef, state.callstack)) return; - const obj = this.buildNewObject(fdef, argvalues, fclos, state, node, scope) + const obj = this.buildNewObject(fdef, fclos, state, node, scope, { callArgs: this.buildCallArgs(node, argvalues, fclos) }) if (logger.isTraceEnabled()) logger.trace(`new expression: ${this.formatScope(obj)}`) if (obj && this.checkerManager?.checkAtNewExprAfter) { @@ -713,16 +696,15 @@ class GoAnalyzer extends Analyzer { * @param cdef * @param state */ - preProcessClassDefinition(scope: any, cdef: any, state: any) { - if (!(cdef && cdef.body)) return UndefinedValue() // Should not happen + override preProcessClassDefinition(scope: any, cdef: any, state: any) { + if (!(cdef && cdef.body)) return new UndefinedValue() // Should not happen // pre-processing const fname = cdef.id?.name - const cscope = Scope.createSubScope(fname, scope, 'class') // class scope - cscope.cdef = cdef - // cscope.fdef = cdef + const cscope = ScopeClass.createSubScope(fname, scope, 'class') // class scope cscope.ast = cdef + cscope.ast.cdef = cdef cscope.__preprocess = true return cscope } @@ -733,15 +715,16 @@ class GoAnalyzer extends Analyzer { * @param cdef * @param state */ - processClassDefinition(scope: any, cdef: any, state: any) { - if (!(cdef && cdef.body)) return UndefinedValue() // Should not happen + override processClassDefinition(scope: any, cdef: any, state: any) { + if (!(cdef && cdef.body)) return new UndefinedValue() // Should not happen // pre-processing const fname = cdef.id?.name - const cscope = Scope.createSubScope(fname, scope, 'class') // class scope - cscope.cdef = cdef - if (cdef._meta?.isInterface) cscope.misc_.isInterface = true + const cscope = ScopeClass.createSubScope(fname, scope, 'class') // class scope + cscope.ast = cdef + cscope.ast.cdef = cdef + if (cdef._meta?.isInterface) cscope.isInterface = true cscope.modifier = {} cscope.inits = new Set() // for storing the variables initialized in the constructor this.resolveClassInheritance(cscope, state) // inherit base classes @@ -769,8 +752,8 @@ class GoAnalyzer extends Analyzer { * @param fclos * @param state */ - resolveClassInheritance(fclos: any, state: any) { - const fdef = fclos.cdef + override resolveClassInheritance(fclos: any, state: any) { + const fdef = fclos.ast.cdef const { supers } = fdef if (!supers || supers.length === 0) return @@ -788,26 +771,27 @@ class GoAnalyzer extends Analyzer { * @param superId */ function _resolveClassInheritance(this: any, fclos: any, superId: any) { - if (fclos?.id === superId?.name) { + if (fclos?.sid === superId?.name) { // to avoid self-referencing return } const superClos = this.processInstruction(scope, superId, state) // const superClos = this.getMemberValue(scope, superId, state); - if (!superClos) return UndefinedValue() + if (!superClos) return new UndefinedValue() fclos.super = superClos // inherit definitions // superValue is used to record values of super class, so that we can handle cases like super.xxx() or super() - const superValue = fclos.value.super || Scope.createSubScope('super', fclos, 'fclos') + const superValue = fclos.value.super || ScopeClass.createSubScope('super', fclos, 'fclos') // super's parent should be assigned to base, _this will track on fclos superValue.parent = superClos for (const fieldName in superClos.value) { if (fieldName === 'super') continue const v = superClos.value[fieldName] - if (v.readonly) continue - const v_copy = cloneWithDepth(v) - v_copy.inherited = true + if (v.runtime?.readonly) continue + const v_copy = shallowCopyValue(v) + if (!v_copy.func) v_copy.func = {} + v_copy.func.inherited = true v_copy._this = fclos v_copy._base = superClos fclos.value[fieldName] = v_copy @@ -815,8 +799,8 @@ class GoAnalyzer extends Analyzer { superValue.value[fieldName] = v_copy // super fclos should fill its fdef with ctor definition if (fieldName === '_CTOR_') { - superValue.fdef = v_copy.fdef - superValue.overloaded = superValue.overloaded || [] + superValue.ast.node = v_copy.ast.fdef + superValue.ast.fdef = v_copy.ast.fdef superValue.overloaded.push(fdef) } @@ -824,9 +808,9 @@ class GoAnalyzer extends Analyzer { } // inherit declarations - for (const x in superClos.decls) { - const v = superClos.decls[x] - fclos.decls[x] = v + for (const x of superClos.ast.declKeys) { + const v = superClos.ast.getDecl(x) + fclos.ast.setDecl(x, v) } // inherit modifiers for (const x in superClos.modifier) { @@ -855,15 +839,26 @@ class GoAnalyzer extends Analyzer { * @param node * @param state */ - processThisExpression(scope: any, node: any, state: any) { - this.thisFClos.misc_.pointer_reference = true + override processThisExpression(scope: Scope, node: ThisExpression, state: State): SymbolValueType { + this.thisFClos.pointerReference = true if (node._meta.type?.type === 'PointerType') { // 引用 return this.thisFClos } // 值传递 // TODO: 只深拷贝this.thisFClos.value即可,疑似循环依赖,待查 - return cloneWithDepth(this.thisFClos, 5) + return buildNewValueInstance( + this, + this.thisFClos, + null, + this.thisFClos.parent, + (x: any) => { + return false + }, + (v: any) => { + return !v + } + ) } /** @@ -873,9 +868,9 @@ class GoAnalyzer extends Analyzer { * @param state * @param prePostFlag */ - processInstruction(scope: any, node: any, state: any, prePostFlag?: any): any { + override processInstruction(scope: any, node: any, state: any, prePostFlag?: any): any { if (node?.name === 'error' || node?.name === 'err') { - return SymbolValue(node) + return new SymbolValue('', { sid: node.name, qid: `${scope.qid}.${node.name}`, ...node }) } return super.processInstruction(scope, node, state, prePostFlag) } @@ -902,7 +897,7 @@ class GoAnalyzer extends Analyzer { */ convertRetValToObjectType(fclos: any, argvalues: any, state: any, node: any, scope: any, retVal: any) { if (retVal.vtype === 'union') { - const declRetType = fclos.ast.returnType + const declRetType = fclos.ast.node.returnType if (declRetType.type === 'TupleType') { const retNum = declRetType.elements.length for (const i in retVal.value) { @@ -920,7 +915,7 @@ class GoAnalyzer extends Analyzer { } else { // declRetType.type !== 'TupleType' for (let rawValue of retVal.value) { - rawValue.rtype = fclos.ast.returnType + rawValue.rtype = fclos.ast.node.returnType if (rawValue.rtype !== 'DynamicType') { const cscope = this.processInstruction(scope, rawValue.rtype, state) if (cscope.vtype === 'class' && !(rawValue.type === 'Identifier' && rawValue.name === 'nil')) { @@ -929,10 +924,10 @@ class GoAnalyzer extends Analyzer { } } } - } else if (_.isArray(retVal) && fclos.ast.returnType.type !== 'VoidType') { + } else if (_.isArray(retVal) && fclos.ast.node.returnType.type !== 'VoidType') { // TODO 这里YASA有bug,暂时先改为对VoidType特判 for (const i in retVal) { - retVal[i].rtype = fclos.ast.returnType.elements[i] + retVal[i].rtype = fclos.ast.node.returnType.elements[i] if (retVal[i].rtype !== 'DynamicType') { let cscope if (retVal[i].rtype.type === 'PointerType') { @@ -946,7 +941,7 @@ class GoAnalyzer extends Analyzer { } } } else { - retVal.rtype = fclos.ast.returnType + retVal.rtype = fclos.ast.node.returnType if (retVal.rtype !== 'DynamicType') { const cscope = this.processInstruction(scope, retVal.rtype, state) if (cscope.vtype === 'class') { @@ -965,8 +960,9 @@ class GoAnalyzer extends Analyzer { * @param node * @param scope */ - executeSingleCall(fclos: any, argvalues: any, state: any, node: any, scope: any) { - const retVal = super.executeSingleCall(fclos, argvalues, state, node, scope) + override executeSingleCall(fclos: any, state: any, node: any, scope: any, callInfo: CallInfo) { + const retVal = super.executeSingleCall(fclos, state, node, scope, callInfo) + const argvalues = getLegacyArgValues(callInfo) return this.convertRetValToObjectType(fclos, argvalues, state, node, scope, retVal) } @@ -978,13 +974,25 @@ class GoAnalyzer extends Analyzer { */ buildTypeObject(oldScope: any, fclos: any) { // clone the basic class object - const obj = _.clone(oldScope) // 浅拷贝即可 + const obj = lodashCloneWithTag(oldScope) // 浅拷贝即可 for (const x in fclos.value) { const v = fclos.value[x] if (!v) continue - const v_copy = cloneWithDepth(v) - if (obj.field.hasOwnProperty(x)) continue - obj.field[x] = v_copy + const v_copy = buildNewValueInstance( + this, + v, + null, + v.parent, + (x: any) => { + return false + }, + (v: any) => { + return !v + } + ) + if (obj.members?.has(x)) continue + if (!obj.members) continue // Guard: skip if members is undefined + obj.members.set(x, v_copy) v_copy._this = obj v_copy.parent = obj } @@ -997,9 +1005,9 @@ class GoAnalyzer extends Analyzer { * @param node * @param state */ - processCompileUnit(scope: any, node: any, state: any) { + override processCompileUnit(scope: Scope, node: CompileUnit, state: State): Value { // 避免同一compileUnit被重复处理(例如,已被init的全局变量会被覆盖定义) - if (node._meta.compileUnitProcessed) return + if (node._meta.compileUnitProcessed) return this.topScope.members.get('UndefinedValue')?.() as Value node._meta.compileUnitProcessed = true if (this.checkerManager && this.checkerManager.checkAtCompileUnit) { const interruptFlag = this.checkerManager.checkAtCompileUnit(this, scope, node, state, { @@ -1007,7 +1015,7 @@ class GoAnalyzer extends Analyzer { entry_fclos: this.entry_fclos, }) // 插件返回状态为:中断后续分析 - if (interruptFlag) return + if (interruptFlag) return this.topScope.members.get('UndefinedValue')?.() as Value } return super.processCompileUnit(scope, node, state) } @@ -1015,7 +1023,7 @@ class GoAnalyzer extends Analyzer { /** * */ - startAnalyze() { + override startAnalyze() { if (this.checkerManager && this.checkerManager.checkAtStartOfAnalyze) { this.checkerManager.checkAtStartOfAnalyze(this, null, null, null, null) } @@ -1053,27 +1061,37 @@ class GoAnalyzer extends Analyzer { let index = 0 while (index < entryPoints.length) { const entryPoint = entryPoints[index++] + if (entryPoint.isPreProcess && this.isTmpSymbolTableOpen) { + this.restoreSymbolTable() + } else if (this.isTmpSymbolTableOpen) { + this.symbolTable.clear() + } + + if (!entryPoint.isPreProcess && !this.isTmpSymbolTableOpen) { + this.switchToTemporarySymbolTable() + } + if (entryPoint.type === constValue.ENGIN_START_FILE_BEGIN) continue entryPointConfig.setCurrentEntryPoint(entryPoint) if ( (isFromRule || entryPoint.functionName === 'main') && hasAnalysised.includes( - `${entryPoint.filePath}.${entryPoint.functionName}/${entryPoint?.entryPointSymVal?._qid}#${entryPoint.entryPointSymVal.ast.parameters}.${entryPoint.attribute}` + `${entryPoint.filePath}.${entryPoint.functionName}/${entryPoint?.entryPointSymVal?.qid}#${entryPoint.entryPointSymVal.ast.node.parameters}.${entryPoint.attribute}` ) ) { continue } hasAnalysised.push( - `${entryPoint.filePath}.${entryPoint.functionName}/${entryPoint?.entryPointSymVal?._qid}#${entryPoint.entryPointSymVal.ast.parameters}.${entryPoint.attribute}` + `${entryPoint.filePath}.${entryPoint.functionName}/${entryPoint?.entryPointSymVal?.qid}#${entryPoint.entryPointSymVal.ast.node.parameters}.${entryPoint.attribute}` ) logger.info( 'EntryPoint [%s.%s] is executing', entryPoint.filePath?.substring(0, entryPoint?.filePath.lastIndexOf('.')), entryPoint.functionName || - `` ) @@ -1081,11 +1099,11 @@ class GoAnalyzer extends Analyzer { const argValues = [] - for (const key in entryPoint.entryPointSymVal?.ast?.parameters) { + for (const key in entryPoint.entryPointSymVal?.ast?.node?.parameters) { argValues.push( this.processInstruction( entryPoint.entryPointSymVal, - entryPoint.entryPointSymVal?.ast?.parameters[key].id, + entryPoint.entryPointSymVal?.ast?.node?.parameters[key].id, state ) ) @@ -1093,17 +1111,17 @@ class GoAnalyzer extends Analyzer { try { this.executeCall( - entryPoint.entryPointSymVal?.ast, + entryPoint.entryPointSymVal?.ast?.node, entryPoint.entryPointSymVal, - argValues, state, - entryPoint.scopeVal + entryPoint.scopeVal, + { callArgs: this.buildCallArgs(entryPoint.entryPointSymVal?.ast?.node, argValues, entryPoint.entryPointSymVal) } ) } catch (e) { handleException( e, - `[${entryPoint.entryPointSymVal?.ast?.id?.name} symbolInterpret failed. Exception message saved in error log`, - `[${entryPoint.entryPointSymVal?.ast?.id?.name} symbolInterpret failed. Exception message saved in error log` + `[${entryPoint.entryPointSymVal?.ast?.node?.id?.name} symbolInterpret failed. Exception message saved in error log`, + `[${entryPoint.entryPointSymVal?.ast?.node?.id?.name} symbolInterpret failed. Exception message saved in error log` ) } if (index === entryPoints.length && !isFromRule) { @@ -1121,11 +1139,11 @@ class GoAnalyzer extends Analyzer { * @param fileName */ preProcess4SingleFile(source: any, fileName: any) { - // 需要将source导入缓存,否则找不到trace - SourceLine.storeCode(fileName, source) - this.moduleManager = GoParser.parseSingleFile(fileName, this.options) - const { packageInfo, moduleName } = this.moduleManager - const pkgValue = this.packageManager.getSubPackage(moduleName, true) + // 先填充 sourceCodeCache,parser 会优先使用 + this.sourceCodeCache.set(fileName, source.split(/\n/)) + this.topScope.context.modules = Parser.parseSingleFile(fileName, this.options, this.sourceCodeCache) + const { packageInfo, moduleName } = this.topScope.context.modules + const pkgValue = this.topScope.context.packages.getSubPackage(moduleName, true) const state = this.initState(this.topScope) this._scanPackages(pkgValue, '__single_file__', packageInfo, state, true) this.pkgValue = pkgValue @@ -1139,23 +1157,38 @@ class GoAnalyzer extends Analyzer { * @param argvalues * @param state */ - executeFunctionInArguments(scope: any, caller: any, callsiteNode: any, argvalues: any, state: any) { + override executeFunctionInArguments(scope: any, caller: any, callsiteNode: any, argvalues: any, state: any) { const needInvoke = Config.invokeCallbackOnUnknownFunction if (needInvoke !== 1 && needInvoke !== 2) return for (let i = 0; i < argvalues.length; i++) { const arg = argvalues[i] if (arg && arg.vtype === 'object') { - const obj = _.clone(arg) // 浅拷贝即可 + const obj = lodashCloneWithTag(arg) // 浅拷贝即可 const newState = _.clone(state) newState.parent = state newState.callstack = state.callstack ? state.callstack.concat([caller]) : [caller] + newState.callsites = state.callsites + ? state.callsites.concat([ + { + code: AstUtil.getRawCode(callsiteNode).slice(0, 100), + nodeHash: callsiteNode._meta?.nodehash, + loc: callsiteNode.loc, + }, + ]) + : [ + { + code: AstUtil.prettyPrintAST(callsiteNode).slice(0, 100), + nodeHash: callsiteNode._meta?.nodehash, + loc: callsiteNode.loc, + }, + ] Object.values(obj.value).forEach((field: any) => { if (field?.vtype === 'fclos') { // only override methods will be concerned - if (!field.ast) return - if (!field?.ast?._meta?.modifiers?.includes('@Override')) return - this.executeCall(callsiteNode, field, [], newState, scope) + if (!field.ast.node) return + if (!field?.ast?.node?._meta?.modifiers?.includes('@Override')) return + this.executeCall(callsiteNode, field, newState, scope, INTERNAL_CALL) } }) } @@ -1184,36 +1217,33 @@ class GoAnalyzer extends Analyzer { * @param node * @param state */ - processBinaryExpression(scope: any, node: any, state: any) { - /* - { operator, - left, - right - } - */ - const newNode = _.clone(node) - newNode.ast = node - const newLeft = (newNode.left = this.processInstruction(scope, node.left, state)) - const newRight = (newNode.right = this.processInstruction(scope, node.right, state)) + override processBinaryExpression(scope: Scope, node: BinaryExpression, state: State): BinaryExprValue { + const newLeft = this.processInstruction(scope, node.left, state) + const newRight = this.processInstruction(scope, node.right, state) if (node.operator === 'push') { this.processOperator(newLeft, node.left, newRight, node.operator, state) } - if (node.operator === 'instanceof') { - newNode._meta.type = node.right - // TODO 250805 用.value修改 - newNode.field = newLeft.field - } - const hasTag = (newLeft && newLeft.hasTagRec) || (newRight && newRight.hasTagRec) - if (hasTag) { - newNode.hasTagRec = hasTag - } + const hasTag = (newLeft && newLeft.taint?.isTaintedRec) || (newRight && newRight.taint?.isTaintedRec) + // checkerManager 需要 newNode 兼容对象 + const newNode: any = { ...node, ast: node, left: newLeft, right: newRight, isTainted: hasTag || null } + if (node.operator === 'instanceof') { + newNode._meta = { ...node._meta, type: node.right } + newNode.value = newLeft.value + } if (this.checkerManager && this.checkerManager.checkAtBinaryOperation) this.checkerManager.checkAtBinaryOperation(this, scope, node, state, { newNode }) - return SymbolValue(newNode) + const result = new BinaryExprValue(scope.qid, node.operator, newLeft, newRight, node, node.loc) as any + if (hasTag) { + result.taint?.mergeFrom([newLeft, newRight]) + } + if (node.operator === 'instanceof') { + result.value = newLeft.value + } + return result } /** @@ -1229,9 +1259,9 @@ class GoAnalyzer extends Analyzer { switch (operator) { case 'push': { this.saveVarInCurrentScope(scope, node, right, state) - const hasTag = (scope && scope.hasTagRec) || (right && right.hasTagRec) + const hasTag = (scope && scope.taint?.isTaintedRec) || (right && right.taint?.isTaintedRec) if (hasTag) { - scope.hasTagRec = hasTag + scope.taint?.mergeFrom([scope, right]) } } } @@ -1243,10 +1273,10 @@ class GoAnalyzer extends Analyzer { * @param node * @param state */ - processMemberAccess(scope: any, node: any, state: any) { + override processMemberAccess(scope: Scope, node: MemberAccess, state: State): SymbolValueType { const defscope = this.processInstruction(scope, node.object, state) if (defscope.vtype === 'union' && Array.isArray(defscope.value)) { - const ret = UnionValue() + const ret = new UnionValue(undefined, undefined, `${scope.qid}.`, node) defscope.value.forEach((defScp: any) => { ret.appendValue(this.accessValueFromDefScope(scope, node, state, defScp)) }) @@ -1276,7 +1306,13 @@ class GoAnalyzer extends Analyzer { } // 模糊类型补充 if (resolvedProp) { + if (!defscope || typeof defscope !== 'object' || !defscope.vtype) { + return new UndefinedValue() + } const res = this.getMemberValue(defscope, resolvedProp, state) + if (node.object.type !== 'SuperExpression' && (res.vtype !== 'union' || !Array.isArray(res.value))) { + res._this = defscope + } if (defscope.rtype && defscope.rtype !== 'DynamicType' && res && res.rtype === undefined) { res.rtype = { type: undefined } res.rtype.definiteType = defscope.rtype.type ? defscope.rtype : defscope.rtype.definiteType @@ -1313,8 +1349,8 @@ class GoAnalyzer extends Analyzer { * @param scope * @param state */ - processLibArgToRet(node: any, fclos: any, argvalues: any, scope: any, state: any) { - const ret = super.processLibArgToRet(node, fclos, argvalues, scope, state) + override processLibArgToRet(node: any, fclos: any, argvalues: any, scope: any, state: any, callInfo: CallInfo) { + const ret = super.processLibArgToRet(node, fclos, argvalues, scope, state, callInfo) // 将fclos的rtype信息保留给返回值 if (fclos.rtype) ret.rtype = fclos.rtype return ret @@ -1326,8 +1362,8 @@ class GoAnalyzer extends Analyzer { * @param node * @param state */ - processIdentifier(scope: any, node: any, state: any) { - if (node.name === 'nil') return PrimitiveValue({ ...node, ast: node, value: undefined }) + override processIdentifier(scope: Scope, node: Identifier, state: State): SymbolValueType { + if (node.name === 'nil') return new PrimitiveValue(scope.qid, 'nil', undefined, null, node.type, node.loc, node) const res = super.processIdentifier(scope, node, state) if (res && this.checkerManager) { this.checkerManager.checkAtIdentifier(this, scope, node, state, { res }) diff --git a/src/engine/analyzer/golang/gin/entrypoint-collector/gin-default-entrypoint.ts b/src/engine/analyzer/golang/gin/entrypoint-collector/gin-default-entrypoint.ts index c7ca91e6..f1a940b8 100644 --- a/src/engine/analyzer/golang/gin/entrypoint-collector/gin-default-entrypoint.ts +++ b/src/engine/analyzer/golang/gin/entrypoint-collector/gin-default-entrypoint.ts @@ -5,7 +5,10 @@ export {} const RouteRegistryProperty = ['POST', 'GET', 'DELETE', 'PUT'] -const RouteRegistryObject = ['github.com/gin-gonic/gin.Default()', 'github.com/gin-gonic/gin.New()'] +const RouteRegistryObject = [ + '.packageManager.github.com/gin-gonic/gin.Default()', + '.packageManager.github.com/gin-gonic/gin.New()', +] const processedRouteRegistry = new Set() @@ -122,16 +125,16 @@ function getGinEntryPointAndSource(packageManager: any) { function collectRouteRegistry(callExpNode: any, calleeObject: any, argValues: any[], scope: any) { const routeFCloses: any[] = [] const propertyName = callExpNode.callee.property?.name - const objectQid = calleeObject._qid + const objectQid = calleeObject.qid // TODO:后续考虑用rtype判断 if ( RouteRegistryObject.some((ginPrefix) => objectQid?.startsWith(ginPrefix)) && RouteRegistryProperty.includes(propertyName) ) { for (const arg of argValues) { - if (arg?.vtype === 'fclos' && arg.ast?.loc) { + if (arg?.vtype === 'fclos' && arg.ast?.node?.loc) { // 避免对同一条路由注册语句重复添加 - const hash = JSON.stringify(arg.ast.loc) + const hash = JSON.stringify(arg.ast.node.loc) if (!processedRouteRegistry.has(hash)) { processedRouteRegistry.add(hash) routeFCloses.push(arg) @@ -149,8 +152,8 @@ function collectRouteRegistry(callExpNode: any, calleeObject: any, argValues: an function getGinDefaultEntrypoint(packageManager: any) { const ginDefaultEntrypointSymvals = AstUtil.satisfy( packageManager, - (n: any) => n.vtype === 'fclos' && n.ast?.parameters && AstUtil.prettyPrintAST(n.ast.parameters).includes(GinType), - (node: any, prop: any) => prop === 'field', + (n: any) => n.vtype === 'fclos' && n.ast?.node?.parameters && AstUtil.prettyPrintAST(n.ast.node.parameters).includes(GinType), + (node: any, prop: any) => prop === '_field', null, true ) diff --git a/src/engine/analyzer/java/common/builtins/abstractwrapper-builtins.ts b/src/engine/analyzer/java/common/builtins/abstractwrapper-builtins.ts new file mode 100644 index 00000000..aad0d20d --- /dev/null +++ b/src/engine/analyzer/java/common/builtins/abstractwrapper-builtins.ts @@ -0,0 +1,243 @@ +const { addElementToBuffer } = require('./buffer') +const { + ValueUtil: { UndefinedValue }, +} = require('../../../../util/value-util') + +/** + * com.baomidou.mybatisplus.core.conditions.AbstractWrapper + */ +class AbstractWrapper { + /** + * allEq + * @param fclos + * @param argvalues + * @param state + * @param node + * @param scope + */ + static allEq(fclos: any, argvalues: any[], state: any, node: any, scope: any) { + const _this = fclos.getThisObj() + if (!_this) { + return new UndefinedValue() + } + if (argvalues.length < 1) { + return _this + } + + if (argvalues.length === 1) { + addElementToBuffer(_this, argvalues[0]) + } else if (argvalues.length === 2) { + for (const argvalue of argvalues) { + if (argvalue?.vtype !== 'fclos') { + addElementToBuffer(_this, argvalue) + } + } + } else if (argvalues.length === 3) { + addElementToBuffer(_this, argvalues[1]) + } else if (argvalues.length === 4) { + addElementToBuffer(_this, argvalues[2]) + } + + return _this + } + + /** + * between + * @param fclos + * @param argvalues + * @param state + * @param node + * @param scope + */ + static between(fclos: any, argvalues: any[], state: any, node: any, scope: any) { + return AbstractWrapper.threeCondition(fclos, argvalues, state, node, scope) + } + + /** + * eq + * @param fclos + * @param argvalues + * @param state + * @param node + * @param scope + */ + static eq(fclos: any, argvalues: any[], state: any, node: any, scope: any) { + return AbstractWrapper.twoCondition(fclos, argvalues, state, node, scope) + } + + /** + * ge + * @param fclos + * @param argvalues + * @param state + * @param node + * @param scope + */ + static ge(fclos: any, argvalues: any[], state: any, node: any, scope: any) { + return AbstractWrapper.twoCondition(fclos, argvalues, state, node, scope) + } + + /** + * gt + * @param fclos + * @param argvalues + * @param state + * @param node + * @param scope + */ + static gt(fclos: any, argvalues: any[], state: any, node: any, scope: any) { + return AbstractWrapper.twoCondition(fclos, argvalues, state, node, scope) + } + + /** + * le + * @param fclos + * @param argvalues + * @param state + * @param node + * @param scope + */ + static le(fclos: any, argvalues: any[], state: any, node: any, scope: any) { + return AbstractWrapper.twoCondition(fclos, argvalues, state, node, scope) + } + + /** + * like + * @param fclos + * @param argvalues + * @param state + * @param node + * @param scope + */ + static like(fclos: any, argvalues: any[], state: any, node: any, scope: any) { + return AbstractWrapper.twoCondition(fclos, argvalues, state, node, scope) + } + + /** + * + * @param fclos + * @param argvalues + * @param state + * @param node + * @param scope + */ + static likeLeft(fclos: any, argvalues: any[], state: any, node: any, scope: any) { + return AbstractWrapper.twoCondition(fclos, argvalues, state, node, scope) + } + + /** + * likeRight + * @param fclos + * @param argvalues + * @param state + * @param node + * @param scope + */ + static likeRight(fclos: any, argvalues: any[], state: any, node: any, scope: any) { + return AbstractWrapper.twoCondition(fclos, argvalues, state, node, scope) + } + + /** + * lt + * @param fclos + * @param argvalues + * @param state + * @param node + * @param scope + */ + static lt(fclos: any, argvalues: any[], state: any, node: any, scope: any) { + return AbstractWrapper.twoCondition(fclos, argvalues, state, node, scope) + } + + /** + * ne + * @param fclos + * @param argvalues + * @param state + * @param node + * @param scope + */ + static ne(fclos: any, argvalues: any[], state: any, node: any, scope: any) { + return AbstractWrapper.twoCondition(fclos, argvalues, state, node, scope) + } + + /** + * notBetween + * @param fclos + * @param argvalues + * @param state + * @param node + * @param scope + */ + static notBetween(fclos: any, argvalues: any[], state: any, node: any, scope: any) { + return AbstractWrapper.threeCondition(fclos, argvalues, state, node, scope) + } + + /** + * notLike + * @param fclos + * @param argvalues + * @param state + * @param node + * @param scope + */ + static notLike(fclos: any, argvalues: any[], state: any, node: any, scope: any) { + return AbstractWrapper.twoCondition(fclos, argvalues, state, node, scope) + } + + /** + * two condition + * @param fclos + * @param argvalues + * @param state + * @param node + * @param scope + */ + static twoCondition(fclos: any, argvalues: any[], state: any, node: any, scope: any) { + const _this = fclos.getThisObj() + if (!_this) { + return new UndefinedValue() + } + if (!argvalues || argvalues.length < 2) { + return _this + } + + if (argvalues.length === 2) { + addElementToBuffer(_this, argvalues[1]) + } else if (argvalues.length === 3) { + addElementToBuffer(_this, argvalues[2]) + } + + return _this + } + + /** + * three condition + * @param fclos + * @param argvalues + * @param state + * @param node + * @param scope + */ + static threeCondition(fclos: any, argvalues: any[], state: any, node: any, scope: any) { + const _this = fclos.getThisObj() + if (!_this) { + return new UndefinedValue() + } + if (!argvalues || argvalues.length < 3) { + return _this + } + + if (argvalues.length === 3) { + addElementToBuffer(_this, argvalues[1]) + addElementToBuffer(_this, argvalues[2]) + } else if (argvalues.length === 4) { + addElementToBuffer(_this, argvalues[2]) + addElementToBuffer(_this, argvalues[3]) + } + + return _this + } +} + +export = AbstractWrapper diff --git a/src/engine/analyzer/java/common/builtins/arrays-builtins.ts b/src/engine/analyzer/java/common/builtins/arrays-builtins.ts new file mode 100644 index 00000000..4a2f627c --- /dev/null +++ b/src/engine/analyzer/java/common/builtins/arrays-builtins.ts @@ -0,0 +1,52 @@ +const Collection = require('./collection-builtins') +const { newInstance } = require('./object') +const { UndefinedValue } = require('../../../common/value/undefine') +const { addElementToBuffer } = require('./buffer') + +/** + * java.util.Arrays + */ +class Arrays extends (Collection as any) { + /** + * Constructor + * @param _this + * @param argvalues + * @param state + * @param node + * @param scope + * @returns {*} + */ + static Arrays(_this: any, argvalues: any[], state: any, node: any, scope: any) { + super.Collection(_this, argvalues, state, node, scope) + return _this + } + + /** + * Arrays.asList + * @param fclos + * @param argvalues + * @param state + * @param node + * @param scope + */ + static asList(fclos: any, argvalues: any[], state: any, node: any, scope: any) { + const obj = newInstance(this, (this as any).topScope?.context.packages, 'java.util.List') + if (!obj) { + return UndefinedValue() + } + if (argvalues?.length > 0) { + for (const argvalue of argvalues) { + if (obj.getMisc('precise')) { + obj.length = obj.length ?? 0 + obj.value[obj.length] = argvalue + obj.length++ + } else { + addElementToBuffer(obj, argvalue) + } + } + } + return obj + } +} + +export = Arrays diff --git a/src/engine/analyzer/java/common/builtins/atomicreference-builtins.ts b/src/engine/analyzer/java/common/builtins/atomicreference-builtins.ts index 62f68fa3..e451e342 100644 --- a/src/engine/analyzer/java/common/builtins/atomicreference-builtins.ts +++ b/src/engine/analyzer/java/common/builtins/atomicreference-builtins.ts @@ -1,5 +1,5 @@ const MemSpaceAtomic = require('../../../common/memSpace') -const UndefinedValueAtomic = require('../../../common/value/undefine') +import { UndefinedValue } from '../../../common/value/undefine' const memSpaceUtilAtomic = new MemSpaceAtomic() @@ -36,14 +36,23 @@ class AtomicReference { * @param node * @param scope */ - static set(fclos: any, argvalues: any[], state: any, node: any, scope: any): void { - const _this = fclos.getThis() - if (!_this) { - return new UndefinedValueAtomic() + static set(fclos: any, argvalues: any[], state: any, node: any, scope: any): any { + const _this = fclos.getThisObj() + if (!_this || !argvalues || argvalues.length === 0) { + return new UndefinedValue() + } + + if (_this.vtype === 'union' && Array.isArray(_this.value)) { + for (const thisObj of _this.value) { + thisObj.arguments = [] + memSpaceUtilAtomic.saveVarInScope(thisObj, '_value', argvalues[0], state) + } + } else { + _this.arguments = [] + memSpaceUtilAtomic.saveVarInScope(_this, '_value', argvalues[0], state) } - memSpaceUtilAtomic.saveVarInScope(_this, '_value', argvalues[0], state) - _this.arguments = [] + return new UndefinedValue() } } diff --git a/src/engine/analyzer/java/common/builtins/buffer.ts b/src/engine/analyzer/java/common/builtins/buffer.ts index 3dbcc199..eeacefd3 100644 --- a/src/engine/analyzer/java/common/builtins/buffer.ts +++ b/src/engine/analyzer/java/common/builtins/buffer.ts @@ -1,4 +1,6 @@ -export {} +const _ = require('lodash') +const QidUnifyUtil = require('../../../../../util/qid-unify-util') + /** * move exist elements to buffer * @param _this @@ -8,7 +10,7 @@ function moveExistElementsToBuffer(_this: any, startIndex?: number): void { if (!_this.getMisc('buffer')) { _this.setMisc('buffer', []) } - if (_this.value) { + if (_.isObject(_this.value)) { for (const key in _this.value) { if (Number(key) >= 0) { if (!startIndex || (typeof startIndex === 'number' && Number(key) >= startIndex)) { @@ -55,7 +57,10 @@ function removeElementFromBuffer(_this: any, element: any): void { } const tmpBuffer: any[] = [] for (const bufferElement of _this.getMisc('buffer')) { - if (bufferElement?._qid !== element?._qid) { + if ( + bufferElement?.logicalQid !== + element?.logicalQid + ) { tmpBuffer.push(bufferElement) } } diff --git a/src/engine/analyzer/java/common/builtins/class-builtins.ts b/src/engine/analyzer/java/common/builtins/class-builtins.ts new file mode 100644 index 00000000..e0970b61 --- /dev/null +++ b/src/engine/analyzer/java/common/builtins/class-builtins.ts @@ -0,0 +1,96 @@ +const UastSpec = require('@ant-yasa/uast-spec') +const { + ValueUtil: { UndefinedValue }, +} = require('../../../../util/value-util') +const MemSpace = require('../../../common/memSpace') +const { getValueFromPackageByQid } = require('../../../../util/value-util') +const { newInstance } = require('./object') + +const memSpaceUtil = new MemSpace() + +/** + * java.lang.Class + */ +class Class { + /** + * getMethod + * @param fclos + * @param argvalues + * @param state + * @param node + * @param scope + * @returns {*} + */ + static getMethod(fclos: any, argvalues: any[], state: any, node: any, scope: any): any { + const _this = fclos.getThisObj() + if (!_this || _this.parent?.vtype !== 'class') { + return new UndefinedValue() + } + if (argvalues.length === 0 || argvalues[0].vtype !== 'primitive') { + return new UndefinedValue() + } + return memSpaceUtil.getMemberValueNoCreate(_this.parent, UastSpec.identifier(argvalues[0].raw_value), state) + } + + /** + * forName + * @param fclos + * @param argvalues + * @param state + * @param node + * @param scope + * @returns {*} + */ + static forName(fclos: any, argvalues: any[], state: any, node: any, scope: any): any { + if (argvalues.length !== 1 || argvalues[0].vtype !== 'primitive' || !argvalues[0].value) { + return new UndefinedValue() + } + + let classVal + const fullType = argvalues[0].raw_value + if (fullType.includes('.')) { + classVal = getValueFromPackageByQid((this as any).topScope?.context.packages, fullType) + } else { + classVal = (this as any).getMemberValueNoCreate(scope, fullType) + } + if (!classVal) { + return new UndefinedValue() + } + return (this as any).getMemberValueNoCreate(classVal, UastSpec.identifier('class'), state, 1) + } + + /** + * getConstructor + * @param fclos + * @param argvalues + * @param state + * @param node + * @param scope + * @returns {*} + */ + static getConstructor(fclos: any, argvalues: any[], state: any, node: any, scope: any): any { + return fclos.getThisObj() + } + + /** + * newInstance + * @param fclos + * @param argvalues + * @param state + * @param node + * @param scope + */ + static newInstance(fclos: any, argvalues: any[], state: any, node: any, scope: any) { + const _this = fclos.getThisObj() + if (!_this || _this.parent?.vtype !== 'class') { + return new UndefinedValue() + } + const obj = newInstance(this, (this as any).topScope?.context.packages, _this.parent.qid) + if (!obj) { + return new UndefinedValue() + } + return obj + } +} + +module.exports = Class diff --git a/src/engine/analyzer/java/common/builtins/collection-builtins.ts b/src/engine/analyzer/java/common/builtins/collection-builtins.ts index f0b2f4f9..7407cc74 100644 --- a/src/engine/analyzer/java/common/builtins/collection-builtins.ts +++ b/src/engine/analyzer/java/common/builtins/collection-builtins.ts @@ -1,3 +1,9 @@ +const { + ValueUtil: { UndefinedValue }, +} = require('../../../../util/value-util') +const { getAllElementFromBuffer, addElementToBuffer } = require('./buffer') +const { newInstance } = require('./object') + /** * java.util.Collection */ @@ -14,6 +20,43 @@ class Collection { static Collection(_this: any, argvalues: any[], state: any, node: any, scope: any) { return _this } + + /** + * Collection.stream + * @param fclos + * @param argvalues + * @param state + * @param node + * @param scope + */ + static stream(fclos: any, argvalues: any[], state: any, node: any, scope: any) { + const _this = fclos.getThisObj() + if (!_this) { + return new UndefinedValue() + } + const obj = newInstance(this, (this as any).topScope?.context.packages, 'java.util.stream.Stream') + if (!obj) { + return new UndefinedValue() + } + + if (!_this.getMisc('precise')) { + if (_this.getMisc('buffer')) { + for (const element of getAllElementFromBuffer(_this)) { + addElementToBuffer(obj, element) + } + } else { + addElementToBuffer(obj, _this) + } + } else { + for (const element of Object.values(_this.value) as any) { + if (element?.vtype !== 'fclos') { + addElementToBuffer(obj, element) + } + } + } + + return obj + } } module.exports = Collection diff --git a/src/engine/analyzer/java/common/builtins/completablefuture-builtins.ts b/src/engine/analyzer/java/common/builtins/completablefuture-builtins.ts index b8a62f38..ceaef052 100644 --- a/src/engine/analyzer/java/common/builtins/completablefuture-builtins.ts +++ b/src/engine/analyzer/java/common/builtins/completablefuture-builtins.ts @@ -1,5 +1,7 @@ +import { buildNewValueInstance } from '../../../../../util/clone-util' + const UastSpec = require('@ant-yasa/uast-spec') -const UndefinedValue = require('../../../common/value/undefine') +import { UndefinedValue } from '../../../common/value/undefine' const MemState = require('../../../common/memState') const MemSpace = require('../../../common/memSpace') @@ -41,7 +43,7 @@ class CompletableFuture { * @param scope */ static join(fclos: any, argvalues: any[], state: any, node: any, scope: any) { - const _this = fclos.getThis() + const _this = fclos.getThisObj() if (!_this || !(this as any).executeCall) { return new UndefinedValue() } @@ -53,7 +55,7 @@ class CompletableFuture { if (elementArgvalues?.length > 0) { elementArgvalues = [res] } - res = (this as any).executeCall(element.node, element.fclos, elementArgvalues, element.state, element.scope) + res = (this as any).executeCall(element.node, element.fclos, element.state, element.scope, { callArgs: (this as any).buildCallArgs(element.node, elementArgvalues, element.fclos) }) } _this.setMisc('thenFuncsWithContext', []) @@ -70,7 +72,7 @@ class CompletableFuture { * @param scope */ static runAsync(fclos: any, argvalues: any[], state: any, node: any, scope: any) { - let instance = new UndefinedValue() + let instance: any = new UndefinedValue() if ( !(this as any).processNewExpression || argvalues.length < 1 || @@ -87,7 +89,19 @@ class CompletableFuture { } instance = (this as any).processNewExpression(scope, newExpression, state) - const futureScope = MemState.deepScopeClone(scope, () => true) + const futureScope = buildNewValueInstance( + this, + scope, + node, + scope, + () => { + return false + }, + (v: any) => { + return !v + }, + 2 + ) const thenFuncsWithContext: any[] = [] const funcOldScope = argvalues[0].parent argvalues[0].parent = futureScope @@ -117,7 +131,7 @@ class CompletableFuture { * @param scope */ static supplyAsync(fclos: any, argvalues: any[], state: any, node: any, scope: any) { - let instance = new UndefinedValue() + let instance: any = new UndefinedValue() if ( !(this as any).processNewExpression || argvalues.length < 1 || @@ -134,7 +148,19 @@ class CompletableFuture { } instance = (this as any).processNewExpression(scope, newExpression, state) - const futureScope = MemState.deepScopeClone(scope, () => true) + const futureScope = buildNewValueInstance( + this, + scope, + node, + scope, + () => { + return false + }, + (v: any) => { + return !v + }, + 2 + ) const thenFuncsWithContext: any[] = [] const funcOldScope = argvalues[0].parent argvalues[0].parent = futureScope @@ -165,12 +191,26 @@ class CompletableFuture { * @param scope */ static thenRun(fclos: any, argvalues: any[], state: any, node: any, scope: any) { - const _this = fclos.getThis() + const _this = fclos.getThisObj() if (!_this || argvalues.length < 1 || argvalues[0].vtype !== 'fclos' || !(this as any).processAndCallFuncDef) { return new UndefinedValue() } - const futureScope = _this.getMisc('futureScope') || MemState.deepScopeClone(scope, () => true) + const futureScope = + _this.getMisc('futureScope') || + buildNewValueInstance( + this, + scope, + node, + scope, + () => { + return false + }, + (v: any) => { + return !v + }, + 2 + ) const thenFuncsWithContext = _this.getMisc('thenFuncsWithContext') || [] const funcOldScope = argvalues[0].parent argvalues[0].parent = futureScope @@ -211,17 +251,31 @@ class CompletableFuture { * @param scope */ static thenApply(fclos: any, argvalues: any[], state: any, node: any, scope: any) { - const _this = fclos.getThis() + const _this = fclos.getThisObj() if (!_this || argvalues.length < 1 || argvalues[0].vtype !== 'fclos' || !(this as any).executeCall) { return new UndefinedValue() } - const futureScope = _this.getMisc('futureScope') || MemState.deepScopeClone(scope, () => true) + const futureScope = + _this.getMisc('futureScope') || + buildNewValueInstance( + this, + scope, + node, + scope, + () => { + return false + }, + (v: any) => { + return !v + }, + 2 + ) const thenFuncsWithContext = _this.getMisc('thenFuncsWithContext') || [] const funcOldScope = argvalues[0].parent argvalues[0].parent = futureScope let result = memSpaceUtil.getMemberValueNoCreate(_this, '_result', state) - result = (this as any).executeCall(node.arguments[0], argvalues[0], [result], state, futureScope) + result = (this as any).executeCall(node.arguments[0], argvalues[0], state, futureScope, { callArgs: (this as any).buildCallArgs(node.arguments[0], [result], argvalues[0]) }) argvalues[0].parent = funcOldScope memSpaceUtil.saveVarInScope(_this, '_result', result, state) scope.value = MemState.unionScopeValues(scope, futureScope) @@ -260,17 +314,31 @@ class CompletableFuture { * @param scope */ static thenAccept(fclos: any, argvalues: any[], state: any, node: any, scope: any) { - const _this = fclos.getThis() + const _this = fclos.getThisObj() if (!_this || argvalues.length < 1 || argvalues[0].vtype !== 'fclos' || !(this as any).executeCall) { return new UndefinedValue() } - const futureScope = _this.getMisc('futureScope') || MemState.deepScopeClone(scope, () => true) + const futureScope = + _this.getMisc('futureScope') || + buildNewValueInstance( + this, + scope, + node, + scope, + () => { + return false + }, + (v: any) => { + return !v + }, + 2 + ) const thenFuncsWithContext = _this.getMisc('thenFuncsWithContext') || [] const funcOldScope = argvalues[0].parent argvalues[0].parent = futureScope const result = memSpaceUtil.getMemberValueNoCreate(_this, '_result', state) - ;(this as any).executeCall(node.arguments[0], argvalues[0], [result], state, futureScope) + ;(this as any).executeCall(node.arguments[0], argvalues[0], state, futureScope, { callArgs: (this as any).buildCallArgs(node.arguments[0], [result], argvalues[0]) }) argvalues[0].parent = funcOldScope scope.value = MemState.unionScopeValues(scope, futureScope) thenFuncsWithContext.push({ diff --git a/src/engine/analyzer/java/common/builtins/executor-builtins.ts b/src/engine/analyzer/java/common/builtins/executor-builtins.ts index 44302141..466154d4 100644 --- a/src/engine/analyzer/java/common/builtins/executor-builtins.ts +++ b/src/engine/analyzer/java/common/builtins/executor-builtins.ts @@ -1,4 +1,7 @@ const _ = require('lodash') +const { + ValueUtil: { UndefinedValue }, +} = require('../../../../util/value-util') /** * java.util.concurrent.Executor @@ -14,10 +17,13 @@ class Executor { */ static execute(fclos: any, argvalues: any[], state: any, node: any, scope: any) { if (argvalues.length < 1) { - return + return new UndefinedValue() } - if (argvalues[0].field?.run && _.isFunction((this as any).executeCall)) { - ;(this as any).executeCall(node, argvalues[0].field?.run, [], state, scope) + const runMethod = argvalues[0]?.members?.get('run') + if (runMethod && _.isFunction((this as any).executeCall)) { + ;(this as any).executeCall(node, runMethod, state, scope, { callArgs: (this as any).buildCallArgs(node, [], runMethod) }) + } else if (argvalues[0].vtype === 'fclos' && _.isFunction((this as any).executeCall)) { + ;(this as any).executeCall(node, argvalues[0], state, scope, { callArgs: (this as any).buildCallArgs(node, [], argvalues[0]) }) } } } diff --git a/src/engine/analyzer/java/common/builtins/executorservice-builtins.ts b/src/engine/analyzer/java/common/builtins/executorservice-builtins.ts new file mode 100644 index 00000000..3abd2cff --- /dev/null +++ b/src/engine/analyzer/java/common/builtins/executorservice-builtins.ts @@ -0,0 +1,112 @@ +const _ = require('lodash') +const Executor = require('./executor-builtins') +const { + ValueUtil: { UndefinedValue }, +} = require('../../../../util/value-util') +const AstUtil = require('../../../../../util/ast-util') +const { getAllElementFromBuffer } = require('./buffer') + +/** + * java.util.concurrent.ExecutorService + */ +class ExecutorService extends Executor { + /** + * submit + * @param fclos + * @param argvalues + * @param state + * @param node + * @param scope + */ + static submit(fclos: any, argvalues: any[], state: any, node: any, scope: any) { + if (argvalues.length < 1) { + return new UndefinedValue() + } + if (argvalues[0]?.members?.get('run') && _.isFunction((this as any).executeCall)) { + ;(this as any).executeCall(node, argvalues[0].members.get('run')!, state, scope, { callArgs: (this as any).buildCallArgs(node, [], argvalues[0].members.get('run')!) }) + } else if (argvalues[0]?.members?.get('call') && _.isFunction((this as any).executeCall)) { + ;(this as any).executeCall(node, argvalues[0].members.get('call')!, state, scope, { callArgs: (this as any).buildCallArgs(node, [], argvalues[0].members.get('call')!) }) + } else if (argvalues[0]?.members?.get('doCall') && _.isFunction((this as any).executeCall)) { + ;(this as any).executeCall(node, argvalues[0].members.get('doCall')!, state, scope, { callArgs: (this as any).buildCallArgs(node, [], argvalues[0].members.get('doCall')!) }) + } else if (argvalues[0].vtype === 'fclos') { + ;(this as any).executeCall(node, argvalues[0], state, scope, { callArgs: (this as any).buildCallArgs(node, [], argvalues[0]) }) + } + return new UndefinedValue() + } + + /** + * invokeAll + * @param fclos + * @param argvalues + * @param state + * @param node + * @param scope + */ + static invokeAll(fclos: any, argvalues: any[], state: any, node: any, scope: any) { + if (argvalues.length < 1 || !argvalues[0]) { + return new UndefinedValue() + } + + let funcs: any[] = [] + + // 优先从 buffer 获取元素(Stream.collect 收集的元素存储在 _misc.buffer 中) + const buffer = argvalues[0]?.getMisc?.('buffer') + if (buffer) { + funcs = getAllElementFromBuffer(argvalues[0]) + } + + // fallback: 通过 satisfy 遍历 + if (funcs.length === 0) { + const satisfyResult = AstUtil.satisfy( + argvalues[0], + (n: any) => + n?.members?.get('call')?.vtype === 'fclos' || + n?.members?.get('doCall')?.vtype === 'fclos' || + (n.vtype === 'fclos' && n.sid?.includes(' { + return false + }, + (v: any) => { + return !v + } + ) newThis._this = newThis newThis.setMisc('precise', false) moveExistElementsToBuffer(newThis) @@ -371,7 +384,7 @@ class List extends (Collection as any) { * @param scope */ static listIterator(fclos: any, argvalues: any[], state: any, node: any, scope: any) { - const _this = fclos.getThis() + const _this = fclos.getThisObj() if (!_this || !argvalues) { return new UndefinedValue() } @@ -380,7 +393,18 @@ class List extends (Collection as any) { return _this } - const newThis = cloneWithDepth(_this, 3) + const newThis = buildNewValueInstance( + this, + _this, + node, + scope, + () => { + return false + }, + (v: any) => { + return !v + } + ) newThis._this = newThis newThis.setMisc('precise', false) newThis.length = 0 @@ -414,7 +438,7 @@ class List extends (Collection as any) { * @param scope */ static remove(fclos: any, argvalues: any[], state: any, node: any, scope: any) { - const _this = fclos.getThis() + const _this = fclos.getThisObj() if (!_this || !argvalues || argvalues.length === 0) { return new UndefinedValue() } @@ -445,7 +469,10 @@ class List extends (Collection as any) { needReturnObj = true } else { for (const indexKey of indexKeys) { - if (_this.value[indexKey]._qid === argvalues[0]._qid) { + if ( + _this.value[indexKey].logicalQid === + argvalues[0].logicalQid + ) { removeKey = indexKey break } @@ -489,7 +516,7 @@ class List extends (Collection as any) { * @param scope */ static removeAll(fclos: any, argvalues: any[], state: any, node: any, scope: any) { - const _this = fclos.getThis() + const _this = fclos.getThisObj() if (_this || !argvalues || argvalues.length === 0) { return new UndefinedValue() } @@ -511,7 +538,7 @@ class List extends (Collection as any) { * @param scope */ static removeFirst(fclos: any, argvalues: any[], state: any, node: any, scope: any) { - const _this = fclos.getThis() + const _this = fclos.getThisObj() if (!_this) { return new UndefinedValue() } @@ -551,7 +578,7 @@ class List extends (Collection as any) { * @param scope */ static removeLast(fclos: any, argvalues: any[], state: any, node: any, scope: any) { - const _this = fclos.getThis() + const _this = fclos.getThisObj() if (!_this) { return new UndefinedValue() } @@ -589,7 +616,7 @@ class List extends (Collection as any) { * @param scope */ static retainAll(fclos: any, argvalues: any[], state: any, node: any, scope: any) { - const _this = fclos.getThis() + const _this = fclos.getThisObj() if (!argvalues || argvalues.length === 0) { return new UndefinedValue() } @@ -609,7 +636,7 @@ class List extends (Collection as any) { * @param scope */ static reversed(fclos: any, argvalues: any[], state: any, node: any, scope: any) { - const _this = fclos.getThis() + const _this = fclos.getThisObj() if (!_this) { return new UndefinedValue() } @@ -640,7 +667,7 @@ class List extends (Collection as any) { * @param scope */ static set(fclos: any, argvalues: any[], state: any, node: any, scope: any) { - const _this = fclos.getThis() + const _this = fclos.getThisObj() if (!_this || !argvalues || argvalues.length !== 2) { return new UndefinedValue() @@ -691,7 +718,7 @@ class List extends (Collection as any) { * @param scope */ static sort(fclos: any, argvalues: any[], state: any, node: any, scope: any) { - const _this = fclos.getThis() + const _this = fclos.getThisObj() if (!_this) { return } @@ -722,12 +749,23 @@ class List extends (Collection as any) { * @param scope */ static subList(fclos: any, argvalues: any[], state: any, node: any, scope: any) { - const _this = fclos.getThis() + const _this = fclos.getThisObj() if (!_this || !argvalues || argvalues.length !== 2) { return new UndefinedValue() } - const newThis = cloneWithDepth(_this, 3) + const newThis = buildNewValueInstance( + this, + _this, + node, + scope, + () => { + return false + }, + (v: any) => { + return !v + } + ) newThis._this = newThis if (newThis.getMisc('precise')) { let startIndex: number = 0 @@ -805,7 +843,7 @@ class List extends (Collection as any) { * @returns {*} */ static toArray(fclos: any, argvalues: any[], state: any, node: any, scope: any) { - return fclos.getThis() + return fclos.getThisObj() } /** @@ -818,7 +856,7 @@ class List extends (Collection as any) { * @private */ static _functionNotFoundCallback_(fclos: any, argvalues: any[], state: any, node: any, scope: any) { - const _this = fclos.getThis() + const _this = fclos.getThisObj() if (!_this) { return } diff --git a/src/engine/analyzer/java/common/builtins/lombok.ts b/src/engine/analyzer/java/common/builtins/lombok.ts index 0bd326a2..38f0b5bd 100644 --- a/src/engine/analyzer/java/common/builtins/lombok.ts +++ b/src/engine/analyzer/java/common/builtins/lombok.ts @@ -1,4 +1,6 @@ -const logger = require('../../../../../util/logger')(__filename) +const { + ValueUtil: { UndefinedValue }, +} = require('../../../../util/value-util') module.exports = { /** @@ -8,10 +10,18 @@ module.exports = { */ processGetter(fname: any, fieldName: any) { return function getter(fclos: any, argvalues: any, state: any, node: any, scope: any) { - if (argvalues.length !== 0) { - logger.warn('getter: params length [%d] is not equal to 0', argvalues.length) + const _this = fclos.getThisObj() + if (!_this) { + return new UndefinedValue() } - return fclos.getThis().getFieldValue(fieldName, true) + const res = _this.getFieldValue(fieldName, true) + if (res && typeof res === 'object' && res?.vtype !== 'fclos' && res?.vtype !== 'class' && ['symbol', 'object'].includes(_this.vtype)) { + res.object = _this + if (_this.taint?.isTaintedRec) { + res.taint?.markSource() + } + } + return res } }, processSetter(fname: any, fieldName: any) { @@ -23,11 +33,30 @@ module.exports = { // } // 没有入参,会把符号值变为undefined return function setter(fclos: any, argvalues: any, state: any, node: any, scope: any) { - if (argvalues.length !== 1) { - logger.warn('setter: params length [%d] is not equal to 1', argvalues.length) + const _this = fclos.getThisObj() + if (!_this) { + return new UndefinedValue() + } + if (_this.vtype === 'primitive') { + return _this + } + _this.setFieldValue(fieldName, argvalues[0]) + return _this + } + }, + _CTOR_(fclos: any, argvalues: any, state: any, node: any, scope: any) { + const _this = fclos.getThisObj() + if (!_this) { + return new UndefinedValue() + } + if (_this.vtype === 'primitive' || !Array.isArray(argvalues)) { + return _this + } + for (const argvalue of argvalues) { + if (argvalue.sid) { + _this.setFieldValue(argvalue.sid, argvalue) } - fclos.getThis().setFieldValue(fieldName, argvalues[0]) - return fclos.getThis() } + return _this }, } diff --git a/src/engine/analyzer/java/common/builtins/map-builtins.ts b/src/engine/analyzer/java/common/builtins/map-builtins.ts index f0ee4204..cc317e9d 100644 --- a/src/engine/analyzer/java/common/builtins/map-builtins.ts +++ b/src/engine/analyzer/java/common/builtins/map-builtins.ts @@ -1,10 +1,12 @@ const _ = require('lodash') const Collection = require('./collection-builtins') const { getSymbolRef } = require('../../../../../util/common-util') -const UnionValue = require('../../../common/value/union') const { clearBuffer, addElementToBuffer, getAllElementFromBuffer } = require('./buffer') -const { cloneWithDepth } = require('../../../../../util/clone-util') -const UndefinedValue = require('../../../common/value/undefine') +const { buildNewValueInstance } = require('../../../../../util/clone-util') +const QidUnifyUtil = require('../../../../../util/qid-unify-util') + +import { UnionValue } from '../../../common/value/union' +import { UndefinedValue } from '../../../common/value/undefine' /** * java.util.Map @@ -40,14 +42,18 @@ class Map extends (Collection as any) { static clear(fclos: any, argvalues: any[], state: any, node: any, scope: any) { const _this = fclos.parent if (!_this) { - return + return new UndefinedValue() } - const keyRefSet = _this.getFieldValue('keyRefSet') + let keyRefSet = _this.getFieldValue('keyRefSet') + if (keyRefSet === null || keyRefSet === undefined || keyRefSet.size === 0) { + keyRefSet = new Set() + _this.setFieldValue('keyRefSet', keyRefSet) + } for (const keyRef of keyRefSet) { const entryValue = _this.getFieldValue(keyRef) - if (Array.isArray(entryValue.field) && entryValue.field.length === 2) { - delete _this.field[keyRef] + if (Array.isArray(entryValue.value) && entryValue.value.length === 2) { + _this.members.delete(keyRef) } } keyRefSet.clear() @@ -55,6 +61,8 @@ class Map extends (Collection as any) { if (!_this.getMisc('precise')) { clearBuffer(_this) } + + return new UndefinedValue() } /** @@ -126,12 +134,23 @@ class Map extends (Collection as any) { * @param scope */ static entrySet(fclos: any, argvalues: any[], state: any, node: any, scope: any) { - const _this = fclos.getThis() + const _this = fclos.getThisObj() if (!_this) { return new UndefinedValue() } - const newThis = cloneWithDepth(_this, 3) + const newThis = buildNewValueInstance( + this, + _this, + node, + scope, + () => { + return false + }, + (v: any) => { + return !v + } + ) newThis._this = newThis return newThis @@ -157,7 +176,26 @@ class Map extends (Collection as any) { * @param node * @param scope */ - static forEach(fclos: any, argvalues: any[], state: any, node: any, scope: any) {} + static forEach(fclos: any, argvalues: any[], state: any, node: any, scope: any) { + const _this = fclos.getThisObj() + if (!_this) { + return new UndefinedValue() + } + + const keyRefSet = _this.getFieldValue('keyRefSet') + if (keyRefSet instanceof Set) { + for (const keyRef of keyRefSet) { + const entryValue = _this.getFieldValue(keyRef) + if (entryValue && Array.isArray(entryValue.value) && entryValue.value.length === 2) { + ;(this as any).executeCall(node, argvalues[0], state, scope, { callArgs: (this as any).buildCallArgs(node, [entryValue.getFieldValue('0'), entryValue.getFieldValue('1')], argvalues[0]) }) + } + } + } else { + ;(this as any).executeCall(node, argvalues[0], state, scope, { callArgs: (this as any).buildCallArgs(node, [_this, _this], argvalues[0]) }) + } + + return new UndefinedValue() + } /** * Map.get @@ -168,13 +206,17 @@ class Map extends (Collection as any) { * @param scope */ static get(fclos: any, argvalues: any[], state: any, node: any, scope: any) { - const _this = fclos.getThis() - if (!_this || !argvalues || argvalues.length === 0) { + const _this = fclos.getThisObj() + if (!_this || !argvalues || argvalues.length === 0 || _this.vtype === 'primitive') { return new UndefinedValue() } const keyRef = getSymbolRef(argvalues[0]) - const keyRefSet = _this.getFieldValue('keyRefSet') + let keyRefSet = _this.getFieldValue('keyRefSet') + if (keyRefSet === null || keyRefSet === undefined || keyRefSet.size === 0) { + keyRefSet = new Set() + _this.setFieldValue('keyRefSet', keyRefSet) + } if (!keyRefSet.has(keyRef)) { if (!_this.getMisc('precise')) { return _this @@ -183,8 +225,8 @@ class Map extends (Collection as any) { } const entryValue = _this.getFieldValue(keyRef) - if (Array.isArray(entryValue.field) && entryValue.field.length === 2) { - return entryValue.field[1] + if (Array.isArray(entryValue.value) && entryValue.value.length === 2) { + return entryValue.getFieldValue('1') } } @@ -239,7 +281,7 @@ class Map extends (Collection as any) { * @param scope */ static keySet(fclos: any, argvalues: any[], state: any, node: any, scope: any) { - const _this = fclos.getThis() + const _this = fclos.getThisObj() if (!_this) { return new UndefinedValue() } @@ -248,17 +290,17 @@ class Map extends (Collection as any) { return _this } - const resSet = new UnionValue({ - id: `${_this.id}-keySet`, - sid: `${_this.sid}-keySet`, - qid: `${_this.qid}-keySet`, - parent: _this, - }) - const keyRefSet = _this.getFieldValue('keyRefSet') + const resSet = new UnionValue(undefined, `${_this.sid}-keySet`, `${_this.qid}-keySet`, node) + resSet.parent = _this + let keyRefSet = _this.getFieldValue('keyRefSet') + if (keyRefSet === null || keyRefSet === undefined || keyRefSet.size === 0) { + keyRefSet = new Set() + _this.setFieldValue('keyRefSet', keyRefSet) + } for (const keyRef of keyRefSet) { const entryValue = _this.getFieldValue(keyRef) - if (Array.isArray(entryValue.field) && entryValue.field.length === 2) { - resSet.appendValue(entryValue.field[0]) + if (Array.isArray(entryValue.value) && entryValue.value.length === 2) { + resSet.appendValue(entryValue.getFieldValue('0')) } } @@ -274,7 +316,7 @@ class Map extends (Collection as any) { * @param scope */ static merge(fclos: any, argvalues: any[], state: any, node: any, scope: any) { - const _this = fclos.getThis() + const _this = fclos.getThisObj() if (!_this || !argvalues || argvalues.length < 3) { return new UndefinedValue() } @@ -293,24 +335,30 @@ class Map extends (Collection as any) { * @param scope */ static put(fclos: any, argvalues: any[], state: any, node: any, scope: any) { - const _this = fclos.getThis() + const _this = fclos.getThisObj() if (!_this || !argvalues || argvalues.length < 2) { return new UndefinedValue() } const keyRef = getSymbolRef(argvalues[0]) - const keyRefSet = _this.getFieldValue('keyRefSet') + let keyRefSet = _this.getFieldValue('keyRefSet') + if (keyRefSet === null || keyRefSet === undefined || keyRefSet.size === 0) { + keyRefSet = new Set() + _this.setFieldValue('keyRefSet', keyRefSet) + } if (keyRefSet.has(keyRef)) { const entryValue = _this.getFieldValue(keyRef) - if (Array.isArray(entryValue.field) && entryValue.field.length === 2) { - entryValue.field[1] = argvalues[1] + try { + if (Array.isArray(entryValue.value) && entryValue.value.length === 2) { + entryValue.setFieldValue('1', argvalues[1]) + } + } catch (e) { + // key覆盖失败,忽略 } } else { // 否则新增 - const kvPair = new UnionValue({ - sid: 'key-value-pair', - parent: _this, - }) + const kvPair = new UnionValue(undefined, 'map-key-value-pair', `${_this.qid}.map-kvp.${keyRef}`, node) + kvPair.parent = _this kvPair.appendValue(argvalues[0]) kvPair.appendValue(argvalues[1]) _this.setFieldValue(keyRef, kvPair) @@ -329,22 +377,24 @@ class Map extends (Collection as any) { * @param scope */ static putAll(fclos: any, argvalues: any[], state: any, node: any, scope: any) { - const _this = fclos.getThis() + const _this = fclos.getThisObj() if (!_this || !argvalues || argvalues.length === 0) { - return + return new UndefinedValue() } const newMap = argvalues[0] if (!newMap || !_.isFunction(newMap.getFieldValue) || !_.isFunction(newMap.getMisc)) { - return + _this.setMisc('precise', false) + addElementToBuffer(_this, newMap) + return new UndefinedValue() } const newKeyRefSet = newMap.getFieldValue('keyRefSet') if (newKeyRefSet) { for (const newKeyRef of newKeyRefSet) { const newEntryValue = newMap.getFieldValue(newKeyRef) - if (Array.isArray(newEntryValue.field) && newEntryValue.field.length === 2) { - const newArgValues = [newEntryValue.field[0], newEntryValue.field[1]] + if (Array.isArray(newEntryValue.value) && newEntryValue.value.length === 2) { + const newArgValues = [newEntryValue.getFieldValue('0'), newEntryValue.getFieldValue('1')] Map.put(fclos, newArgValues, state, node, scope) } } @@ -357,6 +407,8 @@ class Map extends (Collection as any) { } addElementToBuffer(_this, newMap) } + + return new UndefinedValue() } /** @@ -368,7 +420,7 @@ class Map extends (Collection as any) { * @param scope */ static putIfAbsent(fclos: any, argvalues: any[], state: any, node: any, scope: any) { - const _this = fclos.getThis() + const _this = fclos.getThisObj() if (!_this || !argvalues || argvalues.length < 2) { return new UndefinedValue() } @@ -390,28 +442,36 @@ class Map extends (Collection as any) { * @param scope */ static remove(fclos: any, argvalues: any[], state: any, node: any, scope: any) { - const _this = fclos.getThis() + const _this = fclos.getThisObj() if (!_this || !argvalues || argvalues.length < 1) { return new UndefinedValue() } const keyRef = getSymbolRef(argvalues[0]) - const keyRefSet = _this.getFieldValue('keyRefSet') + let keyRefSet = _this.getFieldValue('keyRefSet') + if (keyRefSet === null || keyRefSet === undefined || keyRefSet.size === 0) { + keyRefSet = new Set() + _this.setFieldValue('keyRefSet', keyRefSet) + } if (!keyRefSet.has(keyRef)) { - return + return new UndefinedValue() } const entryValue = _this.getFieldValue(keyRef) - if (Array.isArray(entryValue.field) && entryValue.field.length === 2) { - const value = entryValue.field[1] + if (Array.isArray(entryValue.value) && entryValue.value.length === 2) { + const value = entryValue.getFieldValue('1') if (argvalues.length === 1) { keyRefSet.delete(keyRef) - delete _this.field[keyRef] + _this.members.delete(keyRef) return value } - if (argvalues.length === 2 && value?._qid === argvalues[1]._qid) { + if ( + argvalues.length === 2 && + value?.logicalQid === + argvalues[1].logicalQid + ) { keyRefSet.delete(keyRef) - delete _this.field[keyRef] + _this.members.delete(keyRef) return new UndefinedValue() } } @@ -426,26 +486,30 @@ class Map extends (Collection as any) { * @param scope */ static replace(fclos: any, argvalues: any[], state: any, node: any, scope: any) { - const _this = fclos.getThis() + const _this = fclos.getThisObj() if (!_this || !argvalues || argvalues.length < 2) { - return + return new UndefinedValue() } const keyRef = getSymbolRef(argvalues[0]) - const keyRefSet = _this.getFieldValue('keyRefSet') + let keyRefSet = _this.getFieldValue('keyRefSet') + if (keyRefSet === null || keyRefSet === undefined || keyRefSet.size === 0) { + keyRefSet = new Set() + _this.setFieldValue('keyRefSet', keyRefSet) + } if (!keyRefSet.has(keyRef)) { - return + return new UndefinedValue() } const entryValue = _this.getFieldValue(keyRef) - if (Array.isArray(entryValue.field) && entryValue.field.length === 2) { - const value = entryValue.field[1] + if (Array.isArray(entryValue.value) && entryValue.value.length === 2) { + const value = entryValue.getFieldValue('1') if (argvalues.length === 2) { - entryValue.field[1] = argvalues[1] + entryValue.setFieldValue('1', argvalues[1]) return value } - if (argvalues.length === 3 && value?._qid === argvalues[1]._qid) { - entryValue.field[1] = argvalues[2] + if (argvalues.length === 3 && value?.qid === argvalues[1].qid) { + entryValue.setFieldValue('1', argvalues[2]) return new UndefinedValue() } } @@ -482,7 +546,7 @@ class Map extends (Collection as any) { * @param scope */ static values(fclos: any, argvalues: any[], state: any, node: any, scope: any) { - const _this = fclos.getThis() + const _this = fclos.getThisObj() if (!_this) { return new UndefinedValue() } @@ -491,17 +555,17 @@ class Map extends (Collection as any) { return _this } - const resSet = new UnionValue({ - id: `${_this.id}-valueSet`, - sid: `${_this.sid}-valueSet`, - qid: `${_this.qid}-valueSet`, - parent: _this, - }) - const keyRefSet = _this.getFieldValue('keyRefSet') + const resSet = new UnionValue(undefined, `${_this.sid}-valueSet`, `${_this.qid}-valueSet`, node) + resSet.parent = _this + let keyRefSet = _this.getFieldValue('keyRefSet') + if (keyRefSet === null || keyRefSet === undefined || keyRefSet.size === 0) { + keyRefSet = new Set() + _this.setFieldValue('keyRefSet', keyRefSet) + } for (const keyRef of keyRefSet) { const entryValue = _this.getFieldValue(keyRef) - if (Array.isArray(entryValue.field) && entryValue.field.length === 2) { - resSet.appendValue(entryValue.field[1]) + if (Array.isArray(entryValue.value) && entryValue.value.length === 2) { + resSet.appendValue(entryValue.getFieldValue('1')) } } diff --git a/src/engine/analyzer/java/common/builtins/object-builtins.ts b/src/engine/analyzer/java/common/builtins/object-builtins.ts new file mode 100644 index 00000000..29546809 --- /dev/null +++ b/src/engine/analyzer/java/common/builtins/object-builtins.ts @@ -0,0 +1,44 @@ +const UastSpec = require('@ant-yasa/uast-spec') +const { + ValueUtil: { UndefinedValue }, +} = require('../../../../util/value-util') +const { prettyPrint } = require('../../../../../util/ast-util') +const { getValueFromPackageByQid } = require('../../../../util/value-util') + +/** + * java.lang.Object + */ +class _Object { + /** + * getClass + * @param fclos + * @param argvalues + * @param state + * @param node + * @param scope + * @returns {*} + */ + static getClass(fclos: any, argvalues: any[], state: any, node: any, scope: any): any { + const _this = fclos.getThisObj() + if (!_this) { + return new UndefinedValue() + } + if (_this.rtype?.definiteType && !_this.rtype?.vagueType) { + const fullType = prettyPrint(_this.rtype.definiteType) + let classVal + if (fullType.includes('.')) { + classVal = getValueFromPackageByQid((this as any).topScope?.context.packages, fullType) + } else { + classVal = (this as any).getMemberValueNoCreate(scope, fullType) + } + if (!classVal) { + return new UndefinedValue() + } + return (this as any).getMemberValueNoCreate(classVal, UastSpec.identifier('class'), state, 1) + } + + return new UndefinedValue() + } +} + +module.exports = _Object diff --git a/src/engine/analyzer/java/common/builtins/object.ts b/src/engine/analyzer/java/common/builtins/object.ts new file mode 100644 index 00000000..f6152888 --- /dev/null +++ b/src/engine/analyzer/java/common/builtins/object.ts @@ -0,0 +1,44 @@ +const _ = require('lodash') +const { + ValueUtil: { UndefinedValue }, + getValueFromPackageByQid, +} = require('../../../../util/value-util') +const { buildNewValueInstance } = require('../../../../../util/clone-util') +/** + * newInstance + * @param analyzer + * @param packageManager + * @param type + * @returns {*} + */ +function newInstance(analyzer: any, packageManager: any, type: string, node?: any) { + if (!packageManager || !type) { + return undefined + } + + const classVal = getValueFromPackageByQid(packageManager, type) + if (!classVal) { + return new UndefinedValue() + } + const obj = buildNewValueInstance( + analyzer, + classVal, + node || null, + classVal.parent, + (x: any) => { + return false + }, + (v: any) => { + return !v + } + ) + if (obj.members.get('_CTOR_') && _.isFunction(analyzer?.initState) && _.isFunction(analyzer?.processAndCallFuncDef)) { + const state = analyzer.initState(obj) + analyzer.processAndCallFuncDef(obj, obj.members.get('_CTOR_')!.ast?.node, obj.members.get('_CTOR_')!, state) + } + return obj +} + +module.exports = { + newInstance, +} diff --git a/src/engine/analyzer/java/common/builtins/querywrapper-builtins.ts b/src/engine/analyzer/java/common/builtins/querywrapper-builtins.ts new file mode 100644 index 00000000..c6754111 --- /dev/null +++ b/src/engine/analyzer/java/common/builtins/querywrapper-builtins.ts @@ -0,0 +1,34 @@ +const AbstractWrapper = require('./abstractwrapper-builtins') + +/** + * com.baomidou.mybatisplus.core.conditions.query.QueryWrapper + */ +class QueryWrapper extends AbstractWrapper { + /** + * Constructor + * @param _this + * @param argvalues + * @param state + * @param node + * @param scope + * @constructor + */ + static QueryWrapper(_this: any, argvalues: any[], state: any, node: any, scope: any) { + return _this + } + + /** + * lambda + * @param _this + * @param fclos + * @param argvalues + * @param state + * @param node + * @param scope + */ + static lambda(fclos: any, argvalues: any[], state: any, node: any, scope: any) { + return fclos.getThisObj() + } +} + +export = QueryWrapper diff --git a/src/engine/analyzer/java/common/builtins/queue-builtins.ts b/src/engine/analyzer/java/common/builtins/queue-builtins.ts index 8d6579a4..b8c5dc7e 100644 --- a/src/engine/analyzer/java/common/builtins/queue-builtins.ts +++ b/src/engine/analyzer/java/common/builtins/queue-builtins.ts @@ -4,7 +4,7 @@ const { } = require('./buffer') const MemSpaceQueue = require('../../../common/memSpace') const Collection = require('./collection-builtins') -const UndefinedValueQueue = require('../../../common/value/undefine') +import { UndefinedValue } from '../../../common/value/undefine' const memSpaceUtil = new MemSpaceQueue() @@ -37,9 +37,9 @@ class Queue extends Collection { * @param scope */ static add(fclos: any, argvalues: any[], state: any, node: any, scope: any): any { - const _this = fclos.getThis() + const _this = fclos.getThisObj() if (!_this || !argvalues || argvalues.length === 0) { - return new UndefinedValueQueue() + return new UndefinedValue() } if (!_this.getMisc('precise')) { addElementToBufferQueue(_this, argvalues[0]) @@ -56,7 +56,7 @@ class Queue extends Collection { } } - return new UndefinedValueQueue() + return new UndefinedValue() } /** @@ -68,9 +68,9 @@ class Queue extends Collection { * @param scope */ static element(fclos: any, argvalues: any[], state: any, node: any, scope: any): any { - const _this = fclos.getThis() + const _this = fclos.getThisObj() if (!_this) { - return new UndefinedValueQueue() + return new UndefinedValue() } if (!_this.getMisc('precise')) { @@ -113,9 +113,9 @@ class Queue extends Collection { * @param scope */ static poll(fclos: any, argvalues: any[], state: any, node: any, scope: any): any { - const _this = fclos.getThis() + const _this = fclos.getThisObj() if (!_this) { - return new UndefinedValueQueue() + return new UndefinedValue() } if (!_this.getMisc('precise')) { @@ -166,7 +166,7 @@ class Queue extends Collection { * @private */ static _functionNotFoundCallback_(fclos: any, argvalues: any[], state: any, node: any, scope: any): void { - const _this = fclos.getThis() + const _this = fclos.getThisObj() if (!_this) { return } diff --git a/src/engine/analyzer/java/common/builtins/set-builtins.ts b/src/engine/analyzer/java/common/builtins/set-builtins.ts index a4c5281e..cd6646c7 100644 --- a/src/engine/analyzer/java/common/builtins/set-builtins.ts +++ b/src/engine/analyzer/java/common/builtins/set-builtins.ts @@ -4,8 +4,8 @@ const { clearBuffer: clearBufferSet, removeElementFromBuffer: removeElementFromBufferSet, } = require('./buffer') -const { cloneWithDepth: cloneWithDepthJava } = require('../../../../../util/clone-util') -const UndefinedValueJava = require('../../../common/value/undefine') +const { shallowCopyValue } = require('../../../../../util/clone-util') +import { UndefinedValue } from '../../../common/value/undefine' /** * java.util.Set @@ -35,14 +35,14 @@ class Set extends Collection { * @param scope */ static add(fclos: any, argvalues: any, state: any, node: any, scope: any) { - const _this = fclos.getThis() + const _this = fclos.getThisObj() if (!_this || !argvalues || argvalues.length === 0) { - return new UndefinedValueJava() + return new UndefinedValue() } addElementToBufferSet(_this, argvalues[0]) - return new UndefinedValueJava() + return new UndefinedValue() } /** @@ -54,14 +54,14 @@ class Set extends Collection { * @param scope */ static addAll(fclos: any, argvalues: any, state: any, node: any, scope: any) { - const _this = fclos.getThis() + const _this = fclos.getThisObj() if (!_this || !argvalues || argvalues.length === 0) { - return new UndefinedValueJava() + return new UndefinedValue() } addElementToBufferSet(_this, argvalues[0]) - return new UndefinedValueJava() + return new UndefinedValue() } /** @@ -73,7 +73,7 @@ class Set extends Collection { * @param scope */ static clear(fclos: any, argvalues: any, state: any, node: any, scope: any) { - const _this = fclos.getThis() + const _this = fclos.getThisObj() if (!_this) { return } @@ -91,7 +91,7 @@ class Set extends Collection { * @returns {null} */ static contains(fclos: any, argvalues: any, state: any, node: any, scope: any) { - return new UndefinedValueJava() + return new UndefinedValue() } /** @@ -104,7 +104,7 @@ class Set extends Collection { * @returns {null} */ static containsAll(fclos: any, argvalues: any, state: any, node: any, scope: any) { - return new UndefinedValueJava() + return new UndefinedValue() } /** @@ -116,7 +116,7 @@ class Set extends Collection { * @param scope */ static equals(fclos: any, argvalues: any, state: any, node: any, scope: any) { - return new UndefinedValueJava() + return new UndefinedValue() } /** @@ -129,7 +129,7 @@ class Set extends Collection { * @returns {null} */ static hashCode(fclos: any, argvalues: any, state: any, node: any, scope: any) { - return new UndefinedValueJava() + return new UndefinedValue() } /** @@ -142,7 +142,7 @@ class Set extends Collection { * @returns {null} */ static isEmpty(fclos: any, argvalues: any, state: any, node: any, scope: any) { - return new UndefinedValueJava() + return new UndefinedValue() } /** @@ -155,12 +155,12 @@ class Set extends Collection { * @returns {*} */ static iterator(fclos: any, argvalues: any, state: any, node: any, scope: any) { - const _this = fclos.getThis() + const _this = fclos.getThisObj() if (!_this) { - return new UndefinedValueJava() + return new UndefinedValue() } - const newThis = cloneWithDepthJava(_this, 3) + const newThis = shallowCopyValue(_this) newThis._this = newThis return newThis @@ -175,14 +175,14 @@ class Set extends Collection { * @param scope */ static remove(fclos: any, argvalues: any, state: any, node: any, scope: any) { - const _this = fclos.getThis() + const _this = fclos.getThisObj() if (!_this || !argvalues || argvalues.length === 0) { - return new UndefinedValueJava() + return new UndefinedValue() } removeElementFromBufferSet(_this, argvalues[0]) - return new UndefinedValueJava() + return new UndefinedValue() } /** @@ -194,14 +194,14 @@ class Set extends Collection { * @param scope */ static removeAll(fclos: any, argvalues: any, state: any, node: any, scope: any) { - const _this = fclos.getThis() + const _this = fclos.getThisObj() if (!_this || !argvalues || argvalues.length === 0) { - return new UndefinedValueJava() + return new UndefinedValue() } removeElementFromBufferSet(_this, argvalues[0]) - return new UndefinedValueJava() + return new UndefinedValue() } /** @@ -213,7 +213,7 @@ class Set extends Collection { * @param scope */ static retainAll(fclos: any, argvalues: any, state: any, node: any, scope: any) { - return new UndefinedValueJava() + return new UndefinedValue() } /** @@ -226,7 +226,7 @@ class Set extends Collection { * @returns {null} */ static size(fclos: any, argvalues: any, state: any, node: any, scope: any) { - return new UndefinedValueJava() + return new UndefinedValue() } /** @@ -252,7 +252,7 @@ class Set extends Collection { * @returns {*} */ static toArray(fclos: any, argvalues: any, state: any, node: any, scope: any) { - return fclos.getThis() + return fclos.getThisObj() } } diff --git a/src/engine/analyzer/java/common/builtins/stack-builtins.ts b/src/engine/analyzer/java/common/builtins/stack-builtins.ts index 48dad344..db772752 100644 --- a/src/engine/analyzer/java/common/builtins/stack-builtins.ts +++ b/src/engine/analyzer/java/common/builtins/stack-builtins.ts @@ -1,5 +1,5 @@ const List = require('./list-builtins') -const UndefinedValueStack = require('../../../common/value/undefine') +import { UndefinedValue } from '../../../common/value/undefine' /** * java.util.Stack @@ -30,7 +30,7 @@ class Stack extends List { * @param scope */ static empty(fclos: any, argvalues: any[], state: any, node: any, scope: any): any { - return new UndefinedValueStack() + return new UndefinedValue() } /** @@ -73,7 +73,7 @@ class Stack extends List { if (argvalues.length > 0) { return argvalues[0] } - return new UndefinedValueStack() + return new UndefinedValue() } /** @@ -85,7 +85,7 @@ class Stack extends List { * @param scope */ static search(fclos: any, argvalues: any[], state: any, node: any, scope: any): any { - return new UndefinedValueStack() + return new UndefinedValue() } } diff --git a/src/engine/analyzer/java/common/builtins/stream-builtins.ts b/src/engine/analyzer/java/common/builtins/stream-builtins.ts new file mode 100644 index 00000000..a1cc4b91 --- /dev/null +++ b/src/engine/analyzer/java/common/builtins/stream-builtins.ts @@ -0,0 +1,641 @@ +const { newInstance } = require('./object') + +const { getAllElementFromBuffer, addElementToBuffer } = require('./buffer') +const { + ValueUtil: { UndefinedValue }, +} = require('../../../../util/value-util') +/** + * java.util.stream.Stream + */ +class Stream { + /** + * Constructor + * @param _this + * @param argvalues + * @param state + * @param node + * @param scope + * @constructor + */ + static Stream(_this: any, argvalues: any, state: any, node: any, scope: any) { + return _this + } + + /** + * Stream.allMatch + * @param fclos + * @param argvalues + * @param state + * @param node + * @param scope + * @returns {*} + */ + static allMatch(fclos: any, argvalues: any, state: any, node: any, scope: any) { + return new UndefinedValue() + } + + /** + * Stream.anyMatch + * @param fclos + * @param argvalues + * @param state + * @param node + * @param scope + * @returns {*} + */ + static anyMatch(fclos: any, argvalues: any, state: any, node: any, scope: any) { + return new UndefinedValue() + } + + /** + * Stream.builder + * @param fclos + * @param argvalues + * @param state + * @param node + * @param scope + * @returns {*} + */ + static builder(fclos: any, argvalues: any, state: any, node: any, scope: any) { + return new UndefinedValue() + } + + /** + * Stream.collect + * @param fclos + * @param argvalues + * @param state + * @param node + * @param scope + * @returns {*} + */ + static collect(fclos: any, argvalues: any, state: any, node: any, scope: any) { + return fclos.getThisObj() + } + + /** + * Stream.concat + * @param fclos + * @param argvalues + * @param state + * @param node + * @param scope + * @returns {*} + */ + static concat(fclos: any, argvalues: any, state: any, node: any, scope: any) { + if (argvalues.length !== 2) { + return new UndefinedValue() + } + + const obj = newInstance(this, (this as any).topScope?.context.packages, 'java.util.stream.Stream') + if (!obj) { + return new UndefinedValue() + } + if (argvalues[0]?.getMisc('buffer')) { + for (const element of getAllElementFromBuffer(argvalues[0])) { + addElementToBuffer(obj, element) + } + } else { + addElementToBuffer(obj, argvalues[0]) + } + if (argvalues[1]?.getMisc('buffer')) { + for (const element of getAllElementFromBuffer(argvalues[1])) { + addElementToBuffer(obj, element) + } + } else { + addElementToBuffer(obj, argvalues[1]) + } + + return obj + } + + /** + * Stream.count + * @param fclos + * @param argvalues + * @param state + * @param node + * @param scope + * @returns {*} + */ + static count(fclos: any, argvalues: any, state: any, node: any, scope: any) { + return new UndefinedValue() + } + + /** + * Stream.distinct + * @param fclos + * @param argvalues + * @param state + * @param node + * @param scope + * @returns {*} + */ + static distinct(fclos: any, argvalues: any, state: any, node: any, scope: any) { + return fclos.getThisObj() + } + + /** + * Stream.dropWhile + * @param fclos + * @param argvalues + * @param state + * @param node + * @param scope + * @returns {*} + */ + static dropWhile(fclos: any, argvalues: any, state: any, node: any, scope: any) { + return fclos.getThisObj() + } + + /** + * Stream.empty + * @param fclos + * @param argvalues + * @param state + * @param node + * @param scope + * @returns {*} + */ + static empty(fclos: any, argvalues: any, state: any, node: any, scope: any) { + return new UndefinedValue() + } + + /** + * Stream.filter + * @param fclos + * @param argvalues + * @param state + * @param node + * @param scope + * @returns {*} + */ + static filter(fclos: any, argvalues: any, state: any, node: any, scope: any) { + Stream.forEach.bind(this)(fclos, argvalues, state, node, scope) + return fclos.getThisObj() + } + + /** + * Stream.findAny + * @param fclos + * @param argvalues + * @param state + * @param node + * @param scope + * @returns {*} + */ + static findAny(fclos: any, argvalues: any, state: any, node: any, scope: any) { + return fclos.getThisObj() + } + + /** + * Stream.findFirst + * @param fclos + * @param argvalues + * @param state + * @param node + * @param scope + * @returns {*} + */ + static findFirst(fclos: any, argvalues: any, state: any, node: any, scope: any) { + return fclos.getThisObj() + } + + /** + * Stream.flatMap + * @param fclos + * @param argvalues + * @param state + * @param node + * @param scope + * @returns {*} + */ + static flatMap(fclos: any, argvalues: any, state: any, node: any, scope: any) { + Stream.forEach.bind(this)(fclos, argvalues, state, node, scope) + return fclos.getThisObj() + } + + /** + * Stream.flatMapToDouble + * @param fclos + * @param argvalues + * @param state + * @param node + * @param scope + * @returns {*} + */ + static flatMapToDouble(fclos: any, argvalues: any, state: any, node: any, scope: any) { + return Stream.flatMap.bind(this)(fclos, argvalues, state, node, scope) + } + + /** + * Stream.flatMapToInt + * @param fclos + * @param argvalues + * @param state + * @param node + * @param scope + * @returns {*} + */ + static flatMapToInt(fclos: any, argvalues: any, state: any, node: any, scope: any) { + return Stream.flatMap.bind(this)(fclos, argvalues, state, node, scope) + } + + /** + * Stream.flatMapToLong + * @param fclos + * @param argvalues + * @param state + * @param node + * @param scope + * @returns {*} + */ + static flatMapToLong(fclos: any, argvalues: any, state: any, node: any, scope: any) { + return Stream.flatMap.bind(this)(fclos, argvalues, state, node, scope) + } + + /** + * Stream.forEach + * @param fclos + * @param argvalues + * @param state + * @param node + * @param scope + * @returns {*} + */ + static forEach(fclos: any, argvalues: any, state: any, node: any, scope: any) { + const _this = fclos.getThisObj() + if (!_this || argvalues.length === 0 || argvalues[0].vtype !== 'fclos') { + return new UndefinedValue() + } + + if (_this.getMisc('buffer')) { + const elements = getAllElementFromBuffer(_this) + for (const element of elements) { + ;(this as any).executeCall(node, argvalues[0], state, scope, { callArgs: (this as any).buildCallArgs(node, [element], argvalues[0]) }) + } + } else { + ;(this as any).executeCall(node, argvalues[0], state, scope, { callArgs: (this as any).buildCallArgs(node, [_this], argvalues[0]) }) + } + + return new UndefinedValue() + } + + /** + * Stream.forEachOrdered + * @param _this + * @param argvalues + * @param state + * @param node + * @param scope + * @returns {*} + */ + static forEachOrdered(_this: any, argvalues: any, state: any, node: any, scope: any) { + return Stream.forEach.bind(this)(_this, argvalues, state, node, scope) + } + + /** + * Stream.gather + * @param fclos + * @param argvalues + * @param state + * @param node + * @param scope + * @returns {*} + */ + static gather(fclos: any, argvalues: any, state: any, node: any, scope: any) { + return fclos.getThisObj() + } + + /** + * Stream.generate + * @param fclos + * @param argvalues + * @param state + * @param node + * @param scope + * @returns {*} + */ + static generate(fclos: any, argvalues: any, state: any, node: any, scope: any) { + return fclos.getThisObj() + } + + /** + * Stream.iterate + * @param fclos + * @param argvalues + * @param state + * @param node + * @param scope + * @returns {*} + */ + static iterate(fclos: any, argvalues: any, state: any, node: any, scope: any) { + return new UndefinedValue() + } + + /** + * Stream.limit + * @param fclos + * @param argvalues + * @param state + * @param node + * @param scope + * @returns {*} + */ + static limit(fclos: any, argvalues: any, state: any, node: any, scope: any) { + return fclos.getThisObj() + } + + /** + * Stream.map + * @param fclos + * @param argvalues + * @param state + * @param node + * @param scope + * @returns {*} + */ + static map(fclos: any, argvalues: any, state: any, node: any, scope: any) { + const _this = fclos.getThisObj() + if (!_this || argvalues.length === 0 || argvalues[0].vtype !== 'fclos') { + return _this || new UndefinedValue() + } + + // 收集 mapper 返回值到新 buffer,保持链式调用 + const result = fclos.getThisObj() + if (_this.getMisc('buffer')) { + const elements = getAllElementFromBuffer(_this) + const newBuffer: any[] = [] + for (const element of elements) { + const mapped = (this as any).executeCall(node, argvalues[0], state, scope, { callArgs: (this as any).buildCallArgs(node, [element], argvalues[0]) }) + if (mapped) { + newBuffer.push(mapped) + } + } + result.setMisc('buffer', newBuffer) + } else { + const mapped = (this as any).executeCall(node, argvalues[0], state, scope, { callArgs: (this as any).buildCallArgs(node, [_this], argvalues[0]) }) + if (mapped) { + result.setMisc('buffer', [mapped]) + } + } + + return result + } + + /** + * Stream.mapMulti + * @param fclos + * @param argvalues + * @param state + * @param node + * @param scope + * @returns {*} + */ + static mapMulti(fclos: any, argvalues: any, state: any, node: any, scope: any) { + return Stream.flatMap.bind(this)(fclos, argvalues, state, node, scope) + } + + /** + * Stream.mapMultiToDouble + * @param fclos + * @param argvalues + * @param state + * @param node + * @param scope + * @returns {*} + */ + static mapMultiToDouble(fclos: any, argvalues: any, state: any, node: any, scope: any) { + return Stream.flatMap.bind(this)(fclos, argvalues, state, node, scope) + } + + /** + * Stream.mapMultiToInt + * @param fclos + * @param argvalues + * @param state + * @param node + * @param scope + * @returns {*} + */ + static mapMultiToInt(fclos: any, argvalues: any, state: any, node: any, scope: any) { + return Stream.flatMap.bind(this)(fclos, argvalues, state, node, scope) + } + + /** + * Stream.mapMultiToLong + * @param fclos + * @param argvalues + * @param state + * @param node + * @param scope + * @returns {*} + */ + static mapMultiToLong(fclos: any, argvalues: any, state: any, node: any, scope: any) { + return Stream.flatMap.bind(this)(fclos, argvalues, state, node, scope) + } + + /** + * Stream.mapToDouble + * @param fclos + * @param argvalues + * @param state + * @param node + * @param scope + * @returns {*} + */ + static mapToDouble(fclos: any, argvalues: any, state: any, node: any, scope: any) { + return Stream.flatMap.bind(this)(fclos, argvalues, state, node, scope) + } + + /** + * Stream.mapToInt + * @param fclos + * @param argvalues + * @param state + * @param node + * @param scope + * @returns {*} + */ + static mapToInt(fclos: any, argvalues: any, state: any, node: any, scope: any) { + return Stream.flatMap.bind(this)(fclos, argvalues, state, node, scope) + } + + /** + * Stream.mapToLong + * @param fclos + * @param argvalues + * @param state + * @param node + * @param scope + * @returns {*} + */ + static mapToLong(fclos: any, argvalues: any, state: any, node: any, scope: any) { + return Stream.flatMap.bind(this)(fclos, argvalues, state, node, scope) + } + + /** + * Stream.max + * @param fclos + * @param argvalues + * @param state + * @param node + * @param scope + * @returns {*} + */ + static max(fclos: any, argvalues: any, state: any, node: any, scope: any) { + return fclos.getThisObj() + } + + /** + * Stream.min + * @param fclos + * @param argvalues + * @param state + * @param node + * @param scope + * @returns {*} + */ + static min(fclos: any, argvalues: any, state: any, node: any, scope: any) { + return fclos.getThisObj() + } + + /** + * Stream.noneMatch + * @param fclos + * @param argvalues + * @param state + * @param node + * @param scope + * @returns {*} + */ + static noneMatch(fclos: any, argvalues: any, state: any, node: any, scope: any) { + return new UndefinedValue() + } + + /** + * Stream.of + * @param fclos + * @param argvalues + * @param state + * @param node + * @param scope + * @returns {*} + */ + static of(fclos: any, argvalues: any, state: any, node: any, scope: any) { + const obj = newInstance(this, (this as any).topScope?.context.packages, 'java.util.stream.Stream') + if (!obj) { + return new UndefinedValue() + } + for (const element of argvalues) { + addElementToBuffer(obj, element) + } + return obj + } + + /** + * Stream.ofNullable + * @param fclos + * @param argvalues + * @param state + * @param node + * @param scope + * @returns {*} + */ + static ofNullable(fclos: any, argvalues: any, state: any, node: any, scope: any) { + return Stream.of.bind(this)(fclos, argvalues, state, node, scope) + } + + /** + * Stream.peek + * @param fclos + * @param argvalues + * @param state + * @param node + * @param scope + * @returns {*} + */ + static peek(fclos: any, argvalues: any, state: any, node: any, scope: any) { + return fclos.getThisObj() + } + + /** + * Stream.reduce + * @param fclos + * @param argvalues + * @param state + * @param node + * @param scope + * @returns {*} + */ + static reduce(fclos: any, argvalues: any, state: any, node: any, scope: any) { + return fclos.getThisObj() + } + + /** + * Stream.skip + * @param fclos + * @param argvalues + * @param state + * @param node + * @param scope + * @returns {*} + */ + static skip(fclos: any, argvalues: any, state: any, node: any, scope: any) { + return fclos.getThisObj() + } + + /** + * Stream.sorted + * @param fclos + * @param argvalues + * @param state + * @param node + * @param scope + * @returns {*} + */ + static sorted(fclos: any, argvalues: any, state: any, node: any, scope: any) { + return fclos.getThisObj() + } + + /** + * Stream.takeWhile + * @param fclos + * @param argvalues + * @param state + * @param node + * @param scope + * @returns {*} + */ + static takeWhile(fclos: any, argvalues: any, state: any, node: any, scope: any) { + return fclos.getThisObj() + } + + /** + * Stream.toArray + * @param fclos + * @param argvalues + * @param state + * @param node + * @param scope + * @returns {*} + */ + static toArray(fclos: any, argvalues: any, state: any, node: any, scope: any) { + return fclos.getThisObj() + } + + /** + * Stream.toList + * @param fclos + * @param argvalues + * @param state + * @param node + * @param scope + * @returns {*} + */ + static toList(fclos: any, argvalues: any, state: any, node: any, scope: any) { + return fclos.getThisObj() + } +} + +module.exports = Stream diff --git a/src/engine/analyzer/java/common/builtins/stringbuffer-builtins.ts b/src/engine/analyzer/java/common/builtins/stringbuffer-builtins.ts index b6768f2c..4ecb7dbb 100644 --- a/src/engine/analyzer/java/common/builtins/stringbuffer-builtins.ts +++ b/src/engine/analyzer/java/common/builtins/stringbuffer-builtins.ts @@ -26,7 +26,7 @@ class StringBuffer { * @param scope */ static append(fclos: any, argvalues: any[], state: any, node: any, scope: any): any { - const _this = fclos.getThis() + const _this = fclos.getThisObj() if (!_this || !argvalues || argvalues.length === 0) { return } diff --git a/src/engine/analyzer/java/common/builtins/stringbuilder-builtins.ts b/src/engine/analyzer/java/common/builtins/stringbuilder-builtins.ts index b3240aa1..9fd29a2d 100644 --- a/src/engine/analyzer/java/common/builtins/stringbuilder-builtins.ts +++ b/src/engine/analyzer/java/common/builtins/stringbuilder-builtins.ts @@ -26,7 +26,7 @@ class StringBuilder { * @param scope */ static append(fclos: any, argvalues: any[], state: any, node: any, scope: any): any { - const _this = fclos.getThis() + const _this = fclos.getThisObj() if (!_this || !argvalues || argvalues.length === 0) { return _this } diff --git a/src/engine/analyzer/java/common/builtins/timer-builtins.ts b/src/engine/analyzer/java/common/builtins/timer-builtins.ts index 84870860..63b24ad6 100644 --- a/src/engine/analyzer/java/common/builtins/timer-builtins.ts +++ b/src/engine/analyzer/java/common/builtins/timer-builtins.ts @@ -17,8 +17,9 @@ class Timer { return } const maybeFn = (this as any).executeCall - if (argvalues[0].field?.run && _.isFunction(maybeFn)) { - ;(this as any).executeCall(node, argvalues[0].field?.run, [], state, scope) + const runMethod = argvalues[0].members?.get('run') + if (runMethod && _.isFunction(maybeFn)) { + ;(this as any).executeCall(node, runMethod, state, scope, { callArgs: (this as any).buildCallArgs(node, [], runMethod) }) } } diff --git a/src/engine/analyzer/java/common/entrypoint-collector/java-default-entrypoint.ts b/src/engine/analyzer/java/common/entrypoint-collector/java-default-entrypoint.ts index 7c069575..1e70cc18 100644 --- a/src/engine/analyzer/java/common/entrypoint-collector/java-default-entrypoint.ts +++ b/src/engine/analyzer/java/common/entrypoint-collector/java-default-entrypoint.ts @@ -10,37 +10,47 @@ export {} */ function getJavaMainEntryPointAndSource(packageManager: any) { const TaintSource: any[] = [] - let entryPoints = astUtilJava.satisfy( - packageManager, - (n: any) => n.ast?.id?.name === 'main' && n.vtype === 'fclos', - (node: any, prop: any) => prop === 'field', - null, - true - ) - if (!entryPoints) { - entryPoints = [] - } else if (!Array.isArray(entryPoints)) { - entryPoints = [entryPoints] + + const entryPoints = [] + let list = [] + list.push(packageManager) + while (list.length > 0) { + const newList = [] + for (const item of list) { + if (item.vtype === 'fclos') { + if (item.ast?.node?.type === 'FunctionDefinition' && item.ast?.node?.id?.name === 'main') { + entryPoints.push(item) + } + } else if (item.vtype === 'class' || item.vtype === 'package') { + if (item.members?.size > 0) { + for (const key of item.members.keys()) { + newList.push(item.members.get(key)) + } + } + } + } + list = newList } + for (const entrypoint of entryPoints) { - if (entrypoint.vtype === 'fclos' && entrypoint.ast?.loc?.sourcefile) { + if (entrypoint.vtype === 'fclos' && entrypoint.ast?.node?.loc?.sourcefile) { const mainDirPrefix = configJava.maindirPrefix entrypoint.filePath = mainDirPrefix - ? entrypoint.ast?.loc.sourcefile.substring( - entrypoint.ast?.loc.sourcefile.indexOf(mainDirPrefix) + mainDirPrefix.length + ? entrypoint.ast?.node?.loc.sourcefile.substring( + entrypoint.ast?.node?.loc.sourcefile.indexOf(mainDirPrefix) + mainDirPrefix.length ) - : entrypoint.ast?.loc.sourcefile + : entrypoint.ast?.node?.loc.sourcefile entrypoint.functionName = entrypoint.sid entrypoint.attribute = 'HTTP' } - if (entryPointAndSourceAtSameTimeJava && entrypoint.ast?.parameters && entrypoint.ast?.id.type === 'Identifier') { - for (const param of entrypoint.ast.parameters) { + if (entryPointAndSourceAtSameTimeJava && entrypoint.ast?.node?.parameters && entrypoint.ast?.node?.id.type === 'Identifier') { + for (const param of entrypoint.ast.node.parameters) { if (param.type === 'VariableDeclaration' && param.id?.type === 'Identifier') { TaintSource.push({ introPoint: 4, path: param.id.name, - scopeFunc: entrypoint.ast.id.name, - scopeFile: entrypoint.ast.loc?.sourcefile, + scopeFunc: entrypoint.ast.node.id.name, + scopeFile: entrypoint.ast.node.loc?.sourcefile, locStart: param.id.loc?.start.line, locEnd: param.id.loc?.end.line, locColumnStart: param.id.loc?.start.column, diff --git a/src/engine/analyzer/java/common/java-analyzer.ts b/src/engine/analyzer/java/common/java-analyzer.ts index afdb69f6..8a62dd0a 100644 --- a/src/engine/analyzer/java/common/java-analyzer.ts +++ b/src/engine/analyzer/java/common/java-analyzer.ts @@ -1,34 +1,71 @@ /* eslint-disable @typescript-eslint/naming-convention, @typescript-eslint/no-unused-vars, @typescript-eslint/no-use-before-define */ import JavaTypeRelatedInfoResolver from '../../../../resolver/java/java-type-related-info-resolver' +import type { Invocation } from '../../../../resolver/common/value/invocation' +import type { ClassHierarchy } from '../../../../resolver/common/value/class-hierarchy' +import { InnerFuncDefVisitor } from '../../common/ast-visitor' +import type { + Scope, + State, + Value, + SymbolValue as SymbolValueType, + VoidValue as VoidValueType, + BinaryExprValue, + UnaryExprValue, +} from '../../../../types/analyzer' +import type { + CompileUnit, + VariableDeclaration, + Identifier, + MemberAccess, + ClassDefinition, + AssignmentExpression, + BinaryExpression, + CallExpression, + NewExpression, + UnaryExpression, + TryStatement, + RangeStatement, + FunctionDefinition, +} from '../../../../types/uast' +import type { PrimitiveValue as PrimitiveValueType } from '../../../../types/value' const _ = require('lodash') const fs = require('fs') const path = require('path') -const flatted = require('flatted') const UastSpec = require('@ant-yasa/uast-spec') +const QidUnifyUtil = require('../../../../util/qid-unify-util') const FileUtil = require('../../../../util/file-util') -const logger = require('../../../../util/logger')(__filename) -const Scope = require('../../common/scope') -const Parsing = require('../../../parser/parsing') +const logger: import('../../../../util/logger').Logger = require('../../../../util/logger')(__filename) +const ScopeClass = require('../../common/scope') +const Parser = require('../../../parser/parser') const JavaInitializer = require('./java-initializer') const BasicRuleHandler = require('../../../../checker/common/rules-basic-handler') const { - ValueUtil: { FunctionValue, Scoped, PackageValue, PrimitiveValue }, + ValueUtil: { FunctionValue, Scoped, PackageValue, PrimitiveValue, SymbolValue, VoidValue }, } = require('../../../util/value-util') -const { Analyzer } = require('../../common') +const Analyzer: typeof import('../../common/analyzer').Analyzer = require('../../common/analyzer') const CheckerManager = require('../../common/checker-manager') const CurrentEntryPoint = require('../../common/current-entrypoint') const Constant = require('../../../../util/constant') const Config = require('../../../../config') const { handleException } = require('../../common/exception-handler') -const UndefinedValue = require('../../common/value/undefine') -const { md5 } = require('../../../../util/hash-util') -const { yasaLog } = require('../../../../util/format-util') +const { + ValueUtil: { UndefinedValue }, +} = require('../../../util/value-util') +const FullCallGraphFileEntryPoint = require('../../../../checker/common/full-callgraph-file-entrypoint') +const AstUtil = require('../../../../util/ast-util') +const SourceLine = require('../../common/source-line') +const { checkInvocationMatchSink } = require('../../../../checker/taint/common-kit/sink-util') +const { filterDataFromScope } = require('../../../../util/common-util') +import type { CallInfo } from '../../common/call-args' +const { getLegacyArgValues } = require('../../common/call-args') /** * Java 代码分析器 */ -class JavaAnalyzer extends (Analyzer as any) { +class JavaAnalyzer extends Analyzer { + private unprocessedFileScopes?: Set + /** * 构造函数 * @param options - 分析器选项 @@ -44,6 +81,45 @@ class JavaAnalyzer extends (Analyzer as any) { super(checkerManager, options) this.classMap = new Map() this.typeResolver = new JavaTypeRelatedInfoResolver() + this.entryPointSymValArray = [] + this.globalState = {} + this.enableLibArgToThis = true + this.enablePruneDuringInterpret = true + this.pruneInfoMap = { + aggressiveMode: false, + sinkArray: [], + funcCallSourceSinkSanitizerArray: [], + otherSourceArray: [], + otherSanitizerArray: [], + matchSinkCacheMap: new Map(), + matchSinkNoRecurseCacheMap: new Map(), + matchFuncCallSourceSinkSanitizerCacheMap: new Map(), + dynamicClassArray: [ + 'Class', + 'Thread', + 'Runnable', + 'java.util.Timer', + 'java.util.TimerTask', + 'org.springframework.util.ReflectionUtils', + ], + dynamicPackageArray: [ + 'java.util.concurrent', + 'java.lang.reflect', + 'java.util.function', + 'org.springframework.core.task', + 'org.springframework.scheduling', + 'org.springframework.util.function', + 'org.springframework.retry', + 'org.springframework.web.reactive.function', + 'org.springframework.web.servlet.function', + 'org.springframework.integration.dsl', + 'org.springframework.cloud.function', + 'org.springframework.kafka.listener', + 'reactor.core', + ], + } + this.timeoutEntryPoints = [] + this.extraClassHierarchyByNameMap = new Map() } /** @@ -52,25 +128,21 @@ class JavaAnalyzer extends (Analyzer as any) { * @param fileName - 文件名 */ preProcess4SingleFile(source: any, fileName: any) { - // init global scope JavaInitializer.initGlobalScope(this.topScope) - - // time-out control - ;(this as any).thisIterationTime = 0 - ;(this as any).prevIterationTime = new Date().getTime() + JavaInitializer.initPackageScope(this.topScope.context.packages) this.preloadFileToPackage(source, fileName) - for (const unprocessedFileScope of (this as any).unprocessedFileScopes) { + for (const unprocessedFileScope of this.unprocessedFileScopes!) { if (unprocessedFileScope.isProcessed) continue const state = this.initState(unprocessedFileScope) - this.processInstruction(unprocessedFileScope, unprocessedFileScope.ast, state) + this.processInstruction(unprocessedFileScope, unprocessedFileScope.ast?.node, state) } - ;(this as any).unprocessedFileScopes.clear() - delete (this as any).unprocessedFileScopes + this.unprocessedFileScopes?.clear() + this.unprocessedFileScopes = undefined - JavaInitializer.initPackageScope(this.topScope.packageManager) + this.assembleClassMap(this.topScope.context.packages) - this.assembleClassMap(this.topScope.packageManager) + JavaInitializer.addClassProto(this.classMap, this.topScope.context.packages, this) } /** @@ -80,179 +152,47 @@ class JavaAnalyzer extends (Analyzer as any) { */ // eslint-disable-next-line complexity async scanPackages(dir: any) { - const packageFiles = FileUtil.loadAllFileTextGlobby(['**/*.java', '!target/**', '!**/src/test/**'], dir) - if (packageFiles.length === 0) { - handleException( - null, - 'find no target compileUnit of the project : no java file found in source path', - 'find no target compileUnit of the project : no java file found in source path' - ) - process.exit(1) - } - ;(this as any).unprocessedFileScopes = new Set() + this.unprocessedFileScopes = new Set() const PARSE_CODE_STAGE = 'preProcess.parseCode' const PRELOAD_STAGE = 'preProcess.preload' - this.performanceTracker.start(PARSE_CODE_STAGE) - this.performanceTracker.start(PRELOAD_STAGE) - // 根据配置决定是否使用缓存优化 - // incremental: true/false/force - // - false: 完全不生成和读取 json(禁用缓存,默认值) - // - true: 正常流程(读取缓存,如果变化则重新解析并更新) - // - force: 无论有无变化,都重新生成然后存储 json(强制重新解析但保存缓存) - const incremental = Config.incremental !== false && Config.incremental !== 'false' // 需要显式配置为 true 或 force 才启用 - const forceReparse = Config.incremental === 'force' // 强制重新解析 - const disableCache = Config.incremental === false || Config.incremental === 'false' // 禁用缓存 - - // 加载缓存 list 文件(只有在启用缓存且不是 force 模式时才加载) - const cacheList = !disableCache && !forceReparse ? await this.loadCacheList() : new Map() - - if (disableCache) { - // 禁用缓存模式:完全不生成和读取 json - for (const packageFile of packageFiles) { - this.preloadFileToPackage(packageFile.content, packageFile.file, null) - } - } else if (forceReparse) { - // force 模式:无论有无变化,都重新生成然后存储 json - const cacheEntries: Array<{ path: string; jsonFile: string; crc: string; time?: string }> = [] - const savePromises: Array< - Promise<{ relativePath: string; jsonFile: string; crc: string; time?: string } | null> - > = [] - - for (const packageFile of packageFiles) { - // 强制重新解析,但保存缓存 - const savePromise = this.preloadFileToPackageAsync(packageFile.content, packageFile.file) - savePromises.push(savePromise) - } + // 开始解析阶段:解析源代码为 AST + this.performanceTracker.start(PARSE_CODE_STAGE) + const astMap = await Parser.parseProject(dir, this.options, this.sourceCodeCache) + this.performanceTracker.end(PARSE_CODE_STAGE) - // 等待所有保存完成后再更新 list 文件 - if (savePromises.length > 0) { - Promise.all(savePromises) - .then((savedInfos) => { - for (const info of savedInfos) { - if (info) { - cacheEntries.push({ - path: info.relativePath, - jsonFile: info.jsonFile, - crc: info.crc, - time: info.time, - }) - } - } - if (cacheEntries.length > 0) { - return this.saveCacheList(cacheEntries) - } - }) - .catch((err) => { - logger.warn(`Failed to save cache list: ${err.message}`) - }) - } - } else if (incremental) { - // 并发加载所有文件的缓存(优化模式) - const cacheLoadStart = Date.now() - const cacheLoadPromises = packageFiles.map((packageFile: any) => - this.loadAstFromCache(packageFile.content, packageFile.file, cacheList) + // 防御性检查:确保 astMap 不为 null 或 undefined + if (!astMap) { + handleException( + null, + 'JavaAnalyzer.scanPackages: parseProject returned null or undefined', + 'JavaAnalyzer.scanPackages: parseProject returned null or undefined' ) - const cacheResults = await Promise.all(cacheLoadPromises) - const cacheLoadTime = Date.now() - cacheLoadStart - - // 统计从缓存加载的文件数量 - const cachedCount = cacheResults.filter((r) => r.loadedFromCache).length - const totalCount = packageFiles.length - - // 记录缓存加载时间作为 parseCode 的子步骤 - if (cacheLoadTime > 0) { - this.performanceTracker.record('preProcess.parseCode.loadCache', cacheLoadTime) - } - - // 处理所有文件(使用缓存的 AST 或重新解析) - // 同时收集需要保存的缓存信息 - const cacheEntries: Array<{ path: string; jsonFile: string; crc: string; time?: string }> = [] - const savePromises: Array< - Promise<{ relativePath: string; jsonFile: string; crc: string; time?: string } | null> - > = [] - - for (let i = 0; i < packageFiles.length; i++) { - const packageFile = packageFiles[i] - const cacheResult = cacheResults[i] - - if (!cacheResult.loadedFromCache || cacheResult.needsUpdate) { - // 需要重新解析(包括 CRC 变化的情况),解析后保存缓存 - const savePromise = this.preloadFileToPackageAsync(packageFile.content, packageFile.file) - savePromises.push(savePromise) - } else { - // 从缓存加载,直接使用 - this.preloadFileToPackage(packageFile.content, packageFile.file, cacheResult.ast) - - // 保留 list 中的记录(即使从缓存加载,也保留原有记录) - const relativePath = this.getRelativePath(packageFile.file) - const existingInfo = cacheList.get(relativePath) - if (existingInfo) { - cacheEntries.push({ - path: relativePath, - jsonFile: existingInfo.jsonFile, - crc: existingInfo.crc, - time: existingInfo.time, - }) - } - } - } - - // 等待所有缓存保存完成(异步等待,不阻塞主流程) - Promise.all(savePromises) - .then((savedInfos) => { - // 收集所有保存成功的缓存信息(包括新保存的和需要更新的) - for (const info of savedInfos) { - if (info) { - // 查找是否已存在相同路径的记录,如果存在则更新 - const existingIndex = cacheEntries.findIndex((e) => e.path === info.relativePath) - if (existingIndex >= 0) { - // 更新现有记录(CRC 变化的情况) - cacheEntries[existingIndex] = { - path: info.relativePath, - jsonFile: info.jsonFile, - crc: info.crc, - time: info.time, - } - } else { - // 添加新记录 - cacheEntries.push({ - path: info.relativePath, - jsonFile: info.jsonFile, - crc: info.crc, - time: info.time, - }) - } - } - } - // 保存更新后的 list 文件 - if (cacheEntries.length > 0) { - return this.saveCacheList(cacheEntries) - } - }) - .catch((err) => { - logger.warn(`Failed to save cache list: ${err.message}`) - }) + return + } - // 输出缓存加载统计(不输出每个文件的详细信息) - if (cachedCount > 0) { - yasaLog(`Loaded ${cachedCount}/${totalCount} AST files from cache (${cacheLoadTime}ms)`, 'preProcess') + // 开始预加载阶段:预构建包作用域 + this.performanceTracker.start(PRELOAD_STAGE) + for (const filename in astMap) { + const ast = astMap[filename] + if (ast) { + // sourceCodeCache 已在 parseProject 中自动填充,不需要重新读取 + const code = this.sourceCodeCache.get(filename) + this.preloadFileToPackage(code ? code.join('\n') : '', filename, ast) } } - this.performanceTracker.end(PRELOAD_STAGE) - this.performanceTracker.end(PARSE_CODE_STAGE) // 开始 ProcessModule 阶段:处理所有文件作用域(分析 AST) const PROCESS_MODULE_STAGE = 'preProcess.processModule' this.performanceTracker.start(PROCESS_MODULE_STAGE) - for (const unprocessedFileScope of (this as any).unprocessedFileScopes) { + for (const unprocessedFileScope of this.unprocessedFileScopes!) { if (unprocessedFileScope.isProcessed) continue // unprocessedFileScope.isProcessed = true; const state = this.initState(unprocessedFileScope) - this.processInstruction(unprocessedFileScope, unprocessedFileScope.ast, state) + this.processInstruction(unprocessedFileScope, unprocessedFileScope.ast?.node, state) } - ;(this as any).unprocessedFileScopes.clear() - delete (this as any).unprocessedFileScopes + this.unprocessedFileScopes?.clear() + this.unprocessedFileScopes = undefined this.performanceTracker.end('preProcess.processModule') // 输出时间统计(performanceTracker 已自动输出各阶段耗时) @@ -272,350 +212,47 @@ class JavaAnalyzer extends (Analyzer as any) { * @param methods - 方法集合 */ _preloadBuiltinToPackage(packageName: string, className: string, methods: any) { - const packageScope = this.packageManager.getSubPackage(packageName, true) - const classScope = Scope.createSubScope(className, packageScope, 'class') - if (!packageScope.exports) { - packageScope.exports = Scoped({ + const packageScope = this.topScope.context.packages.getSubPackage(packageName, true) + const qualifiedName = ScopeClass.joinQualifiedName(packageScope.qid, className) + const classScope = ScopeClass.createSubScope(className, packageScope, 'class', qualifiedName) + if (!packageScope.scope.exports) { + packageScope.scope.exports = new Scoped(packageScope.qid, { sid: 'exports', - id: 'exports', parent: packageScope, }) } - packageScope.exports.value[className] = classScope - const qualifiedName = Scope.joinQualifiedName(packageScope.qid, className) - classScope.sort = qualifiedName - classScope.qid = qualifiedName + packageScope.scope.exports.value[className] = classScope for (const prop in methods) { const method = methods[prop] const targetQid = `${classScope.qid}.${prop}` - classScope.value[prop] = FunctionValue({ + classScope.value[prop] = new FunctionValue('', { sid: prop, qid: targetQid, parent: classScope, - execute: method.bind(this), + runtime: { execute: method.bind(this) }, _this: classScope, }) - ;(this as any).funcSymbolTable[targetQid] = classScope.value[prop] - } - } - - /** - * 获取缓存目录路径 - * @returns {string} 缓存目录的绝对路径 - */ - getCacheDir(): string { - let outputDir = Config.intermediateDir - if (!outputDir) { - outputDir = Config.reportDir || './report/' - if (!path.isAbsolute(outputDir)) { - outputDir = path.resolve(process.cwd(), outputDir) - } - outputDir = path.join(outputDir, 'ast-output') - } else if (!path.isAbsolute(outputDir)) { - outputDir = path.resolve(process.cwd(), outputDir) - } - return outputDir - } - - /** - * 获取相对于 sourcePath 的路径 - * @param filename - 文件的绝对路径 - * @returns {string} 相对路径 - */ - getRelativePath(filename: string): string { - const sourceDir = Config.maindir || '' - if (!sourceDir || !filename) { - return filename - } - // 标准化路径,确保使用统一的分隔符 - const normalizedSource = path.normalize(sourceDir).replace(/\\/g, '/') - const normalizedFile = path.normalize(filename).replace(/\\/g, '/') - if (normalizedFile.startsWith(normalizedSource)) { - let relative = normalizedFile.substring(normalizedSource.length) - // 移除开头的斜杠 - if (relative.startsWith('/')) { - relative = relative.substring(1) - } - return relative + this.funcSymbolTable[QidUnifyUtil.qidUnifyByRemoveAngleAndPrefix(targetQid)] = classScope.value[prop] } - // 如果不在 sourceDir 下,返回原路径 - return filename - } - - /** - * 从缓存 list 文件加载所有缓存信息 - * @returns {Promise>} 相对路径到缓存信息的映射 - */ - async loadCacheList(): Promise> { - return new Promise((resolve) => { - const cacheDir = this.getCacheDir() - const listPath = path.join(cacheDir, 'ast-cache-list.json') - - fs.readFile(listPath, 'utf8', (err: NodeJS.ErrnoException | null, content: string) => { - if (err) { - // list 文件不存在,返回空映射 - resolve(new Map()) - return - } - - try { - const listData = JSON.parse(content) - const cacheMap = new Map() - - if (Array.isArray(listData)) { - for (const item of listData) { - if (item.path && item.jsonFile && item.crc) { - cacheMap.set(item.path, { - jsonFile: item.jsonFile, - crc: item.crc, - time: item.time, - }) - } - } - } - - resolve(cacheMap) - } catch (error) { - logger.warn(`Failed to parse cache list: ${(error as Error).message}`) - resolve(new Map()) - } - }) - }) - } - - /** - * 保存缓存 list 文件 - * @param cacheList - 缓存列表数据(包含 path, jsonFile, crc, time) - */ - async saveCacheList(cacheList: Array<{ path: string; jsonFile: string; crc: string; time?: string }>): Promise { - return new Promise((resolve) => { - try { - const cacheDir = this.getCacheDir() - if (!fs.existsSync(cacheDir)) { - fs.mkdirSync(cacheDir, { recursive: true }) - } - - const listPath = path.join(cacheDir, 'ast-cache-list.json') - // list 文件要格式化,方便人阅读 - fs.writeFile(listPath, JSON.stringify(cacheList, null, 2), 'utf8', (err: NodeJS.ErrnoException | null) => { - if (err) { - logger.warn(`Failed to save cache list: ${err.message}`) - } - resolve() - }) - } catch (error) { - logger.warn(`Failed to save cache list: ${(error as Error).message}`) - resolve() - } - }) - } - - /** - * 从缓存加载 AST(异步,支持并发) - * @param source - 源代码内容 - * @param filename - 文件的绝对路径 - * @param cacheList - 缓存列表映射 - * @returns {Promise<{ast: any, loadedFromCache: boolean, needsUpdate: boolean}>} AST、是否从缓存加载、是否需要更新 - */ - async loadAstFromCache( - source: any, - filename: any, - cacheList: Map - ): Promise<{ ast: any; loadedFromCache: boolean; needsUpdate: boolean }> { - return new Promise((resolve) => { - const relativePath = this.getRelativePath(filename) - const cacheInfo = cacheList.get(relativePath) - - // 计算源代码的 CRC(使用 MD5) - const sourceCrc = md5(source) - - if (!cacheInfo) { - // list 中没有记录,需要重新解析并更新 - resolve({ ast: null, loadedFromCache: false, needsUpdate: true }) - return - } - - // 检查 CRC 是否匹配 - if (cacheInfo.crc !== sourceCrc) { - // CRC 不匹配,需要重新解析并更新 list - resolve({ ast: null, loadedFromCache: false, needsUpdate: true }) - return - } - - // CRC 匹配,从 JSON 文件加载 AST - const cacheDir = this.getCacheDir() - // jsonFile 可能包含子目录路径(如 "astcache/filename.json"),直接使用 - const jsonPath = path.join(cacheDir, cacheInfo.jsonFile) - - fs.readFile(jsonPath, 'utf8', (err: NodeJS.ErrnoException | null, astContent: string) => { - if (err) { - // JSON 文件不存在,需要重新解析并更新 - resolve({ ast: null, loadedFromCache: false, needsUpdate: true }) - return - } - - try { - // JSON 文件只包含 flatted 格式的 AST 字符串(未格式化,更快) - const ast = flatted.parse(astContent) - resolve({ ast, loadedFromCache: true, needsUpdate: false }) - } catch (error) { - // JSON 文件损坏,需要重新解析并更新 - logger.warn(`Failed to parse AST cache for ${relativePath}: ${(error as Error).message}`) - resolve({ ast: null, loadedFromCache: false, needsUpdate: true }) - } - }) - }) - } - - /** - * 保存 AST 到缓存(异步) - * @param ast - AST 对象 - * @param source - 源代码内容 - * @param filename - 文件的绝对路径 - * @returns {Promise<{relativePath: string, jsonFile: string, crc: string, time: string}>} 缓存信息 - */ - async saveAstToCache( - ast: any, - source: any, - filename: any - ): Promise<{ relativePath: string; jsonFile: string; crc: string; time: string } | null> { - return new Promise((resolve) => { - try { - const cacheDir = this.getCacheDir() - - // 确保目录存在 - if (!fs.existsSync(cacheDir)) { - fs.mkdirSync(cacheDir, { recursive: true }) - } - - // 获取相对路径 - const relativePath = this.getRelativePath(filename) - - // 使用 hash 生成 JSON 文件名(避免文件名过长) - // JSON 文件保存在 astcache 子目录中 - const astCacheSubDir = 'astcache' - const jsonFileName = `${md5(relativePath)}.json` - const jsonFile = path.join(astCacheSubDir, jsonFileName) - const astCacheDir = path.join(cacheDir, astCacheSubDir) - - // 确保 astcache 子目录存在 - if (!fs.existsSync(astCacheDir)) { - fs.mkdirSync(astCacheDir, { recursive: true }) - } - - const jsonPath = path.join(astCacheDir, jsonFileName) - - // 计算源代码的 CRC - const sourceCrc = md5(source) - - // 使用 flatted 序列化 AST(只保存 AST,不包含其他信息,不格式化以提升性能) - const astSerialized = flatted.stringify(ast) - - // 生成时间戳 - const timestamp = new Date().toISOString() - - // 保存 AST 到 JSON 文件(不格式化,提升序列化/反序列化速度) - fs.writeFile(jsonPath, astSerialized, 'utf8', (err: NodeJS.ErrnoException | null) => { - if (err) { - logger.warn(`Failed to write AST cache for ${relativePath}: ${err.message}`) - resolve(null) - return - } - - // 返回缓存信息,用于更新 list 文件 - resolve({ - relativePath, - jsonFile, - crc: sourceCrc, - time: timestamp, - }) - }) - } catch (error) { - logger.warn(`Failed to write AST cache for ${filename}: ${(error as Error).message}`) - resolve(null) - } - }) - } - - /** - * 解析文件并预加载到包管理器(异步版本,返回缓存信息) - * @param source - 源代码内容 - * @param filename - 文件名 - * @returns {Promise<{relativePath: string, jsonFile: string, crc: string, time: string} | null>} 缓存信息 - */ - async preloadFileToPackageAsync( - source: any, - filename: any - ): Promise<{ relativePath: string; jsonFile: string; crc: string; time: string } | null> { - return new Promise((resolve) => { - this.preloadFileToPackage(source, filename, undefined, (cacheInfo) => { - resolve(cacheInfo) - }) - }) } /** * 解析文件并预加载到包管理器 * * 注意:此方法在循环中被调用多次,每个文件的 parseCode 和 preload 时间都会累加到总时间中。 + * 如果提供了 preParsedAst,直接使用,避免重复解析。 * * @param source - 源代码内容 * @param filename - 文件名 - * @param cachedAst - 从缓存加载的 AST(如果存在) - * @param onCacheSaved - 缓存保存后的回调函数 + * @param preParsedAst - 可选的预解析 AST(来自 parseProject,如果提供则直接使用,避免重复解析) * @returns {any} 包作用域和文件作用域 */ - preloadFileToPackage( - source: any, - filename: any, - cachedAst?: any, - onCacheSaved?: (cacheInfo: { relativePath: string; jsonFile: string; crc: string; time: string } | null) => void - ) { + preloadFileToPackage(source: any, filename: any, preParsedAst?: any) { const { options } = this options.sourcefile = filename - options.language = 'java' - // 使用传入的缓存 AST,如果没有则重新解析 - // cachedAst 为 undefined 表示强制重新解析(force 模式),null 表示不使用缓存 - let ast = cachedAst - const shouldSaveCache = cachedAst !== null // null 表示禁用缓存,undefined 表示强制重新解析但保存缓存 - if (!ast) { - // 记录解析时间(parse 子步骤) - const parseStart = Date.now() - ast = Parsing.parseCode(source, options) - const parseTime = Date.now() - parseStart - this.performanceTracker.record('preProcess.parseCode.parse', parseTime) - - // 异步保存 AST 到缓存(不阻塞主流程) - // 只有在启用缓存或 force 模式时才保存 - if (ast && shouldSaveCache) { - const saveStart = Date.now() - this.saveAstToCache(ast, source, filename) - .then((cacheInfo) => { - // 记录保存缓存时间(saveCache 子步骤) - const saveTime = Date.now() - saveStart - if (saveTime > 0) { - this.performanceTracker.record('preProcess.parseCode.saveCache', saveTime) - } - if (onCacheSaved) { - onCacheSaved(cacheInfo) - } - }) - .catch((err) => { - logger.warn(`Failed to save AST cache for ${filename}: ${err.message}`) - if (onCacheSaved) { - onCacheSaved(null) - } - }) - } else if (onCacheSaved) { - onCacheSaved(null) - } - } else if (onCacheSaved) { - // 从缓存加载,不需要保存 - onCacheSaved(null) - } + const ast = preParsedAst || Parser.parseSingleFile(filename, options, this.sourceCodeCache) - this.sourceCodeCache[filename] = source if (!ast) { handleException( null, @@ -630,24 +267,28 @@ class JavaAnalyzer extends (Analyzer as any) { `JavaAnalyzer.preloadFileToPackage: node type should be CompileUnit, but ${ast?.type}`, `JavaAnalyzer.preloadFileToPackage: node type should be CompileUnit, but ${ast?.type}` ) + // 清理 parse 失败时的 sourceCodeCache,避免后续代码误认为文件已处理 + if (this.sourceCodeCache && this.sourceCodeCache.get(filename)) { + this.sourceCodeCache.delete(filename) + } return undefined } const packageName = ast._meta.qualifiedName ?? '' - const packageScope = this.packageManager.getSubPackage(packageName, true) + const packageScope = this.topScope.context.packages.getSubPackage(packageName, true) // 开始记录 preload 时间:初始化文件作用域、处理类定义等 - const preloadStart = Date.now() + this.performanceTracker.record('preProcess.preload')?.start() // file scope init // value specifies what module exports, closure specifies file closure const fileScope = this.initFileScope(ast, filename, packageScope) - ;(this as any).unprocessedFileScopes = (this as any).unprocessedFileScopes ?? new Set() - ;(this as any).unprocessedFileScopes.add(fileScope) + this.unprocessedFileScopes = this.unprocessedFileScopes ?? new Set() + this.unprocessedFileScopes.add(fileScope) const { body } = ast - ;(this as any).entry_fclos = fileScope - ;(this as any).thisFClos = fileScope + this.entry_fclos = fileScope + this.thisFClos = fileScope const state = this.initState(fileScope) // prebuild @@ -660,14 +301,13 @@ class JavaAnalyzer extends (Analyzer as any) { } const { className, classClos } = this.preprocessClassDefinitionRec(classDef, fileScope, fileScope, packageScope) if (classDef._meta.isPublic) { - packageScope.exports = - packageScope.exports ?? - Scoped({ - id: 'exports', + packageScope.scope.exports = + packageScope.scope.exports ?? + new Scoped(packageScope.qid, { sid: 'export', - parent: null, + parent: packageScope, }) - packageScope.exports.setFieldValue(className, classClos) + packageScope.scope.exports.setFieldValue(className, classClos) } packageScope.setFieldValue(className, classClos) } else if (childNode.type === 'ClassDefinition') { @@ -685,11 +325,10 @@ class JavaAnalyzer extends (Analyzer as any) { if (this.checkerManager && this.checkerManager.checkAtEndOfCompileUnit) { this.checkerManager.checkAtEndOfCompileUnit(this, null, null, state, null) } - this.fileManager[filename] = fileScope + this.fileManager[filename] = fileScope.uuid // 记录 preload 时间:累加到总 preload 时间中 - const preloadTime = Date.now() - preloadStart - this.performanceTracker.record('preProcess.preload', preloadTime) + this.performanceTracker.record('preProcess.preload')?.end() return { packageScope, fileScope } } @@ -705,28 +344,28 @@ class JavaAnalyzer extends (Analyzer as any) { preprocessClassDefinitionRec(node: any, scope: any, fileScope: any, packageScope?: any) { const className = node.id?.name - const classClos = Scope.createSubScope(className, scope, 'class') - const qualifiedName = Scope.joinQualifiedName(scope.qid, className) - classClos.sort = qualifiedName - classClos.qid = qualifiedName - classClos.exports = Scoped({ - id: 'exports', + const classClos = ScopeClass.createSubScope( + className, + scope, + 'class', + ScopeClass.joinQualifiedName(scope.qid, className) + ) + classClos.scope.exports = new Scoped(classClos.qid, { sid: 'exports', - parent: null, + parent: classClos, }) if (node._meta.isPublic) { - scope.exports = - scope.exports ?? - Scoped({ - id: 'exports', + scope.scope.exports = + scope.scope.exports ?? + new Scoped(classClos.qid, { sid: 'exports', - parent: null, + parent: classClos, }) - scope.exports.setFieldValue(className, classClos) + scope.scope.exports.setFieldValue(className, classClos) } - classClos.fdef = node classClos.ast = node - classClos.fileScope = fileScope + classClos.ast.fdef = node + classClos.scope.fileScope = fileScope classClos.packageScope = packageScope const { body } = node if (!body) { @@ -740,6 +379,37 @@ class JavaAnalyzer extends (Analyzer as any) { return { className, classClos } } + /** + * process instruction + * @param scope + * @param node + * @param state + * @param prePostFlag + * @returns {*} + */ + override processInstruction(scope: any, node: any, state: any, prePostFlag?: any): any { + if ( + state.entryPointStartTimestamp && + Config.entryPointTimeoutMs && + Date.now() - state.entryPointStartTimestamp > Config.entryPointTimeoutMs + ) { + this.globalState.entryPointTimeout = true + return new UndefinedValue() + } + let hasException: boolean = false + if (state?.throwstackScopeAndState) { + for (const element of state.throwstackScopeAndState) { + if (element.scope === scope && element.state === state) { + hasException = true + } + } + } + if (hasException) { + return new UndefinedValue() + } + return super.processInstruction(scope, node, state, prePostFlag) + } + /** * 处理编译单元 * @param scope - 作用域 @@ -747,7 +417,7 @@ class JavaAnalyzer extends (Analyzer as any) { * @param state - 状态 * @returns {any} 处理结果 */ - processCompileUnit(scope: any, node: any, state: any) { + override processCompileUnit(scope: Scope, node: CompileUnit, state: State): Value { scope.isProcessed = true return super.processCompileUnit(scope, node, state) } @@ -759,13 +429,13 @@ class JavaAnalyzer extends (Analyzer as any) { * @param state - 状态 * @returns {any} 变量值 */ - processVariableDeclaration(scope: any, node: any, state: any) { + override processVariableDeclaration(scope: Scope, node: VariableDeclaration, state: State): SymbolValueType { const initVal = super.processVariableDeclaration(scope, node, state) if (initVal && node.varType !== null && node.varType !== undefined) { initVal.rtype = { type: undefined } const val = this.getMemberValueNoCreate(scope, node.varType.id, state) - if (val) { - initVal.rtype.definiteType = UastSpec.identifier(val._qid) + if (val?.vtype === 'class') { + initVal.rtype.definiteType = UastSpec.identifier(val.logicalQid) } else { initVal.rtype.definiteType = node.varType.id } @@ -780,22 +450,43 @@ class JavaAnalyzer extends (Analyzer as any) { * @param state - 状态 * @returns {any} 标识符值 */ - processIdentifier(scope: any, node: any, state: any) { - const res = super.processIdentifier(scope, node, state) + override processIdentifier(scope: Scope, node: Identifier, state: State): SymbolValueType { + let res = super.processIdentifier(scope, node, state) if (res && !res.rtype) { res.rtype = { type: undefined } - if (res.vtype === 'class') { - res.rtype.definiteType = UastSpec.identifier(res._qid) - } else { - res.rtype.definiteType = node + if ((res as any).vtype === 'class') { + res.rtype.definiteType = UastSpec.identifier(res.logicalQid) } } - const { fileScope } = res - if (fileScope && !fileScope.isProcessed) { - this.processInstruction(fileScope, fileScope.ast, this.initState(fileScope)) + const resFileScope = res.scope.fileScope + if (resFileScope && !resFileScope.isProcessed) { + this.processInstruction(resFileScope, resFileScope.ast?.node, this.initState(resFileScope)) + } + + if ( + res && + (res as any)?.vtype !== 'fclos' && + (res as any)?.vtype !== 'class' && + res?.parent?.vtype === 'class' && + this.thisFClos && + this.thisFClos.vtype === 'symbol' + ) { + if (this.thisFClos.members?.get(node.name)) { + res = this.thisFClos.members.get(node.name) + } else { + const vCopy = this.thisFClos.cloneAlias() + res = res.cloneAlias ? res.cloneAlias() : _.clone(res) + res._this = vCopy + res.parent = vCopy + res.object = vCopy + if (vCopy.taint?.isTaintedRec) { + res.taint?.markSource() + } + } } + return res } @@ -813,7 +504,7 @@ class JavaAnalyzer extends (Analyzer as any) { * @returns {any} 成员值 */ // eslint-disable-next-line complexity - processMemberAccess(scope: any, node: any, state: any) { + override processMemberAccess(scope: Scope, node: MemberAccess, state: State): SymbolValueType { const defscope = this.processInstruction(scope, node.object, state) const prop = node.property let resolvedProp = prop @@ -821,18 +512,46 @@ class JavaAnalyzer extends (Analyzer as any) { if (node.computed || (prop.type !== 'Identifier' && prop.type !== 'Literal')) { resolvedProp = this.processInstruction(scope, prop, state) } - let res = this.getMemberValue(defscope, resolvedProp, state) + let res + if (resolvedProp?.type === 'Identifier' && resolvedProp.name === 'length' && defscope.length) { + res = new PrimitiveValue(scope.qid, '', defscope.length, 'number', 'Literal', node.loc) + } else { + res = this.getMemberValue(defscope, resolvedProp, state) + } if (this.checkerManager && this.checkerManager.checkAtMemberAccess) { this.checkerManager.checkAtMemberAccess(this, defscope, node, state, { res }) } - if (node.property.type === 'ThisExpression' && defscope.vtype === 'class' && defscope._qid) { - const ancestorInstance = this.getAncestorScopeByQid(scope, `${defscope._qid}`) + if ( + Number.isInteger(res?.object?.length) && + res?.property?.vtype === 'primitive' && + res?.property?.literalType === 'number' + ) { + const index = Number(res.property.value) + if (index >= res.object.length) { + state.throwstack = state.throwstack ?? [] + let throwValue = res.object + throwValue = SourceLine.addSrcLineInfo( + throwValue, + node.object, + node.object.loc && node.object.loc.sourcefile, + 'Throw Pass: ', + AstUtil.prettyPrint(node.object) + ) + state.throwstack.push(throwValue) + + state.throwstackScopeAndState = state.throwstackScopeAndState ?? [] + state.throwstackScopeAndState.push({ scope, state }) + } + } + + if (node.property.type === 'ThisExpression' && defscope.vtype === 'class' && defscope.qid) { + const ancestorInstance = this.getAncestorScopeByQid(scope, `${defscope.qid}`) if (ancestorInstance) { res = ancestorInstance } } - if (defscope.vtype === 'fclos' && defscope._sid?.includes('anonymous') && res.vtype === 'symbol') { + if (defscope.vtype === 'fclos' && defscope.sid?.includes('anonymous') && res.vtype === 'symbol') { res = defscope } @@ -845,29 +564,36 @@ class JavaAnalyzer extends (Analyzer as any) { } const { fileScope } = res if (fileScope && !fileScope.isProcessed) { - this.processInstruction(fileScope, fileScope.ast, this.initState(fileScope)) + this.processInstruction(fileScope, fileScope.ast?.node, this.initState(fileScope)) } if (node.object?.type !== 'SuperExpression') { - if (res.vtype !== 'union') { + if (res.vtype !== 'union' || !Array.isArray(res.value)) { res._this = defscope } else { - const thisUnion = defscope - if (thisUnion?.value) { + const _thisUnion = defscope + if (_thisUnion?.value && Array.isArray(_thisUnion?.value)) { for (const f of res.value) { - for (const thisObj of thisUnion.value) { - if (!f._sid || !thisObj.value) { + for (const _thisObj of _thisUnion.value) { + if (!f.sid || !_thisObj.value) { continue } - if (f === thisObj.value[f._sid]) { - f._this = thisObj + if (f === _thisObj.value[f.sid]) { + f._this = _thisObj } } } } } + res._this = defscope + } else { + // For super.method() calls, bind this to the current instance. + // In Java semantics, super only affects method dispatch (which class's implementation to call), + // not this binding. this inside the parent method should still refer to the current instance. + if (this.thisFClos) { + res._this = this.thisFClos + } } - res._this = defscope return res } @@ -877,50 +603,58 @@ class JavaAnalyzer extends (Analyzer as any) { * @param scope - 作用域 * @param node - AST 节点 * @param _state - 状态(未使用) + * @param state * @returns {any} 导入结果 */ - processImportDirect(scope: any, node: any, _state: any) { + processImportDirect(scope: any, node: any, state: any) { + const importNode = node node = node.from - const fname = node?.value + const fromName = node?.value + const importedName = importNode?.imported?.name || importNode?.local?.name // check cached imports first let packageName = '' const classNames: string[] = [] - if (fname) { - if (fname.includes('.')) { - const lastDotIndex = fname.lastIndexOf('.') - packageName = fname.substring(0, lastDotIndex) - classNames.push(fname.substring(lastDotIndex + 1)) + let lastName: string = '' + if (fromName || importedName) { + const fullName = importedName ? `${fromName}.${importedName}` : fromName + if (fullName?.includes('.')) { + const lastDotIndex = fullName.lastIndexOf('.') + packageName = fullName.substring(0, lastDotIndex) + lastName = fullName.substring(lastDotIndex + 1) + classNames.push(fullName.substring(lastDotIndex + 1)) } else { - classNames.push(fname) + lastName = fullName + classNames.push(fullName) } } - - let packageScope = this.packageManager.getSubPackage(packageName, true) + packageName = packageName.replace('.packageManager.', '') + let packageScope = this.topScope.context.packages.getSubPackage(packageName, true) // if package is not created from import statement, but from full qualified name access if (packageScope.vtype !== 'package') { - packageScope = PackageValue({ + packageScope = new PackageValue('', { vtype: 'package', - sid: fname, + sid: lastName, qid: packageName, - exports: Scoped({ - sid: 'exports', - id: 'exports', - parent: null, - }), parent: this, }) + const exports = new Scoped(packageScope.qid, { + sid: 'exports', + parent: packageScope, + }) + packageScope.scope.exports = exports } let classScope = packageScope for (const className of classNames) { - classScope = Scope.createSubScope(className, packageScope, 'class') - packageScope.exports.value[className] = classScope - const qualifiedName = Scope.joinQualifiedName(packageScope.qid, className) - classScope.sort = qualifiedName - classScope.qid = qualifiedName + classScope = ScopeClass.createSubScope( + className, + packageScope, + 'class', + ScopeClass.joinQualifiedName(packageScope.qid, className) + ) + packageScope.scope.exports.value[className] = classScope } - classScope.sort = classScope.sort ?? fname return classScope } @@ -932,8 +666,8 @@ class JavaAnalyzer extends (Analyzer as any) { * @returns {any} 类定义结果 */ // eslint-disable-next-line complexity - processClassDefinition(scope: any, node: any, state: any) { - const { annotations } = node._meta + override processClassDefinition(scope: Scope, node: ClassDefinition, state: State): SymbolValueType { + const { annotations } = node._meta as any const annotationValues: any[] = [] annotations?.forEach((annotation: any) => { annotationValues.push(this.processInstruction(scope, annotation, state)) @@ -942,8 +676,8 @@ class JavaAnalyzer extends (Analyzer as any) { // adjust the order of the class body, so that static field comes last const { body } = node let bodyStmt: any - if (body?.type === 'ScopedStatement') { - bodyStmt = body.body + if (body && !Array.isArray(body) && (body as any).type === 'ScopedStatement') { + bodyStmt = (body as any).body } else if (Array.isArray(body)) { bodyStmt = body } @@ -955,35 +689,54 @@ class JavaAnalyzer extends (Analyzer as any) { // TODO res.annotations = annotationValues for (const annotation of annotationValues) { - if (annotation.sort === 'lombok.Data') { - const value = res.getRawValue() - for (const prop in value) { - const fieldValue = value[prop] + if (annotation.qid.includes('lombok.Data')) { + const value = res.members + for (const prop of value.keys()) { + const fieldValue = value.get(prop) if (fieldValue.vtype !== 'fclos') { const getterName = `get${getUpperCase(prop)}` - if (value[getterName] === undefined) { + if (!value.has(getterName)) { const targetQid = `${scope.qid}.${getterName}` - value[getterName] = FunctionValue({ - sid: getterName, - qid: targetQid, - parent: scope, - execute: JavaInitializer.builtin.lombok.processGetter(getterName, prop), - }) - ;(this as any).funcSymbolTable[targetQid] = value[getterName] + value.set( + getterName, + new FunctionValue('', { + sid: getterName, + qid: targetQid, + parent: scope, + runtime: { execute: JavaInitializer.builtin.lombok.processGetter(getterName, prop) }, + }) + ) + this.funcSymbolTable[QidUnifyUtil.qidUnifyByRemoveAngleAndPrefix(targetQid)] = value.get(getterName) } const setterName = `set${getUpperCase(prop)}` - if (value[setterName] === undefined) { + if (!value.has(setterName)) { const targetQid = `${scope.qid}.${setterName}` - value[setterName] = FunctionValue({ - sid: setterName, - qid: targetQid, - parent: scope, - execute: JavaInitializer.builtin.lombok.processSetter(setterName, prop), - }) - ;(this as any).funcSymbolTable[targetQid] = value[getterName] + value.set( + setterName, + new FunctionValue('', { + sid: setterName, + qid: targetQid, + parent: scope, + runtime: { execute: JavaInitializer.builtin.lombok.processSetter(setterName, prop) }, + }) + ) + this.funcSymbolTable[QidUnifyUtil.qidUnifyByRemoveAngleAndPrefix(targetQid)] = value.get(getterName) } } } + } else if (annotation.qid.includes('lombok.AllArgsConstructor')) { + const value = res.members + if (!value.has('_CTOR_')) { + value.set( + '_CTOR_', + new FunctionValue('', { + sid: '_CTOR_', + qid: `${res.qid}._CTOR_`, + parent: scope, + runtime: { execute: JavaInitializer.builtin.lombok._CTOR_ }, + }) + ) + } } } return res @@ -996,7 +749,7 @@ class JavaAnalyzer extends (Analyzer as any) { * @param state - 状态 * @returns {any} 赋值结果 */ - processAssignmentExpression(scope: any, node: any, state: any) { + override processAssignmentExpression(scope: Scope, node: AssignmentExpression, state: State): SymbolValueType { const { left } = node const oldVal = this.processInstruction(scope, left, state) @@ -1004,11 +757,16 @@ class JavaAnalyzer extends (Analyzer as any) { if ( node.operator === '=' && - oldVal?.parent === (this as any).thisFClos && - (this as any).thisFClos?.field?.super && - !this.checkFieldDefinedInClass(oldVal._id, (this as any).thisFClos.sort) + oldVal?.parent === this.thisFClos && + this.thisFClos?.members?.get('super') && + !this.checkFieldDefinedInClass(oldVal.sid, this.thisFClos.qid) ) { - this.saveVarInScopeRec((this as any).thisFClos.field.super, left.property, res, state) + this.saveVarInScopeRec( + this.thisFClos.members.get('super')!, + left.type === 'MemberAccess' ? left.property : left, + res, + state + ) } return res @@ -1021,25 +779,69 @@ class JavaAnalyzer extends (Analyzer as any) { * @param state - 状态 * @returns {any} 表达式结果 */ - processBinaryExpression(scope: any, node: any, state: any) { + override processBinaryExpression(scope: Scope, node: BinaryExpression, state: State): BinaryExprValue { let res = super.processBinaryExpression(scope, node, state) if ( res?.left?.vtype === 'primitive' && res?.right?.vtype === 'primitive' && - ['>', '<', '==', '!=', '>=', '<='].includes(res?.operator) + res?.operator && + ['>', '<', '==', '!=', '>=', '<='].includes(res.operator) ) { - const leftPrimitive = res.left.value - const rightPrimitive = res.right.value - const expr = leftPrimitive + res.operator + rightPrimitive - try { - // eslint-disable-next-line no-eval - const result = eval(expr) - if (result != null) { - res = PrimitiveValue({ type: 'Literal', value: result, loc: node.loc }) + const leftPrim = res.left as PrimitiveValueType + const rightPrim = res.right as PrimitiveValueType + let leftPrimitive = leftPrim.value + if (leftPrim.literalType === 'string' && leftPrimitive != null && typeof leftPrimitive === 'string') { + leftPrimitive = `'${leftPrimitive.replaceAll("'", "\\'")}'` + } + let rightPrimitive = rightPrim.value + if (rightPrim.literalType === 'string' && rightPrimitive != null && typeof rightPrimitive === 'string') { + rightPrimitive = `'${rightPrimitive.replaceAll("'", "\\'")}'` + } + if (leftPrimitive != null && rightPrimitive != null) { + const expr = leftPrimitive + res.operator + rightPrimitive + try { + // eslint-disable-next-line no-eval + const result = eval(expr) + if (result != null) { + res = new PrimitiveValue( + scope.qid, + ``, + result, + null, + 'Literal', + node.loc + ) + } + } catch (e) { + // 忽略 eval 错误 + } + } + } else if (res?.operator === 'instanceof') { + if (res?.left?.vtype === 'primitive' && (res.left as PrimitiveValueType).literalType === 'null') { + res = new PrimitiveValue(scope.qid, '', false, null, 'Literal', node.loc) + } else if (res?.right?.vtype === 'class') { + if (res.right.qid === 'java.lang.Object' || res.right.logicalQid === 'java.lang.Object') { + // eslint-disable-next-line sonarjs/no-duplicate-string + res = new PrimitiveValue(scope.qid, '', true, null, 'Literal', node.loc) + } else if ((res?.left as any)?.rtype?.definiteType && !(res.left as any).rtype.vagueType) { + const leftWithRtype = res.left as any + const resType = AstUtil.prettyPrint(leftWithRtype.rtype.definiteType) + if (resType === res.right.qid) { + res = new PrimitiveValue(scope.qid, '', true, null, 'Literal', node.loc) + } else { + const classHierarchy: ClassHierarchy | undefined = this.typeResolver.classHierarchyMap.get(resType) + if (classHierarchy) { + const baseTypes: string[] = this.typeResolver.findBaseTypes(classHierarchy) + for (const baseType of baseTypes) { + if (baseType === res.right.qid) { + res = new PrimitiveValue(scope.qid, '', true, 'boolean', 'Literal', node.loc) + break + } + } + } + } } - } catch (e) { - // 忽略 eval 错误 } } @@ -1054,7 +856,7 @@ class JavaAnalyzer extends (Analyzer as any) { * @returns {any} 调用结果 */ // eslint-disable-next-line complexity - processCallExpression(scope: any, node: any, state: any) { + override processCallExpression(scope: Scope, node: CallExpression, state: State): SymbolValueType { /* { callee, arguments, } @@ -1065,46 +867,248 @@ class JavaAnalyzer extends (Analyzer as any) { einfo: state.einfo, }) - const fclos = this.processInstruction(scope, node.callee, state) - if (!fclos) return UndefinedValue() + let fclos = this.processInstruction(scope, node.callee, state) + + if (!fclos) { + return new UndefinedValue() + } + if (this.entryPointSymValArray.includes(fclos) && !Config.makeAllCG) { + this.globalState.meetOtherEntryPoint = true + return new UndefinedValue() + } + if (node.callee.type === 'ThisExpression' && fclos.qid.includes('' && !fclos?.fdef && !fclos?.execute) { - // let subscope = Scope.createSubScope(argv.sid + '_scope', scope,'scope') - argv = this.processAndCallFuncDef(scope, arg, argv, state) + if (arg.type === 'FunctionDefinition') { + const funcDef = arg as FunctionDefinition + const funcName = funcDef.id?.type === 'Identifier' ? funcDef.id.name : '' + if (funcName.includes(' 0) { + anonymousArgValues = [] + let i = 0 + while (i < funcDef.parameters.length) { + anonymousArgValues.push(_this) + i++ + } + } + argv = this.processAndCallFuncDef(scope, funcDef, argv, state, anonymousArgValues) + argExecuted = true + } } if (argv !== arg) sameArgs = false - if ((logger as any).isTraceEnabled()) (logger as any).trace(`arg: ${this.formatScope(argv)}`) + if (logger.isTraceEnabled()) logger.trace(`arg: ${this.formatScope(argv)}`) if (Array.isArray(argv)) { argvalues.push(...argv) } else { + this.addRtypeToArg(arg, argv) argvalues.push(argv) } } if (sameArgs) argvalues = node.arguments + let res + let meetSameFuncInCallstack = false + + const invocations: Invocation[] = this.findNodeInvocations(scope, node) + const executedInvocations: Invocation[] = [] + let fclosExecuted = false + let sofaDispatched = false + + /* SOFA 分发:接口调用优先通过 SOFA 服务映射分发到实现类 */ + let sofaInterfaceName: string | undefined + let sofaImplList: Array<{ uniqueId: string; ref: string }> | undefined + + if (fclos.vtype === 'fclos' && this.checkFclosInInterfaceOrAbstractClass(fclos)) { + sofaInterfaceName = fclos.parent?.logicalQid + sofaImplList = sofaInterfaceName + ? this.topScope.spring?.sofaServiceInterfaceMap?.get(sofaInterfaceName) + : undefined + } + + /* 当 fclos 为 symbol(如 Map.get() 返回值的方法调用),从 invocations 目标推断 SOFA 接口 */ + if ( + !sofaImplList && + fclos.vtype === 'symbol' && + invocations.length > 10 && + this.topScope.spring?.sofaServiceInterfaceMap + ) { + const sofaMap = this.topScope.spring.sofaServiceInterfaceMap as Map< + string, + Array<{ uniqueId: string; ref: string }> + > + for (const [iface, implList] of sofaMap) { + if (implList.length > 10 && implList.length <= invocations.length * 2) { + /* 验证:SOFA 映射的 ref 能否匹配到 invocations 的目标类 */ + let matchCount = 0 + for (const impl of implList) { + const beanInfo = this.topScope.spring.beanMap?.get(impl.ref) + if (!beanInfo?.className) continue + const classUuid = this.classMap.get(beanInfo.className) + if (!classUuid) continue + const classObj = this.symbolTable.get(classUuid) + if (!classObj) continue + const implFclos = classObj.members?.get(fclos.sid) + if ( + implFclos && + invocations.some( + (inv: Invocation) => + inv.toScope === implFclos || + (inv.toScope?.qid && inv.toScope.qid === implFclos.qid) || + (inv.toScope?.logicalQid && inv.toScope.logicalQid === implFclos.logicalQid) + ) + ) { + matchCount++ + } + if (matchCount >= 3) break + } + if (matchCount >= 3) { + sofaInterfaceName = iface + sofaImplList = implList + break + } + } + } + } + + if (sofaImplList && sofaImplList.length > 0) { + const methodName = fclos.sid + const { sinkArray } = this.pruneInfoMap + /* 复用全局 pruning 缓存:strict 模式(checkUseDynamicFeature=false)的结果是 dynamic 模式的子集,安全复用 */ + const { matchSinkCacheMap } = this.pruneInfoMap + + /* 获取 this 对象:fclos 可能是 symbol(Map.get() 返回值),需要安全处理 */ + const thisObj = typeof fclos.getThisObj === 'function' ? fclos.getThisObj() : fclos._this + + /* 只收集严格匹配 sink 的实现,跳过不匹配的(不再收集 dynamicMatched) */ + let strictMatchCount = 0 + for (const sofaImpl of sofaImplList) { + const beanInfo = this.topScope.spring.beanMap?.get(sofaImpl.ref) + if (!beanInfo?.className) continue + const classUuid = this.classMap.get(beanInfo.className) + if (!classUuid) continue + const classObj = this.symbolTable.get(classUuid) + if (!classObj) continue + const implFclos = classObj.members?.get(methodName) + if (!implFclos || implFclos.vtype !== 'fclos') continue + const implFdef = implFclos.ast?.fdef + if (!implFdef || implFdef.body?.type === 'Noop') continue + + /* 严格匹配:callgraph 中静态可达 sink 才执行 */ + const matchSink = this.checkFclosMatchSink(implFclos, [], sinkArray, matchSinkCacheMap, false) + if (!matchSink) continue + + strictMatchCount++ + implFclos.ast.fdef = implFdef + const oldThis = implFclos._this + implFclos._this = thisObj + res = this.executeCall(node, implFclos, state, scope, { callArgs: this.buildCallArgs(node, argvalues, implFclos) }) + if (res?.type === 'FunctionCall') { + meetSameFuncInCallstack = true + } + implFclos._this = oldThis + } + + if (strictMatchCount > 0) { + sofaDispatched = true + fclosExecuted = true + } + } + + if (!sofaDispatched && (fclos.vtype !== 'fclos' || this.checkFclosInInterfaceOrAbstractClass(fclos))) { + // execute fclos found by callgraph + for (const invocation of invocations) { + if ( + invocation.toScope?.vtype === 'fclos' && + (invocation.toScopeAst || invocation.toScope.runtime?.execute) && + invocation.toScopeAst?.body?.type !== 'Noop' && + !this.checkFclosCanPruneDuringInterpret(invocation.toScope, node, argvalues, state, true) + ) { + if (invocation.toScope.qid === fclos.qid) { + fclosExecuted = true + } + let executed: boolean = false + for (const executedInvocation of executedInvocations) { + if ( + (invocation.toScopeAst && + executedInvocation.toScopeAst && + invocation.toScopeAst._meta?.nodehash === executedInvocation.toScopeAst._meta?.nodehash) || + (invocation.toScope.runtime?.execute && + executedInvocation.toScope.runtime?.execute && + invocation.toScope.runtime.execute === executedInvocation.toScope.runtime.execute) + ) { + executed = true + break + } + } + if (executed) { + continue + } + executedInvocations.push(invocation) + invocation.toScope.ast.fdef = invocation.toScopeAst + const oldThis = invocation.toScope._this + invocation.toScope._this = fclos.getThisObj() + res = this.executeCall(node, invocation.toScope, state, scope, { callArgs: this.buildCallArgs(node, argvalues, invocation.toScope) }) + if (res?.type === 'FunctionCall') { + meetSameFuncInCallstack = true + } + invocation.toScope._this = oldThis + } + } + } + // analyze the resolved function closure and the function arguments - let res = this.executeCall(node, fclos, argvalues, state, scope) + if (!sofaDispatched && ((fclos.vtype === 'fclos' && !fclosExecuted) || executedInvocations.length === 0)) { + if ( + this.checkFclosCanPruneDuringInterpret(fclos, node, argvalues, state, false) || + fclos?.ast?.fdef?.body?.type === 'Noop' + ) { + if (!res) { + res = this.processLibArgToRet(node, fclos, argvalues, scope, state, { callArgs: this.buildCallArgs(node, argvalues, fclos) }) + } + } else { + res = this.executeCall(node, fclos, state, scope, { callArgs: this.buildCallArgs(node, argvalues, fclos) }) + } + if (res?.type === 'FunctionCall') { + meetSameFuncInCallstack = true + } + } if (res) { - res.rtype = fclos.rtype + const resolvedRes = this.resolveRuntimeValueRef(res) + if (resolvedRes && typeof resolvedRes === 'object') { + resolvedRes.rtype = fclos.rtype + } } - if (res instanceof UndefinedValue && fclos._sid?.includes(' 0 && + argvalues[0]?.vtype === 'primitive' && + fclos.getThisObj().value !== argvalues[0].value + ) { + res = new PrimitiveValue(scope.qid, '', false, null, 'Literal', node.loc) + } + } + + // execute fclos of this + if (fclos?._this?.vtype === 'fclos') { + if (['accept', 'apply', 'call', 'run', 'get'].includes(fclos.sid)) { + this.executeCall(node, fclos._this, state, scope, { callArgs: this.buildCallArgs(node, argvalues, fclos._this) }) + } else if (fclos.sid === 'invoke' && argvalues.length >= 1) { + fclos._this._this = argvalues[0] + this.executeCall(node, fclos._this, state, scope, { callArgs: this.buildCallArgs(node, argvalues.slice(1), fclos._this) }) + } + } + + if (meetSameFuncInCallstack && !argExecuted && node.arguments?.length === argvalues.length) { + for (let i = 0; i < node.arguments.length; i++) { + const arg = node.arguments[i] + const argv = argvalues[i] + const argNode = arg as { type?: string; name?: string; parameters?: Array } + if (argNode?.type === 'FunctionDefinition' && argNode?.name?.includes(' 0) { + anonymousArgValues = [] + let j = 0 + while (j < argNode.parameters.length) { + anonymousArgValues.push(_this) + j++ + } + } + this.processAndCallFuncDef(scope, funcDef, argv, state, anonymousArgValues) + argExecuted = true + } + } } if (res && this.checkerManager?.checkAtFunctionCallAfter) { @@ -1134,6 +1180,9 @@ class JavaAnalyzer extends (Analyzer as any) { }) } + if (!res) { + res = new UndefinedValue() + } return res } @@ -1144,12 +1193,11 @@ class JavaAnalyzer extends (Analyzer as any) { * @param state - 状态 * @returns {any} new 表达式结果 */ - processNewExpression(scope: any, node: any, state: any) { + override processNewExpression(scope: Scope, node: NewExpression, state: State): SymbolValueType { if (node._meta && node._meta.isEnumImpl) { - this.processInstruction(scope, node.callee, state) - } else { - return super.processNewExpression(scope, node, state) + return this.processInstruction(scope, node.callee, state) } + return super.processNewExpression(scope, node, state) } /** @@ -1159,16 +1207,30 @@ class JavaAnalyzer extends (Analyzer as any) { * @param state - 状态 * @returns {any} 一元表达式结果 */ - processUnaryExpression(scope: any, node: any, state: any) { + override processUnaryExpression(scope: Scope, node: UnaryExpression, state: State): UnaryExprValue { let res = super.processUnaryExpression(scope, node, state) if (res.argument?.vtype === 'primitive' && res.argument?.literalType === 'number') { const argValueNum = Number(res.argument.value) if (node.operator === '++') { - res = PrimitiveValue({ type: 'Literal', value: argValueNum + 1, loc: node.loc }) + res = new PrimitiveValue( + scope.qid, + ``, + argValueNum + 1, + null, + 'Literal', + node.loc + ) this.saveVarInScope(scope, node.argument, res, state) } else if (node.operator === '--') { - res = PrimitiveValue({ type: 'Literal', value: argValueNum - 1, loc: node.loc }) + res = new PrimitiveValue( + scope.qid, + ``, + argValueNum - 1, + null, + 'Literal', + node.loc + ) this.saveVarInScope(scope, node.argument, res, state) } } @@ -1176,24 +1238,189 @@ class JavaAnalyzer extends (Analyzer as any) { return res } + /** + * + * @param scope + * @param node + * @param state + */ + override processTryStatement(scope: Scope, node: TryStatement, state: State): VoidValueType { + state.throwstack = state.throwstack ?? [] + + this.processInstruction(scope, node.body, state) + + const { handlers } = node + if (handlers) { + for (const clause of handlers) { + const subScope = ScopeClass.createSubScope( + ``, + scope + ) + if (clause && state?.throwstack?.length > 0) { + const throw_value = state.throwstack[0] + for (const param of clause.parameter) { + if (param && param.type === 'VariableDeclaration' && param.init === null) { + param._meta.isCatchParam = true + param.init = { + type: 'Identifier', + name: throw_value.sid, + _meta: param._meta, + loc: param.loc, + parent: param.parent, + } as any + } + } + } + if (clause) { + clause.parameter.forEach((param: any) => this.processInstruction(subScope, param, state)) + this.processInstruction(subScope, clause.body, state) + } + } + } + + if (node.finalizer) { + this.processInstruction(scope, node.finalizer, state) + } + + if (state?.throwstack?.length === 0) { + delete state.throwstack + } + + return new UndefinedValue() + } + + /** + * + * @param scope + * @param node + * @param state + */ + override processRangeStatement(scope: Scope, node: RangeStatement, state: State): any { + const { key, value, right, body } = node + scope = ScopeClass.createSubScope( + ``, + scope + ) + const rightVal = this.processInstruction(scope, right, state) + let executed = false + if ( + !Array.isArray(rightVal) && + (this.inRange || + rightVal?.vtype === 'primitive' || + Object.keys(rightVal.getRawValue()).filter((key) => !key.startsWith('__yasa')).length === 0 || + rightVal?.vtype === 'union' || + !rightVal?.getMisc('precise')) + ) { + if (value) { + if (value.type === 'VariableDeclaration') { + this.saveVarInCurrentScope(scope, value.id, rightVal, state) + } else if (value.type === 'TupleExpression') { + for (const ele of value.elements) { + const eleName = ele && ele.type === 'Identifier' ? ele.name : ele?.name || 'unknown' + this.saveVarInCurrentScope(scope, eleName, rightVal, state) + } + } else { + this.saveVarInScope(scope, value, rightVal, state) + } + } + if (key) { + // TODO js存到value,go存到key。且需要考虑既有key 又有value的场景 + this.saveVarInScope(scope, key, rightVal, state) + } + this.processInstruction(scope, body, state) + executed = true + } else { + this.inRange = true + if (this.isNullLiteral(rightVal)) { + this.inRange = false + return undefined + } + const itr = this.getValueIterator(rightVal, filterDataFromScope) + let countLimit = 30 + for (let { value: field, done } = itr.next(); !done; { value: field, done } = itr.next()) { + if (countLimit-- === 0) { + break + } + if (!field) continue + let { k, v } = field + if (key) { + if (key.type === 'VariableDeclaration') { + this.saveVarInCurrentScope(scope, key.id, k, state) + } else { + // 如果是string,将其构造出符号值再存储 + // TODO 250731 将符号的字面量(而非符号值)作为key存储是否合适,有待商榷。 + if (_.isString(k)) k = new PrimitiveValue(scope.qid, k, k, undefined, key.type, key.loc, key) + this.saveVarInScope(scope, key, k, state) + } + } + if (value) { + if (value.type === 'VariableDeclaration') { + this.saveVarInCurrentScope(scope, value.id, v, state) + } else { + this.saveVarInScope(scope, value, v, state) + } + } + this.processInstruction(scope, body, state) + executed = true + } + this.inRange = false + } + + if (!executed && rightVal?._this?.vtype === 'class' && this.thisFClos && this.thisFClos.vtype === 'symbol') { + this.inRange = true + this.processInstruction(scope, body, state) + this.inRange = false + } + return new VoidValue() + } + + /** + * + * @param scope + * @param node + * @param state + */ + override processCastExpression(scope: any, node: any, state: any) { + const exprVal = this.processInstruction(scope, node.expression, state) + if (exprVal?.vtype === 'fclos' && node?.expression?.type === 'FunctionDefinition') { + this.processAndCallFuncDef(scope, node.expression, exprVal, state) + } + return exprVal + } + /** * 预处理项目目录 * @param dir - 项目目录 */ // eslint-disable-next-line complexity async preProcess(dir: any) { - // init global scope JavaInitializer.initGlobalScope(this.topScope) - - // time-out control - ;(this as any).thisIterationTime = 0 - ;(this as any).prevIterationTime = new Date().getTime() + JavaInitializer.initPackageScope(this.topScope.context.packages) await this.scanPackages(dir) + if (!Config.miniSaveContextEnvironment) { + this.assembleClassMap(this.topScope.context.packages) + if (!Config.loadContextEnvironment) { + JavaInitializer.addClassProto(this.classMap, this.topScope.context.packages, this) + } + } + } - JavaInitializer.initPackageScope(this.topScope.packageManager) + /** + * 加载缓存后的初始化阶段,会创建一些全局builtin + */ + initAfterUsingCache() { + JavaInitializer.initGlobalScope(this.topScope) + JavaInitializer.initPackageScope(this.topScope.context.packages) + this.assembleClassMap(this.topScope.context.packages) + } - this.assembleClassMap(this.topScope.packageManager) + /** + * + */ + override startAnalyze() { + super.startAnalyze() + FullCallGraphFileEntryPoint.makeFullCallGraphByType(this, this.typeResolver) } /** @@ -1202,76 +1429,241 @@ class JavaAnalyzer extends (Analyzer as any) { */ // eslint-disable-next-line complexity symbolInterpret() { - const { entryPoints } = this as any + const { entryPoints } = this const state = this.initState(this.topScope) if (_.isEmpty(entryPoints)) { logger.info('[symbolInterpret]:EntryPoints are not found') return true } + + for (const entryPoint of entryPoints) { + this.entryPointSymValArray.push(entryPoint.entryPointSymVal) + } + + this.pruneInfoMap.sinkArray = this.loadAllSink() + this.pruneInfoMap.funcCallSourceSinkSanitizerArray.push(...this.pruneInfoMap.sinkArray) + + const allSources = this.loadAllSource() + this.pruneInfoMap.funcCallSourceSinkSanitizerArray.push(...allSources[0]) + this.pruneInfoMap.otherSourceArray = allSources[1] + + const allSanitizers = this.loadAllSanitizer() + this.pruneInfoMap.funcCallSourceSinkSanitizerArray.push(...allSanitizers[0]) + this.pruneInfoMap.otherSanitizerArray = allSanitizers[1] + + const pruneSupported = this.checkPruneSupported(entryPoints.length, this.pruneInfoMap.sinkArray.length) + if (pruneSupported) { + logger.info('EntryPoint Pruning is enabled') + } + + const oldEntryPointTimeoutMs = Config.entryPointTimeoutMs + Config.entryPointTimeoutMs = Config.entryPointTimeoutQuickMs const hasAnalysised: any[] = [] // 自定义source入口方式,并根据入口自主加载source for (const entryPoint of entryPoints) { + this.symbolTable.clear() + entryPoint.entryPointSymVal = this.tmpSymbolTable.tmpTableCopyUnit(entryPoint.entryPointSymVal) + entryPoint.scopeVal = this.tmpSymbolTable.tmpTableCopyUnit(entryPoint.scopeVal) if (entryPoint.type === Constant.ENGIN_START_FUNCALL) { if ( hasAnalysised.includes( - `${entryPoint.filePath}.${entryPoint.functionName}/${entryPoint?.entryPointSymVal?._qid}#${entryPoint.entryPointSymVal.ast.parameters}.${entryPoint.attribute}` + `${entryPoint.filePath}.${entryPoint.functionName}/${entryPoint?.entryPointSymVal?.qid}#${entryPoint.entryPointSymVal.ast.node.parameters}.${entryPoint.attribute}` ) ) { continue } + if (pruneSupported) { + const entrypointCanPrune = this.checkFclosCanPrune(entryPoint.entryPointSymVal) + if (entrypointCanPrune) { + logger.info( + 'EntryPoint [%s.%s] is pruned', + entryPoint.filePath?.substring(0, entryPoint.filePath?.lastIndexOf('.')), + entryPoint.functionName || + `` + ) + continue + } + } + hasAnalysised.push( - `${entryPoint.filePath}.${entryPoint.functionName}/${entryPoint?.entryPointSymVal?._qid}#${entryPoint.entryPointSymVal.ast.parameters}.${entryPoint.attribute}` + `${entryPoint.filePath}.${entryPoint.functionName}/${entryPoint?.entryPointSymVal?.qid}#${entryPoint.entryPointSymVal.ast.node.parameters}.${entryPoint.attribute}` ) CurrentEntryPoint.setCurrentEntryPoint(entryPoint) logger.info( 'EntryPoint [%s.%s] is executing', entryPoint.filePath?.substring(0, entryPoint.filePath?.lastIndexOf('.')), entryPoint.functionName || - `` ) - this.checkerManager.checkAtSymbolInterpretOfEntryPointBefore(this, null, null, null, null) + const overloadedList = entryPoint.entryPointSymVal?.overloaded + if (!overloadedList?.length) { + continue + } - const argValues: any[] = [] - try { - for (const key in entryPoint.entryPointSymVal?.ast?.parameters) { - argValues.push( - this.processInstruction( + for (const overloadFuncDef of overloadedList.filter(() => true)) { + this.checkerManager.checkAtSymbolInterpretOfEntryPointBefore(this, null, null, null, null) + ;(state as any).entryPointStartTimestamp = Date.now() + const argValues: any[] = [] + try { + for (const key in overloadFuncDef?.parameters) { + let argValue = this.processInstruction( entryPoint.entryPointSymVal, - entryPoint.entryPointSymVal?.ast?.parameters[key]?.id, + overloadFuncDef?.parameters[key]?.id, state ) + if (argValue.vtype !== 'symbol') { + argValue.taint.sanitize() + const tmpVal = new SymbolValue(entryPoint.entryPointSymVal.qid, { + sid: overloadFuncDef?.parameters[key]?.id?.name, + parent: entryPoint.entryPointSymVal, + }) + entryPoint.entryPointSymVal.value[tmpVal.sid] = tmpVal + argValue = this.processInstruction( + entryPoint.entryPointSymVal, + overloadFuncDef?.parameters[key]?.id, + state + ) + } + if (overloadFuncDef?.parameters[key]?.varType?.id) { + const val = this.getMemberValueNoCreate( + entryPoint.entryPointSymVal, + overloadFuncDef.parameters[key]?.varType.id, + state + ) + if (val?.vtype === 'class') { + argValue.rtype.definiteType = UastSpec.identifier(val.logicalQid) + } else { + argValue.rtype.definiteType = overloadFuncDef.parameters[key].varType.id + } + } + argValues.push(argValue) + } + } catch (e) { + handleException( + e, + 'Error occurred in JavaAnalyzer.symbolInterpret: process argValue err', + 'Error occurred in JavaAnalyzer.symbolInterpret: process argValue err' ) } - } catch (e) { - handleException( - e, - 'Error occurred in JavaAnalyzer.symbolInterpret: process argValue err', - 'Error occurred in JavaAnalyzer.symbolInterpret: process argValue err' - ) + + try { + this.executeCall(overloadFuncDef, entryPoint.entryPointSymVal, state, entryPoint.scopeVal, { callArgs: this.buildCallArgs(overloadFuncDef, argValues, entryPoint.entryPointSymVal) }) + } catch (e) { + handleException( + e, + `[${overloadFuncDef?.id?.name} symbolInterpret failed. Exception message saved in error log file`, + `[${overloadFuncDef?.id?.name} symbolInterpret failed. Exception message saved in error log file` + ) + if (this.globalState.meetOtherEntryPoint) { + delete this.globalState.meetOtherEntryPoint + } + if (this.globalState.entryPointTimeout) { + delete this.globalState.entryPointTimeout + } + } + + if (this.globalState.meetOtherEntryPoint) { + logger.info( + 'EntryPoint [%s.%s] is interrupted because encountered other entrypoint during execution', + entryPoint.filePath?.substring(0, entryPoint.filePath?.lastIndexOf('.')), + entryPoint.functionName || + `` + ) + delete this.globalState.meetOtherEntryPoint + } + if (this.globalState.entryPointTimeout) { + logger.info( + 'EntryPoint [%s.%s] is interrupted because timeout', + entryPoint.filePath?.substring(0, entryPoint.filePath?.lastIndexOf('.')), + entryPoint.functionName || + `` + ) + delete this.globalState.entryPointTimeout + this.timeoutEntryPoints.push({ + entryPoint, + overloadFuncDef, + argValues, + }) + } + + this.checkerManager.checkAtSymbolInterpretOfEntryPointAfter(this, null, null, null, null) } + } + } + Config.entryPointTimeoutMs = oldEntryPointTimeoutMs + + if (this.timeoutEntryPoints.length > 0) { + this.outputAnalyzerExistResult() + logger.info('Rerun timeout entryPoint with aggressive prune mode') + this.pruneInfoMap.aggressiveMode = true + for (const timeoutEntryPoint of this.timeoutEntryPoints) { + this.symbolTable.clear() + this.checkerManager.checkAtSymbolInterpretOfEntryPointBefore(this, null, null, null, null) try { + CurrentEntryPoint.setCurrentEntryPoint(timeoutEntryPoint.entryPoint) + logger.info( + 'EntryPoint [%s.%s] is executing', + timeoutEntryPoint.entryPoint.filePath?.substring( + 0, + timeoutEntryPoint.entryPoint.filePath?.lastIndexOf('.') + ), + timeoutEntryPoint.entryPoint.functionName || + `` + ) + const newState = state as any + newState.entryPointStartTimestamp = Date.now() this.executeCall( - entryPoint.entryPointSymVal?.ast, - entryPoint.entryPointSymVal, - argValues, + timeoutEntryPoint.overloadFuncDef, + timeoutEntryPoint.entryPoint.entryPointSymVal, state, - entryPoint.scopeVal + timeoutEntryPoint.entryPoint.scopeVal, + { callArgs: this.buildCallArgs(timeoutEntryPoint.overloadFuncDef, timeoutEntryPoint.argValues, timeoutEntryPoint.entryPoint.entryPointSymVal) } ) } catch (e) { handleException( e, - `[${entryPoint.entryPointSymVal?.ast?.id?.name} symbolInterpret failed. Exception message saved in error log file`, - `[${entryPoint.entryPointSymVal?.ast?.id?.name} symbolInterpret failed. Exception message saved in error log file` + `[${timeoutEntryPoint.overloadFuncDef?.id?.name} symbolInterpret failed. Exception message saved in error log file`, + `[${timeoutEntryPoint.overloadFuncDef?.id?.name} symbolInterpret failed. Exception message saved in error log file` + ) + if (this.globalState.meetOtherEntryPoint) { + delete this.globalState.meetOtherEntryPoint + } + if (this.globalState.entryPointTimeout) { + delete this.globalState.entryPointTimeout + } + } + + if (this.globalState.meetOtherEntryPoint) { + delete this.globalState.meetOtherEntryPoint + } + if (this.globalState.entryPointTimeout) { + logger.info( + 'EntryPoint [%s.%s] is interrupted because timeout', + timeoutEntryPoint.entryPoint.filePath?.substring( + 0, + timeoutEntryPoint.entryPoint.filePath?.lastIndexOf('.') + ), + timeoutEntryPoint.entryPoint.functionName || + `` ) + delete this.globalState.entryPointTimeout + this.outputAnalyzerExistResult() } + this.checkerManager.checkAtSymbolInterpretOfEntryPointAfter(this, null, null, null, null) } + this.pruneInfoMap.aggressiveMode = false } + return true } @@ -1280,7 +1672,7 @@ class JavaAnalyzer extends (Analyzer as any) { * @param val - 值 * @returns {boolean} 是否为 null 字面量 */ - isNullLiteral(val: any) { + override isNullLiteral(val: any) { return val.getRawValue() === 'null' && val.type === 'Literal' } @@ -1289,8 +1681,8 @@ class JavaAnalyzer extends (Analyzer as any) { * @param scope - 作用域 * @returns {any[]} 导出作用域数组 */ - getExportsScope(scope: any) { - return [scope.exports, scope] + override getExportsScope(scope: any) { + return [scope.scope.exports, scope] } /** @@ -1301,11 +1693,11 @@ class JavaAnalyzer extends (Analyzer as any) { if (!obj) { return } - if (obj.sort && typeof obj.sort === 'string') { - this.classMap.set(obj.sort, obj) - } else if (obj.field) { - for (const key in obj.field) { - this.assembleClassMap(obj.field[key]) + if (obj.vtype === 'class' && obj.qid && typeof obj.qid === 'string') { + this.classMap.set(obj.logicalQid, obj.uuid) + } else if (obj.members?.size > 0) { + for (const key of obj.members.keys()) { + this.assembleClassMap(obj.members.get(key)) } } } @@ -1317,15 +1709,16 @@ class JavaAnalyzer extends (Analyzer as any) { * @returns {boolean} 是否定义 */ checkFieldDefinedInClass(fieldName: string, fullClassName: string) { + fullClassName = QidUnifyUtil.qidUnifyByRemoveAngleAndPrefix(fullClassName) if (!fieldName || !fullClassName || !this.classMap.has(fullClassName)) { return false } - const classObj = this.classMap.get(fullClassName) - if (!classObj.ast || !classObj.ast.body) { + const classObj = this.symbolTable.get(this.classMap.get(fullClassName)) + if (!classObj.ast.node || !classObj.ast.node.body) { return false } - for (const bodyItem of classObj.ast.body) { + for (const bodyItem of classObj.ast.node.body) { if (bodyItem.type !== 'VariableDeclaration') { continue } @@ -1348,17 +1741,437 @@ class JavaAnalyzer extends (Analyzer as any) { return null } while (scope) { - if (scope._qid === qid) { + if (QidUnifyUtil.removeInstanceFromString(scope.qid) === QidUnifyUtil.removeInstanceFromString(qid)) { return scope } scope = scope.parent } return null } + + /** + * find invocations in scope by node hash + * @param scope + * @param node + * @returns {Invocation[]} + */ + findNodeInvocations(scope: any, node: any): Invocation[] { + const resultArray: Invocation[] = [] + const nodeHash = node?._meta?.nodehash + if (!nodeHash) { + return resultArray + } + + let targetScope = scope + while (targetScope) { + if (targetScope.invocationMap?.has(nodeHash)) { + resultArray.push(...targetScope.invocationMap.get(nodeHash)) + break + } + targetScope = targetScope.parent + } + return resultArray + } + + /** + * build new object + * @param fdef + * @param argvalues + * @param fclos + * @param state + * @param node + * @param scope + */ + override buildNewObject(fdef: any, fclos: any, state: any, node: any, scope: any, callInfo: CallInfo) { + const obj = super.buildNewObject(fdef, fclos, state, node, scope, callInfo) + if (obj && node.callee?.type === 'MemberAccess' && /^[1-9]\d*$/.test(node.callee.property.name)) { + obj.length = Number(node.callee.property.name) + } + delete obj.value.class + return obj + } + + /** + * load all sink from rule + */ + loadAllSink() { + const resultArray = [] + const ruleConfigArray = BasicRuleHandler.getRules() + for (const ruleConfig of ruleConfigArray) { + if (!ruleConfig.sinks) { + continue + } + for (const sinkArray of Object.values(ruleConfig.sinks)) { + if (Array.isArray(sinkArray)) { + resultArray.push(...sinkArray) + } + } + } + return resultArray + } + + /** + * load all source from rule + */ + loadAllSource() { + const funcCallSourceArray = [] + const otherSourceArray = [] + const ruleConfigArray = BasicRuleHandler.getRules() + for (const ruleConfig of ruleConfigArray) { + if (!ruleConfig.sources) { + continue + } + for (const key of Object.keys(ruleConfig.sources)) { + if (key.startsWith('FuncCall')) { + funcCallSourceArray.push(...ruleConfig.sources[key]) + } else { + otherSourceArray.push(...ruleConfig.sources[key]) + } + } + } + return [funcCallSourceArray, otherSourceArray] + } + + /** + * load all sanitizer from rule + */ + loadAllSanitizer() { + const funcCallSanitizerArray = [] + const otherSanitizerArray = [] + const ruleConfigArray = BasicRuleHandler.getRules() + for (const ruleConfig of ruleConfigArray) { + if (!ruleConfig.sanitizers) { + continue + } + for (const sanitizer of ruleConfig.sanitizers) { + if (sanitizer.sanitizerType === 'FunctionCallSanitizer') { + funcCallSanitizerArray.push(sanitizer) + } else { + otherSanitizerArray.push(sanitizer) + } + } + } + return [funcCallSanitizerArray, otherSanitizerArray] + } + + /** + * check if prune is supported + * @param entryPointNum + * @param sinkNum + */ + checkPruneSupported(entryPointNum: number, sinkNum: number) { + if (entryPointNum < Config.minEntryPointToEnablePrune || sinkNum <= 0 || Config.makeAllCG) { + return false + } + return !!(this.typeResolver.resolveFinish && this.ainfo?.callgraph) + } + + /** + * check if prune is supported during symbol interpret + * @param sinkNum + * @param otherSanitizerNum + */ + checkPruneSupportedDuringInterpret(sinkNum: number, otherSanitizerNum: number) { + if (sinkNum <= 0 || otherSanitizerNum > 0 || Config.makeAllCG) { + return false + } + return !!(this.typeResolver.resolveFinish && this.ainfo?.callgraph) + } + + /** + * check if fclos can be pruned + * @param fclos + */ + checkFclosCanPrune(fclos: any) { + if (!fclos) { + return false + } + const matchSink = this.checkFclosMatchSink( + fclos, + [], + this.pruneInfoMap.sinkArray, + this.pruneInfoMap.matchSinkCacheMap, + true + ) + return !matchSink + } + + /** + * check if fclos can be pruned during executing + * @param fclos + * @param node + * @param argvalues + * @param state + * @param fromCallGraph + */ + checkFclosCanPruneDuringInterpret(fclos: any, node: any, argvalues: any, state: any, fromCallGraph: boolean) { + if (this.pruneInfoMap.aggressiveMode && state?.callstack?.length >= Config.maxCallstackDepth) { + return true + } + + if (Array.isArray(node.arguments)) { + for (const argument of node.arguments) { + if (argument.type === 'Sequence' || argument.type === 'FunctionDefinition') { + return false + } + } + } + if (Array.isArray(argvalues)) { + for (const argvalue of argvalues) { + if (argvalue.vtype === 'class' || argvalue.vtype === 'fclos') { + return false + } + } + } + + if ( + !this.enablePruneDuringInterpret || + !fclos || + !fclos.ast.fdef || + !this.checkPruneSupportedDuringInterpret( + this.pruneInfoMap.sinkArray.length, + this.pruneInfoMap.otherSanitizerArray.length + ) + ) { + return false + } + const matchSourceSinkSanitizer = this.checkFclosMatchSink( + fclos, + [], + this.pruneInfoMap.funcCallSourceSinkSanitizerArray, + this.pruneInfoMap.matchFuncCallSourceSinkSanitizerCacheMap, + true + ) + if (matchSourceSinkSanitizer) { + return false + } + + if (fromCallGraph) { + return !matchSourceSinkSanitizer + } + return false + } + + /** + * check if fclos match any sink, ignore sub fclos + * @param fclos + * @param sinkArray + * @param matchSinkCacheMap + * @param checkUseDynamicFeature + */ + checkFclosMatchSinkNoRecurse( + fclos: any, + sinkArray: any[], + matchSinkCacheMap: Map, + checkUseDynamicFeature: boolean + ) { + if (!fclos || !fclos.invocationMap || !sinkArray) { + matchSinkCacheMap.set(fclos, false) + return false + } + + if (matchSinkCacheMap.has(fclos)) { + return matchSinkCacheMap.get(fclos) + } + + for (const invocationArray of fclos.invocationMap.values()) { + for (const invocation of invocationArray) { + if (checkUseDynamicFeature) { + for (const dynamicClass of this.pruneInfoMap.dynamicClassArray) { + if (dynamicClass === invocation.calleeType || invocation.calleeType?.endsWith(`.${dynamicClass}`)) { + matchSinkCacheMap.set(fclos, true) + return true + } + } + for (const dynamicPackage of this.pruneInfoMap.dynamicPackageArray) { + if (invocation.calleeType?.startsWith(`${dynamicPackage}.`)) { + matchSinkCacheMap.set(fclos, true) + return true + } + } + } + + for (const sink of sinkArray) { + const invocationMatchSink: boolean = checkInvocationMatchSink(invocation, sink, this.typeResolver) + if (invocationMatchSink) { + matchSinkCacheMap.set(fclos, true) + return true + } + } + } + } + + matchSinkCacheMap.set(fclos, false) + return false + } + + /** + * check if fclos match any sink + * @param fclos + * @param fclosStack + * @param sinkArray + * @param matchSinkCacheMap + * @param checkUseDynamicFeature + */ + checkFclosMatchSink( + fclos: any, + fclosStack: any[], + sinkArray: any[], + matchSinkCacheMap: Map, + checkUseDynamicFeature: boolean + ) { + if (!fclos || !fclos.invocationMap || !sinkArray) { + matchSinkCacheMap.set(fclos, false) + return false + } + + if (matchSinkCacheMap.has(fclos)) { + return matchSinkCacheMap.get(fclos) + } + + // if (checkUseDynamicFeature) { + // const innerFuncDefVisitor = new InnerFuncDefVisitor() + // if (Array.isArray(fclos.overloaded)) { + // for (const funcDef of fclos.overloaded) { + // innerFuncDefVisitor.matchFuncDefCount = 0 + // AstUtil.visit(funcDef, innerFuncDefVisitor) + // if (innerFuncDefVisitor.matchFuncDefCount > 1) { + // matchSinkCacheMap.set(fclos, true) + // return true + // } + // } + // } + // } + + const toScopeArray = [] + for (const invocationArray of fclos.invocationMap.values()) { + for (const invocation of invocationArray) { + if (checkUseDynamicFeature) { + for (const dynamicClass of this.pruneInfoMap.dynamicClassArray) { + if (dynamicClass === invocation.calleeType || invocation.calleeType?.endsWith(`.${dynamicClass}`)) { + matchSinkCacheMap.set(fclos, true) + return true + } + } + for (const dynamicPackage of this.pruneInfoMap.dynamicPackageArray) { + if (invocation.calleeType?.startsWith(`${dynamicPackage}.`)) { + matchSinkCacheMap.set(fclos, true) + return true + } + } + } + + for (const sink of sinkArray) { + const invocationMatchSink: boolean = checkInvocationMatchSink(invocation, sink, this.typeResolver) + if (invocationMatchSink) { + matchSinkCacheMap.set(fclos, true) + return true + } + } + + if (invocation.toScope?.vtype === 'fclos') { + toScopeArray.push(invocation.toScope) + } + } + } + + fclosStack.push(fclos) + const analysedScopeArray: any[] = [] + for (const toScope of toScopeArray) { + if (analysedScopeArray.includes(toScope) || fclosStack.includes(toScope)) { + continue + } + analysedScopeArray.push(toScope) + const subResult = this.checkFclosMatchSink( + toScope, + fclosStack, + sinkArray, + matchSinkCacheMap, + checkUseDynamicFeature + ) + if (subResult) { + matchSinkCacheMap.set(fclos, true) + return true + } + } + fclosStack.pop() + + matchSinkCacheMap.set(fclos, false) + return false + } + + /** + * Resolve UUID-backed values before mutating them during transitional storage migration. + * @param value + */ + private resolveRuntimeValueRef(value: T): T | any { + if (typeof value === 'string' && value.startsWith('symuuid_')) { + return this.symbolTable.get(value) ?? value + } + return value + } + + /** + * add rtype to arg + * @param argAst + * @param argValue + */ + addRtypeToArg(argAst: any, argValue: any) { + const resolvedArgValue = this.resolveRuntimeValueRef(argValue) + if ( + !argAst || + !argAst._meta || + !argAst._meta.nodehash || + !resolvedArgValue || + typeof resolvedArgValue !== 'object' || + (resolvedArgValue.rtype?.definiteType && !resolvedArgValue.rtype.vagueType) || + !(this.typeResolver?.typeResultCacheMap instanceof Map) || + !this.typeResolver.typeResultCacheMap.has(argAst._meta.nodehash) + ) { + return + } + + const resolvedTypeArray = this.typeResolver.typeResultCacheMap.get(argAst._meta.nodehash) + for (const resolvedType of resolvedTypeArray) { + if (resolvedType?.type !== '') { + if (!resolvedArgValue.rtype) { + resolvedArgValue.rtype = { type: undefined } + } + resolvedArgValue.rtype.definiteType = UastSpec.identifier(resolvedType.type) + return + } + } + } + + /** + * check if fclos in interface or abstract class + * @param fclos + */ + checkFclosInInterfaceOrAbstractClass(fclos: any) { + return !!( + (fclos?.parent?.vtype === 'class' && + (fclos.parent.ast?.node?._meta?.isAbstract || fclos.parent.ast?.node?._meta?.isInterface)) || + (fclos?.ast.fdef?.parent?.type === 'ClassDefinition' && + (fclos.ast.fdef.parent._meta?.isAbstract || fclos.ast.fdef.parent._meta?.isInterface)) + ) + } + + /** + * + * @param className + * @param baseClassName + */ + addExtraClassHierarchyByName(className: string, baseClassName: string) { + if (!this.extraClassHierarchyByNameMap.has(className)) { + this.extraClassHierarchyByNameMap.set(className, []) + } + if (!this.extraClassHierarchyByNameMap.get(className).includes(baseClassName)) { + this.extraClassHierarchyByNameMap.get(className).push(baseClassName) + } + } } ;(JavaAnalyzer as any).prototype.initFileScope = JavaInitializer.initFileScope -;(JavaAnalyzer as any).prototype.initInPackageScope = JavaInitializer.initInPackageScope export = JavaAnalyzer diff --git a/src/engine/analyzer/java/common/java-initializer.ts b/src/engine/analyzer/java/common/java-initializer.ts index cb90955b..f36b5c7b 100644 --- a/src/engine/analyzer/java/common/java-initializer.ts +++ b/src/engine/analyzer/java/common/java-initializer.ts @@ -1,14 +1,16 @@ const jsonfile = require('jsonfile') const _ = require('lodash') +const path = require('path') +const QidUnifyUtil = require('../../../../util/qid-unify-util') const { ValueUtil: { ObjectValue, FunctionValue, Scoped }, getValueFromPackageByQid, } = require('../../../util/value-util') - const lombok = require('./builtins/lombok') const config = require('../../../../config') const { getAbsolutePath } = require('../../../../util/file-util') const Scope = require('../../common/scope') +const { buildNewValueInstance } = require('../../../../util/clone-util') /** * */ @@ -49,34 +51,23 @@ class JavaInitializer { // init for module // const modScope = {id:file, vtype: 'modScope', value:{}, closure:{}, decls:node, parent : this.topScope, fdef:node}; if (!file) return - const relateFileName = file.startsWith(config.maindirPrefix) - ? file.substring(config.maindirPrefix.length).split('.')[0] - : file.split('.')[0] - const fileClos = Scoped({ + const relativePath = file.substring(config.maindirPrefix.length) + const filename = path.basename(relativePath, path.extname(relativePath)) + const fileClos = new Scoped('', { + sid: filename, qid: packageScope.qid, - sid: relateFileName, parent: packageScope, decls: {}, - fdef: node, ast: node, }) + fileClos.ast.fdef = node fileClos._this = fileClos fileClos.isProcessed = false - fileClos.exports = packageScope.exports + fileClos.scope.exports = packageScope.scope.exports return fileClos } - /** - * - * @param packageName - */ - static initInPackageScope(packageName: any) { - const packageClos = Scoped({ sid: 'package', parent: (this as any).topScope, decls: {} }) - packageClos._this = packageClos - return packageClos - } - /** * modeling for base type and subtypes in java.lang * @param scope @@ -120,32 +111,32 @@ class JavaInitializer { continue } - const classScope = Scope.createSubScope(className, scope, 'class') - classScope.sort = classScope.qid = fullClassName + const classScope = Scope.createSubScope(className, scope, 'class', fullClassName) for (const method of methods) { if (fullClassName === baseType && method.name === className) { baseClsCtor = method } const targetQid = `${classScope.qid}.${method.name}` - classScope.value[method.name] = FunctionValue({ + classScope.value[method.name] = new FunctionValue('', { sid: method.name, qid: targetQid, parent: classScope, - execute: method, + runtime: { execute: method }, _this: classScope, }) } if (baseClsCtor) { - classScope.execute = baseClsCtor + if (!classScope.runtime) classScope.runtime = {} + classScope.runtime.execute = baseClsCtor if (fullClassName !== baseType) { const targetQid = `${classScope.qid}.${className}` - classScope.value[className] = FunctionValue({ + classScope.value[className] = new FunctionValue('', { sid: className, qid: targetQid, parent: classScope, - execute: baseClsCtor, + runtime: { execute: baseClsCtor }, _this: classScope, }) } @@ -203,40 +194,53 @@ class JavaInitializer { className = fullClassName.substring(lastDotIndex + 1) } const packageScope = packageName ? scope.getSubPackage(packageName, true) : scope - const classScope = Scope.createSubScope(className, packageScope, 'class') - if (!packageScope.exports) { - packageScope.exports = Scoped({ + let classScope + if (packageScope.members.has(className)) { + classScope = packageScope.members.get(className) + } + if (!classScope) { + classScope = Scope.createSubScope(className, packageScope, 'class', Scope.joinQualifiedName(packageScope.qid, className)) + } + if (!packageScope.scope.exports) { + packageScope.scope.exports = new Scoped(packageScope.qid, { sid: 'exports', - id: 'exports', parent: packageScope, }) } - packageScope.exports.value[className] = classScope - classScope.sort = classScope.qid = Scope.joinQualifiedName(packageScope.qid, className) + packageScope.scope.exports.value[className] = classScope for (const method of methods) { if (fullClassName === baseType && method.name === className) { baseClsCtor = method } - const targetQid = `${classScope.qid}.${method.name}` - classScope.value[method.name] = FunctionValue({ - sid: method.name, - qid: targetQid, - parent: classScope, - execute: method, - _this: classScope, - }) + + if (classScope.value[method.name]) { + const fclos = classScope.value[method.name] + if (!fclos.runtime) fclos.runtime = {} + fclos.runtime.execute = method + fclos._this = classScope + } else { + const targetQid = `${classScope.qid}.${method.name}` + classScope.value[method.name] = new FunctionValue('', { + sid: method.name, + qid: targetQid, + parent: classScope, + runtime: { execute: method }, + _this: classScope, + }) + } } if (baseClsCtor) { - classScope.execute = baseClsCtor + if (!classScope.runtime) classScope.runtime = {} + classScope.runtime.execute = baseClsCtor if (fullClassName !== baseType) { const targetQid = `${classScope.qid}.${className}` - classScope.value[className] = FunctionValue({ + classScope.value[className] = new FunctionValue('', { sid: className, qid: targetQid, parent: classScope, - execute: baseClsCtor, + runtime: { execute: baseClsCtor }, _this: classScope, }) } @@ -258,32 +262,29 @@ class JavaInitializer { * @param scope */ static initRuntimeBuiltin(scope: any) { - const Runtime = ObjectValue({ - id: 'Runtime', + const Runtime = new ObjectValue('', { sid: 'Runtime', qid: `Runtime`, parent: scope, }) scope.setFieldValue('Runtime', Runtime) - const getRuntime = FunctionValue({ - id: 'getRuntime', + const getRuntime = new FunctionValue('', { sid: 'getRuntime', qid: `Runtime.getRuntime()`, parent: scope, }) Runtime.setFieldValue('getRuntime()', getRuntime) - const runtimeExec = FunctionValue({ - id: 'exec', + const runtimeExec = new FunctionValue('', { sid: 'exec', qid: `Runtime.getRuntime().exec`, parent: getRuntime, }) getRuntime.setFieldValue('exec', runtimeExec) - if (scope.funcSymbolTable) { + if (scope.context?.funcs) { // eslint-disable-next-line no-param-reassign - scope.funcSymbolTable['Runtime.getRuntime()'] = getRuntime + scope.context.funcs['Runtime.getRuntime()'] = getRuntime // eslint-disable-next-line no-param-reassign - scope.funcSymbolTable['Runtime.getRuntime().exec'] = runtimeExec + scope.context.funcs['Runtime.getRuntime().exec'] = runtimeExec } } @@ -292,48 +293,52 @@ class JavaInitializer { * @param scope */ static initThreadBuiltin(scope: any) { - const Thread = ObjectValue({ - id: 'Thread', + const Thread = new ObjectValue('', { sid: 'Thread', qid: `Thread`, parent: scope, }) scope.setFieldValue('Thread', Thread) - const start = FunctionValue({ - // val为当前符号值,qid为当前坐标, s为scope,返回为预期的fclos - jumpLocate: (val: any, qid: any, s: any) => { - if (s && qid) { - let current = s - while (current) { - if (current.sid === '') { - break + const start = new FunctionValue('', { + func: { + // val为当前符号值,qid为当前坐标, s为scope,返回为预期的fclos + jumpLocate: (val: any, qid: any, s: any) => { + if (s && qid) { + let current = s + while (current) { + if (current.sid === '') { + break + } + current = current.parent + } + const funcs = current.context?.funcs + + // 将 jumpFrom 替换为 jumpTo + const targetQid = qid + .replace(//g, '') + .split('.') + .map((segment: string) => { + return segment === 'start' ? 'run' : segment + }) + .join('.') + if (funcs && funcs[QidUnifyUtil.qidUnifyByRemoveAngleAndPrefix(targetQid)]) { + return funcs[QidUnifyUtil.qidUnifyByRemoveAngleAndPrefix(targetQid)] } - current = current.parent - } - const { funcSymbolTable } = current - - // 将 jumpFrom 替换为 jumpTo - const targetQid = qid - .replace(//g, '') - .split('.') - .map((segment: string) => { - return segment === 'start' ? 'run' : segment - }) - .join('.') - if (funcSymbolTable[targetQid]) { - return funcSymbolTable[targetQid] - } - if (s.arguments instanceof Array) { - for (const argument of s.arguments) { - if (argument.sort?.endsWith('.Runnable') && argument.field?.run) { - return argument.field.run + if (s.arguments instanceof Array) { + for (const argument of s.arguments) { + const runMethod = argument.members?.get('run') + if (argument.qid?.includes('.Runnable<') && runMethod) { + return runMethod + } } } } - } - return undefined + return undefined + }, }, + sid: 'start', + qid: `Thread.start`, parent: Thread, }) Thread.setFieldValue('start', start) @@ -344,22 +349,15 @@ class JavaInitializer { * @param scope */ static initExecutorsBuiltin(scope: any) { - const Executor = getValueFromPackageByQid(scope, 'java.util.concurrent.Executor') - if (!Executor || !Executor.field) { + const ExecutorService = getValueFromPackageByQid(scope, 'java.util.concurrent.ExecutorService') + if (!ExecutorService || !ExecutorService.members) { return } let Executors = getValueFromPackageByQid(scope, 'java.util.concurrent.Executors') if (!Executors) { - Executors = ObjectValue({ - id: 'Executors', - sid: 'Executors', - qid: 'Executors', - parent: scope, - }) - scope.setFieldValue('Executors', Executors) - } else { - Executors.field = {} + const packageScope = scope.getSubPackage('java.util.concurrent', true) + Executors = Scope.createSubScope('Executors', packageScope, 'class') } const returnExecutorFuncNames = [ 'newCachedThreadPool', @@ -375,16 +373,23 @@ class JavaInitializer { 'unconfigurableScheduledExecutorService', ] for (const returnExecutorFuncName of returnExecutorFuncNames) { - const returnExecutorFunc = FunctionValue({ - id: returnExecutorFuncName, - sid: returnExecutorFuncName, - qid: `java.util.concurrent.Executors.${returnExecutorFuncName}`, - parent: scope, - execute: () => { - return Executor - }, - }) - Executors.setFieldValue(`${returnExecutorFuncName}`, returnExecutorFunc) + if (Executors.value[returnExecutorFuncName]) { + const fclos = Executors.value[returnExecutorFuncName] + if (!fclos.runtime) fclos.runtime = {} + fclos.runtime.execute = () => { + return ExecutorService + } + } else { + const returnExecutorFunc = new FunctionValue('', { + sid: returnExecutorFuncName, + qid: `java.util.concurrent.Executors.${returnExecutorFuncName}`, + parent: scope, + runtime: { execute: () => { + return ExecutorService + } }, + }) + Executors.setFieldValue(`${returnExecutorFuncName}`, returnExecutorFunc) + } } } @@ -398,7 +403,7 @@ class JavaInitializer { static resetInitVariables(scope: any) { for (const field of Object.keys(scope.value)) { const v = scope.value[field] - if (v.trace) delete v.trace + if (v.taint) v.taint.clearTrace() } } @@ -420,6 +425,55 @@ class JavaInitializer { return methods } + + /** + * add default property to class + * @param classMap + * @param scope + * @param analyzer + */ + static addClassProto(classMap: Map, scope: any, analyzer: any) { + if (!classMap) { + return + } + const protoClsVal = getValueFromPackageByQid(scope, 'java.lang.Class') + const objectClsVal = getValueFromPackageByQid(scope, 'java.lang.Object') + for (const classValUUid of classMap.values()) { + const classVal = analyzer.symbolTable.get(classValUUid) + classVal.value.class = JavaInitializer.buildClassProtoObject(protoClsVal, classVal, analyzer) + if (!classVal.value.getClass) { + classVal.value.getClass = objectClsVal.value.getClass + } + } + } + + /** + * build class proto object + * @param protoVal + * @param classVal + * @param analyzer + * @returns {*} + */ + static buildClassProtoObject(protoVal: any, classVal: any, analyzer: any) { + const qidSuffix = `_` + const obj = buildNewValueInstance( + analyzer, + protoVal, + null, + protoVal.parent, + (x: any) => { + return x === 'class' + }, + (v: any) => { + return !v + }, + 1, + qidSuffix + ) + obj.parent = analyzer.symbolTable.get(classVal.uuid) + + return obj + } } export = JavaInitializer diff --git a/src/engine/analyzer/java/spring/entrypoint-collector/spring-default-entrypoint.ts b/src/engine/analyzer/java/spring/entrypoint-collector/spring-default-entrypoint.ts index c97535ee..3bd62561 100644 --- a/src/engine/analyzer/java/spring/entrypoint-collector/spring-default-entrypoint.ts +++ b/src/engine/analyzer/java/spring/entrypoint-collector/spring-default-entrypoint.ts @@ -12,6 +12,8 @@ const defaultSpringAnnotations = [ 'DeleteMapping', 'PatchMapping', 'Path', + 'Tool', + 'McpTool', ] /** @@ -20,43 +22,69 @@ const defaultSpringAnnotations = [ */ function getSpringEntryPointAndSource(packageManager: any) { const TaintSource: any[] = [] - let entryPoints = AstUtil.satisfy( - packageManager, - (n: any) => - n.vtype === 'fclos' && - n.ast?._meta && - n.ast?._meta.modifiers && - n.ast?._meta.modifiers.some((m: any) => - defaultSpringAnnotations.some((annotation: any) => m.includes(annotation)) - ), - (node: any, prop: any) => prop === 'field', - null, - true - ) - if (!entryPoints) { - entryPoints = [] - } else if (!Array.isArray(entryPoints)) { - entryPoints = [entryPoints] + + const entryPoints = [] + const visited = new Set() + let list = [] + list.push(packageManager) + while (list.length > 0) { + const newList = [] + for (const item of list) { + if (!item || visited.has(item)) continue + visited.add(item) + if (item.vtype === 'fclos') { + if ( + !item.ast.node || + item.ast.node.type !== 'FunctionDefinition' || + !item.ast.node._meta || + !Array.isArray(item.ast.node._meta.modifiers) + ) { + continue + } + for (const modifier of item.ast.node._meta.modifiers) { + let found = false + for (const springAnnotation of defaultSpringAnnotations) { + if (modifier.includes(springAnnotation)) { + found = true + break + } + } + if (found) { + entryPoints.push(item) + break + } + } + } else if (item.vtype === 'class' || item.vtype === 'package') { + if (item.members?.size > 0) { + for (const key of item.members.keys()) { + const member = item.members.get(key) + if (member) newList.push(member) + } + } + } + } + list = newList } + for (const entrypoint of entryPoints) { - if (entrypoint.vtype === 'fclos' && entrypoint.ast?.loc?.sourcefile) { + if (entrypoint.vtype === 'fclos' && entrypoint.ast?.node?.loc?.sourcefile) { const mainDirPrefix = Config.maindirPrefix entrypoint.filePath = mainDirPrefix - ? entrypoint.ast?.loc.sourcefile.substring( - entrypoint.ast?.loc.sourcefile.indexOf(mainDirPrefix) + mainDirPrefix.length + ? entrypoint.ast?.node?.loc.sourcefile.substring( + entrypoint.ast?.node?.loc.sourcefile.indexOf(mainDirPrefix) + mainDirPrefix.length ) - : entrypoint.ast?.loc.sourcefile + : entrypoint.ast?.node?.loc.sourcefile entrypoint.functionName = entrypoint.sid entrypoint.attribute = 'HTTP' } - if (entryPointAndSourceAtSameTime && entrypoint.ast?.parameters && entrypoint.ast?.id.type === 'Identifier') { - for (const param of entrypoint.ast.parameters) { + if (entryPointAndSourceAtSameTime && entrypoint.ast?.node?.parameters && entrypoint.ast?.node?.id.type === 'Identifier') { + for (const param of entrypoint.ast.node.parameters) { if (param.type === 'VariableDeclaration' && param.id?.type === 'Identifier') { TaintSource.push({ introPoint: 4, path: param.id.name, - scopeFunc: entrypoint.ast.id.name, - scopeFile: entrypoint.ast.loc?.sourcefile, + scopeFunc: entrypoint.ast.node.id.name, + scopeFile: entrypoint.ast.node.loc?.sourcefile, locStart: param.id.loc?.start.line, locEnd: param.id.loc?.end.line, locColumnStart: param.id.loc?.start.column, diff --git a/src/engine/analyzer/java/spring/spring-analyzer.ts b/src/engine/analyzer/java/spring/spring-analyzer.ts index 310affba..16f4fca0 100644 --- a/src/engine/analyzer/java/spring/spring-analyzer.ts +++ b/src/engine/analyzer/java/spring/spring-analyzer.ts @@ -1,125 +1,373 @@ +import JavaInitializer from '../common/java-initializer' +import { INTERNAL_CALL } from '../../common/call-args' + +const UastSpec = require('@ant-yasa/uast-spec') +const Config = require('../../../../config') const logger = require('../../../../util/logger')(__filename) -const JavaAnalyzer = require('../common/java-analyzer') +const JavaAnalyzer: typeof import('../common/java-analyzer') = require('../common/java-analyzer') const AstUtil = require('../../../../util/ast-util') const Initializer = require('./spring-initializer') const _ = require('lodash') const entryPointConfig = require('../../common/current-entrypoint') const constValue = require('../../../../util/constant') const { handleException } = require('../../common/exception-handler') +const FullCallGraphFileEntryPoint = require('../../../../checker/common/full-callgraph-file-entrypoint') +const Rules = require('../../../../checker/common/rules-basic-handler') +const { newInstance } = require('../common/builtins/object') +const { + ValueUtil: { SymbolValue }, +} = require('../../../util/value-util') +const QidUnifyUtil = require('../../../../util/qid-unify-util') +const { getLegacyArgValues } = require('../../common/call-args') +import type { Scope, State, Value } from '../../../../types/analyzer' +import type { + VariableDeclaration, + FunctionDefinition, + ClassDefinition, + Expr, + Stmt, + Decl, + AssignmentExpression, + Literal, + ScopedStatement, +} from '../../../../types/uast' + +type EntryPointSymVal = { + qid?: string + ast?: { node?: { parameters?: unknown; loc: { start: { line: number }; end: { line: number } } } } + overloaded?: FunctionDefinition[] + value?: Record +} + +type EntryPoint = { + type?: string + filePath?: string + functionName?: string + attribute?: string + entryPointSymVal?: EntryPointSymVal + scopeVal?: unknown +} + +type SymbolValueType = ReturnType /** * */ -class SpringAnalyzer extends (JavaAnalyzer as any) { +class SpringAnalyzer extends JavaAnalyzer { /** * * @param options */ - constructor(options: any) { + constructor(options: Record) { super(options) this.beanReferenceAnnotationByName = ['@SofaReference', '@OsgiReference', '@Qualifier', '@Resource'] this.beanReferenceAnnotationByClass = ['@Autowired', '@Resource', '@TestBean'] - this.beanServiceAnnotationOnClass = ['@Component', '@Service', '@Repository'] + this.beanServiceAnnotationOnClass = ['@Component', '@Service', '@Repository', '@SofaService'] this.beanServiceAnnotationOnFunction = ['@Bean'] } /** - * - * @param dir + * 预处理前的初始化阶段,会创建一些全局builtin */ - async preProcess(dir: any) { + override initAfterUsingCache() { // init global scope Initializer.initGlobalScope(this.topScope) + Initializer.initPackageScope(this.topScope.context.packages) + this.assembleClassMap(this.topScope.context.packages) + } - // time-out control - ;(this as any).thisIterationTime = 0 - ;(this as any).prevIterationTime = new Date().getTime() + /** + * + * @param dir + */ + override async preProcess(dir: string) { + Initializer.initGlobalScope(this.topScope) + Initializer.initPackageScope(this.topScope.context.packages, this) await Initializer.initBeans(this.topScope, dir) await this.scanPackages(dir) - Initializer.initPackageScope(this.topScope.packageManager) + if (!Config.miniSaveContextEnvironment) { + this.assembleClassMap(this.topScope.context.packages) + this.compensateDependencyInjection(this.classMap) + if (!Config.loadContextEnvironment) { + JavaInitializer.addClassProto(this.classMap, this.topScope.context.packages, this) + } + } + } - this.assembleClassMap(this.topScope.packageManager) + /** + * + */ + override startAnalyze() { + super.startAnalyze() + this.adJustDependencyInjection(this.classMap, this.topScope.context.packages) } /** * * */ - symbolInterpret() { - const { entryPoints } = this as any - const state = this.initState(this.topScope) + override symbolInterpret() { + type EntryPoint = { + type?: string + filePath?: string + functionName?: string + attribute?: string + entryPointSymVal?: { + qid?: string + ast?: { node?: { parameters?: unknown; loc: { start: { line: number }; end: { line: number } } } } + overloaded?: unknown[] + value?: Record + } + scopeVal?: unknown + } + const entryPoints = (this as { entryPoints?: EntryPoint[] }).entryPoints ?? [] + const state = this.initState(this.topScope) as State & { entryPointStartTimestamp?: number | null } if (_.isEmpty(entryPoints)) { logger.info('[symbolInterpret]:EntryPoints are not found') return true } - const hasAnalysised: any[] = [] + + for (const entryPoint of entryPoints) { + this.entryPointSymValArray.push(entryPoint.entryPointSymVal) + } + + this.pruneInfoMap.sinkArray = this.loadAllSink() + this.pruneInfoMap.funcCallSourceSinkSanitizerArray.push(...this.pruneInfoMap.sinkArray) + + const allSources = this.loadAllSource() + this.pruneInfoMap.funcCallSourceSinkSanitizerArray.push(...allSources[0]) + this.pruneInfoMap.otherSourceArray = allSources[1] + + const allSanitizers = this.loadAllSanitizer() + this.pruneInfoMap.funcCallSourceSinkSanitizerArray.push(...allSanitizers[0]) + this.pruneInfoMap.otherSanitizerArray = allSanitizers[1] + + const pruneSupported = this.checkPruneSupported(entryPoints.length, this.pruneInfoMap.sinkArray.length) + if (pruneSupported) { + logger.info('EntryPoint Pruning is enabled') + } + + const oldEntryPointTimeoutMs = Config.entryPointTimeoutMs + Config.entryPointTimeoutMs = Config.entryPointTimeoutQuickMs + const hasAnalysised: string[] = [] // 自定义source入口方式,并根据入口自主加载source for (const entryPoint of entryPoints) { + this.symbolTable.clear() + entryPoint.entryPointSymVal = this.tmpSymbolTable.tmpTableCopyUnit(entryPoint.entryPointSymVal) + entryPoint.scopeVal = this.tmpSymbolTable.tmpTableCopyUnit(entryPoint.scopeVal) + const symVal = entryPoint.entryPointSymVal + if (!symVal || !symVal.ast?.node) { + continue + } if (entryPoint.type === constValue.ENGIN_START_FUNCALL) { if ( hasAnalysised.includes( - `${entryPoint.filePath}.${entryPoint.functionName}/${entryPoint?.entryPointSymVal?._qid}#${entryPoint.entryPointSymVal.ast.parameters}.${entryPoint.attribute}` + `${entryPoint.filePath}.${entryPoint.functionName}/${symVal.qid}#${symVal.ast?.node?.parameters}.${entryPoint.attribute}` ) ) { continue } + if (pruneSupported) { + const entrypointCanPrune = this.checkFclosCanPrune(symVal) + if (entrypointCanPrune) { + logger.info( + 'EntryPoint [%s.%s] is pruned', + entryPoint.filePath?.substring(0, entryPoint.filePath?.lastIndexOf('.')), + entryPoint.functionName || + `` + ) + continue + } + } + hasAnalysised.push( - `${entryPoint.filePath}.${entryPoint.functionName}/${entryPoint?.entryPointSymVal?._qid}#${entryPoint.entryPointSymVal.ast.parameters}.${entryPoint.attribute}` + `${entryPoint.filePath}.${entryPoint.functionName}/${symVal.qid}#${symVal.ast?.node?.parameters}.${entryPoint.attribute}` ) entryPointConfig.setCurrentEntryPoint(entryPoint) logger.info( 'EntryPoint [%s.%s] is executing', entryPoint.filePath?.substring(0, entryPoint.filePath?.lastIndexOf('.')), entryPoint.functionName || - `` ) - this.checkerManager.checkAtSymbolInterpretOfEntryPointBefore(this, null, null, null, null) + if (!(symVal as any).overloaded?.length) { + continue + } - const argValues: any[] = [] - try { - for (const key in entryPoint.entryPointSymVal?.ast?.parameters) { - argValues.push( - this.processInstruction( - entryPoint.entryPointSymVal, - entryPoint.entryPointSymVal?.ast?.parameters[key].id, + for (const overloadFuncDef of (symVal as any).overloaded.filter(() => true)) { + const fdef = overloadFuncDef as FunctionDefinition + this.checkerManager.checkAtSymbolInterpretOfEntryPointBefore(this, null, null, null, null) + + state.entryPointStartTimestamp = Date.now() + const argValues: Value[] = [] + try { + for (const param of fdef.parameters ?? []) { + if (!param) continue + let argValue = this.processInstruction( + symVal, + param.id, state ) + if (argValue.vtype !== 'symbol') { + argValue.taint.sanitize() + const sid = param.id?.type === 'Identifier' ? param.id.name : undefined + const tmpVal = new SymbolValue(symVal.qid ?? '', { + sid, + parent: symVal, + }) + if (symVal.value && tmpVal.sid) { + symVal.value[tmpVal.sid] = tmpVal + } + argValue = this.processInstruction( + symVal, + param.id, + state + ) + } + if (param.varType?.id) { + const val = this.getMemberValueNoCreate( + symVal, + param.varType.id, + state + ) + if (val?.vtype === 'class') { + argValue.rtype.definiteType = UastSpec.identifier( + val.logicalQid + ) + } else { + argValue.rtype.definiteType = param.varType.id + } + } + argValues.push(argValue) + } + } catch (e) { + handleException( + e, + 'Error occurred in SpringAnalyzer.symbolInterpret: process argValue err', + 'Error occurred in SpringAnalyzer.symbolInterpret: process argValue err' ) } - } catch (e) { - handleException( - e, - 'Error occurred in SpringAnalyzer.symbolInterpret: process argValue err', - 'Error occurred in SpringAnalyzer.symbolInterpret: process argValue err' - ) + + try { + this.executeCall(fdef, symVal, state, entryPoint.scopeVal, { callArgs: this.buildCallArgs(fdef, argValues, symVal) }) + } catch (e) { + const fdefIdName = fdef.id?.name + handleException( + e, + `[${fdefIdName} symbolInterpret failed. Exception message saved in error log file`, + `[${fdefIdName} symbolInterpret failed. Exception message saved in error log file` + ) + if (this.globalState.meetOtherEntryPoint) { + delete this.globalState.meetOtherEntryPoint + } + if (this.globalState.entryPointTimeout) { + delete this.globalState.entryPointTimeout + } + } + + if (this.globalState.meetOtherEntryPoint) { + logger.info( + 'EntryPoint [%s.%s] is interrupted because encountered other entrypoint during execution', + entryPoint.filePath?.substring(0, entryPoint.filePath?.lastIndexOf('.')), + entryPoint.functionName || + `` + ) + delete this.globalState.meetOtherEntryPoint + } + if (this.globalState.entryPointTimeout) { + logger.info( + 'EntryPoint [%s.%s] is interrupted because timeout', + entryPoint.filePath?.substring(0, entryPoint.filePath?.lastIndexOf('.')), + entryPoint.functionName || + `` + ) + delete this.globalState.entryPointTimeout + this.timeoutEntryPoints.push({ + entryPoint, + overloadFuncDef, + argValues, + }) + } + + this.checkerManager.checkAtSymbolInterpretOfEntryPointAfter(this, null, null, null, null) } + } + } + Config.entryPointTimeoutMs = oldEntryPointTimeoutMs + + if (this.timeoutEntryPoints.length > 0) { + this.outputAnalyzerExistResult() + logger.info('Rerun timeout entryPoint with aggressive prune mode') + this.pruneInfoMap.aggressiveMode = true + for (const timeoutEntryPoint of this.timeoutEntryPoints) { + this.symbolTable.clear() + this.checkerManager.checkAtSymbolInterpretOfEntryPointBefore(this, null, null, null, null) try { + entryPointConfig.setCurrentEntryPoint(timeoutEntryPoint.entryPoint) + logger.info( + 'EntryPoint [%s.%s] is executing', + timeoutEntryPoint.entryPoint.filePath?.substring( + 0, + timeoutEntryPoint.entryPoint.filePath?.lastIndexOf('.') + ), + timeoutEntryPoint.entryPoint.functionName || + `` + ) + state.entryPointStartTimestamp = Date.now() this.executeCall( - entryPoint.entryPointSymVal?.ast, - entryPoint.entryPointSymVal, - argValues, + timeoutEntryPoint.overloadFuncDef, + timeoutEntryPoint.entryPoint.entryPointSymVal, state, - entryPoint.scopeVal + timeoutEntryPoint.entryPoint.scopeVal, + { callArgs: this.buildCallArgs(timeoutEntryPoint.overloadFuncDef, timeoutEntryPoint.argValues, timeoutEntryPoint.entryPoint.entryPointSymVal) } ) } catch (e) { handleException( e, - `[${entryPoint.entryPointSymVal?.ast?.id?.name} symbolInterpret failed. Exception message saved in error log file`, - `[${entryPoint.entryPointSymVal?.ast?.id?.name} symbolInterpret failed. Exception message saved in error log file` + `[${timeoutEntryPoint.overloadFuncDef?.id?.name} symbolInterpret failed. Exception message saved in error log file`, + `[${timeoutEntryPoint.overloadFuncDef?.id?.name} symbolInterpret failed. Exception message saved in error log file` ) + if (this.globalState.meetOtherEntryPoint) { + delete this.globalState.meetOtherEntryPoint + } + if (this.globalState.entryPointTimeout) { + delete this.globalState.entryPointTimeout + } } + + if (this.globalState.meetOtherEntryPoint) { + delete this.globalState.meetOtherEntryPoint + } + if (this.globalState.entryPointTimeout) { + logger.info( + 'EntryPoint [%s.%s] is interrupted because timeout', + timeoutEntryPoint.entryPoint.filePath?.substring( + 0, + timeoutEntryPoint.entryPoint.filePath?.lastIndexOf('.') + ), + timeoutEntryPoint.entryPoint.functionName || + `` + ) + delete this.globalState.entryPointTimeout + this.outputAnalyzerExistResult() + } + this.checkerManager.checkAtSymbolInterpretOfEntryPointAfter(this, null, null, null, null) } + this.pruneInfoMap.aggressiveMode = false } + return true } @@ -129,109 +377,112 @@ class SpringAnalyzer extends (JavaAnalyzer as any) { * @param node * @param state */ - processVariableDeclaration(scope: any, node: any, state: any) { - let hasBeanInject = false - // bean注入注解形式 - if (node?._meta?.modifiers && Array.isArray(node?._meta?.modifiers)) { - const decoratorArray = node?._meta?.modifiers.filter((item: any) => item.startsWith('@')) - let isBeanReferenceByName = false - let isBeanReferenceByClass = false - let matchedDecorator = '' - let decoratorMeta = '' - const indexByName = this.beanReferenceAnnotationByName.findIndex((decorator: string) => { - const matchingItem = decoratorArray.find((item: any) => item.includes(decorator)) - if (matchingItem) { - if (matchingItem.includes('@Resource')) { - const regex = /type\s*=\s*([^",]*)/ - const match = matchingItem.match(regex) - if (match) { - return false - } - } - decoratorMeta = matchingItem - return true + override processVariableDeclaration(scope: Scope, node: VariableDeclaration, state: State) { + const idName = node.id?.type === 'Identifier' ? node.id.name : undefined + if (!node.init && !Rules.getPreprocessReady()) { + let targetClassName = '' + if (node.varType?.id?.type === 'Identifier') { + const classRes = this.processIdentifier(scope, node.varType?.id, state) + if (classRes && classRes?.vtype === 'symbol') { + targetClassName = (classRes as any).name + } else { + targetClassName = classRes.logicalQid } - return false - }) - if (indexByName !== -1) { - isBeanReferenceByName = true - matchedDecorator = this.beanReferenceAnnotationByName[indexByName] - } else { - const indexByClass = this.beanReferenceAnnotationByClass.findIndex((decorator: string) => { - const matchingItem = decoratorArray.find((item: any) => item.includes(decorator)) + } + + let hasBeanInject = false + // bean注入注解形式 + if (node?._meta?.modifiers && Array.isArray(node?._meta?.modifiers)) { + const decoratorArray = node?._meta?.modifiers.filter((item: string) => item.startsWith('@')) + let isBeanReferenceByName = false + let isBeanReferenceByClass = false + let matchedDecorator = '' + let decoratorMeta = '' + const indexByName = this.beanReferenceAnnotationByName.findIndex((decorator: string) => { + const matchingItem = decoratorArray.find((item: string) => item.includes(decorator)) if (matchingItem) { + if (matchingItem.includes('@Resource')) { + const regex = /type\s*=\s*([^",]*)/ + const match = matchingItem.match(regex) + if (match) { + return false + } + } decoratorMeta = matchingItem return true } return false }) - if (indexByClass !== -1) { - isBeanReferenceByClass = true - matchedDecorator = this.beanReferenceAnnotationByClass[indexByClass] - } - } - if (isBeanReferenceByName && matchedDecorator !== '' && decoratorMeta !== '') { - let beanName = node.id?.name - if (matchedDecorator === '@SofaReference' && decoratorMeta.includes('uniqueId')) { - const regex = /uniqueId\s*=\s*"([^"]*)"/ - const match = decoratorMeta.match(regex) - if (match) { - beanName = match[1] - } - } else if (matchedDecorator === '@Qualifier' && decoratorMeta.includes('(') && decoratorMeta.includes('"')) { - const qualifierValue = decoratorMeta - .slice(decoratorMeta.indexOf('"') + 1, decoratorMeta.lastIndexOf('"')) - .replace(/\s+/g, '') - if (qualifierValue) { - beanName = qualifierValue - } - } else if (matchedDecorator === '@Resource' && decoratorMeta.includes('name')) { - const regex = /name\s*=\s*"([^"]*)"/ - const match = decoratorMeta.match(regex) - if (match) { - beanName = match[1] + if (indexByName !== -1) { + isBeanReferenceByName = true + matchedDecorator = this.beanReferenceAnnotationByName[indexByName] + } else { + const indexByClass = this.beanReferenceAnnotationByClass.findIndex((decorator: string) => { + const matchingItem = decoratorArray.find((item: string) => item.includes(decorator)) + if (matchingItem) { + decoratorMeta = matchingItem + return true + } + return false + }) + if (indexByClass !== -1) { + isBeanReferenceByClass = true + matchedDecorator = this.beanReferenceAnnotationByClass[indexByClass] } } - hasBeanInject = this.injectBeanByName(beanName, node) - } - if (isBeanReferenceByClass && matchedDecorator !== '' && decoratorMeta !== '' && !hasBeanInject) { - let targetClassName = '' - if (node.varType?.id?.type === 'Identifier') { - if (matchedDecorator === '@Resource') { - const regex = /type\s*=\s*([^",)]*)/ + if (isBeanReferenceByName && matchedDecorator !== '' && decoratorMeta !== '') { + let beanName = idName ?? '' + if (matchedDecorator === '@SofaReference' && decoratorMeta.includes('uniqueId')) { + const regex = /uniqueId\s*=\s*"([^"]*)"/ const match = decoratorMeta.match(regex) if (match) { - node.varType.id.name = match[1].split('.')[0] + beanName = match[1] + } + } else if (matchedDecorator === '@Qualifier' && decoratorMeta.includes('(') && decoratorMeta.includes('"')) { + const qualifierValue = decoratorMeta + .slice(decoratorMeta.indexOf('"') + 1, decoratorMeta.lastIndexOf('"')) + .replace(/\s+/g, '') + if (qualifierValue) { + beanName = qualifierValue + } + } else if (matchedDecorator === '@Resource' && decoratorMeta.includes('name')) { + const regex = /name\s*=\s*"([^"]*)"/ + const match = decoratorMeta.match(regex) + if (match) { + beanName = match[1] } } - const classRes = this.processIdentifier(scope, node.varType?.id, state) - if (classRes && classRes?.vtype === 'symbol') { - targetClassName = classRes.name - } else { - targetClassName = classRes.sort ? classRes.sort : classRes._qid - } + hasBeanInject = this.injectBeanByName(beanName, node, targetClassName) } - if (targetClassName) { - hasBeanInject = this.injectBeanByClass(targetClassName, node) || false + if (isBeanReferenceByClass && matchedDecorator !== '' && decoratorMeta !== '' && !hasBeanInject) { + if (node.varType?.id?.type === 'Identifier') { + if (matchedDecorator === '@Resource') { + const regex = /type\s*=\s*([^",)]*)/ + const match = decoratorMeta.match(regex) + if (match) { + node.varType.id.name = match[1].split('.')[0] + } + } + const classRes = this.processIdentifier(scope, node.varType?.id, state) + if (classRes && classRes?.vtype === 'symbol') { + targetClassName = (classRes as any).name || classRes.qid || '' + } else { + targetClassName = classRes.logicalQid + } + } + if (targetClassName) { + hasBeanInject = this.injectBeanByClass(targetClassName, node) || false + } } } - } - // 同package下无注解形式 - if (!hasBeanInject) { - const beanName = node.id?.name - hasBeanInject = this.injectBeanByName(beanName, node) - } - if (!hasBeanInject) { - let targetClassName = '' - if (node.varType?.id?.type === 'Identifier') { - const classRes = this.getMemberValueNoCreate(scope, node.varType?.id, state) - if (classRes && classRes?.vtype === 'symbol') { - targetClassName = classRes.name - } else { - targetClassName = classRes.sort ? classRes.sort : classRes._qid - } + // 同package下无注解形式 + if (!hasBeanInject) { + const beanName = idName || '' + hasBeanInject = this.injectBeanByName(beanName, node, targetClassName) + } + if (!hasBeanInject) { + this.injectBeanByClass(targetClassName, node) } - this.injectBeanByClass(targetClassName, node) } return super.processVariableDeclaration(scope, node, state) @@ -243,7 +494,7 @@ class SpringAnalyzer extends (JavaAnalyzer as any) { * @param node * @param state */ - processFunctionDefinition(scope: any, node: any, state: any) { + override processFunctionDefinition(scope: Scope, node: FunctionDefinition, state: State) { // bean发布@Bean let isBeanService = false let isPrimary = false @@ -261,7 +512,8 @@ class SpringAnalyzer extends (JavaAnalyzer as any) { isBeanService = true const regex = /name\s*=\s*"([^"]*)"/ const match = modifier.match(regex) - beanName = this.transformBeanNameVariable(node.id?.name) + const funcIdName = node.id?.type === 'Identifier' ? node.id.name : '' + beanName = this.transformBeanNameVariable(funcIdName) if (match && beanName && beanName !== '') { beanName = match[1] } @@ -273,12 +525,12 @@ class SpringAnalyzer extends (JavaAnalyzer as any) { let returnType = '' if (node.returnType?.id?.type === 'Identifier') { const returnClass = node.returnType?.id - const returnTypeIdentifier = this.processIdentifier(scope, returnClass, scope) - returnType = returnTypeIdentifier.sort ? returnTypeIdentifier.sort : returnTypeIdentifier._qid + const returnTypeIdentifier = this.processIdentifier(scope, returnClass, state) + returnType = returnTypeIdentifier.qid } - this.topScope.beanMap.set(beanName, { + this.topScope.spring.beanMap.set(beanName, { initFClos: res, - className: returnType, + className: QidUnifyUtil.qidUnifyByRemoveAngleAndPrefix(returnType), isPrimary, }) } @@ -291,12 +543,14 @@ class SpringAnalyzer extends (JavaAnalyzer as any) { * @param node * @param state */ - processClassDefinition(scope: any, node: any, state: any) { + override processClassDefinition(scope: Scope, node: ClassDefinition, state: State) { let isBeanService = false let beanName = '' let isPrimary = false - if (node._meta?.annotations && Array.isArray(node._meta?.annotations)) { - for (const annotation of node._meta?.annotations) { + const annotations = (node._meta as { annotations?: unknown[] }).annotations + if (annotations && Array.isArray(annotations)) { + for (const rawAnnotation of annotations) { + const annotation = rawAnnotation as any if (AstUtil.prettyPrintAST(annotation).includes('Primary')) { isPrimary = true } @@ -307,11 +561,12 @@ class SpringAnalyzer extends (JavaAnalyzer as any) { ) ) { isBeanService = true - beanName = this.transformBeanNameVariable(node.id?.name) + beanName = this.transformBeanNameVariable(node.id?.name ?? '') if (annotation.type === 'Sequence' && annotation.expressions && Array.isArray(annotation.expressions)) { for (const expr of annotation.expressions) { - if (expr.type === 'Literal' && expr.value) { - beanName = expr.value + const exprBeanName = this.findBeanNameFromSequenceExpr(expr) + if (exprBeanName) { + beanName = exprBeanName break } } @@ -321,8 +576,8 @@ class SpringAnalyzer extends (JavaAnalyzer as any) { } const res = super.processClassDefinition(scope, node, state) if (isBeanService) { - this.topScope.beanMap.set(beanName, { - className: res.sort, + this.topScope.spring.beanMap.set(beanName, { + className: res.logicalQid, isPrimary, }) } @@ -333,59 +588,72 @@ class SpringAnalyzer extends (JavaAnalyzer as any) { * * @param beanName * @param node + * @param targetClassName */ - injectBeanByName(beanName: any, node: any) { + injectBeanByName(beanName: string, node: VariableDeclaration, targetClassName?: string) { if ( beanName && beanName !== '' && - this.topScope.beanMap?.has(beanName) && - this.topScope.beanMap?.get(beanName)?.className + this.topScope.spring.beanMap?.has(beanName) && + this.topScope.spring.beanMap?.get(beanName)?.className ) { - const implValue = this.topScope.beanMap?.get(beanName).className + const implValue = this.topScope.spring.beanMap?.get(beanName).className if (node.varType?.id?.type === 'Identifier' && node.varType?.id?.name) { node.varType.id.name = implValue?.split('.').pop() } - node.init = { + const nodeParent = node.parent + const fromLiteral = { + type: 'Literal', + value: implValue, + literalType: 'string', + _meta: {}, + loc: node.loc, + parent: node.init, + } as unknown as Literal + const importExpr = { type: 'ImportExpression', - from: { - type: 'Literal', - value: implValue, - literalType: 'string', - _meta: {}, - loc: node.loc, - parent: node.init, - }, + from: fromLiteral, arguments: [], _meta: node._meta, loc: node.loc, - parent: node.parent, + parent: nodeParent, + } as unknown as Expr + node.init = importExpr + if (implValue && targetClassName && implValue !== targetClassName) { + this.addExtraClassHierarchyByName(implValue, targetClassName) } return true } // spring reference场景 - if (beanName && beanName !== '' && this.topScope.springReferenceMap.has(beanName)) { - const { interfaceName } = this.topScope.springReferenceMap.get(beanName) - if (interfaceName && this.topScope.springServiceMap.has(interfaceName)) { - const beanRef = this.topScope.springServiceMap.get(interfaceName) - const implValue = this.topScope.beanMap?.get(beanRef.ref)?.className + if (beanName && beanName !== '' && this.topScope.spring.springReferenceMap.has(beanName)) { + const { interfaceName } = this.topScope.spring.springReferenceMap.get(beanName) + if (interfaceName && this.topScope.spring.springServiceMap.has(interfaceName)) { + const beanRef = this.topScope.spring.springServiceMap.get(interfaceName) + const implValue = this.topScope.spring.beanMap?.get(beanRef.ref)?.className if (implValue) { if (node.varType?.id?.type === 'Identifier' && node.varType?.id?.name) { node.varType.id.name = implValue?.split('.').pop() } - node.init = { + const nodeParent = node.parent + const fromLiteral = { + type: 'Literal', + value: implValue, + literalType: 'string', + _meta: {}, + loc: node.loc, + parent: node.init, + } as unknown as Literal + const importExpr = { type: 'ImportExpression', - from: { - type: 'Literal', - value: implValue, - literalType: 'string', - _meta: {}, - loc: node.loc, - parent: node.init, - }, + from: fromLiteral, arguments: [], _meta: node._meta, loc: node.loc, - parent: node.parent, + parent: nodeParent, + } as unknown as Expr + node.init = importExpr + if (implValue && targetClassName && implValue !== targetClassName) { + this.addExtraClassHierarchyByName(implValue, targetClassName) } return true } @@ -399,48 +667,54 @@ class SpringAnalyzer extends (JavaAnalyzer as any) { * @param targetClassName * @param node */ - injectBeanByClass(targetClassName: any, node: any) { + injectBeanByClass(targetClassName: string, node: VariableDeclaration) { let hasFindPrimary = false - for (const beanValue of this.topScope.beanMap.values()) { + for (const beanValue of this.topScope.spring.beanMap.values()) { if (beanValue.isPrimary && beanValue.className === targetClassName) { hasFindPrimary = true - node.init = { + const nodeParent = node.parent + const fromLiteral = { + type: 'Literal', + value: targetClassName, + literalType: 'string', + _meta: {}, + loc: node.loc, + parent: node.init, + } as unknown as Literal + const importExpr = { type: 'ImportExpression', - from: { - type: 'Literal', - value: targetClassName, - literalType: 'string', - _meta: {}, - loc: node.loc, - parent: node.init, - }, + from: fromLiteral, arguments: [], _meta: node._meta, loc: node.loc, - parent: node.parent, - } + parent: nodeParent, + } as unknown as Expr + node.init = importExpr return true } } if (!hasFindPrimary) { - for (const beanValue of this.topScope.beanMap.values()) { + for (const beanValue of this.topScope.spring.beanMap.values()) { if (beanValue.className === targetClassName) { hasFindPrimary = true - node.init = { + const nodeParent = node.parent + const fromLiteral = { + type: 'Literal', + value: targetClassName, + literalType: 'string', + _meta: {}, + loc: node.loc, + parent: node.init, + } as unknown as Literal + const importExpr = { type: 'ImportExpression', - from: { - type: 'Literal', - value: targetClassName, - literalType: 'string', - _meta: {}, - loc: node.loc, - parent: node.init, - }, + from: fromLiteral, arguments: [], _meta: node._meta, loc: node.loc, - parent: node.parent, - } + parent: nodeParent, + } as unknown as Expr + node.init = importExpr return true } } @@ -451,7 +725,7 @@ class SpringAnalyzer extends (JavaAnalyzer as any) { * * @param variable */ - transformBeanNameVariable(variable: any) { + transformBeanNameVariable(variable: string) { // 检查是否是字符串 if (typeof variable !== 'string') { handleException( @@ -475,6 +749,118 @@ class SpringAnalyzer extends (JavaAnalyzer as any) { // 如果不是以大写字母开头,直接返回原变量 return variable } + + /** + * + * @param classMap + */ + compensateDependencyInjection(classMap: Map) { + if (!classMap) { + return + } + for (const classUuid of classMap.values()) { + const classVal = this.symbolTable.get(classUuid) + if ( + classVal.vtype !== 'class' || + !classVal.ast.node || + !Array.isArray(classVal.ast.node.body) || + !classVal.members + ) { + continue + } + for (const bodyAst of classVal.ast.node.body) { + if ( + bodyAst.type !== 'VariableDeclaration' || + !bodyAst.id || + !bodyAst.id.name || + !classVal.members.has(bodyAst.id.name) || + classVal.members.get(bodyAst.id.name)?.vtype !== 'uninitialized' + ) { + continue + } + const state = this.initState(classVal) + this.processVariableDeclaration(classVal, bodyAst, state) + } + } + } + + /** + * inject object instead of class + * @param classMap + * @param packageManager + */ + adJustDependencyInjection(classMap: Map, packageManager: unknown) { + if (!classMap) { + return + } + for (const classValUUid of classMap.values()) { + const classVal = this.symbolTable.get(classValUUid) + if ( + classVal.vtype !== 'class' || + !classVal.ast.node || + !Array.isArray(classVal.ast.node.body) || + classVal.members.size === 0 + ) { + continue + } + for (const bodyAst of classVal.ast.node.body) { + if ( + bodyAst.type !== 'VariableDeclaration' || + !bodyAst.id || + !bodyAst.id.name || + !bodyAst.init || + bodyAst.init.type !== 'ImportExpression' || + !classVal.members.has(bodyAst.id.name) || + classVal.members.get(bodyAst.id.name)?.vtype !== 'class' + ) { + continue + } + const memberVal = classVal.members.get(bodyAst.id.name) + const objVal = newInstance(this, packageManager, memberVal.qid, bodyAst) + objVal.injected = true + objVal.rtype = { type: undefined } + objVal.rtype.definiteType = UastSpec.identifier( + memberVal.logicalQid + ) + const memberValues = objVal?.members ? objVal.members.entries().map(([_, v]: [string, any]) => v) : [] + for (const fieldVal of memberValues) { + const val = fieldVal as { vtype?: string; ast?: { node?: { _meta?: { modifiers?: string[] } } }; sid?: string } + if (val.vtype !== 'fclos' || !val.ast?.node) { + continue + } + if (val.sid === 'afterPropertiesSet' || val.ast?.node?._meta?.modifiers?.includes('@PostConstruct')) { + const state = this.initState(objVal) + this.executeCall(val.ast?.node, val as unknown as SymbolValueType, state, objVal, INTERNAL_CALL) + } + } + classVal.members.set(bodyAst.id.name, objVal) + } + } + } + + /** + * find bean name from sequence expr + * @param expr + */ + findBeanNameFromSequenceExpr(expr: Expr | Stmt | Decl): string | undefined { + let beanName: string | undefined + if (expr.type === 'Literal' && (expr as Literal).value) { + beanName = (expr as Literal).value as string + } else if (expr.type === 'AssignmentExpression' && (expr as AssignmentExpression).right?.type === 'Literal') { + const leftStr = AstUtil.prettyPrintAST((expr as AssignmentExpression).left) + if (leftStr?.endsWith('value') || leftStr?.endsWith('uniqueId')) { + beanName = ((expr as AssignmentExpression).right as Literal).value as string + } + } else if (expr.type === 'ScopedStatement' && Array.isArray((expr as ScopedStatement).body)) { + for (const subExpr of (expr as ScopedStatement).body) { + beanName = this.findBeanNameFromSequenceExpr(subExpr) + if (beanName) { + break + } + } + } + return beanName + } } export = SpringAnalyzer diff --git a/src/engine/analyzer/java/spring/spring-initializer.ts b/src/engine/analyzer/java/spring/spring-initializer.ts index 6da6a840..1267a118 100644 --- a/src/engine/analyzer/java/spring/spring-initializer.ts +++ b/src/engine/analyzer/java/spring/spring-initializer.ts @@ -20,9 +20,16 @@ class SpringInitializer extends (JavaInitializer as any) { const beanMap = new Map() const springReferenceMap = new Map() const springServiceMap = new Map() - topScope.beanMap = beanMap - topScope.springServiceMap = springServiceMap - topScope.springReferenceMap = springReferenceMap + /* SOFA 服务映射:unique-id → {ref, interfaceName},interfaceName → [{uniqueId, ref}] */ + const sofaServiceUniqueIdMap: Map = new Map() + const sofaServiceInterfaceMap: Map> = new Map() + topScope.spring = { + beanMap, + springReferenceMap, + springServiceMap, + sofaServiceUniqueIdMap, + sofaServiceInterfaceMap, + } const xmlFiles = FileUtil.loadAllFileTextGlobby(['**/*.xml'], dir) if (xmlFiles.length === 0) { return @@ -73,9 +80,20 @@ class SpringInitializer extends (JavaInitializer as any) { springServiceArray.forEach((springService: any) => { const ref = springService.$?.REF || '' const interfaceName = springService.$?.INTERFACE || '' + const uniqueId = springService.$?.['UNIQUE-ID'] || '' springServiceMap.set(interfaceName, { ref, }) + /* 填充 SOFA unique-id 映射 */ + if (uniqueId) { + sofaServiceUniqueIdMap.set(uniqueId, { ref, interfaceName }) + } + if (interfaceName) { + if (!sofaServiceInterfaceMap.has(interfaceName)) { + sofaServiceInterfaceMap.set(interfaceName, []) + } + sofaServiceInterfaceMap.get(interfaceName)!.push({ uniqueId, ref }) + } }) } diff --git a/src/engine/analyzer/javascript/common/builtins/array-builtins.ts b/src/engine/analyzer/javascript/common/builtins/array-builtins.ts index 093ae931..bc20e061 100644 --- a/src/engine/analyzer/javascript/common/builtins/array-builtins.ts +++ b/src/engine/analyzer/javascript/common/builtins/array-builtins.ts @@ -1,4 +1,4 @@ -const FunctionValue = require('../../../common/value/function') +import { FunctionValue } from '../../../common/value/function' const { getDataFromScope } = require('../../../../../util/common-util') /** @@ -19,7 +19,7 @@ function processVisitArrayBuiltins(this: any, fclos: any, argvalues: any[], stat const resArray = [] if (forEachHandle && Array.isArray(arrItems) && arrItems.length > 0) { for (const arrItem of arrItems) { - const res = (this as any).executeCall(node, forEachHandle, [arrItem], state, scope) + const res = (this as any).executeCall(node, forEachHandle, state, scope, { callArgs: (this as any).buildCallArgs(node, [arrItem], forEachHandle) }) resArray.push(res) } } diff --git a/src/engine/analyzer/javascript/common/builtins/function.ts b/src/engine/analyzer/javascript/common/builtins/function.ts index c0fc076b..c8951519 100644 --- a/src/engine/analyzer/javascript/common/builtins/function.ts +++ b/src/engine/analyzer/javascript/common/builtins/function.ts @@ -1,5 +1,6 @@ const _ = require('lodash') const { Errors } = require('../../../../../util/error-code') +const { lodashCloneWithTag } = require('../../../../../util/clone-util') const { valueUtil: { @@ -37,8 +38,8 @@ module.exports = { Errors.UnexpectedValue(`argvalues.length should greater than 0`, { no_throw: true }) } if (argvalues.length <= 1) { - argvalues.push(UndefinedValue()) - argvalues.push(UndefinedValue()) + argvalues.push(new UndefinedValue()) + argvalues.push(new UndefinedValue()) } return processFunctionInvoke.call(this, invoke, argvalues[0], Object.values(argvalues[1].value), state, node, scope) }, @@ -57,12 +58,20 @@ module.exports = { * @param node * @param scope */ -function processFunctionInvoke(this: any, invoke: any, _this: any, argvalues: any[], state: any, node: any, scope: any) { +function processFunctionInvoke( + this: any, + invoke: any, + _this: any, + argvalues: any[], + state: any, + node: any, + scope: any +) { const fclos = invoke.parent - const fscope = _.clone(fclos) + const fscope = lodashCloneWithTag(fclos) fscope._this = _this // handle through executeSingleCall instead of executeCall is to prevent // decorator process redundantly, which will cause infinite loop - return (this as any).executeSingleCall(fscope, argvalues, state, node, scope) + return (this as any).executeSingleCall(fscope, state, node, scope, { callArgs: (this as any).buildCallArgs(node, argvalues, fscope) }) } diff --git a/src/engine/analyzer/javascript/common/builtins/map-builtins.ts b/src/engine/analyzer/javascript/common/builtins/map-builtins.ts index 42ff79db..dbc7b446 100644 --- a/src/engine/analyzer/javascript/common/builtins/map-builtins.ts +++ b/src/engine/analyzer/javascript/common/builtins/map-builtins.ts @@ -28,14 +28,14 @@ const SourceLine = require('../../../common/source-line') */ function processMapGet(fclos: any, argvalues: any[], state: any, node: any, scope: any): any { const mapObj = fclos.parent - let res = UndefinedValue() + let res = new UndefinedValue() if (!argvalues || !Array.isArray(argvalues) || argvalues.length !== 1) return res const keyRef = getSymbolRef(argvalues[0]) const keyRefSet = mapObj.getFieldValue('keyRefSet') if (!keyRefSet.has(keyRef)) return res const entryValue = mapObj.getFieldValue(keyRef) - if (Array.isArray(entryValue.field) && entryValue.field.length === 2) { - res = entryValue.field[1] ?? res + if (Array.isArray(entryValue.value) && entryValue.value.length === 2) { + res = entryValue.getFieldValue('1') ?? res } return res } @@ -57,15 +57,13 @@ function processMapSet(fclos: any, argvalues: any[], state: any, node: any, scop // key 相同时 覆盖 if (keyRefSet.has(keyRef)) { const entryValue = mapObj.getFieldValue(keyRef) - if (Array.isArray(entryValue.field) && entryValue.field.length === 2) { - entryValue.field[1] = argvalues[1] + if (Array.isArray(entryValue.value) && entryValue.value.length === 2) { + entryValue.setFieldValue('1', argvalues[1]) } } else { // 否则新增 - const kvPair = UnionValue({ - sid: 'key-value-pair', - parent: mapObj, - }) + const kvPair = new UnionValue(undefined, 'map-key-value-pair', `${mapObj.qid}.`, node) + kvPair.parent = mapObj kvPair.appendValue(argvalues[0]) kvPair.appendValue(argvalues[1]) mapObj.setFieldValue(keyRef, kvPair) @@ -90,9 +88,9 @@ function processMapDelete(fclos: any, argvalues: any[], state: any, node: any, s const keyRefSet = mapObj.getFieldValue('keyRefSet') if (!keyRefSet.has(keyRef)) return const entryValue = mapObj.getFieldValue(keyRef) - if (Array.isArray(entryValue.field) && entryValue.field.length === 2) { + if (Array.isArray(entryValue.value) && entryValue.value.length === 2) { keyRefSet.delete(keyRef) - delete mapObj.field[keyRef] + mapObj.members.delete(keyRef) } } @@ -109,8 +107,8 @@ function processMapClear(fclos: any, argvalues: any[], state: any, node: any, sc const keyRefSet = mapObj.getFieldValue('keyRefSet') for (const keyRef of keyRefSet) { const entryValue = mapObj.getFieldValue(keyRef) - if (Array.isArray(entryValue.field) && entryValue.field.length === 2) { - delete mapObj.field[keyRef] + if (Array.isArray(entryValue.value) && entryValue.value.length === 2) { + mapObj.members.delete(keyRef) } } keyRefSet.clear() @@ -126,17 +124,13 @@ function processMapClear(fclos: any, argvalues: any[], state: any, node: any, sc */ function processMapKeys(fclos: any, argvalues: any[], state: any, node: any, scope: any): any { const mapObj = fclos.parent - const resSet = UnionValue({ - id: `${mapObj.id}-keySet`, - sid: `${mapObj.sid}-keySet`, - qid: `${mapObj.qid}-keySet`, - parent: mapObj, - }) + const resSet = new UnionValue(undefined, `${mapObj.sid}-keySet`, `${mapObj.qid}-keySet`, node) + resSet.parent = mapObj const keyRefSet = mapObj.getFieldValue('keyRefSet') for (const keyRef of keyRefSet) { const entryValue = mapObj.getFieldValue(keyRef) - if (Array.isArray(entryValue.field) && entryValue.field.length === 2) { - resSet.appendValue(entryValue.field[0]) + if (Array.isArray(entryValue.value) && entryValue.value.length === 2) { + resSet.appendValue(entryValue.getFieldValue('0')) } } return resSet @@ -152,17 +146,13 @@ function processMapKeys(fclos: any, argvalues: any[], state: any, node: any, sco */ function processMapValues(fclos: any, argvalues: any[], state: any, node: any, scope: any): any { const mapObj = fclos.parent - const resSet = UnionValue({ - id: `${mapObj.id}-valueSet`, - sid: `${mapObj.sid}-valueSet`, - qid: `${mapObj.qid}-valueSet`, - parent: mapObj, - }) + const resSet = new UnionValue(undefined, `${mapObj.sid}-valueSet`, `${mapObj.qid}-valueSet`, node) + resSet.parent = mapObj const keyRefSet = mapObj.getFieldValue('keyRefSet') for (const keyRef of keyRefSet) { const entryValue = mapObj.getFieldValue(keyRef) - if (Array.isArray(entryValue.field) && entryValue.field.length === 2) { - resSet.appendValue(entryValue.field[1]) + if (Array.isArray(entryValue.value) && entryValue.value.length === 2) { + resSet.appendValue(entryValue.getFieldValue('1')) } } return resSet @@ -200,7 +190,7 @@ function processNewMapBuiltins(map: any, argvalues: any[], state: any, node: any const keyRefSet = new Set() // 有参数初始化map if (Array.isArray(argvalues) && argvalues.length > 0) { - const entries = argvalues[0]?.field && Object.entries(argvalues[0]?.field) + const entries = argvalues[0]?.members && [...argvalues[0].members.entries()] // map的初始化 // 通过数组显示初始化 可能有 ObjectValue符号值 // 通过其他map初始化 可能有 keyRefSet UnionValue 还有prototype @@ -212,27 +202,25 @@ function processNewMapBuiltins(map: any, argvalues: any[], state: any, node: any if (typeof entryValue === 'object' && (entryValue as any)?.vtype === 'object') { // 过滤prototype if ((entryValue as any).sid === 'prototype') continue - const kvPair = Object.values((entryValue as any).field) + const kvPair = [...(entryValue as any).members.values()] if (Array.isArray(kvPair) && kvPair.length === 2) { const keyRef = getSymbolRef(kvPair[0]) - const kvPairValue = UnionValue({ - sid: 'key-value-pair', - parent: map, - }) + const kvPairValue = new UnionValue(undefined, 'map-key-value-pair', `${map.qid}.map-kvp.${keyRef}`, node) + kvPairValue.parent = map kvPairValue.appendValue(kvPair[0]) kvPairValue.appendValue(kvPair[1]) const newPairValue = SourceLine.addSrcLineInfo( kvPairValue, node, node.loc && node.loc.sourcefile, - 'Arg Pass: ', + 'ARG PASS: ', map.sid ) map.setFieldValue(keyRef, newPairValue) keyRefSet.add(keyRef) } } else if (typeof entryValue === 'object' && (entryValue as any)?.vtype === 'union') { - if ((entryValue as any).field && Object.keys((entryValue as any).field).length === 2) { + if ((entryValue as any).value && (entryValue as any).value.length === 2) { map.setFieldValue(entry[0], entryValue) } } else if (entryValue && entryValue instanceof Set && entryValue.size > 0) { @@ -241,7 +229,7 @@ function processNewMapBuiltins(map: any, argvalues: any[], state: any, node: any } } } - if (!map.field.hasOwnProperty('keyRefSet')) { + if (!map.members.has('keyRefSet')) { map.setFieldValue('keyRefSet', keyRefSet) } return map diff --git a/src/engine/analyzer/javascript/common/builtins/operator-builtins.ts b/src/engine/analyzer/javascript/common/builtins/operator-builtins.ts index c2db09fa..7f25afd1 100644 --- a/src/engine/analyzer/javascript/common/builtins/operator-builtins.ts +++ b/src/engine/analyzer/javascript/common/builtins/operator-builtins.ts @@ -1,10 +1,9 @@ const _ = require('lodash') const { valueUtil: { - ValueUtil: { FunctionValue, ObjectValue, PrimitiveValue, UndefinedValue, UnionValue, SymbolValue }, + ValueUtil: { FunctionValue, ObjectValue, PrimitiveValue, UndefinedValue, UnionValue }, }, } = require('../../../common') -const { mergeSets } = require('../../../../../util/common-util') const BINARY_OPERATOR_PROCESS_MAP: Record = { '&&': processAndOperator, @@ -31,12 +30,12 @@ function processBinaryOperator(resValue: any, scope: any, node: any, state: any) } /** - * 校验resValue及其ast收否有效 + * 校验resValue及其ast是否有效 * @param resValue * @returns {boolean} */ function checkLhsAndRhsValid(resValue: any) { - return !!(resValue?.left && resValue?.right && resValue?.ast?.left && resValue?.ast?.right) + return !!(resValue?.left && resValue?.right && resValue?.ast?.node?.left && resValue?.ast?.node?.right) } /** @@ -53,17 +52,24 @@ function processAndOperator(resValue: any, scope: any, node: any, state: any) { // 此处疑似uast有问题 nan应该和undefined一样是primitive // 先打个补丁吧~ if (leftValue?.vtype === 'symbol' && leftValue?.type === 'Identifier' && leftValue?.name === 'NaN') { - return SymbolValue(leftValue) + return leftValue.clone() } - // 当leftValue表示undefined时,raw_value刚好不存在,访问一个不存在的值结果就是undefined if (leftValue?.vtype === 'primitive') { if ((_.has(leftValue, 'raw_value') as any) && leftValue?.raw_value != null) { - return leftValue.raw_value ? SymbolValue(rightValue) : SymbolValue(leftValue) + return leftValue.raw_value + ? rightValue.clone() + : leftValue.clone() } } - if (resValue?.hasTagRec) { - resValue._tags = mergeSets(leftValue._tags, rightValue._tags) - resValue.trace = leftValue.trace || rightValue.trace + if (resValue?.taint.isTaintedRec) { + for (const t of leftValue.taint.getTags() ?? []) resValue.taint.addTag(t) + for (const t of rightValue.taint.getTags() ?? []) resValue.taint.addTag(t) + const traceVal = (leftValue.taint.getFirstTrace()?.length ? leftValue.taint.getFirstTrace() : null) || rightValue.taint.getFirstTrace() + if (traceVal) { + resValue.taint.setAllTraces(traceVal) + } else { + resValue.taint.clearTrace() + } } return resValue } @@ -81,17 +87,24 @@ function processOrOperator(resValue: any, scope: any, node: any, state: any) { const rightValue = resValue.right if (leftValue?.vtype === 'symbol' && leftValue?.type === 'Identifier' && leftValue?.name === 'NaN') { - return SymbolValue(rightValue) + return rightValue.clone() } - // 当leftValue表示undefined时,raw_value刚好不存在,访问一个不存在的值结果就是undefined if (leftValue?.vtype === 'primitive') { if ((_.has(leftValue, 'raw_value') as any) && leftValue?.raw_value != null) { - return leftValue.raw_value ? SymbolValue(leftValue) : SymbolValue(rightValue) + return leftValue.raw_value + ? leftValue.clone() + : rightValue.clone() } } - if (resValue?.hasTagRec) { - resValue._tags = mergeSets(leftValue._tags, rightValue._tags) - resValue.trace = leftValue.trace || rightValue.trace + if (resValue?.taint.isTaintedRec) { + for (const t of leftValue.taint.getTags() ?? []) resValue.taint.addTag(t) + for (const t of rightValue.taint.getTags() ?? []) resValue.taint.addTag(t) + const traceVal = (leftValue.taint.getFirstTrace()?.length ? leftValue.taint.getFirstTrace() : null) || rightValue.taint.getFirstTrace() + if (traceVal) { + resValue.taint.setAllTraces(traceVal) + } else { + resValue.taint.clearTrace() + } } return resValue } @@ -114,12 +127,18 @@ function processNullMergeOperator(resValue: any, scope: any, node: any, state: a // 还有当leftValue为false 0 NaN ‘’时leftValue转换为boolean也为false但此时leftValue本身不为空 // 空值合并关注是否为空,而不是转换以后是否为false,因此要排除这些耦合情况 if (leftValue.raw_value === null || leftValue.raw_value === undefined) { - return SymbolValue(rightValue) + return rightValue.clone() } } - if (resValue?.hasTagRec) { - resValue._tags = mergeSets(leftValue._tags, rightValue._tags) - resValue.trace = leftValue.trace || rightValue.trace + if (resValue?.taint.isTaintedRec) { + for (const t of leftValue.taint.getTags() ?? []) resValue.taint.addTag(t) + for (const t of rightValue.taint.getTags() ?? []) resValue.taint.addTag(t) + const traceVal = (leftValue.taint.getFirstTrace()?.length ? leftValue.taint.getFirstTrace() : null) || rightValue.taint.getFirstTrace() + if (traceVal) { + resValue.taint.setAllTraces(traceVal) + } else { + resValue.taint.clearTrace() + } } return resValue } diff --git a/src/engine/analyzer/javascript/common/builtins/promise.ts b/src/engine/analyzer/javascript/common/builtins/promise.ts index 633e4b06..4460c21a 100644 --- a/src/engine/analyzer/javascript/common/builtins/promise.ts +++ b/src/engine/analyzer/javascript/common/builtins/promise.ts @@ -1,6 +1,6 @@ const { valueUtil: { - ValueUtil: { FunctionValue: PromiseFunctionValue, UndefinedValue: PromiseUndefinedValue }, + ValueUtil: { FunctionValue, UndefinedValue }, }, } = require('../../../common') @@ -16,12 +16,12 @@ function processThen(this: any, fclos: any, argvalues: any[], state: any, node: const handleFulfilled = argvalues && argvalues[0] const promise = fclos.parent if (handleFulfilled) { - if (promise && promise.sid === 'Promise') { + if (promise && (promise.sid === 'Promise' || promise.sid.includes('Promiseele && ele?.vtype!=='fclos') - // .forEach(ele=>{delete setObj.field[ele.sid]}) + // .forEach(ele=>{delete setObj.value[ele.sid]}) return setObj } diff --git a/src/engine/analyzer/javascript/common/js-analyzer.ts b/src/engine/analyzer/javascript/common/js-analyzer.ts index 5db804d1..870a74ac 100644 --- a/src/engine/analyzer/javascript/common/js-analyzer.ts +++ b/src/engine/analyzer/javascript/common/js-analyzer.ts @@ -1,3 +1,4 @@ +import { INTERNAL_CALL } from '../../common/call-args' const path = require('path') const fs = require('fs-extra') const globby = require('fast-glob') @@ -7,19 +8,35 @@ const logger = require('../../../../util/logger')(__filename) const FileUtil = require('../../../../util/file-util') const Statistics = require('../../../../util/statistics') const { ErrorCode, Errors } = require('../../../../util/error-code') -const Parsing = require('../../../parser/parsing') +const Parser = require('../../../parser/parser') const Initializer = require('./js-initializer') const BasicRuleHandler = require('../../../../checker/common/rules-basic-handler') const { AstUtil } = require('../../../../checker/common/checker-kit') const EntryPointConfig = require('../../common/current-entrypoint') const { processBinaryOperator } = require('./builtins/operator-builtins') -const Scope = require('../../common/scope') -const { Analyzer } = require('../../common') +const ScopeClass = require('../../common/scope') +const Analyzer: typeof import('../../common/analyzer').Analyzer = require('../../common/analyzer') +const Unit: typeof import('../../common/value/unit') = require('../../common/value/unit') +import type { Scope, State, Value, SymbolValue as SymbolValueType, VoidValue as VoidValueType, SpreadValue, BinaryExprValue, UnaryExprValue } from '../../../../types/analyzer' +import type { + CallExpression, + TryStatement, + AssignmentExpression, + MemberAccess, + UnaryExpression, + BinaryExpression, + ConditionalExpression, + VariableDeclaration, + SpreadElement, + ObjectExpression, + ForStatement, + ReturnStatement, +} from '../../../../types/uast' const CheckerManager = require('../../common/checker-manager') const { valueUtil: { - ValueUtil: { FunctionValue, ObjectValue, Scoped, PrimitiveValue, UndefinedValue }, + ValueUtil: { FunctionValue, ObjectValue, Scoped, PrimitiveValue, UndefinedValue, VoidValue }, }, } = require('../../common') const { handleException } = require('../../common/exception-handler') @@ -53,39 +70,53 @@ class JsAnalyzer extends Analyzer { /** * 单文件预处理:解析并处理单个文件 - * + * * @param source - 源代码内容 * @param fileName - 文件名 */ preProcess4SingleFile(source: any, fileName: any) { this.initTopScope() - this.state = this.initState() + this.state = this.initState(this.topScope) // 记录 parseCode 时间:解析源代码为 AST this.performanceTracker.start('preProcess.parseCode') - this.uast = this.parseUast(source, fileName) + const { options } = this + options.sourcefile = fileName + // 先填充 sourceCodeCache,parser 会优先使用 + this.sourceCodeCache.set(fileName, source.split(/\n/)) + this.uast = Parser.parseSingleFile(fileName, options, this.sourceCodeCache) this.performanceTracker.end('preProcess.parseCode') - + if (this.uast) { this.initModuleScope(this.uast, fileName) - + // 注意:直接调用 processModule 处理已解析的 AST,避免调用 processModuleSrc 导致重复解析 + + // 直接处理已解析的 AST,避免重复解析 this.performanceTracker.start('preProcess.processModule') this.processModule(this.uast, fileName) this.performanceTracker.end('preProcess.processModule') } } + /** + * 加载缓存后的初始化阶段,会创建一些全局builtin + */ + initAfterUsingCache() { + // init global scope + Initializer.initGlobalScope(this.topScope) + } + /** * 预处理阶段:扫描模块并解析代码 - * + * * @param dir - 项目目录 */ - preProcess(dir: any) { + async preProcess(dir: any) { Initializer.initGlobalScope(this.topScope) // just scan and execute every module - this.scanModules(dir) + await this.scanModules(dir) } /** @@ -101,35 +132,36 @@ class JsAnalyzer extends Analyzer { const hasAnalysised: any[] = [] // 自定义source入口方式,并根据入口自主加载source for (const entryPoint of entryPoints) { + this.symbolTable.clear() if (entryPoint.type === constValue.ENGIN_START_FUNCALL) { if ( hasAnalysised.includes( - `${entryPoint.filePath}.${entryPoint.functionName}/${entryPoint?.entryPointSymVal?._qid}#${entryPoint.entryPointSymVal.ast.parameters}.${entryPoint.attribute}` + `${entryPoint.filePath}.${entryPoint.functionName}/${entryPoint?.entryPointSymVal?.qid}#${entryPoint.entryPointSymVal.ast.node.parameters}.${entryPoint.attribute}` ) ) { continue } hasAnalysised.push( - `${entryPoint.filePath}.${entryPoint.functionName}/${entryPoint?.entryPointSymVal?._qid}#${entryPoint.entryPointSymVal.ast.parameters}.${entryPoint.attribute}` + `${entryPoint.filePath}.${entryPoint.functionName}/${entryPoint?.entryPointSymVal?.qid}#${entryPoint.entryPointSymVal.ast.node.parameters}.${entryPoint.attribute}` ) EntryPointConfig.setCurrentEntryPoint(entryPoint) logger.info( 'EntryPoint [%s.%s] is executing', entryPoint.filePath?.substring(0, entryPoint.filePath?.lastIndexOf('.')), entryPoint.functionName || - `` ) this.checkerManager.checkAtSymbolInterpretOfEntryPointBefore(this, null, null, null, null) const argValues: any[] = [] - for (const key in entryPoint.entryPointSymVal?.ast?.parameters) { + for (const key in entryPoint.entryPointSymVal?.ast?.node?.parameters) { argValues.push( this.processInstruction( entryPoint.entryPointSymVal, - entryPoint.entryPointSymVal?.ast?.parameters[key]?.id, + entryPoint.entryPointSymVal?.ast?.node?.parameters[key]?.id, state ) ) @@ -137,17 +169,17 @@ class JsAnalyzer extends Analyzer { try { this.executeCall( - entryPoint.entryPointSymVal?.ast, + entryPoint.entryPointSymVal?.ast?.node, entryPoint.entryPointSymVal, - argValues, state, - entryPoint.scopeVal + entryPoint.scopeVal, + { callArgs: this.buildCallArgs(entryPoint.entryPointSymVal?.ast?.node, argValues, entryPoint.entryPointSymVal) } ) } catch (e) { handleException( e, - `[${entryPoint.entryPointSymVal?.ast?.id?.name} symbolInterpret failed. Exception message saved in error log file`, - `[${entryPoint.entryPointSymVal?.ast?.id?.name} symbolInterpret failed. Exception message saved in error log file` + `[${entryPoint.entryPointSymVal?.ast?.node?.id?.name} symbolInterpret failed. Exception message saved in error log file`, + `[${entryPoint.entryPointSymVal?.ast?.node?.id?.name} symbolInterpret failed. Exception message saved in error log file` ) } this.checkerManager.checkAtSymbolInterpretOfEntryPointAfter(this, null, null, null, null) @@ -162,31 +194,31 @@ class JsAnalyzer extends Analyzer { try { this.processCompileUnit( entryPoint.scopeVal, - entryPoint.entryPointSymVal?.ast, + entryPoint.entryPointSymVal?.ast?.node, this.initState(this.topScope) ) } catch (e) { handleException( e, - `[${entryPoint.entryPointSymVal?.ast?.loc?.sourcefile} symbolInterpret failed. Exception message saved in error log file`, - `[${entryPoint.entryPointSymVal?.ast?.loc?.sourcefile} symbolInterpret failed. Exception message saved in error log file` + `[${entryPoint.entryPointSymVal?.ast?.node?.loc?.sourcefile} symbolInterpret failed. Exception message saved in error log file`, + `[${entryPoint.entryPointSymVal?.ast?.node?.loc?.sourcefile} symbolInterpret failed. Exception message saved in error log file` ) } } else { const { filePath } = entryPoint - entryPoint.entryPointSymVal = this.fileManager[filePath] - entryPoint.scopeVal = this.fileManager[filePath] + entryPoint.entryPointSymVal = this.symbolTable.get(this.fileManager[filePath]) + entryPoint.scopeVal = this.symbolTable.get(this.fileManager[filePath]) try { this.processCompileUnit( entryPoint.scopeVal, - entryPoint.entryPointSymVal?.ast, + entryPoint.entryPointSymVal?.ast?.node, this.initState(this.topScope) ) } catch (e) { handleException( e, - `[${entryPoint.entryPointSymVal?.ast?.loc?.sourcefile} symbolInterpret failed. Exception message saved in error log file`, - `[${entryPoint.entryPointSymVal?.ast?.loc?.sourcefile} symbolInterpret failed. Exception message saved in error log file` + `[${entryPoint.entryPointSymVal?.ast?.node?.loc?.sourcefile} symbolInterpret failed. Exception message saved in error log file`, + `[${entryPoint.entryPointSymVal?.ast?.node?.loc?.sourcefile} symbolInterpret failed. Exception message saved in error log file` ) } } @@ -196,23 +228,31 @@ class JsAnalyzer extends Analyzer { } /** - * - * @param dir + * 扫描模块:使用统一的 parseProject 接口,支持增量并行解析 + * @param dir - 项目目录 */ - scanModules(dir: any) { - const modules = FileUtil.loadAllFileTextGlobby( - [ - '**/*.(js|ts|mjs|cjs)', - '!**/*.test.(js|ts|mjs|cjs|jsx)', - '!**/node_modules', - '!web', - '!**/public/**', - '!**/*.d.ts', - '!**/*.d.js', - ], - dir - ) - if (modules.length === 0) { + async scanModules(dir: any) { + const PARSE_CODE_STAGE = 'preProcess.parseCode' + const PROCESS_MODULE_STAGE = 'preProcess.processModule' + + // 开始解析阶段:使用统一的 parseProject 接口,支持增量并行 + this.performanceTracker.start(PARSE_CODE_STAGE) + const astMap = await Parser.parseProject(dir, this.options, this.sourceCodeCache) + this.performanceTracker.end(PARSE_CODE_STAGE) + + // 防御性检查:确保 astMap 不为 null 或 undefined + if (!astMap) { + handleException( + null, + 'JsAnalyzer.scanModules: parseProject returned null or undefined', + 'JsAnalyzer.scanModules: parseProject returned null or undefined' + ) + return + } + + // 检查是否有文件被解析 + const fileCount = Object.keys(astMap).length + if (fileCount === 0) { handleException( null, 'find no target compileUnit of the project : no js/ts file found in source path', @@ -220,18 +260,22 @@ class JsAnalyzer extends Analyzer { ) process.exit(0) } - this.performanceTracker.start('preProcess.parseCode') - this.performanceTracker.start('preProcess.processModule') - for (const mod of modules) { - this.processModuleSrc(mod.content, mod.file) + + // 开始 ProcessModule 阶段:处理所有模块(分析 AST) + this.performanceTracker.start(PROCESS_MODULE_STAGE) + for (const filename in astMap) { + const ast = astMap[filename] + if (ast) { + // sourceCodeCache 已在 parseProject 中自动填充,不需要重新读取 + this.processModule(ast, filename) + } } - this.performanceTracker.end('preProcess.processModule') - this.performanceTracker.end('preProcess.parseCode') + this.performanceTracker.end(PROCESS_MODULE_STAGE) } /** * 处理模块源代码:解析并处理单个模块 - * + * * @param source - 源代码内容 * @param filename - 文件名 * @returns 处理结果 @@ -240,36 +284,22 @@ class JsAnalyzer extends Analyzer { const { options } = this options.sourcefile = filename - // 记录 parseCode 时间:解析源代码为 AST - const parseStart = Date.now() - const ast = Parsing.parseCode(source, options) - const parseTime = Date.now() - parseStart - this.performanceTracker.record('preProcess.parseCode', parseTime) + // 先填充 sourceCodeCache,parser 会优先使用 + this.performanceTracker.record('preProcess.parseCode')?.start() + const ast = Parser.parseSingleFile(filename, options, this.sourceCodeCache) + this.performanceTracker.record('preProcess.parseCode')?.end() - this.sourceCodeCache[filename] = source + this.sourceCodeCache.set(filename, source.split(/\n/)) if (ast) { // 记录 processModule 时间:处理模块(分析 AST) - const processStart = Date.now() + this.performanceTracker.record('preProcess.processModule')?.start() const result = this.processModule(ast, filename) - const processTime = Date.now() - processStart - this.performanceTracker.record('preProcess.processModule', processTime) + this.performanceTracker.record('preProcess.processModule')?.end() return result } } - /** - * - * @param source - * @param filename - */ - parseUast(source: any, filename: any) { - const { options } = this - options.sourcefile = filename - this.sourceCodeCache[filename] = source - return Parsing.parseCode(source, options) - } - /** * process module with cache * @param ast @@ -288,19 +318,19 @@ class JsAnalyzer extends Analyzer { ) return } - let m = this.moduleManager.field[filename] - if (m) return m + let m = this.topScope.context.modules.members.get(filename) + if (m && typeof m === 'object') return m // set this.importedModules before processModuleDirect for handling cyclic dependencies properly // module scope init // value specifies what module exports, closure specifies module closure const modClos = this.initModuleScope(ast, filename) - this.moduleManager.field[filename] = modClos.getFieldValue('module.exports') + this.topScope.context.modules.members.set(filename, modClos.getFieldValue('module.exports')) m = this.processModuleDirect(ast, filename, modClos) - if (m && typeof m !== 'undefined') { + if (m && typeof m !== 'undefined' && typeof m === 'object') { m.ast = ast - this.moduleManager.field[filename] = m - this.fileManager[filename] = m + this.topScope.context.modules.members.set(filename, m) + this.fileManager[filename] = m.uuid } return m } @@ -311,19 +341,25 @@ class JsAnalyzer extends Analyzer { * @param file * @returns Unit */ - initModuleScope(node: any, file: any) { + override initModuleScope(node: any, file: any) { // init for module // const modScope = {id:file, vtype: 'modScope', value:{}, closure:{}, decls:node, parent : this.topScope, fdef:node}; if (!file) return - const relateFileName = file.startsWith(config.maindirPrefix) - ? file.substring(config.maindirPrefix.length).split('.')[0] - : file.split('.')[0] - const modClos = Scoped({ sid: relateFileName, parent: this.topScope, decls: {}, fdef: node, ast: node }) + const prefix = file.substring(config.maindirPrefix?.length) + const lastDotIndex = prefix.lastIndexOf('.') + const result = lastDotIndex >= 0 ? prefix.substring(0, lastDotIndex) : prefix + const modClos = new Scoped('', { + sid: result, + parent: this.topScope, + decls: {}, + ast: node, + }) + modClos.ast.fdef = node ;(modClos as any)._this = modClos - const mod = ObjectValue({ id: 'module', parent: modClos }) + const mod = new ObjectValue(modClos.qid, { sid: 'module', parent: modClos }) modClos.value.module = mod - const exp = ObjectValue({ sid: 'module.exports', parent: modClos }) + const exp = new ObjectValue(modClos.qid, { sid: 'module.exports', parent: modClos }) mod.value.exports = exp modClos.value.exports = exp return modClos @@ -359,9 +395,12 @@ class JsAnalyzer extends Analyzer { const moduleExports = modClos.getFieldValue('module.exports') // 处理export是function类型的场景 - if (moduleExports?.field?.default && moduleExports?.field?.default?.vtype === 'fclos') { - this.executeCall(moduleExports.field?.default?.ast, moduleExports.field?.default, [], state, modClos) - Object.assign(moduleExports.field, this.entry_fclos.field) + const moduleDefault = moduleExports?.members?.get('default') + if (moduleDefault?.vtype === 'fclos') { + this.executeCall(moduleDefault.ast?.node, moduleDefault, state, modClos, INTERNAL_CALL) + for (const key of this.entry_fclos.members.keys()) { + moduleExports.members.set(key, this.entry_fclos.members.get(key)) + } } if (this.checkerManager && this.checkerManager.checkAtEndOfCompileUnit) { this.checkerManager.checkAtEndOfCompileUnit(this, null, null, state, null) @@ -376,15 +415,15 @@ class JsAnalyzer extends Analyzer { * @param node * @param state */ - processCallExpression(scope: any, node: any, state: any) { + override processCallExpression(scope: Scope, node: CallExpression, state: State): SymbolValueType { let res try { res = super.processCallExpression(scope, node, state) return res } catch (e) { - // const errorMsg = `YASA Simulation Execution Error in processCallExpression.Loc is ${node.loc.sourcefile} line:${node.loc.start.line}` + // const errorMsg = `YASA Simulation Execution Error in processCallExpression.Loc is ${node.loc.sourcefile} line:${node.loc.start?.line}` // handleException(e, errorMsg) - return UndefinedValue() + return new UndefinedValue() } } @@ -395,7 +434,7 @@ class JsAnalyzer extends Analyzer { * @param state * @returns {UndefinedValue} */ - processTryStatement(scope: any, node: any, state: any) { + override processTryStatement(scope: Scope, node: TryStatement, state: State): VoidValueType { // 往state中创建throwstack state.throwstack = state.throwstack ?? [] // 处理try的body @@ -405,36 +444,38 @@ class JsAnalyzer extends Analyzer { if (node.handlers && node.handlers.length > 0) { // nodejs 一个try只有一个catch 因此只取第一个 const handler = node.handlers[0] - const subScope = JsAnalyzer.createSubScope( - ``, - scope - ) - // 如果有异常则初始化异常的init - if (state?.throwstack?.length > 0) { - const throw_value = state.throwstack[0] - for (const param of handler.parameter) { - if (param && param.type === 'VariableDeclaration' && param.init === null) { - param._meta.isCatchParam = true - // 尽管throwvalue在state中 - // 但还是要设置init,如果init为空会优先进入默认的初始化逻辑 - // 则无法从state.throwstack取值 - param.init = { - type: 'Identifier', - // 此处替换成 最近一个throw的值即可 - name: throw_value.sid, - callee: param.varType.id, - arguments: [], - _meta: param._meta, - loc: param.loc, - parent: param.parent, + if (handler) { + const subScope = ScopeClass.createSubScope( + ``, + scope + ) + // 如果有异常则初始化异常的init + if (state?.throwstack?.length > 0) { + const throw_value = state.throwstack[0] + for (const param of handler.parameter) { + if (param && param.type === 'VariableDeclaration' && param.init === null) { + param._meta.isCatchParam = true + // 尽管throwvalue在state中 + // 但还是要设置init,如果init为空会优先进入默认的初始化逻辑 + // 则无法从state.throwstack取值 + param.init = { + type: 'Identifier', + // 此处替换成 最近一个throw的值即可 + name: throw_value.sid, + callee: param.varType.id, + arguments: [], + _meta: param._meta, + loc: param.loc, + parent: param.parent, + } as any } } } + // 先处理catch的参数 为e赋值 + handler.parameter.forEach((param: any) => this.processInstruction(subScope, param, state)) + // 赋值后的e再处理body + this.processInstruction(subScope, handler.body, state) } - // 先处理catch的参数 为e赋值 - handler.parameter.forEach((param: any) => this.processInstruction(subScope, param, state)) - // 赋值后的e再处理body - this.processInstruction(subScope, handler.body, state) } // 最后处理finally if (node.finalizer) this.processInstruction(scope, node.finalizer, state) @@ -443,6 +484,7 @@ class JsAnalyzer extends Analyzer { if (state?.throwstack?.length === 0) { delete state.throwstack } + return new VoidValue() } /** @@ -451,24 +493,24 @@ class JsAnalyzer extends Analyzer { * @param node * @param state */ - processAssignmentExpression(scope: any, node: any, state: any) { + override processAssignmentExpression(scope: Scope, node: AssignmentExpression, state: State): SymbolValueType { let res try { res = super.processAssignmentExpression(scope, node, state) } catch (e) { - return UndefinedValue() + return new UndefinedValue() } // 如果是解构赋值,且处理最后的rest的赋值,需要对rest的下标进行重整 // [r1,r2,...rest] = [1,2,3,4] // rest <=> [3,4] rest[0]=3 rest[1]=4 - if (res?.ast?._meta?.isArray) { - const rawRestIndexs = Object.keys(res.field) + if ((res as any)?.ast?.node?._meta?.isArray) { + const rawRestIndexs = [...res.members.keys()] .map((keyStr) => parseInt(keyStr)) .filter((keyNum) => Number.isInteger(keyNum)) .sort() // 找到第一个vtype不是undefine的下标 - const offset = rawRestIndexs.findIndex((index) => res.field[index]?.vtype !== 'undefine') + const offset = rawRestIndexs.findIndex((index) => res.members.get(index.toString())?.vtype !== 'undefine') if (offset > 0) { // 将数组划分为2部分 第一部分全是undefined数据,第二部分为有效数据 // 将第二部分数据往左平移,并删除多余索引 @@ -476,26 +518,19 @@ class JsAnalyzer extends Analyzer { // 平移以后 arr=[objectvalue,objectvalue,objectvalue] for (let i = 0; i < rawRestIndexs.length; i++) { if (i < rawRestIndexs.length - offset) { - res.field[i.toString()] = res.field[(offset + i).toString()] + const shifted = res.members.get((offset + i).toString()) + if (shifted) res.members.set(i.toString(), shifted) } else { - delete res.field[i.toString()] + res.members.delete(i.toString()) } } this.saveVarInScope(scope, node.left, res, state) } } // Assignment brings trace back,sometimes in obj (if ObjExpression) - if (res && res?.hasTagRec && node?.operator !== '=' && typeof res?.trace === 'undefined') { - // 添加trace - const trace = { - file: node.loc.sourcefile || node.sourcefile, - line: node.loc.start.line, - node, - tag: 'Var Pass:', - affectedNodeName: (res as any).left._sid, - } + if (res && res?.taint?.isTaintedRec && node?.operator !== '=' && !res?.taint.hasTraces()) { // this.processAssignmentToBinary(res) - ;(res as any).trace = undefined + ;(res as any).taint.clearTrace() } return res } @@ -506,12 +541,12 @@ class JsAnalyzer extends Analyzer { * @param node * @param state */ - processMemberAccess(scope: any, node: any, state: any) { + override processMemberAccess(scope: Scope, node: MemberAccess, state: State): SymbolValueType { let res try { res = super.processMemberAccess(scope, node, state) } catch (e) { - return UndefinedValue() + return new UndefinedValue() } return res } @@ -522,26 +557,24 @@ class JsAnalyzer extends Analyzer { * @param node * @param state */ - processUnaryExpression(scope: any, node: any, state: any) { + override processUnaryExpression(scope: Scope, node: UnaryExpression, state: State): UnaryExprValue { const nodeValue = super.processUnaryExpression(scope, node, state) if (node.operator === 'delete') { - // 根据delete的arguments获取对应 scope的field存储的值 - // 注意这里传入的是node.argument.object 获取到field中node.argument.object的值 - // 这样才能进一步通过target?.field[node.argument.property.name]访问到目标property 并进行删除操作 - // 否则直接delete target操作无效 delete只能作用在变量的属性,不能直接作用在变量上 - const target = this.getDeleteTargetInScopeField(scope, node.argument?.object) + // 根据 delete 的 arguments 获取对应 scope 的 field 存储的值 + // 传入 node.argument.object 获取 field 中对应的值,才能通过 target?.field[property.name] 访问目标 property + // delete 只能作用在变量的属性上,不能直接作用在变量上 + const argAny = node.argument as any + const target = this.getDeleteTargetInScopeField(scope, argAny?.object ?? node.argument) if (target != null) { - const index = node.argument?.computed ? node.argument?.property.value : node.argument?.property.name - if (index != null && target?.field[index] != null) { - // link:uast引入的delete操作的删除语义在 Analyzer.processAssignmentExpression实现 - // 如果是解构赋值,且处理最后的rest的赋值,需要对rest的下标进行重整 - // [r1,r2,...rest] = [1,2,3,4] - // rest <=> [3,4] rest[0]=3 rest[1]=4 + const index = argAny?.computed ? argAny?.property?.value : argAny?.property?.name + const indexKey = index != null ? String(index) : null + const targetMember = indexKey != null ? target?.members?.get(indexKey) : null + if (targetMember != null) { target.setFieldValue( index, - UndefinedValue({ - sid: target?.field[index].sid, - qid: target?.field[index].qid, + new UndefinedValue({ + sid: targetMember.sid, + qid: targetMember.qid, parent: target, }) ) @@ -560,23 +593,24 @@ class JsAnalyzer extends Analyzer { getDeleteTargetInScopeField(scope: any, argNode: any): any { if (!argNode || (argNode.type !== 'MemberAccess' && argNode.type !== 'Identifier')) return - const propName = argNode?.property?.name - if (argNode.type === 'Identifier' || argNode?.object?.type === 'Identifier') { + const argNodeAny = argNode as any + const propName = argNodeAny?.property?.name + if (argNode.type === 'Identifier' || argNodeAny?.object?.type === 'Identifier') { // 单层访问 a.b的情况 - const defScope = Scope.getDefScope(scope, argNode) + const defScope = ScopeClass.getDefScope(scope, argNode) if (!propName) { // 当前argnode本身就是object了 - return defScope?.getFieldValue(argNode.name) + return defScope?.getFieldValue(argNodeAny.name) // return field[argNode.name] } - const objName = argNode.object.name + const objName = argNodeAny.object?.name return defScope?.getFieldValue(objName)?.getFieldValue(propName) // return field[objName].field[propName] } // 多层访问 a.b.c if (argNode?.object?.type === 'MemberAccess') { const objField: any = this.getDeleteTargetInScopeField(scope, argNode.object) - return objField?.field[propName] + return objField?.members?.get(propName) } } @@ -586,7 +620,7 @@ class JsAnalyzer extends Analyzer { * @param node * @param state */ - processBinaryExpression(scope: any, node: any, state: any) { + override processBinaryExpression(scope: Scope, node: BinaryExpression, state: State): BinaryExprValue { let res = super.processBinaryExpression(scope, node, state) res = processBinaryOperator(res, scope, node, state) return res @@ -598,17 +632,17 @@ class JsAnalyzer extends Analyzer { * @param node * @param state */ - processConditionalExpression(scope: any, node: any, state: any) { + override processConditionalExpression(scope: Scope, node: ConditionalExpression, state: State): SymbolValueType { const res = super.processConditionalExpression(scope, node, state) if ( - typeof (res as any).field !== 'undefined' && - (Array.isArray((res as any).field) || Object.getOwnPropertyNames((res as any).field).length !== 0) && - (res as any).hasTagRec !== true + typeof (res as any)._field !== 'undefined' && + (Array.isArray((res as any)._field) || Object.getOwnPropertyNames((res as any)._field).length !== 0) && + (res as any).taint?.isTaintedRec !== true ) { try { - ;(res as any).field.forEach((arg: any) => { - if (arg.hasTagRec) { - ;(res as any).hasTagRec = true + ;(res as any)._field.forEach((arg: any) => { + if (arg.taint?.isTaintedRec) { + ;(res as any).taint?.markSource() throw new Error('LoopInterrupt') } }) @@ -623,7 +657,7 @@ class JsAnalyzer extends Analyzer { * @param node * @param state */ - processVariableDeclaration(scope: any, node: any, state: any) { + override processVariableDeclaration(scope: Scope, node: VariableDeclaration, state: State): SymbolValueType { const res = super.processVariableDeclaration(scope, node, state) // Array内置函数适配,由于array的构造不需要构造方法,因此无法像promise、map、set一样在初始化的时候填充内置函数 @@ -632,44 +666,10 @@ class JsAnalyzer extends Analyzer { Initializer.initArrayBuiltin(res) } - // VariableDeclaration brings traces back - // 处理重复trace情况,本质是由于语法糖拆解多个节点引起的 - if ((res as any)?.trace) { - if (Array.isArray((res as any).trace)) { - const traceDeduplication: any[] = [] - let flag = 0 - for (const argT in (res as any).trace) { - if (argT === '0') { - traceDeduplication[flag] = (res as any).trace[argT] - flag++ - } else { - if ((res as any).trace[argT].tag === 'Field: ') { - continue - } - const tem = traceDeduplication[flag - 1] - if ( - tem.file === (res as any).trace[argT].file && - tem.tag === (res as any).trace[argT].tag && - JSON.stringify(tem.line) === JSON.stringify((res as any).trace[argT].line) - ) { - if (tem.affectedNodeName === (res as any).trace[argT].affectedNodeName) { - continue - } else if (tem.affectedNodeName.includes('__tmp')) { - traceDeduplication.pop() - flag-- - } else continue - } - traceDeduplication[flag] = (res as any).trace[argT] - flag++ - } - } - ;(res as any).trace = traceDeduplication - } - } if ((res as any)?.vtype === 'union') { - if ((res as any).field[0]?.hasTagRec || (res as any).field[1]?.hasTagRec) { - ;(res as any).hasTagRec = true + if ((res as any).getFieldValue('0')?.taint?.isTaintedRec || (res as any).getFieldValue('1')?.taint?.isTaintedRec) { + ;(res as any).taint?.markSource() } } return res @@ -681,42 +681,46 @@ class JsAnalyzer extends Analyzer { * @param node * @param state */ - processSpreadElement(scope: any, node: any, state: any) { + override processSpreadElement(scope: Scope, node: SpreadElement, state: State): SpreadValue { let res = super.processSpreadElement(scope, node, state) if (res) { - if ((res as any).length === 0) { - res = this.processInstruction(scope, node.argument, state) + // 检查 SpreadValue 是否为空,如果为空则重新计算并替换 + // 保持与原始行为一致:当 spread 结果为空时,直接返回 argument 的处理结果 + if (Array.isArray(res) && (res as any).length === 0) { + res = this.processInstruction(scope, node.argument, state) as any } + + // 检查 SpreadValue 的污点信息(兼容数组和 SpreadValue) if (Array.isArray(res)) { const anyHasTag = (res as any).some((item: any) => { - return item.hasTagRec + return item instanceof Unit && item.taint?.isTaintedRec }) // 如果每一个元素都没有污点才return if (!anyHasTag) { - return res + return res as SpreadValue } } - if (scope?.ast?.type === 'ObjectExpression') { - if ((scope as any).hasTagRec !== true) { - ;(scope as any).hasTagRec = (res as any).hasTagRec + if (scope?.ast?.node?.type === 'ObjectExpression') { + if ((scope as any).taint?.isTaintedRec !== true && res instanceof Unit) { + ;(scope as any).taint?.propagateFrom(res) } - if ((scope as any).hasTagRec) { - if (Array.isArray((scope as any).field)) { - ;(scope as any).field.push(res) + if ((scope as any).taint?.isTaintedRec) { + if (Array.isArray((scope as any)._field)) { + ;(scope as any)._field.push(res) } else { let flag = 0 let tmp = `YASATmp${flag}` - while ((scope as any).field[tmp]) { + while ((scope as any).members?.get(tmp)) { flag++ tmp = `YASATmp${flag}` } - ;(scope as any).field[tmp] = res + ;(scope as any).members?.set(tmp, res) } } } } - return res + return res as SpreadValue } /** @@ -725,18 +729,18 @@ class JsAnalyzer extends Analyzer { * @param node * @param state */ - processObjectExpression(scope: any, node: any, state: any) { + override processObjectExpression(scope: Scope, node: ObjectExpression, state: State): SymbolValueType { const res = super.processObjectExpression(scope, node, state) if ((res as any).value) { for (const val in (res as any).value) { if ( (val.includes('CallBack') || val.includes('callback') || val.includes('callBacks')) && (res as any).value[val].vtype === 'fclos' && - (res as any).value[val].fdef + (res as any).value[val].ast.fdef ) { const argvalues: any[] = [] - if ((res as any).value[val].fdef?.parameters && (res as any).value[val].fdef.parameters.length > 0) { - for (const para of (res as any).value[val].fdef.parameters) { + if ((res as any).value[val].ast.fdef?.parameters && (res as any).value[val].ast.fdef.parameters.length > 0) { + for (const para of (res as any).value[val].ast.fdef.parameters) { const argv = this.processInstruction(scope, para, state) if (Array.isArray(argv)) { argvalues.push(...argv) @@ -746,7 +750,7 @@ class JsAnalyzer extends Analyzer { } } // execute call callback - this.executeCall((res as any).value[val].fdef, (res as any).value[val], argvalues, state, scope) + this.executeCall((res as any).value[val].ast.fdef, (res as any).value[val], state, scope, { callArgs: this.buildCallArgs((res as any).value[val].ast.fdef, argvalues, (res as any).value[val]) }) } } } @@ -760,29 +764,34 @@ class JsAnalyzer extends Analyzer { * @param scope * @param state */ - postProcessFunctionDefinition(fclos: any, node: any, scope: any, state: any) { + override postProcessFunctionDefinition(fclos: any, node: any, scope: any, state: any) { super.postProcessFunctionDefinition(fclos, node, scope, state) /** add function builtin * */ // FIXME check builtin override const builtins = [ - FunctionValue({ + new FunctionValue(fclos.qid, { sid: 'apply', _this: (this as any).thisFClos, parent: null, - execute: Initializer.builtin['function.apply'], + runtime: { execute: Initializer.builtin['function.apply'] }, }), - FunctionValue({ + new FunctionValue(fclos.qid, { sid: 'call', _this: (this as any).thisFClos, parent: null, - execute: Initializer.builtin['function.call'], + runtime: { execute: Initializer.builtin['function.call'] }, }), // TODO function.bind ] for (const builtin of builtins) { - this.saveVarInCurrentScope(fclos, PrimitiveValue({ type: 'Literal', value: builtin.sid }), builtin, state) + this.saveVarInCurrentScope( + fclos, + new PrimitiveValue(fclos.qid, builtin.sid, builtin.sid, null, 'Literal'), + builtin, + state + ) builtin.parent = fclos } } @@ -794,13 +803,13 @@ class JsAnalyzer extends Analyzer { * @param state * @returns {*} */ - processImportDirect(scope: any, node: any, state: any) { + processImportDirect(scope: Scope, node: any, state: State): Value { if (node?.from) { node = node.from } // if (DEBUG) logger.info('require: ' + formatNode(node)); const fname = - node?.value || AstUtil.prettyPrint(node) || `${node.loc.start.line}_${node.loc.start.column}` + node?.value || AstUtil.prettyPrint(node) || `${node.loc.start?.line}_${node.loc.start?.column}` if (fname[0] !== '.' || fname.endsWith('.less')) { // load predefined builtin models @@ -819,7 +828,7 @@ class JsAnalyzer extends Analyzer { 'Error occurred in JsAnalyzer.processImportDirect: failed to sourcefile in ast', 'Error occurred in JsAnalyzer.processImportDirect: failed to sourcefile in ast' ) - return + return new UndefinedValue() } let pathname = path.resolve(path.dirname(sourcefile.toString()), fname) @@ -853,19 +862,19 @@ class JsAnalyzer extends Analyzer { } // check cached imports first - const m = this.moduleManager.field[pathname] - if (m) return m + const m = this.topScope.context.modules.members.get(pathname) + if (m && typeof m === 'object') return m let res try { const prog = FileUtil.loadAllFileText(pathname, ['js', 'ts', 'mjs', 'cjs', 'json'])[0] if (prog) { - if (pathname.endsWith('json')) { - prog.content = `module.exports = ${prog.content}` - } - const ast = Parsing.parseCode(prog.content, { sourcefile: prog.file, language: 'js' }) + // 先填充 sourceCodeCache,parser 会优先使用 + const fileContent = pathname.endsWith('json') ? `module.exports = ${prog.content}` : prog.content + this.sourceCodeCache.set(prog.file, fileContent.split(/\n/)) + const ast = Parser.parseSingleFile(prog.file, { ...this.options, sourcefile: prog.file }, this.sourceCodeCache) if (ast) { - this.sourceCodeCache[prog.file] = prog.content + this.sourceCodeCache.set(prog.file, prog.content.split(/\n/)) res = this.processModule(ast, pathname) } } @@ -897,16 +906,15 @@ class JsAnalyzer extends Analyzer { // 1. built-in module // 2. importing from third party package in node_modules - let m = this.moduleManager.field[fname] - if (m) return m - m = ObjectValue({ + let m = this.topScope.context.modules.members.get(fname) + if (m && typeof m === 'object') return m + m = new ObjectValue(this.topScope.context.modules.qid, { sid: fname, - parent: this.moduleManager, - fdef: undefined, + parent: this.topScope.context.modules, node_module: true, }) // v.parent = m; - this.moduleManager.field[fname] = m + this.topScope.context.modules.members.set(fname, m) return m } @@ -916,13 +924,14 @@ class JsAnalyzer extends Analyzer { * @param node * @param state */ - processForStatement(scope: any, node: any, state: any) { + override processForStatement(scope: Scope, node: ForStatement, state: State): VoidValueType { // If ForStatement is aim at iterating over target, tweak node to RangeStatement for better evaluation const { test, update } = node // matching iteration over pattern if ( test?.type === 'BinaryExpression' && test?.right?.type === 'MemberAccess' && + test?.right?.property?.type === 'Identifier' && test?.right?.property?.name === 'length' && update?.type === 'UnaryExpression' && update?.operator === '++' @@ -936,7 +945,7 @@ class JsAnalyzer extends Analyzer { } if (node.init === null && node.test === null && node.update === null) { // for(;;) - return this.processScopedStatement(scope, node.body, state) + return this.processScopedStatement(scope, node.body as any, state) } return super.processForStatement(scope, node, state) } @@ -944,7 +953,7 @@ class JsAnalyzer extends Analyzer { /** * */ - initTopScope() { + override initTopScope() { Initializer.initGlobalScope(this.topScope) } @@ -954,15 +963,15 @@ class JsAnalyzer extends Analyzer { * @param node * @param state */ - processReturnStatement(scope: any, node: any, state: any) { + override processReturnStatement(scope: Scope, node: ReturnStatement, state: State): VoidValueType { let retVal try { retVal = super.processReturnStatement(scope, node, state) } catch (e) { - return UndefinedValue() + return new UndefinedValue() } - if ((node as any).isYield && (retVal as any)._sid === 'Promise') { + if ((node as any).isYield && (retVal.sid === 'Promise' || retVal.sid.includes('Promise, varType: string): void { scope.setFieldValue( 'prototype', - JsObjectValue({ - id: 'prototype', + new ObjectValue(scope.qid, { sid: 'prototype', - qid: 'prototype', parent: scope, }) ) for (const funcName of Object.keys(builtinMap)) { const qqid = varType != null ? `${varType}.${funcName}` : funcName - scope.field.prototype.setFieldValue( + scope.members.get('prototype')!.setFieldValue( funcName, - JsFunctionValue({ + new FunctionValue('', { sid: funcName, qid: qqid, parent: scope, - execute: builtinMap[funcName], + runtime: { execute: builtinMap[funcName] }, }) ) } @@ -83,11 +81,11 @@ class JsInitializer { static initReflectBuiltin(scope: any): void { scope.setFieldValue( 'Reflect', - JsObjectValue({ + new ObjectValue('', { sid: 'Reflect', qid: 'Reflect', parent: scope, - execute: JsInitializer.builtin['Reflect.get'], + runtime: { execute: JsInitializer.builtin['Reflect.get'] }, }) ) @@ -96,13 +94,13 @@ class JsInitializer { if (func === 'defineProperty') { func = 'set' } - scope.field.Reflect.setFieldValue( + scope.members.get('Reflect')!.setFieldValue( func, - JsFunctionValue({ + new FunctionValue('', { sid: func, qid: `Reflect.${func}`, parent: scope, - execute: (JsInitializer.builtin as any)[`Reflect.${func}`], + runtime: { execute: (JsInitializer.builtin as any)[`Reflect.${func}`] }, }) ) } @@ -130,10 +128,10 @@ class JsInitializer { static initSetBuiltin(scope: any): void { scope.setFieldValue( 'Set', - JsObjectValue({ + new ObjectValue(scope.qid, { sid: 'Set', parent: scope, - execute: JsInitializer.builtin.newSet, + runtime: { execute: JsInitializer.builtin.newSet }, }) ) } @@ -145,10 +143,10 @@ class JsInitializer { static initMapBuiltin(scope: any): void { scope.setFieldValue( 'Map', - JsObjectValue({ + new ObjectValue(scope.qid, { sid: 'Map', parent: scope, - execute: JsInitializer.builtin.newMap, + runtime: { execute: JsInitializer.builtin.newMap }, }) ) } @@ -158,15 +156,13 @@ class JsInitializer { * @param scope */ static initVMBuiltin(scope: any): void { - const vm2 = JsObjectValue({ - id: 'vm2', + const vm2 = new ObjectValue('', { sid: 'vm2', qid: `vm2.`, parent: scope, }) scope.setFieldValue('vm2', vm2) - const VM = JsObjectValue({ - id: 'VM', + const VM = new ObjectValue('', { sid: 'VM', qid: `vm2.VM`, parent: scope, @@ -174,7 +170,7 @@ class JsInitializer { vm2.setFieldValue('VM', VM) VM.setFieldValue( 'run', - JsFunctionValue({ + new FunctionValue('', { id: 'run', sid: 'run', qid: `vm2.VM.run`, @@ -189,38 +185,37 @@ class JsInitializer { */ static introduceGlobalBuiltin(scope: any): void { // TODO Global builtins modeling - scope.setFieldValue('Object', JsObjectValue({ sid: 'Object' })) - scope.setFieldValue('Array', JsObjectValue({ sid: 'Array' })) - // scope.setFieldValue('Set', JsObjectValue({ sid: 'Set' })) - scope.setFieldValue('Map', JsObjectValue({ sid: 'Map' })) - scope.setFieldValue('JSON', JsObjectValue({ sid: 'JSON' })) - scope.setFieldValue('Math', JsObjectValue({ sid: 'Math' })) - scope.setFieldValue('Date', JsObjectValue({ sid: 'Date' })) - scope.setFieldValue('console', JsObjectValue({ sid: 'console' })) - scope.setFieldValue('__dirname', JsObjectValue({ sid: '__dirname' })) - scope.setFieldValue('process', JsObjectValue({ sid: 'process' })) - scope.setFieldValue('Symbol', JsObjectValue({ sid: 'Symbol' })) - const requireFuncVal = JsFunctionValue({ + scope.setFieldValue('Object', new ObjectValue('', { sid: 'Object', qid: `${scope.qid}.Object` })) + scope.setFieldValue('Array', new ObjectValue('', { sid: 'Array', qid: `${scope.qid}.Array` })) + scope.setFieldValue('Map', new ObjectValue('', { sid: 'Map', qid: `${scope.qid}.Map` })) + scope.setFieldValue('JSON', new ObjectValue('', { sid: 'JSON', qid: `${scope.qid}.JSON` })) + scope.setFieldValue('Math', new ObjectValue('', { sid: 'Math', qid: `${scope.qid}.Math` })) + scope.setFieldValue('Date', new ObjectValue('', { sid: 'Date', qid: `${scope.qid}.Date` })) + scope.setFieldValue('console', new ObjectValue('', { sid: 'console', qid: `${scope.qid}.console` })) + scope.setFieldValue('__dirname', new ObjectValue('', { sid: '__dirname', qid: `${scope.qid}.__dirname` })) + scope.setFieldValue('process', new ObjectValue('', { sid: 'process', qid: `${scope.qid}.process` })) + scope.setFieldValue('Symbol', new ObjectValue('', { sid: 'Symbol', qid: `${scope.qid}.Symbol` })) + const requireFuncVal = new FunctionValue('', { sid: 'require', - qid: 'require', + qid: `${scope.qid}.require`, parent: scope, - execute: JsInitializer.builtin.require, + runtime: { execute: JsInitializer.builtin.require }, }) scope.setFieldValue('require', requireFuncVal) - if (scope.funcSymbolTable) { + if (scope.context?.funcs) { // eslint-disable-next-line no-param-reassign - scope.funcSymbolTable.require = requireFuncVal + scope.context.funcs.require = requireFuncVal } - const promiseFuncVal = JsFunctionValue({ + const promiseFuncVal = new FunctionValue('', { sid: 'Promise', - qid: 'Promise', + qid: `${scope.qid}.Promise`, parent: scope, - execute: JsInitializer.builtin.Promise, + runtime: { execute: JsInitializer.builtin.Promise }, }) scope.setFieldValue('Promise', promiseFuncVal) - if (scope.funcSymbolTable) { + if (scope.context?.funcs) { // eslint-disable-next-line no-param-reassign - scope.funcSymbolTable.Promise = promiseFuncVal + scope.context.funcs.Promise = promiseFuncVal } // 新增的建模 // Initializer.initArrayBuiltin(scope) @@ -240,7 +235,7 @@ class JsInitializer { static resetInitVariables(scope: any): void { for (const field of Object.keys(scope.value)) { const v = scope.value[field] - if (v.trace) delete v.trace + if (v.taint) v.taint.clearTrace() } } } diff --git a/src/engine/analyzer/javascript/egg/egg-analyzer.ts b/src/engine/analyzer/javascript/egg/egg-analyzer.ts index 04e2f9ae..c7e23ce5 100644 --- a/src/engine/analyzer/javascript/egg/egg-analyzer.ts +++ b/src/engine/analyzer/javascript/egg/egg-analyzer.ts @@ -1,3 +1,5 @@ +import { buildNewCopiedWithTag } from '../../../../util/clone-util' + const path = require('path') const fs = require('fs-extra') const globby = require('fast-glob') @@ -5,7 +7,6 @@ const globby = require('fast-glob') const _ = require('lodash') const logger = require('../../../../util/logger')(__filename) const FileUtil = require('../../../../util/file-util') -const { Errors } = require('../../../../util/error-code') const JsAnalyzer = require('../common/js-analyzer') const Initializer = require('./egg-initializer') const Loader = require('../../../../util/loader') @@ -19,7 +20,6 @@ const { } = require('../../common') const constValue = require('../../../../util/constant') -const { cloneWithDepth } = require('../../../../util/clone-util') const { handleException } = require('../../common/exception-handler') const { eggSanityCheck } = require('../../../../util/framework-util') @@ -32,7 +32,7 @@ const load_mod_enum = { /** * */ -class EggAnalyzer extends (JsAnalyzer as any) { +class EggAnalyzer extends JsAnalyzer { /** * * @param options @@ -48,18 +48,25 @@ class EggAnalyzer extends (JsAnalyzer as any) { preProcess(dir: any) { // init global scope Initializer.initGlobalScope(this.topScope) - // prepare state this.state = this.initState(this.topScope) // 1st process this.scanModules(dir) - Initializer.initEgg(this.moduleManager) + + Initializer.initEgg(this.topScope.context.modules) // 让this.ctx.***能找到符号值 this.loadToApp(dir, this.state) - logger.info(`ParseCode time: ${this.totalParseTime}ms`) - logger.info(`ProcessModule time: ${this.totalProcessTime}ms`) + } + + /** + * 加载缓存后的初始化阶段,会创建一些全局builtin + */ + initAfterUsingCache() { + Initializer.introduceGlobalBuiltin(this.topScope) + // prepare state + this.state = this.initState(this.topScope) } /** @@ -74,37 +81,39 @@ class EggAnalyzer extends (JsAnalyzer as any) { const hasAnalysised: any[] = [] for (const entryPoint of this.entryPoints) { if (entryPoint.type === constValue.ENGIN_START_FUNCALL) { + this.symbolTable.clear() if ( hasAnalysised.includes( - `${entryPoint.filePath}.${entryPoint.functionName}/${entryPoint?.entryPointSymVal?._qid}#${entryPoint.entryPointSymVal.ast.parameters}.${entryPoint.attribute}` + `${entryPoint.filePath}.${entryPoint.functionName}/${entryPoint?.entryPointSymVal?.qid}#${entryPoint.entryPointSymVal.ast.node.parameters}.${entryPoint.attribute}` ) ) { continue } hasAnalysised.push( - `${entryPoint.filePath}.${entryPoint.functionName}/${entryPoint?.entryPointSymVal?._qid}#${entryPoint.entryPointSymVal.ast.parameters}.${entryPoint.attribute}` + `${entryPoint.filePath}.${entryPoint.functionName}/${entryPoint?.entryPointSymVal?.qid}#${entryPoint.entryPointSymVal.ast.node.parameters}.${entryPoint.attribute}` ) EntryPointConfig.setCurrentEntryPoint(entryPoint) const { entryPointSymVal, argValues, scopeVal } = entryPoint - EggCommon.refreshCtx(scopeVal?.value?.ctx?.field) + // TODO(field-removal): refreshCtx 依赖 field proxy 的 delete trap,需配合 refreshCtx 一起迁移 + EggCommon.refreshCtx(scopeVal?.value?.ctx?.value) this.checkerManager.checkAtSymbolInterpretOfEntryPointBefore(this, null, null, null, null) - this.replaceCtxInFunctionParams(entryPointSymVal.ast, argValues, entryPointSymVal, scopeVal, this.state) + this.replaceCtxInFunctionParams(entryPointSymVal.ast.node, argValues, entryPointSymVal, scopeVal, this.state) try { logger.info( 'EntryPoint [%s.%s] is executing ', entryPoint.filePath?.substring(0, entryPoint?.filePath?.lastIndexOf('.')), entryPoint.functionName || - `` ) - this.executeCall(entryPointSymVal.ast, entryPointSymVal, argValues, this.state, scopeVal) + this.executeCall(entryPointSymVal.ast.node, entryPointSymVal, this.state, scopeVal, { callArgs: this.buildCallArgs(entryPointSymVal.ast.node, argValues, entryPointSymVal) }) } catch (e) { handleException( e, - `[${entryPoint.entryPointSymVal?.ast?.id?.name} symbolInterpret failed. Exception message saved in error log file`, - `[${entryPoint.entryPointSymVal?.ast?.id?.name} symbolInterpret failed. Exception message saved in error log file` + `[${entryPoint.entryPointSymVal?.ast?.node?.id?.name} symbolInterpret failed. Exception message saved in error log file`, + `[${entryPoint.entryPointSymVal?.ast?.node?.id?.name} symbolInterpret failed. Exception message saved in error log file` ) } this.checkerManager.checkAtSymbolInterpretOfEntryPointAfter(this, null, null, null, null) @@ -119,31 +128,31 @@ class EggAnalyzer extends (JsAnalyzer as any) { try { this.processCompileUnit( entryPoint.scopeVal, - entryPoint.entryPointSymVal?.ast, + entryPoint.entryPointSymVal?.ast?.node, this.initState(this.topScope) ) } catch (e) { handleException( e, - `[${entryPoint.entryPointSymVal?.ast?.loc?.sourcefile} symbolInterpret failed. Exception message saved in error log file`, - `[${entryPoint.entryPointSymVal?.ast?.loc?.sourcefile} symbolInterpret failed. Exception message saved in error log file` + `[${entryPoint.entryPointSymVal?.ast?.node?.loc?.sourcefile} symbolInterpret failed. Exception message saved in error log file`, + `[${entryPoint.entryPointSymVal?.ast?.node?.loc?.sourcefile} symbolInterpret failed. Exception message saved in error log file` ) } } else { const { filePath } = entryPoint - entryPoint.entryPointSymVal = this.fileManager[filePath] - entryPoint.scopeVal = this.fileManager[filePath] + entryPoint.entryPointSymVal = this.symbolTable.get(this.fileManager[filePath]) + entryPoint.scopeVal = this.symbolTable.get(this.fileManager[filePath]) try { this.processCompileUnit( entryPoint.scopeVal, - entryPoint.entryPointSymVal?.ast, + entryPoint.entryPointSymVal?.ast?.node, this.initState(this.topScope) ) } catch (e) { handleException( e, - `[${entryPoint.entryPointSymVal?.ast?.loc?.sourcefile} symbolInterpret failed. Exception message saved in error log file`, - `[${entryPoint.entryPointSymVal?.ast?.loc?.sourcefile} symbolInterpret failed. Exception message saved in error log file` + `[${entryPoint.entryPointSymVal?.ast?.node?.loc?.sourcefile} symbolInterpret failed. Exception message saved in error log file`, + `[${entryPoint.entryPointSymVal?.ast?.node?.loc?.sourcefile} symbolInterpret failed. Exception message saved in error log file` ) } } @@ -176,7 +185,11 @@ class EggAnalyzer extends (JsAnalyzer as any) { argValues.push(valExport.value.ctx) } else { argValues.push( - this.processInstruction(cloneWithDepth(entryPointSymVal, 2), astNode.parameters[key].id, state) + this.processInstruction( + buildNewCopiedWithTag(this, entryPointSymVal, 'tmp'), + astNode.parameters[key].id, + state + ) ) } } @@ -190,10 +203,10 @@ class EggAnalyzer extends (JsAnalyzer as any) { * @param state */ loadToApp(dir: any, state: any) { - const appclass = this.moduleManager.getFieldValue('Egg.Application') - const app = this.buildNewObject(appclass.fdef, [], appclass, state, appclass.fdef, this.topScope) - const ctxclass = this.moduleManager.getFieldValue('Egg.Context') - const ctx = this.buildNewObject(ctxclass.fdef, [], ctxclass, state, ctxclass.fdef, this.topScope) + const appclass = this.topScope.context.modules.getFieldValue('Egg.Application') + const app = this.buildNewObject(appclass.ast.fdef, appclass, state, appclass.ast.fdef, this.topScope) + const ctxclass = this.topScope.context.modules.getFieldValue('Egg.Context') + const ctx = this.buildNewObject(ctxclass.ast.fdef, ctxclass, state, ctxclass.ast.fdef, this.topScope) this.topScope.setFieldValue('ctx', ctx) this.topScope.setFieldValue('app', app) @@ -273,7 +286,7 @@ class EggAnalyzer extends (JsAnalyzer as any) { for (let i = 0; i < properties.length; i++) { const prop = properties[i] if (i === properties.length - 1) { - const exports = this.moduleManager.field[fullpath] + const exports = this.topScope.context.modules.members.get(fullpath) if (!exports) { handleException(null, '', `${fullpath} module is not found`) continue @@ -285,28 +298,28 @@ class EggAnalyzer extends (JsAnalyzer as any) { continue } let val - let fdef = export_value.fdef || export_value.ast + let fdef = export_value.ast.fdef || export_value.ast.node switch (opt.loadMod) { case load_mod_enum.INST: // generator indicates fdef itself is controller method, e.g. if (!fdef || fdef.generator) { val = export_value } else if (fdef.type === 'FunctionDefinition') { - val = this.executeCall(fdef, export_value, [app], this.initState(export_value), scope) + val = this.executeCall(fdef, export_value, this.initState(export_value), scope, { callArgs: this.buildCallArgs(fdef, [app], export_value) }) if (val && val?.vtype !== 'undefine') { - fdef = val.fdef || val.ast + fdef = val.ast.fdef || val.ast.node if (fdef) { - val = this.buildNewObject(fdef, [], val, this.initState(export_value), fdef, scope) + val = this.buildNewObject(fdef, val, this.initState(export_value), fdef, scope) } } else { val = export_value } } else { - val = this.buildNewObject(fdef, [], export_value, this.initState(export_value), fdef, scope) + val = this.buildNewObject(fdef, export_value, this.initState(export_value), fdef, scope) } break case load_mod_enum.CALL: - val = this.executeCall(fdef, export_value, [app], this.initState(export_value), scope) + val = this.executeCall(fdef, export_value, this.initState(export_value), scope, { callArgs: this.buildCallArgs(fdef, [app], export_value) }) break default: val = export_value @@ -327,10 +340,9 @@ class EggAnalyzer extends (JsAnalyzer as any) { } else { scope.value[prop] = scope.value[prop] || - ObjectValue({ - readonly: false, + new ObjectValue(scope.qid, { + runtime: { readonly: false }, sid: prop, - qid: `${scope.sid}.${prop}`, parent: scope, }) scope = scope.value[prop] @@ -347,9 +359,8 @@ class EggAnalyzer extends (JsAnalyzer as any) { /** * * @param dir - * @param isReScan */ - scanModules(dir: any, isReScan: boolean = false) { + scanModules(dir: any) { if (!eggSanityCheck(dir)) { handleException(null, `egg sanity check failed, dir:${dir}`, `egg sanity check failed, dir:${dir}`) return false @@ -365,7 +376,7 @@ class EggAnalyzer extends (JsAnalyzer as any) { if (configContents && configContents.length > 0) { for (const conf of configContents) { const sourceFile = conf.file - const exports = this.processModuleSrc(conf.content, sourceFile, isReScan) + const exports = this.processModuleSrc(conf.content, sourceFile) // if (!exports || exports.id !== 'module.exports') { if (!exports) { handleException(null, '', `process config module failed, config:${sourceFile}`) @@ -380,7 +391,7 @@ class EggAnalyzer extends (JsAnalyzer as any) { continue } if (config_val.vtype === 'fclos') { - config_val = this.executeCall({}, config_val, [], this.initState(config_val)) + config_val = this.executeCall({}, config_val, this.initState(config_val), undefined) } Initializer.assignConfig((this as any).topScopeTem || this.topScope, config_val) @@ -396,7 +407,7 @@ class EggAnalyzer extends (JsAnalyzer as any) { '**/*.(js|ts|mjs|cjs)', '!**/*.d.ts', '!**/*.d.js', - '!**/*.test.(js|ts|mjs|cjs|jsx)', + '!**/*.test.(js|ts|mjs|cjs|jsx|tsx)', '!**/node_modules', '!web', '!**/public/**', @@ -417,7 +428,7 @@ class EggAnalyzer extends (JsAnalyzer as any) { process.exit(1) } for (const mod of modules) { - this.processModuleSrc(mod.content, mod.file, isReScan) + this.processModuleSrc(mod.content, mod.file) } } @@ -468,14 +479,16 @@ class EggAnalyzer extends (JsAnalyzer as any) { processModuleDirect(ast: any, filename: any, modClos: any) { const res = super.processModuleDirect(ast, filename, modClos) // merge default into parent + const defaultVal = res?.members?.get('default') if ( - res?.field?.default && - typeof (res as any).field?.default !== undefined && - res.field?.default?.vtype !== 'fclos' + defaultVal && + typeof defaultVal !== 'undefined' && + defaultVal?.vtype !== 'fclos' ) { - if (res?.field?.default?.field) { - for (const key in res.field?.default?.field) { - res.field[key] = res.field?.default?.field[key] + if (defaultVal?.members) { + for (const key of defaultVal.members.keys()) { + const val = defaultVal.members.get(key) + if (val) res.members.set(key, val) } } } diff --git a/src/engine/analyzer/javascript/egg/egg-initializer.ts b/src/engine/analyzer/javascript/egg/egg-initializer.ts index a21de170..3911acd2 100644 --- a/src/engine/analyzer/javascript/egg/egg-initializer.ts +++ b/src/engine/analyzer/javascript/egg/egg-initializer.ts @@ -18,39 +18,28 @@ class EggInitializer extends JsInitializer { * @param moduleManager */ static initEgg(moduleManager: any) { - const egg = Scoped({ + const egg = new Scoped(moduleManager.qid, { parent: moduleManager, sid: 'Egg', }) moduleManager.setFieldValue('Egg', egg) // Application - egg.setFieldValue( - 'Application', - Scoped({ - vtype: 'class', - parent: egg, - sid: 'Egg.Application', - fdef: { - type: 'ClassDefinition', - body: [], - }, - }) - ) + const appClass = new Scoped(egg.qid, { + vtype: 'class', + parent: egg, + sid: 'Application', + }) + appClass.ast.fdef = { type: 'ClassDefinition', body: [] } + egg.setFieldValue('Application', appClass) - // Context - egg.setFieldValue( - 'Context', - Scoped({ - vtype: 'class', - parent: egg, - sid: 'Egg.Context', - fdef: { - type: 'ClassDefinition', - body: [], - }, - }) - ) + const ctxClass = new Scoped(egg.qid, { + vtype: 'class', + parent: egg, + sid: 'Context', + }) + ctxClass.ast.fdef = { type: 'ClassDefinition', body: [] } + egg.setFieldValue('Context', ctxClass) } /** @@ -60,16 +49,16 @@ class EggInitializer extends JsInitializer { static initGlobalScope(global: any) { global.setFieldValue( 'app', - Scoped({ - readonly: false, + new Scoped(global.qid, { + runtime: { readonly: false }, sid: 'egg_application', parent: global, }) ) global.setFieldValue( 'ctx', - Scoped({ - readonly: false, + new Scoped(global.qid, { + runtime: { readonly: false }, sid: 'ctx_template', parent: global, }) @@ -93,10 +82,15 @@ class EggInitializer extends JsInitializer { } const config = (topScope.value.config = topScope.value.config || - ObjectValue({ + new ObjectValue(topScope.qid, { sid: 'config', })) - Object.assign(config.value, configVal.vtype ? configVal.value : configVal) + const configSource = configVal.vtype ? configVal.value : configVal + if (configSource && typeof configSource === 'object') { + for (const [key, value] of Object.entries(configSource)) { + config.members.set(key, value as any) + } + } app.value.config = config } @@ -118,7 +112,7 @@ class EggInitializer extends JsInitializer { static resetInitVariables(scope: any) { for (const field of Object.keys(scope.value)) { const v = scope.value[field] - if (v.trace) delete v.trace + if (v.taint) v.taint.clearTrace() } } } diff --git a/src/engine/analyzer/javascript/egg/entrypoint-collector/egg-http.ts b/src/engine/analyzer/javascript/egg/entrypoint-collector/egg-http.ts index 45a3f843..28dec547 100644 --- a/src/engine/analyzer/javascript/egg/entrypoint-collector/egg-http.ts +++ b/src/engine/analyzer/javascript/egg/entrypoint-collector/egg-http.ts @@ -56,12 +56,13 @@ const defaultEggTaintSource = [ /** * * @param fileManager + * @param analyzer */ -function getEggHttpEntryPointsAndSources(fileManager: FileManager) { +function getEggHttpEntryPointsAndSources(fileManager: FileManager, analyzer: any) { const entryPoints: any[] = [] const uastUrlInfoList: UastUrlInfo[] = [] const TaintSource: any[] = [] - const routerFiles = calcRouterFileList(fileManager) + const routerFiles = calcRouterFileList(fileManager, analyzer) if (routerFiles.length === 0) { return { entryPoints, TaintSource } } @@ -70,7 +71,7 @@ function getEggHttpEntryPointsAndSources(fileManager: FileManager) { continue } EggRouterVisitor.routerList = [] - astUtil.visit(fileManager[routerFile].ast, EggRouterVisitor) + astUtil.visit(analyzer.symbolTable.get(fileManager[routerFile]).ast?.node, EggRouterVisitor) uastUrlInfoList.push(...EggRouterVisitor.routerList) } if (uastUrlInfoList.length <= 0) { @@ -86,7 +87,7 @@ function getEggHttpEntryPointsAndSources(fileManager: FileManager) { uastUrlInfo.relativePath = filePath.indexOf('/app/') !== -1 ? filePath.slice(filePath.indexOf('/app/')) : filePath EggMethodVisitor.uastUrlInfo = uastUrlInfo - astUtil.visit(fileManager[filePath].ast, EggMethodVisitor) + astUtil.visit(analyzer.symbolTable.get(fileManager[filePath]).ast?.node, EggMethodVisitor) } } } @@ -129,12 +130,13 @@ function getEggHttpEntryPointsAndSources(fileManager: FileManager) { /** * * @param fileManager + * @param analyzer */ -function calcRouterFileList(fileManager: FileManager): string[] { +function calcRouterFileList(fileManager: FileManager, analyzer: any): string[] { const routerFileList: string[] = [] for (const file of Object.getOwnPropertyNames(fileManager)) { - const codeContent = astUtil.prettyPrintAST(fileManager[file].ast) + const codeContent = astUtil.prettyPrintAST(analyzer.symbolTable.get(fileManager[file]).ast?.node) for (const method of httpMethodList) { if (codeContent.includes(`.${method}(`)) { routerFileList.push(file) diff --git a/src/engine/analyzer/python/common/entrypoint-collector/python-entrypoint.ts b/src/engine/analyzer/python/common/entrypoint-collector/python-entrypoint.ts index 56d4383c..188378b0 100644 --- a/src/engine/analyzer/python/common/entrypoint-collector/python-entrypoint.ts +++ b/src/engine/analyzer/python/common/entrypoint-collector/python-entrypoint.ts @@ -6,6 +6,8 @@ const { } = require('../../inference/entrypoint-collector/inference-default-entrypoint') const { findMcpEntryPointAndSource } = require('../../mcp/entrypoint-collector/mcp-default-entrypoint') const BasicRuleHandler = require('../../../../../checker/common/rules-basic-handler') +const { loadPythonDefaultRule } = require('../../../../../checker/taint/python/python-taint-abstract-checker') +const AstUtil = require('../../../../../util/ast-util') type FileManager = Record @@ -18,15 +20,16 @@ interface FindEntryPointResult { * * @param dir * @param fileManager + * @param analyzer */ -function findPythonFcEntryPointAndSource(dir: string, fileManager: FileManager): FindEntryPointResult { +function findPythonFcEntryPointAndSource(dir: string, fileManager: FileManager, analyzer: any): FindEntryPointResult { const pyFcEntryPointArray: any[] = [] const pyFcEntryPointSourceArray: any[] = [] const filenameAstObj: Record = {} for (const filename in fileManager) { - const modClos = fileManager[filename] - if (modClos.hasOwnProperty('ast')) { - filenameAstObj[filename] = modClos.ast + const modClos = analyzer.symbolTable.get(fileManager[filename]) + if (modClos.ast?.node?._meta?.nodehash !== undefined) { + filenameAstObj[filename] = modClos.ast?.node } } @@ -98,6 +101,14 @@ function getSourceNameList(): string[] { } } } + const defaultRule = loadPythonDefaultRule() + if (Array.isArray(defaultRule) && defaultRule.length > 0) { + for (const rule of defaultRule) { + if (Array.isArray(rule.sources?.TaintSource)) { + sourceList.push(...rule.sources.TaintSource) + } + } + } if (!sourceList) { return sourceNameList } @@ -110,8 +121,94 @@ function getSourceNameList(): string[] { return sourceNameList } +/** + * 构建 fclos 索引 + * 遍历 moduleManager 一次,建立 (filePath, functionName) -> fclos[] 的映射 + * 用于加速后续的 entrypoint 查找 + * + * @param moduleManager 模块管理器 + * @param dir 基础目录 + * @param extractRelativePath 路径提取函数 + * @returns fclos 索引 Map + */ +function buildFclosIndex( + moduleManager: any, + dir: string, + extractRelativePath: (path: string, dir: string) => string | null +): Map { + // 一次性遍历所有 fclos + const allFclos = AstUtil.satisfy( + moduleManager, + (n: any) => n.vtype === 'fclos', + (node: any, prop: any) => prop === '_field', + null, + true + ) + + // 构建索引:(filePath + '::' + functionName) -> fclos[] + const fclosIndex = new Map() + + if (Array.isArray(allFclos)) { + for (const fclos of allFclos) { + const sourcefile = extractRelativePath(fclos?.ast?.node?.loc?.sourcefile, dir) + const funcName = fclos?.ast?.node?.id?.name + + // 构建复合 key,需要区分 null, undefined, 空字符串和正常字符串 + let fileKey + if (sourcefile === null) { + fileKey = '@@NULL@@' + } else if (sourcefile === undefined) { + fileKey = '@@UNDEFINED@@' + } else { + fileKey = sourcefile // 保留空字符串和正常字符串 + } + + const funcKey = funcName === null ? '@@NULL@@' : (funcName === undefined ? '@@UNDEFINED@@' : funcName) + const compositeKey = `${fileKey}::${funcKey}` + + if (!fclosIndex.has(compositeKey)) { + fclosIndex.set(compositeKey, []) + } + fclosIndex.get(compositeKey)!.push(fclos) + } + } + + return fclosIndex +} + +/** + * 从索引中查找 fclos + * + * @param fclosIndex fclos 索引 + * @param filePath 文件路径 + * @param functionName 函数名 + * @returns fclos 数组或 undefined + */ +function lookupFclos( + fclosIndex: Map, + filePath: string | null | undefined, + functionName: string +): any[] | undefined { + // 与 buildFclosIndex 保持完全一致的 key 构建逻辑 + let fileKey + if (filePath === null) { + fileKey = '@@NULL@@' + } else if (filePath === undefined) { + fileKey = '@@UNDEFINED@@' + } else { + fileKey = filePath // 保留空字符串和正常字符串 + } + + const funcKey = functionName === null ? '@@NULL@@' : (functionName === undefined ? '@@UNDEFINED@@' : functionName) + const compositeKey = `${fileKey}::${funcKey}` + + return fclosIndex.get(compositeKey) +} + export = { findPythonFcEntryPointAndSource, findPythonFileEntryPoint, getSourceNameList, + buildFclosIndex, + lookupFclos, } diff --git a/src/engine/analyzer/python/common/python-analyzer.ts b/src/engine/analyzer/python/common/python-analyzer.ts index e7613bad..4fefb6d8 100644 --- a/src/engine/analyzer/python/common/python-analyzer.ts +++ b/src/engine/analyzer/python/common/python-analyzer.ts @@ -1,37 +1,70 @@ -const SymAddress = require('../../common/sym-address') +import type { Instruction } from '@ant-yasa/uast-spec' +import SymAddress from '../../common/sym-address' +import { BinaryExprValue } from '../../common/value/binary-expr' +import type { + Scope, + State, + Value, + SymbolValue as SymbolValueType, + VoidValue as VoidValueType, +} from '../../../../types/analyzer' +import type { CallArgs, CallArg, CallArgKind, CallInfo } from '../../common/call-args' +import { INTERNAL_CALL } from '../../common/call-args' +import type { + ScopedStatement, + CallExpression, + FunctionDefinition, + BinaryExpression, + Identifier, + MemberAccess, + NewExpression, + ReturnStatement, + VariableDeclaration, + AssignmentExpression, +} from '../../../../types/uast' -const { Analyzer } = require('../../common') +const Uuid = require('node-uuid') +const { floor } = require('lodash') +const globby = require('fast-glob') +const _ = require('lodash') +const path = require('path') +const UastSpec = require('@ant-yasa/uast-spec') +const { lodashCloneWithTag } = require('../../../../util/clone-util') +const Analyzer: typeof import('../../common/analyzer').Analyzer = require('../../common/analyzer') +const { getLegacyArgValues } = require('../../common/call-args') const CheckerManager = require('../../common/checker-manager') const BasicRuleHandler = require('../../../../checker/common/rules-basic-handler') -const PythonParser = require('../../../parser/python/python-ast-builder') +const Parser = require('../../../parser/parser') const { - ValueUtil: { ObjectValue, Scoped, PrimitiveValue, UndefinedValue, UnionValue, SymbolValue, PackageValue }, + ValueUtil: { Scoped, PrimitiveValue, UndefinedValue, UnionValue, SymbolValue, VoidValue }, } = require('../../../util/value-util') -const logger = require('../../../../util/logger')(__filename) +const logger: import('../../../../util/logger').Logger = require('../../../../util/logger')(__filename) const Config = require('../../../../config') -const { ErrorCode, Errors } = require('../../../../util/error-code') +const { ErrorCode } = require('../../../../util/error-code') const { assembleFullPath } = require('../../../../util/file-util') -const path = require('path') const SourceLine = require('../../common/source-line') -const Uuid = require('node-uuid') -const Scope = require('../../common/scope') +const ScopeClass = require('../../common/scope') const { unionAllValues } = require('../../common/memStateBVT') const AstUtil = require('../../../../util/ast-util') -const { floor } = require('lodash') const Stat = require('../../../../util/statistics') const constValue = require('../../../../util/constant') const entryPointConfig = require('../../common/current-entrypoint') const FileUtil = require('../../../../util/file-util') -const globby = require('fast-glob') -const _ = require('lodash') const { getSourceNameList } = require('./entrypoint-collector/python-entrypoint') const { handleException } = require('../../common/exception-handler') -const { resolveImportPath } = require('./python-import-resolver') +const { + resolveImportPath, + resolveRelativeImport, + getAllRelativeImportCandidates, + getAllAbsoluteImportCandidates, + findProjectRoot, + buildSearchPaths, +} = require('./python-import-resolver') /** * */ -class PythonAnalyzer extends (Analyzer as any) { +class PythonAnalyzer extends Analyzer { /** * * @param options @@ -45,12 +78,17 @@ class PythonAnalyzer extends (Analyzer as any) { BasicRuleHandler ) super(checkerManager, options) - + this.enableLibArgToThis = true this.fileList = [] - this.astManager = {} - // 搜索路径列表(类似 Python 的 sys.path) + this.pyAstParseManager = {} // 用于解析绝对导入,按优先级排序 this.searchPaths = [] + // import 结果缓存,防止同一 import 被不同文件反复触发组合爆炸 + this._importCache = new Map() + // tryLoadModule 内部缓存,按 (actualPath, fieldKey) 缓存加载结果 + this._tryLoadModuleCache = new Map() + // 规范化文件路径集合,替代 fileList.some() 的 O(n) 线性扫描 + this._normalizedFileSet = new Set() } /** @@ -59,19 +97,11 @@ class PythonAnalyzer extends (Analyzer as any) { * @param dir - 项目目录 */ async preProcess(dir: any) { - try { - ;(this as any).thisIterationTime = 0 - ;(this as any).prevIterationTime = new Date().getTime() + ;(this as any).thisIterationTime = 0 + ;(this as any).prevIterationTime = new Date().getTime() - this.scanModules(dir) - this.astManager = {} - } catch (e) { - handleException( - e, - `Error in PythonAnalyzer:preProcess \n${this.traceNodeInfo((this as any).lastProcessedNode)}`, - `Error in PythonAnalyzer:preProcess \n${this.traceNodeInfo((this as any).lastProcessedNode)}` - ) - } + await this.scanModules(dir) + this.pyAstParseManager = {} } /** @@ -83,14 +113,15 @@ class PythonAnalyzer extends (Analyzer as any) { ;(this as any).thisIterationTime = 0 ;(this as any).prevIterationTime = new Date().getTime() this.fileList = [fileName] + this._normalizedFileSet = new Set([path.normalize(fileName)]) const { options } = this - const ast = PythonParser.parseSingleFile(fileName, options) - this.astManager[fileName] = ast - this.addASTInfo(ast, source, fileName, false as any) + this.sourceCodeCache.set(fileName, source.split(/\n/)) + const ast = Parser.parseSingleFile(fileName, options) + this.pyAstParseManager[fileName] = ast + this.addASTInfo(ast, source, fileName) if (ast) { - this.processModule(ast, fileName, false as any) + this.processModule(ast, fileName) } - SourceLine.storeCode(fileName, source) } /** @@ -106,83 +137,35 @@ class PythonAnalyzer extends (Analyzer as any) { } const hasAnalysised: any[] = [] for (const entryPoint of entryPoints) { + this.symbolTable.clear() if (entryPoint.type === constValue.ENGIN_START_FUNCALL) { if ( hasAnalysised.includes( - `${entryPoint.filePath}.${entryPoint.functionName}/${entryPoint?.entryPointSymVal?._qid}#${entryPoint.entryPointSymVal.ast.parameters}.${entryPoint.attribute}` + `${entryPoint.filePath}.${entryPoint.functionName}/${entryPoint?.entryPointSymVal?.qid}#${entryPoint.entryPointSymVal.ast.node.parameters}.${entryPoint.attribute}` ) ) { continue } hasAnalysised.push( - `${entryPoint.filePath}.${entryPoint.functionName}/${entryPoint?.entryPointSymVal?._qid}#${entryPoint.entryPointSymVal.ast.parameters}.${entryPoint.attribute}` + `${entryPoint.filePath}.${entryPoint.functionName}/${entryPoint?.entryPointSymVal?.qid}#${entryPoint.entryPointSymVal.ast.node.parameters}.${entryPoint.attribute}` ) entryPointConfig.setCurrentEntryPoint(entryPoint) - logger.info( - 'EntryPoint [%s.%s] is executing', - entryPoint.filePath?.substring(0, entryPoint.filePath?.lastIndexOf('.')), - entryPoint.functionName || - `` - ) - - const fileFullPath = assembleFullPath(entryPoint.filePath, Config.maindir) - const sourceNameList = getSourceNameList() - this.refreshCtx(this.moduleManager.field[fileFullPath]?.field, sourceNameList) - this.refreshCtx(this.fileManager[fileFullPath]?.field, sourceNameList) - this.refreshCtx(this.packageManager.field[fileFullPath], sourceNameList) - - this.checkerManager.checkAtSymbolInterpretOfEntryPointBefore(this, null, null, null, null) - const argValues: any[] = [] - try { - for (const key in entryPoint.entryPointSymVal?.ast?.parameters) { - argValues.push( - this.processInstruction( - entryPoint.entryPointSymVal, - entryPoint.entryPointSymVal?.ast?.parameters[key]?.id, - state - ) - ) - } - } catch (e) { - handleException( - e, - 'Error occurred in PythonAnalyzer.symbolInterpret: process argValue err', - 'Error occurred in PythonAnalyzer.symbolInterpret: process argValue err' - ) - } - - if ( - entryPoint?.entryPointSymVal?.parent?.vtype === 'class' && - entryPoint?.entryPointSymVal?.parent?.field._CTOR_ - ) { - this.executeCall( - entryPoint.entryPointSymVal?.parent?.field?._CTOR_?.ast, - entryPoint.entryPointSymVal?.parent?.field?._CTOR_, - [], - state, - entryPoint.entryPointSymVal?.parent?.field?._CTOR_?.ast?.parent - ) + this.executeCallEntryPoint(entryPoint, entryPoint.entryPointSymVal?.ast?.node, state) + // 对重载的符号值也需要进行模拟执行 + const overloadedList = entryPoint.entryPointSymVal?.overloaded + if (!overloadedList || overloadedList.length <= 1) { + continue } - try { - this.executeCall( - entryPoint.entryPointSymVal?.ast, - entryPoint.entryPointSymVal, - argValues, - state, - entryPoint.entryPointSymVal?.parent - ) - } catch (e) { - handleException( - e, - `[${entryPoint.entryPointSymVal?.ast?.id?.name} symbolInterpret failed. Exception message saved in error log file`, - `[${entryPoint.entryPointSymVal?.ast?.id?.name} symbolInterpret failed. Exception message saved in error log file` - ) + for (const overloadFuncDef of overloadedList.filter(() => true)) { + const tmpVal = _.clone(entryPoint) + tmpVal.entryPointSymVal = lodashCloneWithTag(entryPoint.entryPointSymVal) + const clonedDef = _.clone(overloadFuncDef) + tmpVal.entryPointSymVal.ast.fdef = clonedDef + tmpVal.entryPointSymVal.ast = clonedDef + this.executeCallEntryPoint(tmpVal, overloadFuncDef, state) } - this.checkerManager.checkAtSymbolInterpretOfEntryPointAfter(this, null, null, null, null) } else if (entryPoint.type === constValue.ENGIN_START_FILE_BEGIN) { if (hasAnalysised.includes(`fileBegin:${entryPoint.filePath}.${entryPoint.attribute}`)) { continue @@ -193,22 +176,22 @@ class PythonAnalyzer extends (Analyzer as any) { const fileFullPath = assembleFullPath(entryPoint.filePath, Config.maindir) const sourceNameList = getSourceNameList() - this.refreshCtx(this.moduleManager.field[fileFullPath]?.field, sourceNameList) - this.refreshCtx(this.fileManager[fileFullPath]?.field, sourceNameList) - this.refreshCtx(this.packageManager.field[fileFullPath], sourceNameList) + this.refreshCtx(this.topScope.context.modules.members.get(fileFullPath)?.value, sourceNameList) + this.refreshCtx(this.symbolTable.get(this.topScope.context.files[fileFullPath])?.value, sourceNameList) + this.refreshCtx(this.topScope.context.packages.members.get(fileFullPath), sourceNameList) const { filePath } = entryPoint - const scope = this.moduleManager.field[filePath] + const scope = this.topScope.context.modules.members.get(filePath) if (scope) { try { this.checkerManager.checkAtSymbolInterpretOfEntryPointBefore(this, null, null, null, null) - this.processCompileUnit(scope, entryPoint.entryPointSymVal?.ast, state) + this.processCompileUnit(scope, entryPoint.entryPointSymVal?.ast?.node, state) this.checkerManager.checkAtSymbolInterpretOfEntryPointAfter(this, null, null, null, null) } catch (e) { handleException( e, - `[${entryPoint.entryPointSymVal?.ast?.loc?.sourcefile} symbolInterpret failed. Exception message saved in error log file`, - `[${entryPoint.entryPointSymVal?.ast?.loc?.sourcefile} symbolInterpret failed. Exception message saved in error log file` + `[${entryPoint.entryPointSymVal?.ast?.node?.loc?.sourcefile} symbolInterpret failed. Exception message saved in error log file`, + `[${entryPoint.entryPointSymVal?.ast?.node?.loc?.sourcefile} symbolInterpret failed. Exception message saved in error log file` ) } } @@ -217,33 +200,105 @@ class PythonAnalyzer extends (Analyzer as any) { return true } + /** + * + * @param entryPoint + * @param ast + * @param state + */ + executeCallEntryPoint(entryPoint: any, ast: any, state: any) { + logger.info( + 'EntryPoint [%s.%s] is executing', + entryPoint.filePath?.substring(0, entryPoint.filePath?.lastIndexOf('.')), + entryPoint.functionName || + `` + ) + const fileFullPath = assembleFullPath(entryPoint.filePath, Config.maindir) + const sourceNameList = getSourceNameList() + this.refreshCtx(this.topScope.context.modules.members.get(fileFullPath)?.value, sourceNameList) + this.refreshCtx(this.symbolTable.get(this.topScope.context.files[fileFullPath])?.value, sourceNameList) + this.refreshCtx(this.topScope.context.packages.members.get(fileFullPath), sourceNameList) + + this.checkerManager.checkAtSymbolInterpretOfEntryPointBefore(this, null, null, null, null) + + const argValues: any[] = [] + try { + const prevFindIdInCurScope = state?.findIdInCurScope + if (state) state.findIdInCurScope = true + try { + for (const key in ast?.parameters) { + argValues.push(this.processInstruction(entryPoint.entryPointSymVal, ast?.parameters[key]?.id, state)) + } + } finally { + if (state) { + if (prevFindIdInCurScope === undefined) delete state.findIdInCurScope + else state.findIdInCurScope = prevFindIdInCurScope + } + } + } catch (e) { + handleException( + e, + 'Error occurred in PythonAnalyzer.symbolInterpret: process argValue err', + 'Error occurred in PythonAnalyzer.symbolInterpret: process argValue err' + ) + } + if ( + entryPoint?.entryPointSymVal?.parent?.vtype === 'class' && + entryPoint?.entryPointSymVal?.parent?.members?.get('_CTOR_') + ) { + this.executeCall( + entryPoint.entryPointSymVal?.parent?.members?.get('_CTOR_')?.ast?.node, + entryPoint.entryPointSymVal?.parent?.members?.get('_CTOR_'), + state, + entryPoint.entryPointSymVal?.parent?.members?.get('_CTOR_')?.ast?.node?.parent, + INTERNAL_CALL + ) + } + try { + this.executeCall(ast, entryPoint.entryPointSymVal, state, entryPoint.entryPointSymVal?.parent, { + callArgs: this.buildCallArgs(ast, argValues, entryPoint.entryPointSymVal), + }) + } catch (e) { + handleException( + e, + `[${entryPoint.entryPointSymVal?.ast?.node?.id?.name} symbolInterpret failed. Exception message saved in error log file`, + `[${entryPoint.entryPointSymVal?.ast?.node?.id?.name} symbolInterpret failed. Exception message saved in error log file` + ) + } + this.checkerManager.checkAtSymbolInterpretOfEntryPointAfter(this, null, null, null, null) + } + /** * * @param scope * @param node * @param state */ - processBinaryExpression(scope: any, node: any, state: any) { - const new_node: any = _.clone(node) - new_node.ast = node - const new_left = (new_node.left = this.processInstruction(scope, node.left, state)) - const new_right = (new_node.right = this.processInstruction(scope, node.right, state)) + override processBinaryExpression(scope: Scope, node: BinaryExpression, state: State): BinaryExprValue { + const new_left = this.processInstruction(scope, node.left, state) + const new_right = this.processInstruction(scope, node.right, state) if (node.operator === 'push') { this.processOperator(new_left.parent ? new_left.parent : new_left, node.left, new_right, node.operator, state) } + + const has_tag = (new_left && new_left.taint?.isTaintedRec) || (new_right && new_right.taint?.isTaintedRec) + + // checkerManager 需要 newNode 兼容对象 + const newNode: any = { ...node, ast: node, left: new_left, right: new_right, isTainted: has_tag || null } if (node.operator === 'instanceof') { - new_node._meta.type = node.right + newNode._meta = { ...node._meta, type: node.right } } - const has_tag = (new_left && new_left.hasTagRec) || (new_right && new_right.hasTagRec) + if (this.checkerManager && this.checkerManager.checkAtBinaryOperation) + this.checkerManager.checkAtBinaryOperation(this, scope, node, state, { newNode }) + + const result = new BinaryExprValue(scope.qid, node.operator, new_left, new_right, node, node.loc) if (has_tag) { - new_node.hasTagRec = has_tag + result.taint?.mergeFrom([new_left, new_right]) } - - if (this.checkerManager && (this.checkerManager as any).checkAtBinaryOperation) - this.checkerManager.checkAtBinaryOperation(this, scope, node, state, { newNode: new_node }) - - return SymbolValue(new_node) + return result } /** @@ -252,71 +307,33 @@ class PythonAnalyzer extends (Analyzer as any) { * @param node * @param state */ - processCallExpression(scope: any, node: any, state: any) { - if (this.checkerManager && (this.checkerManager as any).checkAtFuncCallSyntax) + override processCallExpression(scope: Scope, node: CallExpression, state: State): any { + if (this.checkerManager && this.checkerManager.checkAtFuncCallSyntax) this.checkerManager.checkAtFuncCallSyntax(this, scope, node, state, { pcond: state.pcond, einfo: state.einfo, }) const fclos = this.processInstruction(scope, node.callee, state) - if (node?.callee?.type === 'MemberAccess' && fclos.fdef && node.callee?.object?.type !== 'SuperExpression') { - fclos._this = this.processInstruction(scope, node.callee.object, state) - } - if (!fclos) return UndefinedValue() + if (!fclos) return new UndefinedValue() const argvalues: any[] = [] - /** - * - * @param paramAST - * @param positionalArgs - * @param keywordArgs - * @param len - */ - function collectArgsFromArray( - paramAST: any[], - positionalArgs: any[], - keywordArgs: Record, - len: number - ) { - const paramNames = paramAST.map((n: any) => n.id.name) - const collectedArgs = new Array(len).fill(undefined) - positionalArgs.forEach((arg, index) => { - if (index < collectedArgs.length) collectedArgs[index] = arg - }) - for (const [key, value] of Object.entries(keywordArgs)) { - const paramIndex = paramNames.indexOf(key) - if (paramIndex !== -1) collectedArgs[paramIndex] = value - } - return collectedArgs - } - - const positionalArgs: any[] = [] - const keywordArgs: Record = {} - for (const arg of node.arguments) { - if (arg.type === 'VariableDeclaration') { - keywordArgs[arg.id.name] = arg - } else { - positionalArgs.push(arg) - } - } - let collectedArgs: any[] - if (fclos.fdef && fclos.fdef.type === 'FunctionDefinition') { - collectedArgs = collectArgsFromArray(fclos.ast.parameters, positionalArgs, keywordArgs, node.arguments.length) - } else { - collectedArgs = node.arguments - } + // 参数按原始顺序处理,由 buildPythonCallArgs 标记 kind,bindCallArgs 负责绑定 + const collectedArgs = node.arguments for (const arg of collectedArgs) { const argv = this.processInstruction(scope, arg, state) - if ((logger as any).isTraceEnabled()) logger.trace(`arg: ${this.formatScope(argv)}`) + if (logger.isTraceEnabled()) logger.trace(`arg: ${this.formatScope(argv)}`) if (Array.isArray(argv)) argvalues.push(...argv) else argvalues.push(argv) } + // 构建结构化 callInfo,携带 keyword/spread/kwspread 信息 + const callInfo: CallInfo = { callArgs: this.buildPythonCallArgs(collectedArgs, argvalues, fclos, node) } + if (argvalues && this.checkerManager) { this.checkerManager.checkAtFunctionCallBefore(this, scope, node, state, { - argvalues, + callInfo, fclos, pcond: state.pcond, entry_fclos: this.entry_fclos, @@ -328,24 +345,33 @@ class PythonAnalyzer extends (Analyzer as any) { } if (fclos.vtype === 'class') { - return this.propagateNewObject(scope, node, state, fclos, argvalues) + const signatureAst = fclos?.members?.get('_CTOR_')?.fdef || fclos?.fdef || fclos?.ast + if (signatureAst?.type === 'FunctionDefinition') { + callInfo.boundCall = this.bindCallArgs(node, fclos, signatureAst, callInfo) + } + return this.propagateNewObject(scope, node, state, fclos, argvalues, callInfo) } // todo 待迁移到库函数建模中 - if (node.callee.type === 'MemberAccess' && node.callee.property.name === 'append' && fclos?.object?.parent) { - this.saveVarInCurrentScope(fclos.object.parent, fclos.object, argvalues[0], state) - return + if ( + node.callee.type === 'MemberAccess' && + node.callee.property.type === 'Identifier' && + node.callee.property.name === 'append' && + (fclos as any)?.object?.parent + ) { + this.saveVarInCurrentScope((fclos as any).object.parent, fclos.object, argvalues[0], state) + return undefined } - const res = this.executeCall(node, fclos, argvalues, state, scope) + const res = this.executeCall(node, fclos, state, scope, callInfo) if (fclos.vtype !== 'fclos' && Config.invokeCallbackOnUnknownFunction) { this.executeFunctionInArguments(scope, fclos, node, argvalues, state) } - if (res && (this.checkerManager as any)?.checkAtFunctionCallAfter) { + if (res && this.checkerManager?.checkAtFunctionCallAfter) { this.checkerManager.checkAtFunctionCallAfter(this, scope, node, state, { + callInfo, fclos, ret: res, - argvalues, pcond: state.pcond, einfo: state.einfo, callstack: state.callstack, @@ -362,15 +388,23 @@ class PythonAnalyzer extends (Analyzer as any) { * @param state * @param fclos * @param argvalues + * @param callInfo */ - propagateNewObject(scope: any, node: any, state: any, fclos: any, argvalues: any) { - if (fclos.field && Object.prototype.hasOwnProperty.call(fclos.field, '_CTOR_')) { - const res = this.buildNewObject(fclos.cdef, argvalues, fclos, state, node, scope) - if (res && (this.checkerManager as any)?.checkAtFunctionCallAfter) { + propagateNewObject( + scope: Scope, + node: CallExpression, + state: State, + fclos: Value, + argvalues: Value[], + callInfo: CallInfo + ): Value { + if (fclos.members?.has('_CTOR_')) { + const res = this.buildNewObject(fclos.ast.cdef, fclos, state, node, scope, callInfo) + if (res && this.checkerManager?.checkAtFunctionCallAfter) { this.checkerManager.checkAtFunctionCallAfter(this, scope, node, state, { + callInfo, fclos, ret: res, - argvalues, pcond: state.pcond, einfo: state.einfo, callstack: state.callstack, @@ -378,12 +412,12 @@ class PythonAnalyzer extends (Analyzer as any) { } return res } - const res = this.processLibArgToRet(node, fclos, argvalues, scope, state) - if (res && (this.checkerManager as any)?.checkAtFunctionCallAfter) { + const res = this.processLibArgToRet(node, fclos, argvalues, scope, state, callInfo) + if (res && this.checkerManager?.checkAtFunctionCallAfter) { this.checkerManager.checkAtFunctionCallAfter(this, scope, node, state, { + callInfo, fclos, ret: res, - argvalues, pcond: state.pcond, einfo: state.einfo, callstack: state.callstack, @@ -393,15 +427,52 @@ class PythonAnalyzer extends (Analyzer as any) { } /** + * 构建 Python 结构化 CallArgs,识别 keyword / spread / kwspread 参数类型 * - * @param scope + * collectedArgs 经过 collectArgsFromArray 重排后与 argvalues 一一对应, + * 通过 AST 节点类型判定参数 kind: + * - VariableDeclaration → keyword(name=value 语法) + * - DereferenceExpression → spread(*args 语法) + * - SpreadElement → kwspread(**kwargs 语法) + * - 其他 → positional + * @param collectedArgs + * @param argvalues + * @param fclos * @param node - * @param state */ - processIdentifier(scope: any, node: any, state: any) { - const res = super.processIdentifier(scope, node, state) - this.checkerManager.checkAtIdentifier(this, scope, node, state, { res }) - return res + buildPythonCallArgs( + collectedArgs: Array, + argvalues: Value[], + fclos: Value, + node: CallExpression + ): CallArgs { + const args: CallArg[] = [] + const len = Math.min(argvalues.length, collectedArgs.length) + + for (let i = 0; i < len; i++) { + const astNode = collectedArgs[i] + let kind: CallArgKind = 'positional' + let name: string | undefined + + if (UastSpec.isVariableDeclaration(astNode)) { + kind = 'keyword' + name = (astNode as VariableDeclaration).id?.name + } else if (astNode?.type === 'DereferenceExpression') { + kind = 'spread' + } else if (astNode?.type === 'SpreadElement') { + kind = 'kwspread' + } + + args.push({ index: i, value: argvalues[i], node: astNode, name, kind }) + } + + // argvalues 因 Array.isArray(argv) 展开可能多于 collectedArgs,多出部分为 positional + for (let i = len; i < argvalues.length; i++) { + args.push({ index: i, value: argvalues[i], kind: 'positional' }) + } + + const receiver = this.getCallReceiver(fclos, node) + return { receiver, args } } /** @@ -411,13 +482,18 @@ class PythonAnalyzer extends (Analyzer as any) { * @param node * @param state */ - processImportDirect(scope: any, node: any, state: any) { - let { from, imported } = node - let sourcefile - while (imported) { - sourcefile = imported.loc.sourcefile + processImportDirect(scope: Scope, node: any, state: State): Value { + const { from, imported } = node + let sourcefile: string | undefined + // 向上遍历 AST 查找 sourcefile,用独立变量避免死循环 + let current = imported + const maxDepth = 50 + let depth = 0 + while (current && depth < maxDepth) { + sourcefile = current.loc?.sourcefile if (sourcefile) break - imported = from?.parent + current = current.parent + depth++ } if (!sourcefile) { handleException( @@ -425,13 +501,24 @@ class PythonAnalyzer extends (Analyzer as any) { 'Error occurred in PythonAnalyzer.processImportDirect: failed to sourcefile in ast', 'Error occurred in PythonAnalyzer.processImportDirect: failed to sourcefile in ast' ) - return UndefinedValue() + return new UndefinedValue() } + const sourceFileAbs = path.resolve(sourcefile.toString()) const projectRoot = Config.maindir?.replace(/\/$/, '') || path.dirname(sourceFileAbs) + // 入口级缓存:按 (sourcefile, from, imported) 生成 key,已处理则直接返回 + const importCacheKey = `${sourceFileAbs}|${from?.value || ''}|${imported?.name || imported?.value || ''}` + const cachedImportResult = this._importCache.get(importCacheKey) + if (cachedImportResult !== undefined) { + return cachedImportResult + } + let importPath: string | null = null let modulePath: string | null = null + const fromValue = from?.value + const importedName = imported?.name && imported.name !== '*' ? imported.name : null + const onlyDots = fromValue?.startsWith('.') ? /^\.+$/.test(fromValue) : false if (!from) { // 处理 "import module" 形式的导入 @@ -439,107 +526,195 @@ class PythonAnalyzer extends (Analyzer as any) { if (importName) { importPath = resolveImportPath(importName, sourceFileAbs, this.fileList, projectRoot) } - } else { - // 处理 "from module import ..." 形式的导入 - const fromValue = from.value - if (fromValue) { - if (fromValue.startsWith('.')) { - // 相对导入,需要区分两种情况: - // 1. "from .. import moduleName" - 导入整个模块,fromValue 只有点号(如 "..") - // 2. "from ..moduleName import fieldName" - 从模块中导入字段,fromValue 包含点号和模块名(如 "..moduleName") - const onlyDots = /^\.+$/.test(fromValue) - if (onlyDots) { - const moduleName = imported?.name && imported.name !== '*' ? imported.name : null - const { resolveRelativeImport } = require('./python-import-resolver') - importPath = resolveRelativeImport(fromValue, sourceFileAbs, this.fileList, moduleName || undefined) - // 不设置 modulePath,因为这是导入整个模块,应该返回整个模块对象 - } else { - importPath = resolveImportPath(fromValue, sourceFileAbs, this.fileList, projectRoot) - if (imported && imported.name && imported.name !== '*') { - modulePath = imported.name - } - } + } else if (fromValue) { + // 相对导入,需要区分两种情况: + // 1. "from .. import moduleName" - 导入整个模块,fromValue 只有点号(如 "..") + // 2. "from ..moduleName import fieldName" - 从模块中导入字段,fromValue 包含点号和模块名(如 "..moduleName") + if (fromValue.startsWith('.')) + if (onlyDots) { + importPath = resolveRelativeImport(fromValue, sourceFileAbs, this.fileList, importedName || undefined) + // 不设置 modulePath,因为这是导入整个模块,应该返回整个模块对象 } else { - // 绝对导入 importPath = resolveImportPath(fromValue, sourceFileAbs, this.fileList, projectRoot) - if (imported && imported.name && imported.name !== '*') { - modulePath = imported.name - } + modulePath = importedName } + else { + // 绝对导入 + importPath = resolveImportPath(fromValue, sourceFileAbs, this.fileList, projectRoot) + modulePath = importedName } } + // 缓存结果并返回的辅助函数 + const cacheAndReturn = (result: Value): Value => { + this._importCache.set(importCacheKey, result) + return result + } + // 如果 resolver 找到了路径,加载模块 if (importPath) { const normalizedPath = path.normalize(importPath) + let candidatePaths: string[] = [] - let targetPath = normalizedPath - if (!targetPath.endsWith('.py')) { - // 可能是包目录,检查是否有 __init__.py - const initFile = path.join(targetPath, '__init__.py') - if (this.fileList.some((f: string) => path.normalize(f) === path.normalize(initFile))) { - targetPath = initFile - } else { - // 尝试添加 .py 扩展名 - const pyFile = `${targetPath}.py` - if (this.fileList.some((f: string) => path.normalize(f) === path.normalize(pyFile))) { - targetPath = pyFile + const buildCandidatePaths = () => { + if (!fromValue) return [] + if (fromValue.startsWith('.')) { + if (onlyDots) { + const resolvedPath = resolveRelativeImport( + fromValue, + sourceFileAbs, + this.fileList, + importedName || undefined + ) + return resolvedPath ? [resolvedPath] : [] } + return getAllRelativeImportCandidates( + fromValue, + sourceFileAbs, + this.fileList, + undefined, + modulePath || undefined + ) } + const root = projectRoot || findProjectRoot(this.fileList, Config.maindir || process.cwd()) + const searchPaths = buildSearchPaths(sourceFileAbs, this.fileList, root) + return getAllAbsoluteImportCandidates(fromValue, searchPaths, this.fileList, modulePath || undefined) + } + + // 先收集全部候选路径,但保持 importPath 为首选 + candidatePaths = buildCandidatePaths() + if (candidatePaths.length > 5) { + logger.warn( + `Large candidatePaths (${candidatePaths.length}) for import from=${fromValue}, imported=${importedName}` + ) + } + if (!candidatePaths.length) { + candidatePaths = [importPath] + } else if (!candidatePaths.some((p) => path.normalize(p) === normalizedPath)) { + candidatePaths.unshift(importPath) + } else if (path.normalize(candidatePaths[0]) !== normalizedPath) { + candidatePaths = [importPath, ...candidatePaths.filter((p) => path.normalize(p) !== normalizedPath)] } - const cachedModule = this.moduleManager.field[targetPath] - if (cachedModule) { - if (modulePath) { - const field = cachedModule.field?.[modulePath] - if (field) return field + const tryLoadModule = ( + targetPath: string, + shouldExtractField: boolean = true + ): { module: any; field: any } | null => { + const isPackageDir = !targetPath.endsWith('.py') + let actualPath = targetPath + const fieldKey = shouldExtractField && modulePath ? modulePath : '' + + if (isPackageDir) { + const initFile = path.join(targetPath, '__init__.py') + const normalizedInitFile = path.normalize(initFile) + if (this._normalizedFileSet.has(normalizedInitFile)) { + actualPath = initFile + } + } + + // tryLoadModule 内部缓存,按 (actualPath, fieldKey) 缓存结果 + const tlmCacheKey = `${actualPath}|${fieldKey}` + if (this._tryLoadModuleCache.has(tlmCacheKey)) { + return this._tryLoadModuleCache.get(tlmCacheKey)! } - return cachedModule + + const getField = (value: any) => (fieldKey ? value.members?.get(fieldKey) : undefined) + + const processingKey = `processing_${actualPath}` + if ((this as any)[processingKey]) { + logger.warn(`Circular import detected for: ${actualPath}`) + return null + } + + try { + ;(this as any)[processingKey] = true + + const cachedModule = this.topScope.context.modules.members.get(actualPath) + if (cachedModule) { + const field = getField(cachedModule) + delete (this as any)[processingKey] + const result = { module: cachedModule, field: field || undefined } + this._tryLoadModuleCache.set(tlmCacheKey, result) + return result + } + + const ast = this.pyAstParseManager[actualPath] + if (ast) { + const module = this.processModule(ast, actualPath) + if (module) { + const field = getField(module) + delete (this as any)[processingKey] + const result = { module, field: field || undefined } + this._tryLoadModuleCache.set(tlmCacheKey, result) + return result + } + } + delete (this as any)[processingKey] + } catch (e) { + delete (this as any)[processingKey] + handleException( + e, + `Error: PythonAnalyzer.processImportDirect: failed to loading: ${actualPath}`, + `Error: PythonAnalyzer.processImportDirect: failed to loading: ${actualPath}` + ) + } + this._tryLoadModuleCache.set(tlmCacheKey, null) + return null } - // 加载并处理模块 - // 检查是否已经在处理中,防止循环导入导致的无限递归 - const processingKey = `processing_${targetPath}` - if ((this as any)[processingKey]) { - logger.warn(`Circular import detected for: ${targetPath}`) - return UndefinedValue() + const shouldExtractFieldForPath = (candidatePath: string) => !candidatePath.endsWith('.py') && modulePath !== null + + // 先尝试已找到的路径 + const firstResult = tryLoadModule(normalizedPath) + if (firstResult?.field) { + return cacheAndReturn(firstResult.field) } - try { - ;(this as any)[processingKey] = true - const ast = this.astManager[targetPath] - if (ast) { - const module = this.processModule(ast, targetPath, false as any) - if (module) { - if (modulePath) { - const field = module.field?.[modulePath] - if (field) { - delete (this as any)[processingKey] - return field + // 如果第一个路径找到了模块但没有所需字段,尝试其他候选路径 + if (modulePath && firstResult && !firstResult.field) { + // 第一个是importPath,前面已经尝试过,跳过 + if (candidatePaths && candidatePaths.length > 1) { + for (let i = 1; i < candidatePaths.length; i++) { + const candidatePath = candidatePaths[i] + const normalizedCandidatePath = path.normalize(candidatePath) + // 避免重复尝试第一个路径 + if (normalizedCandidatePath !== normalizedPath) { + // 判断候选路径是模块文件还是包目录: + // 1. 如果是模块文件(.py),应该返回整个模块对象,不应该尝试提取字段 + // 2. 如果是包目录,才需要尝试提取字段 + const isModuleFile = normalizedCandidatePath.endsWith('.py') + const shouldExtractField = shouldExtractFieldForPath(normalizedCandidatePath) + + const result = tryLoadModule(normalizedCandidatePath, shouldExtractField) + + if (result) { + if (result.field) { + return cacheAndReturn(result.field) + } + if (isModuleFile) { + return cacheAndReturn(result.module) + } } } - delete (this as any)[processingKey] - return module } } - delete (this as any)[processingKey] - } catch (e) { - delete (this as any)[processingKey] - handleException( - e, - `Error: PythonAnalyzer.processImportDirect: failed to loading: ${targetPath}`, - `Error: PythonAnalyzer.processImportDirect: failed to loading: ${targetPath}` - ) + } + + // 如果第一个路径找到了模块,返回它(即使没有所需字段) + if (firstResult) { + return cacheAndReturn(firstResult.module) } } - // 如果找不到,尝试作为三方库处理 + // 如果所有候选路径都尝试过了,但都没有找到,尝试作为三方库处理 const importName = from?.value || imported?.value || imported?.name if (importName) { - return this.loadPredefinedModule(scope, imported?.name || importName, from?.value || 'syslib_from') + return cacheAndReturn( + this.loadPredefinedModule(scope, imported?.name || importName, from?.value || 'syslib_from') + ) } - return UndefinedValue() + return cacheAndReturn(new UndefinedValue()) } /** @@ -548,7 +723,7 @@ class PythonAnalyzer extends (Analyzer as any) { * @param node * @param state */ - processMemberAccess(scope: any, node: any, state: any) { + override processMemberAccess(scope: Scope, node: MemberAccess, state: State): SymbolValueType { const defscope = this.processInstruction(scope, node.object, state) const prop = node.property let resolved_prop = prop @@ -562,6 +737,13 @@ class PythonAnalyzer extends (Analyzer as any) { } if (!resolved_prop) return defscope const res = this.getMemberValue(defscope, resolved_prop, state) + if (node.object.type !== 'SuperExpression' && (res.vtype !== 'union' || !Array.isArray(res.value))) { + res._this = defscope + } else if (node.object.type === 'SuperExpression' && this.thisFClos) { + // For super().method() calls, bind this/self to the current instance. + // In Python semantics, super() only affects method dispatch, not self binding. + res._this = this.thisFClos + } if (this.checkerManager && (this.checkerManager as any).checkAtMemberAccess) { this.checkerManager.checkAtMemberAccess(this, defscope, node, state, { res }) } @@ -572,32 +754,32 @@ class PythonAnalyzer extends (Analyzer as any) { * * @param ast * @param filename - * @param isReScan */ - processModule(ast: any, filename: any, isReScan: any) { + processModule(ast: any, filename: any) { if (!ast) { process.exitCode = ErrorCode.fail_to_parse const sourceFile = filename Stat.fileIssues[sourceFile] = 'Parsing Error' handleException( null, - `Error occurred in JsAnalyzer.processModule: ${sourceFile} parse error`, - `Error occurred in JsAnalyzer.processModule: ${sourceFile} parse error` + `Error occurred in PythonAnalyzer.processModule: ${sourceFile} parse error`, + `Error occurred in PythonAnalyzer.processModule: ${sourceFile} parse error` ) return } this.preloadFileToPackage(ast, filename) - let m = this.moduleManager.field[filename] - if (m && !isReScan) return m + let m = this.topScope.context.modules.members.get(filename) + if (m && typeof m === 'object') return m let relateFileName = 'file' if (ast.loc?.sourcefile) { - relateFileName = ast.loc?.sourcefile?.startsWith(Config.maindirPrefix) - ? ast.loc.sourcefile?.substring(Config.maindirPrefix.length).split('.')[0] - : ast.loc.sourcefile.split('.')[0] + const prefix = ast.loc.sourcefile.substring(Config.maindirPrefix.length) + const lastDotIndex = prefix.lastIndexOf('.') + relateFileName = lastDotIndex >= 0 ? prefix.substring(0, lastDotIndex) : prefix } - const modClos = Scoped({ sid: relateFileName, parent: this.topScope, decls: {}, fdef: ast, ast }) - this.moduleManager.field[filename] = modClos - this.fileManager[filename] = modClos + const modClos = new Scoped(this.topScope.qid, { sid: relateFileName, parent: this.topScope, decls: {}, ast }) + modClos.ast.fdef = ast + this.topScope.context.modules.members.set(filename, modClos) + this.fileManager[filename] = modClos.uuid m = this.processModuleDirect(ast, filename, modClos) ;(m as any).ast = ast return m @@ -633,10 +815,10 @@ class PythonAnalyzer extends (Analyzer as any) { * @param node * @param state */ - processNewObject(scope: any, node: any, state: any) { + override processNewObject(scope: Scope, node: NewExpression, state: State): any { const call = node let fclos = this.processInstruction(scope, node.callee, state) - if (!fclos) return + if (!fclos) return undefined if (fclos.vtype === 'union') { fclos = fclos.value[0] } @@ -652,11 +834,13 @@ class PythonAnalyzer extends (Analyzer as any) { if (same_args) argvalues = call.arguments } - const { fdef } = fclos - const obj = this.buildNewObject(fdef, argvalues, fclos, state, node, scope) - if ((logger as any).isTraceEnabled()) logger.trace(`new expression: ${this.formatScope(obj)}`) + const fdef = fclos.ast?.fdef + const obj = this.buildNewObject(fdef, fclos, state, node, scope, { + callArgs: this.buildCallArgs(node, argvalues, fclos), + }) + if (logger.isTraceEnabled()) logger.trace(`new expression: ${this.formatScope(obj)}`) - if (obj && (this.checkerManager as any)?.checkAtNewExprAfter) { + if (obj && this.checkerManager?.checkAtNewExprAfter) { this.checkerManager.checkAtNewExprAfter(this, scope, node, state, { argvalues, fclos, @@ -682,9 +866,9 @@ class PythonAnalyzer extends (Analyzer as any) { switch (operator) { case 'push': { this.saveVarInCurrentScope(scope, node, argvalues, state) - const has_tag = (scope && scope.hasTagRec) || (argvalues && argvalues.hasTagRec) + const has_tag = (scope && scope.taint?.isTaintedRec) || (argvalues && argvalues.taint?.isTaintedRec) if (has_tag) { - scope.hasTagRec = has_tag + scope.taint?.mergeFrom([scope, argvalues]) } } } @@ -696,7 +880,7 @@ class PythonAnalyzer extends (Analyzer as any) { * @param node * @param state */ - processReturnStatement(scope: any, node: any, state: any) { + override processReturnStatement(scope: Scope, node: ReturnStatement, state: State): VoidValueType { if (node.argument) { const return_value = this.processInstruction(scope, node.argument, state) if (!node.isYield) { @@ -705,7 +889,7 @@ class PythonAnalyzer extends (Analyzer as any) { } else if ((this as any).lastReturnValue.vtype === 'union') { ;(this as any).lastReturnValue.appendValue(return_value) } else { - const tmp = UnionValue() + const tmp = new UnionValue(undefined, undefined, `${scope.qid}.`, node) tmp.appendValue((this as any).lastReturnValue) tmp.appendValue(return_value) ;(this as any).lastReturnValue = tmp @@ -723,7 +907,7 @@ class PythonAnalyzer extends (Analyzer as any) { } return return_value } - return PrimitiveValue({ type: 'Literal', value: null, loc: node.loc }) + return new PrimitiveValue(scope.qid, 'undefined', null, null, 'Literal', node.loc) } /** @@ -732,7 +916,7 @@ class PythonAnalyzer extends (Analyzer as any) { * @param node * @param state */ - processScopedStatement(scope: any, node: any, state: any) { + override processScopedStatement(scope: Scope, node: ScopedStatement, state: State): any { if (node.parent?.type === 'TryStatement') { node.body .filter((n: any) => needCompileFirst(n.type)) @@ -748,22 +932,23 @@ class PythonAnalyzer extends (Analyzer as any) { } else { scopeName = `` } - let block_scope = scope + let blockScope = scope if (node.parent?.type === 'FunctionDefinition') { // 只对函数体内的块语句创建子作用域,python的其他块语句不创建子作用域 - block_scope = Scope.createSubScope(scopeName, scope, 'scope') + blockScope = ScopeClass.createSubScope(scopeName, scope, 'scope') } node.body .filter((n: any) => needCompileFirst(n.type)) - .forEach((s: any) => this.processInstruction(block_scope, s, state)) + .forEach((s: any) => this.processInstruction(blockScope, s, state)) node.body .filter((n: any) => !needCompileFirst(n.type)) - .forEach((s: any) => this.processInstruction(block_scope, s, state)) + .forEach((s: any) => this.processInstruction(blockScope, s, state)) } - if (this.checkerManager && (this.checkerManager as any).checkAtEndOfBlock) { + if (this.checkerManager && this.checkerManager.checkAtEndOfBlock) { this.checkerManager.checkAtEndOfBlock(this, scope, node, state, {}) } + return undefined } /** @@ -772,28 +957,33 @@ class PythonAnalyzer extends (Analyzer as any) { * @param node * @param state */ - processVariableDeclaration(scope: any, node: any, state: any) { + override processVariableDeclaration(scope: Scope, node: VariableDeclaration, state: State): SymbolValueType { const initialNode = node.init const { id } = node - if (!id || id?.name === '_') return UndefinedValue() + if (!id || (id.type === 'Identifier' && id.name === '_')) return new UndefinedValue() + const idName = id.type === 'Identifier' ? id.name : (id as any).name let initVal: any if (!initialNode) { initVal = this.createVarDeclarationScope(id, scope) initVal.uninit = !initialNode - initVal = SourceLine.addSrcLineInfo(initVal, id, id.loc && id.loc.sourcefile, 'Var Pass: ', id.name) - } else if (node?.parent?.type === 'CatchClause' && node?._meta?.isCatchParam && state?.throwstack?.length > 0) { + initVal = SourceLine.addSrcLineInfo(initVal, id, id.loc && id.loc.sourcefile, 'Var Pass: ', idName) + } else if ( + node?.parent?.type === 'CatchClause' && + node?._meta?.isCatchParam && + (state?.throwstack?.length ?? 0) > 0 + ) { initVal = state?.throwstack && state?.throwstack.shift() - initVal = SourceLine.addSrcLineInfo(initVal, node, node.loc && node.loc.sourcefile, 'Var Pass: ', id.name) + initVal = SourceLine.addSrcLineInfo(initVal, node, node.loc && node.loc.sourcefile, 'Var Pass: ', idName) delete node._meta.isCatchParm } else { initVal = this.processInstruction(scope, initialNode, state) if (!(id.type === 'Identifier' && id.name === 'self' && initialNode.type === 'ThisExpression')) { - initVal = SourceLine.addSrcLineInfo(initVal, node, node.loc && node.loc.sourcefile, 'Var Pass: ', id.name) + initVal = SourceLine.addSrcLineInfo(initVal, node, node.loc && node.loc.sourcefile, 'Var Pass: ', idName) } } - if (this.checkerManager && (this.checkerManager as any).checkAtPreDeclaration) + if (this.checkerManager && this.checkerManager.checkAtPreDeclaration) this.checkerManager.checkAtPreDeclaration(this, scope, node, state, { lnode: id, rvalue: null, @@ -801,11 +991,11 @@ class PythonAnalyzer extends (Analyzer as any) { entry_fclos: (this as any).entry_fclos, fdef: state.callstack && state.callstack[state.callstack.length - 1], }) - if (id.name === '*') { + if (idName === '*') { for (const x in initVal.value) { const v = initVal.value[x] if (!v) continue - const v_copy = _.clone(v) + const v_copy = lodashCloneWithTag(v) scope.value[x] = v_copy v_copy._this = scope v_copy.parent = scope @@ -814,16 +1004,12 @@ class PythonAnalyzer extends (Analyzer as any) { this.saveVarInCurrentScope(scope, id, initVal, state) } - if ( - initVal && - !Array.isArray(initVal) && - !(initVal.name || (initVal.id && initVal.id !== '') || initVal.sid) - ) { - initVal.sid = id.name + if (initVal && !Array.isArray(initVal) && !(initVal.name || initVal.sid)) { + initVal.sid = idName delete initVal.id } - scope.decls[id.name] = id + if (idName) scope.ast.setDecl(idName, id) const typeQualifiedName = AstUtil.typeToQualifiedName(node.varType) let declTypeVal @@ -831,9 +1017,6 @@ class PythonAnalyzer extends (Analyzer as any) { declTypeVal = this.getMemberValue(scope, typeQualifiedName, state) } - if (initVal && declTypeVal) { - initVal.sort = declTypeVal.sort - } return initVal } @@ -843,7 +1026,7 @@ class PythonAnalyzer extends (Analyzer as any) { * @param node * @param state */ - processAssignmentExpression(scope: any, node: any, state: any) { + override processAssignmentExpression(scope: Scope, node: AssignmentExpression, state: State): any { /* { operator, left, @@ -856,9 +1039,11 @@ class PythonAnalyzer extends (Analyzer as any) { const { left } = node const { right } = node let tmpVal = this.processInstruction(scope, right, state) - if (node.cloned && !tmpVal?.refCount) { - tmpVal = _.clone(tmpVal) - tmpVal.value = _.clone(tmpVal.value) + if (node.cloned && !tmpVal?.runtime?.refCount) { + tmpVal = lodashCloneWithTag(tmpVal) + if (typeof tmpVal === 'object') { + tmpVal.value = lodashCloneWithTag(tmpVal.value) + } } const oldVal = this.processInstruction(scope, left, state) tmpVal = SourceLine.addSrcLineInfo( @@ -866,17 +1051,22 @@ class PythonAnalyzer extends (Analyzer as any) { node, node.loc && node.loc.sourcefile, 'Var Pass: ', - left.type === 'TupleExpression' ? left.elements : left.name + left.type === 'TupleExpression' ? left.elements : (left as any).name || SymAddress.toStringID(left) ) if (left.type === 'TupleExpression') { this.handleTupleAssign(scope, left, tmpVal, state) } else { - if (!tmpVal) - // explicit null value - tmpVal = PrimitiveValue({ type: 'Literal', value: null, loc: right.loc }) + if (!tmpVal) { + tmpVal = new PrimitiveValue(scope.qid, 'undefined', null, null, 'Literal', right.loc) + } + if (typeof tmpVal !== 'object') { + tmpVal = new PrimitiveValue(scope.qid, ``, tmpVal, null, 'Literal', right.loc) + } const sid = SymAddress.toStringID(node.left) - tmpVal.sid = !tmpVal.id || tmpVal.id === '' ? sid : tmpVal.id + if (typeof tmpVal.sid === 'string' && tmpVal.sid.includes('', ast: node }) } /** @@ -959,27 +1155,27 @@ class PythonAnalyzer extends (Analyzer as any) { */ handleTupleAssign(scope: any, left: any, rightVal: any, state: any) { if (rightVal.vtype === 'union') { - const pairs = floor(rightVal.field.length / left.elements.length) + const pairs = floor(rightVal.value.length / left.elements.length) const scopes = new Array(left.elements.length) for (let i = 0; i < left.elements.length; i++) scopes[i] = new Array(pairs) for (let i = 0; i < pairs; i++) { for (let j = 0; j < left.elements.length; j++) { - scopes[j][i] = rightVal.field[i * left.elements.length + j] + scopes[j][i] = rightVal.value[i * left.elements.length + j] } } for (let i = 0; i < left.elements.length; i++) { const union = unionAllValues(scopes[i], state) this.saveVarInScope(scope, left.elements[i], union, state) } - } else if (Array.isArray(rightVal.field) && rightVal.field.length >= 1) { - const minLen = Math.min(left.elements.length, rightVal.field.length) + } else if (Array.isArray(rightVal.value) && rightVal.value.length >= 1) { + const minLen = Math.min(left.elements.length, rightVal.value.length) for (let i = 0; i < minLen; i++) { - this.saveVarInScope(scope, left.elements[i], rightVal.field[i], state) + this.saveVarInScope(scope, left.elements[i], rightVal.value[i], state) } - } else if (isSequentialNumericKeysField(rightVal)) { - const minLen = Math.min(left.elements.length, Object.keys(rightVal.field).length) + } else if (isSequentialNumericKeysMembers(rightVal)) { + const minLen = Math.min(left.elements.length, rightVal.members.size) for (let i = 0; i < minLen; i++) { - this.saveVarInScope(scope, left.elements[i], rightVal.field[i], state) + this.saveVarInScope(scope, left.elements[i], rightVal.members.get(String(i)), state) } } else { for (const i in left.elements) this.saveVarInScope(scope, left.elements[i], rightVal, state) @@ -989,13 +1185,12 @@ class PythonAnalyzer extends (Analyzer as any) { * * @param obj */ - function isSequentialNumericKeysField(obj: any) { - if (!obj || typeof obj.field !== 'object' || Array.isArray(obj.field) || obj.field === null) return false - const keys = Object.keys(obj.field) - if (keys.length === 0) return false - const numericKeys = keys.map((k) => Number(k)) + function isSequentialNumericKeysMembers(obj: any) { + if (!obj?.members || obj.members.size === 0) return false + const keys = [...obj.members.keys()] + const numericKeys = keys.map((k: string) => Number(k)) if (numericKeys.some(isNaN)) return false - numericKeys.sort((a, b) => a - b) + numericKeys.sort((a: number, b: number) => a - b) for (let i = 0; i < numericKeys.length; i++) { if (numericKeys[i] !== i) return false } @@ -1008,13 +1203,13 @@ class PythonAnalyzer extends (Analyzer as any) { * @param ast * @param source * @param filename - * @param isReScan */ - addASTInfo(ast: any, source: any, filename: any, isReScan: any) { + addASTInfo(ast: any, source: any, filename: any) { const { options } = this options.sourcefile = filename AstUtil.annotateAST(ast, options ? { sourcefile: filename } : null) - this.sourceCodeCache[filename] = source + // sourceCodeCache 已在 parseSingleFile/parseProject 中自动填充,或在调用 addASTInfo 之前已填充 + // 不需要在这里再次赋值 } /** @@ -1024,25 +1219,22 @@ class PythonAnalyzer extends (Analyzer as any) { * @param fname */ loadPredefinedModule(scope: any, importName: any, fname: any) { - let m = this.moduleManager.field[fname] - if (m) { + let m = this.topScope.context.modules.members.get(fname) + if (m && typeof m === 'object') { const fields = m.value if (_.has(fields, importName)) { return fields[importName] } } else { - m = SymbolValue({ id: fname, sid: fname, qid: fname, parent: this.topScope }) + m = new SymbolValue(this.topScope.qid, { sid: fname, qid: fname, parent: this.topScope }) } - const objval = SymbolValue({ - id: `${importName}`, + const objval = new SymbolValue(m.qid, { sid: `${importName}`, - qid: `${fname}.${importName}`, parent: m, - fdef: undefined, node_module: true, }) m.setFieldValue(importName, objval) - this.moduleManager.field[fname] = m + this.topScope.context.modules.members.set(fname, m) return objval } @@ -1052,6 +1244,11 @@ class PythonAnalyzer extends (Analyzer as any) { * @param filename */ preloadFileToPackage(ast: any, filename: any) { + // 已缓存则跳过,避免 __init__.py 被反复处理 + if (this.topScope.context.modules.members.has(filename)) { + return this.topScope.context.modules.members.get(filename) + } + const fullString = path.dirname(filename) const parts = Config.maindir.split('/') const appName = parts[parts.length - 1] @@ -1065,11 +1262,12 @@ class PythonAnalyzer extends (Analyzer as any) { packageName = fullString.substring(index).replaceAll('/', '.') } } - const packageScope = this.packageManager.getSubPackage(packageName, true) + const packageScope = this.topScope.context.packages.getSubPackage(packageName, true) if (path.basename(filename) === '__init__.py') { + // 先注册到 members 再处理,防止递归 import 重复触发 processModuleDirect + this.topScope.context.modules.members.set(filename, packageScope) + this.fileManager[filename] = packageScope.uuid const m = this.processModuleDirect(ast, filename, packageScope) - this.fileManager[filename] = m - this.moduleManager[filename] = m ;(m as any).ast = ast return m } @@ -1081,13 +1279,14 @@ class PythonAnalyzer extends (Analyzer as any) { * @param cdef * @param state */ - preProcessClassDefinition(scope: any, cdef: any, state: any) { - if (!(cdef && cdef.body)) return UndefinedValue() + override preProcessClassDefinition(scope: any, cdef: any, state: any) { + if (!(cdef && cdef.body)) return new UndefinedValue() const fname = cdef.id?.name - const cscope = Scope.createSubScope(fname, scope, 'class') - cscope.cdef = cdef + const cscope = ScopeClass.createSubScope(fname, scope, 'class') + cscope.ast = cdef + cscope.ast.cdef = cdef cscope.modifier = {} cscope.inits = new Set() this.resolveClassInheritance(cscope, state) @@ -1119,10 +1318,14 @@ class PythonAnalyzer extends (Analyzer as any) { return } for (const key in obj) { - if (blacklist.includes(obj[key]._qid)) { - obj[key].hasTagRec = undefined - obj[key]._tags = undefined - obj[key].trace = undefined + if (!obj[key]) { + continue + } + if (blacklist.includes(obj[key].qid)) { + obj[key].taint.sanitize() + obj[key].value = {} + } else if (obj[key].vtype === 'symbol' && blacklist.includes(obj[key].sid)) { + obj[key].taint.sanitize() obj[key].value = {} } } @@ -1133,8 +1336,8 @@ class PythonAnalyzer extends (Analyzer as any) { * @param fclos * @param state */ - resolveClassInheritance(fclos: any, state: any) { - const fdef = fclos.cdef + override resolveClassInheritance(fclos: any, state: any) { + const fdef = fclos.ast.cdef const { supers } = fdef if (!supers || supers.length === 0) return @@ -1156,32 +1359,33 @@ class PythonAnalyzer extends (Analyzer as any) { return } const superClos = this.processInstruction(scope, superId, state) - if (!superClos) return UndefinedValue() + if (!superClos) return new UndefinedValue() fclos.super = superClos - const superValue = fclos.value.super || Scope.createSubScope('super', fclos, 'fclos') + const superValue = fclos.value.super || ScopeClass.createSubScope('super', fclos, 'fclos') superValue.parent = superClos for (const fieldName in superClos.value) { if (fieldName === 'super') continue const v = superClos.value[fieldName] - if (v.readonly) continue - const v_copy = _.clone(v) - v_copy.inherited = true + if (v.runtime?.readonly) continue + const v_copy = lodashCloneWithTag(v) + if (!v_copy.func) v_copy.func = {} + v_copy.func.inherited = true v_copy._this = fclos v_copy._base = superClos fclos.value[fieldName] = v_copy superValue.value[fieldName] = v_copy if (fieldName === '_CTOR_') { - superValue.fdef = v_copy.fdef - superValue.overloaded = superValue.overloaded || [] + superValue.ast.node = v_copy.ast.fdef + superValue.ast.fdef = v_copy.ast.fdef superValue.overloaded.push(fdef) } } - for (const x in superClos.decls) { - const v = superClos.decls[x] - fclos.decls[x] = v + for (const x of superClos.ast.declKeys) { + const v = superClos.ast.getDecl(x) + fclos.ast.setDecl(x, v) } for (const x in superClos.modifier) { const v = superClos.modifier[x] @@ -1210,9 +1414,8 @@ class PythonAnalyzer extends (Analyzer as any) { * 3. 最后逐个处理模块(processModule) * * @param dir - 项目目录 - * @param isReScan - 是否为重新扫描 */ - scanModules(dir: any, isReScan: boolean = false) { + async scanModules(dir: any) { const { options } = this const modules = FileUtil.loadAllFileTextGlobby( ['**/*.(py)', '!**/.venv/**', '!**/vendor/**', '!**/node_modules/**', '!**/site-packages/**'], @@ -1224,6 +1427,8 @@ class PythonAnalyzer extends (Analyzer as any) { caseSensitiveMatch: false, }) .map((relativePath: string) => path.resolve(dir, relativePath)) + // 构建规范化文件路径集合,用于 O(1) 查找 + this._normalizedFileSet = new Set(this.fileList.map((f: string) => path.normalize(f))) if (modules.length === 0) { handleException( null, @@ -1233,33 +1438,64 @@ class PythonAnalyzer extends (Analyzer as any) { process.exit(1) } - // 开始 parseCode 阶段:批量解析所有 Python 包为 AST + // 预先填充 sourceCodeCache,避免 parseProject 中的 postProcessProjectResult 重复读取 + for (const mod of modules) { + this.sourceCodeCache.set(mod.file, mod.content.split(/\n/)) + } + this.performanceTracker.start('preProcess.parseCode') - PythonParser.parsePackages(this.astManager, dir, options) + this.pyAstParseManager = await Parser.parseProject(dir, options, this.sourceCodeCache) this.performanceTracker.end('preProcess.parseCode') this.performanceTracker.start('preProcess.preload') for (const mod of modules) { const filename = mod.file - const ast = this.astManager[filename] + const ast = this.pyAstParseManager[filename] if (ast) { - SourceLine.storeCode(mod.file, mod.content) - this.addASTInfo(ast, mod.content, mod.file, isReScan as any) + this.addASTInfo(ast, mod.content, mod.file) } } this.performanceTracker.end('preProcess.preload') // 开始 ProcessModule 阶段:处理所有模块(分析 AST) this.performanceTracker.start('preProcess.processModule') - for (const mod of modules) { + for (let i = 0; i < modules.length; i++) { + const mod = modules[i] const filename = mod.file - const ast = this.astManager[filename] + const ast = this.pyAstParseManager[filename] if (ast) { - this.processModule(ast, filename, isReScan as any) + this.processModule(ast, filename) } } this.performanceTracker.end('preProcess.processModule') } + + /** + * 判断 fclos 是否有 @classmethod 装饰器 + * @param fclos + */ + hasClassmethodDecorator(fclos: any): boolean { + const decorators = fclos.fdef?._meta?.decorators || fclos.ast?._meta?.decorators + if (!Array.isArray(decorators)) return false + return decorators.some( + (d: any) => + (d.type === 'Identifier' && d.name === 'classmethod') || + (d.type === 'MemberAccess' && d.property?.name === 'classmethod') + ) + } + + /** + * 从 classmethod 的 fclos 解析出所属的 class 对象 + * @param fclos + */ + resolveClassForClassmethod(fclos: any): any { + const thisObj = fclos._this + if (!thisObj) return null + if (thisObj.vtype === 'class') return thisObj + if (thisObj._this?.vtype === 'class') return thisObj._this + if (thisObj.cdef) return thisObj.cdef + return thisObj + } } /** diff --git a/src/engine/analyzer/python/common/python-import-resolver.ts b/src/engine/analyzer/python/common/python-import-resolver.ts index 41105128..ef92d4e0 100644 --- a/src/engine/analyzer/python/common/python-import-resolver.ts +++ b/src/engine/analyzer/python/common/python-import-resolver.ts @@ -12,6 +12,177 @@ const path = require('path') const Config = require('../../../../config') const handleException = require('../../common/exception-handler') +const normalizePath = (filePath: string) => path.normalize(filePath) + +/** + * 文件列表缓存结构 + * 存储规范化后的文件路径集合和相关元数据 + */ +let fileListCache: { + normalizedFileSet: Set + fileListHash: string + projectRoot: string + subDirs: Set +} | null = null + +/** + * 搜索路径缓存 + * 按目录路径存储对应的搜索路径列表(同目录下的文件共享相同的搜索路径) + */ +const searchPathsCache = new Map() + +/** + * 导入解析结果缓存 + * 按导入路径和目录组合存储解析结果(同目录下的文件共享缓存) + */ +const resolveCache = new Map() + +/** + * 目录规范化缓存 + * 缓存已规范化的目录路径,避免重复调用 path.dirname 和 path.normalize + */ +const dirCache = new Map() + +/** + * 模块候选路径缓存 + * 按 baseDir + modulePath + fieldName 组合缓存候选结果 + */ +const moduleCandidatesCache = new Map() + +/** + * 生成文件列表的哈希标识 + * 用于判断文件列表是否发生变化 + * @param fileList + */ +function getFileListHash(fileList: string[]): string { + return `${fileList.length}_${fileList[0] || ''}_${fileList[fileList.length - 1] || ''}` +} + +/** + * 获取文件所在的规范化目录 + * 使用缓存避免重复的 dirname 和 normalize 调用 + * @param filePath + */ +function getNormalizedDir(filePath: string): string { + const cached = dirCache.get(filePath) + if (cached !== undefined) { + return cached + } + const normalized = path.normalize(path.dirname(filePath)) + dirCache.set(filePath, normalized) + return normalized +} + +/** + * 初始化或更新文件列表缓存 + * 将文件列表规范化并建立索引,同时提取项目的子目录结构 + * @param fileList + * @param projectRoot + */ +function ensureFileListCache(fileList: string[], projectRoot: string): void { + const hash = getFileListHash(fileList) + + if (fileListCache && fileListCache.fileListHash === hash && fileListCache.projectRoot === projectRoot) { + return // 缓存仍然有效 + } + + // 重建缓存 + const normalizedFileSet = new Set() + const subDirs = new Set() + const normalizedProjectRoot = path.normalize(projectRoot.replace(/\/$/, '')) + const normalizedProjectRootWithSep = normalizedProjectRoot + path.sep + + for (const file of fileList) { + const normalizedFile = path.normalize(file) + normalizedFileSet.add(normalizedFile) + + // 提取子目录 + if (normalizedFile.startsWith(normalizedProjectRootWithSep)) { + const relativePath = normalizedFile.substring(normalizedProjectRootWithSep.length) + const firstDirIndex = relativePath.indexOf(path.sep) + if (firstDirIndex > 0) { + const firstDir = relativePath.substring(0, firstDirIndex) + const subDirPath = path.normalize(path.join(normalizedProjectRoot, firstDir)) + subDirs.add(subDirPath) + } + } + } + + fileListCache = { + normalizedFileSet, + fileListHash: hash, + projectRoot: normalizedProjectRoot, + subDirs, + } + + // 清空依赖缓存 + searchPathsCache.clear() + resolveCache.clear() + dirCache.clear() + moduleCandidatesCache.clear() +} + +/** + * 检查文件是否存在 + * 优先通过规范化路径集合进行查找 + * @param fileList + * @param filePath + */ +function fileExists(_fileList: string[] | undefined, filePath: string): boolean { + const normalizedPath = path.normalize(filePath) + // 直接用 Set 查找,去掉 O(n) 线性扫描 fallback + return fileListCache?.normalizedFileSet.has(normalizedPath) ?? false +} + +const buildModuleCandidates = ( + baseDir: string, + modulePath: string, + fileList: string[], + fieldName?: string +): string[] => { + const cacheKey = `${baseDir}|${modulePath}|${fieldName || ''}` + const cached = moduleCandidatesCache.get(cacheKey) + if (cached) { + return cached + } + + const candidates: string[] = [] + const fsPath = modulePath.replace(/\./g, path.sep) + + // 候选路径1:作为文件查找 + const filePath = path.join(baseDir, `${fsPath}.py`) + const normalizedFilePath = path.normalize(filePath) + if (fileExists(fileList, normalizedFilePath)) { + candidates.push(normalizedFilePath) + } + + // 候选路径2:作为包目录查找(包含 __init__.py) + const packagePath = path.join(baseDir, fsPath) + const normalizedPackagePath = path.normalize(packagePath) + const initFile = path.join(normalizedPackagePath, '__init__.py') + if (fileExists(fileList, initFile)) { + candidates.push(normalizedPackagePath) + + // 如果指定了字段名,也查找包内的子模块文件(例如:package/module.py) + if (fieldName) { + const subModulePath = path.join(normalizedPackagePath, `${fieldName}.py`) + const normalizedSubModulePath = path.normalize(subModulePath) + if (fileExists(fileList, normalizedSubModulePath)) { + candidates.push(normalizedSubModulePath) + } + } + } + + // 候选路径3:查找包内的模块文件(例如:A/module.py) + const packageModulePath = path.join(normalizedPackagePath, `${path.basename(fsPath)}.py`) + if (fileExists(fileList, packageModulePath)) { + candidates.push(packageModulePath) + } + + moduleCandidatesCache.set(cacheKey, candidates) + return candidates +} + /** * 构建搜索路径列表 * 参考 Python 的 sys.path 机制,按优先级排序: @@ -33,13 +204,21 @@ function buildSearchPaths(sourceFile: string, fileList: string[], projectRoot: s } try { - const normalizedProjectRoot = path.normalize(projectRoot.replace(/\/$/, '')) + ensureFileListCache(fileList, projectRoot) // 1. 当前文件所在目录(最高优先级) - const currentDir = path.dirname(sourceFile) + const currentDir = getNormalizedDir(sourceFile) + const cached = searchPathsCache.get(currentDir) + if (cached) { + return cached + } + + const normalizedProjectRoot = fileListCache!.projectRoot + if (currentDir && !searchPaths.includes(currentDir)) { searchPaths.push(currentDir) } + const seenPaths = new Set(searchPaths) // 2. 从当前文件向上查找所有包含 __init__.py 的包目录 let dir = currentDir @@ -47,84 +226,46 @@ function buildSearchPaths(sourceFile: string, fileList: string[], projectRoot: s const maxLoops = 10 // 防止无限循环 while (dir && dir !== normalizedProjectRoot && dir !== path.dirname(dir) && loopCount < maxLoops) { - try { - const initFile = path.join(dir, '__init__.py') - if ( - fileList.some((f: string) => { - return path.normalize(f) === path.normalize(initFile) - }) && - !searchPaths.includes(dir) - ) { - searchPaths.push(dir) - } - const parentDir = path.dirname(dir) - if (parentDir === dir) break - dir = parentDir - loopCount++ - } catch (e) { - handleException( - e, - `[buildSearchPaths] Error searching package directories at ${dir}`, - `[buildSearchPaths] Error searching package directories at ${dir}` - ) - break + const initFile = path.normalize(path.join(dir, '__init__.py')) + if (fileExists(fileList, initFile) && !seenPaths.has(dir)) { + searchPaths.push(dir) + seenPaths.add(dir) } + const parentDir = path.dirname(dir) + if (parentDir === dir) break + dir = parentDir + loopCount++ } // 3. 项目根目录 - if (normalizedProjectRoot && !searchPaths.includes(normalizedProjectRoot)) { + if (normalizedProjectRoot && !seenPaths.has(normalizedProjectRoot)) { searchPaths.push(normalizedProjectRoot) + seenPaths.add(normalizedProjectRoot) } - // 4. 项目根目录的所有直接子目录(如果包含 Python 文件) - try { - const subDirsWithPythonFiles = new Set() - const normalizedProjectRootWithSep = normalizedProjectRoot + path.sep - - for (const file of fileList) { - try { - const normalizedFile = path.normalize(file) - if (normalizedFile.startsWith(normalizedProjectRootWithSep)) { - const relativePath = normalizedFile.substring(normalizedProjectRootWithSep.length) - const firstDirIndex = relativePath.indexOf(path.sep) - - if (firstDirIndex > 0) { - // 文件在子目录中,提取第一个目录名 - const firstDir = relativePath.substring(0, firstDirIndex) - const subDirPath = path.join(normalizedProjectRoot, firstDir) - subDirsWithPythonFiles.add(path.normalize(subDirPath)) - } - } - } catch (e) { - handleException( - e, - `[buildSearchPaths] Error processing file in subdirectory search: ${e}, file: ${file}`, - `[buildSearchPaths] Error processing file in subdirectory search: ${e}, file: ${file}` - ) - continue - } + // 4. 项目根目录的所有直接子目录(从缓存读取) + for (const subDir of fileListCache!.subDirs) { + if (!seenPaths.has(subDir)) { + searchPaths.push(subDir) + seenPaths.add(subDir) } - - for (const subDir of subDirsWithPythonFiles) { - if (!searchPaths.includes(subDir)) { - searchPaths.push(subDir) - } - } - } catch (e) { - handleException( - e, - `[buildSearchPaths] Error processing subdirectories of ${normalizedProjectRoot}`, - `[buildSearchPaths] Error processing subdirectories of ${normalizedProjectRoot}` - ) } } catch (e) { // 如果整个函数出错,至少返回当前目录 - const currentDir = path.dirname(sourceFile) + const currentDir = getNormalizedDir(sourceFile) if (currentDir && !searchPaths.includes(currentDir)) { searchPaths.push(currentDir) } + handleException( + e, + `[buildSearchPaths] Error building search paths for ${sourceFile}`, + `[buildSearchPaths] Error building search paths for ${sourceFile}` + ) } + // 按目录缓存结果,同目录下的文件可以共享 + const currentDir = getNormalizedDir(sourceFile) + searchPathsCache.set(currentDir, searchPaths) return searchPaths } @@ -136,6 +277,10 @@ function buildSearchPaths(sourceFile: string, fileList: string[], projectRoot: s * @returns 项目根目录 */ function findProjectRoot(fileList: string[], startDir: string): string { + const hash = getFileListHash(fileList || []) + if (fileListCache && fileListCache.fileListHash === hash && fileListCache.projectRoot) { + return fileListCache.projectRoot + } if (!fileList || fileList.length === 0) { return startDir || process.cwd() } @@ -205,69 +350,56 @@ function findProjectRoot(fileList: string[], startDir: string): string { } /** - * 解析绝对导入路径 - * 从所有搜索路径中查找模块 + * 获取绝对导入的所有候选路径(按优先级排序) * * @param modulePath - 模块路径 * @param searchPaths - 搜索路径列表 * @param fileList - 所有 Python 文件的列表 - * @returns 解析后的文件路径,如果找不到返回 null + * @param fieldName - 可选的字段名(用于 `from module import fieldName` 的情况) + * @returns 候选路径数组(按优先级排序) */ -function resolveAbsoluteImport(modulePath: string, searchPaths: string[], fileList: string[]): string | null { - const fsPath = modulePath.replace(/\./g, path.sep) - - for (const searchPath of searchPaths) { - // 尝试作为文件查找 - const filePath = path.join(searchPath, `${fsPath}.py`) - const normalizedFilePath = path.normalize(filePath) - if (fileList.some((f) => path.normalize(f) === normalizedFilePath)) { - return normalizedFilePath - } +function getAllAbsoluteImportCandidates( + modulePath: string, + searchPaths: string[], + fileList: string[], + fieldName?: string +): string[] { + const candidates: string[] = [] + if (!modulePath || !searchPaths || !fileList) { + return candidates + } - // 尝试作为包目录查找(包含 __init__.py) - const packagePath = path.join(searchPath, fsPath) - const normalizedPackagePath = path.normalize(packagePath) - const initFile = path.join(normalizedPackagePath, '__init__.py') - if (fileList.some((f) => path.normalize(f) === path.normalize(initFile))) { - return normalizedPackagePath - } + if (!fileListCache) { + const root = findProjectRoot(fileList, Config.maindir || process.cwd()) + ensureFileListCache(fileList, root) + } - // 尝试查找包内的模块文件 - const packageModulePath = path.join(normalizedPackagePath, `${path.basename(fsPath)}.py`) - if (fileList.some((f) => path.normalize(f) === path.normalize(packageModulePath))) { - return packageModulePath - } + for (const searchPath of searchPaths) { + candidates.push(...buildModuleCandidates(searchPath, modulePath, fileList, fieldName)) } - return null + return candidates } /** - * 解析相对导入路径 - * 从当前文件所在目录开始查找 - * - * 相对导入规则: - * - 向上层级数 = 点号数量 - 1 - * - `..` 表示父包/目录本身(用于 `from .. import module`) + * 解析绝对导入路径 + * 从所有搜索路径中查找模块 * - * @param relativePath - 相对路径(如 ".module" 或 "..parent.module" 或 ".." 或 "....") - * @param currentFile - 当前文件的绝对路径 + * @param modulePath - 模块路径 + * @param searchPaths - 搜索路径列表 * @param fileList - 所有 Python 文件的列表 - * @param moduleName - 可选的模块名(用于 `from .. import moduleName` 的情况) * @returns 解析后的文件路径,如果找不到返回 null */ -function resolveRelativeImport( - relativePath: string, - currentFile: string, - fileList: string[], - moduleName?: string -): string | null { - if (!relativePath || !currentFile || !fileList) { - return null - } +function resolveAbsoluteImport(modulePath: string, searchPaths: string[], fileList: string[]): string | null { + const candidates = getAllAbsoluteImportCandidates(modulePath, searchPaths, fileList) + return candidates.length > 0 ? candidates[0] : null +} +const resolveRelativeTarget = ( + relativePath: string, + currentFile: string +): { targetDir: string | null; modulePath: string; invalid: boolean } => { const currentDir = path.dirname(path.normalize(currentFile)) - let modulePath = relativePath // 计算前导点号的数量 @@ -290,11 +422,10 @@ function resolveRelativeImport( const targetLevel = parts.length - levelsToGoUp if (targetLevel < 0) { - return null + return { targetDir: null, modulePath: '', invalid: true } } if (targetLevel === 0) { - // 到达根目录 targetDir = isAbsolute ? path.sep : '.' } else { const targetParts = parts.slice(0, targetLevel) @@ -307,8 +438,7 @@ function resolveRelativeImport( const normalizedTarget = path.normalize(targetDir) if (normalizedTarget === normalizedDir && levelsToGoUp > 0) { - // 路径没有变化,说明已经到达根目录但还需要向上(用于验证) - return null + return { targetDir: null, modulePath: '', invalid: true } } } @@ -316,50 +446,103 @@ function resolveRelativeImport( modulePath = modulePath.substring(dotIndex).replace(/^\/+/, '') } + return { targetDir, modulePath, invalid: false } +} + +const getRelativeCandidates = ( + targetDir: string, + modulePath: string, + fileList: string[], + fieldName?: string +): string[] => { + return buildModuleCandidates(targetDir, modulePath, fileList, fieldName) +} +/** + * 获取相对导入的所有候选路径(按优先级排序) + * + * @param relativePath - 相对路径(如 ".module" 或 "..parent.module") + * @param currentFile - 当前文件的绝对路径 + * @param fileList - 所有 Python 文件的列表 + * @param moduleName - 可选的模块名(用于 `from .. import moduleName` 的情况) + * @param fieldName - 可选的字段名(用于 `from .module import fieldName` 的情况) + * @returns 候选路径数组(按优先级排序) + */ +function getAllRelativeImportCandidates( + relativePath: string, + currentFile: string, + fileList: string[], + moduleName?: string, + fieldName?: string +): string[] { + const candidates: string[] = [] + if (!relativePath || !currentFile || !fileList) { + return candidates + } + + if (!fileListCache) { + const root = findProjectRoot(fileList, Config.maindir || process.cwd()) + ensureFileListCache(fileList, root) + } + + const { targetDir, modulePath: parsedModulePath, invalid } = resolveRelativeTarget(relativePath, currentFile) + if (invalid || !targetDir) { + return candidates + } + // 处理 `from .. import moduleName` 的情况 - // 如果 relativePath 只有点号(如 ".."),使用 moduleName + let modulePath = parsedModulePath if (!modulePath && moduleName) { modulePath = moduleName } - // 如果没有模块路径(只有点号且没有 moduleName),返回当前目录 if (!modulePath) { - return targetDir + return candidates } + return getRelativeCandidates(targetDir, modulePath, fileList, fieldName) +} - const fsPath = modulePath.replace(/\./g, path.sep) - - // 尝试作为文件查找 - const filePath = path.join(targetDir, `${fsPath}.py`) - const normalizedFilePath = path.normalize(filePath) - const foundFile = fileList.find((f: string) => { - return path.normalize(f) === normalizedFilePath - }) - if (foundFile) { - return normalizedFilePath +/** + * 解析相对导入路径 + * 从当前文件所在目录开始查找 + * + * 相对导入规则: + * - 向上层级数 = 点号数量 - 1 + * - `..` 表示父包/目录本身(用于 `from .. import module`) + * + * @param relativePath - 相对路径(如 ".module" 或 "..parent.module" 或 ".." 或 "....") + * @param currentFile - 当前文件的绝对路径 + * @param fileList - 所有 Python 文件的列表 + * @param moduleName - 可选的模块名(用于 `from .. import moduleName` 的情况) + * @returns 解析后的文件路径,如果找不到返回 null + */ +function resolveRelativeImport( + relativePath: string, + currentFile: string, + fileList: string[], + moduleName?: string +): string | null { + if (!relativePath || !currentFile || !fileList) { + return null } - // 尝试作为包目录查找(包含 __init__.py) - const packagePath = path.join(targetDir, fsPath) - const normalizedPackagePath = path.normalize(packagePath) - const initFile = path.join(normalizedPackagePath, '__init__.py') - const foundInit = fileList.find((f: string) => { - return path.normalize(f) === path.normalize(initFile) - }) - if (foundInit) { - return normalizedPackagePath + const { targetDir, modulePath: parsedModulePath, invalid } = resolveRelativeTarget(relativePath, currentFile) + if (invalid || !targetDir) { + return null } - // 尝试查找包内的模块文件(例如:A/module.py) - const packageModulePath = path.join(normalizedPackagePath, `${path.basename(fsPath)}.py`) - const foundPackageModule = fileList.find((f: string) => { - return path.normalize(f) === path.normalize(packageModulePath) - }) - if (foundPackageModule) { - return packageModulePath + // 处理 `from .. import moduleName` 的情况 + // 如果 relativePath 只有点号(如 ".."),使用 moduleName + let modulePath = parsedModulePath + if (!modulePath && moduleName) { + modulePath = moduleName } - return null + // 如果没有模块路径(只有点号且没有 moduleName),返回当前目录 + if (!modulePath) { + return targetDir + } + const candidates = getRelativeCandidates(targetDir, modulePath, fileList) + return candidates.length > 0 ? candidates[0] : null } /** @@ -380,17 +563,31 @@ function resolveImportPath( if (!importPath) { return null } + const root = projectRoot || findProjectRoot(fileList, Config.maindir || process.cwd()) - const searchPaths = buildSearchPaths(currentFile, fileList, root) + ensureFileListCache(fileList, root) - if (importPath.startsWith('.')) { - return resolveRelativeImport(importPath, currentFile, fileList) + const currentDir = getNormalizedDir(currentFile) + const cacheKey = `${importPath}|${currentDir}` + const cached = resolveCache.get(cacheKey) + if (cached !== undefined) { + return cached } - return resolveAbsoluteImport(importPath, searchPaths, fileList) + + const searchPaths = buildSearchPaths(currentFile, fileList, root) + const result = importPath.startsWith('.') + ? resolveRelativeImport(importPath, currentFile, fileList) + : resolveAbsoluteImport(importPath, searchPaths, fileList) + + resolveCache.set(cacheKey, result) + return result } export = { resolveImportPath, resolveRelativeImport, + getAllRelativeImportCandidates, + getAllAbsoluteImportCandidates, + buildSearchPaths, + findProjectRoot, } - diff --git a/src/engine/analyzer/python/fastapi/entrypoint-collector/fastapi-entrypoint.ts b/src/engine/analyzer/python/fastapi/entrypoint-collector/fastapi-entrypoint.ts index 748c88fd..0e74d408 100644 --- a/src/engine/analyzer/python/fastapi/entrypoint-collector/fastapi-entrypoint.ts +++ b/src/engine/analyzer/python/fastapi/entrypoint-collector/fastapi-entrypoint.ts @@ -270,3 +270,4 @@ function findFastApiEntryPointAndSource(filenameAstObj: FilenameAstMap, dir: str } export = { findFastApiEntryPointAndSource } + diff --git a/src/engine/analyzer/python/flask/entrypoint-collector/flask-default-entrypoint.ts b/src/engine/analyzer/python/flask/entrypoint-collector/flask-default-entrypoint.ts index 65ee9b6d..549e1df7 100644 --- a/src/engine/analyzer/python/flask/entrypoint-collector/flask-default-entrypoint.ts +++ b/src/engine/analyzer/python/flask/entrypoint-collector/flask-default-entrypoint.ts @@ -13,7 +13,84 @@ interface FilenameAstMap { [filename: string]: ASTObject } +// 类视图基类名:Flask-RESTX Resource、Flask MethodView +const CLASS_VIEW_BASE_NAMES = ['Resource', 'MethodView'] +// HTTP 方法名 +const HTTP_METHODS = ['get', 'post', 'put', 'delete', 'patch', 'head', 'options'] + +/** + * 检查装饰器函数是否为 Flask 路由装饰器(@app.route / @app.get 等) + */ +function isFlaskRouteDecorator(decoratorObj: any): boolean { + if (decoratorObj.type !== 'CallExpression' || !decoratorObj.callee) { + return false + } + const { callee } = decoratorObj + if (callee.type !== 'MemberAccess' || !callee.property?.name) { + return false + } + return ['route', 'get', 'post', 'put', 'delete', 'patch'].includes(callee.property.name) +} + +/** + * 从所有文件的 AST 中收集类继承关系 + * 返回 Map> + */ +function buildClassInheritanceMap(filenameAstObj: FilenameAstMap): Map> { + const inheritanceMap = new Map>() + for (const filename in filenameAstObj) { + const body = filenameAstObj[filename]?.body + if (!body) continue + for (const obj of body) { + if (obj.type !== 'ClassDefinition' || !obj.id?.name || !Array.isArray(obj.supers)) continue + const className: string = obj.id.name + if (!inheritanceMap.has(className)) { + inheritanceMap.set(className, new Set()) + } + const parents = inheritanceMap.get(className)! + for (const s of obj.supers) { + if (s.type === 'Identifier' && s.name) { + parents.add(s.name) + } + } + } + } + return inheritanceMap +} + +const MAX_INHERITANCE_DEPTH = 10 + +/** + * 递归检查 className 是否直接或间接继承自 CLASS_VIEW_BASE_NAMES + */ +function isTransitiveClassView( + className: string, + inheritanceMap: Map>, + visited?: Set +): boolean { + if (CLASS_VIEW_BASE_NAMES.includes(className)) return true + if (!visited) visited = new Set() + if (visited.has(className) || visited.size >= MAX_INHERITANCE_DEPTH) return false + visited.add(className) + const parents = inheritanceMap.get(className) + if (!parents) return false + for (const parent of parents) { + if (isTransitiveClassView(parent, inheritanceMap, visited)) return true + } + return false +} + /** + * 检查类是否直接或间接继承自 REST 类视图基类(Resource / MethodView) + */ +function isClassBasedView(classNode: any, inheritanceMap: Map>): boolean { + const className: string | undefined = classNode.id?.name + if (!className) return false + return isTransitiveClassView(className, inheritanceMap) +} + +/** + * 收集装饰器路由函数和类视图中的 HTTP 方法作为 entrypoint * * @param filenameAstObj * @param dir @@ -21,51 +98,69 @@ interface FilenameAstMap { function findFlaskEntryPointAndSource(filenameAstObj: FilenameAstMap, dir: string) { const flaskEntryPointArray: (typeof EntryPoint)[] = [] const flaskEntryPointSourceArray: any[] = [] + const inheritanceMap = buildClassInheritanceMap(filenameAstObj) for (const filename in filenameAstObj) { const body = filenameAstObj[filename]?.body if (!body) { continue } + const shortFileName = extractRelativePath(filename, dir) + for (const obj of body) { + // 路径 A:装饰器路由函数(@app.route / @bp.get 等) if ( - obj.type !== 'FunctionDefinition' || - !obj.hasOwnProperty('parameters') || - !obj.hasOwnProperty('_meta') || - !obj._meta.hasOwnProperty('decorators') || - !obj.hasOwnProperty('id') || - !obj.id.hasOwnProperty('name') + obj.type === 'FunctionDefinition' && + obj.parameters && + obj._meta?.decorators && + obj.id?.name ) { + const funcName = obj.id.name + for (const decoratorObj of obj._meta.decorators) { + if (isFlaskRouteDecorator(decoratorObj)) { + const entryPoint = new EntryPoint(Constant.ENGIN_START_FUNCALL) + entryPoint.filePath = shortFileName + entryPoint.functionName = funcName + entryPoint.attribute = 'HTTP' + flaskEntryPointArray.push(entryPoint) + + if (entryPointAndSourceAtSameTime) { + const paramSourceArray = findSourceOfFuncParam(filename, funcName, obj, null) + if (paramSourceArray) { + flaskEntryPointSourceArray.push(...paramSourceArray) + } + } + break + } + } continue } - const funcName = obj.id.name - - for (const decoratorObj of obj._meta.decorators) { - if (decoratorObj.type === 'CallExpression' && decoratorObj.hasOwnProperty('callee')) { - const { callee } = decoratorObj - if (callee.type === 'MemberAccess') { - if (!callee.hasOwnProperty('property')) { - continue - } - const { property } = callee - if (!property.hasOwnProperty('name')) { - continue - } - if (['route', 'get', 'post', 'put', 'delete', 'patch'].includes(property.name)) { - const shortFileName = extractRelativePath(filename, dir) - - const entryPoint = new EntryPoint(Constant.ENGIN_START_FUNCALL) - entryPoint.filePath = shortFileName - entryPoint.functionName = funcName - entryPoint.attribute = 'HTTP' - flaskEntryPointArray.push(entryPoint) - - if (entryPointAndSourceAtSameTime) { - const paramSourceArray = findSourceOfFuncParam(filename, funcName, obj, null) - if (paramSourceArray) { - flaskEntryPointSourceArray.push(...paramSourceArray) - } - } + + // 路径 B:类视图(继承 Resource / MethodView 的类中的 HTTP 方法) + if (obj.type === 'ClassDefinition' && isClassBasedView(obj, inheritanceMap)) { + const classBody = Array.isArray(obj.body) ? obj.body : [] + for (const member of classBody) { + if ( + member.type !== 'FunctionDefinition' || + !member.id?.name || + !member.parameters + ) { + continue + } + const methodName = member.id.name + if (!HTTP_METHODS.includes(methodName)) { + continue + } + const entryPoint = new EntryPoint(Constant.ENGIN_START_FUNCALL) + entryPoint.filePath = shortFileName + entryPoint.functionName = methodName + entryPoint.attribute = 'HTTP' + flaskEntryPointArray.push(entryPoint) + + if (entryPointAndSourceAtSameTime) { + const paramSourceArray = findSourceOfFuncParam(filename, methodName, member, null) + if (paramSourceArray) { + flaskEntryPointSourceArray.push(...paramSourceArray) } } } diff --git a/src/engine/parser/golang/go-ast-builder.ts b/src/engine/parser/golang/go-ast-builder.ts index 2e079d07..a11bb1a3 100644 --- a/src/engine/parser/golang/go-ast-builder.ts +++ b/src/engine/parser/golang/go-ast-builder.ts @@ -1,31 +1,28 @@ +/* eslint-disable @typescript-eslint/no-require-imports */ +/* eslint-disable @typescript-eslint/no-use-before-define */ const { LanguageType } = require('@ant-yasa/uast-parser-java-js') const ChildProcess = require('child_process') const path = require('path') const fs = require('fs') const JSONStream = require('JSONStream') const { handleException } = require('../../analyzer/common/exception-handler') -const { addNodeHash, deleteParent } = require('../../../util/ast-util') +const { resolveUastBinaryPath } = require('../../../util/file-util') let uastFilePath = './uast.json' /** - * - * @param rootDir - * @param options + * 构建 Go UAST + * @param rootDir - 根目录 + * @param options - 构建选项 + * @returns {any} 构建结果 */ function buildUASTGo(rootDir: any, options: Record) { options = options || {} - if ( - options.language && - options.language !== LanguageType.LANG_GO && - options.language !== 'golang' - ) { + if (options.language && options.language !== LanguageType.LANG_GO && options.language !== 'golang') { handleException( - new Error( - `Go AST Builder received wrong language type: ${options.language}`, - ), - `Error: Go AST Builder received wrong language type: ${options.language}`, + new Error(`Go AST Builder received wrong language type: ${options.language}`), `Error: Go AST Builder received wrong language type: ${options.language}`, + `Error: Go AST Builder received wrong language type: ${options.language}` ) process.exit(1) } @@ -34,21 +31,22 @@ function buildUASTGo(rootDir: any, options: Record) { if (options.single) { isSingle = '-single' } - // prefer user-provided SDK path if present - let uast4go_path = '' - if (options.uastSDKPath && options.uastSDKPath !== '') { - uast4go_path = options.uastSDKPath - } else { - // fallback to default deps location - uast4go_path = path.join(__dirname, '../../../../deps/uast4go/uast4go') - } + + // 使用统一的路径解析函数 + const devPath = path.join(__dirname, '../../../../deps/uast4go/uast4go') + // eslint-disable-next-line @typescript-eslint/naming-convention + const uast4go_path = resolveUastBinaryPath({ + uastSDKPath: options.uastSDKPath, + binaryName: 'uast4go', + devPath, + }) + // if uast4goPath does not exist, exit with error - if (!fs.existsSync(uast4go_path)) { - // neither user-provided path nor bundled deps found — surface a clear error + if (!uast4go_path || !fs.existsSync(uast4go_path)) { handleException( null, - `uast4go not found at ${uast4go_path}. Please set --uastSDKPath to the correct path or install the uast4go sdk under deps/uast4go/uast4go`, - `uast4go not found at ${uast4go_path}. Please set --uastSDKPath to the correct path or install the uast4go sdk under deps/uast4go/uast4go`, + `uast4go not found. Please set --uastSDKPath to the binary or deps directory, or install it under deps/uast4go/uast4go`, + `uast4go not found. Please set --uastSDKPath to the binary or deps directory, or install it under deps/uast4go/uast4go` ) process.exit(1) } @@ -57,30 +55,26 @@ function buildUASTGo(rootDir: any, options: Record) { uastFilePath = options.ASTFileOutput } - const command = - `${uast4go_path} ${isSingle}` + - ` -rootDir=${rootDir}` + - ` -output=${uastFilePath}` + const command = `${uast4go_path} ${isSingle} -rootDir=${rootDir} -output=${uastFilePath}` try { + // eslint-disable-next-line @typescript-eslint/naming-convention const options_for_command = { maxBuffer: 5 * 1024 * 1024 * 1024, // 5GB } ChildProcess.execSync(command, options_for_command) } catch (e) { - handleException( - e, - 'Error occurred in go-ast-builder.buildUAST', - 'Error occurred in go-ast-builder.buildUAST', - ) + // eslint-disable-next-line prettier/prettier + handleException(e, 'Error occurred in go-ast-builder.buildUAST', 'Error occurred in go-ast-builder.buildUAST') return null } } /** - * - * @param rootDir - * @param options + * 解析 Go 包(内部使用) + * @param rootDir - 根目录 + * @param options - 解析选项 + * @returns {Promise} 解析结果 */ async function parsePackage(rootDir: any, options: Record) { if (fs.existsSync(uastFilePath)) { @@ -92,11 +86,8 @@ async function parsePackage(rootDir: any, options: Record) { try { return await parseLargePackage(rootDir, options) } catch (e1) { - handleException( - e1, - `[go-ast-builder] 解析Go AST时发生错误`, - `[go-ast-builder] 解析Go AST时发生错误`, - ) + // eslint-disable-next-line prettier/prettier + handleException(e1, `[go-ast-builder] 解析Go AST时发生错误`, `[go-ast-builder] 解析Go AST时发生错误`) if (fs.existsSync(uastFilePath)) { deleteUAST() } @@ -106,16 +97,16 @@ async function parsePackage(rootDir: any, options: Record) { } /** - * - * @param rootDir - * @param options + * 解析大型 Go 包 + * @param rootDir - 根目录 + * @param options - 解析选项 + * @returns {Promise} 解析结果 */ async function parseLargePackage(rootDir: any, options: Record) { buildUASTGo(rootDir, options) const data = (await parseLargeJsonFile(uastFilePath)) as any[] - addParent(data) - addNodeHash(data) if (options.dumpAST || options.dumpAllAST) { + const { deleteParent } = require('../../../util/ast-util') deleteParent(data) } else if (fs.existsSync(uastFilePath)) { deleteUAST() @@ -124,17 +115,17 @@ async function parseLargePackage(rootDir: any, options: Record) { } /** - * - * @param rootDir - * @param options + * 解析单个 Go 包 + * @param rootDir - 根目录 + * @param options - 解析选项 + * @returns {any} 解析结果 */ function parseSinglePackage(rootDir: any, options: Record) { buildUASTGo(rootDir, options) const data = fs.readFileSync(uastFilePath, 'utf8') const obj = JSON.parse(data) - addParent(obj) - addNodeHash(obj) if (options.dumpAST || options.dumpAllAST) { + const { deleteParent } = require('../../../util/ast-util') deleteParent(obj) } else if (fs.existsSync(uastFilePath)) { deleteUAST() @@ -143,7 +134,7 @@ function parseSinglePackage(rootDir: any, options: Record) { } /** - * + * 删除 UAST 文件 */ function deleteUAST() { const stats = fs.statSync(uastFilePath) // 获取文件/目录状态 @@ -153,7 +144,7 @@ function deleteUAST() { handleException( err, `[go-ast-builder] 删除uast.json文件时发生错误`, - `[go-ast-builder] 删除uast.json文件时发生错误`, + `[go-ast-builder] 删除uast.json文件时发生错误` ) } }) @@ -189,44 +180,32 @@ function parseLargeJsonFile(filePath: string) { } /** - * - * @param obj - * @param parent + * 解析单个文件(统一接口) + * @param filepath - 文件路径 + * @param options - 解析选项 + * @returns {any} 解析结果(包含 packageInfo 和 moduleName) */ -function addParent(obj: any, parent?: any) { - if (!obj) return - if (Array.isArray(obj)) { - obj.forEach((o) => { - addParent(o, parent) - }) - } - if (typeof obj !== 'object' || Array.isArray(obj)) return - for (const key in obj) { - if (key === 'parent') continue - if (obj.hasOwnProperty(key)) { - const subObj = obj[key] - if (subObj?.type) { - subObj.parent = obj - addParent(subObj, subObj) - } else { - addParent(subObj, obj) - } - } +function parseSingleFile(filepath: string, options?: Record): any { + const opts = { ...options, single: true } + const result = parseSinglePackage(filepath, opts) + // 将数组格式 [packageInfo, moduleName] 转换为对象格式 { packageInfo, moduleName } + if (Array.isArray(result)) { + return { packageInfo: result[0], moduleName: result[1] } } + return result } /** - * - * @param rootDir - * @param options + * 解析项目(统一接口) + * @param rootDir - 项目根目录 + * @param options - 解析选项 + * @returns {Promise} 解析结果(包含 packageInfo 和 moduleName) */ -function parseSingleFileGo(rootDir: any, options: Record) { - options = options || {} - options.single = true - return parseSinglePackage(rootDir, options) +async function parseProject(rootDir: string, options?: Record): Promise { + return parsePackage(rootDir, options || {}) } module.exports = { - parsePackage, - parseSingleFile: parseSingleFileGo, + parseSingleFile, + parseProject, } diff --git a/src/engine/parser/java/java-ast-builder.ts b/src/engine/parser/java/java-ast-builder.ts index 7c1d38c4..5bbcfb78 100644 --- a/src/engine/parser/java/java-ast-builder.ts +++ b/src/engine/parser/java/java-ast-builder.ts @@ -1,3 +1,4 @@ +/* eslint-disable @typescript-eslint/no-require-imports */ const { Parser: UastParser, LanguageType } = require('@ant-yasa/uast-parser-java-js') const { handleException } = require('../../analyzer/common/exception-handler') @@ -9,9 +10,10 @@ interface ParseOptions { const uastParser = new UastParser() /** - * - * @param code - * @param options + * 解析 Java 代码 + * @param code - 源代码内容 + * @param options - 解析选项 + * @returns {any} 解析后的 AST */ function parseJava(code: string, options?: ParseOptions) { options = options || {} @@ -27,80 +29,30 @@ function parseJava(code: string, options?: ParseOptions) { return uastParser.parse(code, options) } -// class Environment { -// parent; -// scope; -// -// constructor(parent) { -// this.parent = parent; -// this.scope = new Map(); -// } -// -// resolveName(name) { -// return this.scope.get(name) || this.parent?.resolveName(name); -// } -// -// setName(name, node) { -// this.scope.set(name, node); -// } -// } -// -// function adjust(node, env) { -// if (!node) return; -// if (Array.isArray(node)) { -// return node.map(n => adjust(n)); -// } -// if (!node.type) return; -// switch (node.type) { -// case 'CompileUnit': -// adjust(node.body); -// break; -// case 'ClassDefinition': -// adjust(node.body); -// break; -// case 'FunctionDefinition': { -// const newEnv = new Environment(env); -// adjust(node.parameters, newEnv); -// adjust(node.body, newEnv); -// break; -// } -// case 'VariableDeclaration': { -// env.setName(node.id.name, node); -// break; -// } -// case 'MemberAccess': { -// const obj = node.object; -// if (obj.type === 'Identifier') { -// const n = env.resolveName(obj.name); -// if (!n) { -// n.object = UastSpec.memberAccess(UastSpec.thisExpression(), obj, false); -// } -// } -// } -// case 'Identifier': { -// if (env.resolveName(node.name)) { -// const prop = _.clone(node); -// node.type = 'MemberAccess'; -// node.object = UAST.thisExpression(); -// node.object.loc = node.loc; -// node.property = prop; -// } -// break; -// } -// case 'ScopedStatement': { -// adjust(node.body, new Environment(env)); -// break; -// } -// default: { -// for (const prop in node) { -// adjust(node[prop], env); -// } -// } -// } -// -// return node; -// } +/** + * 解析单个文件(统一接口) + * @param code - 源代码内容 + * @param options - 解析选项 + * @returns {any} 解析后的 AST(未处理后处理) + */ +function parseSingleFile(code: string, options?: ParseOptions): any { + return parseJava(code, options) +} + +/** + * 解析项目(统一接口) + * Java 是单文件语言,项目解析由 parser.ts 统一处理 + * @param _rootDir - 项目根目录(未使用) + * @param _options - 解析选项(未使用) + * @returns {Promise} 解析结果(空对象,表示没有解析结果) + */ +// eslint-disable-next-line @typescript-eslint/no-unused-vars +async function parseProject(_rootDir: string, _options?: ParseOptions): Promise { + // 返回空对象而不是 null,确保调用者可以安全地迭代 + return {} +} module.exports = { - parse: parseJava, + parseSingleFile, + parseProject, } diff --git a/src/engine/parser/javascript/js-ast-builder.ts b/src/engine/parser/javascript/js-ast-builder.ts index 24f000ff..8ae73f89 100644 --- a/src/engine/parser/javascript/js-ast-builder.ts +++ b/src/engine/parser/javascript/js-ast-builder.ts @@ -1,13 +1,22 @@ +/* eslint-disable @typescript-eslint/no-require-imports */ +/* eslint-disable @typescript-eslint/no-use-before-define */ +/* eslint-disable complexity */ +/* eslint-disable sonarjs/cognitive-complexity */ +/* eslint-disable sonarjs/max-switch-cases */ +/* eslint-disable max-lines */ const { Parser: UastParser } = require('@ant-yasa/uast-parser-java-js') const { Errors } = require('../../../util/error-code') const uastParser = new UastParser() +// eslint-disable-next-line @typescript-eslint/no-use-before-define let getUid!: () => number +let sourcefileJS: any /** - * - * @param loc + * 生成临时标识符 + * @param loc - 位置信息 + * @returns {any} 临时标识符节点 */ function getTmpIdentifier(loc: any) { return { @@ -27,14 +36,16 @@ function getTmpIdentifier(loc: any) { } /** - * - * @param pattern - * @param initId + * 处理对象模式 + * @param pattern - 对象模式节点 + * @param initId - 初始化标识符 + * @returns {any[]} 表达式数组 */ function processObjectPattern(pattern: any, initId: any) { const expressions: any[] = [] for (const prop of pattern.properties) { if (prop.type === 'ObjectProperty') { + // eslint-disable-next-line @typescript-eslint/naming-convention const sub_expr = processObjectProperty(prop, initId) if (Array.isArray(sub_expr)) { expressions.push(...sub_expr) @@ -54,15 +65,17 @@ function processObjectPattern(pattern: any, initId: any) { } /** - * - * @param pattern - * @param initId + * 处理数组模式 + * @param pattern - 数组模式节点 + * @param initId - 初始化标识符 + * @returns {any[]} 表达式数组 */ function processArrayPattern(pattern: any, initId: any) { const expressions: any[] = [] for (const i in pattern.elements) { const ele = pattern.elements[i] if (ele) { + // eslint-disable-next-line @typescript-eslint/naming-convention const sub_expr = processObjectProperty( { type: 'ObjectProperty', @@ -87,12 +100,14 @@ function processArrayPattern(pattern: any, initId: any) { } /** - * - * @param pattern - * @param initId + * 处理赋值模式 + * @param pattern - 赋值模式节点 + * @param initId - 初始化标识符 + * @returns {any} 变量声明节点 */ function processAssignmentPattern(pattern: any, initId: any) { const key = pattern.left + // eslint-disable-next-line @typescript-eslint/naming-convention const default_expr = pattern.right return { type: 'VariableDeclaration', @@ -109,9 +124,10 @@ function processAssignmentPattern(pattern: any, initId: any) { } /** - * - * @param pattern - * @param initId + * 处理模式类节点 + * @param pattern - 模式节点 + * @param initId - 初始化标识符 + * @returns {any} 转换后的节点 */ function processPatternLike(pattern: any, initId: any) { if (pattern.type === 'ObjectPattern') { @@ -127,9 +143,10 @@ function processPatternLike(pattern: any, initId: any) { } /** - * - * @param prop - * @param initId + * 处理对象属性 + * @param prop - 对象属性节点 + * @param initId - 初始化标识符 + * @returns {any} 转换后的节点 */ function processObjectProperty(prop: any, initId: any) { const { key, value } = prop @@ -157,9 +174,10 @@ function processObjectProperty(prop: any, initId: any) { /** * convert js AST nodes to Unified AST nodes - * @param ast - * @param node + * @param node - JavaScript AST 节点 + * @returns {any} 转换后的统一 AST 节点 */ +// eslint-disable-next-line sonarjs/max-switch-cases function convert2UAST(node: any): any { try { if (!node) return node @@ -258,13 +276,14 @@ function convert2UAST(node: any): any { return node } case 'PrivateName': { + // eslint-disable-next-line @typescript-eslint/naming-convention const private_node: any = convert2UAST(node.id) private_node.name = `#${private_node.name}` return private_node } case 'BinaryExpression': case 'LogicalExpression': { - node.type = 'BinaryOperation' + node.type = 'BinaryExpression' node.left = convert2UAST(node.left) node.right = convert2UAST(node.right) return node @@ -346,6 +365,7 @@ function convert2UAST(node: any): any { } case 'NewExpression': { node.expression = node.callee + // eslint-disable-next-line @typescript-eslint/naming-convention const callee_name = node.callee && node.callee.name node.typeName = node.typeName || callee_name delete node.callee @@ -402,6 +422,7 @@ function convert2UAST(node: any): any { break } case 'ObjectMethod': { + // eslint-disable-next-line @typescript-eslint/naming-convention const method_value = node node = { type: 'ObjectProperty', @@ -540,7 +561,7 @@ function convert2UAST(node: any): any { /** * put optional properties in extra._meta for concision of UAST - * @param node + * @param node - AST 节点 */ function assembleMeta(node: any) { node.loc = node.loc || {} @@ -566,11 +587,12 @@ function assembleMeta(node: any) { } /** - * - * @param exprs - * @param node + * 追加表达式到函数体 + * @param exprs - 表达式数组 + * @param node - 函数节点 */ function appendBody(exprs: any, node: any) { + // eslint-disable-next-line @typescript-eslint/naming-convention const origin_body = node.body if (origin_body.type === 'BlockStatement') { const stmts = origin_body.body @@ -584,17 +606,44 @@ function appendBody(exprs: any, node: any) { } } -let sourcefileJS: any - /** - * - * @param code - * @param options + * 解析 JavaScript 代码 + * @param code - 源代码内容 + * @param options - 解析选项 + * @returns {any} 解析后的 AST */ function parseJS(code: any, options: any) { return uastParser.parse(code, options) } +/** + * 解析单个文件(统一接口) + * @param code - 源代码内容 + * @param options - 解析选项(包含 sourcefile 或 filepath) + * @returns {any} 解析后的 AST(未处理后处理) + */ +function parseSingleFile(code: string, options?: any): any { + // JavaScript JSON 文件特殊处理:包装为 module.exports + const filepath = options?.sourcefile || options?.filepath + if (filepath && filepath.endsWith('.json')) { + code = `module.exports = ${code}` + } + return parseJS(code, options) +} + +/** + * 解析项目(统一接口) + * JavaScript 是单文件语言,项目解析由 parser.ts 统一处理 + * @param _rootDir - 项目根目录(未使用) + * @param _options - 解析选项(未使用) + * @returns {Promise} 解析结果 + */ +// eslint-disable-next-line @typescript-eslint/no-unused-vars +async function parseProject(_rootDir: string, _options?: any): Promise { + return null +} + module.exports = { - parse: parseJS, + parseSingleFile, + parseProject, } diff --git a/src/engine/parser/parser-core.ts b/src/engine/parser/parser-core.ts new file mode 100644 index 00000000..17506830 --- /dev/null +++ b/src/engine/parser/parser-core.ts @@ -0,0 +1,537 @@ +/** + * 解析器核心逻辑 + * 包含所有解析相关的函数,供 parser.ts 和 parser-worker.ts 使用 + */ + +const fs = require('fs-extra') +const path = require('path') +const AstUtil = require('../../util/ast-util') +const SourceLine = require('../analyzer/common/source-line') +const { Errors } = require('../../util/error-code') +const { addNodeHash } = require('../../util/ast-util') +const { md5 } = require('../../util/hash-util') +const logger = require('../../util/logger')(__filename) + +// 语言解析器配置接口 +interface LanguageParserConfig { + language: string | string[] + unit: 'file' | 'package' + supportsIncremental: boolean + filePatterns: string[] + parseSingleFile?: (code: string, options: Record) => any + parseProject?: (rootDir: string, options: Record) => Promise + needsSourcefile?: boolean + parseAsFiles?: boolean +} + +// 解析器缓存 +const parsers: Record) => any) | null> = { + java: null, + javascript: null, + js: null, + python: null, + golang: null, +} + +/** + * 获取语言解析器 + * @param {string} language - 语言标识 + * @returns {((code: string, options: Record) => any) | null} 解析器函数或 null + */ +function getParser(language: string): ((code: string, options: Record) => any) | null { + if (parsers[language]) { + return parsers[language] + } + + let parser = null + switch (language) { + case 'java': { + const JavaAstBuilder = require('./java/java-ast-builder') + parser = (c: string, opts: Record) => JavaAstBuilder.parseSingleFile(c, opts) + parsers.java = parser + break + } + case 'javascript': + case 'js': { + const JSAstBuilder = require('./javascript/js-ast-builder') + parser = (c: string, opts: Record) => + JSAstBuilder.parseSingleFile(c, { + sanity: opts.sanity, + sourcefile: opts.sourcefile, + }) + parsers.javascript = parser + parsers.js = parser + break + } + case 'python': { + const PythonParser = require('./python/python-ast-builder') + parser = (c: string, opts: Record) => PythonParser.parseSingleFile(c, opts) + parsers.python = parser + break + } + case 'golang': { + const GoParser = require('./golang/go-ast-builder') + parser = (_c: string, opts: Record) => { + if (!opts.sourcefile) { + throw new Error('Go single file parsing requires sourcefile in options') + } + return GoParser.parseSingleFile(opts.sourcefile, opts) + } + parsers.golang = parser + break + } + default: + throw new Error(`Unsupported language: ${language}`) + } + + return parser +} + +/** + * JSON.stringify 的 replacer 函数,用于跳过 parent 属性 + * @param {string} key - 属性键名 + * @param {any} value - 属性值 + * @returns {any} 如果 key 是 'parent' 则返回 undefined(跳过),否则返回原值 + */ +function skipParentReplacer(key: string, value: any): any { + if (key === 'parent') { + return undefined + } + return value +} + +/** + * 检查 AST 是否已经有有效的 nodehash(用于缓存优化) + * 需要验证 hash 是否在当前配置下仍然有效 + * @param {any} ast - AST 节点 + * @param {string} expectedSourcefile - 期望的 sourcefile + * @returns {boolean} 如果 AST 已有有效的 hash 则返回 true + */ +function hasValidNodeHash(ast: any, expectedSourcefile: string): boolean { + if (!ast || typeof ast !== 'object') return false + + // 检查根节点是否有 hash + if (!ast._meta?.nodehash) return false + + // 关键检查:验证 sourcefile 是否匹配 + // nodehash 的计算依赖于 loc.sourcefile(通过 maindirPrefix 影响 relateFilePath) + // 如果 sourcefile 不匹配,说明 hash 可能是在不同的配置下计算的,需要重新计算 + const actualSourcefile = ast.loc?.sourcefile || '' + + // sourcefile 必须匹配,且已有 hash,才能跳过重新计算 + // 注意:这里假设 maindirPrefix 在增量分析时不会变化 + // 如果 maindirPrefix 变化,会导致 hash 不一致,但这种情况应该很少见 + return actualSourcefile === expectedSourcefile +} + +/** + * AST 后处理:设置 sourcefile、添加 parent 指针、添加节点哈希 + * + * 重要:此函数会为 AST 添加 parent 属性 + * - annotateAST 会调用 adjustASTNode,为所有节点添加 parent 指针 + * - 无论是新解析的 AST 还是从缓存加载的 AST,都会添加 parent + * - 最终返回的 AST 包含完整的 parent 链,用于后续分析 + * + * @param {any} ast - AST 节点(可能没有 parent,如从缓存加载的) + * @param {any} code - 源代码内容 + * @param {Record} options - 解析选项 + * @param {boolean} [needsSourcefile] - 是否需要设置 sourcefile + * @param {boolean} [skipHashIfExists] - 如果 AST 已有 hash 且 sourcefile 匹配,是否跳过 hash 计算(用于缓存优化) + * @returns {any} 处理后的 AST(包含 parent 属性) + */ +function processAst( + ast: any, + code: any, + options: Record, + needsSourcefile?: boolean, + skipHashIfExists?: boolean +): any { + const shouldSetSourcefile = needsSourcefile !== false + + const fname = code != null ? SourceLine.storeCode(options?.sourcefile, code) : options?.sourcefile || '' + + if (shouldSetSourcefile) { + // annotateAST 会调用 adjustASTNode,为所有节点添加 parent 指针 + AstUtil.annotateAST(ast, options ? { sourcefile: fname } : null) + if (!ast.loc) ast.loc = {} + ast.loc.sourcefile = fname + } else { + // 即使不设置 sourcefile,也会添加 parent 指针 + AstUtil.annotateAST(ast, { skipSourcefile: true }) + } + + if (skipHashIfExists && hasValidNodeHash(ast, fname)) { + // hash 已存在且有效(sourcefile 匹配),跳过重新计算 + // 这样可以避免对缓存加载的 AST 重复计算 hash,显著提升性能 + } else { + addNodeHash(ast) + } + + return ast +} + +/** + * 后处理解析后的 AST + * @param {any} ast - AST 节点 + * @param {string | null} code - 源代码内容(可为 null) + * @param {Record} options - 解析选项 + * @param {LanguageParserConfig} config - 语言配置 + * @param {boolean} [skipHashIfExists] - 如果 AST 已有 hash 且 sourcefile 匹配,是否跳过 hash 计算(用于缓存优化) + * @returns {any} 处理后的 AST + */ +function processParsedAst( + ast: any, + code: string | null, + options: Record, + config: LanguageParserConfig, + skipHashIfExists?: boolean +): any { + if (!ast) { + return null + } + + if (config.unit === 'package') { + if (Array.isArray(ast)) { + const [packageInfo, moduleName] = ast + const processedPackageInfo = processAst(packageInfo, code, options, config.needsSourcefile, skipHashIfExists) + return { packageInfo: processedPackageInfo, moduleName } + } + if (ast && typeof ast === 'object' && 'packageInfo' in ast && 'moduleName' in ast) { + ast.packageInfo = processAst(ast.packageInfo, code, options, config.needsSourcefile, skipHashIfExists) + return ast + } + return processAst(ast, code, options, config.needsSourcefile, skipHashIfExists) + } + return processAst(ast, code, options, config.needsSourcefile, skipHashIfExists) +} + +/** + * 解析文件(同步版本) + * @param {string} filepath - 文件路径 + * @param {string} code - 源代码内容 + * @param {string} language - 语言标识 + * @param {Record} options - 解析选项 + * @param {{ unit: string; needsSourcefile?: boolean }} config - 配置对象 + * @param {string} config.unit - 分析单元类型 + * @param {boolean} [config.needsSourcefile] - 是否需要设置 sourcefile + * @returns {{ filepath: string; ast: any }} 解析结果 + */ +function parseFile( + filepath: string, + code: string, + language: string, + options: Record, + config: { unit: string; needsSourcefile?: boolean } +): { filepath: string; ast: any } { + // 获取解析器(使用缓存) + const parseSingleFile = getParser(language) + + if (!parseSingleFile) { + throw new Error(`Language ${language} does not support parseSingleFile`) + } + + // 解析文件 + const parseResult = parseSingleFile(code, options) + + if (!parseResult) { + Errors.ParseError(`Failed to parse file: ${filepath}`) + return { filepath, ast: null } + } + + // 后处理 AST + const processedAst = processParsedAst(parseResult, code, options, config as LanguageParserConfig) + + return { filepath, ast: processedAst } +} + +/** + * 从缓存加载 AST(核心能力,不做路径计算) + * + * 注意:从缓存加载的 AST 不包含 parent 属性(因为保存时跳过了) + * - 加载后需要通过 processParsedAst 重新添加 parent + * - processParsedAst 会调用 annotateAST,为所有节点添加 parent 指针 + * + * @param {string} jsonFilePath - 缓存文件的完整路径 + * @returns {Promise} 解析后的 AST(不包含 parent),失败返回 null + */ +async function loadAstFromCache(jsonFilePath: string): Promise { + try { + const astContent = await fs.promises.readFile(jsonFilePath, 'utf8') + // 加载的 AST 不包含 parent(因为保存时跳过了) + return JSON.parse(astContent) + } catch (error) { + logger.warn(`Failed to load AST cache from ${jsonFilePath}: ${(error as Error).message}`) + return null + } +} + +/** + * 保存 AST 到缓存(核心能力,不做路径计算) + * + * 重要:保存到文件的 AST 不包含 parent 属性 + * - parent 是循环引用,无法序列化到 JSON + * - 使用 skipParentReplacer 在序列化时跳过 parent 属性 + * - 原 AST 对象不会被修改(仍然保留 parent,用于返回给用户) + * - 从缓存加载后,会通过 processParsedAst 重新添加 parent + * + * @param {any} ast - AST 节点(可能包含 parent 属性,但保存时会跳过) + * @param {string} jsonFilePath - 缓存文件的完整路径 + * @returns {Promise} 是否保存成功 + */ +async function saveAstToCache(ast: any, jsonFilePath: string): Promise { + return new Promise((resolve) => { + try { + // 确保目录存在 + const cacheDir = path.dirname(jsonFilePath) + if (!fs.existsSync(cacheDir)) { + fs.mkdirSync(cacheDir, { recursive: true }) + } + + // 使用 skipParentReplacer 跳过 parent 属性 + // 序列化时跳过 parent,避免循环引用问题和减少文件大小 + // 原 AST 对象保持不变(仍然有 parent,用于返回给用户) + const astSerialized = JSON.stringify(ast, skipParentReplacer) + fs.writeFile(jsonFilePath, astSerialized, 'utf8', (err: NodeJS.ErrnoException | null) => { + if (err) { + logger.warn(`Failed to write AST cache to ${jsonFilePath}: ${err.message}`) + resolve(false) + return + } + resolve(true) + }) + } catch (error) { + logger.warn(`Failed to save AST cache to ${jsonFilePath}: ${(error as Error).message}`) + resolve(false) + } + }) +} + +/** + * 从 filePatterns 中提取文件扩展名 + * @param {string[]} filePatterns - 文件匹配模式数组 + * @returns {string} 文件扩展名(如 '.go'),如果无法提取则返回空字符串 + */ +function extractFileExtension(filePatterns: string[]): string { + if (!filePatterns || filePatterns.length === 0) { + return '' + } + + const firstPattern = filePatterns.find((pattern) => !pattern.startsWith('!')) + if (!firstPattern) { + return '' + } + + const match = firstPattern.match(/\.\(([^)]+)\)|\.([a-zA-Z0-9]+)(?:\s|$|,|})/) + if (match) { + if (match[1]) { + const extensions = match[1].split(',').map((ext) => ext.trim()) + return `.${extensions[0]}` + } + if (match[2]) { + return `.${match[2]}` + } + } + + return '' +} + +/** + * 递归提取 packageInfo 中所有文件的 AST 并写入文件 + * @param {any} packageInfo - package 类型的解析结果(包含 files 和 subs) + * @param {string} reportDir - 输出目录 + * @param {LanguageParserConfig} config - 语言配置 + * @returns {string[]} AST 文件列表(文件名) + */ +function extractAndDumpPackageAst(packageInfo: any, reportDir: string, config: LanguageParserConfig): string[] { + const astFileList: string[] = [] + + if (!packageInfo || typeof packageInfo !== 'object') { + return astFileList + } + + const fileExtension = extractFileExtension(config.filePatterns) + if (!fileExtension) { + logger.warn(`Cannot extract file extension from filePatterns for language: ${config.language}`) + return astFileList + } + + /** + * 深度搜索并提取 AST + * @param {any} obj - 要搜索的对象 + */ + function deepSearch(obj: any) { + if (!obj || typeof obj !== 'object') { + return + } + + if (Array.isArray(obj)) { + obj.forEach((item) => deepSearch(item)) + return + } + + for (const [key, value] of Object.entries(obj)) { + if (typeof key === 'string' && key.endsWith(fileExtension) && value && typeof value === 'object') { + const { node } = value as any + if (node && typeof node === 'object' && node.type === 'CompileUnit') { + const fileName = `${md5(key)}.json` + const astFilePath = path.join(reportDir, fileName) + fs.writeFileSync(astFilePath, JSON.stringify(node, skipParentReplacer)) + astFileList.push(fileName) + } + continue + } + + deepSearch(value) + } + } + + deepSearch(packageInfo) + return astFileList +} + +/** + * 从 package 信息中递归提取 AST + * @param {any} packageInfo - package 信息对象 + * @param {Array<{ ast: any; filename: string }>} astList - AST 列表(用于收集结果) + */ +function extractFromPackage(packageInfo: any, astList: Array<{ ast: any; filename: string }>): void { + if (packageInfo.files) { + for (const [filename, fileAst] of Object.entries(packageInfo.files)) { + astList.push({ ast: fileAst, filename }) + } + } + if (packageInfo.subs) { + // 与 master 版本保持一致,使用 Object.values() + for (const subPackage of Object.values(packageInfo.subs)) { + extractFromPackage(subPackage, astList) + } + } +} + +/** + * 处理项目 AST:为所有 AST 设置 sourcefile、添加 parent 指针和节点哈希(核心编译逻辑) + * @param {any} result - 解析结果 + * @param {LanguageParserConfig} config - 语言配置 + * @param {Record} options - 解析选项 + * @param {Record} sourceCodeCache - 源代码缓存(必须提供,包含所有需要的文件内容) + */ +function processProjectAst( + result: any, + config: LanguageParserConfig, + options: Record, + sourceCodeCache: Record +): void { + const astList: Array<{ ast: any; filename: string }> = [] + + if (config.unit === 'package') { + if (result && result.packageInfo) { + extractFromPackage(result.packageInfo, astList) + } + } else if (config.unit === 'file') { + if (result && typeof result === 'object' && !Array.isArray(result)) { + for (const [filename, ast] of Object.entries(result)) { + astList.push({ ast, filename }) + } + } + } else { + astList.push({ ast: result, filename: '' }) + } + + for (const { ast, filename } of astList) { + const sourceCode = sourceCodeCache[filename] || null + processParsedAst(ast, sourceCode, { sourcefile: filename, ...options }, config) + } +} + +/** + * 导出所有 AST 到文件 + * @param {any} results - 解析结果 + * @param {string} reportDir - 输出目录 + * @param {LanguageParserConfig} config - 语言配置 + * @returns {Promise} + */ +async function dumpAllAST(results: any, reportDir: string, config: LanguageParserConfig): Promise { + const UAST_JSON = './uast.json' + + // 确保 reportDir 存在(不删除,保留现有内容) + if (!fs.existsSync(reportDir)) { + fs.mkdirSync(reportDir, { recursive: true }) + } + + const astFileList: string[] = [] + + if (config.unit === 'file') { + if (results && typeof results === 'object' && !Array.isArray(results)) { + for (const [filename, ast] of Object.entries(results)) { + const fileName = `${md5(filename)}.json` + const astFilePath = path.join(reportDir, fileName) + fs.writeFileSync(astFilePath, JSON.stringify(ast, skipParentReplacer)) + astFileList.push(fileName) + } + } + } else if (config.unit === 'package') { + if (results && results.packageInfo) { + const packageAstFiles = extractAndDumpPackageAst(results.packageInfo, reportDir, config) + astFileList.push(...packageAstFiles) + } + + if (fs.existsSync(UAST_JSON)) { + try { + const uastFile = fs.statSync(UAST_JSON) + if (uastFile.isFile()) { + fs.unlinkSync(UAST_JSON) + } + } catch (err) { + // Ignore deletion errors + } + } + } + + // 生成 astList.json + const astListPath = path.join(reportDir, 'astList.json') + fs.writeFileSync(astListPath, JSON.stringify(astFileList, null, 2)) +} + +/** + * 只做原始 parse,不含 processAst(annotateAST/addNodeHash) + * 供子进程使用,主线程收到结果后再补 processAst + * @param {string} filepath - 文件路径 + * @param {string} code - 源代码内容 + * @param {string} language - 语言标识 + * @param {Record} options - 解析选项 + * @param {{ unit: string; needsSourcefile?: boolean }} config - 配置对象 + * @returns {{ filepath: string; ast: any }} 原始解析结果(未处理 parent/hash) + */ +function parseFileRaw( + filepath: string, + code: string, + language: string, + options: Record, + config: { unit: string; needsSourcefile?: boolean } +): { filepath: string; ast: any } { + const parseSingleFile = getParser(language) + + if (!parseSingleFile) { + throw new Error(`Language ${language} does not support parseSingleFile`) + } + + const parseResult = parseSingleFile(code, options) + + if (!parseResult) { + Errors.ParseError(`Failed to parse file: ${filepath}`) + return { filepath, ast: null } + } + + return { filepath, ast: parseResult } +} + +module.exports = { + parseFile, + parseFileRaw, + getParser, + processParsedAst, + processProjectAst, + loadAstFromCache, + saveAstToCache, + dumpAllAST, +} diff --git a/src/engine/parser/parser-worker.ts b/src/engine/parser/parser-worker.ts new file mode 100644 index 00000000..f8857919 --- /dev/null +++ b/src/engine/parser/parser-worker.ts @@ -0,0 +1,113 @@ +/** + * 子进程脚本:在独立进程中解析文件(只做原始 parse,不含 processAst) + * 子进程退出后 OS 立即回收内存,解决 worker_threads 共享 RSS 不释放问题 + */ + +// 类型定义 +interface ParseTask { + filepath: string + content: string + language: string + options: Record + config: { + unit: string + needsSourcefile?: boolean + maindirPrefix?: string + } +} + +interface WorkerMessage { + type: 'parse' + task: ParseTask + taskId: number +} + +interface WorkerResponse { + taskId: number + success: boolean + result?: any + error?: string + workTime?: number + messageTime?: number +} + +const { parseFile: parseFileCore } = require('./parser-core') +const config = require('../../config') + +/** + * 原地删除 AST 所有节点的 parent 属性,避免 IPC JSON 序列化循环引用 + */ +function deleteParent(node: any, visited = new Set()): void { + if (!node || typeof node !== 'object' || visited.has(node)) return + visited.add(node) + delete node.parent + for (const key of Object.keys(node)) { + deleteParent(node[key], visited) + } +} + +/** + * 处理解析任务(完整 parse + processAst,发送前删掉 parent 避免循环引用) + */ +async function processParseTask(task: ParseTask): Promise<{ filepath: string; ast: any; error?: string }> { + if (task.config.maindirPrefix !== undefined) { + config.maindirPrefix = task.config.maindirPrefix + } + try { + const result = parseFileCore(task.filepath, task.content, task.language, task.options, task.config) + deleteParent(result.ast) + return result + } catch (error) { + return { + filepath: task.filepath, + ast: null, + error: error instanceof Error ? error.message : String(error), + } + } +} + +// 主进程断开 IPC 时立即退出,防止子进程泄漏 +process.on('disconnect', () => process.exit(0)) + +// 监听主进程消息 +process.on('message', async (message: WorkerMessage) => { + const messageReceiveTime = Date.now() + let messageSendTime = 0 + let workStartTime = 0 + let workEndTime = 0 + + try { + let result + + if (message.type === 'parse') { + workStartTime = Date.now() + result = await processParseTask(message.task) + workEndTime = Date.now() + } else { + throw new Error(`Unknown message type: ${message.type}`) + } + + messageSendTime = Date.now() + const workTime = workEndTime - workStartTime + const messageTime = messageSendTime - messageReceiveTime + const validatedWorkTime = workTime > 0 && workTime < 10000 ? workTime : 1 + + process.send!({ + taskId: message.taskId, + success: true, + result, + workTime: validatedWorkTime, + messageTime, + } as WorkerResponse) + } catch (error) { + messageSendTime = Date.now() + const messageTime = messageSendTime - messageReceiveTime + + process.send!({ + taskId: message.taskId, + success: false, + error: error instanceof Error ? error.message : String(error), + messageTime, + } as WorkerResponse) + } +}) diff --git a/src/engine/parser/parser.ts b/src/engine/parser/parser.ts new file mode 100644 index 00000000..9ffa19c9 --- /dev/null +++ b/src/engine/parser/parser.ts @@ -0,0 +1,1392 @@ +/* eslint-disable max-classes-per-file */ +/* eslint-disable complexity */ +const fs = require('fs-extra') +const path = require('path') +const globby = require('fast-glob') +const { fork } = require('child_process') +const os = require('os') +const FileUtil = require('../../util/file-util') +const { md5 } = require('../../util/hash-util') +const Config = require('../../config') +const logger = require('../../util/logger')(__filename) +const { performanceTracker } = require('../../util/performance-tracker') +const { yasaLog } = require('../../util/format-util') +const { + parseFile: parseFileCore, + processParsedAst: processParsedAstCore, + processProjectAst: processProjectAstCore, + loadAstFromCache: loadAstFromCacheCore, + saveAstToCache: saveAstToCacheCore, + dumpAllAST: dumpAllASTCore, +} = require('./parser-core') +const SourceLine = require('../analyzer/common/source-line') + +// ===================== 常量定义 ===================== +const PREPROCESS_PARSE_CODE_STAGE = 'preProcess.parseCode' +const CPU_COUNT = os.cpus().length +const DEFAULT_WORKER_COUNT = Math.min(Math.ceil(CPU_COUNT * 0.4), 16) +const MAX_CONCURRENCY = Math.max(CPU_COUNT, 16) * 2 + +// ================ 语言解析器配置接口 ================ + +/** + * 语言解析器配置接口 + */ +interface LanguageParserConfig { + /** 语言标识:'java' 或 ['js', 'javascript'] */ + language: string | string[] + /** 分析单元类型 */ + unit: 'file' | 'package' + /** 是否支持增量解析 */ + supportsIncremental: boolean + /** 文件匹配模式,使用 glob 模式 */ + filePatterns: string[] + /** 单文件解析回调 */ + parseSingleFile?: (code: string, options: Record) => any + /** 项目解析回调 */ + parseProject?: (rootDir: string, options: Record) => Promise + + /** + * 是否需要设置 loc.sourcefile(默认 true) + * - false: 外部工具已设置 sourcefile,不需要覆盖(如 Go) + * - true: 需要设置 loc.sourcefile(如 Java/JS/Python) + */ + needsSourcefile?: boolean + + /** + * 是否按文件逐个解析(默认 true) + * - true: 按文件逐个解析(如 Java/JS,使用 parseProjectAsFiles) + * - false: 直接解析整个项目,返回文件映射需要转换(如 Python) + */ + parseAsFiles?: boolean +} + +// =================== 解析器注册表 =================== + +/** + * 解析器注册表 + */ +class ParserRegistry { + private parsers: Map = new Map() + + /** + * 注册语言解析器 + * @param config - 语言解析器配置 + */ + register(config: LanguageParserConfig): void { + const languages = Array.isArray(config.language) ? config.language : [config.language] + for (const lang of languages) { + this.parsers.set(lang, config) + } + } + + /** + * 获取语言配置 + * @param language - 语言标识 + * @returns {LanguageParserConfig | undefined} 语言配置,如果不存在则返回 undefined + */ + get(language: string): LanguageParserConfig | undefined { + return this.parsers.get(language) + } + + /** + * 检查语言是否支持增量 + * @param language - 语言标识 + * @returns {boolean} 是否支持增量解析 + */ + supportsIncremental(language: string): boolean { + const config = this.get(language) + return config ? config.supportsIncremental : false + } + + /** + * 获取所有已注册的语言 + * @returns {string[]} 所有已注册的语言标识数组 + */ + getRegisteredLanguages(): string[] { + return Array.from(this.parsers.keys()) + } +} + +// =================== Worker Pool 管理 =================== + +/** + * 智能 Worker 路径解析:使用 child_process.fork 启动子进程 + * 子进程退出后 OS 立即回收内存,解决 worker_threads 共享 RSS 不释放问题 + * @param {string} workerName - Worker 文件名 + * @returns {any} 子进程实例 + */ +function loadWorker(workerName: string): any { + const isCompiled = __dirname.includes('/dist/') || __dirname.includes('\\dist\\') + // pkg 打包后 execPath 指向二进制自身,不支持 execArgv 中的 V8 flag + const isPkg = !!(process as any).pkg + + if (isCompiled) { + const workerPath = path.join(__dirname, `${workerName}.js`) + if (fs.existsSync(workerPath)) { + return fork(path.resolve(workerPath), [], isPkg + ? { execArgv: [], env: { ...process.env, NODE_OPTIONS: '--max-old-space-size=2048' } } + : { execArgv: ['--max-old-space-size=2048'] }) + } + throw new Error(`Worker file not found: ${workerPath}`) + } + + // 开发环境:使用 tsx 加载 .ts + const workerTsPath = path.join(__dirname, `${workerName}.ts`) + if (fs.existsSync(workerTsPath)) { + let tsxModulePath: string | null = null + try { + tsxModulePath = require.resolve('tsx/cjs') + } catch (error) { + const projectRoot = path.resolve(__dirname, '../../..') + const tsxPath = path.join(projectRoot, 'node_modules', 'tsx', 'cjs', 'index.mjs') + if (fs.existsSync(tsxPath)) { + tsxModulePath = tsxPath + } + } + + if (tsxModulePath) { + return fork(workerTsPath, [], { + execArgv: ['--max-old-space-size=2048', '-r', 'tsx/cjs'], + }) + } + throw new Error( + `Cannot load TypeScript worker: tsx module not found. Please install tsx (npm install tsx) or compile TypeScript first (npx tsc).` + ) + } + + throw new Error(`Worker file not found: ${workerTsPath}`) +} + +/** + * Worker Pool 类:管理多个子进程 + */ +class WorkerPool { + private workers: Array<{ worker: any; busy: boolean; id: number }> = [] + + private taskQueue: Array<{ type: string; task: any; taskId: number; resolve: any; reject: any }> = [] + + private taskIdCounter = 0 + + private _maxWorkers: number + + private stats = { + totalTasks: 0, + totalWorkTime: 0, + workerStartTime: 0, + workerWorkTimes: new Map(), + } + + private lastWorkerIndex: number = 0 + + private pendingTasks: Map = new Map() + + private terminated: boolean = false + + /** 子进程 OOM 计数 */ + oomCount: number = 0 + + /** 子进程连续失败计数,超过阈值停止重建 */ + private consecutiveFailures: number = 0 + private static readonly MAX_CONSECUTIVE_FAILURES = 3 + + /** + * 构造函数 + * @param {number} [maxWorkers] - 最大 worker 数量 + */ + constructor(maxWorkers?: number) { + this._maxWorkers = maxWorkers || DEFAULT_WORKER_COUNT + + if (this._maxWorkers === 0) { + return + } + + const startTime = Date.now() + for (let i = 0; i < this._maxWorkers; i++) { + this.createWorker(i) + } + this.stats.workerStartTime = Date.now() - startTime + } + + /** + * 创建子进程 + * @param {number} id - Worker ID + */ + private createWorker(id: number): void { + try { + const worker = loadWorker('parser-worker') + + worker.on('message', (message: any) => { + this.handleWorkerMessage(id, message) + }) + + worker.on('error', (error: Error) => { + console.error(`Worker ${id} error:`, error) + if (error.message.includes('Cannot find module') || error.message.includes('ERR_MODULE_NOT_FOUND')) { + console.error(`Worker script not found or cannot be loaded: parser-worker`) + console.error( + 'Falling back to single-threaded mode. Please compile TypeScript first or use --disable-workers flag.' + ) + if (this.workers[id]) { + this.workers[id].busy = false + } + return + } + if (this.workers[id] && this.workers[id].worker) { + this.workers[id].worker.kill() + this.createWorker(id) + } + }) + + worker.on('exit', (code: number) => { + if (this.terminated) { + return + } + if (code !== 0) { + console.warn(`Worker ${id} exited with code ${code}`) + this.oomCount++ + this.consecutiveFailures++ + // 子进程非正常退出,reject 该 worker 所有 pending 任务 + for (const [taskId, task] of this.pendingTasks.entries()) { + if (this.workers[id]?.busy) { + this.pendingTasks.delete(taskId) + task.reject(new Error(`Worker ${id} exited with code ${code} (possible OOM)`)) + } + } + if (this.workers[id]) { + this.workers[id].busy = false + } + if (this.consecutiveFailures >= WorkerPool.MAX_CONSECUTIVE_FAILURES) { + console.error(`Worker consecutive failures reached ${this.consecutiveFailures}, stopping worker recreation`) + return + } + this.createWorker(id) + } + }) + + if (this.workers[id]) { + this.workers[id] = { worker, busy: false, id } + } else { + this.workers.push({ worker, busy: false, id }) + } + } catch (error) { + console.error(`Failed to create worker ${id}:`, error) + } + } + + /** + * 处理 worker 消息 + * @param {number} workerId - Worker ID + * @param {any} message - 消息 + */ + private handleWorkerMessage(workerId: number, message: any): void { + const worker = this.workers[workerId] + if (!worker) return + + const task = this.pendingTasks.get(message.taskId) + if (!task) return + + this.consecutiveFailures = 0 + + this.pendingTasks.delete(message.taskId) + worker.busy = false + + if (message.workTime !== undefined && message.workTime > 0) { + this.stats.totalWorkTime += message.workTime + const currentWorkerTime = this.stats.workerWorkTimes.get(workerId) || 0 + this.stats.workerWorkTimes.set(workerId, currentWorkerTime + message.workTime) + } + + if (message.success) { + task.resolve(message.result) + } else { + task.reject(new Error(message.error || 'Unknown error')) + } + + this.processNextTask() + } + + /** + * 处理下一个任务 + */ + private processNextTask(): void { + if (this.taskQueue.length === 0) return + + const idleWorkers = this.workers.filter((w) => !w.busy) + if (idleWorkers.length === 0) return + + const selectedWorker = idleWorkers[this.lastWorkerIndex % idleWorkers.length] + this.lastWorkerIndex = (this.lastWorkerIndex + 1) % idleWorkers.length + const idleWorker = selectedWorker + + const task = this.taskQueue.shift() + if (!task) return + + idleWorker.busy = true + this.pendingTasks.set(task.taskId, task) + + idleWorker.worker.send({ + type: task.type, + task: task.task, + taskId: task.taskId, + }) + } + + /** + * 提交任务 + * @param {string} type - 任务类型 + * @param {any} task - 任务数据 + * @returns {Promise} 任务结果 + */ + async submitTask(type: string, task: any): Promise { + return new Promise((resolve, reject) => { + const taskId = ++this.taskIdCounter + + this.stats.totalTasks++ + + const taskItem = { + type, + task, + taskId, + resolve, + reject, + } + + this.taskQueue.push(taskItem) + this.processNextTask() + }) + } + + /** + * 终止所有 worker + */ + async terminate(): Promise { + if (this.terminated) return + + this.terminated = true + for (const [index, w] of this.workers.entries()) { + if (w.worker) { + try { + w.worker.removeAllListeners('message') + w.worker.removeAllListeners('error') + w.worker.removeAllListeners('exit') + if (w.worker.connected) w.worker.disconnect() + w.worker.kill() + } catch (error) { + logger.warn(`Failed to terminate worker ${index}:`, error) + } + } + } + this.workers = [] + this.taskQueue = [] + this.pendingTasks.clear() + } + + /** + * 获取活跃任务数 + * @returns {number} 活跃任务数 + */ + getActiveTaskCount(): number { + return this.taskQueue.length + this.workers.filter((w) => w.busy).length + } + + /** + * 获取最大 worker 数 + * @returns {number} 最大 worker 数 + */ + getMaxWorkers(): number { + return this._maxWorkers + } + + /** + * 获取统计信息 + * @returns {any} 统计信息 + */ + getStats() { + const workerStats: { [key: number]: number } = {} + for (let i = 0; i < this._maxWorkers; i++) { + workerStats[i] = this.stats.workerWorkTimes.get(i) || 0 + } + + return { + workerCount: this._maxWorkers, + totalTasks: this.stats.totalTasks, + workerStartTime: this.stats.workerStartTime, + totalWorkTime: this.stats.totalWorkTime, + workerWorkTimes: workerStats, + avgWorkTime: this.stats.totalTasks > 0 ? this.stats.totalWorkTime / this.stats.totalTasks : 0, + } + } + + /** + * 重置统计信息 + */ + resetStats(): void { + this.stats = { + totalTasks: 0, + totalWorkTime: 0, + workerStartTime: this.stats.workerStartTime, + workerWorkTimes: new Map(), + } + } +} + +// =================== 缓存列表管理 =================== + +/** + * 获取缓存目录路径 + * @returns {string} 缓存目录路径 + */ +function getCacheDir(): string { + let outputDir = Config.intermediateDir + if (!outputDir) { + outputDir = Config.reportDir || './report/' + if (!path.isAbsolute(outputDir)) { + outputDir = path.resolve(process.cwd(), outputDir) + } + outputDir = path.join(outputDir, 'ast-output') + } else if (!path.isAbsolute(outputDir)) { + outputDir = path.resolve(process.cwd(), outputDir) + } + return outputDir +} + +/** + * 获取文件相对于源目录的相对路径 + * @param {string} filename - 文件路径 + * @returns {string} 相对路径 + */ +function getRelativePath(filename: string): string { + const sourceDir = Config.maindir || '' + if (!sourceDir || !filename) { + return filename + } + const normalizedSource = path.normalize(sourceDir).replace(/\\/g, '/') + const normalizedFile = path.normalize(filename).replace(/\\/g, '/') + if (normalizedFile.startsWith(normalizedSource)) { + let relative = normalizedFile.substring(normalizedSource.length) + if (relative.startsWith('/')) { + relative = relative.substring(1) + } + return relative + } + return filename +} + +/** + * 加载缓存列表 + * @returns {Promise>} 缓存列表的 Map + */ +async function loadCacheList(): Promise> { + return new Promise((resolve) => { + const cacheDir = getCacheDir() + const listPath = path.join(cacheDir, 'ast-cache-list.json') + + fs.readFile(listPath, 'utf8', (err: NodeJS.ErrnoException | null, content: string) => { + if (err) { + resolve(new Map()) + return + } + + try { + const listData = JSON.parse(content) + const cacheMap = new Map() + + if (Array.isArray(listData)) { + for (const item of listData) { + if (item.path && item.jsonFile && item.crc) { + cacheMap.set(item.path, { + jsonFile: item.jsonFile, + crc: item.crc, + time: item.time, + }) + } + } + } + + resolve(cacheMap) + } catch (error) { + logger.warn(`Failed to parse cache list: ${(error as Error).message}`) + resolve(new Map()) + } + }) + }) +} + +// ================= 统一的解析器基类 ================= + +/** + * 统一的解析器基类 + */ +class BaseParser { + protected registry: ParserRegistry + + private workerPool: any = null + + private useWorkers: boolean = true // 是否使用 worker 模式 + + /** + * 构造函数,初始化解析器注册表并注册默认解析器 + * Worker pool 将在第一次使用时创建(延迟初始化) + */ + constructor() { + this.registry = new ParserRegistry() + this.registerDefaultParsers() + } + + /** + * 获取或创建 Worker Pool + * @returns {any} Worker Pool 实例 + */ + private getWorkerPool(): any { + // eslint-disable-next-line sonarjs/no-duplicate-string + const SINGLE_THREADED_FALLBACK_MSG = 'falling back to single-threaded mode' + if (!this.workerPool && this.useWorkers) { + try { + // 检查 worker 文件是否存在(支持 .ts 和 .js) + // __dirname 已经是 src/engine/parser,检查 .ts(开发环境)或 .js(生产环境) + const workerTsPath = path.join(__dirname, 'parser-worker.ts') + const workerJsPath = path.join(__dirname, 'parser-worker.js') + + if (!fs.existsSync(workerTsPath) && !fs.existsSync(workerJsPath)) { + logger.warn(`Worker script not found at ${workerTsPath} or ${workerJsPath}, ${SINGLE_THREADED_FALLBACK_MSG}`) + this.useWorkers = false + return null + } + + // 从配置读取 workerCount:0表示自动计算,>0表示使用设置的值 + const workerCount = Config.workerCount || 0 + const maxWorkers = workerCount > 0 ? workerCount : undefined + this.workerPool = new WorkerPool(maxWorkers) + + const maxWorkersValue = this.workerPool.getMaxWorkers() + + let WORKER_INIT_MESSAGE: string + if (workerCount > 0) { + // 手动设置worker数量 + WORKER_INIT_MESSAGE = `Using ${maxWorkersValue} workers (manually configured)` + } else { + // 自动计算worker数量 + WORKER_INIT_MESSAGE = `Auto-calculated ${maxWorkersValue} workers from ${CPU_COUNT} CPU cores (min(${CPU_COUNT}*0.4,16) = ${maxWorkersValue})` + } + yasaLog(WORKER_INIT_MESSAGE, PREPROCESS_PARSE_CODE_STAGE) + } catch (error) { + logger.warn(`Failed to create worker pool: ${(error as Error).message}, ${SINGLE_THREADED_FALLBACK_MSG}`) + this.useWorkers = false + this.workerPool = null + } + } + return this.workerPool + } + + /** + * 清理 Worker Pool(私有方法) + */ + private async cleanupWorkerPool(): Promise { + if (this.workerPool) { + try { + await this.workerPool.terminate() + this.workerPool = null + } catch (error) { + logger.warn(`Failed to cleanup worker pool: ${(error as Error).message}`) + } + } + } + + /** + * 清理 Worker Pool(公开方法,供外部调用) + */ + async cleanup(): Promise { + await this.cleanupWorkerPool() + } + + /** + * 注册默认的语言解析器(Java, JavaScript, Python, Go) + */ + protected registerDefaultParsers(): void { + // 注册 Java 解析器 + this.registry.register({ + language: 'java', + unit: 'file', + supportsIncremental: true, + parseAsFiles: true, + filePatterns: ['**/*.java', '!target/**', '!**/src/test/**'], + parseSingleFile: (code, options) => { + const JavaAstBuilder = require('./java/java-ast-builder') + return JavaAstBuilder.parseSingleFile(code, options) + }, + parseProject: async (rootDir, options) => { + const JavaAstBuilder = require('./java/java-ast-builder') + return JavaAstBuilder.parseProject(rootDir, options) + }, + needsSourcefile: true, + }) + + // 注册 JavaScript 解析器(支持多个别名:javascript, js) + this.registry.register({ + language: ['javascript', 'js'], + unit: 'file', + supportsIncremental: true, + parseAsFiles: true, + filePatterns: [ + '**/*.(js|ts|mjs|cjs)', + '!**/*.test.(js|ts|mjs|cjs|jsx)', + '!**/node_modules', + '!web', + '!**/public/**', + '!**/*.d.ts', + '!**/*.d.js', + ], + parseSingleFile: (code, options) => { + const JSAstBuilder = require('./javascript/js-ast-builder') + return JSAstBuilder.parseSingleFile(code, { + sanity: options.sanity, + sourcefile: options.sourcefile, + }) + }, + parseProject: async (rootDir, options) => { + const JSAstBuilder = require('./javascript/js-ast-builder') + return JSAstBuilder.parseProject(rootDir, options) + }, + needsSourcefile: true, + }) + + // 注册 Python 解析器 + this.registry.register({ + language: 'python', + unit: 'file', + supportsIncremental: false, + parseAsFiles: false, + filePatterns: ['**/*.(py)', '!**/.venv/**', '!**/vendor/**', '!**/node_modules/**', '!**/site-packages/**'], + parseSingleFile: (code, options) => { + const PythonParser = require('./python/python-ast-builder') + return PythonParser.parseSingleFile(code, options) + }, + parseProject: async (rootDir, options) => { + const PythonParser = require('./python/python-ast-builder') + return PythonParser.parseProject(rootDir, options) + }, + needsSourcefile: true, + }) + + // 注册 Go 解析器 + this.registry.register({ + language: 'golang', + unit: 'package', + supportsIncremental: false, + filePatterns: ['**/*.(go)'], + parseSingleFile: (code, options) => { + const GoParser = require('./golang/go-ast-builder') + const filepath = options.sourcefile + if (!filepath) { + throw new Error('Go single file parsing requires sourcefile in options') + } + return GoParser.parseSingleFile(filepath, options) + }, + parseProject: async (rootDir, options) => { + const GoParser = require('./golang/go-ast-builder') + return GoParser.parseProject(rootDir, options) + }, + needsSourcefile: false, + }) + } + + /** + * 解析单个文件(用户操作接口) + * @param {string} filepath - 文件路径 + * @param {Record} options - 解析选项,必须包含 language + * @param {string} options.language - 语言标识(必填) + * @param {Map} [sourceCodeCache] - 可选的源代码缓存,如果提供则优先从缓存获取,读取后自动填充 + * @returns {any} 解析后的 AST + */ + parseSingleFile( + filepath: string, + options: { language?: string; [key: string]: any }, + sourceCodeCache?: Map + ): any { + const language = options.language! + const config = this.registry.get(language)! + + // 获取文件内容:优先从 sourceCodeCache 获取,否则读取文件并填充到缓存 + let fileContent + if (sourceCodeCache && sourceCodeCache.get(filepath)) { + fileContent = sourceCodeCache.get(filepath)!.join('\n') + } else { + fileContent = fs.readFileSync(filepath, 'utf8') + // 如果提供了 sourceCodeCache,自动填充 + if (sourceCodeCache) { + sourceCodeCache.set(filepath, fileContent.split(/\n/)) + } + } + options.sourcefile = options.sourcefile || filepath + + return this.parseFile(filepath, fileContent, options, config, sourceCodeCache) + } + + /** + * 解析文件(BaseParser 的基本动作) + * @param {string} filepath - 文件路径 + * @param {string} code - 源代码内容 + * @param {Record} options - 解析选项 + * @param {LanguageParserConfig} config - 语言配置 + * @param {Map} [sourceCodeCache] - 可选的源代码缓存 + * @returns {any} 解析后的 AST + */ + private parseFile( + filepath: string, + code: string, + options: Record, + config: LanguageParserConfig, + sourceCodeCache?: Map + ): any { + const parseResult = parseFileCore(filepath, code, options.language!, options, { + unit: config.unit, + needsSourcefile: config.needsSourcefile, + }) + const { ast } = parseResult + + // 如果 parse 失败返回 null,清理 sourceCodeCache,避免后续代码误认为文件已处理 + if (!ast && sourceCodeCache && sourceCodeCache.get(filepath)) { + sourceCodeCache.delete(filepath) + } + + return ast + } + + /** + * 解析项目/包(用户操作接口) + * @param rootDir - 项目根目录 + * @param options - 解析选项,必须包含 language + * @param options.language - 语言标识(必填) + * @param sourceCodeCache - 可选的源代码缓存,如果提供则优先从缓存获取,读取后自动填充 + * @returns {Promise} 解析结果,根据 unit 类型返回不同格式 + */ + async parseProject( + rootDir: string, + options: { language?: string; [key: string]: any }, + sourceCodeCache?: Map + ): Promise { + const language = options.language! + const config = this.registry.get(language)! + + let result: any + + switch (config.unit) { + case 'file': { + if (config.parseAsFiles === false) { + result = await config.parseProject!(rootDir, options) + } else { + const parseResult = await this.parseProjectAsFiles(rootDir, config, options, sourceCodeCache) + result = parseResult.result + // parseProjectAsFiles 路径中,AST 已经处理过了,不需要额外处理 + return result + } + break + } + + case 'package': { + result = await config.parseProject!(rootDir, options) + break + } + + default: + throw new Error(`Unsupported unit type: ${config.unit}`) + } + + // 对于需要后处理的情况(parseAsFiles === false 或 package 类型),处理 AST + const needsPostProcess = config.unit === 'package' || config.parseAsFiles === false + if (result && needsPostProcess) { + if (!sourceCodeCache) { + sourceCodeCache = new Map() + } + + // 从解析结果中提取实际被解析的文件列表 + const parsedFiles = new Set() + if (config.unit === 'package' && result.packageInfo) { + this.extractFilesFromPackage(result.packageInfo, parsedFiles) + } else if (config.unit === 'file' && typeof result === 'object' && !Array.isArray(result)) { + for (const filename of Object.keys(result)) { + parsedFiles.add(filename) + } + } + + // 只加载实际被解析的文件到 sourceCodeCache(按需加载) + for (const filename of parsedFiles) { + if (!sourceCodeCache.get(filename) && filename && fs.existsSync(filename)) { + try { + const content = fs.readFileSync(filename, 'utf8') + sourceCodeCache.set(filename, content.split(/\n/)) + } catch (err) { + logger.warn(`Failed to load source for ${filename}: ${(err as Error).message}`) + } + } + } + + // 转换 Map 为 Record,传给 processProjectAstCore + const sourceCodeCacheRecord: Record = {} + for (const [filepath, lines] of sourceCodeCache.entries()) { + sourceCodeCacheRecord[filepath] = lines.join('\n') + } + + processProjectAstCore(result, config, options, sourceCodeCacheRecord) + } + + return result + } + + /** + * 并发控制:限制同时执行的 Promise 数量 + * @param tasks - 任务数组 + * @param concurrency - 最大并发数 + * @returns {Promise} 所有任务的结果(保持输入顺序) + */ + private async limitConcurrency(tasks: Array<() => Promise>, concurrency: number): Promise { + const results: T[] = new Array(tasks.length) + let index = 0 + + const executeTask = async (taskIndex: number) => { + // parseFile 内部已经捕获异常并返回 null,任务不会抛出异常 + const result = await tasks[taskIndex]() + results[taskIndex] = result + } + + const workers: Array> = [] + + const createWorker = () => { + return (async () => { + // eslint-disable-next-line no-constant-condition + while (true) { + const currentIndex = index + if (currentIndex >= tasks.length) { + break + } + index = currentIndex + 1 + // eslint-disable-next-line no-await-in-loop + await executeTask(currentIndex) + } + })() + } + + for (let i = 0; i < Math.min(concurrency, tasks.length); i++) { + workers.push(createWorker()) + } + + await Promise.all(workers) + return results + } + + /** + * 将项目作为文件集合解析(单文件语言) + * @param rootDir - 项目根目录 + * @param config - 语言配置 + * @param options - 解析选项 + * @param sourceCodeCache - 可选的源代码缓存,如果提供则优先从缓存获取,读取后自动填充 + * @returns {Promise<{ result: Record }>} 文件解析结果映射 + */ + private async parseProjectAsFiles( + rootDir: string, + config: LanguageParserConfig, + options: Record, + sourceCodeCache?: Map + ): Promise<{ result: Record }> { + const language = options.language! + const enableIncremental = this.shouldEnableIncremental(language) + + performanceTracker.record('preProcess.parseCode.loadFiles').start() + // 1. 先获取文件列表(使用 globby,只获取路径,不读取内容) + const filePaths = globby.sync(config.filePatterns, { cwd: rootDir }) + const fullFilePaths = filePaths.map((file: string) => path.join(rootDir, file)) + + // 2. 批量异步并行读取所有文件内容(限制并发数) + type FileContent = { file: string; content: string } + const fileContents: FileContent[] = await this.limitConcurrency( + fullFilePaths.map((filepath: string) => async () => { + // 优先从 sourceCodeCache 获取,否则读取文件 + if (sourceCodeCache && sourceCodeCache.get(filepath)) { + return { file: filepath, content: sourceCodeCache.get(filepath)!.join('\n') } + } + try { + const content = await fs.promises.readFile(filepath, 'utf8') + // 如果提供了 sourceCodeCache,自动填充 + if (sourceCodeCache) { + sourceCodeCache.set(filepath, content.split(/\n/)) + } + return { file: filepath, content } + } catch (err) { + logger.warn(`Failed to read file: ${filepath}, error: ${(err as Error).message}`) + return { file: filepath, content: '' } + } + }), + MAX_CONCURRENCY + ) + + performanceTracker.record('preProcess.parseCode.loadFiles').end() + + // 过滤掉读取失败的文件 + const files: FileContent[] = fileContents.filter((f: FileContent) => f.content !== '') + + // 3. 检查缓存并分离需要解析的文件 + let filesToParse: Array<{ file: string; content: string }> = [] + let cachedResults: Map = new Map() + let cacheList: Map | undefined + + // 判断是否需要加载缓存:false 模式和 force 模式不读取缓存 + const shouldLoadCache = enableIncremental && Config.incremental !== 'force' + if (shouldLoadCache) { + performanceTracker.record('preProcess.parseCode.loadCache').start() + const result = await this.loadCache(files) + filesToParse = result.filesToParse + cachedResults = result.cachedResults + cacheList = result.cacheList + performanceTracker.record('preProcess.parseCode.loadCache').end() + } else { + // false 模式和 force 模式:不读取缓存,所有文件都需要重新解析 + filesToParse = [...files] + } + + // 4. 并发解析需要解析的文件 + performanceTracker.record('preProcess.parseCode.parseFiles').start() + const parsedResults = await this.parseFilesConcurrently(filesToParse, language, options, config, sourceCodeCache) + performanceTracker.record('preProcess.parseCode.parseFiles').end() + + // 4. 合并缓存结果和解析结果 + // 注意:最终返回的 AST 必须包含 parent 属性(用于后续分析) + const results = files.map((file: FileContent) => { + const cached = cachedResults.get(file.file) + if (cached) { + // 从缓存加载的 AST 没有 parent(因为保存时跳过了) + // 需要重新添加 parent、sourcefile 和 hash + // 确保 sourceCodeCache 被填充,即使是从缓存加载的 AST + if (sourceCodeCache && !sourceCodeCache.get(file.file)) { + sourceCodeCache.set(file.file, file.content.split(/\n/)) + } + const fileOptions = { ...options, sourcefile: file.file } + // processParsedAstCore 会调用 annotateAST,重新添加 parent 属性 + // 优化:从缓存加载的 AST 如果已有 hash,跳过重新计算 + const ast = processParsedAstCore(cached, file.content, fileOptions, config, true) + return { + file: file.file, + content: file.content, + ast, // 此时 ast 已包含 parent + } + } + // 新解析的 AST 已经通过 processParsedAstCore 处理,包含 parent + return ( + parsedResults.find((r) => r.file === file.file) || { + file: file.file, + content: file.content, + ast: null, + } + ) + }) + + // 6. 保存新解析的 AST 到缓存(增量模式) + // force 模式:强制重新解析所有文件,不使用缓存,但解析完成后要保存缓存(下次可用) + if (enableIncremental && parsedResults.length > 0) { + performanceTracker.record('preProcess.parseCode.saveCache').start() + await this.saveCache(cacheList, parsedResults) + performanceTracker.record('preProcess.parseCode.saveCache').end() + } + + return { result: this.buildResultMap(results) } + } + + /** + * 并发解析文件(使用 Worker 线程或 Promise 并发) + * @param files - 要解析的文件列表(已经过滤掉缓存命中的文件) + * @param language - 编程语言 + * @param options - 解析选项 + * @param config - 语言配置 + * @param sourceCodeCache - 源代码缓存(可选,如果提供则会被填充) + * @returns {Promise>} 解析结果数组 + */ + private async parseFilesConcurrently( + files: Array<{ file: string; content: string }>, + language: string, + options: Record, + config: LanguageParserConfig, + sourceCodeCache?: Map + ): Promise> { + type FileContent = { file: string; content: string } + type ParseResult = { file: string; content: string; ast: any } + + if (files.length === 0) { + return [] + } + + // 根据文件数量决定使用 Worker 线程还是 Promise 并发解析 + const MIN_FILES_FOR_WORKER = 10 + const shouldUseWorkers = this.useWorkers && files.length >= MIN_FILES_FOR_WORKER + const workerPool = shouldUseWorkers ? this.getWorkerPool() : null + + let parsedResults: ParseResult[] = [] + + if (shouldUseWorkers && workerPool) { + // 使用子进程模式 + const parsePromises = files.map(async (file: FileContent): Promise => { + // OOM 降级:累计 2 次非正常退出后,后续文件走主线程 + if (workerPool.oomCount >= 2) { + const fileOptions = { ...options, sourcefile: file.file } + const ast = this.parseFile(file.file, file.content, fileOptions, config, sourceCodeCache) + return { file: file.file, content: file.content, ast } + } + + const minimalOptions: Record = { sourcefile: file.file } + if (language === 'javascript' || language === 'js') { + minimalOptions.sanity = options.sanity + } + + SourceLine.storeCode(file.file, file.content) + + try { + const parseResult = await workerPool.submitTask('parse', { + filepath: file.file, + content: file.content, + language, + options: minimalOptions, + config: { + unit: config.unit, + needsSourcefile: config.needsSourcefile, + maindirPrefix: Config.maindirPrefix, + }, + }) + + if (parseResult.error) { + logger.warn(`Failed to parse ${file.file} in worker: ${parseResult.error}`) + return { file: file.file, content: file.content, ast: null } + } + + // 子进程已做完整 processAst,但 IPC 序列化丢了 parent,补回来 + const fileOptions = { ...minimalOptions, sourcefile: file.file } + const ast = processParsedAstCore(parseResult.ast, file.content, fileOptions, config, true) + return { file: file.file, content: file.content, ast } + } catch (error) { + // 子进程崩溃(OOM 等),回退到主线程重试 + logger.warn(`Worker failed for ${file.file}: ${(error as Error).message}, retrying on main thread`) + const fileOptions = { ...options, sourcefile: file.file } + const ast = this.parseFile(file.file, file.content, fileOptions, config, sourceCodeCache) + return { file: file.file, content: file.content, ast } + } + }) + + parsedResults = await Promise.all(parsePromises) + + // 打印子进程性能统计 + const workerStats = workerPool.getStats() + if (workerStats.workerWorkTimes) { + const workerTimeStr = Object.entries(workerStats.workerWorkTimes) + .map(([workerId, time]) => `W${workerId}:${(time as number).toFixed(0)}ms`) + .join(', ') + yasaLog(`Work time: ${workerTimeStr}`, PREPROCESS_PARSE_CODE_STAGE) + } + if (workerPool.oomCount > 0) { + yasaLog(`OOM fallbacks: ${workerPool.oomCount}`, PREPROCESS_PARSE_CODE_STAGE) + } + + // 解析完成后立即释放子进程池 + await this.cleanupWorkerPool() + } else { + // 使用 Promise 并发解析 + parsedResults = await this.limitConcurrency( + files.map((file: FileContent) => async () => { + const fileOptions = { ...options, sourcefile: file.file } + const ast = this.parseFile(file.file, file.content, fileOptions, config, sourceCodeCache) + return { + file: file.file, + content: file.content, + ast, + } + }), + MAX_CONCURRENCY + ) + } + + return parsedResults + } + + /** + * 构建结果映射 + * @param results - 文件解析结果数组 + * @returns {Record} 文件路径到 AST 的映射 + */ + private buildResultMap(results: Array<{ file: string; content?: string; ast: any }>): Record { + const resultMap: Record = {} + for (const result of results) { + resultMap[result.file] = result.ast + } + return resultMap + } + + /** + * 从缓存加载 AST 并分离需要解析的文件 + * @param files - 已加载的文件内容数组 + * @returns {Promise<{filesToParse: Array<{file: string; content: string}>, cachedResults: Map, cacheList: Map | undefined}>} 需要解析的文件、缓存的 AST 和缓存列表 + */ + private async loadCache(files: Array<{ file: string; content: string }>): Promise<{ + filesToParse: Array<{ file: string; content: string }> + cachedResults: Map + cacheList: Map | undefined + }> { + const filesToParse: Array<{ file: string; content: string }> = [] + const cachedResults: Map = new Map() + + // 读取缓存列表 + const cacheList = await loadCacheList() + const cacheDir = getCacheDir() + + // 限制并发加载缓存文件数量,避免 "too many open files" 错误 + const MAX_CONCURRENT_CACHE_LOADS = Math.max(require('os').cpus().length, 16) + const cacheCheckTasks = files.map((file: { file: string; content: string }) => { + return async () => { + const relativePath = getRelativePath(file.file) + const cacheInfo = cacheList.get(relativePath) + + if (cacheInfo) { + const sourceCrc = md5(file.content) + if (cacheInfo.crc === sourceCrc) { + // 尝试加载缓存 + const jsonPath = path.join(cacheDir, cacheInfo.jsonFile) + const ast = await loadAstFromCacheCore(jsonPath) + if (ast) { + return { file: file.file, ast, cached: true } + } + // 缓存加载失败,需要重新解析 + } + } + return { file: file.file, ast: null, cached: false } + } + }) + + const cacheCheckResults = await this.limitConcurrency(cacheCheckTasks, MAX_CONCURRENT_CACHE_LOADS) + for (const result of cacheCheckResults) { + if (result.cached && result.ast) { + cachedResults.set(result.file, result.ast) + } else { + const file = files.find((f) => f.file === result.file) + if (file) { + filesToParse.push(file) + } + } + } + + // 输出缓存命中率 + const cachedFilesCount = cachedResults.size + const cacheHitRate = files.length > 0 ? ((cachedFilesCount / files.length) * 100).toFixed(1) : '0.0' + yasaLog(`hit Cache: ${cachedFilesCount}/${files.length} (${cacheHitRate}%)`, PREPROCESS_PARSE_CODE_STAGE) + + return { filesToParse, cachedResults, cacheList } + } + + /** + * 保存缓存(保存新解析的 AST 到缓存文件,并更新缓存列表文件) + * + * 重要:保存到缓存文件的 AST 不包含 parent 属性(序列化时跳过) + * - parent 是循环引用,无法序列化 + * - 保存时跳过 parent 可以避免序列化问题和减少文件大小 + * - 从缓存加载后,会通过 processParsedAstCore 重新添加 parent + * + * @param existingCacheList - 现有的缓存列表(可能为 undefined) + * @param parsedResults - 解析结果数组(AST 包含 parent,但保存时会跳过) + */ + private async saveCache( + existingCacheList: Map | undefined, + parsedResults: Array<{ file: string; content: string; ast: any }> + ): Promise { + try { + // 限制并发保存缓存文件数量,避免 "too many open files" 错误 + // 1. 并行保存所有 AST 到缓存文件(限制并发数) + // 注意:parsedResults 中的 AST 包含 parent,但保存时会跳过(通过 skipParentReplacer) + const cacheSaveTasks = parsedResults + .filter((result) => result.ast) + .map((result) => { + return async () => { + try { + // 计算缓存路径 + const relativePath = getRelativePath(result.file) + const cacheDir = getCacheDir() + const astCacheSubDir = 'astcache' + const jsonFileName = `${md5(relativePath)}.json` + const jsonFile = path.join(astCacheSubDir, jsonFileName) + const jsonPath = path.join(cacheDir, jsonFile) + + // 直接保存 AST(saveAstToCacheCore 内部会使用 skipParentReplacer 跳过 parent 属性) + // 序列化时跳过 parent,但原 AST 对象保持不变(仍然有 parent,用于返回给用户) + // 避免先序列化再解析,减少内存使用 + const success = await saveAstToCacheCore(result.ast, jsonPath) + if (success) { + const sourceCrc = md5(result.content) + const timestamp = new Date().toISOString() + return { + relativePath, + jsonFile, + crc: sourceCrc, + time: timestamp, + } + } + return null + } catch (error) { + logger.warn(`Failed to save cache for ${result.file}: ${(error as Error).message}`) + return null + } + } + }) + + const cacheInfos = await this.limitConcurrency(cacheSaveTasks, MAX_CONCURRENCY) + const validCacheInfos = cacheInfos.filter( + (info): info is { relativePath: string; jsonFile: string; crc: string; time: string } => info !== null + ) + + if (validCacheInfos.length === 0) { + return + } + + // 2. 合并现有缓存列表和新缓存信息 + const cacheListArray: Array<{ path: string; jsonFile: string; crc: string; time?: string }> = [] + + if (existingCacheList) { + for (const [cachePath, info] of existingCacheList.entries()) { + const willBeUpdated = validCacheInfos.some((newInfo) => newInfo.relativePath === cachePath) + if (!willBeUpdated) { + cacheListArray.push({ + path: cachePath, + jsonFile: info.jsonFile, + crc: info.crc, + time: info.time, + }) + } + } + } + + for (const cacheInfo of validCacheInfos) { + cacheListArray.push({ + path: cacheInfo.relativePath, + jsonFile: cacheInfo.jsonFile, + crc: cacheInfo.crc, + time: cacheInfo.time, + }) + } + + // 3. 保存缓存列表文件 + const cacheDir = getCacheDir() + if (!fs.existsSync(cacheDir)) { + fs.mkdirSync(cacheDir, { recursive: true }) + } + const listPath = path.join(cacheDir, 'ast-cache-list.json') + await fs.promises.writeFile(listPath, JSON.stringify(cacheListArray, null, 2), 'utf8') + } catch (error) { + logger.warn(`Failed to save cache list: ${(error as Error).message}`) + } + } + + /** + * 检查是否应该启用增量解析 + * @param language - 语言标识 + * @returns {boolean} 是否启用增量解析 + */ + private shouldEnableIncremental(language: string): boolean { + const config = this.registry.get(language) + if (!config || !config.supportsIncremental) return false + return Config.incremental !== false && Config.incremental !== 'false' + } + + /** + * 从 package 信息中递归提取文件路径 + * @param packageInfo - package 信息对象 + * @param filesSet - 文件路径集合(用于收集结果) + */ + private extractFilesFromPackage(packageInfo: any, filesSet: Set): void { + if (packageInfo.files) { + for (const filename of Object.keys(packageInfo.files)) { + filesSet.add(filename) + } + } + if (packageInfo.subs) { + for (const subPackage of Object.values(packageInfo.subs)) { + this.extractFilesFromPackage(subPackage, filesSet) + } + } + } + + // =================== 增量缓存管理 =================== + + /** + * 导出所有 AST 到文件 + * @param {string} rootDir - 项目根目录 + * @param {string} reportDir - 输出目录 + * @param {Record} options - 解析选项,必须包含 language + * @param {string} options.language - 语言标识(必填) + * @returns {Promise} + */ + async dumpAllAST( + rootDir: string, + reportDir: string, + options: { language?: string; [key: string]: any } + ): Promise { + const language = options.language! + const config = this.registry.get(language)! + + const results = await this.parseProject(rootDir, options) + await dumpAllASTCore(results, reportDir, config) + } +} + +// =============== 创建单例并导出接口 ============== + +const parser = new BaseParser() + +/** + * 解析单个文件(用户操作接口) + * @param filepath - 文件路径 + * @param options - 解析选项,必须包含 language + * @param options.language - 语言标识(必填) + * @param sourceCodeCache - 可选的源代码缓存,如果提供则优先从缓存获取,读取后自动填充 + * @returns {any} 解析后的 AST + * @throws {Error} 如果解析失败 + */ +function parseSingleFile( + filepath: string, + options: { language?: string; [key: string]: any }, + sourceCodeCache?: Map +): any { + return parser.parseSingleFile(filepath, options, sourceCodeCache) +} + +/** + * 解析项目/包(用户操作接口) + * @param {string} rootDir - 项目根目录 + * @param {Record} options - 解析选项,必须包含 language + * @param {string} options.language - 语言标识(必填) + * @param {Map} [sourceCodeCache] - 可选的源代码缓存,如果提供则优先从缓存获取,读取后自动填充 + * @returns {Promise} 解析结果,根据 unit 类型返回不同格式 + */ +async function parseProject( + rootDir: string, + options: { language?: string; [key: string]: any }, + sourceCodeCache?: Map +): Promise { + return parser.parseProject(rootDir, options, sourceCodeCache) +} + +/** + * 导出所有 AST 到文件 + * @param {string} rootDir - 项目根目录 + * @param {string} reportDir - 输出目录 + * @param {Record} options - 解析选项,必须包含 language + * @param {string} options.language - 语言标识(必填) + * @returns {Promise} + */ +async function dumpAllAST( + rootDir: string, + reportDir: string, + options: { language?: string; [key: string]: any } +): Promise { + return parser.dumpAllAST(rootDir, reportDir, options) +} + +// ================== 导出接口 ==================== + +module.exports = { + parseSingleFile, + parseProject, + dumpAllAST, +} diff --git a/src/engine/parser/parsing.ts b/src/engine/parser/parsing.ts index c01a1af1..e69de29b 100644 --- a/src/engine/parser/parsing.ts +++ b/src/engine/parser/parsing.ts @@ -1,439 +0,0 @@ -const fs = require('fs-extra') -const Statistics = require('../../util/statistics') -const AstUtil = require('../../util/ast-util') -const SourceLine = require('../analyzer/common/source-line') -const { Errors } = require('../../util/error-code') -const GoParser = require('./golang/go-ast-builder') -const PythonParser = require('./python/python-ast-builder') -const FileUtil = require('../../util/file-util') -const HashUtil = require('../../util/hash-util') -const { handleException } = require('../analyzer/common/exception-handler') -const { addNodeHash, deleteParent } = require('../../util/ast-util') - -/** - * * Parse the javascript source code (a string) using babel - * @param code - * @param options - */ -function parseJavaScript(code: any, options: Record) { - const JSAstBuilder = require('./javascript/js-ast-builder') - const parsingStart = new Date().getTime() - const ast = JSAstBuilder.parse(code, { sanity: options.sanity, sourcefile: options.sourcefile }) - if (!ast) { - Statistics.parsingTime += new Date().getTime() - parsingStart - Errors.ParseError(`no ast generated from code`) - } - - const fname = SourceLine.storeCode(options && options.sourcefile, code) - AstUtil.annotateAST(ast, options ? { sourcefile: fname } : null) - ast.loc.sourcefile = fname - addNodeHash(ast) - Statistics.parsingTime += new Date().getTime() - parsingStart - return ast -} - -/** - * - * @param code - * @param options - */ -function parseJavaScriptRaw(code: any, options: Record) { - const JSAstBuilder = require('./javascript/js-ast-builder') - const parsingStart = new Date().getTime() - const ast = JSAstBuilder.parse(code, { sanity: options.sanity, sourcefile: options.sourcefile }) - if (!ast) { - Statistics.parsingTime += new Date().getTime() - parsingStart - Errors.ParseError(`no ast generated from code`) - } - AstUtil.annotateAST(ast, options ? { sourcefile: options && options.sourcefile } : null) - ast.loc.sourcefile = SourceLine.storeCode(options && options.sourcefile, code) - addNodeHash(ast) - deleteParent(ast) - Statistics.parsingTime += new Date().getTime() - parsingStart - - return ast -} - -/** - * * Parse the javascript source code (a string) - * @param code - * @param options - */ -function parseJavaParsing(code: any, options: Record) { - const JavaAstBuilder = require('./java/java-ast-builder') - const parsingStart = new Date().getTime() - const ast = JavaAstBuilder.parse(code, { - sanity: options.sanity, - sourcefile: options.sourcefile, - language: 'java', - }) - if (!ast) { - Statistics.parsingTime += new Date().getTime() - parsingStart - Errors.ParseError(`no ast generated from code`) - } - - const fname = SourceLine.storeCode(options && options.sourcefile, code) - AstUtil.annotateAST(ast, options ? { sourcefile: fname } : null) - ast.loc.sourcefile = fname - addNodeHash(ast) - Statistics.parsingTime += new Date().getTime() - parsingStart - return ast -} - -/** - * * Parse the javascript source code (a string), only add loc - * @param code - * @param options - */ -function parseJavaRaw(code: any, options: Record) { - const JavaAstBuilder = require('./java/java-ast-builder') - const parsingStart = new Date().getTime() - const ast = JavaAstBuilder.parse(code, { - sanity: options.sanity, - sourcefile: options.sourcefile, - language: 'java', - }) - if (!ast) { - Statistics.parsingTime += new Date().getTime() - parsingStart - Errors.ParseError(`no ast generated from code`) - } - AstUtil.annotateAST(ast, options ? { sourcefile: options && options.sourcefile } : null) - ast.loc.sourcefile = SourceLine.storeCode(options && options.sourcefile, code) - addNodeHash(ast) - deleteParent(ast) - Statistics.parsingTime += new Date().getTime() - parsingStart - return ast -} - -/** - * Parse the source code according to the source language - * @param code - * @param options - * @returns {*} - */ -function parseCode(code: any, options: Record) { - try { - if (options) { - switch (options.language) { - case 'js': - case 'javascript': - return parseJavaScript(code, options) - case 'java': - return parseJavaParsing(code, options) - case 'python': - return PythonParser.parseSingleFile(code, options) - default: - } - } - return parseJavaScript(code, options) - } catch (e) { - const err_location_tip = options && options.sourcefile ? options.sourcefile : `code snippet: ${code.substr(0, 70)}` - Errors.ParseError(`[${err_location_tip}] parse failed, err: ${(e as Error).toString()}`) - } -} - -/** - * - * @param filepath - * @param code - * @param options - */ -function parseCodeRaw(filepath: any, code: any, options: Record) { - try { - if (options) { - switch (options.language) { - case 'js': - case 'javascript': - return parseJavaScriptRaw(code, options) - case 'golang': - if (filepath.endsWith('.go')) { - options.single = true - } - return GoParser.parsePackage(filepath, options) - case 'java': - return parseJavaRaw(code, options) - case 'python': - return PythonParser.parseSingleFile(filepath, options) - default: - } - } - return parseJavaScriptRaw(code, options) - } catch (e) { - const err_location_tip = options && options.sourcefile ? options.sourcefile : `code snippet: ${code.substr(0, 70)}` - Errors.ParseError(`[${err_location_tip}] parseRaw failed, err: ${(e as Error).toString()}`) - } -} - -/** - * - * @param dir - * @param options - */ -async function parseDirectory(dir: any, options: Record) { - try { - if (options) { - if (!options.reportDir) { - options.reportDir = './uastParseDir' - } - const stats = fs.statSync(options.reportDir) // 获取文件/目录状态 - - if (stats.isFile()) { - // 如果是文件直接删除 - fs.unlinkSync(options.reportDir) - } else if (stats.isDirectory()) { - // 使用现代API递归删除目录 - fs.rmSync(options.reportDir, { recursive: true, force: true }) - } - if (!fs.existsSync(options.reportDir)) { - fs.mkdirSync(options.reportDir, { recursive: true }) - } - if (!options.language) { - handleException( - 'please set target language. YASA support language: js, java, golang, python', - 'please set target language. YASA support language: js, java, golang, python', - null - ) - process.exit(1) - } - switch (options.language) { - case 'js': - case 'javascript': { - const modules = FileUtil.loadAllFileTextGlobby( - [ - '**/*.(js|ts|mjs|cjs)', - '!**/*.test.(js|ts|mjs|cjs|jsx)', - '!**/node_modules', - '!web', - '!**/public/**', - '!**/*.d.ts', - '!**/*.d.js', - ], - dir - ) - if (modules.length === 0) { - handleException( - null, - 'find no target compileUnit of the project : no js/ts file found in source path', - 'find no target compileUnit of the project : no js/ts file found in source path' - ) - process.exit(0) - } - for (const mod of modules) { - options.sourcefile = mod.file - const ast = parseCodeRaw(mod.file, mod.content, options) - const parseResult = JSON.stringify(ast) - if (!options.reportDir) { - options.reportDir = './uastParseDir' - } - const fileName = `${HashUtil.md5(mod.file)}.json` - - fs.writeFileSync(`${options.reportDir}/${fileName}`, parseResult) - } - break - } - case 'golang': { - const goUast = await GoParser.parsePackage(dir, options) - processGoUast(goUast, options) - const uastFile = fs.statSync('./uast.json') // 获取文件/目录状态 - if (uastFile.isFile()) { - fs.unlink('./uast.json', (err: any) => { - if (err) { - handleException( - err, - `[go-ast-builder] 删除uast.json文件时发生错误`, - `[go-ast-builder] 删除uast.json文件时发生错误` - ) - } - }) - } - break - } - case 'java': { - const packageFiles = FileUtil.loadAllFileTextGlobby(['**/*.java', '!target/**', '!src/test/**'], dir) - if (packageFiles.length === 0) { - handleException( - null, - 'find no target compileUnit of the project : no java file found in source path', - 'find no target compileUnit of the project : no java file found in source path' - ) - process.exit(0) - } - for (const packageFile of packageFiles) { - options.sourcefile = packageFile.file - const ast = parseJavaRaw(packageFile.content, options) - const parseResult = JSON.stringify(ast) - const fileName = `${HashUtil.md5(packageFile.file)}.json` - fs.writeFileSync(`${options.reportDir}/${fileName}`, parseResult) - } - break - } - case 'python': { - const pythonUast = {} - PythonParser.parsePackages(pythonUast, dir, options) - processPythonUast(pythonUast, options) - break - } - default: - } - } - } catch (e) { - Errors.ParseError(`[${dir}] parseDirectory failed, err: ${(e as Error).toString()}`) - } -} - -/** - * 处理goUast对象,深度搜索符合条件的节点并序列化到文件中 - * @param {Object} goUast - golang解析后的UAST对象 - * @param options - */ -function processGoUast(goUast: any, options: Record) { - if (!goUast || typeof goUast !== 'object') { - return - } - - /** - * 深度优先搜索对象 - * @param obj - * @param parentPath - */ - function deepSearch(obj: any, parentPath = '') { - if (!obj || typeof obj !== 'object') { - return - } - - // 处理数组 - if (Array.isArray(obj)) { - obj.forEach((item, index) => { - deepSearch(item, `${parentPath}[${index}]`) - }) - return - } - - // 处理对象的每个键值对 - for (const [key, value] of Object.entries(obj)) { - const currentPath = parentPath ? `${parentPath}.${key}` : key - - // 检查key是否以.go结尾 - if (typeof key === 'string' && key.endsWith('.go') && value && typeof value === 'object') { - // 在value中查找包含'node'且node.type为'CompileUnit'的节点 - if ( - (value as any).node && - typeof (value as any).node === 'object' && - (value as any).node.type === 'CompileUnit' - ) { - // 创建没有parent的node副本 - const nodeWithoutParent = removeParentProperty(JSON.parse(JSON.stringify((value as any).node))) - - // 生成输出文件路径 - const fileName = HashUtil.md5(key) - const outputPath = `${options.reportDir}/${fileName}.json` - - try { - // JSON序列化并写入文件 - fs.writeFileSync(outputPath, JSON.stringify(nodeWithoutParent)) - } catch (error) { - handleException( - error, - `写入文件失败: ${outputPath}`, - `写入文件失败: ${outputPath}, 错误: ${(error as Error).message}` - ) - } - } - break - } - - // 递归搜索子对象 - deepSearch(value, currentPath) - } - } - - /** - * 移除所有parent属性的辅助函数 - * @param obj - */ - function removeParentProperty(obj: any): any { - if (!obj || typeof obj !== 'object') { - return obj - } - - if (Array.isArray(obj)) { - return obj.map((item: any) => removeParentProperty(item)) - } - - const result: any = {} - for (const [key, value] of Object.entries(obj)) { - if (key !== 'parent') { - result[key] = removeParentProperty(value) - } - } - - return result - } - - // 开始深度搜索 - deepSearch(goUast) -} - -/** - * 处理pythonUast对象,将其内容输出到文件中 - * @param {Object} pythonUast - python解析后的UAST对象 - * @param {Object} options - 处理选项 - */ -function processPythonUast(pythonUast: any, options: Record) { - if (!pythonUast || typeof pythonUast !== 'object') { - return - } - - // 设置输出目录 - const outputDir = options.reportDir - - // 确保输出目录存在 - try { - fs.ensureDirSync(outputDir) - } catch (error) { - handleException( - error, - `创建目录失败: ${outputDir}`, - `创建目录失败: ${outputDir}, 错误: ${(error as Error).message}` - ) - return - } - - /** - * 遍历pythonUast对象的所有key,将每个key的value写入对应的JSON文件 - * @param {Object} obj - 要处理的对象 - * @param {string} basePath - 基础路径 - */ - function traverseAndWrite(obj: any, basePath = '') { - if (!obj || typeof obj !== 'object') { - return - } - - for (const [key, value] of Object.entries(obj)) { - const fileName = HashUtil.md5(key) - const filePath = `${outputDir}/${fileName}.json` - - try { - // 写入JSON文件 - fs.writeFileSync(filePath, JSON.stringify(value)) - } catch (error) { - handleException( - error, - `写入Python UAST文件失败: ${filePath}`, - `写入文件失败: ${filePath}, 错误: ${(error as Error).message}` - ) - } - } - } - - // 开始处理 - traverseAndWrite(pythonUast) -} - -// *** - -module.exports = { - parseCode, - parseCodeRaw, - parseDirectory, -} diff --git a/src/engine/parser/python/python-ast-builder.ts b/src/engine/parser/python/python-ast-builder.ts index 4e1ff4d8..fe481448 100644 --- a/src/engine/parser/python/python-ast-builder.ts +++ b/src/engine/parser/python/python-ast-builder.ts @@ -1,11 +1,12 @@ +/* eslint-disable @typescript-eslint/no-require-imports */ +/* eslint-disable sonarjs/cognitive-complexity */ const ChildProcess = require('child_process') const path = require('path') const fs = require('fs') const os = require('os') const FileUtil = require('../../../util/file-util') const { handleException } = require('../../analyzer/common/exception-handler') -const { addNodeHash, deleteParent } = require('../../../util/ast-util') -const AstUtil = require('../../../util/ast-util') +const { resolveUastBinaryPath } = require('../../../util/file-util') interface BuildOptions { language?: string @@ -18,19 +19,18 @@ interface BuildOptions { let uastFilePath = './uast' /** - * - * @param rootDir - * @param options + * 构建 Python UAST + * @param rootDir - 根目录 + * @param options - 构建选项 + * @returns {any} 构建结果 */ function buildUASTPython(rootDir: string, options?: BuildOptions): any { options = options || {} if (options.language && options.language !== 'python') { handleException( - new Error( - `Python AST Builder received wrong language type: ${options.language}`, - ), - `Error: Python AST Builder received wrong language type: ${options.language}`, + new Error(`Python AST Builder received wrong language type: ${options.language}`), `Error: Python AST Builder received wrong language type: ${options.language}`, + `Error: Python AST Builder received wrong language type: ${options.language}` ) process.exit(1) } @@ -43,21 +43,21 @@ function buildUASTPython(rootDir: string, options?: BuildOptions): any { isSingle = '' } - // prefer user-provided SDK path if present - let uast4pyPath = '' - if (options.uastSDKPath && options.uastSDKPath !== '') { - uast4pyPath = options.uastSDKPath - } else { - // fallback to default deps location - uast4pyPath = path.join(__dirname, '../../../../deps/uast4py/uast4py') - } + // 使用统一的路径解析函数 + const devPath = path.join(__dirname, '../../../../deps/uast4py/uast4py') + const uast4pyPath = resolveUastBinaryPath({ + uastSDKPath: options.uastSDKPath, + binaryName: 'uast4py', + devPath, + }) + // if uast4pyPath does not exist, exit with error - if (!fs.existsSync(uast4pyPath)) { + if (!uast4pyPath || !fs.existsSync(uast4pyPath)) { handleException( null, // eslint-disable-next-line sonarjs/no-duplicate-string - `uast4py not found at ${uast4pyPath}. Please set --uastSDKPath to the correct path or install the uast4py sdk under deps/uast4py/uast4py`, - `uast4py not found at ${uast4pyPath}. Please set --uastSDKPath to the correct path or install the uast4py sdk under deps/uast4py/uast4py`, + `uast4py not found. Please set --uastSDKPath to the binary or deps directory, or install it under deps/uast4py/uast4py`, + `uast4py not found. Please set --uastSDKPath to the binary or deps directory, or install it under deps/uast4py/uast4py` ) process.exit(0) } @@ -76,18 +76,15 @@ function buildUASTPython(rootDir: string, options?: BuildOptions): any { } ChildProcess.execSync(command, optionForCommand) } catch (e) { - handleException( - e, - `[python-ast-builder] 解析python AST时发生错误`, - `[python-ast-builder] 解析python AST时发生错误`, - ) + // eslint-disable-next-line prettier/prettier + handleException(e, `[python-ast-builder] 解析python AST时发生错误`, `[python-ast-builder] 解析python AST时发生错误`) return null } } /** - * - * @param fpath + * 删除 Python UAST 文件 + * @param fpath - 文件路径 */ function deleteUASTPython(fpath: string) { try { @@ -102,66 +99,73 @@ function deleteUASTPython(fpath: string) { } } catch (err: any) { if (err.code === 'ENOENT') { - handleException( - err, - `[python-ast-builder] 路径不存在: ${fpath}`, - `[python-ast-builder] 路径不存在: ${fpath}`, - ) + // eslint-disable-next-line prettier/prettier + handleException(err, `[python-ast-builder] 路径不存在: ${fpath}`, `[python-ast-builder] 路径不存在: ${fpath}`) } else { - handleException( - err, - `[python-ast-builder] 删除操作失败: ${fpath}`, - `[python-ast-builder] 删除操作失败: ${fpath}`, - ) + // eslint-disable-next-line prettier/prettier + handleException(err, `[python-ast-builder] 删除操作失败: ${fpath}`, `[python-ast-builder] 删除操作失败: ${fpath}`) } } } /** - * - * @param filename - * @param options + * 解析单个文件(统一接口) + * @param code - 源代码内容 + * @param options - 解析选项(包含 sourcefile) + * @returns {any} 解析后的 AST(未处理后处理) */ -function parseSingleFilePython(filename: string, options?: BuildOptions): any { +function parseSingleFilePython(code: string, options?: BuildOptions): any { options = options || {} options.single = true - buildUASTPython(filename, options) - const data = fs.readFileSync(uastFilePath, 'utf8') - if ( - data.startsWith('Syntax error in file') || - data.startsWith('UnicodeDecodeError in file') - ) { - handleException( - null, - `[python-ast-builder] parseSingleFile failed: ${filename}`, - `[python-ast-builder] parseSingleFile failed: ${filename}`, - ) - if (fs.existsSync(uastFilePath)) { + + // 创建临时文件,写入传入的代码内容 + const tempDir = os.tmpdir() + const tempFileName = `${Date.now()}_${Math.random().toString(36).substring(7)}.py` + const tempFilePath = path.join(tempDir, tempFileName) + fs.writeFileSync(tempFilePath, code, 'utf8') + const actualFilePath = tempFilePath + + // 保留原始的 sourcefile 用于 AST 标注,但使用临时文件路径进行解析 + // buildUASTPython 使用 actualFilePath 参数,不会读取 options.sourcefile + + try { + buildUASTPython(actualFilePath, options) + const data = fs.readFileSync(uastFilePath, 'utf8') + if (data.startsWith('Syntax error in file') || data.startsWith('UnicodeDecodeError in file')) { + handleException( + null, + `[python-ast-builder] parseSingleFile failed: ${actualFilePath}`, + `[python-ast-builder] parseSingleFile failed: ${actualFilePath}` + ) + if (fs.existsSync(uastFilePath)) { + deleteUASTPython(uastFilePath) + } + return + } + const obj = JSON.parse(data) + if (!options.dumpAST && fs.existsSync(uastFilePath)) { deleteUASTPython(uastFilePath) } - return - } - const obj = JSON.parse(data) - if (!options.dumpAST && fs.existsSync(uastFilePath)) { - deleteUASTPython(uastFilePath) + return obj + } finally { + // 清理临时文件(如果创建了) + if (tempFilePath) { + try { + fs.unlinkSync(tempFilePath) + } catch (e) { + // 忽略清理错误 + } + } } - AstUtil.annotateAST(obj, { sourcefile: filename }) - addNodeHash(obj) - deleteParent(obj) - return obj } /** - * - * @param astManager - * @param rootDir - * @param options + * 解析 Python 包(内部使用) + * @param pyAstParseManager - AST 管理器 + * @param rootDir - 根目录 + * @param options - 构建选项 */ -function parsePackages( - astManager: any, - rootDir: string, - options?: BuildOptions, -): void { +function parsePackages(pyAstParseManager: any, rootDir: string, options?: BuildOptions): void { if (fs.existsSync(uastFilePath)) { deleteUASTPython(uastFilePath) } @@ -170,22 +174,16 @@ function parsePackages( try { buildUASTPython(rootDir, options) - const uastJsonFiles = FileUtil.loadAllFileTextGlobby( - ['**/*.(json)'], - uastFilePath, - ) + const uastJsonFiles = FileUtil.loadAllFileTextGlobby(['**/*.(json)'], uastFilePath) for (const uastFile of uastJsonFiles) { const data = uastFile.content - if ( - data.startsWith('Syntax error in file') || - data.startsWith('UnicodeDecodeError in file') - ) { + if (data.startsWith('Syntax error in file') || data.startsWith('UnicodeDecodeError in file')) { handleException( null, `[python-ast-builder] parsePackage error: get python ast failed. ${rootDir}`, - `[python-ast-builder] parsePackage error: get python ast failed. ${rootDir}`, + `[python-ast-builder] parsePackage error: get python ast failed. ${rootDir}` ) if (fs.existsSync(uastFile.file)) { deleteUASTPython(uastFile.file) @@ -195,36 +193,40 @@ function parsePackages( const obj = JSON.parse(data) - AstUtil.annotateAST(obj, { sourcefile: obj.loc?.sourcefile }) - - addNodeHash(obj) - - deleteParent(obj) - const filename = obj?.loc?.sourcefile if (filename) { - astManager[filename] = obj + pyAstParseManager[filename] = obj } } } catch (e) { handleException( e, `[python-ast-builder] parsePackage error: ${rootDir}`, - `[python-ast-builder] parsePackage error: ${rootDir}`, + `[python-ast-builder] parsePackage error: ${rootDir}` ) if (fs.existsSync(uastFilePath)) { deleteUASTPython(uastFilePath) } } - if (!options.dumpAST) { - if (fs.existsSync(uastFilePath)) { - deleteUASTPython(uastFilePath) - } + if (!options.dumpAST && fs.existsSync(uastFilePath)) { + deleteUASTPython(uastFilePath) } } +/** + * 解析项目(统一接口) + * @param rootDir - 项目根目录 + * @param options - 解析选项 + * @returns {Promise>} AST 管理器对象 + */ +async function parseProject(rootDir: string, options?: BuildOptions): Promise> { + const astManager: Record = {} + parsePackages(astManager, rootDir, options) + return astManager +} + module.exports = { parseSingleFile: parseSingleFilePython, - parsePackages, + parseProject, } diff --git a/src/engine/parser/uast-sanity.ts b/src/engine/parser/uast-sanity.ts index 68443552..8b05556f 100644 --- a/src/engine/parser/uast-sanity.ts +++ b/src/engine/parser/uast-sanity.ts @@ -68,7 +68,7 @@ const requiredFields: FieldMap = { TupleExpression: ['components'], // MemberAccess: [ 'expression', 'memberName' ], MemberAccess: ['expression', 'property'], - BinaryOperation: ['operator', 'left', 'right'], + BinaryExpression: ['operator', 'left', 'right'], IndexAccess: ['base', 'index'], Conditional: ['condition', 'trueExpression', 'falseExpression'], ForStatement: ['initExpression', 'conditionExpression', 'loopExpression', 'body'], diff --git a/src/engine/util/type-util.ts b/src/engine/util/type-util.ts deleted file mode 100644 index 65e32acb..00000000 --- a/src/engine/util/type-util.ts +++ /dev/null @@ -1,118 +0,0 @@ -/** - * - * @param tp1 - * @param tp2 - */ -function isCompatibleTypes(tp1: string, tp2: string): boolean { - switch (tp1) { - case 'uint': - if (tp2 == 'uint256') return true - break - case 'uint256': - if (tp2 == 'uint') return true - break - - case 'int': - if (tp2 == 'int256') return true - break - case 'int256': - if (tp2 == 'int') return true - break - } - return tp1 == tp2 -} - -/** - * tp1 < tp2 ? - * @param tp1 - * @param tp2 - * @returns {boolean} - */ -function isLossyConversion(tp1: string, tp2: string): boolean { - if (tp1 == tp2) return false - if (!tp1 || !tp2) return false - - if (tp1.startsWith('uint')) { - if (tp2.startsWith('int')) return true - if (tp2.startsWith('uint')) { - let i1 = tp1.substring(4) - let i2 = tp2.substring(4) - if (!i1) i1 = '256' - if (!i2) i2 = '256' - return parseInt(i1) < parseInt(i2) - } - } else if (tp1.startsWith('int')) { - if (tp2.startsWith('uint')) return true - if (tp2.startsWith('int')) { - let i1 = tp1.substring(3) - let i2 = tp2.substring(3) - if (!i1) i1 = '256' - if (!i2) i2 = '256' - return parseInt(i1) < parseInt(i2) - } - } - - // return tp1 == tp2; - return false // unknown, not sure -} - -/** - * Pre-computed arrays for integer bits - * @type {Array} - */ -const UintBytes: any[] = [] -const IntBytes: any[] = [] -for (let i = 8; i <= 256; i += 8) { - UintBytes.push({ k: 2 ^ i, tp: { name: `uint${i}` } }) -} -for (let i = 256; i >= 8; i -= 8) { - IntBytes.push({ k: -2 ^ i, tp: { name: `int${i}` } }) -} - -/** - * - * @param node - * @returns {*} - */ -function inferType(node: any): any { - if (!node) return - if (node.typeName) return node.typeName - switch (node.type) { - case 'Literal': { - const n = node.value - if (Number.isInteger(n)) { - if (n >= 0) { - // simply return uint256 - return UintBytes[UintBytes.length - 1] - // for (let pr of UintBytes) { - // if (n < pr.k) - // return pr.tp; - // } - } - for (const pr of IntBytes) { - if (n <= pr.k) return pr.tp - } - } - } - case 'Identifier': - return node.sort - case 'MemberAccess': { - const obj = node.object - if (obj && obj.sort) { - return obj.sort.valueType - } - return inferType(obj) - } - case 'Conditional': { - return inferType(node.trueExpression) - } - default: - if (node.sort) return node.sort - } -} - -module.exports = { - isCompatibleTypes, - inferType, - isLossyConversion, -} diff --git a/src/engine/util/value-util.ts b/src/engine/util/value-util.ts index a90f1fd4..f9b64c44 100644 --- a/src/engine/util/value-util.ts +++ b/src/engine/util/value-util.ts @@ -1,160 +1,5 @@ const Loader = require('../../util/loader') -/** - * replace an analysis value - * discard non-relevant information - * @param node - * @param f - * @returns {*} - */ -function replaceValue(node: any, f: any): any { - if (!node) return - - if (Array.isArray(node)) { - const res: any[] = [] - for (const child of node) { - res.push(replaceValue(child, f)) - } - return res - } - if (node.type) { - let res = f[node] - if (res) return res - - res = { type: node.type } - for (const child in node) { - if (child != 'parent' && child != 'rrefs' && child != 'trace' && node.hasOwnProperty(child)) { - const v = node[child] - if (v.type || v.vtype || Array.isArray(v)) { - res[child] = replaceValue(v, f) - } - } - } - return res - } - if (node.vtype) { - return f(node) - } - return node -} - -/** - * - * @param node - */ -function normalizeVarAccess(node: any): any { - switch (node.type) { - case 'Literal': - case 'Identifier': - case 'Parameter': - case 'VariableDeclarator': - return node - case 'MemberAccess': - return { - type: node.type, - expression: normalizeVarAccess(node.object), - property: normalizeVarAccess(node.property), - } - } - switch (node.vtype) { - case 'object': { - const { parent } = node - if (!parent || parent.vtype === 'scope') { - return node.ast - } - return { type: 'MemberAccess', expression: normalizeVarAccess(parent), property: node.ast } - } - } -} - -/** - * - * @param val1 - * @param val2 - * @returns {*} - */ -function isSameAddress(val1: any, val2: any): boolean { - if (val1 === val2) return true - if (!val1 || !val2) return false - - switch (val1.type) { - case 'MemberAccess': - return isSameAddress(val1.expression, val2.expression) && isSameAddress(val1.property, val2.property) - case 'Identifier': - case 'Parameter': - if (val2.type) return val1.name === val2.name - case 'Literal': - return val1.value === val2.value - } - return false -} - -/** - * compare two values, e.g. two field objects with parents - * @param val1 - * @param val2 - * @returns {*} - */ -function isSameValue(val1: any, val2: any): boolean { - if (val1 === val2) return true - if (!val1 || !val2) return false - - switch (val1.type) { - case 'MemberAccess': - return isSameValue(val1.expression, val2.expression) && isSameValue(val1.property, val2.property) - case 'Identifier': - case 'Parameter': - if (val2.type) return val1.name === val2.name - case 'Literal': - return val1.value === val2.value - case 'UnaryOperation': - return val1.operator === val2.operator && isSameValue(val1.subExpression, val2.subExpression) - case 'BinaryOperation': - return val1.operator === val2.operator && isSameValue(val1.left, val2.left) && isSameValue(val1.right, val2.right) - // default: - // return false; - } - switch (val1.vtype) { - case 'object': - if (val1.id !== val2.id) return false - return isSameValue(val1.parent, val2.parent) - case 'scope': - return val1.id === val2.id - } - return false -} - -/** - * whether the value is associated with a shared variable - * @param val - * @returns {*} - */ -function isFromSharedVar(val: any): any { - if (!val) return false - // the case of heap field - switch (val.vtype) { - case 'object': { - const node = val.ast - if (node) { - if (node.type === 'VariableDeclaration' && node.isStateVar) return node - } - return isFromSharedVar(val.parent) - } - case 'union': { - for (const v of val.value) { - const res = isFromSharedVar(v) - if (res) return res - } - return - } - } - // the case of symbolic identity - switch (val.type) { - case 'MemberAccess': - return isFromSharedVar(val.expression) - } -} - /** * get value from package manager by qid * @param scope @@ -164,34 +9,94 @@ function getValueFromPackageByQid(scope: any, qid: string): any { if (!qid || !qid.includes('.')) { return null } - + if (qid.includes('')) { + const QidUnifyUtil = require('../../util/qid-unify-util') + qid = new QidUnifyUtil(qid).removeGlobal().get() + } qid = qid.startsWith('.') ? qid.slice(1) : qid const arr = Loader.getPackageNameProperties(qid) let packageManagerT = scope arr.forEach((path: string) => { - packageManagerT = packageManagerT?.field[path] + packageManagerT = packageManagerT?.members ? packageManagerT.members.get(path) : packageManagerT?.getMemberValue?.(path) }) return packageManagerT } // *** +// 导入 Value 类(直接路由到构造函数) + +const { UnknownValue } = require('../analyzer/common/value/unkown') +const { UndefinedValue: UndefinedValueClass } = require('../analyzer/common/value/undefine') +const { VoidValue: VoidValueClass } = require('../analyzer/common/value/void') +const { UninitializedValue } = require('../analyzer/common/value/uninit') +const { ObjectValue } = require('../analyzer/common/value/object') +const { Scoped } = require('../analyzer/common/value/scoped') +const { ClassValue } = require('../analyzer/common/value/class') +const { FunctionValue } = require('../analyzer/common/value/function') +const { PrimitiveValue } = require('../analyzer/common/value/primitive') +const { UnionValue: UnionValueClass } = require('../analyzer/common/value/union') +const { SymbolValue } = require('../analyzer/common/value/symbolic') +const { PackageValue } = require('../analyzer/common/value/package') +const { BVTValue } = require('../analyzer/common/value/bvt') +const { TypedValue } = require('../analyzer/common/value/typed') +const { TaintedValue } = require('../analyzer/common/value/tainted') +const { SpreadValue } = require('../analyzer/common/value/spread') +const { ExprValue } = require('../analyzer/common/value/expr-value') +const { BinaryExprValue } = require('../analyzer/common/value/binary-expr') +const { UnaryExprValue } = require('../analyzer/common/value/unary-expr') +const { MemberExprValue } = require('../analyzer/common/value/member-expr') +const { CallExprValue } = require('../analyzer/common/value/call-expr') +const { IdentifierRefValue } = require('../analyzer/common/value/identifier-ref') +const { ValueRefMap } = require('../analyzer/common/value/value-ref-map') +const { ValueRefList } = require('../analyzer/common/value/value-ref-list') + +// 特殊包装函数(只保留无参数或特殊参数的) +function UndefinedValue(opts?: any) { + return new UndefinedValueClass(opts) +} -module.exports = { - replaceValue, - normalizeVarAccess, +function VoidValue() { + return new VoidValueClass() +} - isSameAddress, - isSameValue, +function UnionValue(value?: any[], sid?: string, qid?: string) { + return new UnionValueClass(value, sid, qid) +} - isFromSharedVar, +module.exports = { getValueFromPackageByQid, - ValueUtil: require('../analyzer/common/value/constructor'), Unit: require('../analyzer/common/value/unit'), - Scoped: require('../analyzer/common/value/scoped'), - ObjectValue: require('../analyzer/common/value/object'), - FunctionValue: require('../analyzer/common/value/function'), - PrimitiveValue: require('../analyzer/common/value/primitive'), - SymbolValue: require('../analyzer/common/value/symbolic'), + ValueRefMap, + + ValueUtil: { + // 直接路由到类构造函数 + UnknownValue, + UninitializedValue, + ObjectValue, + Scoped, + ClassValue, + FunctionValue, + PrimitiveValue, + SymbolValue, + PackageValue, + BVTValue, + TypedValue, + TaintedValue, + SpreadValue, + ExprValue, + BinaryExprValue, + UnaryExprValue, + MemberExprValue, + CallExprValue, + IdentifierRefValue, + ValueRefMap, + ValueRefList, + + // 特殊包装函数(无参数或可选参数) + UndefinedValue, + VoidValue, + UnionValue, + }, } diff --git a/src/interface/starter.ts b/src/interface/starter.ts index fdc29ef0..9b5bc45b 100644 --- a/src/interface/starter.ts +++ b/src/interface/starter.ts @@ -1,11 +1,14 @@ /* eslint-disable @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-call, import/no-commonjs, @typescript-eslint/no-use-before-define */ + +import { yasaLog } from "../util/format-util" + const fs = require('fs-extra') const path = require('path') // eslint-disable-next-line @typescript-eslint/naming-convention const _ = require('lodash') const { Command } = require('commander') const Config = require('../config') -const Parsing = require('../engine/parser/parsing') +const Parser = require('../engine/parser/parser') const Stat = require('../util/statistics') const logger = require('../util/logger')(__filename) const FileUtil = require('../util/file-util') @@ -14,29 +17,43 @@ const FrameworkUtil = require('../util/framework-util') const { handleException } = require('../engine/analyzer/common/exception-handler') const OutputStrategyAutoRegister = require('../engine/analyzer/common/output-strategy-auto-register') const { yasaWarning } = require('../util/format-util') +const { logScanSummary, logScanInit } = require('../util/diagnostics-log-util') +const { performanceTracker } = require('../util/performance-tracker') +// eslint-disable-next-line @typescript-eslint/no-require-imports +const { YASA_VERSION } = require('../util/constant') /** * the main entry point of the usual scan * @param {any} dir - Source directory or file path * @param {any[]} args - Command line arguments (default: []) * @param {any} printf - Print function for output (optional) - * @param {any} isSync - Whether to run synchronously (optional) * @returns {Promise} Analyzer results or undefined */ -async function execute(dir: any, args: any[] = [], printf?: any, isSync?: any) { +async function execute(dir: any, args: any[] = [], printf?: any) { + // 记录整个程序开始时间(端到端时间) + performanceTracker.start() + let result: any + + // 为了保证兼容性,目前 analyzer 只有 yasa analyzer 和 null 两种 const analyzer = await initAnalyzer(dir, args, printf) + if (analyzer) { const processingDir = Config.maindir - let isSuccess = false - if (!isSync) { - isSuccess = await executeAnalyzerAsync(analyzer, processingDir) - } else { - isSuccess = executeAnalyzer(analyzer, processingDir) - } - if (isSuccess) { - return outputAnalyzerResult(analyzer, printf) + const exitCode = await executeAnalyzer(analyzer, processingDir) + process.exitCode = exitCode + if (exitCode === 0) { + result = await outputAnalyzerResult(analyzer, printf) } } + + // 输出性能报告(如果执行过 collectAnalysisData(analyzer) 则输出 overview,否则只输出 summary) + performanceTracker.outputPerformanceReport() + + if (analyzer) { + logScanSummary(analyzer, performanceTracker) + } + + return result } /** @@ -45,7 +62,7 @@ async function execute(dir: any, args: any[] = [], printf?: any, isSync?: any) { * @param {any} printf - Print function for output * @returns {any} All findings or null */ -function outputAnalyzerResult(analyzer: any, printf: any) { +async function outputAnalyzerResult(analyzer: any, printf: any) { if (!printf || typeof printf !== 'function') { printf = logger.info.bind(logger) } @@ -66,6 +83,7 @@ function outputAnalyzerResult(analyzer: any, printf: any) { yasaSeparator('') } logger.info('analyze done') + return allFindings } @@ -85,6 +103,8 @@ async function initAnalyzer(dir: any, args: any[] = [], printf?: any) { } // 标记是否显式设置了 --intermediate-dir let intermediateDirExplicitlySet = false + // 标记是否显式设置了 --context-environment-dir + let contextEnvironmentDirExplicitlySet = false // load the basic configuration from e.g. 'config.json' loadConfig(Config.configFilePath) @@ -139,7 +159,7 @@ async function initAnalyzer(dir: any, args: any[] = [], printf?: any) { .option('--ruleConfigFile ', '指定规则配置文件', (file: any) => { const ruleConfigFile = path.isAbsolute(file) ? file : path.resolve(path.join(process.cwd(), file)) Config.ruleConfigFile = ruleConfigFile - logger.info('Rule config file: ', ruleConfigFile) + yasaLog(`Using rule config file: ${ruleConfigFile}`, 'init') }) .option('--entrypointMode ', '指定入口点模式(BOTH/SELF_COLLECT/ONLY_CUSTOM)', (mode: any) => { const validModes = ['BOTH', 'SELF_COLLECT', 'ONLY_CUSTOM'] @@ -152,17 +172,17 @@ async function initAnalyzer(dir: any, args: any[] = [], printf?: any) { } else { Config.entryPointMode = mode } - logger.info('EntrypointMode set: ', mode) + yasaLog(`EntrypointMode set: ${mode}`, 'init') }) .option('--checkerIds ', '指定检查器id列表(逗号分隔)', (list: any) => { const checkerIds = list.split(',') Config.checkerIds = _.assign(Config.checkerIds, checkerIds) - logger.info('Specific checkerIds:', checkerIds) + yasaLog(`Specified checker IDs: [${checkerIds.join(', ')}]`, 'init') }) .option('--checkerPackIds ', '指定检查器组id列表(逗号分隔)', (list: any) => { const checkerPackIds = list.split(',') Config.checkerPackIds = _.assign(Config.checkerPackIds, checkerPackIds) - logger.info('Specific checkerPackIds:', checkerPackIds) + yasaLog(`Specified checker pack IDs: [${checkerPackIds.join(', ')}]`, 'init') }) .option('--dumpAST', 'dump单文件AST', () => { Config.dumpAST = true @@ -254,6 +274,50 @@ async function initAnalyzer(dir: any, args: any[] = [], printf?: any) { .option('--cgAlgo ', '指定构建CallGraph的算法', (cgAlgo: any) => { Config.cgAlgo = cgAlgo }) + .option('--taintTraceOutputStrategy ', '污点追踪输出策略(callstack-only/full)', (strategy: any) => { + Config.taintTraceOutputStrategy = strategy + }) + .option('--workerCount ', '指定Worker数量(0表示自动计算,>0表示使用设置的值)', (count: any) => { + const workerCount = parseInt(count, 10) + if (Number.isNaN(workerCount) || workerCount < 0) { + handleException( + null, + 'ERROR: --workerCount must be a non-negative integer', + 'ERROR: --workerCount must be a non-negative integer' + ) + process.exit(1) + } + Config.workerCount = workerCount + }) + .option('--contextEnvironmentDir ', '指定上下文环境缓存目录路径', (contextEnvironmentDir: any) => { + contextEnvironmentDirExplicitlySet = true + // 检查如果目录为空,提示错误并禁用上下文环境功能 + if (!contextEnvironmentDir || contextEnvironmentDir.trim() === '') { + handleException( + null, + 'ERROR: --contextEnvironmentDir cannot be empty. Context environment features will be disabled.', + 'ERROR: --contextEnvironmentDir cannot be empty. Context environment features will be disabled.' + ) + Config.saveContextEnvironment = false + Config.miniSaveContextEnvironment = false + Config.loadContextEnvironment = false + Config.contextEnvironmentDir = '' + } else { + Config.contextEnvironmentDir = contextEnvironmentDir + } + }) + .option('--saveContextEnvironment', '保存上下文环境模式', () => { + Config.saveContextEnvironment = true + }) + .option('--miniSaveContextEnvironment', '保存上下文环境模式', () => { + Config.miniSaveContextEnvironment = true + }) + .option('--loadContextEnvironment', '加载上下文环境模式', () => { + Config.loadContextEnvironment = true + }) + .option('--loadContextEnvironmentId ', '加载上下文环境模式', (id: any) => { + Config.loadContextEnvironmentId = id + }) // 处理非选项参数(如直接传入的目录) program.arguments('[paths...]').action((paths: any) => { if (paths.length > 0) { @@ -279,7 +343,7 @@ async function initAnalyzer(dir: any, args: any[] = [], printf?: any) { }) // 处理未知选项 - program.allowUnknownOption(false) + program.allowUnknownOption(true) program.allowExcessArguments() // 处理帮助信息 @@ -287,7 +351,7 @@ async function initAnalyzer(dir: any, args: any[] = [], printf?: any) { printHelp() }) - program.version('0.2.6-inner') + program.version(YASA_VERSION) // 解析命令行参数 program.parse(args, { from: 'user' }) @@ -305,6 +369,20 @@ async function initAnalyzer(dir: any, args: any[] = [], printf?: any) { Config.intermediateDir = '' } + // 检查如果启用了保存或加载上下文环境,但 --context-environment-dir 未设置或为空,则禁用相关功能 + if ( + (Config.saveContextEnvironment || Config.loadContextEnvironment || Config.miniSaveContextEnvironment) && + (!contextEnvironmentDirExplicitlySet || !Config.contextEnvironmentDir || Config.contextEnvironmentDir.trim() === '') + ) { + yasaWarning( + '--context-environment-dir must be specified when save-context-environment or load-context-environment is enabled. Context environment features will be disabled.' + ) + Config.saveContextEnvironment = false + Config.loadContextEnvironment = false + Config.miniSaveContextEnvironment = false + Config.contextEnvironmentDir = '' + } + Stat.parsingTime = 0 // 解析分析目标 @@ -320,7 +398,7 @@ async function initAnalyzer(dir: any, args: any[] = [], printf?: any) { maindir += '/' } // record the main directory - logger.info(`source path: ${maindir}`) + yasaLog(`Source path: ${maindir}`, 'init') Config.maindir = maindir Config.maindirPrefix = maindir.substring(0, maindir.lastIndexOf('/')) } catch (e: any) { @@ -375,7 +453,7 @@ async function initAnalyzer(dir: any, args: any[] = [], printf?: any) { fs.mkdirSync(reportPathAbs, { recursive: true }) } } - logger.info('Report directory:', Config.reportDir) + yasaLog(`Report directory: ${Config.reportDir}`, 'init') } } @@ -395,9 +473,9 @@ async function initAnalyzer(dir: any, args: any[] = [], printf?: any) { return } if (Config.ASTFileOutput) { - dumpAST(apps, fs.writeFileSync) + await dumpAST(apps, fs.writeFileSync) } else { - dumpAST(apps, logger.info.bind(logger)) + await dumpAST(apps, logger.info.bind(logger)) } process.exit(0) } @@ -405,7 +483,14 @@ async function initAnalyzer(dir: any, args: any[] = [], printf?: any) { // dump all AST if (Config.dumpAllAST) { try { - await Parsing.parseDirectory(Config.maindir, Config) + // 确保 reportDir 存在 + if (!Config.reportDir) { + Config.reportDir = './uastParseDir' + } + + // 使用统一接口导出所有 AST + await Parser.dumpAllAST(Config.maindir, Config.reportDir, Config) + logger.info('parseDirectory UAST success!') process.exit(0) } catch (e: any) { @@ -485,55 +570,34 @@ async function initAnalyzer(dir: any, args: any[] = [], printf?: any) { Config.analyzer = f Analyzer = (analyzerEnum as any)[Config.analyzer] } - logger.info(`Analyze Language: ${Config.language}`) - logger.info(`Analyze Analyer: ${Config.analyzer}`) + yasaLog(`Analysis language: ${Config.language}`, 'init') + yasaLog(`Analysis analyzer: ${Config.analyzer}`, 'init') + logScanInit(performanceTracker) return new Analyzer(Config) } /** - * Execute analyzer asynchronously + * Execute analyzer * @param {any} analyzer - The analyzer instance * @param {any} processingDir - Directory to process - * @returns {Promise} Success status + * @returns {Promise} Exit code: 0 for success, 1 for failure */ -async function executeAnalyzerAsync(analyzer: any, processingDir: any) { +async function executeAnalyzer(analyzer: any, processingDir: any): Promise { try { if (Config.single) { const source = fs.readFileSync(processingDir, 'utf8') - if (!analyzer.analyzeSingleFile(source, processingDir)) { - return false + const singleFileResult = await analyzer.analyzeSingleFile(source, processingDir) + if (!singleFileResult) { + return 1 } - } else if (!(await analyzer.analyzeProjectAsync(processingDir))) { - return false - } - return true - } catch (e: any) { - handleException(e, 'Error occurred in executeAnalyzerAsync!!!!', 'Error occurred in executeAnalyzerAsync!!!!') - } - return false -} - -/** - * Execute analyzer synchronously - * @param {any} analyzer - The analyzer instance - * @param {any} processingDir - Directory to process - * @returns {boolean} Success status - */ -function executeAnalyzer(analyzer: any, processingDir: any) { - try { - if (Config.single) { - const source = fs.readFileSync(processingDir, 'utf8') - if (!analyzer.analyzeSingleFile(source, processingDir)) { - return false - } - } else if (!analyzer.analyzeProject(processingDir)) { - return false + } else if (!(await analyzer.analyzeProject(processingDir))) { + return 1 } - return true + return 0 } catch (e: any) { - handleException(e, 'Error in executeAnalyzerAsync occurred!!!!', 'Error in executeAnalyzerAsync occurred!!!!') + handleException(e, 'Error occurred in executeAnalyzer!!!!', 'Error occurred in executeAnalyzer!!!!') + return 1 } - return false } // 递归函数,用于删除对象及其子对象中的 'parent' 属性 @@ -583,7 +647,9 @@ function loadSource(absdirs: any) { case 'js': case 'typescript': case 'ts': - fext = ['js', 'ts', 'cjs', 'mjs'] + case 'jsx': + case 'tsx': + fext = ['js', 'ts', 'cjs', 'mjs', 'jsx', 'tsx'] dirFilter.push('node_modules') break case 'java': @@ -689,14 +755,20 @@ function printHelp() { * @param {any} apps - Array of application objects with file and content * @param {any} printf - Print function for output */ -function dumpAST(apps: any, printf: any) { +async function dumpAST(apps: any, printf: any) { + const { deleteParent } = require('../util/ast-util') for (const app of apps) { if (!Config.ASTFileOutput) { printf('dump file AST:', app.file) } Config.sourcefile = app.file - const ast = Parsing.parseCodeRaw(app.file, app.content, Config) - // golang较为特殊,它是返回的是promise,单独处理 + // 使用统一接口 parseSingleFile,传入源代码缓存对象,然后删除 parent 指针 + // 创建 sourceCodeCache 对象,将文件路径映射到内容(存储为行数组) + const sourceCodeCache = new Map() + sourceCodeCache.set(app.file, app.content.split(/\n/)) + // eslint-disable-next-line no-await-in-loop + const ast = Parser.parseSingleFile(app.file, Config, sourceCodeCache) + deleteParent(ast) if (Config.language !== 'golang') { const parseResult = JSON.stringify(ast) if (Config.ASTFileOutput) { @@ -748,6 +820,8 @@ function detectFileLanguage(filename: any) { case 'js': case 'mjs': case 'cjs': + case 'tsx': + case 'jsx': return 'javascript' case 'go': return 'golang' diff --git a/src/main.ts b/src/main.ts index 7ff403d9..e162685f 100644 --- a/src/main.ts +++ b/src/main.ts @@ -1,10 +1,14 @@ +import v8 from 'v8' + const { execute } = require('./interface/starter') const logger = require('./util/logger')(__filename) const { ErrorCode: ErrorCodeMain } = require('./util/error-code') - const { handleException: handleExceptionMain } = require('./engine/analyzer/common/exception-handler') +const { YASA_VERSION } = require('./util/constant') ;(async function run() { + logger.info(`version: ${YASA_VERSION}`) + logger.info(`v8 heap_size_limit: ${v8.getHeapStatistics().heap_size_limit / 1024 / 1024}`, 'MB') logger.info(`main file:${require.main?.filename}`) try { const args = process.argv.slice(2) diff --git a/src/report/report.sarif b/src/report/report.sarif deleted file mode 100644 index 0a9885e3..00000000 --- a/src/report/report.sarif +++ /dev/null @@ -1 +0,0 @@ -{"runs":[{"tool":{"driver":{"name":"yasa","version":"0.1"}},"graphs":[{"description":{"text":"call graph"},"nodes":[{"id":"<__entry_point__>"},{"id":"/src/test..range"},{"id":"/src/test..print"},{"id":"/src/test.print"},{"id":"syslib_from.logging.getLogger"},{"id":"get_server_tenant_tqps_monitor \\n[db_monitor_client.py : 231_238]","location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-db-base/src/mcp_db_base/db_monitor_client.py"},"region":{"startLine":231,"startColumn":1,"endLine":238,"endColumn":74,"snippet":{}}}}},{"id":"deal_server_port \\n[db_monitor_client.py : 12_16]","location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-db-base/src/mcp_db_base/db_monitor_client.py"},"region":{"startLine":12,"startColumn":1,"endLine":16,"endColumn":22,"snippet":{}}}}},{"id":"mcp_db_base.maas_sql_client.get_multi_metric"},{"id":"mcp_db_base.maas_sql_client.process_timeseries_data"},{"id":"syslib_from.json.dumps"},{"id":"syslib_from.asyncio.run"},{"id":"/src/mcp-db-base/src/mcp_db_base/db_monitor_client..print"},{"id":"/src/mcp-db-base/src/mcp_db_base/dba_metadata_utils.DbSlot.Field"},{"id":"/src/mcp-db-base/src/mcp_db_base/dba_metadata_utils.DBMetadata.Field"},{"id":"DBAMetadataUtil :: __init__ \\n[dba_metadata_utils.py : 86_89]","location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-db-base/src/mcp_db_base/dba_metadata_utils.py"},"region":{"startLine":86,"startColumn":5,"endLine":89,"endColumn":37,"snippet":{}}}}},{"id":"get_db_meta \\n[dba_metadata_utils.py : 514_546]","location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-db-base/src/mcp_db_base/dba_metadata_utils.py"},"region":{"startLine":514,"startColumn":1,"endLine":546,"endColumn":43,"snippet":{}}}}},{"id":"syslib_from.logging.getLogger(__name__).info"},{"id":"DBAMetadataUtil :: fill_app_db_info \\n[dba_metadata_utils.py : 224_293]","location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-db-base/src/mcp_db_base/dba_metadata_utils.py"},"region":{"startLine":224,"startColumn":5,"endLine":293,"endColumn":45,"snippet":{}}}}},{"id":"mcp_db_base.omc_client.get_app_dbs"},{"id":"/src/mcp-db-base/src/mcp_db_base/dba_metadata_utils.DBAMetadataUtil.fill_app_db_info.fill_app_db_info_scope..len"},{"id":"mcp_db_base.omc_client.get_app_dbs(db_target.app, var site:any=db_target.site, var env:any=db_target.env).get"},{"id":"DBAMetadataUtil :: _get_physics_db_info \\n[dba_metadata_utils.py : 488_500]","location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-db-base/src/mcp_db_base/dba_metadata_utils.py"},"region":{"startLine":488,"startColumn":5,"endLine":500,"endColumn":24,"snippet":{}}}}},{"id":"mcp_db_base.omc_client.get_dbs"},{"id":"/src/mcp-db-base/src/mcp_db_base/dba_metadata_utils.DBAMetadataUtil._get_physics_db_info._get_physics_db_info_scope....len"},{"id":"mcp_db_base.omc_client.get_dbs(var db:any=logic_arn).get"},{"id":"db_metadata.tenant_arn.split"},{"id":"DBAMetadataUtil :: _fill_db_cluster \\n[dba_metadata_utils.py : 502_511]","location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-db-base/src/mcp_db_base/dba_metadata_utils.py"},"region":{"startLine":502,"startColumn":5,"endLine":511,"endColumn":26,"snippet":{}}}}},{"id":"mcp_db_base.omc_client.get_tenant_info"},{"id":"mcp_db_base.omc_client.get_tenant_info(var tenant:any=tenant_arn).get"},{"id":"mcp_db_base.omc_client.get_tenant_info(var tenant:any=tenant_arn).get(clusterArn).split"},{"id":"get"},{"id":"mcp_db_base.omc_client.get_app_dbs(db_target.app, var site:any=db_target.site, var env:any=db_target.env).get(tenantArn).split"},{"id":"split"},{"id":"tenant_arn.split"},{"id":"db_metadata.append"},{"id":"append"},{"id":"DBAMetadataUtil :: fill_table_info \\n[dba_metadata_utils.py : 383_476]","location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-db-base/src/mcp_db_base/dba_metadata_utils.py"},"region":{"startLine":383,"startColumn":5,"endLine":476,"endColumn":37,"snippet":{}}}}},{"id":"mcp_db_base.omc_client.get_logic_dbs"},{"id":"mcp_db_base.omc_client.get_logic_dbs(var arn:any=table_arn).get"},{"id":"DBAMetadataUtil :: _set_app_by_logic \\n[dba_metadata_utils.py : 478_486]","location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-db-base/src/mcp_db_base/dba_metadata_utils.py"},"region":{"startLine":478,"startColumn":5,"endLine":486,"endColumn":53,"snippet":{}}}}},{"id":"mcp_db_base.omc_client.get_apps"},{"id":"mcp_db_base.omc_client.get_apps(var app_name:any=db_metadata.app_name, var site:any=db_metadata.site, var env:any=db_metadata.env).get"},{"id":"mcp_db_base.omc_client.get_logic_tables"},{"id":"mcp_db_base.omc_client.get_logic_tables(var table:any=table_info).get"},{"id":"mcp_db_base.omc_client.get_name_by_arn"},{"id":"mcp_db_base.omc_client.get_tables"},{"id":"mcp_db_base.omc_client.get_tables(var table:any=table_info).get"},{"id":"DBAMetadataUtil :: fill_db_info \\n[dba_metadata_utils.py : 110_205]","location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-db-base/src/mcp_db_base/dba_metadata_utils.py"},"region":{"startLine":110,"startColumn":5,"endLine":205,"endColumn":41,"snippet":{}}}}},{"id":"mcp_db_base.omc_client.get_logic_dbs(var arn:any=db_arn).get"},{"id":"DBAMetadataUtil :: _filter_physic_dbs \\n[dba_metadata_utils.py : 207_221]","location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-db-base/src/mcp_db_base/dba_metadata_utils.py"},"region":{"startLine":207,"startColumn":5,"endLine":221,"endColumn":23,"snippet":{}}}}},{"id":"....get"},{"id":"mcp_db_base.omc_client.get_dbs(var db:any=logic_arn).get(tenantArn, ...).find"},{"id":"get(tenantArn, ...).find"},{"id":"....get(tenantArn, ...).find"},{"id":"DBAMetadataUtil :: _add_confirm_pyhsic_dbs \\n[dba_metadata_utils.py : 91_108]","location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-db-base/src/mcp_db_base/dba_metadata_utils.py"},"region":{"startLine":91,"startColumn":5,"endLine":108,"endColumn":45,"snippet":{}}}}},{"id":"....get(tenantArn).split"},{"id":"mcp_db_base.omc_client.get_dbs(var db:any=logic_arn).get(tenantArn).split"},{"id":"get(tenantArn).split"},{"id":"extend"},{"id":"mcp_db_base.omc_client.get_dbs(var db:any=db_arn).get"},{"id":"mcp_db_base.omc_client.get_dbs(var db:any=db_arn).get(tenantArn, ...).find"},{"id":"mcp_db_base.omc_client.get_dbs(var db:any=db_arn).get(tenantArn).split"},{"id":"db_metadatas.append"},{"id":"physics_dbs.extend"},{"id":"mcp_db_base.omc_client.get_db_by_search_name"},{"id":"mcp_db_base.omc_client.get_db_by_search_name(var is_logic:any=is_logic, var search_name:any=%+searchName+%, var site:any=db_target.site, var env:any=db_target.env).get"},{"id":"/src/mcp-db-base/src/mcp_db_base/dba_metadata_utils.DBAMetadataUtil.fill_db_info.fill_db_info_scope..............print"},{"id":"get_single_metric \\n[maas_sql_client.py : 190_196]","location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-db-base/src/mcp_db_base/maas_sql_client.py"},"region":{"startLine":190,"startColumn":1,"endLine":196,"endColumn":18,"snippet":{}}}}},{"id":"ob@@vm_system@@node@@DEFAULT@@1@@DEFAULT.where_condition.format"},{"id":"`node` = \\'{node}\\'.where_condition.format"},{"id":"get_maas_sql_data \\n[maas_sql_client.py : 155_177]","location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-db-base/src/mcp_db_base/maas_sql_client.py"},"region":{"startLine":155,"startColumn":1,"endLine":177,"endColumn":33,"snippet":{}}}}},{"id":"replace_seconds_with_zero \\n[maas_sql_client.py : 218_230]","location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-db-base/src/mcp_db_base/maas_sql_client.py"},"region":{"startLine":218,"startColumn":1,"endLine":230,"endColumn":24,"snippet":{}}}}},{"id":"syslib_from.re.sub"},{"id":"replace_func \\n[maas_sql_client.py : 224_225]","location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-db-base/src/mcp_db_base/maas_sql_client.py"},"region":{"startLine":224,"startColumn":5,"endLine":225,"endColumn":38,"snippet":{}}}}},{"id":"match.group"},{"id":"_headers \\n[maas_sql_client.py : 62_85]","location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-db-base/src/mcp_db_base/maas_sql_client.py"},"region":{"startLine":62,"startColumn":1,"endLine":85,"endColumn":19,"snippet":{}}}}},{"id":"syslib_from.os.environ.get"},{"id":"syslib_from.time.time"},{"id":"/src/mcp-db-base/src/mcp_db_base/maas_sql_client._headers._headers_scope..int"},{"id":"syslib_from.random.sample"},{"id":"join"},{"id":"/src/mcp-db-base/src/mcp_db_base/maas_sql_client._headers._headers_scope..str"},{"id":"syslib_from.base64.b64decode"},{"id":"/src/mcp-db-base/src/mcp_db_base/maas_sql_client._headers._headers_scope..bytes"},{"id":"syslib_from.hmac.new"},{"id":"syslib_from.hmac.new(var key:any=base64.b64decode(_SECRET_KEY), var msg:any=bytes(msg, var encoding:any=utf-8), var digestmod:any=hashlib.sha256).digest"},{"id":"syslib_from.base64.b64encode"},{"id":"call_maas_sql_api \\n[maas_sql_client.py : 88_134]","location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-db-base/src/mcp_db_base/maas_sql_client.py"},"region":{"startLine":88,"startColumn":1,"endLine":134,"endColumn":66,"snippet":{}}}}},{"id":"mcp_common.request.http_client.AsyncRestClient"},{"id":"POST.lower"},{"id":"/src/mcp-db-base/src/mcp_db_base/maas_sql_client.call_maas_sql_api.call_maas_sql_api_scope..getattr"},{"id":"/src/mcp-db-base/src/mcp_db_base/maas_sql_client.call_maas_sql_api.call_maas_sql_api_scope..getattr(client, method.lower())"},{"id":"/src/mcp-db-base/src/mcp_db_base/maas_sql_client.call_maas_sql_api.call_maas_sql_api_scope..getattr(client, method.lower())(var endpoint:any=endpoint, var null:any=request_kwargs).g..."},{"id":"/src/mcp-db-base/src/mcp_db_base/maas_sql_client.call_maas_sql_api.call_maas_sql_api_scope...isinstance"},{"id":"syslib_from.json.loads"},{"id":"_handle_empty_response \\n[maas_sql_client.py : 137_143]","location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-db-base/src/mcp_db_base/maas_sql_client.py"},"region":{"startLine":137,"startColumn":1,"endLine":143,"endColumn":6,"snippet":{}}}}},{"id":"/src/mcp-db-base/src/mcp_db_base/maas_sql_client._handle_empty_response._handle_empty_response_scope..ValueError"},{"id":"_handle_error_response \\n[maas_sql_client.py : 146_152]","location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-db-base/src/mcp_db_base/maas_sql_client.py"},"region":{"startLine":146,"startColumn":1,"endLine":152,"endColumn":6,"snippet":{}}}}},{"id":"/src/mcp-db-base/src/mcp_db_base/maas_sql_client._handle_error_response._handle_error_response_scope..ValueError"},{"id":"/src/mcp-db-base/src/mcp_db_base/maas_sql_client.call_maas_sql_api.call_maas_sql_api_scope...str"},{"id":"syslib_from.logging.getLogger(__name__).error"},{"id":"/src/mcp-db-base/src/mcp_db_base/maas_sql_client.call_maas_sql_api.call_maas_sql_api_scope...ValueError"},{"id":"syslib_from.logging.getLogger(__name__).exception"},{"id":"/src/mcp-db-base/src/mcp_db_base/maas_sql_client.get_maas_sql_data.get_maas_sql_data_scope...str"},{"id":"/src/mcp-db-base/src/mcp_db_base/maas_sql_client.get_maas_sql_data.get_maas_sql_data_scope...ValueError"},{"id":"/src/mcp-db-base/src/mcp_db_base/maas_sql_client..print"},{"id":"get_cluster_arch \\n[ocp_client.py : 81_135]","location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-db-base/src/mcp_db_base/ocp_client.py"},"region":{"startLine":81,"startColumn":1,"endLine":135,"endColumn":33,"snippet":{}}}}},{"id":"mcp_common.utils.mist_util.get_mist_secret"},{"id":"/src/mcp-db-base/src/mcp_db_base/ocp_client.get_cluster_arch.get_cluster_arch_scope...str"},{"id":"/src/mcp-db-base/src/mcp_db_base/ocp_client.get_cluster_arch.get_cluster_arch_scope...print"},{"id":"syslib_from.logging.getLogger(__name__).debug"},{"id":"round"},{"id":"int"},{"id":"str"},{"id":"temp_params.copy"},{"id":"rpc_sign \\n[ocp_client.py : 32_62]","location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-db-base/src/mcp_db_base/ocp_client.py"},"region":{"startLine":32,"startColumn":1,"endLine":62,"endColumn":21,"snippet":{}}}}},{"id":"temp_params.keys"},{"id":"/src/mcp-db-base/src/mcp_db_base/ocp_client.rpc_sign.rpc_sign_scope..sorted"},{"id":"percent_encode \\n[ocp_client.py : 65_67]","location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-db-base/src/mcp_db_base/ocp_client.py"},"region":{"startLine":65,"startColumn":1,"endLine":67,"endColumn":87,"snippet":{}}}}},{"id":"/src/mcp-db-base/src/mcp_db_base/ocp_client.percent_encode.percent_encode_scope..str"},{"id":"/src/mcp-db-base/src/mcp_db_base/ocp_client.percent_encode.percent_encode_scope..urllib.parse.quote"},{"id":"/src/mcp-db-base/src/mcp_db_base/ocp_client.percent_encode.percent_encode_scope..urllib.parse.quote(str(s), var safe:any=).replace"},{"id":"/src/mcp-db-base/src/mcp_db_base/ocp_client.percent_encode.percent_encode_scope..urllib.parse.quote(str(s), var safe:any=).replace(+, %20).replace"},{"id":"&.join"},{"id":"encode"},{"id":"&.join({0:percent_encode(method), 1:percent_encode(/), 2:percent_encode(param_str)}).encode"},{"id":"syslib_from.hmac.new(key, string_to_sign.encode(utf-8), sha1).digest"},{"id":"syslib_from.base64.b64encode(hashed.digest()).decode"},{"id":"temp_params.copy().update"},{"id":"get_url \\n[ocp_client.py : 77_78]","location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-db-base/src/mcp_db_base/ocp_client.py"},"region":{"startLine":77,"startColumn":1,"endLine":78,"endColumn":30,"snippet":{}}}}},{"id":"dbass_auth_header \\n[ocp_client.py : 70_74]","location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-db-base/src/mcp_db_base/ocp_client.py"},"region":{"startLine":70,"startColumn":1,"endLine":74,"endColumn":6,"snippet":{}}}}},{"id":"mcp_common.request.http_client.AsyncRestClient(var base_url:any=get_url(site, env), var max_connections:any=50, var timeout:any=15, var retries:any=3, var default_headers:any=dbass_auth_header()).get"},{"id":"mcp_common.request.http_client.AsyncRestClient(var base_url:any=get_url(site, env), var max_connections:any=50, var timeout:any=15, var retries:any=3, var default_headers:any=dbass_auth_header()).get(..."},{"id":"/src/mcp-db-base/src/mcp_db_base/ocp_client.get_cluster_arch.get_cluster_arch_scope...ValueError"},{"id":"/src/mcp-db-base/src/mcp_db_base/ocp_client.get_cluster_arch.get_cluster_arch_scope...str"},{"id":"/src/mcp-db-base/src/mcp_db_base/ocp_client.get_cluster_arch.get_cluster_arch_scope...ValueError"},{"id":"/src/mcp-db-base/src/mcp_db_base/ocp_client.get_cluster_arch.get_cluster_arch_scope...str"},{"id":"/src/mcp-db-base/src/mcp_db_base/ocp_client.get_cluster_arch.get_cluster_arch_scope...ValueError"},{"id":"/src/mcp-db-base/src/mcp_db_base/ocp_client..print"},{"id":"get_dbs \\n[omc_client.py : 169_194]","location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-db-base/src/mcp_db_base/omc_client.py"},"region":{"startLine":169,"startColumn":1,"endLine":194,"endColumn":33,"snippet":{}}}}},{"id":"is_arn \\n[omc_client.py : 581_585]","location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-db-base/src/mcp_db_base/omc_client.py"},"region":{"startLine":581,"startColumn":1,"endLine":585,"endColumn":21,"snippet":{}}}}},{"id":"acs:alipay:rds::ipay:logic-database:221604704.isupportcenter.startswith"},{"id":"params.update"},{"id":"is_logic_arn \\n[omc_client.py : 588_590]","location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-db-base/src/mcp_db_base/omc_client.py"},"region":{"startLine":588,"startColumn":1,"endLine":590,"endColumn":43,"snippet":{}}}}},{"id":"syslib_from.re.fullmatch"},{"id":"/src/mcp-db-base/src/mcp_db_base/omc_client.is_logic_arn.is_logic_arn_scope..bool"},{"id":"_headers \\n[omc_client.py : 29_49]","location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-db-base/src/mcp_db_base/omc_client.py"},"region":{"startLine":29,"startColumn":1,"endLine":49,"endColumn":6,"snippet":{}}}}},{"id":"datetime.datetime.now"},{"id":"datetime.datetime.now().strftime"},{"id":"syslib_from.base64.b64decode(OMC_TOKEN).decode"},{"id":"syslib_from.base64.b64decode(OMC_TOKEN).decode(utf-8).encode"},{"id":"syslib_from.hmac.new(access_key.encode(), api_uri+access_id+timestamp.encode(), hashlib.sha1).digest"},{"id":"syslib_from.base64.b64encode(hmac.new(access_key.encode(), api_uri+access_id+timestamp.encode(), hashlib.sha1).digest()).decode"},{"id":"call_omc_api \\n[omc_client.py : 63_105]","location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-db-base/src/mcp_db_base/omc_client.py"},"region":{"startLine":63,"startColumn":1,"endLine":105,"endColumn":65,"snippet":{}}}}},{"id":"get_url \\n[omc_client.py : 52_60]","location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-db-base/src/mcp_db_base/omc_client.py"},"region":{"startLine":52,"startColumn":1,"endLine":60,"endColumn":29,"snippet":{}}}}},{"id":"OMC_URL.get"},{"id":"/src/mcp-db-base/src/mcp_db_base/omc_client.get_url.get_url_scope..site_map.get"},{"id":"GET.lower"},{"id":"/src/mcp-db-base/src/mcp_db_base/omc_client.call_omc_api.call_omc_api_scope..getattr"},{"id":"/src/mcp-db-base/src/mcp_db_base/omc_client.call_omc_api.call_omc_api_scope..getattr(client, method.lower())"},{"id":"/src/mcp-db-base/src/mcp_db_base/omc_client.call_omc_api.call_omc_api_scope..getattr(client, method.lower())(var endpoint:any=endpoint, var null:any=request_kwargs).get"},{"id":"_handle_error_response \\n[omc_client.py : 142_148]","location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-db-base/src/mcp_db_base/omc_client.py"},"region":{"startLine":142,"startColumn":1,"endLine":148,"endColumn":6,"snippet":{}}}}},{"id":"/src/mcp-db-base/src/mcp_db_base/omc_client._handle_error_response._handle_error_response_scope..ValueError"},{"id":"/src/mcp-db-base/src/mcp_db_base/omc_client.call_omc_api.call_omc_api_scope...str"},{"id":"/src/mcp-db-base/src/mcp_db_base/omc_client.call_omc_api.call_omc_api_scope...ValueError"},{"id":"/src/mcp-db-base/src/mcp_db_base/omc_client.get_dbs.get_dbs_scope...str"},{"id":"/src/mcp-db-base/src/mcp_db_base/omc_client.get_dbs.get_dbs_scope...ValueError"},{"id":"/src/mcp-db-base/src/mcp_db_base/omc_client..print"},{"id":"get_ob_capacity_monitor \\n[prometheus_client.py : 262_303]","location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-db-base/src/mcp_db_base/prometheus_client.py"},"region":{"startLine":262,"startColumn":1,"endLine":303,"endColumn":33,"snippet":{}}}}},{"id":"mcp_db_base.db_utils.str_to_timestamp"},{"id":"|.join"},{"id":"/src/mcp-db-base/src/mcp_db_base/prometheus_client.get_ob_capacity_monitor.get_ob_capacity_monitor_scope...len"},{"id":"/src/mcp-db-base/src/mcp_db_base/prometheus_client.get_ob_capacity_monitor.get_ob_capacity_monitor_scope...params.update"},{"id":"call_promtheus_api \\n[prometheus_client.py : 102_159]","location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-db-base/src/mcp_db_base/prometheus_client.py"},"region":{"startLine":102,"startColumn":1,"endLine":159,"endColumn":14,"snippet":{}}}}},{"id":"get_promtheus_url \\n[prometheus_client.py : 55_76]","location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-db-base/src/mcp_db_base/prometheus_client.py"},"region":{"startLine":55,"startColumn":1,"endLine":76,"endColumn":14,"snippet":{}}}}},{"id":"query_promtheus_db \\n[prometheus_client.py : 17_52]","location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-db-base/src/mcp_db_base/prometheus_client.py"},"region":{"startLine":17,"startColumn":1,"endLine":52,"endColumn":18,"snippet":{}}}}},{"id":"syslib_from.pymysql.connect"},{"id":"syslib_from.pymysql.connect(var host:any=DB_PROXY_URL, var port:any=DB_PROXY_PORT, var user:any=USER, var password:any=PASSWORD, var database:any=ob_event_hub, var charset:any=utf8mb4, var cursorclass..."},{"id":"/src/mcp-db-base/src/mcp_db_base/prometheus_client.get_promtheus_url.get_promtheus_url_scope...ValueError"},{"id":"/src/mcp-db-base/src/mcp_db_base/prometheus_client.query_promtheus_db.query_promtheus_db_scope..result.keys"},{"id":"/src/mcp-db-base/src/mcp_db_base/prometheus_client.get_promtheus_url.get_promtheus_url_scope..list"},{"id":"/src/mcp-db-base/src/mcp_db_base/prometheus_client.get_promtheus_url.get_promtheus_url_scope..len"},{"id":"/src/mcp-db-base/src/mcp_db_base/prometheus_client.get_promtheus_url.get_promtheus_url_scope...ValueError"},{"id":"/src/mcp-db-base/src/mcp_db_base/prometheus_client.query_promtheus_db.query_promtheus_db_scope..result.get"},{"id":"_headers \\n[prometheus_client.py : 79_81]","location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-db-base/src/mcp_db_base/prometheus_client.py"},"region":{"startLine":79,"startColumn":1,"endLine":81,"endColumn":19,"snippet":{}}}}},{"id":"/src/mcp-db-base/src/mcp_db_base/prometheus_client.call_promtheus_api.call_promtheus_api_scope..getattr"},{"id":"/src/mcp-db-base/src/mcp_db_base/prometheus_client.call_promtheus_api.call_promtheus_api_scope..getattr(client, method.lower())"},{"id":"/src/mcp-db-base/src/mcp_db_base/prometheus_client.call_promtheus_api.call_promtheus_api_scope...len"},{"id":"_handle_empty_response \\n[prometheus_client.py : 84_90]","location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-db-base/src/mcp_db_base/prometheus_client.py"},"region":{"startLine":84,"startColumn":1,"endLine":90,"endColumn":6,"snippet":{}}}}},{"id":"/src/mcp-db-base/src/mcp_db_base/prometheus_client.call_promtheus_api.call_promtheus_api_scope..getattr(client, method.lower())(var endpoint:any=endpoint, var null:any=request_kwar..."},{"id":"_handle_error_response \\n[prometheus_client.py : 93_99]","location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-db-base/src/mcp_db_base/prometheus_client.py"},"region":{"startLine":93,"startColumn":1,"endLine":99,"endColumn":6,"snippet":{}}}}},{"id":"/src/mcp-db-base/src/mcp_db_base/prometheus_client._handle_error_response._handle_error_response_scope..ValueError"},{"id":"/src/mcp-db-base/src/mcp_db_base/prometheus_client.call_promtheus_api.call_promtheus_api_scope...str"},{"id":"/src/mcp-db-base/src/mcp_db_base/prometheus_client.call_promtheus_api.call_promtheus_api_scope...ValueError"},{"id":"/src/mcp-db-base/src/mcp_db_base/prometheus_client.call_promtheus_api.call_promtheus_api_scope...str"},{"id":"tidy_serial_data \\n[prometheus_client.py : 172_219]","location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-db-base/src/mcp_db_base/prometheus_client.py"},"region":{"startLine":172,"startColumn":1,"endLine":219,"endColumn":27,"snippet":{}}}}},{"id":"/src/mcp-db-base/src/mcp_db_base/prometheus_client.tidy_serial_data.tidy_serial_data_scope..isinstance"},{"id":"metric.get"},{"id":"values_infos.append"},{"id":"/src/mcp-db-base/src/mcp_db_base/prometheus_client.get_ob_capacity_monitor.get_ob_capacity_monitor_scope...str"},{"id":"/src/mcp-db-base/src/mcp_db_base/prometheus_client.get_ob_capacity_monitor.get_ob_capacity_monitor_scope...ValueError"},{"id":"/src/mcp-db-base/src/mcp_db_base/prometheus_client..print"},{"id":"syslib_from.pydantic.VERSION.startswith"},{"id":"/src/mcp-db-base/src/mcp_db_base/pydantic_extend..NotImplementedError"},{"id":"get_top_sql \\n[tars_client.py : 203_228]","location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-db-base/src/mcp_db_base/tars_client.py"},"region":{"startLine":203,"startColumn":1,"endLine":228,"endColumn":33,"snippet":{}}}}},{"id":"/src/mcp-db-base/src/mcp_db_base/tars_client.get_top_sql.get_top_sql_scope...ValueError"},{"id":"_top_sql \\n[tars_client.py : 141_200]","location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-db-base/src/mcp_db_base/tars_client.py"},"region":{"startLine":141,"startColumn":1,"endLine":200,"endColumn":23,"snippet":{}}}}},{"id":"params.get"},{"id":"_headers \\n[tars_client.py : 29_36]","location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-db-base/src/mcp_db_base/tars_client.py"},"region":{"startLine":29,"startColumn":1,"endLine":36,"endColumn":6,"snippet":{}}}}},{"id":"syslib_from.base64.b64decode(TARS_TOKEN).decode"},{"id":"call_tars_api \\n[tars_client.py : 53_104]","location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-db-base/src/mcp_db_base/tars_client.py"},"region":{"startLine":53,"startColumn":1,"endLine":104,"endColumn":66,"snippet":{}}}}},{"id":"get_url \\n[tars_client.py : 49_50]","location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-db-base/src/mcp_db_base/tars_client.py"},"region":{"startLine":49,"startColumn":1,"endLine":50,"endColumn":31,"snippet":{}}}}},{"id":"/src/mcp-db-base/src/mcp_db_base/tars_client.call_tars_api.call_tars_api_scope..getattr"},{"id":"/src/mcp-db-base/src/mcp_db_base/tars_client.call_tars_api.call_tars_api_scope..getattr(client, method.lower())"},{"id":"/src/mcp-db-base/src/mcp_db_base/tars_client.call_tars_api.call_tars_api_scope..isinstance"},{"id":"/src/mcp-db-base/src/mcp_db_base/tars_client.call_tars_api.call_tars_api_scope..getattr(client, method.lower())(var endpoint:any=endpoint, var null:any=request_kwargs).get"},{"id":"_handle_empty_response \\n[tars_client.py : 107_109]","location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-db-base/src/mcp_db_base/tars_client.py"},"region":{"startLine":107,"startColumn":1,"endLine":109,"endColumn":58,"snippet":{}}}}},{"id":"_handle_error_response \\n[tars_client.py : 111_117]","location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-db-base/src/mcp_db_base/tars_client.py"},"region":{"startLine":111,"startColumn":1,"endLine":117,"endColumn":6,"snippet":{}}}}},{"id":"/src/mcp-db-base/src/mcp_db_base/tars_client._handle_error_response._handle_error_response_scope..str"},{"id":"/src/mcp-db-base/src/mcp_db_base/tars_client._handle_error_response._handle_error_response_scope..ValueError"},{"id":"syslib_from.demjson3.decode"},{"id":"syslib_from.demjson3.decode(response).get"},{"id":"/src/mcp-db-base/src/mcp_db_base/tars_client.call_tars_api.call_tars_api_scope...str"},{"id":"/src/mcp-db-base/src/mcp_db_base/tars_client.call_tars_api.call_tars_api_scope...ValueError"},{"id":"params.copy"},{"id":"/src/mcp-db-base/src/mcp_db_base/tars_client._top_sql._top_sql_scope..len"},{"id":"get(result, {}).get"},{"id":"/src/mcp-db-base/src/mcp_db_base/tars_client._top_sql._top_sql_scope..sum"},{"id":"/src/mcp-db-base/src/mcp_db_base/tars_client._top_sql._top_sql_scope..sorted"},{"id":"/src/mcp-db-base/src/mcp_db_base/tars_client._top_sql._top_sql_scope.. \\n[tars_client.py : 160_160]","location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-db-base/src/mcp_db_base/tars_client.py"},"region":{"startLine":160,"startColumn":37,"endLine":160,"endColumn":97,"snippet":{}}}}},{"id":"x.get"},{"id":"/src/mcp-db-base/src/mcp_db_base/tars_client._top_sql._top_sql_scope..sorted(sql_list, var key:any=function (var x:any){return x.get(executionCount, 0)*x.get(cpuTimeMs, 0)}, var r..."},{"id":"get_sql_detail \\n[tars_client.py : 288_295]","location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-db-base/src/mcp_db_base/tars_client.py"},"region":{"startLine":288,"startColumn":1,"endLine":295,"endColumn":33,"snippet":{}}}}},{"id":"/src/mcp-db-base/src/mcp_db_base/tars_client.get_sql_detail.get_sql_detail_scope...str"},{"id":"/src/mcp-db-base/src/mcp_db_base/tars_client.get_sql_detail.get_sql_detail_scope...ValueError"},{"id":"syslib_from.asyncio.gather"},{"id":"{:.2%}.format"},{"id":"top_five.get.sqlId.get"},{"id":"/src/mcp-db-base/src/mcp_db_base/tars_client.get_top_sql.get_top_sql_scope...str"},{"id":"/src/mcp-db-base/src/mcp_db_base/tars_client.get_top_sql.get_top_sql_scope...ValueError"},{"id":"/src/mcp-db-base/src/mcp_db_base/tars_client..print"},{"id":"mcp.server.Server"},{"id":".server.list_tools"},{"id":".server.call_tool"},{"id":"main \\n[yuntu_cmd_util.py : 89_103]","location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpAntlogs/src/mcpAntlogs/yuntu_cmd_util.py"},"region":{"startLine":89,"startColumn":1,"endLine":103,"endColumn":42,"snippet":{}}}}},{"id":"execute_cmd \\n[yuntu_cmd_util.py : 8_86]","location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpAntlogs/src/mcpAntlogs/yuntu_cmd_util.py"},"region":{"startLine":8,"startColumn":1,"endLine":86,"endColumn":20,"snippet":{}}}}},{"id":"syslib_from.requests.post"},{"id":"syslib_from.requests.post(base_url+/openapi/troubleshoot/config/sequenceExecutePipeline, var headers:any=headers, var json:any=payload, var timeout:any=30).raise_for_status"},{"id":"syslib_from.requests.post(base_url+/openapi/troubleshoot/config/sequenceExecutePipeline, var headers:any=headers, var json:any=payload, var timeout:any=30).json"},{"id":"syslib_from.requests.post(base_url+/openapi/troubleshoot/config/sequenceExecutePipeline, var headers:any=headers, var json:any=payload, var timeout:any=30).json().get"},{"id":"/src/mcpAntlogs/src/mcpAntlogs/yuntu_cmd_util.execute_cmd.execute_cmd_scope...print"},{"id":"syslib_from.requests.post(base_url+/openapi/troubleshoot/config/sequenceExecutePipeline, var headers:any=headers, var json:any=payload, var timeout:any=30).json().get(result, {}).get"},{"id":"syslib_from.requests.post(base_url+/openapi/troubleshoot/config/sequenceExecutePipeline, var headers:any=headers, var json:any=payload, var timeout:any=30).json().get(result, {}).get(nodeDataMap, {})...."},{"id":"/src/mcpAntlogs/src/mcpAntlogs/yuntu_cmd_util.execute_cmd.execute_cmd_scope...print"},{"id":"/src/mcpAntlogs/src/mcpAntlogs/yuntu_cmd_util.execute_cmd.execute_cmd_scope...print"},{"id":"syslib_from.html.unescape"},{"id":"syslib_from.html.unescape(log_content).replace"},{"id":"payload.loads"},{"id":"/src/mcpAntlogs/src/mcpAntlogs/yuntu_cmd_util.execute_cmd.execute_cmd_scope...str"},{"id":"/src/mcpAntlogs/src/mcpAntlogs/yuntu_cmd_util.execute_cmd.execute_cmd_scope...print"},{"id":"/src/mcpAntlogs/src/mcpAntlogs/yuntu_cmd_util.main.main_scope...print"},{"id":"payload.loads(html.unescape(log_content).replace(\\\\\\\", \\\")).get"},{"id":"/src/mcpAntlogs/src/mcpAntlogs/yuntu_cmd_util.main.main_scope...print"},{"id":"syslib_from.unittest.main"},{"id":"/src/mcpAntmonitor/src/mcpAntmonitor/server.int"},{"id":"get_app_metric \\n[antmonitor_client.py : 189_226]","location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpAntmonitor/src/mcpAntmonitor/antmonitor_client.py"},"region":{"startLine":189,"startColumn":1,"endLine":226,"endColumn":33,"snippet":{}}}}},{"id":"/src/mcpAntmonitor/src/mcpAntmonitor/antmonitor_client.get_app_metric.get_app_metric_scope..len"},{"id":"METRICS_TO_DEFAULT_COLUMN.get"},{"id":",.join"},{"id":"_get_maas_sql_data \\n[antmonitor_client.py : 135_171]","location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpAntmonitor/src/mcpAntmonitor/antmonitor_client.py"},"region":{"startLine":135,"startColumn":1,"endLine":171,"endColumn":33,"snippet":{}}}}},{"id":"_replace_seconds_with_zero \\n[antmonitor_client.py : 174_186]","location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpAntmonitor/src/mcpAntmonitor/antmonitor_client.py"},"region":{"startLine":174,"startColumn":1,"endLine":186,"endColumn":24,"snippet":{}}}}},{"id":"replace_func \\n[antmonitor_client.py : 180_181]","location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpAntmonitor/src/mcpAntmonitor/antmonitor_client.py"},"region":{"startLine":180,"startColumn":5,"endLine":181,"endColumn":38,"snippet":{}}}}},{"id":"_headers \\n[antmonitor_client.py : 45_65]","location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpAntmonitor/src/mcpAntmonitor/antmonitor_client.py"},"region":{"startLine":45,"startColumn":1,"endLine":65,"endColumn":19,"snippet":{}}}}},{"id":"/src/mcpAntmonitor/src/mcpAntmonitor/antmonitor_client._headers._headers_scope..int"},{"id":"/src/mcpAntmonitor/src/mcpAntmonitor/antmonitor_client._headers._headers_scope..str"},{"id":"/src/mcpAntmonitor/src/mcpAntmonitor/antmonitor_client._headers._headers_scope..bytes"},{"id":"_call_maas_sql_api \\n[antmonitor_client.py : 68_114]","location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpAntmonitor/src/mcpAntmonitor/antmonitor_client.py"},"region":{"startLine":68,"startColumn":1,"endLine":114,"endColumn":66,"snippet":{}}}}},{"id":"/src/mcpAntmonitor/src/mcpAntmonitor/antmonitor_client._call_maas_sql_api._call_maas_sql_api_scope..getattr"},{"id":"/src/mcpAntmonitor/src/mcpAntmonitor/antmonitor_client._call_maas_sql_api._call_maas_sql_api_scope..getattr(client, method.lower())"},{"id":"/src/mcpAntmonitor/src/mcpAntmonitor/antmonitor_client._call_maas_sql_api._call_maas_sql_api_scope..getattr(client, method.lower())(var endpoint:any=endpoint, var null:any=request_k..."},{"id":"/src/mcpAntmonitor/src/mcpAntmonitor/antmonitor_client._call_maas_sql_api._call_maas_sql_api_scope...isinstance"},{"id":"_handle_empty_response \\n[antmonitor_client.py : 117_123]","location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpAntmonitor/src/mcpAntmonitor/antmonitor_client.py"},"region":{"startLine":117,"startColumn":1,"endLine":123,"endColumn":6,"snippet":{}}}}},{"id":"/src/mcpAntmonitor/src/mcpAntmonitor/antmonitor_client._handle_empty_response._handle_empty_response_scope..ValueError"},{"id":"syslib_from.logging.getLogger(__name__).warning"},{"id":"_handle_error_response \\n[antmonitor_client.py : 126_132]","location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpAntmonitor/src/mcpAntmonitor/antmonitor_client.py"},"region":{"startLine":126,"startColumn":1,"endLine":132,"endColumn":6,"snippet":{}}}}},{"id":"/src/mcpAntmonitor/src/mcpAntmonitor/antmonitor_client._handle_error_response._handle_error_response_scope..ValueError"},{"id":"/src/mcpAntmonitor/src/mcpAntmonitor/antmonitor_client._call_maas_sql_api._call_maas_sql_api_scope...str"},{"id":"/src/mcpAntmonitor/src/mcpAntmonitor/antmonitor_client._call_maas_sql_api._call_maas_sql_api_scope...ValueError"},{"id":"syslib_from.datetime.datetime.fromtimestamp"},{"id":"syslib_from.datetime.datetime.fromtimestamp(timestamp).strftime"},{"id":"/src/mcpAntmonitor/src/mcpAntmonitor/antmonitor_client._get_maas_sql_data._get_maas_sql_data_scope.......str"},{"id":"/src/mcpAntmonitor/src/mcpAntmonitor/antmonitor_client._get_maas_sql_data._get_maas_sql_data_scope...ValueError"},{"id":"/src/mcpAntmonitor/src/mcpAntmonitor/antmonitor_client.get_app_metric.get_app_metric_scope...str"},{"id":"/src/mcpAntmonitor/src/mcpAntmonitor/antmonitor_client.get_app_metric.get_app_metric_scope...ValueError"},{"id":"/src/mcpAntmonitor/src/mcpAntmonitor/antmonitor_client..print"},{"id":"syslib_from.os.path.abspath"},{"id":"syslib_from.os.path.dirname"},{"id":"syslib_from.sys.path.append"},{"id":"layotto_turbo.layotto.subscribe"},{"id":"oneapi.antschedulerconsole.JobOpenApiFacade.JobOpenApiFacade"},{"id":"oneapi.antschedulerconsole.OperationRecordOpenApiFacade.OperationRecordOpenApiFacade"},{"id":"oneapi.cloudinc.AntvipDomainQueryFacade.AntvipDomainQueryFacade"},{"id":"run_code \\n[server.py : 127_184]","location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpCodeExecutor/src/mcpCodeExecutor/server.py"},"region":{"startLine":127,"startColumn":1,"endLine":184,"endColumn":65,"snippet":{}}}}},{"id":"_get_trace_id \\n[server.py : 117_125]","location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpCodeExecutor/src/mcpCodeExecutor/server.py"},"region":{"startLine":117,"startColumn":1,"endLine":125,"endColumn":29,"snippet":{}}}}},{"id":"mcp.server.Server(SERVER_NAME).request_context.meta.model_extra.get"},{"id":"syslib_from.logging.getLogger(mcp-server).info"},{"id":"mcp.server.Server(SERVER_NAME).request_context.meta.model_extra.get(headers).decode"},{"id":"mcp.server.Server(SERVER_NAME).request_context.meta.model_extra.get(headers).decode(utf-8).lower"},{"id":"syslib_from.uuid.uuid4"},{"id":"/src/mcpCodeExecutor/src/mcpCodeExecutor/server._get_trace_id._get_trace_id_scope..str"},{"id":"/src/mcpCodeExecutor/src/mcpCodeExecutor/server.run_code.run_code_scope..int"},{"id":"/src/mcpCodeExecutor/src/mcpCodeExecutor/server.run_code.run_code_scope..str"},{"id":"syslib_from.random.randint"},{"id":"syslib_from.os.environ.get(RUNTIME_ENV_ID, PROD).upper"},{"id":"isinstance"},{"id":"syslib_from.httpx.AsyncClient"},{"id":"syslib_from.httpx.AsyncClient().post"},{"id":"syslib_from.httpx.AsyncClient().post(url, var headers:any=headers, var json:any=req_body).raise_for_status"},{"id":"syslib_from.httpx.AsyncClient().post(url, var headers:any=headers, var json:any=req_body).json"},{"id":"syslib_from.httpx.AsyncClient().post(url, var headers:any=headers, var json:any=req_body).json().get"},{"id":"req_body.loads"},{"id":"req_body.loads(data_field).get"},{"id":"/src/mcpCodeExecutor/src/mcpCodeExecutor/server..print"},{"id":"main \\n[__init__.py : 3_4]","location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpTvp/src/mcpTvp/__init__.py"},"region":{"startLine":3,"startColumn":1,"endLine":4,"endColumn":29,"snippet":{}}}}},{"id":"mcpDataSync.server.mcp.run"},{"id":"mcp.server.FastMCP"},{"id":".server.tool"},{"id":"main \\n[odc_client_v2.py : 466_478]","location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDbOdc/src/mcpDbOdc/odc_client_v2.py"},"region":{"startLine":466,"startColumn":1,"endLine":478,"endColumn":39,"snippet":{}}}}},{"id":"OdcClientV2 :: __init__ \\n[odc_client_v2.py : 21_48]","location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDbOdc/src/mcpDbOdc/odc_client_v2.py"},"region":{"startLine":21,"startColumn":5,"endLine":48,"endColumn":63,"snippet":{}}}}},{"id":"OdcClientV2 :: _get_url \\n[odc_client_v2.py : 59_64]","location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDbOdc/src/mcpDbOdc/odc_client_v2.py"},"region":{"startLine":59,"startColumn":5,"endLine":64,"endColumn":49,"snippet":{}}}}},{"id":"ODC_URL.get"},{"id":"ODC_URL.site.get"},{"id":"OdcClientV2 :: create_project \\n[odc_client_v2.py : 94_140]","location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDbOdc/src/mcpDbOdc/odc_client_v2.py"},"region":{"startLine":94,"startColumn":5,"endLine":140,"endColumn":10,"snippet":{}}}}},{"id":"OdcClientV2 :: _call_api \\n[odc_client_v2.py : 404_442]","location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDbOdc/src/mcpDbOdc/odc_client_v2.py"},"region":{"startLine":404,"startColumn":5,"endLine":442,"endColumn":59,"snippet":{}}}}},{"id":"/src/mcpDbOdc/src/mcpDbOdc/odc_client_v2.OdcClientV2._request"},{"id":"OdcClientV2 :: _handle_empty_response \\n[odc_client_v2.py : 444_452]","location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDbOdc/src/mcpDbOdc/odc_client_v2.py"},"region":{"startLine":444,"startColumn":5,"endLine":452,"endColumn":36,"snippet":{}}}}},{"id":"/src/mcpDbOdc/src/mcpDbOdc/odc_client_v2.OdcClientV2._request(method, endpoint, var params:any=params, var json:any=data).get"},{"id":"/src/mcpDbOdc/src/mcpDbOdc/odc_client_v2.OdcClientV2._handle_empty_response._handle_empty_response_scope..ValueError"},{"id":"OdcClientV2 :: _handle_error_response \\n[odc_client_v2.py : 454_462]","location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDbOdc/src/mcpDbOdc/odc_client_v2.py"},"region":{"startLine":454,"startColumn":5,"endLine":462,"endColumn":36,"snippet":{}}}}},{"id":"/src/mcpDbOdc/src/mcpDbOdc/odc_client_v2.OdcClientV2._handle_error_response._handle_error_response_scope..ValueError"},{"id":"/src/mcpDbOdc/src/mcpDbOdc/odc_client_v2.OdcClientV2._call_api._call_api_scope...str"},{"id":"/src/mcpDbOdc/src/mcpDbOdc/odc_client_v2.OdcClientV2._call_api._call_api_scope...ValueError"},{"id":"/src/mcpDbOdc/src/mcpDbOdc/odc_client_v2.main.main_scope..print"},{"id":".server.list_resources"},{"id":".server.read_resource"},{"id":".server.list_prompts"},{"id":".server.get_prompt"},{"id":"get_pysql_user_name \\n[client.py : 191_213]","location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDbQuery/src/mcpDbQuery/client.py"},"region":{"startLine":191,"startColumn":1,"endLine":213,"endColumn":54,"snippet":{}}}}},{"id":"mcp_db_base.omc_client.get_physic_dbs"},{"id":"/src/mcpDbQuery/src/mcpDbQuery/client.get_pysql_user_name.get_pysql_user_name_scope..len"},{"id":"/src/mcpDbQuery/src/mcpDbQuery/client.get_pysql_user_name.get_pysql_user_name_scope...Exception"},{"id":"mcp_db_base.omc_client.get_physic_dbs(var arn:any=db_arn).get"},{"id":"/src/mcpDbQuery/src/mcpDbQuery/client.get_pysql_user_name.get_pysql_user_name_scope...Exception"},{"id":"/src/mcpDbQuery/src/mcpDbQuery/client.get_pysql_user_name.get_pysql_user_name_scope...Exception"},{"id":"/src/mcpDbQuery/src/mcpDbQuery/client.get_pysql_user_name.get_pysql_user_name_scope...Exception"},{"id":"mcp_db_base.omc_client.get_cluster_info_v2(var cluster_arn:any=cluster_arn).get"},{"id":"/src/mcpDbQuery/src/mcpDbQuery/client.get_pysql_user_name.get_pysql_user_name_scope...Exception"},{"id":"/src/mcpDbQuery/src/mcpDbQuery/client.get_pysql_user_name.get_pysql_user_name_scope...Exception"},{"id":"/src/mcpDbQuery/src/mcpDbQuery/client..print"},{"id":"main \\n[__init__.py : 4_5]","location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDrm/src/mcpDrm/__init__.py"},"region":{"startLine":4,"startColumn":1,"endLine":5,"endColumn":32,"snippet":{}}}}},{"id":"server.server.run"},{"id":"syslib_from.config.Config"},{"id":"page_search_work_item \\n[client.py : 94_139]","location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDima/src/mcpDima/client.py"},"region":{"startLine":94,"startColumn":1,"endLine":139,"endColumn":38,"snippet":{}}}}},{"id":"get_staff_id_by_nick_name \\n[client.py : 187_197]","location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDima/src/mcpDima/client.py"},"region":{"startLine":187,"startColumn":1,"endLine":197,"endColumn":55,"snippet":{}}}}},{"id":"syslib_from.aiohttp.ClientSession"},{"id":"syslib_from.aiohttp.ClientSession().get"},{"id":"syslib_from.aiohttp.ClientSession().get(url, var params:any=params, var ssl:any=false).json"},{"id":"syslib_from.aiohttp.ClientSession().get(url, var params:any=params, var ssl:any=false).json().get"},{"id":"syslib_from.aiohttp.ClientSession().get(url, var params:any=params, var ssl:any=false).json().get(data).get"},{"id":"syslib_from.asyncio.create_task"},{"id":"syslib_from.config.WORK_ITEM_FILTER_VALUES_DICT.get"},{"id":"new_value.append"},{"id":"/src/mcpDima/src/mcpDima/client.page_search_work_item.page_search_work_item_scope.....len"},{"id":"get_dima_user_id_list \\n[client.py : 174_184]","location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDima/src/mcpDima/client.py"},"region":{"startLine":174,"startColumn":1,"endLine":184,"endColumn":105,"snippet":{}}}}},{"id":"syslib_from.sign.get_dima_header"},{"id":"syslib_from.aiohttp.ClientSession().post"},{"id":"syslib_from.aiohttp.ClientSession().post(url, var json:any=body, var headers:any=sign.get_dima_header(config_.ak, config_.sk), var ssl:any=false).json"},{"id":"syslib_from.aiohttp.ClientSession().post(url, var json:any=body, var headers:any=sign.get_dima_header(config_.ak, config_.sk), var ssl:any=false).json().get"},{"id":"syslib_from.aiohttp.ClientSession().post(url, var json:any=body, var headers:any=sign.get_dima_header(config_.ak, config_.sk), var ssl:any=false).json().get(data).get"},{"id":"syslib_from.aiohttp.ClientSession().post(url, var params:any=params, var json:any=body, var headers:any=sign.get_dima_header(config_.ak, config_.sk), var ssl:any=false).json"},{"id":"syslib_from.aiohttp.ClientSession().post(url, var params:any=params, var json:any=body, var headers:any=sign.get_dima_header(config_.ak, config_.sk), var ssl:any=false).json().get"},{"id":"syslib_from.model.WorkItem.model_validate"},{"id":"syslib_from.model.to_json"},{"id":"/src/mcpDima/src/mcpDima/client..print"},{"id":"syslib_from.os.path.join"},{"id":"oneapi.opssla.DrmManageFacade.DrmManageFacade"},{"id":"oneapi.opssla.DrmLargeConfigManageFacade.DrmLargeConfigManageFacade"},{"id":"oneapi.opssla.ResourceMetaDataFacade.ResourceMetaDataFacade"},{"id":"query_cur_drm_value \\n[server.py : 89_115]","location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDrm/src/mcpDrm/server.py"},"region":{"startLine":89,"startColumn":1,"endLine":115,"endColumn":59,"snippet":{}}}}},{"id":"oneapi.opssla.ResourceMetaDataFacade.ResourceMetaDataFacade(layotto).search"},{"id":"/src/mcpDrm/src/mcpDrm/server.query_cur_drm_value.query_cur_drm_value_scope..len"},{"id":"/src/mcpDrm/src/mcpDrm/server.query_cur_drm_value.query_cur_drm_value_scope...ValueError"},{"id":"oneapi.opssla.ResourceMetaDataFacade.ResourceMetaDataFacade(layotto).search(resource_id, var limit:any=100).data.get"},{"id":"oneapi.opssla.DrmManageFacade.DrmManageFacade(layotto).queryBatchValue_f4ac1f8"},{"id":"oneapi.opssla.DrmManageFacade.DrmManageFacade(layotto).queryBatchValue_b6fef5f"},{"id":"/src/mcpDrm/src/mcpDrm/server.query_cur_drm_value.query_cur_drm_value_scope..resp.get_json"},{"id":"/src/mcpDrm/src/mcpDrm/server..print"},{"id":"mcp_common.utils.oss_utils.get_file_infos"},{"id":"mcp_common.utils.oss_utils.get_file_infos({0:opsgpt/upload/yicheng/66100217_标注结果明细.csv}).to_dict"},{"id":"/src/mcpFileOperation/src/mcpFileOperation/server..print"},{"id":"_find_property_by_scene_code \\n[server_client.py : 122_154]","location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpFluxFind/src/mcpFluxFind/server_client.py"},"region":{"startLine":122,"startColumn":1,"endLine":154,"endColumn":14,"snippet":{}}}}},{"id":"syslib_from.requests.get"},{"id":"syslib_from.requests.get(url, var params:any=params).raise_for_status"},{"id":"syslib_from.requests.get(url, var params:any=params).json"},{"id":"syslib_from.requests.get(url, var params:any=params).json().get"},{"id":"syslib_from.requests.get(url, var params:any=params).json().get(data).get"},{"id":"/src/mcpFluxFind/src/mcpFluxFind/server_client._find_property_by_scene_code._find_property_by_scene_code_scope...type"},{"id":"/src/mcpFluxFind/src/mcpFluxFind/server_client._find_property_by_scene_code._find_property_by_scene_code_scope...print_debug_info"},{"id":"syslib_from.traceback.print_exc"},{"id":"/src/mcpFluxFind/src/mcpFluxFind/server_client..print"},{"id":"/src/mcpFluxScene/src/mcpFluxScene/app..ImportError"},{"id":"invoke_test_report_agent_new \\n[scene_client.py : 519_563]","location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpFluxScene/src/mcpFluxScene/scene_client.py"},"region":{"startLine":519,"startColumn":1,"endLine":563,"endColumn":14,"snippet":{}}}}},{"id":"factory.ClientFactory"},{"id":"factory.ClientFactory(DORAEMON_API_KEY_ID, DORAEMON_API_KEY_SECRET, var api_url:any=DORAEMON_API_URL).get_client"},{"id":"factory.ClientFactory(DORAEMON_API_KEY_ID, DORAEMON_API_KEY_SECRET, var api_url:any=DORAEMON_API_URL).get_client(TEST_REPORT_APP_ID, text).completion"},{"id":"handle_response_text \\n[scene_client.py : 566_592]","location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpFluxScene/src/mcpFluxScene/scene_client.py"},"region":{"startLine":566,"startColumn":1,"endLine":592,"endColumn":41,"snippet":{}}}}},{"id":"unexpected media type: {}.format"},{"id":"/src/mcpFluxScene/src/mcpFluxScene/scene_client.handle_response_text.handle_response_text_scope..assert"},{"id":"/src/mcpFluxScene/src/mcpFluxScene/scene_client.invoke_test_report_agent_new.invoke_test_report_agent_new_scope...type"},{"id":"print_debug_info \\n[scene_client.py : 357_358]","location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpFluxScene/src/mcpFluxScene/scene_client.py"},"region":{"startLine":357,"startColumn":1,"endLine":358,"endColumn":19,"snippet":{}}}}},{"id":"/src/mcpFluxScene/src/mcpFluxScene/scene_client.print_debug_info.print_debug_info_scope..print"},{"id":"/src/mcpFluxScene/src/mcpFluxScene/scene_client..print"},{"id":"oneapi.linglongmng.LinglongModuleFacade.LinglongModuleFacade"},{"id":"oneapi.linglongmng.FunctionMngServiceFacade.FunctionMngServiceFacade"},{"id":"get_multi_metric \\n[maas_sql_client.py : 175_182]","location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpMonitorWithFile/src/mcpMonitorWithFile/maas_sql_client.py"},"region":{"startLine":175,"startColumn":1,"endLine":182,"endColumn":18,"snippet":{}}}}},{"id":"ob@@sysstat@@tenant@@DEFAULT@@1@@DEFAULT.where_condition.format"},{"id":"`tenant` = \\'{tenant}\\'.where_condition.format"},{"id":"_get_maas_sql_data \\n[maas_sql_client.py : 136_172]","location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpMonitorWithFile/src/mcpMonitorWithFile/maas_sql_client.py"},"region":{"startLine":136,"startColumn":1,"endLine":172,"endColumn":33,"snippet":{}}}}},{"id":"_replace_seconds_with_zero \\n[maas_sql_client.py : 199_211]","location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpMonitorWithFile/src/mcpMonitorWithFile/maas_sql_client.py"},"region":{"startLine":199,"startColumn":1,"endLine":211,"endColumn":24,"snippet":{}}}}},{"id":"replace_func \\n[maas_sql_client.py : 205_206]","location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpMonitorWithFile/src/mcpMonitorWithFile/maas_sql_client.py"},"region":{"startLine":205,"startColumn":5,"endLine":206,"endColumn":38,"snippet":{}}}}},{"id":"_headers \\n[maas_sql_client.py : 43_66]","location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpMonitorWithFile/src/mcpMonitorWithFile/maas_sql_client.py"},"region":{"startLine":43,"startColumn":1,"endLine":66,"endColumn":19,"snippet":{}}}}},{"id":"/src/mcpMonitorWithFile/src/mcpMonitorWithFile/maas_sql_client._headers._headers_scope..int"},{"id":"/src/mcpMonitorWithFile/src/mcpMonitorWithFile/maas_sql_client._headers._headers_scope..str"},{"id":"/src/mcpMonitorWithFile/src/mcpMonitorWithFile/maas_sql_client._headers._headers_scope..bytes"},{"id":"_call_maas_sql_api \\n[maas_sql_client.py : 69_115]","location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpMonitorWithFile/src/mcpMonitorWithFile/maas_sql_client.py"},"region":{"startLine":69,"startColumn":1,"endLine":115,"endColumn":66,"snippet":{}}}}},{"id":"/src/mcpMonitorWithFile/src/mcpMonitorWithFile/maas_sql_client._call_maas_sql_api._call_maas_sql_api_scope..getattr"},{"id":"/src/mcpMonitorWithFile/src/mcpMonitorWithFile/maas_sql_client._call_maas_sql_api._call_maas_sql_api_scope..getattr(client, method.lower())"},{"id":"/src/mcpMonitorWithFile/src/mcpMonitorWithFile/maas_sql_client._call_maas_sql_api._call_maas_sql_api_scope..getattr(client, method.lower())(var endpoint:any=endpoint, var null:any=r..."},{"id":"/src/mcpMonitorWithFile/src/mcpMonitorWithFile/maas_sql_client._call_maas_sql_api._call_maas_sql_api_scope...isinstance"},{"id":"_handle_empty_response \\n[maas_sql_client.py : 118_124]","location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpMonitorWithFile/src/mcpMonitorWithFile/maas_sql_client.py"},"region":{"startLine":118,"startColumn":1,"endLine":124,"endColumn":6,"snippet":{}}}}},{"id":"/src/mcpMonitorWithFile/src/mcpMonitorWithFile/maas_sql_client._handle_empty_response._handle_empty_response_scope..ValueError"},{"id":"_handle_error_response \\n[maas_sql_client.py : 127_133]","location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpMonitorWithFile/src/mcpMonitorWithFile/maas_sql_client.py"},"region":{"startLine":127,"startColumn":1,"endLine":133,"endColumn":6,"snippet":{}}}}},{"id":"/src/mcpMonitorWithFile/src/mcpMonitorWithFile/maas_sql_client._handle_error_response._handle_error_response_scope..ValueError"},{"id":"/src/mcpMonitorWithFile/src/mcpMonitorWithFile/maas_sql_client._call_maas_sql_api._call_maas_sql_api_scope...str"},{"id":"/src/mcpMonitorWithFile/src/mcpMonitorWithFile/maas_sql_client._call_maas_sql_api._call_maas_sql_api_scope...ValueError"},{"id":"/src/mcpMonitorWithFile/src/mcpMonitorWithFile/maas_sql_client._get_maas_sql_data._get_maas_sql_data_scope.......str"},{"id":"/src/mcpMonitorWithFile/src/mcpMonitorWithFile/maas_sql_client._get_maas_sql_data._get_maas_sql_data_scope...ValueError"},{"id":"/src/mcpMonitorWithFile/src/mcpMonitorWithFile/maas_sql_client..print"},{"id":"get_metric \\n[server.py : 125_135]","location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpMonitorWithSql/src/mcpMonitorWithSql/server.py"},"region":{"startLine":125,"startColumn":1,"endLine":135,"endColumn":50,"snippet":{}}}}},{"id":"_get_header \\n[server.py : 115_122]","location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpMonitorWithSql/src/mcpMonitorWithSql/server.py"},"region":{"startLine":115,"startColumn":1,"endLine":122,"endColumn":19,"snippet":{}}}}},{"id":"/src/mcpMonitorWithSql/src/mcpMonitorWithSql/server..print"},{"id":"aiologger.Logger"},{"id":"aiologger.handlers.streams.AsyncStreamHandler"},{"id":"aiologger.formatters.base.Formatter"},{"id":"aiologger.formatters.json.JsonFormatter"},{"id":"syslib_from.os.path.exists"},{"id":"/src/mcpOpenSearch/src/mcpOpenSearch/util.assert"},{"id":"handle_call_tool \\n[server.py : 170_212]","location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpOpsCloud/src/mcpOpsCloud/server.py"},"region":{"startLine":170,"startColumn":1,"endLine":212,"endColumn":16,"snippet":{}}}}},{"id":"/src/mcpOpsCloud/src/mcpOpsCloud/server.handle_call_tool.handle_call_tool_scope...ValueError"},{"id":"/src/mcpOpsCloud/src/mcpOpsCloud/server.handle_call_tool.handle_call_tool_scope...ValueError"},{"id":"opscloud.OpsCloud"},{"id":"opscloud.OpsCloud().analyse_change"},{"id":"warp_result \\n[server.py : 215_229]","location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpOpsCloud/src/mcpOpsCloud/server.py"},"region":{"startLine":215,"startColumn":1,"endLine":229,"endColumn":10,"snippet":{}}}}},{"id":"/src/mcpOpsCloud/src/mcpOpsCloud/server.warp_result.warp_result_scope..len"},{"id":"syslib_from.mcp/types.TextContent"},{"id":"opscloud_app_change.OpsCloudAppChange"},{"id":"opscloud_app_change.OpsCloudAppChange().search_app_change_with_simple"},{"id":"opscloud_drm_change.OpsCloudDrmChange"},{"id":"opscloud_drm_change.OpsCloudDrmChange().search_drm_change_with_simple"},{"id":"opscloud_drm_change.OpsCloudDrmChange().search_drm_change_full_result"},{"id":"/src/mcpOpsCloud/src/mcpOpsCloud/server..print"},{"id":"search_app_change_with_simple"},{"id":"/src/mcpOpsCloud/src/mcpOpsCloud/opscloud_app_change..print"},{"id":"search_drm_change_with_simple"},{"id":"/src/mcpOpsCloud/src/mcpOpsCloud/opscloud_drm_change..print"},{"id":"search_full_change_full_result"},{"id":"/src/mcpOpsCloud/src/mcpOpsCloud/opscloud_full_change..print"},{"id":"layotto_turbo.layotto._layotto_client.initialize_app"},{"id":"oneapi.archdatacenter.BackendAppQueryFacade.BackendAppQueryFacade"},{"id":"oneapi.huanyu.CustomChangePlanFacade.CustomChangePlanFacade"},{"id":"syslib_from.logging.basicConfig"},{"id":"maas_service.MaasService"},{"id":"MaasService :: __init__ \\n[maas_service.py : 39_43]","location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpQueryMultiAppMetrics/src/mcpQueryMultiAppMetrics/maas_service.py"},"region":{"startLine":39,"startColumn":5,"endLine":43,"endColumn":41,"snippet":{}}}}},{"id":"MaasService :: query_maas_by_sql_new_engine \\n[maas_service.py : 461_507]","location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpQueryMultiAppMetrics/src/mcpQueryMultiAppMetrics/maas_service.py"},"region":{"startLine":461,"startColumn":5,"endLine":507,"endColumn":10,"snippet":{}}}}},{"id":"MaasService :: replace_seconds_with_zero \\n[maas_service.py : 73_87]","location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpQueryMultiAppMetrics/src/mcpQueryMultiAppMetrics/maas_service.py"},"region":{"startLine":73,"startColumn":5,"endLine":87,"endColumn":28,"snippet":{}}}}},{"id":"replace_func \\n[maas_service.py : 82_83]","location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpQueryMultiAppMetrics/src/mcpQueryMultiAppMetrics/maas_service.py"},"region":{"startLine":82,"startColumn":9,"endLine":83,"endColumn":42,"snippet":{}}}}},{"id":"MaasService :: replace_env \\n[maas_service.py : 62_70]","location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpQueryMultiAppMetrics/src/mcpQueryMultiAppMetrics/maas_service.py"},"region":{"startLine":62,"startColumn":5,"endLine":70,"endColumn":19,"snippet":{}}}}},{"id":"syslib_from.re.sub(pattern, replace_func, sql).replace"},{"id":"syslib_from.json.dumps({sql:sql}, var ensure_ascii:any=false).encode"},{"id":"syslib_from.requests.post(self.new_engine_url, var headers:any=headers, var data:any=payload).json"},{"id":"/src/mcpQueryMultiAppMetrics/src/mcpQueryMultiAppMetrics/maas_service.MaasService.query_maas_by_sql_new_engine.query_maas_by_sql_new_engine_scope..print"},{"id":"syslib_from.requests.post(self.new_engine_url, var headers:any=headers, var data:any=payload).json().data.headers.index"},{"id":"/src/mcpQueryMultiAppMetrics/src/mcpQueryMultiAppMetrics/maas_service.MaasService.query_maas_by_sql_new_engine.query_maas_by_sql_new_engine_scope....print"},{"id":"/src/mcpQueryMultiAppMetrics/src/mcpQueryMultiAppMetrics/maas_service.MaasService.query_app_trace_err"},{"id":"get_app_info \\n[rmc_utils.py : 8_58]","location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpQuerySingleAppMetrics/src/mcpQuerySingleAppMetrics/rmc_utils.py"},"region":{"startLine":8,"startColumn":1,"endLine":58,"endColumn":36,"snippet":{}}}}},{"id":"/src/mcpQueryMultiAppMetrics/src/mcpQueryMultiAppMetrics/rmc_utils.get_app_info.get_app_info_scope...len"},{"id":"syslib_from.json.loads(result.text).data.data.appGroup.replace"},{"id":"/src/mcpQueryMultiAppMetrics/src/mcpQueryMultiAppMetrics/rmc_utils..print"},{"id":"main \\n[merchant_client.py : 138_145]","location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpQueryRiskMerchantInfo/src/mcpQueryRiskMerchantInfo/merchant_client.py"},"region":{"startLine":138,"startColumn":5,"endLine":145,"endColumn":38,"snippet":{}}}}},{"id":"query_risk_merchant_info \\n[merchant_client.py : 79_133]","location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpQueryRiskMerchantInfo/src/mcpQueryRiskMerchantInfo/merchant_client.py"},"region":{"startLine":79,"startColumn":1,"endLine":133,"endColumn":64,"snippet":{}}}}},{"id":"_call_risk_merchant_api \\n[merchant_client.py : 19_58]","location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpQueryRiskMerchantInfo/src/mcpQueryRiskMerchantInfo/merchant_client.py"},"region":{"startLine":19,"startColumn":1,"endLine":58,"endColumn":74,"snippet":{}}}}},{"id":"_headers \\n[merchant_client.py : 11_16]","location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpQueryRiskMerchantInfo/src/mcpQueryRiskMerchantInfo/merchant_client.py"},"region":{"startLine":11,"startColumn":1,"endLine":16,"endColumn":19,"snippet":{}}}}},{"id":"/src/mcpQueryRiskMerchantInfo/src/mcpQueryRiskMerchantInfo/merchant_client._call_risk_merchant_api._call_risk_merchant_api_scope..getattr"},{"id":"/src/mcpQueryRiskMerchantInfo/src/mcpQueryRiskMerchantInfo/merchant_client._call_risk_merchant_api._call_risk_merchant_api_scope..getattr(client, method.lower())"},{"id":"/src/mcpQueryRiskMerchantInfo/src/mcpQueryRiskMerchantInfo/merchant_client._call_risk_merchant_api._call_risk_merchant_api_scope..getattr(client, method.lower())(var endpoint:any=end..."},{"id":"/src/mcpQueryRiskMerchantInfo/src/mcpQueryRiskMerchantInfo/merchant_client._call_risk_merchant_api._call_risk_merchant_api_scope...isinstance"},{"id":"_handle_empty_response \\n[merchant_client.py : 61_67]","location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpQueryRiskMerchantInfo/src/mcpQueryRiskMerchantInfo/merchant_client.py"},"region":{"startLine":61,"startColumn":1,"endLine":67,"endColumn":6,"snippet":{}}}}},{"id":"/src/mcpQueryRiskMerchantInfo/src/mcpQueryRiskMerchantInfo/merchant_client._handle_empty_response._handle_empty_response_scope..ValueError"},{"id":"_handle_error_response \\n[merchant_client.py : 70_76]","location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpQueryRiskMerchantInfo/src/mcpQueryRiskMerchantInfo/merchant_client.py"},"region":{"startLine":70,"startColumn":1,"endLine":76,"endColumn":6,"snippet":{}}}}},{"id":"/src/mcpQueryRiskMerchantInfo/src/mcpQueryRiskMerchantInfo/merchant_client._handle_error_response._handle_error_response_scope..ValueError"},{"id":"/src/mcpQueryRiskMerchantInfo/src/mcpQueryRiskMerchantInfo/merchant_client._call_risk_merchant_api._call_risk_merchant_api_scope...str"},{"id":"/src/mcpQueryRiskMerchantInfo/src/mcpQueryRiskMerchantInfo/merchant_client._call_risk_merchant_api._call_risk_merchant_api_scope...ValueError"},{"id":"get(basicInfo, {}).get"},{"id":"/src/mcpQueryRiskMerchantInfo/src/mcpQueryRiskMerchantInfo/merchant_client.query_risk_merchant_info.query_risk_merchant_info_scope...str"},{"id":"/src/mcpQueryRiskMerchantInfo/src/mcpQueryRiskMerchantInfo/merchant_client.query_risk_merchant_info.query_risk_merchant_info_scope...ValueError"},{"id":"/src/mcpQueryRiskMerchantInfo/src/mcpQueryRiskMerchantInfo/merchant_client..main.main_scope..print"},{"id":"/src/mcpQueryRiskMerchantInfo/src/mcpQueryRiskMerchantInfo/merchant_client..main.main_scope...str"},{"id":"MaasService :: __init__ \\n[maas_service.py : 43_47]","location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpQuerySingleAppMetrics/src/mcpQuerySingleAppMetrics/maas_service.py"},"region":{"startLine":43,"startColumn":5,"endLine":47,"endColumn":41,"snippet":{}}}}},{"id":"MaasService :: query_maas_by_sql_new_engine \\n[maas_service.py : 465_511]","location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpQuerySingleAppMetrics/src/mcpQuerySingleAppMetrics/maas_service.py"},"region":{"startLine":465,"startColumn":5,"endLine":511,"endColumn":10,"snippet":{}}}}},{"id":"MaasService :: replace_seconds_with_zero \\n[maas_service.py : 77_91]","location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpQuerySingleAppMetrics/src/mcpQuerySingleAppMetrics/maas_service.py"},"region":{"startLine":77,"startColumn":5,"endLine":91,"endColumn":28,"snippet":{}}}}},{"id":"replace_func \\n[maas_service.py : 86_87]","location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpQuerySingleAppMetrics/src/mcpQuerySingleAppMetrics/maas_service.py"},"region":{"startLine":86,"startColumn":9,"endLine":87,"endColumn":42,"snippet":{}}}}},{"id":"MaasService :: replace_env \\n[maas_service.py : 66_74]","location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpQuerySingleAppMetrics/src/mcpQuerySingleAppMetrics/maas_service.py"},"region":{"startLine":66,"startColumn":5,"endLine":74,"endColumn":19,"snippet":{}}}}},{"id":"/src/mcpQuerySingleAppMetrics/src/mcpQuerySingleAppMetrics/maas_service.MaasService.query_maas_by_sql_new_engine.query_maas_by_sql_new_engine_scope..print"},{"id":"/src/mcpQuerySingleAppMetrics/src/mcpQuerySingleAppMetrics/maas_service.MaasService.query_maas_by_sql_new_engine.query_maas_by_sql_new_engine_scope....print"},{"id":"/src/mcpQuerySingleAppMetrics/src/mcpQuerySingleAppMetrics/rmc_utils.get_app_info.get_app_info_scope...len"},{"id":"/src/mcpQuerySingleAppMetrics/src/mcpQuerySingleAppMetrics/rmc_utils..print"},{"id":"codeGenChat \\n[ropcn_utils.py : 153_192]","location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpRopnTaskStatusAnalyse/src/mcpRopnTaskStatusAnalyse/ropcn_utils.py"},"region":{"startLine":153,"startColumn":1,"endLine":192,"endColumn":81,"snippet":{}}}}},{"id":"syslib_from.requests.post(var url:any=https://codegencore.alipay.com/api/answer/repo/general/chat, var data:any=json.dumps(payload, var ensure_ascii:any=true), var headers:any={Content-Type:applicatio..."},{"id":"/src/mcpRopnTaskStatusAnalyse/src/mcpRopnTaskStatusAnalyse/ropcn_utils.codeGenChat.codeGenChat_scope..len"},{"id":"data.__contains__"},{"id":"/src/mcpRopnTaskStatusAnalyse/src/mcpRopnTaskStatusAnalyse/ropcn_utils.codeGenChat.codeGenChat_scope.....str"},{"id":"syslib_from.traceback.format_exc"},{"id":"/src/mcpRopnTaskStatusAnalyse/src/mcpRopnTaskStatusAnalyse/ropcn_utils..print"},{"id":"get_app_call_info \\n[server.py : 168_196]","location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpSim/src/mcpSim/server.py"},"region":{"startLine":168,"startColumn":1,"endLine":196,"endColumn":51,"snippet":{}}}}},{"id":"syslib_from.requests.get(url, var headers:any=header, var params:any=params, var verify:any=false).raise_for_status"},{"id":"syslib_from.requests.get(url, var headers:any=header, var params:any=params, var verify:any=false).json"},{"id":"syslib_from.requests.get(url, var headers:any=header, var params:any=params, var verify:any=false).json().get"},{"id":"syslib_from.logging.getLogger(mcp-server).warning"},{"id":"syslib_from.logging.getLogger(mcp-server).error"},{"id":"/src/mcpSim/src/mcpSim/server.get_app_call_info.get_app_call_info_scope...str"},{"id":"/src/mcpSim/src/mcpSim/server..print"},{"id":"mcpSqlExecute.server.mcp.run"},{"id":"main \\n[server.py : 100_114]","location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpTestAnalysis/src/mcpTestAnalysis/server.py"},"region":{"startLine":100,"startColumn":5,"endLine":114,"endColumn":41,"snippet":{}}}}},{"id":"handle_call_tool \\n[server.py : 55_77]","location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpTestAnalysis/src/mcpTestAnalysis/server.py"},"region":{"startLine":55,"startColumn":1,"endLine":77,"endColumn":67,"snippet":{}}}}},{"id":"/src/mcpTestAnalysis/src/mcpTestAnalysis/server.handle_call_tool.handle_call_tool_scope...ValueError"},{"id":"/src/mcpTestAnalysis/src/mcpTestAnalysis/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"id":"syslib_from.client.get_branch_prompt"},{"id":"/src/mcpTestAnalysis/src/mcpTestAnalysis/server..main.main_scope..print"},{"id":"main \\n[client.py : 106_110]","location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpTestAnalysisDocument/src/mcpTestAnalysisDocument/client.py"},"region":{"startLine":106,"startColumn":5,"endLine":110,"endColumn":66,"snippet":{}}}}},{"id":"get_code_diffs \\n[client.py : 40_72]","location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpTestAnalysisDocument/src/mcpTestAnalysisDocument/client.py"},"region":{"startLine":40,"startColumn":1,"endLine":72,"endColumn":28,"snippet":{}}}}},{"id":"CodeAnalysisResult :: __init__ \\n[client.py : 25_28]","location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpTestAnalysisDocument/src/mcpTestAnalysisDocument/client.py"},"region":{"startLine":25,"startColumn":5,"endLine":28,"endColumn":29,"snippet":{}}}}},{"id":"_headers \\n[client.py : 16_20]","location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpTestAnalysisDocument/src/mcpTestAnalysisDocument/client.py"},"region":{"startLine":16,"startColumn":1,"endLine":20,"endColumn":6,"snippet":{}}}}},{"id":"mcp_common.request.http_client.AsyncRestClient(var base_url:any=https://instemc.alipay.com, var default_headers:any=_headers()).post"},{"id":"mcp_common.request.http_client.AsyncRestClient(var base_url:any=https://instemc.alipay.com, var default_headers:any=_headers()).post(var endpoint:any=/testAnalysis/getCodeDiffs, var data:any=diff_url)..."},{"id":"/src/mcpTestAnalysis/src/mcpTestAnalysis/client.get_code_diffs.get_code_diffs_scope...str"},{"id":"mcp_common.request.http_client.AsyncRestClient(var base_url:any=https://instemc.alipay.com, var default_headers:any=_headers()).__aexit__"},{"id":"CodeAnalysisResult :: to_dict \\n[client.py : 30_35]","location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpTestAnalysisDocument/src/mcpTestAnalysisDocument/client.py"},"region":{"startLine":30,"startColumn":5,"endLine":35,"endColumn":10,"snippet":{}}}}},{"id":"/src/mcpTestAnalysis/src/mcpTestAnalysis/client..main.main_scope..print"},{"id":"sofapy.core.app.create_app"},{"id":"main \\n[test_hello.py : 33_66]","location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpTestAnalysis/src/tests/test_hello.py"},"region":{"startLine":33,"startColumn":1,"endLine":66,"endColumn":52,"snippet":{}}}}},{"id":"sofapy.middlewares.rpc.MCPSubService"},{"id":"sofapy.core.app.create_app(deriskcore, user_config).subscribe_mcp_service"},{"id":"sofapy.core.mcp.client.client.MCPClient.create"},{"id":"sofapy.core.mcp.client.client.MCPClient.create(service_code, var header:any=properties).connect_to_server"},{"id":"sofapy.core.mcp.client.client.MCPClient.create(service_code, var header:any=properties).list_tools"},{"id":"/src/mcpTestAnalysis/src/tests/test_hello.main.main_scope..print"},{"id":"sofapy.core.mcp.client.client.MCPClient.create(service_code, var header:any=properties).cleanup"},{"id":"/src/mcpTestAnalysis/src/tests/test_hello.main.main_scope..str"},{"id":"/src/mcpTestAnalysis/src/tests/test_hello.main.main_scope..str(uuid.uuid4()).replace"},{"id":"sofapy.core.mcp.client.client.MCPClient.create(service_code, var header:any=properties).call_tool"},{"id":"/src/mcpTestAnalysisDocument/src/mcpTestAnalysisDocument/client.get_code_diffs.get_code_diffs_scope...str"},{"id":"/src/mcpTestAnalysisDocument/src/mcpTestAnalysisDocument/client..main.main_scope..print"},{"id":"main \\n[report_client.py : 80_84]","location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpTestAnalysisDocument/src/mcpTestAnalysisDocument/report_client.py"},"region":{"startLine":80,"startColumn":5,"endLine":84,"endColumn":66,"snippet":{}}}}},{"id":"write_document \\n[report_client.py : 42_74]","location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpTestAnalysisDocument/src/mcpTestAnalysisDocument/report_client.py"},"region":{"startLine":42,"startColumn":1,"endLine":74,"endColumn":28,"snippet":{}}}}},{"id":"Result :: __init__ \\n[report_client.py : 27_30]","location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpTestAnalysisDocument/src/mcpTestAnalysisDocument/report_client.py"},"region":{"startLine":27,"startColumn":5,"endLine":30,"endColumn":26,"snippet":{}}}}},{"id":"_headers \\n[report_client.py : 18_22]","location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpTestAnalysisDocument/src/mcpTestAnalysisDocument/report_client.py"},"region":{"startLine":18,"startColumn":1,"endLine":22,"endColumn":6,"snippet":{}}}}},{"id":"mcp_common.request.http_client.AsyncRestClient(var base_url:any=https://instemc.alipay.com/yuque, var default_headers:any=_headers()).post"},{"id":"mcp_common.request.http_client.AsyncRestClient(var base_url:any=https://instemc.alipay.com/yuque, var default_headers:any=_headers()).post(var endpoint:any=/writeDocument, var data:any=payload).get"},{"id":"/src/mcpTestAnalysisDocument/src/mcpTestAnalysisDocument/report_client.write_document.write_document_scope...str"},{"id":"mcp_common.request.http_client.AsyncRestClient(var base_url:any=https://instemc.alipay.com/yuque, var default_headers:any=_headers()).__aexit__"},{"id":"Result :: to_dict \\n[report_client.py : 32_37]","location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpTestAnalysisDocument/src/mcpTestAnalysisDocument/report_client.py"},"region":{"startLine":32,"startColumn":5,"endLine":37,"endColumn":10,"snippet":{}}}}},{"id":"/src/mcpTestAnalysisDocument/src/mcpTestAnalysisDocument/report_client..main.main_scope..print"},{"id":"main \\n[yuque_markdown.py : 215_219]","location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpTestAnalysisDocument/src/mcpTestAnalysisDocument/yuque_markdown.py"},"region":{"startLine":215,"startColumn":5,"endLine":219,"endColumn":66,"snippet":{}}}}},{"id":"split_block_remain_pic_url \\n[yuque_markdown.py : 74_98]","location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpTestAnalysisDocument/src/mcpTestAnalysisDocument/yuque_markdown.py"},"region":{"startLine":74,"startColumn":1,"endLine":98,"endColumn":28,"snippet":{}}}}},{"id":"Result :: __init__ \\n[yuque_markdown.py : 24_27]","location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpTestAnalysisDocument/src/mcpTestAnalysisDocument/yuque_markdown.py"},"region":{"startLine":24,"startColumn":5,"endLine":27,"endColumn":26,"snippet":{}}}}},{"id":"_headers \\n[yuque_markdown.py : 15_19]","location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpTestAnalysisDocument/src/mcpTestAnalysisDocument/yuque_markdown.py"},"region":{"startLine":15,"startColumn":1,"endLine":19,"endColumn":6,"snippet":{}}}}},{"id":"mcp_common.request.http_client.AsyncRestClient(var base_url:any=https://instemc.alipay.com/yuque, var default_headers:any=_headers()).post(var endpoint:any=/splitBlockRemainPicUrl, var data:any=payloa..."},{"id":"/src/mcpTestAnalysisDocument/src/mcpTestAnalysisDocument/yuque_markdown.split_block_remain_pic_url.split_block_remain_pic_url_scope...str"},{"id":"Result :: to_dict \\n[yuque_markdown.py : 29_34]","location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpTestAnalysisDocument/src/mcpTestAnalysisDocument/yuque_markdown.py"},"region":{"startLine":29,"startColumn":5,"endLine":34,"endColumn":10,"snippet":{}}}}},{"id":"/src/mcpTestAnalysisDocument/src/mcpTestAnalysisDocument/yuque_markdown..main.main_scope..print"},{"id":"mcpTvp.server.mcp.run"},{"id":"execute_cypress_script \\n[tvp_client.py : 21_39]","location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpTvp/src/mcpTvp/tvp_client.py"},"region":{"startLine":21,"startColumn":1,"endLine":39,"endColumn":20,"snippet":{}}}}},{"id":"_execute_script \\n[tvp_client.py : 102_131]","location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpTvp/src/mcpTvp/tvp_client.py"},"region":{"startLine":102,"startColumn":1,"endLine":131,"endColumn":16,"snippet":{}}}}},{"id":"describe(\\'截图\\', function () {"},{"id":"syslib_from.base64.b64encode(script_byte).decode"},{"id":"syslib_from.json.dumps(env_list).encode"},{"id":"syslib_from.base64.b64encode(env_byte).decode"},{"id":"syslib_from.requests.post(url, var headers:any=TVP_HEADER, var json:any=params).raise_for_status"},{"id":"syslib_from.requests.post(url, var headers:any=TVP_HEADER, var json:any=params).json"},{"id":"syslib_from.requests.post(url, var headers:any=TVP_HEADER, var json:any=params).json().get"},{"id":"/src/mcpTvp/src/mcpTvp/tvp_client..print"},{"id":"/src/mcpYuntu/src/mcpYuntu/server..get_yuntu_call_tree"},{"id":"/src/mcpYuntu/src/mcpYuntu/server..asyncio.run"},{"id":"/src/mcpYuntu/src/mcpYuntu/server..print"},{"id":"yuntu_util.sample_trace"},{"id":"YUNTU_CONFIG.get"},{"id":"get_yuntu_call_key_message_by_service \\n[yuntu_client.py : 174_203]","location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpYuntu/src/mcpYuntu/yuntu_client.py"},"region":{"startLine":174,"startColumn":1,"endLine":203,"endColumn":20,"snippet":{}}}}},{"id":"_get_complete_tree \\n[yuntu_client.py : 206_221]","location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpYuntu/src/mcpYuntu/yuntu_client.py"},"region":{"startLine":206,"startColumn":1,"endLine":221,"endColumn":16,"snippet":{}}}}},{"id":"syslib_from.requests.get(url, var headers:any=YUNTU_HEADER, var params:any=params, var verify:any=false).raise_for_status"},{"id":"syslib_from.requests.get(url, var headers:any=YUNTU_HEADER, var params:any=params, var verify:any=false).json"},{"id":"syslib_from.requests.get(url, var headers:any=YUNTU_HEADER, var params:any=params, var verify:any=false).json().get"},{"id":"/src/mcpYuntu/src/mcpYuntu/yuntu_client.TraceResult.model_validate"},{"id":"_collect_key_message_by_service \\n[yuntu_client.py : 291_304]","location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpYuntu/src/mcpYuntu/yuntu_client.py"},"region":{"startLine":291,"startColumn":1,"endLine":304,"endColumn":107,"snippet":{}}}}},{"id":"com.alipay.mobilecashier.senior.service.facade.MobilecashierOrderFacade:1.0:escrowexprod.lower"},{"id":"/src/mcpYuntu/src/mcpYuntu/yuntu_client.TraceResult.model_validate(result.get(result)).traceInfo.serviceName.lower"},{"id":"....traceInfo.serviceName.lower"},{"id":"checkAndPayOrder.lower"},{"id":"/src/mcpYuntu/src/mcpYuntu/yuntu_client.TraceResult.model_validate(result.get(result)).traceInfo.methodName.lower"},{"id":"....traceInfo.methodName.lower"},{"id":"current_path.copy"},{"id":"_find_subtree \\n[yuntu_client.py : 224_236]","location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpYuntu/src/mcpYuntu/yuntu_client.py"},"region":{"startLine":224,"startColumn":1,"endLine":236,"endColumn":16,"snippet":{}}}}},{"id":"_collect_nodes \\n[yuntu_client.py : 265_278]","location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpYuntu/src/mcpYuntu/yuntu_client.py"},"region":{"startLine":265,"startColumn":1,"endLine":278,"endColumn":21,"snippet":{}}}}},{"id":"/src/mcpYuntu/src/mcpYuntu/yuntu_client..print"},{"id":"main \\n[test_sample_yuntu.py : 39_59]","location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpYuntu/src/tests/test_sample_yuntu.py"},"region":{"startLine":39,"startColumn":1,"endLine":59,"endColumn":45,"snippet":{}}}}},{"id":"/src/mcpYuntu/src/tests/test_sample_yuntu.main.main_scope..open"},{"id":"/src/mcpYuntu/src/tests/test_sample_yuntu.main.main_scope..open(resource/yuntu.txt, r, var encoding:any=UTF-8).read"},{"id":"sample_trace \\n[test_sample_yuntu.py : 61_71]","location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpYuntu/src/tests/test_sample_yuntu.py"},"region":{"startLine":61,"startColumn":1,"endLine":71,"endColumn":10,"snippet":{}}}}},{"id":"process_node \\n[test_sample_yuntu.py : 4_36]","location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpYuntu/src/tests/test_sample_yuntu.py"},"region":{"startLine":4,"startColumn":1,"endLine":36,"endColumn":16,"snippet":{}}}}},{"id":"syslib_from.json.loads(input_json).traceInfo.children.get"},{"id":"syslib_from.json.loads(input_json).traceInfo.children.get(serviceName).split"},{"id":"/src/mcpYuntu/src/tests/test_sample_yuntu.process_node.process_node_scope...len"},{"id":"/src/mcpYuntu/src/tests/test_sample_yuntu.process_node.process_node_scope....int"},{"id":"syslib_from.json.loads(input_json).traceInfo.children.pop"},{"id":"syslib_from.json.loads(input_json).traceInfo.children.pop(data).pop"},{"id":"syslib_from.json.loads(input_json).traceInfo.children.update"},{"id":"/src/mcpYuntu/src/tests/test_sample_yuntu.main.main_scope..len"},{"id":"/src/mcpYuntu/src/tests/test_sample_yuntu.main.main_scope..print"},{"id":"main \\n[report_client.py : 78_82]","location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpyuque/src/mcpyuque/report_client.py"},"region":{"startLine":78,"startColumn":5,"endLine":82,"endColumn":66,"snippet":{}}}}},{"id":"write_document \\n[report_client.py : 40_72]","location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpyuque/src/mcpyuque/report_client.py"},"region":{"startLine":40,"startColumn":1,"endLine":72,"endColumn":28,"snippet":{}}}}},{"id":"Result :: __init__ \\n[report_client.py : 25_28]","location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpyuque/src/mcpyuque/report_client.py"},"region":{"startLine":25,"startColumn":5,"endLine":28,"endColumn":26,"snippet":{}}}}},{"id":"_headers \\n[report_client.py : 16_20]","location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpyuque/src/mcpyuque/report_client.py"},"region":{"startLine":16,"startColumn":1,"endLine":20,"endColumn":6,"snippet":{}}}}},{"id":"/src/mcpyuque/src/mcpyuque/report_client.write_document.write_document_scope...str"},{"id":"Result :: to_dict \\n[report_client.py : 30_35]","location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpyuque/src/mcpyuque/report_client.py"},"region":{"startLine":30,"startColumn":5,"endLine":35,"endColumn":10,"snippet":{}}}}},{"id":"/src/mcpyuque/src/mcpyuque/report_client..main.main_scope..print"},{"id":"main \\n[yuque_markdown.py : 106_110]","location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpyuque/src/mcpyuque/yuque_markdown.py"},"region":{"startLine":106,"startColumn":5,"endLine":110,"endColumn":66,"snippet":{}}}}},{"id":"split_block_remain_pic_url \\n[yuque_markdown.py : 75_99]","location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpyuque/src/mcpyuque/yuque_markdown.py"},"region":{"startLine":75,"startColumn":1,"endLine":99,"endColumn":28,"snippet":{}}}}},{"id":"Result :: __init__ \\n[yuque_markdown.py : 25_28]","location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpyuque/src/mcpyuque/yuque_markdown.py"},"region":{"startLine":25,"startColumn":5,"endLine":28,"endColumn":26,"snippet":{}}}}},{"id":"_headers \\n[yuque_markdown.py : 16_20]","location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpyuque/src/mcpyuque/yuque_markdown.py"},"region":{"startLine":16,"startColumn":1,"endLine":20,"endColumn":6,"snippet":{}}}}},{"id":"/src/mcpyuque/src/mcpyuque/yuque_markdown.split_block_remain_pic_url.split_block_remain_pic_url_scope...str"},{"id":"Result :: to_dict \\n[yuque_markdown.py : 30_35]","location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpyuque/src/mcpyuque/yuque_markdown.py"},"region":{"startLine":30,"startColumn":5,"endLine":35,"endColumn":10,"snippet":{}}}}},{"id":"/src/mcpyuque/src/mcpyuque/yuque_markdown..main.main_scope..print"},{"id":"AntnluserviceAPI :: __init__ \\n[antnluservice.py : 19_20]","location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-common/src/mcp_common/remote/antnluservice.py"},"region":{"startLine":19,"startColumn":5,"endLine":20,"endColumn":55,"snippet":{}}}}},{"id":"/src/mcp-common/src/mcp_common/remote/codefuse_search.SymbolLocation.Field"},{"id":"/src/mcp-common/src/mcp_common/remote/codefuse_search.Symbol.Field"},{"id":"/src/mcp-common/src/mcp_common/remote/codefuse_search.SymbolLocation"},{"id":"SymbolSearchAPI :: __init__ \\n[codefuse_search.py : 60_65]","location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-common/src/mcp_common/remote/codefuse_search.py"},"region":{"startLine":60,"startColumn":5,"endLine":65,"endColumn":10,"snippet":{}}}}},{"id":"/src/mcp-common/src/mcp_common/remote/codefuse_search.SymbolSearchAPI._CTOR_.__init___scope..dict"},{"id":"CodeInsightAPI :: __init__ \\n[codeinsight.py : 26_31]","location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-common/src/mcp_common/remote/codeinsight.py"},"region":{"startLine":26,"startColumn":5,"endLine":31,"endColumn":10,"snippet":{}}}}},{"id":"/src/mcp-common/src/mcp_common/remote/codeinsight.CodeInsightAPI._CTOR_.__init___scope..dict"},{"id":"encrypt \\n[crypto.py : 47_71]","location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-common/src/mcp_common/utils/crypto.py"},"region":{"startLine":47,"startColumn":1,"endLine":71,"endColumn":20,"snippet":{}}}}},{"id":"pathlib.Path"},{"id":"/src/mcp-common/src/mcp_common/utils/crypto.encrypt.encrypt_scope..open"},{"id":"/src/mcp-common/src/mcp_common/utils/crypto.encrypt.encrypt_scope..open(public_key_pem_path, rb).read"},{"id":"cryptography.hazmat.backends.default_backend"},{"id":"cryptography.hazmat.primitives.serialization.load_pem_public_key"},{"id":"hello world.encode"},{"id":"cryptography.hazmat.primitives.hashes.SHA256"},{"id":"cryptography.hazmat.primitives.asymmetric.padding.MGF1"},{"id":"cryptography.hazmat.primitives.asymmetric.padding.OAEP"},{"id":"cryptography.hazmat.primitives.serialization.load_pem_public_key(pem_data, var backend:any=default_backend()).encrypt"},{"id":"cryptography.hazmat.primitives.serialization.load_pem_public_key(pem_data, var backend:any=default_backend()).encrypt(message.encode(), padding.OAEP(var mgf:any=padding.MGF1(var algorithm:any=hashes.S..."},{"id":"/src/mcp-common/src/mcp_common/utils/crypto..print"},{"id":"CodeConfig :: __init__ \\n[code_config.py : 30_48]","location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-common/src/mcp_common/utils/code_config.py"},"region":{"startLine":30,"startColumn":5,"endLine":48,"endColumn":45,"snippet":{}}}}},{"id":"/src/mcp-common/src/mcp_common/utils/code_config.CodeConfig._CTOR_.__init___scope..open"},{"id":"syslib_from.yaml.safe_load"},{"id":"CodeConfig :: unfold \\n[code_config.py : 50_57]","location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-common/src/mcp_common/utils/code_config.py"},"region":{"startLine":50,"startColumn":5,"endLine":57,"endColumn":27,"snippet":{}}}}},{"id":"syslib_from.yaml.safe_load(f).items"},{"id":"/src/mcp-common/src/mcp_common/utils/code_config.CodeConfig.unfold.unfold_scope....isinstance"},{"id":"upper"},{"id":"upper().upper"},{"id":"sv.upper"},{"id":"syslib_from.yaml.safe_load(f).items().upper"},{"id":"CodeConfig :: decrypt \\n[code_config.py : 60_66]","location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-common/src/mcp_common/utils/code_config.py"},"region":{"startLine":60,"startColumn":5,"endLine":66,"endColumn":27,"snippet":{}}}}},{"id":"items"},{"id":"/src/mcp-common/src/mcp_common/utils/code_config.CodeConfig.decrypt.decrypt_scope....isinstance"},{"id":"items().startswith"},{"id":"items().replace"},{"id":"decrypt \\n[crypto.py : 75_99]","location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-common/src/mcp_common/utils/crypto.py"},"region":{"startLine":75,"startColumn":1,"endLine":99,"endColumn":20,"snippet":{}}}}},{"id":"/src/mcp-common/src/mcp_common/utils/crypto.decrypt.decrypt_scope..open"},{"id":"/src/mcp-common/src/mcp_common/utils/crypto.decrypt.decrypt_scope..open(private_key_pem_path, rb).read"},{"id":"cryptography.hazmat.primitives.serialization.load_pem_private_key"},{"id":"/src/mcp-common/src/mcp_common/utils/crypto.decrypt.decrypt_scope..bytes.fromhex"},{"id":"cryptography.hazmat.primitives.serialization.load_pem_private_key(pem_data, var password:any=..., var backend:any=default_backend()).decrypt"},{"id":"cryptography.hazmat.primitives.serialization.load_pem_private_key(pem_data, var password:any=..., var backend:any=default_backend()).decrypt(bytes.fromhex(ciphertext), padding.OAEP(var mgf:any=padding..."},{"id":"items().upper"},{"id":"....upper"},{"id":"/src/mcp-common/src/mcp_common/utils/code_config.CodeConfig._CTOR_.__init___scope...dir"},{"id":"/src/mcp-common/src/mcp_common/utils/code_config.CodeConfig._CTOR_.__init___scope...filter"},{"id":"/src/mcp-common/src/mcp_common/utils/code_config.CodeConfig._CTOR_.__init___scope... \\n[code_config.py : 42_42]","location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-common/src/mcp_common/utils/code_config.py"},"region":{"startLine":42,"startColumn":29,"endLine":42,"endColumn":76,"snippet":{}}}}},{"id":"x.startswith"},{"id":"x.isupper"},{"id":"syslib_from.os.getenv"},{"id":"/src/mcp-common/src/mcp_common/utils/env_util.cachetools.TTLCache"},{"id":"/src/mcp-common/src/mcp_common/utils/env_util.cachetools.cached"},{"id":"syslib_from.cachetools.TTLCache"},{"id":"syslib_from.cachetools.cached"},{"id":"EnvUtil :: __init__ \\n[env_util.py : 25_28]","location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-common/src/mcp_common/utils/env_util.py"},"region":{"startLine":25,"startColumn":5,"endLine":28,"endColumn":52,"snippet":{}}}}},{"id":"syslib_from.logging.Formatter"},{"id":"layotto_turbo.layotto.init_mist"},{"id":"get_mist_secret \\n[mist_util.py : 13_18]","location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-common/src/mcp_common/utils/mist_util.py"},"region":{"startLine":13,"startColumn":1,"endLine":18,"endColumn":69,"snippet":{}}}}},{"id":"layotto_turbo.layotto.get_secret_from_mist"},{"id":"/src/mcp-common/src/mcp_common/utils/mist_util.get_mist_secret.get_mist_secret_scope...ValueError"},{"id":"/src/mcp-common/src/mcp_common/utils/mist_util..print"},{"id":"syslib_from.oss2.Auth"},{"id":"syslib_from.oss2.Bucket"},{"id":"create_oss_path \\n[oss_utils.py : 244_245]","location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-common/src/mcp_common/utils/oss_utils.py"},"region":{"startLine":244,"startColumn":1,"endLine":245,"endColumn":55,"snippet":{}}}}},{"id":"/src/mcp-common/src/mcp_common/utils/oss_utils..print"},{"id":"handle_call_tool \\n[server.py : 172_202]","location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpAntlogs/src/mcpAntlogs/server.py"},"region":{"startLine":172,"startColumn":1,"endLine":202,"endColumn":54,"snippet":{}}}}},{"id":"/src/mcpAntlogs/src/mcpAntlogs/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"id":"/src/mcpAntlogs/src/mcpAntlogs/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"id":"/src/mcpAntlogs/src/mcpAntlogs/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"id":"/src/mcpAntlogs/src/mcpAntlogs/server.handle_call_tool.arguments.get"},{"id":"query_app_trace_log \\n[server.py : 35_81]","location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpAntlogs/src/mcpAntlogs/server.py"},"region":{"startLine":35,"startColumn":1,"endLine":81,"endColumn":20,"snippet":{}}}}},{"id":"syslib_from.logging.info"},{"id":"query_raw \\n[server.py : 84_109]","location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpAntlogs/src/mcpAntlogs/server.py"},"region":{"startLine":84,"startColumn":1,"endLine":109,"endColumn":25,"snippet":{}}}}},{"id":"/src/mcpAntlogs/src/mcpAntlogs/server.query_raw.query_raw_scope..int"},{"id":"/src/mcpAntlogs/src/mcpAntlogs/server.query_raw.query_raw_scope..str"},{"id":"/src/mcpAntlogs/src/mcpAntlogs/server.query_raw.query_raw_scope..bytes"},{"id":"syslib_from.requests.post(_MAAS_URL, var headers:any=headers, var data:any=payload, var timeout:any=(5, 60)).json"},{"id":"syslib_from.json.loads(resp_str).data.appDiffLogDatas.get"},{"id":"syslib_from.json.loads(resp_str).data.appDiffLogDatas.get(errorLog, {}).get"},{"id":"error_pattern_utils.is_error_log"},{"id":"/src/mcpAntlogs/src/mcpAntlogs/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"id":"/src/mcpAntlogs/src/mcpAntlogs/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"id":"/src/mcpAntlogs/src/mcpAntlogs/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"id":"query_machine_log \\n[server.py : 112_130]","location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpAntlogs/src/mcpAntlogs/server.py"},"region":{"startLine":112,"startColumn":1,"endLine":130,"endColumn":47,"snippet":{}}}}},{"id":"yuntu_cmd_util.execute_cmd"},{"id":"/src/mcpAntlogs/src/mcpAntlogs/server.query_machine_log.query_machine_log_scope...str"},{"id":"/src/mcpAntlogs/src/mcpAntlogs/server.handle_call_tool.handle_call_tool_scope...ValueError"},{"id":"handle_call_tool \\n[server.py : 115_154]","location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpAntmonitor/src/mcpAntmonitor/server.py"},"region":{"startLine":115,"startColumn":1,"endLine":154,"endColumn":54,"snippet":{}}}}},{"id":"/src/mcpAntmonitor/src/mcpAntmonitor/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"id":"/src/mcpAntmonitor/src/mcpAntmonitor/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"id":"/src/mcpAntmonitor/src/mcpAntmonitor/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"id":"/src/mcpAntmonitor/src/mcpAntmonitor/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"id":"/src/mcpAntmonitor/src/mcpAntmonitor/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"id":"/src/mcpAntmonitor/src/mcpAntmonitor/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"id":"/src/mcpAntmonitor/src/mcpAntmonitor/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"id":"/src/mcpAntmonitor/src/mcpAntmonitor/server.handle_call_tool.arguments.get"},{"id":"syslib_from.antmonitor_client.get_app_metric"},{"id":"/src/mcpAntmonitor/src/mcpAntmonitor/server.handle_call_tool.handle_call_tool_scope...ValueError"},{"id":"handle_call_tool \\n[server.py : 61_129]","location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpAntscheduler/src/mcpAntscheduler/server.py"},"region":{"startLine":61,"startColumn":1,"endLine":129,"endColumn":54,"snippet":{}}}}},{"id":"/src/mcpAntscheduler/src/mcpAntscheduler/server.handle_call_tool.handle_call_tool_scope..json.dumps"},{"id":"/src/mcpAntscheduler/src/mcpAntscheduler/server.handle_call_tool.handle_call_tool_scope..info_logger.info"},{"id":"/src/mcpAntscheduler/src/mcpAntscheduler/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"id":"/src/mcpAntscheduler/src/mcpAntscheduler/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"id":"/src/mcpAntscheduler/src/mcpAntscheduler/server.handle_call_tool.handle_call_tool_scope...get_job_list_by_app"},{"id":"/src/mcpAntscheduler/src/mcpAntscheduler/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"id":"/src/mcpAntscheduler/src/mcpAntscheduler/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"id":"/src/mcpAntscheduler/src/mcpAntscheduler/server.handle_call_tool.handle_call_tool_scope...query_job_operation_record"},{"id":"/src/mcpAntscheduler/src/mcpAntscheduler/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"id":"/src/mcpAntscheduler/src/mcpAntscheduler/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"id":"/src/mcpAntscheduler/src/mcpAntscheduler/server.handle_call_tool.handle_call_tool_scope...get_job_list_by_app"},{"id":"/src/mcpAntscheduler/src/mcpAntscheduler/server.handle_call_tool.handle_call_tool_scope..json.loads"},{"id":"/src/mcpAntscheduler/src/mcpAntscheduler/server.handle_call_tool.handle_call_tool_scope......len"},{"id":"/src/mcpAntscheduler/src/mcpAntscheduler/server.handle_call_tool.handle_call_tool_scope..json.loads(result_text).get"},{"id":"/src/mcpAntscheduler/src/mcpAntscheduler/server.handle_call_tool.handle_call_tool_scope..json.loads(result_text).get(jobItems, {}).get"},{"id":"/src/mcpAntscheduler/src/mcpAntscheduler/server.handle_call_tool.handle_call_tool_scope........ValueError"},{"id":"handle_call_tool \\n[server.py : 145_218]","location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpCloudinc/src/mcpCloudinc/server.py"},"region":{"startLine":145,"startColumn":1,"endLine":218,"endColumn":54,"snippet":{}}}}},{"id":"/src/mcpCloudinc/src/mcpCloudinc/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"id":"/src/mcpCloudinc/src/mcpCloudinc/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"id":"get_domain_name_by_app \\n[server.py : 238_273]","location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpCloudinc/src/mcpCloudinc/server.py"},"region":{"startLine":238,"startColumn":1,"endLine":273,"endColumn":20,"snippet":{}}}}},{"id":"get_dns_domain_by_app \\n[server.py : 240_261]","location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpCloudinc/src/mcpCloudinc/server.py"},"region":{"startLine":240,"startColumn":9,"endLine":261,"endColumn":24,"snippet":{}}}}},{"id":"CLOUDINC_DNS_URL_DICT.get"},{"id":"CLOUDINC_DNS_URL_DICT.get(prod).get"},{"id":"syslib_from.requests.post(config.get(url), var json:any=body).raise_for_status"},{"id":"syslib_from.requests.post(config.get(url), var json:any=body).json"},{"id":"syslib_from.requests.post(config.get(url), var json:any=body).json().get"},{"id":"syslib_from.requests.post(config.get(url), var json:any=body).json().get(data).get"},{"id":"syslib_from.requests.post(config.get(url), var json:any=body).json().get(data).get(domains).get"},{"id":"get_antvip_detail_by_app \\n[server.py : 276_296]","location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpCloudinc/src/mcpCloudinc/server.py"},"region":{"startLine":276,"startColumn":1,"endLine":296,"endColumn":20,"snippet":{}}}}},{"id":"oneapi.cloudinc.AntvipDomainQueryFacade.AntvipDomainQueryFacade(layotto).queryByApp"},{"id":"oneapi.cloudinc.AntvipDomainQueryFacade.AntvipDomainQueryFacade(layotto).queryByApp(var appName:any=app).data.target.get_json"},{"id":"/src/mcpCloudinc/src/mcpCloudinc/server.get_antvip_detail_by_app.get_antvip_detail_by_app_scope...str"},{"id":"syslib_from.json.loads(antvip_result).get"},{"id":"syslib_from.asyncio.gather(task1, task2).append"},{"id":"/src/mcpCloudinc/src/mcpCloudinc/server.get_domain_name_by_app.get_domain_name_by_app_scope...str"},{"id":"/src/mcpCloudinc/src/mcpCloudinc/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"id":"/src/mcpCloudinc/src/mcpCloudinc/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"id":"/src/mcpCloudinc/src/mcpCloudinc/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"id":"/src/mcpCloudinc/src/mcpCloudinc/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"id":"/src/mcpCloudinc/src/mcpCloudinc/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"id":"/src/mcpCloudinc/src/mcpCloudinc/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"id":"get_domain_by_ips \\n[server.py : 299_330]","location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpCloudinc/src/mcpCloudinc/server.py"},"region":{"startLine":299,"startColumn":1,"endLine":330,"endColumn":20,"snippet":{}}}}},{"id":"CLOUDINC_URL_DICT.get"},{"id":"CLOUDINC_URL_DICT.get(tenant).get"},{"id":"syslib_from.requests.get(url, var headers:any=headers, var params:any=params).raise_for_status"},{"id":"syslib_from.requests.get(url, var headers:any=headers, var params:any=params).json"},{"id":"syslib_from.requests.get(url, var headers:any=headers, var params:any=params).json().get"},{"id":"/src/mcpCloudinc/src/mcpCloudinc/server.get_domain_by_ips.get_domain_by_ips_scope...str"},{"id":"/src/mcpCloudinc/src/mcpCloudinc/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"id":"/src/mcpCloudinc/src/mcpCloudinc/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"id":"/src/mcpCloudinc/src/mcpCloudinc/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"id":"/src/mcpCloudinc/src/mcpCloudinc/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"id":"/src/mcpCloudinc/src/mcpCloudinc/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"id":"get_domain_detail \\n[server.py : 333_365]","location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpCloudinc/src/mcpCloudinc/server.py"},"region":{"startLine":333,"startColumn":1,"endLine":365,"endColumn":20,"snippet":{}}}}},{"id":"/src/mcpCloudinc/src/mcpCloudinc/server.get_domain_detail.get_domain_detail_scope...str"},{"id":"/src/mcpCloudinc/src/mcpCloudinc/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"id":"/src/mcpCloudinc/src/mcpCloudinc/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"id":"/src/mcpCloudinc/src/mcpCloudinc/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"id":"/src/mcpCloudinc/src/mcpCloudinc/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"id":"/src/mcpCloudinc/src/mcpCloudinc/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"id":"/src/mcpCloudinc/src/mcpCloudinc/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"id":"get_domain_labels \\n[server.py : 368_400]","location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpCloudinc/src/mcpCloudinc/server.py"},"region":{"startLine":368,"startColumn":1,"endLine":400,"endColumn":20,"snippet":{}}}}},{"id":"syslib_from.requests.get(url, var headers:any=headers).raise_for_status"},{"id":"syslib_from.requests.get(url, var headers:any=headers).json"},{"id":"syslib_from.requests.get(url, var headers:any=headers).json().get"},{"id":"/src/mcpCloudinc/src/mcpCloudinc/server.get_domain_labels.get_domain_labels_scope...str"},{"id":"/src/mcpCloudinc/src/mcpCloudinc/server.handle_call_tool.handle_call_tool_scope...ValueError"},{"id":"handle_call_tool \\n[server.py : 115_149]","location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpCmdExecution/src/mcpCmdExecution/server.py"},"region":{"startLine":115,"startColumn":1,"endLine":149,"endColumn":54,"snippet":{}}}}},{"id":"/src/mcpCmdExecution/src/mcpCmdExecution/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"id":"/src/mcpCmdExecution/src/mcpCmdExecution/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"id":"/src/mcpCmdExecution/src/mcpCmdExecution/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"id":"/src/mcpCmdExecution/src/mcpCmdExecution/server.handle_call_tool.arguments.get"},{"id":"command_execution \\n[server.py : 70_111]","location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpCmdExecution/src/mcpCmdExecution/server.py"},"region":{"startLine":70,"startColumn":1,"endLine":111,"endColumn":15,"snippet":{}}}}},{"id":"/src/mcpCmdExecution/src/mcpCmdExecution/server.command_execution.command_execution_scope..dict"},{"id":"mcp_common.remote.codeinsight.code_insight_api.mcp_server_backend_api"},{"id":"mcp_common.remote.codeinsight.code_insight_api.mcp_server_backend_api(var params:any=dict(var name:any=Consts.CMD_EXECUTION.name, var arguments:any=dict(var appName:any=app_name, var command:any=comma..."},{"id":"syslib_from.logging.getLogger(mcp-server).exception"},{"id":"/src/mcpCmdExecution/src/mcpCmdExecution/server.handle_call_tool.handle_call_tool_scope...ValueError"},{"id":"handle_call_tool \\n[server.py : 200_257]","location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpCodeContent/src/mcpCodeContent/server.py"},"region":{"startLine":200,"startColumn":1,"endLine":257,"endColumn":54,"snippet":{}}}}},{"id":"/src/mcpCodeContent/src/mcpCodeContent/server.handle_call_tool.handle_call_tool_scope...ValueError"},{"id":"/src/mcpCodeContent/src/mcpCodeContent/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"id":"/src/mcpCodeContent/src/mcpCodeContent/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"id":"/src/mcpCodeContent/src/mcpCodeContent/server.handle_call_tool.arguments.get"},{"id":"read_file_content \\n[server.py : 107_149]","location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpCodeContent/src/mcpCodeContent/server.py"},"region":{"startLine":107,"startColumn":1,"endLine":149,"endColumn":15,"snippet":{}}}}},{"id":"/src/mcpCodeContent/src/mcpCodeContent/server.read_file_content.read_file_content_scope..dict"},{"id":"mcp_common.remote.codeinsight.code_insight_api.mcp_server_backend_api(var params:any=dict(var name:any=Consts.READ_FILE_CONTENT.name, var arguments:any=dict(var appName:any=app_name, var filePath:any=..."},{"id":"/src/mcpCodeContent/src/mcpCodeContent/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"id":"/src/mcpCodeContent/src/mcpCodeContent/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"id":"extract_function_snippet \\n[server.py : 152_196]","location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpCodeContent/src/mcpCodeContent/server.py"},"region":{"startLine":152,"startColumn":1,"endLine":196,"endColumn":15,"snippet":{}}}}},{"id":"/src/mcpCodeContent/src/mcpCodeContent/server.extract_function_snippet.extract_function_snippet_scope..dict"},{"id":"mcp_common.remote.codeinsight.code_insight_api.mcp_server_backend_api(var params:any=dict(var name:any=Consts.EXTRACT_FUNCTION_SNIPPET.name, var arguments:any=dict(var appName:any=app_name, var filePa..."},{"id":"/src/mcpCodeContent/src/mcpCodeContent/server.handle_call_tool.handle_call_tool_scope...ValueError"},{"id":"handle_call_tool \\n[server.py : 68_99]","location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpCodeExecutor/src/mcpCodeExecutor/server.py"},"region":{"startLine":68,"startColumn":1,"endLine":99,"endColumn":11,"snippet":{}}}}},{"id":"/src/mcpCodeExecutor/src/mcpCodeExecutor/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"id":"/src/mcpCodeExecutor/src/mcpCodeExecutor/server.handle_call_tool.arguments.get"},{"id":"/src/mcpCodeExecutor/src/mcpCodeExecutor/server.handle_call_tool.handle_call_tool_scope...ValueError"},{"id":"handle_call_tool \\n[server.py : 220_275]","location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpCodeSearch/src/mcpCodeSearch/server.py"},"region":{"startLine":220,"startColumn":1,"endLine":275,"endColumn":54,"snippet":{}}}}},{"id":"/src/mcpCodeSearch/src/mcpCodeSearch/server.handle_call_tool.handle_call_tool_scope...ValueError"},{"id":"/src/mcpCodeSearch/src/mcpCodeSearch/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"id":"/src/mcpCodeSearch/src/mcpCodeSearch/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"id":"/src/mcpCodeSearch/src/mcpCodeSearch/server.handle_call_tool.arguments.get"},{"id":"error_code_search \\n[server.py : 127_169]","location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpCodeSearch/src/mcpCodeSearch/server.py"},"region":{"startLine":127,"startColumn":1,"endLine":169,"endColumn":15,"snippet":{}}}}},{"id":"/src/mcpCodeSearch/src/mcpCodeSearch/server.error_code_search.error_code_search_scope..dict"},{"id":"mcp_common.remote.codeinsight.code_insight_api.mcp_server_backend_api(var params:any=dict(var name:any=Consts.CODE_SEARCH.name, var arguments:any=dict(var appName:any=app_name, var searchPattern:any=s..."},{"id":"format_content \\n[server.py : 107_124]","location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpCodeSearch/src/mcpCodeSearch/server.py"},"region":{"startLine":107,"startColumn":1,"endLine":124,"endColumn":15,"snippet":{}}}}},{"id":"/src/mcpCodeSearch/src/mcpCodeSearch/server.format_content.format_content_scope...enumerate"},{"id":"/src/mcpCodeSearch/src/mcpCodeSearch/server.format_content.format_content_scope...enumerate(data_list).get"},{"id":"mcp_common.utils.consts.CODE_PATTERN.format"},{"id":"/src/mcpCodeSearch/src/mcpCodeSearch/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"id":"/src/mcpCodeSearch/src/mcpCodeSearch/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"id":"locate_class_file \\n[server.py : 172_216]","location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpCodeSearch/src/mcpCodeSearch/server.py"},"region":{"startLine":172,"startColumn":1,"endLine":216,"endColumn":15,"snippet":{}}}}},{"id":"/src/mcpCodeSearch/src/mcpCodeSearch/server.locate_class_file.locate_class_file_scope..dict"},{"id":"mcp_common.remote.codeinsight.code_insight_api.mcp_server_backend_api(var params:any=dict(var name:any=Consts.LOCATE_CLASS_FILE.name, var arguments:any=dict(var appName:any=app_name, var className:any..."},{"id":"/src/mcpCodeSearch/src/mcpCodeSearch/server.locate_class_file.locate_class_file_scope.....enumerate"},{"id":"/src/mcpCodeSearch/src/mcpCodeSearch/server.locate_class_file.locate_class_file_scope.....enumerate(data_list).get"},{"id":"/src/mcpCodeSearch/src/mcpCodeSearch/server.handle_call_tool.handle_call_tool_scope...ValueError"},{"id":"add \\n[server.py : 6_13]","location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpSqlExecute/src/mcpSqlExecute/server.py"},"region":{"startLine":6,"startColumn":1,"endLine":13,"endColumn":17,"snippet":{}}}}},{"id":"handle_call_tool \\n[server.py : 191_337]","location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDbCapacity/src/mcpDbCapacity/server.py"},"region":{"startLine":191,"startColumn":1,"endLine":337,"endColumn":65,"snippet":{}}}}},{"id":"/src/mcpDbCapacity/src/mcpDbCapacity/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"id":"/src/mcpDbCapacity/src/mcpDbCapacity/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"id":"/src/mcpDbCapacity/src/mcpDbCapacity/server.handle_call_tool.arguments.get"},{"id":"get_db_node_capacity \\n[server.py : 396_434]","location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDbCapacity/src/mcpDbCapacity/server.py"},"region":{"startLine":396,"startColumn":1,"endLine":434,"endColumn":29,"snippet":{}}}}},{"id":"mcp_db_base.ocp_client.get_cluster_arch"},{"id":"/src/mcpDbCapacity/src/mcpDbCapacity/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"id":"/src/mcpDbCapacity/src/mcpDbCapacity/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"id":"get_db_node_capacity_v2 \\n[server.py : 357_363]","location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDbCapacity/src/mcpDbCapacity/server.py"},"region":{"startLine":357,"startColumn":1,"endLine":363,"endColumn":57,"snippet":{}}}}},{"id":"mcp_db_base.prometheus_client.get_ob_capacity_monitor"},{"id":"/src/mcpDbCapacity/src/mcpDbCapacity/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"id":"get_db_cluster_capacity \\n[server.py : 437_446]","location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDbCapacity/src/mcpDbCapacity/server.py"},"region":{"startLine":437,"startColumn":1,"endLine":446,"endColumn":29,"snippet":{}}}}},{"id":"/src/mcpDbCapacity/src/mcpDbCapacity/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"id":"get_db_cluster_capacity_v2 \\n[server.py : 366_370]","location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDbCapacity/src/mcpDbCapacity/server.py"},"region":{"startLine":366,"startColumn":1,"endLine":370,"endColumn":57,"snippet":{}}}}},{"id":"/src/mcpDbCapacity/src/mcpDbCapacity/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"id":"/src/mcpDbCapacity/src/mcpDbCapacity/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"id":"get_db_tenant_capacity \\n[server.py : 449_524]","location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDbCapacity/src/mcpDbCapacity/server.py"},"region":{"startLine":449,"startColumn":1,"endLine":524,"endColumn":34,"snippet":{}}}}},{"id":"mcp_db_base.ocp_client.get_cluster_arch(cluster).get"},{"id":"/src/mcpDbCapacity/src/mcpDbCapacity/server.get_db_tenant_capacity.get_db_tenant_capacity_scope..len"},{"id":"....unit_info.keys"},{"id":"cluster_server_map.keys"},{"id":"/src/mcpDbCapacity/src/mcpDbCapacity/server.get_db_tenant_capacity.get_db_tenant_capacity_scope..list"},{"id":"/src/mcpDbCapacity/src/mcpDbCapacity/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"id":"/src/mcpDbCapacity/src/mcpDbCapacity/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"id":"get_db_tenant_capacity_v2 \\n[server.py : 373_393]","location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDbCapacity/src/mcpDbCapacity/server.py"},"region":{"startLine":373,"startColumn":1,"endLine":393,"endColumn":57,"snippet":{}}}}},{"id":"mcp_db_base.ocp_client.get_cluster_arch(cluster).get(tenant_info_list, ...).get"},{"id":"mcp_db_base.ocp_client.get_cluster_arch(cluster).get(tenant_info_list, ...).get(unit_info).keys"},{"id":"/src/mcpDbCapacity/src/mcpDbCapacity/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"id":"/src/mcpDbCapacity/src/mcpDbCapacity/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"id":"get_db_tenant_spec \\n[server.py : 527_528]","location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDbCapacity/src/mcpDbCapacity/server.py"},"region":{"startLine":527,"startColumn":1,"endLine":528,"endColumn":72,"snippet":{}}}}},{"id":"/src/mcpDbCapacity/src/mcpDbCapacity/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"id":"/src/mcpDbCapacity/src/mcpDbCapacity/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"id":"get_db_tenant_dump \\n[server.py : 536_537]","location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDbCapacity/src/mcpDbCapacity/server.py"},"region":{"startLine":536,"startColumn":1,"endLine":537,"endColumn":72,"snippet":{}}}}},{"id":"/src/mcpDbCapacity/src/mcpDbCapacity/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"id":"/src/mcpDbCapacity/src/mcpDbCapacity/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"id":"get_db_connector_count \\n[server.py : 531_533]","location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDbCapacity/src/mcpDbCapacity/server.py"},"region":{"startLine":531,"startColumn":1,"endLine":533,"endColumn":76,"snippet":{}}}}},{"id":"/src/mcpDbCapacity/src/mcpDbCapacity/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"id":"/src/mcpDbCapacity/src/mcpDbCapacity/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"id":"/src/mcpDbCapacity/src/mcpDbCapacity/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"id":"db_capacity_evalute \\n[server.py : 540_542]","location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDbCapacity/src/mcpDbCapacity/server.py"},"region":{"startLine":540,"startColumn":1,"endLine":542,"endColumn":78,"snippet":{}}}}},{"id":"/src/mcpDbCapacity/src/mcpDbCapacity/server.handle_call_tool.handle_call_tool_scope...ValueError"},{"id":"mcp.server.Server(mcp-db-capacity).request_context.session.send_flowing_data"},{"id":"handle_call_tool \\n[server.py : 92_163]","location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDbChanges/src/mcpDbChanges/server.py"},"region":{"startLine":92,"startColumn":1,"endLine":163,"endColumn":11,"snippet":{}}}}},{"id":"/src/mcpDbChanges/src/mcpDbChanges/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"id":"/src/mcpDbChanges/src/mcpDbChanges/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"id":"/src/mcpDbChanges/src/mcpDbChanges/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"id":"/src/mcpDbChanges/src/mcpDbChanges/server.handle_call_tool.arguments.get"},{"id":"mcp_db_base.tars_client.get_top_sql"},{"id":"/src/mcpDbChanges/src/mcpDbChanges/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"id":"/src/mcpDbChanges/src/mcpDbChanges/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"id":"/src/mcpDbChanges/src/mcpDbChanges/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"id":"/src/mcpDbChanges/src/mcpDbChanges/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"id":"mcp_db_base.tars_client.get_node_top_sql"},{"id":"/src/mcpDbChanges/src/mcpDbChanges/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"id":"/src/mcpDbChanges/src/mcpDbChanges/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"id":"mcp_db_base.tars_client.get_sql_detail_v1"},{"id":"/src/mcpDbChanges/src/mcpDbChanges/server.handle_call_tool.handle_call_tool_scope...ValueError"},{"id":"handle_call_tool \\n[server.py : 96_154]","location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDbLog/src/mcpDbLog/server.py"},"region":{"startLine":96,"startColumn":1,"endLine":154,"endColumn":11,"snippet":{}}}}},{"id":"/src/mcpDbLog/src/mcpDbLog/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"id":"_validate_arguments \\n[server.py : 89_92]","location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDbLog/src/mcpDbLog/server.py"},"region":{"startLine":89,"startColumn":1,"endLine":92,"endColumn":67,"snippet":{}}}}},{"id":"/src/mcpDbLog/src/mcpDbLog/server._validate_arguments._validate_arguments_scope..all"},{"id":"/src/mcpDbLog/src/mcpDbLog/server._validate_arguments._validate_arguments_scope...ValueError"},{"id":"antshell.get_obproxy_info_by_trace"},{"id":"/src/mcpDbLog/src/mcpDbLog/server.handle_call_tool.arguments.get"},{"id":"antshell.get_observer_trace_by_sql"},{"id":"antshell.get_observer_info_by_trace"},{"id":"/src/mcpDbLog/src/mcpDbLog/server.handle_call_tool.handle_call_tool_scope...ValueError"},{"id":"handle_call_tool \\n[server.py : 173_298]","location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDbMeta/src/mcpDbMeta/server.py"},"region":{"startLine":173,"startColumn":1,"endLine":298,"endColumn":11,"snippet":{}}}}},{"id":"/src/mcpDbMeta/src/mcpDbMeta/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"id":"/src/mcpDbMeta/src/mcpDbMeta/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"id":"/src/mcpDbMeta/src/mcpDbMeta/server.handle_call_tool.arguments.get"},{"id":"/src/mcpDbMeta/src/mcpDbMeta/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"id":"/src/mcpDbMeta/src/mcpDbMeta/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"id":"mcp_db_base.prometheus_client.get_ob_merge_parameter_value"},{"id":"/src/mcpDbMeta/src/mcpDbMeta/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"id":"mcp_db_base.dba_metadata_utils.get_db_meta"},{"id":"mcp_db_base.dba_metadata_utils.get_db_meta(var app:any=app, var cluster:any=cluster, var tenant:any=tenant, var db:any=db, var table:any=table, var sql_id:any=sql_id, var server:any=server).to_dict"},{"id":"/src/mcpDbMeta/src/mcpDbMeta/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"id":"mcp_db_base.omc_client.get_table_capacity"},{"id":"/src/mcpDbMeta/src/mcpDbMeta/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"id":"mcp_db_base.omc_client.get_table_schema"},{"id":"/src/mcpDbMeta/src/mcpDbMeta/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"id":"mcp_db_base.omc_client.get_table_indexs"},{"id":"/src/mcpDbMeta/src/mcpDbMeta/server.handle_call_tool.handle_call_tool_scope...ValueError"},{"id":"handle_call_tool \\n[server.py : 322_587]","location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDbMonitor/src/mcpDbMonitor/server.py"},"region":{"startLine":322,"startColumn":1,"endLine":587,"endColumn":11,"snippet":{}}}}},{"id":"validate_arguments \\n[server.py : 331_353]","location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDbMonitor/src/mcpDbMonitor/server.py"},"region":{"startLine":331,"startColumn":5,"endLine":353,"endColumn":99,"snippet":{}}}}},{"id":"/src/mcpDbMonitor/src/mcpDbMonitor/server.handle_call_tool.handle_call_tool_scope..validate_arguments.validate_arguments_scope...ValueErr..."},{"id":"/src/mcpDbMonitor/src/mcpDbMonitor/server.handle_call_tool.handle_call_tool_scope..validate_arguments.validate_arguments_scope...ValueErr..."},{"id":"/src/mcpDbMonitor/src/mcpDbMonitor/server.handle_call_tool.arguments.get"},{"id":"datetime.datetime.strptime"},{"id":"/src/mcpDbMonitor/src/mcpDbMonitor/server.handle_call_tool.handle_call_tool_scope..validate_arguments.validate_arguments_scope...str"},{"id":"/src/mcpDbMonitor/src/mcpDbMonitor/server.handle_call_tool.handle_call_tool_scope..validate_arguments.validate_arguments_scope...ValueErr..."},{"id":"/src/mcpDbMonitor/src/mcpDbMonitor/server.handle_call_tool.handle_call_tool_scope..validate_arguments.validate_arguments_scope...str"},{"id":"/src/mcpDbMonitor/src/mcpDbMonitor/server.handle_call_tool.handle_call_tool_scope..validate_arguments.validate_arguments_scope...ValueErr..."},{"id":"datetime.timedelta"},{"id":"/src/mcpDbMonitor/src/mcpDbMonitor/server.handle_call_tool.handle_call_tool_scope..validate_arguments.validate_arguments_scope...ValueErr..."},{"id":"/src/mcpDbMonitor/src/mcpDbMonitor/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"id":"mcp_db_base.db_monitor_client.get_tqps"},{"id":"/src/mcpDbMonitor/src/mcpDbMonitor/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"id":"mcp_db_base.db_monitor_client.get_rt"},{"id":"/src/mcpDbMonitor/src/mcpDbMonitor/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"id":"mcp_db_base.db_monitor_client.get_sql_count"},{"id":"/src/mcpDbMonitor/src/mcpDbMonitor/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"id":"mcp_db_base.db_monitor_client.get_sql_rt"},{"id":"/src/mcpDbMonitor/src/mcpDbMonitor/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"id":"mcp_db_base.db_monitor_client.get_logic_read"},{"id":"/src/mcpDbMonitor/src/mcpDbMonitor/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"id":"mcp_db_base.db_monitor_client.get_cpu_usage"},{"id":"/src/mcpDbMonitor/src/mcpDbMonitor/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"id":"mcp_db_base.db_monitor_client.get_storage_layer_row_count"},{"id":"/src/mcpDbMonitor/src/mcpDbMonitor/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"id":"mcp_db_base.db_monitor_client.get_clog_process_time"},{"id":"mcp_db_base.db_monitor_client.get_server_cpu"},{"id":"mcp_db_base.db_monitor_client.get_server_load"},{"id":"mcp_db_base.db_monitor_client.get_nc_ntp_offset"},{"id":"mcp_db_base.db_monitor_client.get_server_tenant_tqps_monitor"},{"id":"mcp_db_base.db_monitor_client.get_server_tenant_rt_monitor"},{"id":"/src/mcpDbMonitor/src/mcpDbMonitor/server.handle_call_tool.handle_call_tool_scope...ValueError"},{"id":"handle_call_tool \\n[server.py : 74_108]","location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDbOdc/src/mcpDbOdc/server.py"},"region":{"startLine":74,"startColumn":1,"endLine":108,"endColumn":80,"snippet":{}}}}},{"id":"/src/mcpDbOdc/src/mcpDbOdc/server.handle_call_tool.handle_call_tool_scope...ValueError"},{"id":"_validate_arguments \\n[server.py : 67_70]","location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDbOdc/src/mcpDbOdc/server.py"},"region":{"startLine":67,"startColumn":1,"endLine":70,"endColumn":67,"snippet":{}}}}},{"id":"/src/mcpDbOdc/src/mcpDbOdc/server._validate_arguments._validate_arguments_scope..all"},{"id":"/src/mcpDbOdc/src/mcpDbOdc/server._validate_arguments._validate_arguments_scope...ValueError"},{"id":"/src/mcpDbOdc/src/mcpDbOdc/server.handle_call_tool.arguments.get"},{"id":"odc_client.create_apply_order"},{"id":"/src/mcpDbOdc/src/mcpDbOdc/server.handle_call_tool.handle_call_tool_scope...ValueError"},{"id":"handle_call_tool \\n[server.py : 209_310]","location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDbQuery/src/mcpDbQuery/server.py"},"region":{"startLine":209,"startColumn":1,"endLine":310,"endColumn":67,"snippet":{}}}}},{"id":"/src/mcpDbQuery/src/mcpDbQuery/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"id":"/src/mcpDbQuery/src/mcpDbQuery/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"id":"/src/mcpDbQuery/src/mcpDbQuery/server.handle_call_tool.arguments.get"},{"id":"syslib_from.client.query_db"},{"id":"/src/mcpDbQuery/src/mcpDbQuery/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"id":"/src/mcpDbQuery/src/mcpDbQuery/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"id":"is_valid_app \\n[server.py : 217_218]","location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDbQuery/src/mcpDbQuery/server.py"},"region":{"startLine":217,"startColumn":5,"endLine":218,"endColumn":57,"snippet":{}}}}},{"id":"/src/mcpDbQuery/src/mcpDbQuery/server.handle_call_tool.handle_call_tool_scope..is_valid_app.is_valid_app_scope..bool"},{"id":"/src/mcpDbQuery/src/mcpDbQuery/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"id":"/src/mcpDbQuery/src/mcpDbQuery/server.handle_call_tool.handle_call_tool_scope...target_date.strftime"},{"id":"/src/mcpDbQuery/src/mcpDbQuery/server.handle_call_tool.handle_call_tool_scope...str"},{"id":"/src/mcpDbQuery/src/mcpDbQuery/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"id":"/src/mcpDbQuery/src/mcpDbQuery/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"id":"/src/mcpDbQuery/src/mcpDbQuery/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"id":"/src/mcpDbQuery/src/mcpDbQuery/server.handle_call_tool.handle_call_tool_scope...target_date.strftime"},{"id":"/src/mcpDbQuery/src/mcpDbQuery/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"id":"/src/mcpDbQuery/src/mcpDbQuery/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"id":"/src/mcpDbQuery/src/mcpDbQuery/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"id":"/src/mcpDbQuery/src/mcpDbQuery/server.handle_call_tool.handle_call_tool_scope...target_date.strftime"},{"id":"get_mcp_headers \\n[server.py : 25_32]","location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDbQuery/src/mcpDbQuery/server.py"},"region":{"startLine":25,"startColumn":1,"endLine":32,"endColumn":19,"snippet":{}}}}},{"id":"mcp.server.Server(mcp-db-query).request_context.meta.model_extra.get"},{"id":"mcp.server.Server(mcp-db-query).request_context.meta.model_extra.get(headers).decode"},{"id":"mcp.server.Server(mcp-db-query).request_context.meta.model_extra.get(headers).decode(utf-8).lower"},{"id":"/src/mcpDbQuery/src/mcpDbQuery/server.handle_call_tool.handle_call_tool_scope...ValueError"},{"id":"query_specific_db \\n[server.py : 27_38]","location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDbQueryPrivate/src/mcpDbQueryPrivate/server.py"},"region":{"startLine":27,"startColumn":1,"endLine":38,"endColumn":92,"snippet":{}}}}},{"id":"WHITE_PROD_DB.get"},{"id":"_query_physic_db \\n[server.py : 64_90]","location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDbQueryPrivate/src/mcpDbQueryPrivate/server.py"},"region":{"startLine":64,"startColumn":1,"endLine":90,"endColumn":18,"snippet":{}}}}},{"id":"DB_CONFIG.get"},{"id":"get_pysql_user_name \\n[server.py : 93_115]","location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDbQueryPrivate/src/mcpDbQueryPrivate/server.py"},"region":{"startLine":93,"startColumn":1,"endLine":115,"endColumn":54,"snippet":{}}}}},{"id":"/src/mcpDbQueryPrivate/src/mcpDbQueryPrivate/server.get_pysql_user_name.get_pysql_user_name_scope..len"},{"id":"/src/mcpDbQueryPrivate/src/mcpDbQueryPrivate/server.get_pysql_user_name.get_pysql_user_name_scope...Exception"},{"id":"/src/mcpDbQueryPrivate/src/mcpDbQueryPrivate/server.get_pysql_user_name.get_pysql_user_name_scope...Exception"},{"id":"/src/mcpDbQueryPrivate/src/mcpDbQueryPrivate/server.get_pysql_user_name.get_pysql_user_name_scope...Exception"},{"id":"/src/mcpDbQueryPrivate/src/mcpDbQueryPrivate/server.get_pysql_user_name.get_pysql_user_name_scope...Exception"},{"id":"/src/mcpDbQueryPrivate/src/mcpDbQueryPrivate/server.get_pysql_user_name.get_pysql_user_name_scope...Exception"},{"id":"/src/mcpDbQueryPrivate/src/mcpDbQueryPrivate/server.get_pysql_user_name.get_pysql_user_name_scope...Exception"},{"id":"/src/mcpDbQueryPrivate/src/mcpDbQueryPrivate/server._query_physic_db._query_physic_db_scope..int"},{"id":"syslib_from.pymysql.connect(var host:any=db_config.get(host), var port:any=int(db_config.get(port)), var user:any=pysql_user, var password:any=db_config.get(password), var database:any=db_name, var ch..."},{"id":"/src/mcpDbQueryPrivate/src/mcpDbQueryPrivate/server._query_physic_db._query_physic_db_scope...ValueError"},{"id":"WHITE_PROD_DB.keys"},{"id":"/src/mcpDbQueryPrivate/src/mcpDbQueryPrivate/server.query_specific_db.query_specific_db_scope...Exception"},{"id":"query_layotto_db \\n[server.py : 42_49]","location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDbQueryPrivate/src/mcpDbQueryPrivate/server.py"},"region":{"startLine":42,"startColumn":1,"endLine":49,"endColumn":63,"snippet":{}}}}},{"id":"_query_layotto_db \\n[server.py : 52_61]","location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDbQueryPrivate/src/mcpDbQueryPrivate/server.py"},"region":{"startLine":52,"startColumn":1,"endLine":61,"endColumn":52,"snippet":{}}}}},{"id":"layotto_turbo.layotto.init_mysql"},{"id":"layotto_turbo.layotto.init_mysql(database).cursor"},{"id":"layotto_turbo.layotto.init_mysql(database).cursor().execute"},{"id":"layotto_turbo.layotto.init_mysql(database).cursor().fetchall"},{"id":"/src/mcpDbQueryPrivate/src/mcpDbQueryPrivate/server._query_layotto_db._query_layotto_db_scope...Exception"},{"id":"handle_call_tool \\n[server.py : 164_317]","location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDbSql/src/mcpDbSql/server.py"},"region":{"startLine":164,"startColumn":1,"endLine":317,"endColumn":11,"snippet":{}}}}},{"id":"/src/mcpDbSql/src/mcpDbSql/server.handle_call_tool.arguments.get"},{"id":"/src/mcpDbSql/src/mcpDbSql/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"id":"/src/mcpDbSql/src/mcpDbSql/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"id":"/src/mcpDbSql/src/mcpDbSql/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"id":"/src/mcpDbSql/src/mcpDbSql/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"id":"/src/mcpDbSql/src/mcpDbSql/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"id":"/src/mcpDbSql/src/mcpDbSql/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"id":"/src/mcpDbSql/src/mcpDbSql/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"id":"/src/mcpDbSql/src/mcpDbSql/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"id":"mcp_db_base.tars_client.get_sql_detail"},{"id":"/src/mcpDbSql/src/mcpDbSql/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"id":"/src/mcpDbSql/src/mcpDbSql/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"id":"/src/mcpDbSql/src/mcpDbSql/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"id":"mcp_db_base.tars_client.get_sql_plan"},{"id":"/src/mcpDbSql/src/mcpDbSql/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"id":"/src/mcpDbSql/src/mcpDbSql/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"id":"/src/mcpDbSql/src/mcpDbSql/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"id":"/src/mcpDbSql/src/mcpDbSql/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"id":"mcp_db_base.tars_client.get_hot_account"},{"id":"/src/mcpDbSql/src/mcpDbSql/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"id":"/src/mcpDbSql/src/mcpDbSql/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"id":"/src/mcpDbSql/src/mcpDbSql/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"id":"/src/mcpDbSql/src/mcpDbSql/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"id":"/src/mcpDbSql/src/mcpDbSql/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"id":"mcp_db_base.tars_client.get_sql_quota"},{"id":"/src/mcpDbSql/src/mcpDbSql/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"id":"/src/mcpDbSql/src/mcpDbSql/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"id":"/src/mcpDbSql/src/mcpDbSql/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"id":"mcp_db_base.tars_client.get_sql_plan_his"},{"id":"/src/mcpDbSql/src/mcpDbSql/server.handle_call_tool.handle_call_tool_scope...ValueError"},{"id":"handle_call_tool \\n[server.py : 232_314]","location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDima/src/mcpDima/server.py"},"region":{"startLine":232,"startColumn":1,"endLine":314,"endColumn":68,"snippet":{}}}}},{"id":"/src/mcpDima/src/mcpDima/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"id":"/src/mcpDima/src/mcpDima/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"id":"syslib_from.client.get_space_detail"},{"id":"/src/mcpDima/src/mcpDima/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"id":"/src/mcpDima/src/mcpDima/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"id":"syslib_from.client.get_space_list_by_staff"},{"id":"/src/mcpDima/src/mcpDima/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"id":"/src/mcpDima/src/mcpDima/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"id":"syslib_from.client.get_project_list_by_space"},{"id":"/src/mcpDima/src/mcpDima/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"id":"/src/mcpDima/src/mcpDima/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"id":"syslib_from.client.get_project_detail"},{"id":"/src/mcpDima/src/mcpDima/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"id":"/src/mcpDima/src/mcpDima/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"id":"syslib_from.client.get_sprint_detail"},{"id":"/src/mcpDima/src/mcpDima/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"id":"/src/mcpDima/src/mcpDima/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"id":"syslib_from.client.get_sprint_list"},{"id":"/src/mcpDima/src/mcpDima/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"id":"/src/mcpDima/src/mcpDima/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"id":"syslib_from.client.search_sprint"},{"id":"/src/mcpDima/src/mcpDima/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"id":"/src/mcpDima/src/mcpDima/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"id":"syslib_from.client.get_work_item_detail"},{"id":"/src/mcpDima/src/mcpDima/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"id":"/src/mcpDima/src/mcpDima/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"id":"/src/mcpDima/src/mcpDima/server.handle_call_tool.arguments.get"},{"id":"syslib_from.client.page_search_work_item"},{"id":"/src/mcpDima/src/mcpDima/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"id":"/src/mcpDima/src/mcpDima/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"id":"syslib_from.client.get_work_item_comment"},{"id":"/src/mcpDima/src/mcpDima/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"id":"/src/mcpDima/src/mcpDima/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"id":"syslib_from.client.search_dept_info"},{"id":"/src/mcpDima/src/mcpDima/server.handle_call_tool.handle_call_tool_scope...ValueError"},{"id":"find_attribute_by_data_id \\n[server.py : 26_33]","location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDrm/src/mcpDrm/server.py"},"region":{"startLine":26,"startColumn":1,"endLine":33,"endColumn":59,"snippet":{}}}}},{"id":"oneapi.opssla.ResourceMetaDataFacade.ResourceMetaDataFacade(layotto).findAttributeByDataId"},{"id":"oneapi.opssla.ResourceMetaDataFacade.ResourceMetaDataFacade(layotto).findAttributeByDataId(data_id).get_json"},{"id":"find_resource_by_app \\n[server.py : 37_44]","location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDrm/src/mcpDrm/server.py"},"region":{"startLine":37,"startColumn":1,"endLine":44,"endColumn":59,"snippet":{}}}}},{"id":"oneapi.opssla.ResourceMetaDataFacade.ResourceMetaDataFacade(layotto).findByApp"},{"id":"oneapi.opssla.ResourceMetaDataFacade.ResourceMetaDataFacade(layotto).findByApp(app_name).get_json"},{"id":"search_resource \\n[server.py : 48_55]","location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDrm/src/mcpDrm/server.py"},"region":{"startLine":48,"startColumn":1,"endLine":55,"endColumn":59,"snippet":{}}}}},{"id":"oneapi.opssla.ResourceMetaDataFacade.ResourceMetaDataFacade(layotto).search(keyword, var limit:any=100).get_json"},{"id":"query_push_drm_value \\n[server.py : 59_85]","location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDrm/src/mcpDrm/server.py"},"region":{"startLine":59,"startColumn":1,"endLine":85,"endColumn":59,"snippet":{}}}}},{"id":"/src/mcpDrm/src/mcpDrm/server.query_push_drm_value.query_push_drm_value_scope..len"},{"id":"/src/mcpDrm/src/mcpDrm/server.query_push_drm_value.query_push_drm_value_scope...ValueError"},{"id":"oneapi.opssla.DrmManageFacade.DrmManageFacade(layotto).queryValueByZoneNames"},{"id":"oneapi.opssla.DrmManageFacade.DrmManageFacade(layotto).queryValueByAllZone"},{"id":"/src/mcpDrm/src/mcpDrm/server.query_push_drm_value.query_push_drm_value_scope..resp.get_json"},{"id":"handle_call_tool \\n[server.py : 60_86]","location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpFileOperation/src/mcpFileOperation/server.py"},"region":{"startLine":60,"startColumn":1,"endLine":86,"endColumn":11,"snippet":{}}}}},{"id":"/src/mcpFileOperation/src/mcpFileOperation/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"id":"mcp_common.utils.oss_utils.get_file_infos(arguments.file_full_names).to_dict"},{"id":"syslib_from.mcp/types.ImageContent"},{"id":"/src/mcpFileOperation/src/mcpFileOperation/server.handle_call_tool.handle_call_tool_scope...ValueError"},{"id":"handle_call_tool \\n[server.py : 130_185]","location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpFluxExecute/src/mcpFluxExecute/server.py"},"region":{"startLine":130,"startColumn":1,"endLine":185,"endColumn":54,"snippet":{}}}}},{"id":"/src/mcpFluxExecute/src/mcpFluxExecute/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"id":"/src/mcpFluxExecute/src/mcpFluxExecute/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"id":"/src/mcpFluxExecute/src/mcpFluxExecute/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"id":"/src/mcpFluxExecute/src/mcpFluxExecute/server.handle_call_tool.arguments.get"},{"id":"/src/mcpFluxExecute/src/mcpFluxExecute/server.handle_call_tool.handle_call_tool_scope...query_feature_value"},{"id":"/src/mcpFluxExecute/src/mcpFluxExecute/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"id":"/src/mcpFluxExecute/src/mcpFluxExecute/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"id":"/src/mcpFluxExecute/src/mcpFluxExecute/server.handle_call_tool.handle_call_tool_scope...query_app_goc_method"},{"id":"/src/mcpFluxExecute/src/mcpFluxExecute/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"id":"/src/mcpFluxExecute/src/mcpFluxExecute/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"id":"/src/mcpFluxExecute/src/mcpFluxExecute/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"id":"/src/mcpFluxExecute/src/mcpFluxExecute/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"id":"/src/mcpFluxExecute/src/mcpFluxExecute/server.handle_call_tool.handle_call_tool_scope...query_app_feature"},{"id":"/src/mcpFluxExecute/src/mcpFluxExecute/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"id":"/src/mcpFluxExecute/src/mcpFluxExecute/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"id":"/src/mcpFluxExecute/src/mcpFluxExecute/server.handle_call_tool.handle_call_tool_scope...query_top_call_interface"},{"id":"/src/mcpFluxExecute/src/mcpFluxExecute/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"id":"/src/mcpFluxExecute/src/mcpFluxExecute/server.handle_call_tool.handle_call_tool_scope...query_trace_detail"},{"id":"/src/mcpFluxExecute/src/mcpFluxExecute/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"id":"/src/mcpFluxExecute/src/mcpFluxExecute/server.handle_call_tool.handle_call_tool_scope...query_monitor_data"},{"id":"/src/mcpFluxExecute/src/mcpFluxExecute/server.handle_call_tool.handle_call_tool_scope...ValueError"},{"id":"handle_call_tool \\n[server.py : 62_94]","location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpFluxFind/src/mcpFluxFind/server.py"},"region":{"startLine":62,"startColumn":1,"endLine":94,"endColumn":54,"snippet":{}}}}},{"id":"/src/mcpFluxFind/src/mcpFluxFind/server.handle_call_tool.handle_call_tool_scope..info_logger.info"},{"id":"/src/mcpFluxFind/src/mcpFluxFind/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"id":"/src/mcpFluxFind/src/mcpFluxFind/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"id":"/src/mcpFluxFind/src/mcpFluxFind/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"id":"/src/mcpFluxFind/src/mcpFluxFind/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"id":"/src/mcpFluxFind/src/mcpFluxFind/server.handle_call_tool.arguments.get"},{"id":"/src/mcpFluxFind/src/mcpFluxFind/server.handle_call_tool.handle_call_tool_scope...find_flux_by_search"},{"id":"/src/mcpFluxFind/src/mcpFluxFind/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"id":"/src/mcpFluxFind/src/mcpFluxFind/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"id":"/src/mcpFluxFind/src/mcpFluxFind/server.handle_call_tool.handle_call_tool_scope...find_property_by_scene_code"},{"id":"/src/mcpFluxFind/src/mcpFluxFind/server.handle_call_tool.handle_call_tool_scope...ValueError"},{"id":"handle_call_tool \\n[server.py : 172_231]","location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpFluxScene/src/mcpFluxScene/server.py"},"region":{"startLine":172,"startColumn":1,"endLine":231,"endColumn":54,"snippet":{}}}}},{"id":"/src/mcpFluxScene/src/mcpFluxScene/server.handle_call_tool.handle_call_tool_scope..info_logger.info"},{"id":"/src/mcpFluxScene/src/mcpFluxScene/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"id":"/src/mcpFluxScene/src/mcpFluxScene/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"id":"/src/mcpFluxScene/src/mcpFluxScene/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"id":"/src/mcpFluxScene/src/mcpFluxScene/server.handle_call_tool.arguments.get"},{"id":"/src/mcpFluxScene/src/mcpFluxScene/server.handle_call_tool.handle_call_tool_scope...create_flux_scene"},{"id":"/src/mcpFluxScene/src/mcpFluxScene/server.handle_call_tool.handle_call_tool_scope...batch_create_flux_scene"},{"id":"/src/mcpFluxScene/src/mcpFluxScene/server.handle_call_tool.handle_call_tool_scope...test_analysis_agent"},{"id":"/src/mcpFluxScene/src/mcpFluxScene/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"id":"/src/mcpFluxScene/src/mcpFluxScene/server.handle_call_tool.handle_call_tool_scope...text_use_case_agent"},{"id":"/src/mcpFluxScene/src/mcpFluxScene/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"id":"/src/mcpFluxScene/src/mcpFluxScene/server.handle_call_tool.handle_call_tool_scope...test_report_agent"},{"id":"/src/mcpFluxScene/src/mcpFluxScene/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"id":"/src/mcpFluxScene/src/mcpFluxScene/server.handle_call_tool.handle_call_tool_scope...scene_mining_agent"},{"id":"/src/mcpFluxScene/src/mcpFluxScene/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"id":"/src/mcpFluxScene/src/mcpFluxScene/server.handle_call_tool.handle_call_tool_scope...end_to_end_agent"},{"id":"/src/mcpFluxScene/src/mcpFluxScene/server.handle_call_tool.handle_call_tool_scope...ValueError"},{"id":"handle_call_tool \\n[server.py : 37_59]","location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpGetDbOperationByTraceId/src/mcpGetDbOperationByTraceId/server.py"},"region":{"startLine":37,"startColumn":1,"endLine":59,"endColumn":54,"snippet":{}}}}},{"id":"/src/mcpGetDbOperationByTraceId/src/mcpGetDbOperationByTraceId/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"id":"/src/mcpGetDbOperationByTraceId/src/mcpGetDbOperationByTraceId/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"id":"/src/mcpGetDbOperationByTraceId/src/mcpGetDbOperationByTraceId/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"id":"/src/mcpGetDbOperationByTraceId/src/mcpGetDbOperationByTraceId/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"id":"get_db_operation_by_trace_id \\n[server.py : 77_126]","location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpGetDbOperationByTraceId/src/mcpGetDbOperationByTraceId/server.py"},"region":{"startLine":77,"startColumn":1,"endLine":126,"endColumn":20,"snippet":{}}}}},{"id":"syslib_from.aiohttp.ClientTimeout"},{"id":"syslib_from.aiohttp.ClientSession(var timeout:any=timeout).post"},{"id":"syslib_from.aiohttp.ClientSession(var timeout:any=timeout).post(var url:any=url, var headers:any=headers, var json:any=request_body, var ssl:any=false).raise_for_status"},{"id":"syslib_from.aiohttp.ClientSession(var timeout:any=timeout).post(var url:any=url, var headers:any=headers, var json:any=request_body, var ssl:any=false).json"},{"id":"syslib_from.aiohttp.ClientSession(var timeout:any=timeout).post(var url:any=url, var headers:any=headers, var json:any=request_body, var ssl:any=false).json().get"},{"id":"syslib_from.aiohttp.ClientSession(var timeout:any=timeout).post(var url:any=url, var headers:any=headers, var json:any=request_body, var ssl:any=false).text"},{"id":"/src/mcpGetDbOperationByTraceId/src/mcpGetDbOperationByTraceId/server.handle_call_tool.handle_call_tool_scope...ValueError"},{"id":"handle_call_tool \\n[server.py : 165_206]","location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpGlobalSearch/src/mcpGlobalSearch/server.py"},"region":{"startLine":165,"startColumn":1,"endLine":206,"endColumn":6,"snippet":{}}}}},{"id":"/src/mcpGlobalSearch/src/mcpGlobalSearch/server.handle_call_tool.handle_call_tool_scope...ValueError"},{"id":"/src/mcpGlobalSearch/src/mcpGlobalSearch/server.handle_call_tool.handle_call_tool_scope...ValueError"},{"id":"/src/mcpGlobalSearch/src/mcpGlobalSearch/server.handle_call_tool.arguments.get"},{"id":"/src/mcpGlobalSearch/src/mcpGlobalSearch/server.handle_call_tool.handle_call_tool_scope...ValueError"},{"id":"/src/mcpGlobalSearch/src/mcpGlobalSearch/server.handle_call_tool.handle_call_tool_scope...ValueError"},{"id":"symbol_global_search \\n[server.py : 117_161]","location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpGlobalSearch/src/mcpGlobalSearch/server.py"},"region":{"startLine":117,"startColumn":1,"endLine":161,"endColumn":15,"snippet":{}}}}},{"id":"/src/mcpGlobalSearch/src/mcpGlobalSearch/server.symbol_global_search.symbol_global_search_scope..dict"},{"id":"/src/mcpGlobalSearch/src/mcpGlobalSearch/server.symbol_global_search.symbol_global_search_scope..isinstance"},{"id":"mcp_common.remote.codeinsight.code_insight_api.mcp_server_backend_api(var params:any=dict(var name:any=Consts.GLOBAL_SEARCH.name, var arguments:any=dict(var searchType:any=search_type, var searchPatte..."},{"id":"mcp_common.remote.codefuse_search.Symbol"},{"id":"/src/mcpGlobalSearch/src/mcpGlobalSearch/server.symbol_global_search.symbol_global_search_scope.....enumerate"},{"id":"/src/mcpGlobalSearch/src/mcpGlobalSearch/server.symbol_global_search.symbol_global_search_scope........ValueError"},{"id":"/src/mcpLinglong/src/mcpLinglong/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"id":"/src/mcpLinglong/src/mcpLinglong/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"id":"/src/mcpLinglong/src/mcpLinglong/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"id":"get_module_by_scene_service \\n[server.py : 135_171]","location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpLinglong/src/mcpLinglong/server.py"},"region":{"startLine":135,"startColumn":1,"endLine":171,"endColumn":20,"snippet":{}}}}},{"id":"oneapi.linglongmng.LinglongModuleFacade.ModuleQueryBySceneServiceRequest"},{"id":"oneapi.linglongmng.LinglongModuleFacade.LinglongModuleFacade(layotto).queryModuleBySceneService"},{"id":"oneapi.linglongmng.LinglongModuleFacade.LinglongModuleFacade(layotto).queryModuleBySceneService(req).data.data.get_json"},{"id":"/src/mcpLinglong/src/mcpLinglong/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"id":"/src/mcpLinglong/src/mcpLinglong/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"id":"get_function_by_id \\n[server.py : 174_192]","location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpLinglong/src/mcpLinglong/server.py"},"region":{"startLine":174,"startColumn":1,"endLine":192,"endColumn":20,"snippet":{}}}}},{"id":"oneapi.linglongmng.FunctionMngServiceFacade.FunctionMngServiceFacade(layotto).queryById"},{"id":"oneapi.linglongmng.FunctionMngServiceFacade.FunctionMngServiceFacade(layotto).queryById(id).data.data.get_json"},{"id":"/src/mcpLinglong/src/mcpLinglong/server.handle_call_tool.handle_call_tool_scope...ValueError"},{"id":"handle_call_tool \\n[server.py : 65_91]","location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpLinkw/src/mcpLinkw/server.py"},"region":{"startLine":65,"startColumn":1,"endLine":91,"endColumn":54,"snippet":{}}}}},{"id":"/src/mcpLinkw/src/mcpLinkw/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"id":"/src/mcpLinkw/src/mcpLinkw/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"id":"get_joint_debug_env_detail_by_group_id \\n[server.py : 111_131]","location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpLinkw/src/mcpLinkw/server.py"},"region":{"startLine":111,"startColumn":1,"endLine":131,"endColumn":20,"snippet":{}}}}},{"id":"syslib_from.requests.get(url, var headers:any=LINKW_OPEN_API_HEADER, var params:any=params).raise_for_status"},{"id":"syslib_from.requests.get(url, var headers:any=LINKW_OPEN_API_HEADER, var params:any=params).json"},{"id":"syslib_from.requests.get(url, var headers:any=LINKW_OPEN_API_HEADER, var params:any=params).json().get"},{"id":"/src/mcpLinkw/src/mcpLinkw/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"id":"/src/mcpLinkw/src/mcpLinkw/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"id":"get_pod_detail_by_dev_group \\n[server.py : 134_156]","location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpLinkw/src/mcpLinkw/server.py"},"region":{"startLine":134,"startColumn":1,"endLine":156,"endColumn":20,"snippet":{}}}}},{"id":"/src/mcpLinkw/src/mcpLinkw/server.handle_call_tool.handle_call_tool_scope...ValueError"},{"id":"handle_call_tool \\n[server.py : 94_165]","location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpLogQuery/src/mcpLogQuery/server.py"},"region":{"startLine":94,"startColumn":1,"endLine":165,"endColumn":11,"snippet":{}}}}},{"id":"_get_header \\n[server.py : 207_208]","location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpLogQuery/src/mcpLogQuery/server.py"},"region":{"startLine":207,"startColumn":1,"endLine":208,"endColumn":35,"snippet":{}}}}},{"id":"_get_headers \\n[server.py : 191_205]","location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpLogQuery/src/mcpLogQuery/server.py"},"region":{"startLine":191,"startColumn":1,"endLine":205,"endColumn":19,"snippet":{}}}}},{"id":"headers.get"},{"id":"_valid_params \\n[server.py : 183_188]","location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpLogQuery/src/mcpLogQuery/server.py"},"region":{"startLine":183,"startColumn":1,"endLine":188,"endColumn":58,"snippet":{}}}}},{"id":"/src/mcpLogQuery/src/mcpLogQuery/server._valid_params._valid_params_scope...ValueError"},{"id":"/src/mcpLogQuery/src/mcpLogQuery/server.handle_call_tool.arguments.get"},{"id":"/src/mcpLogQuery/src/mcpLogQuery/server._valid_params._valid_params_scope.....ValueError"},{"id":"sim_snapshot.get_sim_snapshot"},{"id":"/src/mcpLogQuery/src/mcpLogQuery/server.handle_call_tool.handle_call_tool_scope...ValueError"},{"id":"handle_call_tool \\n[server.py : 79_146]","location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpMonitorWithFile/src/mcpMonitorWithFile/server.py"},"region":{"startLine":79,"startColumn":1,"endLine":146,"endColumn":11,"snippet":{}}}}},{"id":"validate_arguments \\n[server.py : 88_110]","location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpMonitorWithFile/src/mcpMonitorWithFile/server.py"},"region":{"startLine":88,"startColumn":5,"endLine":110,"endColumn":99,"snippet":{}}}}},{"id":"/src/mcpMonitorWithFile/src/mcpMonitorWithFile/server.handle_call_tool.handle_call_tool_scope..validate_arguments.validate_arguments_scope......"},{"id":"/src/mcpMonitorWithFile/src/mcpMonitorWithFile/server.handle_call_tool.handle_call_tool_scope..validate_arguments.validate_arguments_scope......"},{"id":"/src/mcpMonitorWithFile/src/mcpMonitorWithFile/server.handle_call_tool.arguments.get"},{"id":"/src/mcpMonitorWithFile/src/mcpMonitorWithFile/server.handle_call_tool.handle_call_tool_scope..validate_arguments.validate_arguments_scope....."},{"id":"/src/mcpMonitorWithFile/src/mcpMonitorWithFile/server.handle_call_tool.handle_call_tool_scope..validate_arguments.validate_arguments_scope...validate_arguments.validate_arguments_scope.....ValueError"},{"id":"/src/mcpMonitorWithFile/src/mcpMonitorWithFile/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"id":"/src/mcpMonitorWithFile/src/mcpMonitorWithFile/server.handle_call_tool.handle_call_tool_scope...isinstance"},{"id":"/src/mcpMonitorWithFile/src/mcpMonitorWithFile/server.handle_call_tool.handle_call_tool_scope....type"},{"id":"/src/mcpMonitorWithFile/src/mcpMonitorWithFile/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"id":"maas_sql_client.get_monitor_metric"},{"id":"_save_metric_to_oss_csv \\n[server.py : 166_186]","location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpMonitorWithFile/src/mcpMonitorWithFile/server.py"},"region":{"startLine":166,"startColumn":1,"endLine":186,"endColumn":33,"snippet":{}}}}},{"id":"_get_trace_id \\n[server.py : 189_197]","location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpMonitorWithFile/src/mcpMonitorWithFile/server.py"},"region":{"startLine":189,"startColumn":1,"endLine":197,"endColumn":29,"snippet":{}}}}},{"id":"mcp.server.Server(mcp-monitor-with-file).request_context.meta.model_extra.get"},{"id":"mcp.server.Server(mcp-monitor-with-file).request_context.meta.model_extra.get(headers).decode"},{"id":"mcp.server.Server(mcp-monitor-with-file).request_context.meta.model_extra.get(headers).decode(utf-8).lower"},{"id":"/src/mcpMonitorWithFile/src/mcpMonitorWithFile/server._get_trace_id._get_trace_id_scope..str"},{"id":"/src/mcpMonitorWithFile/src/mcpMonitorWithFile/server._save_metric_to_oss_csv._save_metric_to_oss_csv_scope..str"},{"id":"mcp_common.utils.oss_utils.create_oss_path"},{"id":"syslib_from.io.StringIO"},{"id":"syslib_from.csv.writer"},{"id":"maas_sql_client.get_monitor_metric(var cluster:any=cluster, var tenant:any=tenant, var columns:any=metrics, var start_time:any=start_time, var end_time:any=end_time).get"},{"id":"syslib_from.csv.writer(output).writerow"},{"id":"syslib_from.io.StringIO().getvalue"},{"id":"syslib_from.io.StringIO().getvalue().encode"},{"id":"mcp_common.utils.oss_utils.upload_bytes"},{"id":"mcp_common.utils.oss_utils.upload_bytes(oss_path, csv_bytes, file_desc).to_dict"},{"id":"/src/mcpMonitorWithFile/src/mcpMonitorWithFile/server._save_metric_to_oss_csv._save_metric_to_oss_csv_scope...ValueError"},{"id":"/src/mcpMonitorWithFile/src/mcpMonitorWithFile/server.handle_call_tool.handle_call_tool_scope...ValueError"},{"id":"handle_call_tool \\n[server.py : 65_95]","location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpyuque/src/mcpyuque/server.py"},"region":{"startLine":65,"startColumn":1,"endLine":95,"endColumn":54,"snippet":{}}}}},{"id":"/src/mcpMonitorWithSql/src/mcpMonitorWithSql/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"id":"/src/mcpMonitorWithSql/src/mcpMonitorWithSql/server.handle_call_tool.handle_call_tool_scope...ValueError"},{"id":"handle_call_tool \\n[server.py : 253_279]","location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpOpenSearch/src/mcpOpenSearch/server.py"},"region":{"startLine":253,"startColumn":1,"endLine":279,"endColumn":67,"snippet":{}}}}},{"id":"/src/mcpOpenSearch/src/mcpOpenSearch/server.handle_call_tool.handle_call_tool_scope...ValueError"},{"id":"direct_search_tool \\n[server.py : 133_165]","location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpOpenSearch/src/mcpOpenSearch/server.py"},"region":{"startLine":133,"startColumn":1,"endLine":165,"endColumn":18,"snippet":{}}}}},{"id":"aiologger.Logger(var name:any=__name__).info"},{"id":"syslib_from.search_engine.SearchEngineApp"},{"id":"syslib_from.asyncio.to_thread"},{"id":"syslib_from.asyncio.get_event_loop"},{"id":"syslib_from.asyncio.get_event_loop().run_in_executor"},{"id":"mcp.types.TextContent"},{"id":"deep_search_tool \\n[server.py : 168_184]","location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpOpenSearch/src/mcpOpenSearch/server.py"},"region":{"startLine":168,"startColumn":1,"endLine":184,"endColumn":25,"snippet":{}}}}},{"id":"invoke_search_tool \\n[server.py : 45_124]","location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpOpenSearch/src/mcpOpenSearch/server.py"},"region":{"startLine":45,"startColumn":1,"endLine":124,"endColumn":14,"snippet":{}}}}},{"id":"syslib_from.sys.platform.startswith"},{"id":"/src/mcpOpenSearch/src/mcpOpenSearch/server.invoke_search_tool.invoke_search_tool_scope.....RuntimeError"},{"id":"syslib_from.httpx.AsyncHTTPTransport"},{"id":"syslib_from.openai.AsyncOpenAI"},{"id":"syslib_from.deep_research.research"},{"id":"/src/mcpOpenSearch/src/mcpOpenSearch/server.invoke_search_tool.invoke_search_tool_scope..len"},{"id":"syslib_from.deep_research.write_final_report"},{"id":"aiologger.Logger(var name:any=__name__).debug"},{"id":"aiologger.Logger(var name:any=__name__).error"},{"id":"deep_research_tool \\n[server.py : 187_204]","location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpOpenSearch/src/mcpOpenSearch/server.py"},"region":{"startLine":187,"startColumn":1,"endLine":204,"endColumn":25,"snippet":{}}}}},{"id":"/src/mcpOpenSearch/src/mcpOpenSearch/server.handle_call_tool.handle_call_tool_scope.....ValueError"},{"id":"handle_call_tool \\n[server.py : 126_163]","location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpPaas/src/mcpPaas/server.py"},"region":{"startLine":126,"startColumn":1,"endLine":163,"endColumn":54,"snippet":{}}}}},{"id":"paas_client.info_logger.info"},{"id":"/src/mcpPaas/src/mcpPaas/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"id":"paas_client.get_app_meta"},{"id":"/src/mcpPaas/src/mcpPaas/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"id":"paas_client.get_app_pod"},{"id":"/src/mcpPaas/src/mcpPaas/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"id":"paas_client.get_app_pod_count"},{"id":"/src/mcpPaas/src/mcpPaas/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"id":"/src/mcpPaas/src/mcpPaas/server.handle_call_tool.arguments.get"},{"id":"get_app_baseline \\n[server.py : 26_51]","location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpPaas/src/mcpPaas/server.py"},"region":{"startLine":26,"startColumn":1,"endLine":51,"endColumn":44,"snippet":{}}}}},{"id":"get_mcp_headers \\n[server.py : 14_23]","location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpPaas/src/mcpPaas/server.py"},"region":{"startLine":14,"startColumn":1,"endLine":23,"endColumn":19,"snippet":{}}}}},{"id":"mcp.server.Server(mcp-paas).request_context.meta.model_extra.get"},{"id":"mcp.server.Server(mcp-paas).request_context.meta.model_extra.get(headers).decode"},{"id":"mcp.server.Server(mcp-paas).request_context.meta.model_extra.get(headers).decode(utf-8).lower"},{"id":"/src/mcpPaas/src/mcpPaas/server.get_app_baseline.get_app_baseline_scope...Exception"},{"id":"syslib_from.requests.get(var url:any=https://unimetaservice.alipay.com/webapi/corsproxy/http://zappinfo-pool.global.alipay.com/genericBaseline/getAppBaselineView.json, var params:any=params, var heade..."},{"id":"syslib_from.json.loads(response.text).get"},{"id":"/src/mcpPaas/src/mcpPaas/server.get_app_baseline.get_app_baseline_scope...Exception"},{"id":"syslib_from.json.loads(response.text).get(resultView).get"},{"id":"paas_client.info_logger.error"},{"id":"/src/mcpPaas/src/mcpPaas/server.get_app_baseline.get_app_baseline_scope...Exception"},{"id":"/src/mcpPaas/src/mcpPaas/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"id":"paas_client.get_change_detail"},{"id":"/src/mcpPaas/src/mcpPaas/server.handle_call_tool.handle_call_tool_scope...ValueError"},{"id":"handle_call_tool \\n[server.py : 132_156]","location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpPackageSearch/src/mcpPackageSearch/server.py"},"region":{"startLine":132,"startColumn":1,"endLine":156,"endColumn":54,"snippet":{}}}}},{"id":"/src/mcpPackageSearch/src/mcpPackageSearch/server.handle_call_tool.handle_call_tool_scope...ValueError"},{"id":"/src/mcpPackageSearch/src/mcpPackageSearch/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"id":"/src/mcpPackageSearch/src/mcpPackageSearch/server.handle_call_tool.arguments.get"},{"id":"app_caller_analysis \\n[server.py : 94_128]","location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpPackageSearch/src/mcpPackageSearch/server.py"},"region":{"startLine":94,"startColumn":1,"endLine":128,"endColumn":15,"snippet":{}}}}},{"id":"/src/mcpPackageSearch/src/mcpPackageSearch/server.app_caller_analysis.app_caller_analysis_scope..dict"},{"id":"mcp_common.remote.codeinsight.code_insight_api.mcp_server_backend_api(var params:any=dict(var name:any=Consts.APP_CALLER_ANALYSIS.name, var arguments:any=dict(var appName:any=app_name, var packageKeyw..."},{"id":"format_dependency \\n[server.py : 74_91]","location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpPackageSearch/src/mcpPackageSearch/server.py"},"region":{"startLine":74,"startColumn":1,"endLine":91,"endColumn":15,"snippet":{}}}}},{"id":"/src/mcpPackageSearch/src/mcpPackageSearch/server.format_dependency.format_dependency_scope...enumerate"},{"id":"/src/mcpPackageSearch/src/mcpPackageSearch/server.format_dependency.format_dependency_scope...enumerate(data_list).items"},{"id":"/src/mcpPackageSearch/src/mcpPackageSearch/server.handle_call_tool.handle_call_tool_scope...ValueError"},{"id":"query_multi_app_metrics \\n[server.py : 535_556]","location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpQueryMultiAppMetrics/src/mcpQueryMultiAppMetrics/server.py"},"region":{"startLine":535,"startColumn":1,"endLine":556,"endColumn":28,"snippet":{}}}}},{"id":"/src/mcpQueryMultiAppMetrics/src/mcpQueryMultiAppMetrics/server.query_multi_app_metrics.zones.upper"},{"id":"get_result \\n[server.py : 282_333]","location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpQueryMultiAppMetrics/src/mcpQueryMultiAppMetrics/server.py"},"region":{"startLine":282,"startColumn":1,"endLine":333,"endColumn":90,"snippet":{}}}}},{"id":"/src/mcpQueryMultiAppMetrics/src/mcpQueryMultiAppMetrics/server.query_multi_app_metrics.zones.upper().upper"},{"id":"start_time.strftime"},{"id":"get_app_result \\n[server.py : 174_194]","location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpQueryMultiAppMetrics/src/mcpQueryMultiAppMetrics/server.py"},"region":{"startLine":174,"startColumn":1,"endLine":194,"endColumn":34,"snippet":{}}}}},{"id":"query \\n[server.py : 66_77]","location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpQueryMultiAppMetrics/src/mcpQueryMultiAppMetrics/server.py"},"region":{"startLine":66,"startColumn":1,"endLine":77,"endColumn":22,"snippet":{}}}}},{"id":"maas_service.MaasService().query_maas_by_sql_new_engine"},{"id":"/src/mcpQueryMultiAppMetrics/src/mcpQueryMultiAppMetrics/server.query.query_scope...Exception"},{"id":"maas_service.MaasService().query_maas_by_sql_new_engine(sql).rows.replace"},{"id":"/src/mcpQueryMultiAppMetrics/src/mcpQueryMultiAppMetrics/server.get_app_result.get_app_result_scope....str"},{"id":"/src/mcpQueryMultiAppMetrics/src/mcpQueryMultiAppMetrics/server.get_app_result.get_app_result_scope....str(row.3).replace"},{"id":"query_gray \\n[server.py : 80_93]","location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpQueryMultiAppMetrics/src/mcpQueryMultiAppMetrics/server.py"},"region":{"startLine":80,"startColumn":1,"endLine":93,"endColumn":22,"snippet":{}}}}},{"id":"map.key.table.replace"},{"id":"/src/mcpQueryMultiAppMetrics/src/mcpQueryMultiAppMetrics/server.query_gray.query_gray_scope...Exception"},{"id":"/src/mcpQueryMultiAppMetrics/src/mcpQueryMultiAppMetrics/server.get_app_result.get_app_result_scope....str"},{"id":"/src/mcpQueryMultiAppMetrics/src/mcpQueryMultiAppMetrics/server.get_app_result.get_app_result_scope....str(row.3).replace"},{"id":"/src/mcpQueryMultiAppMetrics/src/mcpQueryMultiAppMetrics/server.get_result.get_result_scope..set"},{"id":"app_and_zone_to_result.values"},{"id":"/src/mcpQueryMultiAppMetrics/src/mcpQueryMultiAppMetrics/server.get_result.get_result_scope..set().update"},{"id":"query_topic_producer \\n[server.py : 96_116]","location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpQueryMultiAppMetrics/src/mcpQueryMultiAppMetrics/server.py"},"region":{"startLine":96,"startColumn":1,"endLine":116,"endColumn":25,"snippet":{}}}}},{"id":"/src/mcpQueryMultiAppMetrics/src/mcpQueryMultiAppMetrics/server.query_topic_producer.query_topic_producer_scope...Exception"},{"id":"maas_service.MaasService().query_maas_by_sql_new_engine("},{"id":"find_sub_topic_source_app \\n[server.py : 197_208]","location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpQueryMultiAppMetrics/src/mcpQueryMultiAppMetrics/server.py"},"region":{"startLine":197,"startColumn":1,"endLine":208,"endColumn":28,"snippet":{}}}}},{"id":"source_apps.extend"},{"id":"/src/mcpQueryMultiAppMetrics/src/mcpQueryMultiAppMetrics/server.find_sub_topic_source_app.find_sub_topic_source_app_scope....set"},{"id":"print_multi_app_meta \\n[server.py : 336_430]","location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpQueryMultiAppMetrics/src/mcpQueryMultiAppMetrics/server.py"},"region":{"startLine":336,"startColumn":1,"endLine":430,"endColumn":34,"snippet":{}}}}},{"id":"| 风险状态 | app | 机房 | 风险详情 |.append"},{"id":"result_list.extend"},{"id":"handle_call_tool \\n[server.py : 560_582]","location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpQueryMultiAppMetrics/src/mcpQueryMultiAppMetrics/server.py"},"region":{"startLine":560,"startColumn":1,"endLine":582,"endColumn":6,"snippet":{}}}}},{"id":"/src/mcpQueryMultiAppMetrics/src/mcpQueryMultiAppMetrics/server.handle_call_tool.handle_call_tool_scope...ValueError"},{"id":"/src/mcpQueryMultiAppMetrics/src/mcpQueryMultiAppMetrics/server.handle_call_tool.handle_call_tool_scope...ValueError"},{"id":"/src/mcpQueryMultiAppMetrics/src/mcpQueryMultiAppMetrics/server.handle_call_tool.arguments.zones.upper"},{"id":"/src/mcpQueryMultiAppMetrics/src/mcpQueryMultiAppMetrics/server.handle_call_tool.arguments.zones.upper().upper"},{"id":"handle_call_tool \\n[server.py : 39_59]","location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpQueryRiskMerchantInfo/src/mcpQueryRiskMerchantInfo/server.py"},"region":{"startLine":39,"startColumn":1,"endLine":59,"endColumn":54,"snippet":{}}}}},{"id":"/src/mcpQueryRiskMerchantInfo/src/mcpQueryRiskMerchantInfo/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"id":"syslib_from.merchant_client.query_risk_merchant_info"},{"id":"/src/mcpQueryRiskMerchantInfo/src/mcpQueryRiskMerchantInfo/server.handle_call_tool.handle_call_tool_scope....str"},{"id":"/src/mcpQueryRiskMerchantInfo/src/mcpQueryRiskMerchantInfo/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"id":"/src/mcpQueryRiskMerchantInfo/src/mcpQueryRiskMerchantInfo/server.handle_call_tool.handle_call_tool_scope...ValueError"},{"id":"handle_call_tool \\n[server.py : 699_761]","location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpQuerySingleAppMetrics/src/mcpQuerySingleAppMetrics/server.py"},"region":{"startLine":699,"startColumn":1,"endLine":761,"endColumn":46,"snippet":{}}}}},{"id":"/src/mcpQuerySingleAppMetrics/src/mcpQuerySingleAppMetrics/server.handle_call_tool.handle_call_tool_scope...ValueError"},{"id":"query_single_app_em14_total_metrics \\n[server.py : 52_317]","location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpQuerySingleAppMetrics/src/mcpQuerySingleAppMetrics/server.py"},"region":{"startLine":52,"startColumn":1,"endLine":317,"endColumn":18,"snippet":{}}}}},{"id":"strftime"},{"id":"mcpAntscheduler.client.get_job_list_by_app"},{"id":"/src/mcpQuerySingleAppMetrics/src/mcpQuerySingleAppMetrics/server.query_single_app_em14_total_metrics.query_single_app_em14_total_metrics_scope....len"},{"id":"|{}|.format(|.join({0:中风险❗️, 1:上游调用(service(MOSN)), 2:调用量级是+str(service_total)})).append"},{"id":"|{}|.format(|.join({0:低风险⚠️️, 1:调用下游 RPC(sal), 2:调用量级是+str(sal_total)})).append"},{"id":"query_single_app_em14_total_pod \\n[server.py : 603_613]","location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpQuerySingleAppMetrics/src/mcpQuerySingleAppMetrics/server.py"},"region":{"startLine":603,"startColumn":1,"endLine":613,"endColumn":18,"snippet":{}}}}},{"id":"query_single_app_em14_total_pod_raw \\n[server.py : 561_600]","location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpQuerySingleAppMetrics/src/mcpQuerySingleAppMetrics/server.py"},"region":{"startLine":561,"startColumn":1,"endLine":600,"endColumn":39,"snippet":{}}}}},{"id":"get_start_end_time \\n[server.py : 499_507]","location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpQuerySingleAppMetrics/src/mcpQuerySingleAppMetrics/server.py"},"region":{"startLine":499,"startColumn":1,"endLine":507,"endColumn":22,"snippet":{}}}}},{"id":"/src/mcpQuerySingleAppMetrics/src/mcpQuerySingleAppMetrics/server.query_single_app_em14_total_pod.query_single_app_em14_total_pod_scope...Exception"},{"id":"/src/mcpQuerySingleAppMetrics/src/mcpQuerySingleAppMetrics/server.query_single_app_em14_total_pod.query_single_app_em14_total_pod_scope....s..."},{"id":"/src/mcpQuerySingleAppMetrics/src/mcpQuerySingleAppMetrics/server.query_single_app_em14_total_pod.query_single_app_em14_total_pod_scope....s..."},{"id":"query_single_app_em14_mq_sub \\n[server.py : 510_558]","location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpQuerySingleAppMetrics/src/mcpQuerySingleAppMetrics/server.py"},"region":{"startLine":510,"startColumn":1,"endLine":558,"endColumn":27,"snippet":{}}}}},{"id":"get_app_result \\n[server.py : 349_367]","location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpQuerySingleAppMetrics/src/mcpQuerySingleAppMetrics/server.py"},"region":{"startLine":349,"startColumn":1,"endLine":367,"endColumn":25,"snippet":{}}}}},{"id":"query \\n[server.py : 335_346]","location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpQuerySingleAppMetrics/src/mcpQuerySingleAppMetrics/server.py"},"region":{"startLine":335,"startColumn":1,"endLine":346,"endColumn":22,"snippet":{}}}}},{"id":"/src/mcpQuerySingleAppMetrics/src/mcpQuerySingleAppMetrics/server.query.query_scope...Exception"},{"id":"query_gray \\n[server.py : 320_332]","location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpQuerySingleAppMetrics/src/mcpQuerySingleAppMetrics/server.py"},"region":{"startLine":320,"startColumn":1,"endLine":332,"endColumn":22,"snippet":{}}}}},{"id":"/src/mcpQuerySingleAppMetrics/src/mcpQuerySingleAppMetrics/server.query_gray.query_gray_scope...Exception"},{"id":"/src/mcpQuerySingleAppMetrics/src/mcpQuerySingleAppMetrics/server.query_single_app_em14_mq_sub.query_single_app_em14_mq_sub_scope..set"},{"id":"app_to_result.values"},{"id":"/src/mcpQuerySingleAppMetrics/src/mcpQuerySingleAppMetrics/server.query_single_app_em14_mq_sub.query_single_app_em14_mq_sub_scope..set().update"},{"id":"query_topic_producer \\n[server.py : 387_410]","location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpQuerySingleAppMetrics/src/mcpQuerySingleAppMetrics/server.py"},"region":{"startLine":387,"startColumn":1,"endLine":410,"endColumn":25,"snippet":{}}}}},{"id":"/src/mcpQuerySingleAppMetrics/src/mcpQuerySingleAppMetrics/server.query_topic_producer.query_topic_producer_scope...Exception"},{"id":"find_sub_topic_source_app \\n[server.py : 370_381]","location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpQuerySingleAppMetrics/src/mcpQuerySingleAppMetrics/server.py"},"region":{"startLine":370,"startColumn":1,"endLine":381,"endColumn":28,"snippet":{}}}}},{"id":"/src/mcpQuerySingleAppMetrics/src/mcpQuerySingleAppMetrics/server.find_sub_topic_source_app.find_sub_topic_source_app_scope....set"},{"id":"app_2_source_app.values"},{"id":"rmc_utils.get_app_info"},{"id":"/src/mcpQuerySingleAppMetrics/src/mcpQuerySingleAppMetrics/server.query_single_app_em14_mq_sub.query_single_app_em14_mq_sub_scope...Exception"},{"id":"query_single_app_service_detail_in_em14 \\n[server.py : 413_468]","location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpQuerySingleAppMetrics/src/mcpQuerySingleAppMetrics/server.py"},"region":{"startLine":413,"startColumn":1,"endLine":468,"endColumn":18,"snippet":{}}}}},{"id":"/src/mcpQuerySingleAppMetrics/src/mcpQuerySingleAppMetrics/server.query_single_app_service_detail_in_em14.query_single_app_service_detail_in_em14_scope......ValueError"},{"id":"handle_call_tool \\n[server.py : 486_601]","location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpRepoInfo/src/mcpRepoInfo/server.py"},"region":{"startLine":486,"startColumn":1,"endLine":601,"endColumn":11,"snippet":{}}}}},{"id":"/src/mcpRepoInfo/src/mcpRepoInfo/server.handle_call_tool.handle_call_tool_scope...ValueError"},{"id":"/src/mcpRepoInfo/src/mcpRepoInfo/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"id":"/src/mcpRepoInfo/src/mcpRepoInfo/server.handle_call_tool.arguments.get"},{"id":"get_pull_requests \\n[server.py : 219_272]","location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpRepoInfo/src/mcpRepoInfo/server.py"},"region":{"startLine":219,"startColumn":1,"endLine":272,"endColumn":15,"snippet":{}}}}},{"id":"/src/mcpRepoInfo/src/mcpRepoInfo/server.get_pull_requests.get_pull_requests_scope..dict"},{"id":"mcp_common.remote.codeinsight.code_insight_api.mcp_server_backend_api(var params:any=dict(var name:any=Consts.GET_PULL_REQUESTS.name, var arguments:any=dict(var appName:any=app_name, var limit:any=lim..."},{"id":"/src/mcpRepoInfo/src/mcpRepoInfo/server.get_pull_requests.get_pull_requests_scope.....enumerate"},{"id":"/src/mcpRepoInfo/src/mcpRepoInfo/server.get_pull_requests.get_pull_requests_scope.....enumerate(pr_list).get"},{"id":"mcp_common.utils.consts.PR_PATTERN.format"},{"id":"/src/mcpRepoInfo/src/mcpRepoInfo/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"id":"/src/mcpRepoInfo/src/mcpRepoInfo/server.handle_call_tool.handle_call_tool_scope......ValueErro..."},{"id":"get_commit_list \\n[server.py : 275_327]","location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpRepoInfo/src/mcpRepoInfo/server.py"},"region":{"startLine":275,"startColumn":1,"endLine":327,"endColumn":77,"snippet":{}}}}},{"id":"/src/mcpRepoInfo/src/mcpRepoInfo/server.get_commit_list.get_commit_list_scope...dict"},{"id":"mcp_common.remote.codeinsight.code_insight_api.mcp_server_backend_api(var params:any=dict(var name:any=Consts.GET_COMMIT_LIST.name, var arguments:any=dict(var appName:any=app_name, var type:any=query_..."},{"id":"/src/mcpRepoInfo/src/mcpRepoInfo/server.get_commit_list.get_commit_list_scope......enumerate"},{"id":"/src/mcpRepoInfo/src/mcpRepoInfo/server.get_commit_list.get_commit_list_scope......enumerate(co..."},{"id":"mcp_common.utils.consts.COMMIT_PATTERN.format"},{"id":"/src/mcpRepoInfo/src/mcpRepoInfo/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"id":"/src/mcpRepoInfo/src/mcpRepoInfo/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"id":"get_commit_info \\n[server.py : 330_408]","location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpRepoInfo/src/mcpRepoInfo/server.py"},"region":{"startLine":330,"startColumn":1,"endLine":408,"endColumn":15,"snippet":{}}}}},{"id":"/src/mcpRepoInfo/src/mcpRepoInfo/server.get_commit_info.get_commit_info_scope..dict"},{"id":"mcp_common.remote.codeinsight.code_insight_api.mcp_server_backend_api(var params:any=dict(var name:any=Consts.GET_COMMIT_INFO.name, var arguments:any=dict(var appName:any=app_name, var commitId:any=co..."},{"id":"/src/mcpRepoInfo/src/mcpRepoInfo/server.get_commit_info.get_commit_info_scope...enumerate"},{"id":"mcp_common.utils.repo_util.parse_diff_change_type"},{"id":"/src/mcpRepoInfo/src/mcpRepoInfo/server.get_commit_info.get_commit_info_scope...enumerate(commit_diffs).get"},{"id":"mcp_common.utils.consts.DIFF_PATTERN.format"},{"id":"/src/mcpRepoInfo/src/mcpRepoInfo/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"id":"get_repo_url \\n[server.py : 411_444]","location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpRepoInfo/src/mcpRepoInfo/server.py"},"region":{"startLine":411,"startColumn":1,"endLine":444,"endColumn":15,"snippet":{}}}}},{"id":"/src/mcpRepoInfo/src/mcpRepoInfo/server.get_repo_url.get_repo_url_scope..dict"},{"id":"mcp_common.remote.codeinsight.code_insight_api.mcp_server_backend_api(var params:any=dict(var name:any=Consts.GET_REPO_URL.name, var arguments:any=dict(var appName:any=app_name, var antCodeToken:any=a..."},{"id":"/src/mcpRepoInfo/src/mcpRepoInfo/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"id":"get_app_list \\n[server.py : 447_482]","location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpRepoInfo/src/mcpRepoInfo/server.py"},"region":{"startLine":447,"startColumn":1,"endLine":482,"endColumn":15,"snippet":{}}}}},{"id":"/src/mcpRepoInfo/src/mcpRepoInfo/server.get_app_list.get_app_list_scope..dict"},{"id":"mcp_common.remote.codeinsight.code_insight_api.mcp_server_backend_api(var params:any=dict(var name:any=Consts.GET_DEPLOYMENT_UNIT.name, var arguments:any=dict(var repoUrl:any=repo_url))).get"},{"id":"/src/mcpRepoInfo/src/mcpRepoInfo/server.get_app_list.get_app_list_scope......enumerate"},{"id":"/src/mcpRepoInfo/src/mcpRepoInfo/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"id":"/src/mcpRepoInfo/src/mcpRepoInfo/server.handle_call_tool.handle_call_tool_scope...ValueError"},{"id":"handle_call_tool \\n[server.py : 46_64]","location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpReportNotify/src/mcpReportNotify/server.py"},"region":{"startLine":46,"startColumn":1,"endLine":64,"endColumn":54,"snippet":{}}}}},{"id":"/src/mcpReportNotify/src/mcpReportNotify/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"id":"/src/mcpReportNotify/src/mcpReportNotify/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"id":"/src/mcpReportNotify/src/mcpReportNotify/server.handle_call_tool.arguments.get"},{"id":"/src/mcpReportNotify/src/mcpReportNotify/server.handle_call_tool.handle_call_tool_scope...ding_notify_text"},{"id":"/src/mcpReportNotify/src/mcpReportNotify/server.handle_call_tool.handle_call_tool_scope...ValueError"},{"id":"handle_call_tool \\n[server.py : 58_91]","location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpRiskPunish/src/mcpRiskPunish/server.py"},"region":{"startLine":58,"startColumn":1,"endLine":91,"endColumn":54,"snippet":{}}}}},{"id":"/src/mcpRiskPunish/src/mcpRiskPunish/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"id":"/src/mcpRiskPunish/src/mcpRiskPunish/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"id":"/src/mcpRiskPunish/src/mcpRiskPunish/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"id":"/src/mcpRiskPunish/src/mcpRiskPunish/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"id":"/src/mcpRiskPunish/src/mcpRiskPunish/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"id":"/src/mcpRiskPunish/src/mcpRiskPunish/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"id":"/src/mcpRiskPunish/src/mcpRiskPunish/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"id":"/src/mcpRiskPunish/src/mcpRiskPunish/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"id":"/src/mcpRiskPunish/src/mcpRiskPunish/server.handle_call_tool.arguments.get"},{"id":"/src/mcpRiskPunish/src/mcpRiskPunish/server.handle_call_tool.handle_call_tool_scope...create_dima_link"},{"id":"/src/mcpRiskPunish/src/mcpRiskPunish/server.handle_call_tool.handle_call_tool_scope...ValueError"},{"id":"handle_call_tool \\n[server.py : 132_261]","location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpRopnTaskStatusAnalyse/src/mcpRopnTaskStatusAnalyse/server.py"},"region":{"startLine":132,"startColumn":1,"endLine":261,"endColumn":28,"snippet":{}}}}},{"id":"/src/mcpRopnTaskStatusAnalyse/src/mcpRopnTaskStatusAnalyse/server.handle_call_tool.handle_call_tool_scope....str"},{"id":"/src/mcpRopnTaskStatusAnalyse/src/mcpRopnTaskStatusAnalyse/server.handle_call_tool.handle_call_tool_scope....str(arguments.taskId_list).s..."},{"id":"ropcn_utils.groupByTaskStatus"},{"id":"/src/mcpRopnTaskStatusAnalyse/src/mcpRopnTaskStatusAnalyse/server.handle_call_tool.handle_call_tool_scope.....str"},{"id":"/src/mcpRopnTaskStatusAnalyse/src/mcpRopnTaskStatusAnalyse/server.handle_call_tool.handle_call_tool_scope.....str(arg..."},{"id":"ropcn_utils.groupByTypeAndSource"},{"id":"/src/mcpRopnTaskStatusAnalyse/src/mcpRopnTaskStatusAnalyse/server.handle_call_tool.handle_call_tool_scope..............ValueError"},{"id":"handle_call_tool \\n[server.py : 137_171]","location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpSemanticSearch/src/mcpSemanticSearch/server.py"},"region":{"startLine":137,"startColumn":1,"endLine":171,"endColumn":54,"snippet":{}}}}},{"id":"/src/mcpSemanticSearch/src/mcpSemanticSearch/server.handle_call_tool.handle_call_tool_scope...ValueError"},{"id":"/src/mcpSemanticSearch/src/mcpSemanticSearch/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"id":"/src/mcpSemanticSearch/src/mcpSemanticSearch/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"id":"/src/mcpSemanticSearch/src/mcpSemanticSearch/server.handle_call_tool.arguments.get"},{"id":"semantic_search \\n[server.py : 92_133]","location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpSemanticSearch/src/mcpSemanticSearch/server.py"},"region":{"startLine":92,"startColumn":1,"endLine":133,"endColumn":15,"snippet":{}}}}},{"id":"/src/mcpSemanticSearch/src/mcpSemanticSearch/server.semantic_search.semantic_search_scope..dict"},{"id":"mcp_common.remote.codeinsight.code_insight_api.mcp_server_backend_api(var params:any=dict(var name:any=Consts.SEMANTIC_SEARCH.name, var arguments:any=dict(var appName:any=app_name, var repoUrl:any=rep..."},{"id":"format_content \\n[server.py : 72_89]","location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpSemanticSearch/src/mcpSemanticSearch/server.py"},"region":{"startLine":72,"startColumn":1,"endLine":89,"endColumn":15,"snippet":{}}}}},{"id":"/src/mcpSemanticSearch/src/mcpSemanticSearch/server.format_content.format_content_scope...enumerate"},{"id":"/src/mcpSemanticSearch/src/mcpSemanticSearch/server.format_content.format_content_scope...enumerate(data_list).get"},{"id":"/src/mcpSemanticSearch/src/mcpSemanticSearch/server.handle_call_tool.handle_call_tool_scope...ValueError"},{"id":"handle_call_tool \\n[server.py : 318_373]","location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpSim/src/mcpSim/server.py"},"region":{"startLine":318,"startColumn":1,"endLine":373,"endColumn":54,"snippet":{}}}}},{"id":"/src/mcpSim/src/mcpSim/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"id":"/src/mcpSim/src/mcpSim/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"id":"get_node_trace_asset \\n[server.py : 17_45]","location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpSim/src/mcpSim/server.py"},"region":{"startLine":17,"startColumn":1,"endLine":45,"endColumn":54,"snippet":{}}}}},{"id":"syslib_from.requests.post(url, var headers:any=header, var json:any=params, var verify:any=false).raise_for_status"},{"id":"syslib_from.requests.post(url, var headers:any=header, var json:any=params, var verify:any=false).json"},{"id":"syslib_from.requests.post(url, var headers:any=header, var json:any=params, var verify:any=false).json().get"},{"id":"/src/mcpSim/src/mcpSim/server.get_node_trace_asset.get_node_trace_asset_scope...str"},{"id":"/src/mcpSim/src/mcpSim/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"id":"get_node_path \\n[server.py : 48_74]","location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpSim/src/mcpSim/server.py"},"region":{"startLine":48,"startColumn":1,"endLine":74,"endColumn":47,"snippet":{}}}}},{"id":"/src/mcpSim/src/mcpSim/server.get_node_path.get_node_path_scope...str"},{"id":"/src/mcpSim/src/mcpSim/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"id":"/src/mcpSim/src/mcpSim/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"id":"get_node_rpc_call \\n[server.py : 76_104]","location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpSim/src/mcpSim/server.py"},"region":{"startLine":76,"startColumn":1,"endLine":104,"endColumn":51,"snippet":{}}}}},{"id":"/src/mcpSim/src/mcpSim/server.get_node_rpc_call.get_node_rpc_call_scope...str"},{"id":"/src/mcpSim/src/mcpSim/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"id":"/src/mcpSim/src/mcpSim/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"id":"get_node_sub_call \\n[server.py : 107_135]","location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpSim/src/mcpSim/server.py"},"region":{"startLine":107,"startColumn":1,"endLine":135,"endColumn":51,"snippet":{}}}}},{"id":"/src/mcpSim/src/mcpSim/server.get_node_sub_call.get_node_sub_call_scope...str"},{"id":"/src/mcpSim/src/mcpSim/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"id":"/src/mcpSim/src/mcpSim/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"id":"get_node_sub_rpc_call \\n[server.py : 138_166]","location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpSim/src/mcpSim/server.py"},"region":{"startLine":138,"startColumn":1,"endLine":166,"endColumn":55,"snippet":{}}}}},{"id":"/src/mcpSim/src/mcpSim/server.get_node_sub_rpc_call.get_node_sub_rpc_call_scope...str"},{"id":"/src/mcpSim/src/mcpSim/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"id":"/src/mcpSim/src/mcpSim/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"id":"/src/mcpSim/src/mcpSim/server.handle_call_tool.handle_call_tool_scope...ValueError"},{"id":"handle_call_tool \\n[server.py : 473_580]","location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpSymbolAnalysis/src/mcpSymbolAnalysis/server.py"},"region":{"startLine":473,"startColumn":1,"endLine":580,"endColumn":54,"snippet":{}}}}},{"id":"/src/mcpSymbolAnalysis/src/mcpSymbolAnalysis/server.handle_call_tool.handle_call_tool_scope...ValueError"},{"id":"/src/mcpSymbolAnalysis/src/mcpSymbolAnalysis/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"id":"/src/mcpSymbolAnalysis/src/mcpSymbolAnalysis/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"id":"/src/mcpSymbolAnalysis/src/mcpSymbolAnalysis/server.handle_call_tool.arguments.get"},{"id":"get_class_methods \\n[server.py : 262_304]","location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpSymbolAnalysis/src/mcpSymbolAnalysis/server.py"},"region":{"startLine":262,"startColumn":1,"endLine":304,"endColumn":15,"snippet":{}}}}},{"id":"/src/mcpSymbolAnalysis/src/mcpSymbolAnalysis/server.get_class_methods.get_class_methods_scope..dict"},{"id":"mcp_common.remote.codeinsight.code_insight_api.mcp_server_backend_api(var params:any=dict(var name:any=Consts.GET_CLASS_METHODS.name, var arguments:any=dict(var appName:any=app_name, var fullyQualifie..."},{"id":"format_content \\n[server.py : 238_259]","location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpSymbolAnalysis/src/mcpSymbolAnalysis/server.py"},"region":{"startLine":238,"startColumn":1,"endLine":259,"endColumn":15,"snippet":{}}}}},{"id":"/src/mcpSymbolAnalysis/src/mcpSymbolAnalysis/server.format_content.format_content_scope...enumerate"},{"id":"/src/mcpSymbolAnalysis/src/mcpSymbolAnalysis/server.format_content.format_content_scope...enumerate(data_list).get"},{"id":"/src/mcpSymbolAnalysis/src/mcpSymbolAnalysis/server.format_content.format_content_scope...enumerate(data_list).get(extra_data, {}).get"},{"id":"/src/mcpSymbolAnalysis/src/mcpSymbolAnalysis/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"id":"/src/mcpSymbolAnalysis/src/mcpSymbolAnalysis/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"id":"analyze_method_call_chain \\n[server.py : 307_353]","location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpSymbolAnalysis/src/mcpSymbolAnalysis/server.py"},"region":{"startLine":307,"startColumn":1,"endLine":353,"endColumn":15,"snippet":{}}}}},{"id":"/src/mcpSymbolAnalysis/src/mcpSymbolAnalysis/server.analyze_method_call_chain.analyze_method_call_chain_scope..dict"},{"id":"mcp_common.remote.codeinsight.code_insight_api.mcp_server_backend_api(var params:any=dict(var name:any=Consts.ANALYZE_METHOD_CALL_CHAIN.name, var arguments:any=dict(var appName:any=app_name, var fully..."},{"id":"/src/mcpSymbolAnalysis/src/mcpSymbolAnalysis/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"id":"/src/mcpSymbolAnalysis/src/mcpSymbolAnalysis/server.handle_call_tool.handle_call_tool_scope......dict"},{"id":"mcp_common.remote.codeinsight.code_insight_api.mcp_server_backend_api(var params:any=dict(var name:any=Consts.RESOLVE_METHOD_REFERENCE.name, var arguments:any=dict(var appName:any=app_name, var fullyQ..."},{"id":"/src/mcpSymbolAnalysis/src/mcpSymbolAnalysis/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"id":"/src/mcpSymbolAnalysis/src/mcpSymbolAnalysis/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"id":"resolve_method_callee \\n[server.py : 409_453]","location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpSymbolAnalysis/src/mcpSymbolAnalysis/server.py"},"region":{"startLine":409,"startColumn":1,"endLine":453,"endColumn":15,"snippet":{}}}}},{"id":"/src/mcpSymbolAnalysis/src/mcpSymbolAnalysis/server.resolve_method_callee.resolve_method_callee_scope..dict"},{"id":"mcp_common.remote.codeinsight.code_insight_api.mcp_server_backend_api(var params:any=dict(var name:any=Consts.RESOLVE_METHOD_CALLEE.name, var arguments:any=dict(var appName:any=app_name, var fullyQual..."},{"id":"/src/mcpSymbolAnalysis/src/mcpSymbolAnalysis/server.handle_call_tool.handle_call_tool_scope...ValueError"},{"id":"add \\n[server.py : 7_8]","location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpTemplate/src/mcpTemplate/server.py"},"region":{"startLine":7,"startColumn":1,"endLine":8,"endColumn":17,"snippet":{}}}}},{"id":"/src/mcpTestAnalysis/src/mcpTestAnalysis/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"id":"syslib_from.client.get_code_diffs"},{"id":"/src/mcpTestAnalysis/src/mcpTestAnalysis/server.handle_call_tool.handle_call_tool_scope...ValueError"},{"id":"handle_call_tool \\n[server.py : 106_153]","location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpTestAnalysisDocument/src/mcpTestAnalysisDocument/server.py"},"region":{"startLine":106,"startColumn":1,"endLine":153,"endColumn":54,"snippet":{}}}}},{"id":"/src/mcpTestAnalysisDocument/src/mcpTestAnalysisDocument/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"id":"/src/mcpTestAnalysisDocument/src/mcpTestAnalysisDocument/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"id":"syslib_from.report_client.write_document"},{"id":"/src/mcpTestAnalysisDocument/src/mcpTestAnalysisDocument/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"id":"/src/mcpTestAnalysisDocument/src/mcpTestAnalysisDocument/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"id":"syslib_from.yuque_markdown.fetch_yuque_document_split_block_remain_pic"},{"id":"/src/mcpTestAnalysisDocument/src/mcpTestAnalysisDocument/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"id":"/src/mcpTestAnalysisDocument/src/mcpTestAnalysisDocument/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"id":"syslib_from.yuque_markdown.chat_with_pic"},{"id":"/src/mcpTestAnalysisDocument/src/mcpTestAnalysisDocument/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"id":"/src/mcpTestAnalysisDocument/src/mcpTestAnalysisDocument/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"id":"syslib_from.yuque_markdown.get_dima_document"},{"id":"/src/mcpTestAnalysisDocument/src/mcpTestAnalysisDocument/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"id":"/src/mcpTestAnalysisDocument/src/mcpTestAnalysisDocument/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"id":"/src/mcpTestAnalysisDocument/src/mcpTestAnalysisDocument/server.handle_call_tool.handle_call_tool_scope...ValueError"},{"id":"handle_call_tool \\n[server.py : 79_118]","location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpTvp/src/mcpTvp/server.py"},"region":{"startLine":79,"startColumn":1,"endLine":118,"endColumn":54,"snippet":{}}}}},{"id":"/src/mcpTvp/src/mcpTvp/server.handle_call_tool.handle_call_tool_scope..json.dumps"},{"id":"/src/mcpTvp/src/mcpTvp/server.handle_call_tool.handle_call_tool_scope..info_logger.info"},{"id":"/src/mcpTvp/src/mcpTvp/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"id":"/src/mcpTvp/src/mcpTvp/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"id":"/src/mcpTvp/src/mcpTvp/server.handle_call_tool.arguments.get"},{"id":"/src/mcpTvp/src/mcpTvp/server.handle_call_tool.handle_call_tool_scope...execute_cypress_script"},{"id":"/src/mcpTvp/src/mcpTvp/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"id":"/src/mcpTvp/src/mcpTvp/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"id":"/src/mcpTvp/src/mcpTvp/server.handle_call_tool.handle_call_tool_scope...execute_playwright_script"},{"id":"/src/mcpTvp/src/mcpTvp/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"id":"/src/mcpTvp/src/mcpTvp/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"id":"/src/mcpTvp/src/mcpTvp/server.handle_call_tool.handle_call_tool_scope...query_script_execute_status"},{"id":"/src/mcpTvp/src/mcpTvp/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"id":"/src/mcpTvp/src/mcpTvp/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"id":"/src/mcpTvp/src/mcpTvp/server.handle_call_tool.handle_call_tool_scope...query_script_execute_result"},{"id":"/src/mcpTvp/src/mcpTvp/server.handle_call_tool.handle_call_tool_scope...ValueError"},{"id":"handle_call_tool \\n[server.py : 35_47]","location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpUtils/src/mcpUtils/server.py"},"region":{"startLine":35,"startColumn":1,"endLine":47,"endColumn":54,"snippet":{}}}}},{"id":"get_current_time \\n[server.py : 9_10]","location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpUtils/src/mcpUtils/server.py"},"region":{"startLine":9,"startColumn":1,"endLine":10,"endColumn":65,"snippet":{}}}}},{"id":"syslib_from.datetime.datetime.now"},{"id":"syslib_from.datetime.datetime.now().strftime"},{"id":"/src/mcpUtils/src/mcpUtils/server.handle_call_tool.handle_call_tool_scope...ValueError"},{"id":"handle_call_tool \\n[server.py : 41_71]","location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpVarySearch/src/mcpVarySearch/server.py"},"region":{"startLine":41,"startColumn":1,"endLine":71,"endColumn":6,"snippet":{}}}}},{"id":"/src/mcpVarySearch/src/mcpVarySearch/server.handle_call_tool.handle_call_tool_scope...ValueError"},{"id":"/src/mcpVarySearch/src/mcpVarySearch/server.handle_call_tool.handle_call_tool_scope...ValueError"},{"id":"/src/mcpVarySearch/src/mcpVarySearch/server.handle_call_tool.arguments.get"},{"id":"/src/mcpVarySearch/src/mcpVarySearch/server.handle_call_tool.handle_call_tool_scope...ValueError"},{"id":"vary_search \\n[server.py : 91_130]","location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpVarySearch/src/mcpVarySearch/server.py"},"region":{"startLine":91,"startColumn":1,"endLine":130,"endColumn":20,"snippet":{}}}}},{"id":"syslib_from.pytz.timezone"},{"id":"syslib_from.pytz.timezone(Asia/Shanghai).localize"},{"id":"syslib_from.pytz.timezone(Asia/Shanghai).localize(datetime.strptime(start_time, ft)).timestamp"},{"id":"syslib_from.pytz.timezone(Asia/Shanghai).localize(datetime.strptime(end_time, ft)).timestamp"},{"id":"syslib_from.requests.post(url, var headers:any=headers, var json:any=payload).raise_for_status"},{"id":"syslib_from.requests.post(url, var headers:any=headers, var json:any=payload).json"},{"id":"syslib_from.requests.post(url, var headers:any=headers, var json:any=payload).json().get"},{"id":"payload.dumps"},{"id":"/src/mcpVarySearch/src/mcpVarySearch/server.vary_search.vary_search_scope...str"},{"id":"handle_call_tool \\n[server.py : 170_267]","location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpYuntu/src/mcpYuntu/server.py"},"region":{"startLine":170,"startColumn":1,"endLine":267,"endColumn":54,"snippet":{}}}}},{"id":"/src/mcpYuntu/src/mcpYuntu/server.handle_call_tool.handle_call_tool_scope..json.dumps"},{"id":"/src/mcpYuntu/src/mcpYuntu/server.handle_call_tool.handle_call_tool_scope..info_logger.info"},{"id":"/src/mcpYuntu/src/mcpYuntu/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"id":"/src/mcpYuntu/src/mcpYuntu/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"id":"/src/mcpYuntu/src/mcpYuntu/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"id":"/src/mcpYuntu/src/mcpYuntu/server.handle_call_tool.handle_call_tool_scope...get_yuntu_call_tree"},{"id":"/src/mcpYuntu/src/mcpYuntu/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"id":"/src/mcpYuntu/src/mcpYuntu/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"id":"/src/mcpYuntu/src/mcpYuntu/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"id":"/src/mcpYuntu/src/mcpYuntu/server.handle_call_tool.handle_call_tool_scope...get_yuntu_call_tree"},{"id":"/src/mcpYuntu/src/mcpYuntu/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"id":"/src/mcpYuntu/src/mcpYuntu/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"id":"/src/mcpYuntu/src/mcpYuntu/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"id":"/src/mcpYuntu/src/mcpYuntu/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"id":"/src/mcpYuntu/src/mcpYuntu/server.handle_call_tool.handle_call_tool_scope...get_yuntu_call_sub_tree_by_rpc_id"},{"id":"/src/mcpYuntu/src/mcpYuntu/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"id":"/src/mcpYuntu/src/mcpYuntu/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"id":"/src/mcpYuntu/src/mcpYuntu/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"id":"/src/mcpYuntu/src/mcpYuntu/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"id":"/src/mcpYuntu/src/mcpYuntu/server.handle_call_tool.handle_call_tool_scope...get_yuntu_call_rpc_id_by_app"},{"id":"/src/mcpYuntu/src/mcpYuntu/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"id":"/src/mcpYuntu/src/mcpYuntu/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"id":"/src/mcpYuntu/src/mcpYuntu/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"id":"/src/mcpYuntu/src/mcpYuntu/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"id":"/src/mcpYuntu/src/mcpYuntu/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"id":"/src/mcpYuntu/src/mcpYuntu/server.handle_call_tool.handle_call_tool_scope...get_yuntu_call_key_message_by_service"},{"id":"/src/mcpYuntu/src/mcpYuntu/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"id":"/src/mcpYuntu/src/mcpYuntu/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"id":"/src/mcpYuntu/src/mcpYuntu/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"id":"/src/mcpYuntu/src/mcpYuntu/server.handle_call_tool.handle_call_tool_scope...execute_tool"},{"id":"/src/mcpYuntu/src/mcpYuntu/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"id":"/src/mcpYuntu/src/mcpYuntu/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"id":"/src/mcpYuntu/src/mcpYuntu/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"id":"/src/mcpYuntu/src/mcpYuntu/server.handle_call_tool.handle_call_tool_scope...execute_tool"},{"id":"/src/mcpYuntu/src/mcpYuntu/server.handle_call_tool.handle_call_tool_scope...ValueError"},{"id":"/src/mcpyuque/src/mcpyuque/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"id":"/src/mcpyuque/src/mcpyuque/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"id":"/src/mcpyuque/src/mcpyuque/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"id":"/src/mcpyuque/src/mcpyuque/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"id":"fetch_yuque_document \\n[yuque_markdown.py : 40_72]","location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpyuque/src/mcpyuque/yuque_markdown.py"},"region":{"startLine":40,"startColumn":1,"endLine":72,"endColumn":28,"snippet":{}}}}},{"id":"mcp_common.request.http_client.AsyncRestClient(var base_url:any=https://instemc.alipay.com/yuque, var default_headers:any=_headers()).post(var endpoint:any=/yuque2markDown, var data:any=payload).get"},{"id":"/src/mcpyuque/src/mcpyuque/yuque_markdown.fetch_yuque_document.fetch_yuque_document_scope...str"},{"id":"/src/mcpyuque/src/mcpyuque/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"id":"/src/mcpyuque/src/mcpyuque/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"id":"/src/mcpyuque/src/mcpyuque/server.handle_call_tool.handle_call_tool_scope...ValueError"}],"edges":[{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/test.py"},"region":{"startLine":2,"startColumn":10,"endLine":2,"endColumn":19,"snippet":{}}}},"id":"<__entry_point__>->/src/test..range","sourceNodeId":"<__entry_point__>","targetNodeId":"/src/test..range"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/test.py"},"region":{"startLine":5,"startColumn":5,"endLine":5,"endColumn":13,"snippet":{}}}},"id":"<__entry_point__>->/src/test..print","sourceNodeId":"<__entry_point__>","targetNodeId":"/src/test..print"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/test.py"},"region":{"startLine":8,"startColumn":1,"endLine":8,"endColumn":9,"snippet":{}}}},"id":"<__entry_point__>->/src/test.print","sourceNodeId":"<__entry_point__>","targetNodeId":"/src/test.print"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-common/src/mcp_common/utils/time_util.py"},"region":{"startLine":11,"startColumn":15,"endLine":11,"endColumn":42,"snippet":{}}}},"id":"<__entry_point__>->syslib_from.logging.getLogger","sourceNodeId":"<__entry_point__>","targetNodeId":"syslib_from.logging.getLogger"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-db-base/src/mcp_db_base/db_monitor_client.py"},"region":{"startLine":255,"startColumn":23,"endLine":255,"endColumn":116,"snippet":{}}}},"id":"<__entry_point__>->get_server_tenant_tqps_monitor \\n[db_monitor_client.py : 231_238]","sourceNodeId":"<__entry_point__>","targetNodeId":"get_server_tenant_tqps_monitor \\n[db_monitor_client.py : 231_238]"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-db-base/src/mcp_db_base/db_monitor_client.py"},"region":{"startLine":234,"startColumn":57,"endLine":234,"endColumn":81,"snippet":{}}}},"id":"get_server_tenant_tqps_monitor \\n[db_monitor_client.py : 231_238]->deal_server_port \\n[db_monitor_client.py : 12_16]","sourceNodeId":"get_server_tenant_tqps_monitor \\n[db_monitor_client.py : 231_238]","targetNodeId":"deal_server_port \\n[db_monitor_client.py : 12_16]"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-db-base/src/mcp_db_base/db_monitor_client.py"},"region":{"startLine":232,"startColumn":29,"endLine":234,"endColumn":82,"snippet":{}}}},"id":"get_server_tenant_tqps_monitor \\n[db_monitor_client.py : 231_238]->mcp_db_base.maas_sql_client.get_multi_metric","sourceNodeId":"get_server_tenant_tqps_monitor \\n[db_monitor_client.py : 231_238]","targetNodeId":"mcp_db_base.maas_sql_client.get_multi_metric"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-db-base/src/mcp_db_base/db_monitor_client.py"},"region":{"startLine":235,"startColumn":38,"endLine":237,"endColumn":116,"snippet":{}}}},"id":"get_server_tenant_tqps_monitor \\n[db_monitor_client.py : 231_238]->mcp_db_base.maas_sql_client.process_timeseries_data","sourceNodeId":"get_server_tenant_tqps_monitor \\n[db_monitor_client.py : 231_238]","targetNodeId":"mcp_db_base.maas_sql_client.process_timeseries_data"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-db-base/src/mcp_db_base/db_monitor_client.py"},"region":{"startLine":238,"startColumn":12,"endLine":238,"endColumn":74,"snippet":{}}}},"id":"get_server_tenant_tqps_monitor \\n[db_monitor_client.py : 231_238]->syslib_from.json.dumps","sourceNodeId":"get_server_tenant_tqps_monitor \\n[db_monitor_client.py : 231_238]","targetNodeId":"syslib_from.json.dumps"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpyuque/src/mcpyuque/yuque_markdown.py"},"region":{"startLine":112,"startColumn":5,"endLine":112,"endColumn":24,"snippet":{}}}},"id":"<__entry_point__>->syslib_from.asyncio.run","sourceNodeId":"<__entry_point__>","targetNodeId":"syslib_from.asyncio.run"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-db-base/src/mcp_db_base/db_monitor_client.py"},"region":{"startLine":255,"startColumn":5,"endLine":255,"endColumn":118,"snippet":{}}}},"id":"<__entry_point__>->/src/mcp-db-base/src/mcp_db_base/db_monitor_client..print","sourceNodeId":"<__entry_point__>","targetNodeId":"/src/mcp-db-base/src/mcp_db_base/db_monitor_client..print"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-db-base/src/mcp_db_base/dba_metadata_utils.py"},"region":{"startLine":28,"startColumn":28,"endLine":28,"endColumn":108,"snippet":{}}}},"id":"<__entry_point__>->/src/mcp-db-base/src/mcp_db_base/dba_metadata_utils.DbSlot.Field","sourceNodeId":"<__entry_point__>","targetNodeId":"/src/mcp-db-base/src/mcp_db_base/dba_metadata_utils.DbSlot.Field"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-db-base/src/mcp_db_base/dba_metadata_utils.py"},"region":{"startLine":70,"startColumn":26,"endLine":70,"endColumn":73,"snippet":{}}}},"id":"<__entry_point__>->/src/mcp-db-base/src/mcp_db_base/dba_metadata_utils.DBMetadata.Field","sourceNodeId":"<__entry_point__>","targetNodeId":"/src/mcp-db-base/src/mcp_db_base/dba_metadata_utils.DBMetadata.Field"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-db-base/src/mcp_db_base/dba_metadata_utils.py"},"region":{"startLine":550,"startColumn":19,"endLine":550,"endColumn":36,"snippet":{}}}},"id":"<__entry_point__>->DBAMetadataUtil :: __init__ \\n[dba_metadata_utils.py : 86_89]","sourceNodeId":"<__entry_point__>","targetNodeId":"DBAMetadataUtil :: __init__ \\n[dba_metadata_utils.py : 86_89]"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-db-base/src/mcp_db_base/dba_metadata_utils.py"},"region":{"startLine":563,"startColumn":27,"endLine":568,"endColumn":7,"snippet":{}}}},"id":"<__entry_point__>->get_db_meta \\n[dba_metadata_utils.py : 514_546]","sourceNodeId":"<__entry_point__>","targetNodeId":"get_db_meta \\n[dba_metadata_utils.py : 514_546]"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-db-base/src/mcp_db_base/dba_metadata_utils.py"},"region":{"startLine":517,"startColumn":5,"endLine":518,"endColumn":123,"snippet":{}}}},"id":"get_db_meta \\n[dba_metadata_utils.py : 514_546]->syslib_from.logging.getLogger(__name__).info","sourceNodeId":"get_db_meta \\n[dba_metadata_utils.py : 514_546]","targetNodeId":"syslib_from.logging.getLogger(__name__).info"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-db-base/src/mcp_db_base/dba_metadata_utils.py"},"region":{"startLine":522,"startColumn":19,"endLine":522,"endColumn":36,"snippet":{}}}},"id":"get_db_meta \\n[dba_metadata_utils.py : 514_546]->DBAMetadataUtil :: __init__ \\n[dba_metadata_utils.py : 86_89]","sourceNodeId":"get_db_meta \\n[dba_metadata_utils.py : 514_546]","targetNodeId":"DBAMetadataUtil :: __init__ \\n[dba_metadata_utils.py : 86_89]"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-db-base/src/mcp_db_base/dba_metadata_utils.py"},"region":{"startLine":526,"startColumn":30,"endLine":526,"endColumn":83,"snippet":{}}}},"id":"get_db_meta \\n[dba_metadata_utils.py : 514_546]->DBAMetadataUtil :: fill_app_db_info \\n[dba_metadata_utils.py : 224_293]","sourceNodeId":"get_db_meta \\n[dba_metadata_utils.py : 514_546]","targetNodeId":"DBAMetadataUtil :: fill_app_db_info \\n[dba_metadata_utils.py : 224_293]"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-db-base/src/mcp_db_base/dba_metadata_utils.py"},"region":{"startLine":227,"startColumn":19,"endLine":227,"endColumn":91,"snippet":{}}}},"id":"DBAMetadataUtil :: fill_app_db_info \\n[dba_metadata_utils.py : 224_293]->mcp_db_base.omc_client.get_app_dbs","sourceNodeId":"DBAMetadataUtil :: fill_app_db_info \\n[dba_metadata_utils.py : 224_293]","targetNodeId":"mcp_db_base.omc_client.get_app_dbs"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-db-base/src/mcp_db_base/dba_metadata_utils.py"},"region":{"startLine":228,"startColumn":12,"endLine":228,"endColumn":24,"snippet":{}}}},"id":"DBAMetadataUtil :: fill_app_db_info \\n[dba_metadata_utils.py : 224_293]->/src/mcp-db-base/src/mcp_db_base/dba_metadata_utils.DBAMetadataUtil.fill_app_db_info.fill_app_db_info_scope..len","sourceNodeId":"DBAMetadataUtil :: fill_app_db_info \\n[dba_metadata_utils.py : 224_293]","targetNodeId":"/src/mcp-db-base/src/mcp_db_base/dba_metadata_utils.DBAMetadataUtil.fill_app_db_info.fill_app_db_info_scope..len"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-db-base/src/mcp_db_base/dba_metadata_utils.py"},"region":{"startLine":291,"startColumn":39,"endLine":291,"endColumn":52,"snippet":{}}}},"id":"DBAMetadataUtil :: fill_app_db_info \\n[dba_metadata_utils.py : 224_293]->mcp_db_base.omc_client.get_app_dbs(db_target.app, var site:any=db_target.site, var env:any=db_target.env).get","sourceNodeId":"DBAMetadataUtil :: fill_app_db_info \\n[dba_metadata_utils.py : 224_293]","targetNodeId":"mcp_db_base.omc_client.get_app_dbs(db_target.app, var site:any=db_target.site, var env:any=db_target.env).get"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-db-base/src/mcp_db_base/dba_metadata_utils.py"},"region":{"startLine":277,"startColumn":35,"endLine":277,"endColumn":70,"snippet":{}}}},"id":"DBAMetadataUtil :: fill_app_db_info \\n[dba_metadata_utils.py : 224_293]->DBAMetadataUtil :: _get_physics_db_info \\n[dba_metadata_utils.py : 488_500]","sourceNodeId":"DBAMetadataUtil :: fill_app_db_info \\n[dba_metadata_utils.py : 224_293]","targetNodeId":"DBAMetadataUtil :: _get_physics_db_info \\n[dba_metadata_utils.py : 488_500]"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-db-base/src/mcp_db_base/dba_metadata_utils.py"},"region":{"startLine":491,"startColumn":21,"endLine":491,"endColumn":40,"snippet":{}}}},"id":"DBAMetadataUtil :: _get_physics_db_info \\n[dba_metadata_utils.py : 488_500]->mcp_db_base.omc_client.get_app_dbs(db_target.app, var site:any=db_target.site, var env:any=db_target.env).get","sourceNodeId":"DBAMetadataUtil :: _get_physics_db_info \\n[dba_metadata_utils.py : 488_500]","targetNodeId":"mcp_db_base.omc_client.get_app_dbs(db_target.app, var site:any=db_target.site, var env:any=db_target.env).get"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-db-base/src/mcp_db_base/dba_metadata_utils.py"},"region":{"startLine":493,"startColumn":19,"endLine":493,"endColumn":46,"snippet":{}}}},"id":"DBAMetadataUtil :: _get_physics_db_info \\n[dba_metadata_utils.py : 488_500]->mcp_db_base.omc_client.get_dbs","sourceNodeId":"DBAMetadataUtil :: _get_physics_db_info \\n[dba_metadata_utils.py : 488_500]","targetNodeId":"mcp_db_base.omc_client.get_dbs"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-db-base/src/mcp_db_base/dba_metadata_utils.py"},"region":{"startLine":495,"startColumn":20,"endLine":495,"endColumn":28,"snippet":{}}}},"id":"DBAMetadataUtil :: _get_physics_db_info \\n[dba_metadata_utils.py : 488_500]->/src/mcp-db-base/src/mcp_db_base/dba_metadata_utils.DBAMetadataUtil._get_physics_db_info._get_physics_db_info_scope....len","sourceNodeId":"DBAMetadataUtil :: _get_physics_db_info \\n[dba_metadata_utils.py : 488_500]","targetNodeId":"/src/mcp-db-base/src/mcp_db_base/dba_metadata_utils.DBAMetadataUtil._get_physics_db_info._get_physics_db_info_scope....len"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-db-base/src/mcp_db_base/dba_metadata_utils.py"},"region":{"startLine":498,"startColumn":46,"endLine":498,"endColumn":66,"snippet":{}}}},"id":"DBAMetadataUtil :: _get_physics_db_info \\n[dba_metadata_utils.py : 488_500]->mcp_db_base.omc_client.get_dbs(var db:any=logic_arn).get","sourceNodeId":"DBAMetadataUtil :: _get_physics_db_info \\n[dba_metadata_utils.py : 488_500]","targetNodeId":"mcp_db_base.omc_client.get_dbs(var db:any=logic_arn).get"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-db-base/src/mcp_db_base/dba_metadata_utils.py"},"region":{"startLine":240,"startColumn":43,"endLine":240,"endColumn":76,"snippet":{}}}},"id":"DBAMetadataUtil :: fill_app_db_info \\n[dba_metadata_utils.py : 224_293]->db_metadata.tenant_arn.split","sourceNodeId":"DBAMetadataUtil :: fill_app_db_info \\n[dba_metadata_utils.py : 224_293]","targetNodeId":"db_metadata.tenant_arn.split"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-db-base/src/mcp_db_base/dba_metadata_utils.py"},"region":{"startLine":284,"startColumn":53,"endLine":286,"endColumn":26,"snippet":{}}}},"id":"DBAMetadataUtil :: fill_app_db_info \\n[dba_metadata_utils.py : 224_293]->DBAMetadataUtil :: _fill_db_cluster \\n[dba_metadata_utils.py : 502_511]","sourceNodeId":"DBAMetadataUtil :: fill_app_db_info \\n[dba_metadata_utils.py : 224_293]","targetNodeId":"DBAMetadataUtil :: _fill_db_cluster \\n[dba_metadata_utils.py : 502_511]"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-db-base/src/mcp_db_base/dba_metadata_utils.py"},"region":{"startLine":504,"startColumn":23,"endLine":506,"endColumn":10,"snippet":{}}}},"id":"DBAMetadataUtil :: _fill_db_cluster \\n[dba_metadata_utils.py : 502_511]->mcp_db_base.omc_client.get_tenant_info","sourceNodeId":"DBAMetadataUtil :: _fill_db_cluster \\n[dba_metadata_utils.py : 502_511]","targetNodeId":"mcp_db_base.omc_client.get_tenant_info"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-db-base/src/mcp_db_base/dba_metadata_utils.py"},"region":{"startLine":508,"startColumn":27,"endLine":508,"endColumn":56,"snippet":{}}}},"id":"DBAMetadataUtil :: _fill_db_cluster \\n[dba_metadata_utils.py : 502_511]->mcp_db_base.omc_client.get_tenant_info(var tenant:any=tenant_arn).get","sourceNodeId":"DBAMetadataUtil :: _fill_db_cluster \\n[dba_metadata_utils.py : 502_511]","targetNodeId":"mcp_db_base.omc_client.get_tenant_info(var tenant:any=tenant_arn).get"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-db-base/src/mcp_db_base/dba_metadata_utils.py"},"region":{"startLine":510,"startColumn":37,"endLine":510,"endColumn":59,"snippet":{}}}},"id":"DBAMetadataUtil :: _fill_db_cluster \\n[dba_metadata_utils.py : 502_511]->mcp_db_base.omc_client.get_tenant_info(var tenant:any=tenant_arn).get(clusterArn).split","sourceNodeId":"DBAMetadataUtil :: _fill_db_cluster \\n[dba_metadata_utils.py : 502_511]","targetNodeId":"mcp_db_base.omc_client.get_tenant_info(var tenant:any=tenant_arn).get(clusterArn).split"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-db-base/src/mcp_db_base/dba_metadata_utils.py"},"region":{"startLine":291,"startColumn":39,"endLine":291,"endColumn":52,"snippet":{}}}},"id":"DBAMetadataUtil :: fill_app_db_info \\n[dba_metadata_utils.py : 224_293]->get","sourceNodeId":"DBAMetadataUtil :: fill_app_db_info \\n[dba_metadata_utils.py : 224_293]","targetNodeId":"get"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-db-base/src/mcp_db_base/dba_metadata_utils.py"},"region":{"startLine":263,"startColumn":51,"endLine":263,"endColumn":84,"snippet":{}}}},"id":"DBAMetadataUtil :: fill_app_db_info \\n[dba_metadata_utils.py : 224_293]->mcp_db_base.omc_client.get_app_dbs(db_target.app, var site:any=db_target.site, var env:any=db_target.env).get(tenantArn).split","sourceNodeId":"DBAMetadataUtil :: fill_app_db_info \\n[dba_metadata_utils.py : 224_293]","targetNodeId":"mcp_db_base.omc_client.get_app_dbs(db_target.app, var site:any=db_target.site, var env:any=db_target.env).get(tenantArn).split"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-db-base/src/mcp_db_base/dba_metadata_utils.py"},"region":{"startLine":491,"startColumn":21,"endLine":491,"endColumn":40,"snippet":{}}}},"id":"DBAMetadataUtil :: _get_physics_db_info \\n[dba_metadata_utils.py : 488_500]->get","sourceNodeId":"DBAMetadataUtil :: _get_physics_db_info \\n[dba_metadata_utils.py : 488_500]","targetNodeId":"get"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-db-base/src/mcp_db_base/dba_metadata_utils.py"},"region":{"startLine":282,"startColumn":51,"endLine":282,"endColumn":84,"snippet":{}}}},"id":"DBAMetadataUtil :: fill_app_db_info \\n[dba_metadata_utils.py : 224_293]->split","sourceNodeId":"DBAMetadataUtil :: fill_app_db_info \\n[dba_metadata_utils.py : 224_293]","targetNodeId":"split"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-db-base/src/mcp_db_base/dba_metadata_utils.py"},"region":{"startLine":282,"startColumn":51,"endLine":282,"endColumn":84,"snippet":{}}}},"id":"DBAMetadataUtil :: fill_app_db_info \\n[dba_metadata_utils.py : 224_293]->tenant_arn.split","sourceNodeId":"DBAMetadataUtil :: fill_app_db_info \\n[dba_metadata_utils.py : 224_293]","targetNodeId":"tenant_arn.split"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-db-base/src/mcp_db_base/dba_metadata_utils.py"},"region":{"startLine":292,"startColumn":21,"endLine":292,"endColumn":53,"snippet":{}}}},"id":"DBAMetadataUtil :: fill_app_db_info \\n[dba_metadata_utils.py : 224_293]->db_metadata.append","sourceNodeId":"DBAMetadataUtil :: fill_app_db_info \\n[dba_metadata_utils.py : 224_293]","targetNodeId":"db_metadata.append"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-db-base/src/mcp_db_base/dba_metadata_utils.py"},"region":{"startLine":292,"startColumn":21,"endLine":292,"endColumn":53,"snippet":{}}}},"id":"DBAMetadataUtil :: fill_app_db_info \\n[dba_metadata_utils.py : 224_293]->append","sourceNodeId":"DBAMetadataUtil :: fill_app_db_info \\n[dba_metadata_utils.py : 224_293]","targetNodeId":"append"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-db-base/src/mcp_db_base/dba_metadata_utils.py"},"region":{"startLine":529,"startColumn":30,"endLine":529,"endColumn":82,"snippet":{}}}},"id":"get_db_meta \\n[dba_metadata_utils.py : 514_546]->DBAMetadataUtil :: fill_table_info \\n[dba_metadata_utils.py : 383_476]","sourceNodeId":"get_db_meta \\n[dba_metadata_utils.py : 514_546]","targetNodeId":"DBAMetadataUtil :: fill_table_info \\n[dba_metadata_utils.py : 383_476]"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-db-base/src/mcp_db_base/dba_metadata_utils.py"},"region":{"startLine":392,"startColumn":23,"endLine":392,"endColumn":57,"snippet":{}}}},"id":"DBAMetadataUtil :: fill_table_info \\n[dba_metadata_utils.py : 383_476]->mcp_db_base.omc_client.get_logic_dbs","sourceNodeId":"DBAMetadataUtil :: fill_table_info \\n[dba_metadata_utils.py : 383_476]","targetNodeId":"mcp_db_base.omc_client.get_logic_dbs"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-db-base/src/mcp_db_base/dba_metadata_utils.py"},"region":{"startLine":398,"startColumn":50,"endLine":398,"endColumn":70,"snippet":{}}}},"id":"DBAMetadataUtil :: fill_table_info \\n[dba_metadata_utils.py : 383_476]->mcp_db_base.omc_client.get_logic_dbs(var arn:any=table_arn).get","sourceNodeId":"DBAMetadataUtil :: fill_table_info \\n[dba_metadata_utils.py : 383_476]","targetNodeId":"mcp_db_base.omc_client.get_logic_dbs(var arn:any=table_arn).get"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-db-base/src/mcp_db_base/dba_metadata_utils.py"},"region":{"startLine":399,"startColumn":21,"endLine":401,"endColumn":22,"snippet":{}}}},"id":"DBAMetadataUtil :: fill_table_info \\n[dba_metadata_utils.py : 383_476]->DBAMetadataUtil :: _set_app_by_logic \\n[dba_metadata_utils.py : 478_486]","sourceNodeId":"DBAMetadataUtil :: fill_table_info \\n[dba_metadata_utils.py : 383_476]","targetNodeId":"DBAMetadataUtil :: _set_app_by_logic \\n[dba_metadata_utils.py : 478_486]"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-db-base/src/mcp_db_base/dba_metadata_utils.py"},"region":{"startLine":481,"startColumn":32,"endLine":481,"endColumn":55,"snippet":{}}}},"id":"DBAMetadataUtil :: _set_app_by_logic \\n[dba_metadata_utils.py : 478_486]->mcp_db_base.omc_client.get_logic_dbs(var arn:any=table_arn).get","sourceNodeId":"DBAMetadataUtil :: _set_app_by_logic \\n[dba_metadata_utils.py : 478_486]","targetNodeId":"mcp_db_base.omc_client.get_logic_dbs(var arn:any=table_arn).get"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-db-base/src/mcp_db_base/dba_metadata_utils.py"},"region":{"startLine":483,"startColumn":20,"endLine":483,"endColumn":109,"snippet":{}}}},"id":"DBAMetadataUtil :: _set_app_by_logic \\n[dba_metadata_utils.py : 478_486]->mcp_db_base.omc_client.get_apps","sourceNodeId":"DBAMetadataUtil :: _set_app_by_logic \\n[dba_metadata_utils.py : 478_486]","targetNodeId":"mcp_db_base.omc_client.get_apps"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-db-base/src/mcp_db_base/dba_metadata_utils.py"},"region":{"startLine":486,"startColumn":39,"endLine":486,"endColumn":53,"snippet":{}}}},"id":"DBAMetadataUtil :: _set_app_by_logic \\n[dba_metadata_utils.py : 478_486]->mcp_db_base.omc_client.get_apps(var app_name:any=db_metadata.app_name, var site:any=db_metadata.site, var env:any=db_metadata.env).get","sourceNodeId":"DBAMetadataUtil :: _set_app_by_logic \\n[dba_metadata_utils.py : 478_486]","targetNodeId":"mcp_db_base.omc_client.get_apps(var app_name:any=db_metadata.app_name, var site:any=db_metadata.site, var env:any=db_metadata.env).get"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-db-base/src/mcp_db_base/dba_metadata_utils.py"},"region":{"startLine":404,"startColumn":39,"endLine":404,"endColumn":52,"snippet":{}}}},"id":"DBAMetadataUtil :: fill_table_info \\n[dba_metadata_utils.py : 383_476]->get","sourceNodeId":"DBAMetadataUtil :: fill_table_info \\n[dba_metadata_utils.py : 383_476]","targetNodeId":"get"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-db-base/src/mcp_db_base/dba_metadata_utils.py"},"region":{"startLine":460,"startColumn":35,"endLine":462,"endColumn":22,"snippet":{}}}},"id":"DBAMetadataUtil :: fill_table_info \\n[dba_metadata_utils.py : 383_476]->mcp_db_base.omc_client.get_logic_tables","sourceNodeId":"DBAMetadataUtil :: fill_table_info \\n[dba_metadata_utils.py : 383_476]","targetNodeId":"mcp_db_base.omc_client.get_logic_tables"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-db-base/src/mcp_db_base/dba_metadata_utils.py"},"region":{"startLine":417,"startColumn":39,"endLine":417,"endColumn":60,"snippet":{}}}},"id":"DBAMetadataUtil :: fill_table_info \\n[dba_metadata_utils.py : 383_476]->mcp_db_base.omc_client.get_logic_tables(var table:any=table_info).get","sourceNodeId":"DBAMetadataUtil :: fill_table_info \\n[dba_metadata_utils.py : 383_476]","targetNodeId":"mcp_db_base.omc_client.get_logic_tables(var table:any=table_info).get"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-db-base/src/mcp_db_base/dba_metadata_utils.py"},"region":{"startLine":427,"startColumn":43,"endLine":427,"endColumn":89,"snippet":{}}}},"id":"DBAMetadataUtil :: fill_table_info \\n[dba_metadata_utils.py : 383_476]->mcp_db_base.omc_client.get_name_by_arn","sourceNodeId":"DBAMetadataUtil :: fill_table_info \\n[dba_metadata_utils.py : 383_476]","targetNodeId":"mcp_db_base.omc_client.get_name_by_arn"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-db-base/src/mcp_db_base/dba_metadata_utils.py"},"region":{"startLine":475,"startColumn":25,"endLine":475,"endColumn":63,"snippet":{}}}},"id":"DBAMetadataUtil :: fill_table_info \\n[dba_metadata_utils.py : 383_476]->append","sourceNodeId":"DBAMetadataUtil :: fill_table_info \\n[dba_metadata_utils.py : 383_476]","targetNodeId":"append"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-db-base/src/mcp_db_base/dba_metadata_utils.py"},"region":{"startLine":469,"startColumn":35,"endLine":471,"endColumn":22,"snippet":{}}}},"id":"DBAMetadataUtil :: fill_table_info \\n[dba_metadata_utils.py : 383_476]->mcp_db_base.omc_client.get_tables","sourceNodeId":"DBAMetadataUtil :: fill_table_info \\n[dba_metadata_utils.py : 383_476]","targetNodeId":"mcp_db_base.omc_client.get_tables"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-db-base/src/mcp_db_base/dba_metadata_utils.py"},"region":{"startLine":433,"startColumn":39,"endLine":433,"endColumn":60,"snippet":{}}}},"id":"DBAMetadataUtil :: fill_table_info \\n[dba_metadata_utils.py : 383_476]->mcp_db_base.omc_client.get_tables(var table:any=table_info).get","sourceNodeId":"DBAMetadataUtil :: fill_table_info \\n[dba_metadata_utils.py : 383_476]","targetNodeId":"mcp_db_base.omc_client.get_tables(var table:any=table_info).get"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-db-base/src/mcp_db_base/dba_metadata_utils.py"},"region":{"startLine":441,"startColumn":41,"endLine":441,"endColumn":85,"snippet":{}}}},"id":"DBAMetadataUtil :: fill_table_info \\n[dba_metadata_utils.py : 383_476]->DBAMetadataUtil :: fill_db_info \\n[dba_metadata_utils.py : 110_205]","sourceNodeId":"DBAMetadataUtil :: fill_table_info \\n[dba_metadata_utils.py : 383_476]","targetNodeId":"DBAMetadataUtil :: fill_db_info \\n[dba_metadata_utils.py : 110_205]"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-db-base/src/mcp_db_base/dba_metadata_utils.py"},"region":{"startLine":178,"startColumn":29,"endLine":178,"endColumn":78,"snippet":{}}}},"id":"DBAMetadataUtil :: fill_db_info \\n[dba_metadata_utils.py : 110_205]->mcp_db_base.omc_client.get_logic_dbs","sourceNodeId":"DBAMetadataUtil :: fill_db_info \\n[dba_metadata_utils.py : 110_205]","targetNodeId":"mcp_db_base.omc_client.get_logic_dbs"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-db-base/src/mcp_db_base/dba_metadata_utils.py"},"region":{"startLine":202,"startColumn":39,"endLine":204,"endColumn":26,"snippet":{}}}},"id":"DBAMetadataUtil :: fill_db_info \\n[dba_metadata_utils.py : 110_205]->DBAMetadataUtil :: _get_physics_db_info \\n[dba_metadata_utils.py : 488_500]","sourceNodeId":"DBAMetadataUtil :: fill_db_info \\n[dba_metadata_utils.py : 110_205]","targetNodeId":"DBAMetadataUtil :: _get_physics_db_info \\n[dba_metadata_utils.py : 488_500]"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-db-base/src/mcp_db_base/dba_metadata_utils.py"},"region":{"startLine":491,"startColumn":21,"endLine":491,"endColumn":40,"snippet":{}}}},"id":"DBAMetadataUtil :: _get_physics_db_info \\n[dba_metadata_utils.py : 488_500]->mcp_db_base.omc_client.get_logic_dbs(var arn:any=db_arn).get","sourceNodeId":"DBAMetadataUtil :: _get_physics_db_info \\n[dba_metadata_utils.py : 488_500]","targetNodeId":"mcp_db_base.omc_client.get_logic_dbs(var arn:any=db_arn).get"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-db-base/src/mcp_db_base/dba_metadata_utils.py"},"region":{"startLine":192,"startColumn":42,"endLine":192,"endColumn":81,"snippet":{}}}},"id":"DBAMetadataUtil :: fill_db_info \\n[dba_metadata_utils.py : 110_205]->DBAMetadataUtil :: _filter_physic_dbs \\n[dba_metadata_utils.py : 207_221]","sourceNodeId":"DBAMetadataUtil :: fill_db_info \\n[dba_metadata_utils.py : 110_205]","targetNodeId":"DBAMetadataUtil :: _filter_physic_dbs \\n[dba_metadata_utils.py : 207_221]"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-db-base/src/mcp_db_base/dba_metadata_utils.py"},"region":{"startLine":214,"startColumn":34,"endLine":214,"endColumn":59,"snippet":{}}}},"id":"DBAMetadataUtil :: _filter_physic_dbs \\n[dba_metadata_utils.py : 207_221]->mcp_db_base.omc_client.get_dbs(var db:any=logic_arn).get","sourceNodeId":"DBAMetadataUtil :: _filter_physic_dbs \\n[dba_metadata_utils.py : 207_221]","targetNodeId":"mcp_db_base.omc_client.get_dbs(var db:any=logic_arn).get"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-db-base/src/mcp_db_base/dba_metadata_utils.py"},"region":{"startLine":214,"startColumn":34,"endLine":214,"endColumn":59,"snippet":{}}}},"id":"DBAMetadataUtil :: _filter_physic_dbs \\n[dba_metadata_utils.py : 207_221]->get","sourceNodeId":"DBAMetadataUtil :: _filter_physic_dbs \\n[dba_metadata_utils.py : 207_221]","targetNodeId":"get"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-db-base/src/mcp_db_base/dba_metadata_utils.py"},"region":{"startLine":214,"startColumn":34,"endLine":214,"endColumn":59,"snippet":{}}}},"id":"DBAMetadataUtil :: _filter_physic_dbs \\n[dba_metadata_utils.py : 207_221]->....get","sourceNodeId":"DBAMetadataUtil :: _filter_physic_dbs \\n[dba_metadata_utils.py : 207_221]","targetNodeId":"....get"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-db-base/src/mcp_db_base/dba_metadata_utils.py"},"region":{"startLine":216,"startColumn":24,"endLine":216,"endColumn":57,"snippet":{}}}},"id":"DBAMetadataUtil :: _filter_physic_dbs \\n[dba_metadata_utils.py : 207_221]->mcp_db_base.omc_client.get_dbs(var db:any=logic_arn).get(tenantArn, ...).find","sourceNodeId":"DBAMetadataUtil :: _filter_physic_dbs \\n[dba_metadata_utils.py : 207_221]","targetNodeId":"mcp_db_base.omc_client.get_dbs(var db:any=logic_arn).get(tenantArn, ...).find"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-db-base/src/mcp_db_base/dba_metadata_utils.py"},"region":{"startLine":216,"startColumn":24,"endLine":216,"endColumn":57,"snippet":{}}}},"id":"DBAMetadataUtil :: _filter_physic_dbs \\n[dba_metadata_utils.py : 207_221]->get(tenantArn, ...).find","sourceNodeId":"DBAMetadataUtil :: _filter_physic_dbs \\n[dba_metadata_utils.py : 207_221]","targetNodeId":"get(tenantArn, ...).find"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-db-base/src/mcp_db_base/dba_metadata_utils.py"},"region":{"startLine":216,"startColumn":24,"endLine":216,"endColumn":57,"snippet":{}}}},"id":"DBAMetadataUtil :: _filter_physic_dbs \\n[dba_metadata_utils.py : 207_221]->....get(tenantArn, ...).find","sourceNodeId":"DBAMetadataUtil :: _filter_physic_dbs \\n[dba_metadata_utils.py : 207_221]","targetNodeId":"....get(tenantArn, ...).find"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-db-base/src/mcp_db_base/dba_metadata_utils.py"},"region":{"startLine":194,"startColumn":25,"endLine":194,"endColumn":93,"snippet":{}}}},"id":"DBAMetadataUtil :: fill_db_info \\n[dba_metadata_utils.py : 110_205]->DBAMetadataUtil :: _add_confirm_pyhsic_dbs \\n[dba_metadata_utils.py : 91_108]","sourceNodeId":"DBAMetadataUtil :: fill_db_info \\n[dba_metadata_utils.py : 110_205]","targetNodeId":"DBAMetadataUtil :: _add_confirm_pyhsic_dbs \\n[dba_metadata_utils.py : 91_108]"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-db-base/src/mcp_db_base/dba_metadata_utils.py"},"region":{"startLine":107,"startColumn":31,"endLine":107,"endColumn":44,"snippet":{}}}},"id":"DBAMetadataUtil :: _add_confirm_pyhsic_dbs \\n[dba_metadata_utils.py : 91_108]->....get","sourceNodeId":"DBAMetadataUtil :: _add_confirm_pyhsic_dbs \\n[dba_metadata_utils.py : 91_108]","targetNodeId":"....get"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-db-base/src/mcp_db_base/dba_metadata_utils.py"},"region":{"startLine":107,"startColumn":31,"endLine":107,"endColumn":44,"snippet":{}}}},"id":"DBAMetadataUtil :: _add_confirm_pyhsic_dbs \\n[dba_metadata_utils.py : 91_108]->mcp_db_base.omc_client.get_dbs(var db:any=logic_arn).get","sourceNodeId":"DBAMetadataUtil :: _add_confirm_pyhsic_dbs \\n[dba_metadata_utils.py : 91_108]","targetNodeId":"mcp_db_base.omc_client.get_dbs(var db:any=logic_arn).get"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-db-base/src/mcp_db_base/dba_metadata_utils.py"},"region":{"startLine":107,"startColumn":31,"endLine":107,"endColumn":44,"snippet":{}}}},"id":"DBAMetadataUtil :: _add_confirm_pyhsic_dbs \\n[dba_metadata_utils.py : 91_108]->get","sourceNodeId":"DBAMetadataUtil :: _add_confirm_pyhsic_dbs \\n[dba_metadata_utils.py : 91_108]","targetNodeId":"get"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-db-base/src/mcp_db_base/dba_metadata_utils.py"},"region":{"startLine":99,"startColumn":43,"endLine":99,"endColumn":76,"snippet":{}}}},"id":"DBAMetadataUtil :: _add_confirm_pyhsic_dbs \\n[dba_metadata_utils.py : 91_108]->....get(tenantArn).split","sourceNodeId":"DBAMetadataUtil :: _add_confirm_pyhsic_dbs \\n[dba_metadata_utils.py : 91_108]","targetNodeId":"....get(tenantArn).split"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-db-base/src/mcp_db_base/dba_metadata_utils.py"},"region":{"startLine":99,"startColumn":43,"endLine":99,"endColumn":76,"snippet":{}}}},"id":"DBAMetadataUtil :: _add_confirm_pyhsic_dbs \\n[dba_metadata_utils.py : 91_108]->mcp_db_base.omc_client.get_dbs(var db:any=logic_arn).get(tenantArn).split","sourceNodeId":"DBAMetadataUtil :: _add_confirm_pyhsic_dbs \\n[dba_metadata_utils.py : 91_108]","targetNodeId":"mcp_db_base.omc_client.get_dbs(var db:any=logic_arn).get(tenantArn).split"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-db-base/src/mcp_db_base/dba_metadata_utils.py"},"region":{"startLine":99,"startColumn":43,"endLine":99,"endColumn":76,"snippet":{}}}},"id":"DBAMetadataUtil :: _add_confirm_pyhsic_dbs \\n[dba_metadata_utils.py : 91_108]->get(tenantArn).split","sourceNodeId":"DBAMetadataUtil :: _add_confirm_pyhsic_dbs \\n[dba_metadata_utils.py : 91_108]","targetNodeId":"get(tenantArn).split"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-db-base/src/mcp_db_base/dba_metadata_utils.py"},"region":{"startLine":100,"startColumn":45,"endLine":102,"endColumn":18,"snippet":{}}}},"id":"DBAMetadataUtil :: _add_confirm_pyhsic_dbs \\n[dba_metadata_utils.py : 91_108]->DBAMetadataUtil :: _fill_db_cluster \\n[dba_metadata_utils.py : 502_511]","sourceNodeId":"DBAMetadataUtil :: _add_confirm_pyhsic_dbs \\n[dba_metadata_utils.py : 91_108]","targetNodeId":"DBAMetadataUtil :: _fill_db_cluster \\n[dba_metadata_utils.py : 502_511]"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-db-base/src/mcp_db_base/dba_metadata_utils.py"},"region":{"startLine":188,"startColumn":29,"endLine":188,"endColumn":67,"snippet":{}}}},"id":"DBAMetadataUtil :: fill_db_info \\n[dba_metadata_utils.py : 110_205]->extend","sourceNodeId":"DBAMetadataUtil :: fill_db_info \\n[dba_metadata_utils.py : 110_205]","targetNodeId":"extend"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-db-base/src/mcp_db_base/dba_metadata_utils.py"},"region":{"startLine":191,"startColumn":27,"endLine":191,"endColumn":73,"snippet":{}}}},"id":"DBAMetadataUtil :: fill_db_info \\n[dba_metadata_utils.py : 110_205]->mcp_db_base.omc_client.get_dbs","sourceNodeId":"DBAMetadataUtil :: fill_db_info \\n[dba_metadata_utils.py : 110_205]","targetNodeId":"mcp_db_base.omc_client.get_dbs"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-db-base/src/mcp_db_base/dba_metadata_utils.py"},"region":{"startLine":214,"startColumn":34,"endLine":214,"endColumn":59,"snippet":{}}}},"id":"DBAMetadataUtil :: _filter_physic_dbs \\n[dba_metadata_utils.py : 207_221]->mcp_db_base.omc_client.get_dbs(var db:any=db_arn).get","sourceNodeId":"DBAMetadataUtil :: _filter_physic_dbs \\n[dba_metadata_utils.py : 207_221]","targetNodeId":"mcp_db_base.omc_client.get_dbs(var db:any=db_arn).get"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-db-base/src/mcp_db_base/dba_metadata_utils.py"},"region":{"startLine":216,"startColumn":24,"endLine":216,"endColumn":57,"snippet":{}}}},"id":"DBAMetadataUtil :: _filter_physic_dbs \\n[dba_metadata_utils.py : 207_221]->mcp_db_base.omc_client.get_dbs(var db:any=db_arn).get(tenantArn, ...).find","sourceNodeId":"DBAMetadataUtil :: _filter_physic_dbs \\n[dba_metadata_utils.py : 207_221]","targetNodeId":"mcp_db_base.omc_client.get_dbs(var db:any=db_arn).get(tenantArn, ...).find"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-db-base/src/mcp_db_base/dba_metadata_utils.py"},"region":{"startLine":107,"startColumn":31,"endLine":107,"endColumn":44,"snippet":{}}}},"id":"DBAMetadataUtil :: _add_confirm_pyhsic_dbs \\n[dba_metadata_utils.py : 91_108]->mcp_db_base.omc_client.get_dbs(var db:any=db_arn).get","sourceNodeId":"DBAMetadataUtil :: _add_confirm_pyhsic_dbs \\n[dba_metadata_utils.py : 91_108]","targetNodeId":"mcp_db_base.omc_client.get_dbs(var db:any=db_arn).get"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-db-base/src/mcp_db_base/dba_metadata_utils.py"},"region":{"startLine":99,"startColumn":43,"endLine":99,"endColumn":76,"snippet":{}}}},"id":"DBAMetadataUtil :: _add_confirm_pyhsic_dbs \\n[dba_metadata_utils.py : 91_108]->mcp_db_base.omc_client.get_dbs(var db:any=db_arn).get(tenantArn).split","sourceNodeId":"DBAMetadataUtil :: _add_confirm_pyhsic_dbs \\n[dba_metadata_utils.py : 91_108]","targetNodeId":"mcp_db_base.omc_client.get_dbs(var db:any=db_arn).get(tenantArn).split"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-db-base/src/mcp_db_base/dba_metadata_utils.py"},"region":{"startLine":108,"startColumn":13,"endLine":108,"endColumn":45,"snippet":{}}}},"id":"DBAMetadataUtil :: _add_confirm_pyhsic_dbs \\n[dba_metadata_utils.py : 91_108]->db_metadatas.append","sourceNodeId":"DBAMetadataUtil :: _add_confirm_pyhsic_dbs \\n[dba_metadata_utils.py : 91_108]","targetNodeId":"db_metadatas.append"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-db-base/src/mcp_db_base/dba_metadata_utils.py"},"region":{"startLine":195,"startColumn":25,"endLine":195,"endColumn":63,"snippet":{}}}},"id":"DBAMetadataUtil :: fill_db_info \\n[dba_metadata_utils.py : 110_205]->physics_dbs.extend","sourceNodeId":"DBAMetadataUtil :: fill_db_info \\n[dba_metadata_utils.py : 110_205]","targetNodeId":"physics_dbs.extend"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-db-base/src/mcp_db_base/dba_metadata_utils.py"},"region":{"startLine":137,"startColumn":23,"endLine":139,"endColumn":18,"snippet":{}}}},"id":"DBAMetadataUtil :: fill_db_info \\n[dba_metadata_utils.py : 110_205]->mcp_db_base.omc_client.get_db_by_search_name","sourceNodeId":"DBAMetadataUtil :: fill_db_info \\n[dba_metadata_utils.py : 110_205]","targetNodeId":"mcp_db_base.omc_client.get_db_by_search_name"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-db-base/src/mcp_db_base/dba_metadata_utils.py"},"region":{"startLine":201,"startColumn":25,"endLine":201,"endColumn":73,"snippet":{}}}},"id":"DBAMetadataUtil :: fill_db_info \\n[dba_metadata_utils.py : 110_205]->DBAMetadataUtil :: _set_app_by_logic \\n[dba_metadata_utils.py : 478_486]","sourceNodeId":"DBAMetadataUtil :: fill_db_info \\n[dba_metadata_utils.py : 110_205]","targetNodeId":"DBAMetadataUtil :: _set_app_by_logic \\n[dba_metadata_utils.py : 478_486]"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-db-base/src/mcp_db_base/dba_metadata_utils.py"},"region":{"startLine":481,"startColumn":32,"endLine":481,"endColumn":55,"snippet":{}}}},"id":"DBAMetadataUtil :: _set_app_by_logic \\n[dba_metadata_utils.py : 478_486]->mcp_db_base.omc_client.get_db_by_search_name(var is_logic:any=is_logic, var search_name:any=%+searchName+%, var site:any=db_target.site, var env:any=db_target.env).get","sourceNodeId":"DBAMetadataUtil :: _set_app_by_logic \\n[dba_metadata_utils.py : 478_486]","targetNodeId":"mcp_db_base.omc_client.get_db_by_search_name(var is_logic:any=is_logic, var search_name:any=%+searchName+%, var site:any=db_target.site, var env:any=db_target.env).get"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-db-base/src/mcp_db_base/dba_metadata_utils.py"},"region":{"startLine":174,"startColumn":39,"endLine":174,"endColumn":52,"snippet":{}}}},"id":"DBAMetadataUtil :: fill_db_info \\n[dba_metadata_utils.py : 110_205]->get","sourceNodeId":"DBAMetadataUtil :: fill_db_info \\n[dba_metadata_utils.py : 110_205]","targetNodeId":"get"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-db-base/src/mcp_db_base/dba_metadata_utils.py"},"region":{"startLine":155,"startColumn":42,"endLine":155,"endColumn":56,"snippet":{}}}},"id":"DBAMetadataUtil :: fill_db_info \\n[dba_metadata_utils.py : 110_205]->/src/mcp-db-base/src/mcp_db_base/dba_metadata_utils.DBAMetadataUtil.fill_db_info.fill_db_info_scope.........mcp_db_base.omc_client.get_logic_dbs(var arn:any=logic_db_arn).get","sourceNodeId":"DBAMetadataUtil :: _set_app_by_logic \\n[dba_metadata_utils.py : 478_486]","targetNodeId":"mcp_db_base.omc_client.get_logic_dbs(var arn:any=logic_db_arn).get"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-db-base/src/mcp_db_base/dba_metadata_utils.py"},"region":{"startLine":162,"startColumn":55,"endLine":162,"endColumn":88,"snippet":{}}}},"id":"DBAMetadataUtil :: fill_db_info \\n[dba_metadata_utils.py : 110_205]->tenant_arn.split","sourceNodeId":"DBAMetadataUtil :: fill_db_info \\n[dba_metadata_utils.py : 110_205]","targetNodeId":"tenant_arn.split"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-db-base/src/mcp_db_base/dba_metadata_utils.py"},"region":{"startLine":164,"startColumn":57,"endLine":166,"endColumn":30,"snippet":{}}}},"id":"DBAMetadataUtil :: fill_db_info \\n[dba_metadata_utils.py : 110_205]->DBAMetadataUtil :: _fill_db_cluster \\n[dba_metadata_utils.py : 502_511]","sourceNodeId":"DBAMetadataUtil :: fill_db_info \\n[dba_metadata_utils.py : 110_205]","targetNodeId":"DBAMetadataUtil :: _fill_db_cluster \\n[dba_metadata_utils.py : 502_511]"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-db-base/src/mcp_db_base/dba_metadata_utils.py"},"region":{"startLine":175,"startColumn":21,"endLine":175,"endColumn":53,"snippet":{}}}},"id":"DBAMetadataUtil :: fill_db_info \\n[dba_metadata_utils.py : 110_205]->db_metadatas.append","sourceNodeId":"DBAMetadataUtil :: fill_db_info \\n[dba_metadata_utils.py : 110_205]","targetNodeId":"db_metadatas.append"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-db-base/src/mcp_db_base/dba_metadata_utils.py"},"region":{"startLine":199,"startColumn":38,"endLine":199,"endColumn":52,"snippet":{}}}},"id":"DBAMetadataUtil :: fill_db_info \\n[dba_metadata_utils.py : 110_205]->/src/mcp-db-base/src/mcp_db_base/dba_metadata_utils.DBAMetadataUtil.fill_db_info.fill_db_info_scope.........mcp_db_base.omc_client.get_logic_dbs(db_name, var site:any=db_target.site).get","sourceNodeId":"DBAMetadataUtil :: fill_db_info \\n[dba_metadata_utils.py : 110_205]","targetNodeId":"mcp_db_base.omc_client.get_logic_dbs(db_name, var site:any=db_target.site).get"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-db-base/src/mcp_db_base/dba_metadata_utils.py"},"region":{"startLine":491,"startColumn":21,"endLine":491,"endColumn":40,"snippet":{}}}},"id":"DBAMetadataUtil :: _get_physics_db_info \\n[dba_metadata_utils.py : 488_500]->mcp_db_base.omc_client.get_logic_dbs(db_name, var site:any=db_target.site).get","sourceNodeId":"DBAMetadataUtil :: _get_physics_db_info \\n[dba_metadata_utils.py : 488_500]","targetNodeId":"mcp_db_base.omc_client.get_logic_dbs(db_name, var site:any=db_target.site).get"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-db-base/src/mcp_db_base/dba_metadata_utils.py"},"region":{"startLine":214,"startColumn":34,"endLine":214,"endColumn":59,"snippet":{}}}},"id":"DBAMetadataUtil :: _filter_physic_dbs \\n[dba_metadata_utils.py : 207_221]->mcp_db_base.omc_client.get_dbs(var db:any=db_name, var site:any=db_target.site).get","sourceNodeId":"DBAMetadataUtil :: _filter_physic_dbs \\n[dba_metadata_utils.py : 207_221]","targetNodeId":"mcp_db_base.omc_client.get_dbs(var db:any=db_name, var site:any=db_target.site).get"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-db-base/src/mcp_db_base/dba_metadata_utils.py"},"region":{"startLine":216,"startColumn":24,"endLine":216,"endColumn":57,"snippet":{}}}},"id":"DBAMetadataUtil :: _filter_physic_dbs \\n[dba_metadata_utils.py : 207_221]->mcp_db_base.omc_client.get_dbs(var db:any=db_name, var site:any=db_target.site).get(tenantArn, ...).find","sourceNodeId":"DBAMetadataUtil :: _filter_physic_dbs \\n[dba_metadata_utils.py : 207_221]","targetNodeId":"mcp_db_base.omc_client.get_dbs(var db:any=db_name, var site:any=db_target.site).get(tenantArn, ...).find"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-db-base/src/mcp_db_base/dba_metadata_utils.py"},"region":{"startLine":107,"startColumn":31,"endLine":107,"endColumn":44,"snippet":{}}}},"id":"DBAMetadataUtil :: _add_confirm_pyhsic_dbs \\n[dba_metadata_utils.py : 91_108]->mcp_db_base.omc_client.get_dbs(var db:any=db_name, var site:any=db_target.site).get","sourceNodeId":"DBAMetadataUtil :: _add_confirm_pyhsic_dbs \\n[dba_metadata_utils.py : 91_108]","targetNodeId":"mcp_db_base.omc_client.get_dbs(var db:any=db_name, var site:any=db_target.site).get"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-db-base/src/mcp_db_base/dba_metadata_utils.py"},"region":{"startLine":99,"startColumn":43,"endLine":99,"endColumn":76,"snippet":{}}}},"id":"DBAMetadataUtil :: _add_confirm_pyhsic_dbs \\n[dba_metadata_utils.py : 91_108]->mcp_db_base.omc_client.get_dbs(var db:any=db_name, var site:any=db_target.site).get(tenantArn).split","sourceNodeId":"DBAMetadataUtil :: _add_confirm_pyhsic_dbs \\n[dba_metadata_utils.py : 91_108]","targetNodeId":"mcp_db_base.omc_client.get_dbs(var db:any=db_name, var site:any=db_target.site).get(tenantArn).split"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-db-base/src/mcp_db_base/dba_metadata_utils.py"},"region":{"startLine":481,"startColumn":32,"endLine":481,"endColumn":55,"snippet":{}}}},"id":"DBAMetadataUtil :: _set_app_by_logic \\n[dba_metadata_utils.py : 478_486]->0.get","sourceNodeId":"DBAMetadataUtil :: _set_app_by_logic \\n[dba_metadata_utils.py : 478_486]","targetNodeId":"0.get"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-db-base/src/mcp_db_base/dba_metadata_utils.py"},"region":{"startLine":444,"startColumn":42,"endLine":444,"endColumn":55,"snippet":{}}}},"id":"DBAMetadataUtil :: fill_table_info \\n[dba_metadata_utils.py : 383_476]->/src/mcp-db-base/src/mcp_db_base/dba_metadata_utils.DBAMetadataUtil.fill_table_info.fill_table_info_scope.........mcp_db_base.omc_client.get_logic_tables(var db_arn:any=db_metadata.db_arn, var table:any=table_info).get","sourceNodeId":"DBAMetadataUtil :: fill_table_info \\n[dba_metadata_utils.py : 383_476]","targetNodeId":"mcp_db_base.omc_client.get_logic_tables(var db_arn:any=db_metadata.db_arn, var table:any=table_info).get"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-db-base/src/mcp_db_base/dba_metadata_utils.py"},"region":{"startLine":474,"startColumn":53,"endLine":474,"endColumn":75,"snippet":{}}}},"id":"DBAMetadataUtil :: fill_table_info \\n[dba_metadata_utils.py : 383_476]->mcp_db_base.omc_client.get_tables(var db_arn:any=db_metadata.db_arn, var table:any=table_info).get","sourceNodeId":"DBAMetadataUtil :: fill_table_info \\n[dba_metadata_utils.py : 383_476]","targetNodeId":"mcp_db_base.omc_client.get_tables(var db_arn:any=db_metadata.db_arn, var table:any=table_info).get"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-db-base/src/mcp_db_base/dba_metadata_utils.py"},"region":{"startLine":532,"startColumn":30,"endLine":532,"endColumn":79,"snippet":{}}}},"id":"get_db_meta \\n[dba_metadata_utils.py : 514_546]->DBAMetadataUtil :: fill_db_info \\n[dba_metadata_utils.py : 110_205]","sourceNodeId":"get_db_meta \\n[dba_metadata_utils.py : 514_546]","targetNodeId":"DBAMetadataUtil :: fill_db_info \\n[dba_metadata_utils.py : 110_205]"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-db-base/src/mcp_db_base/dba_metadata_utils.py"},"region":{"startLine":535,"startColumn":17,"endLine":535,"endColumn":70,"snippet":{}}}},"id":"get_db_meta \\n[dba_metadata_utils.py : 514_546]->DBAMetadataUtil :: fill_tenant_info \\n[dba_metadata_utils.py : 344_381]","sourceNodeId":"get_db_meta \\n[dba_metadata_utils.py : 514_546]","targetNodeId":"DBAMetadataUtil :: fill_tenant_info \\n[dba_metadata_utils.py : 344_381]"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-db-base/src/mcp_db_base/dba_metadata_utils.py"},"region":{"startLine":353,"startColumn":16,"endLine":353,"endColumn":35,"snippet":{}}}},"id":"DBAMetadataUtil :: fill_tenant_info \\n[dba_metadata_utils.py : 344_381]->is_arn \\n[dba_metadata_utils.py : 76_80]","sourceNodeId":"DBAMetadataUtil :: fill_tenant_info \\n[dba_metadata_utils.py : 344_381]","targetNodeId":"is_arn \\n[dba_metadata_utils.py : 76_80]"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-db-base/src/mcp_db_base/dba_metadata_utils.py"},"region":{"startLine":77,"startColumn":8,"endLine":77,"endColumn":41,"snippet":{}}}},"id":"is_arn \\n[dba_metadata_utils.py : 76_80]->....startswith","sourceNodeId":"is_arn \\n[dba_metadata_utils.py : 76_80]","targetNodeId":"....startswith"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-db-base/src/mcp_db_base/dba_metadata_utils.py"},"region":{"startLine":77,"startColumn":8,"endLine":77,"endColumn":41,"snippet":{}}}},"id":"is_arn \\n[dba_metadata_utils.py : 76_80]->db_target.tenant.startswith","sourceNodeId":"is_arn \\n[dba_metadata_utils.py : 76_80]","targetNodeId":"db_target.tenant.startswith"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-db-base/src/mcp_db_base/dba_metadata_utils.py"},"region":{"startLine":369,"startColumn":27,"endLine":369,"endColumn":68,"snippet":{}}}},"id":"DBAMetadataUtil :: fill_tenant_info \\n[dba_metadata_utils.py : 344_381]->mcp_db_base.omc_client.get_tenant_info","sourceNodeId":"DBAMetadataUtil :: fill_tenant_info \\n[dba_metadata_utils.py : 344_381]","targetNodeId":"mcp_db_base.omc_client.get_tenant_info"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-db-base/src/mcp_db_base/dba_metadata_utils.py"},"region":{"startLine":365,"startColumn":39,"endLine":365,"endColumn":56,"snippet":{}}}},"id":"DBAMetadataUtil :: fill_tenant_info \\n[dba_metadata_utils.py : 344_381]->mcp_db_base.omc_client.get_tenant_info(var tenant:any=arn).get","sourceNodeId":"DBAMetadataUtil :: fill_tenant_info \\n[dba_metadata_utils.py : 344_381]","targetNodeId":"mcp_db_base.omc_client.get_tenant_info(var tenant:any=arn).get"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-db-base/src/mcp_db_base/dba_metadata_utils.py"},"region":{"startLine":376,"startColumn":48,"endLine":376,"endColumn":76,"snippet":{}}}},"id":"DBAMetadataUtil :: fill_tenant_info \\n[dba_metadata_utils.py : 344_381]->mcp_db_base.omc_client.get_name_by_arn","sourceNodeId":"DBAMetadataUtil :: fill_tenant_info \\n[dba_metadata_utils.py : 344_381]","targetNodeId":"mcp_db_base.omc_client.get_name_by_arn"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-db-base/src/mcp_db_base/dba_metadata_utils.py"},"region":{"startLine":378,"startColumn":39,"endLine":378,"endColumn":56,"snippet":{}}}},"id":"DBAMetadataUtil :: fill_tenant_info \\n[dba_metadata_utils.py : 344_381]->mcp_db_base.omc_client.get_tenant_info(var tenant:any=tenant_name).get","sourceNodeId":"DBAMetadataUtil :: fill_tenant_info \\n[dba_metadata_utils.py : 344_381]","targetNodeId":"mcp_db_base.omc_client.get_tenant_info(var tenant:any=tenant_name).get"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-db-base/src/mcp_db_base/dba_metadata_utils.py"},"region":{"startLine":379,"startColumn":21,"endLine":379,"endColumn":53,"snippet":{}}}},"id":"DBAMetadataUtil :: fill_tenant_info \\n[dba_metadata_utils.py : 344_381]->db_metadatas.append","sourceNodeId":"DBAMetadataUtil :: fill_tenant_info \\n[dba_metadata_utils.py : 344_381]","targetNodeId":"db_metadatas.append"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-db-base/src/mcp_db_base/dba_metadata_utils.py"},"region":{"startLine":538,"startColumn":17,"endLine":538,"endColumn":71,"snippet":{}}}},"id":"get_db_meta \\n[dba_metadata_utils.py : 514_546]->DBAMetadataUtil :: fill_cluster_info \\n[dba_metadata_utils.py : 314_342]","sourceNodeId":"get_db_meta \\n[dba_metadata_utils.py : 514_546]","targetNodeId":"DBAMetadataUtil :: fill_cluster_info \\n[dba_metadata_utils.py : 314_342]"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-db-base/src/mcp_db_base/dba_metadata_utils.py"},"region":{"startLine":323,"startColumn":16,"endLine":323,"endColumn":36,"snippet":{}}}},"id":"DBAMetadataUtil :: fill_cluster_info \\n[dba_metadata_utils.py : 314_342]->is_arn \\n[dba_metadata_utils.py : 76_80]","sourceNodeId":"DBAMetadataUtil :: fill_cluster_info \\n[dba_metadata_utils.py : 314_342]","targetNodeId":"is_arn \\n[dba_metadata_utils.py : 76_80]"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-db-base/src/mcp_db_base/dba_metadata_utils.py"},"region":{"startLine":77,"startColumn":8,"endLine":77,"endColumn":41,"snippet":{}}}},"id":"is_arn \\n[dba_metadata_utils.py : 76_80]->db_slot.cluster.startswith","sourceNodeId":"is_arn \\n[dba_metadata_utils.py : 76_80]","targetNodeId":"db_slot.cluster.startswith"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-db-base/src/mcp_db_base/dba_metadata_utils.py"},"region":{"startLine":324,"startColumn":27,"endLine":324,"endColumn":66,"snippet":{}}}},"id":"DBAMetadataUtil :: fill_cluster_info \\n[dba_metadata_utils.py : 314_342]->mcp_db_base.omc_client.get_cluster_info_v2","sourceNodeId":"DBAMetadataUtil :: fill_cluster_info \\n[dba_metadata_utils.py : 314_342]","targetNodeId":"mcp_db_base.omc_client.get_cluster_info_v2"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-db-base/src/mcp_db_base/dba_metadata_utils.py"},"region":{"startLine":329,"startColumn":35,"endLine":329,"endColumn":53,"snippet":{}}}},"id":"DBAMetadataUtil :: fill_cluster_info \\n[dba_metadata_utils.py : 314_342]->mcp_db_base.omc_client.get_cluster_info_v2(cluster_info).get","sourceNodeId":"DBAMetadataUtil :: fill_cluster_info \\n[dba_metadata_utils.py : 314_342]","targetNodeId":"mcp_db_base.omc_client.get_cluster_info_v2(cluster_info).get"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-db-base/src/mcp_db_base/dba_metadata_utils.py"},"region":{"startLine":334,"startColumn":28,"endLine":334,"endColumn":64,"snippet":{}}}},"id":"DBAMetadataUtil :: fill_cluster_info \\n[dba_metadata_utils.py : 314_342]->mcp_db_base.omc_client.get_cluster_info","sourceNodeId":"DBAMetadataUtil :: fill_cluster_info \\n[dba_metadata_utils.py : 314_342]","targetNodeId":"mcp_db_base.omc_client.get_cluster_info"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-db-base/src/mcp_db_base/dba_metadata_utils.py"},"region":{"startLine":340,"startColumn":44,"endLine":340,"endColumn":62,"snippet":{}}}},"id":"DBAMetadataUtil :: fill_cluster_info \\n[dba_metadata_utils.py : 314_342]->mcp_db_base.omc_client.get_cluster_info(cluster_name).get","sourceNodeId":"DBAMetadataUtil :: fill_cluster_info \\n[dba_metadata_utils.py : 314_342]","targetNodeId":"mcp_db_base.omc_client.get_cluster_info(cluster_name).get"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-db-base/src/mcp_db_base/dba_metadata_utils.py"},"region":{"startLine":569,"startColumn":5,"endLine":569,"endColumn":19,"snippet":{}}}},"id":"<__entry_point__>->/src/mcp-db-base/src/mcp_db_base/dba_metadata_utils..print","sourceNodeId":"<__entry_point__>","targetNodeId":"/src/mcp-db-base/src/mcp_db_base/dba_metadata_utils..print"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-db-base/src/mcp_db_base/maas_sql_client.py"},"region":{"startLine":396,"startColumn":9,"endLine":397,"endColumn":54,"snippet":{}}}},"id":"<__entry_point__>->get_single_metric \\n[maas_sql_client.py : 190_196]","sourceNodeId":"<__entry_point__>","targetNodeId":"get_single_metric \\n[maas_sql_client.py : 190_196]"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-db-base/src/mcp_db_base/maas_sql_client.py"},"region":{"startLine":194,"startColumn":69,"endLine":194,"endColumn":111,"snippet":{}}}},"id":"get_single_metric \\n[maas_sql_client.py : 190_196]->ob@@vm_system@@node@@DEFAULT@@1@@DEFAULT.where_condition.format","sourceNodeId":"get_single_metric \\n[maas_sql_client.py : 190_196]","targetNodeId":"ob@@vm_system@@node@@DEFAULT@@1@@DEFAULT.where_condition.format"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-db-base/src/mcp_db_base/maas_sql_client.py"},"region":{"startLine":194,"startColumn":69,"endLine":194,"endColumn":111,"snippet":{}}}},"id":"get_single_metric \\n[maas_sql_client.py : 190_196]->`node` = \\'{node}\\'.where_condition.format","sourceNodeId":"get_single_metric \\n[maas_sql_client.py : 190_196]","targetNodeId":"`node` = \\'{node}\\'.where_condition.format"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-db-base/src/mcp_db_base/maas_sql_client.py"},"region":{"startLine":193,"startColumn":14,"endLine":195,"endColumn":9,"snippet":{}}}},"id":"get_single_metric \\n[maas_sql_client.py : 190_196]->get_maas_sql_data \\n[maas_sql_client.py : 155_177]","sourceNodeId":"get_single_metric \\n[maas_sql_client.py : 190_196]","targetNodeId":"get_maas_sql_data \\n[maas_sql_client.py : 155_177]"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-db-base/src/mcp_db_base/maas_sql_client.py"},"region":{"startLine":164,"startColumn":15,"endLine":164,"endColumn":45,"snippet":{}}}},"id":"get_maas_sql_data \\n[maas_sql_client.py : 155_177]->replace_seconds_with_zero \\n[maas_sql_client.py : 218_230]","sourceNodeId":"get_maas_sql_data \\n[maas_sql_client.py : 155_177]","targetNodeId":"replace_seconds_with_zero \\n[maas_sql_client.py : 218_230]"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-db-base/src/mcp_db_base/maas_sql_client.py"},"region":{"startLine":229,"startColumn":20,"endLine":229,"endColumn":54,"snippet":{}}}},"id":"replace_seconds_with_zero \\n[maas_sql_client.py : 218_230]->syslib_from.re.sub","sourceNodeId":"replace_seconds_with_zero \\n[maas_sql_client.py : 218_230]","targetNodeId":"syslib_from.re.sub"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-db-base/src/mcp_db_base/maas_sql_client.py"},"region":{"startLine":229,"startColumn":20,"endLine":229,"endColumn":54,"snippet":{}}}},"id":"syslib_from.re.sub->replace_func \\n[maas_sql_client.py : 224_225]","sourceNodeId":"syslib_from.re.sub","targetNodeId":"replace_func \\n[maas_sql_client.py : 224_225]"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-db-base/src/mcp_db_base/maas_sql_client.py"},"region":{"startLine":225,"startColumn":16,"endLine":225,"endColumn":30,"snippet":{}}}},"id":"replace_func \\n[maas_sql_client.py : 224_225]->match.group","sourceNodeId":"replace_func \\n[maas_sql_client.py : 224_225]","targetNodeId":"match.group"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-db-base/src/mcp_db_base/maas_sql_client.py"},"region":{"startLine":173,"startColumn":76,"endLine":173,"endColumn":86,"snippet":{}}}},"id":"get_maas_sql_data \\n[maas_sql_client.py : 155_177]->_headers \\n[maas_sql_client.py : 62_85]","sourceNodeId":"get_maas_sql_data \\n[maas_sql_client.py : 155_177]","targetNodeId":"_headers \\n[maas_sql_client.py : 62_85]"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-db-base/src/mcp_db_base/maas_sql_client.py"},"region":{"startLine":64,"startColumn":19,"endLine":64,"endColumn":44,"snippet":{}}}},"id":"_headers \\n[maas_sql_client.py : 62_85]->syslib_from.os.environ.get","sourceNodeId":"_headers \\n[maas_sql_client.py : 62_85]","targetNodeId":"syslib_from.os.environ.get"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-db-base/src/mcp_db_base/maas_sql_client.py"},"region":{"startLine":65,"startColumn":5,"endLine":65,"endColumn":41,"snippet":{}}}},"id":"_headers \\n[maas_sql_client.py : 62_85]->syslib_from.logging.getLogger(__name__).info","sourceNodeId":"_headers \\n[maas_sql_client.py : 62_85]","targetNodeId":"syslib_from.logging.getLogger(__name__).info"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-db-base/src/mcp_db_base/maas_sql_client.py"},"region":{"startLine":66,"startColumn":25,"endLine":66,"endColumn":36,"snippet":{}}}},"id":"_headers \\n[maas_sql_client.py : 62_85]->syslib_from.time.time","sourceNodeId":"_headers \\n[maas_sql_client.py : 62_85]","targetNodeId":"syslib_from.time.time"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-db-base/src/mcp_db_base/maas_sql_client.py"},"region":{"startLine":66,"startColumn":21,"endLine":66,"endColumn":37,"snippet":{}}}},"id":"_headers \\n[maas_sql_client.py : 62_85]->/src/mcp-db-base/src/mcp_db_base/maas_sql_client._headers._headers_scope..int","sourceNodeId":"_headers \\n[maas_sql_client.py : 62_85]","targetNodeId":"/src/mcp-db-base/src/mcp_db_base/maas_sql_client._headers._headers_scope..int"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-db-base/src/mcp_db_base/maas_sql_client.py"},"region":{"startLine":67,"startColumn":24,"endLine":67,"endColumn":55,"snippet":{}}}},"id":"_headers \\n[maas_sql_client.py : 62_85]->syslib_from.random.sample","sourceNodeId":"_headers \\n[maas_sql_client.py : 62_85]","targetNodeId":"syslib_from.random.sample"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-db-base/src/mcp_db_base/maas_sql_client.py"},"region":{"startLine":67,"startColumn":16,"endLine":67,"endColumn":56,"snippet":{}}}},"id":"_headers \\n[maas_sql_client.py : 62_85]->join","sourceNodeId":"_headers \\n[maas_sql_client.py : 62_85]","targetNodeId":"join"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-db-base/src/mcp_db_base/maas_sql_client.py"},"region":{"startLine":80,"startColumn":29,"endLine":80,"endColumn":47,"snippet":{}}}},"id":"_headers \\n[maas_sql_client.py : 62_85]->/src/mcp-db-base/src/mcp_db_base/maas_sql_client._headers._headers_scope..str","sourceNodeId":"_headers \\n[maas_sql_client.py : 62_85]","targetNodeId":"/src/mcp-db-base/src/mcp_db_base/maas_sql_client._headers._headers_scope..str"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-db-base/src/mcp_db_base/maas_sql_client.py"},"region":{"startLine":71,"startColumn":17,"endLine":71,"endColumn":46,"snippet":{}}}},"id":"_headers \\n[maas_sql_client.py : 62_85]->syslib_from.base64.b64decode","sourceNodeId":"_headers \\n[maas_sql_client.py : 62_85]","targetNodeId":"syslib_from.base64.b64decode"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-db-base/src/mcp_db_base/maas_sql_client.py"},"region":{"startLine":72,"startColumn":17,"endLine":72,"endColumn":45,"snippet":{}}}},"id":"_headers \\n[maas_sql_client.py : 62_85]->/src/mcp-db-base/src/mcp_db_base/maas_sql_client._headers._headers_scope..bytes","sourceNodeId":"_headers \\n[maas_sql_client.py : 62_85]","targetNodeId":"/src/mcp-db-base/src/mcp_db_base/maas_sql_client._headers._headers_scope..bytes"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-db-base/src/mcp_db_base/maas_sql_client.py"},"region":{"startLine":70,"startColumn":9,"endLine":74,"endColumn":10,"snippet":{}}}},"id":"_headers \\n[maas_sql_client.py : 62_85]->syslib_from.hmac.new","sourceNodeId":"_headers \\n[maas_sql_client.py : 62_85]","targetNodeId":"syslib_from.hmac.new"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-db-base/src/mcp_db_base/maas_sql_client.py"},"region":{"startLine":70,"startColumn":9,"endLine":74,"endColumn":19,"snippet":{}}}},"id":"_headers \\n[maas_sql_client.py : 62_85]->syslib_from.hmac.new(var key:any=base64.b64decode(_SECRET_KEY), var msg:any=bytes(msg, var encoding:any=utf-8), var digestmod:any=hashlib.sha256).digest","sourceNodeId":"_headers \\n[maas_sql_client.py : 62_85]","targetNodeId":"syslib_from.hmac.new(var key:any=base64.b64decode(_SECRET_KEY), var msg:any=bytes(msg, var encoding:any=utf-8), var digestmod:any=hashlib.sha256).digest"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-db-base/src/mcp_db_base/maas_sql_client.py"},"region":{"startLine":69,"startColumn":12,"endLine":75,"endColumn":6,"snippet":{}}}},"id":"_headers \\n[maas_sql_client.py : 62_85]->syslib_from.base64.b64encode","sourceNodeId":"_headers \\n[maas_sql_client.py : 62_85]","targetNodeId":"syslib_from.base64.b64encode"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-db-base/src/mcp_db_base/maas_sql_client.py"},"region":{"startLine":173,"startColumn":20,"endLine":173,"endColumn":101,"snippet":{}}}},"id":"get_maas_sql_data \\n[maas_sql_client.py : 155_177]->call_maas_sql_api \\n[maas_sql_client.py : 88_134]","sourceNodeId":"get_maas_sql_data \\n[maas_sql_client.py : 155_177]","targetNodeId":"call_maas_sql_api \\n[maas_sql_client.py : 88_134]"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-db-base/src/mcp_db_base/maas_sql_client.py"},"region":{"startLine":107,"startColumn":57,"endLine":107,"endColumn":67,"snippet":{}}}},"id":"call_maas_sql_api \\n[maas_sql_client.py : 88_134]->_headers \\n[maas_sql_client.py : 62_85]","sourceNodeId":"call_maas_sql_api \\n[maas_sql_client.py : 88_134]","targetNodeId":"_headers \\n[maas_sql_client.py : 62_85]"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-db-base/src/mcp_db_base/maas_sql_client.py"},"region":{"startLine":109,"startColumn":16,"endLine":115,"endColumn":6,"snippet":{}}}},"id":"call_maas_sql_api \\n[maas_sql_client.py : 88_134]->mcp_common.request.http_client.AsyncRestClient","sourceNodeId":"call_maas_sql_api \\n[maas_sql_client.py : 88_134]","targetNodeId":"mcp_common.request.http_client.AsyncRestClient"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-db-base/src/mcp_db_base/maas_sql_client.py"},"region":{"startLine":118,"startColumn":43,"endLine":118,"endColumn":57,"snippet":{}}}},"id":"call_maas_sql_api \\n[maas_sql_client.py : 88_134]->POST.lower","sourceNodeId":"call_maas_sql_api \\n[maas_sql_client.py : 88_134]","targetNodeId":"POST.lower"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-db-base/src/mcp_db_base/maas_sql_client.py"},"region":{"startLine":118,"startColumn":27,"endLine":118,"endColumn":58,"snippet":{}}}},"id":"call_maas_sql_api \\n[maas_sql_client.py : 88_134]->/src/mcp-db-base/src/mcp_db_base/maas_sql_client.call_maas_sql_api.call_maas_sql_api_scope..getattr","sourceNodeId":"call_maas_sql_api \\n[maas_sql_client.py : 88_134]","targetNodeId":"/src/mcp-db-base/src/mcp_db_base/maas_sql_client.call_maas_sql_api.call_maas_sql_api_scope..getattr"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-db-base/src/mcp_db_base/maas_sql_client.py"},"region":{"startLine":119,"startColumn":24,"endLine":119,"endColumn":78,"snippet":{}}}},"id":"call_maas_sql_api \\n[maas_sql_client.py : 88_134]->/src/mcp-db-base/src/mcp_db_base/maas_sql_client.call_maas_sql_api.call_maas_sql_api_scope..getattr(client, method.lower())","sourceNodeId":"call_maas_sql_api \\n[maas_sql_client.py : 88_134]","targetNodeId":"/src/mcp-db-base/src/mcp_db_base/maas_sql_client.call_maas_sql_api.call_maas_sql_api_scope..getattr(client, method.lower())"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-db-base/src/mcp_db_base/maas_sql_client.py"},"region":{"startLine":129,"startColumn":17,"endLine":129,"endColumn":73,"snippet":{}}}},"id":"call_maas_sql_api \\n[maas_sql_client.py : 88_134]->syslib_from.logging.getLogger(__name__).info","sourceNodeId":"call_maas_sql_api \\n[maas_sql_client.py : 88_134]","targetNodeId":"syslib_from.logging.getLogger(__name__).info"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-db-base/src/mcp_db_base/maas_sql_client.py"},"region":{"startLine":123,"startColumn":24,"endLine":123,"endColumn":44,"snippet":{}}}},"id":"call_maas_sql_api \\n[maas_sql_client.py : 88_134]->/src/mcp-db-base/src/mcp_db_base/maas_sql_client.call_maas_sql_api.call_maas_sql_api_scope..getattr(client, method.lower())(var endpoint:any=endpoint, var null:any=request_kwargs).g...","sourceNodeId":"call_maas_sql_api \\n[maas_sql_client.py : 88_134]","targetNodeId":"/src/mcp-db-base/src/mcp_db_base/maas_sql_client.call_maas_sql_api.call_maas_sql_api_scope..getattr(client, method.lower())(var endpoint:any=endpoint, var null:any=request_kwargs).g..."},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-db-base/src/mcp_db_base/maas_sql_client.py"},"region":{"startLine":124,"startColumn":20,"endLine":124,"endColumn":41,"snippet":{}}}},"id":"call_maas_sql_api \\n[maas_sql_client.py : 88_134]->/src/mcp-db-base/src/mcp_db_base/maas_sql_client.call_maas_sql_api.call_maas_sql_api_scope...isinstance","sourceNodeId":"call_maas_sql_api \\n[maas_sql_client.py : 88_134]","targetNodeId":"/src/mcp-db-base/src/mcp_db_base/maas_sql_client.call_maas_sql_api.call_maas_sql_api_scope...isinstance"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-db-base/src/mcp_db_base/maas_sql_client.py"},"region":{"startLine":125,"startColumn":28,"endLine":125,"endColumn":44,"snippet":{}}}},"id":"call_maas_sql_api \\n[maas_sql_client.py : 88_134]->syslib_from.json.loads","sourceNodeId":"call_maas_sql_api \\n[maas_sql_client.py : 88_134]","targetNodeId":"syslib_from.json.loads"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-db-base/src/mcp_db_base/maas_sql_client.py"},"region":{"startLine":127,"startColumn":36,"endLine":127,"endColumn":68,"snippet":{}}}},"id":"call_maas_sql_api \\n[maas_sql_client.py : 88_134]->_handle_empty_response \\n[maas_sql_client.py : 137_143]","sourceNodeId":"call_maas_sql_api \\n[maas_sql_client.py : 88_134]","targetNodeId":"_handle_empty_response \\n[maas_sql_client.py : 137_143]"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-db-base/src/mcp_db_base/maas_sql_client.py"},"region":{"startLine":142,"startColumn":25,"endLine":142,"endColumn":57,"snippet":{}}}},"id":"_handle_empty_response \\n[maas_sql_client.py : 137_143]->/src/mcp-db-base/src/mcp_db_base/maas_sql_client.call_maas_sql_api.call_maas_sql_api_scope..getattr(client, method.lower())(var endpoint:any=endpoint, var null:any=request_kwargs).g...","sourceNodeId":"_handle_empty_response \\n[maas_sql_client.py : 137_143]","targetNodeId":"/src/mcp-db-base/src/mcp_db_base/maas_sql_client.call_maas_sql_api.call_maas_sql_api_scope..getattr(client, method.lower())(var endpoint:any=endpoint, var null:any=request_kwargs).g..."},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-db-base/src/mcp_db_base/maas_sql_client.py"},"region":{"startLine":139,"startColumn":11,"endLine":143,"endColumn":6,"snippet":{}}}},"id":"_handle_empty_response \\n[maas_sql_client.py : 137_143]->/src/mcp-db-base/src/mcp_db_base/maas_sql_client._handle_empty_response._handle_empty_response_scope..ValueError","sourceNodeId":"_handle_empty_response \\n[maas_sql_client.py : 137_143]","targetNodeId":"/src/mcp-db-base/src/mcp_db_base/maas_sql_client._handle_empty_response._handle_empty_response_scope..ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-db-base/src/mcp_db_base/maas_sql_client.py"},"region":{"startLine":130,"startColumn":17,"endLine":130,"endColumn":49,"snippet":{}}}},"id":"call_maas_sql_api \\n[maas_sql_client.py : 88_134]->_handle_error_response \\n[maas_sql_client.py : 146_152]","sourceNodeId":"call_maas_sql_api \\n[maas_sql_client.py : 88_134]","targetNodeId":"_handle_error_response \\n[maas_sql_client.py : 146_152]"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-db-base/src/mcp_db_base/maas_sql_client.py"},"region":{"startLine":151,"startColumn":25,"endLine":151,"endColumn":57,"snippet":{}}}},"id":"_handle_error_response \\n[maas_sql_client.py : 146_152]->/src/mcp-db-base/src/mcp_db_base/maas_sql_client.call_maas_sql_api.call_maas_sql_api_scope..getattr(client, method.lower())(var endpoint:any=endpoint, var null:any=request_kwargs).g...","sourceNodeId":"_handle_error_response \\n[maas_sql_client.py : 146_152]","targetNodeId":"/src/mcp-db-base/src/mcp_db_base/maas_sql_client.call_maas_sql_api.call_maas_sql_api_scope..getattr(client, method.lower())(var endpoint:any=endpoint, var null:any=request_kwargs).g..."},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-db-base/src/mcp_db_base/maas_sql_client.py"},"region":{"startLine":148,"startColumn":11,"endLine":152,"endColumn":6,"snippet":{}}}},"id":"_handle_error_response \\n[maas_sql_client.py : 146_152]->/src/mcp-db-base/src/mcp_db_base/maas_sql_client._handle_error_response._handle_error_response_scope..ValueError","sourceNodeId":"_handle_error_response \\n[maas_sql_client.py : 146_152]","targetNodeId":"/src/mcp-db-base/src/mcp_db_base/maas_sql_client._handle_error_response._handle_error_response_scope..ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-db-base/src/mcp_db_base/maas_sql_client.py"},"region":{"startLine":134,"startColumn":56,"endLine":134,"endColumn":64,"snippet":{}}}},"id":"call_maas_sql_api \\n[maas_sql_client.py : 88_134]->/src/mcp-db-base/src/mcp_db_base/maas_sql_client.call_maas_sql_api.call_maas_sql_api_scope...str","sourceNodeId":"call_maas_sql_api \\n[maas_sql_client.py : 88_134]","targetNodeId":"/src/mcp-db-base/src/mcp_db_base/maas_sql_client.call_maas_sql_api.call_maas_sql_api_scope...str"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-db-base/src/mcp_db_base/maas_sql_client.py"},"region":{"startLine":133,"startColumn":13,"endLine":133,"endColumn":55,"snippet":{}}}},"id":"call_maas_sql_api \\n[maas_sql_client.py : 88_134]->syslib_from.logging.getLogger(__name__).error","sourceNodeId":"call_maas_sql_api \\n[maas_sql_client.py : 88_134]","targetNodeId":"syslib_from.logging.getLogger(__name__).error"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-db-base/src/mcp_db_base/maas_sql_client.py"},"region":{"startLine":134,"startColumn":19,"endLine":134,"endColumn":66,"snippet":{}}}},"id":"call_maas_sql_api \\n[maas_sql_client.py : 88_134]->/src/mcp-db-base/src/mcp_db_base/maas_sql_client.call_maas_sql_api.call_maas_sql_api_scope...ValueError","sourceNodeId":"call_maas_sql_api \\n[maas_sql_client.py : 88_134]","targetNodeId":"/src/mcp-db-base/src/mcp_db_base/maas_sql_client.call_maas_sql_api.call_maas_sql_api_scope...ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-db-base/src/mcp_db_base/maas_sql_client.py"},"region":{"startLine":176,"startColumn":9,"endLine":176,"endColumn":59,"snippet":{}}}},"id":"get_maas_sql_data \\n[maas_sql_client.py : 155_177]->syslib_from.logging.getLogger(__name__).exception","sourceNodeId":"get_maas_sql_data \\n[maas_sql_client.py : 155_177]","targetNodeId":"syslib_from.logging.getLogger(__name__).exception"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-db-base/src/mcp_db_base/maas_sql_client.py"},"region":{"startLine":177,"startColumn":26,"endLine":177,"endColumn":32,"snippet":{}}}},"id":"get_maas_sql_data \\n[maas_sql_client.py : 155_177]->/src/mcp-db-base/src/mcp_db_base/maas_sql_client.get_maas_sql_data.get_maas_sql_data_scope...str","sourceNodeId":"get_maas_sql_data \\n[maas_sql_client.py : 155_177]","targetNodeId":"/src/mcp-db-base/src/mcp_db_base/maas_sql_client.get_maas_sql_data.get_maas_sql_data_scope...str"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-db-base/src/mcp_db_base/maas_sql_client.py"},"region":{"startLine":177,"startColumn":15,"endLine":177,"endColumn":33,"snippet":{}}}},"id":"get_maas_sql_data \\n[maas_sql_client.py : 155_177]->/src/mcp-db-base/src/mcp_db_base/maas_sql_client.get_maas_sql_data.get_maas_sql_data_scope...ValueError","sourceNodeId":"get_maas_sql_data \\n[maas_sql_client.py : 155_177]","targetNodeId":"/src/mcp-db-base/src/mcp_db_base/maas_sql_client.get_maas_sql_data.get_maas_sql_data_scope...ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpQueryMultiAppMetrics/src/mcpQueryMultiAppMetrics/maas_service.py"},"region":{"startLine":625,"startColumn":11,"endLine":625,"endColumn":46,"snippet":{}}}},"id":"<__entry_point__>->syslib_from.json.dumps","sourceNodeId":"<__entry_point__>","targetNodeId":"syslib_from.json.dumps"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-db-base/src/mcp_db_base/maas_sql_client.py"},"region":{"startLine":398,"startColumn":5,"endLine":398,"endColumn":15,"snippet":{}}}},"id":"<__entry_point__>->/src/mcp-db-base/src/mcp_db_base/maas_sql_client..print","sourceNodeId":"<__entry_point__>","targetNodeId":"/src/mcp-db-base/src/mcp_db_base/maas_sql_client..print"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpYuntu/src/mcpYuntu/yuntu_client.py"},"region":{"startLine":14,"startColumn":14,"endLine":14,"endColumn":37,"snippet":{}}}},"id":"<__entry_point__>->syslib_from.os.environ.get","sourceNodeId":"<__entry_point__>","targetNodeId":"syslib_from.os.environ.get"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-db-base/src/mcp_db_base/ocp_client.py"},"region":{"startLine":138,"startColumn":23,"endLine":138,"endColumn":51,"snippet":{}}}},"id":"<__entry_point__>->get_cluster_arch \\n[ocp_client.py : 81_135]","sourceNodeId":"<__entry_point__>","targetNodeId":"get_cluster_arch \\n[ocp_client.py : 81_135]"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-db-base/src/mcp_db_base/ocp_client.py"},"region":{"startLine":82,"startColumn":5,"endLine":82,"endColumn":47,"snippet":{}}}},"id":"get_cluster_arch \\n[ocp_client.py : 81_135]->syslib_from.logging.getLogger(__name__).info","sourceNodeId":"get_cluster_arch \\n[ocp_client.py : 81_135]","targetNodeId":"syslib_from.logging.getLogger(__name__).info"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-db-base/src/mcp_db_base/ocp_client.py"},"region":{"startLine":85,"startColumn":20,"endLine":85,"endColumn":46,"snippet":{}}}},"id":"get_cluster_arch \\n[ocp_client.py : 81_135]->syslib_from.os.environ.get","sourceNodeId":"get_cluster_arch \\n[ocp_client.py : 81_135]","targetNodeId":"syslib_from.os.environ.get"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-db-base/src/mcp_db_base/ocp_client.py"},"region":{"startLine":90,"startColumn":38,"endLine":90,"endColumn":80,"snippet":{}}}},"id":"get_cluster_arch \\n[ocp_client.py : 81_135]->mcp_common.utils.mist_util.get_mist_secret","sourceNodeId":"get_cluster_arch \\n[ocp_client.py : 81_135]","targetNodeId":"mcp_common.utils.mist_util.get_mist_secret"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-db-base/src/mcp_db_base/ocp_client.py"},"region":{"startLine":93,"startColumn":74,"endLine":93,"endColumn":82,"snippet":{}}}},"id":"get_cluster_arch \\n[ocp_client.py : 81_135]->/src/mcp-db-base/src/mcp_db_base/ocp_client.get_cluster_arch.get_cluster_arch_scope...str","sourceNodeId":"get_cluster_arch \\n[ocp_client.py : 81_135]","targetNodeId":"/src/mcp-db-base/src/mcp_db_base/ocp_client.get_cluster_arch.get_cluster_arch_scope...str"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-db-base/src/mcp_db_base/ocp_client.py"},"region":{"startLine":92,"startColumn":13,"endLine":92,"endColumn":61,"snippet":{}}}},"id":"get_cluster_arch \\n[ocp_client.py : 81_135]->/src/mcp-db-base/src/mcp_db_base/ocp_client.get_cluster_arch.get_cluster_arch_scope...print","sourceNodeId":"get_cluster_arch \\n[ocp_client.py : 81_135]","targetNodeId":"/src/mcp-db-base/src/mcp_db_base/ocp_client.get_cluster_arch.get_cluster_arch_scope...print"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-db-base/src/mcp_db_base/ocp_client.py"},"region":{"startLine":93,"startColumn":13,"endLine":93,"endColumn":84,"snippet":{}}}},"id":"get_cluster_arch \\n[ocp_client.py : 81_135]->syslib_from.logging.getLogger(__name__).debug","sourceNodeId":"get_cluster_arch \\n[ocp_client.py : 81_135]","targetNodeId":"syslib_from.logging.getLogger(__name__).debug"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-db-base/src/mcp_db_base/ocp_client.py"},"region":{"startLine":104,"startColumn":40,"endLine":104,"endColumn":51,"snippet":{}}}},"id":"get_cluster_arch \\n[ocp_client.py : 81_135]->syslib_from.time.time","sourceNodeId":"get_cluster_arch \\n[ocp_client.py : 81_135]","targetNodeId":"syslib_from.time.time"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-db-base/src/mcp_db_base/ocp_client.py"},"region":{"startLine":104,"startColumn":34,"endLine":104,"endColumn":59,"snippet":{}}}},"id":"get_cluster_arch \\n[ocp_client.py : 81_135]->round","sourceNodeId":"get_cluster_arch \\n[ocp_client.py : 81_135]","targetNodeId":"round"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-db-base/src/mcp_db_base/ocp_client.py"},"region":{"startLine":104,"startColumn":30,"endLine":104,"endColumn":60,"snippet":{}}}},"id":"get_cluster_arch \\n[ocp_client.py : 81_135]->int","sourceNodeId":"get_cluster_arch \\n[ocp_client.py : 81_135]","targetNodeId":"int"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-db-base/src/mcp_db_base/ocp_client.py"},"region":{"startLine":104,"startColumn":26,"endLine":104,"endColumn":61,"snippet":{}}}},"id":"get_cluster_arch \\n[ocp_client.py : 81_135]->str","sourceNodeId":"get_cluster_arch \\n[ocp_client.py : 81_135]","targetNodeId":"str"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-db-base/src/mcp_db_base/ocp_client.py"},"region":{"startLine":106,"startColumn":18,"endLine":106,"endColumn":36,"snippet":{}}}},"id":"get_cluster_arch \\n[ocp_client.py : 81_135]->temp_params.copy","sourceNodeId":"get_cluster_arch \\n[ocp_client.py : 81_135]","targetNodeId":"temp_params.copy"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-db-base/src/mcp_db_base/ocp_client.py"},"region":{"startLine":108,"startColumn":29,"endLine":108,"endColumn":71,"snippet":{}}}},"id":"get_cluster_arch \\n[ocp_client.py : 81_135]->rpc_sign \\n[ocp_client.py : 32_62]","sourceNodeId":"get_cluster_arch \\n[ocp_client.py : 81_135]","targetNodeId":"rpc_sign \\n[ocp_client.py : 32_62]"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-db-base/src/mcp_db_base/ocp_client.py"},"region":{"startLine":34,"startColumn":26,"endLine":34,"endColumn":46,"snippet":{}}}},"id":"rpc_sign \\n[ocp_client.py : 32_62]->temp_params.keys","sourceNodeId":"rpc_sign \\n[ocp_client.py : 32_62]","targetNodeId":"temp_params.keys"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-db-base/src/mcp_db_base/ocp_client.py"},"region":{"startLine":34,"startColumn":19,"endLine":34,"endColumn":47,"snippet":{}}}},"id":"rpc_sign \\n[ocp_client.py : 32_62]->/src/mcp-db-base/src/mcp_db_base/ocp_client.rpc_sign.rpc_sign_scope..sorted","sourceNodeId":"rpc_sign \\n[ocp_client.py : 32_62]","targetNodeId":"/src/mcp-db-base/src/mcp_db_base/ocp_client.rpc_sign.rpc_sign_scope..sorted"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-db-base/src/mcp_db_base/ocp_client.py"},"region":{"startLine":52,"startColumn":9,"endLine":52,"endColumn":34,"snippet":{}}}},"id":"rpc_sign \\n[ocp_client.py : 32_62]->percent_encode \\n[ocp_client.py : 65_67]","sourceNodeId":"rpc_sign \\n[ocp_client.py : 32_62]","targetNodeId":"percent_encode \\n[ocp_client.py : 65_67]"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-db-base/src/mcp_db_base/ocp_client.py"},"region":{"startLine":67,"startColumn":31,"endLine":67,"endColumn":37,"snippet":{}}}},"id":"percent_encode \\n[ocp_client.py : 65_67]->/src/mcp-db-base/src/mcp_db_base/ocp_client.percent_encode.percent_encode_scope..str","sourceNodeId":"percent_encode \\n[ocp_client.py : 65_67]","targetNodeId":"/src/mcp-db-base/src/mcp_db_base/ocp_client.percent_encode.percent_encode_scope..str"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-db-base/src/mcp_db_base/ocp_client.py"},"region":{"startLine":67,"startColumn":12,"endLine":67,"endColumn":47,"snippet":{}}}},"id":"percent_encode \\n[ocp_client.py : 65_67]->/src/mcp-db-base/src/mcp_db_base/ocp_client.percent_encode.percent_encode_scope..urllib.parse.quote","sourceNodeId":"percent_encode \\n[ocp_client.py : 65_67]","targetNodeId":"/src/mcp-db-base/src/mcp_db_base/ocp_client.percent_encode.percent_encode_scope..urllib.parse.quote"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-db-base/src/mcp_db_base/ocp_client.py"},"region":{"startLine":67,"startColumn":12,"endLine":67,"endColumn":67,"snippet":{}}}},"id":"percent_encode \\n[ocp_client.py : 65_67]->/src/mcp-db-base/src/mcp_db_base/ocp_client.percent_encode.percent_encode_scope..urllib.parse.quote(str(s), var safe:any=).replace","sourceNodeId":"percent_encode \\n[ocp_client.py : 65_67]","targetNodeId":"/src/mcp-db-base/src/mcp_db_base/ocp_client.percent_encode.percent_encode_scope..urllib.parse.quote(str(s), var safe:any=).replace"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-db-base/src/mcp_db_base/ocp_client.py"},"region":{"startLine":67,"startColumn":12,"endLine":67,"endColumn":87,"snippet":{}}}},"id":"percent_encode \\n[ocp_client.py : 65_67]->/src/mcp-db-base/src/mcp_db_base/ocp_client.percent_encode.percent_encode_scope..urllib.parse.quote(str(s), var safe:any=).replace(+, %20).replace","sourceNodeId":"percent_encode \\n[ocp_client.py : 65_67]","targetNodeId":"/src/mcp-db-base/src/mcp_db_base/ocp_client.percent_encode.percent_encode_scope..urllib.parse.quote(str(s), var safe:any=).replace(+, %20).replace"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-db-base/src/mcp_db_base/ocp_client.py"},"region":{"startLine":49,"startColumn":22,"endLine":53,"endColumn":7,"snippet":{}}}},"id":"rpc_sign \\n[ocp_client.py : 32_62]->&.join","sourceNodeId":"rpc_sign \\n[ocp_client.py : 32_62]","targetNodeId":"&.join"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-db-base/src/mcp_db_base/ocp_client.py"},"region":{"startLine":56,"startColumn":11,"endLine":56,"endColumn":43,"snippet":{}}}},"id":"rpc_sign \\n[ocp_client.py : 32_62]->encode","sourceNodeId":"rpc_sign \\n[ocp_client.py : 32_62]","targetNodeId":"encode"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-db-base/src/mcp_db_base/ocp_client.py"},"region":{"startLine":59,"startColumn":28,"endLine":59,"endColumn":58,"snippet":{}}}},"id":"rpc_sign \\n[ocp_client.py : 32_62]->&.join({0:percent_encode(method), 1:percent_encode(/), 2:percent_encode(param_str)}).encode","sourceNodeId":"rpc_sign \\n[ocp_client.py : 32_62]","targetNodeId":"&.join({0:percent_encode(method), 1:percent_encode(/), 2:percent_encode(param_str)}).encode"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-db-base/src/mcp_db_base/ocp_client.py"},"region":{"startLine":59,"startColumn":14,"endLine":59,"endColumn":65,"snippet":{}}}},"id":"rpc_sign \\n[ocp_client.py : 32_62]->syslib_from.hmac.new","sourceNodeId":"rpc_sign \\n[ocp_client.py : 32_62]","targetNodeId":"syslib_from.hmac.new"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-db-base/src/mcp_db_base/ocp_client.py"},"region":{"startLine":60,"startColumn":34,"endLine":60,"endColumn":49,"snippet":{}}}},"id":"rpc_sign \\n[ocp_client.py : 32_62]->syslib_from.hmac.new(key, string_to_sign.encode(utf-8), sha1).digest","sourceNodeId":"rpc_sign \\n[ocp_client.py : 32_62]","targetNodeId":"syslib_from.hmac.new(key, string_to_sign.encode(utf-8), sha1).digest"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-db-base/src/mcp_db_base/ocp_client.py"},"region":{"startLine":60,"startColumn":17,"endLine":60,"endColumn":50,"snippet":{}}}},"id":"rpc_sign \\n[ocp_client.py : 32_62]->syslib_from.base64.b64encode","sourceNodeId":"rpc_sign \\n[ocp_client.py : 32_62]","targetNodeId":"syslib_from.base64.b64encode"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-db-base/src/mcp_db_base/ocp_client.py"},"region":{"startLine":60,"startColumn":17,"endLine":60,"endColumn":66,"snippet":{}}}},"id":"rpc_sign \\n[ocp_client.py : 32_62]->syslib_from.base64.b64encode(hashed.digest()).decode","sourceNodeId":"rpc_sign \\n[ocp_client.py : 32_62]","targetNodeId":"syslib_from.base64.b64encode(hashed.digest()).decode"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-db-base/src/mcp_db_base/ocp_client.py"},"region":{"startLine":107,"startColumn":9,"endLine":109,"endColumn":11,"snippet":{}}}},"id":"get_cluster_arch \\n[ocp_client.py : 81_135]->temp_params.copy().update","sourceNodeId":"get_cluster_arch \\n[ocp_client.py : 81_135]","targetNodeId":"temp_params.copy().update"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-db-base/src/mcp_db_base/ocp_client.py"},"region":{"startLine":112,"startColumn":26,"endLine":112,"endColumn":44,"snippet":{}}}},"id":"get_cluster_arch \\n[ocp_client.py : 81_135]->get_url \\n[ocp_client.py : 77_78]","sourceNodeId":"get_cluster_arch \\n[ocp_client.py : 81_135]","targetNodeId":"get_url \\n[ocp_client.py : 77_78]"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-db-base/src/mcp_db_base/ocp_client.py"},"region":{"startLine":116,"startColumn":33,"endLine":116,"endColumn":52,"snippet":{}}}},"id":"get_cluster_arch \\n[ocp_client.py : 81_135]->dbass_auth_header \\n[ocp_client.py : 70_74]","sourceNodeId":"get_cluster_arch \\n[ocp_client.py : 81_135]","targetNodeId":"dbass_auth_header \\n[ocp_client.py : 70_74]"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-db-base/src/mcp_db_base/ocp_client.py"},"region":{"startLine":111,"startColumn":20,"endLine":117,"endColumn":10,"snippet":{}}}},"id":"get_cluster_arch \\n[ocp_client.py : 81_135]->mcp_common.request.http_client.AsyncRestClient","sourceNodeId":"get_cluster_arch \\n[ocp_client.py : 81_135]","targetNodeId":"mcp_common.request.http_client.AsyncRestClient"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-db-base/src/mcp_db_base/ocp_client.py"},"region":{"startLine":120,"startColumn":28,"endLine":123,"endColumn":18,"snippet":{}}}},"id":"get_cluster_arch \\n[ocp_client.py : 81_135]->mcp_common.request.http_client.AsyncRestClient(var base_url:any=get_url(site, env), var max_connections:any=50, var timeout:any=15, var retries:any=3, var default_headers:any=dbass_auth_header()).get","sourceNodeId":"get_cluster_arch \\n[ocp_client.py : 81_135]","targetNodeId":"mcp_common.request.http_client.AsyncRestClient(var base_url:any=get_url(site, env), var max_connections:any=50, var timeout:any=15, var retries:any=3, var default_headers:any=dbass_auth_header()).get"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-db-base/src/mcp_db_base/ocp_client.py"},"region":{"startLine":128,"startColumn":76,"endLine":128,"endColumn":105,"snippet":{}}}},"id":"get_cluster_arch \\n[ocp_client.py : 81_135]->mcp_common.request.http_client.AsyncRestClient(var base_url:any=get_url(site, env), var max_connections:any=50, var timeout:any=15, var retries:any=3, var default_headers:any=dbass_auth_header()).get(...","sourceNodeId":"get_cluster_arch \\n[ocp_client.py : 81_135]","targetNodeId":"mcp_common.request.http_client.AsyncRestClient(var base_url:any=get_url(site, env), var max_connections:any=50, var timeout:any=15, var retries:any=3, var default_headers:any=dbass_auth_header()).get(..."},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-db-base/src/mcp_db_base/ocp_client.py"},"region":{"startLine":127,"startColumn":27,"endLine":128,"endColumn":107,"snippet":{}}}},"id":"get_cluster_arch \\n[ocp_client.py : 81_135]->/src/mcp-db-base/src/mcp_db_base/ocp_client.get_cluster_arch.get_cluster_arch_scope...ValueError","sourceNodeId":"get_cluster_arch \\n[ocp_client.py : 81_135]","targetNodeId":"/src/mcp-db-base/src/mcp_db_base/ocp_client.get_cluster_arch.get_cluster_arch_scope...ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-db-base/src/mcp_db_base/ocp_client.py"},"region":{"startLine":132,"startColumn":70,"endLine":132,"endColumn":78,"snippet":{}}}},"id":"get_cluster_arch \\n[ocp_client.py : 81_135]->/src/mcp-db-base/src/mcp_db_base/ocp_client.get_cluster_arch.get_cluster_arch_scope...str","sourceNodeId":"get_cluster_arch \\n[ocp_client.py : 81_135]","targetNodeId":"/src/mcp-db-base/src/mcp_db_base/ocp_client.get_cluster_arch.get_cluster_arch_scope...str"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-db-base/src/mcp_db_base/ocp_client.py"},"region":{"startLine":131,"startColumn":17,"endLine":131,"endColumn":62,"snippet":{}}}},"id":"get_cluster_arch \\n[ocp_client.py : 81_135]->syslib_from.logging.getLogger(__name__).error","sourceNodeId":"get_cluster_arch \\n[ocp_client.py : 81_135]","targetNodeId":"syslib_from.logging.getLogger(__name__).error"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-db-base/src/mcp_db_base/ocp_client.py"},"region":{"startLine":132,"startColumn":23,"endLine":132,"endColumn":80,"snippet":{}}}},"id":"get_cluster_arch \\n[ocp_client.py : 81_135]->/src/mcp-db-base/src/mcp_db_base/ocp_client.get_cluster_arch.get_cluster_arch_scope...ValueError","sourceNodeId":"get_cluster_arch \\n[ocp_client.py : 81_135]","targetNodeId":"/src/mcp-db-base/src/mcp_db_base/ocp_client.get_cluster_arch.get_cluster_arch_scope...ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-db-base/src/mcp_db_base/ocp_client.py"},"region":{"startLine":134,"startColumn":9,"endLine":134,"endColumn":59,"snippet":{}}}},"id":"get_cluster_arch \\n[ocp_client.py : 81_135]->syslib_from.logging.getLogger(__name__).exception","sourceNodeId":"get_cluster_arch \\n[ocp_client.py : 81_135]","targetNodeId":"syslib_from.logging.getLogger(__name__).exception"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-db-base/src/mcp_db_base/ocp_client.py"},"region":{"startLine":135,"startColumn":26,"endLine":135,"endColumn":32,"snippet":{}}}},"id":"get_cluster_arch \\n[ocp_client.py : 81_135]->/src/mcp-db-base/src/mcp_db_base/ocp_client.get_cluster_arch.get_cluster_arch_scope...str","sourceNodeId":"get_cluster_arch \\n[ocp_client.py : 81_135]","targetNodeId":"/src/mcp-db-base/src/mcp_db_base/ocp_client.get_cluster_arch.get_cluster_arch_scope...str"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-db-base/src/mcp_db_base/ocp_client.py"},"region":{"startLine":135,"startColumn":15,"endLine":135,"endColumn":33,"snippet":{}}}},"id":"get_cluster_arch \\n[ocp_client.py : 81_135]->/src/mcp-db-base/src/mcp_db_base/ocp_client.get_cluster_arch.get_cluster_arch_scope...ValueError","sourceNodeId":"get_cluster_arch \\n[ocp_client.py : 81_135]","targetNodeId":"/src/mcp-db-base/src/mcp_db_base/ocp_client.get_cluster_arch.get_cluster_arch_scope...ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-db-base/src/mcp_db_base/ocp_client.py"},"region":{"startLine":138,"startColumn":5,"endLine":138,"endColumn":53,"snippet":{}}}},"id":"<__entry_point__>->/src/mcp-db-base/src/mcp_db_base/ocp_client..print","sourceNodeId":"<__entry_point__>","targetNodeId":"/src/mcp-db-base/src/mcp_db_base/ocp_client..print"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-db-base/src/mcp_db_base/omc_client.py"},"region":{"startLine":613,"startColumn":23,"endLine":613,"endColumn":94,"snippet":{}}}},"id":"<__entry_point__>->get_dbs \\n[omc_client.py : 169_194]","sourceNodeId":"<__entry_point__>","targetNodeId":"get_dbs \\n[omc_client.py : 169_194]"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-db-base/src/mcp_db_base/omc_client.py"},"region":{"startLine":171,"startColumn":5,"endLine":171,"endColumn":33,"snippet":{}}}},"id":"get_dbs \\n[omc_client.py : 169_194]->syslib_from.logging.getLogger(__name__).info","sourceNodeId":"get_dbs \\n[omc_client.py : 169_194]","targetNodeId":"syslib_from.logging.getLogger(__name__).info"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-db-base/src/mcp_db_base/omc_client.py"},"region":{"startLine":179,"startColumn":16,"endLine":179,"endColumn":26,"snippet":{}}}},"id":"get_dbs \\n[omc_client.py : 169_194]->is_arn \\n[omc_client.py : 581_585]","sourceNodeId":"get_dbs \\n[omc_client.py : 169_194]","targetNodeId":"is_arn \\n[omc_client.py : 581_585]"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-db-base/src/mcp_db_base/omc_client.py"},"region":{"startLine":582,"startColumn":15,"endLine":582,"endColumn":48,"snippet":{}}}},"id":"is_arn \\n[omc_client.py : 581_585]->acs:alipay:rds::ipay:logic-database:221604704.isupportcenter.startswith","sourceNodeId":"is_arn \\n[omc_client.py : 581_585]","targetNodeId":"acs:alipay:rds::ipay:logic-database:221604704.isupportcenter.startswith"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-db-base/src/mcp_db_base/omc_client.py"},"region":{"startLine":187,"startColumn":13,"endLine":187,"endColumn":53,"snippet":{}}}},"id":"get_dbs \\n[omc_client.py : 169_194]->params.update","sourceNodeId":"get_dbs \\n[omc_client.py : 169_194]","targetNodeId":"params.update"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-db-base/src/mcp_db_base/omc_client.py"},"region":{"startLine":182,"startColumn":16,"endLine":182,"endColumn":32,"snippet":{}}}},"id":"get_dbs \\n[omc_client.py : 169_194]->is_logic_arn \\n[omc_client.py : 588_590]","sourceNodeId":"get_dbs \\n[omc_client.py : 169_194]","targetNodeId":"is_logic_arn \\n[omc_client.py : 588_590]"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-db-base/src/mcp_db_base/omc_client.py"},"region":{"startLine":590,"startColumn":17,"endLine":590,"endColumn":42,"snippet":{}}}},"id":"is_logic_arn \\n[omc_client.py : 588_590]->syslib_from.re.fullmatch","sourceNodeId":"is_logic_arn \\n[omc_client.py : 588_590]","targetNodeId":"syslib_from.re.fullmatch"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-db-base/src/mcp_db_base/omc_client.py"},"region":{"startLine":590,"startColumn":12,"endLine":590,"endColumn":43,"snippet":{}}}},"id":"is_logic_arn \\n[omc_client.py : 588_590]->/src/mcp-db-base/src/mcp_db_base/omc_client.is_logic_arn.is_logic_arn_scope..bool","sourceNodeId":"is_logic_arn \\n[omc_client.py : 588_590]","targetNodeId":"/src/mcp-db-base/src/mcp_db_base/omc_client.is_logic_arn.is_logic_arn_scope..bool"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-db-base/src/mcp_db_base/omc_client.py"},"region":{"startLine":190,"startColumn":19,"endLine":190,"endColumn":36,"snippet":{}}}},"id":"get_dbs \\n[omc_client.py : 169_194]->_headers \\n[omc_client.py : 29_49]","sourceNodeId":"get_dbs \\n[omc_client.py : 169_194]","targetNodeId":"_headers \\n[omc_client.py : 29_49]"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-db-base/src/mcp_db_base/omc_client.py"},"region":{"startLine":31,"startColumn":17,"endLine":31,"endColumn":31,"snippet":{}}}},"id":"_headers \\n[omc_client.py : 29_49]->datetime.datetime.now","sourceNodeId":"_headers \\n[omc_client.py : 29_49]","targetNodeId":"datetime.datetime.now"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-db-base/src/mcp_db_base/omc_client.py"},"region":{"startLine":31,"startColumn":17,"endLine":31,"endColumn":58,"snippet":{}}}},"id":"_headers \\n[omc_client.py : 29_49]->datetime.datetime.now().strftime","sourceNodeId":"_headers \\n[omc_client.py : 29_49]","targetNodeId":"datetime.datetime.now().strftime"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-db-base/src/mcp_db_base/omc_client.py"},"region":{"startLine":34,"startColumn":17,"endLine":34,"endColumn":44,"snippet":{}}}},"id":"_headers \\n[omc_client.py : 29_49]->syslib_from.os.environ.get","sourceNodeId":"_headers \\n[omc_client.py : 29_49]","targetNodeId":"syslib_from.os.environ.get"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-db-base/src/mcp_db_base/omc_client.py"},"region":{"startLine":36,"startColumn":18,"endLine":36,"endColumn":45,"snippet":{}}}},"id":"_headers \\n[omc_client.py : 29_49]->syslib_from.base64.b64decode","sourceNodeId":"_headers \\n[omc_client.py : 29_49]","targetNodeId":"syslib_from.base64.b64decode"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-db-base/src/mcp_db_base/omc_client.py"},"region":{"startLine":36,"startColumn":18,"endLine":36,"endColumn":61,"snippet":{}}}},"id":"_headers \\n[omc_client.py : 29_49]->syslib_from.base64.b64decode(OMC_TOKEN).decode","sourceNodeId":"_headers \\n[omc_client.py : 29_49]","targetNodeId":"syslib_from.base64.b64decode(OMC_TOKEN).decode"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-db-base/src/mcp_db_base/omc_client.py"},"region":{"startLine":39,"startColumn":13,"endLine":39,"endColumn":32,"snippet":{}}}},"id":"_headers \\n[omc_client.py : 29_49]->syslib_from.base64.b64decode(OMC_TOKEN).decode(utf-8).encode","sourceNodeId":"_headers \\n[omc_client.py : 29_49]","targetNodeId":"syslib_from.base64.b64decode(OMC_TOKEN).decode(utf-8).encode"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-db-base/src/mcp_db_base/omc_client.py"},"region":{"startLine":40,"startColumn":13,"endLine":40,"endColumn":56,"snippet":{}}}},"id":"_headers \\n[omc_client.py : 29_49]->encode","sourceNodeId":"_headers \\n[omc_client.py : 29_49]","targetNodeId":"encode"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-db-base/src/mcp_db_base/omc_client.py"},"region":{"startLine":38,"startColumn":9,"endLine":42,"endColumn":10,"snippet":{}}}},"id":"_headers \\n[omc_client.py : 29_49]->syslib_from.hmac.new","sourceNodeId":"_headers \\n[omc_client.py : 29_49]","targetNodeId":"syslib_from.hmac.new"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-db-base/src/mcp_db_base/omc_client.py"},"region":{"startLine":38,"startColumn":9,"endLine":42,"endColumn":19,"snippet":{}}}},"id":"_headers \\n[omc_client.py : 29_49]->syslib_from.hmac.new(access_key.encode(), api_uri+access_id+timestamp.encode(), hashlib.sha1).digest","sourceNodeId":"_headers \\n[omc_client.py : 29_49]","targetNodeId":"syslib_from.hmac.new(access_key.encode(), api_uri+access_id+timestamp.encode(), hashlib.sha1).digest"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-db-base/src/mcp_db_base/omc_client.py"},"region":{"startLine":37,"startColumn":17,"endLine":43,"endColumn":6,"snippet":{}}}},"id":"_headers \\n[omc_client.py : 29_49]->syslib_from.base64.b64encode","sourceNodeId":"_headers \\n[omc_client.py : 29_49]","targetNodeId":"syslib_from.base64.b64encode"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-db-base/src/mcp_db_base/omc_client.py"},"region":{"startLine":37,"startColumn":17,"endLine":43,"endColumn":22,"snippet":{}}}},"id":"_headers \\n[omc_client.py : 29_49]->syslib_from.base64.b64encode(hmac.new(access_key.encode(), api_uri+access_id+timestamp.encode(), hashlib.sha1).digest()).decode","sourceNodeId":"_headers \\n[omc_client.py : 29_49]","targetNodeId":"syslib_from.base64.b64encode(hmac.new(access_key.encode(), api_uri+access_id+timestamp.encode(), hashlib.sha1).digest()).decode"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-db-base/src/mcp_db_base/omc_client.py"},"region":{"startLine":191,"startColumn":16,"endLine":191,"endColumn":85,"snippet":{}}}},"id":"get_dbs \\n[omc_client.py : 169_194]->call_omc_api \\n[omc_client.py : 63_105]","sourceNodeId":"get_dbs \\n[omc_client.py : 169_194]","targetNodeId":"call_omc_api \\n[omc_client.py : 63_105]"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-db-base/src/mcp_db_base/omc_client.py"},"region":{"startLine":86,"startColumn":22,"endLine":86,"endColumn":40,"snippet":{}}}},"id":"call_omc_api \\n[omc_client.py : 63_105]->get_url \\n[omc_client.py : 52_60]","sourceNodeId":"call_omc_api \\n[omc_client.py : 63_105]","targetNodeId":"get_url \\n[omc_client.py : 52_60]"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-db-base/src/mcp_db_base/omc_client.py"},"region":{"startLine":53,"startColumn":12,"endLine":53,"endColumn":35,"snippet":{}}}},"id":"get_url \\n[omc_client.py : 52_60]->OMC_URL.get","sourceNodeId":"get_url \\n[omc_client.py : 52_60]","targetNodeId":"OMC_URL.get"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-db-base/src/mcp_db_base/omc_client.py"},"region":{"startLine":57,"startColumn":12,"endLine":57,"endColumn":35,"snippet":{}}}},"id":"get_url \\n[omc_client.py : 52_60]->/src/mcp-db-base/src/mcp_db_base/omc_client.get_url.get_url_scope..site_map.get","sourceNodeId":"get_url \\n[omc_client.py : 52_60]","targetNodeId":"/src/mcp-db-base/src/mcp_db_base/omc_client.get_url.get_url_scope..site_map.get"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-db-base/src/mcp_db_base/omc_client.py"},"region":{"startLine":85,"startColumn":16,"endLine":91,"endColumn":6,"snippet":{}}}},"id":"call_omc_api \\n[omc_client.py : 63_105]->mcp_common.request.http_client.AsyncRestClient","sourceNodeId":"call_omc_api \\n[omc_client.py : 63_105]","targetNodeId":"mcp_common.request.http_client.AsyncRestClient"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-db-base/src/mcp_db_base/omc_client.py"},"region":{"startLine":94,"startColumn":43,"endLine":94,"endColumn":57,"snippet":{}}}},"id":"call_omc_api \\n[omc_client.py : 63_105]->GET.lower","sourceNodeId":"call_omc_api \\n[omc_client.py : 63_105]","targetNodeId":"GET.lower"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-db-base/src/mcp_db_base/omc_client.py"},"region":{"startLine":94,"startColumn":27,"endLine":94,"endColumn":58,"snippet":{}}}},"id":"call_omc_api \\n[omc_client.py : 63_105]->/src/mcp-db-base/src/mcp_db_base/omc_client.call_omc_api.call_omc_api_scope..getattr","sourceNodeId":"call_omc_api \\n[omc_client.py : 63_105]","targetNodeId":"/src/mcp-db-base/src/mcp_db_base/omc_client.call_omc_api.call_omc_api_scope..getattr"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-db-base/src/mcp_db_base/omc_client.py"},"region":{"startLine":95,"startColumn":24,"endLine":95,"endColumn":78,"snippet":{}}}},"id":"call_omc_api \\n[omc_client.py : 63_105]->/src/mcp-db-base/src/mcp_db_base/omc_client.call_omc_api.call_omc_api_scope..getattr(client, method.lower())","sourceNodeId":"call_omc_api \\n[omc_client.py : 63_105]","targetNodeId":"/src/mcp-db-base/src/mcp_db_base/omc_client.call_omc_api.call_omc_api_scope..getattr(client, method.lower())"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-db-base/src/mcp_db_base/omc_client.py"},"region":{"startLine":99,"startColumn":48,"endLine":99,"endColumn":70,"snippet":{}}}},"id":"call_omc_api \\n[omc_client.py : 63_105]->/src/mcp-db-base/src/mcp_db_base/omc_client.call_omc_api.call_omc_api_scope..getattr(client, method.lower())(var endpoint:any=endpoint, var null:any=request_kwargs).get","sourceNodeId":"call_omc_api \\n[omc_client.py : 63_105]","targetNodeId":"/src/mcp-db-base/src/mcp_db_base/omc_client.call_omc_api.call_omc_api_scope..getattr(client, method.lower())(var endpoint:any=endpoint, var null:any=request_kwargs).get"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-db-base/src/mcp_db_base/omc_client.py"},"region":{"startLine":101,"startColumn":17,"endLine":101,"endColumn":49,"snippet":{}}}},"id":"call_omc_api \\n[omc_client.py : 63_105]->_handle_error_response \\n[omc_client.py : 142_148]","sourceNodeId":"call_omc_api \\n[omc_client.py : 63_105]","targetNodeId":"_handle_error_response \\n[omc_client.py : 142_148]"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-db-base/src/mcp_db_base/omc_client.py"},"region":{"startLine":147,"startColumn":25,"endLine":147,"endColumn":57,"snippet":{}}}},"id":"_handle_error_response \\n[omc_client.py : 142_148]->/src/mcp-db-base/src/mcp_db_base/omc_client.call_omc_api.call_omc_api_scope..getattr(client, method.lower())(var endpoint:any=endpoint, var null:any=request_kwargs).get","sourceNodeId":"_handle_error_response \\n[omc_client.py : 142_148]","targetNodeId":"/src/mcp-db-base/src/mcp_db_base/omc_client.call_omc_api.call_omc_api_scope..getattr(client, method.lower())(var endpoint:any=endpoint, var null:any=request_kwargs).get"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-db-base/src/mcp_db_base/omc_client.py"},"region":{"startLine":144,"startColumn":11,"endLine":148,"endColumn":6,"snippet":{}}}},"id":"_handle_error_response \\n[omc_client.py : 142_148]->/src/mcp-db-base/src/mcp_db_base/omc_client._handle_error_response._handle_error_response_scope..ValueError","sourceNodeId":"_handle_error_response \\n[omc_client.py : 142_148]","targetNodeId":"/src/mcp-db-base/src/mcp_db_base/omc_client._handle_error_response._handle_error_response_scope..ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-db-base/src/mcp_db_base/omc_client.py"},"region":{"startLine":105,"startColumn":55,"endLine":105,"endColumn":63,"snippet":{}}}},"id":"call_omc_api \\n[omc_client.py : 63_105]->/src/mcp-db-base/src/mcp_db_base/omc_client.call_omc_api.call_omc_api_scope...str","sourceNodeId":"call_omc_api \\n[omc_client.py : 63_105]","targetNodeId":"/src/mcp-db-base/src/mcp_db_base/omc_client.call_omc_api.call_omc_api_scope...str"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-db-base/src/mcp_db_base/omc_client.py"},"region":{"startLine":104,"startColumn":13,"endLine":104,"endColumn":55,"snippet":{}}}},"id":"call_omc_api \\n[omc_client.py : 63_105]->syslib_from.logging.getLogger(__name__).error","sourceNodeId":"call_omc_api \\n[omc_client.py : 63_105]","targetNodeId":"syslib_from.logging.getLogger(__name__).error"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-db-base/src/mcp_db_base/omc_client.py"},"region":{"startLine":105,"startColumn":19,"endLine":105,"endColumn":65,"snippet":{}}}},"id":"call_omc_api \\n[omc_client.py : 63_105]->/src/mcp-db-base/src/mcp_db_base/omc_client.call_omc_api.call_omc_api_scope...ValueError","sourceNodeId":"call_omc_api \\n[omc_client.py : 63_105]","targetNodeId":"/src/mcp-db-base/src/mcp_db_base/omc_client.call_omc_api.call_omc_api_scope...ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-db-base/src/mcp_db_base/omc_client.py"},"region":{"startLine":193,"startColumn":9,"endLine":193,"endColumn":50,"snippet":{}}}},"id":"get_dbs \\n[omc_client.py : 169_194]->syslib_from.logging.getLogger(__name__).exception","sourceNodeId":"get_dbs \\n[omc_client.py : 169_194]","targetNodeId":"syslib_from.logging.getLogger(__name__).exception"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-db-base/src/mcp_db_base/omc_client.py"},"region":{"startLine":194,"startColumn":26,"endLine":194,"endColumn":32,"snippet":{}}}},"id":"get_dbs \\n[omc_client.py : 169_194]->/src/mcp-db-base/src/mcp_db_base/omc_client.get_dbs.get_dbs_scope...str","sourceNodeId":"get_dbs \\n[omc_client.py : 169_194]","targetNodeId":"/src/mcp-db-base/src/mcp_db_base/omc_client.get_dbs.get_dbs_scope...str"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-db-base/src/mcp_db_base/omc_client.py"},"region":{"startLine":194,"startColumn":15,"endLine":194,"endColumn":33,"snippet":{}}}},"id":"get_dbs \\n[omc_client.py : 169_194]->/src/mcp-db-base/src/mcp_db_base/omc_client.get_dbs.get_dbs_scope...ValueError","sourceNodeId":"get_dbs \\n[omc_client.py : 169_194]","targetNodeId":"/src/mcp-db-base/src/mcp_db_base/omc_client.get_dbs.get_dbs_scope...ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-db-base/src/mcp_db_base/omc_client.py"},"region":{"startLine":613,"startColumn":5,"endLine":613,"endColumn":96,"snippet":{}}}},"id":"<__entry_point__>->/src/mcp-db-base/src/mcp_db_base/omc_client..print","sourceNodeId":"<__entry_point__>","targetNodeId":"/src/mcp-db-base/src/mcp_db_base/omc_client..print"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-db-base/src/mcp_db_base/prometheus_client.py"},"region":{"startLine":307,"startColumn":23,"endLine":307,"endColumn":74,"snippet":{}}}},"id":"<__entry_point__>->get_ob_capacity_monitor \\n[prometheus_client.py : 262_303]","sourceNodeId":"<__entry_point__>","targetNodeId":"get_ob_capacity_monitor \\n[prometheus_client.py : 262_303]"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-db-base/src/mcp_db_base/prometheus_client.py"},"region":{"startLine":266,"startColumn":5,"endLine":266,"endColumn":89,"snippet":{}}}},"id":"get_ob_capacity_monitor \\n[prometheus_client.py : 262_303]->syslib_from.logging.getLogger(__name__).info","sourceNodeId":"get_ob_capacity_monitor \\n[prometheus_client.py : 262_303]","targetNodeId":"syslib_from.logging.getLogger(__name__).info"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-db-base/src/mcp_db_base/prometheus_client.py"},"region":{"startLine":269,"startColumn":20,"endLine":269,"endColumn":46,"snippet":{}}}},"id":"get_ob_capacity_monitor \\n[prometheus_client.py : 262_303]->mcp_db_base.db_utils.str_to_timestamp","sourceNodeId":"get_ob_capacity_monitor \\n[prometheus_client.py : 262_303]","targetNodeId":"mcp_db_base.db_utils.str_to_timestamp"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-db-base/src/mcp_db_base/prometheus_client.py"},"region":{"startLine":271,"startColumn":30,"endLine":271,"endColumn":48,"snippet":{}}}},"id":"get_ob_capacity_monitor \\n[prometheus_client.py : 262_303]->|.join","sourceNodeId":"get_ob_capacity_monitor \\n[prometheus_client.py : 262_303]","targetNodeId":"|.join"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-db-base/src/mcp_db_base/prometheus_client.py"},"region":{"startLine":272,"startColumn":16,"endLine":272,"endColumn":29,"snippet":{}}}},"id":"get_ob_capacity_monitor \\n[prometheus_client.py : 262_303]->/src/mcp-db-base/src/mcp_db_base/prometheus_client.get_ob_capacity_monitor.get_ob_capacity_monitor_scope...len","sourceNodeId":"get_ob_capacity_monitor \\n[prometheus_client.py : 262_303]","targetNodeId":"/src/mcp-db-base/src/mcp_db_base/prometheus_client.get_ob_capacity_monitor.get_ob_capacity_monitor_scope...len"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-db-base/src/mcp_db_base/prometheus_client.py"},"region":{"startLine":287,"startColumn":13,"endLine":291,"endColumn":15,"snippet":{}}}},"id":"get_ob_capacity_monitor \\n[prometheus_client.py : 262_303]->/src/mcp-db-base/src/mcp_db_base/prometheus_client.get_ob_capacity_monitor.get_ob_capacity_monitor_scope...params.update","sourceNodeId":"get_ob_capacity_monitor \\n[prometheus_client.py : 262_303]","targetNodeId":"/src/mcp-db-base/src/mcp_db_base/prometheus_client.get_ob_capacity_monitor.get_ob_capacity_monitor_scope...params.update"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-db-base/src/mcp_db_base/prometheus_client.py"},"region":{"startLine":293,"startColumn":26,"endLine":293,"endColumn":103,"snippet":{}}}},"id":"get_ob_capacity_monitor \\n[prometheus_client.py : 262_303]->call_promtheus_api \\n[prometheus_client.py : 102_159]","sourceNodeId":"get_ob_capacity_monitor \\n[prometheus_client.py : 262_303]","targetNodeId":"call_promtheus_api \\n[prometheus_client.py : 102_159]"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-db-base/src/mcp_db_base/prometheus_client.py"},"region":{"startLine":124,"startColumn":15,"endLine":124,"endColumn":64,"snippet":{}}}},"id":"call_promtheus_api \\n[prometheus_client.py : 102_159]->get_promtheus_url \\n[prometheus_client.py : 55_76]","sourceNodeId":"call_promtheus_api \\n[prometheus_client.py : 102_159]","targetNodeId":"get_promtheus_url \\n[prometheus_client.py : 55_76]"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-db-base/src/mcp_db_base/prometheus_client.py"},"region":{"startLine":56,"startColumn":5,"endLine":56,"endColumn":54,"snippet":{}}}},"id":"get_promtheus_url \\n[prometheus_client.py : 55_76]->syslib_from.logging.getLogger(__name__).info","sourceNodeId":"get_promtheus_url \\n[prometheus_client.py : 55_76]","targetNodeId":"syslib_from.logging.getLogger(__name__).info"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-db-base/src/mcp_db_base/prometheus_client.py"},"region":{"startLine":64,"startColumn":18,"endLine":64,"endColumn":55,"snippet":{}}}},"id":"get_promtheus_url \\n[prometheus_client.py : 55_76]->query_promtheus_db \\n[prometheus_client.py : 17_52]","sourceNodeId":"get_promtheus_url \\n[prometheus_client.py : 55_76]","targetNodeId":"query_promtheus_db \\n[prometheus_client.py : 17_52]"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-db-base/src/mcp_db_base/prometheus_client.py"},"region":{"startLine":26,"startColumn":14,"endLine":34,"endColumn":10,"snippet":{}}}},"id":"query_promtheus_db \\n[prometheus_client.py : 17_52]->syslib_from.pymysql.connect","sourceNodeId":"query_promtheus_db \\n[prometheus_client.py : 17_52]","targetNodeId":"syslib_from.pymysql.connect"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-db-base/src/mcp_db_base/prometheus_client.py"},"region":{"startLine":42,"startColumn":30,"endLine":42,"endColumn":47,"snippet":{}}}},"id":"query_promtheus_db \\n[prometheus_client.py : 17_52]->syslib_from.pymysql.connect(var host:any=DB_PROXY_URL, var port:any=DB_PROXY_PORT, var user:any=USER, var password:any=PASSWORD, var database:any=ob_event_hub, var charset:any=utf8mb4, var cursorclass...","sourceNodeId":"query_promtheus_db \\n[prometheus_client.py : 17_52]","targetNodeId":"syslib_from.pymysql.connect(var host:any=DB_PROXY_URL, var port:any=DB_PROXY_PORT, var user:any=USER, var password:any=PASSWORD, var database:any=ob_event_hub, var charset:any=utf8mb4, var cursorclass..."},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-db-base/src/mcp_db_base/prometheus_client.py"},"region":{"startLine":50,"startColumn":9,"endLine":50,"endColumn":56,"snippet":{}}}},"id":"query_promtheus_db \\n[prometheus_client.py : 17_52]->syslib_from.logging.getLogger(__name__).exception","sourceNodeId":"query_promtheus_db \\n[prometheus_client.py : 17_52]","targetNodeId":"syslib_from.logging.getLogger(__name__).exception"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-db-base/src/mcp_db_base/prometheus_client.py"},"region":{"startLine":66,"startColumn":19,"endLine":66,"endColumn":76,"snippet":{}}}},"id":"get_promtheus_url \\n[prometheus_client.py : 55_76]->/src/mcp-db-base/src/mcp_db_base/prometheus_client.get_promtheus_url.get_promtheus_url_scope...ValueError","sourceNodeId":"get_promtheus_url \\n[prometheus_client.py : 55_76]","targetNodeId":"/src/mcp-db-base/src/mcp_db_base/prometheus_client.get_promtheus_url.get_promtheus_url_scope...ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-db-base/src/mcp_db_base/prometheus_client.py"},"region":{"startLine":69,"startColumn":23,"endLine":69,"endColumn":33,"snippet":{}}}},"id":"get_promtheus_url \\n[prometheus_client.py : 55_76]->/src/mcp-db-base/src/mcp_db_base/prometheus_client.query_promtheus_db.query_promtheus_db_scope..result.keys","sourceNodeId":"get_promtheus_url \\n[prometheus_client.py : 55_76]","targetNodeId":"/src/mcp-db-base/src/mcp_db_base/prometheus_client.query_promtheus_db.query_promtheus_db_scope..result.keys"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-db-base/src/mcp_db_base/prometheus_client.py"},"region":{"startLine":69,"startColumn":18,"endLine":69,"endColumn":34,"snippet":{}}}},"id":"get_promtheus_url \\n[prometheus_client.py : 55_76]->/src/mcp-db-base/src/mcp_db_base/prometheus_client.get_promtheus_url.get_promtheus_url_scope..list","sourceNodeId":"get_promtheus_url \\n[prometheus_client.py : 55_76]","targetNodeId":"/src/mcp-db-base/src/mcp_db_base/prometheus_client.get_promtheus_url.get_promtheus_url_scope..list"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-db-base/src/mcp_db_base/prometheus_client.py"},"region":{"startLine":70,"startColumn":12,"endLine":70,"endColumn":23,"snippet":{}}}},"id":"get_promtheus_url \\n[prometheus_client.py : 55_76]->/src/mcp-db-base/src/mcp_db_base/prometheus_client.get_promtheus_url.get_promtheus_url_scope..len","sourceNodeId":"get_promtheus_url \\n[prometheus_client.py : 55_76]","targetNodeId":"/src/mcp-db-base/src/mcp_db_base/prometheus_client.get_promtheus_url.get_promtheus_url_scope..len"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-db-base/src/mcp_db_base/prometheus_client.py"},"region":{"startLine":71,"startColumn":19,"endLine":71,"endColumn":87,"snippet":{}}}},"id":"get_promtheus_url \\n[prometheus_client.py : 55_76]->/src/mcp-db-base/src/mcp_db_base/prometheus_client.get_promtheus_url.get_promtheus_url_scope...ValueError","sourceNodeId":"get_promtheus_url \\n[prometheus_client.py : 55_76]","targetNodeId":"/src/mcp-db-base/src/mcp_db_base/prometheus_client.get_promtheus_url.get_promtheus_url_scope...ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-db-base/src/mcp_db_base/prometheus_client.py"},"region":{"startLine":73,"startColumn":16,"endLine":73,"endColumn":36,"snippet":{}}}},"id":"get_promtheus_url \\n[prometheus_client.py : 55_76]->/src/mcp-db-base/src/mcp_db_base/prometheus_client.query_promtheus_db.query_promtheus_db_scope..result.get","sourceNodeId":"get_promtheus_url \\n[prometheus_client.py : 55_76]","targetNodeId":"/src/mcp-db-base/src/mcp_db_base/prometheus_client.query_promtheus_db.query_promtheus_db_scope..result.get"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-db-base/src/mcp_db_base/prometheus_client.py"},"region":{"startLine":75,"startColumn":9,"endLine":75,"endColumn":55,"snippet":{}}}},"id":"get_promtheus_url \\n[prometheus_client.py : 55_76]->syslib_from.logging.getLogger(__name__).error","sourceNodeId":"get_promtheus_url \\n[prometheus_client.py : 55_76]","targetNodeId":"syslib_from.logging.getLogger(__name__).error"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-db-base/src/mcp_db_base/prometheus_client.py"},"region":{"startLine":151,"startColumn":21,"endLine":151,"endColumn":82,"snippet":{}}}},"id":"call_promtheus_api \\n[prometheus_client.py : 102_159]->syslib_from.logging.getLogger(__name__).info","sourceNodeId":"call_promtheus_api \\n[prometheus_client.py : 102_159]","targetNodeId":"syslib_from.logging.getLogger(__name__).info"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-db-base/src/mcp_db_base/prometheus_client.py"},"region":{"startLine":129,"startColumn":61,"endLine":129,"endColumn":71,"snippet":{}}}},"id":"call_promtheus_api \\n[prometheus_client.py : 102_159]->_headers \\n[prometheus_client.py : 79_81]","sourceNodeId":"call_promtheus_api \\n[prometheus_client.py : 102_159]","targetNodeId":"_headers \\n[prometheus_client.py : 79_81]"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-db-base/src/mcp_db_base/prometheus_client.py"},"region":{"startLine":131,"startColumn":20,"endLine":137,"endColumn":10,"snippet":{}}}},"id":"call_promtheus_api \\n[prometheus_client.py : 102_159]->mcp_common.request.http_client.AsyncRestClient","sourceNodeId":"call_promtheus_api \\n[prometheus_client.py : 102_159]","targetNodeId":"mcp_common.request.http_client.AsyncRestClient"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-db-base/src/mcp_db_base/prometheus_client.py"},"region":{"startLine":140,"startColumn":47,"endLine":140,"endColumn":61,"snippet":{}}}},"id":"call_promtheus_api \\n[prometheus_client.py : 102_159]->GET.lower","sourceNodeId":"call_promtheus_api \\n[prometheus_client.py : 102_159]","targetNodeId":"GET.lower"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-db-base/src/mcp_db_base/prometheus_client.py"},"region":{"startLine":140,"startColumn":31,"endLine":140,"endColumn":62,"snippet":{}}}},"id":"call_promtheus_api \\n[prometheus_client.py : 102_159]->/src/mcp-db-base/src/mcp_db_base/prometheus_client.call_promtheus_api.call_promtheus_api_scope..getattr","sourceNodeId":"call_promtheus_api \\n[prometheus_client.py : 102_159]","targetNodeId":"/src/mcp-db-base/src/mcp_db_base/prometheus_client.call_promtheus_api.call_promtheus_api_scope..getattr"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-db-base/src/mcp_db_base/prometheus_client.py"},"region":{"startLine":141,"startColumn":28,"endLine":141,"endColumn":82,"snippet":{}}}},"id":"call_promtheus_api \\n[prometheus_client.py : 102_159]->/src/mcp-db-base/src/mcp_db_base/prometheus_client.call_promtheus_api.call_promtheus_api_scope..getattr(client, method.lower())","sourceNodeId":"call_promtheus_api \\n[prometheus_client.py : 102_159]","targetNodeId":"/src/mcp-db-base/src/mcp_db_base/prometheus_client.call_promtheus_api.call_promtheus_api_scope..getattr(client, method.lower())"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-db-base/src/mcp_db_base/prometheus_client.py"},"region":{"startLine":146,"startColumn":24,"endLine":146,"endColumn":55,"snippet":{}}}},"id":"call_promtheus_api \\n[prometheus_client.py : 102_159]->/src/mcp-db-base/src/mcp_db_base/prometheus_client.call_promtheus_api.call_promtheus_api_scope...len","sourceNodeId":"call_promtheus_api \\n[prometheus_client.py : 102_159]","targetNodeId":"/src/mcp-db-base/src/mcp_db_base/prometheus_client.call_promtheus_api.call_promtheus_api_scope...len"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-db-base/src/mcp_db_base/prometheus_client.py"},"region":{"startLine":147,"startColumn":32,"endLine":147,"endColumn":64,"snippet":{}}}},"id":"call_promtheus_api \\n[prometheus_client.py : 102_159]->_handle_empty_response \\n[prometheus_client.py : 84_90]","sourceNodeId":"call_promtheus_api \\n[prometheus_client.py : 102_159]","targetNodeId":"_handle_empty_response \\n[prometheus_client.py : 84_90]"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-db-base/src/mcp_db_base/prometheus_client.py"},"region":{"startLine":89,"startColumn":25,"endLine":89,"endColumn":55,"snippet":{}}}},"id":"_handle_empty_response \\n[prometheus_client.py : 84_90]->/src/mcp-db-base/src/mcp_db_base/prometheus_client.call_promtheus_api.call_promtheus_api_scope..getattr(client, method.lower())(var endpoint:any=endpoint, var null:any=request_kwar...","sourceNodeId":"_handle_empty_response \\n[prometheus_client.py : 84_90]","targetNodeId":"/src/mcp-db-base/src/mcp_db_base/prometheus_client.call_promtheus_api.call_promtheus_api_scope..getattr(client, method.lower())(var endpoint:any=endpoint, var null:any=request_kwar..."},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-db-base/src/mcp_db_base/prometheus_client.py"},"region":{"startLine":152,"startColumn":21,"endLine":152,"endColumn":53,"snippet":{}}}},"id":"call_promtheus_api \\n[prometheus_client.py : 102_159]->_handle_error_response \\n[prometheus_client.py : 93_99]","sourceNodeId":"call_promtheus_api \\n[prometheus_client.py : 102_159]","targetNodeId":"_handle_error_response \\n[prometheus_client.py : 93_99]"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-db-base/src/mcp_db_base/prometheus_client.py"},"region":{"startLine":98,"startColumn":25,"endLine":98,"endColumn":55,"snippet":{}}}},"id":"_handle_error_response \\n[prometheus_client.py : 93_99]->/src/mcp-db-base/src/mcp_db_base/prometheus_client.call_promtheus_api.call_promtheus_api_scope..getattr(client, method.lower())(var endpoint:any=endpoint, var null:any=request_kwar...","sourceNodeId":"_handle_error_response \\n[prometheus_client.py : 93_99]","targetNodeId":"/src/mcp-db-base/src/mcp_db_base/prometheus_client.call_promtheus_api.call_promtheus_api_scope..getattr(client, method.lower())(var endpoint:any=endpoint, var null:any=request_kwar..."},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-db-base/src/mcp_db_base/prometheus_client.py"},"region":{"startLine":95,"startColumn":11,"endLine":99,"endColumn":6,"snippet":{}}}},"id":"_handle_error_response \\n[prometheus_client.py : 93_99]->/src/mcp-db-base/src/mcp_db_base/prometheus_client._handle_error_response._handle_error_response_scope..ValueError","sourceNodeId":"_handle_error_response \\n[prometheus_client.py : 93_99]","targetNodeId":"/src/mcp-db-base/src/mcp_db_base/prometheus_client._handle_error_response._handle_error_response_scope..ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-db-base/src/mcp_db_base/prometheus_client.py"},"region":{"startLine":156,"startColumn":65,"endLine":156,"endColumn":73,"snippet":{}}}},"id":"call_promtheus_api \\n[prometheus_client.py : 102_159]->/src/mcp-db-base/src/mcp_db_base/prometheus_client.call_promtheus_api.call_promtheus_api_scope...str","sourceNodeId":"call_promtheus_api \\n[prometheus_client.py : 102_159]","targetNodeId":"/src/mcp-db-base/src/mcp_db_base/prometheus_client.call_promtheus_api.call_promtheus_api_scope...str"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-db-base/src/mcp_db_base/prometheus_client.py"},"region":{"startLine":155,"startColumn":17,"endLine":155,"endColumn":59,"snippet":{}}}},"id":"call_promtheus_api \\n[prometheus_client.py : 102_159]->syslib_from.logging.getLogger(__name__).error","sourceNodeId":"call_promtheus_api \\n[prometheus_client.py : 102_159]","targetNodeId":"syslib_from.logging.getLogger(__name__).error"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-db-base/src/mcp_db_base/prometheus_client.py"},"region":{"startLine":156,"startColumn":23,"endLine":156,"endColumn":75,"snippet":{}}}},"id":"call_promtheus_api \\n[prometheus_client.py : 102_159]->/src/mcp-db-base/src/mcp_db_base/prometheus_client.call_promtheus_api.call_promtheus_api_scope...ValueError","sourceNodeId":"call_promtheus_api \\n[prometheus_client.py : 102_159]","targetNodeId":"/src/mcp-db-base/src/mcp_db_base/prometheus_client.call_promtheus_api.call_promtheus_api_scope...ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-db-base/src/mcp_db_base/prometheus_client.py"},"region":{"startLine":158,"startColumn":56,"endLine":158,"endColumn":64,"snippet":{}}}},"id":"call_promtheus_api \\n[prometheus_client.py : 102_159]->/src/mcp-db-base/src/mcp_db_base/prometheus_client.call_promtheus_api.call_promtheus_api_scope...str","sourceNodeId":"call_promtheus_api \\n[prometheus_client.py : 102_159]","targetNodeId":"/src/mcp-db-base/src/mcp_db_base/prometheus_client.call_promtheus_api.call_promtheus_api_scope...str"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-db-base/src/mcp_db_base/prometheus_client.py"},"region":{"startLine":158,"startColumn":9,"endLine":158,"endColumn":69,"snippet":{}}}},"id":"call_promtheus_api \\n[prometheus_client.py : 102_159]->syslib_from.logging.getLogger(__name__).exception","sourceNodeId":"call_promtheus_api \\n[prometheus_client.py : 102_159]","targetNodeId":"syslib_from.logging.getLogger(__name__).exception"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-db-base/src/mcp_db_base/prometheus_client.py"},"region":{"startLine":297,"startColumn":23,"endLine":297,"endColumn":55,"snippet":{}}}},"id":"get_ob_capacity_monitor \\n[prometheus_client.py : 262_303]->tidy_serial_data \\n[prometheus_client.py : 172_219]","sourceNodeId":"get_ob_capacity_monitor \\n[prometheus_client.py : 262_303]","targetNodeId":"tidy_serial_data \\n[prometheus_client.py : 172_219]"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-db-base/src/mcp_db_base/prometheus_client.py"},"region":{"startLine":174,"startColumn":8,"endLine":174,"endColumn":39,"snippet":{}}}},"id":"tidy_serial_data \\n[prometheus_client.py : 172_219]->/src/mcp-db-base/src/mcp_db_base/prometheus_client.tidy_serial_data.tidy_serial_data_scope..isinstance","sourceNodeId":"tidy_serial_data \\n[prometheus_client.py : 172_219]","targetNodeId":"/src/mcp-db-base/src/mcp_db_base/prometheus_client.tidy_serial_data.tidy_serial_data_scope..isinstance"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-db-base/src/mcp_db_base/prometheus_client.py"},"region":{"startLine":181,"startColumn":17,"endLine":181,"endColumn":40,"snippet":{}}}},"id":"tidy_serial_data \\n[prometheus_client.py : 172_219]->get","sourceNodeId":"tidy_serial_data \\n[prometheus_client.py : 172_219]","targetNodeId":"get"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-db-base/src/mcp_db_base/prometheus_client.py"},"region":{"startLine":205,"startColumn":30,"endLine":205,"endColumn":49,"snippet":{}}}},"id":"tidy_serial_data \\n[prometheus_client.py : 172_219]->/src/mcp-db-base/src/mcp_db_base/prometheus_client.call_promtheus_api.call_promtheus_api_scope..getattr(client, method.lower())(var endpoint:any=endpoint, var null:any=request_kwar...","sourceNodeId":"tidy_serial_data \\n[prometheus_client.py : 172_219]","targetNodeId":"/src/mcp-db-base/src/mcp_db_base/prometheus_client.call_promtheus_api.call_promtheus_api_scope..getattr(client, method.lower())(var endpoint:any=endpoint, var null:any=request_kwar..."},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-db-base/src/mcp_db_base/prometheus_client.py"},"region":{"startLine":205,"startColumn":30,"endLine":205,"endColumn":49,"snippet":{}}}},"id":"tidy_serial_data \\n[prometheus_client.py : 172_219]->metric.get","sourceNodeId":"tidy_serial_data \\n[prometheus_client.py : 172_219]","targetNodeId":"metric.get"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-db-base/src/mcp_db_base/prometheus_client.py"},"region":{"startLine":195,"startColumn":17,"endLine":198,"endColumn":19,"snippet":{}}}},"id":"tidy_serial_data \\n[prometheus_client.py : 172_219]->values_infos.append","sourceNodeId":"tidy_serial_data \\n[prometheus_client.py : 172_219]","targetNodeId":"values_infos.append"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-db-base/src/mcp_db_base/prometheus_client.py"},"region":{"startLine":215,"startColumn":17,"endLine":218,"endColumn":19,"snippet":{}}}},"id":"tidy_serial_data \\n[prometheus_client.py : 172_219]->append","sourceNodeId":"tidy_serial_data \\n[prometheus_client.py : 172_219]","targetNodeId":"append"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-db-base/src/mcp_db_base/prometheus_client.py"},"region":{"startLine":202,"startColumn":17,"endLine":202,"endColumn":61,"snippet":{}}}},"id":"tidy_serial_data \\n[prometheus_client.py : 172_219]->extend","sourceNodeId":"tidy_serial_data \\n[prometheus_client.py : 172_219]","targetNodeId":"extend"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-db-base/src/mcp_db_base/prometheus_client.py"},"region":{"startLine":302,"startColumn":9,"endLine":302,"endColumn":65,"snippet":{}}}},"id":"get_ob_capacity_monitor \\n[prometheus_client.py : 262_303]->syslib_from.logging.getLogger(__name__).exception","sourceNodeId":"get_ob_capacity_monitor \\n[prometheus_client.py : 262_303]","targetNodeId":"syslib_from.logging.getLogger(__name__).exception"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-db-base/src/mcp_db_base/prometheus_client.py"},"region":{"startLine":303,"startColumn":26,"endLine":303,"endColumn":32,"snippet":{}}}},"id":"get_ob_capacity_monitor \\n[prometheus_client.py : 262_303]->/src/mcp-db-base/src/mcp_db_base/prometheus_client.get_ob_capacity_monitor.get_ob_capacity_monitor_scope...str","sourceNodeId":"get_ob_capacity_monitor \\n[prometheus_client.py : 262_303]","targetNodeId":"/src/mcp-db-base/src/mcp_db_base/prometheus_client.get_ob_capacity_monitor.get_ob_capacity_monitor_scope...str"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-db-base/src/mcp_db_base/prometheus_client.py"},"region":{"startLine":303,"startColumn":15,"endLine":303,"endColumn":33,"snippet":{}}}},"id":"get_ob_capacity_monitor \\n[prometheus_client.py : 262_303]->/src/mcp-db-base/src/mcp_db_base/prometheus_client.get_ob_capacity_monitor.get_ob_capacity_monitor_scope...ValueError","sourceNodeId":"get_ob_capacity_monitor \\n[prometheus_client.py : 262_303]","targetNodeId":"/src/mcp-db-base/src/mcp_db_base/prometheus_client.get_ob_capacity_monitor.get_ob_capacity_monitor_scope...ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-db-base/src/mcp_db_base/prometheus_client.py"},"region":{"startLine":307,"startColumn":5,"endLine":307,"endColumn":76,"snippet":{}}}},"id":"<__entry_point__>->/src/mcp-db-base/src/mcp_db_base/prometheus_client..print","sourceNodeId":"<__entry_point__>","targetNodeId":"/src/mcp-db-base/src/mcp_db_base/prometheus_client..print"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-db-base/src/mcp_db_base/pydantic_extend.py"},"region":{"startLine":5,"startColumn":4,"endLine":5,"endColumn":37,"snippet":{}}}},"id":"<__entry_point__>->syslib_from.pydantic.VERSION.startswith","sourceNodeId":"<__entry_point__>","targetNodeId":"syslib_from.pydantic.VERSION.startswith"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-db-base/src/mcp_db_base/pydantic_extend.py"},"region":{"startLine":7,"startColumn":11,"endLine":7,"endColumn":87,"snippet":{}}}},"id":"<__entry_point__>->/src/mcp-db-base/src/mcp_db_base/pydantic_extend..NotImplementedError","sourceNodeId":"<__entry_point__>","targetNodeId":"/src/mcp-db-base/src/mcp_db_base/pydantic_extend..NotImplementedError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-db-base/src/mcp_db_base/tars_client.py"},"region":{"startLine":408,"startColumn":34,"endLine":409,"endColumn":73,"snippet":{}}}},"id":"<__entry_point__>->get_top_sql \\n[tars_client.py : 203_228]","sourceNodeId":"<__entry_point__>","targetNodeId":"get_top_sql \\n[tars_client.py : 203_228]"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-db-base/src/mcp_db_base/tars_client.py"},"region":{"startLine":206,"startColumn":5,"endLine":206,"endColumn":75,"snippet":{}}}},"id":"get_top_sql \\n[tars_client.py : 203_228]->syslib_from.logging.getLogger(__name__).info","sourceNodeId":"get_top_sql \\n[tars_client.py : 203_228]","targetNodeId":"syslib_from.logging.getLogger(__name__).info"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-db-base/src/mcp_db_base/tars_client.py"},"region":{"startLine":212,"startColumn":29,"endLine":212,"endColumn":55,"snippet":{}}}},"id":"get_top_sql \\n[tars_client.py : 203_228]->mcp_db_base.db_utils.str_to_timestamp","sourceNodeId":"get_top_sql \\n[tars_client.py : 203_228]","targetNodeId":"mcp_db_base.db_utils.str_to_timestamp"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-db-base/src/mcp_db_base/tars_client.py"},"region":{"startLine":217,"startColumn":19,"endLine":217,"endColumn":93,"snippet":{}}}},"id":"get_top_sql \\n[tars_client.py : 203_228]->/src/mcp-db-base/src/mcp_db_base/tars_client.get_top_sql.get_top_sql_scope...ValueError","sourceNodeId":"get_top_sql \\n[tars_client.py : 203_228]","targetNodeId":"/src/mcp-db-base/src/mcp_db_base/tars_client.get_top_sql.get_top_sql_scope...ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-db-base/src/mcp_db_base/tars_client.py"},"region":{"startLine":223,"startColumn":13,"endLine":223,"endColumn":45,"snippet":{}}}},"id":"get_top_sql \\n[tars_client.py : 203_228]->params.update","sourceNodeId":"get_top_sql \\n[tars_client.py : 203_228]","targetNodeId":"params.update"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-db-base/src/mcp_db_base/tars_client.py"},"region":{"startLine":225,"startColumn":16,"endLine":225,"endColumn":49,"snippet":{}}}},"id":"get_top_sql \\n[tars_client.py : 203_228]->_top_sql \\n[tars_client.py : 141_200]","sourceNodeId":"get_top_sql \\n[tars_client.py : 203_228]","targetNodeId":"_top_sql \\n[tars_client.py : 141_200]"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-db-base/src/mcp_db_base/tars_client.py"},"region":{"startLine":158,"startColumn":5,"endLine":158,"endColumn":73,"snippet":{}}}},"id":"_top_sql \\n[tars_client.py : 141_200]->syslib_from.logging.getLogger(__name__).info","sourceNodeId":"_top_sql \\n[tars_client.py : 141_200]","targetNodeId":"syslib_from.logging.getLogger(__name__).info"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-db-base/src/mcp_db_base/tars_client.py"},"region":{"startLine":143,"startColumn":22,"endLine":143,"endColumn":49,"snippet":{}}}},"id":"_top_sql \\n[tars_client.py : 141_200]->params.get","sourceNodeId":"_top_sql \\n[tars_client.py : 141_200]","targetNodeId":"params.get"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-db-base/src/mcp_db_base/tars_client.py"},"region":{"startLine":150,"startColumn":87,"endLine":150,"endColumn":97,"snippet":{}}}},"id":"_top_sql \\n[tars_client.py : 141_200]->_headers \\n[tars_client.py : 29_36]","sourceNodeId":"_top_sql \\n[tars_client.py : 141_200]","targetNodeId":"_headers \\n[tars_client.py : 29_36]"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-db-base/src/mcp_db_base/tars_client.py"},"region":{"startLine":30,"startColumn":18,"endLine":30,"endColumn":46,"snippet":{}}}},"id":"_headers \\n[tars_client.py : 29_36]->syslib_from.os.environ.get","sourceNodeId":"_headers \\n[tars_client.py : 29_36]","targetNodeId":"syslib_from.os.environ.get"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-db-base/src/mcp_db_base/tars_client.py"},"region":{"startLine":32,"startColumn":18,"endLine":32,"endColumn":46,"snippet":{}}}},"id":"_headers \\n[tars_client.py : 29_36]->syslib_from.base64.b64decode","sourceNodeId":"_headers \\n[tars_client.py : 29_36]","targetNodeId":"syslib_from.base64.b64decode"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-db-base/src/mcp_db_base/tars_client.py"},"region":{"startLine":32,"startColumn":18,"endLine":32,"endColumn":62,"snippet":{}}}},"id":"_headers \\n[tars_client.py : 29_36]->syslib_from.base64.b64decode(TARS_TOKEN).decode","sourceNodeId":"_headers \\n[tars_client.py : 29_36]","targetNodeId":"syslib_from.base64.b64decode(TARS_TOKEN).decode"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-db-base/src/mcp_db_base/tars_client.py"},"region":{"startLine":150,"startColumn":27,"endLine":150,"endColumn":116,"snippet":{}}}},"id":"_top_sql \\n[tars_client.py : 141_200]->call_tars_api \\n[tars_client.py : 53_104]","sourceNodeId":"_top_sql \\n[tars_client.py : 141_200]","targetNodeId":"call_tars_api \\n[tars_client.py : 53_104]"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-db-base/src/mcp_db_base/tars_client.py"},"region":{"startLine":74,"startColumn":57,"endLine":74,"endColumn":67,"snippet":{}}}},"id":"call_tars_api \\n[tars_client.py : 53_104]->_headers \\n[tars_client.py : 29_36]","sourceNodeId":"call_tars_api \\n[tars_client.py : 53_104]","targetNodeId":"_headers \\n[tars_client.py : 29_36]"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-db-base/src/mcp_db_base/tars_client.py"},"region":{"startLine":77,"startColumn":22,"endLine":77,"endColumn":40,"snippet":{}}}},"id":"call_tars_api \\n[tars_client.py : 53_104]->get_url \\n[tars_client.py : 49_50]","sourceNodeId":"call_tars_api \\n[tars_client.py : 53_104]","targetNodeId":"get_url \\n[tars_client.py : 49_50]"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-db-base/src/mcp_db_base/tars_client.py"},"region":{"startLine":76,"startColumn":16,"endLine":82,"endColumn":6,"snippet":{}}}},"id":"call_tars_api \\n[tars_client.py : 53_104]->mcp_common.request.http_client.AsyncRestClient","sourceNodeId":"call_tars_api \\n[tars_client.py : 53_104]","targetNodeId":"mcp_common.request.http_client.AsyncRestClient"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-db-base/src/mcp_db_base/tars_client.py"},"region":{"startLine":85,"startColumn":43,"endLine":85,"endColumn":57,"snippet":{}}}},"id":"call_tars_api \\n[tars_client.py : 53_104]->GET.lower","sourceNodeId":"call_tars_api \\n[tars_client.py : 53_104]","targetNodeId":"GET.lower"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-db-base/src/mcp_db_base/tars_client.py"},"region":{"startLine":85,"startColumn":27,"endLine":85,"endColumn":58,"snippet":{}}}},"id":"call_tars_api \\n[tars_client.py : 53_104]->/src/mcp-db-base/src/mcp_db_base/tars_client.call_tars_api.call_tars_api_scope..getattr","sourceNodeId":"call_tars_api \\n[tars_client.py : 53_104]","targetNodeId":"/src/mcp-db-base/src/mcp_db_base/tars_client.call_tars_api.call_tars_api_scope..getattr"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-db-base/src/mcp_db_base/tars_client.py"},"region":{"startLine":86,"startColumn":24,"endLine":86,"endColumn":78,"snippet":{}}}},"id":"call_tars_api \\n[tars_client.py : 53_104]->/src/mcp-db-base/src/mcp_db_base/tars_client.call_tars_api.call_tars_api_scope..getattr(client, method.lower())","sourceNodeId":"call_tars_api \\n[tars_client.py : 53_104]","targetNodeId":"/src/mcp-db-base/src/mcp_db_base/tars_client.call_tars_api.call_tars_api_scope..getattr(client, method.lower())"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-db-base/src/mcp_db_base/tars_client.py"},"region":{"startLine":87,"startColumn":16,"endLine":87,"endColumn":42,"snippet":{}}}},"id":"call_tars_api \\n[tars_client.py : 53_104]->/src/mcp-db-base/src/mcp_db_base/tars_client.call_tars_api.call_tars_api_scope..isinstance","sourceNodeId":"call_tars_api \\n[tars_client.py : 53_104]","targetNodeId":"/src/mcp-db-base/src/mcp_db_base/tars_client.call_tars_api.call_tars_api_scope..isinstance"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-db-base/src/mcp_db_base/tars_client.py"},"region":{"startLine":90,"startColumn":52,"endLine":90,"endColumn":74,"snippet":{}}}},"id":"call_tars_api \\n[tars_client.py : 53_104]->/src/mcp-db-base/src/mcp_db_base/tars_client.call_tars_api.call_tars_api_scope..getattr(client, method.lower())(var endpoint:any=endpoint, var null:any=request_kwargs).get","sourceNodeId":"call_tars_api \\n[tars_client.py : 53_104]","targetNodeId":"/src/mcp-db-base/src/mcp_db_base/tars_client.call_tars_api.call_tars_api_scope..getattr(client, method.lower())(var endpoint:any=endpoint, var null:any=request_kwargs).get"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-db-base/src/mcp_db_base/tars_client.py"},"region":{"startLine":98,"startColumn":70,"endLine":98,"endColumn":98,"snippet":{}}}},"id":"call_tars_api \\n[tars_client.py : 53_104]->_handle_empty_response \\n[tars_client.py : 107_109]","sourceNodeId":"call_tars_api \\n[tars_client.py : 53_104]","targetNodeId":"_handle_empty_response \\n[tars_client.py : 107_109]"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-db-base/src/mcp_db_base/tars_client.py"},"region":{"startLine":100,"startColumn":21,"endLine":100,"endColumn":49,"snippet":{}}}},"id":"call_tars_api \\n[tars_client.py : 53_104]->_handle_error_response \\n[tars_client.py : 111_117]","sourceNodeId":"call_tars_api \\n[tars_client.py : 53_104]","targetNodeId":"_handle_error_response \\n[tars_client.py : 111_117]"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-db-base/src/mcp_db_base/tars_client.py"},"region":{"startLine":116,"startColumn":25,"endLine":116,"endColumn":65,"snippet":{}}}},"id":"_handle_error_response \\n[tars_client.py : 111_117]->/src/mcp-db-base/src/mcp_db_base/tars_client.call_tars_api.call_tars_api_scope..getattr(client, method.lower())(var endpoint:any=endpoint, var null:any=request_kwargs).get","sourceNodeId":"_handle_error_response \\n[tars_client.py : 111_117]","targetNodeId":"/src/mcp-db-base/src/mcp_db_base/tars_client.call_tars_api.call_tars_api_scope..getattr(client, method.lower())(var endpoint:any=endpoint, var null:any=request_kwargs).get"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-db-base/src/mcp_db_base/tars_client.py"},"region":{"startLine":116,"startColumn":50,"endLine":116,"endColumn":63,"snippet":{}}}},"id":"_handle_error_response \\n[tars_client.py : 111_117]->/src/mcp-db-base/src/mcp_db_base/tars_client._handle_error_response._handle_error_response_scope..str","sourceNodeId":"_handle_error_response \\n[tars_client.py : 111_117]","targetNodeId":"/src/mcp-db-base/src/mcp_db_base/tars_client._handle_error_response._handle_error_response_scope..str"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-db-base/src/mcp_db_base/tars_client.py"},"region":{"startLine":113,"startColumn":11,"endLine":117,"endColumn":6,"snippet":{}}}},"id":"_handle_error_response \\n[tars_client.py : 111_117]->/src/mcp-db-base/src/mcp_db_base/tars_client._handle_error_response._handle_error_response_scope..ValueError","sourceNodeId":"_handle_error_response \\n[tars_client.py : 111_117]","targetNodeId":"/src/mcp-db-base/src/mcp_db_base/tars_client._handle_error_response._handle_error_response_scope..ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-db-base/src/mcp_db_base/tars_client.py"},"region":{"startLine":96,"startColumn":24,"endLine":96,"endColumn":49,"snippet":{}}}},"id":"call_tars_api \\n[tars_client.py : 53_104]->syslib_from.demjson3.decode","sourceNodeId":"call_tars_api \\n[tars_client.py : 53_104]","targetNodeId":"syslib_from.demjson3.decode"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-db-base/src/mcp_db_base/tars_client.py"},"region":{"startLine":98,"startColumn":48,"endLine":98,"endColumn":66,"snippet":{}}}},"id":"call_tars_api \\n[tars_client.py : 53_104]->syslib_from.demjson3.decode(response).get","sourceNodeId":"call_tars_api \\n[tars_client.py : 53_104]","targetNodeId":"syslib_from.demjson3.decode(response).get"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-db-base/src/mcp_db_base/tars_client.py"},"region":{"startLine":116,"startColumn":25,"endLine":116,"endColumn":65,"snippet":{}}}},"id":"_handle_error_response \\n[tars_client.py : 111_117]->syslib_from.demjson3.decode(response).get","sourceNodeId":"_handle_error_response \\n[tars_client.py : 111_117]","targetNodeId":"syslib_from.demjson3.decode(response).get"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-db-base/src/mcp_db_base/tars_client.py"},"region":{"startLine":104,"startColumn":56,"endLine":104,"endColumn":64,"snippet":{}}}},"id":"call_tars_api \\n[tars_client.py : 53_104]->/src/mcp-db-base/src/mcp_db_base/tars_client.call_tars_api.call_tars_api_scope...str","sourceNodeId":"call_tars_api \\n[tars_client.py : 53_104]","targetNodeId":"/src/mcp-db-base/src/mcp_db_base/tars_client.call_tars_api.call_tars_api_scope...str"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-db-base/src/mcp_db_base/tars_client.py"},"region":{"startLine":103,"startColumn":13,"endLine":103,"endColumn":55,"snippet":{}}}},"id":"call_tars_api \\n[tars_client.py : 53_104]->syslib_from.logging.getLogger(__name__).error","sourceNodeId":"call_tars_api \\n[tars_client.py : 53_104]","targetNodeId":"syslib_from.logging.getLogger(__name__).error"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-db-base/src/mcp_db_base/tars_client.py"},"region":{"startLine":104,"startColumn":19,"endLine":104,"endColumn":66,"snippet":{}}}},"id":"call_tars_api \\n[tars_client.py : 53_104]->/src/mcp-db-base/src/mcp_db_base/tars_client.call_tars_api.call_tars_api_scope...ValueError","sourceNodeId":"call_tars_api \\n[tars_client.py : 53_104]","targetNodeId":"/src/mcp-db-base/src/mcp_db_base/tars_client.call_tars_api.call_tars_api_scope...ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-db-base/src/mcp_db_base/tars_client.py"},"region":{"startLine":151,"startColumn":20,"endLine":151,"endColumn":53,"snippet":{}}}},"id":"_top_sql \\n[tars_client.py : 141_200]->get","sourceNodeId":"_top_sql \\n[tars_client.py : 141_200]","targetNodeId":"get"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-db-base/src/mcp_db_base/tars_client.py"},"region":{"startLine":148,"startColumn":21,"endLine":148,"endColumn":34,"snippet":{}}}},"id":"_top_sql \\n[tars_client.py : 141_200]->params.copy","sourceNodeId":"_top_sql \\n[tars_client.py : 141_200]","targetNodeId":"params.copy"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-db-base/src/mcp_db_base/tars_client.py"},"region":{"startLine":158,"startColumn":56,"endLine":158,"endColumn":71,"snippet":{}}}},"id":"_top_sql \\n[tars_client.py : 141_200]->/src/mcp-db-base/src/mcp_db_base/tars_client._top_sql._top_sql_scope..len","sourceNodeId":"_top_sql \\n[tars_client.py : 141_200]","targetNodeId":"/src/mcp-db-base/src/mcp_db_base/tars_client._top_sql._top_sql_scope..len"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-db-base/src/mcp_db_base/tars_client.py"},"region":{"startLine":159,"startColumn":56,"endLine":159,"endColumn":80,"snippet":{}}}},"id":"_top_sql \\n[tars_client.py : 141_200]->get(result, {}).get","sourceNodeId":"_top_sql \\n[tars_client.py : 141_200]","targetNodeId":"get(result, {}).get"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-db-base/src/mcp_db_base/tars_client.py"},"region":{"startLine":159,"startColumn":20,"endLine":159,"endColumn":102,"snippet":{}}}},"id":"_top_sql \\n[tars_client.py : 141_200]->/src/mcp-db-base/src/mcp_db_base/tars_client._top_sql._top_sql_scope..sum","sourceNodeId":"_top_sql \\n[tars_client.py : 141_200]","targetNodeId":"/src/mcp-db-base/src/mcp_db_base/tars_client._top_sql._top_sql_scope..sum"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-db-base/src/mcp_db_base/tars_client.py"},"region":{"startLine":160,"startColumn":16,"endLine":161,"endColumn":36,"snippet":{}}}},"id":"_top_sql \\n[tars_client.py : 141_200]->/src/mcp-db-base/src/mcp_db_base/tars_client._top_sql._top_sql_scope..sorted","sourceNodeId":"_top_sql \\n[tars_client.py : 141_200]","targetNodeId":"/src/mcp-db-base/src/mcp_db_base/tars_client._top_sql._top_sql_scope..sorted"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-db-base/src/mcp_db_base/tars_client.py"},"region":{"startLine":160,"startColumn":16,"endLine":161,"endColumn":36,"snippet":{}}}},"id":"/src/mcp-db-base/src/mcp_db_base/tars_client._top_sql._top_sql_scope..sorted->/src/mcp-db-base/src/mcp_db_base/tars_client._top_sql._top_sql_scope.. \\n[tars_client.py : 160_160]","sourceNodeId":"/src/mcp-db-base/src/mcp_db_base/tars_client._top_sql._top_sql_scope..sorted","targetNodeId":"/src/mcp-db-base/src/mcp_db_base/tars_client._top_sql._top_sql_scope.. \\n[tars_client.py : 160_160]"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-db-base/src/mcp_db_base/tars_client.py"},"region":{"startLine":160,"startColumn":76,"endLine":160,"endColumn":97,"snippet":{}}}},"id":"/src/mcp-db-base/src/mcp_db_base/tars_client._top_sql._top_sql_scope.. \\n[tars_client.py : 160_160]->x.get","sourceNodeId":"/src/mcp-db-base/src/mcp_db_base/tars_client._top_sql._top_sql_scope.. \\n[tars_client.py : 160_160]","targetNodeId":"x.get"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-db-base/src/mcp_db_base/tars_client.py"},"region":{"startLine":196,"startColumn":26,"endLine":196,"endColumn":56,"snippet":{}}}},"id":"_top_sql \\n[tars_client.py : 141_200]->/src/mcp-db-base/src/mcp_db_base/tars_client._top_sql._top_sql_scope..sorted(sql_list, var key:any=function (var x:any){return x.get(executionCount, 0)*x.get(cpuTimeMs, 0)}, var r...","sourceNodeId":"_top_sql \\n[tars_client.py : 141_200]","targetNodeId":"/src/mcp-db-base/src/mcp_db_base/tars_client._top_sql._top_sql_scope..sorted(sql_list, var key:any=function (var x:any){return x.get(executionCount, 0)*x.get(cpuTimeMs, 0)}, var r..."},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-db-base/src/mcp_db_base/tars_client.py"},"region":{"startLine":165,"startColumn":29,"endLine":165,"endColumn":72,"snippet":{}}}},"id":"_top_sql \\n[tars_client.py : 141_200]->get_sql_detail \\n[tars_client.py : 288_295]","sourceNodeId":"_top_sql \\n[tars_client.py : 141_200]","targetNodeId":"get_sql_detail \\n[tars_client.py : 288_295]"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-db-base/src/mcp_db_base/tars_client.py"},"region":{"startLine":290,"startColumn":5,"endLine":290,"endColumn":57,"snippet":{}}}},"id":"get_sql_detail \\n[tars_client.py : 288_295]->syslib_from.logging.getLogger(__name__).info","sourceNodeId":"get_sql_detail \\n[tars_client.py : 288_295]","targetNodeId":"syslib_from.logging.getLogger(__name__).info"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-db-base/src/mcp_db_base/tars_client.py"},"region":{"startLine":292,"startColumn":86,"endLine":292,"endColumn":96,"snippet":{}}}},"id":"get_sql_detail \\n[tars_client.py : 288_295]->_headers \\n[tars_client.py : 29_36]","sourceNodeId":"get_sql_detail \\n[tars_client.py : 288_295]","targetNodeId":"_headers \\n[tars_client.py : 29_36]"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-db-base/src/mcp_db_base/tars_client.py"},"region":{"startLine":292,"startColumn":16,"endLine":292,"endColumn":108,"snippet":{}}}},"id":"get_sql_detail \\n[tars_client.py : 288_295]->call_tars_api \\n[tars_client.py : 53_104]","sourceNodeId":"get_sql_detail \\n[tars_client.py : 288_295]","targetNodeId":"call_tars_api \\n[tars_client.py : 53_104]"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-db-base/src/mcp_db_base/tars_client.py"},"region":{"startLine":294,"startColumn":9,"endLine":294,"endColumn":57,"snippet":{}}}},"id":"get_sql_detail \\n[tars_client.py : 288_295]->syslib_from.logging.getLogger(__name__).exception","sourceNodeId":"get_sql_detail \\n[tars_client.py : 288_295]","targetNodeId":"syslib_from.logging.getLogger(__name__).exception"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-db-base/src/mcp_db_base/tars_client.py"},"region":{"startLine":295,"startColumn":26,"endLine":295,"endColumn":32,"snippet":{}}}},"id":"get_sql_detail \\n[tars_client.py : 288_295]->/src/mcp-db-base/src/mcp_db_base/tars_client.get_sql_detail.get_sql_detail_scope...str","sourceNodeId":"get_sql_detail \\n[tars_client.py : 288_295]","targetNodeId":"/src/mcp-db-base/src/mcp_db_base/tars_client.get_sql_detail.get_sql_detail_scope...str"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-db-base/src/mcp_db_base/tars_client.py"},"region":{"startLine":295,"startColumn":15,"endLine":295,"endColumn":33,"snippet":{}}}},"id":"get_sql_detail \\n[tars_client.py : 288_295]->/src/mcp-db-base/src/mcp_db_base/tars_client.get_sql_detail.get_sql_detail_scope...ValueError","sourceNodeId":"get_sql_detail \\n[tars_client.py : 288_295]","targetNodeId":"/src/mcp-db-base/src/mcp_db_base/tars_client.get_sql_detail.get_sql_detail_scope...ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-db-base/src/mcp_db_base/tars_client.py"},"region":{"startLine":166,"startColumn":17,"endLine":166,"endColumn":52,"snippet":{}}}},"id":"_top_sql \\n[tars_client.py : 141_200]->syslib_from.asyncio.gather","sourceNodeId":"_top_sql \\n[tars_client.py : 141_200]","targetNodeId":"syslib_from.asyncio.gather"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-db-base/src/mcp_db_base/tars_client.py"},"region":{"startLine":178,"startColumn":36,"endLine":178,"endColumn":63,"snippet":{}}}},"id":"_top_sql \\n[tars_client.py : 141_200]->{:.2%}.format","sourceNodeId":"_top_sql \\n[tars_client.py : 141_200]","targetNodeId":"{:.2%}.format"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-db-base/src/mcp_db_base/tars_client.py"},"region":{"startLine":184,"startColumn":26,"endLine":184,"endColumn":49,"snippet":{}}}},"id":"_top_sql \\n[tars_client.py : 141_200]->top_five.get.sqlId.get","sourceNodeId":"_top_sql \\n[tars_client.py : 141_200]","targetNodeId":"top_five.get.sqlId.get"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-db-base/src/mcp_db_base/tars_client.py"},"region":{"startLine":227,"startColumn":9,"endLine":227,"endColumn":54,"snippet":{}}}},"id":"get_top_sql \\n[tars_client.py : 203_228]->syslib_from.logging.getLogger(__name__).exception","sourceNodeId":"get_top_sql \\n[tars_client.py : 203_228]","targetNodeId":"syslib_from.logging.getLogger(__name__).exception"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-db-base/src/mcp_db_base/tars_client.py"},"region":{"startLine":228,"startColumn":26,"endLine":228,"endColumn":32,"snippet":{}}}},"id":"get_top_sql \\n[tars_client.py : 203_228]->/src/mcp-db-base/src/mcp_db_base/tars_client.get_top_sql.get_top_sql_scope...str","sourceNodeId":"get_top_sql \\n[tars_client.py : 203_228]","targetNodeId":"/src/mcp-db-base/src/mcp_db_base/tars_client.get_top_sql.get_top_sql_scope...str"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-db-base/src/mcp_db_base/tars_client.py"},"region":{"startLine":228,"startColumn":15,"endLine":228,"endColumn":33,"snippet":{}}}},"id":"get_top_sql \\n[tars_client.py : 203_228]->/src/mcp-db-base/src/mcp_db_base/tars_client.get_top_sql.get_top_sql_scope...ValueError","sourceNodeId":"get_top_sql \\n[tars_client.py : 203_228]","targetNodeId":"/src/mcp-db-base/src/mcp_db_base/tars_client.get_top_sql.get_top_sql_scope...ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-db-base/src/mcp_db_base/tars_client.py"},"region":{"startLine":408,"startColumn":5,"endLine":409,"endColumn":96,"snippet":{}}}},"id":"<__entry_point__>->/src/mcp-db-base/src/mcp_db_base/tars_client..print","sourceNodeId":"<__entry_point__>","targetNodeId":"/src/mcp-db-base/src/mcp_db_base/tars_client..print"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpyuque/src/mcpyuque/server.py"},"region":{"startLine":15,"startColumn":10,"endLine":15,"endColumn":28,"snippet":{}}}},"id":"<__entry_point__>->mcp.server.Server","sourceNodeId":"<__entry_point__>","targetNodeId":"mcp.server.Server"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpyuque/src/mcpyuque/server.py"},"region":{"startLine":19,"startColumn":2,"endLine":19,"endColumn":21,"snippet":{}}}},"id":"<__entry_point__>->.server.list_tools","sourceNodeId":"<__entry_point__>","targetNodeId":".server.list_tools"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpyuque/src/mcpyuque/server.py"},"region":{"startLine":64,"startColumn":2,"endLine":64,"endColumn":20,"snippet":{}}}},"id":"<__entry_point__>->.server.call_tool","sourceNodeId":"<__entry_point__>","targetNodeId":".server.call_tool"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpAntlogs/src/mcpAntlogs/yuntu_cmd_util.py"},"region":{"startLine":109,"startColumn":5,"endLine":109,"endColumn":11,"snippet":{}}}},"id":"<__entry_point__>->main \\n[yuntu_cmd_util.py : 89_103]","sourceNodeId":"<__entry_point__>","targetNodeId":"main \\n[yuntu_cmd_util.py : 89_103]"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpAntlogs/src/mcpAntlogs/yuntu_cmd_util.py"},"region":{"startLine":91,"startColumn":14,"endLine":94,"endColumn":6,"snippet":{}}}},"id":"main \\n[yuntu_cmd_util.py : 89_103]->execute_cmd \\n[yuntu_cmd_util.py : 8_86]","sourceNodeId":"main \\n[yuntu_cmd_util.py : 89_103]","targetNodeId":"execute_cmd \\n[yuntu_cmd_util.py : 8_86]"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpAntlogs/src/mcpAntlogs/yuntu_cmd_util.py"},"region":{"startLine":50,"startColumn":20,"endLine":55,"endColumn":10,"snippet":{}}}},"id":"execute_cmd \\n[yuntu_cmd_util.py : 8_86]->syslib_from.requests.post","sourceNodeId":"execute_cmd \\n[yuntu_cmd_util.py : 8_86]","targetNodeId":"syslib_from.requests.post"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpAntlogs/src/mcpAntlogs/yuntu_cmd_util.py"},"region":{"startLine":58,"startColumn":9,"endLine":58,"endColumn":36,"snippet":{}}}},"id":"execute_cmd \\n[yuntu_cmd_util.py : 8_86]->syslib_from.requests.post(base_url+/openapi/troubleshoot/config/sequenceExecutePipeline, var headers:any=headers, var json:any=payload, var timeout:any=30).raise_for_status","sourceNodeId":"execute_cmd \\n[yuntu_cmd_util.py : 8_86]","targetNodeId":"syslib_from.requests.post(base_url+/openapi/troubleshoot/config/sequenceExecutePipeline, var headers:any=headers, var json:any=payload, var timeout:any=30).raise_for_status"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpAntlogs/src/mcpAntlogs/yuntu_cmd_util.py"},"region":{"startLine":59,"startColumn":18,"endLine":59,"endColumn":33,"snippet":{}}}},"id":"execute_cmd \\n[yuntu_cmd_util.py : 8_86]->syslib_from.requests.post(base_url+/openapi/troubleshoot/config/sequenceExecutePipeline, var headers:any=headers, var json:any=payload, var timeout:any=30).json","sourceNodeId":"execute_cmd \\n[yuntu_cmd_util.py : 8_86]","targetNodeId":"syslib_from.requests.post(base_url+/openapi/troubleshoot/config/sequenceExecutePipeline, var headers:any=headers, var json:any=payload, var timeout:any=30).json"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpAntlogs/src/mcpAntlogs/yuntu_cmd_util.py"},"region":{"startLine":67,"startColumn":21,"endLine":67,"endColumn":45,"snippet":{}}}},"id":"execute_cmd \\n[yuntu_cmd_util.py : 8_86]->syslib_from.requests.post(base_url+/openapi/troubleshoot/config/sequenceExecutePipeline, var headers:any=headers, var json:any=payload, var timeout:any=30).json().get","sourceNodeId":"execute_cmd \\n[yuntu_cmd_util.py : 8_86]","targetNodeId":"syslib_from.requests.post(base_url+/openapi/troubleshoot/config/sequenceExecutePipeline, var headers:any=headers, var json:any=payload, var timeout:any=30).json().get"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpAntlogs/src/mcpAntlogs/yuntu_cmd_util.py"},"region":{"startLine":63,"startColumn":13,"endLine":63,"endColumn":85,"snippet":{}}}},"id":"execute_cmd \\n[yuntu_cmd_util.py : 8_86]->/src/mcpAntlogs/src/mcpAntlogs/yuntu_cmd_util.execute_cmd.execute_cmd_scope...print","sourceNodeId":"execute_cmd \\n[yuntu_cmd_util.py : 8_86]","targetNodeId":"/src/mcpAntlogs/src/mcpAntlogs/yuntu_cmd_util.execute_cmd.execute_cmd_scope...print"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpAntlogs/src/mcpAntlogs/yuntu_cmd_util.py"},"region":{"startLine":67,"startColumn":21,"endLine":67,"endColumn":68,"snippet":{}}}},"id":"execute_cmd \\n[yuntu_cmd_util.py : 8_86]->syslib_from.requests.post(base_url+/openapi/troubleshoot/config/sequenceExecutePipeline, var headers:any=headers, var json:any=payload, var timeout:any=30).json().get(result, {}).get","sourceNodeId":"execute_cmd \\n[yuntu_cmd_util.py : 8_86]","targetNodeId":"syslib_from.requests.post(base_url+/openapi/troubleshoot/config/sequenceExecutePipeline, var headers:any=headers, var json:any=payload, var timeout:any=30).json().get(result, {}).get"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpAntlogs/src/mcpAntlogs/yuntu_cmd_util.py"},"region":{"startLine":72,"startColumn":23,"endLine":72,"endColumn":53,"snippet":{}}}},"id":"execute_cmd \\n[yuntu_cmd_util.py : 8_86]->syslib_from.requests.post(base_url+/openapi/troubleshoot/config/sequenceExecutePipeline, var headers:any=headers, var json:any=payload, var timeout:any=30).json().get(result, {}).get(nodeDataMap, {})....","sourceNodeId":"execute_cmd \\n[yuntu_cmd_util.py : 8_86]","targetNodeId":"syslib_from.requests.post(base_url+/openapi/troubleshoot/config/sequenceExecutePipeline, var headers:any=headers, var json:any=payload, var timeout:any=30).json().get(result, {}).get(nodeDataMap, {})...."},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpAntlogs/src/mcpAntlogs/yuntu_cmd_util.py"},"region":{"startLine":69,"startColumn":13,"endLine":69,"endColumn":39,"snippet":{}}}},"id":"execute_cmd \\n[yuntu_cmd_util.py : 8_86]->/src/mcpAntlogs/src/mcpAntlogs/yuntu_cmd_util.execute_cmd.execute_cmd_scope...print","sourceNodeId":"execute_cmd \\n[yuntu_cmd_util.py : 8_86]","targetNodeId":"/src/mcpAntlogs/src/mcpAntlogs/yuntu_cmd_util.execute_cmd.execute_cmd_scope...print"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpAntlogs/src/mcpAntlogs/yuntu_cmd_util.py"},"region":{"startLine":74,"startColumn":13,"endLine":74,"endColumn":39,"snippet":{}}}},"id":"execute_cmd \\n[yuntu_cmd_util.py : 8_86]->/src/mcpAntlogs/src/mcpAntlogs/yuntu_cmd_util.execute_cmd.execute_cmd_scope...print","sourceNodeId":"execute_cmd \\n[yuntu_cmd_util.py : 8_86]","targetNodeId":"/src/mcpAntlogs/src/mcpAntlogs/yuntu_cmd_util.execute_cmd.execute_cmd_scope...print"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpAntlogs/src/mcpAntlogs/yuntu_cmd_util.py"},"region":{"startLine":77,"startColumn":27,"endLine":77,"endColumn":53,"snippet":{}}}},"id":"execute_cmd \\n[yuntu_cmd_util.py : 8_86]->syslib_from.html.unescape","sourceNodeId":"execute_cmd \\n[yuntu_cmd_util.py : 8_86]","targetNodeId":"syslib_from.html.unescape"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpAntlogs/src/mcpAntlogs/yuntu_cmd_util.py"},"region":{"startLine":77,"startColumn":27,"endLine":77,"endColumn":72,"snippet":{}}}},"id":"execute_cmd \\n[yuntu_cmd_util.py : 8_86]->syslib_from.html.unescape(log_content).replace","sourceNodeId":"execute_cmd \\n[yuntu_cmd_util.py : 8_86]","targetNodeId":"syslib_from.html.unescape(log_content).replace"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpAntlogs/src/mcpAntlogs/yuntu_cmd_util.py"},"region":{"startLine":77,"startColumn":16,"endLine":77,"endColumn":73,"snippet":{}}}},"id":"execute_cmd \\n[yuntu_cmd_util.py : 8_86]->payload.loads","sourceNodeId":"execute_cmd \\n[yuntu_cmd_util.py : 8_86]","targetNodeId":"payload.loads"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpAntlogs/src/mcpAntlogs/yuntu_cmd_util.py"},"region":{"startLine":85,"startColumn":35,"endLine":85,"endColumn":43,"snippet":{}}}},"id":"execute_cmd \\n[yuntu_cmd_util.py : 8_86]->/src/mcpAntlogs/src/mcpAntlogs/yuntu_cmd_util.execute_cmd.execute_cmd_scope...str","sourceNodeId":"execute_cmd \\n[yuntu_cmd_util.py : 8_86]","targetNodeId":"/src/mcpAntlogs/src/mcpAntlogs/yuntu_cmd_util.execute_cmd.execute_cmd_scope...str"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpAntlogs/src/mcpAntlogs/yuntu_cmd_util.py"},"region":{"startLine":85,"startColumn":9,"endLine":85,"endColumn":45,"snippet":{}}}},"id":"execute_cmd \\n[yuntu_cmd_util.py : 8_86]->/src/mcpAntlogs/src/mcpAntlogs/yuntu_cmd_util.execute_cmd.execute_cmd_scope...print","sourceNodeId":"execute_cmd \\n[yuntu_cmd_util.py : 8_86]","targetNodeId":"/src/mcpAntlogs/src/mcpAntlogs/yuntu_cmd_util.execute_cmd.execute_cmd_scope...print"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpAntlogs/src/mcpAntlogs/yuntu_cmd_util.py"},"region":{"startLine":101,"startColumn":13,"endLine":101,"endColumn":23,"snippet":{}}}},"id":"main \\n[yuntu_cmd_util.py : 89_103]->/src/mcpAntlogs/src/mcpAntlogs/yuntu_cmd_util.main.main_scope...print","sourceNodeId":"main \\n[yuntu_cmd_util.py : 89_103]","targetNodeId":"/src/mcpAntlogs/src/mcpAntlogs/yuntu_cmd_util.main.main_scope...print"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpAntlogs/src/mcpAntlogs/yuntu_cmd_util.py"},"region":{"startLine":98,"startColumn":15,"endLine":98,"endColumn":43,"snippet":{}}}},"id":"main \\n[yuntu_cmd_util.py : 89_103]->syslib_from.json.dumps","sourceNodeId":"main \\n[yuntu_cmd_util.py : 89_103]","targetNodeId":"syslib_from.json.dumps"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpAntlogs/src/mcpAntlogs/yuntu_cmd_util.py"},"region":{"startLine":99,"startColumn":23,"endLine":99,"endColumn":46,"snippet":{}}}},"id":"main \\n[yuntu_cmd_util.py : 89_103]->....get","sourceNodeId":"main \\n[yuntu_cmd_util.py : 89_103]","targetNodeId":"....get"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpAntlogs/src/mcpAntlogs/yuntu_cmd_util.py"},"region":{"startLine":99,"startColumn":23,"endLine":99,"endColumn":46,"snippet":{}}}},"id":"main \\n[yuntu_cmd_util.py : 89_103]->payload.loads(html.unescape(log_content).replace(\\\\\\\", \\\")).get","sourceNodeId":"main \\n[yuntu_cmd_util.py : 89_103]","targetNodeId":"payload.loads(html.unescape(log_content).replace(\\\\\\\", \\\")).get"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpAntlogs/src/mcpAntlogs/yuntu_cmd_util.py"},"region":{"startLine":103,"startColumn":9,"endLine":103,"endColumn":42,"snippet":{}}}},"id":"main \\n[yuntu_cmd_util.py : 89_103]->/src/mcpAntlogs/src/mcpAntlogs/yuntu_cmd_util.main.main_scope...print","sourceNodeId":"main \\n[yuntu_cmd_util.py : 89_103]","targetNodeId":"/src/mcpAntlogs/src/mcpAntlogs/yuntu_cmd_util.main.main_scope...print"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpyuque/src/tests/test_hello.py"},"region":{"startLine":18,"startColumn":5,"endLine":18,"endColumn":20,"snippet":{}}}},"id":"<__entry_point__>->syslib_from.unittest.main","sourceNodeId":"<__entry_point__>","targetNodeId":"syslib_from.unittest.main"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpAntmonitor/src/mcpAntmonitor/server.py"},"region":{"startLine":14,"startColumn":14,"endLine":14,"endColumn":66,"snippet":{}}}},"id":"<__entry_point__>->/src/mcpAntmonitor/src/mcpAntmonitor/server.int","sourceNodeId":"<__entry_point__>","targetNodeId":"/src/mcpAntmonitor/src/mcpAntmonitor/server.int"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpAntmonitor/src/mcpAntmonitor/antmonitor_client.py"},"region":{"startLine":234,"startColumn":9,"endLine":235,"endColumn":92,"snippet":{}}}},"id":"<__entry_point__>->get_app_metric \\n[antmonitor_client.py : 189_226]","sourceNodeId":"<__entry_point__>","targetNodeId":"get_app_metric \\n[antmonitor_client.py : 189_226]"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpAntmonitor/src/mcpAntmonitor/antmonitor_client.py"},"region":{"startLine":218,"startColumn":41,"endLine":218,"endColumn":58,"snippet":{}}}},"id":"get_app_metric \\n[antmonitor_client.py : 189_226]->/src/mcpAntmonitor/src/mcpAntmonitor/antmonitor_client.get_app_metric.get_app_metric_scope..len","sourceNodeId":"get_app_metric \\n[antmonitor_client.py : 189_226]","targetNodeId":"/src/mcpAntmonitor/src/mcpAntmonitor/antmonitor_client.get_app_metric.get_app_metric_scope..len"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpAntmonitor/src/mcpAntmonitor/antmonitor_client.py"},"region":{"startLine":211,"startColumn":33,"endLine":211,"endColumn":86,"snippet":{}}}},"id":"get_app_metric \\n[antmonitor_client.py : 189_226]->METRICS_TO_DEFAULT_COLUMN.get","sourceNodeId":"get_app_metric \\n[antmonitor_client.py : 189_226]","targetNodeId":"METRICS_TO_DEFAULT_COLUMN.get"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpAntmonitor/src/mcpAntmonitor/antmonitor_client.py"},"region":{"startLine":213,"startColumn":48,"endLine":213,"endColumn":65,"snippet":{}}}},"id":"get_app_metric \\n[antmonitor_client.py : 189_226]->,.join","sourceNodeId":"get_app_metric \\n[antmonitor_client.py : 189_226]","targetNodeId":",.join"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpAntmonitor/src/mcpAntmonitor/antmonitor_client.py"},"region":{"startLine":220,"startColumn":18,"endLine":220,"endColumn":51,"snippet":{}}}},"id":"get_app_metric \\n[antmonitor_client.py : 189_226]->_get_maas_sql_data \\n[antmonitor_client.py : 135_171]","sourceNodeId":"get_app_metric \\n[antmonitor_client.py : 189_226]","targetNodeId":"_get_maas_sql_data \\n[antmonitor_client.py : 135_171]"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpAntmonitor/src/mcpAntmonitor/antmonitor_client.py"},"region":{"startLine":144,"startColumn":15,"endLine":144,"endColumn":46,"snippet":{}}}},"id":"_get_maas_sql_data \\n[antmonitor_client.py : 135_171]->_replace_seconds_with_zero \\n[antmonitor_client.py : 174_186]","sourceNodeId":"_get_maas_sql_data \\n[antmonitor_client.py : 135_171]","targetNodeId":"_replace_seconds_with_zero \\n[antmonitor_client.py : 174_186]"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpAntmonitor/src/mcpAntmonitor/antmonitor_client.py"},"region":{"startLine":185,"startColumn":20,"endLine":185,"endColumn":54,"snippet":{}}}},"id":"_replace_seconds_with_zero \\n[antmonitor_client.py : 174_186]->syslib_from.re.sub","sourceNodeId":"_replace_seconds_with_zero \\n[antmonitor_client.py : 174_186]","targetNodeId":"syslib_from.re.sub"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpAntmonitor/src/mcpAntmonitor/antmonitor_client.py"},"region":{"startLine":185,"startColumn":20,"endLine":185,"endColumn":54,"snippet":{}}}},"id":"syslib_from.re.sub->replace_func \\n[antmonitor_client.py : 180_181]","sourceNodeId":"syslib_from.re.sub","targetNodeId":"replace_func \\n[antmonitor_client.py : 180_181]"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpAntmonitor/src/mcpAntmonitor/antmonitor_client.py"},"region":{"startLine":181,"startColumn":16,"endLine":181,"endColumn":30,"snippet":{}}}},"id":"replace_func \\n[antmonitor_client.py : 180_181]->match.group","sourceNodeId":"replace_func \\n[antmonitor_client.py : 180_181]","targetNodeId":"match.group"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpAntmonitor/src/mcpAntmonitor/antmonitor_client.py"},"region":{"startLine":153,"startColumn":77,"endLine":153,"endColumn":87,"snippet":{}}}},"id":"_get_maas_sql_data \\n[antmonitor_client.py : 135_171]->_headers \\n[antmonitor_client.py : 45_65]","sourceNodeId":"_get_maas_sql_data \\n[antmonitor_client.py : 135_171]","targetNodeId":"_headers \\n[antmonitor_client.py : 45_65]"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpAntmonitor/src/mcpAntmonitor/antmonitor_client.py"},"region":{"startLine":46,"startColumn":25,"endLine":46,"endColumn":36,"snippet":{}}}},"id":"_headers \\n[antmonitor_client.py : 45_65]->syslib_from.time.time","sourceNodeId":"_headers \\n[antmonitor_client.py : 45_65]","targetNodeId":"syslib_from.time.time"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpAntmonitor/src/mcpAntmonitor/antmonitor_client.py"},"region":{"startLine":46,"startColumn":21,"endLine":46,"endColumn":37,"snippet":{}}}},"id":"_headers \\n[antmonitor_client.py : 45_65]->/src/mcpAntmonitor/src/mcpAntmonitor/antmonitor_client._headers._headers_scope..int","sourceNodeId":"_headers \\n[antmonitor_client.py : 45_65]","targetNodeId":"/src/mcpAntmonitor/src/mcpAntmonitor/antmonitor_client._headers._headers_scope..int"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpAntmonitor/src/mcpAntmonitor/antmonitor_client.py"},"region":{"startLine":47,"startColumn":24,"endLine":47,"endColumn":55,"snippet":{}}}},"id":"_headers \\n[antmonitor_client.py : 45_65]->syslib_from.random.sample","sourceNodeId":"_headers \\n[antmonitor_client.py : 45_65]","targetNodeId":"syslib_from.random.sample"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpAntmonitor/src/mcpAntmonitor/antmonitor_client.py"},"region":{"startLine":47,"startColumn":16,"endLine":47,"endColumn":56,"snippet":{}}}},"id":"_headers \\n[antmonitor_client.py : 45_65]->join","sourceNodeId":"_headers \\n[antmonitor_client.py : 45_65]","targetNodeId":"join"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpAntmonitor/src/mcpAntmonitor/antmonitor_client.py"},"region":{"startLine":60,"startColumn":29,"endLine":60,"endColumn":47,"snippet":{}}}},"id":"_headers \\n[antmonitor_client.py : 45_65]->/src/mcpAntmonitor/src/mcpAntmonitor/antmonitor_client._headers._headers_scope..str","sourceNodeId":"_headers \\n[antmonitor_client.py : 45_65]","targetNodeId":"/src/mcpAntmonitor/src/mcpAntmonitor/antmonitor_client._headers._headers_scope..str"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpAntmonitor/src/mcpAntmonitor/antmonitor_client.py"},"region":{"startLine":51,"startColumn":17,"endLine":51,"endColumn":46,"snippet":{}}}},"id":"_headers \\n[antmonitor_client.py : 45_65]->syslib_from.base64.b64decode","sourceNodeId":"_headers \\n[antmonitor_client.py : 45_65]","targetNodeId":"syslib_from.base64.b64decode"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpAntmonitor/src/mcpAntmonitor/antmonitor_client.py"},"region":{"startLine":52,"startColumn":17,"endLine":52,"endColumn":45,"snippet":{}}}},"id":"_headers \\n[antmonitor_client.py : 45_65]->/src/mcpAntmonitor/src/mcpAntmonitor/antmonitor_client._headers._headers_scope..bytes","sourceNodeId":"_headers \\n[antmonitor_client.py : 45_65]","targetNodeId":"/src/mcpAntmonitor/src/mcpAntmonitor/antmonitor_client._headers._headers_scope..bytes"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpAntmonitor/src/mcpAntmonitor/antmonitor_client.py"},"region":{"startLine":50,"startColumn":9,"endLine":54,"endColumn":10,"snippet":{}}}},"id":"_headers \\n[antmonitor_client.py : 45_65]->syslib_from.hmac.new","sourceNodeId":"_headers \\n[antmonitor_client.py : 45_65]","targetNodeId":"syslib_from.hmac.new"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpAntmonitor/src/mcpAntmonitor/antmonitor_client.py"},"region":{"startLine":50,"startColumn":9,"endLine":54,"endColumn":19,"snippet":{}}}},"id":"_headers \\n[antmonitor_client.py : 45_65]->syslib_from.hmac.new(var key:any=base64.b64decode(_SECRET_KEY), var msg:any=bytes(msg, var encoding:any=utf-8), var digestmod:any=hashlib.sha256).digest","sourceNodeId":"_headers \\n[antmonitor_client.py : 45_65]","targetNodeId":"syslib_from.hmac.new(var key:any=base64.b64decode(_SECRET_KEY), var msg:any=bytes(msg, var encoding:any=utf-8), var digestmod:any=hashlib.sha256).digest"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpAntmonitor/src/mcpAntmonitor/antmonitor_client.py"},"region":{"startLine":49,"startColumn":12,"endLine":55,"endColumn":6,"snippet":{}}}},"id":"_headers \\n[antmonitor_client.py : 45_65]->syslib_from.base64.b64encode","sourceNodeId":"_headers \\n[antmonitor_client.py : 45_65]","targetNodeId":"syslib_from.base64.b64encode"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpAntmonitor/src/mcpAntmonitor/antmonitor_client.py"},"region":{"startLine":153,"startColumn":20,"endLine":153,"endColumn":102,"snippet":{}}}},"id":"_get_maas_sql_data \\n[antmonitor_client.py : 135_171]->_call_maas_sql_api \\n[antmonitor_client.py : 68_114]","sourceNodeId":"_get_maas_sql_data \\n[antmonitor_client.py : 135_171]","targetNodeId":"_call_maas_sql_api \\n[antmonitor_client.py : 68_114]"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpAntmonitor/src/mcpAntmonitor/antmonitor_client.py"},"region":{"startLine":87,"startColumn":57,"endLine":87,"endColumn":67,"snippet":{}}}},"id":"_call_maas_sql_api \\n[antmonitor_client.py : 68_114]->_headers \\n[antmonitor_client.py : 45_65]","sourceNodeId":"_call_maas_sql_api \\n[antmonitor_client.py : 68_114]","targetNodeId":"_headers \\n[antmonitor_client.py : 45_65]"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpAntmonitor/src/mcpAntmonitor/antmonitor_client.py"},"region":{"startLine":89,"startColumn":16,"endLine":95,"endColumn":6,"snippet":{}}}},"id":"_call_maas_sql_api \\n[antmonitor_client.py : 68_114]->mcp_common.request.http_client.AsyncRestClient","sourceNodeId":"_call_maas_sql_api \\n[antmonitor_client.py : 68_114]","targetNodeId":"mcp_common.request.http_client.AsyncRestClient"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpAntmonitor/src/mcpAntmonitor/antmonitor_client.py"},"region":{"startLine":98,"startColumn":43,"endLine":98,"endColumn":57,"snippet":{}}}},"id":"_call_maas_sql_api \\n[antmonitor_client.py : 68_114]->POST.lower","sourceNodeId":"_call_maas_sql_api \\n[antmonitor_client.py : 68_114]","targetNodeId":"POST.lower"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpAntmonitor/src/mcpAntmonitor/antmonitor_client.py"},"region":{"startLine":98,"startColumn":27,"endLine":98,"endColumn":58,"snippet":{}}}},"id":"_call_maas_sql_api \\n[antmonitor_client.py : 68_114]->/src/mcpAntmonitor/src/mcpAntmonitor/antmonitor_client._call_maas_sql_api._call_maas_sql_api_scope..getattr","sourceNodeId":"_call_maas_sql_api \\n[antmonitor_client.py : 68_114]","targetNodeId":"/src/mcpAntmonitor/src/mcpAntmonitor/antmonitor_client._call_maas_sql_api._call_maas_sql_api_scope..getattr"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpAntmonitor/src/mcpAntmonitor/antmonitor_client.py"},"region":{"startLine":99,"startColumn":24,"endLine":99,"endColumn":78,"snippet":{}}}},"id":"_call_maas_sql_api \\n[antmonitor_client.py : 68_114]->/src/mcpAntmonitor/src/mcpAntmonitor/antmonitor_client._call_maas_sql_api._call_maas_sql_api_scope..getattr(client, method.lower())","sourceNodeId":"_call_maas_sql_api \\n[antmonitor_client.py : 68_114]","targetNodeId":"/src/mcpAntmonitor/src/mcpAntmonitor/antmonitor_client._call_maas_sql_api._call_maas_sql_api_scope..getattr(client, method.lower())"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpAntmonitor/src/mcpAntmonitor/antmonitor_client.py"},"region":{"startLine":100,"startColumn":13,"endLine":100,"endColumn":92,"snippet":{}}}},"id":"_call_maas_sql_api \\n[antmonitor_client.py : 68_114]->syslib_from.logging.getLogger(__name__).info","sourceNodeId":"_call_maas_sql_api \\n[antmonitor_client.py : 68_114]","targetNodeId":"syslib_from.logging.getLogger(__name__).info"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpAntmonitor/src/mcpAntmonitor/antmonitor_client.py"},"region":{"startLine":103,"startColumn":24,"endLine":103,"endColumn":44,"snippet":{}}}},"id":"_call_maas_sql_api \\n[antmonitor_client.py : 68_114]->/src/mcpAntmonitor/src/mcpAntmonitor/antmonitor_client._call_maas_sql_api._call_maas_sql_api_scope..getattr(client, method.lower())(var endpoint:any=endpoint, var null:any=request_k...","sourceNodeId":"_call_maas_sql_api \\n[antmonitor_client.py : 68_114]","targetNodeId":"/src/mcpAntmonitor/src/mcpAntmonitor/antmonitor_client._call_maas_sql_api._call_maas_sql_api_scope..getattr(client, method.lower())(var endpoint:any=endpoint, var null:any=request_k..."},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpAntmonitor/src/mcpAntmonitor/antmonitor_client.py"},"region":{"startLine":104,"startColumn":20,"endLine":104,"endColumn":41,"snippet":{}}}},"id":"_call_maas_sql_api \\n[antmonitor_client.py : 68_114]->/src/mcpAntmonitor/src/mcpAntmonitor/antmonitor_client._call_maas_sql_api._call_maas_sql_api_scope...isinstance","sourceNodeId":"_call_maas_sql_api \\n[antmonitor_client.py : 68_114]","targetNodeId":"/src/mcpAntmonitor/src/mcpAntmonitor/antmonitor_client._call_maas_sql_api._call_maas_sql_api_scope...isinstance"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpAntmonitor/src/mcpAntmonitor/antmonitor_client.py"},"region":{"startLine":105,"startColumn":28,"endLine":105,"endColumn":44,"snippet":{}}}},"id":"_call_maas_sql_api \\n[antmonitor_client.py : 68_114]->syslib_from.json.loads","sourceNodeId":"_call_maas_sql_api \\n[antmonitor_client.py : 68_114]","targetNodeId":"syslib_from.json.loads"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpAntmonitor/src/mcpAntmonitor/antmonitor_client.py"},"region":{"startLine":107,"startColumn":36,"endLine":107,"endColumn":68,"snippet":{}}}},"id":"_call_maas_sql_api \\n[antmonitor_client.py : 68_114]->_handle_empty_response \\n[antmonitor_client.py : 117_123]","sourceNodeId":"_call_maas_sql_api \\n[antmonitor_client.py : 68_114]","targetNodeId":"_handle_empty_response \\n[antmonitor_client.py : 117_123]"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpAntmonitor/src/mcpAntmonitor/antmonitor_client.py"},"region":{"startLine":122,"startColumn":25,"endLine":122,"endColumn":57,"snippet":{}}}},"id":"_handle_empty_response \\n[antmonitor_client.py : 117_123]->/src/mcpAntmonitor/src/mcpAntmonitor/antmonitor_client._call_maas_sql_api._call_maas_sql_api_scope..getattr(client, method.lower())(var endpoint:any=endpoint, var null:any=request_k...","sourceNodeId":"_handle_empty_response \\n[antmonitor_client.py : 117_123]","targetNodeId":"/src/mcpAntmonitor/src/mcpAntmonitor/antmonitor_client._call_maas_sql_api._call_maas_sql_api_scope..getattr(client, method.lower())(var endpoint:any=endpoint, var null:any=request_k..."},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpAntmonitor/src/mcpAntmonitor/antmonitor_client.py"},"region":{"startLine":119,"startColumn":11,"endLine":123,"endColumn":6,"snippet":{}}}},"id":"_handle_empty_response \\n[antmonitor_client.py : 117_123]->/src/mcpAntmonitor/src/mcpAntmonitor/antmonitor_client._handle_empty_response._handle_empty_response_scope..ValueError","sourceNodeId":"_handle_empty_response \\n[antmonitor_client.py : 117_123]","targetNodeId":"/src/mcpAntmonitor/src/mcpAntmonitor/antmonitor_client._handle_empty_response._handle_empty_response_scope..ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpAntmonitor/src/mcpAntmonitor/antmonitor_client.py"},"region":{"startLine":109,"startColumn":17,"endLine":109,"endColumn":113,"snippet":{}}}},"id":"_call_maas_sql_api \\n[antmonitor_client.py : 68_114]->syslib_from.logging.getLogger(__name__).warning","sourceNodeId":"_call_maas_sql_api \\n[antmonitor_client.py : 68_114]","targetNodeId":"syslib_from.logging.getLogger(__name__).warning"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpAntmonitor/src/mcpAntmonitor/antmonitor_client.py"},"region":{"startLine":110,"startColumn":17,"endLine":110,"endColumn":49,"snippet":{}}}},"id":"_call_maas_sql_api \\n[antmonitor_client.py : 68_114]->_handle_error_response \\n[antmonitor_client.py : 126_132]","sourceNodeId":"_call_maas_sql_api \\n[antmonitor_client.py : 68_114]","targetNodeId":"_handle_error_response \\n[antmonitor_client.py : 126_132]"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpAntmonitor/src/mcpAntmonitor/antmonitor_client.py"},"region":{"startLine":131,"startColumn":25,"endLine":131,"endColumn":57,"snippet":{}}}},"id":"_handle_error_response \\n[antmonitor_client.py : 126_132]->/src/mcpAntmonitor/src/mcpAntmonitor/antmonitor_client._call_maas_sql_api._call_maas_sql_api_scope..getattr(client, method.lower())(var endpoint:any=endpoint, var null:any=request_k...","sourceNodeId":"_handle_error_response \\n[antmonitor_client.py : 126_132]","targetNodeId":"/src/mcpAntmonitor/src/mcpAntmonitor/antmonitor_client._call_maas_sql_api._call_maas_sql_api_scope..getattr(client, method.lower())(var endpoint:any=endpoint, var null:any=request_k..."},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpAntmonitor/src/mcpAntmonitor/antmonitor_client.py"},"region":{"startLine":128,"startColumn":11,"endLine":132,"endColumn":6,"snippet":{}}}},"id":"_handle_error_response \\n[antmonitor_client.py : 126_132]->/src/mcpAntmonitor/src/mcpAntmonitor/antmonitor_client._handle_error_response._handle_error_response_scope..ValueError","sourceNodeId":"_handle_error_response \\n[antmonitor_client.py : 126_132]","targetNodeId":"/src/mcpAntmonitor/src/mcpAntmonitor/antmonitor_client._handle_error_response._handle_error_response_scope..ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpAntmonitor/src/mcpAntmonitor/antmonitor_client.py"},"region":{"startLine":114,"startColumn":56,"endLine":114,"endColumn":64,"snippet":{}}}},"id":"_call_maas_sql_api \\n[antmonitor_client.py : 68_114]->/src/mcpAntmonitor/src/mcpAntmonitor/antmonitor_client._call_maas_sql_api._call_maas_sql_api_scope...str","sourceNodeId":"_call_maas_sql_api \\n[antmonitor_client.py : 68_114]","targetNodeId":"/src/mcpAntmonitor/src/mcpAntmonitor/antmonitor_client._call_maas_sql_api._call_maas_sql_api_scope...str"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpAntmonitor/src/mcpAntmonitor/antmonitor_client.py"},"region":{"startLine":113,"startColumn":13,"endLine":113,"endColumn":92,"snippet":{}}}},"id":"_call_maas_sql_api \\n[antmonitor_client.py : 68_114]->syslib_from.logging.getLogger(__name__).error","sourceNodeId":"_call_maas_sql_api \\n[antmonitor_client.py : 68_114]","targetNodeId":"syslib_from.logging.getLogger(__name__).error"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpAntmonitor/src/mcpAntmonitor/antmonitor_client.py"},"region":{"startLine":114,"startColumn":19,"endLine":114,"endColumn":66,"snippet":{}}}},"id":"_call_maas_sql_api \\n[antmonitor_client.py : 68_114]->/src/mcpAntmonitor/src/mcpAntmonitor/antmonitor_client._call_maas_sql_api._call_maas_sql_api_scope...ValueError","sourceNodeId":"_call_maas_sql_api \\n[antmonitor_client.py : 68_114]","targetNodeId":"/src/mcpAntmonitor/src/mcpAntmonitor/antmonitor_client._call_maas_sql_api._call_maas_sql_api_scope...ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpAntmonitor/src/mcpAntmonitor/antmonitor_client.py"},"region":{"startLine":159,"startColumn":24,"endLine":159,"endColumn":66,"snippet":{}}}},"id":"_get_maas_sql_data \\n[antmonitor_client.py : 135_171]->syslib_from.datetime.datetime.fromtimestamp","sourceNodeId":"_get_maas_sql_data \\n[antmonitor_client.py : 135_171]","targetNodeId":"syslib_from.datetime.datetime.fromtimestamp"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpAntmonitor/src/mcpAntmonitor/antmonitor_client.py"},"region":{"startLine":159,"startColumn":24,"endLine":159,"endColumn":93,"snippet":{}}}},"id":"_get_maas_sql_data \\n[antmonitor_client.py : 135_171]->syslib_from.datetime.datetime.fromtimestamp(timestamp).strftime","sourceNodeId":"_get_maas_sql_data \\n[antmonitor_client.py : 135_171]","targetNodeId":"syslib_from.datetime.datetime.fromtimestamp(timestamp).strftime"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpAntmonitor/src/mcpAntmonitor/antmonitor_client.py"},"region":{"startLine":161,"startColumn":37,"endLine":161,"endColumn":50,"snippet":{}}}},"id":"_get_maas_sql_data \\n[antmonitor_client.py : 135_171]->/src/mcpAntmonitor/src/mcpAntmonitor/antmonitor_client._get_maas_sql_data._get_maas_sql_data_scope........./src/mcpAntmonitor/src/mcpAntmonitor/antmonitor_client._get_maas_sql_data._get_maas_sql_data_scope...str","sourceNodeId":"_get_maas_sql_data \\n[antmonitor_client.py : 135_171]","targetNodeId":"/src/mcpAntmonitor/src/mcpAntmonitor/antmonitor_client._get_maas_sql_data._get_maas_sql_data_scope...str"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpAntmonitor/src/mcpAntmonitor/antmonitor_client.py"},"region":{"startLine":170,"startColumn":9,"endLine":170,"endColumn":101,"snippet":{}}}},"id":"_get_maas_sql_data \\n[antmonitor_client.py : 135_171]->syslib_from.logging.getLogger(__name__).warning","sourceNodeId":"_get_maas_sql_data \\n[antmonitor_client.py : 135_171]","targetNodeId":"syslib_from.logging.getLogger(__name__).warning"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpAntmonitor/src/mcpAntmonitor/antmonitor_client.py"},"region":{"startLine":171,"startColumn":15,"endLine":171,"endColumn":33,"snippet":{}}}},"id":"_get_maas_sql_data \\n[antmonitor_client.py : 135_171]->/src/mcpAntmonitor/src/mcpAntmonitor/antmonitor_client._get_maas_sql_data._get_maas_sql_data_scope...ValueError","sourceNodeId":"_get_maas_sql_data \\n[antmonitor_client.py : 135_171]","targetNodeId":"/src/mcpAntmonitor/src/mcpAntmonitor/antmonitor_client._get_maas_sql_data._get_maas_sql_data_scope...ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpAntmonitor/src/mcpAntmonitor/antmonitor_client.py"},"region":{"startLine":221,"startColumn":15,"endLine":221,"endColumn":53,"snippet":{}}}},"id":"get_app_metric \\n[antmonitor_client.py : 189_226]->syslib_from.json.dumps","sourceNodeId":"get_app_metric \\n[antmonitor_client.py : 189_226]","targetNodeId":"syslib_from.json.dumps"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpAntmonitor/src/mcpAntmonitor/antmonitor_client.py"},"region":{"startLine":222,"startColumn":9,"endLine":222,"endColumn":91,"snippet":{}}}},"id":"get_app_metric \\n[antmonitor_client.py : 189_226]->syslib_from.logging.getLogger(__name__).info","sourceNodeId":"get_app_metric \\n[antmonitor_client.py : 189_226]","targetNodeId":"syslib_from.logging.getLogger(__name__).info"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpAntmonitor/src/mcpAntmonitor/antmonitor_client.py"},"region":{"startLine":226,"startColumn":26,"endLine":226,"endColumn":32,"snippet":{}}}},"id":"get_app_metric \\n[antmonitor_client.py : 189_226]->/src/mcpAntmonitor/src/mcpAntmonitor/antmonitor_client.get_app_metric.get_app_metric_scope...str","sourceNodeId":"get_app_metric \\n[antmonitor_client.py : 189_226]","targetNodeId":"/src/mcpAntmonitor/src/mcpAntmonitor/antmonitor_client.get_app_metric.get_app_metric_scope...str"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpAntmonitor/src/mcpAntmonitor/antmonitor_client.py"},"region":{"startLine":225,"startColumn":9,"endLine":225,"endColumn":95,"snippet":{}}}},"id":"get_app_metric \\n[antmonitor_client.py : 189_226]->syslib_from.logging.getLogger(__name__).error","sourceNodeId":"get_app_metric \\n[antmonitor_client.py : 189_226]","targetNodeId":"syslib_from.logging.getLogger(__name__).error"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpAntmonitor/src/mcpAntmonitor/antmonitor_client.py"},"region":{"startLine":226,"startColumn":15,"endLine":226,"endColumn":33,"snippet":{}}}},"id":"get_app_metric \\n[antmonitor_client.py : 189_226]->/src/mcpAntmonitor/src/mcpAntmonitor/antmonitor_client.get_app_metric.get_app_metric_scope...ValueError","sourceNodeId":"get_app_metric \\n[antmonitor_client.py : 189_226]","targetNodeId":"/src/mcpAntmonitor/src/mcpAntmonitor/antmonitor_client.get_app_metric.get_app_metric_scope...ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpAntmonitor/src/mcpAntmonitor/antmonitor_client.py"},"region":{"startLine":233,"startColumn":5,"endLine":235,"endColumn":94,"snippet":{}}}},"id":"<__entry_point__>->/src/mcpAntmonitor/src/mcpAntmonitor/antmonitor_client..print","sourceNodeId":"<__entry_point__>","targetNodeId":"/src/mcpAntmonitor/src/mcpAntmonitor/antmonitor_client..print"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpRopnTaskStatusAnalyse/src/mcpRopnTaskStatusAnalyse/server.py"},"region":{"startLine":14,"startColumn":31,"endLine":14,"endColumn":56,"snippet":{}}}},"id":"<__entry_point__>->syslib_from.os.path.abspath","sourceNodeId":"<__entry_point__>","targetNodeId":"syslib_from.os.path.abspath"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpRopnTaskStatusAnalyse/src/mcpRopnTaskStatusAnalyse/server.py"},"region":{"startLine":14,"startColumn":15,"endLine":14,"endColumn":57,"snippet":{}}}},"id":"<__entry_point__>->syslib_from.os.path.dirname","sourceNodeId":"<__entry_point__>","targetNodeId":"syslib_from.os.path.dirname"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpRopnTaskStatusAnalyse/src/mcpRopnTaskStatusAnalyse/server.py"},"region":{"startLine":15,"startColumn":1,"endLine":15,"endColumn":29,"snippet":{}}}},"id":"<__entry_point__>->syslib_from.sys.path.append","sourceNodeId":"<__entry_point__>","targetNodeId":"syslib_from.sys.path.append"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpPaas/src/mcpPaas/paas_client.py"},"region":{"startLine":13,"startColumn":1,"endLine":13,"endColumn":45,"snippet":{}}}},"id":"<__entry_point__>->layotto_turbo.layotto.subscribe","sourceNodeId":"<__entry_point__>","targetNodeId":"layotto_turbo.layotto.subscribe"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpAntscheduler/src/mcpAntscheduler/client.py"},"region":{"startLine":16,"startColumn":23,"endLine":16,"endColumn":48,"snippet":{}}}},"id":"<__entry_point__>->oneapi.antschedulerconsole.JobOpenApiFacade.JobOpenApiFacade","sourceNodeId":"<__entry_point__>","targetNodeId":"oneapi.antschedulerconsole.JobOpenApiFacade.JobOpenApiFacade"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpAntscheduler/src/mcpAntscheduler/client.py"},"region":{"startLine":17,"startColumn":27,"endLine":17,"endColumn":64,"snippet":{}}}},"id":"<__entry_point__>->oneapi.antschedulerconsole.OperationRecordOpenApiFacade.OperationRecordOpenApiFacade","sourceNodeId":"<__entry_point__>","targetNodeId":"oneapi.antschedulerconsole.OperationRecordOpenApiFacade.OperationRecordOpenApiFacade"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpCloudinc/src/mcpCloudinc/server.py"},"region":{"startLine":48,"startColumn":16,"endLine":48,"endColumn":48,"snippet":{}}}},"id":"<__entry_point__>->oneapi.cloudinc.AntvipDomainQueryFacade.AntvipDomainQueryFacade","sourceNodeId":"<__entry_point__>","targetNodeId":"oneapi.cloudinc.AntvipDomainQueryFacade.AntvipDomainQueryFacade"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpCodeExecutor/src/mcpCodeExecutor/server.py"},"region":{"startLine":189,"startColumn":23,"endLine":189,"endColumn":49,"snippet":{}}}},"id":"<__entry_point__>->run_code \\n[server.py : 127_184]","sourceNodeId":"<__entry_point__>","targetNodeId":"run_code \\n[server.py : 127_184]"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpCodeExecutor/src/mcpCodeExecutor/server.py"},"region":{"startLine":142,"startColumn":23,"endLine":142,"endColumn":38,"snippet":{}}}},"id":"run_code \\n[server.py : 127_184]->_get_trace_id \\n[server.py : 117_125]","sourceNodeId":"run_code \\n[server.py : 127_184]","targetNodeId":"_get_trace_id \\n[server.py : 117_125]"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpCodeExecutor/src/mcpCodeExecutor/server.py"},"region":{"startLine":118,"startColumn":19,"endLine":118,"endColumn":73,"snippet":{}}}},"id":"_get_trace_id \\n[server.py : 117_125]->mcp.server.Server(SERVER_NAME).request_context.meta.model_extra.get","sourceNodeId":"_get_trace_id \\n[server.py : 117_125]","targetNodeId":"mcp.server.Server(SERVER_NAME).request_context.meta.model_extra.get"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpCodeExecutor/src/mcpCodeExecutor/server.py"},"region":{"startLine":119,"startColumn":5,"endLine":119,"endColumn":51,"snippet":{}}}},"id":"_get_trace_id \\n[server.py : 117_125]->syslib_from.logging.getLogger(mcp-server).info","sourceNodeId":"_get_trace_id \\n[server.py : 117_125]","targetNodeId":"syslib_from.logging.getLogger(mcp-server).info"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpCodeExecutor/src/mcpCodeExecutor/server.py"},"region":{"startLine":124,"startColumn":24,"endLine":124,"endColumn":41,"snippet":{}}}},"id":"_get_trace_id \\n[server.py : 117_125]->mcp.server.Server(SERVER_NAME).request_context.meta.model_extra.get(headers).decode","sourceNodeId":"_get_trace_id \\n[server.py : 117_125]","targetNodeId":"mcp.server.Server(SERVER_NAME).request_context.meta.model_extra.get(headers).decode"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpCodeExecutor/src/mcpCodeExecutor/server.py"},"region":{"startLine":122,"startColumn":19,"endLine":122,"endColumn":44,"snippet":{}}}},"id":"_get_trace_id \\n[server.py : 117_125]->mcp.server.Server(SERVER_NAME).request_context.meta.model_extra.get(headers).decode(utf-8).lower","sourceNodeId":"_get_trace_id \\n[server.py : 117_125]","targetNodeId":"mcp.server.Server(SERVER_NAME).request_context.meta.model_extra.get(headers).decode(utf-8).lower"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpCodeExecutor/src/mcpCodeExecutor/server.py"},"region":{"startLine":125,"startColumn":16,"endLine":125,"endColumn":28,"snippet":{}}}},"id":"_get_trace_id \\n[server.py : 117_125]->syslib_from.uuid.uuid4","sourceNodeId":"_get_trace_id \\n[server.py : 117_125]","targetNodeId":"syslib_from.uuid.uuid4"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpCodeExecutor/src/mcpCodeExecutor/server.py"},"region":{"startLine":125,"startColumn":12,"endLine":125,"endColumn":29,"snippet":{}}}},"id":"_get_trace_id \\n[server.py : 117_125]->/src/mcpCodeExecutor/src/mcpCodeExecutor/server._get_trace_id._get_trace_id_scope..str","sourceNodeId":"_get_trace_id \\n[server.py : 117_125]","targetNodeId":"/src/mcpCodeExecutor/src/mcpCodeExecutor/server._get_trace_id._get_trace_id_scope..str"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpCodeExecutor/src/mcpCodeExecutor/server.py"},"region":{"startLine":145,"startColumn":23,"endLine":145,"endColumn":34,"snippet":{}}}},"id":"run_code \\n[server.py : 127_184]->syslib_from.time.time","sourceNodeId":"run_code \\n[server.py : 127_184]","targetNodeId":"syslib_from.time.time"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpCodeExecutor/src/mcpCodeExecutor/server.py"},"region":{"startLine":145,"startColumn":19,"endLine":145,"endColumn":42,"snippet":{}}}},"id":"run_code \\n[server.py : 127_184]->/src/mcpCodeExecutor/src/mcpCodeExecutor/server.run_code.run_code_scope..int","sourceNodeId":"run_code \\n[server.py : 127_184]","targetNodeId":"/src/mcpCodeExecutor/src/mcpCodeExecutor/server.run_code.run_code_scope..int"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpCodeExecutor/src/mcpCodeExecutor/server.py"},"region":{"startLine":184,"startColumn":56,"endLine":184,"endColumn":64,"snippet":{}}}},"id":"run_code \\n[server.py : 127_184]->/src/mcpCodeExecutor/src/mcpCodeExecutor/server.run_code.run_code_scope..str","sourceNodeId":"run_code \\n[server.py : 127_184]","targetNodeId":"/src/mcpCodeExecutor/src/mcpCodeExecutor/server.run_code.run_code_scope..str"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpCodeExecutor/src/mcpCodeExecutor/server.py"},"region":{"startLine":145,"startColumn":50,"endLine":145,"endColumn":78,"snippet":{}}}},"id":"run_code \\n[server.py : 127_184]->syslib_from.random.randint","sourceNodeId":"run_code \\n[server.py : 127_184]","targetNodeId":"syslib_from.random.randint"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpCodeExecutor/src/mcpCodeExecutor/server.py"},"region":{"startLine":149,"startColumn":25,"endLine":149,"endColumn":36,"snippet":{}}}},"id":"run_code \\n[server.py : 127_184]->syslib_from.os.environ.get(RUNTIME_ENV_ID, PROD).upper","sourceNodeId":"run_code \\n[server.py : 127_184]","targetNodeId":"syslib_from.os.environ.get(RUNTIME_ENV_ID, PROD).upper"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpCodeExecutor/src/mcpCodeExecutor/server.py"},"region":{"startLine":152,"startColumn":27,"endLine":152,"endColumn":39,"snippet":{}}}},"id":"run_code \\n[server.py : 127_184]->syslib_from.uuid.uuid4","sourceNodeId":"run_code \\n[server.py : 127_184]","targetNodeId":"syslib_from.uuid.uuid4"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpCodeExecutor/src/mcpCodeExecutor/server.py"},"region":{"startLine":154,"startColumn":79,"endLine":154,"endColumn":112,"snippet":{}}}},"id":"run_code \\n[server.py : 127_184]->isinstance","sourceNodeId":"run_code \\n[server.py : 127_184]","targetNodeId":"isinstance"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpCodeExecutor/src/mcpCodeExecutor/server.py"},"region":{"startLine":154,"startColumn":30,"endLine":154,"endColumn":55,"snippet":{}}}},"id":"run_code \\n[server.py : 127_184]->,.join","sourceNodeId":"run_code \\n[server.py : 127_184]","targetNodeId":",.join"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpCodeExecutor/src/mcpCodeExecutor/server.py"},"region":{"startLine":162,"startColumn":20,"endLine":162,"endColumn":39,"snippet":{}}}},"id":"run_code \\n[server.py : 127_184]->syslib_from.httpx.AsyncClient","sourceNodeId":"run_code \\n[server.py : 127_184]","targetNodeId":"syslib_from.httpx.AsyncClient"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpCodeExecutor/src/mcpCodeExecutor/server.py"},"region":{"startLine":163,"startColumn":24,"endLine":163,"endColumn":78,"snippet":{}}}},"id":"run_code \\n[server.py : 127_184]->syslib_from.httpx.AsyncClient().post","sourceNodeId":"run_code \\n[server.py : 127_184]","targetNodeId":"syslib_from.httpx.AsyncClient().post"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpCodeExecutor/src/mcpCodeExecutor/server.py"},"region":{"startLine":164,"startColumn":13,"endLine":164,"endColumn":40,"snippet":{}}}},"id":"run_code \\n[server.py : 127_184]->syslib_from.httpx.AsyncClient().post(url, var headers:any=headers, var json:any=req_body).raise_for_status","sourceNodeId":"run_code \\n[server.py : 127_184]","targetNodeId":"syslib_from.httpx.AsyncClient().post(url, var headers:any=headers, var json:any=req_body).raise_for_status"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpCodeExecutor/src/mcpCodeExecutor/server.py"},"region":{"startLine":165,"startColumn":22,"endLine":165,"endColumn":37,"snippet":{}}}},"id":"run_code \\n[server.py : 127_184]->syslib_from.httpx.AsyncClient().post(url, var headers:any=headers, var json:any=req_body).json","sourceNodeId":"run_code \\n[server.py : 127_184]","targetNodeId":"syslib_from.httpx.AsyncClient().post(url, var headers:any=headers, var json:any=req_body).json"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpCodeExecutor/src/mcpCodeExecutor/server.py"},"region":{"startLine":173,"startColumn":20,"endLine":173,"endColumn":41,"snippet":{}}}},"id":"run_code \\n[server.py : 127_184]->syslib_from.httpx.AsyncClient().post(url, var headers:any=headers, var json:any=req_body).json().get","sourceNodeId":"run_code \\n[server.py : 127_184]","targetNodeId":"syslib_from.httpx.AsyncClient().post(url, var headers:any=headers, var json:any=req_body).json().get"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpCodeExecutor/src/mcpCodeExecutor/server.py"},"region":{"startLine":169,"startColumn":33,"endLine":169,"endColumn":55,"snippet":{}}}},"id":"run_code \\n[server.py : 127_184]->req_body.loads","sourceNodeId":"run_code \\n[server.py : 127_184]","targetNodeId":"req_body.loads"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpCodeExecutor/src/mcpCodeExecutor/server.py"},"region":{"startLine":176,"startColumn":39,"endLine":176,"endColumn":69,"snippet":{}}}},"id":"run_code \\n[server.py : 127_184]->req_body.loads(data_field).get","sourceNodeId":"run_code \\n[server.py : 127_184]","targetNodeId":"req_body.loads(data_field).get"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpCodeExecutor/src/mcpCodeExecutor/server.py"},"region":{"startLine":190,"startColumn":5,"endLine":190,"endColumn":15,"snippet":{}}}},"id":"<__entry_point__>->/src/mcpCodeExecutor/src/mcpCodeExecutor/server..print","sourceNodeId":"<__entry_point__>","targetNodeId":"/src/mcpCodeExecutor/src/mcpCodeExecutor/server..print"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpTvp/src/mcpTvp/__init__.py"},"region":{"startLine":7,"startColumn":5,"endLine":7,"endColumn":11,"snippet":{}}}},"id":"<__entry_point__>->main \\n[__init__.py : 3_4]","sourceNodeId":"<__entry_point__>","targetNodeId":"main \\n[__init__.py : 3_4]"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDataSync/src/mcpDataSync/__init__.py"},"region":{"startLine":4,"startColumn":5,"endLine":4,"endColumn":29,"snippet":{}}}},"id":"main \\n[__init__.py : 3_4]->mcpDataSync.server.mcp.run","sourceNodeId":"main \\n[__init__.py : 3_4]","targetNodeId":"mcpDataSync.server.mcp.run"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpTemplate/src/mcpTemplate/server.py"},"region":{"startLine":3,"startColumn":10,"endLine":3,"endColumn":28,"snippet":{}}}},"id":"<__entry_point__>->mcp.server.FastMCP","sourceNodeId":"<__entry_point__>","targetNodeId":"mcp.server.FastMCP"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpTemplate/src/mcpTemplate/server.py"},"region":{"startLine":6,"startColumn":2,"endLine":6,"endColumn":15,"snippet":{}}}},"id":"<__entry_point__>->.server.tool","sourceNodeId":"<__entry_point__>","targetNodeId":".server.tool"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDbOdc/src/mcpDbOdc/odc_client_v2.py"},"region":{"startLine":501,"startColumn":17,"endLine":501,"endColumn":23,"snippet":{}}}},"id":"<__entry_point__>->main \\n[odc_client_v2.py : 466_478]","sourceNodeId":"<__entry_point__>","targetNodeId":"main \\n[odc_client_v2.py : 466_478]"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDbOdc/src/mcpDbOdc/odc_client_v2.py"},"region":{"startLine":467,"startColumn":16,"endLine":467,"endColumn":71,"snippet":{}}}},"id":"main \\n[odc_client_v2.py : 466_478]->OdcClientV2 :: __init__ \\n[odc_client_v2.py : 21_48]","sourceNodeId":"main \\n[odc_client_v2.py : 466_478]","targetNodeId":"OdcClientV2 :: __init__ \\n[odc_client_v2.py : 21_48]"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDbOdc/src/mcpDbOdc/odc_client_v2.py"},"region":{"startLine":38,"startColumn":24,"endLine":38,"endColumn":48,"snippet":{}}}},"id":"OdcClientV2 :: __init__ \\n[odc_client_v2.py : 21_48]->OdcClientV2 :: _get_url \\n[odc_client_v2.py : 59_64]","sourceNodeId":"OdcClientV2 :: __init__ \\n[odc_client_v2.py : 21_48]","targetNodeId":"OdcClientV2 :: _get_url \\n[odc_client_v2.py : 59_64]"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDbOdc/src/mcpDbOdc/odc_client_v2.py"},"region":{"startLine":61,"startColumn":16,"endLine":61,"endColumn":33,"snippet":{}}}},"id":"OdcClientV2 :: _get_url \\n[odc_client_v2.py : 59_64]->ODC_URL.get","sourceNodeId":"OdcClientV2 :: _get_url \\n[odc_client_v2.py : 59_64]","targetNodeId":"ODC_URL.get"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDbOdc/src/mcpDbOdc/odc_client_v2.py"},"region":{"startLine":64,"startColumn":16,"endLine":64,"endColumn":49,"snippet":{}}}},"id":"OdcClientV2 :: _get_url \\n[odc_client_v2.py : 59_64]->ODC_URL.site.get","sourceNodeId":"OdcClientV2 :: _get_url \\n[odc_client_v2.py : 59_64]","targetNodeId":"ODC_URL.site.get"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDbOdc/src/mcpDbOdc/odc_client_v2.py"},"region":{"startLine":48,"startColumn":9,"endLine":48,"endColumn":63,"snippet":{}}}},"id":"OdcClientV2 :: __init__ \\n[odc_client_v2.py : 21_48]->syslib_from.logging.getLogger(__name__).info","sourceNodeId":"OdcClientV2 :: __init__ \\n[odc_client_v2.py : 21_48]","targetNodeId":"syslib_from.logging.getLogger(__name__).info"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDbOdc/src/mcpDbOdc/odc_client_v2.py"},"region":{"startLine":469,"startColumn":19,"endLine":477,"endColumn":10,"snippet":{}}}},"id":"main \\n[odc_client_v2.py : 466_478]->OdcClientV2 :: create_project \\n[odc_client_v2.py : 94_140]","sourceNodeId":"main \\n[odc_client_v2.py : 466_478]","targetNodeId":"OdcClientV2 :: create_project \\n[odc_client_v2.py : 94_140]"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDbOdc/src/mcpDbOdc/odc_client_v2.py"},"region":{"startLine":121,"startColumn":9,"endLine":121,"endColumn":54,"snippet":{}}}},"id":"OdcClientV2 :: create_project \\n[odc_client_v2.py : 94_140]->syslib_from.logging.getLogger(__name__).info","sourceNodeId":"OdcClientV2 :: create_project \\n[odc_client_v2.py : 94_140]","targetNodeId":"syslib_from.logging.getLogger(__name__).info"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDbOdc/src/mcpDbOdc/odc_client_v2.py"},"region":{"startLine":138,"startColumn":16,"endLine":140,"endColumn":10,"snippet":{}}}},"id":"OdcClientV2 :: create_project \\n[odc_client_v2.py : 94_140]->OdcClientV2 :: _call_api \\n[odc_client_v2.py : 404_442]","sourceNodeId":"OdcClientV2 :: create_project \\n[odc_client_v2.py : 94_140]","targetNodeId":"OdcClientV2 :: _call_api \\n[odc_client_v2.py : 404_442]"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDbOdc/src/mcpDbOdc/odc_client_v2.py"},"region":{"startLine":429,"startColumn":13,"endLine":429,"endColumn":53,"snippet":{}}}},"id":"OdcClientV2 :: _call_api \\n[odc_client_v2.py : 404_442]->syslib_from.logging.getLogger(__name__).info","sourceNodeId":"OdcClientV2 :: _call_api \\n[odc_client_v2.py : 404_442]","targetNodeId":"syslib_from.logging.getLogger(__name__).info"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDbOdc/src/mcpDbOdc/odc_client_v2.py"},"region":{"startLine":428,"startColumn":24,"endLine":428,"endColumn":87,"snippet":{}}}},"id":"OdcClientV2 :: _call_api \\n[odc_client_v2.py : 404_442]->/src/mcpDbOdc/src/mcpDbOdc/odc_client_v2.OdcClientV2._request","sourceNodeId":"OdcClientV2 :: _call_api \\n[odc_client_v2.py : 404_442]","targetNodeId":"/src/mcpDbOdc/src/mcpDbOdc/odc_client_v2.OdcClientV2._request"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDbOdc/src/mcpDbOdc/odc_client_v2.py"},"region":{"startLine":433,"startColumn":17,"endLine":433,"endColumn":64,"snippet":{}}}},"id":"OdcClientV2 :: _call_api \\n[odc_client_v2.py : 404_442]->OdcClientV2 :: _handle_empty_response \\n[odc_client_v2.py : 444_452]","sourceNodeId":"OdcClientV2 :: _call_api \\n[odc_client_v2.py : 404_442]","targetNodeId":"OdcClientV2 :: _handle_empty_response \\n[odc_client_v2.py : 444_452]"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDbOdc/src/mcpDbOdc/odc_client_v2.py"},"region":{"startLine":449,"startColumn":29,"endLine":449,"endColumn":61,"snippet":{}}}},"id":"OdcClientV2 :: _handle_empty_response \\n[odc_client_v2.py : 444_452]->/src/mcpDbOdc/src/mcpDbOdc/odc_client_v2.OdcClientV2._request(method, endpoint, var params:any=params, var json:any=data).get","sourceNodeId":"OdcClientV2 :: _handle_empty_response \\n[odc_client_v2.py : 444_452]","targetNodeId":"/src/mcpDbOdc/src/mcpDbOdc/odc_client_v2.OdcClientV2._request(method, endpoint, var params:any=params, var json:any=data).get"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDbOdc/src/mcpDbOdc/odc_client_v2.py"},"region":{"startLine":451,"startColumn":9,"endLine":451,"endColumn":32,"snippet":{}}}},"id":"OdcClientV2 :: _handle_empty_response \\n[odc_client_v2.py : 444_452]->syslib_from.logging.getLogger(__name__).error","sourceNodeId":"OdcClientV2 :: _handle_empty_response \\n[odc_client_v2.py : 444_452]","targetNodeId":"syslib_from.logging.getLogger(__name__).error"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDbOdc/src/mcpDbOdc/odc_client_v2.py"},"region":{"startLine":452,"startColumn":15,"endLine":452,"endColumn":36,"snippet":{}}}},"id":"OdcClientV2 :: _handle_empty_response \\n[odc_client_v2.py : 444_452]->/src/mcpDbOdc/src/mcpDbOdc/odc_client_v2.OdcClientV2._handle_empty_response._handle_empty_response_scope..ValueError","sourceNodeId":"OdcClientV2 :: _handle_empty_response \\n[odc_client_v2.py : 444_452]","targetNodeId":"/src/mcpDbOdc/src/mcpDbOdc/odc_client_v2.OdcClientV2._handle_empty_response._handle_empty_response_scope..ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDbOdc/src/mcpDbOdc/odc_client_v2.py"},"region":{"startLine":438,"startColumn":20,"endLine":438,"endColumn":44,"snippet":{}}}},"id":"OdcClientV2 :: _call_api \\n[odc_client_v2.py : 404_442]->/src/mcpDbOdc/src/mcpDbOdc/odc_client_v2.OdcClientV2._request(method, endpoint, var params:any=params, var json:any=data).get","sourceNodeId":"OdcClientV2 :: _call_api \\n[odc_client_v2.py : 404_442]","targetNodeId":"/src/mcpDbOdc/src/mcpDbOdc/odc_client_v2.OdcClientV2._request(method, endpoint, var params:any=params, var json:any=data).get"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDbOdc/src/mcpDbOdc/odc_client_v2.py"},"region":{"startLine":436,"startColumn":17,"endLine":436,"endColumn":64,"snippet":{}}}},"id":"OdcClientV2 :: _call_api \\n[odc_client_v2.py : 404_442]->OdcClientV2 :: _handle_error_response \\n[odc_client_v2.py : 454_462]","sourceNodeId":"OdcClientV2 :: _call_api \\n[odc_client_v2.py : 404_442]","targetNodeId":"OdcClientV2 :: _handle_error_response \\n[odc_client_v2.py : 454_462]"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDbOdc/src/mcpDbOdc/odc_client_v2.py"},"region":{"startLine":459,"startColumn":29,"endLine":459,"endColumn":61,"snippet":{}}}},"id":"OdcClientV2 :: _handle_error_response \\n[odc_client_v2.py : 454_462]->/src/mcpDbOdc/src/mcpDbOdc/odc_client_v2.OdcClientV2._request(method, endpoint, var params:any=params, var json:any=data).get","sourceNodeId":"OdcClientV2 :: _handle_error_response \\n[odc_client_v2.py : 454_462]","targetNodeId":"/src/mcpDbOdc/src/mcpDbOdc/odc_client_v2.OdcClientV2._request(method, endpoint, var params:any=params, var json:any=data).get"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDbOdc/src/mcpDbOdc/odc_client_v2.py"},"region":{"startLine":461,"startColumn":9,"endLine":461,"endColumn":32,"snippet":{}}}},"id":"OdcClientV2 :: _handle_error_response \\n[odc_client_v2.py : 454_462]->syslib_from.logging.getLogger(__name__).error","sourceNodeId":"OdcClientV2 :: _handle_error_response \\n[odc_client_v2.py : 454_462]","targetNodeId":"syslib_from.logging.getLogger(__name__).error"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDbOdc/src/mcpDbOdc/odc_client_v2.py"},"region":{"startLine":462,"startColumn":15,"endLine":462,"endColumn":36,"snippet":{}}}},"id":"OdcClientV2 :: _handle_error_response \\n[odc_client_v2.py : 454_462]->/src/mcpDbOdc/src/mcpDbOdc/odc_client_v2.OdcClientV2._handle_error_response._handle_error_response_scope..ValueError","sourceNodeId":"OdcClientV2 :: _handle_error_response \\n[odc_client_v2.py : 454_462]","targetNodeId":"/src/mcpDbOdc/src/mcpDbOdc/odc_client_v2.OdcClientV2._handle_error_response._handle_error_response_scope..ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDbOdc/src/mcpDbOdc/odc_client_v2.py"},"region":{"startLine":441,"startColumn":13,"endLine":441,"endColumn":58,"snippet":{}}}},"id":"OdcClientV2 :: _call_api \\n[odc_client_v2.py : 404_442]->syslib_from.logging.getLogger(__name__).exception","sourceNodeId":"OdcClientV2 :: _call_api \\n[odc_client_v2.py : 404_442]","targetNodeId":"syslib_from.logging.getLogger(__name__).exception"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDbOdc/src/mcpDbOdc/odc_client_v2.py"},"region":{"startLine":442,"startColumn":49,"endLine":442,"endColumn":57,"snippet":{}}}},"id":"OdcClientV2 :: _call_api \\n[odc_client_v2.py : 404_442]->/src/mcpDbOdc/src/mcpDbOdc/odc_client_v2.OdcClientV2._call_api._call_api_scope...str","sourceNodeId":"OdcClientV2 :: _call_api \\n[odc_client_v2.py : 404_442]","targetNodeId":"/src/mcpDbOdc/src/mcpDbOdc/odc_client_v2.OdcClientV2._call_api._call_api_scope...str"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDbOdc/src/mcpDbOdc/odc_client_v2.py"},"region":{"startLine":442,"startColumn":19,"endLine":442,"endColumn":59,"snippet":{}}}},"id":"OdcClientV2 :: _call_api \\n[odc_client_v2.py : 404_442]->/src/mcpDbOdc/src/mcpDbOdc/odc_client_v2.OdcClientV2._call_api._call_api_scope...ValueError","sourceNodeId":"OdcClientV2 :: _call_api \\n[odc_client_v2.py : 404_442]","targetNodeId":"/src/mcpDbOdc/src/mcpDbOdc/odc_client_v2.OdcClientV2._call_api._call_api_scope...ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDbOdc/src/mcpDbOdc/odc_client_v2.py"},"region":{"startLine":478,"startColumn":5,"endLine":478,"endColumn":39,"snippet":{}}}},"id":"main \\n[odc_client_v2.py : 466_478]->/src/mcpDbOdc/src/mcpDbOdc/odc_client_v2.main.main_scope..print","sourceNodeId":"main \\n[odc_client_v2.py : 466_478]","targetNodeId":"/src/mcpDbOdc/src/mcpDbOdc/odc_client_v2.main.main_scope..print"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpOpsCloud/src/mcpOpsCloud/server.py"},"region":{"startLine":23,"startColumn":2,"endLine":23,"endColumn":25,"snippet":{}}}},"id":"<__entry_point__>->.server.list_resources","sourceNodeId":"<__entry_point__>","targetNodeId":".server.list_resources"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpOpsCloud/src/mcpOpsCloud/server.py"},"region":{"startLine":40,"startColumn":2,"endLine":40,"endColumn":24,"snippet":{}}}},"id":"<__entry_point__>->.server.read_resource","sourceNodeId":"<__entry_point__>","targetNodeId":".server.read_resource"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpOpsCloud/src/mcpOpsCloud/server.py"},"region":{"startLine":56,"startColumn":2,"endLine":56,"endColumn":23,"snippet":{}}}},"id":"<__entry_point__>->.server.list_prompts","sourceNodeId":"<__entry_point__>","targetNodeId":".server.list_prompts"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpOpsCloud/src/mcpOpsCloud/server.py"},"region":{"startLine":77,"startColumn":2,"endLine":77,"endColumn":21,"snippet":{}}}},"id":"<__entry_point__>->.server.get_prompt","sourceNodeId":"<__entry_point__>","targetNodeId":".server.get_prompt"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDbQuery/src/mcpDbQuery/client.py"},"region":{"startLine":238,"startColumn":23,"endLine":238,"endColumn":126,"snippet":{}}}},"id":"<__entry_point__>->get_pysql_user_name \\n[client.py : 191_213]","sourceNodeId":"<__entry_point__>","targetNodeId":"get_pysql_user_name \\n[client.py : 191_213]"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDbQuery/src/mcpDbQuery/client.py"},"region":{"startLine":193,"startColumn":22,"endLine":193,"endColumn":54,"snippet":{}}}},"id":"get_pysql_user_name \\n[client.py : 191_213]->mcp_db_base.omc_client.get_physic_dbs","sourceNodeId":"get_pysql_user_name \\n[client.py : 191_213]","targetNodeId":"mcp_db_base.omc_client.get_physic_dbs"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDbQuery/src/mcpDbQuery/client.py"},"region":{"startLine":194,"startColumn":12,"endLine":194,"endColumn":27,"snippet":{}}}},"id":"get_pysql_user_name \\n[client.py : 191_213]->/src/mcpDbQuery/src/mcpDbQuery/client.get_pysql_user_name.get_pysql_user_name_scope..len","sourceNodeId":"get_pysql_user_name \\n[client.py : 191_213]","targetNodeId":"/src/mcpDbQuery/src/mcpDbQuery/client.get_pysql_user_name.get_pysql_user_name_scope..len"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDbQuery/src/mcpDbQuery/client.py"},"region":{"startLine":195,"startColumn":19,"endLine":195,"endColumn":68,"snippet":{}}}},"id":"get_pysql_user_name \\n[client.py : 191_213]->/src/mcpDbQuery/src/mcpDbQuery/client.get_pysql_user_name.get_pysql_user_name_scope...Exception","sourceNodeId":"get_pysql_user_name \\n[client.py : 191_213]","targetNodeId":"/src/mcpDbQuery/src/mcpDbQuery/client.get_pysql_user_name.get_pysql_user_name_scope...Exception"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDbQuery/src/mcpDbQuery/client.py"},"region":{"startLine":197,"startColumn":22,"endLine":197,"endColumn":54,"snippet":{}}}},"id":"get_pysql_user_name \\n[client.py : 191_213]->mcp_db_base.omc_client.get_physic_dbs(var arn:any=db_arn).get","sourceNodeId":"get_pysql_user_name \\n[client.py : 191_213]","targetNodeId":"mcp_db_base.omc_client.get_physic_dbs(var arn:any=db_arn).get"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDbQuery/src/mcpDbQuery/client.py"},"region":{"startLine":199,"startColumn":19,"endLine":199,"endColumn":68,"snippet":{}}}},"id":"get_pysql_user_name \\n[client.py : 191_213]->/src/mcpDbQuery/src/mcpDbQuery/client.get_pysql_user_name.get_pysql_user_name_scope...Exception","sourceNodeId":"get_pysql_user_name \\n[client.py : 191_213]","targetNodeId":"/src/mcpDbQuery/src/mcpDbQuery/client.get_pysql_user_name.get_pysql_user_name_scope...Exception"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDbQuery/src/mcpDbQuery/client.py"},"region":{"startLine":200,"startColumn":23,"endLine":200,"endColumn":63,"snippet":{}}}},"id":"get_pysql_user_name \\n[client.py : 191_213]->mcp_db_base.omc_client.get_tenant_info","sourceNodeId":"get_pysql_user_name \\n[client.py : 191_213]","targetNodeId":"mcp_db_base.omc_client.get_tenant_info"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDbQuery/src/mcpDbQuery/client.py"},"region":{"startLine":204,"startColumn":23,"endLine":204,"endColumn":58,"snippet":{}}}},"id":"get_pysql_user_name \\n[client.py : 191_213]->mcp_db_base.omc_client.get_tenant_info(var tenant:any=tenant_arn).get","sourceNodeId":"get_pysql_user_name \\n[client.py : 191_213]","targetNodeId":"mcp_db_base.omc_client.get_tenant_info(var tenant:any=tenant_arn).get"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDbQuery/src/mcpDbQuery/client.py"},"region":{"startLine":202,"startColumn":19,"endLine":202,"endColumn":75,"snippet":{}}}},"id":"get_pysql_user_name \\n[client.py : 191_213]->/src/mcpDbQuery/src/mcpDbQuery/client.get_pysql_user_name.get_pysql_user_name_scope...Exception","sourceNodeId":"get_pysql_user_name \\n[client.py : 191_213]","targetNodeId":"/src/mcpDbQuery/src/mcpDbQuery/client.get_pysql_user_name.get_pysql_user_name_scope...Exception"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDbQuery/src/mcpDbQuery/client.py"},"region":{"startLine":206,"startColumn":19,"endLine":206,"endColumn":75,"snippet":{}}}},"id":"get_pysql_user_name \\n[client.py : 191_213]->/src/mcpDbQuery/src/mcpDbQuery/client.get_pysql_user_name.get_pysql_user_name_scope...Exception","sourceNodeId":"get_pysql_user_name \\n[client.py : 191_213]","targetNodeId":"/src/mcpDbQuery/src/mcpDbQuery/client.get_pysql_user_name.get_pysql_user_name_scope...Exception"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDbQuery/src/mcpDbQuery/client.py"},"region":{"startLine":207,"startColumn":24,"endLine":207,"endColumn":74,"snippet":{}}}},"id":"get_pysql_user_name \\n[client.py : 191_213]->mcp_db_base.omc_client.get_cluster_info_v2","sourceNodeId":"get_pysql_user_name \\n[client.py : 191_213]","targetNodeId":"mcp_db_base.omc_client.get_cluster_info_v2"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDbQuery/src/mcpDbQuery/client.py"},"region":{"startLine":210,"startColumn":24,"endLine":210,"endColumn":55,"snippet":{}}}},"id":"get_pysql_user_name \\n[client.py : 191_213]->mcp_db_base.omc_client.get_cluster_info_v2(var cluster_arn:any=cluster_arn).get","sourceNodeId":"get_pysql_user_name \\n[client.py : 191_213]","targetNodeId":"mcp_db_base.omc_client.get_cluster_info_v2(var cluster_arn:any=cluster_arn).get"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDbQuery/src/mcpDbQuery/client.py"},"region":{"startLine":209,"startColumn":19,"endLine":209,"endColumn":78,"snippet":{}}}},"id":"get_pysql_user_name \\n[client.py : 191_213]->/src/mcpDbQuery/src/mcpDbQuery/client.get_pysql_user_name.get_pysql_user_name_scope...Exception","sourceNodeId":"get_pysql_user_name \\n[client.py : 191_213]","targetNodeId":"/src/mcpDbQuery/src/mcpDbQuery/client.get_pysql_user_name.get_pysql_user_name_scope...Exception"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDbQuery/src/mcpDbQuery/client.py"},"region":{"startLine":213,"startColumn":15,"endLine":213,"endColumn":54,"snippet":{}}}},"id":"get_pysql_user_name \\n[client.py : 191_213]->/src/mcpDbQuery/src/mcpDbQuery/client.get_pysql_user_name.get_pysql_user_name_scope...Exception","sourceNodeId":"get_pysql_user_name \\n[client.py : 191_213]","targetNodeId":"/src/mcpDbQuery/src/mcpDbQuery/client.get_pysql_user_name.get_pysql_user_name_scope...Exception"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDbQuery/src/mcpDbQuery/client.py"},"region":{"startLine":238,"startColumn":5,"endLine":238,"endColumn":128,"snippet":{}}}},"id":"<__entry_point__>->/src/mcpDbQuery/src/mcpDbQuery/client..print","sourceNodeId":"<__entry_point__>","targetNodeId":"/src/mcpDbQuery/src/mcpDbQuery/client..print"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDrm/src/mcpDrm/__init__.py"},"region":{"startLine":9,"startColumn":5,"endLine":9,"endColumn":11,"snippet":{}}}},"id":"<__entry_point__>->main \\n[__init__.py : 4_5]","sourceNodeId":"<__entry_point__>","targetNodeId":"main \\n[__init__.py : 4_5]"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDrm/src/mcpDrm/__init__.py"},"region":{"startLine":5,"startColumn":5,"endLine":5,"endColumn":32,"snippet":{}}}},"id":"main \\n[__init__.py : 4_5]->server.server.run","sourceNodeId":"main \\n[__init__.py : 4_5]","targetNodeId":"server.server.run"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpOpenSearch/src/mcpOpenSearch/util.py"},"region":{"startLine":15,"startColumn":11,"endLine":15,"endColumn":26,"snippet":{}}}},"id":"<__entry_point__>->syslib_from.config.Config","sourceNodeId":"<__entry_point__>","targetNodeId":"syslib_from.config.Config"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDima/src/mcpDima/client.py"},"region":{"startLine":211,"startColumn":23,"endLine":211,"endColumn":138,"snippet":{}}}},"id":"<__entry_point__>->page_search_work_item \\n[client.py : 94_139]","sourceNodeId":"<__entry_point__>","targetNodeId":"page_search_work_item \\n[client.py : 94_139]"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDima/src/mcpDima/client.py"},"region":{"startLine":122,"startColumn":54,"endLine":122,"endColumn":86,"snippet":{}}}},"id":"page_search_work_item \\n[client.py : 94_139]->get_staff_id_by_nick_name \\n[client.py : 187_197]","sourceNodeId":"page_search_work_item \\n[client.py : 94_139]","targetNodeId":"get_staff_id_by_nick_name \\n[client.py : 187_197]"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDima/src/mcpDima/client.py"},"region":{"startLine":192,"startColumn":16,"endLine":192,"endColumn":39,"snippet":{}}}},"id":"get_staff_id_by_nick_name \\n[client.py : 187_197]->syslib_from.aiohttp.ClientSession","sourceNodeId":"get_staff_id_by_nick_name \\n[client.py : 187_197]","targetNodeId":"syslib_from.aiohttp.ClientSession"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDima/src/mcpDima/client.py"},"region":{"startLine":193,"startColumn":20,"endLine":193,"endColumn":62,"snippet":{}}}},"id":"get_staff_id_by_nick_name \\n[client.py : 187_197]->syslib_from.aiohttp.ClientSession().get","sourceNodeId":"get_staff_id_by_nick_name \\n[client.py : 187_197]","targetNodeId":"syslib_from.aiohttp.ClientSession().get"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDima/src/mcpDima/client.py"},"region":{"startLine":194,"startColumn":22,"endLine":194,"endColumn":39,"snippet":{}}}},"id":"get_staff_id_by_nick_name \\n[client.py : 187_197]->syslib_from.aiohttp.ClientSession().get(url, var params:any=params, var ssl:any=false).json","sourceNodeId":"get_staff_id_by_nick_name \\n[client.py : 187_197]","targetNodeId":"syslib_from.aiohttp.ClientSession().get(url, var params:any=params, var ssl:any=false).json"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDima/src/mcpDima/client.py"},"region":{"startLine":197,"startColumn":20,"endLine":197,"endColumn":38,"snippet":{}}}},"id":"get_staff_id_by_nick_name \\n[client.py : 187_197]->syslib_from.aiohttp.ClientSession().get(url, var params:any=params, var ssl:any=false).json().get","sourceNodeId":"get_staff_id_by_nick_name \\n[client.py : 187_197]","targetNodeId":"syslib_from.aiohttp.ClientSession().get(url, var params:any=params, var ssl:any=false).json().get"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDima/src/mcpDima/client.py"},"region":{"startLine":197,"startColumn":20,"endLine":197,"endColumn":55,"snippet":{}}}},"id":"get_staff_id_by_nick_name \\n[client.py : 187_197]->syslib_from.aiohttp.ClientSession().get(url, var params:any=params, var ssl:any=false).json().get(data).get","sourceNodeId":"get_staff_id_by_nick_name \\n[client.py : 187_197]","targetNodeId":"syslib_from.aiohttp.ClientSession().get(url, var params:any=params, var ssl:any=false).json().get(data).get"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDima/src/mcpDima/client.py"},"region":{"startLine":122,"startColumn":34,"endLine":122,"endColumn":87,"snippet":{}}}},"id":"page_search_work_item \\n[client.py : 94_139]->syslib_from.asyncio.create_task","sourceNodeId":"page_search_work_item \\n[client.py : 94_139]","targetNodeId":"syslib_from.asyncio.create_task"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDima/src/mcpDima/client.py"},"region":{"startLine":124,"startColumn":38,"endLine":124,"endColumn":91,"snippet":{}}}},"id":"page_search_work_item \\n[client.py : 94_139]->syslib_from.config.WORK_ITEM_FILTER_VALUES_DICT.get","sourceNodeId":"page_search_work_item \\n[client.py : 94_139]","targetNodeId":"syslib_from.config.WORK_ITEM_FILTER_VALUES_DICT.get"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDima/src/mcpDima/client.py"},"region":{"startLine":124,"startColumn":21,"endLine":124,"endColumn":92,"snippet":{}}}},"id":"page_search_work_item \\n[client.py : 94_139]->new_value.append","sourceNodeId":"page_search_work_item \\n[client.py : 94_139]","targetNodeId":"new_value.append"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDima/src/mcpDima/client.py"},"region":{"startLine":124,"startColumn":21,"endLine":124,"endColumn":92,"snippet":{}}}},"id":"page_search_work_item \\n[client.py : 94_139]->append","sourceNodeId":"page_search_work_item \\n[client.py : 94_139]","targetNodeId":"append"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDima/src/mcpDima/client.py"},"region":{"startLine":125,"startColumn":16,"endLine":125,"endColumn":26,"snippet":{}}}},"id":"page_search_work_item \\n[client.py : 94_139]->/src/mcpDima/src/mcpDima/client.page_search_work_item.page_search_work_item_scope.....len","sourceNodeId":"page_search_work_item \\n[client.py : 94_139]","targetNodeId":"/src/mcpDima/src/mcpDima/client.page_search_work_item.page_search_work_item_scope.....len"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDima/src/mcpDima/client.py"},"region":{"startLine":126,"startColumn":33,"endLine":126,"endColumn":61,"snippet":{}}}},"id":"page_search_work_item \\n[client.py : 94_139]->syslib_from.asyncio.gather","sourceNodeId":"page_search_work_item \\n[client.py : 94_139]","targetNodeId":"syslib_from.asyncio.gather"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDima/src/mcpDima/client.py"},"region":{"startLine":127,"startColumn":29,"endLine":127,"endColumn":71,"snippet":{}}}},"id":"page_search_work_item \\n[client.py : 94_139]->get_dima_user_id_list \\n[client.py : 174_184]","sourceNodeId":"page_search_work_item \\n[client.py : 94_139]","targetNodeId":"get_dima_user_id_list \\n[client.py : 174_184]"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDima/src/mcpDima/client.py"},"region":{"startLine":179,"startColumn":16,"endLine":179,"endColumn":39,"snippet":{}}}},"id":"get_dima_user_id_list \\n[client.py : 174_184]->syslib_from.aiohttp.ClientSession","sourceNodeId":"get_dima_user_id_list \\n[client.py : 174_184]","targetNodeId":"syslib_from.aiohttp.ClientSession"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDima/src/mcpDima/client.py"},"region":{"startLine":180,"startColumn":57,"endLine":180,"endColumn":101,"snippet":{}}}},"id":"get_dima_user_id_list \\n[client.py : 174_184]->syslib_from.sign.get_dima_header","sourceNodeId":"get_dima_user_id_list \\n[client.py : 174_184]","targetNodeId":"syslib_from.sign.get_dima_header"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDima/src/mcpDima/client.py"},"region":{"startLine":180,"startColumn":20,"endLine":180,"endColumn":113,"snippet":{}}}},"id":"get_dima_user_id_list \\n[client.py : 174_184]->syslib_from.aiohttp.ClientSession().post","sourceNodeId":"get_dima_user_id_list \\n[client.py : 174_184]","targetNodeId":"syslib_from.aiohttp.ClientSession().post"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDima/src/mcpDima/client.py"},"region":{"startLine":181,"startColumn":22,"endLine":181,"endColumn":39,"snippet":{}}}},"id":"get_dima_user_id_list \\n[client.py : 174_184]->syslib_from.aiohttp.ClientSession().post(url, var json:any=body, var headers:any=sign.get_dima_header(config_.ak, config_.sk), var ssl:any=false).json","sourceNodeId":"get_dima_user_id_list \\n[client.py : 174_184]","targetNodeId":"syslib_from.aiohttp.ClientSession().post(url, var json:any=body, var headers:any=sign.get_dima_header(config_.ak, config_.sk), var ssl:any=false).json"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDima/src/mcpDima/client.py"},"region":{"startLine":184,"startColumn":52,"endLine":184,"endColumn":70,"snippet":{}}}},"id":"get_dima_user_id_list \\n[client.py : 174_184]->syslib_from.aiohttp.ClientSession().post(url, var json:any=body, var headers:any=sign.get_dima_header(config_.ak, config_.sk), var ssl:any=false).json().get","sourceNodeId":"get_dima_user_id_list \\n[client.py : 174_184]","targetNodeId":"syslib_from.aiohttp.ClientSession().post(url, var json:any=body, var headers:any=sign.get_dima_header(config_.ak, config_.sk), var ssl:any=false).json().get"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDima/src/mcpDima/client.py"},"region":{"startLine":184,"startColumn":21,"endLine":184,"endColumn":39,"snippet":{}}}},"id":"get_dima_user_id_list \\n[client.py : 174_184]->syslib_from.aiohttp.ClientSession().post(url, var json:any=body, var headers:any=sign.get_dima_header(config_.ak, config_.sk), var ssl:any=false).json().get(data).get","sourceNodeId":"get_dima_user_id_list \\n[client.py : 174_184]","targetNodeId":"syslib_from.aiohttp.ClientSession().post(url, var json:any=body, var headers:any=sign.get_dima_header(config_.ak, config_.sk), var ssl:any=false).json().get(data).get"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDima/src/mcpDima/client.py"},"region":{"startLine":131,"startColumn":16,"endLine":131,"endColumn":39,"snippet":{}}}},"id":"page_search_work_item \\n[client.py : 94_139]->syslib_from.aiohttp.ClientSession","sourceNodeId":"page_search_work_item \\n[client.py : 94_139]","targetNodeId":"syslib_from.aiohttp.ClientSession"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDima/src/mcpDima/client.py"},"region":{"startLine":133,"startColumn":41,"endLine":133,"endColumn":85,"snippet":{}}}},"id":"page_search_work_item \\n[client.py : 94_139]->syslib_from.sign.get_dima_header","sourceNodeId":"page_search_work_item \\n[client.py : 94_139]","targetNodeId":"syslib_from.sign.get_dima_header"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDima/src/mcpDima/client.py"},"region":{"startLine":132,"startColumn":20,"endLine":133,"endColumn":97,"snippet":{}}}},"id":"page_search_work_item \\n[client.py : 94_139]->syslib_from.aiohttp.ClientSession().post","sourceNodeId":"page_search_work_item \\n[client.py : 94_139]","targetNodeId":"syslib_from.aiohttp.ClientSession().post"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDima/src/mcpDima/client.py"},"region":{"startLine":134,"startColumn":29,"endLine":134,"endColumn":46,"snippet":{}}}},"id":"page_search_work_item \\n[client.py : 94_139]->syslib_from.aiohttp.ClientSession().post(url, var params:any=params, var json:any=body, var headers:any=sign.get_dima_header(config_.ak, config_.sk), var ssl:any=false).json","sourceNodeId":"page_search_work_item \\n[client.py : 94_139]","targetNodeId":"syslib_from.aiohttp.ClientSession().post(url, var params:any=params, var json:any=body, var headers:any=sign.get_dima_header(config_.ak, config_.sk), var ssl:any=false).json"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDima/src/mcpDima/client.py"},"region":{"startLine":136,"startColumn":20,"endLine":136,"endColumn":48,"snippet":{}}}},"id":"page_search_work_item \\n[client.py : 94_139]->syslib_from.aiohttp.ClientSession().post(url, var params:any=params, var json:any=body, var headers:any=sign.get_dima_header(config_.ak, config_.sk), var ssl:any=false).json().get","sourceNodeId":"page_search_work_item \\n[client.py : 94_139]","targetNodeId":"syslib_from.aiohttp.ClientSession().post(url, var params:any=params, var json:any=body, var headers:any=sign.get_dima_header(config_.ak, config_.sk), var ssl:any=false).json().get"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDima/src/mcpDima/client.py"},"region":{"startLine":138,"startColumn":19,"endLine":138,"endColumn":54,"snippet":{}}}},"id":"page_search_work_item \\n[client.py : 94_139]->syslib_from.model.WorkItem.model_validate","sourceNodeId":"page_search_work_item \\n[client.py : 94_139]","targetNodeId":"syslib_from.model.WorkItem.model_validate"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDima/src/mcpDima/client.py"},"region":{"startLine":139,"startColumn":20,"endLine":139,"endColumn":38,"snippet":{}}}},"id":"page_search_work_item \\n[client.py : 94_139]->syslib_from.model.to_json","sourceNodeId":"page_search_work_item \\n[client.py : 94_139]","targetNodeId":"syslib_from.model.to_json"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDima/src/mcpDima/client.py"},"region":{"startLine":211,"startColumn":5,"endLine":211,"endColumn":140,"snippet":{}}}},"id":"<__entry_point__>->/src/mcpDima/src/mcpDima/client..print","sourceNodeId":"<__entry_point__>","targetNodeId":"/src/mcpDima/src/mcpDima/client..print"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpOpenSearch/src/mcpOpenSearch/util.py"},"region":{"startLine":23,"startColumn":23,"endLine":23,"endColumn":98,"snippet":{}}}},"id":"<__entry_point__>->syslib_from.os.path.join","sourceNodeId":"<__entry_point__>","targetNodeId":"syslib_from.os.path.join"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDrm/src/mcpDrm/server.py"},"region":{"startLine":18,"startColumn":21,"endLine":18,"endColumn":45,"snippet":{}}}},"id":"<__entry_point__>->oneapi.opssla.DrmManageFacade.DrmManageFacade","sourceNodeId":"<__entry_point__>","targetNodeId":"oneapi.opssla.DrmManageFacade.DrmManageFacade"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDrm/src/mcpDrm/server.py"},"region":{"startLine":19,"startColumn":34,"endLine":19,"endColumn":69,"snippet":{}}}},"id":"<__entry_point__>->oneapi.opssla.DrmLargeConfigManageFacade.DrmLargeConfigManageFacade","sourceNodeId":"<__entry_point__>","targetNodeId":"oneapi.opssla.DrmLargeConfigManageFacade.DrmLargeConfigManageFacade"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDrm/src/mcpDrm/server.py"},"region":{"startLine":20,"startColumn":29,"endLine":20,"endColumn":60,"snippet":{}}}},"id":"<__entry_point__>->oneapi.opssla.ResourceMetaDataFacade.ResourceMetaDataFacade","sourceNodeId":"<__entry_point__>","targetNodeId":"oneapi.opssla.ResourceMetaDataFacade.ResourceMetaDataFacade"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDrm/src/mcpDrm/server.py"},"region":{"startLine":89,"startColumn":1,"endLine":115,"endColumn":59,"snippet":{}}}},"id":"<__entry_point__>->query_cur_drm_value \\n[server.py : 89_115]","sourceNodeId":"<__entry_point__>","targetNodeId":"query_cur_drm_value \\n[server.py : 89_115]"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDrm/src/mcpDrm/server.py"},"region":{"startLine":97,"startColumn":16,"endLine":97,"endColumn":72,"snippet":{}}}},"id":"query_cur_drm_value \\n[server.py : 89_115]->oneapi.opssla.ResourceMetaDataFacade.ResourceMetaDataFacade(layotto).search","sourceNodeId":"query_cur_drm_value \\n[server.py : 89_115]","targetNodeId":"oneapi.opssla.ResourceMetaDataFacade.ResourceMetaDataFacade(layotto).search"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDrm/src/mcpDrm/server.py"},"region":{"startLine":100,"startColumn":18,"endLine":100,"endColumn":28,"snippet":{}}}},"id":"query_cur_drm_value \\n[server.py : 89_115]->/src/mcpDrm/src/mcpDrm/server.query_cur_drm_value.query_cur_drm_value_scope..len","sourceNodeId":"query_cur_drm_value \\n[server.py : 89_115]","targetNodeId":"/src/mcpDrm/src/mcpDrm/server.query_cur_drm_value.query_cur_drm_value_scope..len"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDrm/src/mcpDrm/server.py"},"region":{"startLine":99,"startColumn":15,"endLine":99,"endColumn":65,"snippet":{}}}},"id":"query_cur_drm_value \\n[server.py : 89_115]->/src/mcpDrm/src/mcpDrm/server.query_cur_drm_value.query_cur_drm_value_scope...ValueError","sourceNodeId":"query_cur_drm_value \\n[server.py : 89_115]","targetNodeId":"/src/mcpDrm/src/mcpDrm/server.query_cur_drm_value.query_cur_drm_value_scope...ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDrm/src/mcpDrm/server.py"},"region":{"startLine":112,"startColumn":29,"endLine":112,"endColumn":68,"snippet":{}}}},"id":"query_cur_drm_value \\n[server.py : 89_115]->oneapi.opssla.ResourceMetaDataFacade.ResourceMetaDataFacade(layotto).search(resource_id, var limit:any=100).data.get","sourceNodeId":"query_cur_drm_value \\n[server.py : 89_115]","targetNodeId":"oneapi.opssla.ResourceMetaDataFacade.ResourceMetaDataFacade(layotto).search(resource_id, var limit:any=100).data.get"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDrm/src/mcpDrm/server.py"},"region":{"startLine":101,"startColumn":16,"endLine":107,"endColumn":10,"snippet":{}}}},"id":"query_cur_drm_value \\n[server.py : 89_115]->oneapi.opssla.DrmManageFacade.DrmManageFacade(layotto).queryBatchValue_f4ac1f8","sourceNodeId":"query_cur_drm_value \\n[server.py : 89_115]","targetNodeId":"oneapi.opssla.DrmManageFacade.DrmManageFacade(layotto).queryBatchValue_f4ac1f8"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDrm/src/mcpDrm/server.py"},"region":{"startLine":109,"startColumn":16,"endLine":114,"endColumn":10,"snippet":{}}}},"id":"query_cur_drm_value \\n[server.py : 89_115]->oneapi.opssla.DrmManageFacade.DrmManageFacade(layotto).queryBatchValue_b6fef5f","sourceNodeId":"query_cur_drm_value \\n[server.py : 89_115]","targetNodeId":"oneapi.opssla.DrmManageFacade.DrmManageFacade(layotto).queryBatchValue_b6fef5f"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDrm/src/mcpDrm/server.py"},"region":{"startLine":115,"startColumn":23,"endLine":115,"endColumn":38,"snippet":{}}}},"id":"query_cur_drm_value \\n[server.py : 89_115]->/src/mcpDrm/src/mcpDrm/server.query_cur_drm_value.query_cur_drm_value_scope..resp.get_json","sourceNodeId":"query_cur_drm_value \\n[server.py : 89_115]","targetNodeId":"/src/mcpDrm/src/mcpDrm/server.query_cur_drm_value.query_cur_drm_value_scope..resp.get_json"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDrm/src/mcpDrm/server.py"},"region":{"startLine":115,"startColumn":12,"endLine":115,"endColumn":59,"snippet":{}}}},"id":"query_cur_drm_value \\n[server.py : 89_115]->syslib_from.json.dumps","sourceNodeId":"query_cur_drm_value \\n[server.py : 89_115]","targetNodeId":"syslib_from.json.dumps"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDrm/src/mcpDrm/server.py"},"region":{"startLine":127,"startColumn":5,"endLine":128,"endColumn":120,"snippet":{}}}},"id":"<__entry_point__>->/src/mcpDrm/src/mcpDrm/server..print","sourceNodeId":"<__entry_point__>","targetNodeId":"/src/mcpDrm/src/mcpDrm/server..print"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpFileOperation/src/mcpFileOperation/server.py"},"region":{"startLine":106,"startColumn":11,"endLine":106,"endColumn":84,"snippet":{}}}},"id":"<__entry_point__>->mcp_common.utils.oss_utils.get_file_infos","sourceNodeId":"<__entry_point__>","targetNodeId":"mcp_common.utils.oss_utils.get_file_infos"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpFileOperation/src/mcpFileOperation/server.py"},"region":{"startLine":107,"startColumn":11,"endLine":107,"endColumn":27,"snippet":{}}}},"id":"<__entry_point__>->mcp_common.utils.oss_utils.get_file_infos({0:opsgpt/upload/yicheng/66100217_标注结果明细.csv}).to_dict","sourceNodeId":"<__entry_point__>","targetNodeId":"mcp_common.utils.oss_utils.get_file_infos({0:opsgpt/upload/yicheng/66100217_标注结果明细.csv}).to_dict"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpFileOperation/src/mcpFileOperation/server.py"},"region":{"startLine":107,"startColumn":5,"endLine":107,"endColumn":28,"snippet":{}}}},"id":"<__entry_point__>->/src/mcpFileOperation/src/mcpFileOperation/server..print","sourceNodeId":"<__entry_point__>","targetNodeId":"/src/mcpFileOperation/src/mcpFileOperation/server..print"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpFluxFind/src/mcpFluxFind/server_client.py"},"region":{"startLine":170,"startColumn":14,"endLine":170,"endColumn":54,"snippet":{}}}},"id":"<__entry_point__>->_find_property_by_scene_code \\n[server_client.py : 122_154]","sourceNodeId":"<__entry_point__>","targetNodeId":"_find_property_by_scene_code \\n[server_client.py : 122_154]"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpFluxFind/src/mcpFluxFind/server_client.py"},"region":{"startLine":150,"startColumn":9,"endLine":150,"endColumn":148,"snippet":{}}}},"id":"_find_property_by_scene_code \\n[server_client.py : 122_154]->syslib_from.logging.getLogger(mcp-server).info","sourceNodeId":"_find_property_by_scene_code \\n[server_client.py : 122_154]","targetNodeId":"syslib_from.logging.getLogger(mcp-server).info"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpFluxFind/src/mcpFluxFind/server_client.py"},"region":{"startLine":134,"startColumn":20,"endLine":134,"endColumn":52,"snippet":{}}}},"id":"_find_property_by_scene_code \\n[server_client.py : 122_154]->syslib_from.requests.get","sourceNodeId":"_find_property_by_scene_code \\n[server_client.py : 122_154]","targetNodeId":"syslib_from.requests.get"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpFluxFind/src/mcpFluxFind/server_client.py"},"region":{"startLine":135,"startColumn":9,"endLine":135,"endColumn":36,"snippet":{}}}},"id":"_find_property_by_scene_code \\n[server_client.py : 122_154]->syslib_from.requests.get(url, var params:any=params).raise_for_status","sourceNodeId":"_find_property_by_scene_code \\n[server_client.py : 122_154]","targetNodeId":"syslib_from.requests.get(url, var params:any=params).raise_for_status"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpFluxFind/src/mcpFluxFind/server_client.py"},"region":{"startLine":136,"startColumn":18,"endLine":136,"endColumn":33,"snippet":{}}}},"id":"_find_property_by_scene_code \\n[server_client.py : 122_154]->syslib_from.requests.get(url, var params:any=params).json","sourceNodeId":"_find_property_by_scene_code \\n[server_client.py : 122_154]","targetNodeId":"syslib_from.requests.get(url, var params:any=params).json"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpFluxFind/src/mcpFluxFind/server_client.py"},"region":{"startLine":142,"startColumn":20,"endLine":142,"endColumn":38,"snippet":{}}}},"id":"_find_property_by_scene_code \\n[server_client.py : 122_154]->syslib_from.requests.get(url, var params:any=params).json().get","sourceNodeId":"_find_property_by_scene_code \\n[server_client.py : 122_154]","targetNodeId":"syslib_from.requests.get(url, var params:any=params).json().get"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpFluxFind/src/mcpFluxFind/server_client.py"},"region":{"startLine":144,"startColumn":24,"endLine":144,"endColumn":49,"snippet":{}}}},"id":"_find_property_by_scene_code \\n[server_client.py : 122_154]->syslib_from.requests.get(url, var params:any=params).json().get(data).get","sourceNodeId":"_find_property_by_scene_code \\n[server_client.py : 122_154]","targetNodeId":"syslib_from.requests.get(url, var params:any=params).json().get(data).get"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpFluxFind/src/mcpFluxFind/server_client.py"},"region":{"startLine":151,"startColumn":29,"endLine":151,"endColumn":36,"snippet":{}}}},"id":"_find_property_by_scene_code \\n[server_client.py : 122_154]->/src/mcpFluxFind/src/mcpFluxFind/server_client._find_property_by_scene_code._find_property_by_scene_code_scope...type","sourceNodeId":"_find_property_by_scene_code \\n[server_client.py : 122_154]","targetNodeId":"/src/mcpFluxFind/src/mcpFluxFind/server_client._find_property_by_scene_code._find_property_by_scene_code_scope...type"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpFluxFind/src/mcpFluxFind/server_client.py"},"region":{"startLine":151,"startColumn":9,"endLine":151,"endColumn":53,"snippet":{}}}},"id":"_find_property_by_scene_code \\n[server_client.py : 122_154]->/src/mcpFluxFind/src/mcpFluxFind/server_client._find_property_by_scene_code._find_property_by_scene_code_scope...print_debug_info","sourceNodeId":"_find_property_by_scene_code \\n[server_client.py : 122_154]","targetNodeId":"/src/mcpFluxFind/src/mcpFluxFind/server_client._find_property_by_scene_code._find_property_by_scene_code_scope...print_debug_info"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpFluxFind/src/mcpFluxFind/server_client.py"},"region":{"startLine":152,"startColumn":9,"endLine":152,"endColumn":30,"snippet":{}}}},"id":"_find_property_by_scene_code \\n[server_client.py : 122_154]->syslib_from.traceback.print_exc","sourceNodeId":"_find_property_by_scene_code \\n[server_client.py : 122_154]","targetNodeId":"syslib_from.traceback.print_exc"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpFluxFind/src/mcpFluxFind/server_client.py"},"region":{"startLine":171,"startColumn":5,"endLine":171,"endColumn":18,"snippet":{}}}},"id":"<__entry_point__>->/src/mcpFluxFind/src/mcpFluxFind/server_client..print","sourceNodeId":"<__entry_point__>","targetNodeId":"/src/mcpFluxFind/src/mcpFluxFind/server_client..print"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpFluxScene/src/mcpFluxScene/app.py"},"region":{"startLine":9,"startColumn":11,"endLine":9,"endColumn":77,"snippet":{}}}},"id":"<__entry_point__>->/src/mcpFluxScene/src/mcpFluxScene/app..ImportError","sourceNodeId":"<__entry_point__>","targetNodeId":"/src/mcpFluxScene/src/mcpFluxScene/app..ImportError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpFluxScene/src/mcpFluxScene/scene_client.py"},"region":{"startLine":606,"startColumn":14,"endLine":606,"endColumn":58,"snippet":{}}}},"id":"<__entry_point__>->invoke_test_report_agent_new \\n[scene_client.py : 519_563]","sourceNodeId":"<__entry_point__>","targetNodeId":"invoke_test_report_agent_new \\n[scene_client.py : 519_563]"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpFluxScene/src/mcpFluxScene/scene_client.py"},"region":{"startLine":523,"startColumn":18,"endLine":523,"endColumn":30,"snippet":{}}}},"id":"invoke_test_report_agent_new \\n[scene_client.py : 519_563]->syslib_from.uuid.uuid4","sourceNodeId":"invoke_test_report_agent_new \\n[scene_client.py : 519_563]","targetNodeId":"syslib_from.uuid.uuid4"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpFluxScene/src/mcpFluxScene/scene_client.py"},"region":{"startLine":559,"startColumn":9,"endLine":559,"endColumn":129,"snippet":{}}}},"id":"invoke_test_report_agent_new \\n[scene_client.py : 519_563]->syslib_from.logging.getLogger(mcp-server).info","sourceNodeId":"invoke_test_report_agent_new \\n[scene_client.py : 519_563]","targetNodeId":"syslib_from.logging.getLogger(mcp-server).info"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpFluxScene/src/mcpFluxScene/scene_client.py"},"region":{"startLine":545,"startColumn":22,"endLine":545,"endColumn":33,"snippet":{}}}},"id":"invoke_test_report_agent_new \\n[scene_client.py : 519_563]->syslib_from.time.time","sourceNodeId":"invoke_test_report_agent_new \\n[scene_client.py : 519_563]","targetNodeId":"syslib_from.time.time"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpFluxScene/src/mcpFluxScene/scene_client.py"},"region":{"startLine":546,"startColumn":26,"endLine":546,"endColumn":111,"snippet":{}}}},"id":"invoke_test_report_agent_new \\n[scene_client.py : 519_563]->factory.ClientFactory","sourceNodeId":"invoke_test_report_agent_new \\n[scene_client.py : 519_563]","targetNodeId":"factory.ClientFactory"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpFluxScene/src/mcpFluxScene/scene_client.py"},"region":{"startLine":549,"startColumn":23,"endLine":549,"endColumn":76,"snippet":{}}}},"id":"invoke_test_report_agent_new \\n[scene_client.py : 519_563]->factory.ClientFactory(DORAEMON_API_KEY_ID, DORAEMON_API_KEY_SECRET, var api_url:any=DORAEMON_API_URL).get_client","sourceNodeId":"invoke_test_report_agent_new \\n[scene_client.py : 519_563]","targetNodeId":"factory.ClientFactory(DORAEMON_API_KEY_ID, DORAEMON_API_KEY_SECRET, var api_url:any=DORAEMON_API_URL).get_client"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpFluxScene/src/mcpFluxScene/scene_client.py"},"region":{"startLine":550,"startColumn":27,"endLine":550,"endColumn":107,"snippet":{}}}},"id":"invoke_test_report_agent_new \\n[scene_client.py : 519_563]->factory.ClientFactory(DORAEMON_API_KEY_ID, DORAEMON_API_KEY_SECRET, var api_url:any=DORAEMON_API_URL).get_client(TEST_REPORT_APP_ID, text).completion","sourceNodeId":"invoke_test_report_agent_new \\n[scene_client.py : 519_563]","targetNodeId":"factory.ClientFactory(DORAEMON_API_KEY_ID, DORAEMON_API_KEY_SECRET, var api_url:any=DORAEMON_API_URL).get_client(TEST_REPORT_APP_ID, text).completion"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpFluxScene/src/mcpFluxScene/scene_client.py"},"region":{"startLine":552,"startColumn":56,"endLine":552,"endColumn":105,"snippet":{}}}},"id":"invoke_test_report_agent_new \\n[scene_client.py : 519_563]->handle_response_text \\n[scene_client.py : 566_592]","sourceNodeId":"invoke_test_report_agent_new \\n[scene_client.py : 519_563]","targetNodeId":"handle_response_text \\n[scene_client.py : 566_592]"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpFluxScene/src/mcpFluxScene/scene_client.py"},"region":{"startLine":571,"startColumn":34,"endLine":571,"endColumn":80,"snippet":{}}}},"id":"handle_response_text \\n[scene_client.py : 566_592]->unexpected media type: {}.format","sourceNodeId":"handle_response_text \\n[scene_client.py : 566_592]","targetNodeId":"unexpected media type: {}.format"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpFluxScene/src/mcpFluxScene/scene_client.py"},"region":{"startLine":571,"startColumn":5,"endLine":571,"endColumn":80,"snippet":{}}}},"id":"handle_response_text \\n[scene_client.py : 566_592]->/src/mcpFluxScene/src/mcpFluxScene/scene_client.handle_response_text.handle_response_text_scope..assert","sourceNodeId":"handle_response_text \\n[scene_client.py : 566_592]","targetNodeId":"/src/mcpFluxScene/src/mcpFluxScene/scene_client.handle_response_text.handle_response_text_scope..assert"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpFluxScene/src/mcpFluxScene/scene_client.py"},"region":{"startLine":587,"startColumn":16,"endLine":587,"endColumn":27,"snippet":{}}}},"id":"handle_response_text \\n[scene_client.py : 566_592]->syslib_from.time.time","sourceNodeId":"handle_response_text \\n[scene_client.py : 566_592]","targetNodeId":"syslib_from.time.time"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpFluxScene/src/mcpFluxScene/scene_client.py"},"region":{"startLine":590,"startColumn":5,"endLine":590,"endColumn":95,"snippet":{}}}},"id":"handle_response_text \\n[scene_client.py : 566_592]->syslib_from.logging.getLogger(mcp-server).info","sourceNodeId":"handle_response_text \\n[scene_client.py : 566_592]","targetNodeId":"syslib_from.logging.getLogger(mcp-server).info"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpFluxScene/src/mcpFluxScene/scene_client.py"},"region":{"startLine":560,"startColumn":29,"endLine":560,"endColumn":36,"snippet":{}}}},"id":"invoke_test_report_agent_new \\n[scene_client.py : 519_563]->/src/mcpFluxScene/src/mcpFluxScene/scene_client.invoke_test_report_agent_new.invoke_test_report_agent_new_scope...type","sourceNodeId":"invoke_test_report_agent_new \\n[scene_client.py : 519_563]","targetNodeId":"/src/mcpFluxScene/src/mcpFluxScene/scene_client.invoke_test_report_agent_new.invoke_test_report_agent_new_scope...type"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpFluxScene/src/mcpFluxScene/scene_client.py"},"region":{"startLine":560,"startColumn":9,"endLine":560,"endColumn":53,"snippet":{}}}},"id":"invoke_test_report_agent_new \\n[scene_client.py : 519_563]->print_debug_info \\n[scene_client.py : 357_358]","sourceNodeId":"invoke_test_report_agent_new \\n[scene_client.py : 519_563]","targetNodeId":"print_debug_info \\n[scene_client.py : 357_358]"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpFluxScene/src/mcpFluxScene/scene_client.py"},"region":{"startLine":358,"startColumn":5,"endLine":358,"endColumn":19,"snippet":{}}}},"id":"print_debug_info \\n[scene_client.py : 357_358]->/src/mcpFluxScene/src/mcpFluxScene/scene_client.print_debug_info.print_debug_info_scope..print","sourceNodeId":"print_debug_info \\n[scene_client.py : 357_358]","targetNodeId":"/src/mcpFluxScene/src/mcpFluxScene/scene_client.print_debug_info.print_debug_info_scope..print"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpFluxScene/src/mcpFluxScene/scene_client.py"},"region":{"startLine":561,"startColumn":9,"endLine":561,"endColumn":30,"snippet":{}}}},"id":"invoke_test_report_agent_new \\n[scene_client.py : 519_563]->syslib_from.traceback.print_exc","sourceNodeId":"invoke_test_report_agent_new \\n[scene_client.py : 519_563]","targetNodeId":"syslib_from.traceback.print_exc"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpFluxScene/src/mcpFluxScene/scene_client.py"},"region":{"startLine":607,"startColumn":5,"endLine":607,"endColumn":18,"snippet":{}}}},"id":"<__entry_point__>->/src/mcpFluxScene/src/mcpFluxScene/scene_client..print","sourceNodeId":"<__entry_point__>","targetNodeId":"/src/mcpFluxScene/src/mcpFluxScene/scene_client..print"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpLinglong/src/mcpLinglong/server.py"},"region":{"startLine":18,"startColumn":19,"endLine":18,"endColumn":48,"snippet":{}}}},"id":"<__entry_point__>->oneapi.linglongmng.LinglongModuleFacade.LinglongModuleFacade","sourceNodeId":"<__entry_point__>","targetNodeId":"oneapi.linglongmng.LinglongModuleFacade.LinglongModuleFacade"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpLinglong/src/mcpLinglong/server.py"},"region":{"startLine":19,"startColumn":21,"endLine":19,"endColumn":54,"snippet":{}}}},"id":"<__entry_point__>->oneapi.linglongmng.FunctionMngServiceFacade.FunctionMngServiceFacade","sourceNodeId":"<__entry_point__>","targetNodeId":"oneapi.linglongmng.FunctionMngServiceFacade.FunctionMngServiceFacade"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpMonitorWithFile/src/mcpMonitorWithFile/maas_sql_client.py"},"region":{"startLine":222,"startColumn":9,"endLine":223,"endColumn":54,"snippet":{}}}},"id":"<__entry_point__>->get_multi_metric \\n[maas_sql_client.py : 175_182]","sourceNodeId":"<__entry_point__>","targetNodeId":"get_multi_metric \\n[maas_sql_client.py : 175_182]"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpMonitorWithFile/src/mcpMonitorWithFile/maas_sql_client.py"},"region":{"startLine":181,"startColumn":34,"endLine":181,"endColumn":54,"snippet":{}}}},"id":"get_multi_metric \\n[maas_sql_client.py : 175_182]->,.join","sourceNodeId":"get_multi_metric \\n[maas_sql_client.py : 175_182]","targetNodeId":",.join"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpMonitorWithFile/src/mcpMonitorWithFile/maas_sql_client.py"},"region":{"startLine":181,"startColumn":93,"endLine":181,"endColumn":135,"snippet":{}}}},"id":"get_multi_metric \\n[maas_sql_client.py : 175_182]->ob@@sysstat@@tenant@@DEFAULT@@1@@DEFAULT.where_condition.format","sourceNodeId":"get_multi_metric \\n[maas_sql_client.py : 175_182]","targetNodeId":"ob@@sysstat@@tenant@@DEFAULT@@1@@DEFAULT.where_condition.format"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpMonitorWithFile/src/mcpMonitorWithFile/maas_sql_client.py"},"region":{"startLine":181,"startColumn":93,"endLine":181,"endColumn":135,"snippet":{}}}},"id":"get_multi_metric \\n[maas_sql_client.py : 175_182]->`tenant` = \\'{tenant}\\'.where_condition.format","sourceNodeId":"get_multi_metric \\n[maas_sql_client.py : 175_182]","targetNodeId":"`tenant` = \\'{tenant}\\'.where_condition.format"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpMonitorWithFile/src/mcpMonitorWithFile/maas_sql_client.py"},"region":{"startLine":180,"startColumn":14,"endLine":181,"endColumn":203,"snippet":{}}}},"id":"get_multi_metric \\n[maas_sql_client.py : 175_182]->_get_maas_sql_data \\n[maas_sql_client.py : 136_172]","sourceNodeId":"get_multi_metric \\n[maas_sql_client.py : 175_182]","targetNodeId":"_get_maas_sql_data \\n[maas_sql_client.py : 136_172]"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpMonitorWithFile/src/mcpMonitorWithFile/maas_sql_client.py"},"region":{"startLine":145,"startColumn":15,"endLine":145,"endColumn":46,"snippet":{}}}},"id":"_get_maas_sql_data \\n[maas_sql_client.py : 136_172]->_replace_seconds_with_zero \\n[maas_sql_client.py : 199_211]","sourceNodeId":"_get_maas_sql_data \\n[maas_sql_client.py : 136_172]","targetNodeId":"_replace_seconds_with_zero \\n[maas_sql_client.py : 199_211]"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpMonitorWithFile/src/mcpMonitorWithFile/maas_sql_client.py"},"region":{"startLine":210,"startColumn":20,"endLine":210,"endColumn":54,"snippet":{}}}},"id":"_replace_seconds_with_zero \\n[maas_sql_client.py : 199_211]->syslib_from.re.sub","sourceNodeId":"_replace_seconds_with_zero \\n[maas_sql_client.py : 199_211]","targetNodeId":"syslib_from.re.sub"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpMonitorWithFile/src/mcpMonitorWithFile/maas_sql_client.py"},"region":{"startLine":210,"startColumn":20,"endLine":210,"endColumn":54,"snippet":{}}}},"id":"syslib_from.re.sub->replace_func \\n[maas_sql_client.py : 205_206]","sourceNodeId":"syslib_from.re.sub","targetNodeId":"replace_func \\n[maas_sql_client.py : 205_206]"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpMonitorWithFile/src/mcpMonitorWithFile/maas_sql_client.py"},"region":{"startLine":206,"startColumn":16,"endLine":206,"endColumn":30,"snippet":{}}}},"id":"replace_func \\n[maas_sql_client.py : 205_206]->match.group","sourceNodeId":"replace_func \\n[maas_sql_client.py : 205_206]","targetNodeId":"match.group"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpMonitorWithFile/src/mcpMonitorWithFile/maas_sql_client.py"},"region":{"startLine":154,"startColumn":77,"endLine":154,"endColumn":87,"snippet":{}}}},"id":"_get_maas_sql_data \\n[maas_sql_client.py : 136_172]->_headers \\n[maas_sql_client.py : 43_66]","sourceNodeId":"_get_maas_sql_data \\n[maas_sql_client.py : 136_172]","targetNodeId":"_headers \\n[maas_sql_client.py : 43_66]"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpMonitorWithFile/src/mcpMonitorWithFile/maas_sql_client.py"},"region":{"startLine":45,"startColumn":19,"endLine":45,"endColumn":44,"snippet":{}}}},"id":"_headers \\n[maas_sql_client.py : 43_66]->syslib_from.os.environ.get","sourceNodeId":"_headers \\n[maas_sql_client.py : 43_66]","targetNodeId":"syslib_from.os.environ.get"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpMonitorWithFile/src/mcpMonitorWithFile/maas_sql_client.py"},"region":{"startLine":46,"startColumn":5,"endLine":46,"endColumn":41,"snippet":{}}}},"id":"_headers \\n[maas_sql_client.py : 43_66]->syslib_from.logging.getLogger(__name__).info","sourceNodeId":"_headers \\n[maas_sql_client.py : 43_66]","targetNodeId":"syslib_from.logging.getLogger(__name__).info"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpMonitorWithFile/src/mcpMonitorWithFile/maas_sql_client.py"},"region":{"startLine":47,"startColumn":25,"endLine":47,"endColumn":36,"snippet":{}}}},"id":"_headers \\n[maas_sql_client.py : 43_66]->syslib_from.time.time","sourceNodeId":"_headers \\n[maas_sql_client.py : 43_66]","targetNodeId":"syslib_from.time.time"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpMonitorWithFile/src/mcpMonitorWithFile/maas_sql_client.py"},"region":{"startLine":47,"startColumn":21,"endLine":47,"endColumn":37,"snippet":{}}}},"id":"_headers \\n[maas_sql_client.py : 43_66]->/src/mcpMonitorWithFile/src/mcpMonitorWithFile/maas_sql_client._headers._headers_scope..int","sourceNodeId":"_headers \\n[maas_sql_client.py : 43_66]","targetNodeId":"/src/mcpMonitorWithFile/src/mcpMonitorWithFile/maas_sql_client._headers._headers_scope..int"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpMonitorWithFile/src/mcpMonitorWithFile/maas_sql_client.py"},"region":{"startLine":48,"startColumn":24,"endLine":48,"endColumn":55,"snippet":{}}}},"id":"_headers \\n[maas_sql_client.py : 43_66]->syslib_from.random.sample","sourceNodeId":"_headers \\n[maas_sql_client.py : 43_66]","targetNodeId":"syslib_from.random.sample"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpMonitorWithFile/src/mcpMonitorWithFile/maas_sql_client.py"},"region":{"startLine":48,"startColumn":16,"endLine":48,"endColumn":56,"snippet":{}}}},"id":"_headers \\n[maas_sql_client.py : 43_66]->join","sourceNodeId":"_headers \\n[maas_sql_client.py : 43_66]","targetNodeId":"join"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpMonitorWithFile/src/mcpMonitorWithFile/maas_sql_client.py"},"region":{"startLine":61,"startColumn":29,"endLine":61,"endColumn":47,"snippet":{}}}},"id":"_headers \\n[maas_sql_client.py : 43_66]->/src/mcpMonitorWithFile/src/mcpMonitorWithFile/maas_sql_client._headers._headers_scope..str","sourceNodeId":"_headers \\n[maas_sql_client.py : 43_66]","targetNodeId":"/src/mcpMonitorWithFile/src/mcpMonitorWithFile/maas_sql_client._headers._headers_scope..str"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpMonitorWithFile/src/mcpMonitorWithFile/maas_sql_client.py"},"region":{"startLine":52,"startColumn":17,"endLine":52,"endColumn":46,"snippet":{}}}},"id":"_headers \\n[maas_sql_client.py : 43_66]->syslib_from.base64.b64decode","sourceNodeId":"_headers \\n[maas_sql_client.py : 43_66]","targetNodeId":"syslib_from.base64.b64decode"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpMonitorWithFile/src/mcpMonitorWithFile/maas_sql_client.py"},"region":{"startLine":53,"startColumn":17,"endLine":53,"endColumn":45,"snippet":{}}}},"id":"_headers \\n[maas_sql_client.py : 43_66]->/src/mcpMonitorWithFile/src/mcpMonitorWithFile/maas_sql_client._headers._headers_scope..bytes","sourceNodeId":"_headers \\n[maas_sql_client.py : 43_66]","targetNodeId":"/src/mcpMonitorWithFile/src/mcpMonitorWithFile/maas_sql_client._headers._headers_scope..bytes"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpMonitorWithFile/src/mcpMonitorWithFile/maas_sql_client.py"},"region":{"startLine":51,"startColumn":9,"endLine":55,"endColumn":10,"snippet":{}}}},"id":"_headers \\n[maas_sql_client.py : 43_66]->syslib_from.hmac.new","sourceNodeId":"_headers \\n[maas_sql_client.py : 43_66]","targetNodeId":"syslib_from.hmac.new"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpMonitorWithFile/src/mcpMonitorWithFile/maas_sql_client.py"},"region":{"startLine":51,"startColumn":9,"endLine":55,"endColumn":19,"snippet":{}}}},"id":"_headers \\n[maas_sql_client.py : 43_66]->syslib_from.hmac.new(var key:any=base64.b64decode(_SECRET_KEY), var msg:any=bytes(msg, var encoding:any=utf-8), var digestmod:any=hashlib.sha256).digest","sourceNodeId":"_headers \\n[maas_sql_client.py : 43_66]","targetNodeId":"syslib_from.hmac.new(var key:any=base64.b64decode(_SECRET_KEY), var msg:any=bytes(msg, var encoding:any=utf-8), var digestmod:any=hashlib.sha256).digest"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpMonitorWithFile/src/mcpMonitorWithFile/maas_sql_client.py"},"region":{"startLine":50,"startColumn":12,"endLine":56,"endColumn":6,"snippet":{}}}},"id":"_headers \\n[maas_sql_client.py : 43_66]->syslib_from.base64.b64encode","sourceNodeId":"_headers \\n[maas_sql_client.py : 43_66]","targetNodeId":"syslib_from.base64.b64encode"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpMonitorWithFile/src/mcpMonitorWithFile/maas_sql_client.py"},"region":{"startLine":154,"startColumn":20,"endLine":154,"endColumn":102,"snippet":{}}}},"id":"_get_maas_sql_data \\n[maas_sql_client.py : 136_172]->_call_maas_sql_api \\n[maas_sql_client.py : 69_115]","sourceNodeId":"_get_maas_sql_data \\n[maas_sql_client.py : 136_172]","targetNodeId":"_call_maas_sql_api \\n[maas_sql_client.py : 69_115]"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpMonitorWithFile/src/mcpMonitorWithFile/maas_sql_client.py"},"region":{"startLine":88,"startColumn":57,"endLine":88,"endColumn":67,"snippet":{}}}},"id":"_call_maas_sql_api \\n[maas_sql_client.py : 69_115]->_headers \\n[maas_sql_client.py : 43_66]","sourceNodeId":"_call_maas_sql_api \\n[maas_sql_client.py : 69_115]","targetNodeId":"_headers \\n[maas_sql_client.py : 43_66]"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpMonitorWithFile/src/mcpMonitorWithFile/maas_sql_client.py"},"region":{"startLine":90,"startColumn":16,"endLine":96,"endColumn":6,"snippet":{}}}},"id":"_call_maas_sql_api \\n[maas_sql_client.py : 69_115]->mcp_common.request.http_client.AsyncRestClient","sourceNodeId":"_call_maas_sql_api \\n[maas_sql_client.py : 69_115]","targetNodeId":"mcp_common.request.http_client.AsyncRestClient"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpMonitorWithFile/src/mcpMonitorWithFile/maas_sql_client.py"},"region":{"startLine":99,"startColumn":43,"endLine":99,"endColumn":57,"snippet":{}}}},"id":"_call_maas_sql_api \\n[maas_sql_client.py : 69_115]->POST.lower","sourceNodeId":"_call_maas_sql_api \\n[maas_sql_client.py : 69_115]","targetNodeId":"POST.lower"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpMonitorWithFile/src/mcpMonitorWithFile/maas_sql_client.py"},"region":{"startLine":99,"startColumn":27,"endLine":99,"endColumn":58,"snippet":{}}}},"id":"_call_maas_sql_api \\n[maas_sql_client.py : 69_115]->/src/mcpMonitorWithFile/src/mcpMonitorWithFile/maas_sql_client._call_maas_sql_api._call_maas_sql_api_scope..getattr","sourceNodeId":"_call_maas_sql_api \\n[maas_sql_client.py : 69_115]","targetNodeId":"/src/mcpMonitorWithFile/src/mcpMonitorWithFile/maas_sql_client._call_maas_sql_api._call_maas_sql_api_scope..getattr"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpMonitorWithFile/src/mcpMonitorWithFile/maas_sql_client.py"},"region":{"startLine":100,"startColumn":24,"endLine":100,"endColumn":78,"snippet":{}}}},"id":"_call_maas_sql_api \\n[maas_sql_client.py : 69_115]->/src/mcpMonitorWithFile/src/mcpMonitorWithFile/maas_sql_client._call_maas_sql_api._call_maas_sql_api_scope..getattr(client, method.lower())","sourceNodeId":"_call_maas_sql_api \\n[maas_sql_client.py : 69_115]","targetNodeId":"/src/mcpMonitorWithFile/src/mcpMonitorWithFile/maas_sql_client._call_maas_sql_api._call_maas_sql_api_scope..getattr(client, method.lower())"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpMonitorWithFile/src/mcpMonitorWithFile/maas_sql_client.py"},"region":{"startLine":110,"startColumn":17,"endLine":110,"endColumn":73,"snippet":{}}}},"id":"_call_maas_sql_api \\n[maas_sql_client.py : 69_115]->syslib_from.logging.getLogger(__name__).info","sourceNodeId":"_call_maas_sql_api \\n[maas_sql_client.py : 69_115]","targetNodeId":"syslib_from.logging.getLogger(__name__).info"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpMonitorWithFile/src/mcpMonitorWithFile/maas_sql_client.py"},"region":{"startLine":104,"startColumn":24,"endLine":104,"endColumn":44,"snippet":{}}}},"id":"_call_maas_sql_api \\n[maas_sql_client.py : 69_115]->/src/mcpMonitorWithFile/src/mcpMonitorWithFile/maas_sql_client._call_maas_sql_api._call_maas_sql_api_scope..getattr(client, method.lower())(var endpoint:any=endpoint, var null:any=r...","sourceNodeId":"_call_maas_sql_api \\n[maas_sql_client.py : 69_115]","targetNodeId":"/src/mcpMonitorWithFile/src/mcpMonitorWithFile/maas_sql_client._call_maas_sql_api._call_maas_sql_api_scope..getattr(client, method.lower())(var endpoint:any=endpoint, var null:any=r..."},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpMonitorWithFile/src/mcpMonitorWithFile/maas_sql_client.py"},"region":{"startLine":105,"startColumn":20,"endLine":105,"endColumn":41,"snippet":{}}}},"id":"_call_maas_sql_api \\n[maas_sql_client.py : 69_115]->/src/mcpMonitorWithFile/src/mcpMonitorWithFile/maas_sql_client._call_maas_sql_api._call_maas_sql_api_scope...isinstance","sourceNodeId":"_call_maas_sql_api \\n[maas_sql_client.py : 69_115]","targetNodeId":"/src/mcpMonitorWithFile/src/mcpMonitorWithFile/maas_sql_client._call_maas_sql_api._call_maas_sql_api_scope...isinstance"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpMonitorWithFile/src/mcpMonitorWithFile/maas_sql_client.py"},"region":{"startLine":106,"startColumn":28,"endLine":106,"endColumn":44,"snippet":{}}}},"id":"_call_maas_sql_api \\n[maas_sql_client.py : 69_115]->syslib_from.json.loads","sourceNodeId":"_call_maas_sql_api \\n[maas_sql_client.py : 69_115]","targetNodeId":"syslib_from.json.loads"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpMonitorWithFile/src/mcpMonitorWithFile/maas_sql_client.py"},"region":{"startLine":108,"startColumn":36,"endLine":108,"endColumn":68,"snippet":{}}}},"id":"_call_maas_sql_api \\n[maas_sql_client.py : 69_115]->_handle_empty_response \\n[maas_sql_client.py : 118_124]","sourceNodeId":"_call_maas_sql_api \\n[maas_sql_client.py : 69_115]","targetNodeId":"_handle_empty_response \\n[maas_sql_client.py : 118_124]"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpMonitorWithFile/src/mcpMonitorWithFile/maas_sql_client.py"},"region":{"startLine":123,"startColumn":25,"endLine":123,"endColumn":57,"snippet":{}}}},"id":"_handle_empty_response \\n[maas_sql_client.py : 118_124]->/src/mcpMonitorWithFile/src/mcpMonitorWithFile/maas_sql_client._call_maas_sql_api._call_maas_sql_api_scope..getattr(client, method.lower())(var endpoint:any=endpoint, var null:any=r...","sourceNodeId":"_handle_empty_response \\n[maas_sql_client.py : 118_124]","targetNodeId":"/src/mcpMonitorWithFile/src/mcpMonitorWithFile/maas_sql_client._call_maas_sql_api._call_maas_sql_api_scope..getattr(client, method.lower())(var endpoint:any=endpoint, var null:any=r..."},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpMonitorWithFile/src/mcpMonitorWithFile/maas_sql_client.py"},"region":{"startLine":120,"startColumn":11,"endLine":124,"endColumn":6,"snippet":{}}}},"id":"_handle_empty_response \\n[maas_sql_client.py : 118_124]->/src/mcpMonitorWithFile/src/mcpMonitorWithFile/maas_sql_client._handle_empty_response._handle_empty_response_scope..ValueError","sourceNodeId":"_handle_empty_response \\n[maas_sql_client.py : 118_124]","targetNodeId":"/src/mcpMonitorWithFile/src/mcpMonitorWithFile/maas_sql_client._handle_empty_response._handle_empty_response_scope..ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpMonitorWithFile/src/mcpMonitorWithFile/maas_sql_client.py"},"region":{"startLine":111,"startColumn":17,"endLine":111,"endColumn":49,"snippet":{}}}},"id":"_call_maas_sql_api \\n[maas_sql_client.py : 69_115]->_handle_error_response \\n[maas_sql_client.py : 127_133]","sourceNodeId":"_call_maas_sql_api \\n[maas_sql_client.py : 69_115]","targetNodeId":"_handle_error_response \\n[maas_sql_client.py : 127_133]"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpMonitorWithFile/src/mcpMonitorWithFile/maas_sql_client.py"},"region":{"startLine":132,"startColumn":25,"endLine":132,"endColumn":57,"snippet":{}}}},"id":"_handle_error_response \\n[maas_sql_client.py : 127_133]->/src/mcpMonitorWithFile/src/mcpMonitorWithFile/maas_sql_client._call_maas_sql_api._call_maas_sql_api_scope..getattr(client, method.lower())(var endpoint:any=endpoint, var null:any=r...","sourceNodeId":"_handle_error_response \\n[maas_sql_client.py : 127_133]","targetNodeId":"/src/mcpMonitorWithFile/src/mcpMonitorWithFile/maas_sql_client._call_maas_sql_api._call_maas_sql_api_scope..getattr(client, method.lower())(var endpoint:any=endpoint, var null:any=r..."},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpMonitorWithFile/src/mcpMonitorWithFile/maas_sql_client.py"},"region":{"startLine":129,"startColumn":11,"endLine":133,"endColumn":6,"snippet":{}}}},"id":"_handle_error_response \\n[maas_sql_client.py : 127_133]->/src/mcpMonitorWithFile/src/mcpMonitorWithFile/maas_sql_client._handle_error_response._handle_error_response_scope..ValueError","sourceNodeId":"_handle_error_response \\n[maas_sql_client.py : 127_133]","targetNodeId":"/src/mcpMonitorWithFile/src/mcpMonitorWithFile/maas_sql_client._handle_error_response._handle_error_response_scope..ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpMonitorWithFile/src/mcpMonitorWithFile/maas_sql_client.py"},"region":{"startLine":115,"startColumn":56,"endLine":115,"endColumn":64,"snippet":{}}}},"id":"_call_maas_sql_api \\n[maas_sql_client.py : 69_115]->/src/mcpMonitorWithFile/src/mcpMonitorWithFile/maas_sql_client._call_maas_sql_api._call_maas_sql_api_scope...str","sourceNodeId":"_call_maas_sql_api \\n[maas_sql_client.py : 69_115]","targetNodeId":"/src/mcpMonitorWithFile/src/mcpMonitorWithFile/maas_sql_client._call_maas_sql_api._call_maas_sql_api_scope...str"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpMonitorWithFile/src/mcpMonitorWithFile/maas_sql_client.py"},"region":{"startLine":114,"startColumn":13,"endLine":114,"endColumn":55,"snippet":{}}}},"id":"_call_maas_sql_api \\n[maas_sql_client.py : 69_115]->syslib_from.logging.getLogger(__name__).error","sourceNodeId":"_call_maas_sql_api \\n[maas_sql_client.py : 69_115]","targetNodeId":"syslib_from.logging.getLogger(__name__).error"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpMonitorWithFile/src/mcpMonitorWithFile/maas_sql_client.py"},"region":{"startLine":115,"startColumn":19,"endLine":115,"endColumn":66,"snippet":{}}}},"id":"_call_maas_sql_api \\n[maas_sql_client.py : 69_115]->/src/mcpMonitorWithFile/src/mcpMonitorWithFile/maas_sql_client._call_maas_sql_api._call_maas_sql_api_scope...ValueError","sourceNodeId":"_call_maas_sql_api \\n[maas_sql_client.py : 69_115]","targetNodeId":"/src/mcpMonitorWithFile/src/mcpMonitorWithFile/maas_sql_client._call_maas_sql_api._call_maas_sql_api_scope...ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpMonitorWithFile/src/mcpMonitorWithFile/maas_sql_client.py"},"region":{"startLine":160,"startColumn":24,"endLine":160,"endColumn":66,"snippet":{}}}},"id":"_get_maas_sql_data \\n[maas_sql_client.py : 136_172]->syslib_from.datetime.datetime.fromtimestamp","sourceNodeId":"_get_maas_sql_data \\n[maas_sql_client.py : 136_172]","targetNodeId":"syslib_from.datetime.datetime.fromtimestamp"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpMonitorWithFile/src/mcpMonitorWithFile/maas_sql_client.py"},"region":{"startLine":160,"startColumn":24,"endLine":160,"endColumn":96,"snippet":{}}}},"id":"_get_maas_sql_data \\n[maas_sql_client.py : 136_172]->syslib_from.datetime.datetime.fromtimestamp(timestamp).strftime","sourceNodeId":"_get_maas_sql_data \\n[maas_sql_client.py : 136_172]","targetNodeId":"syslib_from.datetime.datetime.fromtimestamp(timestamp).strftime"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpMonitorWithFile/src/mcpMonitorWithFile/maas_sql_client.py"},"region":{"startLine":162,"startColumn":37,"endLine":162,"endColumn":50,"snippet":{}}}},"id":"_get_maas_sql_data \\n[maas_sql_client.py : 136_172]->/src/mcpMonitorWithFile/src/mcpMonitorWithFile/maas_sql_client._get_maas_sql_data._get_maas_sql_data_scope........./src/mcpMonitorWithFile/src/mcpMonitorWithFile/maas_sql_client._get_maas_sql_data._get_maas_sql_data_scope...str","sourceNodeId":"_get_maas_sql_data \\n[maas_sql_client.py : 136_172]","targetNodeId":"/src/mcpMonitorWithFile/src/mcpMonitorWithFile/maas_sql_client._get_maas_sql_data._get_maas_sql_data_scope...str"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpMonitorWithFile/src/mcpMonitorWithFile/maas_sql_client.py"},"region":{"startLine":171,"startColumn":9,"endLine":171,"endColumn":106,"snippet":{}}}},"id":"_get_maas_sql_data \\n[maas_sql_client.py : 136_172]->syslib_from.logging.getLogger(__name__).warning","sourceNodeId":"_get_maas_sql_data \\n[maas_sql_client.py : 136_172]","targetNodeId":"syslib_from.logging.getLogger(__name__).warning"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpMonitorWithFile/src/mcpMonitorWithFile/maas_sql_client.py"},"region":{"startLine":172,"startColumn":15,"endLine":172,"endColumn":33,"snippet":{}}}},"id":"_get_maas_sql_data \\n[maas_sql_client.py : 136_172]->/src/mcpMonitorWithFile/src/mcpMonitorWithFile/maas_sql_client._get_maas_sql_data._get_maas_sql_data_scope...ValueError","sourceNodeId":"_get_maas_sql_data \\n[maas_sql_client.py : 136_172]","targetNodeId":"/src/mcpMonitorWithFile/src/mcpMonitorWithFile/maas_sql_client._get_maas_sql_data._get_maas_sql_data_scope...ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpMonitorWithFile/src/mcpMonitorWithFile/maas_sql_client.py"},"region":{"startLine":224,"startColumn":5,"endLine":224,"endColumn":15,"snippet":{}}}},"id":"<__entry_point__>->/src/mcpMonitorWithFile/src/mcpMonitorWithFile/maas_sql_client..print","sourceNodeId":"<__entry_point__>","targetNodeId":"/src/mcpMonitorWithFile/src/mcpMonitorWithFile/maas_sql_client..print"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpMonitorWithSql/src/mcpMonitorWithSql/server.py"},"region":{"startLine":186,"startColumn":23,"endLine":186,"endColumn":45,"snippet":{}}}},"id":"<__entry_point__>->get_metric \\n[server.py : 125_135]","sourceNodeId":"<__entry_point__>","targetNodeId":"get_metric \\n[server.py : 125_135]"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpMonitorWithSql/src/mcpMonitorWithSql/server.py"},"region":{"startLine":134,"startColumn":14,"endLine":134,"endColumn":27,"snippet":{}}}},"id":"get_metric \\n[server.py : 125_135]->_get_header \\n[server.py : 115_122]","sourceNodeId":"get_metric \\n[server.py : 125_135]","targetNodeId":"_get_header \\n[server.py : 115_122]"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpMonitorWithSql/src/mcpMonitorWithSql/server.py"},"region":{"startLine":116,"startColumn":19,"endLine":116,"endColumn":73,"snippet":{}}}},"id":"_get_header \\n[server.py : 115_122]->mcp.server.Server(SERVER_NAME).request_context.meta.model_extra.get","sourceNodeId":"_get_header \\n[server.py : 115_122]","targetNodeId":"mcp.server.Server(SERVER_NAME).request_context.meta.model_extra.get"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpMonitorWithSql/src/mcpMonitorWithSql/server.py"},"region":{"startLine":120,"startColumn":17,"endLine":120,"endColumn":34,"snippet":{}}}},"id":"_get_header \\n[server.py : 115_122]->mcp.server.Server(SERVER_NAME).request_context.meta.model_extra.get(headers).decode","sourceNodeId":"_get_header \\n[server.py : 115_122]","targetNodeId":"mcp.server.Server(SERVER_NAME).request_context.meta.model_extra.get(headers).decode"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpMonitorWithSql/src/mcpMonitorWithSql/server.py"},"region":{"startLine":119,"startColumn":15,"endLine":119,"endColumn":40,"snippet":{}}}},"id":"_get_header \\n[server.py : 115_122]->mcp.server.Server(SERVER_NAME).request_context.meta.model_extra.get(headers).decode(utf-8).lower","sourceNodeId":"_get_header \\n[server.py : 115_122]","targetNodeId":"mcp.server.Server(SERVER_NAME).request_context.meta.model_extra.get(headers).decode(utf-8).lower"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpMonitorWithSql/src/mcpMonitorWithSql/server.py"},"region":{"startLine":135,"startColumn":12,"endLine":135,"endColumn":50,"snippet":{}}}},"id":"get_metric \\n[server.py : 125_135]->syslib_from.json.dumps","sourceNodeId":"get_metric \\n[server.py : 125_135]","targetNodeId":"syslib_from.json.dumps"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpMonitorWithSql/src/mcpMonitorWithSql/server.py"},"region":{"startLine":187,"startColumn":5,"endLine":187,"endColumn":15,"snippet":{}}}},"id":"<__entry_point__>->/src/mcpMonitorWithSql/src/mcpMonitorWithSql/server..print","sourceNodeId":"<__entry_point__>","targetNodeId":"/src/mcpMonitorWithSql/src/mcpMonitorWithSql/server..print"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpOpenSearch/src/mcpOpenSearch/util.py"},"region":{"startLine":17,"startColumn":10,"endLine":17,"endColumn":33,"snippet":{}}}},"id":"<__entry_point__>->aiologger.Logger","sourceNodeId":"<__entry_point__>","targetNodeId":"aiologger.Logger"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpOpenSearch/src/mcpOpenSearch/util.py"},"region":{"startLine":18,"startColumn":20,"endLine":18,"endColumn":40,"snippet":{}}}},"id":"<__entry_point__>->aiologger.handlers.streams.AsyncStreamHandler","sourceNodeId":"<__entry_point__>","targetNodeId":"aiologger.handlers.streams.AsyncStreamHandler"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpOpenSearch/src/mcpOpenSearch/logger.py"},"region":{"startLine":38,"startColumn":18,"endLine":41,"endColumn":2,"snippet":{}}}},"id":"<__entry_point__>->aiologger.formatters.base.Formatter","sourceNodeId":"<__entry_point__>","targetNodeId":"aiologger.formatters.base.Formatter"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpOpenSearch/src/mcpOpenSearch/logger.py"},"region":{"startLine":56,"startColumn":26,"endLine":56,"endColumn":41,"snippet":{}}}},"id":"<__entry_point__>->aiologger.formatters.json.JsonFormatter","sourceNodeId":"<__entry_point__>","targetNodeId":"aiologger.formatters.json.JsonFormatter"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpOpenSearch/src/mcpOpenSearch/util.py"},"region":{"startLine":23,"startColumn":8,"endLine":23,"endColumn":99,"snippet":{}}}},"id":"<__entry_point__>->syslib_from.os.path.exists","sourceNodeId":"<__entry_point__>","targetNodeId":"syslib_from.os.path.exists"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpOpenSearch/src/mcpOpenSearch/util.py"},"region":{"startLine":23,"startColumn":1,"endLine":23,"endColumn":118,"snippet":{}}}},"id":"<__entry_point__>->/src/mcpOpenSearch/src/mcpOpenSearch/util.assert","sourceNodeId":"<__entry_point__>","targetNodeId":"/src/mcpOpenSearch/src/mcpOpenSearch/util.assert"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpOpsCloud/src/mcpOpsCloud/server.py"},"region":{"startLine":248,"startColumn":63,"endLine":254,"endColumn":9,"snippet":{}}}},"id":"<__entry_point__>->syslib_from.json.loads","sourceNodeId":"<__entry_point__>","targetNodeId":"syslib_from.json.loads"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpOpsCloud/src/mcpOpsCloud/server.py"},"region":{"startLine":170,"startColumn":1,"endLine":212,"endColumn":16,"snippet":{}}}},"id":"<__entry_point__>->handle_call_tool \\n[server.py : 170_212]","sourceNodeId":"<__entry_point__>","targetNodeId":"handle_call_tool \\n[server.py : 170_212]"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpOpsCloud/src/mcpOpsCloud/server.py"},"region":{"startLine":178,"startColumn":73,"endLine":178,"endColumn":94,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 170_212]->syslib_from.json.dumps","sourceNodeId":"handle_call_tool \\n[server.py : 170_212]","targetNodeId":"syslib_from.json.dumps"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpOpsCloud/src/mcpOpsCloud/server.py"},"region":{"startLine":178,"startColumn":9,"endLine":178,"endColumn":95,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 170_212]->syslib_from.logging.getLogger(__name__).info","sourceNodeId":"handle_call_tool \\n[server.py : 170_212]","targetNodeId":"syslib_from.logging.getLogger(__name__).info"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpOpsCloud/src/mcpOpsCloud/server.py"},"region":{"startLine":180,"startColumn":19,"endLine":180,"endColumn":67,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 170_212]->/src/mcpOpsCloud/src/mcpOpsCloud/server.handle_call_tool.handle_call_tool_scope...ValueError","sourceNodeId":"handle_call_tool \\n[server.py : 170_212]","targetNodeId":"/src/mcpOpsCloud/src/mcpOpsCloud/server.handle_call_tool.handle_call_tool_scope...ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpOpsCloud/src/mcpOpsCloud/server.py"},"region":{"startLine":182,"startColumn":19,"endLine":182,"endColumn":71,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 170_212]->/src/mcpOpsCloud/src/mcpOpsCloud/server.handle_call_tool.handle_call_tool_scope...ValueError","sourceNodeId":"handle_call_tool \\n[server.py : 170_212]","targetNodeId":"/src/mcpOpsCloud/src/mcpOpsCloud/server.handle_call_tool.handle_call_tool_scope...ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpOpsCloud/src/mcpOpsCloud/server.py"},"region":{"startLine":185,"startColumn":25,"endLine":185,"endColumn":35,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 170_212]->opscloud.OpsCloud","sourceNodeId":"handle_call_tool \\n[server.py : 170_212]","targetNodeId":"opscloud.OpsCloud"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpOpsCloud/src/mcpOpsCloud/server.py"},"region":{"startLine":186,"startColumn":30,"endLine":186,"endColumn":88,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 170_212]->opscloud.OpsCloud().analyse_change","sourceNodeId":"handle_call_tool \\n[server.py : 170_212]","targetNodeId":"opscloud.OpsCloud().analyse_change"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpOpsCloud/src/mcpOpsCloud/server.py"},"region":{"startLine":208,"startColumn":20,"endLine":208,"endColumn":51,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 170_212]->warp_result \\n[server.py : 215_229]","sourceNodeId":"handle_call_tool \\n[server.py : 170_212]","targetNodeId":"warp_result \\n[server.py : 215_229]"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpOpsCloud/src/mcpOpsCloud/server.py"},"region":{"startLine":216,"startColumn":26,"endLine":216,"endColumn":37,"snippet":{}}}},"id":"warp_result \\n[server.py : 215_229]->/src/mcpOpsCloud/src/mcpOpsCloud/server.warp_result.warp_result_scope..len","sourceNodeId":"warp_result \\n[server.py : 215_229]","targetNodeId":"/src/mcpOpsCloud/src/mcpOpsCloud/server.warp_result.warp_result_scope..len"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpOpsCloud/src/mcpOpsCloud/server.py"},"region":{"startLine":225,"startColumn":13,"endLine":228,"endColumn":14,"snippet":{}}}},"id":"warp_result \\n[server.py : 215_229]->syslib_from.mcp/types.TextContent","sourceNodeId":"warp_result \\n[server.py : 215_229]","targetNodeId":"syslib_from.mcp/types.TextContent"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpOpsCloud/src/mcpOpsCloud/server.py"},"region":{"startLine":227,"startColumn":22,"endLine":227,"endColumn":60,"snippet":{}}}},"id":"warp_result \\n[server.py : 215_229]->syslib_from.json.dumps","sourceNodeId":"warp_result \\n[server.py : 215_229]","targetNodeId":"syslib_from.json.dumps"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpOpsCloud/src/mcpOpsCloud/server.py"},"region":{"startLine":193,"startColumn":25,"endLine":193,"endColumn":44,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 170_212]->opscloud_app_change.OpsCloudAppChange","sourceNodeId":"handle_call_tool \\n[server.py : 170_212]","targetNodeId":"opscloud_app_change.OpsCloudAppChange"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpOpsCloud/src/mcpOpsCloud/server.py"},"region":{"startLine":194,"startColumn":22,"endLine":195,"endColumn":90,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 170_212]->opscloud_app_change.OpsCloudAppChange().search_app_change_with_simple","sourceNodeId":"handle_call_tool \\n[server.py : 170_212]","targetNodeId":"opscloud_app_change.OpsCloudAppChange().search_app_change_with_simple"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpOpsCloud/src/mcpOpsCloud/server.py"},"region":{"startLine":205,"startColumn":25,"endLine":205,"endColumn":44,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 170_212]->opscloud_drm_change.OpsCloudDrmChange","sourceNodeId":"handle_call_tool \\n[server.py : 170_212]","targetNodeId":"opscloud_drm_change.OpsCloudDrmChange"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpOpsCloud/src/mcpOpsCloud/server.py"},"region":{"startLine":200,"startColumn":22,"endLine":201,"endColumn":90,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 170_212]->opscloud_drm_change.OpsCloudDrmChange().search_drm_change_with_simple","sourceNodeId":"handle_call_tool \\n[server.py : 170_212]","targetNodeId":"opscloud_drm_change.OpsCloudDrmChange().search_drm_change_with_simple"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpOpsCloud/src/mcpOpsCloud/server.py"},"region":{"startLine":206,"startColumn":22,"endLine":207,"endColumn":90,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 170_212]->opscloud_drm_change.OpsCloudDrmChange().search_drm_change_full_result","sourceNodeId":"handle_call_tool \\n[server.py : 170_212]","targetNodeId":"opscloud_drm_change.OpsCloudDrmChange().search_drm_change_full_result"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpOpsCloud/src/mcpOpsCloud/server.py"},"region":{"startLine":211,"startColumn":9,"endLine":211,"endColumn":44,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 170_212]->syslib_from.logging.getLogger(__name__).error","sourceNodeId":"handle_call_tool \\n[server.py : 170_212]","targetNodeId":"syslib_from.logging.getLogger(__name__).error"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpOpsCloud/src/mcpOpsCloud/server.py"},"region":{"startLine":255,"startColumn":5,"endLine":255,"endColumn":15,"snippet":{}}}},"id":"<__entry_point__>->/src/mcpOpsCloud/src/mcpOpsCloud/server..print","sourceNodeId":"<__entry_point__>","targetNodeId":"/src/mcpOpsCloud/src/mcpOpsCloud/server..print"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpOpsCloud/src/mcpOpsCloud/opscloud_app_change.py"},"region":{"startLine":959,"startColumn":23,"endLine":961,"endColumn":95,"snippet":{}}}},"id":"<__entry_point__>->search_app_change_with_simple","sourceNodeId":"<__entry_point__>","targetNodeId":"search_app_change_with_simple"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpOpsCloud/src/mcpOpsCloud/opscloud_app_change.py"},"region":{"startLine":962,"startColumn":5,"endLine":962,"endColumn":15,"snippet":{}}}},"id":"<__entry_point__>->/src/mcpOpsCloud/src/mcpOpsCloud/opscloud_app_change..print","sourceNodeId":"<__entry_point__>","targetNodeId":"/src/mcpOpsCloud/src/mcpOpsCloud/opscloud_app_change..print"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpOpsCloud/src/mcpOpsCloud/opscloud_full_change.py"},"region":{"startLine":918,"startColumn":5,"endLine":918,"endColumn":26,"snippet":{}}}},"id":"<__entry_point__>->syslib_from.logging.getLogger(__name__).info","sourceNodeId":"<__entry_point__>","targetNodeId":"syslib_from.logging.getLogger(__name__).info"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpOpsCloud/src/mcpOpsCloud/opscloud_drm_change.py"},"region":{"startLine":986,"startColumn":23,"endLine":988,"endColumn":95,"snippet":{}}}},"id":"<__entry_point__>->search_drm_change_with_simple","sourceNodeId":"<__entry_point__>","targetNodeId":"search_drm_change_with_simple"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpOpsCloud/src/mcpOpsCloud/opscloud_drm_change.py"},"region":{"startLine":989,"startColumn":5,"endLine":989,"endColumn":15,"snippet":{}}}},"id":"<__entry_point__>->/src/mcpOpsCloud/src/mcpOpsCloud/opscloud_drm_change..print","sourceNodeId":"<__entry_point__>","targetNodeId":"/src/mcpOpsCloud/src/mcpOpsCloud/opscloud_drm_change..print"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpOpsCloud/src/mcpOpsCloud/opscloud_full_change.py"},"region":{"startLine":914,"startColumn":23,"endLine":916,"endColumn":93,"snippet":{}}}},"id":"<__entry_point__>->search_full_change_full_result","sourceNodeId":"<__entry_point__>","targetNodeId":"search_full_change_full_result"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpOpsCloud/src/mcpOpsCloud/opscloud_full_change.py"},"region":{"startLine":917,"startColumn":5,"endLine":917,"endColumn":15,"snippet":{}}}},"id":"<__entry_point__>->/src/mcpOpsCloud/src/mcpOpsCloud/opscloud_full_change..print","sourceNodeId":"<__entry_point__>","targetNodeId":"/src/mcpOpsCloud/src/mcpOpsCloud/opscloud_full_change..print"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpPaas/src/mcpPaas/paas_client.py"},"region":{"startLine":11,"startColumn":1,"endLine":11,"endColumn":49,"snippet":{}}}},"id":"<__entry_point__>->layotto_turbo.layotto._layotto_client.initialize_app","sourceNodeId":"<__entry_point__>","targetNodeId":"layotto_turbo.layotto._layotto_client.initialize_app"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpPaas/src/mcpPaas/paas_client.py"},"region":{"startLine":14,"startColumn":36,"endLine":14,"endColumn":66,"snippet":{}}}},"id":"<__entry_point__>->oneapi.archdatacenter.BackendAppQueryFacade.BackendAppQueryFacade","sourceNodeId":"<__entry_point__>","targetNodeId":"oneapi.archdatacenter.BackendAppQueryFacade.BackendAppQueryFacade"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpPaas/src/mcpPaas/paas_client.py"},"region":{"startLine":15,"startColumn":29,"endLine":15,"endColumn":60,"snippet":{}}}},"id":"<__entry_point__>->oneapi.huanyu.CustomChangePlanFacade.CustomChangePlanFacade","sourceNodeId":"<__entry_point__>","targetNodeId":"oneapi.huanyu.CustomChangePlanFacade.CustomChangePlanFacade"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-common/src/mcp_common/request/http_client.py"},"region":{"startLine":10,"startColumn":1,"endLine":13,"endColumn":2,"snippet":{}}}},"id":"<__entry_point__>->syslib_from.logging.basicConfig","sourceNodeId":"<__entry_point__>","targetNodeId":"syslib_from.logging.basicConfig"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpQueryMultiAppMetrics/src/mcpQueryMultiAppMetrics/server.py"},"region":{"startLine":24,"startColumn":8,"endLine":24,"endColumn":21,"snippet":{}}}},"id":"<__entry_point__>->maas_service.MaasService","sourceNodeId":"<__entry_point__>","targetNodeId":"maas_service.MaasService"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpQueryMultiAppMetrics/src/mcpQueryMultiAppMetrics/maas_service.py"},"region":{"startLine":623,"startColumn":11,"endLine":623,"endColumn":24,"snippet":{}}}},"id":"<__entry_point__>->MaasService :: __init__ \\n[maas_service.py : 39_43]","sourceNodeId":"<__entry_point__>","targetNodeId":"MaasService :: __init__ \\n[maas_service.py : 39_43]"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpQueryMultiAppMetrics/src/mcpQueryMultiAppMetrics/maas_service.py"},"region":{"startLine":609,"startColumn":12,"endLine":610,"endColumn":236,"snippet":{}}}},"id":"<__entry_point__>->MaasService :: query_maas_by_sql_new_engine \\n[maas_service.py : 461_507]","sourceNodeId":"<__entry_point__>","targetNodeId":"MaasService :: query_maas_by_sql_new_engine \\n[maas_service.py : 461_507]"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpQueryMultiAppMetrics/src/mcpQueryMultiAppMetrics/maas_service.py"},"region":{"startLine":73,"startColumn":5,"endLine":87,"endColumn":28,"snippet":{}}}},"id":"MaasService :: query_maas_by_sql_new_engine \\n[maas_service.py : 461_507]->MaasService :: replace_seconds_with_zero \\n[maas_service.py : 73_87]","sourceNodeId":"MaasService :: query_maas_by_sql_new_engine \\n[maas_service.py : 461_507]","targetNodeId":"MaasService :: replace_seconds_with_zero \\n[maas_service.py : 73_87]"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpQueryMultiAppMetrics/src/mcpQueryMultiAppMetrics/maas_service.py"},"region":{"startLine":86,"startColumn":24,"endLine":86,"endColumn":58,"snippet":{}}}},"id":"MaasService :: replace_seconds_with_zero \\n[maas_service.py : 73_87]->syslib_from.re.sub","sourceNodeId":"MaasService :: replace_seconds_with_zero \\n[maas_service.py : 73_87]","targetNodeId":"syslib_from.re.sub"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpQueryMultiAppMetrics/src/mcpQueryMultiAppMetrics/maas_service.py"},"region":{"startLine":86,"startColumn":24,"endLine":86,"endColumn":58,"snippet":{}}}},"id":"syslib_from.re.sub->replace_func \\n[maas_service.py : 82_83]","sourceNodeId":"syslib_from.re.sub","targetNodeId":"replace_func \\n[maas_service.py : 82_83]"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpQueryMultiAppMetrics/src/mcpQueryMultiAppMetrics/maas_service.py"},"region":{"startLine":83,"startColumn":20,"endLine":83,"endColumn":34,"snippet":{}}}},"id":"replace_func \\n[maas_service.py : 82_83]->match.group","sourceNodeId":"replace_func \\n[maas_service.py : 82_83]","targetNodeId":"match.group"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpQueryMultiAppMetrics/src/mcpQueryMultiAppMetrics/maas_service.py"},"region":{"startLine":62,"startColumn":5,"endLine":70,"endColumn":19,"snippet":{}}}},"id":"MaasService :: query_maas_by_sql_new_engine \\n[maas_service.py : 461_507]->MaasService :: replace_env \\n[maas_service.py : 62_70]","sourceNodeId":"MaasService :: query_maas_by_sql_new_engine \\n[maas_service.py : 461_507]","targetNodeId":"MaasService :: replace_env \\n[maas_service.py : 62_70]"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpQueryMultiAppMetrics/src/mcpQueryMultiAppMetrics/maas_service.py"},"region":{"startLine":69,"startColumn":20,"endLine":69,"endColumn":68,"snippet":{}}}},"id":"MaasService :: replace_env \\n[maas_service.py : 62_70]->syslib_from.re.sub(pattern, replace_func, sql).replace","sourceNodeId":"MaasService :: replace_env \\n[maas_service.py : 62_70]","targetNodeId":"syslib_from.re.sub(pattern, replace_func, sql).replace"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpQueryMultiAppMetrics/src/mcpQueryMultiAppMetrics/maas_service.py"},"region":{"startLine":493,"startColumn":15,"endLine":493,"endColumn":55,"snippet":{}}}},"id":"MaasService :: query_maas_by_sql_new_engine \\n[maas_service.py : 461_507]->syslib_from.json.dumps","sourceNodeId":"MaasService :: query_maas_by_sql_new_engine \\n[maas_service.py : 461_507]","targetNodeId":"syslib_from.json.dumps"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpQueryMultiAppMetrics/src/mcpQueryMultiAppMetrics/maas_service.py"},"region":{"startLine":488,"startColumn":13,"endLine":488,"endColumn":102,"snippet":{}}}},"id":"MaasService :: query_maas_by_sql_new_engine \\n[maas_service.py : 461_507]->syslib_from.logging.getLogger(__name__).info","sourceNodeId":"MaasService :: query_maas_by_sql_new_engine \\n[maas_service.py : 461_507]","targetNodeId":"syslib_from.logging.getLogger(__name__).info"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpQueryMultiAppMetrics/src/mcpQueryMultiAppMetrics/maas_service.py"},"region":{"startLine":484,"startColumn":19,"endLine":484,"endColumn":42,"snippet":{}}}},"id":"MaasService :: query_maas_by_sql_new_engine \\n[maas_service.py : 461_507]->syslib_from.json.dumps({sql:sql}, var ensure_ascii:any=false).encode","sourceNodeId":"MaasService :: query_maas_by_sql_new_engine \\n[maas_service.py : 461_507]","targetNodeId":"syslib_from.json.dumps({sql:sql}, var ensure_ascii:any=false).encode"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpQueryMultiAppMetrics/src/mcpQueryMultiAppMetrics/maas_service.py"},"region":{"startLine":485,"startColumn":25,"endLine":485,"endColumn":90,"snippet":{}}}},"id":"MaasService :: query_maas_by_sql_new_engine \\n[maas_service.py : 461_507]->syslib_from.requests.post","sourceNodeId":"MaasService :: query_maas_by_sql_new_engine \\n[maas_service.py : 461_507]","targetNodeId":"syslib_from.requests.post"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpQueryMultiAppMetrics/src/mcpQueryMultiAppMetrics/maas_service.py"},"region":{"startLine":485,"startColumn":25,"endLine":485,"endColumn":97,"snippet":{}}}},"id":"MaasService :: query_maas_by_sql_new_engine \\n[maas_service.py : 461_507]->syslib_from.requests.post(self.new_engine_url, var headers:any=headers, var data:any=payload).json","sourceNodeId":"MaasService :: query_maas_by_sql_new_engine \\n[maas_service.py : 461_507]","targetNodeId":"syslib_from.requests.post(self.new_engine_url, var headers:any=headers, var data:any=payload).json"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpQueryMultiAppMetrics/src/mcpQueryMultiAppMetrics/maas_service.py"},"region":{"startLine":493,"startColumn":9,"endLine":493,"endColumn":56,"snippet":{}}}},"id":"MaasService :: query_maas_by_sql_new_engine \\n[maas_service.py : 461_507]->/src/mcpQueryMultiAppMetrics/src/mcpQueryMultiAppMetrics/maas_service.MaasService.query_maas_by_sql_new_engine.query_maas_by_sql_new_engine_scope..print","sourceNodeId":"MaasService :: query_maas_by_sql_new_engine \\n[maas_service.py : 461_507]","targetNodeId":"/src/mcpQueryMultiAppMetrics/src/mcpQueryMultiAppMetrics/maas_service.MaasService.query_maas_by_sql_new_engine.query_maas_by_sql_new_engine_scope..print"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpQueryMultiAppMetrics/src/mcpQueryMultiAppMetrics/maas_service.py"},"region":{"startLine":495,"startColumn":28,"endLine":495,"endColumn":63,"snippet":{}}}},"id":"MaasService :: query_maas_by_sql_new_engine \\n[maas_service.py : 461_507]->syslib_from.requests.post(self.new_engine_url, var headers:any=headers, var data:any=payload).json().data.headers.index","sourceNodeId":"MaasService :: query_maas_by_sql_new_engine \\n[maas_service.py : 461_507]","targetNodeId":"syslib_from.requests.post(self.new_engine_url, var headers:any=headers, var data:any=payload).json().data.headers.index"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpQueryMultiAppMetrics/src/mcpQueryMultiAppMetrics/maas_service.py"},"region":{"startLine":498,"startColumn":24,"endLine":498,"endColumn":66,"snippet":{}}}},"id":"MaasService :: query_maas_by_sql_new_engine \\n[maas_service.py : 461_507]->syslib_from.datetime.datetime.fromtimestamp","sourceNodeId":"MaasService :: query_maas_by_sql_new_engine \\n[maas_service.py : 461_507]","targetNodeId":"syslib_from.datetime.datetime.fromtimestamp"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpQueryMultiAppMetrics/src/mcpQueryMultiAppMetrics/maas_service.py"},"region":{"startLine":498,"startColumn":24,"endLine":498,"endColumn":93,"snippet":{}}}},"id":"MaasService :: query_maas_by_sql_new_engine \\n[maas_service.py : 461_507]->syslib_from.datetime.datetime.fromtimestamp(timestamp).strftime","sourceNodeId":"MaasService :: query_maas_by_sql_new_engine \\n[maas_service.py : 461_507]","targetNodeId":"syslib_from.datetime.datetime.fromtimestamp(timestamp).strftime"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpQueryMultiAppMetrics/src/mcpQueryMultiAppMetrics/maas_service.py"},"region":{"startLine":500,"startColumn":37,"endLine":500,"endColumn":50,"snippet":{}}}},"id":"MaasService :: query_maas_by_sql_new_engine \\n[maas_service.py : 461_507]->/src/mcpQueryMultiAppMetrics/src/mcpQueryMultiAppMetrics/maas_service.MaasService.query_maas_by_sql_new_engine.query_maas_by_sql_new_engine_scope.....->/src/mcpQueryMultiAppMetrics/src/mcpQueryMultiAppMetrics/maas_service..print","sourceNodeId":"<__entry_point__>","targetNodeId":"/src/mcpQueryMultiAppMetrics/src/mcpQueryMultiAppMetrics/maas_service..print"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpQueryMultiAppMetrics/src/mcpQueryMultiAppMetrics/maas_service.py"},"region":{"startLine":623,"startColumn":11,"endLine":624,"endColumn":104,"snippet":{}}}},"id":"<__entry_point__>->/src/mcpQueryMultiAppMetrics/src/mcpQueryMultiAppMetrics/maas_service.MaasService.query_app_trace_err","sourceNodeId":"<__entry_point__>","targetNodeId":"/src/mcpQueryMultiAppMetrics/src/mcpQueryMultiAppMetrics/maas_service.MaasService.query_app_trace_err"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpQuerySingleAppMetrics/src/mcpQuerySingleAppMetrics/rmc_utils.py"},"region":{"startLine":62,"startColumn":12,"endLine":62,"endColumn":37,"snippet":{}}}},"id":"<__entry_point__>->get_app_info \\n[rmc_utils.py : 8_58]","sourceNodeId":"<__entry_point__>","targetNodeId":"get_app_info \\n[rmc_utils.py : 8_58]"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpQuerySingleAppMetrics/src/mcpQuerySingleAppMetrics/rmc_utils.py"},"region":{"startLine":44,"startColumn":45,"endLine":44,"endColumn":84,"snippet":{}}}},"id":"get_app_info \\n[rmc_utils.py : 8_58]->syslib_from.json.dumps","sourceNodeId":"get_app_info \\n[rmc_utils.py : 8_58]","targetNodeId":"syslib_from.json.dumps"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpQuerySingleAppMetrics/src/mcpQuerySingleAppMetrics/rmc_utils.py"},"region":{"startLine":43,"startColumn":26,"endLine":45,"endColumn":85,"snippet":{}}}},"id":"get_app_info \\n[rmc_utils.py : 8_58]->syslib_from.requests.post","sourceNodeId":"get_app_info \\n[rmc_utils.py : 8_58]","targetNodeId":"syslib_from.requests.post"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpQuerySingleAppMetrics/src/mcpQuerySingleAppMetrics/rmc_utils.py"},"region":{"startLine":46,"startColumn":30,"endLine":46,"endColumn":53,"snippet":{}}}},"id":"get_app_info \\n[rmc_utils.py : 8_58]->syslib_from.json.loads","sourceNodeId":"get_app_info \\n[rmc_utils.py : 8_58]","targetNodeId":"syslib_from.json.loads"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpQueryMultiAppMetrics/src/mcpQueryMultiAppMetrics/rmc_utils.py"},"region":{"startLine":47,"startColumn":20,"endLine":47,"endColumn":51,"snippet":{}}}},"id":"get_app_info \\n[rmc_utils.py : 8_58]->/src/mcpQueryMultiAppMetrics/src/mcpQueryMultiAppMetrics/rmc_utils.get_app_info.get_app_info_scope...len","sourceNodeId":"get_app_info \\n[rmc_utils.py : 8_58]","targetNodeId":"/src/mcpQueryMultiAppMetrics/src/mcpQueryMultiAppMetrics/rmc_utils.get_app_info.get_app_info_scope...len"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpQuerySingleAppMetrics/src/mcpQuerySingleAppMetrics/rmc_utils.py"},"region":{"startLine":32,"startColumn":74,"endLine":32,"endColumn":110,"snippet":{}}}},"id":"get_app_info \\n[rmc_utils.py : 8_58]->syslib_from.json.loads(result.text).data.data.appGroup.replace","sourceNodeId":"get_app_info \\n[rmc_utils.py : 8_58]","targetNodeId":"syslib_from.json.loads(result.text).data.data.appGroup.replace"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpQueryMultiAppMetrics/src/mcpQueryMultiAppMetrics/rmc_utils.py"},"region":{"startLine":63,"startColumn":5,"endLine":63,"endColumn":16,"snippet":{}}}},"id":"<__entry_point__>->/src/mcpQueryMultiAppMetrics/src/mcpQueryMultiAppMetrics/rmc_utils..print","sourceNodeId":"<__entry_point__>","targetNodeId":"/src/mcpQueryMultiAppMetrics/src/mcpQueryMultiAppMetrics/rmc_utils..print"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpQueryRiskMerchantInfo/src/mcpQueryRiskMerchantInfo/merchant_client.py"},"region":{"startLine":147,"startColumn":17,"endLine":147,"endColumn":23,"snippet":{}}}},"id":"<__entry_point__>->main \\n[merchant_client.py : 138_145]","sourceNodeId":"<__entry_point__>","targetNodeId":"main \\n[merchant_client.py : 138_145]"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpQueryRiskMerchantInfo/src/mcpQueryRiskMerchantInfo/merchant_client.py"},"region":{"startLine":140,"startColumn":22,"endLine":142,"endColumn":14,"snippet":{}}}},"id":"main \\n[merchant_client.py : 138_145]->query_risk_merchant_info \\n[merchant_client.py : 79_133]","sourceNodeId":"main \\n[merchant_client.py : 138_145]","targetNodeId":"query_risk_merchant_info \\n[merchant_client.py : 79_133]"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpQueryRiskMerchantInfo/src/mcpQueryRiskMerchantInfo/merchant_client.py"},"region":{"startLine":107,"startColumn":20,"endLine":111,"endColumn":10,"snippet":{}}}},"id":"query_risk_merchant_info \\n[merchant_client.py : 79_133]->_call_risk_merchant_api \\n[merchant_client.py : 19_58]","sourceNodeId":"query_risk_merchant_info \\n[merchant_client.py : 79_133]","targetNodeId":"_call_risk_merchant_api \\n[merchant_client.py : 19_58]"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpQueryRiskMerchantInfo/src/mcpQueryRiskMerchantInfo/merchant_client.py"},"region":{"startLine":35,"startColumn":51,"endLine":35,"endColumn":61,"snippet":{}}}},"id":"_call_risk_merchant_api \\n[merchant_client.py : 19_58]->_headers \\n[merchant_client.py : 11_16]","sourceNodeId":"_call_risk_merchant_api \\n[merchant_client.py : 19_58]","targetNodeId":"_headers \\n[merchant_client.py : 11_16]"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpQueryRiskMerchantInfo/src/mcpQueryRiskMerchantInfo/merchant_client.py"},"region":{"startLine":37,"startColumn":16,"endLine":40,"endColumn":6,"snippet":{}}}},"id":"_call_risk_merchant_api \\n[merchant_client.py : 19_58]->mcp_common.request.http_client.AsyncRestClient","sourceNodeId":"_call_risk_merchant_api \\n[merchant_client.py : 19_58]","targetNodeId":"mcp_common.request.http_client.AsyncRestClient"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpQueryRiskMerchantInfo/src/mcpQueryRiskMerchantInfo/merchant_client.py"},"region":{"startLine":42,"startColumn":43,"endLine":42,"endColumn":57,"snippet":{}}}},"id":"_call_risk_merchant_api \\n[merchant_client.py : 19_58]->GET.lower","sourceNodeId":"_call_risk_merchant_api \\n[merchant_client.py : 19_58]","targetNodeId":"GET.lower"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpQueryRiskMerchantInfo/src/mcpQueryRiskMerchantInfo/merchant_client.py"},"region":{"startLine":42,"startColumn":27,"endLine":42,"endColumn":58,"snippet":{}}}},"id":"_call_risk_merchant_api \\n[merchant_client.py : 19_58]->/src/mcpQueryRiskMerchantInfo/src/mcpQueryRiskMerchantInfo/merchant_client._call_risk_merchant_api._call_risk_merchant_api_scope..getattr","sourceNodeId":"_call_risk_merchant_api \\n[merchant_client.py : 19_58]","targetNodeId":"/src/mcpQueryRiskMerchantInfo/src/mcpQueryRiskMerchantInfo/merchant_client._call_risk_merchant_api._call_risk_merchant_api_scope..getattr"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpQueryRiskMerchantInfo/src/mcpQueryRiskMerchantInfo/merchant_client.py"},"region":{"startLine":43,"startColumn":24,"endLine":43,"endColumn":78,"snippet":{}}}},"id":"_call_risk_merchant_api \\n[merchant_client.py : 19_58]->/src/mcpQueryRiskMerchantInfo/src/mcpQueryRiskMerchantInfo/merchant_client._call_risk_merchant_api._call_risk_merchant_api_scope..getattr(client, method.lower())","sourceNodeId":"_call_risk_merchant_api \\n[merchant_client.py : 19_58]","targetNodeId":"/src/mcpQueryRiskMerchantInfo/src/mcpQueryRiskMerchantInfo/merchant_client._call_risk_merchant_api._call_risk_merchant_api_scope..getattr(client, method.lower())"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpQueryRiskMerchantInfo/src/mcpQueryRiskMerchantInfo/merchant_client.py"},"region":{"startLine":44,"startColumn":13,"endLine":44,"endColumn":83,"snippet":{}}}},"id":"_call_risk_merchant_api \\n[merchant_client.py : 19_58]->syslib_from.logging.getLogger(__name__).info","sourceNodeId":"_call_risk_merchant_api \\n[merchant_client.py : 19_58]","targetNodeId":"syslib_from.logging.getLogger(__name__).info"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpQueryRiskMerchantInfo/src/mcpQueryRiskMerchantInfo/merchant_client.py"},"region":{"startLine":47,"startColumn":24,"endLine":47,"endColumn":44,"snippet":{}}}},"id":"_call_risk_merchant_api \\n[merchant_client.py : 19_58]->/src/mcpQueryRiskMerchantInfo/src/mcpQueryRiskMerchantInfo/merchant_client._call_risk_merchant_api._call_risk_merchant_api_scope..getattr(client, method.lower())(var endpoint:any=end...","sourceNodeId":"_call_risk_merchant_api \\n[merchant_client.py : 19_58]","targetNodeId":"/src/mcpQueryRiskMerchantInfo/src/mcpQueryRiskMerchantInfo/merchant_client._call_risk_merchant_api._call_risk_merchant_api_scope..getattr(client, method.lower())(var endpoint:any=end..."},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpQueryRiskMerchantInfo/src/mcpQueryRiskMerchantInfo/merchant_client.py"},"region":{"startLine":48,"startColumn":20,"endLine":48,"endColumn":41,"snippet":{}}}},"id":"_call_risk_merchant_api \\n[merchant_client.py : 19_58]->/src/mcpQueryRiskMerchantInfo/src/mcpQueryRiskMerchantInfo/merchant_client._call_risk_merchant_api._call_risk_merchant_api_scope...isinstance","sourceNodeId":"_call_risk_merchant_api \\n[merchant_client.py : 19_58]","targetNodeId":"/src/mcpQueryRiskMerchantInfo/src/mcpQueryRiskMerchantInfo/merchant_client._call_risk_merchant_api._call_risk_merchant_api_scope...isinstance"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpQueryRiskMerchantInfo/src/mcpQueryRiskMerchantInfo/merchant_client.py"},"region":{"startLine":49,"startColumn":28,"endLine":49,"endColumn":44,"snippet":{}}}},"id":"_call_risk_merchant_api \\n[merchant_client.py : 19_58]->syslib_from.json.loads","sourceNodeId":"_call_risk_merchant_api \\n[merchant_client.py : 19_58]","targetNodeId":"syslib_from.json.loads"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpQueryRiskMerchantInfo/src/mcpQueryRiskMerchantInfo/merchant_client.py"},"region":{"startLine":51,"startColumn":36,"endLine":51,"endColumn":68,"snippet":{}}}},"id":"_call_risk_merchant_api \\n[merchant_client.py : 19_58]->_handle_empty_response \\n[merchant_client.py : 61_67]","sourceNodeId":"_call_risk_merchant_api \\n[merchant_client.py : 19_58]","targetNodeId":"_handle_empty_response \\n[merchant_client.py : 61_67]"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpQueryRiskMerchantInfo/src/mcpQueryRiskMerchantInfo/merchant_client.py"},"region":{"startLine":66,"startColumn":25,"endLine":66,"endColumn":57,"snippet":{}}}},"id":"_handle_empty_response \\n[merchant_client.py : 61_67]->/src/mcpQueryRiskMerchantInfo/src/mcpQueryRiskMerchantInfo/merchant_client._call_risk_merchant_api._call_risk_merchant_api_scope..getattr(client, method.lower())(var endpoint:any=end...","sourceNodeId":"_handle_empty_response \\n[merchant_client.py : 61_67]","targetNodeId":"/src/mcpQueryRiskMerchantInfo/src/mcpQueryRiskMerchantInfo/merchant_client._call_risk_merchant_api._call_risk_merchant_api_scope..getattr(client, method.lower())(var endpoint:any=end..."},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpQueryRiskMerchantInfo/src/mcpQueryRiskMerchantInfo/merchant_client.py"},"region":{"startLine":63,"startColumn":11,"endLine":67,"endColumn":6,"snippet":{}}}},"id":"_handle_empty_response \\n[merchant_client.py : 61_67]->/src/mcpQueryRiskMerchantInfo/src/mcpQueryRiskMerchantInfo/merchant_client._handle_empty_response._handle_empty_response_scope..ValueError","sourceNodeId":"_handle_empty_response \\n[merchant_client.py : 61_67]","targetNodeId":"/src/mcpQueryRiskMerchantInfo/src/mcpQueryRiskMerchantInfo/merchant_client._handle_empty_response._handle_empty_response_scope..ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpQueryRiskMerchantInfo/src/mcpQueryRiskMerchantInfo/merchant_client.py"},"region":{"startLine":53,"startColumn":17,"endLine":53,"endColumn":99,"snippet":{}}}},"id":"_call_risk_merchant_api \\n[merchant_client.py : 19_58]->syslib_from.logging.getLogger(__name__).warning","sourceNodeId":"_call_risk_merchant_api \\n[merchant_client.py : 19_58]","targetNodeId":"syslib_from.logging.getLogger(__name__).warning"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpQueryRiskMerchantInfo/src/mcpQueryRiskMerchantInfo/merchant_client.py"},"region":{"startLine":54,"startColumn":17,"endLine":54,"endColumn":49,"snippet":{}}}},"id":"_call_risk_merchant_api \\n[merchant_client.py : 19_58]->_handle_error_response \\n[merchant_client.py : 70_76]","sourceNodeId":"_call_risk_merchant_api \\n[merchant_client.py : 19_58]","targetNodeId":"_handle_error_response \\n[merchant_client.py : 70_76]"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpQueryRiskMerchantInfo/src/mcpQueryRiskMerchantInfo/merchant_client.py"},"region":{"startLine":75,"startColumn":25,"endLine":75,"endColumn":57,"snippet":{}}}},"id":"_handle_error_response \\n[merchant_client.py : 70_76]->/src/mcpQueryRiskMerchantInfo/src/mcpQueryRiskMerchantInfo/merchant_client._call_risk_merchant_api._call_risk_merchant_api_scope..getattr(client, method.lower())(var endpoint:any=end...","sourceNodeId":"_handle_error_response \\n[merchant_client.py : 70_76]","targetNodeId":"/src/mcpQueryRiskMerchantInfo/src/mcpQueryRiskMerchantInfo/merchant_client._call_risk_merchant_api._call_risk_merchant_api_scope..getattr(client, method.lower())(var endpoint:any=end..."},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpQueryRiskMerchantInfo/src/mcpQueryRiskMerchantInfo/merchant_client.py"},"region":{"startLine":72,"startColumn":11,"endLine":76,"endColumn":6,"snippet":{}}}},"id":"_handle_error_response \\n[merchant_client.py : 70_76]->/src/mcpQueryRiskMerchantInfo/src/mcpQueryRiskMerchantInfo/merchant_client._handle_error_response._handle_error_response_scope..ValueError","sourceNodeId":"_handle_error_response \\n[merchant_client.py : 70_76]","targetNodeId":"/src/mcpQueryRiskMerchantInfo/src/mcpQueryRiskMerchantInfo/merchant_client._handle_error_response._handle_error_response_scope..ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpQueryRiskMerchantInfo/src/mcpQueryRiskMerchantInfo/merchant_client.py"},"region":{"startLine":58,"startColumn":64,"endLine":58,"endColumn":72,"snippet":{}}}},"id":"_call_risk_merchant_api \\n[merchant_client.py : 19_58]->/src/mcpQueryRiskMerchantInfo/src/mcpQueryRiskMerchantInfo/merchant_client._call_risk_merchant_api._call_risk_merchant_api_scope...str","sourceNodeId":"_call_risk_merchant_api \\n[merchant_client.py : 19_58]","targetNodeId":"/src/mcpQueryRiskMerchantInfo/src/mcpQueryRiskMerchantInfo/merchant_client._call_risk_merchant_api._call_risk_merchant_api_scope...str"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpQueryRiskMerchantInfo/src/mcpQueryRiskMerchantInfo/merchant_client.py"},"region":{"startLine":57,"startColumn":13,"endLine":57,"endColumn":89,"snippet":{}}}},"id":"_call_risk_merchant_api \\n[merchant_client.py : 19_58]->syslib_from.logging.getLogger(__name__).error","sourceNodeId":"_call_risk_merchant_api \\n[merchant_client.py : 19_58]","targetNodeId":"syslib_from.logging.getLogger(__name__).error"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpQueryRiskMerchantInfo/src/mcpQueryRiskMerchantInfo/merchant_client.py"},"region":{"startLine":58,"startColumn":19,"endLine":58,"endColumn":74,"snippet":{}}}},"id":"_call_risk_merchant_api \\n[merchant_client.py : 19_58]->/src/mcpQueryRiskMerchantInfo/src/mcpQueryRiskMerchantInfo/merchant_client._call_risk_merchant_api._call_risk_merchant_api_scope...ValueError","sourceNodeId":"_call_risk_merchant_api \\n[merchant_client.py : 19_58]","targetNodeId":"/src/mcpQueryRiskMerchantInfo/src/mcpQueryRiskMerchantInfo/merchant_client._call_risk_merchant_api._call_risk_merchant_api_scope...ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpQueryRiskMerchantInfo/src/mcpQueryRiskMerchantInfo/merchant_client.py"},"region":{"startLine":113,"startColumn":9,"endLine":113,"endColumn":85,"snippet":{}}}},"id":"query_risk_merchant_info \\n[merchant_client.py : 79_133]->syslib_from.logging.getLogger(__name__).info","sourceNodeId":"query_risk_merchant_info \\n[merchant_client.py : 79_133]","targetNodeId":"syslib_from.logging.getLogger(__name__).info"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpQueryRiskMerchantInfo/src/mcpQueryRiskMerchantInfo/merchant_client.py"},"region":{"startLine":126,"startColumn":36,"endLine":126,"endColumn":75,"snippet":{}}}},"id":"query_risk_merchant_info \\n[merchant_client.py : 79_133]->get","sourceNodeId":"query_risk_merchant_info \\n[merchant_client.py : 79_133]","targetNodeId":"get"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpQueryRiskMerchantInfo/src/mcpQueryRiskMerchantInfo/merchant_client.py"},"region":{"startLine":124,"startColumn":29,"endLine":124,"endColumn":82,"snippet":{}}}},"id":"query_risk_merchant_info \\n[merchant_client.py : 79_133]->get(basicInfo, {}).get","sourceNodeId":"query_risk_merchant_info \\n[merchant_client.py : 79_133]","targetNodeId":"get(basicInfo, {}).get"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpQueryRiskMerchantInfo/src/mcpQueryRiskMerchantInfo/merchant_client.py"},"region":{"startLine":133,"startColumn":54,"endLine":133,"endColumn":62,"snippet":{}}}},"id":"query_risk_merchant_info \\n[merchant_client.py : 79_133]->/src/mcpQueryRiskMerchantInfo/src/mcpQueryRiskMerchantInfo/merchant_client.query_risk_merchant_info.query_risk_merchant_info_scope...str","sourceNodeId":"query_risk_merchant_info \\n[merchant_client.py : 79_133]","targetNodeId":"/src/mcpQueryRiskMerchantInfo/src/mcpQueryRiskMerchantInfo/merchant_client.query_risk_merchant_info.query_risk_merchant_info_scope...str"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpQueryRiskMerchantInfo/src/mcpQueryRiskMerchantInfo/merchant_client.py"},"region":{"startLine":132,"startColumn":9,"endLine":132,"endColumn":84,"snippet":{}}}},"id":"query_risk_merchant_info \\n[merchant_client.py : 79_133]->syslib_from.logging.getLogger(__name__).error","sourceNodeId":"query_risk_merchant_info \\n[merchant_client.py : 79_133]","targetNodeId":"syslib_from.logging.getLogger(__name__).error"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpQueryRiskMerchantInfo/src/mcpQueryRiskMerchantInfo/merchant_client.py"},"region":{"startLine":133,"startColumn":15,"endLine":133,"endColumn":64,"snippet":{}}}},"id":"query_risk_merchant_info \\n[merchant_client.py : 79_133]->/src/mcpQueryRiskMerchantInfo/src/mcpQueryRiskMerchantInfo/merchant_client.query_risk_merchant_info.query_risk_merchant_info_scope...ValueError","sourceNodeId":"query_risk_merchant_info \\n[merchant_client.py : 79_133]","targetNodeId":"/src/mcpQueryRiskMerchantInfo/src/mcpQueryRiskMerchantInfo/merchant_client.query_risk_merchant_info.query_risk_merchant_info_scope...ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpQueryRiskMerchantInfo/src/mcpQueryRiskMerchantInfo/merchant_client.py"},"region":{"startLine":143,"startColumn":19,"endLine":143,"endColumn":67,"snippet":{}}}},"id":"main \\n[merchant_client.py : 138_145]->syslib_from.json.dumps","sourceNodeId":"main \\n[merchant_client.py : 138_145]","targetNodeId":"syslib_from.json.dumps"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpQueryRiskMerchantInfo/src/mcpQueryRiskMerchantInfo/merchant_client.py"},"region":{"startLine":145,"startColumn":13,"endLine":145,"endColumn":38,"snippet":{}}}},"id":"main \\n[merchant_client.py : 138_145]->/src/mcpQueryRiskMerchantInfo/src/mcpQueryRiskMerchantInfo/merchant_client..main.main_scope..print","sourceNodeId":"main \\n[merchant_client.py : 138_145]","targetNodeId":"/src/mcpQueryRiskMerchantInfo/src/mcpQueryRiskMerchantInfo/merchant_client..main.main_scope..print"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpQueryRiskMerchantInfo/src/mcpQueryRiskMerchantInfo/merchant_client.py"},"region":{"startLine":145,"startColumn":28,"endLine":145,"endColumn":36,"snippet":{}}}},"id":"main \\n[merchant_client.py : 138_145]->/src/mcpQueryRiskMerchantInfo/src/mcpQueryRiskMerchantInfo/merchant_client..main.main_scope...str","sourceNodeId":"main \\n[merchant_client.py : 138_145]","targetNodeId":"/src/mcpQueryRiskMerchantInfo/src/mcpQueryRiskMerchantInfo/merchant_client..main.main_scope...str"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpQuerySingleAppMetrics/src/mcpQuerySingleAppMetrics/server.py"},"region":{"startLine":27,"startColumn":18,"endLine":27,"endColumn":68,"snippet":{}}}},"id":"<__entry_point__>->,.join","sourceNodeId":"<__entry_point__>","targetNodeId":",.join"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpQuerySingleAppMetrics/src/mcpQuerySingleAppMetrics/maas_service.py"},"region":{"startLine":613,"startColumn":12,"endLine":613,"endColumn":25,"snippet":{}}}},"id":"<__entry_point__>->MaasService :: __init__ \\n[maas_service.py : 43_47]","sourceNodeId":"<__entry_point__>","targetNodeId":"MaasService :: __init__ \\n[maas_service.py : 43_47]"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpQuerySingleAppMetrics/src/mcpQuerySingleAppMetrics/maas_service.py"},"region":{"startLine":614,"startColumn":12,"endLine":615,"endColumn":236,"snippet":{}}}},"id":"<__entry_point__>->MaasService :: query_maas_by_sql_new_engine \\n[maas_service.py : 465_511]","sourceNodeId":"<__entry_point__>","targetNodeId":"MaasService :: query_maas_by_sql_new_engine \\n[maas_service.py : 465_511]"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpQuerySingleAppMetrics/src/mcpQuerySingleAppMetrics/maas_service.py"},"region":{"startLine":77,"startColumn":5,"endLine":91,"endColumn":28,"snippet":{}}}},"id":"MaasService :: query_maas_by_sql_new_engine \\n[maas_service.py : 465_511]->MaasService :: replace_seconds_with_zero \\n[maas_service.py : 77_91]","sourceNodeId":"MaasService :: query_maas_by_sql_new_engine \\n[maas_service.py : 465_511]","targetNodeId":"MaasService :: replace_seconds_with_zero \\n[maas_service.py : 77_91]"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpQuerySingleAppMetrics/src/mcpQuerySingleAppMetrics/maas_service.py"},"region":{"startLine":90,"startColumn":24,"endLine":90,"endColumn":58,"snippet":{}}}},"id":"MaasService :: replace_seconds_with_zero \\n[maas_service.py : 77_91]->syslib_from.re.sub","sourceNodeId":"MaasService :: replace_seconds_with_zero \\n[maas_service.py : 77_91]","targetNodeId":"syslib_from.re.sub"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpQuerySingleAppMetrics/src/mcpQuerySingleAppMetrics/maas_service.py"},"region":{"startLine":90,"startColumn":24,"endLine":90,"endColumn":58,"snippet":{}}}},"id":"syslib_from.re.sub->replace_func \\n[maas_service.py : 86_87]","sourceNodeId":"syslib_from.re.sub","targetNodeId":"replace_func \\n[maas_service.py : 86_87]"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpQuerySingleAppMetrics/src/mcpQuerySingleAppMetrics/maas_service.py"},"region":{"startLine":87,"startColumn":20,"endLine":87,"endColumn":34,"snippet":{}}}},"id":"replace_func \\n[maas_service.py : 86_87]->match.group","sourceNodeId":"replace_func \\n[maas_service.py : 86_87]","targetNodeId":"match.group"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpQuerySingleAppMetrics/src/mcpQuerySingleAppMetrics/maas_service.py"},"region":{"startLine":66,"startColumn":5,"endLine":74,"endColumn":19,"snippet":{}}}},"id":"MaasService :: query_maas_by_sql_new_engine \\n[maas_service.py : 465_511]->MaasService :: replace_env \\n[maas_service.py : 66_74]","sourceNodeId":"MaasService :: query_maas_by_sql_new_engine \\n[maas_service.py : 465_511]","targetNodeId":"MaasService :: replace_env \\n[maas_service.py : 66_74]"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpQuerySingleAppMetrics/src/mcpQuerySingleAppMetrics/maas_service.py"},"region":{"startLine":73,"startColumn":20,"endLine":73,"endColumn":68,"snippet":{}}}},"id":"MaasService :: replace_env \\n[maas_service.py : 66_74]->syslib_from.re.sub(pattern, replace_func, sql).replace","sourceNodeId":"MaasService :: replace_env \\n[maas_service.py : 66_74]","targetNodeId":"syslib_from.re.sub(pattern, replace_func, sql).replace"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpQuerySingleAppMetrics/src/mcpQuerySingleAppMetrics/maas_service.py"},"region":{"startLine":497,"startColumn":15,"endLine":497,"endColumn":55,"snippet":{}}}},"id":"MaasService :: query_maas_by_sql_new_engine \\n[maas_service.py : 465_511]->syslib_from.json.dumps","sourceNodeId":"MaasService :: query_maas_by_sql_new_engine \\n[maas_service.py : 465_511]","targetNodeId":"syslib_from.json.dumps"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpQuerySingleAppMetrics/src/mcpQuerySingleAppMetrics/maas_service.py"},"region":{"startLine":492,"startColumn":13,"endLine":492,"endColumn":102,"snippet":{}}}},"id":"MaasService :: query_maas_by_sql_new_engine \\n[maas_service.py : 465_511]->syslib_from.logging.getLogger(__name__).info","sourceNodeId":"MaasService :: query_maas_by_sql_new_engine \\n[maas_service.py : 465_511]","targetNodeId":"syslib_from.logging.getLogger(__name__).info"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpQuerySingleAppMetrics/src/mcpQuerySingleAppMetrics/maas_service.py"},"region":{"startLine":488,"startColumn":19,"endLine":488,"endColumn":42,"snippet":{}}}},"id":"MaasService :: query_maas_by_sql_new_engine \\n[maas_service.py : 465_511]->syslib_from.json.dumps({sql:sql}, var ensure_ascii:any=false).encode","sourceNodeId":"MaasService :: query_maas_by_sql_new_engine \\n[maas_service.py : 465_511]","targetNodeId":"syslib_from.json.dumps({sql:sql}, var ensure_ascii:any=false).encode"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpQuerySingleAppMetrics/src/mcpQuerySingleAppMetrics/maas_service.py"},"region":{"startLine":489,"startColumn":25,"endLine":489,"endColumn":90,"snippet":{}}}},"id":"MaasService :: query_maas_by_sql_new_engine \\n[maas_service.py : 465_511]->syslib_from.requests.post","sourceNodeId":"MaasService :: query_maas_by_sql_new_engine \\n[maas_service.py : 465_511]","targetNodeId":"syslib_from.requests.post"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpQuerySingleAppMetrics/src/mcpQuerySingleAppMetrics/maas_service.py"},"region":{"startLine":489,"startColumn":25,"endLine":489,"endColumn":97,"snippet":{}}}},"id":"MaasService :: query_maas_by_sql_new_engine \\n[maas_service.py : 465_511]->syslib_from.requests.post(self.new_engine_url, var headers:any=headers, var data:any=payload).json","sourceNodeId":"MaasService :: query_maas_by_sql_new_engine \\n[maas_service.py : 465_511]","targetNodeId":"syslib_from.requests.post(self.new_engine_url, var headers:any=headers, var data:any=payload).json"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpQuerySingleAppMetrics/src/mcpQuerySingleAppMetrics/maas_service.py"},"region":{"startLine":497,"startColumn":9,"endLine":497,"endColumn":56,"snippet":{}}}},"id":"MaasService :: query_maas_by_sql_new_engine \\n[maas_service.py : 465_511]->/src/mcpQuerySingleAppMetrics/src/mcpQuerySingleAppMetrics/maas_service.MaasService.query_maas_by_sql_new_engine.query_maas_by_sql_new_engine_scope..print","sourceNodeId":"MaasService :: query_maas_by_sql_new_engine \\n[maas_service.py : 465_511]","targetNodeId":"/src/mcpQuerySingleAppMetrics/src/mcpQuerySingleAppMetrics/maas_service.MaasService.query_maas_by_sql_new_engine.query_maas_by_sql_new_engine_scope..print"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpQuerySingleAppMetrics/src/mcpQuerySingleAppMetrics/maas_service.py"},"region":{"startLine":499,"startColumn":28,"endLine":499,"endColumn":63,"snippet":{}}}},"id":"MaasService :: query_maas_by_sql_new_engine \\n[maas_service.py : 465_511]->syslib_from.requests.post(self.new_engine_url, var headers:any=headers, var data:any=payload).json().data.headers.index","sourceNodeId":"MaasService :: query_maas_by_sql_new_engine \\n[maas_service.py : 465_511]","targetNodeId":"syslib_from.requests.post(self.new_engine_url, var headers:any=headers, var data:any=payload).json().data.headers.index"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpQuerySingleAppMetrics/src/mcpQuerySingleAppMetrics/maas_service.py"},"region":{"startLine":502,"startColumn":24,"endLine":502,"endColumn":66,"snippet":{}}}},"id":"MaasService :: query_maas_by_sql_new_engine \\n[maas_service.py : 465_511]->syslib_from.datetime.datetime.fromtimestamp","sourceNodeId":"MaasService :: query_maas_by_sql_new_engine \\n[maas_service.py : 465_511]","targetNodeId":"syslib_from.datetime.datetime.fromtimestamp"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpQuerySingleAppMetrics/src/mcpQuerySingleAppMetrics/maas_service.py"},"region":{"startLine":502,"startColumn":24,"endLine":502,"endColumn":93,"snippet":{}}}},"id":"MaasService :: query_maas_by_sql_new_engine \\n[maas_service.py : 465_511]->syslib_from.datetime.datetime.fromtimestamp(timestamp).strftime","sourceNodeId":"MaasService :: query_maas_by_sql_new_engine \\n[maas_service.py : 465_511]","targetNodeId":"syslib_from.datetime.datetime.fromtimestamp(timestamp).strftime"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpQuerySingleAppMetrics/src/mcpQuerySingleAppMetrics/maas_service.py"},"region":{"startLine":504,"startColumn":37,"endLine":504,"endColumn":50,"snippet":{}}}},"id":"MaasService :: query_maas_by_sql_new_engine \\n[maas_service.py : 465_511]->/src/mcpQuerySingleAppMetrics/src/mcpQuerySingleAppMetrics/maas_service.MaasService.query_maas_by_sql_new_engine.query_maas_by_sql_new_engine_scope.....->/src/mcpQuerySingleAppMetrics/src/mcpQuerySingleAppMetrics/maas_service..print","sourceNodeId":"<__entry_point__>","targetNodeId":"/src/mcpQuerySingleAppMetrics/src/mcpQuerySingleAppMetrics/maas_service..print"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpQuerySingleAppMetrics/src/mcpQuerySingleAppMetrics/rmc_utils.py"},"region":{"startLine":47,"startColumn":20,"endLine":47,"endColumn":51,"snippet":{}}}},"id":"get_app_info \\n[rmc_utils.py : 8_58]->/src/mcpQuerySingleAppMetrics/src/mcpQuerySingleAppMetrics/rmc_utils.get_app_info.get_app_info_scope...len","sourceNodeId":"get_app_info \\n[rmc_utils.py : 8_58]","targetNodeId":"/src/mcpQuerySingleAppMetrics/src/mcpQuerySingleAppMetrics/rmc_utils.get_app_info.get_app_info_scope...len"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpQuerySingleAppMetrics/src/mcpQuerySingleAppMetrics/rmc_utils.py"},"region":{"startLine":63,"startColumn":5,"endLine":63,"endColumn":16,"snippet":{}}}},"id":"<__entry_point__>->/src/mcpQuerySingleAppMetrics/src/mcpQuerySingleAppMetrics/rmc_utils..print","sourceNodeId":"<__entry_point__>","targetNodeId":"/src/mcpQuerySingleAppMetrics/src/mcpQuerySingleAppMetrics/rmc_utils..print"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpRopnTaskStatusAnalyse/src/mcpRopnTaskStatusAnalyse/ropcn_utils.py"},"region":{"startLine":197,"startColumn":11,"endLine":197,"endColumn":75,"snippet":{}}}},"id":"<__entry_point__>->codeGenChat \\n[ropcn_utils.py : 153_192]","sourceNodeId":"<__entry_point__>","targetNodeId":"codeGenChat \\n[ropcn_utils.py : 153_192]"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpRopnTaskStatusAnalyse/src/mcpRopnTaskStatusAnalyse/ropcn_utils.py"},"region":{"startLine":173,"startColumn":37,"endLine":173,"endColumn":75,"snippet":{}}}},"id":"codeGenChat \\n[ropcn_utils.py : 153_192]->syslib_from.json.dumps","sourceNodeId":"codeGenChat \\n[ropcn_utils.py : 153_192]","targetNodeId":"syslib_from.json.dumps"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpRopnTaskStatusAnalyse/src/mcpRopnTaskStatusAnalyse/ropcn_utils.py"},"region":{"startLine":172,"startColumn":18,"endLine":175,"endColumn":71,"snippet":{}}}},"id":"codeGenChat \\n[ropcn_utils.py : 153_192]->syslib_from.requests.post","sourceNodeId":"codeGenChat \\n[ropcn_utils.py : 153_192]","targetNodeId":"syslib_from.requests.post"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpRopnTaskStatusAnalyse/src/mcpRopnTaskStatusAnalyse/ropcn_utils.py"},"region":{"startLine":177,"startColumn":9,"endLine":177,"endColumn":87,"snippet":{}}}},"id":"codeGenChat \\n[ropcn_utils.py : 153_192]->syslib_from.logging.getLogger(__name__).info","sourceNodeId":"codeGenChat \\n[ropcn_utils.py : 153_192]","targetNodeId":"syslib_from.logging.getLogger(__name__).info"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpRopnTaskStatusAnalyse/src/mcpRopnTaskStatusAnalyse/ropcn_utils.py"},"region":{"startLine":181,"startColumn":26,"endLine":181,"endColumn":58,"snippet":{}}}},"id":"codeGenChat \\n[ropcn_utils.py : 153_192]->syslib_from.requests.post(var url:any=https://codegencore.alipay.com/api/answer/repo/general/chat, var data:any=json.dumps(payload, var ensure_ascii:any=true), var headers:any={Content-Type:applicatio...","sourceNodeId":"codeGenChat \\n[ropcn_utils.py : 153_192]","targetNodeId":"syslib_from.requests.post(var url:any=https://codegencore.alipay.com/api/answer/repo/general/chat, var data:any=json.dumps(payload, var ensure_ascii:any=true), var headers:any={Content-Type:applicatio..."},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpRopnTaskStatusAnalyse/src/mcpRopnTaskStatusAnalyse/ropcn_utils.py"},"region":{"startLine":186,"startColumn":47,"endLine":186,"endColumn":77,"snippet":{}}}},"id":"codeGenChat \\n[ropcn_utils.py : 153_192]->/src/mcpRopnTaskStatusAnalyse/src/mcpRopnTaskStatusAnalyse/ropcn_utils.codeGenChat.codeGenChat_scope..len","sourceNodeId":"codeGenChat \\n[ropcn_utils.py : 153_192]","targetNodeId":"/src/mcpRopnTaskStatusAnalyse/src/mcpRopnTaskStatusAnalyse/ropcn_utils.codeGenChat.codeGenChat_scope..len"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpRopnTaskStatusAnalyse/src/mcpRopnTaskStatusAnalyse/ropcn_utils.py"},"region":{"startLine":184,"startColumn":20,"endLine":184,"endColumn":87,"snippet":{}}}},"id":"codeGenChat \\n[ropcn_utils.py : 153_192]->data.__contains__","sourceNodeId":"codeGenChat \\n[ropcn_utils.py : 153_192]","targetNodeId":"data.__contains__"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpRopnTaskStatusAnalyse/src/mcpRopnTaskStatusAnalyse/ropcn_utils.py"},"region":{"startLine":185,"startColumn":33,"endLine":185,"endColumn":49,"snippet":{}}}},"id":"codeGenChat \\n[ropcn_utils.py : 153_192]->syslib_from.json.loads","sourceNodeId":"codeGenChat \\n[ropcn_utils.py : 153_192]","targetNodeId":"syslib_from.json.loads"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpRopnTaskStatusAnalyse/src/mcpRopnTaskStatusAnalyse/ropcn_utils.py"},"region":{"startLine":186,"startColumn":51,"endLine":186,"endColumn":76,"snippet":{}}}},"id":"codeGenChat \\n[ropcn_utils.py : 153_192]->/src/mcpRopnTaskStatusAnalyse/src/mcpRopnTaskStatusAnalyse/ropcn_utils.codeGenChat.codeGenChat_scope.....str","sourceNodeId":"codeGenChat \\n[ropcn_utils.py : 153_192]","targetNodeId":"/src/mcpRopnTaskStatusAnalyse/src/mcpRopnTaskStatusAnalyse/ropcn_utils.codeGenChat.codeGenChat_scope.....str"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpRopnTaskStatusAnalyse/src/mcpRopnTaskStatusAnalyse/ropcn_utils.py"},"region":{"startLine":189,"startColumn":16,"endLine":189,"endColumn":38,"snippet":{}}}},"id":"codeGenChat \\n[ropcn_utils.py : 153_192]->join","sourceNodeId":"codeGenChat \\n[ropcn_utils.py : 153_192]","targetNodeId":"join"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpRopnTaskStatusAnalyse/src/mcpRopnTaskStatusAnalyse/ropcn_utils.py"},"region":{"startLine":192,"startColumn":56,"endLine":192,"endColumn":80,"snippet":{}}}},"id":"codeGenChat \\n[ropcn_utils.py : 153_192]->syslib_from.traceback.format_exc","sourceNodeId":"codeGenChat \\n[ropcn_utils.py : 153_192]","targetNodeId":"syslib_from.traceback.format_exc"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpRopnTaskStatusAnalyse/src/mcpRopnTaskStatusAnalyse/ropcn_utils.py"},"region":{"startLine":191,"startColumn":9,"endLine":191,"endColumn":109,"snippet":{}}}},"id":"codeGenChat \\n[ropcn_utils.py : 153_192]->syslib_from.logging.getLogger(__name__).error","sourceNodeId":"codeGenChat \\n[ropcn_utils.py : 153_192]","targetNodeId":"syslib_from.logging.getLogger(__name__).error"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpRopnTaskStatusAnalyse/src/mcpRopnTaskStatusAnalyse/ropcn_utils.py"},"region":{"startLine":197,"startColumn":5,"endLine":197,"endColumn":76,"snippet":{}}}},"id":"<__entry_point__>->/src/mcpRopnTaskStatusAnalyse/src/mcpRopnTaskStatusAnalyse/ropcn_utils..print","sourceNodeId":"<__entry_point__>","targetNodeId":"/src/mcpRopnTaskStatusAnalyse/src/mcpRopnTaskStatusAnalyse/ropcn_utils..print"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpSim/src/mcpSim/server.py"},"region":{"startLine":396,"startColumn":23,"endLine":396,"endColumn":88,"snippet":{}}}},"id":"<__entry_point__>->get_app_call_info \\n[server.py : 168_196]","sourceNodeId":"<__entry_point__>","targetNodeId":"get_app_call_info \\n[server.py : 168_196]"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpSim/src/mcpSim/server.py"},"region":{"startLine":186,"startColumn":20,"endLine":186,"endColumn":82,"snippet":{}}}},"id":"get_app_call_info \\n[server.py : 168_196]->syslib_from.requests.get","sourceNodeId":"get_app_call_info \\n[server.py : 168_196]","targetNodeId":"syslib_from.requests.get"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpSim/src/mcpSim/server.py"},"region":{"startLine":187,"startColumn":9,"endLine":187,"endColumn":36,"snippet":{}}}},"id":"get_app_call_info \\n[server.py : 168_196]->syslib_from.requests.get(url, var headers:any=header, var params:any=params, var verify:any=false).raise_for_status","sourceNodeId":"get_app_call_info \\n[server.py : 168_196]","targetNodeId":"syslib_from.requests.get(url, var headers:any=header, var params:any=params, var verify:any=false).raise_for_status"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpSim/src/mcpSim/server.py"},"region":{"startLine":188,"startColumn":18,"endLine":188,"endColumn":33,"snippet":{}}}},"id":"get_app_call_info \\n[server.py : 168_196]->syslib_from.requests.get(url, var headers:any=header, var params:any=params, var verify:any=false).json","sourceNodeId":"get_app_call_info \\n[server.py : 168_196]","targetNodeId":"syslib_from.requests.get(url, var headers:any=header, var params:any=params, var verify:any=false).json"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpSim/src/mcpSim/server.py"},"region":{"startLine":191,"startColumn":20,"endLine":191,"endColumn":37,"snippet":{}}}},"id":"get_app_call_info \\n[server.py : 168_196]->syslib_from.requests.get(url, var headers:any=header, var params:any=params, var verify:any=false).json().get","sourceNodeId":"get_app_call_info \\n[server.py : 168_196]","targetNodeId":"syslib_from.requests.get(url, var headers:any=header, var params:any=params, var verify:any=false).json().get"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpSim/src/mcpSim/server.py"},"region":{"startLine":190,"startColumn":13,"endLine":190,"endColumn":97,"snippet":{}}}},"id":"get_app_call_info \\n[server.py : 168_196]->syslib_from.logging.getLogger(mcp-server).info","sourceNodeId":"get_app_call_info \\n[server.py : 168_196]","targetNodeId":"syslib_from.logging.getLogger(mcp-server).info"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpSim/src/mcpSim/server.py"},"region":{"startLine":192,"startColumn":9,"endLine":192,"endColumn":96,"snippet":{}}}},"id":"get_app_call_info \\n[server.py : 168_196]->syslib_from.logging.getLogger(mcp-server).warning","sourceNodeId":"get_app_call_info \\n[server.py : 168_196]","targetNodeId":"syslib_from.logging.getLogger(mcp-server).warning"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpSim/src/mcpSim/server.py"},"region":{"startLine":195,"startColumn":9,"endLine":195,"endColumn":89,"snippet":{}}}},"id":"get_app_call_info \\n[server.py : 168_196]->syslib_from.logging.getLogger(mcp-server).error","sourceNodeId":"get_app_call_info \\n[server.py : 168_196]","targetNodeId":"syslib_from.logging.getLogger(mcp-server).error"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpSim/src/mcpSim/server.py"},"region":{"startLine":196,"startColumn":42,"endLine":196,"endColumn":50,"snippet":{}}}},"id":"get_app_call_info \\n[server.py : 168_196]->/src/mcpSim/src/mcpSim/server.get_app_call_info.get_app_call_info_scope...str","sourceNodeId":"get_app_call_info \\n[server.py : 168_196]","targetNodeId":"/src/mcpSim/src/mcpSim/server.get_app_call_info.get_app_call_info_scope...str"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpSim/src/mcpSim/server.py"},"region":{"startLine":396,"startColumn":5,"endLine":396,"endColumn":90,"snippet":{}}}},"id":"<__entry_point__>->/src/mcpSim/src/mcpSim/server..print","sourceNodeId":"<__entry_point__>","targetNodeId":"/src/mcpSim/src/mcpSim/server..print"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpSqlExecute/src/mcpSqlExecute/__init__.py"},"region":{"startLine":4,"startColumn":5,"endLine":4,"endColumn":29,"snippet":{}}}},"id":"main \\n[__init__.py : 3_4]->mcpSqlExecute.server.mcp.run","sourceNodeId":"main \\n[__init__.py : 3_4]","targetNodeId":"mcpSqlExecute.server.mcp.run"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpTemplate/src/mcpTemplate/__init__.py"},"region":{"startLine":4,"startColumn":5,"endLine":4,"endColumn":34,"snippet":{}}}},"id":"main \\n[__init__.py : 3_4]->server.server.run","sourceNodeId":"main \\n[__init__.py : 3_4]","targetNodeId":"server.server.run"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpTestAnalysis/src/mcpTestAnalysis/server.py"},"region":{"startLine":116,"startColumn":17,"endLine":116,"endColumn":23,"snippet":{}}}},"id":"<__entry_point__>->main \\n[server.py : 100_114]","sourceNodeId":"<__entry_point__>","targetNodeId":"main \\n[server.py : 100_114]"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpTestAnalysis/src/mcpTestAnalysis/server.py"},"region":{"startLine":54,"startColumn":2,"endLine":54,"endColumn":20,"snippet":{}}}},"id":"main \\n[server.py : 100_114]->.server.call_tool","sourceNodeId":"main \\n[server.py : 100_114]","targetNodeId":".server.call_tool"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpTestAnalysis/src/mcpTestAnalysis/server.py"},"region":{"startLine":109,"startColumn":22,"endLine":109,"endColumn":71,"snippet":{}}}},"id":"main \\n[server.py : 100_114]->handle_call_tool \\n[server.py : 55_77]","sourceNodeId":"main \\n[server.py : 100_114]","targetNodeId":"handle_call_tool \\n[server.py : 55_77]"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpTestAnalysis/src/mcpTestAnalysis/server.py"},"region":{"startLine":63,"startColumn":72,"endLine":63,"endColumn":115,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 55_77]->syslib_from.json.dumps","sourceNodeId":"handle_call_tool \\n[server.py : 55_77]","targetNodeId":"syslib_from.json.dumps"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpTestAnalysis/src/mcpTestAnalysis/server.py"},"region":{"startLine":62,"startColumn":5,"endLine":63,"endColumn":117,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 55_77]->syslib_from.logging.getLogger(__name__).info","sourceNodeId":"handle_call_tool \\n[server.py : 55_77]","targetNodeId":"syslib_from.logging.getLogger(__name__).info"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpTestAnalysis/src/mcpTestAnalysis/server.py"},"region":{"startLine":65,"startColumn":15,"endLine":65,"endColumn":54,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 55_77]->/src/mcpTestAnalysis/src/mcpTestAnalysis/server.handle_call_tool.handle_call_tool_scope...ValueError","sourceNodeId":"handle_call_tool \\n[server.py : 55_77]","targetNodeId":"/src/mcpTestAnalysis/src/mcpTestAnalysis/server.handle_call_tool.handle_call_tool_scope...ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpTestAnalysis/src/mcpTestAnalysis/server.py"},"region":{"startLine":73,"startColumn":23,"endLine":73,"endColumn":71,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 55_77]->/src/mcpTestAnalysis/src/mcpTestAnalysis/server.handle_call_tool.handle_call_tool_scope....ValueError","sourceNodeId":"handle_call_tool \\n[server.py : 55_77]","targetNodeId":"/src/mcpTestAnalysis/src/mcpTestAnalysis/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpTestAnalysis/src/mcpTestAnalysis/server.py"},"region":{"startLine":74,"startColumn":27,"endLine":74,"endColumn":97,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 55_77]->syslib_from.client.get_branch_prompt","sourceNodeId":"handle_call_tool \\n[server.py : 55_77]","targetNodeId":"syslib_from.client.get_branch_prompt"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpTestAnalysis/src/mcpTestAnalysis/server.py"},"region":{"startLine":77,"startColumn":13,"endLine":77,"endColumn":66,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 55_77]->syslib_from.mcp/types.TextContent","sourceNodeId":"handle_call_tool \\n[server.py : 55_77]","targetNodeId":"syslib_from.mcp/types.TextContent"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpTestAnalysis/src/mcpTestAnalysis/server.py"},"region":{"startLine":114,"startColumn":13,"endLine":114,"endColumn":41,"snippet":{}}}},"id":"main \\n[server.py : 100_114]->/src/mcpTestAnalysis/src/mcpTestAnalysis/server..main.main_scope..print","sourceNodeId":"main \\n[server.py : 100_114]","targetNodeId":"/src/mcpTestAnalysis/src/mcpTestAnalysis/server..main.main_scope..print"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpTestAnalysisDocument/src/mcpTestAnalysisDocument/client.py"},"region":{"startLine":112,"startColumn":17,"endLine":112,"endColumn":23,"snippet":{}}}},"id":"<__entry_point__>->main \\n[client.py : 106_110]","sourceNodeId":"<__entry_point__>","targetNodeId":"main \\n[client.py : 106_110]"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpTestAnalysisDocument/src/mcpTestAnalysisDocument/client.py"},"region":{"startLine":107,"startColumn":20,"endLine":109,"endColumn":10,"snippet":{}}}},"id":"main \\n[client.py : 106_110]->get_code_diffs \\n[client.py : 40_72]","sourceNodeId":"main \\n[client.py : 106_110]","targetNodeId":"get_code_diffs \\n[client.py : 40_72]"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpTestAnalysisDocument/src/mcpTestAnalysisDocument/client.py"},"region":{"startLine":41,"startColumn":14,"endLine":41,"endColumn":34,"snippet":{}}}},"id":"get_code_diffs \\n[client.py : 40_72]->CodeAnalysisResult :: __init__ \\n[client.py : 25_28]","sourceNodeId":"get_code_diffs \\n[client.py : 40_72]","targetNodeId":"CodeAnalysisResult :: __init__ \\n[client.py : 25_28]"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpTestAnalysisDocument/src/mcpTestAnalysisDocument/client.py"},"region":{"startLine":50,"startColumn":33,"endLine":50,"endColumn":43,"snippet":{}}}},"id":"get_code_diffs \\n[client.py : 40_72]->_headers \\n[client.py : 16_20]","sourceNodeId":"get_code_diffs \\n[client.py : 40_72]","targetNodeId":"_headers \\n[client.py : 16_20]"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpTestAnalysisDocument/src/mcpTestAnalysisDocument/client.py"},"region":{"startLine":48,"startColumn":20,"endLine":51,"endColumn":10,"snippet":{}}}},"id":"get_code_diffs \\n[client.py : 40_72]->mcp_common.request.http_client.AsyncRestClient","sourceNodeId":"get_code_diffs \\n[client.py : 40_72]","targetNodeId":"mcp_common.request.http_client.AsyncRestClient"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpTestAnalysisDocument/src/mcpTestAnalysisDocument/client.py"},"region":{"startLine":53,"startColumn":24,"endLine":53,"endColumn":95,"snippet":{}}}},"id":"get_code_diffs \\n[client.py : 40_72]->mcp_common.request.http_client.AsyncRestClient(var base_url:any=https://instemc.alipay.com, var default_headers:any=_headers()).post","sourceNodeId":"get_code_diffs \\n[client.py : 40_72]","targetNodeId":"mcp_common.request.http_client.AsyncRestClient(var base_url:any=https://instemc.alipay.com, var default_headers:any=_headers()).post"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpTestAnalysisDocument/src/mcpTestAnalysisDocument/client.py"},"region":{"startLine":62,"startColumn":33,"endLine":62,"endColumn":81,"snippet":{}}}},"id":"get_code_diffs \\n[client.py : 40_72]->mcp_common.request.http_client.AsyncRestClient(var base_url:any=https://instemc.alipay.com, var default_headers:any=_headers()).post(var endpoint:any=/testAnalysis/getCodeDiffs, var data:any=diff_url)...","sourceNodeId":"get_code_diffs \\n[client.py : 40_72]","targetNodeId":"mcp_common.request.http_client.AsyncRestClient(var base_url:any=https://instemc.alipay.com, var default_headers:any=_headers()).post(var endpoint:any=/testAnalysis/getCodeDiffs, var data:any=diff_url)..."},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpTestAnalysisDocument/src/mcpTestAnalysisDocument/client.py"},"region":{"startLine":65,"startColumn":9,"endLine":65,"endColumn":48,"snippet":{}}}},"id":"get_code_diffs \\n[client.py : 40_72]->syslib_from.logging.getLogger(__name__).exception","sourceNodeId":"get_code_diffs \\n[client.py : 40_72]","targetNodeId":"syslib_from.logging.getLogger(__name__).exception"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpTestAnalysis/src/mcpTestAnalysis/client.py"},"region":{"startLine":66,"startColumn":51,"endLine":66,"endColumn":59,"snippet":{}}}},"id":"get_code_diffs \\n[client.py : 40_72]->/src/mcpTestAnalysis/src/mcpTestAnalysis/client.get_code_diffs.get_code_diffs_scope...str","sourceNodeId":"get_code_diffs \\n[client.py : 40_72]","targetNodeId":"/src/mcpTestAnalysis/src/mcpTestAnalysis/client.get_code_diffs.get_code_diffs_scope...str"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpTestAnalysisDocument/src/mcpTestAnalysisDocument/client.py"},"region":{"startLine":70,"startColumn":13,"endLine":70,"endColumn":53,"snippet":{}}}},"id":"get_code_diffs \\n[client.py : 40_72]->mcp_common.request.http_client.AsyncRestClient(var base_url:any=https://instemc.alipay.com, var default_headers:any=_headers()).__aexit__","sourceNodeId":"get_code_diffs \\n[client.py : 40_72]","targetNodeId":"mcp_common.request.http_client.AsyncRestClient(var base_url:any=https://instemc.alipay.com, var default_headers:any=_headers()).__aexit__"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpTestAnalysisDocument/src/mcpTestAnalysisDocument/client.py"},"region":{"startLine":72,"startColumn":12,"endLine":72,"endColumn":28,"snippet":{}}}},"id":"get_code_diffs \\n[client.py : 40_72]->CodeAnalysisResult :: to_dict \\n[client.py : 30_35]","sourceNodeId":"get_code_diffs \\n[client.py : 40_72]","targetNodeId":"CodeAnalysisResult :: to_dict \\n[client.py : 30_35]"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpTestAnalysisDocument/src/mcpTestAnalysisDocument/client.py"},"region":{"startLine":110,"startColumn":15,"endLine":110,"endColumn":65,"snippet":{}}}},"id":"main \\n[client.py : 106_110]->syslib_from.json.dumps","sourceNodeId":"main \\n[client.py : 106_110]","targetNodeId":"syslib_from.json.dumps"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpTestAnalysis/src/mcpTestAnalysis/client.py"},"region":{"startLine":110,"startColumn":9,"endLine":110,"endColumn":66,"snippet":{}}}},"id":"main \\n[client.py : 106_110]->/src/mcpTestAnalysis/src/mcpTestAnalysis/client..main.main_scope..print","sourceNodeId":"main \\n[client.py : 106_110]","targetNodeId":"/src/mcpTestAnalysis/src/mcpTestAnalysis/client..main.main_scope..print"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpTestAnalysis/src/tests/test_hello.py"},"region":{"startLine":30,"startColumn":13,"endLine":30,"endColumn":50,"snippet":{}}}},"id":"<__entry_point__>->sofapy.core.app.create_app","sourceNodeId":"<__entry_point__>","targetNodeId":"sofapy.core.app.create_app"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpTestAnalysis/src/tests/test_hello.py"},"region":{"startLine":70,"startColumn":17,"endLine":70,"endColumn":23,"snippet":{}}}},"id":"<__entry_point__>->main \\n[test_hello.py : 33_66]","sourceNodeId":"<__entry_point__>","targetNodeId":"main \\n[test_hello.py : 33_66]"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpTestAnalysis/src/tests/test_hello.py"},"region":{"startLine":34,"startColumn":37,"endLine":34,"endColumn":103,"snippet":{}}}},"id":"main \\n[test_hello.py : 33_66]->sofapy.middlewares.rpc.MCPSubService","sourceNodeId":"main \\n[test_hello.py : 33_66]","targetNodeId":"sofapy.middlewares.rpc.MCPSubService"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpTestAnalysis/src/tests/test_hello.py"},"region":{"startLine":34,"startColumn":5,"endLine":34,"endColumn":104,"snippet":{}}}},"id":"main \\n[test_hello.py : 33_66]->sofapy.core.app.create_app(deriskcore, user_config).subscribe_mcp_service","sourceNodeId":"main \\n[test_hello.py : 33_66]","targetNodeId":"sofapy.core.app.create_app(deriskcore, user_config).subscribe_mcp_service"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpTestAnalysis/src/tests/test_hello.py"},"region":{"startLine":54,"startColumn":18,"endLine":54,"endColumn":66,"snippet":{}}}},"id":"main \\n[test_hello.py : 33_66]->sofapy.core.mcp.client.client.MCPClient.create","sourceNodeId":"main \\n[test_hello.py : 33_66]","targetNodeId":"sofapy.core.mcp.client.client.MCPClient.create"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpTestAnalysis/src/tests/test_hello.py"},"region":{"startLine":57,"startColumn":13,"endLine":57,"endColumn":103,"snippet":{}}}},"id":"main \\n[test_hello.py : 33_66]->sofapy.core.mcp.client.client.MCPClient.create(service_code, var header:any=properties).connect_to_server","sourceNodeId":"main \\n[test_hello.py : 33_66]","targetNodeId":"sofapy.core.mcp.client.client.MCPClient.create(service_code, var header:any=properties).connect_to_server"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpTestAnalysis/src/tests/test_hello.py"},"region":{"startLine":42,"startColumn":20,"endLine":42,"endColumn":45,"snippet":{}}}},"id":"main \\n[test_hello.py : 33_66]->sofapy.core.mcp.client.client.MCPClient.create(service_code, var header:any=properties).list_tools","sourceNodeId":"main \\n[test_hello.py : 33_66]","targetNodeId":"sofapy.core.mcp.client.client.MCPClient.create(service_code, var header:any=properties).list_tools"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpTestAnalysis/src/tests/test_hello.py"},"region":{"startLine":66,"startColumn":9,"endLine":66,"endColumn":52,"snippet":{}}}},"id":"main \\n[test_hello.py : 33_66]->/src/mcpTestAnalysis/src/tests/test_hello.main.main_scope..print","sourceNodeId":"main \\n[test_hello.py : 33_66]","targetNodeId":"/src/mcpTestAnalysis/src/tests/test_hello.main.main_scope..print"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpTestAnalysis/src/tests/test_hello.py"},"region":{"startLine":61,"startColumn":13,"endLine":61,"endColumn":35,"snippet":{}}}},"id":"main \\n[test_hello.py : 33_66]->sofapy.core.mcp.client.client.MCPClient.create(service_code, var header:any=properties).cleanup","sourceNodeId":"main \\n[test_hello.py : 33_66]","targetNodeId":"sofapy.core.mcp.client.client.MCPClient.create(service_code, var header:any=properties).cleanup"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpTestAnalysis/src/tests/test_hello.py"},"region":{"startLine":56,"startColumn":28,"endLine":56,"endColumn":40,"snippet":{}}}},"id":"main \\n[test_hello.py : 33_66]->syslib_from.uuid.uuid4","sourceNodeId":"main \\n[test_hello.py : 33_66]","targetNodeId":"syslib_from.uuid.uuid4"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpTestAnalysis/src/tests/test_hello.py"},"region":{"startLine":56,"startColumn":24,"endLine":56,"endColumn":41,"snippet":{}}}},"id":"main \\n[test_hello.py : 33_66]->/src/mcpTestAnalysis/src/tests/test_hello.main.main_scope..str","sourceNodeId":"main \\n[test_hello.py : 33_66]","targetNodeId":"/src/mcpTestAnalysis/src/tests/test_hello.main.main_scope..str"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpTestAnalysis/src/tests/test_hello.py"},"region":{"startLine":56,"startColumn":24,"endLine":56,"endColumn":57,"snippet":{}}}},"id":"main \\n[test_hello.py : 33_66]->/src/mcpTestAnalysis/src/tests/test_hello.main.main_scope..str(uuid.uuid4()).replace","sourceNodeId":"main \\n[test_hello.py : 33_66]","targetNodeId":"/src/mcpTestAnalysis/src/tests/test_hello.main.main_scope..str(uuid.uuid4()).replace"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpTestAnalysis/src/tests/test_hello.py"},"region":{"startLine":58,"startColumn":20,"endLine":58,"endColumn":187,"snippet":{}}}},"id":"main \\n[test_hello.py : 33_66]->sofapy.core.mcp.client.client.MCPClient.create(service_code, var header:any=properties).call_tool","sourceNodeId":"main \\n[test_hello.py : 33_66]","targetNodeId":"sofapy.core.mcp.client.client.MCPClient.create(service_code, var header:any=properties).call_tool"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpTestAnalysisDocument/src/mcpTestAnalysisDocument/client.py"},"region":{"startLine":66,"startColumn":51,"endLine":66,"endColumn":59,"snippet":{}}}},"id":"get_code_diffs \\n[client.py : 40_72]->/src/mcpTestAnalysisDocument/src/mcpTestAnalysisDocument/client.get_code_diffs.get_code_diffs_scope...str","sourceNodeId":"get_code_diffs \\n[client.py : 40_72]","targetNodeId":"/src/mcpTestAnalysisDocument/src/mcpTestAnalysisDocument/client.get_code_diffs.get_code_diffs_scope...str"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpTestAnalysisDocument/src/mcpTestAnalysisDocument/client.py"},"region":{"startLine":110,"startColumn":9,"endLine":110,"endColumn":66,"snippet":{}}}},"id":"main \\n[client.py : 106_110]->/src/mcpTestAnalysisDocument/src/mcpTestAnalysisDocument/client..main.main_scope..print","sourceNodeId":"main \\n[client.py : 106_110]","targetNodeId":"/src/mcpTestAnalysisDocument/src/mcpTestAnalysisDocument/client..main.main_scope..print"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpTestAnalysisDocument/src/mcpTestAnalysisDocument/report_client.py"},"region":{"startLine":86,"startColumn":17,"endLine":86,"endColumn":23,"snippet":{}}}},"id":"<__entry_point__>->main \\n[report_client.py : 80_84]","sourceNodeId":"<__entry_point__>","targetNodeId":"main \\n[report_client.py : 80_84]"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpTestAnalysisDocument/src/mcpTestAnalysisDocument/report_client.py"},"region":{"startLine":81,"startColumn":20,"endLine":83,"endColumn":10,"snippet":{}}}},"id":"main \\n[report_client.py : 80_84]->write_document \\n[report_client.py : 42_74]","sourceNodeId":"main \\n[report_client.py : 80_84]","targetNodeId":"write_document \\n[report_client.py : 42_74]"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpTestAnalysisDocument/src/mcpTestAnalysisDocument/report_client.py"},"region":{"startLine":43,"startColumn":14,"endLine":43,"endColumn":22,"snippet":{}}}},"id":"write_document \\n[report_client.py : 42_74]->Result :: __init__ \\n[report_client.py : 27_30]","sourceNodeId":"write_document \\n[report_client.py : 42_74]","targetNodeId":"Result :: __init__ \\n[report_client.py : 27_30]"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpTestAnalysisDocument/src/mcpTestAnalysisDocument/report_client.py"},"region":{"startLine":53,"startColumn":33,"endLine":53,"endColumn":43,"snippet":{}}}},"id":"write_document \\n[report_client.py : 42_74]->_headers \\n[report_client.py : 18_22]","sourceNodeId":"write_document \\n[report_client.py : 42_74]","targetNodeId":"_headers \\n[report_client.py : 18_22]"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpTestAnalysisDocument/src/mcpTestAnalysisDocument/report_client.py"},"region":{"startLine":51,"startColumn":20,"endLine":54,"endColumn":10,"snippet":{}}}},"id":"write_document \\n[report_client.py : 42_74]->mcp_common.request.http_client.AsyncRestClient","sourceNodeId":"write_document \\n[report_client.py : 42_74]","targetNodeId":"mcp_common.request.http_client.AsyncRestClient"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpTestAnalysisDocument/src/mcpTestAnalysisDocument/report_client.py"},"region":{"startLine":56,"startColumn":24,"endLine":56,"endColumn":82,"snippet":{}}}},"id":"write_document \\n[report_client.py : 42_74]->mcp_common.request.http_client.AsyncRestClient(var base_url:any=https://instemc.alipay.com/yuque, var default_headers:any=_headers()).post","sourceNodeId":"write_document \\n[report_client.py : 42_74]","targetNodeId":"mcp_common.request.http_client.AsyncRestClient(var base_url:any=https://instemc.alipay.com/yuque, var default_headers:any=_headers()).post"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpTestAnalysisDocument/src/mcpTestAnalysisDocument/report_client.py"},"region":{"startLine":64,"startColumn":30,"endLine":64,"endColumn":72,"snippet":{}}}},"id":"write_document \\n[report_client.py : 42_74]->mcp_common.request.http_client.AsyncRestClient(var base_url:any=https://instemc.alipay.com/yuque, var default_headers:any=_headers()).post(var endpoint:any=/writeDocument, var data:any=payload).get","sourceNodeId":"write_document \\n[report_client.py : 42_74]","targetNodeId":"mcp_common.request.http_client.AsyncRestClient(var base_url:any=https://instemc.alipay.com/yuque, var default_headers:any=_headers()).post(var endpoint:any=/writeDocument, var data:any=payload).get"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpTestAnalysisDocument/src/mcpTestAnalysisDocument/report_client.py"},"region":{"startLine":67,"startColumn":9,"endLine":67,"endColumn":54,"snippet":{}}}},"id":"write_document \\n[report_client.py : 42_74]->syslib_from.logging.getLogger(__name__).exception","sourceNodeId":"write_document \\n[report_client.py : 42_74]","targetNodeId":"syslib_from.logging.getLogger(__name__).exception"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpTestAnalysisDocument/src/mcpTestAnalysisDocument/report_client.py"},"region":{"startLine":68,"startColumn":54,"endLine":68,"endColumn":62,"snippet":{}}}},"id":"write_document \\n[report_client.py : 42_74]->/src/mcpTestAnalysisDocument/src/mcpTestAnalysisDocument/report_client.write_document.write_document_scope...str","sourceNodeId":"write_document \\n[report_client.py : 42_74]","targetNodeId":"/src/mcpTestAnalysisDocument/src/mcpTestAnalysisDocument/report_client.write_document.write_document_scope...str"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpTestAnalysisDocument/src/mcpTestAnalysisDocument/report_client.py"},"region":{"startLine":72,"startColumn":13,"endLine":72,"endColumn":53,"snippet":{}}}},"id":"write_document \\n[report_client.py : 42_74]->mcp_common.request.http_client.AsyncRestClient(var base_url:any=https://instemc.alipay.com/yuque, var default_headers:any=_headers()).__aexit__","sourceNodeId":"write_document \\n[report_client.py : 42_74]","targetNodeId":"mcp_common.request.http_client.AsyncRestClient(var base_url:any=https://instemc.alipay.com/yuque, var default_headers:any=_headers()).__aexit__"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpTestAnalysisDocument/src/mcpTestAnalysisDocument/report_client.py"},"region":{"startLine":74,"startColumn":12,"endLine":74,"endColumn":28,"snippet":{}}}},"id":"write_document \\n[report_client.py : 42_74]->Result :: to_dict \\n[report_client.py : 32_37]","sourceNodeId":"write_document \\n[report_client.py : 42_74]","targetNodeId":"Result :: to_dict \\n[report_client.py : 32_37]"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpTestAnalysisDocument/src/mcpTestAnalysisDocument/report_client.py"},"region":{"startLine":84,"startColumn":15,"endLine":84,"endColumn":65,"snippet":{}}}},"id":"main \\n[report_client.py : 80_84]->syslib_from.json.dumps","sourceNodeId":"main \\n[report_client.py : 80_84]","targetNodeId":"syslib_from.json.dumps"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpTestAnalysisDocument/src/mcpTestAnalysisDocument/report_client.py"},"region":{"startLine":84,"startColumn":9,"endLine":84,"endColumn":66,"snippet":{}}}},"id":"main \\n[report_client.py : 80_84]->/src/mcpTestAnalysisDocument/src/mcpTestAnalysisDocument/report_client..main.main_scope..print","sourceNodeId":"main \\n[report_client.py : 80_84]","targetNodeId":"/src/mcpTestAnalysisDocument/src/mcpTestAnalysisDocument/report_client..main.main_scope..print"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpTestAnalysisDocument/src/mcpTestAnalysisDocument/yuque_markdown.py"},"region":{"startLine":221,"startColumn":17,"endLine":221,"endColumn":23,"snippet":{}}}},"id":"<__entry_point__>->main \\n[yuque_markdown.py : 215_219]","sourceNodeId":"<__entry_point__>","targetNodeId":"main \\n[yuque_markdown.py : 215_219]"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpTestAnalysisDocument/src/mcpTestAnalysisDocument/yuque_markdown.py"},"region":{"startLine":218,"startColumn":20,"endLine":218,"endColumn":67,"snippet":{}}}},"id":"main \\n[yuque_markdown.py : 215_219]->split_block_remain_pic_url \\n[yuque_markdown.py : 74_98]","sourceNodeId":"main \\n[yuque_markdown.py : 215_219]","targetNodeId":"split_block_remain_pic_url \\n[yuque_markdown.py : 74_98]"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpTestAnalysisDocument/src/mcpTestAnalysisDocument/yuque_markdown.py"},"region":{"startLine":75,"startColumn":14,"endLine":75,"endColumn":22,"snippet":{}}}},"id":"split_block_remain_pic_url \\n[yuque_markdown.py : 74_98]->Result :: __init__ \\n[yuque_markdown.py : 24_27]","sourceNodeId":"split_block_remain_pic_url \\n[yuque_markdown.py : 74_98]","targetNodeId":"Result :: __init__ \\n[yuque_markdown.py : 24_27]"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpTestAnalysisDocument/src/mcpTestAnalysisDocument/yuque_markdown.py"},"region":{"startLine":83,"startColumn":33,"endLine":83,"endColumn":43,"snippet":{}}}},"id":"split_block_remain_pic_url \\n[yuque_markdown.py : 74_98]->_headers \\n[yuque_markdown.py : 15_19]","sourceNodeId":"split_block_remain_pic_url \\n[yuque_markdown.py : 74_98]","targetNodeId":"_headers \\n[yuque_markdown.py : 15_19]"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpTestAnalysisDocument/src/mcpTestAnalysisDocument/yuque_markdown.py"},"region":{"startLine":81,"startColumn":20,"endLine":84,"endColumn":10,"snippet":{}}}},"id":"split_block_remain_pic_url \\n[yuque_markdown.py : 74_98]->mcp_common.request.http_client.AsyncRestClient","sourceNodeId":"split_block_remain_pic_url \\n[yuque_markdown.py : 74_98]","targetNodeId":"mcp_common.request.http_client.AsyncRestClient"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpTestAnalysisDocument/src/mcpTestAnalysisDocument/yuque_markdown.py"},"region":{"startLine":85,"startColumn":24,"endLine":85,"endColumn":91,"snippet":{}}}},"id":"split_block_remain_pic_url \\n[yuque_markdown.py : 74_98]->mcp_common.request.http_client.AsyncRestClient(var base_url:any=https://instemc.alipay.com/yuque, var default_headers:any=_headers()).post","sourceNodeId":"split_block_remain_pic_url \\n[yuque_markdown.py : 74_98]","targetNodeId":"mcp_common.request.http_client.AsyncRestClient(var base_url:any=https://instemc.alipay.com/yuque, var default_headers:any=_headers()).post"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpTestAnalysisDocument/src/mcpTestAnalysisDocument/yuque_markdown.py"},"region":{"startLine":92,"startColumn":30,"endLine":92,"endColumn":75,"snippet":{}}}},"id":"split_block_remain_pic_url \\n[yuque_markdown.py : 74_98]->mcp_common.request.http_client.AsyncRestClient(var base_url:any=https://instemc.alipay.com/yuque, var default_headers:any=_headers()).post(var endpoint:any=/splitBlockRemainPicUrl, var data:any=payloa...","sourceNodeId":"split_block_remain_pic_url \\n[yuque_markdown.py : 74_98]","targetNodeId":"mcp_common.request.http_client.AsyncRestClient(var base_url:any=https://instemc.alipay.com/yuque, var default_headers:any=_headers()).post(var endpoint:any=/splitBlockRemainPicUrl, var data:any=payloa..."},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpTestAnalysisDocument/src/mcpTestAnalysisDocument/yuque_markdown.py"},"region":{"startLine":96,"startColumn":63,"endLine":96,"endColumn":71,"snippet":{}}}},"id":"split_block_remain_pic_url \\n[yuque_markdown.py : 74_98]->/src/mcpTestAnalysisDocument/src/mcpTestAnalysisDocument/yuque_markdown.split_block_remain_pic_url.split_block_remain_pic_url_scope...str","sourceNodeId":"split_block_remain_pic_url \\n[yuque_markdown.py : 74_98]","targetNodeId":"/src/mcpTestAnalysisDocument/src/mcpTestAnalysisDocument/yuque_markdown.split_block_remain_pic_url.split_block_remain_pic_url_scope...str"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpTestAnalysisDocument/src/mcpTestAnalysisDocument/yuque_markdown.py"},"region":{"startLine":95,"startColumn":9,"endLine":95,"endColumn":73,"snippet":{}}}},"id":"split_block_remain_pic_url \\n[yuque_markdown.py : 74_98]->syslib_from.logging.getLogger(__name__).exception","sourceNodeId":"split_block_remain_pic_url \\n[yuque_markdown.py : 74_98]","targetNodeId":"syslib_from.logging.getLogger(__name__).exception"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpTestAnalysisDocument/src/mcpTestAnalysisDocument/yuque_markdown.py"},"region":{"startLine":98,"startColumn":12,"endLine":98,"endColumn":28,"snippet":{}}}},"id":"split_block_remain_pic_url \\n[yuque_markdown.py : 74_98]->Result :: to_dict \\n[yuque_markdown.py : 29_34]","sourceNodeId":"split_block_remain_pic_url \\n[yuque_markdown.py : 74_98]","targetNodeId":"Result :: to_dict \\n[yuque_markdown.py : 29_34]"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpTestAnalysisDocument/src/mcpTestAnalysisDocument/yuque_markdown.py"},"region":{"startLine":219,"startColumn":15,"endLine":219,"endColumn":65,"snippet":{}}}},"id":"main \\n[yuque_markdown.py : 215_219]->syslib_from.json.dumps","sourceNodeId":"main \\n[yuque_markdown.py : 215_219]","targetNodeId":"syslib_from.json.dumps"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpTestAnalysisDocument/src/mcpTestAnalysisDocument/yuque_markdown.py"},"region":{"startLine":219,"startColumn":9,"endLine":219,"endColumn":66,"snippet":{}}}},"id":"main \\n[yuque_markdown.py : 215_219]->/src/mcpTestAnalysisDocument/src/mcpTestAnalysisDocument/yuque_markdown..main.main_scope..print","sourceNodeId":"main \\n[yuque_markdown.py : 215_219]","targetNodeId":"/src/mcpTestAnalysisDocument/src/mcpTestAnalysisDocument/yuque_markdown..main.main_scope..print"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpTvp/src/mcpTvp/__init__.py"},"region":{"startLine":4,"startColumn":5,"endLine":4,"endColumn":29,"snippet":{}}}},"id":"main \\n[__init__.py : 3_4]->mcpTvp.server.mcp.run","sourceNodeId":"main \\n[__init__.py : 3_4]","targetNodeId":"mcpTvp.server.mcp.run"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpTvp/src/mcpTvp/tvp_client.py"},"region":{"startLine":186,"startColumn":23,"endLine":186,"endColumn":52,"snippet":{}}}},"id":"<__entry_point__>->execute_cypress_script \\n[tvp_client.py : 21_39]","sourceNodeId":"<__entry_point__>","targetNodeId":"execute_cypress_script \\n[tvp_client.py : 21_39]"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpTvp/src/mcpTvp/tvp_client.py"},"region":{"startLine":30,"startColumn":23,"endLine":30,"endColumn":75,"snippet":{}}}},"id":"execute_cypress_script \\n[tvp_client.py : 21_39]->_execute_script \\n[tvp_client.py : 102_131]","sourceNodeId":"execute_cypress_script \\n[tvp_client.py : 21_39]","targetNodeId":"_execute_script \\n[tvp_client.py : 102_131]"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpTvp/src/mcpTvp/tvp_client.py"},"region":{"startLine":104,"startColumn":19,"endLine":104,"endColumn":41,"snippet":{}}}},"id":"_execute_script \\n[tvp_client.py : 102_131]->describe(\\'截图\\', function () {","sourceNodeId":"_execute_script \\n[tvp_client.py : 102_131]","targetNodeId":"describe(\\'截图\\', function () {"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpTvp/src/mcpTvp/tvp_client.py"},"region":{"startLine":110,"startColumn":18,"endLine":110,"endColumn":44,"snippet":{}}}},"id":"_execute_script \\n[tvp_client.py : 102_131]->syslib_from.base64.b64encode","sourceNodeId":"_execute_script \\n[tvp_client.py : 102_131]","targetNodeId":"syslib_from.base64.b64encode"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpTvp/src/mcpTvp/tvp_client.py"},"region":{"startLine":105,"startColumn":21,"endLine":105,"endColumn":66,"snippet":{}}}},"id":"_execute_script \\n[tvp_client.py : 102_131]->syslib_from.base64.b64encode(script_byte).decode","sourceNodeId":"_execute_script \\n[tvp_client.py : 102_131]","targetNodeId":"syslib_from.base64.b64encode(script_byte).decode"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpTvp/src/mcpTvp/tvp_client.py"},"region":{"startLine":108,"startColumn":16,"endLine":108,"endColumn":36,"snippet":{}}}},"id":"_execute_script \\n[tvp_client.py : 102_131]->syslib_from.json.dumps","sourceNodeId":"_execute_script \\n[tvp_client.py : 102_131]","targetNodeId":"syslib_from.json.dumps"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpTvp/src/mcpTvp/tvp_client.py"},"region":{"startLine":109,"startColumn":16,"endLine":109,"endColumn":40,"snippet":{}}}},"id":"_execute_script \\n[tvp_client.py : 102_131]->syslib_from.json.dumps(env_list).encode","sourceNodeId":"_execute_script \\n[tvp_client.py : 102_131]","targetNodeId":"syslib_from.json.dumps(env_list).encode"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpTvp/src/mcpTvp/tvp_client.py"},"region":{"startLine":110,"startColumn":18,"endLine":110,"endColumn":60,"snippet":{}}}},"id":"_execute_script \\n[tvp_client.py : 102_131]->syslib_from.base64.b64encode(env_byte).decode","sourceNodeId":"_execute_script \\n[tvp_client.py : 102_131]","targetNodeId":"syslib_from.base64.b64encode(env_byte).decode"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpTvp/src/mcpTvp/tvp_client.py"},"region":{"startLine":130,"startColumn":5,"endLine":130,"endColumn":94,"snippet":{}}}},"id":"_execute_script \\n[tvp_client.py : 102_131]->syslib_from.logging.getLogger(mcp-server).info","sourceNodeId":"_execute_script \\n[tvp_client.py : 102_131]","targetNodeId":"syslib_from.logging.getLogger(mcp-server).info"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpTvp/src/mcpTvp/tvp_client.py"},"region":{"startLine":121,"startColumn":20,"endLine":121,"endColumn":71,"snippet":{}}}},"id":"_execute_script \\n[tvp_client.py : 102_131]->syslib_from.requests.post","sourceNodeId":"_execute_script \\n[tvp_client.py : 102_131]","targetNodeId":"syslib_from.requests.post"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpTvp/src/mcpTvp/tvp_client.py"},"region":{"startLine":122,"startColumn":9,"endLine":122,"endColumn":36,"snippet":{}}}},"id":"_execute_script \\n[tvp_client.py : 102_131]->syslib_from.requests.post(url, var headers:any=TVP_HEADER, var json:any=params).raise_for_status","sourceNodeId":"_execute_script \\n[tvp_client.py : 102_131]","targetNodeId":"syslib_from.requests.post(url, var headers:any=TVP_HEADER, var json:any=params).raise_for_status"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpTvp/src/mcpTvp/tvp_client.py"},"region":{"startLine":123,"startColumn":18,"endLine":123,"endColumn":33,"snippet":{}}}},"id":"_execute_script \\n[tvp_client.py : 102_131]->syslib_from.requests.post(url, var headers:any=TVP_HEADER, var json:any=params).json","sourceNodeId":"_execute_script \\n[tvp_client.py : 102_131]","targetNodeId":"syslib_from.requests.post(url, var headers:any=TVP_HEADER, var json:any=params).json"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpTvp/src/mcpTvp/tvp_client.py"},"region":{"startLine":126,"startColumn":34,"endLine":126,"endColumn":52,"snippet":{}}}},"id":"_execute_script \\n[tvp_client.py : 102_131]->syslib_from.requests.post(url, var headers:any=TVP_HEADER, var json:any=params).json().get","sourceNodeId":"_execute_script \\n[tvp_client.py : 102_131]","targetNodeId":"syslib_from.requests.post(url, var headers:any=TVP_HEADER, var json:any=params).json().get"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpTvp/src/mcpTvp/tvp_client.py"},"region":{"startLine":32,"startColumn":13,"endLine":32,"endColumn":121,"snippet":{}}}},"id":"execute_cypress_script \\n[tvp_client.py : 21_39]->syslib_from.logging.getLogger(mcp-server).warning","sourceNodeId":"execute_cypress_script \\n[tvp_client.py : 21_39]","targetNodeId":"syslib_from.logging.getLogger(mcp-server).warning"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpTvp/src/mcpTvp/tvp_client.py"},"region":{"startLine":35,"startColumn":9,"endLine":35,"endColumn":99,"snippet":{}}}},"id":"execute_cypress_script \\n[tvp_client.py : 21_39]->syslib_from.logging.getLogger(mcp-server).info","sourceNodeId":"execute_cypress_script \\n[tvp_client.py : 21_39]","targetNodeId":"syslib_from.logging.getLogger(mcp-server).info"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpTvp/src/mcpTvp/tvp_client.py"},"region":{"startLine":38,"startColumn":9,"endLine":38,"endColumn":98,"snippet":{}}}},"id":"execute_cypress_script \\n[tvp_client.py : 21_39]->syslib_from.logging.getLogger(mcp-server).error","sourceNodeId":"execute_cypress_script \\n[tvp_client.py : 21_39]","targetNodeId":"syslib_from.logging.getLogger(mcp-server).error"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpTvp/src/mcpTvp/tvp_client.py"},"region":{"startLine":186,"startColumn":5,"endLine":186,"endColumn":54,"snippet":{}}}},"id":"<__entry_point__>->/src/mcpTvp/src/mcpTvp/tvp_client..print","sourceNodeId":"<__entry_point__>","targetNodeId":"/src/mcpTvp/src/mcpTvp/tvp_client..print"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpYuntu/src/mcpYuntu/server.py"},"region":{"startLine":288,"startColumn":23,"endLine":288,"endColumn":109,"snippet":{}}}},"id":"<__entry_point__>->/src/mcpYuntu/src/mcpYuntu/server..get_yuntu_call_tree","sourceNodeId":"<__entry_point__>","targetNodeId":"/src/mcpYuntu/src/mcpYuntu/server..get_yuntu_call_tree"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpYuntu/src/mcpYuntu/server.py"},"region":{"startLine":288,"startColumn":11,"endLine":288,"endColumn":110,"snippet":{}}}},"id":"<__entry_point__>->/src/mcpYuntu/src/mcpYuntu/server..asyncio.run","sourceNodeId":"<__entry_point__>","targetNodeId":"/src/mcpYuntu/src/mcpYuntu/server..asyncio.run"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpYuntu/src/mcpYuntu/server.py"},"region":{"startLine":290,"startColumn":5,"endLine":290,"endColumn":29,"snippet":{}}}},"id":"<__entry_point__>->/src/mcpYuntu/src/mcpYuntu/server..print","sourceNodeId":"<__entry_point__>","targetNodeId":"/src/mcpYuntu/src/mcpYuntu/server..print"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpYuntu/src/mcpYuntu/server.py"},"region":{"startLine":290,"startColumn":11,"endLine":290,"endColumn":28,"snippet":{}}}},"id":"<__entry_point__>->yuntu_util.sample_trace","sourceNodeId":"<__entry_point__>","targetNodeId":"yuntu_util.sample_trace"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpYuntu/src/mcpYuntu/yuntu_client.py"},"region":{"startLine":20,"startColumn":19,"endLine":20,"endColumn":44,"snippet":{}}}},"id":"<__entry_point__>->YUNTU_CONFIG.get","sourceNodeId":"<__entry_point__>","targetNodeId":"YUNTU_CONFIG.get"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpYuntu/src/mcpYuntu/yuntu_client.py"},"region":{"startLine":385,"startColumn":9,"endLine":387,"endColumn":78,"snippet":{}}}},"id":"<__entry_point__>->get_yuntu_call_key_message_by_service \\n[yuntu_client.py : 174_203]","sourceNodeId":"<__entry_point__>","targetNodeId":"get_yuntu_call_key_message_by_service \\n[yuntu_client.py : 174_203]"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpYuntu/src/mcpYuntu/yuntu_client.py"},"region":{"startLine":187,"startColumn":24,"endLine":187,"endColumn":84,"snippet":{}}}},"id":"get_yuntu_call_key_message_by_service \\n[yuntu_client.py : 174_203]->_get_complete_tree \\n[yuntu_client.py : 206_221]","sourceNodeId":"get_yuntu_call_key_message_by_service \\n[yuntu_client.py : 174_203]","targetNodeId":"_get_complete_tree \\n[yuntu_client.py : 206_221]"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpYuntu/src/mcpYuntu/yuntu_client.py"},"region":{"startLine":207,"startColumn":13,"endLine":207,"endColumn":38,"snippet":{}}}},"id":"_get_complete_tree \\n[yuntu_client.py : 206_221]->YUNTU_CONFIG.get","sourceNodeId":"_get_complete_tree \\n[yuntu_client.py : 206_221]","targetNodeId":"YUNTU_CONFIG.get"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpYuntu/src/mcpYuntu/yuntu_client.py"},"region":{"startLine":213,"startColumn":20,"endLine":213,"endColumn":88,"snippet":{}}}},"id":"_get_complete_tree \\n[yuntu_client.py : 206_221]->syslib_from.requests.get","sourceNodeId":"_get_complete_tree \\n[yuntu_client.py : 206_221]","targetNodeId":"syslib_from.requests.get"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpYuntu/src/mcpYuntu/yuntu_client.py"},"region":{"startLine":214,"startColumn":9,"endLine":214,"endColumn":36,"snippet":{}}}},"id":"_get_complete_tree \\n[yuntu_client.py : 206_221]->syslib_from.requests.get(url, var headers:any=YUNTU_HEADER, var params:any=params, var verify:any=false).raise_for_status","sourceNodeId":"_get_complete_tree \\n[yuntu_client.py : 206_221]","targetNodeId":"syslib_from.requests.get(url, var headers:any=YUNTU_HEADER, var params:any=params, var verify:any=false).raise_for_status"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpYuntu/src/mcpYuntu/yuntu_client.py"},"region":{"startLine":215,"startColumn":18,"endLine":215,"endColumn":33,"snippet":{}}}},"id":"_get_complete_tree \\n[yuntu_client.py : 206_221]->syslib_from.requests.get(url, var headers:any=YUNTU_HEADER, var params:any=params, var verify:any=false).json","sourceNodeId":"_get_complete_tree \\n[yuntu_client.py : 206_221]","targetNodeId":"syslib_from.requests.get(url, var headers:any=YUNTU_HEADER, var params:any=params, var verify:any=false).json"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpYuntu/src/mcpYuntu/yuntu_client.py"},"region":{"startLine":217,"startColumn":55,"endLine":217,"endColumn":75,"snippet":{}}}},"id":"_get_complete_tree \\n[yuntu_client.py : 206_221]->syslib_from.requests.get(url, var headers:any=YUNTU_HEADER, var params:any=params, var verify:any=false).json().get","sourceNodeId":"_get_complete_tree \\n[yuntu_client.py : 206_221]","targetNodeId":"syslib_from.requests.get(url, var headers:any=YUNTU_HEADER, var params:any=params, var verify:any=false).json().get"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpYuntu/src/mcpYuntu/yuntu_client.py"},"region":{"startLine":217,"startColumn":28,"endLine":217,"endColumn":76,"snippet":{}}}},"id":"_get_complete_tree \\n[yuntu_client.py : 206_221]->/src/mcpYuntu/src/mcpYuntu/yuntu_client.TraceResult.model_validate","sourceNodeId":"_get_complete_tree \\n[yuntu_client.py : 206_221]","targetNodeId":"/src/mcpYuntu/src/mcpYuntu/yuntu_client.TraceResult.model_validate"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpYuntu/src/mcpYuntu/yuntu_client.py"},"region":{"startLine":189,"startColumn":13,"endLine":189,"endColumn":132,"snippet":{}}}},"id":"get_yuntu_call_key_message_by_service \\n[yuntu_client.py : 174_203]->syslib_from.logging.getLogger(mcp-server).warning","sourceNodeId":"get_yuntu_call_key_message_by_service \\n[yuntu_client.py : 174_203]","targetNodeId":"syslib_from.logging.getLogger(mcp-server).warning"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpYuntu/src/mcpYuntu/yuntu_client.py"},"region":{"startLine":192,"startColumn":9,"endLine":193,"endColumn":77,"snippet":{}}}},"id":"get_yuntu_call_key_message_by_service \\n[yuntu_client.py : 174_203]->_collect_key_message_by_service \\n[yuntu_client.py : 291_304]","sourceNodeId":"get_yuntu_call_key_message_by_service \\n[yuntu_client.py : 174_203]","targetNodeId":"_collect_key_message_by_service \\n[yuntu_client.py : 291_304]"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpYuntu/src/mcpYuntu/yuntu_client.py"},"region":{"startLine":296,"startColumn":45,"endLine":296,"endColumn":65,"snippet":{}}}},"id":"_collect_key_message_by_service \\n[yuntu_client.py : 291_304]->com.alipay.mobilecashier.senior.service.facade.MobilecashierOrderFacade:1.0:escrowexprod.lower","sourceNodeId":"_collect_key_message_by_service \\n[yuntu_client.py : 291_304]","targetNodeId":"com.alipay.mobilecashier.senior.service.facade.MobilecashierOrderFacade:1.0:escrowexprod.lower"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpYuntu/src/mcpYuntu/yuntu_client.py"},"region":{"startLine":296,"startColumn":69,"endLine":296,"endColumn":93,"snippet":{}}}},"id":"_collect_key_message_by_service \\n[yuntu_client.py : 291_304]->/src/mcpYuntu/src/mcpYuntu/yuntu_client.TraceResult.model_validate(result.get(result)).traceInfo.serviceName.lower","sourceNodeId":"_collect_key_message_by_service \\n[yuntu_client.py : 291_304]","targetNodeId":"/src/mcpYuntu/src/mcpYuntu/yuntu_client.TraceResult.model_validate(result.get(result)).traceInfo.serviceName.lower"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpYuntu/src/mcpYuntu/yuntu_client.py"},"region":{"startLine":296,"startColumn":69,"endLine":296,"endColumn":93,"snippet":{}}}},"id":"_collect_key_message_by_service \\n[yuntu_client.py : 291_304]->....traceInfo.serviceName.lower","sourceNodeId":"_collect_key_message_by_service \\n[yuntu_client.py : 291_304]","targetNodeId":"....traceInfo.serviceName.lower"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpYuntu/src/mcpYuntu/yuntu_client.py"},"region":{"startLine":296,"startColumn":98,"endLine":296,"endColumn":117,"snippet":{}}}},"id":"_collect_key_message_by_service \\n[yuntu_client.py : 291_304]->checkAndPayOrder.lower","sourceNodeId":"_collect_key_message_by_service \\n[yuntu_client.py : 291_304]","targetNodeId":"checkAndPayOrder.lower"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpYuntu/src/mcpYuntu/yuntu_client.py"},"region":{"startLine":296,"startColumn":121,"endLine":296,"endColumn":144,"snippet":{}}}},"id":"_collect_key_message_by_service \\n[yuntu_client.py : 291_304]->/src/mcpYuntu/src/mcpYuntu/yuntu_client.TraceResult.model_validate(result.get(result)).traceInfo.methodName.lower","sourceNodeId":"_collect_key_message_by_service \\n[yuntu_client.py : 291_304]","targetNodeId":"/src/mcpYuntu/src/mcpYuntu/yuntu_client.TraceResult.model_validate(result.get(result)).traceInfo.methodName.lower"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpYuntu/src/mcpYuntu/yuntu_client.py"},"region":{"startLine":296,"startColumn":121,"endLine":296,"endColumn":144,"snippet":{}}}},"id":"_collect_key_message_by_service \\n[yuntu_client.py : 291_304]->....traceInfo.methodName.lower","sourceNodeId":"_collect_key_message_by_service \\n[yuntu_client.py : 291_304]","targetNodeId":"....traceInfo.methodName.lower"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpYuntu/src/mcpYuntu/yuntu_client.py"},"region":{"startLine":304,"startColumn":79,"endLine":304,"endColumn":98,"snippet":{}}}},"id":"_collect_key_message_by_service \\n[yuntu_client.py : 291_304]->current_path.copy","sourceNodeId":"_collect_key_message_by_service \\n[yuntu_client.py : 291_304]","targetNodeId":"current_path.copy"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpYuntu/src/mcpYuntu/yuntu_client.py"},"region":{"startLine":196,"startColumn":26,"endLine":196,"endColumn":79,"snippet":{}}}},"id":"get_yuntu_call_key_message_by_service \\n[yuntu_client.py : 174_203]->_find_subtree \\n[yuntu_client.py : 224_236]","sourceNodeId":"get_yuntu_call_key_message_by_service \\n[yuntu_client.py : 174_203]","targetNodeId":"_find_subtree \\n[yuntu_client.py : 224_236]"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpYuntu/src/mcpYuntu/yuntu_client.py"},"region":{"startLine":197,"startColumn":24,"endLine":197,"endColumn":50,"snippet":{}}}},"id":"get_yuntu_call_key_message_by_service \\n[yuntu_client.py : 174_203]->_collect_nodes \\n[yuntu_client.py : 265_278]","sourceNodeId":"get_yuntu_call_key_message_by_service \\n[yuntu_client.py : 174_203]","targetNodeId":"_collect_nodes \\n[yuntu_client.py : 265_278]"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpYuntu/src/mcpYuntu/yuntu_client.py"},"region":{"startLine":199,"startColumn":9,"endLine":199,"endColumn":118,"snippet":{}}}},"id":"get_yuntu_call_key_message_by_service \\n[yuntu_client.py : 174_203]->syslib_from.logging.getLogger(mcp-server).info","sourceNodeId":"get_yuntu_call_key_message_by_service \\n[yuntu_client.py : 174_203]","targetNodeId":"syslib_from.logging.getLogger(mcp-server).info"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpYuntu/src/mcpYuntu/yuntu_client.py"},"region":{"startLine":202,"startColumn":9,"endLine":202,"endColumn":108,"snippet":{}}}},"id":"get_yuntu_call_key_message_by_service \\n[yuntu_client.py : 174_203]->syslib_from.logging.getLogger(mcp-server).error","sourceNodeId":"get_yuntu_call_key_message_by_service \\n[yuntu_client.py : 174_203]","targetNodeId":"syslib_from.logging.getLogger(mcp-server).error"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpYuntu/src/mcpYuntu/yuntu_client.py"},"region":{"startLine":384,"startColumn":5,"endLine":387,"endColumn":80,"snippet":{}}}},"id":"<__entry_point__>->/src/mcpYuntu/src/mcpYuntu/yuntu_client..print","sourceNodeId":"<__entry_point__>","targetNodeId":"/src/mcpYuntu/src/mcpYuntu/yuntu_client..print"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpYuntu/src/tests/test_sample_yuntu.py"},"region":{"startLine":74,"startColumn":5,"endLine":74,"endColumn":11,"snippet":{}}}},"id":"<__entry_point__>->main \\n[test_sample_yuntu.py : 39_59]","sourceNodeId":"<__entry_point__>","targetNodeId":"main \\n[test_sample_yuntu.py : 39_59]"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpYuntu/src/tests/test_sample_yuntu.py"},"region":{"startLine":42,"startColumn":10,"endLine":42,"endColumn":59,"snippet":{}}}},"id":"main \\n[test_sample_yuntu.py : 39_59]->/src/mcpYuntu/src/tests/test_sample_yuntu.main.main_scope..open","sourceNodeId":"main \\n[test_sample_yuntu.py : 39_59]","targetNodeId":"/src/mcpYuntu/src/tests/test_sample_yuntu.main.main_scope..open"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpYuntu/src/tests/test_sample_yuntu.py"},"region":{"startLine":43,"startColumn":22,"endLine":43,"endColumn":30,"snippet":{}}}},"id":"main \\n[test_sample_yuntu.py : 39_59]->/src/mcpYuntu/src/tests/test_sample_yuntu.main.main_scope..open(resource/yuntu.txt, r, var encoding:any=UTF-8).read","sourceNodeId":"main \\n[test_sample_yuntu.py : 39_59]","targetNodeId":"/src/mcpYuntu/src/tests/test_sample_yuntu.main.main_scope..open(resource/yuntu.txt, r, var encoding:any=UTF-8).read"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpYuntu/src/tests/test_sample_yuntu.py"},"region":{"startLine":46,"startColumn":17,"endLine":46,"endColumn":39,"snippet":{}}}},"id":"main \\n[test_sample_yuntu.py : 39_59]->syslib_from.json.loads","sourceNodeId":"main \\n[test_sample_yuntu.py : 39_59]","targetNodeId":"syslib_from.json.loads"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpYuntu/src/tests/test_sample_yuntu.py"},"region":{"startLine":53,"startColumn":9,"endLine":53,"endColumn":38,"snippet":{}}}},"id":"main \\n[test_sample_yuntu.py : 39_59]->sample_trace \\n[test_sample_yuntu.py : 61_71]","sourceNodeId":"main \\n[test_sample_yuntu.py : 39_59]","targetNodeId":"sample_trace \\n[test_sample_yuntu.py : 61_71]"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpYuntu/src/tests/test_sample_yuntu.py"},"region":{"startLine":65,"startColumn":13,"endLine":65,"endColumn":38,"snippet":{}}}},"id":"sample_trace \\n[test_sample_yuntu.py : 61_71]->process_node \\n[test_sample_yuntu.py : 4_36]","sourceNodeId":"sample_trace \\n[test_sample_yuntu.py : 61_71]","targetNodeId":"process_node \\n[test_sample_yuntu.py : 4_36]"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpYuntu/src/tests/test_sample_yuntu.py"},"region":{"startLine":33,"startColumn":21,"endLine":33,"endColumn":40,"snippet":{}}}},"id":"process_node \\n[test_sample_yuntu.py : 4_36]->syslib_from.json.loads(input_json).traceInfo.children.get","sourceNodeId":"process_node \\n[test_sample_yuntu.py : 4_36]","targetNodeId":"syslib_from.json.loads(input_json).traceInfo.children.get"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpYuntu/src/tests/test_sample_yuntu.py"},"region":{"startLine":10,"startColumn":31,"endLine":10,"endColumn":65,"snippet":{}}}},"id":"process_node \\n[test_sample_yuntu.py : 4_36]->syslib_from.json.loads(input_json).traceInfo.children.get(serviceName).split","sourceNodeId":"process_node \\n[test_sample_yuntu.py : 4_36]","targetNodeId":"syslib_from.json.loads(input_json).traceInfo.children.get(serviceName).split"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpYuntu/src/tests/test_sample_yuntu.py"},"region":{"startLine":18,"startColumn":29,"endLine":18,"endColumn":50,"snippet":{}}}},"id":"process_node \\n[test_sample_yuntu.py : 4_36]->/src/mcpYuntu/src/tests/test_sample_yuntu.process_node.process_node_scope...len","sourceNodeId":"process_node \\n[test_sample_yuntu.py : 4_36]","targetNodeId":"/src/mcpYuntu/src/tests/test_sample_yuntu.process_node.process_node_scope...len"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpYuntu/src/tests/test_sample_yuntu.py"},"region":{"startLine":18,"startColumn":25,"endLine":18,"endColumn":57,"snippet":{}}}},"id":"process_node \\n[test_sample_yuntu.py : 4_36]->/src/mcpYuntu/src/tests/test_sample_yuntu.process_node.process_node_scope....int","sourceNodeId":"process_node \\n[test_sample_yuntu.py : 4_36]","targetNodeId":"/src/mcpYuntu/src/tests/test_sample_yuntu.process_node.process_node_scope....int"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpYuntu/src/tests/test_sample_yuntu.py"},"region":{"startLine":23,"startColumn":16,"endLine":23,"endColumn":32,"snippet":{}}}},"id":"process_node \\n[test_sample_yuntu.py : 4_36]->syslib_from.json.loads(input_json).traceInfo.children.pop","sourceNodeId":"process_node \\n[test_sample_yuntu.py : 4_36]","targetNodeId":"syslib_from.json.loads(input_json).traceInfo.children.pop"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpYuntu/src/tests/test_sample_yuntu.py"},"region":{"startLine":29,"startColumn":9,"endLine":29,"endColumn":37,"snippet":{}}}},"id":"process_node \\n[test_sample_yuntu.py : 4_36]->syslib_from.json.loads(input_json).traceInfo.children.pop(data).pop","sourceNodeId":"process_node \\n[test_sample_yuntu.py : 4_36]","targetNodeId":"syslib_from.json.loads(input_json).traceInfo.children.pop(data).pop"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpYuntu/src/tests/test_sample_yuntu.py"},"region":{"startLine":31,"startColumn":9,"endLine":31,"endColumn":26,"snippet":{}}}},"id":"process_node \\n[test_sample_yuntu.py : 4_36]->syslib_from.json.loads(input_json).traceInfo.children.update","sourceNodeId":"process_node \\n[test_sample_yuntu.py : 4_36]","targetNodeId":"syslib_from.json.loads(input_json).traceInfo.children.update"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpYuntu/src/tests/test_sample_yuntu.py"},"region":{"startLine":54,"startColumn":25,"endLine":54,"endColumn":66,"snippet":{}}}},"id":"main \\n[test_sample_yuntu.py : 39_59]->syslib_from.json.dumps","sourceNodeId":"main \\n[test_sample_yuntu.py : 39_59]","targetNodeId":"syslib_from.json.dumps"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpYuntu/src/tests/test_sample_yuntu.py"},"region":{"startLine":59,"startColumn":28,"endLine":59,"endColumn":43,"snippet":{}}}},"id":"main \\n[test_sample_yuntu.py : 39_59]->/src/mcpYuntu/src/tests/test_sample_yuntu.main.main_scope..len","sourceNodeId":"main \\n[test_sample_yuntu.py : 39_59]","targetNodeId":"/src/mcpYuntu/src/tests/test_sample_yuntu.main.main_scope..len"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpYuntu/src/tests/test_sample_yuntu.py"},"region":{"startLine":59,"startColumn":9,"endLine":59,"endColumn":45,"snippet":{}}}},"id":"main \\n[test_sample_yuntu.py : 39_59]->/src/mcpYuntu/src/tests/test_sample_yuntu.main.main_scope..print","sourceNodeId":"main \\n[test_sample_yuntu.py : 39_59]","targetNodeId":"/src/mcpYuntu/src/tests/test_sample_yuntu.main.main_scope..print"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpyuque/src/mcpyuque/report_client.py"},"region":{"startLine":84,"startColumn":17,"endLine":84,"endColumn":23,"snippet":{}}}},"id":"<__entry_point__>->main \\n[report_client.py : 78_82]","sourceNodeId":"<__entry_point__>","targetNodeId":"main \\n[report_client.py : 78_82]"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpyuque/src/mcpyuque/report_client.py"},"region":{"startLine":79,"startColumn":20,"endLine":81,"endColumn":10,"snippet":{}}}},"id":"main \\n[report_client.py : 78_82]->write_document \\n[report_client.py : 40_72]","sourceNodeId":"main \\n[report_client.py : 78_82]","targetNodeId":"write_document \\n[report_client.py : 40_72]"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpyuque/src/mcpyuque/report_client.py"},"region":{"startLine":41,"startColumn":14,"endLine":41,"endColumn":22,"snippet":{}}}},"id":"write_document \\n[report_client.py : 40_72]->Result :: __init__ \\n[report_client.py : 25_28]","sourceNodeId":"write_document \\n[report_client.py : 40_72]","targetNodeId":"Result :: __init__ \\n[report_client.py : 25_28]"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpyuque/src/mcpyuque/report_client.py"},"region":{"startLine":51,"startColumn":33,"endLine":51,"endColumn":43,"snippet":{}}}},"id":"write_document \\n[report_client.py : 40_72]->_headers \\n[report_client.py : 16_20]","sourceNodeId":"write_document \\n[report_client.py : 40_72]","targetNodeId":"_headers \\n[report_client.py : 16_20]"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpyuque/src/mcpyuque/report_client.py"},"region":{"startLine":49,"startColumn":20,"endLine":52,"endColumn":10,"snippet":{}}}},"id":"write_document \\n[report_client.py : 40_72]->mcp_common.request.http_client.AsyncRestClient","sourceNodeId":"write_document \\n[report_client.py : 40_72]","targetNodeId":"mcp_common.request.http_client.AsyncRestClient"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpyuque/src/mcpyuque/report_client.py"},"region":{"startLine":54,"startColumn":24,"endLine":54,"endColumn":82,"snippet":{}}}},"id":"write_document \\n[report_client.py : 40_72]->mcp_common.request.http_client.AsyncRestClient(var base_url:any=https://instemc.alipay.com/yuque, var default_headers:any=_headers()).post","sourceNodeId":"write_document \\n[report_client.py : 40_72]","targetNodeId":"mcp_common.request.http_client.AsyncRestClient(var base_url:any=https://instemc.alipay.com/yuque, var default_headers:any=_headers()).post"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpyuque/src/mcpyuque/report_client.py"},"region":{"startLine":62,"startColumn":30,"endLine":62,"endColumn":72,"snippet":{}}}},"id":"write_document \\n[report_client.py : 40_72]->mcp_common.request.http_client.AsyncRestClient(var base_url:any=https://instemc.alipay.com/yuque, var default_headers:any=_headers()).post(var endpoint:any=/writeDocument, var data:any=payload).get","sourceNodeId":"write_document \\n[report_client.py : 40_72]","targetNodeId":"mcp_common.request.http_client.AsyncRestClient(var base_url:any=https://instemc.alipay.com/yuque, var default_headers:any=_headers()).post(var endpoint:any=/writeDocument, var data:any=payload).get"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpyuque/src/mcpyuque/report_client.py"},"region":{"startLine":65,"startColumn":9,"endLine":65,"endColumn":54,"snippet":{}}}},"id":"write_document \\n[report_client.py : 40_72]->syslib_from.logging.getLogger(__name__).exception","sourceNodeId":"write_document \\n[report_client.py : 40_72]","targetNodeId":"syslib_from.logging.getLogger(__name__).exception"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpyuque/src/mcpyuque/report_client.py"},"region":{"startLine":66,"startColumn":54,"endLine":66,"endColumn":62,"snippet":{}}}},"id":"write_document \\n[report_client.py : 40_72]->/src/mcpyuque/src/mcpyuque/report_client.write_document.write_document_scope...str","sourceNodeId":"write_document \\n[report_client.py : 40_72]","targetNodeId":"/src/mcpyuque/src/mcpyuque/report_client.write_document.write_document_scope...str"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpyuque/src/mcpyuque/report_client.py"},"region":{"startLine":70,"startColumn":13,"endLine":70,"endColumn":53,"snippet":{}}}},"id":"write_document \\n[report_client.py : 40_72]->mcp_common.request.http_client.AsyncRestClient(var base_url:any=https://instemc.alipay.com/yuque, var default_headers:any=_headers()).__aexit__","sourceNodeId":"write_document \\n[report_client.py : 40_72]","targetNodeId":"mcp_common.request.http_client.AsyncRestClient(var base_url:any=https://instemc.alipay.com/yuque, var default_headers:any=_headers()).__aexit__"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpyuque/src/mcpyuque/report_client.py"},"region":{"startLine":72,"startColumn":12,"endLine":72,"endColumn":28,"snippet":{}}}},"id":"write_document \\n[report_client.py : 40_72]->Result :: to_dict \\n[report_client.py : 30_35]","sourceNodeId":"write_document \\n[report_client.py : 40_72]","targetNodeId":"Result :: to_dict \\n[report_client.py : 30_35]"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpyuque/src/mcpyuque/report_client.py"},"region":{"startLine":82,"startColumn":15,"endLine":82,"endColumn":65,"snippet":{}}}},"id":"main \\n[report_client.py : 78_82]->syslib_from.json.dumps","sourceNodeId":"main \\n[report_client.py : 78_82]","targetNodeId":"syslib_from.json.dumps"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpyuque/src/mcpyuque/report_client.py"},"region":{"startLine":82,"startColumn":9,"endLine":82,"endColumn":66,"snippet":{}}}},"id":"main \\n[report_client.py : 78_82]->/src/mcpyuque/src/mcpyuque/report_client..main.main_scope..print","sourceNodeId":"main \\n[report_client.py : 78_82]","targetNodeId":"/src/mcpyuque/src/mcpyuque/report_client..main.main_scope..print"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpyuque/src/mcpyuque/yuque_markdown.py"},"region":{"startLine":112,"startColumn":17,"endLine":112,"endColumn":23,"snippet":{}}}},"id":"<__entry_point__>->main \\n[yuque_markdown.py : 106_110]","sourceNodeId":"<__entry_point__>","targetNodeId":"main \\n[yuque_markdown.py : 106_110]"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpyuque/src/mcpyuque/yuque_markdown.py"},"region":{"startLine":109,"startColumn":20,"endLine":109,"endColumn":67,"snippet":{}}}},"id":"main \\n[yuque_markdown.py : 106_110]->split_block_remain_pic_url \\n[yuque_markdown.py : 75_99]","sourceNodeId":"main \\n[yuque_markdown.py : 106_110]","targetNodeId":"split_block_remain_pic_url \\n[yuque_markdown.py : 75_99]"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpyuque/src/mcpyuque/yuque_markdown.py"},"region":{"startLine":76,"startColumn":14,"endLine":76,"endColumn":22,"snippet":{}}}},"id":"split_block_remain_pic_url \\n[yuque_markdown.py : 75_99]->Result :: __init__ \\n[yuque_markdown.py : 25_28]","sourceNodeId":"split_block_remain_pic_url \\n[yuque_markdown.py : 75_99]","targetNodeId":"Result :: __init__ \\n[yuque_markdown.py : 25_28]"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpyuque/src/mcpyuque/yuque_markdown.py"},"region":{"startLine":84,"startColumn":33,"endLine":84,"endColumn":43,"snippet":{}}}},"id":"split_block_remain_pic_url \\n[yuque_markdown.py : 75_99]->_headers \\n[yuque_markdown.py : 16_20]","sourceNodeId":"split_block_remain_pic_url \\n[yuque_markdown.py : 75_99]","targetNodeId":"_headers \\n[yuque_markdown.py : 16_20]"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpyuque/src/mcpyuque/yuque_markdown.py"},"region":{"startLine":82,"startColumn":20,"endLine":85,"endColumn":10,"snippet":{}}}},"id":"split_block_remain_pic_url \\n[yuque_markdown.py : 75_99]->mcp_common.request.http_client.AsyncRestClient","sourceNodeId":"split_block_remain_pic_url \\n[yuque_markdown.py : 75_99]","targetNodeId":"mcp_common.request.http_client.AsyncRestClient"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpyuque/src/mcpyuque/yuque_markdown.py"},"region":{"startLine":86,"startColumn":24,"endLine":86,"endColumn":91,"snippet":{}}}},"id":"split_block_remain_pic_url \\n[yuque_markdown.py : 75_99]->mcp_common.request.http_client.AsyncRestClient(var base_url:any=https://instemc.alipay.com/yuque, var default_headers:any=_headers()).post","sourceNodeId":"split_block_remain_pic_url \\n[yuque_markdown.py : 75_99]","targetNodeId":"mcp_common.request.http_client.AsyncRestClient(var base_url:any=https://instemc.alipay.com/yuque, var default_headers:any=_headers()).post"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpyuque/src/mcpyuque/yuque_markdown.py"},"region":{"startLine":93,"startColumn":30,"endLine":93,"endColumn":75,"snippet":{}}}},"id":"split_block_remain_pic_url \\n[yuque_markdown.py : 75_99]->mcp_common.request.http_client.AsyncRestClient(var base_url:any=https://instemc.alipay.com/yuque, var default_headers:any=_headers()).post(var endpoint:any=/splitBlockRemainPicUrl, var data:any=payloa...","sourceNodeId":"split_block_remain_pic_url \\n[yuque_markdown.py : 75_99]","targetNodeId":"mcp_common.request.http_client.AsyncRestClient(var base_url:any=https://instemc.alipay.com/yuque, var default_headers:any=_headers()).post(var endpoint:any=/splitBlockRemainPicUrl, var data:any=payloa..."},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpyuque/src/mcpyuque/yuque_markdown.py"},"region":{"startLine":97,"startColumn":63,"endLine":97,"endColumn":71,"snippet":{}}}},"id":"split_block_remain_pic_url \\n[yuque_markdown.py : 75_99]->/src/mcpyuque/src/mcpyuque/yuque_markdown.split_block_remain_pic_url.split_block_remain_pic_url_scope...str","sourceNodeId":"split_block_remain_pic_url \\n[yuque_markdown.py : 75_99]","targetNodeId":"/src/mcpyuque/src/mcpyuque/yuque_markdown.split_block_remain_pic_url.split_block_remain_pic_url_scope...str"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpyuque/src/mcpyuque/yuque_markdown.py"},"region":{"startLine":96,"startColumn":9,"endLine":96,"endColumn":73,"snippet":{}}}},"id":"split_block_remain_pic_url \\n[yuque_markdown.py : 75_99]->syslib_from.logging.getLogger(__name__).exception","sourceNodeId":"split_block_remain_pic_url \\n[yuque_markdown.py : 75_99]","targetNodeId":"syslib_from.logging.getLogger(__name__).exception"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpyuque/src/mcpyuque/yuque_markdown.py"},"region":{"startLine":99,"startColumn":12,"endLine":99,"endColumn":28,"snippet":{}}}},"id":"split_block_remain_pic_url \\n[yuque_markdown.py : 75_99]->Result :: to_dict \\n[yuque_markdown.py : 30_35]","sourceNodeId":"split_block_remain_pic_url \\n[yuque_markdown.py : 75_99]","targetNodeId":"Result :: to_dict \\n[yuque_markdown.py : 30_35]"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpyuque/src/mcpyuque/yuque_markdown.py"},"region":{"startLine":110,"startColumn":15,"endLine":110,"endColumn":65,"snippet":{}}}},"id":"main \\n[yuque_markdown.py : 106_110]->syslib_from.json.dumps","sourceNodeId":"main \\n[yuque_markdown.py : 106_110]","targetNodeId":"syslib_from.json.dumps"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpyuque/src/mcpyuque/yuque_markdown.py"},"region":{"startLine":110,"startColumn":9,"endLine":110,"endColumn":66,"snippet":{}}}},"id":"main \\n[yuque_markdown.py : 106_110]->/src/mcpyuque/src/mcpyuque/yuque_markdown..main.main_scope..print","sourceNodeId":"main \\n[yuque_markdown.py : 106_110]","targetNodeId":"/src/mcpyuque/src/mcpyuque/yuque_markdown..main.main_scope..print"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-common/src/mcp_common/remote/antnluservice.py"},"region":{"startLine":45,"startColumn":21,"endLine":45,"endColumn":39,"snippet":{}}}},"id":"<__entry_point__>->AntnluserviceAPI :: __init__ \\n[antnluservice.py : 19_20]","sourceNodeId":"<__entry_point__>","targetNodeId":"AntnluserviceAPI :: __init__ \\n[antnluservice.py : 19_20]"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-common/src/mcp_common/remote/codefuse_search.py"},"region":{"startLine":26,"startColumn":30,"endLine":26,"endColumn":92,"snippet":{}}}},"id":"<__entry_point__>->/src/mcp-common/src/mcp_common/remote/codefuse_search.SymbolLocation.Field","sourceNodeId":"<__entry_point__>","targetNodeId":"/src/mcp-common/src/mcp_common/remote/codefuse_search.SymbolLocation.Field"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-common/src/mcp_common/remote/codefuse_search.py"},"region":{"startLine":38,"startColumn":49,"endLine":38,"endColumn":126,"snippet":{}}}},"id":"<__entry_point__>->/src/mcp-common/src/mcp_common/remote/codefuse_search.Symbol.Field","sourceNodeId":"<__entry_point__>","targetNodeId":"/src/mcp-common/src/mcp_common/remote/codefuse_search.Symbol.Field"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-common/src/mcp_common/remote/codefuse_search.py"},"region":{"startLine":37,"startColumn":48,"endLine":37,"endColumn":64,"snippet":{}}}},"id":"<__entry_point__>->/src/mcp-common/src/mcp_common/remote/codefuse_search.SymbolLocation","sourceNodeId":"<__entry_point__>","targetNodeId":"/src/mcp-common/src/mcp_common/remote/codefuse_search.SymbolLocation"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-common/src/mcp_common/remote/codefuse_search.py"},"region":{"startLine":155,"startColumn":21,"endLine":155,"endColumn":38,"snippet":{}}}},"id":"<__entry_point__>->SymbolSearchAPI :: __init__ \\n[codefuse_search.py : 60_65]","sourceNodeId":"<__entry_point__>","targetNodeId":"SymbolSearchAPI :: __init__ \\n[codefuse_search.py : 60_65]"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-common/src/mcp_common/remote/codefuse_search.py"},"region":{"startLine":62,"startColumn":24,"endLine":65,"endColumn":10,"snippet":{}}}},"id":"SymbolSearchAPI :: __init__ \\n[codefuse_search.py : 60_65]->/src/mcp-common/src/mcp_common/remote/codefuse_search.SymbolSearchAPI._CTOR_.__init___scope..dict","sourceNodeId":"SymbolSearchAPI :: __init__ \\n[codefuse_search.py : 60_65]","targetNodeId":"/src/mcp-common/src/mcp_common/remote/codefuse_search.SymbolSearchAPI._CTOR_.__init___scope..dict"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-common/src/mcp_common/remote/codeinsight.py"},"region":{"startLine":248,"startColumn":20,"endLine":248,"endColumn":36,"snippet":{}}}},"id":"<__entry_point__>->CodeInsightAPI :: __init__ \\n[codeinsight.py : 26_31]","sourceNodeId":"<__entry_point__>","targetNodeId":"CodeInsightAPI :: __init__ \\n[codeinsight.py : 26_31]"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-common/src/mcp_common/remote/codeinsight.py"},"region":{"startLine":29,"startColumn":24,"endLine":31,"endColumn":10,"snippet":{}}}},"id":"CodeInsightAPI :: __init__ \\n[codeinsight.py : 26_31]->/src/mcp-common/src/mcp_common/remote/codeinsight.CodeInsightAPI._CTOR_.__init___scope..dict","sourceNodeId":"CodeInsightAPI :: __init__ \\n[codeinsight.py : 26_31]","targetNodeId":"/src/mcp-common/src/mcp_common/remote/codeinsight.CodeInsightAPI._CTOR_.__init___scope..dict"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-common/src/mcp_common/utils/crypto.py"},"region":{"startLine":104,"startColumn":15,"endLine":104,"endColumn":37,"snippet":{}}}},"id":"<__entry_point__>->encrypt \\n[crypto.py : 47_71]","sourceNodeId":"<__entry_point__>","targetNodeId":"encrypt \\n[crypto.py : 47_71]"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-common/src/mcp_common/utils/crypto.py"},"region":{"startLine":50,"startColumn":29,"endLine":50,"endColumn":54,"snippet":{}}}},"id":"encrypt \\n[crypto.py : 47_71]->syslib_from.os.path.abspath","sourceNodeId":"encrypt \\n[crypto.py : 47_71]","targetNodeId":"syslib_from.os.path.abspath"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-common/src/mcp_common/utils/crypto.py"},"region":{"startLine":52,"startColumn":23,"endLine":52,"endColumn":57,"snippet":{}}}},"id":"encrypt \\n[crypto.py : 47_71]->syslib_from.os.path.dirname","sourceNodeId":"encrypt \\n[crypto.py : 47_71]","targetNodeId":"syslib_from.os.path.dirname"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-common/src/mcp_common/utils/crypto.py"},"region":{"startLine":53,"startColumn":36,"endLine":53,"endColumn":79,"snippet":{}}}},"id":"encrypt \\n[crypto.py : 47_71]->syslib_from.os.path.join","sourceNodeId":"encrypt \\n[crypto.py : 47_71]","targetNodeId":"syslib_from.os.path.join"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-common/src/mcp_common/utils/crypto.py"},"region":{"startLine":53,"startColumn":31,"endLine":53,"endColumn":80,"snippet":{}}}},"id":"encrypt \\n[crypto.py : 47_71]->pathlib.Path","sourceNodeId":"encrypt \\n[crypto.py : 47_71]","targetNodeId":"pathlib.Path"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-common/src/mcp_common/utils/crypto.py"},"region":{"startLine":55,"startColumn":15,"endLine":55,"endColumn":46,"snippet":{}}}},"id":"encrypt \\n[crypto.py : 47_71]->/src/mcp-common/src/mcp_common/utils/crypto.encrypt.encrypt_scope..open","sourceNodeId":"encrypt \\n[crypto.py : 47_71]","targetNodeId":"/src/mcp-common/src/mcp_common/utils/crypto.encrypt.encrypt_scope..open"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-common/src/mcp_common/utils/crypto.py"},"region":{"startLine":56,"startColumn":24,"endLine":56,"endColumn":32,"snippet":{}}}},"id":"encrypt \\n[crypto.py : 47_71]->/src/mcp-common/src/mcp_common/utils/crypto.encrypt.encrypt_scope..open(public_key_pem_path, rb).read","sourceNodeId":"encrypt \\n[crypto.py : 47_71]","targetNodeId":"/src/mcp-common/src/mcp_common/utils/crypto.encrypt.encrypt_scope..open(public_key_pem_path, rb).read"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-common/src/mcp_common/utils/crypto.py"},"region":{"startLine":59,"startColumn":25,"endLine":59,"endColumn":42,"snippet":{}}}},"id":"encrypt \\n[crypto.py : 47_71]->cryptography.hazmat.backends.default_backend","sourceNodeId":"encrypt \\n[crypto.py : 47_71]","targetNodeId":"cryptography.hazmat.backends.default_backend"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-common/src/mcp_common/utils/crypto.py"},"region":{"startLine":57,"startColumn":35,"endLine":60,"endColumn":14,"snippet":{}}}},"id":"encrypt \\n[crypto.py : 47_71]->cryptography.hazmat.primitives.serialization.load_pem_public_key","sourceNodeId":"encrypt \\n[crypto.py : 47_71]","targetNodeId":"cryptography.hazmat.primitives.serialization.load_pem_public_key"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-common/src/mcp_common/utils/crypto.py"},"region":{"startLine":62,"startColumn":17,"endLine":62,"endColumn":33,"snippet":{}}}},"id":"encrypt \\n[crypto.py : 47_71]->hello world.encode","sourceNodeId":"encrypt \\n[crypto.py : 47_71]","targetNodeId":"hello world.encode"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-common/src/mcp_common/utils/crypto.py"},"region":{"startLine":65,"startColumn":31,"endLine":65,"endColumn":46,"snippet":{}}}},"id":"encrypt \\n[crypto.py : 47_71]->cryptography.hazmat.primitives.hashes.SHA256","sourceNodeId":"encrypt \\n[crypto.py : 47_71]","targetNodeId":"cryptography.hazmat.primitives.hashes.SHA256"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-common/src/mcp_common/utils/crypto.py"},"region":{"startLine":64,"startColumn":25,"endLine":64,"endColumn":64,"snippet":{}}}},"id":"encrypt \\n[crypto.py : 47_71]->cryptography.hazmat.primitives.asymmetric.padding.MGF1","sourceNodeId":"encrypt \\n[crypto.py : 47_71]","targetNodeId":"cryptography.hazmat.primitives.asymmetric.padding.MGF1"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-common/src/mcp_common/utils/crypto.py"},"region":{"startLine":63,"startColumn":17,"endLine":67,"endColumn":18,"snippet":{}}}},"id":"encrypt \\n[crypto.py : 47_71]->cryptography.hazmat.primitives.asymmetric.padding.OAEP","sourceNodeId":"encrypt \\n[crypto.py : 47_71]","targetNodeId":"cryptography.hazmat.primitives.asymmetric.padding.OAEP"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-common/src/mcp_common/utils/crypto.py"},"region":{"startLine":61,"startColumn":26,"endLine":68,"endColumn":14,"snippet":{}}}},"id":"encrypt \\n[crypto.py : 47_71]->cryptography.hazmat.primitives.serialization.load_pem_public_key(pem_data, var backend:any=default_backend()).encrypt","sourceNodeId":"encrypt \\n[crypto.py : 47_71]","targetNodeId":"cryptography.hazmat.primitives.serialization.load_pem_public_key(pem_data, var backend:any=default_backend()).encrypt"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-common/src/mcp_common/utils/crypto.py"},"region":{"startLine":69,"startColumn":20,"endLine":69,"endColumn":36,"snippet":{}}}},"id":"encrypt \\n[crypto.py : 47_71]->cryptography.hazmat.primitives.serialization.load_pem_public_key(pem_data, var backend:any=default_backend()).encrypt(message.encode(), padding.OAEP(var mgf:any=padding.MGF1(var algorithm:any=hashes.S...","sourceNodeId":"encrypt \\n[crypto.py : 47_71]","targetNodeId":"cryptography.hazmat.primitives.serialization.load_pem_public_key(pem_data, var backend:any=default_backend()).encrypt(message.encode(), padding.OAEP(var mgf:any=padding.MGF1(var algorithm:any=hashes.S..."},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-common/src/mcp_common/utils/crypto.py"},"region":{"startLine":105,"startColumn":5,"endLine":105,"endColumn":19,"snippet":{}}}},"id":"<__entry_point__>->/src/mcp-common/src/mcp_common/utils/crypto..print","sourceNodeId":"<__entry_point__>","targetNodeId":"/src/mcp-common/src/mcp_common/utils/crypto..print"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-common/src/mcp_common/utils/code_config.py"},"region":{"startLine":69,"startColumn":16,"endLine":69,"endColumn":28,"snippet":{}}}},"id":"<__entry_point__>->CodeConfig :: __init__ \\n[code_config.py : 30_48]","sourceNodeId":"<__entry_point__>","targetNodeId":"CodeConfig :: __init__ \\n[code_config.py : 30_48]"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-common/src/mcp_common/utils/code_config.py"},"region":{"startLine":31,"startColumn":29,"endLine":31,"endColumn":54,"snippet":{}}}},"id":"CodeConfig :: __init__ \\n[code_config.py : 30_48]->syslib_from.os.path.abspath","sourceNodeId":"CodeConfig :: __init__ \\n[code_config.py : 30_48]","targetNodeId":"syslib_from.os.path.abspath"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-common/src/mcp_common/utils/code_config.py"},"region":{"startLine":32,"startColumn":23,"endLine":32,"endColumn":57,"snippet":{}}}},"id":"CodeConfig :: __init__ \\n[code_config.py : 30_48]->syslib_from.os.path.dirname","sourceNodeId":"CodeConfig :: __init__ \\n[code_config.py : 30_48]","targetNodeId":"syslib_from.os.path.dirname"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-common/src/mcp_common/utils/code_config.py"},"region":{"startLine":33,"startColumn":33,"endLine":33,"endColumn":78,"snippet":{}}}},"id":"CodeConfig :: __init__ \\n[code_config.py : 30_48]->syslib_from.os.path.join","sourceNodeId":"CodeConfig :: __init__ \\n[code_config.py : 30_48]","targetNodeId":"syslib_from.os.path.join"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-common/src/mcp_common/utils/code_config.py"},"region":{"startLine":33,"startColumn":28,"endLine":33,"endColumn":79,"snippet":{}}}},"id":"CodeConfig :: __init__ \\n[code_config.py : 30_48]->pathlib.Path","sourceNodeId":"CodeConfig :: __init__ \\n[code_config.py : 30_48]","targetNodeId":"pathlib.Path"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-common/src/mcp_common/utils/code_config.py"},"region":{"startLine":35,"startColumn":14,"endLine":35,"endColumn":59,"snippet":{}}}},"id":"CodeConfig :: __init__ \\n[code_config.py : 30_48]->/src/mcp-common/src/mcp_common/utils/code_config.CodeConfig._CTOR_.__init___scope..open","sourceNodeId":"CodeConfig :: __init__ \\n[code_config.py : 30_48]","targetNodeId":"/src/mcp-common/src/mcp_common/utils/code_config.CodeConfig._CTOR_.__init___scope..open"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-common/src/mcp_common/utils/code_config.py"},"region":{"startLine":36,"startColumn":25,"endLine":36,"endColumn":42,"snippet":{}}}},"id":"CodeConfig :: __init__ \\n[code_config.py : 30_48]->syslib_from.yaml.safe_load","sourceNodeId":"CodeConfig :: __init__ \\n[code_config.py : 30_48]","targetNodeId":"syslib_from.yaml.safe_load"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-common/src/mcp_common/utils/code_config.py"},"region":{"startLine":39,"startColumn":59,"endLine":39,"endColumn":81,"snippet":{}}}},"id":"CodeConfig :: __init__ \\n[code_config.py : 30_48]->CodeConfig :: unfold \\n[code_config.py : 50_57]","sourceNodeId":"CodeConfig :: __init__ \\n[code_config.py : 30_48]","targetNodeId":"CodeConfig :: unfold \\n[code_config.py : 50_57]"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-common/src/mcp_common/utils/code_config.py"},"region":{"startLine":52,"startColumn":21,"endLine":52,"endColumn":33,"snippet":{}}}},"id":"CodeConfig :: unfold \\n[code_config.py : 50_57]->syslib_from.yaml.safe_load(f).items","sourceNodeId":"CodeConfig :: unfold \\n[code_config.py : 50_57]","targetNodeId":"syslib_from.yaml.safe_load(f).items"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-common/src/mcp_common/utils/code_config.py"},"region":{"startLine":53,"startColumn":16,"endLine":53,"endColumn":35,"snippet":{}}}},"id":"CodeConfig :: unfold \\n[code_config.py : 50_57]->/src/mcp-common/src/mcp_common/utils/code_config.CodeConfig.unfold.unfold_scope....isinstance","sourceNodeId":"CodeConfig :: unfold \\n[code_config.py : 50_57]","targetNodeId":"/src/mcp-common/src/mcp_common/utils/code_config.CodeConfig.unfold.unfold_scope....isinstance"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-common/src/mcp_common/utils/code_config.py"},"region":{"startLine":55,"startColumn":27,"endLine":55,"endColumn":46,"snippet":{}}}},"id":"CodeConfig :: unfold \\n[code_config.py : 50_57]->upper","sourceNodeId":"CodeConfig :: unfold \\n[code_config.py : 50_57]","targetNodeId":"upper"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-common/src/mcp_common/utils/code_config.py"},"region":{"startLine":39,"startColumn":22,"endLine":39,"endColumn":33,"snippet":{}}}},"id":"CodeConfig :: __init__ \\n[code_config.py : 30_48]->upper().upper","sourceNodeId":"CodeConfig :: __init__ \\n[code_config.py : 30_48]","targetNodeId":"upper().upper"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-common/src/mcp_common/utils/code_config.py"},"region":{"startLine":39,"startColumn":22,"endLine":39,"endColumn":33,"snippet":{}}}},"id":"CodeConfig :: __init__ \\n[code_config.py : 30_48]->sv.upper","sourceNodeId":"CodeConfig :: __init__ \\n[code_config.py : 30_48]","targetNodeId":"sv.upper"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-common/src/mcp_common/utils/code_config.py"},"region":{"startLine":39,"startColumn":22,"endLine":39,"endColumn":33,"snippet":{}}}},"id":"CodeConfig :: __init__ \\n[code_config.py : 30_48]->syslib_from.yaml.safe_load(f).items().upper","sourceNodeId":"CodeConfig :: __init__ \\n[code_config.py : 30_48]","targetNodeId":"syslib_from.yaml.safe_load(f).items().upper"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-common/src/mcp_common/utils/code_config.py"},"region":{"startLine":60,"startColumn":5,"endLine":66,"endColumn":27,"snippet":{}}}},"id":"CodeConfig :: __init__ \\n[code_config.py : 30_48]->CodeConfig :: decrypt \\n[code_config.py : 60_66]","sourceNodeId":"CodeConfig :: __init__ \\n[code_config.py : 30_48]","targetNodeId":"CodeConfig :: decrypt \\n[code_config.py : 60_66]"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-common/src/mcp_common/utils/code_config.py"},"region":{"startLine":62,"startColumn":21,"endLine":62,"endColumn":33,"snippet":{}}}},"id":"CodeConfig :: decrypt \\n[code_config.py : 60_66]->items","sourceNodeId":"CodeConfig :: decrypt \\n[code_config.py : 60_66]","targetNodeId":"items"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-common/src/mcp_common/utils/code_config.py"},"region":{"startLine":63,"startColumn":16,"endLine":63,"endColumn":34,"snippet":{}}}},"id":"CodeConfig :: decrypt \\n[code_config.py : 60_66]->/src/mcp-common/src/mcp_common/utils/code_config.CodeConfig.decrypt.decrypt_scope....isinstance","sourceNodeId":"CodeConfig :: decrypt \\n[code_config.py : 60_66]","targetNodeId":"/src/mcp-common/src/mcp_common/utils/code_config.CodeConfig.decrypt.decrypt_scope....isinstance"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-common/src/mcp_common/utils/code_config.py"},"region":{"startLine":63,"startColumn":39,"endLine":63,"endColumn":60,"snippet":{}}}},"id":"CodeConfig :: decrypt \\n[code_config.py : 60_66]->items().startswith","sourceNodeId":"CodeConfig :: decrypt \\n[code_config.py : 60_66]","targetNodeId":"items().startswith"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-common/src/mcp_common/utils/code_config.py"},"region":{"startLine":64,"startColumn":41,"endLine":64,"endColumn":63,"snippet":{}}}},"id":"CodeConfig :: decrypt \\n[code_config.py : 60_66]->items().replace","sourceNodeId":"CodeConfig :: decrypt \\n[code_config.py : 60_66]","targetNodeId":"items().replace"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-common/src/mcp_common/utils/code_config.py"},"region":{"startLine":64,"startColumn":26,"endLine":64,"endColumn":64,"snippet":{}}}},"id":"CodeConfig :: decrypt \\n[code_config.py : 60_66]->decrypt \\n[crypto.py : 75_99]","sourceNodeId":"CodeConfig :: decrypt \\n[code_config.py : 60_66]","targetNodeId":"decrypt \\n[crypto.py : 75_99]"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-common/src/mcp_common/utils/crypto.py"},"region":{"startLine":78,"startColumn":29,"endLine":78,"endColumn":54,"snippet":{}}}},"id":"decrypt \\n[crypto.py : 75_99]->syslib_from.os.path.abspath","sourceNodeId":"decrypt \\n[crypto.py : 75_99]","targetNodeId":"syslib_from.os.path.abspath"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-common/src/mcp_common/utils/crypto.py"},"region":{"startLine":80,"startColumn":23,"endLine":80,"endColumn":57,"snippet":{}}}},"id":"decrypt \\n[crypto.py : 75_99]->syslib_from.os.path.dirname","sourceNodeId":"decrypt \\n[crypto.py : 75_99]","targetNodeId":"syslib_from.os.path.dirname"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-common/src/mcp_common/utils/crypto.py"},"region":{"startLine":81,"startColumn":37,"endLine":81,"endColumn":81,"snippet":{}}}},"id":"decrypt \\n[crypto.py : 75_99]->syslib_from.os.path.join","sourceNodeId":"decrypt \\n[crypto.py : 75_99]","targetNodeId":"syslib_from.os.path.join"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-common/src/mcp_common/utils/crypto.py"},"region":{"startLine":81,"startColumn":32,"endLine":81,"endColumn":82,"snippet":{}}}},"id":"decrypt \\n[crypto.py : 75_99]->pathlib.Path","sourceNodeId":"decrypt \\n[crypto.py : 75_99]","targetNodeId":"pathlib.Path"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-common/src/mcp_common/utils/crypto.py"},"region":{"startLine":83,"startColumn":14,"endLine":83,"endColumn":46,"snippet":{}}}},"id":"decrypt \\n[crypto.py : 75_99]->/src/mcp-common/src/mcp_common/utils/crypto.decrypt.decrypt_scope..open","sourceNodeId":"decrypt \\n[crypto.py : 75_99]","targetNodeId":"/src/mcp-common/src/mcp_common/utils/crypto.decrypt.decrypt_scope..open"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-common/src/mcp_common/utils/crypto.py"},"region":{"startLine":84,"startColumn":24,"endLine":84,"endColumn":32,"snippet":{}}}},"id":"decrypt \\n[crypto.py : 75_99]->/src/mcp-common/src/mcp_common/utils/crypto.decrypt.decrypt_scope..open(private_key_pem_path, rb).read","sourceNodeId":"decrypt \\n[crypto.py : 75_99]","targetNodeId":"/src/mcp-common/src/mcp_common/utils/crypto.decrypt.decrypt_scope..open(private_key_pem_path, rb).read"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-common/src/mcp_common/utils/crypto.py"},"region":{"startLine":88,"startColumn":25,"endLine":88,"endColumn":42,"snippet":{}}}},"id":"decrypt \\n[crypto.py : 75_99]->cryptography.hazmat.backends.default_backend","sourceNodeId":"decrypt \\n[crypto.py : 75_99]","targetNodeId":"cryptography.hazmat.backends.default_backend"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-common/src/mcp_common/utils/crypto.py"},"region":{"startLine":85,"startColumn":36,"endLine":89,"endColumn":14,"snippet":{}}}},"id":"decrypt \\n[crypto.py : 75_99]->cryptography.hazmat.primitives.serialization.load_pem_private_key","sourceNodeId":"decrypt \\n[crypto.py : 75_99]","targetNodeId":"cryptography.hazmat.primitives.serialization.load_pem_private_key"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-common/src/mcp_common/utils/crypto.py"},"region":{"startLine":91,"startColumn":17,"endLine":91,"endColumn":42,"snippet":{}}}},"id":"decrypt \\n[crypto.py : 75_99]->/src/mcp-common/src/mcp_common/utils/crypto.decrypt.decrypt_scope..bytes.fromhex","sourceNodeId":"decrypt \\n[crypto.py : 75_99]","targetNodeId":"/src/mcp-common/src/mcp_common/utils/crypto.decrypt.decrypt_scope..bytes.fromhex"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-common/src/mcp_common/utils/crypto.py"},"region":{"startLine":94,"startColumn":31,"endLine":94,"endColumn":46,"snippet":{}}}},"id":"decrypt \\n[crypto.py : 75_99]->cryptography.hazmat.primitives.hashes.SHA256","sourceNodeId":"decrypt \\n[crypto.py : 75_99]","targetNodeId":"cryptography.hazmat.primitives.hashes.SHA256"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-common/src/mcp_common/utils/crypto.py"},"region":{"startLine":93,"startColumn":25,"endLine":93,"endColumn":64,"snippet":{}}}},"id":"decrypt \\n[crypto.py : 75_99]->cryptography.hazmat.primitives.asymmetric.padding.MGF1","sourceNodeId":"decrypt \\n[crypto.py : 75_99]","targetNodeId":"cryptography.hazmat.primitives.asymmetric.padding.MGF1"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-common/src/mcp_common/utils/crypto.py"},"region":{"startLine":92,"startColumn":17,"endLine":96,"endColumn":18,"snippet":{}}}},"id":"decrypt \\n[crypto.py : 75_99]->cryptography.hazmat.primitives.asymmetric.padding.OAEP","sourceNodeId":"decrypt \\n[crypto.py : 75_99]","targetNodeId":"cryptography.hazmat.primitives.asymmetric.padding.OAEP"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-common/src/mcp_common/utils/crypto.py"},"region":{"startLine":90,"startColumn":20,"endLine":97,"endColumn":14,"snippet":{}}}},"id":"decrypt \\n[crypto.py : 75_99]->cryptography.hazmat.primitives.serialization.load_pem_private_key(pem_data, var password:any=..., var backend:any=default_backend()).decrypt","sourceNodeId":"decrypt \\n[crypto.py : 75_99]","targetNodeId":"cryptography.hazmat.primitives.serialization.load_pem_private_key(pem_data, var password:any=..., var backend:any=default_backend()).decrypt"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-common/src/mcp_common/utils/crypto.py"},"region":{"startLine":90,"startColumn":20,"endLine":97,"endColumn":23,"snippet":{}}}},"id":"decrypt \\n[crypto.py : 75_99]->cryptography.hazmat.primitives.serialization.load_pem_private_key(pem_data, var password:any=..., var backend:any=default_backend()).decrypt(bytes.fromhex(ciphertext), padding.OAEP(var mgf:any=padding...","sourceNodeId":"decrypt \\n[crypto.py : 75_99]","targetNodeId":"cryptography.hazmat.primitives.serialization.load_pem_private_key(pem_data, var password:any=..., var backend:any=default_backend()).decrypt(bytes.fromhex(ciphertext), padding.OAEP(var mgf:any=padding..."},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-common/src/mcp_common/utils/code_config.py"},"region":{"startLine":40,"startColumn":22,"endLine":40,"endColumn":33,"snippet":{}}}},"id":"CodeConfig :: __init__ \\n[code_config.py : 30_48]->items().upper","sourceNodeId":"CodeConfig :: __init__ \\n[code_config.py : 30_48]","targetNodeId":"items().upper"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-common/src/mcp_common/utils/code_config.py"},"region":{"startLine":40,"startColumn":22,"endLine":40,"endColumn":33,"snippet":{}}}},"id":"CodeConfig :: __init__ \\n[code_config.py : 30_48]->cryptography.hazmat.primitives.serialization.load_pem_private_key(pem_data, var password:any=..., var backend:any=default_backend()).decrypt(bytes.fromhex(ciphertext), padding.OAEP(var mgf:any=padding...","sourceNodeId":"CodeConfig :: __init__ \\n[code_config.py : 30_48]","targetNodeId":"cryptography.hazmat.primitives.serialization.load_pem_private_key(pem_data, var password:any=..., var backend:any=default_backend()).decrypt(bytes.fromhex(ciphertext), padding.OAEP(var mgf:any=padding..."},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-common/src/mcp_common/utils/code_config.py"},"region":{"startLine":40,"startColumn":22,"endLine":40,"endColumn":33,"snippet":{}}}},"id":"CodeConfig :: __init__ \\n[code_config.py : 30_48]->....upper","sourceNodeId":"CodeConfig :: __init__ \\n[code_config.py : 30_48]","targetNodeId":"....upper"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-common/src/mcp_common/utils/code_config.py"},"region":{"startLine":42,"startColumn":78,"endLine":42,"endColumn":97,"snippet":{}}}},"id":"CodeConfig :: __init__ \\n[code_config.py : 30_48]->/src/mcp-common/src/mcp_common/utils/code_config.CodeConfig._CTOR_.__init___scope...dir","sourceNodeId":"CodeConfig :: __init__ \\n[code_config.py : 30_48]","targetNodeId":"/src/mcp-common/src/mcp_common/utils/code_config.CodeConfig._CTOR_.__init___scope...dir"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-common/src/mcp_common/utils/code_config.py"},"region":{"startLine":42,"startColumn":22,"endLine":42,"endColumn":98,"snippet":{}}}},"id":"CodeConfig :: __init__ \\n[code_config.py : 30_48]->/src/mcp-common/src/mcp_common/utils/code_config.CodeConfig._CTOR_.__init___scope...filter","sourceNodeId":"CodeConfig :: __init__ \\n[code_config.py : 30_48]","targetNodeId":"/src/mcp-common/src/mcp_common/utils/code_config.CodeConfig._CTOR_.__init___scope...filter"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-common/src/mcp_common/utils/code_config.py"},"region":{"startLine":42,"startColumn":22,"endLine":42,"endColumn":98,"snippet":{}}}},"id":"/src/mcp-common/src/mcp_common/utils/code_config.CodeConfig._CTOR_.__init___scope...filter->/src/mcp-common/src/mcp_common/utils/code_config.CodeConfig._CTOR_.__init___scope... \\n[code_config.py : 42_42]","sourceNodeId":"/src/mcp-common/src/mcp_common/utils/code_config.CodeConfig._CTOR_.__init___scope...filter","targetNodeId":"/src/mcp-common/src/mcp_common/utils/code_config.CodeConfig._CTOR_.__init___scope... \\n[code_config.py : 42_42]"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-common/src/mcp_common/utils/code_config.py"},"region":{"startLine":42,"startColumn":43,"endLine":42,"endColumn":60,"snippet":{}}}},"id":"/src/mcp-common/src/mcp_common/utils/code_config.CodeConfig._CTOR_.__init___scope... \\n[code_config.py : 42_42]->x.startswith","sourceNodeId":"/src/mcp-common/src/mcp_common/utils/code_config.CodeConfig._CTOR_.__init___scope... \\n[code_config.py : 42_42]","targetNodeId":"x.startswith"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-common/src/mcp_common/utils/code_config.py"},"region":{"startLine":42,"startColumn":65,"endLine":42,"endColumn":76,"snippet":{}}}},"id":"/src/mcp-common/src/mcp_common/utils/code_config.CodeConfig._CTOR_.__init___scope... \\n[code_config.py : 42_42]->x.isupper","sourceNodeId":"/src/mcp-common/src/mcp_common/utils/code_config.CodeConfig._CTOR_.__init___scope... \\n[code_config.py : 42_42]","targetNodeId":"x.isupper"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-common/src/mcp_common/utils/code_config.py"},"region":{"startLine":43,"startColumn":21,"endLine":43,"endColumn":47,"snippet":{}}}},"id":"CodeConfig :: __init__ \\n[code_config.py : 30_48]->get","sourceNodeId":"CodeConfig :: __init__ \\n[code_config.py : 30_48]","targetNodeId":"get"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-common/src/mcp_common/utils/code_config.py"},"region":{"startLine":45,"startColumn":25,"endLine":45,"endColumn":47,"snippet":{}}}},"id":"CodeConfig :: __init__ \\n[code_config.py : 30_48]->syslib_from.os.getenv","sourceNodeId":"CodeConfig :: __init__ \\n[code_config.py : 30_48]","targetNodeId":"syslib_from.os.getenv"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-common/src/mcp_common/utils/env_util.py"},"region":{"startLine":38,"startColumn":30,"endLine":38,"endColumn":73,"snippet":{}}}},"id":"<__entry_point__>->/src/mcp-common/src/mcp_common/utils/env_util.cachetools.TTLCache","sourceNodeId":"<__entry_point__>","targetNodeId":"/src/mcp-common/src/mcp_common/utils/env_util.cachetools.TTLCache"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-common/src/mcp_common/utils/env_util.py"},"region":{"startLine":38,"startColumn":6,"endLine":38,"endColumn":74,"snippet":{}}}},"id":"<__entry_point__>->/src/mcp-common/src/mcp_common/utils/env_util.cachetools.cached","sourceNodeId":"<__entry_point__>","targetNodeId":"/src/mcp-common/src/mcp_common/utils/env_util.cachetools.cached"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-common/src/mcp_common/utils/env_util.py"},"region":{"startLine":38,"startColumn":30,"endLine":38,"endColumn":73,"snippet":{}}}},"id":"<__entry_point__>->syslib_from.cachetools.TTLCache","sourceNodeId":"<__entry_point__>","targetNodeId":"syslib_from.cachetools.TTLCache"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-common/src/mcp_common/utils/env_util.py"},"region":{"startLine":38,"startColumn":6,"endLine":38,"endColumn":74,"snippet":{}}}},"id":"<__entry_point__>->syslib_from.cachetools.cached","sourceNodeId":"<__entry_point__>","targetNodeId":"syslib_from.cachetools.cached"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-common/src/mcp_common/utils/env_util.py"},"region":{"startLine":93,"startColumn":15,"endLine":93,"endColumn":24,"snippet":{}}}},"id":"<__entry_point__>->EnvUtil :: __init__ \\n[env_util.py : 25_28]","sourceNodeId":"<__entry_point__>","targetNodeId":"EnvUtil :: __init__ \\n[env_util.py : 25_28]"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-common/src/mcp_common/utils/logger.py"},"region":{"startLine":14,"startColumn":13,"endLine":14,"endColumn":86,"snippet":{}}}},"id":"<__entry_point__>->syslib_from.logging.Formatter","sourceNodeId":"<__entry_point__>","targetNodeId":"syslib_from.logging.Formatter"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-common/src/mcp_common/utils/mist_util.py"},"region":{"startLine":11,"startColumn":1,"endLine":11,"endColumn":20,"snippet":{}}}},"id":"<__entry_point__>->layotto_turbo.layotto.init_mist","sourceNodeId":"<__entry_point__>","targetNodeId":"layotto_turbo.layotto.init_mist"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-common/src/mcp_common/utils/mist_util.py"},"region":{"startLine":22,"startColumn":30,"endLine":22,"endColumn":49,"snippet":{}}}},"id":"<__entry_point__>->get_mist_secret \\n[mist_util.py : 13_18]","sourceNodeId":"<__entry_point__>","targetNodeId":"get_mist_secret \\n[mist_util.py : 13_18]"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-common/src/mcp_common/utils/mist_util.py"},"region":{"startLine":14,"startColumn":14,"endLine":14,"endColumn":47,"snippet":{}}}},"id":"get_mist_secret \\n[mist_util.py : 13_18]->layotto_turbo.layotto.get_secret_from_mist","sourceNodeId":"get_mist_secret \\n[mist_util.py : 13_18]","targetNodeId":"layotto_turbo.layotto.get_secret_from_mist"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-common/src/mcp_common/utils/mist_util.py"},"region":{"startLine":18,"startColumn":15,"endLine":18,"endColumn":69,"snippet":{}}}},"id":"get_mist_secret \\n[mist_util.py : 13_18]->/src/mcp-common/src/mcp_common/utils/mist_util.get_mist_secret.get_mist_secret_scope...ValueError","sourceNodeId":"get_mist_secret \\n[mist_util.py : 13_18]","targetNodeId":"/src/mcp-common/src/mcp_common/utils/mist_util.get_mist_secret.get_mist_secret_scope...ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-common/src/mcp_common/utils/mist_util.py"},"region":{"startLine":23,"startColumn":5,"endLine":23,"endColumn":40,"snippet":{}}}},"id":"<__entry_point__>->/src/mcp-common/src/mcp_common/utils/mist_util..print","sourceNodeId":"<__entry_point__>","targetNodeId":"/src/mcp-common/src/mcp_common/utils/mist_util..print"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-common/src/mcp_common/utils/oss_utils.py"},"region":{"startLine":15,"startColumn":28,"endLine":15,"endColumn":84,"snippet":{}}}},"id":"<__entry_point__>->mcp_common.utils.mist_util.get_mist_secret","sourceNodeId":"<__entry_point__>","targetNodeId":"mcp_common.utils.mist_util.get_mist_secret"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-common/src/mcp_common/utils/oss_utils.py"},"region":{"startLine":21,"startColumn":8,"endLine":21,"endColumn":43,"snippet":{}}}},"id":"<__entry_point__>->syslib_from.oss2.Auth","sourceNodeId":"<__entry_point__>","targetNodeId":"syslib_from.oss2.Auth"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-common/src/mcp_common/utils/oss_utils.py"},"region":{"startLine":22,"startColumn":10,"endLine":22,"endColumn":60,"snippet":{}}}},"id":"<__entry_point__>->syslib_from.oss2.Bucket","sourceNodeId":"<__entry_point__>","targetNodeId":"syslib_from.oss2.Bucket"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-common/src/mcp_common/utils/oss_utils.py"},"region":{"startLine":282,"startColumn":11,"endLine":282,"endColumn":44,"snippet":{}}}},"id":"<__entry_point__>->create_oss_path \\n[oss_utils.py : 244_245]","sourceNodeId":"<__entry_point__>","targetNodeId":"create_oss_path \\n[oss_utils.py : 244_245]"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcp-common/src/mcp_common/utils/oss_utils.py"},"region":{"startLine":282,"startColumn":5,"endLine":282,"endColumn":45,"snippet":{}}}},"id":"<__entry_point__>->/src/mcp-common/src/mcp_common/utils/oss_utils..print","sourceNodeId":"<__entry_point__>","targetNodeId":"/src/mcp-common/src/mcp_common/utils/oss_utils..print"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpAntlogs/src/mcpAntlogs/server.py"},"region":{"startLine":172,"startColumn":1,"endLine":202,"endColumn":54,"snippet":{}}}},"id":"<__entry_point__>->handle_call_tool \\n[server.py : 172_202]","sourceNodeId":"<__entry_point__>","targetNodeId":"handle_call_tool \\n[server.py : 172_202]"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpAntlogs/src/mcpAntlogs/server.py"},"region":{"startLine":180,"startColumn":66,"endLine":180,"endColumn":109,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 172_202]->syslib_from.json.dumps","sourceNodeId":"handle_call_tool \\n[server.py : 172_202]","targetNodeId":"syslib_from.json.dumps"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpAntlogs/src/mcpAntlogs/server.py"},"region":{"startLine":179,"startColumn":5,"endLine":180,"endColumn":111,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 172_202]->syslib_from.logging.getLogger(mcp-server).info","sourceNodeId":"handle_call_tool \\n[server.py : 172_202]","targetNodeId":"syslib_from.logging.getLogger(mcp-server).info"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpAntlogs/src/mcpAntlogs/server.py"},"region":{"startLine":184,"startColumn":23,"endLine":184,"endColumn":54,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 172_202]->/src/mcpAntlogs/src/mcpAntlogs/server.handle_call_tool.handle_call_tool_scope....ValueError","sourceNodeId":"handle_call_tool \\n[server.py : 172_202]","targetNodeId":"/src/mcpAntlogs/src/mcpAntlogs/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpAntlogs/src/mcpAntlogs/server.py"},"region":{"startLine":186,"startColumn":23,"endLine":186,"endColumn":62,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 172_202]->/src/mcpAntlogs/src/mcpAntlogs/server.handle_call_tool.handle_call_tool_scope....ValueError","sourceNodeId":"handle_call_tool \\n[server.py : 172_202]","targetNodeId":"/src/mcpAntlogs/src/mcpAntlogs/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpAntlogs/src/mcpAntlogs/server.py"},"region":{"startLine":188,"startColumn":23,"endLine":188,"endColumn":62,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 172_202]->/src/mcpAntlogs/src/mcpAntlogs/server.handle_call_tool.handle_call_tool_scope....ValueError","sourceNodeId":"handle_call_tool \\n[server.py : 172_202]","targetNodeId":"/src/mcpAntlogs/src/mcpAntlogs/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpAntlogs/src/mcpAntlogs/server.py"},"region":{"startLine":189,"startColumn":132,"endLine":189,"endColumn":155,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 172_202]->/src/mcpAntlogs/src/mcpAntlogs/server.handle_call_tool.arguments.get","sourceNodeId":"handle_call_tool \\n[server.py : 172_202]","targetNodeId":"/src/mcpAntlogs/src/mcpAntlogs/server.handle_call_tool.arguments.get"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpAntlogs/src/mcpAntlogs/server.py"},"region":{"startLine":189,"startColumn":27,"endLine":189,"endColumn":156,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 172_202]->query_app_trace_log \\n[server.py : 35_81]","sourceNodeId":"handle_call_tool \\n[server.py : 172_202]","targetNodeId":"query_app_trace_log \\n[server.py : 35_81]"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpAntlogs/src/mcpAntlogs/server.py"},"region":{"startLine":62,"startColumn":20,"endLine":62,"endColumn":65,"snippet":{}}}},"id":"query_app_trace_log \\n[server.py : 35_81]->syslib_from.json.dumps","sourceNodeId":"query_app_trace_log \\n[server.py : 35_81]","targetNodeId":"syslib_from.json.dumps"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpAntlogs/src/mcpAntlogs/server.py"},"region":{"startLine":65,"startColumn":9,"endLine":65,"endColumn":47,"snippet":{}}}},"id":"query_app_trace_log \\n[server.py : 35_81]->syslib_from.logging.info","sourceNodeId":"query_app_trace_log \\n[server.py : 35_81]","targetNodeId":"syslib_from.logging.info"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpAntlogs/src/mcpAntlogs/server.py"},"region":{"startLine":61,"startColumn":25,"endLine":61,"endColumn":43,"snippet":{}}}},"id":"query_app_trace_log \\n[server.py : 35_81]->query_raw \\n[server.py : 84_109]","sourceNodeId":"query_app_trace_log \\n[server.py : 35_81]","targetNodeId":"query_raw \\n[server.py : 84_109]"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpAntlogs/src/mcpAntlogs/server.py"},"region":{"startLine":88,"startColumn":25,"endLine":88,"endColumn":36,"snippet":{}}}},"id":"query_raw \\n[server.py : 84_109]->syslib_from.time.time","sourceNodeId":"query_raw \\n[server.py : 84_109]","targetNodeId":"syslib_from.time.time"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpAntlogs/src/mcpAntlogs/server.py"},"region":{"startLine":88,"startColumn":21,"endLine":88,"endColumn":37,"snippet":{}}}},"id":"query_raw \\n[server.py : 84_109]->/src/mcpAntlogs/src/mcpAntlogs/server.query_raw.query_raw_scope..int","sourceNodeId":"query_raw \\n[server.py : 84_109]","targetNodeId":"/src/mcpAntlogs/src/mcpAntlogs/server.query_raw.query_raw_scope..int"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpAntlogs/src/mcpAntlogs/server.py"},"region":{"startLine":89,"startColumn":24,"endLine":89,"endColumn":55,"snippet":{}}}},"id":"query_raw \\n[server.py : 84_109]->syslib_from.random.sample","sourceNodeId":"query_raw \\n[server.py : 84_109]","targetNodeId":"syslib_from.random.sample"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpAntlogs/src/mcpAntlogs/server.py"},"region":{"startLine":89,"startColumn":16,"endLine":89,"endColumn":56,"snippet":{}}}},"id":"query_raw \\n[server.py : 84_109]->join","sourceNodeId":"query_raw \\n[server.py : 84_109]","targetNodeId":"join"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpAntlogs/src/mcpAntlogs/server.py"},"region":{"startLine":102,"startColumn":29,"endLine":102,"endColumn":47,"snippet":{}}}},"id":"query_raw \\n[server.py : 84_109]->/src/mcpAntlogs/src/mcpAntlogs/server.query_raw.query_raw_scope..str","sourceNodeId":"query_raw \\n[server.py : 84_109]","targetNodeId":"/src/mcpAntlogs/src/mcpAntlogs/server.query_raw.query_raw_scope..str"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpAntlogs/src/mcpAntlogs/server.py"},"region":{"startLine":93,"startColumn":17,"endLine":93,"endColumn":46,"snippet":{}}}},"id":"query_raw \\n[server.py : 84_109]->syslib_from.base64.b64decode","sourceNodeId":"query_raw \\n[server.py : 84_109]","targetNodeId":"syslib_from.base64.b64decode"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpAntlogs/src/mcpAntlogs/server.py"},"region":{"startLine":94,"startColumn":17,"endLine":94,"endColumn":45,"snippet":{}}}},"id":"query_raw \\n[server.py : 84_109]->/src/mcpAntlogs/src/mcpAntlogs/server.query_raw.query_raw_scope..bytes","sourceNodeId":"query_raw \\n[server.py : 84_109]","targetNodeId":"/src/mcpAntlogs/src/mcpAntlogs/server.query_raw.query_raw_scope..bytes"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpAntlogs/src/mcpAntlogs/server.py"},"region":{"startLine":92,"startColumn":9,"endLine":96,"endColumn":10,"snippet":{}}}},"id":"query_raw \\n[server.py : 84_109]->syslib_from.hmac.new","sourceNodeId":"query_raw \\n[server.py : 84_109]","targetNodeId":"syslib_from.hmac.new"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpAntlogs/src/mcpAntlogs/server.py"},"region":{"startLine":92,"startColumn":9,"endLine":96,"endColumn":19,"snippet":{}}}},"id":"query_raw \\n[server.py : 84_109]->syslib_from.hmac.new(var key:any=base64.b64decode(_SECRET_KEY), var msg:any=bytes(msg, var encoding:any=utf-8), var digestmod:any=hashlib.sha256).digest","sourceNodeId":"query_raw \\n[server.py : 84_109]","targetNodeId":"syslib_from.hmac.new(var key:any=base64.b64decode(_SECRET_KEY), var msg:any=bytes(msg, var encoding:any=utf-8), var digestmod:any=hashlib.sha256).digest"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpAntlogs/src/mcpAntlogs/server.py"},"region":{"startLine":91,"startColumn":12,"endLine":97,"endColumn":6,"snippet":{}}}},"id":"query_raw \\n[server.py : 84_109]->syslib_from.base64.b64encode","sourceNodeId":"query_raw \\n[server.py : 84_109]","targetNodeId":"syslib_from.base64.b64encode"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpAntlogs/src/mcpAntlogs/server.py"},"region":{"startLine":107,"startColumn":5,"endLine":107,"endColumn":45,"snippet":{}}}},"id":"query_raw \\n[server.py : 84_109]->syslib_from.logging.info","sourceNodeId":"query_raw \\n[server.py : 84_109]","targetNodeId":"syslib_from.logging.info"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpAntlogs/src/mcpAntlogs/server.py"},"region":{"startLine":108,"startColumn":21,"endLine":108,"endColumn":93,"snippet":{}}}},"id":"query_raw \\n[server.py : 84_109]->syslib_from.requests.post","sourceNodeId":"query_raw \\n[server.py : 84_109]","targetNodeId":"syslib_from.requests.post"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpAntlogs/src/mcpAntlogs/server.py"},"region":{"startLine":108,"startColumn":21,"endLine":108,"endColumn":100,"snippet":{}}}},"id":"query_raw \\n[server.py : 84_109]->syslib_from.requests.post(_MAAS_URL, var headers:any=headers, var data:any=payload, var timeout:any=(5, 60)).json","sourceNodeId":"query_raw \\n[server.py : 84_109]","targetNodeId":"syslib_from.requests.post(_MAAS_URL, var headers:any=headers, var data:any=payload, var timeout:any=(5, 60)).json"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpAntlogs/src/mcpAntlogs/server.py"},"region":{"startLine":63,"startColumn":20,"endLine":63,"endColumn":65,"snippet":{}}}},"id":"query_app_trace_log \\n[server.py : 35_81]->syslib_from.re.sub","sourceNodeId":"query_app_trace_log \\n[server.py : 35_81]","targetNodeId":"syslib_from.re.sub"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpAntlogs/src/mcpAntlogs/server.py"},"region":{"startLine":64,"startColumn":16,"endLine":64,"endColumn":36,"snippet":{}}}},"id":"query_app_trace_log \\n[server.py : 35_81]->syslib_from.json.loads","sourceNodeId":"query_app_trace_log \\n[server.py : 35_81]","targetNodeId":"syslib_from.json.loads"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpAntlogs/src/mcpAntlogs/server.py"},"region":{"startLine":67,"startColumn":13,"endLine":67,"endColumn":101,"snippet":{}}}},"id":"query_app_trace_log \\n[server.py : 35_81]->syslib_from.logging.getLogger(mcp-server).warning","sourceNodeId":"query_app_trace_log \\n[server.py : 35_81]","targetNodeId":"syslib_from.logging.getLogger(mcp-server).warning"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpAntlogs/src/mcpAntlogs/server.py"},"region":{"startLine":76,"startColumn":42,"endLine":76,"endColumn":70,"snippet":{}}}},"id":"query_app_trace_log \\n[server.py : 35_81]->syslib_from.json.loads(resp_str).data.appDiffLogDatas.get","sourceNodeId":"query_app_trace_log \\n[server.py : 35_81]","targetNodeId":"syslib_from.json.loads(resp_str).data.appDiffLogDatas.get"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpAntlogs/src/mcpAntlogs/server.py"},"region":{"startLine":73,"startColumn":23,"endLine":73,"endColumn":70,"snippet":{}}}},"id":"query_app_trace_log \\n[server.py : 35_81]->syslib_from.json.loads(resp_str).data.appDiffLogDatas.get(errorLog, {}).get","sourceNodeId":"query_app_trace_log \\n[server.py : 35_81]","targetNodeId":"syslib_from.json.loads(resp_str).data.appDiffLogDatas.get(errorLog, {}).get"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpAntlogs/src/mcpAntlogs/server.py"},"region":{"startLine":75,"startColumn":16,"endLine":75,"endColumn":37,"snippet":{}}}},"id":"query_app_trace_log \\n[server.py : 35_81]->error_pattern_utils.is_error_log","sourceNodeId":"query_app_trace_log \\n[server.py : 35_81]","targetNodeId":"error_pattern_utils.is_error_log"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpAntlogs/src/mcpAntlogs/server.py"},"region":{"startLine":77,"startColumn":9,"endLine":77,"endColumn":107,"snippet":{}}}},"id":"query_app_trace_log \\n[server.py : 35_81]->syslib_from.logging.getLogger(mcp-server).info","sourceNodeId":"query_app_trace_log \\n[server.py : 35_81]","targetNodeId":"syslib_from.logging.getLogger(mcp-server).info"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpAntlogs/src/mcpAntlogs/server.py"},"region":{"startLine":80,"startColumn":9,"endLine":80,"endColumn":92,"snippet":{}}}},"id":"query_app_trace_log \\n[server.py : 35_81]->syslib_from.logging.getLogger(mcp-server).error","sourceNodeId":"query_app_trace_log \\n[server.py : 35_81]","targetNodeId":"syslib_from.logging.getLogger(mcp-server).error"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpAntlogs/src/mcpAntlogs/server.py"},"region":{"startLine":200,"startColumn":21,"endLine":200,"endColumn":69,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 172_202]->syslib_from.mcp/types.TextContent","sourceNodeId":"handle_call_tool \\n[server.py : 172_202]","targetNodeId":"syslib_from.mcp/types.TextContent"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpAntlogs/src/mcpAntlogs/server.py"},"region":{"startLine":193,"startColumn":23,"endLine":193,"endColumn":61,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 172_202]->/src/mcpAntlogs/src/mcpAntlogs/server.handle_call_tool.handle_call_tool_scope....ValueError","sourceNodeId":"handle_call_tool \\n[server.py : 172_202]","targetNodeId":"/src/mcpAntlogs/src/mcpAntlogs/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpAntlogs/src/mcpAntlogs/server.py"},"region":{"startLine":195,"startColumn":23,"endLine":195,"endColumn":62,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 172_202]->/src/mcpAntlogs/src/mcpAntlogs/server.handle_call_tool.handle_call_tool_scope....ValueError","sourceNodeId":"handle_call_tool \\n[server.py : 172_202]","targetNodeId":"/src/mcpAntlogs/src/mcpAntlogs/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpAntlogs/src/mcpAntlogs/server.py"},"region":{"startLine":197,"startColumn":23,"endLine":197,"endColumn":61,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 172_202]->/src/mcpAntlogs/src/mcpAntlogs/server.handle_call_tool.handle_call_tool_scope....ValueError","sourceNodeId":"handle_call_tool \\n[server.py : 172_202]","targetNodeId":"/src/mcpAntlogs/src/mcpAntlogs/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpAntlogs/src/mcpAntlogs/server.py"},"region":{"startLine":198,"startColumn":27,"endLine":199,"endColumn":82,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 172_202]->query_machine_log \\n[server.py : 112_130]","sourceNodeId":"handle_call_tool \\n[server.py : 172_202]","targetNodeId":"query_machine_log \\n[server.py : 112_130]"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpAntlogs/src/mcpAntlogs/server.py"},"region":{"startLine":124,"startColumn":20,"endLine":124,"endColumn":45,"snippet":{}}}},"id":"query_machine_log \\n[server.py : 112_130]->yuntu_cmd_util.execute_cmd","sourceNodeId":"query_machine_log \\n[server.py : 112_130]","targetNodeId":"yuntu_cmd_util.execute_cmd"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpAntlogs/src/mcpAntlogs/server.py"},"region":{"startLine":129,"startColumn":9,"endLine":129,"endColumn":82,"snippet":{}}}},"id":"query_machine_log \\n[server.py : 112_130]->syslib_from.logging.getLogger(mcp-server).error","sourceNodeId":"query_machine_log \\n[server.py : 112_130]","targetNodeId":"syslib_from.logging.getLogger(mcp-server).error"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpAntlogs/src/mcpAntlogs/server.py"},"region":{"startLine":130,"startColumn":38,"endLine":130,"endColumn":46,"snippet":{}}}},"id":"query_machine_log \\n[server.py : 112_130]->/src/mcpAntlogs/src/mcpAntlogs/server.query_machine_log.query_machine_log_scope...str","sourceNodeId":"query_machine_log \\n[server.py : 112_130]","targetNodeId":"/src/mcpAntlogs/src/mcpAntlogs/server.query_machine_log.query_machine_log_scope...str"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpAntlogs/src/mcpAntlogs/server.py"},"region":{"startLine":202,"startColumn":19,"endLine":202,"endColumn":54,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 172_202]->/src/mcpAntlogs/src/mcpAntlogs/server.handle_call_tool.handle_call_tool_scope...ValueError","sourceNodeId":"handle_call_tool \\n[server.py : 172_202]","targetNodeId":"/src/mcpAntlogs/src/mcpAntlogs/server.handle_call_tool.handle_call_tool_scope...ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpAntmonitor/src/mcpAntmonitor/server.py"},"region":{"startLine":115,"startColumn":1,"endLine":154,"endColumn":54,"snippet":{}}}},"id":"<__entry_point__>->handle_call_tool \\n[server.py : 115_154]","sourceNodeId":"<__entry_point__>","targetNodeId":"handle_call_tool \\n[server.py : 115_154]"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpAntmonitor/src/mcpAntmonitor/server.py"},"region":{"startLine":148,"startColumn":27,"endLine":148,"endColumn":65,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 115_154]->syslib_from.json.dumps","sourceNodeId":"handle_call_tool \\n[server.py : 115_154]","targetNodeId":"syslib_from.json.dumps"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpAntmonitor/src/mcpAntmonitor/server.py"},"region":{"startLine":122,"startColumn":5,"endLine":123,"endColumn":114,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 115_154]->syslib_from.logging.getLogger(__name__).info","sourceNodeId":"handle_call_tool \\n[server.py : 115_154]","targetNodeId":"syslib_from.logging.getLogger(__name__).info"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpAntmonitor/src/mcpAntmonitor/server.py"},"region":{"startLine":127,"startColumn":23,"endLine":127,"endColumn":62,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 115_154]->/src/mcpAntmonitor/src/mcpAntmonitor/server.handle_call_tool.handle_call_tool_scope....ValueError","sourceNodeId":"handle_call_tool \\n[server.py : 115_154]","targetNodeId":"/src/mcpAntmonitor/src/mcpAntmonitor/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpAntmonitor/src/mcpAntmonitor/server.py"},"region":{"startLine":129,"startColumn":23,"endLine":129,"endColumn":62,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 115_154]->/src/mcpAntmonitor/src/mcpAntmonitor/server.handle_call_tool.handle_call_tool_scope....ValueError","sourceNodeId":"handle_call_tool \\n[server.py : 115_154]","targetNodeId":"/src/mcpAntmonitor/src/mcpAntmonitor/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpAntmonitor/src/mcpAntmonitor/server.py"},"region":{"startLine":131,"startColumn":23,"endLine":131,"endColumn":61,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 115_154]->/src/mcpAntmonitor/src/mcpAntmonitor/server.handle_call_tool.handle_call_tool_scope....ValueError","sourceNodeId":"handle_call_tool \\n[server.py : 115_154]","targetNodeId":"/src/mcpAntmonitor/src/mcpAntmonitor/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpAntmonitor/src/mcpAntmonitor/server.py"},"region":{"startLine":133,"startColumn":23,"endLine":133,"endColumn":57,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 115_154]->/src/mcpAntmonitor/src/mcpAntmonitor/server.handle_call_tool.handle_call_tool_scope....ValueError","sourceNodeId":"handle_call_tool \\n[server.py : 115_154]","targetNodeId":"/src/mcpAntmonitor/src/mcpAntmonitor/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpAntmonitor/src/mcpAntmonitor/server.py"},"region":{"startLine":135,"startColumn":23,"endLine":135,"endColumn":64,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 115_154]->/src/mcpAntmonitor/src/mcpAntmonitor/server.handle_call_tool.handle_call_tool_scope....ValueError","sourceNodeId":"handle_call_tool \\n[server.py : 115_154]","targetNodeId":"/src/mcpAntmonitor/src/mcpAntmonitor/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpAntmonitor/src/mcpAntmonitor/server.py"},"region":{"startLine":137,"startColumn":23,"endLine":137,"endColumn":62,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 115_154]->/src/mcpAntmonitor/src/mcpAntmonitor/server.handle_call_tool.handle_call_tool_scope....ValueError","sourceNodeId":"handle_call_tool \\n[server.py : 115_154]","targetNodeId":"/src/mcpAntmonitor/src/mcpAntmonitor/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpAntmonitor/src/mcpAntmonitor/server.py"},"region":{"startLine":139,"startColumn":23,"endLine":139,"endColumn":57,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 115_154]->/src/mcpAntmonitor/src/mcpAntmonitor/server.handle_call_tool.handle_call_tool_scope....ValueError","sourceNodeId":"handle_call_tool \\n[server.py : 115_154]","targetNodeId":"/src/mcpAntmonitor/src/mcpAntmonitor/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpAntmonitor/src/mcpAntmonitor/server.py"},"region":{"startLine":147,"startColumn":66,"endLine":147,"endColumn":96,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 115_154]->/src/mcpAntmonitor/src/mcpAntmonitor/server.handle_call_tool.arguments.get","sourceNodeId":"handle_call_tool \\n[server.py : 115_154]","targetNodeId":"/src/mcpAntmonitor/src/mcpAntmonitor/server.handle_call_tool.arguments.get"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpAntmonitor/src/mcpAntmonitor/server.py"},"region":{"startLine":141,"startColumn":22,"endLine":147,"endColumn":97,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 115_154]->syslib_from.antmonitor_client.get_app_metric","sourceNodeId":"handle_call_tool \\n[server.py : 115_154]","targetNodeId":"syslib_from.antmonitor_client.get_app_metric"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpAntmonitor/src/mcpAntmonitor/server.py"},"region":{"startLine":152,"startColumn":21,"endLine":152,"endColumn":69,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 115_154]->syslib_from.mcp/types.TextContent","sourceNodeId":"handle_call_tool \\n[server.py : 115_154]","targetNodeId":"syslib_from.mcp/types.TextContent"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpAntmonitor/src/mcpAntmonitor/server.py"},"region":{"startLine":154,"startColumn":19,"endLine":154,"endColumn":54,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 115_154]->/src/mcpAntmonitor/src/mcpAntmonitor/server.handle_call_tool.handle_call_tool_scope...ValueError","sourceNodeId":"handle_call_tool \\n[server.py : 115_154]","targetNodeId":"/src/mcpAntmonitor/src/mcpAntmonitor/server.handle_call_tool.handle_call_tool_scope...ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpAntscheduler/src/mcpAntscheduler/server.py"},"region":{"startLine":61,"startColumn":1,"endLine":129,"endColumn":54,"snippet":{}}}},"id":"<__entry_point__>->handle_call_tool \\n[server.py : 61_129]","sourceNodeId":"<__entry_point__>","targetNodeId":"handle_call_tool \\n[server.py : 61_129]"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpAntscheduler/src/mcpAntscheduler/server.py"},"region":{"startLine":69,"startColumn":71,"endLine":69,"endColumn":114,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 61_129]->/src/mcpAntscheduler/src/mcpAntscheduler/server.handle_call_tool.handle_call_tool_scope..json.dumps","sourceNodeId":"handle_call_tool \\n[server.py : 61_129]","targetNodeId":"/src/mcpAntscheduler/src/mcpAntscheduler/server.handle_call_tool.handle_call_tool_scope..json.dumps"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpAntscheduler/src/mcpAntscheduler/server.py"},"region":{"startLine":68,"startColumn":5,"endLine":69,"endColumn":116,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 61_129]->/src/mcpAntscheduler/src/mcpAntscheduler/server.handle_call_tool.handle_call_tool_scope..info_logger.info","sourceNodeId":"handle_call_tool \\n[server.py : 61_129]","targetNodeId":"/src/mcpAntscheduler/src/mcpAntscheduler/server.handle_call_tool.handle_call_tool_scope..info_logger.info"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpAntscheduler/src/mcpAntscheduler/server.py"},"region":{"startLine":73,"startColumn":23,"endLine":73,"endColumn":53,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 61_129]->/src/mcpAntscheduler/src/mcpAntscheduler/server.handle_call_tool.handle_call_tool_scope....ValueError","sourceNodeId":"handle_call_tool \\n[server.py : 61_129]","targetNodeId":"/src/mcpAntscheduler/src/mcpAntscheduler/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpAntscheduler/src/mcpAntscheduler/server.py"},"region":{"startLine":75,"startColumn":23,"endLine":75,"endColumn":57,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 61_129]->/src/mcpAntscheduler/src/mcpAntscheduler/server.handle_call_tool.handle_call_tool_scope....ValueError","sourceNodeId":"handle_call_tool \\n[server.py : 61_129]","targetNodeId":"/src/mcpAntscheduler/src/mcpAntscheduler/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpAntscheduler/src/mcpAntscheduler/server.py"},"region":{"startLine":76,"startColumn":27,"endLine":76,"endColumn":74,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 61_129]->/src/mcpAntscheduler/src/mcpAntscheduler/server.handle_call_tool.handle_call_tool_scope...get_job_list_by_app","sourceNodeId":"handle_call_tool \\n[server.py : 61_129]","targetNodeId":"/src/mcpAntscheduler/src/mcpAntscheduler/server.handle_call_tool.handle_call_tool_scope...get_job_list_by_app"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpAntscheduler/src/mcpAntscheduler/server.py"},"region":{"startLine":127,"startColumn":25,"endLine":127,"endColumn":68,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 61_129]->syslib_from.mcp/types.TextContent","sourceNodeId":"handle_call_tool \\n[server.py : 61_129]","targetNodeId":"syslib_from.mcp/types.TextContent"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpAntscheduler/src/mcpAntscheduler/server.py"},"region":{"startLine":80,"startColumn":23,"endLine":80,"endColumn":53,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 61_129]->/src/mcpAntscheduler/src/mcpAntscheduler/server.handle_call_tool.handle_call_tool_scope....ValueError","sourceNodeId":"handle_call_tool \\n[server.py : 61_129]","targetNodeId":"/src/mcpAntscheduler/src/mcpAntscheduler/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpAntscheduler/src/mcpAntscheduler/server.py"},"region":{"startLine":82,"startColumn":23,"endLine":82,"endColumn":62,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 61_129]->/src/mcpAntscheduler/src/mcpAntscheduler/server.handle_call_tool.handle_call_tool_scope....ValueError","sourceNodeId":"handle_call_tool \\n[server.py : 61_129]","targetNodeId":"/src/mcpAntscheduler/src/mcpAntscheduler/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpAntscheduler/src/mcpAntscheduler/server.py"},"region":{"startLine":83,"startColumn":27,"endLine":85,"endColumn":91,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 61_129]->/src/mcpAntscheduler/src/mcpAntscheduler/server.handle_call_tool.handle_call_tool_scope...query_job_operation_record","sourceNodeId":"handle_call_tool \\n[server.py : 61_129]","targetNodeId":"/src/mcpAntscheduler/src/mcpAntscheduler/server.handle_call_tool.handle_call_tool_scope...query_job_operation_record"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpAntscheduler/src/mcpAntscheduler/server.py"},"region":{"startLine":90,"startColumn":27,"endLine":90,"endColumn":57,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 61_129]->/src/mcpAntscheduler/src/mcpAntscheduler/server.handle_call_tool.handle_call_tool_scope....ValueError","sourceNodeId":"handle_call_tool \\n[server.py : 61_129]","targetNodeId":"/src/mcpAntscheduler/src/mcpAntscheduler/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpAntscheduler/src/mcpAntscheduler/server.py"},"region":{"startLine":92,"startColumn":27,"endLine":92,"endColumn":61,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 61_129]->/src/mcpAntscheduler/src/mcpAntscheduler/server.handle_call_tool.handle_call_tool_scope....ValueError","sourceNodeId":"handle_call_tool \\n[server.py : 61_129]","targetNodeId":"/src/mcpAntscheduler/src/mcpAntscheduler/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpAntscheduler/src/mcpAntscheduler/server.py"},"region":{"startLine":94,"startColumn":31,"endLine":94,"endColumn":78,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 61_129]->/src/mcpAntscheduler/src/mcpAntscheduler/server.handle_call_tool.handle_call_tool_scope...get_job_list_by_app","sourceNodeId":"handle_call_tool \\n[server.py : 61_129]","targetNodeId":"/src/mcpAntscheduler/src/mcpAntscheduler/server.handle_call_tool.handle_call_tool_scope...get_job_list_by_app"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpAntscheduler/src/mcpAntscheduler/server.py"},"region":{"startLine":96,"startColumn":29,"endLine":96,"endColumn":52,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 61_129]->/src/mcpAntscheduler/src/mcpAntscheduler/server.handle_call_tool.handle_call_tool_scope..json.loads","sourceNodeId":"handle_call_tool \\n[server.py : 61_129]","targetNodeId":"/src/mcpAntscheduler/src/mcpAntscheduler/server.handle_call_tool.handle_call_tool_scope..json.loads"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpAntscheduler/src/mcpAntscheduler/server.py"},"region":{"startLine":100,"startColumn":50,"endLine":100,"endColumn":70,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 61_129]->/src/mcpAntscheduler/src/mcpAntscheduler/server.handle_call_tool.handle_call_tool_scope......len","sourceNodeId":"handle_call_tool \\n[server.py : 61_129]","targetNodeId":"/src/mcpAntscheduler/src/mcpAntscheduler/server.handle_call_tool.handle_call_tool_scope......len"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpAntscheduler/src/mcpAntscheduler/server.py"},"region":{"startLine":103,"startColumn":76,"endLine":103,"endColumn":99,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 61_129]->/src/mcpAntscheduler/src/mcpAntscheduler/server.handle_call_tool.handle_call_tool_scope..json.loads(result_text).get","sourceNodeId":"handle_call_tool \\n[server.py : 61_129]","targetNodeId":"/src/mcpAntscheduler/src/mcpAntscheduler/server.handle_call_tool.handle_call_tool_scope..json.loads(result_text).get"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpAntscheduler/src/mcpAntscheduler/server.py"},"region":{"startLine":103,"startColumn":38,"endLine":103,"endColumn":62,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 61_129]->/src/mcpAntscheduler/src/mcpAntscheduler/server.handle_call_tool.handle_call_tool_scope..json.loads(result_text).get(jobItems, {}).get","sourceNodeId":"handle_call_tool \\n[server.py : 61_129]","targetNodeId":"/src/mcpAntscheduler/src/mcpAntscheduler/server.handle_call_tool.handle_call_tool_scope..json.loads(result_text).get(jobItems, {}).get"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpAntscheduler/src/mcpAntscheduler/server.py"},"region":{"startLine":114,"startColumn":32,"endLine":114,"endColumn":107,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 61_129]->/src/mcpAntscheduler/src/mcpAntscheduler/server.handle_call_tool.handle_call_tool_scope...........,.join","sourceNodeId":"handle_call_tool \\n[server.py : 61_129]","targetNodeId":",.join"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpAntscheduler/src/mcpAntscheduler/server.py"},"region":{"startLine":108,"startColumn":48,"endLine":108,"endColumn":74,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 61_129]->get","sourceNodeId":"handle_call_tool \\n[server.py : 61_129]","targetNodeId":"get"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpAntscheduler/src/mcpAntscheduler/server.py"},"region":{"startLine":127,"startColumn":61,"endLine":127,"endColumn":67,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 61_129]->str","sourceNodeId":"handle_call_tool \\n[server.py : 61_129]","targetNodeId":"str"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpAntscheduler/src/mcpAntscheduler/server.py"},"region":{"startLine":129,"startColumn":19,"endLine":129,"endColumn":54,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 61_129]->/src/mcpAntscheduler/src/mcpAntscheduler/server.handle_call_tool.handle_call_tool_scope...ValueError","sourceNodeId":"handle_call_tool \\n[server.py : 61_129]","targetNodeId":"/src/mcpAntscheduler/src/mcpAntscheduler/server.handle_call_tool.handle_call_tool_scope...ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpCloudinc/src/mcpCloudinc/server.py"},"region":{"startLine":145,"startColumn":1,"endLine":218,"endColumn":54,"snippet":{}}}},"id":"<__entry_point__>->handle_call_tool \\n[server.py : 145_218]","sourceNodeId":"<__entry_point__>","targetNodeId":"handle_call_tool \\n[server.py : 145_218]"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpCloudinc/src/mcpCloudinc/server.py"},"region":{"startLine":153,"startColumn":67,"endLine":153,"endColumn":110,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 145_218]->syslib_from.json.dumps","sourceNodeId":"handle_call_tool \\n[server.py : 145_218]","targetNodeId":"syslib_from.json.dumps"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpCloudinc/src/mcpCloudinc/server.py"},"region":{"startLine":152,"startColumn":5,"endLine":153,"endColumn":112,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 145_218]->syslib_from.logging.getLogger(mcp-server).info","sourceNodeId":"handle_call_tool \\n[server.py : 145_218]","targetNodeId":"syslib_from.logging.getLogger(mcp-server).info"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpCloudinc/src/mcpCloudinc/server.py"},"region":{"startLine":157,"startColumn":23,"endLine":157,"endColumn":53,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 145_218]->/src/mcpCloudinc/src/mcpCloudinc/server.handle_call_tool.handle_call_tool_scope....ValueError","sourceNodeId":"handle_call_tool \\n[server.py : 145_218]","targetNodeId":"/src/mcpCloudinc/src/mcpCloudinc/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpCloudinc/src/mcpCloudinc/server.py"},"region":{"startLine":159,"startColumn":23,"endLine":159,"endColumn":61,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 145_218]->/src/mcpCloudinc/src/mcpCloudinc/server.handle_call_tool.handle_call_tool_scope....ValueError","sourceNodeId":"handle_call_tool \\n[server.py : 145_218]","targetNodeId":"/src/mcpCloudinc/src/mcpCloudinc/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpCloudinc/src/mcpCloudinc/server.py"},"region":{"startLine":160,"startColumn":27,"endLine":160,"endColumn":77,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 145_218]->get_domain_name_by_app \\n[server.py : 238_273]","sourceNodeId":"handle_call_tool \\n[server.py : 145_218]","targetNodeId":"get_domain_name_by_app \\n[server.py : 238_273]"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpCloudinc/src/mcpCloudinc/server.py"},"region":{"startLine":263,"startColumn":37,"endLine":263,"endColumn":63,"snippet":{}}}},"id":"get_domain_name_by_app \\n[server.py : 238_273]->get_dns_domain_by_app \\n[server.py : 240_261]","sourceNodeId":"get_domain_name_by_app \\n[server.py : 238_273]","targetNodeId":"get_dns_domain_by_app \\n[server.py : 240_261]"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpCloudinc/src/mcpCloudinc/server.py"},"region":{"startLine":241,"startColumn":22,"endLine":241,"endColumn":55,"snippet":{}}}},"id":"get_dns_domain_by_app \\n[server.py : 240_261]->CLOUDINC_DNS_URL_DICT.get","sourceNodeId":"get_dns_domain_by_app \\n[server.py : 240_261]","targetNodeId":"CLOUDINC_DNS_URL_DICT.get"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpCloudinc/src/mcpCloudinc/server.py"},"region":{"startLine":250,"startColumn":38,"endLine":250,"endColumn":55,"snippet":{}}}},"id":"get_dns_domain_by_app \\n[server.py : 240_261]->CLOUDINC_DNS_URL_DICT.get(prod).get","sourceNodeId":"get_dns_domain_by_app \\n[server.py : 240_261]","targetNodeId":"CLOUDINC_DNS_URL_DICT.get(prod).get"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpCloudinc/src/mcpCloudinc/server.py"},"region":{"startLine":250,"startColumn":24,"endLine":250,"endColumn":67,"snippet":{}}}},"id":"get_dns_domain_by_app \\n[server.py : 240_261]->syslib_from.requests.post","sourceNodeId":"get_dns_domain_by_app \\n[server.py : 240_261]","targetNodeId":"syslib_from.requests.post"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpCloudinc/src/mcpCloudinc/server.py"},"region":{"startLine":251,"startColumn":13,"endLine":251,"endColumn":40,"snippet":{}}}},"id":"get_dns_domain_by_app \\n[server.py : 240_261]->syslib_from.requests.post(config.get(url), var json:any=body).raise_for_status","sourceNodeId":"get_dns_domain_by_app \\n[server.py : 240_261]","targetNodeId":"syslib_from.requests.post(config.get(url), var json:any=body).raise_for_status"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpCloudinc/src/mcpCloudinc/server.py"},"region":{"startLine":252,"startColumn":22,"endLine":252,"endColumn":37,"snippet":{}}}},"id":"get_dns_domain_by_app \\n[server.py : 240_261]->syslib_from.requests.post(config.get(url), var json:any=body).json","sourceNodeId":"get_dns_domain_by_app \\n[server.py : 240_261]","targetNodeId":"syslib_from.requests.post(config.get(url), var json:any=body).json"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpCloudinc/src/mcpCloudinc/server.py"},"region":{"startLine":255,"startColumn":27,"endLine":255,"endColumn":45,"snippet":{}}}},"id":"get_dns_domain_by_app \\n[server.py : 240_261]->syslib_from.requests.post(config.get(url), var json:any=body).json().get","sourceNodeId":"get_dns_domain_by_app \\n[server.py : 240_261]","targetNodeId":"syslib_from.requests.post(config.get(url), var json:any=body).json().get"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpCloudinc/src/mcpCloudinc/server.py"},"region":{"startLine":254,"startColumn":17,"endLine":254,"endColumn":108,"snippet":{}}}},"id":"get_dns_domain_by_app \\n[server.py : 240_261]->syslib_from.logging.getLogger(mcp-server).info","sourceNodeId":"get_dns_domain_by_app \\n[server.py : 240_261]","targetNodeId":"syslib_from.logging.getLogger(mcp-server).info"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpCloudinc/src/mcpCloudinc/server.py"},"region":{"startLine":255,"startColumn":27,"endLine":255,"endColumn":60,"snippet":{}}}},"id":"get_dns_domain_by_app \\n[server.py : 240_261]->syslib_from.requests.post(config.get(url), var json:any=body).json().get(data).get","sourceNodeId":"get_dns_domain_by_app \\n[server.py : 240_261]","targetNodeId":"syslib_from.requests.post(config.get(url), var json:any=body).json().get(data).get"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpCloudinc/src/mcpCloudinc/server.py"},"region":{"startLine":258,"startColumn":40,"endLine":258,"endColumn":58,"snippet":{}}}},"id":"get_dns_domain_by_app \\n[server.py : 240_261]->syslib_from.requests.post(config.get(url), var json:any=body).json().get(data).get(domains).get","sourceNodeId":"get_dns_domain_by_app \\n[server.py : 240_261]","targetNodeId":"syslib_from.requests.post(config.get(url), var json:any=body).json().get(data).get(domains).get"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpCloudinc/src/mcpCloudinc/server.py"},"region":{"startLine":260,"startColumn":13,"endLine":260,"endColumn":117,"snippet":{}}}},"id":"get_dns_domain_by_app \\n[server.py : 240_261]->syslib_from.logging.getLogger(mcp-server).warning","sourceNodeId":"get_dns_domain_by_app \\n[server.py : 240_261]","targetNodeId":"syslib_from.logging.getLogger(mcp-server).warning"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpCloudinc/src/mcpCloudinc/server.py"},"region":{"startLine":264,"startColumn":17,"endLine":264,"endColumn":67,"snippet":{}}}},"id":"get_domain_name_by_app \\n[server.py : 238_273]->syslib_from.asyncio.create_task","sourceNodeId":"get_domain_name_by_app \\n[server.py : 238_273]","targetNodeId":"syslib_from.asyncio.create_task"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpCloudinc/src/mcpCloudinc/server.py"},"region":{"startLine":264,"startColumn":37,"endLine":264,"endColumn":66,"snippet":{}}}},"id":"get_domain_name_by_app \\n[server.py : 238_273]->get_antvip_detail_by_app \\n[server.py : 276_296]","sourceNodeId":"get_domain_name_by_app \\n[server.py : 238_273]","targetNodeId":"get_antvip_detail_by_app \\n[server.py : 276_296]"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpCloudinc/src/mcpCloudinc/server.py"},"region":{"startLine":285,"startColumn":16,"endLine":285,"endColumn":52,"snippet":{}}}},"id":"get_antvip_detail_by_app \\n[server.py : 276_296]->oneapi.cloudinc.AntvipDomainQueryFacade.AntvipDomainQueryFacade(layotto).queryByApp","sourceNodeId":"get_antvip_detail_by_app \\n[server.py : 276_296]","targetNodeId":"oneapi.cloudinc.AntvipDomainQueryFacade.AntvipDomainQueryFacade(layotto).queryByApp"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpCloudinc/src/mcpCloudinc/server.py"},"region":{"startLine":287,"startColumn":13,"endLine":287,"endColumn":97,"snippet":{}}}},"id":"get_antvip_detail_by_app \\n[server.py : 276_296]->syslib_from.logging.getLogger(mcp-server).info","sourceNodeId":"get_antvip_detail_by_app \\n[server.py : 276_296]","targetNodeId":"syslib_from.logging.getLogger(mcp-server).info"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpCloudinc/src/mcpCloudinc/server.py"},"region":{"startLine":290,"startColumn":28,"endLine":290,"endColumn":43,"snippet":{}}}},"id":"get_antvip_detail_by_app \\n[server.py : 276_296]->oneapi.cloudinc.AntvipDomainQueryFacade.AntvipDomainQueryFacade(layotto).queryByApp(var appName:any=app).data.target.get_json","sourceNodeId":"get_antvip_detail_by_app \\n[server.py : 276_296]","targetNodeId":"oneapi.cloudinc.AntvipDomainQueryFacade.AntvipDomainQueryFacade(layotto).queryByApp(var appName:any=app).data.target.get_json"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpCloudinc/src/mcpCloudinc/server.py"},"region":{"startLine":291,"startColumn":20,"endLine":291,"endColumn":55,"snippet":{}}}},"id":"get_antvip_detail_by_app \\n[server.py : 276_296]->syslib_from.json.dumps","sourceNodeId":"get_antvip_detail_by_app \\n[server.py : 276_296]","targetNodeId":"syslib_from.json.dumps"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpCloudinc/src/mcpCloudinc/server.py"},"region":{"startLine":292,"startColumn":9,"endLine":292,"endColumn":104,"snippet":{}}}},"id":"get_antvip_detail_by_app \\n[server.py : 276_296]->syslib_from.logging.getLogger(mcp-server).warning","sourceNodeId":"get_antvip_detail_by_app \\n[server.py : 276_296]","targetNodeId":"syslib_from.logging.getLogger(mcp-server).warning"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpCloudinc/src/mcpCloudinc/server.py"},"region":{"startLine":295,"startColumn":86,"endLine":295,"endColumn":94,"snippet":{}}}},"id":"get_antvip_detail_by_app \\n[server.py : 276_296]->/src/mcpCloudinc/src/mcpCloudinc/server.get_antvip_detail_by_app.get_antvip_detail_by_app_scope...str","sourceNodeId":"get_antvip_detail_by_app \\n[server.py : 276_296]","targetNodeId":"/src/mcpCloudinc/src/mcpCloudinc/server.get_antvip_detail_by_app.get_antvip_detail_by_app_scope...str"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpCloudinc/src/mcpCloudinc/server.py"},"region":{"startLine":295,"startColumn":9,"endLine":295,"endColumn":96,"snippet":{}}}},"id":"get_antvip_detail_by_app \\n[server.py : 276_296]->syslib_from.logging.getLogger(mcp-server).error","sourceNodeId":"get_antvip_detail_by_app \\n[server.py : 276_296]","targetNodeId":"syslib_from.logging.getLogger(mcp-server).error"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpCloudinc/src/mcpCloudinc/server.py"},"region":{"startLine":265,"startColumn":37,"endLine":265,"endColumn":71,"snippet":{}}}},"id":"get_domain_name_by_app \\n[server.py : 238_273]->syslib_from.asyncio.gather","sourceNodeId":"get_domain_name_by_app \\n[server.py : 238_273]","targetNodeId":"syslib_from.asyncio.gather"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpCloudinc/src/mcpCloudinc/server.py"},"region":{"startLine":267,"startColumn":25,"endLine":267,"endColumn":50,"snippet":{}}}},"id":"get_domain_name_by_app \\n[server.py : 238_273]->syslib_from.json.loads","sourceNodeId":"get_domain_name_by_app \\n[server.py : 238_273]","targetNodeId":"syslib_from.json.loads"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpCloudinc/src/mcpCloudinc/server.py"},"region":{"startLine":269,"startColumn":34,"endLine":269,"endColumn":50,"snippet":{}}}},"id":"get_domain_name_by_app \\n[server.py : 238_273]->syslib_from.json.loads(antvip_result).get","sourceNodeId":"get_domain_name_by_app \\n[server.py : 238_273]","targetNodeId":"syslib_from.json.loads(antvip_result).get"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpCloudinc/src/mcpCloudinc/server.py"},"region":{"startLine":269,"startColumn":13,"endLine":269,"endColumn":51,"snippet":{}}}},"id":"get_domain_name_by_app \\n[server.py : 238_273]->syslib_from.asyncio.gather(task1, task2).append","sourceNodeId":"get_domain_name_by_app \\n[server.py : 238_273]","targetNodeId":"syslib_from.asyncio.gather(task1, task2).append"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpCloudinc/src/mcpCloudinc/server.py"},"region":{"startLine":270,"startColumn":16,"endLine":270,"endColumn":61,"snippet":{}}}},"id":"get_domain_name_by_app \\n[server.py : 238_273]->syslib_from.json.dumps","sourceNodeId":"get_domain_name_by_app \\n[server.py : 238_273]","targetNodeId":"syslib_from.json.dumps"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpCloudinc/src/mcpCloudinc/server.py"},"region":{"startLine":272,"startColumn":91,"endLine":272,"endColumn":99,"snippet":{}}}},"id":"get_domain_name_by_app \\n[server.py : 238_273]->/src/mcpCloudinc/src/mcpCloudinc/server.get_domain_name_by_app.get_domain_name_by_app_scope...str","sourceNodeId":"get_domain_name_by_app \\n[server.py : 238_273]","targetNodeId":"/src/mcpCloudinc/src/mcpCloudinc/server.get_domain_name_by_app.get_domain_name_by_app_scope...str"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpCloudinc/src/mcpCloudinc/server.py"},"region":{"startLine":272,"startColumn":9,"endLine":272,"endColumn":101,"snippet":{}}}},"id":"get_domain_name_by_app \\n[server.py : 238_273]->syslib_from.logging.getLogger(mcp-server).error","sourceNodeId":"get_domain_name_by_app \\n[server.py : 238_273]","targetNodeId":"syslib_from.logging.getLogger(mcp-server).error"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpCloudinc/src/mcpCloudinc/server.py"},"region":{"startLine":216,"startColumn":21,"endLine":216,"endColumn":74,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 145_218]->syslib_from.mcp/types.TextContent","sourceNodeId":"handle_call_tool \\n[server.py : 145_218]","targetNodeId":"syslib_from.mcp/types.TextContent"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpCloudinc/src/mcpCloudinc/server.py"},"region":{"startLine":164,"startColumn":23,"endLine":164,"endColumn":53,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 145_218]->/src/mcpCloudinc/src/mcpCloudinc/server.handle_call_tool.handle_call_tool_scope....ValueError","sourceNodeId":"handle_call_tool \\n[server.py : 145_218]","targetNodeId":"/src/mcpCloudinc/src/mcpCloudinc/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpCloudinc/src/mcpCloudinc/server.py"},"region":{"startLine":166,"startColumn":23,"endLine":166,"endColumn":61,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 145_218]->/src/mcpCloudinc/src/mcpCloudinc/server.handle_call_tool.handle_call_tool_scope....ValueError","sourceNodeId":"handle_call_tool \\n[server.py : 145_218]","targetNodeId":"/src/mcpCloudinc/src/mcpCloudinc/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpCloudinc/src/mcpCloudinc/server.py"},"region":{"startLine":167,"startColumn":27,"endLine":167,"endColumn":79,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 145_218]->get_antvip_detail_by_app \\n[server.py : 276_296]","sourceNodeId":"handle_call_tool \\n[server.py : 145_218]","targetNodeId":"get_antvip_detail_by_app \\n[server.py : 276_296]"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpCloudinc/src/mcpCloudinc/server.py"},"region":{"startLine":171,"startColumn":23,"endLine":171,"endColumn":53,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 145_218]->/src/mcpCloudinc/src/mcpCloudinc/server.handle_call_tool.handle_call_tool_scope....ValueError","sourceNodeId":"handle_call_tool \\n[server.py : 145_218]","targetNodeId":"/src/mcpCloudinc/src/mcpCloudinc/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpCloudinc/src/mcpCloudinc/server.py"},"region":{"startLine":173,"startColumn":23,"endLine":173,"endColumn":61,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 145_218]->/src/mcpCloudinc/src/mcpCloudinc/server.handle_call_tool.handle_call_tool_scope....ValueError","sourceNodeId":"handle_call_tool \\n[server.py : 145_218]","targetNodeId":"/src/mcpCloudinc/src/mcpCloudinc/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpCloudinc/src/mcpCloudinc/server.py"},"region":{"startLine":175,"startColumn":23,"endLine":175,"endColumn":64,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 145_218]->/src/mcpCloudinc/src/mcpCloudinc/server.handle_call_tool.handle_call_tool_scope....ValueError","sourceNodeId":"handle_call_tool \\n[server.py : 145_218]","targetNodeId":"/src/mcpCloudinc/src/mcpCloudinc/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpCloudinc/src/mcpCloudinc/server.py"},"region":{"startLine":177,"startColumn":23,"endLine":177,"endColumn":68,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 145_218]->/src/mcpCloudinc/src/mcpCloudinc/server.handle_call_tool.handle_call_tool_scope....ValueError","sourceNodeId":"handle_call_tool \\n[server.py : 145_218]","targetNodeId":"/src/mcpCloudinc/src/mcpCloudinc/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpCloudinc/src/mcpCloudinc/server.py"},"region":{"startLine":178,"startColumn":27,"endLine":180,"endColumn":72,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 145_218]->get_domain_by_ips \\n[server.py : 299_330]","sourceNodeId":"handle_call_tool \\n[server.py : 145_218]","targetNodeId":"get_domain_by_ips \\n[server.py : 299_330]"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpCloudinc/src/mcpCloudinc/server.py"},"region":{"startLine":313,"startColumn":14,"endLine":313,"endColumn":43,"snippet":{}}}},"id":"get_domain_by_ips \\n[server.py : 299_330]->CLOUDINC_URL_DICT.get","sourceNodeId":"get_domain_by_ips \\n[server.py : 299_330]","targetNodeId":"CLOUDINC_URL_DICT.get"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpCloudinc/src/mcpCloudinc/server.py"},"region":{"startLine":313,"startColumn":14,"endLine":313,"endColumn":52,"snippet":{}}}},"id":"get_domain_by_ips \\n[server.py : 299_330]->CLOUDINC_URL_DICT.get(tenant).get","sourceNodeId":"get_domain_by_ips \\n[server.py : 299_330]","targetNodeId":"CLOUDINC_URL_DICT.get(tenant).get"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpCloudinc/src/mcpCloudinc/server.py"},"region":{"startLine":325,"startColumn":20,"endLine":325,"endColumn":72,"snippet":{}}}},"id":"get_domain_by_ips \\n[server.py : 299_330]->syslib_from.json.dumps","sourceNodeId":"get_domain_by_ips \\n[server.py : 299_330]","targetNodeId":"syslib_from.json.dumps"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpCloudinc/src/mcpCloudinc/server.py"},"region":{"startLine":320,"startColumn":20,"endLine":320,"endColumn":69,"snippet":{}}}},"id":"get_domain_by_ips \\n[server.py : 299_330]->syslib_from.requests.get","sourceNodeId":"get_domain_by_ips \\n[server.py : 299_330]","targetNodeId":"syslib_from.requests.get"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpCloudinc/src/mcpCloudinc/server.py"},"region":{"startLine":321,"startColumn":9,"endLine":321,"endColumn":36,"snippet":{}}}},"id":"get_domain_by_ips \\n[server.py : 299_330]->syslib_from.requests.get(url, var headers:any=headers, var params:any=params).raise_for_status","sourceNodeId":"get_domain_by_ips \\n[server.py : 299_330]","targetNodeId":"syslib_from.requests.get(url, var headers:any=headers, var params:any=params).raise_for_status"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpCloudinc/src/mcpCloudinc/server.py"},"region":{"startLine":322,"startColumn":18,"endLine":322,"endColumn":33,"snippet":{}}}},"id":"get_domain_by_ips \\n[server.py : 299_330]->syslib_from.requests.get(url, var headers:any=headers, var params:any=params).json","sourceNodeId":"get_domain_by_ips \\n[server.py : 299_330]","targetNodeId":"syslib_from.requests.get(url, var headers:any=headers, var params:any=params).json"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpCloudinc/src/mcpCloudinc/server.py"},"region":{"startLine":325,"startColumn":31,"endLine":325,"endColumn":51,"snippet":{}}}},"id":"get_domain_by_ips \\n[server.py : 299_330]->syslib_from.requests.get(url, var headers:any=headers, var params:any=params).json().get","sourceNodeId":"get_domain_by_ips \\n[server.py : 299_330]","targetNodeId":"syslib_from.requests.get(url, var headers:any=headers, var params:any=params).json().get"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpCloudinc/src/mcpCloudinc/server.py"},"region":{"startLine":324,"startColumn":13,"endLine":324,"endColumn":99,"snippet":{}}}},"id":"get_domain_by_ips \\n[server.py : 299_330]->syslib_from.logging.getLogger(mcp-server).info","sourceNodeId":"get_domain_by_ips \\n[server.py : 299_330]","targetNodeId":"syslib_from.logging.getLogger(mcp-server).info"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpCloudinc/src/mcpCloudinc/server.py"},"region":{"startLine":326,"startColumn":9,"endLine":326,"endColumn":110,"snippet":{}}}},"id":"get_domain_by_ips \\n[server.py : 299_330]->syslib_from.logging.getLogger(mcp-server).warning","sourceNodeId":"get_domain_by_ips \\n[server.py : 299_330]","targetNodeId":"syslib_from.logging.getLogger(mcp-server).warning"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpCloudinc/src/mcpCloudinc/server.py"},"region":{"startLine":329,"startColumn":86,"endLine":329,"endColumn":94,"snippet":{}}}},"id":"get_domain_by_ips \\n[server.py : 299_330]->/src/mcpCloudinc/src/mcpCloudinc/server.get_domain_by_ips.get_domain_by_ips_scope...str","sourceNodeId":"get_domain_by_ips \\n[server.py : 299_330]","targetNodeId":"/src/mcpCloudinc/src/mcpCloudinc/server.get_domain_by_ips.get_domain_by_ips_scope...str"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpCloudinc/src/mcpCloudinc/server.py"},"region":{"startLine":329,"startColumn":9,"endLine":329,"endColumn":96,"snippet":{}}}},"id":"get_domain_by_ips \\n[server.py : 299_330]->syslib_from.logging.getLogger(mcp-server).error","sourceNodeId":"get_domain_by_ips \\n[server.py : 299_330]","targetNodeId":"syslib_from.logging.getLogger(mcp-server).error"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpCloudinc/src/mcpCloudinc/server.py"},"region":{"startLine":184,"startColumn":23,"endLine":184,"endColumn":53,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 145_218]->/src/mcpCloudinc/src/mcpCloudinc/server.handle_call_tool.handle_call_tool_scope....ValueError","sourceNodeId":"handle_call_tool \\n[server.py : 145_218]","targetNodeId":"/src/mcpCloudinc/src/mcpCloudinc/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpCloudinc/src/mcpCloudinc/server.py"},"region":{"startLine":186,"startColumn":23,"endLine":186,"endColumn":69,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 145_218]->/src/mcpCloudinc/src/mcpCloudinc/server.handle_call_tool.handle_call_tool_scope....ValueError","sourceNodeId":"handle_call_tool \\n[server.py : 145_218]","targetNodeId":"/src/mcpCloudinc/src/mcpCloudinc/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpCloudinc/src/mcpCloudinc/server.py"},"region":{"startLine":188,"startColumn":23,"endLine":188,"endColumn":68,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 145_218]->/src/mcpCloudinc/src/mcpCloudinc/server.handle_call_tool.handle_call_tool_scope....ValueError","sourceNodeId":"handle_call_tool \\n[server.py : 145_218]","targetNodeId":"/src/mcpCloudinc/src/mcpCloudinc/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpCloudinc/src/mcpCloudinc/server.py"},"region":{"startLine":190,"startColumn":23,"endLine":190,"endColumn":64,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 145_218]->/src/mcpCloudinc/src/mcpCloudinc/server.handle_call_tool.handle_call_tool_scope....ValueError","sourceNodeId":"handle_call_tool \\n[server.py : 145_218]","targetNodeId":"/src/mcpCloudinc/src/mcpCloudinc/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpCloudinc/src/mcpCloudinc/server.py"},"region":{"startLine":192,"startColumn":23,"endLine":192,"endColumn":61,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 145_218]->/src/mcpCloudinc/src/mcpCloudinc/server.handle_call_tool.handle_call_tool_scope....ValueError","sourceNodeId":"handle_call_tool \\n[server.py : 145_218]","targetNodeId":"/src/mcpCloudinc/src/mcpCloudinc/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpCloudinc/src/mcpCloudinc/server.py"},"region":{"startLine":193,"startColumn":27,"endLine":196,"endColumn":72,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 145_218]->get_domain_detail \\n[server.py : 333_365]","sourceNodeId":"handle_call_tool \\n[server.py : 145_218]","targetNodeId":"get_domain_detail \\n[server.py : 333_365]"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpCloudinc/src/mcpCloudinc/server.py"},"region":{"startLine":348,"startColumn":14,"endLine":348,"endColumn":43,"snippet":{}}}},"id":"get_domain_detail \\n[server.py : 333_365]->CLOUDINC_URL_DICT.get","sourceNodeId":"get_domain_detail \\n[server.py : 333_365]","targetNodeId":"CLOUDINC_URL_DICT.get"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpCloudinc/src/mcpCloudinc/server.py"},"region":{"startLine":348,"startColumn":14,"endLine":348,"endColumn":52,"snippet":{}}}},"id":"get_domain_detail \\n[server.py : 333_365]->CLOUDINC_URL_DICT.get(tenant).get","sourceNodeId":"get_domain_detail \\n[server.py : 333_365]","targetNodeId":"CLOUDINC_URL_DICT.get(tenant).get"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpCloudinc/src/mcpCloudinc/server.py"},"region":{"startLine":360,"startColumn":20,"endLine":360,"endColumn":72,"snippet":{}}}},"id":"get_domain_detail \\n[server.py : 333_365]->syslib_from.json.dumps","sourceNodeId":"get_domain_detail \\n[server.py : 333_365]","targetNodeId":"syslib_from.json.dumps"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpCloudinc/src/mcpCloudinc/server.py"},"region":{"startLine":355,"startColumn":20,"endLine":355,"endColumn":69,"snippet":{}}}},"id":"get_domain_detail \\n[server.py : 333_365]->syslib_from.requests.get","sourceNodeId":"get_domain_detail \\n[server.py : 333_365]","targetNodeId":"syslib_from.requests.get"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpCloudinc/src/mcpCloudinc/server.py"},"region":{"startLine":356,"startColumn":9,"endLine":356,"endColumn":36,"snippet":{}}}},"id":"get_domain_detail \\n[server.py : 333_365]->syslib_from.requests.get(url, var headers:any=headers, var params:any=params).raise_for_status","sourceNodeId":"get_domain_detail \\n[server.py : 333_365]","targetNodeId":"syslib_from.requests.get(url, var headers:any=headers, var params:any=params).raise_for_status"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpCloudinc/src/mcpCloudinc/server.py"},"region":{"startLine":357,"startColumn":18,"endLine":357,"endColumn":33,"snippet":{}}}},"id":"get_domain_detail \\n[server.py : 333_365]->syslib_from.requests.get(url, var headers:any=headers, var params:any=params).json","sourceNodeId":"get_domain_detail \\n[server.py : 333_365]","targetNodeId":"syslib_from.requests.get(url, var headers:any=headers, var params:any=params).json"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpCloudinc/src/mcpCloudinc/server.py"},"region":{"startLine":360,"startColumn":31,"endLine":360,"endColumn":51,"snippet":{}}}},"id":"get_domain_detail \\n[server.py : 333_365]->syslib_from.requests.get(url, var headers:any=headers, var params:any=params).json().get","sourceNodeId":"get_domain_detail \\n[server.py : 333_365]","targetNodeId":"syslib_from.requests.get(url, var headers:any=headers, var params:any=params).json().get"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpCloudinc/src/mcpCloudinc/server.py"},"region":{"startLine":359,"startColumn":13,"endLine":359,"endColumn":99,"snippet":{}}}},"id":"get_domain_detail \\n[server.py : 333_365]->syslib_from.logging.getLogger(mcp-server).info","sourceNodeId":"get_domain_detail \\n[server.py : 333_365]","targetNodeId":"syslib_from.logging.getLogger(mcp-server).info"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpCloudinc/src/mcpCloudinc/server.py"},"region":{"startLine":361,"startColumn":9,"endLine":361,"endColumn":110,"snippet":{}}}},"id":"get_domain_detail \\n[server.py : 333_365]->syslib_from.logging.getLogger(mcp-server).warning","sourceNodeId":"get_domain_detail \\n[server.py : 333_365]","targetNodeId":"syslib_from.logging.getLogger(mcp-server).warning"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpCloudinc/src/mcpCloudinc/server.py"},"region":{"startLine":364,"startColumn":86,"endLine":364,"endColumn":94,"snippet":{}}}},"id":"get_domain_detail \\n[server.py : 333_365]->/src/mcpCloudinc/src/mcpCloudinc/server.get_domain_detail.get_domain_detail_scope...str","sourceNodeId":"get_domain_detail \\n[server.py : 333_365]","targetNodeId":"/src/mcpCloudinc/src/mcpCloudinc/server.get_domain_detail.get_domain_detail_scope...str"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpCloudinc/src/mcpCloudinc/server.py"},"region":{"startLine":364,"startColumn":9,"endLine":364,"endColumn":96,"snippet":{}}}},"id":"get_domain_detail \\n[server.py : 333_365]->syslib_from.logging.getLogger(mcp-server).error","sourceNodeId":"get_domain_detail \\n[server.py : 333_365]","targetNodeId":"syslib_from.logging.getLogger(mcp-server).error"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpCloudinc/src/mcpCloudinc/server.py"},"region":{"startLine":200,"startColumn":23,"endLine":200,"endColumn":53,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 145_218]->/src/mcpCloudinc/src/mcpCloudinc/server.handle_call_tool.handle_call_tool_scope....ValueError","sourceNodeId":"handle_call_tool \\n[server.py : 145_218]","targetNodeId":"/src/mcpCloudinc/src/mcpCloudinc/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpCloudinc/src/mcpCloudinc/server.py"},"region":{"startLine":202,"startColumn":23,"endLine":202,"endColumn":69,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 145_218]->/src/mcpCloudinc/src/mcpCloudinc/server.handle_call_tool.handle_call_tool_scope....ValueError","sourceNodeId":"handle_call_tool \\n[server.py : 145_218]","targetNodeId":"/src/mcpCloudinc/src/mcpCloudinc/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpCloudinc/src/mcpCloudinc/server.py"},"region":{"startLine":204,"startColumn":23,"endLine":204,"endColumn":68,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 145_218]->/src/mcpCloudinc/src/mcpCloudinc/server.handle_call_tool.handle_call_tool_scope....ValueError","sourceNodeId":"handle_call_tool \\n[server.py : 145_218]","targetNodeId":"/src/mcpCloudinc/src/mcpCloudinc/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpCloudinc/src/mcpCloudinc/server.py"},"region":{"startLine":206,"startColumn":23,"endLine":206,"endColumn":64,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 145_218]->/src/mcpCloudinc/src/mcpCloudinc/server.handle_call_tool.handle_call_tool_scope....ValueError","sourceNodeId":"handle_call_tool \\n[server.py : 145_218]","targetNodeId":"/src/mcpCloudinc/src/mcpCloudinc/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpCloudinc/src/mcpCloudinc/server.py"},"region":{"startLine":208,"startColumn":23,"endLine":208,"endColumn":61,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 145_218]->/src/mcpCloudinc/src/mcpCloudinc/server.handle_call_tool.handle_call_tool_scope....ValueError","sourceNodeId":"handle_call_tool \\n[server.py : 145_218]","targetNodeId":"/src/mcpCloudinc/src/mcpCloudinc/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpCloudinc/src/mcpCloudinc/server.py"},"region":{"startLine":210,"startColumn":23,"endLine":210,"endColumn":60,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 145_218]->/src/mcpCloudinc/src/mcpCloudinc/server.handle_call_tool.handle_call_tool_scope....ValueError","sourceNodeId":"handle_call_tool \\n[server.py : 145_218]","targetNodeId":"/src/mcpCloudinc/src/mcpCloudinc/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpCloudinc/src/mcpCloudinc/server.py"},"region":{"startLine":211,"startColumn":27,"endLine":215,"endColumn":70,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 145_218]->get_domain_labels \\n[server.py : 368_400]","sourceNodeId":"handle_call_tool \\n[server.py : 145_218]","targetNodeId":"get_domain_labels \\n[server.py : 368_400]"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpCloudinc/src/mcpCloudinc/server.py"},"region":{"startLine":384,"startColumn":14,"endLine":384,"endColumn":43,"snippet":{}}}},"id":"get_domain_labels \\n[server.py : 368_400]->CLOUDINC_URL_DICT.get","sourceNodeId":"get_domain_labels \\n[server.py : 368_400]","targetNodeId":"CLOUDINC_URL_DICT.get"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpCloudinc/src/mcpCloudinc/server.py"},"region":{"startLine":384,"startColumn":14,"endLine":384,"endColumn":52,"snippet":{}}}},"id":"get_domain_labels \\n[server.py : 368_400]->CLOUDINC_URL_DICT.get(tenant).get","sourceNodeId":"get_domain_labels \\n[server.py : 368_400]","targetNodeId":"CLOUDINC_URL_DICT.get(tenant).get"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpCloudinc/src/mcpCloudinc/server.py"},"region":{"startLine":390,"startColumn":20,"endLine":390,"endColumn":54,"snippet":{}}}},"id":"get_domain_labels \\n[server.py : 368_400]->syslib_from.requests.get","sourceNodeId":"get_domain_labels \\n[server.py : 368_400]","targetNodeId":"syslib_from.requests.get"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpCloudinc/src/mcpCloudinc/server.py"},"region":{"startLine":391,"startColumn":9,"endLine":391,"endColumn":36,"snippet":{}}}},"id":"get_domain_labels \\n[server.py : 368_400]->syslib_from.requests.get(url, var headers:any=headers).raise_for_status","sourceNodeId":"get_domain_labels \\n[server.py : 368_400]","targetNodeId":"syslib_from.requests.get(url, var headers:any=headers).raise_for_status"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpCloudinc/src/mcpCloudinc/server.py"},"region":{"startLine":392,"startColumn":18,"endLine":392,"endColumn":33,"snippet":{}}}},"id":"get_domain_labels \\n[server.py : 368_400]->syslib_from.requests.get(url, var headers:any=headers).json","sourceNodeId":"get_domain_labels \\n[server.py : 368_400]","targetNodeId":"syslib_from.requests.get(url, var headers:any=headers).json"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpCloudinc/src/mcpCloudinc/server.py"},"region":{"startLine":395,"startColumn":31,"endLine":395,"endColumn":51,"snippet":{}}}},"id":"get_domain_labels \\n[server.py : 368_400]->syslib_from.requests.get(url, var headers:any=headers).json().get","sourceNodeId":"get_domain_labels \\n[server.py : 368_400]","targetNodeId":"syslib_from.requests.get(url, var headers:any=headers).json().get"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpCloudinc/src/mcpCloudinc/server.py"},"region":{"startLine":394,"startColumn":13,"endLine":394,"endColumn":99,"snippet":{}}}},"id":"get_domain_labels \\n[server.py : 368_400]->syslib_from.logging.getLogger(mcp-server).info","sourceNodeId":"get_domain_labels \\n[server.py : 368_400]","targetNodeId":"syslib_from.logging.getLogger(mcp-server).info"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpCloudinc/src/mcpCloudinc/server.py"},"region":{"startLine":395,"startColumn":20,"endLine":395,"endColumn":72,"snippet":{}}}},"id":"get_domain_labels \\n[server.py : 368_400]->syslib_from.json.dumps","sourceNodeId":"get_domain_labels \\n[server.py : 368_400]","targetNodeId":"syslib_from.json.dumps"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpCloudinc/src/mcpCloudinc/server.py"},"region":{"startLine":396,"startColumn":9,"endLine":396,"endColumn":104,"snippet":{}}}},"id":"get_domain_labels \\n[server.py : 368_400]->syslib_from.logging.getLogger(mcp-server).warning","sourceNodeId":"get_domain_labels \\n[server.py : 368_400]","targetNodeId":"syslib_from.logging.getLogger(mcp-server).warning"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpCloudinc/src/mcpCloudinc/server.py"},"region":{"startLine":399,"startColumn":86,"endLine":399,"endColumn":94,"snippet":{}}}},"id":"get_domain_labels \\n[server.py : 368_400]->/src/mcpCloudinc/src/mcpCloudinc/server.get_domain_labels.get_domain_labels_scope...str","sourceNodeId":"get_domain_labels \\n[server.py : 368_400]","targetNodeId":"/src/mcpCloudinc/src/mcpCloudinc/server.get_domain_labels.get_domain_labels_scope...str"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpCloudinc/src/mcpCloudinc/server.py"},"region":{"startLine":399,"startColumn":9,"endLine":399,"endColumn":96,"snippet":{}}}},"id":"get_domain_labels \\n[server.py : 368_400]->syslib_from.logging.getLogger(mcp-server).error","sourceNodeId":"get_domain_labels \\n[server.py : 368_400]","targetNodeId":"syslib_from.logging.getLogger(mcp-server).error"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpCloudinc/src/mcpCloudinc/server.py"},"region":{"startLine":218,"startColumn":19,"endLine":218,"endColumn":54,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 145_218]->/src/mcpCloudinc/src/mcpCloudinc/server.handle_call_tool.handle_call_tool_scope...ValueError","sourceNodeId":"handle_call_tool \\n[server.py : 145_218]","targetNodeId":"/src/mcpCloudinc/src/mcpCloudinc/server.handle_call_tool.handle_call_tool_scope...ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpCmdExecution/src/mcpCmdExecution/server.py"},"region":{"startLine":115,"startColumn":1,"endLine":149,"endColumn":54,"snippet":{}}}},"id":"<__entry_point__>->handle_call_tool \\n[server.py : 115_149]","sourceNodeId":"<__entry_point__>","targetNodeId":"handle_call_tool \\n[server.py : 115_149]"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpCmdExecution/src/mcpCmdExecution/server.py"},"region":{"startLine":122,"startColumn":80,"endLine":122,"endColumn":123,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 115_149]->syslib_from.json.dumps","sourceNodeId":"handle_call_tool \\n[server.py : 115_149]","targetNodeId":"syslib_from.json.dumps"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpCmdExecution/src/mcpCmdExecution/server.py"},"region":{"startLine":122,"startColumn":5,"endLine":122,"endColumn":125,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 115_149]->syslib_from.logging.getLogger(mcp-server).info","sourceNodeId":"handle_call_tool \\n[server.py : 115_149]","targetNodeId":"syslib_from.logging.getLogger(mcp-server).info"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpCmdExecution/src/mcpCmdExecution/server.py"},"region":{"startLine":126,"startColumn":23,"endLine":126,"endColumn":56,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 115_149]->/src/mcpCmdExecution/src/mcpCmdExecution/server.handle_call_tool.handle_call_tool_scope....ValueError","sourceNodeId":"handle_call_tool \\n[server.py : 115_149]","targetNodeId":"/src/mcpCmdExecution/src/mcpCmdExecution/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpCmdExecution/src/mcpCmdExecution/server.py"},"region":{"startLine":129,"startColumn":23,"endLine":129,"endColumn":105,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 115_149]->/src/mcpCmdExecution/src/mcpCmdExecution/server.handle_call_tool.handle_call_tool_scope....ValueError","sourceNodeId":"handle_call_tool \\n[server.py : 115_149]","targetNodeId":"/src/mcpCmdExecution/src/mcpCmdExecution/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpCmdExecution/src/mcpCmdExecution/server.py"},"region":{"startLine":132,"startColumn":23,"endLine":132,"endColumn":77,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 115_149]->/src/mcpCmdExecution/src/mcpCmdExecution/server.handle_call_tool.handle_call_tool_scope....ValueError","sourceNodeId":"handle_call_tool \\n[server.py : 115_149]","targetNodeId":"/src/mcpCmdExecution/src/mcpCmdExecution/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpCmdExecution/src/mcpCmdExecution/server.py"},"region":{"startLine":137,"startColumn":25,"endLine":137,"endColumn":61,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 115_149]->/src/mcpCmdExecution/src/mcpCmdExecution/server.handle_call_tool.arguments.get","sourceNodeId":"handle_call_tool \\n[server.py : 115_149]","targetNodeId":"/src/mcpCmdExecution/src/mcpCmdExecution/server.handle_call_tool.arguments.get"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpCmdExecution/src/mcpCmdExecution/server.py"},"region":{"startLine":138,"startColumn":19,"endLine":143,"endColumn":14,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 115_149]->command_execution \\n[server.py : 70_111]","sourceNodeId":"handle_call_tool \\n[server.py : 115_149]","targetNodeId":"command_execution \\n[server.py : 70_111]"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpCmdExecution/src/mcpCmdExecution/server.py"},"region":{"startLine":101,"startColumn":13,"endLine":101,"endColumn":107,"snippet":{}}}},"id":"command_execution \\n[server.py : 70_111]->syslib_from.logging.getLogger(mcp-server).info","sourceNodeId":"command_execution \\n[server.py : 70_111]","targetNodeId":"syslib_from.logging.getLogger(mcp-server).info"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpCmdExecution/src/mcpCmdExecution/server.py"},"region":{"startLine":82,"startColumn":20,"endLine":90,"endColumn":14,"snippet":{}}}},"id":"command_execution \\n[server.py : 70_111]->/src/mcpCmdExecution/src/mcpCmdExecution/server.command_execution.command_execution_scope..dict","sourceNodeId":"command_execution \\n[server.py : 70_111]","targetNodeId":"/src/mcpCmdExecution/src/mcpCmdExecution/server.command_execution.command_execution_scope..dict"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpCmdExecution/src/mcpCmdExecution/server.py"},"region":{"startLine":81,"startColumn":39,"endLine":91,"endColumn":10,"snippet":{}}}},"id":"command_execution \\n[server.py : 70_111]->mcp_common.remote.codeinsight.code_insight_api.mcp_server_backend_api","sourceNodeId":"command_execution \\n[server.py : 70_111]","targetNodeId":"mcp_common.remote.codeinsight.code_insight_api.mcp_server_backend_api"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpCmdExecution/src/mcpCmdExecution/server.py"},"region":{"startLine":104,"startColumn":36,"endLine":104,"endColumn":81,"snippet":{}}}},"id":"command_execution \\n[server.py : 70_111]->syslib_from.json.dumps","sourceNodeId":"command_execution \\n[server.py : 70_111]","targetNodeId":"syslib_from.json.dumps"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpCmdExecution/src/mcpCmdExecution/server.py"},"region":{"startLine":100,"startColumn":23,"endLine":100,"endColumn":63,"snippet":{}}}},"id":"command_execution \\n[server.py : 70_111]->mcp_common.remote.codeinsight.code_insight_api.mcp_server_backend_api(var params:any=dict(var name:any=Consts.CMD_EXECUTION.name, var arguments:any=dict(var appName:any=app_name, var command:any=comma...","sourceNodeId":"command_execution \\n[server.py : 70_111]","targetNodeId":"mcp_common.remote.codeinsight.code_insight_api.mcp_server_backend_api(var params:any=dict(var name:any=Consts.CMD_EXECUTION.name, var arguments:any=dict(var appName:any=app_name, var command:any=comma..."},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpCmdExecution/src/mcpCmdExecution/server.py"},"region":{"startLine":103,"startColumn":13,"endLine":104,"endColumn":83,"snippet":{}}}},"id":"command_execution \\n[server.py : 70_111]->syslib_from.logging.getLogger(mcp-server).warning","sourceNodeId":"command_execution \\n[server.py : 70_111]","targetNodeId":"syslib_from.logging.getLogger(mcp-server).warning"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpCmdExecution/src/mcpCmdExecution/server.py"},"region":{"startLine":107,"startColumn":9,"endLine":107,"endColumn":108,"snippet":{}}}},"id":"command_execution \\n[server.py : 70_111]->syslib_from.logging.getLogger(mcp-server).exception","sourceNodeId":"command_execution \\n[server.py : 70_111]","targetNodeId":"syslib_from.logging.getLogger(mcp-server).exception"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpCmdExecution/src/mcpCmdExecution/server.py"},"region":{"startLine":144,"startColumn":21,"endLine":147,"endColumn":14,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 115_149]->syslib_from.mcp/types.TextContent","sourceNodeId":"handle_call_tool \\n[server.py : 115_149]","targetNodeId":"syslib_from.mcp/types.TextContent"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpCmdExecution/src/mcpCmdExecution/server.py"},"region":{"startLine":149,"startColumn":19,"endLine":149,"endColumn":54,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 115_149]->/src/mcpCmdExecution/src/mcpCmdExecution/server.handle_call_tool.handle_call_tool_scope...ValueError","sourceNodeId":"handle_call_tool \\n[server.py : 115_149]","targetNodeId":"/src/mcpCmdExecution/src/mcpCmdExecution/server.handle_call_tool.handle_call_tool_scope...ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpCodeContent/src/mcpCodeContent/server.py"},"region":{"startLine":200,"startColumn":1,"endLine":257,"endColumn":54,"snippet":{}}}},"id":"<__entry_point__>->handle_call_tool \\n[server.py : 200_257]","sourceNodeId":"<__entry_point__>","targetNodeId":"handle_call_tool \\n[server.py : 200_257]"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpCodeContent/src/mcpCodeContent/server.py"},"region":{"startLine":207,"startColumn":80,"endLine":207,"endColumn":123,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 200_257]->syslib_from.json.dumps","sourceNodeId":"handle_call_tool \\n[server.py : 200_257]","targetNodeId":"syslib_from.json.dumps"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpCodeContent/src/mcpCodeContent/server.py"},"region":{"startLine":207,"startColumn":5,"endLine":207,"endColumn":125,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 200_257]->syslib_from.logging.getLogger(mcp-server).info","sourceNodeId":"handle_call_tool \\n[server.py : 200_257]","targetNodeId":"syslib_from.logging.getLogger(mcp-server).info"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpCodeContent/src/mcpCodeContent/server.py"},"region":{"startLine":209,"startColumn":15,"endLine":209,"endColumn":48,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 200_257]->/src/mcpCodeContent/src/mcpCodeContent/server.handle_call_tool.handle_call_tool_scope...ValueError","sourceNodeId":"handle_call_tool \\n[server.py : 200_257]","targetNodeId":"/src/mcpCodeContent/src/mcpCodeContent/server.handle_call_tool.handle_call_tool_scope...ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpCodeContent/src/mcpCodeContent/server.py"},"region":{"startLine":214,"startColumn":23,"endLine":214,"endColumn":105,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 200_257]->/src/mcpCodeContent/src/mcpCodeContent/server.handle_call_tool.handle_call_tool_scope....ValueError","sourceNodeId":"handle_call_tool \\n[server.py : 200_257]","targetNodeId":"/src/mcpCodeContent/src/mcpCodeContent/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpCodeContent/src/mcpCodeContent/server.py"},"region":{"startLine":217,"startColumn":23,"endLine":217,"endColumn":79,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 200_257]->/src/mcpCodeContent/src/mcpCodeContent/server.handle_call_tool.handle_call_tool_scope....ValueError","sourceNodeId":"handle_call_tool \\n[server.py : 200_257]","targetNodeId":"/src/mcpCodeContent/src/mcpCodeContent/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpCodeContent/src/mcpCodeContent/server.py"},"region":{"startLine":244,"startColumn":25,"endLine":244,"endColumn":61,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 200_257]->/src/mcpCodeContent/src/mcpCodeContent/server.handle_call_tool.arguments.get","sourceNodeId":"handle_call_tool \\n[server.py : 200_257]","targetNodeId":"/src/mcpCodeContent/src/mcpCodeContent/server.handle_call_tool.arguments.get"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpCodeContent/src/mcpCodeContent/server.py"},"region":{"startLine":223,"startColumn":19,"endLine":228,"endColumn":14,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 200_257]->read_file_content \\n[server.py : 107_149]","sourceNodeId":"handle_call_tool \\n[server.py : 200_257]","targetNodeId":"read_file_content \\n[server.py : 107_149]"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpCodeContent/src/mcpCodeContent/server.py"},"region":{"startLine":139,"startColumn":13,"endLine":139,"endColumn":111,"snippet":{}}}},"id":"read_file_content \\n[server.py : 107_149]->syslib_from.logging.getLogger(mcp-server).info","sourceNodeId":"read_file_content \\n[server.py : 107_149]","targetNodeId":"syslib_from.logging.getLogger(mcp-server).info"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpCodeContent/src/mcpCodeContent/server.py"},"region":{"startLine":119,"startColumn":20,"endLine":127,"endColumn":14,"snippet":{}}}},"id":"read_file_content \\n[server.py : 107_149]->/src/mcpCodeContent/src/mcpCodeContent/server.read_file_content.read_file_content_scope..dict","sourceNodeId":"read_file_content \\n[server.py : 107_149]","targetNodeId":"/src/mcpCodeContent/src/mcpCodeContent/server.read_file_content.read_file_content_scope..dict"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpCodeContent/src/mcpCodeContent/server.py"},"region":{"startLine":118,"startColumn":39,"endLine":128,"endColumn":10,"snippet":{}}}},"id":"read_file_content \\n[server.py : 107_149]->mcp_common.remote.codeinsight.code_insight_api.mcp_server_backend_api","sourceNodeId":"read_file_content \\n[server.py : 107_149]","targetNodeId":"mcp_common.remote.codeinsight.code_insight_api.mcp_server_backend_api"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpCodeContent/src/mcpCodeContent/server.py"},"region":{"startLine":142,"startColumn":35,"endLine":142,"endColumn":80,"snippet":{}}}},"id":"read_file_content \\n[server.py : 107_149]->syslib_from.json.dumps","sourceNodeId":"read_file_content \\n[server.py : 107_149]","targetNodeId":"syslib_from.json.dumps"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpCodeContent/src/mcpCodeContent/server.py"},"region":{"startLine":138,"startColumn":23,"endLine":138,"endColumn":63,"snippet":{}}}},"id":"read_file_content \\n[server.py : 107_149]->mcp_common.remote.codeinsight.code_insight_api.mcp_server_backend_api(var params:any=dict(var name:any=Consts.READ_FILE_CONTENT.name, var arguments:any=dict(var appName:any=app_name, var filePath:any=...","sourceNodeId":"read_file_content \\n[server.py : 107_149]","targetNodeId":"mcp_common.remote.codeinsight.code_insight_api.mcp_server_backend_api(var params:any=dict(var name:any=Consts.READ_FILE_CONTENT.name, var arguments:any=dict(var appName:any=app_name, var filePath:any=..."},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpCodeContent/src/mcpCodeContent/server.py"},"region":{"startLine":141,"startColumn":13,"endLine":142,"endColumn":82,"snippet":{}}}},"id":"read_file_content \\n[server.py : 107_149]->syslib_from.logging.getLogger(mcp-server).warning","sourceNodeId":"read_file_content \\n[server.py : 107_149]","targetNodeId":"syslib_from.logging.getLogger(mcp-server).warning"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpCodeContent/src/mcpCodeContent/server.py"},"region":{"startLine":145,"startColumn":9,"endLine":145,"endColumn":112,"snippet":{}}}},"id":"read_file_content \\n[server.py : 107_149]->syslib_from.logging.getLogger(mcp-server).exception","sourceNodeId":"read_file_content \\n[server.py : 107_149]","targetNodeId":"syslib_from.logging.getLogger(mcp-server).exception"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpCodeContent/src/mcpCodeContent/server.py"},"region":{"startLine":252,"startColumn":21,"endLine":255,"endColumn":14,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 200_257]->syslib_from.mcp/types.TextContent","sourceNodeId":"handle_call_tool \\n[server.py : 200_257]","targetNodeId":"syslib_from.mcp/types.TextContent"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpCodeContent/src/mcpCodeContent/server.py"},"region":{"startLine":235,"startColumn":23,"endLine":235,"endColumn":105,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 200_257]->/src/mcpCodeContent/src/mcpCodeContent/server.handle_call_tool.handle_call_tool_scope....ValueError","sourceNodeId":"handle_call_tool \\n[server.py : 200_257]","targetNodeId":"/src/mcpCodeContent/src/mcpCodeContent/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpCodeContent/src/mcpCodeContent/server.py"},"region":{"startLine":238,"startColumn":23,"endLine":238,"endColumn":113,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 200_257]->/src/mcpCodeContent/src/mcpCodeContent/server.handle_call_tool.handle_call_tool_scope....ValueError","sourceNodeId":"handle_call_tool \\n[server.py : 200_257]","targetNodeId":"/src/mcpCodeContent/src/mcpCodeContent/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpCodeContent/src/mcpCodeContent/server.py"},"region":{"startLine":245,"startColumn":19,"endLine":251,"endColumn":14,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 200_257]->extract_function_snippet \\n[server.py : 152_196]","sourceNodeId":"handle_call_tool \\n[server.py : 200_257]","targetNodeId":"extract_function_snippet \\n[server.py : 152_196]"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpCodeContent/src/mcpCodeContent/server.py"},"region":{"startLine":186,"startColumn":13,"endLine":186,"endColumn":118,"snippet":{}}}},"id":"extract_function_snippet \\n[server.py : 152_196]->syslib_from.logging.getLogger(mcp-server).info","sourceNodeId":"extract_function_snippet \\n[server.py : 152_196]","targetNodeId":"syslib_from.logging.getLogger(mcp-server).info"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpCodeContent/src/mcpCodeContent/server.py"},"region":{"startLine":165,"startColumn":20,"endLine":174,"endColumn":14,"snippet":{}}}},"id":"extract_function_snippet \\n[server.py : 152_196]->/src/mcpCodeContent/src/mcpCodeContent/server.extract_function_snippet.extract_function_snippet_scope..dict","sourceNodeId":"extract_function_snippet \\n[server.py : 152_196]","targetNodeId":"/src/mcpCodeContent/src/mcpCodeContent/server.extract_function_snippet.extract_function_snippet_scope..dict"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpCodeContent/src/mcpCodeContent/server.py"},"region":{"startLine":164,"startColumn":39,"endLine":175,"endColumn":10,"snippet":{}}}},"id":"extract_function_snippet \\n[server.py : 152_196]->mcp_common.remote.codeinsight.code_insight_api.mcp_server_backend_api","sourceNodeId":"extract_function_snippet \\n[server.py : 152_196]","targetNodeId":"mcp_common.remote.codeinsight.code_insight_api.mcp_server_backend_api"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpCodeContent/src/mcpCodeContent/server.py"},"region":{"startLine":189,"startColumn":36,"endLine":189,"endColumn":81,"snippet":{}}}},"id":"extract_function_snippet \\n[server.py : 152_196]->syslib_from.json.dumps","sourceNodeId":"extract_function_snippet \\n[server.py : 152_196]","targetNodeId":"syslib_from.json.dumps"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpCodeContent/src/mcpCodeContent/server.py"},"region":{"startLine":185,"startColumn":23,"endLine":185,"endColumn":63,"snippet":{}}}},"id":"extract_function_snippet \\n[server.py : 152_196]->mcp_common.remote.codeinsight.code_insight_api.mcp_server_backend_api(var params:any=dict(var name:any=Consts.EXTRACT_FUNCTION_SNIPPET.name, var arguments:any=dict(var appName:any=app_name, var filePa...","sourceNodeId":"extract_function_snippet \\n[server.py : 152_196]","targetNodeId":"mcp_common.remote.codeinsight.code_insight_api.mcp_server_backend_api(var params:any=dict(var name:any=Consts.EXTRACT_FUNCTION_SNIPPET.name, var arguments:any=dict(var appName:any=app_name, var filePa..."},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpCodeContent/src/mcpCodeContent/server.py"},"region":{"startLine":188,"startColumn":13,"endLine":189,"endColumn":83,"snippet":{}}}},"id":"extract_function_snippet \\n[server.py : 152_196]->syslib_from.logging.getLogger(mcp-server).warning","sourceNodeId":"extract_function_snippet \\n[server.py : 152_196]","targetNodeId":"syslib_from.logging.getLogger(mcp-server).warning"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpCodeContent/src/mcpCodeContent/server.py"},"region":{"startLine":192,"startColumn":9,"endLine":192,"endColumn":119,"snippet":{}}}},"id":"extract_function_snippet \\n[server.py : 152_196]->syslib_from.logging.getLogger(mcp-server).exception","sourceNodeId":"extract_function_snippet \\n[server.py : 152_196]","targetNodeId":"syslib_from.logging.getLogger(mcp-server).exception"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpCodeContent/src/mcpCodeContent/server.py"},"region":{"startLine":257,"startColumn":19,"endLine":257,"endColumn":54,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 200_257]->/src/mcpCodeContent/src/mcpCodeContent/server.handle_call_tool.handle_call_tool_scope...ValueError","sourceNodeId":"handle_call_tool \\n[server.py : 200_257]","targetNodeId":"/src/mcpCodeContent/src/mcpCodeContent/server.handle_call_tool.handle_call_tool_scope...ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpCodeExecutor/src/mcpCodeExecutor/server.py"},"region":{"startLine":68,"startColumn":1,"endLine":99,"endColumn":11,"snippet":{}}}},"id":"<__entry_point__>->handle_call_tool \\n[server.py : 68_99]","sourceNodeId":"<__entry_point__>","targetNodeId":"handle_call_tool \\n[server.py : 68_99]"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpCodeExecutor/src/mcpCodeExecutor/server.py"},"region":{"startLine":89,"startColumn":26,"endLine":89,"endColumn":69,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 68_99]->syslib_from.json.dumps","sourceNodeId":"handle_call_tool \\n[server.py : 68_99]","targetNodeId":"syslib_from.json.dumps"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpCodeExecutor/src/mcpCodeExecutor/server.py"},"region":{"startLine":86,"startColumn":17,"endLine":86,"endColumn":102,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 68_99]->syslib_from.logging.getLogger(mcp-server).info","sourceNodeId":"handle_call_tool \\n[server.py : 68_99]","targetNodeId":"syslib_from.logging.getLogger(mcp-server).info"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpCodeExecutor/src/mcpCodeExecutor/server.py"},"region":{"startLine":81,"startColumn":27,"endLine":81,"endColumn":62,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 68_99]->/src/mcpCodeExecutor/src/mcpCodeExecutor/server.handle_call_tool.handle_call_tool_scope....ValueError","sourceNodeId":"handle_call_tool \\n[server.py : 68_99]","targetNodeId":"/src/mcpCodeExecutor/src/mcpCodeExecutor/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpCodeExecutor/src/mcpCodeExecutor/server.py"},"region":{"startLine":84,"startColumn":62,"endLine":84,"endColumn":94,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 68_99]->/src/mcpCodeExecutor/src/mcpCodeExecutor/server.handle_call_tool.arguments.get","sourceNodeId":"handle_call_tool \\n[server.py : 68_99]","targetNodeId":"/src/mcpCodeExecutor/src/mcpCodeExecutor/server.handle_call_tool.arguments.get"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpCodeExecutor/src/mcpCodeExecutor/server.py"},"region":{"startLine":83,"startColumn":31,"endLine":85,"endColumn":47,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 68_99]->run_code \\n[server.py : 127_184]","sourceNodeId":"handle_call_tool \\n[server.py : 68_99]","targetNodeId":"run_code \\n[server.py : 127_184]"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpCodeExecutor/src/mcpCodeExecutor/server.py"},"region":{"startLine":96,"startColumn":17,"endLine":99,"endColumn":10,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 68_99]->syslib_from.mcp/types.TextContent","sourceNodeId":"handle_call_tool \\n[server.py : 68_99]","targetNodeId":"syslib_from.mcp/types.TextContent"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpCodeExecutor/src/mcpCodeExecutor/server.py"},"region":{"startLine":93,"startColumn":23,"endLine":93,"endColumn":58,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 68_99]->/src/mcpCodeExecutor/src/mcpCodeExecutor/server.handle_call_tool.handle_call_tool_scope...ValueError","sourceNodeId":"handle_call_tool \\n[server.py : 68_99]","targetNodeId":"/src/mcpCodeExecutor/src/mcpCodeExecutor/server.handle_call_tool.handle_call_tool_scope...ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpCodeExecutor/src/mcpCodeExecutor/server.py"},"region":{"startLine":95,"startColumn":9,"endLine":95,"endColumn":85,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 68_99]->syslib_from.logging.getLogger(mcp-server).error","sourceNodeId":"handle_call_tool \\n[server.py : 68_99]","targetNodeId":"syslib_from.logging.getLogger(mcp-server).error"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpCodeSearch/src/mcpCodeSearch/server.py"},"region":{"startLine":220,"startColumn":1,"endLine":275,"endColumn":54,"snippet":{}}}},"id":"<__entry_point__>->handle_call_tool \\n[server.py : 220_275]","sourceNodeId":"<__entry_point__>","targetNodeId":"handle_call_tool \\n[server.py : 220_275]"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpCodeSearch/src/mcpCodeSearch/server.py"},"region":{"startLine":227,"startColumn":80,"endLine":227,"endColumn":123,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 220_275]->syslib_from.json.dumps","sourceNodeId":"handle_call_tool \\n[server.py : 220_275]","targetNodeId":"syslib_from.json.dumps"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpCodeSearch/src/mcpCodeSearch/server.py"},"region":{"startLine":227,"startColumn":5,"endLine":227,"endColumn":125,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 220_275]->syslib_from.logging.getLogger(mcp-server).info","sourceNodeId":"handle_call_tool \\n[server.py : 220_275]","targetNodeId":"syslib_from.logging.getLogger(mcp-server).info"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpCodeSearch/src/mcpCodeSearch/server.py"},"region":{"startLine":229,"startColumn":15,"endLine":229,"endColumn":48,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 220_275]->/src/mcpCodeSearch/src/mcpCodeSearch/server.handle_call_tool.handle_call_tool_scope...ValueError","sourceNodeId":"handle_call_tool \\n[server.py : 220_275]","targetNodeId":"/src/mcpCodeSearch/src/mcpCodeSearch/server.handle_call_tool.handle_call_tool_scope...ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpCodeSearch/src/mcpCodeSearch/server.py"},"region":{"startLine":234,"startColumn":23,"endLine":234,"endColumn":105,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 220_275]->/src/mcpCodeSearch/src/mcpCodeSearch/server.handle_call_tool.handle_call_tool_scope....ValueError","sourceNodeId":"handle_call_tool \\n[server.py : 220_275]","targetNodeId":"/src/mcpCodeSearch/src/mcpCodeSearch/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpCodeSearch/src/mcpCodeSearch/server.py"},"region":{"startLine":237,"startColumn":23,"endLine":237,"endColumn":84,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 220_275]->/src/mcpCodeSearch/src/mcpCodeSearch/server.handle_call_tool.handle_call_tool_scope....ValueError","sourceNodeId":"handle_call_tool \\n[server.py : 220_275]","targetNodeId":"/src/mcpCodeSearch/src/mcpCodeSearch/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpCodeSearch/src/mcpCodeSearch/server.py"},"region":{"startLine":263,"startColumn":25,"endLine":263,"endColumn":61,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 220_275]->/src/mcpCodeSearch/src/mcpCodeSearch/server.handle_call_tool.arguments.get","sourceNodeId":"handle_call_tool \\n[server.py : 220_275]","targetNodeId":"/src/mcpCodeSearch/src/mcpCodeSearch/server.handle_call_tool.arguments.get"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpCodeSearch/src/mcpCodeSearch/server.py"},"region":{"startLine":243,"startColumn":19,"endLine":248,"endColumn":14,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 220_275]->error_code_search \\n[server.py : 127_169]","sourceNodeId":"handle_call_tool \\n[server.py : 220_275]","targetNodeId":"error_code_search \\n[server.py : 127_169]"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpCodeSearch/src/mcpCodeSearch/server.py"},"region":{"startLine":159,"startColumn":13,"endLine":159,"endColumn":105,"snippet":{}}}},"id":"error_code_search \\n[server.py : 127_169]->syslib_from.logging.getLogger(mcp-server).info","sourceNodeId":"error_code_search \\n[server.py : 127_169]","targetNodeId":"syslib_from.logging.getLogger(mcp-server).info"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpCodeSearch/src/mcpCodeSearch/server.py"},"region":{"startLine":139,"startColumn":20,"endLine":147,"endColumn":14,"snippet":{}}}},"id":"error_code_search \\n[server.py : 127_169]->/src/mcpCodeSearch/src/mcpCodeSearch/server.error_code_search.error_code_search_scope..dict","sourceNodeId":"error_code_search \\n[server.py : 127_169]","targetNodeId":"/src/mcpCodeSearch/src/mcpCodeSearch/server.error_code_search.error_code_search_scope..dict"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpCodeSearch/src/mcpCodeSearch/server.py"},"region":{"startLine":138,"startColumn":39,"endLine":148,"endColumn":10,"snippet":{}}}},"id":"error_code_search \\n[server.py : 127_169]->mcp_common.remote.codeinsight.code_insight_api.mcp_server_backend_api","sourceNodeId":"error_code_search \\n[server.py : 127_169]","targetNodeId":"mcp_common.remote.codeinsight.code_insight_api.mcp_server_backend_api"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpCodeSearch/src/mcpCodeSearch/server.py"},"region":{"startLine":162,"startColumn":35,"endLine":162,"endColumn":80,"snippet":{}}}},"id":"error_code_search \\n[server.py : 127_169]->syslib_from.json.dumps","sourceNodeId":"error_code_search \\n[server.py : 127_169]","targetNodeId":"syslib_from.json.dumps"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpCodeSearch/src/mcpCodeSearch/server.py"},"region":{"startLine":158,"startColumn":23,"endLine":158,"endColumn":53,"snippet":{}}}},"id":"error_code_search \\n[server.py : 127_169]->mcp_common.remote.codeinsight.code_insight_api.mcp_server_backend_api(var params:any=dict(var name:any=Consts.CODE_SEARCH.name, var arguments:any=dict(var appName:any=app_name, var searchPattern:any=s...","sourceNodeId":"error_code_search \\n[server.py : 127_169]","targetNodeId":"mcp_common.remote.codeinsight.code_insight_api.mcp_server_backend_api(var params:any=dict(var name:any=Consts.CODE_SEARCH.name, var arguments:any=dict(var appName:any=app_name, var searchPattern:any=s..."},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpCodeSearch/src/mcpCodeSearch/server.py"},"region":{"startLine":156,"startColumn":23,"endLine":156,"endColumn":48,"snippet":{}}}},"id":"error_code_search \\n[server.py : 127_169]->format_content \\n[server.py : 107_124]","sourceNodeId":"error_code_search \\n[server.py : 127_169]","targetNodeId":"format_content \\n[server.py : 107_124]"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpCodeSearch/src/mcpCodeSearch/server.py"},"region":{"startLine":110,"startColumn":28,"endLine":110,"endColumn":48,"snippet":{}}}},"id":"format_content \\n[server.py : 107_124]->/src/mcpCodeSearch/src/mcpCodeSearch/server.format_content.format_content_scope...enumerate","sourceNodeId":"format_content \\n[server.py : 107_124]","targetNodeId":"/src/mcpCodeSearch/src/mcpCodeSearch/server.format_content.format_content_scope...enumerate"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpCodeSearch/src/mcpCodeSearch/server.py"},"region":{"startLine":114,"startColumn":20,"endLine":114,"endColumn":43,"snippet":{}}}},"id":"format_content \\n[server.py : 107_124]->/src/mcpCodeSearch/src/mcpCodeSearch/server.format_content.format_content_scope...enumerate(data_list).get","sourceNodeId":"format_content \\n[server.py : 107_124]","targetNodeId":"/src/mcpCodeSearch/src/mcpCodeSearch/server.format_content.format_content_scope...enumerate(data_list).get"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpCodeSearch/src/mcpCodeSearch/server.py"},"region":{"startLine":115,"startColumn":20,"endLine":119,"endColumn":14,"snippet":{}}}},"id":"format_content \\n[server.py : 107_124]->mcp_common.utils.consts.CODE_PATTERN.format","sourceNodeId":"format_content \\n[server.py : 107_124]","targetNodeId":"mcp_common.utils.consts.CODE_PATTERN.format"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpCodeSearch/src/mcpCodeSearch/server.py"},"region":{"startLine":122,"startColumn":9,"endLine":122,"endColumn":86,"snippet":{}}}},"id":"format_content \\n[server.py : 107_124]->syslib_from.logging.getLogger(mcp-server).exception","sourceNodeId":"format_content \\n[server.py : 107_124]","targetNodeId":"syslib_from.logging.getLogger(mcp-server).exception"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpCodeSearch/src/mcpCodeSearch/server.py"},"region":{"startLine":161,"startColumn":13,"endLine":162,"endColumn":82,"snippet":{}}}},"id":"error_code_search \\n[server.py : 127_169]->syslib_from.logging.getLogger(mcp-server).warning","sourceNodeId":"error_code_search \\n[server.py : 127_169]","targetNodeId":"syslib_from.logging.getLogger(mcp-server).warning"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpCodeSearch/src/mcpCodeSearch/server.py"},"region":{"startLine":165,"startColumn":9,"endLine":165,"endColumn":106,"snippet":{}}}},"id":"error_code_search \\n[server.py : 127_169]->syslib_from.logging.getLogger(mcp-server).exception","sourceNodeId":"error_code_search \\n[server.py : 127_169]","targetNodeId":"syslib_from.logging.getLogger(mcp-server).exception"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpCodeSearch/src/mcpCodeSearch/server.py"},"region":{"startLine":270,"startColumn":21,"endLine":273,"endColumn":14,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 220_275]->syslib_from.mcp/types.TextContent","sourceNodeId":"handle_call_tool \\n[server.py : 220_275]","targetNodeId":"syslib_from.mcp/types.TextContent"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpCodeSearch/src/mcpCodeSearch/server.py"},"region":{"startLine":255,"startColumn":23,"endLine":255,"endColumn":105,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 220_275]->/src/mcpCodeSearch/src/mcpCodeSearch/server.handle_call_tool.handle_call_tool_scope....ValueError","sourceNodeId":"handle_call_tool \\n[server.py : 220_275]","targetNodeId":"/src/mcpCodeSearch/src/mcpCodeSearch/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpCodeSearch/src/mcpCodeSearch/server.py"},"region":{"startLine":258,"startColumn":23,"endLine":258,"endColumn":80,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 220_275]->/src/mcpCodeSearch/src/mcpCodeSearch/server.handle_call_tool.handle_call_tool_scope....ValueError","sourceNodeId":"handle_call_tool \\n[server.py : 220_275]","targetNodeId":"/src/mcpCodeSearch/src/mcpCodeSearch/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpCodeSearch/src/mcpCodeSearch/server.py"},"region":{"startLine":264,"startColumn":19,"endLine":269,"endColumn":14,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 220_275]->locate_class_file \\n[server.py : 172_216]","sourceNodeId":"handle_call_tool \\n[server.py : 220_275]","targetNodeId":"locate_class_file \\n[server.py : 172_216]"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpCodeSearch/src/mcpCodeSearch/server.py"},"region":{"startLine":206,"startColumn":13,"endLine":206,"endColumn":111,"snippet":{}}}},"id":"locate_class_file \\n[server.py : 172_216]->syslib_from.logging.getLogger(mcp-server).info","sourceNodeId":"locate_class_file \\n[server.py : 172_216]","targetNodeId":"syslib_from.logging.getLogger(mcp-server).info"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpCodeSearch/src/mcpCodeSearch/server.py"},"region":{"startLine":184,"startColumn":20,"endLine":192,"endColumn":14,"snippet":{}}}},"id":"locate_class_file \\n[server.py : 172_216]->/src/mcpCodeSearch/src/mcpCodeSearch/server.locate_class_file.locate_class_file_scope..dict","sourceNodeId":"locate_class_file \\n[server.py : 172_216]","targetNodeId":"/src/mcpCodeSearch/src/mcpCodeSearch/server.locate_class_file.locate_class_file_scope..dict"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpCodeSearch/src/mcpCodeSearch/server.py"},"region":{"startLine":183,"startColumn":39,"endLine":193,"endColumn":10,"snippet":{}}}},"id":"locate_class_file \\n[server.py : 172_216]->mcp_common.remote.codeinsight.code_insight_api.mcp_server_backend_api","sourceNodeId":"locate_class_file \\n[server.py : 172_216]","targetNodeId":"mcp_common.remote.codeinsight.code_insight_api.mcp_server_backend_api"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpCodeSearch/src/mcpCodeSearch/server.py"},"region":{"startLine":209,"startColumn":35,"endLine":209,"endColumn":80,"snippet":{}}}},"id":"locate_class_file \\n[server.py : 172_216]->syslib_from.json.dumps","sourceNodeId":"locate_class_file \\n[server.py : 172_216]","targetNodeId":"syslib_from.json.dumps"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpCodeSearch/src/mcpCodeSearch/server.py"},"region":{"startLine":205,"startColumn":23,"endLine":205,"endColumn":53,"snippet":{}}}},"id":"locate_class_file \\n[server.py : 172_216]->mcp_common.remote.codeinsight.code_insight_api.mcp_server_backend_api(var params:any=dict(var name:any=Consts.LOCATE_CLASS_FILE.name, var arguments:any=dict(var appName:any=app_name, var className:any...","sourceNodeId":"locate_class_file \\n[server.py : 172_216]","targetNodeId":"mcp_common.remote.codeinsight.code_insight_api.mcp_server_backend_api(var params:any=dict(var name:any=Consts.LOCATE_CLASS_FILE.name, var arguments:any=dict(var appName:any=app_name, var className:any..."},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpCodeSearch/src/mcpCodeSearch/server.py"},"region":{"startLine":201,"startColumn":36,"endLine":201,"endColumn":56,"snippet":{}}}},"id":"locate_class_file \\n[server.py : 172_216]->/src/mcpCodeSearch/src/mcpCodeSearch/server.locate_class_file.locate_class_file_scope.....enumerate","sourceNodeId":"locate_class_file \\n[server.py : 172_216]","targetNodeId":"/src/mcpCodeSearch/src/mcpCodeSearch/server.locate_class_file.locate_class_file_scope.....enumerate"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpCodeSearch/src/mcpCodeSearch/server.py"},"region":{"startLine":202,"startColumn":37,"endLine":202,"endColumn":62,"snippet":{}}}},"id":"locate_class_file \\n[server.py : 172_216]->/src/mcpCodeSearch/src/mcpCodeSearch/server.locate_class_file.locate_class_file_scope.....enumerate(data_list).get","sourceNodeId":"locate_class_file \\n[server.py : 172_216]","targetNodeId":"/src/mcpCodeSearch/src/mcpCodeSearch/server.locate_class_file.locate_class_file_scope.....enumerate(data_list).get"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpCodeSearch/src/mcpCodeSearch/server.py"},"region":{"startLine":208,"startColumn":13,"endLine":209,"endColumn":82,"snippet":{}}}},"id":"locate_class_file \\n[server.py : 172_216]->syslib_from.logging.getLogger(mcp-server).warning","sourceNodeId":"locate_class_file \\n[server.py : 172_216]","targetNodeId":"syslib_from.logging.getLogger(mcp-server).warning"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpCodeSearch/src/mcpCodeSearch/server.py"},"region":{"startLine":212,"startColumn":9,"endLine":212,"endColumn":112,"snippet":{}}}},"id":"locate_class_file \\n[server.py : 172_216]->syslib_from.logging.getLogger(mcp-server).exception","sourceNodeId":"locate_class_file \\n[server.py : 172_216]","targetNodeId":"syslib_from.logging.getLogger(mcp-server).exception"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpCodeSearch/src/mcpCodeSearch/server.py"},"region":{"startLine":275,"startColumn":19,"endLine":275,"endColumn":54,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 220_275]->/src/mcpCodeSearch/src/mcpCodeSearch/server.handle_call_tool.handle_call_tool_scope...ValueError","sourceNodeId":"handle_call_tool \\n[server.py : 220_275]","targetNodeId":"/src/mcpCodeSearch/src/mcpCodeSearch/server.handle_call_tool.handle_call_tool_scope...ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpSqlExecute/src/mcpSqlExecute/server.py"},"region":{"startLine":6,"startColumn":1,"endLine":13,"endColumn":17,"snippet":{}}}},"id":"<__entry_point__>->add \\n[server.py : 6_13]","sourceNodeId":"<__entry_point__>","targetNodeId":"add \\n[server.py : 6_13]"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDbCapacity/src/mcpDbCapacity/server.py"},"region":{"startLine":191,"startColumn":1,"endLine":337,"endColumn":65,"snippet":{}}}},"id":"<__entry_point__>->handle_call_tool \\n[server.py : 191_337]","sourceNodeId":"<__entry_point__>","targetNodeId":"handle_call_tool \\n[server.py : 191_337]"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDbCapacity/src/mcpDbCapacity/server.py"},"region":{"startLine":199,"startColumn":70,"endLine":199,"endColumn":113,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 191_337]->syslib_from.json.dumps","sourceNodeId":"handle_call_tool \\n[server.py : 191_337]","targetNodeId":"syslib_from.json.dumps"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDbCapacity/src/mcpDbCapacity/server.py"},"region":{"startLine":198,"startColumn":5,"endLine":199,"endColumn":115,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 191_337]->syslib_from.logging.getLogger(mcp-server).info","sourceNodeId":"handle_call_tool \\n[server.py : 191_337]","targetNodeId":"syslib_from.logging.getLogger(mcp-server).info"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDbCapacity/src/mcpDbCapacity/server.py"},"region":{"startLine":203,"startColumn":23,"endLine":203,"endColumn":61,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 191_337]->/src/mcpDbCapacity/src/mcpDbCapacity/server.handle_call_tool.handle_call_tool_scope....ValueError","sourceNodeId":"handle_call_tool \\n[server.py : 191_337]","targetNodeId":"/src/mcpDbCapacity/src/mcpDbCapacity/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDbCapacity/src/mcpDbCapacity/server.py"},"region":{"startLine":206,"startColumn":23,"endLine":206,"endColumn":58,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 191_337]->/src/mcpDbCapacity/src/mcpDbCapacity/server.handle_call_tool.handle_call_tool_scope....ValueError","sourceNodeId":"handle_call_tool \\n[server.py : 191_337]","targetNodeId":"/src/mcpDbCapacity/src/mcpDbCapacity/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDbCapacity/src/mcpDbCapacity/server.py"},"region":{"startLine":314,"startColumn":86,"endLine":314,"endColumn":112,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 191_337]->/src/mcpDbCapacity/src/mcpDbCapacity/server.handle_call_tool.arguments.get","sourceNodeId":"handle_call_tool \\n[server.py : 191_337]","targetNodeId":"/src/mcpDbCapacity/src/mcpDbCapacity/server.handle_call_tool.arguments.get"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDbCapacity/src/mcpDbCapacity/server.py"},"region":{"startLine":208,"startColumn":27,"endLine":210,"endColumn":85,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 191_337]->get_db_node_capacity \\n[server.py : 396_434]","sourceNodeId":"handle_call_tool \\n[server.py : 191_337]","targetNodeId":"get_db_node_capacity \\n[server.py : 396_434]"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDbCapacity/src/mcpDbCapacity/server.py"},"region":{"startLine":430,"startColumn":9,"endLine":430,"endColumn":108,"snippet":{}}}},"id":"get_db_node_capacity \\n[server.py : 396_434]->syslib_from.logging.getLogger(mcp-server).info","sourceNodeId":"get_db_node_capacity \\n[server.py : 396_434]","targetNodeId":"syslib_from.logging.getLogger(mcp-server).info"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDbCapacity/src/mcpDbCapacity/server.py"},"region":{"startLine":398,"startColumn":25,"endLine":398,"endColumn":56,"snippet":{}}}},"id":"get_db_node_capacity \\n[server.py : 396_434]->mcp_db_base.ocp_client.get_cluster_arch","sourceNodeId":"get_db_node_capacity \\n[server.py : 396_434]","targetNodeId":"mcp_db_base.ocp_client.get_cluster_arch"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDbCapacity/src/mcpDbCapacity/server.py"},"region":{"startLine":431,"startColumn":16,"endLine":431,"endColumn":61,"snippet":{}}}},"id":"get_db_node_capacity \\n[server.py : 396_434]->syslib_from.json.dumps","sourceNodeId":"get_db_node_capacity \\n[server.py : 396_434]","targetNodeId":"syslib_from.json.dumps"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDbCapacity/src/mcpDbCapacity/server.py"},"region":{"startLine":433,"startColumn":9,"endLine":433,"endColumn":100,"snippet":{}}}},"id":"get_db_node_capacity \\n[server.py : 396_434]->syslib_from.logging.getLogger(mcp-server).warning","sourceNodeId":"get_db_node_capacity \\n[server.py : 396_434]","targetNodeId":"syslib_from.logging.getLogger(mcp-server).warning"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDbCapacity/src/mcpDbCapacity/server.py"},"region":{"startLine":329,"startColumn":21,"endLine":332,"endColumn":14,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 191_337]->syslib_from.mcp/types.TextContent","sourceNodeId":"handle_call_tool \\n[server.py : 191_337]","targetNodeId":"syslib_from.mcp/types.TextContent"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDbCapacity/src/mcpDbCapacity/server.py"},"region":{"startLine":217,"startColumn":23,"endLine":217,"endColumn":61,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 191_337]->/src/mcpDbCapacity/src/mcpDbCapacity/server.handle_call_tool.handle_call_tool_scope....ValueError","sourceNodeId":"handle_call_tool \\n[server.py : 191_337]","targetNodeId":"/src/mcpDbCapacity/src/mcpDbCapacity/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDbCapacity/src/mcpDbCapacity/server.py"},"region":{"startLine":220,"startColumn":23,"endLine":220,"endColumn":58,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 191_337]->/src/mcpDbCapacity/src/mcpDbCapacity/server.handle_call_tool.handle_call_tool_scope....ValueError","sourceNodeId":"handle_call_tool \\n[server.py : 191_337]","targetNodeId":"/src/mcpDbCapacity/src/mcpDbCapacity/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDbCapacity/src/mcpDbCapacity/server.py"},"region":{"startLine":222,"startColumn":27,"endLine":224,"endColumn":88,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 191_337]->get_db_node_capacity_v2 \\n[server.py : 357_363]","sourceNodeId":"handle_call_tool \\n[server.py : 191_337]","targetNodeId":"get_db_node_capacity_v2 \\n[server.py : 357_363]"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDbCapacity/src/mcpDbCapacity/server.py"},"region":{"startLine":362,"startColumn":5,"endLine":362,"endColumn":107,"snippet":{}}}},"id":"get_db_node_capacity_v2 \\n[server.py : 357_363]->syslib_from.logging.getLogger(mcp-server).info","sourceNodeId":"get_db_node_capacity_v2 \\n[server.py : 357_363]","targetNodeId":"syslib_from.logging.getLogger(mcp-server).info"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDbCapacity/src/mcpDbCapacity/server.py"},"region":{"startLine":360,"startColumn":21,"endLine":361,"endColumn":59,"snippet":{}}}},"id":"get_db_node_capacity_v2 \\n[server.py : 357_363]->mcp_db_base.prometheus_client.get_ob_capacity_monitor","sourceNodeId":"get_db_node_capacity_v2 \\n[server.py : 357_363]","targetNodeId":"mcp_db_base.prometheus_client.get_ob_capacity_monitor"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDbCapacity/src/mcpDbCapacity/server.py"},"region":{"startLine":363,"startColumn":12,"endLine":363,"endColumn":57,"snippet":{}}}},"id":"get_db_node_capacity_v2 \\n[server.py : 357_363]->syslib_from.json.dumps","sourceNodeId":"get_db_node_capacity_v2 \\n[server.py : 357_363]","targetNodeId":"syslib_from.json.dumps"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDbCapacity/src/mcpDbCapacity/server.py"},"region":{"startLine":231,"startColumn":23,"endLine":231,"endColumn":61,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 191_337]->/src/mcpDbCapacity/src/mcpDbCapacity/server.handle_call_tool.handle_call_tool_scope....ValueError","sourceNodeId":"handle_call_tool \\n[server.py : 191_337]","targetNodeId":"/src/mcpDbCapacity/src/mcpDbCapacity/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDbCapacity/src/mcpDbCapacity/server.py"},"region":{"startLine":233,"startColumn":27,"endLine":235,"endColumn":88,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 191_337]->get_db_cluster_capacity \\n[server.py : 437_446]","sourceNodeId":"handle_call_tool \\n[server.py : 191_337]","targetNodeId":"get_db_cluster_capacity \\n[server.py : 437_446]"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDbCapacity/src/mcpDbCapacity/server.py"},"region":{"startLine":442,"startColumn":9,"endLine":442,"endColumn":114,"snippet":{}}}},"id":"get_db_cluster_capacity \\n[server.py : 437_446]->syslib_from.logging.getLogger(mcp-server).info","sourceNodeId":"get_db_cluster_capacity \\n[server.py : 437_446]","targetNodeId":"syslib_from.logging.getLogger(mcp-server).info"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDbCapacity/src/mcpDbCapacity/server.py"},"region":{"startLine":439,"startColumn":25,"endLine":439,"endColumn":56,"snippet":{}}}},"id":"get_db_cluster_capacity \\n[server.py : 437_446]->mcp_db_base.ocp_client.get_cluster_arch","sourceNodeId":"get_db_cluster_capacity \\n[server.py : 437_446]","targetNodeId":"mcp_db_base.ocp_client.get_cluster_arch"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDbCapacity/src/mcpDbCapacity/server.py"},"region":{"startLine":443,"startColumn":16,"endLine":443,"endColumn":64,"snippet":{}}}},"id":"get_db_cluster_capacity \\n[server.py : 437_446]->syslib_from.json.dumps","sourceNodeId":"get_db_cluster_capacity \\n[server.py : 437_446]","targetNodeId":"syslib_from.json.dumps"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDbCapacity/src/mcpDbCapacity/server.py"},"region":{"startLine":445,"startColumn":9,"endLine":445,"endColumn":103,"snippet":{}}}},"id":"get_db_cluster_capacity \\n[server.py : 437_446]->syslib_from.logging.getLogger(mcp-server).warning","sourceNodeId":"get_db_cluster_capacity \\n[server.py : 437_446]","targetNodeId":"syslib_from.logging.getLogger(mcp-server).warning"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDbCapacity/src/mcpDbCapacity/server.py"},"region":{"startLine":242,"startColumn":23,"endLine":242,"endColumn":61,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 191_337]->/src/mcpDbCapacity/src/mcpDbCapacity/server.handle_call_tool.handle_call_tool_scope....ValueError","sourceNodeId":"handle_call_tool \\n[server.py : 191_337]","targetNodeId":"/src/mcpDbCapacity/src/mcpDbCapacity/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDbCapacity/src/mcpDbCapacity/server.py"},"region":{"startLine":244,"startColumn":27,"endLine":246,"endColumn":91,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 191_337]->get_db_cluster_capacity_v2 \\n[server.py : 366_370]","sourceNodeId":"handle_call_tool \\n[server.py : 191_337]","targetNodeId":"get_db_cluster_capacity_v2 \\n[server.py : 366_370]"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDbCapacity/src/mcpDbCapacity/server.py"},"region":{"startLine":369,"startColumn":5,"endLine":369,"endColumn":110,"snippet":{}}}},"id":"get_db_cluster_capacity_v2 \\n[server.py : 366_370]->syslib_from.logging.getLogger(mcp-server).info","sourceNodeId":"get_db_cluster_capacity_v2 \\n[server.py : 366_370]","targetNodeId":"syslib_from.logging.getLogger(mcp-server).info"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDbCapacity/src/mcpDbCapacity/server.py"},"region":{"startLine":368,"startColumn":21,"endLine":368,"endColumn":108,"snippet":{}}}},"id":"get_db_cluster_capacity_v2 \\n[server.py : 366_370]->mcp_db_base.prometheus_client.get_ob_capacity_monitor","sourceNodeId":"get_db_cluster_capacity_v2 \\n[server.py : 366_370]","targetNodeId":"mcp_db_base.prometheus_client.get_ob_capacity_monitor"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDbCapacity/src/mcpDbCapacity/server.py"},"region":{"startLine":370,"startColumn":12,"endLine":370,"endColumn":57,"snippet":{}}}},"id":"get_db_cluster_capacity_v2 \\n[server.py : 366_370]->syslib_from.json.dumps","sourceNodeId":"get_db_cluster_capacity_v2 \\n[server.py : 366_370]","targetNodeId":"syslib_from.json.dumps"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDbCapacity/src/mcpDbCapacity/server.py"},"region":{"startLine":253,"startColumn":23,"endLine":253,"endColumn":61,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 191_337]->/src/mcpDbCapacity/src/mcpDbCapacity/server.handle_call_tool.handle_call_tool_scope....ValueError","sourceNodeId":"handle_call_tool \\n[server.py : 191_337]","targetNodeId":"/src/mcpDbCapacity/src/mcpDbCapacity/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDbCapacity/src/mcpDbCapacity/server.py"},"region":{"startLine":256,"startColumn":23,"endLine":256,"endColumn":60,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 191_337]->/src/mcpDbCapacity/src/mcpDbCapacity/server.handle_call_tool.handle_call_tool_scope....ValueError","sourceNodeId":"handle_call_tool \\n[server.py : 191_337]","targetNodeId":"/src/mcpDbCapacity/src/mcpDbCapacity/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDbCapacity/src/mcpDbCapacity/server.py"},"region":{"startLine":258,"startColumn":27,"endLine":260,"endColumn":87,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 191_337]->get_db_tenant_capacity \\n[server.py : 449_524]","sourceNodeId":"handle_call_tool \\n[server.py : 191_337]","targetNodeId":"get_db_tenant_capacity \\n[server.py : 449_524]"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDbCapacity/src/mcpDbCapacity/server.py"},"region":{"startLine":523,"startColumn":5,"endLine":523,"endColumn":103,"snippet":{}}}},"id":"get_db_tenant_capacity \\n[server.py : 449_524]->syslib_from.logging.getLogger(mcp-server).info","sourceNodeId":"get_db_tenant_capacity \\n[server.py : 449_524]","targetNodeId":"syslib_from.logging.getLogger(mcp-server).info"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDbCapacity/src/mcpDbCapacity/server.py"},"region":{"startLine":452,"startColumn":25,"endLine":452,"endColumn":56,"snippet":{}}}},"id":"get_db_tenant_capacity \\n[server.py : 449_524]->mcp_db_base.ocp_client.get_cluster_arch","sourceNodeId":"get_db_tenant_capacity \\n[server.py : 449_524]","targetNodeId":"mcp_db_base.ocp_client.get_cluster_arch"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDbCapacity/src/mcpDbCapacity/server.py"},"region":{"startLine":455,"startColumn":24,"endLine":455,"endColumn":71,"snippet":{}}}},"id":"get_db_tenant_capacity \\n[server.py : 449_524]->mcp_db_base.ocp_client.get_cluster_arch(cluster).get","sourceNodeId":"get_db_tenant_capacity \\n[server.py : 449_524]","targetNodeId":"mcp_db_base.ocp_client.get_cluster_arch(cluster).get"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDbCapacity/src/mcpDbCapacity/server.py"},"region":{"startLine":460,"startColumn":29,"endLine":460,"endColumn":50,"snippet":{}}}},"id":"get_db_tenant_capacity \\n[server.py : 449_524]->/src/mcpDbCapacity/src/mcpDbCapacity/server.get_db_tenant_capacity.get_db_tenant_capacity_scope..len","sourceNodeId":"get_db_tenant_capacity \\n[server.py : 449_524]","targetNodeId":"/src/mcpDbCapacity/src/mcpDbCapacity/server.get_db_tenant_capacity.get_db_tenant_capacity_scope..len"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDbCapacity/src/mcpDbCapacity/server.py"},"region":{"startLine":466,"startColumn":9,"endLine":466,"endColumn":118,"snippet":{}}}},"id":"get_db_tenant_capacity \\n[server.py : 449_524]->syslib_from.logging.getLogger(mcp-server).warning","sourceNodeId":"get_db_tenant_capacity \\n[server.py : 449_524]","targetNodeId":"syslib_from.logging.getLogger(mcp-server).warning"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDbCapacity/src/mcpDbCapacity/server.py"},"region":{"startLine":476,"startColumn":16,"endLine":476,"endColumn":47,"snippet":{}}}},"id":"get_db_tenant_capacity \\n[server.py : 449_524]->....unit_info.keys","sourceNodeId":"get_db_tenant_capacity \\n[server.py : 449_524]","targetNodeId":"....unit_info.keys"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDbCapacity/src/mcpDbCapacity/server.py"},"region":{"startLine":521,"startColumn":57,"endLine":521,"endColumn":82,"snippet":{}}}},"id":"get_db_tenant_capacity \\n[server.py : 449_524]->cluster_server_map.keys","sourceNodeId":"get_db_tenant_capacity \\n[server.py : 449_524]","targetNodeId":"cluster_server_map.keys"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDbCapacity/src/mcpDbCapacity/server.py"},"region":{"startLine":521,"startColumn":52,"endLine":521,"endColumn":83,"snippet":{}}}},"id":"get_db_tenant_capacity \\n[server.py : 449_524]->/src/mcpDbCapacity/src/mcpDbCapacity/server.get_db_tenant_capacity.get_db_tenant_capacity_scope..list","sourceNodeId":"get_db_tenant_capacity \\n[server.py : 449_524]","targetNodeId":"/src/mcpDbCapacity/src/mcpDbCapacity/server.get_db_tenant_capacity.get_db_tenant_capacity_scope..list"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDbCapacity/src/mcpDbCapacity/server.py"},"region":{"startLine":524,"startColumn":12,"endLine":524,"endColumn":34,"snippet":{}}}},"id":"get_db_tenant_capacity \\n[server.py : 449_524]->syslib_from.json.dumps","sourceNodeId":"get_db_tenant_capacity \\n[server.py : 449_524]","targetNodeId":"syslib_from.json.dumps"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDbCapacity/src/mcpDbCapacity/server.py"},"region":{"startLine":268,"startColumn":23,"endLine":268,"endColumn":61,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 191_337]->/src/mcpDbCapacity/src/mcpDbCapacity/server.handle_call_tool.handle_call_tool_scope....ValueError","sourceNodeId":"handle_call_tool \\n[server.py : 191_337]","targetNodeId":"/src/mcpDbCapacity/src/mcpDbCapacity/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDbCapacity/src/mcpDbCapacity/server.py"},"region":{"startLine":271,"startColumn":23,"endLine":271,"endColumn":60,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 191_337]->/src/mcpDbCapacity/src/mcpDbCapacity/server.handle_call_tool.handle_call_tool_scope....ValueError","sourceNodeId":"handle_call_tool \\n[server.py : 191_337]","targetNodeId":"/src/mcpDbCapacity/src/mcpDbCapacity/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDbCapacity/src/mcpDbCapacity/server.py"},"region":{"startLine":273,"startColumn":27,"endLine":275,"endColumn":90,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 191_337]->get_db_tenant_capacity_v2 \\n[server.py : 373_393]","sourceNodeId":"handle_call_tool \\n[server.py : 191_337]","targetNodeId":"get_db_tenant_capacity_v2 \\n[server.py : 373_393]"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDbCapacity/src/mcpDbCapacity/server.py"},"region":{"startLine":392,"startColumn":5,"endLine":392,"endColumn":109,"snippet":{}}}},"id":"get_db_tenant_capacity_v2 \\n[server.py : 373_393]->syslib_from.logging.getLogger(mcp-server).info","sourceNodeId":"get_db_tenant_capacity_v2 \\n[server.py : 373_393]","targetNodeId":"syslib_from.logging.getLogger(mcp-server).info"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDbCapacity/src/mcpDbCapacity/server.py"},"region":{"startLine":376,"startColumn":25,"endLine":376,"endColumn":56,"snippet":{}}}},"id":"get_db_tenant_capacity_v2 \\n[server.py : 373_393]->mcp_db_base.ocp_client.get_cluster_arch","sourceNodeId":"get_db_tenant_capacity_v2 \\n[server.py : 373_393]","targetNodeId":"mcp_db_base.ocp_client.get_cluster_arch"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDbCapacity/src/mcpDbCapacity/server.py"},"region":{"startLine":377,"startColumn":24,"endLine":377,"endColumn":71,"snippet":{}}}},"id":"get_db_tenant_capacity_v2 \\n[server.py : 373_393]->mcp_db_base.ocp_client.get_cluster_arch(cluster).get","sourceNodeId":"get_db_tenant_capacity_v2 \\n[server.py : 373_393]","targetNodeId":"mcp_db_base.ocp_client.get_cluster_arch(cluster).get"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDbCapacity/src/mcpDbCapacity/server.py"},"region":{"startLine":382,"startColumn":25,"endLine":382,"endColumn":46,"snippet":{}}}},"id":"get_db_tenant_capacity_v2 \\n[server.py : 373_393]->mcp_db_base.ocp_client.get_cluster_arch(cluster).get(tenant_info_list, ...).get","sourceNodeId":"get_db_tenant_capacity_v2 \\n[server.py : 373_393]","targetNodeId":"mcp_db_base.ocp_client.get_cluster_arch(cluster).get(tenant_info_list, ...).get"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDbCapacity/src/mcpDbCapacity/server.py"},"region":{"startLine":383,"startColumn":28,"endLine":383,"endColumn":44,"snippet":{}}}},"id":"get_db_tenant_capacity_v2 \\n[server.py : 373_393]->mcp_db_base.ocp_client.get_cluster_arch(cluster).get(tenant_info_list, ...).get(unit_info).keys","sourceNodeId":"get_db_tenant_capacity_v2 \\n[server.py : 373_393]","targetNodeId":"mcp_db_base.ocp_client.get_cluster_arch(cluster).get(tenant_info_list, ...).get(unit_info).keys"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDbCapacity/src/mcpDbCapacity/server.py"},"region":{"startLine":386,"startColumn":9,"endLine":386,"endColumn":121,"snippet":{}}}},"id":"get_db_tenant_capacity_v2 \\n[server.py : 373_393]->syslib_from.logging.getLogger(mcp-server).warning","sourceNodeId":"get_db_tenant_capacity_v2 \\n[server.py : 373_393]","targetNodeId":"syslib_from.logging.getLogger(mcp-server).warning"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDbCapacity/src/mcpDbCapacity/server.py"},"region":{"startLine":389,"startColumn":21,"endLine":391,"endColumn":59,"snippet":{}}}},"id":"get_db_tenant_capacity_v2 \\n[server.py : 373_393]->mcp_db_base.prometheus_client.get_ob_capacity_monitor","sourceNodeId":"get_db_tenant_capacity_v2 \\n[server.py : 373_393]","targetNodeId":"mcp_db_base.prometheus_client.get_ob_capacity_monitor"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDbCapacity/src/mcpDbCapacity/server.py"},"region":{"startLine":393,"startColumn":12,"endLine":393,"endColumn":57,"snippet":{}}}},"id":"get_db_tenant_capacity_v2 \\n[server.py : 373_393]->syslib_from.json.dumps","sourceNodeId":"get_db_tenant_capacity_v2 \\n[server.py : 373_393]","targetNodeId":"syslib_from.json.dumps"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDbCapacity/src/mcpDbCapacity/server.py"},"region":{"startLine":282,"startColumn":23,"endLine":282,"endColumn":61,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 191_337]->/src/mcpDbCapacity/src/mcpDbCapacity/server.handle_call_tool.handle_call_tool_scope....ValueError","sourceNodeId":"handle_call_tool \\n[server.py : 191_337]","targetNodeId":"/src/mcpDbCapacity/src/mcpDbCapacity/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDbCapacity/src/mcpDbCapacity/server.py"},"region":{"startLine":285,"startColumn":23,"endLine":285,"endColumn":60,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 191_337]->/src/mcpDbCapacity/src/mcpDbCapacity/server.handle_call_tool.handle_call_tool_scope....ValueError","sourceNodeId":"handle_call_tool \\n[server.py : 191_337]","targetNodeId":"/src/mcpDbCapacity/src/mcpDbCapacity/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDbCapacity/src/mcpDbCapacity/server.py"},"region":{"startLine":287,"startColumn":27,"endLine":288,"endColumn":109,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 191_337]->get_db_tenant_spec \\n[server.py : 527_528]","sourceNodeId":"handle_call_tool \\n[server.py : 191_337]","targetNodeId":"get_db_tenant_spec \\n[server.py : 527_528]"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDbCapacity/src/mcpDbCapacity/server.py"},"region":{"startLine":295,"startColumn":23,"endLine":295,"endColumn":61,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 191_337]->/src/mcpDbCapacity/src/mcpDbCapacity/server.handle_call_tool.handle_call_tool_scope....ValueError","sourceNodeId":"handle_call_tool \\n[server.py : 191_337]","targetNodeId":"/src/mcpDbCapacity/src/mcpDbCapacity/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDbCapacity/src/mcpDbCapacity/server.py"},"region":{"startLine":298,"startColumn":23,"endLine":298,"endColumn":60,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 191_337]->/src/mcpDbCapacity/src/mcpDbCapacity/server.handle_call_tool.handle_call_tool_scope....ValueError","sourceNodeId":"handle_call_tool \\n[server.py : 191_337]","targetNodeId":"/src/mcpDbCapacity/src/mcpDbCapacity/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDbCapacity/src/mcpDbCapacity/server.py"},"region":{"startLine":300,"startColumn":27,"endLine":301,"endColumn":109,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 191_337]->get_db_tenant_dump \\n[server.py : 536_537]","sourceNodeId":"handle_call_tool \\n[server.py : 191_337]","targetNodeId":"get_db_tenant_dump \\n[server.py : 536_537]"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDbCapacity/src/mcpDbCapacity/server.py"},"region":{"startLine":308,"startColumn":23,"endLine":308,"endColumn":61,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 191_337]->/src/mcpDbCapacity/src/mcpDbCapacity/server.handle_call_tool.handle_call_tool_scope....ValueError","sourceNodeId":"handle_call_tool \\n[server.py : 191_337]","targetNodeId":"/src/mcpDbCapacity/src/mcpDbCapacity/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDbCapacity/src/mcpDbCapacity/server.py"},"region":{"startLine":311,"startColumn":23,"endLine":311,"endColumn":60,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 191_337]->/src/mcpDbCapacity/src/mcpDbCapacity/server.handle_call_tool.handle_call_tool_scope....ValueError","sourceNodeId":"handle_call_tool \\n[server.py : 191_337]","targetNodeId":"/src/mcpDbCapacity/src/mcpDbCapacity/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDbCapacity/src/mcpDbCapacity/server.py"},"region":{"startLine":313,"startColumn":27,"endLine":314,"endColumn":113,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 191_337]->get_db_connector_count \\n[server.py : 531_533]","sourceNodeId":"handle_call_tool \\n[server.py : 191_337]","targetNodeId":"get_db_connector_count \\n[server.py : 531_533]"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDbCapacity/src/mcpDbCapacity/server.py"},"region":{"startLine":321,"startColumn":23,"endLine":321,"endColumn":61,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 191_337]->/src/mcpDbCapacity/src/mcpDbCapacity/server.handle_call_tool.handle_call_tool_scope....ValueError","sourceNodeId":"handle_call_tool \\n[server.py : 191_337]","targetNodeId":"/src/mcpDbCapacity/src/mcpDbCapacity/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDbCapacity/src/mcpDbCapacity/server.py"},"region":{"startLine":324,"startColumn":23,"endLine":324,"endColumn":60,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 191_337]->/src/mcpDbCapacity/src/mcpDbCapacity/server.handle_call_tool.handle_call_tool_scope....ValueError","sourceNodeId":"handle_call_tool \\n[server.py : 191_337]","targetNodeId":"/src/mcpDbCapacity/src/mcpDbCapacity/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDbCapacity/src/mcpDbCapacity/server.py"},"region":{"startLine":327,"startColumn":23,"endLine":327,"endColumn":56,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 191_337]->/src/mcpDbCapacity/src/mcpDbCapacity/server.handle_call_tool.handle_call_tool_scope....ValueError","sourceNodeId":"handle_call_tool \\n[server.py : 191_337]","targetNodeId":"/src/mcpDbCapacity/src/mcpDbCapacity/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDbCapacity/src/mcpDbCapacity/server.py"},"region":{"startLine":331,"startColumn":22,"endLine":331,"endColumn":107,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 191_337]->db_capacity_evalute \\n[server.py : 540_542]","sourceNodeId":"handle_call_tool \\n[server.py : 191_337]","targetNodeId":"db_capacity_evalute \\n[server.py : 540_542]"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDbCapacity/src/mcpDbCapacity/server.py"},"region":{"startLine":335,"startColumn":19,"endLine":335,"endColumn":54,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 191_337]->/src/mcpDbCapacity/src/mcpDbCapacity/server.handle_call_tool.handle_call_tool_scope...ValueError","sourceNodeId":"handle_call_tool \\n[server.py : 191_337]","targetNodeId":"/src/mcpDbCapacity/src/mcpDbCapacity/server.handle_call_tool.handle_call_tool_scope...ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDbCapacity/src/mcpDbCapacity/server.py"},"region":{"startLine":337,"startColumn":5,"endLine":337,"endColumn":65,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 191_337]->mcp.server.Server(mcp-db-capacity).request_context.session.send_flowing_data","sourceNodeId":"handle_call_tool \\n[server.py : 191_337]","targetNodeId":"mcp.server.Server(mcp-db-capacity).request_context.session.send_flowing_data"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDbChanges/src/mcpDbChanges/server.py"},"region":{"startLine":92,"startColumn":1,"endLine":163,"endColumn":11,"snippet":{}}}},"id":"<__entry_point__>->handle_call_tool \\n[server.py : 92_163]","sourceNodeId":"<__entry_point__>","targetNodeId":"handle_call_tool \\n[server.py : 92_163]"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDbChanges/src/mcpDbChanges/server.py"},"region":{"startLine":99,"startColumn":82,"endLine":99,"endColumn":125,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 92_163]->syslib_from.json.dumps","sourceNodeId":"handle_call_tool \\n[server.py : 92_163]","targetNodeId":"syslib_from.json.dumps"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDbChanges/src/mcpDbChanges/server.py"},"region":{"startLine":151,"startColumn":17,"endLine":151,"endColumn":99,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 92_163]->syslib_from.logging.getLogger(mcp-server).info","sourceNodeId":"handle_call_tool \\n[server.py : 92_163]","targetNodeId":"syslib_from.logging.getLogger(mcp-server).info"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDbChanges/src/mcpDbChanges/server.py"},"region":{"startLine":104,"startColumn":27,"endLine":104,"endColumn":65,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 92_163]->/src/mcpDbChanges/src/mcpDbChanges/server.handle_call_tool.handle_call_tool_scope....ValueError","sourceNodeId":"handle_call_tool \\n[server.py : 92_163]","targetNodeId":"/src/mcpDbChanges/src/mcpDbChanges/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDbChanges/src/mcpDbChanges/server.py"},"region":{"startLine":107,"startColumn":27,"endLine":107,"endColumn":69,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 92_163]->/src/mcpDbChanges/src/mcpDbChanges/server.handle_call_tool.handle_call_tool_scope....ValueError","sourceNodeId":"handle_call_tool \\n[server.py : 92_163]","targetNodeId":"/src/mcpDbChanges/src/mcpDbChanges/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDbChanges/src/mcpDbChanges/server.py"},"region":{"startLine":110,"startColumn":27,"endLine":110,"endColumn":67,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 92_163]->/src/mcpDbChanges/src/mcpDbChanges/server.handle_call_tool.handle_call_tool_scope....ValueError","sourceNodeId":"handle_call_tool \\n[server.py : 92_163]","targetNodeId":"/src/mcpDbChanges/src/mcpDbChanges/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDbChanges/src/mcpDbChanges/server.py"},"region":{"startLine":115,"startColumn":59,"endLine":115,"endColumn":85,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 92_163]->/src/mcpDbChanges/src/mcpDbChanges/server.handle_call_tool.arguments.get","sourceNodeId":"handle_call_tool \\n[server.py : 92_163]","targetNodeId":"/src/mcpDbChanges/src/mcpDbChanges/server.handle_call_tool.arguments.get"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDbChanges/src/mcpDbChanges/server.py"},"region":{"startLine":112,"startColumn":31,"endLine":115,"endColumn":86,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 92_163]->mcp_db_base.tars_client.get_top_sql","sourceNodeId":"handle_call_tool \\n[server.py : 92_163]","targetNodeId":"mcp_db_base.tars_client.get_top_sql"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDbChanges/src/mcpDbChanges/server.py"},"region":{"startLine":160,"startColumn":17,"endLine":163,"endColumn":10,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 92_163]->syslib_from.mcp/types.TextContent","sourceNodeId":"handle_call_tool \\n[server.py : 92_163]","targetNodeId":"syslib_from.mcp/types.TextContent"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDbChanges/src/mcpDbChanges/server.py"},"region":{"startLine":123,"startColumn":27,"endLine":123,"endColumn":65,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 92_163]->/src/mcpDbChanges/src/mcpDbChanges/server.handle_call_tool.handle_call_tool_scope....ValueError","sourceNodeId":"handle_call_tool \\n[server.py : 92_163]","targetNodeId":"/src/mcpDbChanges/src/mcpDbChanges/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDbChanges/src/mcpDbChanges/server.py"},"region":{"startLine":126,"startColumn":27,"endLine":126,"endColumn":67,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 92_163]->/src/mcpDbChanges/src/mcpDbChanges/server.handle_call_tool.handle_call_tool_scope....ValueError","sourceNodeId":"handle_call_tool \\n[server.py : 92_163]","targetNodeId":"/src/mcpDbChanges/src/mcpDbChanges/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDbChanges/src/mcpDbChanges/server.py"},"region":{"startLine":129,"startColumn":27,"endLine":129,"endColumn":69,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 92_163]->/src/mcpDbChanges/src/mcpDbChanges/server.handle_call_tool.handle_call_tool_scope....ValueError","sourceNodeId":"handle_call_tool \\n[server.py : 92_163]","targetNodeId":"/src/mcpDbChanges/src/mcpDbChanges/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDbChanges/src/mcpDbChanges/server.py"},"region":{"startLine":132,"startColumn":27,"endLine":132,"endColumn":67,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 92_163]->/src/mcpDbChanges/src/mcpDbChanges/server.handle_call_tool.handle_call_tool_scope....ValueError","sourceNodeId":"handle_call_tool \\n[server.py : 92_163]","targetNodeId":"/src/mcpDbChanges/src/mcpDbChanges/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDbChanges/src/mcpDbChanges/server.py"},"region":{"startLine":134,"startColumn":31,"endLine":137,"endColumn":77,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 92_163]->mcp_db_base.tars_client.get_node_top_sql","sourceNodeId":"handle_call_tool \\n[server.py : 92_163]","targetNodeId":"mcp_db_base.tars_client.get_node_top_sql"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDbChanges/src/mcpDbChanges/server.py"},"region":{"startLine":145,"startColumn":27,"endLine":145,"endColumn":65,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 92_163]->/src/mcpDbChanges/src/mcpDbChanges/server.handle_call_tool.handle_call_tool_scope....ValueError","sourceNodeId":"handle_call_tool \\n[server.py : 92_163]","targetNodeId":"/src/mcpDbChanges/src/mcpDbChanges/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDbChanges/src/mcpDbChanges/server.py"},"region":{"startLine":148,"startColumn":27,"endLine":148,"endColumn":64,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 92_163]->/src/mcpDbChanges/src/mcpDbChanges/server.handle_call_tool.handle_call_tool_scope....ValueError","sourceNodeId":"handle_call_tool \\n[server.py : 92_163]","targetNodeId":"/src/mcpDbChanges/src/mcpDbChanges/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDbChanges/src/mcpDbChanges/server.py"},"region":{"startLine":150,"startColumn":31,"endLine":150,"endColumn":110,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 92_163]->mcp_db_base.tars_client.get_sql_detail_v1","sourceNodeId":"handle_call_tool \\n[server.py : 92_163]","targetNodeId":"mcp_db_base.tars_client.get_sql_detail_v1"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDbChanges/src/mcpDbChanges/server.py"},"region":{"startLine":157,"startColumn":23,"endLine":157,"endColumn":58,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 92_163]->/src/mcpDbChanges/src/mcpDbChanges/server.handle_call_tool.handle_call_tool_scope...ValueError","sourceNodeId":"handle_call_tool \\n[server.py : 92_163]","targetNodeId":"/src/mcpDbChanges/src/mcpDbChanges/server.handle_call_tool.handle_call_tool_scope...ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDbChanges/src/mcpDbChanges/server.py"},"region":{"startLine":159,"startColumn":9,"endLine":159,"endColumn":82,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 92_163]->syslib_from.logging.getLogger(mcp-server).error","sourceNodeId":"handle_call_tool \\n[server.py : 92_163]","targetNodeId":"syslib_from.logging.getLogger(mcp-server).error"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDbLog/src/mcpDbLog/server.py"},"region":{"startLine":96,"startColumn":1,"endLine":154,"endColumn":11,"snippet":{}}}},"id":"<__entry_point__>->handle_call_tool \\n[server.py : 96_154]","sourceNodeId":"<__entry_point__>","targetNodeId":"handle_call_tool \\n[server.py : 96_154]"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDbLog/src/mcpDbLog/server.py"},"region":{"startLine":104,"startColumn":65,"endLine":104,"endColumn":108,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 96_154]->syslib_from.json.dumps","sourceNodeId":"handle_call_tool \\n[server.py : 96_154]","targetNodeId":"syslib_from.json.dumps"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDbLog/src/mcpDbLog/server.py"},"region":{"startLine":139,"startColumn":17,"endLine":140,"endColumn":82,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 96_154]->syslib_from.logging.getLogger(mcp-server).info","sourceNodeId":"handle_call_tool \\n[server.py : 96_154]","targetNodeId":"syslib_from.logging.getLogger(mcp-server).info"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDbLog/src/mcpDbLog/server.py"},"region":{"startLine":109,"startColumn":27,"endLine":109,"endColumn":60,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 96_154]->/src/mcpDbLog/src/mcpDbLog/server.handle_call_tool.handle_call_tool_scope....ValueError","sourceNodeId":"handle_call_tool \\n[server.py : 96_154]","targetNodeId":"/src/mcpDbLog/src/mcpDbLog/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDbLog/src/mcpDbLog/server.py"},"region":{"startLine":133,"startColumn":17,"endLine":133,"endColumn":71,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 96_154]->_validate_arguments \\n[server.py : 89_92]","sourceNodeId":"handle_call_tool \\n[server.py : 96_154]","targetNodeId":"_validate_arguments \\n[server.py : 89_92]"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDbLog/src/mcpDbLog/server.py"},"region":{"startLine":91,"startColumn":12,"endLine":91,"endColumn":64,"snippet":{}}}},"id":"_validate_arguments \\n[server.py : 89_92]->/src/mcpDbLog/src/mcpDbLog/server._validate_arguments._validate_arguments_scope..all","sourceNodeId":"_validate_arguments \\n[server.py : 89_92]","targetNodeId":"/src/mcpDbLog/src/mcpDbLog/server._validate_arguments._validate_arguments_scope..all"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDbLog/src/mcpDbLog/server.py"},"region":{"startLine":92,"startColumn":15,"endLine":92,"endColumn":67,"snippet":{}}}},"id":"_validate_arguments \\n[server.py : 89_92]->/src/mcpDbLog/src/mcpDbLog/server._validate_arguments._validate_arguments_scope...ValueError","sourceNodeId":"_validate_arguments \\n[server.py : 89_92]","targetNodeId":"/src/mcpDbLog/src/mcpDbLog/server._validate_arguments._validate_arguments_scope...ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDbLog/src/mcpDbLog/server.py"},"region":{"startLine":112,"startColumn":31,"endLine":112,"endColumn":111,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 96_154]->antshell.get_obproxy_info_by_trace","sourceNodeId":"handle_call_tool \\n[server.py : 96_154]","targetNodeId":"antshell.get_obproxy_info_by_trace"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDbLog/src/mcpDbLog/server.py"},"region":{"startLine":151,"startColumn":17,"endLine":154,"endColumn":10,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 96_154]->syslib_from.mcp/types.TextContent","sourceNodeId":"handle_call_tool \\n[server.py : 96_154]","targetNodeId":"syslib_from.mcp/types.TextContent"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDbLog/src/mcpDbLog/server.py"},"region":{"startLine":138,"startColumn":39,"endLine":138,"endColumn":79,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 96_154]->/src/mcpDbLog/src/mcpDbLog/server.handle_call_tool.arguments.get","sourceNodeId":"handle_call_tool \\n[server.py : 96_154]","targetNodeId":"/src/mcpDbLog/src/mcpDbLog/server.handle_call_tool.arguments.get"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDbLog/src/mcpDbLog/server.py"},"region":{"startLine":122,"startColumn":31,"endLine":125,"endColumn":62,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 96_154]->antshell.get_observer_trace_by_sql","sourceNodeId":"handle_call_tool \\n[server.py : 96_154]","targetNodeId":"antshell.get_observer_trace_by_sql"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDbLog/src/mcpDbLog/server.py"},"region":{"startLine":135,"startColumn":31,"endLine":138,"endColumn":80,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 96_154]->antshell.get_observer_info_by_trace","sourceNodeId":"handle_call_tool \\n[server.py : 96_154]","targetNodeId":"antshell.get_observer_info_by_trace"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDbLog/src/mcpDbLog/server.py"},"region":{"startLine":147,"startColumn":23,"endLine":147,"endColumn":58,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 96_154]->/src/mcpDbLog/src/mcpDbLog/server.handle_call_tool.handle_call_tool_scope...ValueError","sourceNodeId":"handle_call_tool \\n[server.py : 96_154]","targetNodeId":"/src/mcpDbLog/src/mcpDbLog/server.handle_call_tool.handle_call_tool_scope...ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDbLog/src/mcpDbLog/server.py"},"region":{"startLine":149,"startColumn":9,"endLine":150,"endColumn":65,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 96_154]->syslib_from.logging.getLogger(mcp-server).exception","sourceNodeId":"handle_call_tool \\n[server.py : 96_154]","targetNodeId":"syslib_from.logging.getLogger(mcp-server).exception"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDbMeta/src/mcpDbMeta/server.py"},"region":{"startLine":173,"startColumn":1,"endLine":298,"endColumn":11,"snippet":{}}}},"id":"<__entry_point__>->handle_call_tool \\n[server.py : 173_298]","sourceNodeId":"<__entry_point__>","targetNodeId":"handle_call_tool \\n[server.py : 173_298]"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDbMeta/src/mcpDbMeta/server.py"},"region":{"startLine":282,"startColumn":31,"endLine":285,"endColumn":87,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 173_298]->syslib_from.json.dumps","sourceNodeId":"handle_call_tool \\n[server.py : 173_298]","targetNodeId":"syslib_from.json.dumps"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDbMeta/src/mcpDbMeta/server.py"},"region":{"startLine":286,"startColumn":17,"endLine":286,"endColumn":96,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 173_298]->syslib_from.logging.getLogger(mcp-server).info","sourceNodeId":"handle_call_tool \\n[server.py : 173_298]","targetNodeId":"syslib_from.logging.getLogger(mcp-server).info"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDbMeta/src/mcpDbMeta/server.py"},"region":{"startLine":186,"startColumn":27,"endLine":186,"endColumn":65,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 173_298]->/src/mcpDbMeta/src/mcpDbMeta/server.handle_call_tool.handle_call_tool_scope....ValueError","sourceNodeId":"handle_call_tool \\n[server.py : 173_298]","targetNodeId":"/src/mcpDbMeta/src/mcpDbMeta/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDbMeta/src/mcpDbMeta/server.py"},"region":{"startLine":188,"startColumn":42,"endLine":188,"endColumn":94,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 173_298]->mcp_db_base.omc_client.get_cluster_info","sourceNodeId":"handle_call_tool \\n[server.py : 173_298]","targetNodeId":"mcp_db_base.omc_client.get_cluster_info"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDbMeta/src/mcpDbMeta/server.py"},"region":{"startLine":295,"startColumn":17,"endLine":298,"endColumn":10,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 173_298]->syslib_from.mcp/types.TextContent","sourceNodeId":"handle_call_tool \\n[server.py : 173_298]","targetNodeId":"syslib_from.mcp/types.TextContent"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDbMeta/src/mcpDbMeta/server.py"},"region":{"startLine":197,"startColumn":27,"endLine":197,"endColumn":64,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 173_298]->/src/mcpDbMeta/src/mcpDbMeta/server.handle_call_tool.handle_call_tool_scope....ValueError","sourceNodeId":"handle_call_tool \\n[server.py : 173_298]","targetNodeId":"/src/mcpDbMeta/src/mcpDbMeta/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDbMeta/src/mcpDbMeta/server.py"},"region":{"startLine":284,"startColumn":69,"endLine":284,"endColumn":95,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 173_298]->/src/mcpDbMeta/src/mcpDbMeta/server.handle_call_tool.arguments.get","sourceNodeId":"handle_call_tool \\n[server.py : 173_298]","targetNodeId":"/src/mcpDbMeta/src/mcpDbMeta/server.handle_call_tool.arguments.get"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDbMeta/src/mcpDbMeta/server.py"},"region":{"startLine":199,"startColumn":42,"endLine":200,"endColumn":95,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 173_298]->mcp_db_base.omc_client.get_tenant_info","sourceNodeId":"handle_call_tool \\n[server.py : 173_298]","targetNodeId":"mcp_db_base.omc_client.get_tenant_info"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDbMeta/src/mcpDbMeta/server.py"},"region":{"startLine":208,"startColumn":27,"endLine":208,"endColumn":60,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 173_298]->/src/mcpDbMeta/src/mcpDbMeta/server.handle_call_tool.handle_call_tool_scope....ValueError","sourceNodeId":"handle_call_tool \\n[server.py : 173_298]","targetNodeId":"/src/mcpDbMeta/src/mcpDbMeta/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDbMeta/src/mcpDbMeta/server.py"},"region":{"startLine":210,"startColumn":42,"endLine":210,"endColumn":75,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 173_298]->mcp_db_base.omc_client.get_dbs","sourceNodeId":"handle_call_tool \\n[server.py : 173_298]","targetNodeId":"mcp_db_base.omc_client.get_dbs"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDbMeta/src/mcpDbMeta/server.py"},"region":{"startLine":218,"startColumn":27,"endLine":218,"endColumn":65,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 173_298]->/src/mcpDbMeta/src/mcpDbMeta/server.handle_call_tool.handle_call_tool_scope....ValueError","sourceNodeId":"handle_call_tool \\n[server.py : 173_298]","targetNodeId":"/src/mcpDbMeta/src/mcpDbMeta/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDbMeta/src/mcpDbMeta/server.py"},"region":{"startLine":220,"startColumn":42,"endLine":225,"endColumn":78,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 173_298]->mcp_db_base.prometheus_client.get_ob_merge_parameter_value","sourceNodeId":"handle_call_tool \\n[server.py : 173_298]","targetNodeId":"mcp_db_base.prometheus_client.get_ob_merge_parameter_value"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDbMeta/src/mcpDbMeta/server.py"},"region":{"startLine":241,"startColumn":27,"endLine":241,"endColumn":162,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 173_298]->/src/mcpDbMeta/src/mcpDbMeta/server.handle_call_tool.handle_call_tool_scope....ValueError","sourceNodeId":"handle_call_tool \\n[server.py : 173_298]","targetNodeId":"/src/mcpDbMeta/src/mcpDbMeta/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDbMeta/src/mcpDbMeta/server.py"},"region":{"startLine":243,"startColumn":51,"endLine":244,"endColumn":105,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 173_298]->mcp_db_base.dba_metadata_utils.get_db_meta","sourceNodeId":"handle_call_tool \\n[server.py : 173_298]","targetNodeId":"mcp_db_base.dba_metadata_utils.get_db_meta"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDbMeta/src/mcpDbMeta/server.py"},"region":{"startLine":246,"startColumn":43,"endLine":246,"endColumn":57,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 173_298]->mcp_db_base.dba_metadata_utils.get_db_meta(var app:any=app, var cluster:any=cluster, var tenant:any=tenant, var db:any=db, var table:any=table, var sql_id:any=sql_id, var server:any=server).to_dict","sourceNodeId":"handle_call_tool \\n[server.py : 173_298]","targetNodeId":"mcp_db_base.dba_metadata_utils.get_db_meta(var app:any=app, var cluster:any=cluster, var tenant:any=tenant, var db:any=db, var table:any=table, var sql_id:any=sql_id, var server:any=server).to_dict"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDbMeta/src/mcpDbMeta/server.py"},"region":{"startLine":254,"startColumn":27,"endLine":254,"endColumn":67,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 173_298]->/src/mcpDbMeta/src/mcpDbMeta/server.handle_call_tool.handle_call_tool_scope....ValueError","sourceNodeId":"handle_call_tool \\n[server.py : 173_298]","targetNodeId":"/src/mcpDbMeta/src/mcpDbMeta/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDbMeta/src/mcpDbMeta/server.py"},"region":{"startLine":256,"startColumn":42,"endLine":259,"endColumn":68,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 173_298]->mcp_db_base.omc_client.get_table_capacity","sourceNodeId":"handle_call_tool \\n[server.py : 173_298]","targetNodeId":"mcp_db_base.omc_client.get_table_capacity"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDbMeta/src/mcpDbMeta/server.py"},"region":{"startLine":267,"startColumn":27,"endLine":267,"endColumn":67,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 173_298]->/src/mcpDbMeta/src/mcpDbMeta/server.handle_call_tool.handle_call_tool_scope....ValueError","sourceNodeId":"handle_call_tool \\n[server.py : 173_298]","targetNodeId":"/src/mcpDbMeta/src/mcpDbMeta/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDbMeta/src/mcpDbMeta/server.py"},"region":{"startLine":269,"startColumn":42,"endLine":272,"endColumn":66,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 173_298]->mcp_db_base.omc_client.get_table_schema","sourceNodeId":"handle_call_tool \\n[server.py : 173_298]","targetNodeId":"mcp_db_base.omc_client.get_table_schema"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDbMeta/src/mcpDbMeta/server.py"},"region":{"startLine":280,"startColumn":27,"endLine":280,"endColumn":67,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 173_298]->/src/mcpDbMeta/src/mcpDbMeta/server.handle_call_tool.handle_call_tool_scope....ValueError","sourceNodeId":"handle_call_tool \\n[server.py : 173_298]","targetNodeId":"/src/mcpDbMeta/src/mcpDbMeta/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDbMeta/src/mcpDbMeta/server.py"},"region":{"startLine":282,"startColumn":42,"endLine":285,"endColumn":66,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 173_298]->mcp_db_base.omc_client.get_table_indexs","sourceNodeId":"handle_call_tool \\n[server.py : 173_298]","targetNodeId":"mcp_db_base.omc_client.get_table_indexs"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDbMeta/src/mcpDbMeta/server.py"},"region":{"startLine":292,"startColumn":23,"endLine":292,"endColumn":58,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 173_298]->/src/mcpDbMeta/src/mcpDbMeta/server.handle_call_tool.handle_call_tool_scope...ValueError","sourceNodeId":"handle_call_tool \\n[server.py : 173_298]","targetNodeId":"/src/mcpDbMeta/src/mcpDbMeta/server.handle_call_tool.handle_call_tool_scope...ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDbMeta/src/mcpDbMeta/server.py"},"region":{"startLine":294,"startColumn":9,"endLine":294,"endColumn":83,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 173_298]->syslib_from.logging.getLogger(mcp-server).exception","sourceNodeId":"handle_call_tool \\n[server.py : 173_298]","targetNodeId":"syslib_from.logging.getLogger(mcp-server).exception"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDbMonitor/src/mcpDbMonitor/server.py"},"region":{"startLine":322,"startColumn":1,"endLine":587,"endColumn":11,"snippet":{}}}},"id":"<__entry_point__>->handle_call_tool \\n[server.py : 322_587]","sourceNodeId":"<__entry_point__>","targetNodeId":"handle_call_tool \\n[server.py : 322_587]"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDbMonitor/src/mcpDbMonitor/server.py"},"region":{"startLine":330,"startColumn":69,"endLine":330,"endColumn":112,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 322_587]->syslib_from.json.dumps","sourceNodeId":"handle_call_tool \\n[server.py : 322_587]","targetNodeId":"syslib_from.json.dumps"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDbMonitor/src/mcpDbMonitor/server.py"},"region":{"startLine":576,"startColumn":17,"endLine":576,"endColumn":118,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 322_587]->syslib_from.logging.getLogger(mcp-server).info","sourceNodeId":"handle_call_tool \\n[server.py : 322_587]","targetNodeId":"syslib_from.logging.getLogger(mcp-server).info"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDbMonitor/src/mcpDbMonitor/server.py"},"region":{"startLine":570,"startColumn":17,"endLine":570,"endColumn":37,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 322_587]->validate_arguments \\n[server.py : 331_353]","sourceNodeId":"handle_call_tool \\n[server.py : 322_587]","targetNodeId":"validate_arguments \\n[server.py : 331_353]"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDbMonitor/src/mcpDbMonitor/server.py"},"region":{"startLine":333,"startColumn":19,"endLine":333,"endColumn":69,"snippet":{}}}},"id":"validate_arguments \\n[server.py : 331_353]->/src/mcpDbMonitor/src/mcpDbMonitor/server.handle_call_tool.handle_call_tool_scope..validate_arguments.validate_arguments_scope...ValueErr...","sourceNodeId":"validate_arguments \\n[server.py : 331_353]","targetNodeId":"/src/mcpDbMonitor/src/mcpDbMonitor/server.handle_call_tool.handle_call_tool_scope..validate_arguments.validate_arguments_scope...ValueErr..."},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDbMonitor/src/mcpDbMonitor/server.py"},"region":{"startLine":335,"startColumn":19,"endLine":335,"endColumn":67,"snippet":{}}}},"id":"validate_arguments \\n[server.py : 331_353]->/src/mcpDbMonitor/src/mcpDbMonitor/server.handle_call_tool.handle_call_tool_scope..validate_arguments.validate_arguments_scope...ValueErr...","sourceNodeId":"validate_arguments \\n[server.py : 331_353]","targetNodeId":"/src/mcpDbMonitor/src/mcpDbMonitor/server.handle_call_tool.handle_call_tool_scope..validate_arguments.validate_arguments_scope...ValueErr..."},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDbMonitor/src/mcpDbMonitor/server.py"},"region":{"startLine":347,"startColumn":37,"endLine":347,"endColumn":57,"snippet":{}}}},"id":"validate_arguments \\n[server.py : 331_353]->/src/mcpDbMonitor/src/mcpDbMonitor/server.handle_call_tool.arguments.get","sourceNodeId":"validate_arguments \\n[server.py : 331_353]","targetNodeId":"/src/mcpDbMonitor/src/mcpDbMonitor/server.handle_call_tool.arguments.get"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDbMonitor/src/mcpDbMonitor/server.py"},"region":{"startLine":347,"startColumn":19,"endLine":347,"endColumn":71,"snippet":{}}}},"id":"validate_arguments \\n[server.py : 331_353]->datetime.datetime.strptime","sourceNodeId":"validate_arguments \\n[server.py : 331_353]","targetNodeId":"datetime.datetime.strptime"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDbMonitor/src/mcpDbMonitor/server.py"},"region":{"startLine":345,"startColumn":95,"endLine":345,"endColumn":103,"snippet":{}}}},"id":"validate_arguments \\n[server.py : 331_353]->/src/mcpDbMonitor/src/mcpDbMonitor/server.handle_call_tool.handle_call_tool_scope..validate_arguments.validate_arguments_scope...str","sourceNodeId":"validate_arguments \\n[server.py : 331_353]","targetNodeId":"/src/mcpDbMonitor/src/mcpDbMonitor/server.handle_call_tool.handle_call_tool_scope..validate_arguments.validate_arguments_scope...str"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDbMonitor/src/mcpDbMonitor/server.py"},"region":{"startLine":345,"startColumn":19,"endLine":345,"endColumn":105,"snippet":{}}}},"id":"validate_arguments \\n[server.py : 331_353]->/src/mcpDbMonitor/src/mcpDbMonitor/server.handle_call_tool.handle_call_tool_scope..validate_arguments.validate_arguments_scope...ValueErr...","sourceNodeId":"validate_arguments \\n[server.py : 331_353]","targetNodeId":"/src/mcpDbMonitor/src/mcpDbMonitor/server.handle_call_tool.handle_call_tool_scope..validate_arguments.validate_arguments_scope...ValueErr..."},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDbMonitor/src/mcpDbMonitor/server.py"},"region":{"startLine":349,"startColumn":93,"endLine":349,"endColumn":101,"snippet":{}}}},"id":"validate_arguments \\n[server.py : 331_353]->/src/mcpDbMonitor/src/mcpDbMonitor/server.handle_call_tool.handle_call_tool_scope..validate_arguments.validate_arguments_scope...str","sourceNodeId":"validate_arguments \\n[server.py : 331_353]","targetNodeId":"/src/mcpDbMonitor/src/mcpDbMonitor/server.handle_call_tool.handle_call_tool_scope..validate_arguments.validate_arguments_scope...str"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDbMonitor/src/mcpDbMonitor/server.py"},"region":{"startLine":349,"startColumn":19,"endLine":349,"endColumn":103,"snippet":{}}}},"id":"validate_arguments \\n[server.py : 331_353]->/src/mcpDbMonitor/src/mcpDbMonitor/server.handle_call_tool.handle_call_tool_scope..validate_arguments.validate_arguments_scope...ValueErr...","sourceNodeId":"validate_arguments \\n[server.py : 331_353]","targetNodeId":"/src/mcpDbMonitor/src/mcpDbMonitor/server.handle_call_tool.handle_call_tool_scope..validate_arguments.validate_arguments_scope...ValueErr..."},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDbMonitor/src/mcpDbMonitor/server.py"},"region":{"startLine":352,"startColumn":20,"endLine":352,"endColumn":41,"snippet":{}}}},"id":"validate_arguments \\n[server.py : 331_353]->datetime.timedelta","sourceNodeId":"validate_arguments \\n[server.py : 331_353]","targetNodeId":"datetime.timedelta"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDbMonitor/src/mcpDbMonitor/server.py"},"region":{"startLine":353,"startColumn":19,"endLine":353,"endColumn":99,"snippet":{}}}},"id":"validate_arguments \\n[server.py : 331_353]->/src/mcpDbMonitor/src/mcpDbMonitor/server.handle_call_tool.handle_call_tool_scope..validate_arguments.validate_arguments_scope...ValueErr...","sourceNodeId":"validate_arguments \\n[server.py : 331_353]","targetNodeId":"/src/mcpDbMonitor/src/mcpDbMonitor/server.handle_call_tool.handle_call_tool_scope..validate_arguments.validate_arguments_scope...ValueErr..."},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDbMonitor/src/mcpDbMonitor/server.py"},"region":{"startLine":478,"startColumn":26,"endLine":478,"endColumn":49,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 322_587]->/src/mcpDbMonitor/src/mcpDbMonitor/server.handle_call_tool.arguments.get","sourceNodeId":"handle_call_tool \\n[server.py : 322_587]","targetNodeId":"/src/mcpDbMonitor/src/mcpDbMonitor/server.handle_call_tool.arguments.get"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDbMonitor/src/mcpDbMonitor/server.py"},"region":{"startLine":362,"startColumn":27,"endLine":362,"endColumn":75,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 322_587]->/src/mcpDbMonitor/src/mcpDbMonitor/server.handle_call_tool.handle_call_tool_scope....ValueError","sourceNodeId":"handle_call_tool \\n[server.py : 322_587]","targetNodeId":"/src/mcpDbMonitor/src/mcpDbMonitor/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDbMonitor/src/mcpDbMonitor/server.py"},"region":{"startLine":364,"startColumn":31,"endLine":367,"endColumn":76,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 322_587]->mcp_db_base.db_monitor_client.get_tqps","sourceNodeId":"handle_call_tool \\n[server.py : 322_587]","targetNodeId":"mcp_db_base.db_monitor_client.get_tqps"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDbMonitor/src/mcpDbMonitor/server.py"},"region":{"startLine":584,"startColumn":17,"endLine":587,"endColumn":10,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 322_587]->syslib_from.mcp/types.TextContent","sourceNodeId":"handle_call_tool \\n[server.py : 322_587]","targetNodeId":"syslib_from.mcp/types.TextContent"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDbMonitor/src/mcpDbMonitor/server.py"},"region":{"startLine":378,"startColumn":27,"endLine":378,"endColumn":75,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 322_587]->/src/mcpDbMonitor/src/mcpDbMonitor/server.handle_call_tool.handle_call_tool_scope....ValueError","sourceNodeId":"handle_call_tool \\n[server.py : 322_587]","targetNodeId":"/src/mcpDbMonitor/src/mcpDbMonitor/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDbMonitor/src/mcpDbMonitor/server.py"},"region":{"startLine":380,"startColumn":31,"endLine":383,"endColumn":74,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 322_587]->mcp_db_base.db_monitor_client.get_rt","sourceNodeId":"handle_call_tool \\n[server.py : 322_587]","targetNodeId":"mcp_db_base.db_monitor_client.get_rt"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDbMonitor/src/mcpDbMonitor/server.py"},"region":{"startLine":395,"startColumn":27,"endLine":395,"endColumn":75,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 322_587]->/src/mcpDbMonitor/src/mcpDbMonitor/server.handle_call_tool.handle_call_tool_scope....ValueError","sourceNodeId":"handle_call_tool \\n[server.py : 322_587]","targetNodeId":"/src/mcpDbMonitor/src/mcpDbMonitor/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDbMonitor/src/mcpDbMonitor/server.py"},"region":{"startLine":397,"startColumn":31,"endLine":400,"endColumn":81,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 322_587]->mcp_db_base.db_monitor_client.get_sql_count","sourceNodeId":"handle_call_tool \\n[server.py : 322_587]","targetNodeId":"mcp_db_base.db_monitor_client.get_sql_count"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDbMonitor/src/mcpDbMonitor/server.py"},"region":{"startLine":412,"startColumn":27,"endLine":412,"endColumn":75,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 322_587]->/src/mcpDbMonitor/src/mcpDbMonitor/server.handle_call_tool.handle_call_tool_scope....ValueError","sourceNodeId":"handle_call_tool \\n[server.py : 322_587]","targetNodeId":"/src/mcpDbMonitor/src/mcpDbMonitor/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDbMonitor/src/mcpDbMonitor/server.py"},"region":{"startLine":414,"startColumn":31,"endLine":417,"endColumn":78,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 322_587]->mcp_db_base.db_monitor_client.get_sql_rt","sourceNodeId":"handle_call_tool \\n[server.py : 322_587]","targetNodeId":"mcp_db_base.db_monitor_client.get_sql_rt"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDbMonitor/src/mcpDbMonitor/server.py"},"region":{"startLine":429,"startColumn":27,"endLine":429,"endColumn":75,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 322_587]->/src/mcpDbMonitor/src/mcpDbMonitor/server.handle_call_tool.handle_call_tool_scope....ValueError","sourceNodeId":"handle_call_tool \\n[server.py : 322_587]","targetNodeId":"/src/mcpDbMonitor/src/mcpDbMonitor/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDbMonitor/src/mcpDbMonitor/server.py"},"region":{"startLine":431,"startColumn":31,"endLine":434,"endColumn":82,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 322_587]->mcp_db_base.db_monitor_client.get_logic_read","sourceNodeId":"handle_call_tool \\n[server.py : 322_587]","targetNodeId":"mcp_db_base.db_monitor_client.get_logic_read"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDbMonitor/src/mcpDbMonitor/server.py"},"region":{"startLine":446,"startColumn":27,"endLine":446,"endColumn":75,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 322_587]->/src/mcpDbMonitor/src/mcpDbMonitor/server.handle_call_tool.handle_call_tool_scope....ValueError","sourceNodeId":"handle_call_tool \\n[server.py : 322_587]","targetNodeId":"/src/mcpDbMonitor/src/mcpDbMonitor/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDbMonitor/src/mcpDbMonitor/server.py"},"region":{"startLine":448,"startColumn":31,"endLine":451,"endColumn":81,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 322_587]->mcp_db_base.db_monitor_client.get_cpu_usage","sourceNodeId":"handle_call_tool \\n[server.py : 322_587]","targetNodeId":"mcp_db_base.db_monitor_client.get_cpu_usage"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDbMonitor/src/mcpDbMonitor/server.py"},"region":{"startLine":462,"startColumn":27,"endLine":462,"endColumn":75,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 322_587]->/src/mcpDbMonitor/src/mcpDbMonitor/server.handle_call_tool.handle_call_tool_scope....ValueError","sourceNodeId":"handle_call_tool \\n[server.py : 322_587]","targetNodeId":"/src/mcpDbMonitor/src/mcpDbMonitor/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDbMonitor/src/mcpDbMonitor/server.py"},"region":{"startLine":464,"startColumn":26,"endLine":469,"endColumn":18,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 322_587]->mcp_db_base.db_monitor_client.get_storage_layer_row_count","sourceNodeId":"handle_call_tool \\n[server.py : 322_587]","targetNodeId":"mcp_db_base.db_monitor_client.get_storage_layer_row_count"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDbMonitor/src/mcpDbMonitor/server.py"},"region":{"startLine":480,"startColumn":27,"endLine":480,"endColumn":75,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 322_587]->/src/mcpDbMonitor/src/mcpDbMonitor/server.handle_call_tool.handle_call_tool_scope....ValueError","sourceNodeId":"handle_call_tool \\n[server.py : 322_587]","targetNodeId":"/src/mcpDbMonitor/src/mcpDbMonitor/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDbMonitor/src/mcpDbMonitor/server.py"},"region":{"startLine":482,"startColumn":26,"endLine":487,"endColumn":18,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 322_587]->mcp_db_base.db_monitor_client.get_clog_process_time","sourceNodeId":"handle_call_tool \\n[server.py : 322_587]","targetNodeId":"mcp_db_base.db_monitor_client.get_clog_process_time"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDbMonitor/src/mcpDbMonitor/server.py"},"region":{"startLine":508,"startColumn":26,"endLine":513,"endColumn":18,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 322_587]->mcp_db_base.db_monitor_client.get_server_cpu","sourceNodeId":"handle_call_tool \\n[server.py : 322_587]","targetNodeId":"mcp_db_base.db_monitor_client.get_server_cpu"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDbMonitor/src/mcpDbMonitor/server.py"},"region":{"startLine":534,"startColumn":26,"endLine":539,"endColumn":18,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 322_587]->mcp_db_base.db_monitor_client.get_server_load","sourceNodeId":"handle_call_tool \\n[server.py : 322_587]","targetNodeId":"mcp_db_base.db_monitor_client.get_server_load"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDbMonitor/src/mcpDbMonitor/server.py"},"region":{"startLine":547,"startColumn":26,"endLine":551,"endColumn":18,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 322_587]->mcp_db_base.db_monitor_client.get_nc_ntp_offset","sourceNodeId":"handle_call_tool \\n[server.py : 322_587]","targetNodeId":"mcp_db_base.db_monitor_client.get_nc_ntp_offset"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDbMonitor/src/mcpDbMonitor/server.py"},"region":{"startLine":559,"startColumn":26,"endLine":563,"endColumn":18,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 322_587]->mcp_db_base.db_monitor_client.get_server_tenant_tqps_monitor","sourceNodeId":"handle_call_tool \\n[server.py : 322_587]","targetNodeId":"mcp_db_base.db_monitor_client.get_server_tenant_tqps_monitor"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDbMonitor/src/mcpDbMonitor/server.py"},"region":{"startLine":571,"startColumn":26,"endLine":575,"endColumn":18,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 322_587]->mcp_db_base.db_monitor_client.get_server_tenant_rt_monitor","sourceNodeId":"handle_call_tool \\n[server.py : 322_587]","targetNodeId":"mcp_db_base.db_monitor_client.get_server_tenant_rt_monitor"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDbMonitor/src/mcpDbMonitor/server.py"},"region":{"startLine":581,"startColumn":23,"endLine":581,"endColumn":58,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 322_587]->/src/mcpDbMonitor/src/mcpDbMonitor/server.handle_call_tool.handle_call_tool_scope...ValueError","sourceNodeId":"handle_call_tool \\n[server.py : 322_587]","targetNodeId":"/src/mcpDbMonitor/src/mcpDbMonitor/server.handle_call_tool.handle_call_tool_scope...ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDbMonitor/src/mcpDbMonitor/server.py"},"region":{"startLine":583,"startColumn":9,"endLine":583,"endColumn":86,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 322_587]->syslib_from.logging.getLogger(mcp-server).exception","sourceNodeId":"handle_call_tool \\n[server.py : 322_587]","targetNodeId":"syslib_from.logging.getLogger(mcp-server).exception"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDbOdc/src/mcpDbOdc/server.py"},"region":{"startLine":74,"startColumn":1,"endLine":108,"endColumn":80,"snippet":{}}}},"id":"<__entry_point__>->handle_call_tool \\n[server.py : 74_108]","sourceNodeId":"<__entry_point__>","targetNodeId":"handle_call_tool \\n[server.py : 74_108]"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDbOdc/src/mcpDbOdc/server.py"},"region":{"startLine":82,"startColumn":65,"endLine":82,"endColumn":108,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 74_108]->syslib_from.json.dumps","sourceNodeId":"handle_call_tool \\n[server.py : 74_108]","targetNodeId":"syslib_from.json.dumps"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDbOdc/src/mcpDbOdc/server.py"},"region":{"startLine":99,"startColumn":17,"endLine":99,"endColumn":93,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 74_108]->syslib_from.logging.getLogger(mcp-server).info","sourceNodeId":"handle_call_tool \\n[server.py : 74_108]","targetNodeId":"syslib_from.logging.getLogger(mcp-server).info"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDbOdc/src/mcpDbOdc/server.py"},"region":{"startLine":85,"startColumn":19,"endLine":85,"endColumn":51,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 74_108]->/src/mcpDbOdc/src/mcpDbOdc/server.handle_call_tool.handle_call_tool_scope...ValueError","sourceNodeId":"handle_call_tool \\n[server.py : 74_108]","targetNodeId":"/src/mcpDbOdc/src/mcpDbOdc/server.handle_call_tool.handle_call_tool_scope...ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDbOdc/src/mcpDbOdc/server.py"},"region":{"startLine":89,"startColumn":17,"endLine":89,"endColumn":96,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 74_108]->_validate_arguments \\n[server.py : 67_70]","sourceNodeId":"handle_call_tool \\n[server.py : 74_108]","targetNodeId":"_validate_arguments \\n[server.py : 67_70]"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDbOdc/src/mcpDbOdc/server.py"},"region":{"startLine":69,"startColumn":12,"endLine":69,"endColumn":64,"snippet":{}}}},"id":"_validate_arguments \\n[server.py : 67_70]->/src/mcpDbOdc/src/mcpDbOdc/server._validate_arguments._validate_arguments_scope..all","sourceNodeId":"_validate_arguments \\n[server.py : 67_70]","targetNodeId":"/src/mcpDbOdc/src/mcpDbOdc/server._validate_arguments._validate_arguments_scope..all"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDbOdc/src/mcpDbOdc/server.py"},"region":{"startLine":70,"startColumn":15,"endLine":70,"endColumn":67,"snippet":{}}}},"id":"_validate_arguments \\n[server.py : 67_70]->/src/mcpDbOdc/src/mcpDbOdc/server._validate_arguments._validate_arguments_scope...ValueError","sourceNodeId":"_validate_arguments \\n[server.py : 67_70]","targetNodeId":"/src/mcpDbOdc/src/mcpDbOdc/server._validate_arguments._validate_arguments_scope...ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDbOdc/src/mcpDbOdc/server.py"},"region":{"startLine":97,"startColumn":25,"endLine":97,"endColumn":53,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 74_108]->/src/mcpDbOdc/src/mcpDbOdc/server.handle_call_tool.arguments.get","sourceNodeId":"handle_call_tool \\n[server.py : 74_108]","targetNodeId":"/src/mcpDbOdc/src/mcpDbOdc/server.handle_call_tool.arguments.get"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDbOdc/src/mcpDbOdc/server.py"},"region":{"startLine":90,"startColumn":26,"endLine":98,"endColumn":18,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 74_108]->odc_client.create_apply_order","sourceNodeId":"handle_call_tool \\n[server.py : 74_108]","targetNodeId":"odc_client.create_apply_order"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDbOdc/src/mcpDbOdc/server.py"},"region":{"startLine":108,"startColumn":17,"endLine":108,"endColumn":79,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 74_108]->syslib_from.mcp/types.TextContent","sourceNodeId":"handle_call_tool \\n[server.py : 74_108]","targetNodeId":"syslib_from.mcp/types.TextContent"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDbOdc/src/mcpDbOdc/server.py"},"region":{"startLine":104,"startColumn":23,"endLine":104,"endColumn":58,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 74_108]->/src/mcpDbOdc/src/mcpDbOdc/server.handle_call_tool.handle_call_tool_scope...ValueError","sourceNodeId":"handle_call_tool \\n[server.py : 74_108]","targetNodeId":"/src/mcpDbOdc/src/mcpDbOdc/server.handle_call_tool.handle_call_tool_scope...ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDbOdc/src/mcpDbOdc/server.py"},"region":{"startLine":107,"startColumn":9,"endLine":107,"endColumn":82,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 74_108]->syslib_from.logging.getLogger(mcp-server).exception","sourceNodeId":"handle_call_tool \\n[server.py : 74_108]","targetNodeId":"syslib_from.logging.getLogger(mcp-server).exception"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDbOdc/src/mcpDbOdc/server.py"},"region":{"startLine":108,"startColumn":69,"endLine":108,"endColumn":77,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 74_108]->str","sourceNodeId":"handle_call_tool \\n[server.py : 74_108]","targetNodeId":"str"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDbQuery/src/mcpDbQuery/server.py"},"region":{"startLine":209,"startColumn":1,"endLine":310,"endColumn":67,"snippet":{}}}},"id":"<__entry_point__>->handle_call_tool \\n[server.py : 209_310]","sourceNodeId":"<__entry_point__>","targetNodeId":"handle_call_tool \\n[server.py : 209_310]"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDbQuery/src/mcpDbQuery/server.py"},"region":{"startLine":223,"startColumn":23,"endLine":223,"endColumn":54,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 209_310]->/src/mcpDbQuery/src/mcpDbQuery/server.handle_call_tool.handle_call_tool_scope....ValueError","sourceNodeId":"handle_call_tool \\n[server.py : 209_310]","targetNodeId":"/src/mcpDbQuery/src/mcpDbQuery/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDbQuery/src/mcpDbQuery/server.py"},"region":{"startLine":225,"startColumn":23,"endLine":225,"endColumn":63,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 209_310]->/src/mcpDbQuery/src/mcpDbQuery/server.handle_call_tool.handle_call_tool_scope....ValueError","sourceNodeId":"handle_call_tool \\n[server.py : 209_310]","targetNodeId":"/src/mcpDbQuery/src/mcpDbQuery/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDbQuery/src/mcpDbQuery/server.py"},"region":{"startLine":305,"startColumn":65,"endLine":305,"endColumn":91,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 209_310]->/src/mcpDbQuery/src/mcpDbQuery/server.handle_call_tool.arguments.get","sourceNodeId":"handle_call_tool \\n[server.py : 209_310]","targetNodeId":"/src/mcpDbQuery/src/mcpDbQuery/server.handle_call_tool.arguments.get"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDbQuery/src/mcpDbQuery/server.py"},"region":{"startLine":304,"startColumn":27,"endLine":305,"endColumn":92,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 209_310]->syslib_from.client.query_db","sourceNodeId":"handle_call_tool \\n[server.py : 209_310]","targetNodeId":"syslib_from.client.query_db"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDbQuery/src/mcpDbQuery/server.py"},"region":{"startLine":231,"startColumn":23,"endLine":231,"endColumn":54,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 209_310]->/src/mcpDbQuery/src/mcpDbQuery/server.handle_call_tool.handle_call_tool_scope....ValueError","sourceNodeId":"handle_call_tool \\n[server.py : 209_310]","targetNodeId":"/src/mcpDbQuery/src/mcpDbQuery/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDbQuery/src/mcpDbQuery/server.py"},"region":{"startLine":233,"startColumn":23,"endLine":233,"endColumn":63,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 209_310]->/src/mcpDbQuery/src/mcpDbQuery/server.handle_call_tool.handle_call_tool_scope....ValueError","sourceNodeId":"handle_call_tool \\n[server.py : 209_310]","targetNodeId":"/src/mcpDbQuery/src/mcpDbQuery/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDbQuery/src/mcpDbQuery/server.py"},"region":{"startLine":292,"startColumn":20,"endLine":292,"endColumn":55,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 209_310]->is_valid_app \\n[server.py : 217_218]","sourceNodeId":"handle_call_tool \\n[server.py : 209_310]","targetNodeId":"is_valid_app \\n[server.py : 217_218]"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDbQuery/src/mcpDbQuery/server.py"},"region":{"startLine":218,"startColumn":21,"endLine":218,"endColumn":56,"snippet":{}}}},"id":"is_valid_app \\n[server.py : 217_218]->syslib_from.re.fullmatch","sourceNodeId":"is_valid_app \\n[server.py : 217_218]","targetNodeId":"syslib_from.re.fullmatch"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDbQuery/src/mcpDbQuery/server.py"},"region":{"startLine":218,"startColumn":16,"endLine":218,"endColumn":57,"snippet":{}}}},"id":"is_valid_app \\n[server.py : 217_218]->/src/mcpDbQuery/src/mcpDbQuery/server.handle_call_tool.handle_call_tool_scope..is_valid_app.is_valid_app_scope..bool","sourceNodeId":"is_valid_app \\n[server.py : 217_218]","targetNodeId":"/src/mcpDbQuery/src/mcpDbQuery/server.handle_call_tool.handle_call_tool_scope..is_valid_app.is_valid_app_scope..bool"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDbQuery/src/mcpDbQuery/server.py"},"region":{"startLine":235,"startColumn":23,"endLine":235,"endColumn":53,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 209_310]->/src/mcpDbQuery/src/mcpDbQuery/server.handle_call_tool.handle_call_tool_scope....ValueError","sourceNodeId":"handle_call_tool \\n[server.py : 209_310]","targetNodeId":"/src/mcpDbQuery/src/mcpDbQuery/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDbQuery/src/mcpDbQuery/server.py"},"region":{"startLine":295,"startColumn":19,"endLine":295,"endColumn":33,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 209_310]->datetime.datetime.now","sourceNodeId":"handle_call_tool \\n[server.py : 209_310]","targetNodeId":"datetime.datetime.now"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDbQuery/src/mcpDbQuery/server.py"},"region":{"startLine":300,"startColumn":37,"endLine":300,"endColumn":54,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 209_310]->datetime.timedelta","sourceNodeId":"handle_call_tool \\n[server.py : 209_310]","targetNodeId":"datetime.timedelta"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDbQuery/src/mcpDbQuery/server.py"},"region":{"startLine":243,"startColumn":31,"endLine":243,"endColumn":61,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 209_310]->/src/mcpDbQuery/src/mcpDbQuery/server.handle_call_tool.handle_call_tool_scope...target_date.strftime","sourceNodeId":"handle_call_tool \\n[server.py : 209_310]","targetNodeId":"/src/mcpDbQuery/src/mcpDbQuery/server.handle_call_tool.handle_call_tool_scope...target_date.strftime"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDbQuery/src/mcpDbQuery/server.py"},"region":{"startLine":265,"startColumn":44,"endLine":265,"endColumn":82,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 209_310]->/src/mcpDbQuery/src/mcpDbQuery/server.handle_call_tool.handle_call_tool_scope...str","sourceNodeId":"handle_call_tool \\n[server.py : 209_310]","targetNodeId":"/src/mcpDbQuery/src/mcpDbQuery/server.handle_call_tool.handle_call_tool_scope...str"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDbQuery/src/mcpDbQuery/server.py"},"region":{"startLine":251,"startColumn":13,"endLine":251,"endColumn":89,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 209_310]->syslib_from.logging.getLogger(mcp-server).info","sourceNodeId":"handle_call_tool \\n[server.py : 209_310]","targetNodeId":"syslib_from.logging.getLogger(mcp-server).info"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDbQuery/src/mcpDbQuery/server.py"},"region":{"startLine":251,"startColumn":66,"endLine":251,"endColumn":88,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 209_310]->syslib_from.json.dumps","sourceNodeId":"handle_call_tool \\n[server.py : 209_310]","targetNodeId":"syslib_from.json.dumps"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDbQuery/src/mcpDbQuery/server.py"},"region":{"startLine":269,"startColumn":23,"endLine":269,"endColumn":54,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 209_310]->/src/mcpDbQuery/src/mcpDbQuery/server.handle_call_tool.handle_call_tool_scope....ValueError","sourceNodeId":"handle_call_tool \\n[server.py : 209_310]","targetNodeId":"/src/mcpDbQuery/src/mcpDbQuery/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDbQuery/src/mcpDbQuery/server.py"},"region":{"startLine":271,"startColumn":23,"endLine":271,"endColumn":63,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 209_310]->/src/mcpDbQuery/src/mcpDbQuery/server.handle_call_tool.handle_call_tool_scope....ValueError","sourceNodeId":"handle_call_tool \\n[server.py : 209_310]","targetNodeId":"/src/mcpDbQuery/src/mcpDbQuery/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDbQuery/src/mcpDbQuery/server.py"},"region":{"startLine":273,"startColumn":23,"endLine":273,"endColumn":53,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 209_310]->/src/mcpDbQuery/src/mcpDbQuery/server.handle_call_tool.handle_call_tool_scope....ValueError","sourceNodeId":"handle_call_tool \\n[server.py : 209_310]","targetNodeId":"/src/mcpDbQuery/src/mcpDbQuery/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDbQuery/src/mcpDbQuery/server.py"},"region":{"startLine":281,"startColumn":31,"endLine":281,"endColumn":61,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 209_310]->/src/mcpDbQuery/src/mcpDbQuery/server.handle_call_tool.handle_call_tool_scope...target_date.strftime","sourceNodeId":"handle_call_tool \\n[server.py : 209_310]","targetNodeId":"/src/mcpDbQuery/src/mcpDbQuery/server.handle_call_tool.handle_call_tool_scope...target_date.strftime"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDbQuery/src/mcpDbQuery/server.py"},"region":{"startLine":289,"startColumn":23,"endLine":289,"endColumn":54,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 209_310]->/src/mcpDbQuery/src/mcpDbQuery/server.handle_call_tool.handle_call_tool_scope....ValueError","sourceNodeId":"handle_call_tool \\n[server.py : 209_310]","targetNodeId":"/src/mcpDbQuery/src/mcpDbQuery/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDbQuery/src/mcpDbQuery/server.py"},"region":{"startLine":291,"startColumn":23,"endLine":291,"endColumn":63,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 209_310]->/src/mcpDbQuery/src/mcpDbQuery/server.handle_call_tool.handle_call_tool_scope....ValueError","sourceNodeId":"handle_call_tool \\n[server.py : 209_310]","targetNodeId":"/src/mcpDbQuery/src/mcpDbQuery/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDbQuery/src/mcpDbQuery/server.py"},"region":{"startLine":293,"startColumn":23,"endLine":293,"endColumn":53,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 209_310]->/src/mcpDbQuery/src/mcpDbQuery/server.handle_call_tool.handle_call_tool_scope....ValueError","sourceNodeId":"handle_call_tool \\n[server.py : 209_310]","targetNodeId":"/src/mcpDbQuery/src/mcpDbQuery/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDbQuery/src/mcpDbQuery/server.py"},"region":{"startLine":301,"startColumn":31,"endLine":301,"endColumn":61,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 209_310]->/src/mcpDbQuery/src/mcpDbQuery/server.handle_call_tool.handle_call_tool_scope...target_date.strftime","sourceNodeId":"handle_call_tool \\n[server.py : 209_310]","targetNodeId":"/src/mcpDbQuery/src/mcpDbQuery/server.handle_call_tool.handle_call_tool_scope...target_date.strftime"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDbQuery/src/mcpDbQuery/server.py"},"region":{"startLine":307,"startColumn":27,"endLine":307,"endColumn":44,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 209_310]->get_mcp_headers \\n[server.py : 25_32]","sourceNodeId":"handle_call_tool \\n[server.py : 209_310]","targetNodeId":"get_mcp_headers \\n[server.py : 25_32]"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDbQuery/src/mcpDbQuery/server.py"},"region":{"startLine":26,"startColumn":19,"endLine":26,"endColumn":73,"snippet":{}}}},"id":"get_mcp_headers \\n[server.py : 25_32]->mcp.server.Server(mcp-db-query).request_context.meta.model_extra.get","sourceNodeId":"get_mcp_headers \\n[server.py : 25_32]","targetNodeId":"mcp.server.Server(mcp-db-query).request_context.meta.model_extra.get"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDbQuery/src/mcpDbQuery/server.py"},"region":{"startLine":30,"startColumn":17,"endLine":30,"endColumn":34,"snippet":{}}}},"id":"get_mcp_headers \\n[server.py : 25_32]->mcp.server.Server(mcp-db-query).request_context.meta.model_extra.get(headers).decode","sourceNodeId":"get_mcp_headers \\n[server.py : 25_32]","targetNodeId":"mcp.server.Server(mcp-db-query).request_context.meta.model_extra.get(headers).decode"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDbQuery/src/mcpDbQuery/server.py"},"region":{"startLine":29,"startColumn":15,"endLine":29,"endColumn":40,"snippet":{}}}},"id":"get_mcp_headers \\n[server.py : 25_32]->mcp.server.Server(mcp-db-query).request_context.meta.model_extra.get(headers).decode(utf-8).lower","sourceNodeId":"get_mcp_headers \\n[server.py : 25_32]","targetNodeId":"mcp.server.Server(mcp-db-query).request_context.meta.model_extra.get(headers).decode(utf-8).lower"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDbQuery/src/mcpDbQuery/server.py"},"region":{"startLine":309,"startColumn":19,"endLine":309,"endColumn":54,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 209_310]->/src/mcpDbQuery/src/mcpDbQuery/server.handle_call_tool.handle_call_tool_scope...ValueError","sourceNodeId":"handle_call_tool \\n[server.py : 209_310]","targetNodeId":"/src/mcpDbQuery/src/mcpDbQuery/server.handle_call_tool.handle_call_tool_scope...ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDbQuery/src/mcpDbQuery/server.py"},"region":{"startLine":310,"startColumn":13,"endLine":310,"endColumn":66,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 209_310]->syslib_from.mcp/types.TextContent","sourceNodeId":"handle_call_tool \\n[server.py : 209_310]","targetNodeId":"syslib_from.mcp/types.TextContent"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDbQueryPrivate/src/mcpDbQueryPrivate/server.py"},"region":{"startLine":27,"startColumn":1,"endLine":38,"endColumn":92,"snippet":{}}}},"id":"<__entry_point__>->query_specific_db \\n[server.py : 27_38]","sourceNodeId":"<__entry_point__>","targetNodeId":"query_specific_db \\n[server.py : 27_38]"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDbQueryPrivate/src/mcpDbQueryPrivate/server.py"},"region":{"startLine":35,"startColumn":64,"endLine":35,"endColumn":91,"snippet":{}}}},"id":"query_specific_db \\n[server.py : 27_38]->WHITE_PROD_DB.get","sourceNodeId":"query_specific_db \\n[server.py : 27_38]","targetNodeId":"WHITE_PROD_DB.get"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDbQueryPrivate/src/mcpDbQueryPrivate/server.py"},"region":{"startLine":35,"startColumn":16,"endLine":36,"endColumn":72,"snippet":{}}}},"id":"query_specific_db \\n[server.py : 27_38]->_query_physic_db \\n[server.py : 64_90]","sourceNodeId":"query_specific_db \\n[server.py : 27_38]","targetNodeId":"_query_physic_db \\n[server.py : 64_90]"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDbQueryPrivate/src/mcpDbQueryPrivate/server.py"},"region":{"startLine":71,"startColumn":26,"endLine":71,"endColumn":51,"snippet":{}}}},"id":"_query_physic_db \\n[server.py : 64_90]->DB_CONFIG.get","sourceNodeId":"_query_physic_db \\n[server.py : 64_90]","targetNodeId":"DB_CONFIG.get"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDbQueryPrivate/src/mcpDbQueryPrivate/server.py"},"region":{"startLine":66,"startColumn":22,"endLine":66,"endColumn":90,"snippet":{}}}},"id":"_query_physic_db \\n[server.py : 64_90]->get_pysql_user_name \\n[server.py : 93_115]","sourceNodeId":"_query_physic_db \\n[server.py : 64_90]","targetNodeId":"get_pysql_user_name \\n[server.py : 93_115]"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDbQueryPrivate/src/mcpDbQueryPrivate/server.py"},"region":{"startLine":95,"startColumn":22,"endLine":95,"endColumn":54,"snippet":{}}}},"id":"get_pysql_user_name \\n[server.py : 93_115]->mcp_db_base.omc_client.get_physic_dbs","sourceNodeId":"get_pysql_user_name \\n[server.py : 93_115]","targetNodeId":"mcp_db_base.omc_client.get_physic_dbs"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDbQueryPrivate/src/mcpDbQueryPrivate/server.py"},"region":{"startLine":96,"startColumn":12,"endLine":96,"endColumn":27,"snippet":{}}}},"id":"get_pysql_user_name \\n[server.py : 93_115]->/src/mcpDbQueryPrivate/src/mcpDbQueryPrivate/server.get_pysql_user_name.get_pysql_user_name_scope..len","sourceNodeId":"get_pysql_user_name \\n[server.py : 93_115]","targetNodeId":"/src/mcpDbQueryPrivate/src/mcpDbQueryPrivate/server.get_pysql_user_name.get_pysql_user_name_scope..len"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDbQueryPrivate/src/mcpDbQueryPrivate/server.py"},"region":{"startLine":97,"startColumn":19,"endLine":97,"endColumn":68,"snippet":{}}}},"id":"get_pysql_user_name \\n[server.py : 93_115]->/src/mcpDbQueryPrivate/src/mcpDbQueryPrivate/server.get_pysql_user_name.get_pysql_user_name_scope...Exception","sourceNodeId":"get_pysql_user_name \\n[server.py : 93_115]","targetNodeId":"/src/mcpDbQueryPrivate/src/mcpDbQueryPrivate/server.get_pysql_user_name.get_pysql_user_name_scope...Exception"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDbQueryPrivate/src/mcpDbQueryPrivate/server.py"},"region":{"startLine":99,"startColumn":22,"endLine":99,"endColumn":54,"snippet":{}}}},"id":"get_pysql_user_name \\n[server.py : 93_115]->mcp_db_base.omc_client.get_physic_dbs(var arn:any=db_arn).get","sourceNodeId":"get_pysql_user_name \\n[server.py : 93_115]","targetNodeId":"mcp_db_base.omc_client.get_physic_dbs(var arn:any=db_arn).get"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDbQueryPrivate/src/mcpDbQueryPrivate/server.py"},"region":{"startLine":101,"startColumn":19,"endLine":101,"endColumn":68,"snippet":{}}}},"id":"get_pysql_user_name \\n[server.py : 93_115]->/src/mcpDbQueryPrivate/src/mcpDbQueryPrivate/server.get_pysql_user_name.get_pysql_user_name_scope...Exception","sourceNodeId":"get_pysql_user_name \\n[server.py : 93_115]","targetNodeId":"/src/mcpDbQueryPrivate/src/mcpDbQueryPrivate/server.get_pysql_user_name.get_pysql_user_name_scope...Exception"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDbQueryPrivate/src/mcpDbQueryPrivate/server.py"},"region":{"startLine":102,"startColumn":23,"endLine":102,"endColumn":63,"snippet":{}}}},"id":"get_pysql_user_name \\n[server.py : 93_115]->mcp_db_base.omc_client.get_tenant_info","sourceNodeId":"get_pysql_user_name \\n[server.py : 93_115]","targetNodeId":"mcp_db_base.omc_client.get_tenant_info"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDbQueryPrivate/src/mcpDbQueryPrivate/server.py"},"region":{"startLine":106,"startColumn":23,"endLine":106,"endColumn":58,"snippet":{}}}},"id":"get_pysql_user_name \\n[server.py : 93_115]->mcp_db_base.omc_client.get_tenant_info(var tenant:any=tenant_arn).get","sourceNodeId":"get_pysql_user_name \\n[server.py : 93_115]","targetNodeId":"mcp_db_base.omc_client.get_tenant_info(var tenant:any=tenant_arn).get"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDbQueryPrivate/src/mcpDbQueryPrivate/server.py"},"region":{"startLine":104,"startColumn":19,"endLine":104,"endColumn":75,"snippet":{}}}},"id":"get_pysql_user_name \\n[server.py : 93_115]->/src/mcpDbQueryPrivate/src/mcpDbQueryPrivate/server.get_pysql_user_name.get_pysql_user_name_scope...Exception","sourceNodeId":"get_pysql_user_name \\n[server.py : 93_115]","targetNodeId":"/src/mcpDbQueryPrivate/src/mcpDbQueryPrivate/server.get_pysql_user_name.get_pysql_user_name_scope...Exception"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDbQueryPrivate/src/mcpDbQueryPrivate/server.py"},"region":{"startLine":108,"startColumn":19,"endLine":108,"endColumn":75,"snippet":{}}}},"id":"get_pysql_user_name \\n[server.py : 93_115]->/src/mcpDbQueryPrivate/src/mcpDbQueryPrivate/server.get_pysql_user_name.get_pysql_user_name_scope...Exception","sourceNodeId":"get_pysql_user_name \\n[server.py : 93_115]","targetNodeId":"/src/mcpDbQueryPrivate/src/mcpDbQueryPrivate/server.get_pysql_user_name.get_pysql_user_name_scope...Exception"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDbQueryPrivate/src/mcpDbQueryPrivate/server.py"},"region":{"startLine":109,"startColumn":24,"endLine":109,"endColumn":74,"snippet":{}}}},"id":"get_pysql_user_name \\n[server.py : 93_115]->mcp_db_base.omc_client.get_cluster_info_v2","sourceNodeId":"get_pysql_user_name \\n[server.py : 93_115]","targetNodeId":"mcp_db_base.omc_client.get_cluster_info_v2"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDbQueryPrivate/src/mcpDbQueryPrivate/server.py"},"region":{"startLine":112,"startColumn":24,"endLine":112,"endColumn":55,"snippet":{}}}},"id":"get_pysql_user_name \\n[server.py : 93_115]->mcp_db_base.omc_client.get_cluster_info_v2(var cluster_arn:any=cluster_arn).get","sourceNodeId":"get_pysql_user_name \\n[server.py : 93_115]","targetNodeId":"mcp_db_base.omc_client.get_cluster_info_v2(var cluster_arn:any=cluster_arn).get"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDbQueryPrivate/src/mcpDbQueryPrivate/server.py"},"region":{"startLine":111,"startColumn":19,"endLine":111,"endColumn":78,"snippet":{}}}},"id":"get_pysql_user_name \\n[server.py : 93_115]->/src/mcpDbQueryPrivate/src/mcpDbQueryPrivate/server.get_pysql_user_name.get_pysql_user_name_scope...Exception","sourceNodeId":"get_pysql_user_name \\n[server.py : 93_115]","targetNodeId":"/src/mcpDbQueryPrivate/src/mcpDbQueryPrivate/server.get_pysql_user_name.get_pysql_user_name_scope...Exception"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDbQueryPrivate/src/mcpDbQueryPrivate/server.py"},"region":{"startLine":115,"startColumn":15,"endLine":115,"endColumn":54,"snippet":{}}}},"id":"get_pysql_user_name \\n[server.py : 93_115]->/src/mcpDbQueryPrivate/src/mcpDbQueryPrivate/server.get_pysql_user_name.get_pysql_user_name_scope...Exception","sourceNodeId":"get_pysql_user_name \\n[server.py : 93_115]","targetNodeId":"/src/mcpDbQueryPrivate/src/mcpDbQueryPrivate/server.get_pysql_user_name.get_pysql_user_name_scope...Exception"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDbQueryPrivate/src/mcpDbQueryPrivate/server.py"},"region":{"startLine":69,"startColumn":22,"endLine":69,"endColumn":48,"snippet":{}}}},"id":"_query_physic_db \\n[server.py : 64_90]->/src/mcpDbQueryPrivate/src/mcpDbQueryPrivate/server._query_physic_db._query_physic_db_scope..int","sourceNodeId":"_query_physic_db \\n[server.py : 64_90]","targetNodeId":"/src/mcpDbQueryPrivate/src/mcpDbQueryPrivate/server._query_physic_db._query_physic_db_scope..int"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDbQueryPrivate/src/mcpDbQueryPrivate/server.py"},"region":{"startLine":67,"startColumn":14,"endLine":75,"endColumn":10,"snippet":{}}}},"id":"_query_physic_db \\n[server.py : 64_90]->syslib_from.pymysql.connect","sourceNodeId":"_query_physic_db \\n[server.py : 64_90]","targetNodeId":"syslib_from.pymysql.connect"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDbQueryPrivate/src/mcpDbQueryPrivate/server.py"},"region":{"startLine":81,"startColumn":30,"endLine":81,"endColumn":47,"snippet":{}}}},"id":"_query_physic_db \\n[server.py : 64_90]->syslib_from.pymysql.connect(var host:any=db_config.get(host), var port:any=int(db_config.get(port)), var user:any=pysql_user, var password:any=db_config.get(password), var database:any=db_name, var ch...","sourceNodeId":"_query_physic_db \\n[server.py : 64_90]","targetNodeId":"syslib_from.pymysql.connect(var host:any=db_config.get(host), var port:any=int(db_config.get(port)), var user:any=pysql_user, var password:any=db_config.get(password), var database:any=db_name, var ch..."},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDbQueryPrivate/src/mcpDbQueryPrivate/server.py"},"region":{"startLine":89,"startColumn":15,"endLine":89,"endColumn":64,"snippet":{}}}},"id":"_query_physic_db \\n[server.py : 64_90]->/src/mcpDbQueryPrivate/src/mcpDbQueryPrivate/server._query_physic_db._query_physic_db_scope...ValueError","sourceNodeId":"_query_physic_db \\n[server.py : 64_90]","targetNodeId":"/src/mcpDbQueryPrivate/src/mcpDbQueryPrivate/server._query_physic_db._query_physic_db_scope...ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDbQueryPrivate/src/mcpDbQueryPrivate/server.py"},"region":{"startLine":38,"startColumn":53,"endLine":38,"endColumn":75,"snippet":{}}}},"id":"query_specific_db \\n[server.py : 27_38]->WHITE_PROD_DB.keys","sourceNodeId":"query_specific_db \\n[server.py : 27_38]","targetNodeId":"WHITE_PROD_DB.keys"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDbQueryPrivate/src/mcpDbQueryPrivate/server.py"},"region":{"startLine":38,"startColumn":15,"endLine":38,"endColumn":92,"snippet":{}}}},"id":"query_specific_db \\n[server.py : 27_38]->/src/mcpDbQueryPrivate/src/mcpDbQueryPrivate/server.query_specific_db.query_specific_db_scope...Exception","sourceNodeId":"query_specific_db \\n[server.py : 27_38]","targetNodeId":"/src/mcpDbQueryPrivate/src/mcpDbQueryPrivate/server.query_specific_db.query_specific_db_scope...Exception"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDbQueryPrivate/src/mcpDbQueryPrivate/server.py"},"region":{"startLine":42,"startColumn":1,"endLine":49,"endColumn":63,"snippet":{}}}},"id":"<__entry_point__>->query_layotto_db \\n[server.py : 42_49]","sourceNodeId":"<__entry_point__>","targetNodeId":"query_layotto_db \\n[server.py : 42_49]"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDbQueryPrivate/src/mcpDbQueryPrivate/server.py"},"region":{"startLine":49,"startColumn":12,"endLine":49,"endColumn":63,"snippet":{}}}},"id":"query_layotto_db \\n[server.py : 42_49]->_query_layotto_db \\n[server.py : 52_61]","sourceNodeId":"query_layotto_db \\n[server.py : 42_49]","targetNodeId":"_query_layotto_db \\n[server.py : 52_61]"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDbQueryPrivate/src/mcpDbQueryPrivate/server.py"},"region":{"startLine":53,"startColumn":18,"endLine":53,"endColumn":46,"snippet":{}}}},"id":"_query_layotto_db \\n[server.py : 52_61]->layotto_turbo.layotto.init_mysql","sourceNodeId":"_query_layotto_db \\n[server.py : 52_61]","targetNodeId":"layotto_turbo.layotto.init_mysql"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDbQueryPrivate/src/mcpDbQueryPrivate/server.py"},"region":{"startLine":55,"startColumn":14,"endLine":55,"endColumn":33,"snippet":{}}}},"id":"_query_layotto_db \\n[server.py : 52_61]->layotto_turbo.layotto.init_mysql(database).cursor","sourceNodeId":"_query_layotto_db \\n[server.py : 52_61]","targetNodeId":"layotto_turbo.layotto.init_mysql(database).cursor"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDbQueryPrivate/src/mcpDbQueryPrivate/server.py"},"region":{"startLine":57,"startColumn":13,"endLine":57,"endColumn":32,"snippet":{}}}},"id":"_query_layotto_db \\n[server.py : 52_61]->layotto_turbo.layotto.init_mysql(database).cursor().execute","sourceNodeId":"_query_layotto_db \\n[server.py : 52_61]","targetNodeId":"layotto_turbo.layotto.init_mysql(database).cursor().execute"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDbQueryPrivate/src/mcpDbQueryPrivate/server.py"},"region":{"startLine":58,"startColumn":22,"endLine":58,"endColumn":39,"snippet":{}}}},"id":"_query_layotto_db \\n[server.py : 52_61]->layotto_turbo.layotto.init_mysql(database).cursor().fetchall","sourceNodeId":"_query_layotto_db \\n[server.py : 52_61]","targetNodeId":"layotto_turbo.layotto.init_mysql(database).cursor().fetchall"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDbQueryPrivate/src/mcpDbQueryPrivate/server.py"},"region":{"startLine":61,"startColumn":15,"endLine":61,"endColumn":52,"snippet":{}}}},"id":"_query_layotto_db \\n[server.py : 52_61]->/src/mcpDbQueryPrivate/src/mcpDbQueryPrivate/server._query_layotto_db._query_layotto_db_scope...Exception","sourceNodeId":"_query_layotto_db \\n[server.py : 52_61]","targetNodeId":"/src/mcpDbQueryPrivate/src/mcpDbQueryPrivate/server._query_layotto_db._query_layotto_db_scope...Exception"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDbSql/src/mcpDbSql/server.py"},"region":{"startLine":164,"startColumn":1,"endLine":317,"endColumn":11,"snippet":{}}}},"id":"<__entry_point__>->handle_call_tool \\n[server.py : 164_317]","sourceNodeId":"<__entry_point__>","targetNodeId":"handle_call_tool \\n[server.py : 164_317]"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDbSql/src/mcpDbSql/server.py"},"region":{"startLine":307,"startColumn":26,"endLine":307,"endColumn":69,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 164_317]->syslib_from.json.dumps","sourceNodeId":"handle_call_tool \\n[server.py : 164_317]","targetNodeId":"syslib_from.json.dumps"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDbSql/src/mcpDbSql/server.py"},"region":{"startLine":304,"startColumn":17,"endLine":304,"endColumn":95,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 164_317]->syslib_from.logging.getLogger(mcp-server).info","sourceNodeId":"handle_call_tool \\n[server.py : 164_317]","targetNodeId":"syslib_from.logging.getLogger(mcp-server).info"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDbSql/src/mcpDbSql/server.py"},"region":{"startLine":303,"startColumn":127,"endLine":303,"endColumn":150,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 164_317]->/src/mcpDbSql/src/mcpDbSql/server.handle_call_tool.arguments.get","sourceNodeId":"handle_call_tool \\n[server.py : 164_317]","targetNodeId":"/src/mcpDbSql/src/mcpDbSql/server.handle_call_tool.arguments.get"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDbSql/src/mcpDbSql/server.py"},"region":{"startLine":183,"startColumn":27,"endLine":183,"endColumn":72,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 164_317]->/src/mcpDbSql/src/mcpDbSql/server.handle_call_tool.handle_call_tool_scope....ValueError","sourceNodeId":"handle_call_tool \\n[server.py : 164_317]","targetNodeId":"/src/mcpDbSql/src/mcpDbSql/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDbSql/src/mcpDbSql/server.py"},"region":{"startLine":186,"startColumn":27,"endLine":186,"endColumn":69,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 164_317]->/src/mcpDbSql/src/mcpDbSql/server.handle_call_tool.handle_call_tool_scope....ValueError","sourceNodeId":"handle_call_tool \\n[server.py : 164_317]","targetNodeId":"/src/mcpDbSql/src/mcpDbSql/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDbSql/src/mcpDbSql/server.py"},"region":{"startLine":189,"startColumn":27,"endLine":189,"endColumn":67,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 164_317]->/src/mcpDbSql/src/mcpDbSql/server.handle_call_tool.handle_call_tool_scope....ValueError","sourceNodeId":"handle_call_tool \\n[server.py : 164_317]","targetNodeId":"/src/mcpDbSql/src/mcpDbSql/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDbSql/src/mcpDbSql/server.py"},"region":{"startLine":191,"startColumn":31,"endLine":195,"endColumn":79,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 164_317]->mcp_db_base.tars_client.get_top_sql","sourceNodeId":"handle_call_tool \\n[server.py : 164_317]","targetNodeId":"mcp_db_base.tars_client.get_top_sql"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDbSql/src/mcpDbSql/server.py"},"region":{"startLine":314,"startColumn":17,"endLine":317,"endColumn":10,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 164_317]->syslib_from.mcp/types.TextContent","sourceNodeId":"handle_call_tool \\n[server.py : 164_317]","targetNodeId":"syslib_from.mcp/types.TextContent"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDbSql/src/mcpDbSql/server.py"},"region":{"startLine":203,"startColumn":27,"endLine":203,"endColumn":65,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 164_317]->/src/mcpDbSql/src/mcpDbSql/server.handle_call_tool.handle_call_tool_scope....ValueError","sourceNodeId":"handle_call_tool \\n[server.py : 164_317]","targetNodeId":"/src/mcpDbSql/src/mcpDbSql/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDbSql/src/mcpDbSql/server.py"},"region":{"startLine":206,"startColumn":27,"endLine":206,"endColumn":67,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 164_317]->/src/mcpDbSql/src/mcpDbSql/server.handle_call_tool.handle_call_tool_scope....ValueError","sourceNodeId":"handle_call_tool \\n[server.py : 164_317]","targetNodeId":"/src/mcpDbSql/src/mcpDbSql/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDbSql/src/mcpDbSql/server.py"},"region":{"startLine":209,"startColumn":27,"endLine":209,"endColumn":69,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 164_317]->/src/mcpDbSql/src/mcpDbSql/server.handle_call_tool.handle_call_tool_scope....ValueError","sourceNodeId":"handle_call_tool \\n[server.py : 164_317]","targetNodeId":"/src/mcpDbSql/src/mcpDbSql/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDbSql/src/mcpDbSql/server.py"},"region":{"startLine":212,"startColumn":27,"endLine":212,"endColumn":67,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 164_317]->/src/mcpDbSql/src/mcpDbSql/server.handle_call_tool.handle_call_tool_scope....ValueError","sourceNodeId":"handle_call_tool \\n[server.py : 164_317]","targetNodeId":"/src/mcpDbSql/src/mcpDbSql/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDbSql/src/mcpDbSql/server.py"},"region":{"startLine":214,"startColumn":31,"endLine":217,"endColumn":71,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 164_317]->mcp_db_base.tars_client.get_node_top_sql","sourceNodeId":"handle_call_tool \\n[server.py : 164_317]","targetNodeId":"mcp_db_base.tars_client.get_node_top_sql"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDbSql/src/mcpDbSql/server.py"},"region":{"startLine":225,"startColumn":27,"endLine":225,"endColumn":64,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 164_317]->/src/mcpDbSql/src/mcpDbSql/server.handle_call_tool.handle_call_tool_scope....ValueError","sourceNodeId":"handle_call_tool \\n[server.py : 164_317]","targetNodeId":"/src/mcpDbSql/src/mcpDbSql/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDbSql/src/mcpDbSql/server.py"},"region":{"startLine":227,"startColumn":31,"endLine":227,"endColumn":79,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 164_317]->mcp_db_base.tars_client.get_sql_detail","sourceNodeId":"handle_call_tool \\n[server.py : 164_317]","targetNodeId":"mcp_db_base.tars_client.get_sql_detail"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDbSql/src/mcpDbSql/server.py"},"region":{"startLine":235,"startColumn":27,"endLine":235,"endColumn":65,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 164_317]->/src/mcpDbSql/src/mcpDbSql/server.handle_call_tool.handle_call_tool_scope....ValueError","sourceNodeId":"handle_call_tool \\n[server.py : 164_317]","targetNodeId":"/src/mcpDbSql/src/mcpDbSql/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDbSql/src/mcpDbSql/server.py"},"region":{"startLine":238,"startColumn":27,"endLine":238,"endColumn":64,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 164_317]->/src/mcpDbSql/src/mcpDbSql/server.handle_call_tool.handle_call_tool_scope....ValueError","sourceNodeId":"handle_call_tool \\n[server.py : 164_317]","targetNodeId":"/src/mcpDbSql/src/mcpDbSql/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDbSql/src/mcpDbSql/server.py"},"region":{"startLine":241,"startColumn":27,"endLine":241,"endColumn":64,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 164_317]->/src/mcpDbSql/src/mcpDbSql/server.handle_call_tool.handle_call_tool_scope....ValueError","sourceNodeId":"handle_call_tool \\n[server.py : 164_317]","targetNodeId":"/src/mcpDbSql/src/mcpDbSql/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDbSql/src/mcpDbSql/server.py"},"region":{"startLine":243,"startColumn":31,"endLine":244,"endColumn":81,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 164_317]->mcp_db_base.tars_client.get_sql_plan","sourceNodeId":"handle_call_tool \\n[server.py : 164_317]","targetNodeId":"mcp_db_base.tars_client.get_sql_plan"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDbSql/src/mcpDbSql/server.py"},"region":{"startLine":252,"startColumn":27,"endLine":252,"endColumn":65,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 164_317]->/src/mcpDbSql/src/mcpDbSql/server.handle_call_tool.handle_call_tool_scope....ValueError","sourceNodeId":"handle_call_tool \\n[server.py : 164_317]","targetNodeId":"/src/mcpDbSql/src/mcpDbSql/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDbSql/src/mcpDbSql/server.py"},"region":{"startLine":255,"startColumn":27,"endLine":255,"endColumn":64,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 164_317]->/src/mcpDbSql/src/mcpDbSql/server.handle_call_tool.handle_call_tool_scope....ValueError","sourceNodeId":"handle_call_tool \\n[server.py : 164_317]","targetNodeId":"/src/mcpDbSql/src/mcpDbSql/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDbSql/src/mcpDbSql/server.py"},"region":{"startLine":258,"startColumn":27,"endLine":258,"endColumn":69,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 164_317]->/src/mcpDbSql/src/mcpDbSql/server.handle_call_tool.handle_call_tool_scope....ValueError","sourceNodeId":"handle_call_tool \\n[server.py : 164_317]","targetNodeId":"/src/mcpDbSql/src/mcpDbSql/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDbSql/src/mcpDbSql/server.py"},"region":{"startLine":261,"startColumn":27,"endLine":261,"endColumn":67,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 164_317]->/src/mcpDbSql/src/mcpDbSql/server.handle_call_tool.handle_call_tool_scope....ValueError","sourceNodeId":"handle_call_tool \\n[server.py : 164_317]","targetNodeId":"/src/mcpDbSql/src/mcpDbSql/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDbSql/src/mcpDbSql/server.py"},"region":{"startLine":263,"startColumn":31,"endLine":264,"endColumn":77,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 164_317]->mcp_db_base.tars_client.get_hot_account","sourceNodeId":"handle_call_tool \\n[server.py : 164_317]","targetNodeId":"mcp_db_base.tars_client.get_hot_account"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDbSql/src/mcpDbSql/server.py"},"region":{"startLine":272,"startColumn":27,"endLine":272,"endColumn":65,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 164_317]->/src/mcpDbSql/src/mcpDbSql/server.handle_call_tool.handle_call_tool_scope....ValueError","sourceNodeId":"handle_call_tool \\n[server.py : 164_317]","targetNodeId":"/src/mcpDbSql/src/mcpDbSql/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDbSql/src/mcpDbSql/server.py"},"region":{"startLine":275,"startColumn":27,"endLine":275,"endColumn":64,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 164_317]->/src/mcpDbSql/src/mcpDbSql/server.handle_call_tool.handle_call_tool_scope....ValueError","sourceNodeId":"handle_call_tool \\n[server.py : 164_317]","targetNodeId":"/src/mcpDbSql/src/mcpDbSql/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDbSql/src/mcpDbSql/server.py"},"region":{"startLine":278,"startColumn":27,"endLine":278,"endColumn":64,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 164_317]->/src/mcpDbSql/src/mcpDbSql/server.handle_call_tool.handle_call_tool_scope....ValueError","sourceNodeId":"handle_call_tool \\n[server.py : 164_317]","targetNodeId":"/src/mcpDbSql/src/mcpDbSql/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDbSql/src/mcpDbSql/server.py"},"region":{"startLine":281,"startColumn":27,"endLine":281,"endColumn":69,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 164_317]->/src/mcpDbSql/src/mcpDbSql/server.handle_call_tool.handle_call_tool_scope....ValueError","sourceNodeId":"handle_call_tool \\n[server.py : 164_317]","targetNodeId":"/src/mcpDbSql/src/mcpDbSql/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDbSql/src/mcpDbSql/server.py"},"region":{"startLine":284,"startColumn":27,"endLine":284,"endColumn":67,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 164_317]->/src/mcpDbSql/src/mcpDbSql/server.handle_call_tool.handle_call_tool_scope....ValueError","sourceNodeId":"handle_call_tool \\n[server.py : 164_317]","targetNodeId":"/src/mcpDbSql/src/mcpDbSql/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDbSql/src/mcpDbSql/server.py"},"region":{"startLine":286,"startColumn":31,"endLine":287,"endColumn":77,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 164_317]->mcp_db_base.tars_client.get_sql_quota","sourceNodeId":"handle_call_tool \\n[server.py : 164_317]","targetNodeId":"mcp_db_base.tars_client.get_sql_quota"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDbSql/src/mcpDbSql/server.py"},"region":{"startLine":295,"startColumn":27,"endLine":295,"endColumn":65,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 164_317]->/src/mcpDbSql/src/mcpDbSql/server.handle_call_tool.handle_call_tool_scope....ValueError","sourceNodeId":"handle_call_tool \\n[server.py : 164_317]","targetNodeId":"/src/mcpDbSql/src/mcpDbSql/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDbSql/src/mcpDbSql/server.py"},"region":{"startLine":298,"startColumn":27,"endLine":298,"endColumn":64,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 164_317]->/src/mcpDbSql/src/mcpDbSql/server.handle_call_tool.handle_call_tool_scope....ValueError","sourceNodeId":"handle_call_tool \\n[server.py : 164_317]","targetNodeId":"/src/mcpDbSql/src/mcpDbSql/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDbSql/src/mcpDbSql/server.py"},"region":{"startLine":301,"startColumn":27,"endLine":301,"endColumn":64,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 164_317]->/src/mcpDbSql/src/mcpDbSql/server.handle_call_tool.handle_call_tool_scope....ValueError","sourceNodeId":"handle_call_tool \\n[server.py : 164_317]","targetNodeId":"/src/mcpDbSql/src/mcpDbSql/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDbSql/src/mcpDbSql/server.py"},"region":{"startLine":303,"startColumn":31,"endLine":303,"endColumn":151,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 164_317]->mcp_db_base.tars_client.get_sql_plan_his","sourceNodeId":"handle_call_tool \\n[server.py : 164_317]","targetNodeId":"mcp_db_base.tars_client.get_sql_plan_his"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDbSql/src/mcpDbSql/server.py"},"region":{"startLine":311,"startColumn":23,"endLine":311,"endColumn":58,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 164_317]->/src/mcpDbSql/src/mcpDbSql/server.handle_call_tool.handle_call_tool_scope...ValueError","sourceNodeId":"handle_call_tool \\n[server.py : 164_317]","targetNodeId":"/src/mcpDbSql/src/mcpDbSql/server.handle_call_tool.handle_call_tool_scope...ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDbSql/src/mcpDbSql/server.py"},"region":{"startLine":313,"startColumn":9,"endLine":313,"endColumn":78,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 164_317]->syslib_from.logging.getLogger(mcp-server).error","sourceNodeId":"handle_call_tool \\n[server.py : 164_317]","targetNodeId":"syslib_from.logging.getLogger(mcp-server).error"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDima/src/mcpDima/server.py"},"region":{"startLine":232,"startColumn":1,"endLine":314,"endColumn":68,"snippet":{}}}},"id":"<__entry_point__>->handle_call_tool \\n[server.py : 232_314]","sourceNodeId":"<__entry_point__>","targetNodeId":"handle_call_tool \\n[server.py : 232_314]"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDima/src/mcpDima/server.py"},"region":{"startLine":240,"startColumn":63,"endLine":240,"endColumn":106,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 232_314]->syslib_from.json.dumps","sourceNodeId":"handle_call_tool \\n[server.py : 232_314]","targetNodeId":"syslib_from.json.dumps"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDima/src/mcpDima/server.py"},"region":{"startLine":239,"startColumn":5,"endLine":240,"endColumn":108,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 232_314]->syslib_from.logging.getLogger(mcp-server).info","sourceNodeId":"handle_call_tool \\n[server.py : 232_314]","targetNodeId":"syslib_from.logging.getLogger(mcp-server).info"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDima/src/mcpDima/server.py"},"region":{"startLine":245,"startColumn":27,"endLine":245,"endColumn":58,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 232_314]->/src/mcpDima/src/mcpDima/server.handle_call_tool.handle_call_tool_scope....ValueError","sourceNodeId":"handle_call_tool \\n[server.py : 232_314]","targetNodeId":"/src/mcpDima/src/mcpDima/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDima/src/mcpDima/server.py"},"region":{"startLine":247,"startColumn":27,"endLine":247,"endColumn":68,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 232_314]->/src/mcpDima/src/mcpDima/server.handle_call_tool.handle_call_tool_scope....ValueError","sourceNodeId":"handle_call_tool \\n[server.py : 232_314]","targetNodeId":"/src/mcpDima/src/mcpDima/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDima/src/mcpDima/server.py"},"region":{"startLine":248,"startColumn":31,"endLine":248,"endColumn":92,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 232_314]->syslib_from.client.get_space_detail","sourceNodeId":"handle_call_tool \\n[server.py : 232_314]","targetNodeId":"syslib_from.client.get_space_detail"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDima/src/mcpDima/server.py"},"region":{"startLine":251,"startColumn":27,"endLine":251,"endColumn":58,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 232_314]->/src/mcpDima/src/mcpDima/server.handle_call_tool.handle_call_tool_scope....ValueError","sourceNodeId":"handle_call_tool \\n[server.py : 232_314]","targetNodeId":"/src/mcpDima/src/mcpDima/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDima/src/mcpDima/server.py"},"region":{"startLine":253,"startColumn":27,"endLine":253,"endColumn":68,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 232_314]->/src/mcpDima/src/mcpDima/server.handle_call_tool.handle_call_tool_scope....ValueError","sourceNodeId":"handle_call_tool \\n[server.py : 232_314]","targetNodeId":"/src/mcpDima/src/mcpDima/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDima/src/mcpDima/server.py"},"region":{"startLine":254,"startColumn":31,"endLine":254,"endColumn":99,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 232_314]->syslib_from.client.get_space_list_by_staff","sourceNodeId":"handle_call_tool \\n[server.py : 232_314]","targetNodeId":"syslib_from.client.get_space_list_by_staff"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDima/src/mcpDima/server.py"},"region":{"startLine":257,"startColumn":27,"endLine":257,"endColumn":58,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 232_314]->/src/mcpDima/src/mcpDima/server.handle_call_tool.handle_call_tool_scope....ValueError","sourceNodeId":"handle_call_tool \\n[server.py : 232_314]","targetNodeId":"/src/mcpDima/src/mcpDima/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDima/src/mcpDima/server.py"},"region":{"startLine":259,"startColumn":27,"endLine":259,"endColumn":68,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 232_314]->/src/mcpDima/src/mcpDima/server.handle_call_tool.handle_call_tool_scope....ValueError","sourceNodeId":"handle_call_tool \\n[server.py : 232_314]","targetNodeId":"/src/mcpDima/src/mcpDima/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDima/src/mcpDima/server.py"},"region":{"startLine":260,"startColumn":31,"endLine":260,"endColumn":101,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 232_314]->syslib_from.client.get_project_list_by_space","sourceNodeId":"handle_call_tool \\n[server.py : 232_314]","targetNodeId":"syslib_from.client.get_project_list_by_space"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDima/src/mcpDima/server.py"},"region":{"startLine":263,"startColumn":27,"endLine":263,"endColumn":58,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 232_314]->/src/mcpDima/src/mcpDima/server.handle_call_tool.handle_call_tool_scope....ValueError","sourceNodeId":"handle_call_tool \\n[server.py : 232_314]","targetNodeId":"/src/mcpDima/src/mcpDima/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDima/src/mcpDima/server.py"},"region":{"startLine":265,"startColumn":27,"endLine":265,"endColumn":70,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 232_314]->/src/mcpDima/src/mcpDima/server.handle_call_tool.handle_call_tool_scope....ValueError","sourceNodeId":"handle_call_tool \\n[server.py : 232_314]","targetNodeId":"/src/mcpDima/src/mcpDima/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDima/src/mcpDima/server.py"},"region":{"startLine":266,"startColumn":31,"endLine":266,"endColumn":98,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 232_314]->syslib_from.client.get_project_detail","sourceNodeId":"handle_call_tool \\n[server.py : 232_314]","targetNodeId":"syslib_from.client.get_project_detail"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDima/src/mcpDima/server.py"},"region":{"startLine":269,"startColumn":27,"endLine":269,"endColumn":58,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 232_314]->/src/mcpDima/src/mcpDima/server.handle_call_tool.handle_call_tool_scope....ValueError","sourceNodeId":"handle_call_tool \\n[server.py : 232_314]","targetNodeId":"/src/mcpDima/src/mcpDima/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDima/src/mcpDima/server.py"},"region":{"startLine":271,"startColumn":27,"endLine":271,"endColumn":69,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 232_314]->/src/mcpDima/src/mcpDima/server.handle_call_tool.handle_call_tool_scope....ValueError","sourceNodeId":"handle_call_tool \\n[server.py : 232_314]","targetNodeId":"/src/mcpDima/src/mcpDima/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDima/src/mcpDima/server.py"},"region":{"startLine":272,"startColumn":31,"endLine":272,"endColumn":95,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 232_314]->syslib_from.client.get_sprint_detail","sourceNodeId":"handle_call_tool \\n[server.py : 232_314]","targetNodeId":"syslib_from.client.get_sprint_detail"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDima/src/mcpDima/server.py"},"region":{"startLine":275,"startColumn":27,"endLine":275,"endColumn":58,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 232_314]->/src/mcpDima/src/mcpDima/server.handle_call_tool.handle_call_tool_scope....ValueError","sourceNodeId":"handle_call_tool \\n[server.py : 232_314]","targetNodeId":"/src/mcpDima/src/mcpDima/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDima/src/mcpDima/server.py"},"region":{"startLine":277,"startColumn":27,"endLine":277,"endColumn":86,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 232_314]->/src/mcpDima/src/mcpDima/server.handle_call_tool.handle_call_tool_scope....ValueError","sourceNodeId":"handle_call_tool \\n[server.py : 232_314]","targetNodeId":"/src/mcpDima/src/mcpDima/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDima/src/mcpDima/server.py"},"region":{"startLine":278,"startColumn":31,"endLine":278,"endColumn":131,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 232_314]->syslib_from.client.get_sprint_list","sourceNodeId":"handle_call_tool \\n[server.py : 232_314]","targetNodeId":"syslib_from.client.get_sprint_list"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDima/src/mcpDima/server.py"},"region":{"startLine":281,"startColumn":27,"endLine":281,"endColumn":58,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 232_314]->/src/mcpDima/src/mcpDima/server.handle_call_tool.handle_call_tool_scope....ValueError","sourceNodeId":"handle_call_tool \\n[server.py : 232_314]","targetNodeId":"/src/mcpDima/src/mcpDima/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDima/src/mcpDima/server.py"},"region":{"startLine":283,"startColumn":27,"endLine":283,"endColumn":67,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 232_314]->/src/mcpDima/src/mcpDima/server.handle_call_tool.handle_call_tool_scope....ValueError","sourceNodeId":"handle_call_tool \\n[server.py : 232_314]","targetNodeId":"/src/mcpDima/src/mcpDima/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDima/src/mcpDima/server.py"},"region":{"startLine":284,"startColumn":31,"endLine":284,"endColumn":87,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 232_314]->syslib_from.client.search_sprint","sourceNodeId":"handle_call_tool \\n[server.py : 232_314]","targetNodeId":"syslib_from.client.search_sprint"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDima/src/mcpDima/server.py"},"region":{"startLine":287,"startColumn":27,"endLine":287,"endColumn":58,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 232_314]->/src/mcpDima/src/mcpDima/server.handle_call_tool.handle_call_tool_scope....ValueError","sourceNodeId":"handle_call_tool \\n[server.py : 232_314]","targetNodeId":"/src/mcpDima/src/mcpDima/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDima/src/mcpDima/server.py"},"region":{"startLine":289,"startColumn":27,"endLine":289,"endColumn":72,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 232_314]->/src/mcpDima/src/mcpDima/server.handle_call_tool.handle_call_tool_scope....ValueError","sourceNodeId":"handle_call_tool \\n[server.py : 232_314]","targetNodeId":"/src/mcpDima/src/mcpDima/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDima/src/mcpDima/server.py"},"region":{"startLine":290,"startColumn":31,"endLine":290,"endColumn":104,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 232_314]->syslib_from.client.get_work_item_detail","sourceNodeId":"handle_call_tool \\n[server.py : 232_314]","targetNodeId":"syslib_from.client.get_work_item_detail"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDima/src/mcpDima/server.py"},"region":{"startLine":293,"startColumn":27,"endLine":293,"endColumn":58,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 232_314]->/src/mcpDima/src/mcpDima/server.handle_call_tool.handle_call_tool_scope....ValueError","sourceNodeId":"handle_call_tool \\n[server.py : 232_314]","targetNodeId":"/src/mcpDima/src/mcpDima/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDima/src/mcpDima/server.py"},"region":{"startLine":295,"startColumn":27,"endLine":295,"endColumn":97,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 232_314]->/src/mcpDima/src/mcpDima/server.handle_call_tool.handle_call_tool_scope....ValueError","sourceNodeId":"handle_call_tool \\n[server.py : 232_314]","targetNodeId":"/src/mcpDima/src/mcpDima/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDima/src/mcpDima/server.py"},"region":{"startLine":297,"startColumn":150,"endLine":297,"endColumn":176,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 232_314]->/src/mcpDima/src/mcpDima/server.handle_call_tool.arguments.get","sourceNodeId":"handle_call_tool \\n[server.py : 232_314]","targetNodeId":"/src/mcpDima/src/mcpDima/server.handle_call_tool.arguments.get"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDima/src/mcpDima/server.py"},"region":{"startLine":296,"startColumn":31,"endLine":297,"endColumn":177,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 232_314]->syslib_from.client.page_search_work_item","sourceNodeId":"handle_call_tool \\n[server.py : 232_314]","targetNodeId":"syslib_from.client.page_search_work_item"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDima/src/mcpDima/server.py"},"region":{"startLine":300,"startColumn":27,"endLine":300,"endColumn":58,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 232_314]->/src/mcpDima/src/mcpDima/server.handle_call_tool.handle_call_tool_scope....ValueError","sourceNodeId":"handle_call_tool \\n[server.py : 232_314]","targetNodeId":"/src/mcpDima/src/mcpDima/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDima/src/mcpDima/server.py"},"region":{"startLine":302,"startColumn":27,"endLine":302,"endColumn":72,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 232_314]->/src/mcpDima/src/mcpDima/server.handle_call_tool.handle_call_tool_scope....ValueError","sourceNodeId":"handle_call_tool \\n[server.py : 232_314]","targetNodeId":"/src/mcpDima/src/mcpDima/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDima/src/mcpDima/server.py"},"region":{"startLine":303,"startColumn":31,"endLine":303,"endColumn":105,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 232_314]->syslib_from.client.get_work_item_comment","sourceNodeId":"handle_call_tool \\n[server.py : 232_314]","targetNodeId":"syslib_from.client.get_work_item_comment"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDima/src/mcpDima/server.py"},"region":{"startLine":306,"startColumn":27,"endLine":306,"endColumn":58,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 232_314]->/src/mcpDima/src/mcpDima/server.handle_call_tool.handle_call_tool_scope....ValueError","sourceNodeId":"handle_call_tool \\n[server.py : 232_314]","targetNodeId":"/src/mcpDima/src/mcpDima/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDima/src/mcpDima/server.py"},"region":{"startLine":308,"startColumn":27,"endLine":308,"endColumn":67,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 232_314]->/src/mcpDima/src/mcpDima/server.handle_call_tool.handle_call_tool_scope....ValueError","sourceNodeId":"handle_call_tool \\n[server.py : 232_314]","targetNodeId":"/src/mcpDima/src/mcpDima/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDima/src/mcpDima/server.py"},"region":{"startLine":309,"startColumn":31,"endLine":309,"endColumn":90,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 232_314]->syslib_from.client.search_dept_info","sourceNodeId":"handle_call_tool \\n[server.py : 232_314]","targetNodeId":"syslib_from.client.search_dept_info"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDima/src/mcpDima/server.py"},"region":{"startLine":311,"startColumn":23,"endLine":311,"endColumn":58,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 232_314]->/src/mcpDima/src/mcpDima/server.handle_call_tool.handle_call_tool_scope...ValueError","sourceNodeId":"handle_call_tool \\n[server.py : 232_314]","targetNodeId":"/src/mcpDima/src/mcpDima/server.handle_call_tool.handle_call_tool_scope...ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDima/src/mcpDima/server.py"},"region":{"startLine":314,"startColumn":17,"endLine":314,"endColumn":67,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 232_314]->syslib_from.mcp/types.TextContent","sourceNodeId":"handle_call_tool \\n[server.py : 232_314]","targetNodeId":"syslib_from.mcp/types.TextContent"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDrm/src/mcpDrm/server.py"},"region":{"startLine":26,"startColumn":1,"endLine":33,"endColumn":59,"snippet":{}}}},"id":"<__entry_point__>->find_attribute_by_data_id \\n[server.py : 26_33]","sourceNodeId":"<__entry_point__>","targetNodeId":"find_attribute_by_data_id \\n[server.py : 26_33]"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDrm/src/mcpDrm/server.py"},"region":{"startLine":32,"startColumn":12,"endLine":32,"endColumn":68,"snippet":{}}}},"id":"find_attribute_by_data_id \\n[server.py : 26_33]->oneapi.opssla.ResourceMetaDataFacade.ResourceMetaDataFacade(layotto).findAttributeByDataId","sourceNodeId":"find_attribute_by_data_id \\n[server.py : 26_33]","targetNodeId":"oneapi.opssla.ResourceMetaDataFacade.ResourceMetaDataFacade(layotto).findAttributeByDataId"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDrm/src/mcpDrm/server.py"},"region":{"startLine":33,"startColumn":23,"endLine":33,"endColumn":38,"snippet":{}}}},"id":"find_attribute_by_data_id \\n[server.py : 26_33]->oneapi.opssla.ResourceMetaDataFacade.ResourceMetaDataFacade(layotto).findAttributeByDataId(data_id).get_json","sourceNodeId":"find_attribute_by_data_id \\n[server.py : 26_33]","targetNodeId":"oneapi.opssla.ResourceMetaDataFacade.ResourceMetaDataFacade(layotto).findAttributeByDataId(data_id).get_json"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDrm/src/mcpDrm/server.py"},"region":{"startLine":33,"startColumn":12,"endLine":33,"endColumn":59,"snippet":{}}}},"id":"find_attribute_by_data_id \\n[server.py : 26_33]->syslib_from.json.dumps","sourceNodeId":"find_attribute_by_data_id \\n[server.py : 26_33]","targetNodeId":"syslib_from.json.dumps"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDrm/src/mcpDrm/server.py"},"region":{"startLine":37,"startColumn":1,"endLine":44,"endColumn":59,"snippet":{}}}},"id":"<__entry_point__>->find_resource_by_app \\n[server.py : 37_44]","sourceNodeId":"<__entry_point__>","targetNodeId":"find_resource_by_app \\n[server.py : 37_44]"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDrm/src/mcpDrm/server.py"},"region":{"startLine":43,"startColumn":12,"endLine":43,"endColumn":57,"snippet":{}}}},"id":"find_resource_by_app \\n[server.py : 37_44]->oneapi.opssla.ResourceMetaDataFacade.ResourceMetaDataFacade(layotto).findByApp","sourceNodeId":"find_resource_by_app \\n[server.py : 37_44]","targetNodeId":"oneapi.opssla.ResourceMetaDataFacade.ResourceMetaDataFacade(layotto).findByApp"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDrm/src/mcpDrm/server.py"},"region":{"startLine":44,"startColumn":23,"endLine":44,"endColumn":38,"snippet":{}}}},"id":"find_resource_by_app \\n[server.py : 37_44]->oneapi.opssla.ResourceMetaDataFacade.ResourceMetaDataFacade(layotto).findByApp(app_name).get_json","sourceNodeId":"find_resource_by_app \\n[server.py : 37_44]","targetNodeId":"oneapi.opssla.ResourceMetaDataFacade.ResourceMetaDataFacade(layotto).findByApp(app_name).get_json"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDrm/src/mcpDrm/server.py"},"region":{"startLine":44,"startColumn":12,"endLine":44,"endColumn":59,"snippet":{}}}},"id":"find_resource_by_app \\n[server.py : 37_44]->syslib_from.json.dumps","sourceNodeId":"find_resource_by_app \\n[server.py : 37_44]","targetNodeId":"syslib_from.json.dumps"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDrm/src/mcpDrm/server.py"},"region":{"startLine":48,"startColumn":1,"endLine":55,"endColumn":59,"snippet":{}}}},"id":"<__entry_point__>->search_resource \\n[server.py : 48_55]","sourceNodeId":"<__entry_point__>","targetNodeId":"search_resource \\n[server.py : 48_55]"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDrm/src/mcpDrm/server.py"},"region":{"startLine":54,"startColumn":12,"endLine":54,"endColumn":64,"snippet":{}}}},"id":"search_resource \\n[server.py : 48_55]->oneapi.opssla.ResourceMetaDataFacade.ResourceMetaDataFacade(layotto).search","sourceNodeId":"search_resource \\n[server.py : 48_55]","targetNodeId":"oneapi.opssla.ResourceMetaDataFacade.ResourceMetaDataFacade(layotto).search"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDrm/src/mcpDrm/server.py"},"region":{"startLine":55,"startColumn":23,"endLine":55,"endColumn":38,"snippet":{}}}},"id":"search_resource \\n[server.py : 48_55]->oneapi.opssla.ResourceMetaDataFacade.ResourceMetaDataFacade(layotto).search(keyword, var limit:any=100).get_json","sourceNodeId":"search_resource \\n[server.py : 48_55]","targetNodeId":"oneapi.opssla.ResourceMetaDataFacade.ResourceMetaDataFacade(layotto).search(keyword, var limit:any=100).get_json"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDrm/src/mcpDrm/server.py"},"region":{"startLine":55,"startColumn":12,"endLine":55,"endColumn":59,"snippet":{}}}},"id":"search_resource \\n[server.py : 48_55]->syslib_from.json.dumps","sourceNodeId":"search_resource \\n[server.py : 48_55]","targetNodeId":"syslib_from.json.dumps"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDrm/src/mcpDrm/server.py"},"region":{"startLine":59,"startColumn":1,"endLine":85,"endColumn":59,"snippet":{}}}},"id":"<__entry_point__>->query_push_drm_value \\n[server.py : 59_85]","sourceNodeId":"<__entry_point__>","targetNodeId":"query_push_drm_value \\n[server.py : 59_85]"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDrm/src/mcpDrm/server.py"},"region":{"startLine":67,"startColumn":16,"endLine":67,"endColumn":72,"snippet":{}}}},"id":"query_push_drm_value \\n[server.py : 59_85]->oneapi.opssla.ResourceMetaDataFacade.ResourceMetaDataFacade(layotto).search","sourceNodeId":"query_push_drm_value \\n[server.py : 59_85]","targetNodeId":"oneapi.opssla.ResourceMetaDataFacade.ResourceMetaDataFacade(layotto).search"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDrm/src/mcpDrm/server.py"},"region":{"startLine":70,"startColumn":18,"endLine":70,"endColumn":28,"snippet":{}}}},"id":"query_push_drm_value \\n[server.py : 59_85]->/src/mcpDrm/src/mcpDrm/server.query_push_drm_value.query_push_drm_value_scope..len","sourceNodeId":"query_push_drm_value \\n[server.py : 59_85]","targetNodeId":"/src/mcpDrm/src/mcpDrm/server.query_push_drm_value.query_push_drm_value_scope..len"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDrm/src/mcpDrm/server.py"},"region":{"startLine":69,"startColumn":15,"endLine":69,"endColumn":65,"snippet":{}}}},"id":"query_push_drm_value \\n[server.py : 59_85]->/src/mcpDrm/src/mcpDrm/server.query_push_drm_value.query_push_drm_value_scope...ValueError","sourceNodeId":"query_push_drm_value \\n[server.py : 59_85]","targetNodeId":"/src/mcpDrm/src/mcpDrm/server.query_push_drm_value.query_push_drm_value_scope...ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDrm/src/mcpDrm/server.py"},"region":{"startLine":82,"startColumn":29,"endLine":82,"endColumn":68,"snippet":{}}}},"id":"query_push_drm_value \\n[server.py : 59_85]->oneapi.opssla.ResourceMetaDataFacade.ResourceMetaDataFacade(layotto).search(resource_id, var limit:any=100).data.get","sourceNodeId":"query_push_drm_value \\n[server.py : 59_85]","targetNodeId":"oneapi.opssla.ResourceMetaDataFacade.ResourceMetaDataFacade(layotto).search(resource_id, var limit:any=100).data.get"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDrm/src/mcpDrm/server.py"},"region":{"startLine":71,"startColumn":16,"endLine":77,"endColumn":10,"snippet":{}}}},"id":"query_push_drm_value \\n[server.py : 59_85]->oneapi.opssla.DrmManageFacade.DrmManageFacade(layotto).queryValueByZoneNames","sourceNodeId":"query_push_drm_value \\n[server.py : 59_85]","targetNodeId":"oneapi.opssla.DrmManageFacade.DrmManageFacade(layotto).queryValueByZoneNames"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDrm/src/mcpDrm/server.py"},"region":{"startLine":79,"startColumn":16,"endLine":84,"endColumn":10,"snippet":{}}}},"id":"query_push_drm_value \\n[server.py : 59_85]->oneapi.opssla.DrmManageFacade.DrmManageFacade(layotto).queryValueByAllZone","sourceNodeId":"query_push_drm_value \\n[server.py : 59_85]","targetNodeId":"oneapi.opssla.DrmManageFacade.DrmManageFacade(layotto).queryValueByAllZone"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDrm/src/mcpDrm/server.py"},"region":{"startLine":85,"startColumn":23,"endLine":85,"endColumn":38,"snippet":{}}}},"id":"query_push_drm_value \\n[server.py : 59_85]->/src/mcpDrm/src/mcpDrm/server.query_push_drm_value.query_push_drm_value_scope..resp.get_json","sourceNodeId":"query_push_drm_value \\n[server.py : 59_85]","targetNodeId":"/src/mcpDrm/src/mcpDrm/server.query_push_drm_value.query_push_drm_value_scope..resp.get_json"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDrm/src/mcpDrm/server.py"},"region":{"startLine":85,"startColumn":12,"endLine":85,"endColumn":59,"snippet":{}}}},"id":"query_push_drm_value \\n[server.py : 59_85]->syslib_from.json.dumps","sourceNodeId":"query_push_drm_value \\n[server.py : 59_85]","targetNodeId":"syslib_from.json.dumps"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpFileOperation/src/mcpFileOperation/server.py"},"region":{"startLine":60,"startColumn":1,"endLine":86,"endColumn":11,"snippet":{}}}},"id":"<__entry_point__>->handle_call_tool \\n[server.py : 60_86]","sourceNodeId":"<__entry_point__>","targetNodeId":"handle_call_tool \\n[server.py : 60_86]"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpFileOperation/src/mcpFileOperation/server.py"},"region":{"startLine":77,"startColumn":84,"endLine":77,"endColumn":128,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 60_86]->syslib_from.json.dumps","sourceNodeId":"handle_call_tool \\n[server.py : 60_86]","targetNodeId":"syslib_from.json.dumps"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpFileOperation/src/mcpFileOperation/server.py"},"region":{"startLine":76,"startColumn":17,"endLine":76,"endColumn":97,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 60_86]->syslib_from.logging.getLogger(mcp-server).info","sourceNodeId":"handle_call_tool \\n[server.py : 60_86]","targetNodeId":"syslib_from.logging.getLogger(mcp-server).info"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpFileOperation/src/mcpFileOperation/server.py"},"region":{"startLine":73,"startColumn":27,"endLine":73,"endColumn":73,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 60_86]->/src/mcpFileOperation/src/mcpFileOperation/server.handle_call_tool.handle_call_tool_scope....ValueError","sourceNodeId":"handle_call_tool \\n[server.py : 60_86]","targetNodeId":"/src/mcpFileOperation/src/mcpFileOperation/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpFileOperation/src/mcpFileOperation/server.py"},"region":{"startLine":75,"startColumn":47,"endLine":75,"endColumn":91,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 60_86]->mcp_common.utils.oss_utils.get_file_infos","sourceNodeId":"handle_call_tool \\n[server.py : 60_86]","targetNodeId":"mcp_common.utils.oss_utils.get_file_infos"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpFileOperation/src/mcpFileOperation/server.py"},"region":{"startLine":77,"startColumn":95,"endLine":77,"endColumn":107,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 60_86]->mcp_common.utils.oss_utils.get_file_infos(arguments.file_full_names).to_dict","sourceNodeId":"handle_call_tool \\n[server.py : 60_86]","targetNodeId":"mcp_common.utils.oss_utils.get_file_infos(arguments.file_full_names).to_dict"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpFileOperation/src/mcpFileOperation/server.py"},"region":{"startLine":77,"startColumn":25,"endLine":77,"endColumn":129,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 60_86]->syslib_from.mcp/types.ImageContent","sourceNodeId":"handle_call_tool \\n[server.py : 60_86]","targetNodeId":"syslib_from.mcp/types.ImageContent"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpFileOperation/src/mcpFileOperation/server.py"},"region":{"startLine":80,"startColumn":23,"endLine":80,"endColumn":58,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 60_86]->/src/mcpFileOperation/src/mcpFileOperation/server.handle_call_tool.handle_call_tool_scope...ValueError","sourceNodeId":"handle_call_tool \\n[server.py : 60_86]","targetNodeId":"/src/mcpFileOperation/src/mcpFileOperation/server.handle_call_tool.handle_call_tool_scope...ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpFileOperation/src/mcpFileOperation/server.py"},"region":{"startLine":82,"startColumn":9,"endLine":82,"endColumn":81,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 60_86]->syslib_from.logging.getLogger(mcp-server).error","sourceNodeId":"handle_call_tool \\n[server.py : 60_86]","targetNodeId":"syslib_from.logging.getLogger(mcp-server).error"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpFileOperation/src/mcpFileOperation/server.py"},"region":{"startLine":83,"startColumn":17,"endLine":86,"endColumn":10,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 60_86]->syslib_from.mcp/types.TextContent","sourceNodeId":"handle_call_tool \\n[server.py : 60_86]","targetNodeId":"syslib_from.mcp/types.TextContent"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpFluxExecute/src/mcpFluxExecute/server.py"},"region":{"startLine":130,"startColumn":1,"endLine":185,"endColumn":54,"snippet":{}}}},"id":"<__entry_point__>->handle_call_tool \\n[server.py : 130_185]","sourceNodeId":"<__entry_point__>","targetNodeId":"handle_call_tool \\n[server.py : 130_185]"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpFluxExecute/src/mcpFluxExecute/server.py"},"region":{"startLine":140,"startColumn":23,"endLine":140,"endColumn":53,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 130_185]->/src/mcpFluxExecute/src/mcpFluxExecute/server.handle_call_tool.handle_call_tool_scope....ValueError","sourceNodeId":"handle_call_tool \\n[server.py : 130_185]","targetNodeId":"/src/mcpFluxExecute/src/mcpFluxExecute/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpFluxExecute/src/mcpFluxExecute/server.py"},"region":{"startLine":142,"startColumn":23,"endLine":142,"endColumn":61,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 130_185]->/src/mcpFluxExecute/src/mcpFluxExecute/server.handle_call_tool.handle_call_tool_scope....ValueError","sourceNodeId":"handle_call_tool \\n[server.py : 130_185]","targetNodeId":"/src/mcpFluxExecute/src/mcpFluxExecute/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpFluxExecute/src/mcpFluxExecute/server.py"},"region":{"startLine":144,"startColumn":23,"endLine":144,"endColumn":64,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 130_185]->/src/mcpFluxExecute/src/mcpFluxExecute/server.handle_call_tool.handle_call_tool_scope....ValueError","sourceNodeId":"handle_call_tool \\n[server.py : 130_185]","targetNodeId":"/src/mcpFluxExecute/src/mcpFluxExecute/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpFluxExecute/src/mcpFluxExecute/server.py"},"region":{"startLine":182,"startColumn":82,"endLine":182,"endColumn":108,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 130_185]->/src/mcpFluxExecute/src/mcpFluxExecute/server.handle_call_tool.arguments.get","sourceNodeId":"handle_call_tool \\n[server.py : 130_185]","targetNodeId":"/src/mcpFluxExecute/src/mcpFluxExecute/server.handle_call_tool.arguments.get"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpFluxExecute/src/mcpFluxExecute/server.py"},"region":{"startLine":145,"startColumn":22,"endLine":146,"endColumn":87,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 130_185]->/src/mcpFluxExecute/src/mcpFluxExecute/server.handle_call_tool.handle_call_tool_scope...query_feature_value","sourceNodeId":"handle_call_tool \\n[server.py : 130_185]","targetNodeId":"/src/mcpFluxExecute/src/mcpFluxExecute/server.handle_call_tool.handle_call_tool_scope...query_feature_value"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpFluxExecute/src/mcpFluxExecute/server.py"},"region":{"startLine":183,"startColumn":21,"endLine":183,"endColumn":64,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 130_185]->syslib_from.mcp/types.TextContent","sourceNodeId":"handle_call_tool \\n[server.py : 130_185]","targetNodeId":"syslib_from.mcp/types.TextContent"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpFluxExecute/src/mcpFluxExecute/server.py"},"region":{"startLine":150,"startColumn":23,"endLine":150,"endColumn":53,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 130_185]->/src/mcpFluxExecute/src/mcpFluxExecute/server.handle_call_tool.handle_call_tool_scope....ValueError","sourceNodeId":"handle_call_tool \\n[server.py : 130_185]","targetNodeId":"/src/mcpFluxExecute/src/mcpFluxExecute/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpFluxExecute/src/mcpFluxExecute/server.py"},"region":{"startLine":152,"startColumn":23,"endLine":152,"endColumn":61,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 130_185]->/src/mcpFluxExecute/src/mcpFluxExecute/server.handle_call_tool.handle_call_tool_scope....ValueError","sourceNodeId":"handle_call_tool \\n[server.py : 130_185]","targetNodeId":"/src/mcpFluxExecute/src/mcpFluxExecute/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpFluxExecute/src/mcpFluxExecute/server.py"},"region":{"startLine":153,"startColumn":22,"endLine":153,"endColumn":82,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 130_185]->/src/mcpFluxExecute/src/mcpFluxExecute/server.handle_call_tool.handle_call_tool_scope...query_app_goc_method","sourceNodeId":"handle_call_tool \\n[server.py : 130_185]","targetNodeId":"/src/mcpFluxExecute/src/mcpFluxExecute/server.handle_call_tool.handle_call_tool_scope...query_app_goc_method"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpFluxExecute/src/mcpFluxExecute/server.py"},"region":{"startLine":157,"startColumn":23,"endLine":157,"endColumn":53,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 130_185]->/src/mcpFluxExecute/src/mcpFluxExecute/server.handle_call_tool.handle_call_tool_scope....ValueError","sourceNodeId":"handle_call_tool \\n[server.py : 130_185]","targetNodeId":"/src/mcpFluxExecute/src/mcpFluxExecute/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpFluxExecute/src/mcpFluxExecute/server.py"},"region":{"startLine":159,"startColumn":23,"endLine":159,"endColumn":61,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 130_185]->/src/mcpFluxExecute/src/mcpFluxExecute/server.handle_call_tool.handle_call_tool_scope....ValueError","sourceNodeId":"handle_call_tool \\n[server.py : 130_185]","targetNodeId":"/src/mcpFluxExecute/src/mcpFluxExecute/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpFluxExecute/src/mcpFluxExecute/server.py"},"region":{"startLine":161,"startColumn":23,"endLine":161,"endColumn":67,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 130_185]->/src/mcpFluxExecute/src/mcpFluxExecute/server.handle_call_tool.handle_call_tool_scope....ValueError","sourceNodeId":"handle_call_tool \\n[server.py : 130_185]","targetNodeId":"/src/mcpFluxExecute/src/mcpFluxExecute/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpFluxExecute/src/mcpFluxExecute/server.py"},"region":{"startLine":163,"startColumn":23,"endLine":163,"endColumn":58,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 130_185]->/src/mcpFluxExecute/src/mcpFluxExecute/server.handle_call_tool.handle_call_tool_scope....ValueError","sourceNodeId":"handle_call_tool \\n[server.py : 130_185]","targetNodeId":"/src/mcpFluxExecute/src/mcpFluxExecute/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpFluxExecute/src/mcpFluxExecute/server.py"},"region":{"startLine":164,"startColumn":22,"endLine":165,"endColumn":112,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 130_185]->/src/mcpFluxExecute/src/mcpFluxExecute/server.handle_call_tool.handle_call_tool_scope...query_app_feature","sourceNodeId":"handle_call_tool \\n[server.py : 130_185]","targetNodeId":"/src/mcpFluxExecute/src/mcpFluxExecute/server.handle_call_tool.handle_call_tool_scope...query_app_feature"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpFluxExecute/src/mcpFluxExecute/server.py"},"region":{"startLine":169,"startColumn":23,"endLine":169,"endColumn":61,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 130_185]->/src/mcpFluxExecute/src/mcpFluxExecute/server.handle_call_tool.handle_call_tool_scope....ValueError","sourceNodeId":"handle_call_tool \\n[server.py : 130_185]","targetNodeId":"/src/mcpFluxExecute/src/mcpFluxExecute/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpFluxExecute/src/mcpFluxExecute/server.py"},"region":{"startLine":171,"startColumn":23,"endLine":171,"endColumn":59,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 130_185]->/src/mcpFluxExecute/src/mcpFluxExecute/server.handle_call_tool.handle_call_tool_scope....ValueError","sourceNodeId":"handle_call_tool \\n[server.py : 130_185]","targetNodeId":"/src/mcpFluxExecute/src/mcpFluxExecute/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpFluxExecute/src/mcpFluxExecute/server.py"},"region":{"startLine":172,"startColumn":22,"endLine":172,"endColumn":115,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 130_185]->/src/mcpFluxExecute/src/mcpFluxExecute/server.handle_call_tool.handle_call_tool_scope...query_top_call_interface","sourceNodeId":"handle_call_tool \\n[server.py : 130_185]","targetNodeId":"/src/mcpFluxExecute/src/mcpFluxExecute/server.handle_call_tool.handle_call_tool_scope...query_top_call_interface"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpFluxExecute/src/mcpFluxExecute/server.py"},"region":{"startLine":176,"startColumn":23,"endLine":176,"endColumn":61,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 130_185]->/src/mcpFluxExecute/src/mcpFluxExecute/server.handle_call_tool.handle_call_tool_scope....ValueError","sourceNodeId":"handle_call_tool \\n[server.py : 130_185]","targetNodeId":"/src/mcpFluxExecute/src/mcpFluxExecute/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpFluxExecute/src/mcpFluxExecute/server.py"},"region":{"startLine":177,"startColumn":22,"endLine":177,"endColumn":105,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 130_185]->/src/mcpFluxExecute/src/mcpFluxExecute/server.handle_call_tool.handle_call_tool_scope...query_trace_detail","sourceNodeId":"handle_call_tool \\n[server.py : 130_185]","targetNodeId":"/src/mcpFluxExecute/src/mcpFluxExecute/server.handle_call_tool.handle_call_tool_scope...query_trace_detail"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpFluxExecute/src/mcpFluxExecute/server.py"},"region":{"startLine":181,"startColumn":23,"endLine":181,"endColumn":57,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 130_185]->/src/mcpFluxExecute/src/mcpFluxExecute/server.handle_call_tool.handle_call_tool_scope....ValueError","sourceNodeId":"handle_call_tool \\n[server.py : 130_185]","targetNodeId":"/src/mcpFluxExecute/src/mcpFluxExecute/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpFluxExecute/src/mcpFluxExecute/server.py"},"region":{"startLine":182,"startColumn":22,"endLine":182,"endColumn":109,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 130_185]->/src/mcpFluxExecute/src/mcpFluxExecute/server.handle_call_tool.handle_call_tool_scope...query_monitor_data","sourceNodeId":"handle_call_tool \\n[server.py : 130_185]","targetNodeId":"/src/mcpFluxExecute/src/mcpFluxExecute/server.handle_call_tool.handle_call_tool_scope...query_monitor_data"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpFluxExecute/src/mcpFluxExecute/server.py"},"region":{"startLine":185,"startColumn":19,"endLine":185,"endColumn":54,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 130_185]->/src/mcpFluxExecute/src/mcpFluxExecute/server.handle_call_tool.handle_call_tool_scope...ValueError","sourceNodeId":"handle_call_tool \\n[server.py : 130_185]","targetNodeId":"/src/mcpFluxExecute/src/mcpFluxExecute/server.handle_call_tool.handle_call_tool_scope...ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpFluxFind/src/mcpFluxFind/server.py"},"region":{"startLine":62,"startColumn":1,"endLine":94,"endColumn":54,"snippet":{}}}},"id":"<__entry_point__>->handle_call_tool \\n[server.py : 62_94]","sourceNodeId":"<__entry_point__>","targetNodeId":"handle_call_tool \\n[server.py : 62_94]"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpFluxFind/src/mcpFluxFind/server.py"},"region":{"startLine":70,"startColumn":68,"endLine":70,"endColumn":111,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 62_94]->syslib_from.json.dumps","sourceNodeId":"handle_call_tool \\n[server.py : 62_94]","targetNodeId":"syslib_from.json.dumps"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpFluxFind/src/mcpFluxFind/server.py"},"region":{"startLine":69,"startColumn":5,"endLine":70,"endColumn":113,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 62_94]->/src/mcpFluxFind/src/mcpFluxFind/server.handle_call_tool.handle_call_tool_scope..info_logger.info","sourceNodeId":"handle_call_tool \\n[server.py : 62_94]","targetNodeId":"/src/mcpFluxFind/src/mcpFluxFind/server.handle_call_tool.handle_call_tool_scope..info_logger.info"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpFluxFind/src/mcpFluxFind/server.py"},"region":{"startLine":74,"startColumn":23,"endLine":74,"endColumn":53,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 62_94]->/src/mcpFluxFind/src/mcpFluxFind/server.handle_call_tool.handle_call_tool_scope....ValueError","sourceNodeId":"handle_call_tool \\n[server.py : 62_94]","targetNodeId":"/src/mcpFluxFind/src/mcpFluxFind/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpFluxFind/src/mcpFluxFind/server.py"},"region":{"startLine":76,"startColumn":23,"endLine":76,"endColumn":62,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 62_94]->/src/mcpFluxFind/src/mcpFluxFind/server.handle_call_tool.handle_call_tool_scope....ValueError","sourceNodeId":"handle_call_tool \\n[server.py : 62_94]","targetNodeId":"/src/mcpFluxFind/src/mcpFluxFind/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpFluxFind/src/mcpFluxFind/server.py"},"region":{"startLine":78,"startColumn":23,"endLine":78,"endColumn":68,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 62_94]->/src/mcpFluxFind/src/mcpFluxFind/server.handle_call_tool.handle_call_tool_scope....ValueError","sourceNodeId":"handle_call_tool \\n[server.py : 62_94]","targetNodeId":"/src/mcpFluxFind/src/mcpFluxFind/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpFluxFind/src/mcpFluxFind/server.py"},"region":{"startLine":80,"startColumn":23,"endLine":80,"endColumn":65,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 62_94]->/src/mcpFluxFind/src/mcpFluxFind/server.handle_call_tool.handle_call_tool_scope....ValueError","sourceNodeId":"handle_call_tool \\n[server.py : 62_94]","targetNodeId":"/src/mcpFluxFind/src/mcpFluxFind/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpFluxFind/src/mcpFluxFind/server.py"},"region":{"startLine":91,"startColumn":67,"endLine":91,"endColumn":94,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 62_94]->/src/mcpFluxFind/src/mcpFluxFind/server.handle_call_tool.arguments.get","sourceNodeId":"handle_call_tool \\n[server.py : 62_94]","targetNodeId":"/src/mcpFluxFind/src/mcpFluxFind/server.handle_call_tool.arguments.get"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpFluxFind/src/mcpFluxFind/server.py"},"region":{"startLine":81,"startColumn":24,"endLine":84,"endColumn":97,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 62_94]->/src/mcpFluxFind/src/mcpFluxFind/server.handle_call_tool.handle_call_tool_scope...find_flux_by_search","sourceNodeId":"handle_call_tool \\n[server.py : 62_94]","targetNodeId":"/src/mcpFluxFind/src/mcpFluxFind/server.handle_call_tool.handle_call_tool_scope...find_flux_by_search"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpFluxFind/src/mcpFluxFind/server.py"},"region":{"startLine":92,"startColumn":21,"endLine":92,"endColumn":64,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 62_94]->syslib_from.mcp/types.TextContent","sourceNodeId":"handle_call_tool \\n[server.py : 62_94]","targetNodeId":"syslib_from.mcp/types.TextContent"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpFluxFind/src/mcpFluxFind/server.py"},"region":{"startLine":88,"startColumn":23,"endLine":88,"endColumn":53,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 62_94]->/src/mcpFluxFind/src/mcpFluxFind/server.handle_call_tool.handle_call_tool_scope....ValueError","sourceNodeId":"handle_call_tool \\n[server.py : 62_94]","targetNodeId":"/src/mcpFluxFind/src/mcpFluxFind/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpFluxFind/src/mcpFluxFind/server.py"},"region":{"startLine":90,"startColumn":23,"endLine":90,"endColumn":64,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 62_94]->/src/mcpFluxFind/src/mcpFluxFind/server.handle_call_tool.handle_call_tool_scope....ValueError","sourceNodeId":"handle_call_tool \\n[server.py : 62_94]","targetNodeId":"/src/mcpFluxFind/src/mcpFluxFind/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpFluxFind/src/mcpFluxFind/server.py"},"region":{"startLine":91,"startColumn":22,"endLine":91,"endColumn":95,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 62_94]->/src/mcpFluxFind/src/mcpFluxFind/server.handle_call_tool.handle_call_tool_scope...find_property_by_scene_code","sourceNodeId":"handle_call_tool \\n[server.py : 62_94]","targetNodeId":"/src/mcpFluxFind/src/mcpFluxFind/server.handle_call_tool.handle_call_tool_scope...find_property_by_scene_code"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpFluxFind/src/mcpFluxFind/server.py"},"region":{"startLine":94,"startColumn":19,"endLine":94,"endColumn":54,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 62_94]->/src/mcpFluxFind/src/mcpFluxFind/server.handle_call_tool.handle_call_tool_scope...ValueError","sourceNodeId":"handle_call_tool \\n[server.py : 62_94]","targetNodeId":"/src/mcpFluxFind/src/mcpFluxFind/server.handle_call_tool.handle_call_tool_scope...ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpFluxScene/src/mcpFluxScene/server.py"},"region":{"startLine":172,"startColumn":1,"endLine":231,"endColumn":54,"snippet":{}}}},"id":"<__entry_point__>->handle_call_tool \\n[server.py : 172_231]","sourceNodeId":"<__entry_point__>","targetNodeId":"handle_call_tool \\n[server.py : 172_231]"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpFluxScene/src/mcpFluxScene/server.py"},"region":{"startLine":180,"startColumn":69,"endLine":180,"endColumn":112,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 172_231]->syslib_from.json.dumps","sourceNodeId":"handle_call_tool \\n[server.py : 172_231]","targetNodeId":"syslib_from.json.dumps"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpFluxScene/src/mcpFluxScene/server.py"},"region":{"startLine":179,"startColumn":5,"endLine":180,"endColumn":114,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 172_231]->/src/mcpFluxScene/src/mcpFluxScene/server.handle_call_tool.handle_call_tool_scope..info_logger.info","sourceNodeId":"handle_call_tool \\n[server.py : 172_231]","targetNodeId":"/src/mcpFluxScene/src/mcpFluxScene/server.handle_call_tool.handle_call_tool_scope..info_logger.info"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpFluxScene/src/mcpFluxScene/server.py"},"region":{"startLine":184,"startColumn":23,"endLine":184,"endColumn":53,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 172_231]->/src/mcpFluxScene/src/mcpFluxScene/server.handle_call_tool.handle_call_tool_scope....ValueError","sourceNodeId":"handle_call_tool \\n[server.py : 172_231]","targetNodeId":"/src/mcpFluxScene/src/mcpFluxScene/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpFluxScene/src/mcpFluxScene/server.py"},"region":{"startLine":186,"startColumn":23,"endLine":186,"endColumn":62,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 172_231]->/src/mcpFluxScene/src/mcpFluxScene/server.handle_call_tool.handle_call_tool_scope....ValueError","sourceNodeId":"handle_call_tool \\n[server.py : 172_231]","targetNodeId":"/src/mcpFluxScene/src/mcpFluxScene/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpFluxScene/src/mcpFluxScene/server.py"},"region":{"startLine":188,"startColumn":23,"endLine":188,"endColumn":64,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 172_231]->/src/mcpFluxScene/src/mcpFluxScene/server.handle_call_tool.handle_call_tool_scope....ValueError","sourceNodeId":"handle_call_tool \\n[server.py : 172_231]","targetNodeId":"/src/mcpFluxScene/src/mcpFluxScene/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpFluxScene/src/mcpFluxScene/server.py"},"region":{"startLine":228,"startColumn":55,"endLine":228,"endColumn":81,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 172_231]->/src/mcpFluxScene/src/mcpFluxScene/server.handle_call_tool.arguments.get","sourceNodeId":"handle_call_tool \\n[server.py : 172_231]","targetNodeId":"/src/mcpFluxScene/src/mcpFluxScene/server.handle_call_tool.arguments.get"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpFluxScene/src/mcpFluxScene/server.py"},"region":{"startLine":189,"startColumn":24,"endLine":193,"endColumn":95,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 172_231]->/src/mcpFluxScene/src/mcpFluxScene/server.handle_call_tool.handle_call_tool_scope...create_flux_scene","sourceNodeId":"handle_call_tool \\n[server.py : 172_231]","targetNodeId":"/src/mcpFluxScene/src/mcpFluxScene/server.handle_call_tool.handle_call_tool_scope...create_flux_scene"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpFluxScene/src/mcpFluxScene/server.py"},"region":{"startLine":229,"startColumn":21,"endLine":229,"endColumn":64,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 172_231]->syslib_from.mcp/types.TextContent","sourceNodeId":"handle_call_tool \\n[server.py : 172_231]","targetNodeId":"syslib_from.mcp/types.TextContent"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpFluxScene/src/mcpFluxScene/server.py"},"region":{"startLine":196,"startColumn":22,"endLine":196,"endColumn":104,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 172_231]->/src/mcpFluxScene/src/mcpFluxScene/server.handle_call_tool.handle_call_tool_scope...batch_create_flux_scene","sourceNodeId":"handle_call_tool \\n[server.py : 172_231]","targetNodeId":"/src/mcpFluxScene/src/mcpFluxScene/server.handle_call_tool.handle_call_tool_scope...batch_create_flux_scene"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpFluxScene/src/mcpFluxScene/server.py"},"region":{"startLine":199,"startColumn":22,"endLine":201,"endColumn":91,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 172_231]->/src/mcpFluxScene/src/mcpFluxScene/server.handle_call_tool.handle_call_tool_scope...test_analysis_agent","sourceNodeId":"handle_call_tool \\n[server.py : 172_231]","targetNodeId":"/src/mcpFluxScene/src/mcpFluxScene/server.handle_call_tool.handle_call_tool_scope...test_analysis_agent"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpFluxScene/src/mcpFluxScene/server.py"},"region":{"startLine":205,"startColumn":23,"endLine":205,"endColumn":84,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 172_231]->/src/mcpFluxScene/src/mcpFluxScene/server.handle_call_tool.handle_call_tool_scope....ValueError","sourceNodeId":"handle_call_tool \\n[server.py : 172_231]","targetNodeId":"/src/mcpFluxScene/src/mcpFluxScene/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpFluxScene/src/mcpFluxScene/server.py"},"region":{"startLine":206,"startColumn":22,"endLine":206,"endColumn":89,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 172_231]->/src/mcpFluxScene/src/mcpFluxScene/server.handle_call_tool.handle_call_tool_scope...text_use_case_agent","sourceNodeId":"handle_call_tool \\n[server.py : 172_231]","targetNodeId":"/src/mcpFluxScene/src/mcpFluxScene/server.handle_call_tool.handle_call_tool_scope...text_use_case_agent"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpFluxScene/src/mcpFluxScene/server.py"},"region":{"startLine":210,"startColumn":23,"endLine":210,"endColumn":89,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 172_231]->/src/mcpFluxScene/src/mcpFluxScene/server.handle_call_tool.handle_call_tool_scope....ValueError","sourceNodeId":"handle_call_tool \\n[server.py : 172_231]","targetNodeId":"/src/mcpFluxScene/src/mcpFluxScene/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpFluxScene/src/mcpFluxScene/server.py"},"region":{"startLine":211,"startColumn":22,"endLine":215,"endColumn":109,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 172_231]->/src/mcpFluxScene/src/mcpFluxScene/server.handle_call_tool.handle_call_tool_scope...test_report_agent","sourceNodeId":"handle_call_tool \\n[server.py : 172_231]","targetNodeId":"/src/mcpFluxScene/src/mcpFluxScene/server.handle_call_tool.handle_call_tool_scope...test_report_agent"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpFluxScene/src/mcpFluxScene/server.py"},"region":{"startLine":219,"startColumn":23,"endLine":219,"endColumn":84,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 172_231]->/src/mcpFluxScene/src/mcpFluxScene/server.handle_call_tool.handle_call_tool_scope....ValueError","sourceNodeId":"handle_call_tool \\n[server.py : 172_231]","targetNodeId":"/src/mcpFluxScene/src/mcpFluxScene/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpFluxScene/src/mcpFluxScene/server.py"},"region":{"startLine":220,"startColumn":22,"endLine":222,"endColumn":94,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 172_231]->/src/mcpFluxScene/src/mcpFluxScene/server.handle_call_tool.handle_call_tool_scope...scene_mining_agent","sourceNodeId":"handle_call_tool \\n[server.py : 172_231]","targetNodeId":"/src/mcpFluxScene/src/mcpFluxScene/server.handle_call_tool.handle_call_tool_scope...scene_mining_agent"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpFluxScene/src/mcpFluxScene/server.py"},"region":{"startLine":226,"startColumn":23,"endLine":226,"endColumn":82,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 172_231]->/src/mcpFluxScene/src/mcpFluxScene/server.handle_call_tool.handle_call_tool_scope....ValueError","sourceNodeId":"handle_call_tool \\n[server.py : 172_231]","targetNodeId":"/src/mcpFluxScene/src/mcpFluxScene/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpFluxScene/src/mcpFluxScene/server.py"},"region":{"startLine":227,"startColumn":22,"endLine":228,"endColumn":82,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 172_231]->/src/mcpFluxScene/src/mcpFluxScene/server.handle_call_tool.handle_call_tool_scope...end_to_end_agent","sourceNodeId":"handle_call_tool \\n[server.py : 172_231]","targetNodeId":"/src/mcpFluxScene/src/mcpFluxScene/server.handle_call_tool.handle_call_tool_scope...end_to_end_agent"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpFluxScene/src/mcpFluxScene/server.py"},"region":{"startLine":231,"startColumn":19,"endLine":231,"endColumn":54,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 172_231]->/src/mcpFluxScene/src/mcpFluxScene/server.handle_call_tool.handle_call_tool_scope...ValueError","sourceNodeId":"handle_call_tool \\n[server.py : 172_231]","targetNodeId":"/src/mcpFluxScene/src/mcpFluxScene/server.handle_call_tool.handle_call_tool_scope...ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpGetDbOperationByTraceId/src/mcpGetDbOperationByTraceId/server.py"},"region":{"startLine":37,"startColumn":1,"endLine":59,"endColumn":54,"snippet":{}}}},"id":"<__entry_point__>->handle_call_tool \\n[server.py : 37_59]","sourceNodeId":"<__entry_point__>","targetNodeId":"handle_call_tool \\n[server.py : 37_59]"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpGetDbOperationByTraceId/src/mcpGetDbOperationByTraceId/server.py"},"region":{"startLine":45,"startColumn":64,"endLine":45,"endColumn":107,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 37_59]->syslib_from.json.dumps","sourceNodeId":"handle_call_tool \\n[server.py : 37_59]","targetNodeId":"syslib_from.json.dumps"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpGetDbOperationByTraceId/src/mcpGetDbOperationByTraceId/server.py"},"region":{"startLine":44,"startColumn":5,"endLine":45,"endColumn":109,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 37_59]->syslib_from.logging.getLogger(mcp-server).info","sourceNodeId":"handle_call_tool \\n[server.py : 37_59]","targetNodeId":"syslib_from.logging.getLogger(mcp-server).info"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpGetDbOperationByTraceId/src/mcpGetDbOperationByTraceId/server.py"},"region":{"startLine":49,"startColumn":23,"endLine":49,"endColumn":53,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 37_59]->/src/mcpGetDbOperationByTraceId/src/mcpGetDbOperationByTraceId/server.handle_call_tool.handle_call_tool_scope....ValueError","sourceNodeId":"handle_call_tool \\n[server.py : 37_59]","targetNodeId":"/src/mcpGetDbOperationByTraceId/src/mcpGetDbOperationByTraceId/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpGetDbOperationByTraceId/src/mcpGetDbOperationByTraceId/server.py"},"region":{"startLine":51,"startColumn":23,"endLine":51,"endColumn":57,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 37_59]->/src/mcpGetDbOperationByTraceId/src/mcpGetDbOperationByTraceId/server.handle_call_tool.handle_call_tool_scope....ValueError","sourceNodeId":"handle_call_tool \\n[server.py : 37_59]","targetNodeId":"/src/mcpGetDbOperationByTraceId/src/mcpGetDbOperationByTraceId/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpGetDbOperationByTraceId/src/mcpGetDbOperationByTraceId/server.py"},"region":{"startLine":53,"startColumn":23,"endLine":53,"endColumn":92,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 37_59]->/src/mcpGetDbOperationByTraceId/src/mcpGetDbOperationByTraceId/server.handle_call_tool.handle_call_tool_scope....ValueError","sourceNodeId":"handle_call_tool \\n[server.py : 37_59]","targetNodeId":"/src/mcpGetDbOperationByTraceId/src/mcpGetDbOperationByTraceId/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpGetDbOperationByTraceId/src/mcpGetDbOperationByTraceId/server.py"},"region":{"startLine":55,"startColumn":23,"endLine":55,"endColumn":62,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 37_59]->/src/mcpGetDbOperationByTraceId/src/mcpGetDbOperationByTraceId/server.handle_call_tool.handle_call_tool_scope....ValueError","sourceNodeId":"handle_call_tool \\n[server.py : 37_59]","targetNodeId":"/src/mcpGetDbOperationByTraceId/src/mcpGetDbOperationByTraceId/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpGetDbOperationByTraceId/src/mcpGetDbOperationByTraceId/server.py"},"region":{"startLine":56,"startColumn":27,"endLine":56,"endColumn":115,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 37_59]->get_db_operation_by_trace_id \\n[server.py : 77_126]","sourceNodeId":"handle_call_tool \\n[server.py : 37_59]","targetNodeId":"get_db_operation_by_trace_id \\n[server.py : 77_126]"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpGetDbOperationByTraceId/src/mcpGetDbOperationByTraceId/server.py"},"region":{"startLine":103,"startColumn":19,"endLine":103,"endColumn":50,"snippet":{}}}},"id":"get_db_operation_by_trace_id \\n[server.py : 77_126]->syslib_from.aiohttp.ClientTimeout","sourceNodeId":"get_db_operation_by_trace_id \\n[server.py : 77_126]","targetNodeId":"syslib_from.aiohttp.ClientTimeout"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpGetDbOperationByTraceId/src/mcpGetDbOperationByTraceId/server.py"},"region":{"startLine":104,"startColumn":20,"endLine":104,"endColumn":58,"snippet":{}}}},"id":"get_db_operation_by_trace_id \\n[server.py : 77_126]->syslib_from.aiohttp.ClientSession","sourceNodeId":"get_db_operation_by_trace_id \\n[server.py : 77_126]","targetNodeId":"syslib_from.aiohttp.ClientSession"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpGetDbOperationByTraceId/src/mcpGetDbOperationByTraceId/server.py"},"region":{"startLine":105,"startColumn":24,"endLine":110,"endColumn":14,"snippet":{}}}},"id":"get_db_operation_by_trace_id \\n[server.py : 77_126]->syslib_from.aiohttp.ClientSession(var timeout:any=timeout).post","sourceNodeId":"get_db_operation_by_trace_id \\n[server.py : 77_126]","targetNodeId":"syslib_from.aiohttp.ClientSession(var timeout:any=timeout).post"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpGetDbOperationByTraceId/src/mcpGetDbOperationByTraceId/server.py"},"region":{"startLine":111,"startColumn":17,"endLine":111,"endColumn":40,"snippet":{}}}},"id":"get_db_operation_by_trace_id \\n[server.py : 77_126]->syslib_from.aiohttp.ClientSession(var timeout:any=timeout).post(var url:any=url, var headers:any=headers, var json:any=request_body, var ssl:any=false).raise_for_status","sourceNodeId":"get_db_operation_by_trace_id \\n[server.py : 77_126]","targetNodeId":"syslib_from.aiohttp.ClientSession(var timeout:any=timeout).post(var url:any=url, var headers:any=headers, var json:any=request_body, var ssl:any=false).raise_for_status"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpGetDbOperationByTraceId/src/mcpGetDbOperationByTraceId/server.py"},"region":{"startLine":113,"startColumn":38,"endLine":113,"endColumn":55,"snippet":{}}}},"id":"get_db_operation_by_trace_id \\n[server.py : 77_126]->syslib_from.aiohttp.ClientSession(var timeout:any=timeout).post(var url:any=url, var headers:any=headers, var json:any=request_body, var ssl:any=false).json","sourceNodeId":"get_db_operation_by_trace_id \\n[server.py : 77_126]","targetNodeId":"syslib_from.aiohttp.ClientSession(var timeout:any=timeout).post(var url:any=url, var headers:any=headers, var json:any=request_body, var ssl:any=false).json"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpGetDbOperationByTraceId/src/mcpGetDbOperationByTraceId/server.py"},"region":{"startLine":116,"startColumn":33,"endLine":116,"endColumn":58,"snippet":{}}}},"id":"get_db_operation_by_trace_id \\n[server.py : 77_126]->syslib_from.aiohttp.ClientSession(var timeout:any=timeout).post(var url:any=url, var headers:any=headers, var json:any=request_body, var ssl:any=false).json().get","sourceNodeId":"get_db_operation_by_trace_id \\n[server.py : 77_126]","targetNodeId":"syslib_from.aiohttp.ClientSession(var timeout:any=timeout).post(var url:any=url, var headers:any=headers, var json:any=request_body, var ssl:any=false).json().get"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpGetDbOperationByTraceId/src/mcpGetDbOperationByTraceId/server.py"},"region":{"startLine":119,"startColumn":73,"endLine":119,"endColumn":92,"snippet":{}}}},"id":"get_db_operation_by_trace_id \\n[server.py : 77_126]->syslib_from.aiohttp.ClientSession(var timeout:any=timeout).post(var url:any=url, var headers:any=headers, var json:any=request_body, var ssl:any=false).text","sourceNodeId":"get_db_operation_by_trace_id \\n[server.py : 77_126]","targetNodeId":"syslib_from.aiohttp.ClientSession(var timeout:any=timeout).post(var url:any=url, var headers:any=headers, var json:any=request_body, var ssl:any=false).text"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpGetDbOperationByTraceId/src/mcpGetDbOperationByTraceId/server.py"},"region":{"startLine":125,"startColumn":9,"endLine":125,"endColumn":50,"snippet":{}}}},"id":"get_db_operation_by_trace_id \\n[server.py : 77_126]->syslib_from.logging.getLogger(mcp-server).warning","sourceNodeId":"get_db_operation_by_trace_id \\n[server.py : 77_126]","targetNodeId":"syslib_from.logging.getLogger(mcp-server).warning"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpGetDbOperationByTraceId/src/mcpGetDbOperationByTraceId/server.py"},"region":{"startLine":57,"startColumn":21,"endLine":57,"endColumn":74,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 37_59]->syslib_from.mcp/types.TextContent","sourceNodeId":"handle_call_tool \\n[server.py : 37_59]","targetNodeId":"syslib_from.mcp/types.TextContent"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpGetDbOperationByTraceId/src/mcpGetDbOperationByTraceId/server.py"},"region":{"startLine":59,"startColumn":19,"endLine":59,"endColumn":54,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 37_59]->/src/mcpGetDbOperationByTraceId/src/mcpGetDbOperationByTraceId/server.handle_call_tool.handle_call_tool_scope...ValueError","sourceNodeId":"handle_call_tool \\n[server.py : 37_59]","targetNodeId":"/src/mcpGetDbOperationByTraceId/src/mcpGetDbOperationByTraceId/server.handle_call_tool.handle_call_tool_scope...ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpGlobalSearch/src/mcpGlobalSearch/server.py"},"region":{"startLine":165,"startColumn":1,"endLine":206,"endColumn":6,"snippet":{}}}},"id":"<__entry_point__>->handle_call_tool \\n[server.py : 165_206]","sourceNodeId":"<__entry_point__>","targetNodeId":"handle_call_tool \\n[server.py : 165_206]"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpGlobalSearch/src/mcpGlobalSearch/server.py"},"region":{"startLine":172,"startColumn":80,"endLine":172,"endColumn":123,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 165_206]->syslib_from.json.dumps","sourceNodeId":"handle_call_tool \\n[server.py : 165_206]","targetNodeId":"syslib_from.json.dumps"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpGlobalSearch/src/mcpGlobalSearch/server.py"},"region":{"startLine":172,"startColumn":5,"endLine":172,"endColumn":125,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 165_206]->syslib_from.logging.getLogger(mcp-server).info","sourceNodeId":"handle_call_tool \\n[server.py : 165_206]","targetNodeId":"syslib_from.logging.getLogger(mcp-server).info"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpGlobalSearch/src/mcpGlobalSearch/server.py"},"region":{"startLine":175,"startColumn":15,"endLine":175,"endColumn":50,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 165_206]->/src/mcpGlobalSearch/src/mcpGlobalSearch/server.handle_call_tool.handle_call_tool_scope...ValueError","sourceNodeId":"handle_call_tool \\n[server.py : 165_206]","targetNodeId":"/src/mcpGlobalSearch/src/mcpGlobalSearch/server.handle_call_tool.handle_call_tool_scope...ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpGlobalSearch/src/mcpGlobalSearch/server.py"},"region":{"startLine":178,"startColumn":15,"endLine":178,"endColumn":46,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 165_206]->/src/mcpGlobalSearch/src/mcpGlobalSearch/server.handle_call_tool.handle_call_tool_scope...ValueError","sourceNodeId":"handle_call_tool \\n[server.py : 165_206]","targetNodeId":"/src/mcpGlobalSearch/src/mcpGlobalSearch/server.handle_call_tool.handle_call_tool_scope...ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpGlobalSearch/src/mcpGlobalSearch/server.py"},"region":{"startLine":184,"startColumn":17,"endLine":184,"endColumn":57,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 165_206]->/src/mcpGlobalSearch/src/mcpGlobalSearch/server.handle_call_tool.arguments.get","sourceNodeId":"handle_call_tool \\n[server.py : 165_206]","targetNodeId":"/src/mcpGlobalSearch/src/mcpGlobalSearch/server.handle_call_tool.arguments.get"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpGlobalSearch/src/mcpGlobalSearch/server.py"},"region":{"startLine":187,"startColumn":15,"endLine":187,"endColumn":95,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 165_206]->/src/mcpGlobalSearch/src/mcpGlobalSearch/server.handle_call_tool.handle_call_tool_scope...ValueError","sourceNodeId":"handle_call_tool \\n[server.py : 165_206]","targetNodeId":"/src/mcpGlobalSearch/src/mcpGlobalSearch/server.handle_call_tool.handle_call_tool_scope...ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpGlobalSearch/src/mcpGlobalSearch/server.py"},"region":{"startLine":190,"startColumn":15,"endLine":190,"endColumn":81,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 165_206]->/src/mcpGlobalSearch/src/mcpGlobalSearch/server.handle_call_tool.handle_call_tool_scope...ValueError","sourceNodeId":"handle_call_tool \\n[server.py : 165_206]","targetNodeId":"/src/mcpGlobalSearch/src/mcpGlobalSearch/server.handle_call_tool.handle_call_tool_scope...ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpGlobalSearch/src/mcpGlobalSearch/server.py"},"region":{"startLine":193,"startColumn":11,"endLine":199,"endColumn":6,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 165_206]->symbol_global_search \\n[server.py : 117_161]","sourceNodeId":"handle_call_tool \\n[server.py : 165_206]","targetNodeId":"symbol_global_search \\n[server.py : 117_161]"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpGlobalSearch/src/mcpGlobalSearch/server.py"},"region":{"startLine":128,"startColumn":20,"endLine":137,"endColumn":14,"snippet":{}}}},"id":"symbol_global_search \\n[server.py : 117_161]->/src/mcpGlobalSearch/src/mcpGlobalSearch/server.symbol_global_search.symbol_global_search_scope..dict","sourceNodeId":"symbol_global_search \\n[server.py : 117_161]","targetNodeId":"/src/mcpGlobalSearch/src/mcpGlobalSearch/server.symbol_global_search.symbol_global_search_scope..dict"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpGlobalSearch/src/mcpGlobalSearch/server.py"},"region":{"startLine":127,"startColumn":39,"endLine":138,"endColumn":10,"snippet":{}}}},"id":"symbol_global_search \\n[server.py : 117_161]->mcp_common.remote.codeinsight.code_insight_api.mcp_server_backend_api","sourceNodeId":"symbol_global_search \\n[server.py : 117_161]","targetNodeId":"mcp_common.remote.codeinsight.code_insight_api.mcp_server_backend_api"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpGlobalSearch/src/mcpGlobalSearch/server.py"},"region":{"startLine":139,"startColumn":12,"endLine":139,"endColumn":41,"snippet":{}}}},"id":"symbol_global_search \\n[server.py : 117_161]->/src/mcpGlobalSearch/src/mcpGlobalSearch/server.symbol_global_search.symbol_global_search_scope..isinstance","sourceNodeId":"symbol_global_search \\n[server.py : 117_161]","targetNodeId":"/src/mcpGlobalSearch/src/mcpGlobalSearch/server.symbol_global_search.symbol_global_search_scope..isinstance"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpGlobalSearch/src/mcpGlobalSearch/server.py"},"region":{"startLine":152,"startColumn":23,"endLine":152,"endColumn":63,"snippet":{}}}},"id":"symbol_global_search \\n[server.py : 117_161]->mcp_common.remote.codeinsight.code_insight_api.mcp_server_backend_api(var params:any=dict(var name:any=Consts.GLOBAL_SEARCH.name, var arguments:any=dict(var searchType:any=search_type, var searchPatte...","sourceNodeId":"symbol_global_search \\n[server.py : 117_161]","targetNodeId":"mcp_common.remote.codeinsight.code_insight_api.mcp_server_backend_api(var params:any=dict(var name:any=Consts.GLOBAL_SEARCH.name, var arguments:any=dict(var searchType:any=search_type, var searchPatte..."},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpGlobalSearch/src/mcpGlobalSearch/server.py"},"region":{"startLine":146,"startColumn":32,"endLine":146,"endColumn":43,"snippet":{}}}},"id":"symbol_global_search \\n[server.py : 117_161]->mcp_common.remote.codefuse_search.Symbol","sourceNodeId":"symbol_global_search \\n[server.py : 117_161]","targetNodeId":"mcp_common.remote.codefuse_search.Symbol"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpGlobalSearch/src/mcpGlobalSearch/server.py"},"region":{"startLine":147,"startColumn":38,"endLine":147,"endColumn":60,"snippet":{}}}},"id":"symbol_global_search \\n[server.py : 117_161]->/src/mcpGlobalSearch/src/mcpGlobalSearch/server.symbol_global_search.symbol_global_search_scope.....enumerate","sourceNodeId":"symbol_global_search \\n[server.py : 117_161]","targetNodeId":"/src/mcpGlobalSearch/src/mcpGlobalSearch/server.symbol_global_search.symbol_global_search_scope.....enumerate"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpGlobalSearch/src/mcpGlobalSearch/server.py"},"region":{"startLine":148,"startColumn":42,"endLine":148,"endColumn":56,"snippet":{}}}},"id":"symbol_global_search \\n[server.py : 117_161]->/src/mcpGlobalSearch/src/mcpGlobalSearch/server.symbol_global_search.symbol_global_search_scope.........syslib_from.logging.getLogger(mcp-server).info","sourceNodeId":"symbol_global_search \\n[server.py : 117_161]","targetNodeId":"syslib_from.logging.getLogger(mcp-server).info"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpGlobalSearch/src/mcpGlobalSearch/server.py"},"region":{"startLine":154,"startColumn":39,"endLine":154,"endColumn":74,"snippet":{}}}},"id":"symbol_global_search \\n[server.py : 117_161]->syslib_from.json.dumps","sourceNodeId":"symbol_global_search \\n[server.py : 117_161]","targetNodeId":"syslib_from.json.dumps"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpGlobalSearch/src/mcpGlobalSearch/server.py"},"region":{"startLine":153,"startColumn":17,"endLine":154,"endColumn":76,"snippet":{}}}},"id":"symbol_global_search \\n[server.py : 117_161]->syslib_from.logging.getLogger(mcp-server).warning","sourceNodeId":"symbol_global_search \\n[server.py : 117_161]","targetNodeId":"syslib_from.logging.getLogger(mcp-server).warning"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpGlobalSearch/src/mcpGlobalSearch/server.py"},"region":{"startLine":157,"startColumn":9,"endLine":157,"endColumn":108,"snippet":{}}}},"id":"symbol_global_search \\n[server.py : 117_161]->syslib_from.logging.getLogger(mcp-server).exception","sourceNodeId":"symbol_global_search \\n[server.py : 117_161]","targetNodeId":"syslib_from.logging.getLogger(mcp-server).exception"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpGlobalSearch/src/mcpGlobalSearch/server.py"},"region":{"startLine":202,"startColumn":9,"endLine":205,"endColumn":10,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 165_206]->syslib_from.mcp/types.TextContent","sourceNodeId":"handle_call_tool \\n[server.py : 165_206]","targetNodeId":"syslib_from.mcp/types.TextContent"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpLinglong/src/mcpLinglong/server.py"},"region":{"startLine":82,"startColumn":1,"endLine":115,"endColumn":54,"snippet":{}}}},"id":"<__entry_point__>->handle_call_tool \\n[server.py : 82_115]","sourceNodeId":"<__entry_point__>","targetNodeId":"handle_call_tool \\n[server.py : 82_115]"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpLinglong/src/mcpLinglong/server.py"},"region":{"startLine":90,"startColumn":67,"endLine":90,"endColumn":110,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 82_115]->syslib_from.json.dumps","sourceNodeId":"handle_call_tool \\n[server.py : 82_115]","targetNodeId":"syslib_from.json.dumps"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpLinglong/src/mcpLinglong/server.py"},"region":{"startLine":89,"startColumn":5,"endLine":90,"endColumn":112,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 82_115]->syslib_from.logging.getLogger(mcp-server).info","sourceNodeId":"handle_call_tool \\n[server.py : 82_115]","targetNodeId":"syslib_from.logging.getLogger(mcp-server).info"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpLinglong/src/mcpLinglong/server.py"},"region":{"startLine":94,"startColumn":23,"endLine":94,"endColumn":53,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 82_115]->/src/mcpLinglong/src/mcpLinglong/server.handle_call_tool.handle_call_tool_scope....ValueError","sourceNodeId":"handle_call_tool \\n[server.py : 82_115]","targetNodeId":"/src/mcpLinglong/src/mcpLinglong/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpLinglong/src/mcpLinglong/server.py"},"region":{"startLine":96,"startColumn":23,"endLine":96,"endColumn":57,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 82_115]->/src/mcpLinglong/src/mcpLinglong/server.handle_call_tool.handle_call_tool_scope....ValueError","sourceNodeId":"handle_call_tool \\n[server.py : 82_115]","targetNodeId":"/src/mcpLinglong/src/mcpLinglong/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpLinglong/src/mcpLinglong/server.py"},"region":{"startLine":98,"startColumn":23,"endLine":98,"endColumn":68,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 82_115]->/src/mcpLinglong/src/mcpLinglong/server.handle_call_tool.handle_call_tool_scope....ValueError","sourceNodeId":"handle_call_tool \\n[server.py : 82_115]","targetNodeId":"/src/mcpLinglong/src/mcpLinglong/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpLinglong/src/mcpLinglong/server.py"},"region":{"startLine":100,"startColumn":23,"endLine":100,"endColumn":63,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 82_115]->/src/mcpLinglong/src/mcpLinglong/server.handle_call_tool.handle_call_tool_scope....ValueError","sourceNodeId":"handle_call_tool \\n[server.py : 82_115]","targetNodeId":"/src/mcpLinglong/src/mcpLinglong/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpLinglong/src/mcpLinglong/server.py"},"region":{"startLine":101,"startColumn":27,"endLine":105,"endColumn":96,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 82_115]->get_module_by_scene_service \\n[server.py : 135_171]","sourceNodeId":"handle_call_tool \\n[server.py : 82_115]","targetNodeId":"get_module_by_scene_service \\n[server.py : 135_171]"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpLinglong/src/mcpLinglong/server.py"},"region":{"startLine":152,"startColumn":15,"endLine":158,"endColumn":10,"snippet":{}}}},"id":"get_module_by_scene_service \\n[server.py : 135_171]->oneapi.linglongmng.LinglongModuleFacade.ModuleQueryBySceneServiceRequest","sourceNodeId":"get_module_by_scene_service \\n[server.py : 135_171]","targetNodeId":"oneapi.linglongmng.LinglongModuleFacade.ModuleQueryBySceneServiceRequest"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpLinglong/src/mcpLinglong/server.py"},"region":{"startLine":159,"startColumn":16,"endLine":159,"endColumn":62,"snippet":{}}}},"id":"get_module_by_scene_service \\n[server.py : 135_171]->oneapi.linglongmng.LinglongModuleFacade.LinglongModuleFacade(layotto).queryModuleBySceneService","sourceNodeId":"get_module_by_scene_service \\n[server.py : 135_171]","targetNodeId":"oneapi.linglongmng.LinglongModuleFacade.LinglongModuleFacade(layotto).queryModuleBySceneService"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpLinglong/src/mcpLinglong/server.py"},"region":{"startLine":161,"startColumn":13,"endLine":161,"endColumn":118,"snippet":{}}}},"id":"get_module_by_scene_service \\n[server.py : 135_171]->syslib_from.logging.getLogger(mcp-server).warning","sourceNodeId":"get_module_by_scene_service \\n[server.py : 135_171]","targetNodeId":"syslib_from.logging.getLogger(mcp-server).warning"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpLinglong/src/mcpLinglong/server.py"},"region":{"startLine":165,"startColumn":27,"endLine":165,"endColumn":42,"snippet":{}}}},"id":"get_module_by_scene_service \\n[server.py : 135_171]->oneapi.linglongmng.LinglongModuleFacade.LinglongModuleFacade(layotto).queryModuleBySceneService(req).data.data.get_json","sourceNodeId":"get_module_by_scene_service \\n[server.py : 135_171]","targetNodeId":"oneapi.linglongmng.LinglongModuleFacade.LinglongModuleFacade(layotto).queryModuleBySceneService(req).data.data.get_json"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpLinglong/src/mcpLinglong/server.py"},"region":{"startLine":166,"startColumn":15,"endLine":166,"endColumn":53,"snippet":{}}}},"id":"get_module_by_scene_service \\n[server.py : 135_171]->syslib_from.json.dumps","sourceNodeId":"get_module_by_scene_service \\n[server.py : 135_171]","targetNodeId":"syslib_from.json.dumps"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpLinglong/src/mcpLinglong/server.py"},"region":{"startLine":167,"startColumn":9,"endLine":167,"endColumn":102,"snippet":{}}}},"id":"get_module_by_scene_service \\n[server.py : 135_171]->syslib_from.logging.getLogger(mcp-server).info","sourceNodeId":"get_module_by_scene_service \\n[server.py : 135_171]","targetNodeId":"syslib_from.logging.getLogger(mcp-server).info"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpLinglong/src/mcpLinglong/server.py"},"region":{"startLine":170,"startColumn":9,"endLine":170,"endColumn":101,"snippet":{}}}},"id":"get_module_by_scene_service \\n[server.py : 135_171]->syslib_from.logging.getLogger(mcp-server).error","sourceNodeId":"get_module_by_scene_service \\n[server.py : 135_171]","targetNodeId":"syslib_from.logging.getLogger(mcp-server).error"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpLinglong/src/mcpLinglong/server.py"},"region":{"startLine":113,"startColumn":21,"endLine":113,"endColumn":74,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 82_115]->syslib_from.mcp/types.TextContent","sourceNodeId":"handle_call_tool \\n[server.py : 82_115]","targetNodeId":"syslib_from.mcp/types.TextContent"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpLinglong/src/mcpLinglong/server.py"},"region":{"startLine":109,"startColumn":23,"endLine":109,"endColumn":53,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 82_115]->/src/mcpLinglong/src/mcpLinglong/server.handle_call_tool.handle_call_tool_scope....ValueError","sourceNodeId":"handle_call_tool \\n[server.py : 82_115]","targetNodeId":"/src/mcpLinglong/src/mcpLinglong/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpLinglong/src/mcpLinglong/server.py"},"region":{"startLine":111,"startColumn":23,"endLine":111,"endColumn":56,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 82_115]->/src/mcpLinglong/src/mcpLinglong/server.handle_call_tool.handle_call_tool_scope....ValueError","sourceNodeId":"handle_call_tool \\n[server.py : 82_115]","targetNodeId":"/src/mcpLinglong/src/mcpLinglong/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpLinglong/src/mcpLinglong/server.py"},"region":{"startLine":112,"startColumn":27,"endLine":112,"endColumn":71,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 82_115]->get_function_by_id \\n[server.py : 174_192]","sourceNodeId":"handle_call_tool \\n[server.py : 82_115]","targetNodeId":"get_function_by_id \\n[server.py : 174_192]"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpLinglong/src/mcpLinglong/server.py"},"region":{"startLine":183,"startColumn":16,"endLine":183,"endColumn":47,"snippet":{}}}},"id":"get_function_by_id \\n[server.py : 174_192]->oneapi.linglongmng.FunctionMngServiceFacade.FunctionMngServiceFacade(layotto).queryById","sourceNodeId":"get_function_by_id \\n[server.py : 174_192]","targetNodeId":"oneapi.linglongmng.FunctionMngServiceFacade.FunctionMngServiceFacade(layotto).queryById"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpLinglong/src/mcpLinglong/server.py"},"region":{"startLine":185,"startColumn":13,"endLine":185,"endColumn":107,"snippet":{}}}},"id":"get_function_by_id \\n[server.py : 174_192]->syslib_from.logging.getLogger(mcp-server).warning","sourceNodeId":"get_function_by_id \\n[server.py : 174_192]","targetNodeId":"syslib_from.logging.getLogger(mcp-server).warning"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpLinglong/src/mcpLinglong/server.py"},"region":{"startLine":187,"startColumn":26,"endLine":187,"endColumn":51,"snippet":{}}}},"id":"get_function_by_id \\n[server.py : 174_192]->oneapi.linglongmng.FunctionMngServiceFacade.FunctionMngServiceFacade(layotto).queryById(id).data.data.get_json","sourceNodeId":"get_function_by_id \\n[server.py : 174_192]","targetNodeId":"oneapi.linglongmng.FunctionMngServiceFacade.FunctionMngServiceFacade(layotto).queryById(id).data.data.get_json"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpLinglong/src/mcpLinglong/server.py"},"region":{"startLine":187,"startColumn":15,"endLine":187,"endColumn":72,"snippet":{}}}},"id":"get_function_by_id \\n[server.py : 174_192]->syslib_from.json.dumps","sourceNodeId":"get_function_by_id \\n[server.py : 174_192]","targetNodeId":"syslib_from.json.dumps"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpLinglong/src/mcpLinglong/server.py"},"region":{"startLine":188,"startColumn":9,"endLine":188,"endColumn":93,"snippet":{}}}},"id":"get_function_by_id \\n[server.py : 174_192]->syslib_from.logging.getLogger(mcp-server).info","sourceNodeId":"get_function_by_id \\n[server.py : 174_192]","targetNodeId":"syslib_from.logging.getLogger(mcp-server).info"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpLinglong/src/mcpLinglong/server.py"},"region":{"startLine":191,"startColumn":9,"endLine":191,"endColumn":92,"snippet":{}}}},"id":"get_function_by_id \\n[server.py : 174_192]->syslib_from.logging.getLogger(mcp-server).error","sourceNodeId":"get_function_by_id \\n[server.py : 174_192]","targetNodeId":"syslib_from.logging.getLogger(mcp-server).error"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpLinglong/src/mcpLinglong/server.py"},"region":{"startLine":115,"startColumn":19,"endLine":115,"endColumn":54,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 82_115]->/src/mcpLinglong/src/mcpLinglong/server.handle_call_tool.handle_call_tool_scope...ValueError","sourceNodeId":"handle_call_tool \\n[server.py : 82_115]","targetNodeId":"/src/mcpLinglong/src/mcpLinglong/server.handle_call_tool.handle_call_tool_scope...ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpLinkw/src/mcpLinkw/server.py"},"region":{"startLine":65,"startColumn":1,"endLine":91,"endColumn":54,"snippet":{}}}},"id":"<__entry_point__>->handle_call_tool \\n[server.py : 65_91]","sourceNodeId":"<__entry_point__>","targetNodeId":"handle_call_tool \\n[server.py : 65_91]"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpLinkw/src/mcpLinkw/server.py"},"region":{"startLine":73,"startColumn":64,"endLine":73,"endColumn":107,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 65_91]->syslib_from.json.dumps","sourceNodeId":"handle_call_tool \\n[server.py : 65_91]","targetNodeId":"syslib_from.json.dumps"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpLinkw/src/mcpLinkw/server.py"},"region":{"startLine":72,"startColumn":5,"endLine":73,"endColumn":109,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 65_91]->syslib_from.logging.getLogger(mcp-server).info","sourceNodeId":"handle_call_tool \\n[server.py : 65_91]","targetNodeId":"syslib_from.logging.getLogger(mcp-server).info"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpLinkw/src/mcpLinkw/server.py"},"region":{"startLine":77,"startColumn":23,"endLine":77,"endColumn":53,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 65_91]->/src/mcpLinkw/src/mcpLinkw/server.handle_call_tool.handle_call_tool_scope....ValueError","sourceNodeId":"handle_call_tool \\n[server.py : 65_91]","targetNodeId":"/src/mcpLinkw/src/mcpLinkw/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpLinkw/src/mcpLinkw/server.py"},"region":{"startLine":79,"startColumn":23,"endLine":79,"endColumn":62,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 65_91]->/src/mcpLinkw/src/mcpLinkw/server.handle_call_tool.handle_call_tool_scope....ValueError","sourceNodeId":"handle_call_tool \\n[server.py : 65_91]","targetNodeId":"/src/mcpLinkw/src/mcpLinkw/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpLinkw/src/mcpLinkw/server.py"},"region":{"startLine":80,"startColumn":27,"endLine":80,"endColumn":103,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 65_91]->get_joint_debug_env_detail_by_group_id \\n[server.py : 111_131]","sourceNodeId":"handle_call_tool \\n[server.py : 65_91]","targetNodeId":"get_joint_debug_env_detail_by_group_id \\n[server.py : 111_131]"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpLinkw/src/mcpLinkw/server.py"},"region":{"startLine":124,"startColumn":20,"endLine":124,"endColumn":83,"snippet":{}}}},"id":"get_joint_debug_env_detail_by_group_id \\n[server.py : 111_131]->syslib_from.requests.get","sourceNodeId":"get_joint_debug_env_detail_by_group_id \\n[server.py : 111_131]","targetNodeId":"syslib_from.requests.get"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpLinkw/src/mcpLinkw/server.py"},"region":{"startLine":125,"startColumn":9,"endLine":125,"endColumn":36,"snippet":{}}}},"id":"get_joint_debug_env_detail_by_group_id \\n[server.py : 111_131]->syslib_from.requests.get(url, var headers:any=LINKW_OPEN_API_HEADER, var params:any=params).raise_for_status","sourceNodeId":"get_joint_debug_env_detail_by_group_id \\n[server.py : 111_131]","targetNodeId":"syslib_from.requests.get(url, var headers:any=LINKW_OPEN_API_HEADER, var params:any=params).raise_for_status"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpLinkw/src/mcpLinkw/server.py"},"region":{"startLine":126,"startColumn":18,"endLine":126,"endColumn":33,"snippet":{}}}},"id":"get_joint_debug_env_detail_by_group_id \\n[server.py : 111_131]->syslib_from.requests.get(url, var headers:any=LINKW_OPEN_API_HEADER, var params:any=params).json","sourceNodeId":"get_joint_debug_env_detail_by_group_id \\n[server.py : 111_131]","targetNodeId":"syslib_from.requests.get(url, var headers:any=LINKW_OPEN_API_HEADER, var params:any=params).json"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpLinkw/src/mcpLinkw/server.py"},"region":{"startLine":127,"startColumn":9,"endLine":127,"endColumn":113,"snippet":{}}}},"id":"get_joint_debug_env_detail_by_group_id \\n[server.py : 111_131]->syslib_from.logging.getLogger(mcp-server).info","sourceNodeId":"get_joint_debug_env_detail_by_group_id \\n[server.py : 111_131]","targetNodeId":"syslib_from.logging.getLogger(mcp-server).info"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpLinkw/src/mcpLinkw/server.py"},"region":{"startLine":128,"startColumn":27,"endLine":128,"endColumn":45,"snippet":{}}}},"id":"get_joint_debug_env_detail_by_group_id \\n[server.py : 111_131]->syslib_from.requests.get(url, var headers:any=LINKW_OPEN_API_HEADER, var params:any=params).json().get","sourceNodeId":"get_joint_debug_env_detail_by_group_id \\n[server.py : 111_131]","targetNodeId":"syslib_from.requests.get(url, var headers:any=LINKW_OPEN_API_HEADER, var params:any=params).json().get"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpLinkw/src/mcpLinkw/server.py"},"region":{"startLine":128,"startColumn":16,"endLine":128,"endColumn":66,"snippet":{}}}},"id":"get_joint_debug_env_detail_by_group_id \\n[server.py : 111_131]->syslib_from.json.dumps","sourceNodeId":"get_joint_debug_env_detail_by_group_id \\n[server.py : 111_131]","targetNodeId":"syslib_from.json.dumps"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpLinkw/src/mcpLinkw/server.py"},"region":{"startLine":130,"startColumn":9,"endLine":130,"endColumn":109,"snippet":{}}}},"id":"get_joint_debug_env_detail_by_group_id \\n[server.py : 111_131]->syslib_from.logging.getLogger(mcp-server).error","sourceNodeId":"get_joint_debug_env_detail_by_group_id \\n[server.py : 111_131]","targetNodeId":"syslib_from.logging.getLogger(mcp-server).error"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpLinkw/src/mcpLinkw/server.py"},"region":{"startLine":89,"startColumn":21,"endLine":89,"endColumn":74,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 65_91]->syslib_from.mcp/types.TextContent","sourceNodeId":"handle_call_tool \\n[server.py : 65_91]","targetNodeId":"syslib_from.mcp/types.TextContent"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpLinkw/src/mcpLinkw/server.py"},"region":{"startLine":84,"startColumn":23,"endLine":84,"endColumn":53,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 65_91]->/src/mcpLinkw/src/mcpLinkw/server.handle_call_tool.handle_call_tool_scope....ValueError","sourceNodeId":"handle_call_tool \\n[server.py : 65_91]","targetNodeId":"/src/mcpLinkw/src/mcpLinkw/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpLinkw/src/mcpLinkw/server.py"},"region":{"startLine":86,"startColumn":23,"endLine":86,"endColumn":63,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 65_91]->/src/mcpLinkw/src/mcpLinkw/server.handle_call_tool.handle_call_tool_scope....ValueError","sourceNodeId":"handle_call_tool \\n[server.py : 65_91]","targetNodeId":"/src/mcpLinkw/src/mcpLinkw/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpLinkw/src/mcpLinkw/server.py"},"region":{"startLine":87,"startColumn":27,"endLine":88,"endColumn":88,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 65_91]->get_pod_detail_by_dev_group \\n[server.py : 134_156]","sourceNodeId":"handle_call_tool \\n[server.py : 65_91]","targetNodeId":"get_pod_detail_by_dev_group \\n[server.py : 134_156]"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpLinkw/src/mcpLinkw/server.py"},"region":{"startLine":149,"startColumn":20,"endLine":149,"endColumn":83,"snippet":{}}}},"id":"get_pod_detail_by_dev_group \\n[server.py : 134_156]->syslib_from.requests.get","sourceNodeId":"get_pod_detail_by_dev_group \\n[server.py : 134_156]","targetNodeId":"syslib_from.requests.get"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpLinkw/src/mcpLinkw/server.py"},"region":{"startLine":150,"startColumn":9,"endLine":150,"endColumn":36,"snippet":{}}}},"id":"get_pod_detail_by_dev_group \\n[server.py : 134_156]->syslib_from.requests.get(url, var headers:any=LINKW_OPEN_API_HEADER, var params:any=params).raise_for_status","sourceNodeId":"get_pod_detail_by_dev_group \\n[server.py : 134_156]","targetNodeId":"syslib_from.requests.get(url, var headers:any=LINKW_OPEN_API_HEADER, var params:any=params).raise_for_status"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpLinkw/src/mcpLinkw/server.py"},"region":{"startLine":151,"startColumn":18,"endLine":151,"endColumn":33,"snippet":{}}}},"id":"get_pod_detail_by_dev_group \\n[server.py : 134_156]->syslib_from.requests.get(url, var headers:any=LINKW_OPEN_API_HEADER, var params:any=params).json","sourceNodeId":"get_pod_detail_by_dev_group \\n[server.py : 134_156]","targetNodeId":"syslib_from.requests.get(url, var headers:any=LINKW_OPEN_API_HEADER, var params:any=params).json"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpLinkw/src/mcpLinkw/server.py"},"region":{"startLine":152,"startColumn":9,"endLine":152,"endColumn":102,"snippet":{}}}},"id":"get_pod_detail_by_dev_group \\n[server.py : 134_156]->syslib_from.logging.getLogger(mcp-server).info","sourceNodeId":"get_pod_detail_by_dev_group \\n[server.py : 134_156]","targetNodeId":"syslib_from.logging.getLogger(mcp-server).info"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpLinkw/src/mcpLinkw/server.py"},"region":{"startLine":153,"startColumn":27,"endLine":153,"endColumn":45,"snippet":{}}}},"id":"get_pod_detail_by_dev_group \\n[server.py : 134_156]->syslib_from.requests.get(url, var headers:any=LINKW_OPEN_API_HEADER, var params:any=params).json().get","sourceNodeId":"get_pod_detail_by_dev_group \\n[server.py : 134_156]","targetNodeId":"syslib_from.requests.get(url, var headers:any=LINKW_OPEN_API_HEADER, var params:any=params).json().get"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpLinkw/src/mcpLinkw/server.py"},"region":{"startLine":153,"startColumn":16,"endLine":153,"endColumn":66,"snippet":{}}}},"id":"get_pod_detail_by_dev_group \\n[server.py : 134_156]->syslib_from.json.dumps","sourceNodeId":"get_pod_detail_by_dev_group \\n[server.py : 134_156]","targetNodeId":"syslib_from.json.dumps"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpLinkw/src/mcpLinkw/server.py"},"region":{"startLine":155,"startColumn":9,"endLine":155,"endColumn":98,"snippet":{}}}},"id":"get_pod_detail_by_dev_group \\n[server.py : 134_156]->syslib_from.logging.getLogger(mcp-server).error","sourceNodeId":"get_pod_detail_by_dev_group \\n[server.py : 134_156]","targetNodeId":"syslib_from.logging.getLogger(mcp-server).error"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpLinkw/src/mcpLinkw/server.py"},"region":{"startLine":91,"startColumn":19,"endLine":91,"endColumn":54,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 65_91]->/src/mcpLinkw/src/mcpLinkw/server.handle_call_tool.handle_call_tool_scope...ValueError","sourceNodeId":"handle_call_tool \\n[server.py : 65_91]","targetNodeId":"/src/mcpLinkw/src/mcpLinkw/server.handle_call_tool.handle_call_tool_scope...ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpLogQuery/src/mcpLogQuery/server.py"},"region":{"startLine":94,"startColumn":1,"endLine":165,"endColumn":11,"snippet":{}}}},"id":"<__entry_point__>->handle_call_tool \\n[server.py : 94_165]","sourceNodeId":"<__entry_point__>","targetNodeId":"handle_call_tool \\n[server.py : 94_165]"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpLogQuery/src/mcpLogQuery/server.py"},"region":{"startLine":101,"startColumn":81,"endLine":101,"endColumn":124,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 94_165]->syslib_from.json.dumps","sourceNodeId":"handle_call_tool \\n[server.py : 94_165]","targetNodeId":"syslib_from.json.dumps"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpLogQuery/src/mcpLogQuery/server.py"},"region":{"startLine":152,"startColumn":17,"endLine":152,"endColumn":98,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 94_165]->syslib_from.logging.getLogger(mcp-server).info","sourceNodeId":"handle_call_tool \\n[server.py : 94_165]","targetNodeId":"syslib_from.logging.getLogger(mcp-server).info"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpLogQuery/src/mcpLogQuery/server.py"},"region":{"startLine":104,"startColumn":16,"endLine":104,"endColumn":43,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 94_165]->_get_header \\n[server.py : 207_208]","sourceNodeId":"handle_call_tool \\n[server.py : 94_165]","targetNodeId":"_get_header \\n[server.py : 207_208]"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpLogQuery/src/mcpLogQuery/server.py"},"region":{"startLine":208,"startColumn":12,"endLine":208,"endColumn":26,"snippet":{}}}},"id":"_get_header \\n[server.py : 207_208]->_get_headers \\n[server.py : 191_205]","sourceNodeId":"_get_header \\n[server.py : 207_208]","targetNodeId":"_get_headers \\n[server.py : 191_205]"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpLogQuery/src/mcpLogQuery/server.py"},"region":{"startLine":194,"startColumn":23,"endLine":194,"endColumn":77,"snippet":{}}}},"id":"_get_headers \\n[server.py : 191_205]->mcp.server.Server(SERVER_NAME).request_context.meta.model_extra.get","sourceNodeId":"_get_headers \\n[server.py : 191_205]","targetNodeId":"mcp.server.Server(SERVER_NAME).request_context.meta.model_extra.get"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpLogQuery/src/mcpLogQuery/server.py"},"region":{"startLine":204,"startColumn":5,"endLine":204,"endColumn":49,"snippet":{}}}},"id":"_get_headers \\n[server.py : 191_205]->syslib_from.logging.getLogger(mcp-server).info","sourceNodeId":"_get_headers \\n[server.py : 191_205]","targetNodeId":"syslib_from.logging.getLogger(mcp-server).info"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpLogQuery/src/mcpLogQuery/server.py"},"region":{"startLine":199,"startColumn":25,"endLine":199,"endColumn":42,"snippet":{}}}},"id":"_get_headers \\n[server.py : 191_205]->mcp.server.Server(SERVER_NAME).request_context.meta.model_extra.get(headers).decode","sourceNodeId":"_get_headers \\n[server.py : 191_205]","targetNodeId":"mcp.server.Server(SERVER_NAME).request_context.meta.model_extra.get(headers).decode"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpLogQuery/src/mcpLogQuery/server.py"},"region":{"startLine":198,"startColumn":23,"endLine":198,"endColumn":48,"snippet":{}}}},"id":"_get_headers \\n[server.py : 191_205]->mcp.server.Server(SERVER_NAME).request_context.meta.model_extra.get(headers).decode(utf-8).lower","sourceNodeId":"_get_headers \\n[server.py : 191_205]","targetNodeId":"mcp.server.Server(SERVER_NAME).request_context.meta.model_extra.get(headers).decode(utf-8).lower"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpLogQuery/src/mcpLogQuery/server.py"},"region":{"startLine":202,"startColumn":52,"endLine":202,"endColumn":76,"snippet":{}}}},"id":"_get_headers \\n[server.py : 191_205]->syslib_from.traceback.format_exc","sourceNodeId":"_get_headers \\n[server.py : 191_205]","targetNodeId":"syslib_from.traceback.format_exc"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpLogQuery/src/mcpLogQuery/server.py"},"region":{"startLine":202,"startColumn":9,"endLine":202,"endColumn":78,"snippet":{}}}},"id":"_get_headers \\n[server.py : 191_205]->syslib_from.logging.getLogger(mcp-server).error","sourceNodeId":"_get_headers \\n[server.py : 191_205]","targetNodeId":"syslib_from.logging.getLogger(mcp-server).error"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpLogQuery/src/mcpLogQuery/server.py"},"region":{"startLine":208,"startColumn":12,"endLine":208,"endColumn":35,"snippet":{}}}},"id":"_get_header \\n[server.py : 207_208]->headers.get","sourceNodeId":"_get_header \\n[server.py : 207_208]","targetNodeId":"headers.get"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpLogQuery/src/mcpLogQuery/server.py"},"region":{"startLine":142,"startColumn":17,"endLine":142,"endColumn":88,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 94_165]->_valid_params \\n[server.py : 183_188]","sourceNodeId":"handle_call_tool \\n[server.py : 94_165]","targetNodeId":"_valid_params \\n[server.py : 183_188]"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpLogQuery/src/mcpLogQuery/server.py"},"region":{"startLine":185,"startColumn":15,"endLine":185,"endColumn":45,"snippet":{}}}},"id":"_valid_params \\n[server.py : 183_188]->/src/mcpLogQuery/src/mcpLogQuery/server._valid_params._valid_params_scope...ValueError","sourceNodeId":"_valid_params \\n[server.py : 183_188]","targetNodeId":"/src/mcpLogQuery/src/mcpLogQuery/server._valid_params._valid_params_scope...ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpLogQuery/src/mcpLogQuery/server.py"},"region":{"startLine":187,"startColumn":16,"endLine":187,"endColumn":36,"snippet":{}}}},"id":"_valid_params \\n[server.py : 183_188]->/src/mcpLogQuery/src/mcpLogQuery/server.handle_call_tool.arguments.get","sourceNodeId":"_valid_params \\n[server.py : 183_188]","targetNodeId":"/src/mcpLogQuery/src/mcpLogQuery/server.handle_call_tool.arguments.get"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpLogQuery/src/mcpLogQuery/server.py"},"region":{"startLine":188,"startColumn":19,"endLine":188,"endColumn":58,"snippet":{}}}},"id":"_valid_params \\n[server.py : 183_188]->/src/mcpLogQuery/src/mcpLogQuery/server._valid_params._valid_params_scope.....ValueError","sourceNodeId":"_valid_params \\n[server.py : 183_188]","targetNodeId":"/src/mcpLogQuery/src/mcpLogQuery/server._valid_params._valid_params_scope.....ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpLogQuery/src/mcpLogQuery/server.py"},"region":{"startLine":144,"startColumn":35,"endLine":148,"endColumn":67,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 94_165]->sim_snapshot.get_sim_snapshot","sourceNodeId":"handle_call_tool \\n[server.py : 94_165]","targetNodeId":"sim_snapshot.get_sim_snapshot"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpLogQuery/src/mcpLogQuery/server.py"},"region":{"startLine":162,"startColumn":17,"endLine":165,"endColumn":10,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 94_165]->syslib_from.mcp/types.TextContent","sourceNodeId":"handle_call_tool \\n[server.py : 94_165]","targetNodeId":"syslib_from.mcp/types.TextContent"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpLogQuery/src/mcpLogQuery/server.py"},"region":{"startLine":158,"startColumn":23,"endLine":158,"endColumn":58,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 94_165]->/src/mcpLogQuery/src/mcpLogQuery/server.handle_call_tool.handle_call_tool_scope...ValueError","sourceNodeId":"handle_call_tool \\n[server.py : 94_165]","targetNodeId":"/src/mcpLogQuery/src/mcpLogQuery/server.handle_call_tool.handle_call_tool_scope...ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpLogQuery/src/mcpLogQuery/server.py"},"region":{"startLine":164,"startColumn":50,"endLine":164,"endColumn":74,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 94_165]->syslib_from.traceback.format_exc","sourceNodeId":"handle_call_tool \\n[server.py : 94_165]","targetNodeId":"syslib_from.traceback.format_exc"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpLogQuery/src/mcpLogQuery/server.py"},"region":{"startLine":161,"startColumn":9,"endLine":161,"endColumn":102,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 94_165]->syslib_from.logging.getLogger(mcp-server).error","sourceNodeId":"handle_call_tool \\n[server.py : 94_165]","targetNodeId":"syslib_from.logging.getLogger(mcp-server).error"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpMonitorWithFile/src/mcpMonitorWithFile/server.py"},"region":{"startLine":79,"startColumn":1,"endLine":146,"endColumn":11,"snippet":{}}}},"id":"<__entry_point__>->handle_call_tool \\n[server.py : 79_146]","sourceNodeId":"<__entry_point__>","targetNodeId":"handle_call_tool \\n[server.py : 79_146]"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpMonitorWithFile/src/mcpMonitorWithFile/server.py"},"region":{"startLine":87,"startColumn":76,"endLine":87,"endColumn":119,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 79_146]->syslib_from.json.dumps","sourceNodeId":"handle_call_tool \\n[server.py : 79_146]","targetNodeId":"syslib_from.json.dumps"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpMonitorWithFile/src/mcpMonitorWithFile/server.py"},"region":{"startLine":135,"startColumn":17,"endLine":135,"endColumn":125,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 79_146]->syslib_from.logging.getLogger(mcp-server).info","sourceNodeId":"handle_call_tool \\n[server.py : 79_146]","targetNodeId":"syslib_from.logging.getLogger(mcp-server).info"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpMonitorWithFile/src/mcpMonitorWithFile/server.py"},"region":{"startLine":115,"startColumn":17,"endLine":115,"endColumn":37,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 79_146]->validate_arguments \\n[server.py : 88_110]","sourceNodeId":"handle_call_tool \\n[server.py : 79_146]","targetNodeId":"validate_arguments \\n[server.py : 88_110]"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpMonitorWithFile/src/mcpMonitorWithFile/server.py"},"region":{"startLine":90,"startColumn":19,"endLine":90,"endColumn":69,"snippet":{}}}},"id":"validate_arguments \\n[server.py : 88_110]->/src/mcpMonitorWithFile/src/mcpMonitorWithFile/server.handle_call_tool.handle_call_tool_scope..validate_arguments.validate_arguments_scope......","sourceNodeId":"validate_arguments \\n[server.py : 88_110]","targetNodeId":"/src/mcpMonitorWithFile/src/mcpMonitorWithFile/server.handle_call_tool.handle_call_tool_scope..validate_arguments.validate_arguments_scope......"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpMonitorWithFile/src/mcpMonitorWithFile/server.py"},"region":{"startLine":92,"startColumn":19,"endLine":92,"endColumn":67,"snippet":{}}}},"id":"validate_arguments \\n[server.py : 88_110]->/src/mcpMonitorWithFile/src/mcpMonitorWithFile/server.handle_call_tool.handle_call_tool_scope..validate_arguments.validate_arguments_scope......","sourceNodeId":"validate_arguments \\n[server.py : 88_110]","targetNodeId":"/src/mcpMonitorWithFile/src/mcpMonitorWithFile/server.handle_call_tool.handle_call_tool_scope..validate_arguments.validate_arguments_scope......"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpMonitorWithFile/src/mcpMonitorWithFile/server.py"},"region":{"startLine":104,"startColumn":37,"endLine":104,"endColumn":57,"snippet":{}}}},"id":"validate_arguments \\n[server.py : 88_110]->/src/mcpMonitorWithFile/src/mcpMonitorWithFile/server.handle_call_tool.arguments.get","sourceNodeId":"validate_arguments \\n[server.py : 88_110]","targetNodeId":"/src/mcpMonitorWithFile/src/mcpMonitorWithFile/server.handle_call_tool.arguments.get"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpMonitorWithFile/src/mcpMonitorWithFile/server.py"},"region":{"startLine":104,"startColumn":19,"endLine":104,"endColumn":71,"snippet":{}}}},"id":"validate_arguments \\n[server.py : 88_110]->datetime.datetime.strptime","sourceNodeId":"validate_arguments \\n[server.py : 88_110]","targetNodeId":"datetime.datetime.strptime"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpMonitorWithFile/src/mcpMonitorWithFile/server.py"},"region":{"startLine":102,"startColumn":19,"endLine":102,"endColumn":105,"snippet":{}}}},"id":"validate_arguments \\n[server.py : 88_110]->/src/mcpMonitorWithFile/src/mcpMonitorWithFile/server.handle_call_tool.handle_call_tool_scope..validate_arguments.validate_arguments_scope.....","sourceNodeId":"validate_arguments \\n[server.py : 88_110]","targetNodeId":"/src/mcpMonitorWithFile/src/mcpMonitorWithFile/server.handle_call_tool.handle_call_tool_scope..validate_arguments.validate_arguments_scope....."},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpMonitorWithFile/src/mcpMonitorWithFile/server.py"},"region":{"startLine":106,"startColumn":19,"endLine":106,"endColumn":103,"snippet":{}}}},"id":"validate_arguments \\n[server.py : 88_110]->/src/mcpMonitorWithFile/src/mcpMonitorWithFile/server.handle_call_tool.handle_call_tool_scope..validate_arguments.validate_arguments_scope...validate_arguments.validate_arguments_scope..datetime.timedelta","sourceNodeId":"validate_arguments \\n[server.py : 88_110]","targetNodeId":"datetime.timedelta"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpMonitorWithFile/src/mcpMonitorWithFile/server.py"},"region":{"startLine":110,"startColumn":19,"endLine":110,"endColumn":99,"snippet":{}}}},"id":"validate_arguments \\n[server.py : 88_110]->/src/mcpMonitorWithFile/src/mcpMonitorWithFile/server.handle_call_tool.handle_call_tool_scope..validate_arguments.validate_arguments_scope...validate_arguments.validate_arguments_scope../src/mcpMonitorWithFile/src/mcpMonitorWithFile/server.handle_call_tool.arguments.get","sourceNodeId":"handle_call_tool \\n[server.py : 79_146]","targetNodeId":"/src/mcpMonitorWithFile/src/mcpMonitorWithFile/server.handle_call_tool.arguments.get"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpMonitorWithFile/src/mcpMonitorWithFile/server.py"},"region":{"startLine":120,"startColumn":27,"endLine":120,"endColumn":75,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 79_146]->/src/mcpMonitorWithFile/src/mcpMonitorWithFile/server.handle_call_tool.handle_call_tool_scope....ValueError","sourceNodeId":"handle_call_tool \\n[server.py : 79_146]","targetNodeId":"/src/mcpMonitorWithFile/src/mcpMonitorWithFile/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpMonitorWithFile/src/mcpMonitorWithFile/server.py"},"region":{"startLine":122,"startColumn":27,"endLine":122,"endColumn":65,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 79_146]->/src/mcpMonitorWithFile/src/mcpMonitorWithFile/server.handle_call_tool.handle_call_tool_scope....ValueError","sourceNodeId":"handle_call_tool \\n[server.py : 79_146]","targetNodeId":"/src/mcpMonitorWithFile/src/mcpMonitorWithFile/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpMonitorWithFile/src/mcpMonitorWithFile/server.py"},"region":{"startLine":123,"startColumn":24,"endLine":123,"endColumn":49,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 79_146]->/src/mcpMonitorWithFile/src/mcpMonitorWithFile/server.handle_call_tool.handle_call_tool_scope...isinstance","sourceNodeId":"handle_call_tool \\n[server.py : 79_146]","targetNodeId":"/src/mcpMonitorWithFile/src/mcpMonitorWithFile/server.handle_call_tool.handle_call_tool_scope...isinstance"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpMonitorWithFile/src/mcpMonitorWithFile/server.py"},"region":{"startLine":124,"startColumn":89,"endLine":124,"endColumn":102,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 79_146]->/src/mcpMonitorWithFile/src/mcpMonitorWithFile/server.handle_call_tool.handle_call_tool_scope....type","sourceNodeId":"handle_call_tool \\n[server.py : 79_146]","targetNodeId":"/src/mcpMonitorWithFile/src/mcpMonitorWithFile/server.handle_call_tool.handle_call_tool_scope....type"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpMonitorWithFile/src/mcpMonitorWithFile/server.py"},"region":{"startLine":124,"startColumn":27,"endLine":124,"endColumn":122,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 79_146]->/src/mcpMonitorWithFile/src/mcpMonitorWithFile/server.handle_call_tool.handle_call_tool_scope....ValueError","sourceNodeId":"handle_call_tool \\n[server.py : 79_146]","targetNodeId":"/src/mcpMonitorWithFile/src/mcpMonitorWithFile/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpMonitorWithFile/src/mcpMonitorWithFile/server.py"},"region":{"startLine":128,"startColumn":26,"endLine":132,"endColumn":67,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 79_146]->maas_sql_client.get_monitor_metric","sourceNodeId":"handle_call_tool \\n[server.py : 79_146]","targetNodeId":"maas_sql_client.get_monitor_metric"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpMonitorWithFile/src/mcpMonitorWithFile/server.py"},"region":{"startLine":136,"startColumn":25,"endLine":136,"endColumn":67,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 79_146]->_save_metric_to_oss_csv \\n[server.py : 166_186]","sourceNodeId":"handle_call_tool \\n[server.py : 79_146]","targetNodeId":"_save_metric_to_oss_csv \\n[server.py : 166_186]"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpMonitorWithFile/src/mcpMonitorWithFile/server.py"},"region":{"startLine":173,"startColumn":20,"endLine":173,"endColumn":35,"snippet":{}}}},"id":"_save_metric_to_oss_csv \\n[server.py : 166_186]->_get_trace_id \\n[server.py : 189_197]","sourceNodeId":"_save_metric_to_oss_csv \\n[server.py : 166_186]","targetNodeId":"_get_trace_id \\n[server.py : 189_197]"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpMonitorWithFile/src/mcpMonitorWithFile/server.py"},"region":{"startLine":190,"startColumn":19,"endLine":190,"endColumn":73,"snippet":{}}}},"id":"_get_trace_id \\n[server.py : 189_197]->mcp.server.Server(mcp-monitor-with-file).request_context.meta.model_extra.get","sourceNodeId":"_get_trace_id \\n[server.py : 189_197]","targetNodeId":"mcp.server.Server(mcp-monitor-with-file).request_context.meta.model_extra.get"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpMonitorWithFile/src/mcpMonitorWithFile/server.py"},"region":{"startLine":191,"startColumn":5,"endLine":191,"endColumn":51,"snippet":{}}}},"id":"_get_trace_id \\n[server.py : 189_197]->syslib_from.logging.getLogger(mcp-server).info","sourceNodeId":"_get_trace_id \\n[server.py : 189_197]","targetNodeId":"syslib_from.logging.getLogger(mcp-server).info"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpMonitorWithFile/src/mcpMonitorWithFile/server.py"},"region":{"startLine":196,"startColumn":24,"endLine":196,"endColumn":41,"snippet":{}}}},"id":"_get_trace_id \\n[server.py : 189_197]->mcp.server.Server(mcp-monitor-with-file).request_context.meta.model_extra.get(headers).decode","sourceNodeId":"_get_trace_id \\n[server.py : 189_197]","targetNodeId":"mcp.server.Server(mcp-monitor-with-file).request_context.meta.model_extra.get(headers).decode"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpMonitorWithFile/src/mcpMonitorWithFile/server.py"},"region":{"startLine":194,"startColumn":19,"endLine":194,"endColumn":44,"snippet":{}}}},"id":"_get_trace_id \\n[server.py : 189_197]->mcp.server.Server(mcp-monitor-with-file).request_context.meta.model_extra.get(headers).decode(utf-8).lower","sourceNodeId":"_get_trace_id \\n[server.py : 189_197]","targetNodeId":"mcp.server.Server(mcp-monitor-with-file).request_context.meta.model_extra.get(headers).decode(utf-8).lower"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpMonitorWithFile/src/mcpMonitorWithFile/server.py"},"region":{"startLine":197,"startColumn":16,"endLine":197,"endColumn":28,"snippet":{}}}},"id":"_get_trace_id \\n[server.py : 189_197]->syslib_from.uuid.uuid4","sourceNodeId":"_get_trace_id \\n[server.py : 189_197]","targetNodeId":"syslib_from.uuid.uuid4"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpMonitorWithFile/src/mcpMonitorWithFile/server.py"},"region":{"startLine":197,"startColumn":12,"endLine":197,"endColumn":29,"snippet":{}}}},"id":"_get_trace_id \\n[server.py : 189_197]->/src/mcpMonitorWithFile/src/mcpMonitorWithFile/server._get_trace_id._get_trace_id_scope..str","sourceNodeId":"_get_trace_id \\n[server.py : 189_197]","targetNodeId":"/src/mcpMonitorWithFile/src/mcpMonitorWithFile/server._get_trace_id._get_trace_id_scope..str"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpMonitorWithFile/src/mcpMonitorWithFile/server.py"},"region":{"startLine":174,"startColumn":35,"endLine":174,"endColumn":47,"snippet":{}}}},"id":"_save_metric_to_oss_csv \\n[server.py : 166_186]->syslib_from.uuid.uuid4","sourceNodeId":"_save_metric_to_oss_csv \\n[server.py : 166_186]","targetNodeId":"syslib_from.uuid.uuid4"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpMonitorWithFile/src/mcpMonitorWithFile/server.py"},"region":{"startLine":186,"startColumn":26,"endLine":186,"endColumn":32,"snippet":{}}}},"id":"_save_metric_to_oss_csv \\n[server.py : 166_186]->/src/mcpMonitorWithFile/src/mcpMonitorWithFile/server._save_metric_to_oss_csv._save_metric_to_oss_csv_scope..str","sourceNodeId":"_save_metric_to_oss_csv \\n[server.py : 166_186]","targetNodeId":"/src/mcpMonitorWithFile/src/mcpMonitorWithFile/server._save_metric_to_oss_csv._save_metric_to_oss_csv_scope..str"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpMonitorWithFile/src/mcpMonitorWithFile/server.py"},"region":{"startLine":175,"startColumn":20,"endLine":175,"endColumn":66,"snippet":{}}}},"id":"_save_metric_to_oss_csv \\n[server.py : 166_186]->mcp_common.utils.oss_utils.create_oss_path","sourceNodeId":"_save_metric_to_oss_csv \\n[server.py : 166_186]","targetNodeId":"mcp_common.utils.oss_utils.create_oss_path"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpMonitorWithFile/src/mcpMonitorWithFile/server.py"},"region":{"startLine":176,"startColumn":18,"endLine":176,"endColumn":31,"snippet":{}}}},"id":"_save_metric_to_oss_csv \\n[server.py : 166_186]->syslib_from.io.StringIO","sourceNodeId":"_save_metric_to_oss_csv \\n[server.py : 166_186]","targetNodeId":"syslib_from.io.StringIO"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpMonitorWithFile/src/mcpMonitorWithFile/server.py"},"region":{"startLine":177,"startColumn":18,"endLine":177,"endColumn":36,"snippet":{}}}},"id":"_save_metric_to_oss_csv \\n[server.py : 166_186]->syslib_from.csv.writer","sourceNodeId":"_save_metric_to_oss_csv \\n[server.py : 166_186]","targetNodeId":"syslib_from.csv.writer"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpMonitorWithFile/src/mcpMonitorWithFile/server.py"},"region":{"startLine":179,"startColumn":20,"endLine":179,"endColumn":43,"snippet":{}}}},"id":"_save_metric_to_oss_csv \\n[server.py : 166_186]->maas_sql_client.get_monitor_metric(var cluster:any=cluster, var tenant:any=tenant, var columns:any=metrics, var start_time:any=start_time, var end_time:any=end_time).get","sourceNodeId":"_save_metric_to_oss_csv \\n[server.py : 166_186]","targetNodeId":"maas_sql_client.get_monitor_metric(var cluster:any=cluster, var tenant:any=tenant, var columns:any=metrics, var start_time:any=start_time, var end_time:any=end_time).get"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpMonitorWithFile/src/mcpMonitorWithFile/server.py"},"region":{"startLine":180,"startColumn":13,"endLine":180,"endColumn":33,"snippet":{}}}},"id":"_save_metric_to_oss_csv \\n[server.py : 166_186]->syslib_from.csv.writer(output).writerow","sourceNodeId":"_save_metric_to_oss_csv \\n[server.py : 166_186]","targetNodeId":"syslib_from.csv.writer(output).writerow"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpMonitorWithFile/src/mcpMonitorWithFile/server.py"},"region":{"startLine":181,"startColumn":21,"endLine":181,"endColumn":38,"snippet":{}}}},"id":"_save_metric_to_oss_csv \\n[server.py : 166_186]->syslib_from.io.StringIO().getvalue","sourceNodeId":"_save_metric_to_oss_csv \\n[server.py : 166_186]","targetNodeId":"syslib_from.io.StringIO().getvalue"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpMonitorWithFile/src/mcpMonitorWithFile/server.py"},"region":{"startLine":181,"startColumn":21,"endLine":181,"endColumn":54,"snippet":{}}}},"id":"_save_metric_to_oss_csv \\n[server.py : 166_186]->syslib_from.io.StringIO().getvalue().encode","sourceNodeId":"_save_metric_to_oss_csv \\n[server.py : 166_186]","targetNodeId":"syslib_from.io.StringIO().getvalue().encode"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpMonitorWithFile/src/mcpMonitorWithFile/server.py"},"region":{"startLine":182,"startColumn":21,"endLine":182,"endColumn":75,"snippet":{}}}},"id":"_save_metric_to_oss_csv \\n[server.py : 166_186]->mcp_common.utils.oss_utils.upload_bytes","sourceNodeId":"_save_metric_to_oss_csv \\n[server.py : 166_186]","targetNodeId":"mcp_common.utils.oss_utils.upload_bytes"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpMonitorWithFile/src/mcpMonitorWithFile/server.py"},"region":{"startLine":183,"startColumn":86,"endLine":183,"endColumn":105,"snippet":{}}}},"id":"_save_metric_to_oss_csv \\n[server.py : 166_186]->mcp_common.utils.oss_utils.upload_bytes(oss_path, csv_bytes, file_desc).to_dict","sourceNodeId":"_save_metric_to_oss_csv \\n[server.py : 166_186]","targetNodeId":"mcp_common.utils.oss_utils.upload_bytes(oss_path, csv_bytes, file_desc).to_dict"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpMonitorWithFile/src/mcpMonitorWithFile/server.py"},"region":{"startLine":183,"startColumn":75,"endLine":183,"endColumn":126,"snippet":{}}}},"id":"_save_metric_to_oss_csv \\n[server.py : 166_186]->syslib_from.json.dumps","sourceNodeId":"_save_metric_to_oss_csv \\n[server.py : 166_186]","targetNodeId":"syslib_from.json.dumps"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpMonitorWithFile/src/mcpMonitorWithFile/server.py"},"region":{"startLine":183,"startColumn":16,"endLine":183,"endColumn":127,"snippet":{}}}},"id":"_save_metric_to_oss_csv \\n[server.py : 166_186]->syslib_from.mcp/types.ImageContent","sourceNodeId":"_save_metric_to_oss_csv \\n[server.py : 166_186]","targetNodeId":"syslib_from.mcp/types.ImageContent"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpMonitorWithFile/src/mcpMonitorWithFile/server.py"},"region":{"startLine":185,"startColumn":9,"endLine":185,"endColumn":59,"snippet":{}}}},"id":"_save_metric_to_oss_csv \\n[server.py : 166_186]->syslib_from.logging.getLogger(mcp-server).error","sourceNodeId":"_save_metric_to_oss_csv \\n[server.py : 166_186]","targetNodeId":"syslib_from.logging.getLogger(mcp-server).error"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpMonitorWithFile/src/mcpMonitorWithFile/server.py"},"region":{"startLine":186,"startColumn":15,"endLine":186,"endColumn":33,"snippet":{}}}},"id":"_save_metric_to_oss_csv \\n[server.py : 166_186]->/src/mcpMonitorWithFile/src/mcpMonitorWithFile/server._save_metric_to_oss_csv._save_metric_to_oss_csv_scope...ValueError","sourceNodeId":"_save_metric_to_oss_csv \\n[server.py : 166_186]","targetNodeId":"/src/mcpMonitorWithFile/src/mcpMonitorWithFile/server._save_metric_to_oss_csv._save_metric_to_oss_csv_scope...ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpMonitorWithFile/src/mcpMonitorWithFile/server.py"},"region":{"startLine":138,"startColumn":61,"endLine":138,"endColumn":105,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 79_146]->str","sourceNodeId":"handle_call_tool \\n[server.py : 79_146]","targetNodeId":"str"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpMonitorWithFile/src/mcpMonitorWithFile/server.py"},"region":{"startLine":143,"startColumn":17,"endLine":146,"endColumn":10,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 79_146]->syslib_from.mcp/types.TextContent","sourceNodeId":"handle_call_tool \\n[server.py : 79_146]","targetNodeId":"syslib_from.mcp/types.TextContent"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpMonitorWithFile/src/mcpMonitorWithFile/server.py"},"region":{"startLine":140,"startColumn":23,"endLine":140,"endColumn":58,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 79_146]->/src/mcpMonitorWithFile/src/mcpMonitorWithFile/server.handle_call_tool.handle_call_tool_scope...ValueError","sourceNodeId":"handle_call_tool \\n[server.py : 79_146]","targetNodeId":"/src/mcpMonitorWithFile/src/mcpMonitorWithFile/server.handle_call_tool.handle_call_tool_scope...ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpMonitorWithFile/src/mcpMonitorWithFile/server.py"},"region":{"startLine":142,"startColumn":9,"endLine":142,"endColumn":93,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 79_146]->syslib_from.logging.getLogger(mcp-server).exception","sourceNodeId":"handle_call_tool \\n[server.py : 79_146]","targetNodeId":"syslib_from.logging.getLogger(mcp-server).exception"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpyuque/src/mcpyuque/server.py"},"region":{"startLine":65,"startColumn":1,"endLine":95,"endColumn":54,"snippet":{}}}},"id":"<__entry_point__>->handle_call_tool \\n[server.py : 65_95]","sourceNodeId":"<__entry_point__>","targetNodeId":"handle_call_tool \\n[server.py : 65_95]"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpMonitorWithSql/src/mcpMonitorWithSql/server.py"},"region":{"startLine":73,"startColumn":68,"endLine":73,"endColumn":111,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 65_95]->syslib_from.json.dumps","sourceNodeId":"handle_call_tool \\n[server.py : 65_95]","targetNodeId":"syslib_from.json.dumps"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpMonitorWithSql/src/mcpMonitorWithSql/server.py"},"region":{"startLine":82,"startColumn":17,"endLine":82,"endColumn":98,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 65_95]->syslib_from.logging.getLogger(mcp-server).info","sourceNodeId":"handle_call_tool \\n[server.py : 65_95]","targetNodeId":"syslib_from.logging.getLogger(mcp-server).info"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpMonitorWithSql/src/mcpMonitorWithSql/server.py"},"region":{"startLine":79,"startColumn":27,"endLine":79,"endColumn":61,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 65_95]->/src/mcpMonitorWithSql/src/mcpMonitorWithSql/server.handle_call_tool.handle_call_tool_scope....ValueError","sourceNodeId":"handle_call_tool \\n[server.py : 65_95]","targetNodeId":"/src/mcpMonitorWithSql/src/mcpMonitorWithSql/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpMonitorWithSql/src/mcpMonitorWithSql/server.py"},"region":{"startLine":81,"startColumn":31,"endLine":81,"endColumn":65,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 65_95]->get_metric \\n[server.py : 125_135]","sourceNodeId":"handle_call_tool \\n[server.py : 65_95]","targetNodeId":"get_metric \\n[server.py : 125_135]"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpyuque/src/mcpyuque/server.py"},"region":{"startLine":93,"startColumn":21,"endLine":93,"endColumn":74,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 65_95]->syslib_from.mcp/types.TextContent","sourceNodeId":"handle_call_tool \\n[server.py : 65_95]","targetNodeId":"syslib_from.mcp/types.TextContent"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpMonitorWithSql/src/mcpMonitorWithSql/server.py"},"region":{"startLine":89,"startColumn":23,"endLine":89,"endColumn":58,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 65_95]->/src/mcpMonitorWithSql/src/mcpMonitorWithSql/server.handle_call_tool.handle_call_tool_scope...ValueError","sourceNodeId":"handle_call_tool \\n[server.py : 65_95]","targetNodeId":"/src/mcpMonitorWithSql/src/mcpMonitorWithSql/server.handle_call_tool.handle_call_tool_scope...ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpMonitorWithSql/src/mcpMonitorWithSql/server.py"},"region":{"startLine":94,"startColumn":50,"endLine":94,"endColumn":74,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 65_95]->syslib_from.traceback.format_exc","sourceNodeId":"handle_call_tool \\n[server.py : 65_95]","targetNodeId":"syslib_from.traceback.format_exc"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpMonitorWithSql/src/mcpMonitorWithSql/server.py"},"region":{"startLine":91,"startColumn":9,"endLine":91,"endColumn":102,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 65_95]->syslib_from.logging.getLogger(mcp-server).error","sourceNodeId":"handle_call_tool \\n[server.py : 65_95]","targetNodeId":"syslib_from.logging.getLogger(mcp-server).error"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpOpenSearch/src/mcpOpenSearch/server.py"},"region":{"startLine":253,"startColumn":1,"endLine":279,"endColumn":67,"snippet":{}}}},"id":"<__entry_point__>->handle_call_tool \\n[server.py : 253_279]","sourceNodeId":"<__entry_point__>","targetNodeId":"handle_call_tool \\n[server.py : 253_279]"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpOpenSearch/src/mcpOpenSearch/server.py"},"region":{"startLine":260,"startColumn":15,"endLine":260,"endColumn":52,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 253_279]->/src/mcpOpenSearch/src/mcpOpenSearch/server.handle_call_tool.handle_call_tool_scope...ValueError","sourceNodeId":"handle_call_tool \\n[server.py : 253_279]","targetNodeId":"/src/mcpOpenSearch/src/mcpOpenSearch/server.handle_call_tool.handle_call_tool_scope...ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpOpenSearch/src/mcpOpenSearch/server.py"},"region":{"startLine":264,"startColumn":27,"endLine":264,"endColumn":77,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 253_279]->direct_search_tool \\n[server.py : 133_165]","sourceNodeId":"handle_call_tool \\n[server.py : 253_279]","targetNodeId":"direct_search_tool \\n[server.py : 133_165]"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpOpenSearch/src/mcpOpenSearch/server.py"},"region":{"startLine":164,"startColumn":5,"endLine":164,"endColumn":145,"snippet":{}}}},"id":"direct_search_tool \\n[server.py : 133_165]->aiologger.Logger(var name:any=__name__).info","sourceNodeId":"direct_search_tool \\n[server.py : 133_165]","targetNodeId":"aiologger.Logger(var name:any=__name__).info"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpOpenSearch/src/mcpOpenSearch/server.py"},"region":{"startLine":164,"startColumn":109,"endLine":164,"endColumn":120,"snippet":{}}}},"id":"direct_search_tool \\n[server.py : 133_165]->syslib_from.time.time","sourceNodeId":"direct_search_tool \\n[server.py : 133_165]","targetNodeId":"syslib_from.time.time"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpOpenSearch/src/mcpOpenSearch/server.py"},"region":{"startLine":142,"startColumn":25,"endLine":142,"endColumn":56,"snippet":{}}}},"id":"direct_search_tool \\n[server.py : 133_165]->syslib_from.search_engine.SearchEngineApp","sourceNodeId":"direct_search_tool \\n[server.py : 133_165]","targetNodeId":"syslib_from.search_engine.SearchEngineApp"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpOpenSearch/src/mcpOpenSearch/server.py"},"region":{"startLine":146,"startColumn":25,"endLine":151,"endColumn":10,"snippet":{}}}},"id":"direct_search_tool \\n[server.py : 133_165]->syslib_from.asyncio.to_thread","sourceNodeId":"direct_search_tool \\n[server.py : 133_165]","targetNodeId":"syslib_from.asyncio.to_thread"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpOpenSearch/src/mcpOpenSearch/server.py"},"region":{"startLine":153,"startColumn":16,"endLine":153,"endColumn":40,"snippet":{}}}},"id":"direct_search_tool \\n[server.py : 133_165]->syslib_from.asyncio.get_event_loop","sourceNodeId":"direct_search_tool \\n[server.py : 133_165]","targetNodeId":"syslib_from.asyncio.get_event_loop"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpOpenSearch/src/mcpOpenSearch/server.py"},"region":{"startLine":154,"startColumn":25,"endLine":159,"endColumn":53,"snippet":{}}}},"id":"direct_search_tool \\n[server.py : 133_165]->syslib_from.asyncio.get_event_loop().run_in_executor","sourceNodeId":"direct_search_tool \\n[server.py : 133_165]","targetNodeId":"syslib_from.asyncio.get_event_loop().run_in_executor"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpOpenSearch/src/mcpOpenSearch/server.py"},"region":{"startLine":163,"startColumn":14,"endLine":163,"endColumn":107,"snippet":{}}}},"id":"direct_search_tool \\n[server.py : 133_165]->join","sourceNodeId":"direct_search_tool \\n[server.py : 133_165]","targetNodeId":"join"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpOpenSearch/src/mcpOpenSearch/server.py"},"region":{"startLine":279,"startColumn":17,"endLine":279,"endColumn":66,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 253_279]->mcp.types.TextContent","sourceNodeId":"handle_call_tool \\n[server.py : 253_279]","targetNodeId":"mcp.types.TextContent"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpOpenSearch/src/mcpOpenSearch/server.py"},"region":{"startLine":268,"startColumn":27,"endLine":268,"endColumn":75,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 253_279]->deep_search_tool \\n[server.py : 168_184]","sourceNodeId":"handle_call_tool \\n[server.py : 253_279]","targetNodeId":"deep_search_tool \\n[server.py : 168_184]"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpOpenSearch/src/mcpOpenSearch/server.py"},"region":{"startLine":182,"startColumn":5,"endLine":182,"endColumn":150,"snippet":{}}}},"id":"deep_search_tool \\n[server.py : 168_184]->aiologger.Logger(var name:any=__name__).info","sourceNodeId":"deep_search_tool \\n[server.py : 168_184]","targetNodeId":"aiologger.Logger(var name:any=__name__).info"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpOpenSearch/src/mcpOpenSearch/server.py"},"region":{"startLine":182,"startColumn":114,"endLine":182,"endColumn":125,"snippet":{}}}},"id":"deep_search_tool \\n[server.py : 168_184]->syslib_from.time.time","sourceNodeId":"deep_search_tool \\n[server.py : 168_184]","targetNodeId":"syslib_from.time.time"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpOpenSearch/src/mcpOpenSearch/server.py"},"region":{"startLine":178,"startColumn":21,"endLine":178,"endColumn":101,"snippet":{}}}},"id":"deep_search_tool \\n[server.py : 168_184]->invoke_search_tool \\n[server.py : 45_124]","sourceNodeId":"deep_search_tool \\n[server.py : 168_184]","targetNodeId":"invoke_search_tool \\n[server.py : 45_124]"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpOpenSearch/src/mcpOpenSearch/server.py"},"region":{"startLine":69,"startColumn":12,"endLine":69,"endColumn":56,"snippet":{}}}},"id":"invoke_search_tool \\n[server.py : 45_124]->syslib_from.sys.platform.startswith","sourceNodeId":"invoke_search_tool \\n[server.py : 45_124]","targetNodeId":"syslib_from.sys.platform.startswith"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpOpenSearch/src/mcpOpenSearch/server.py"},"region":{"startLine":65,"startColumn":19,"endLine":65,"endColumn":55,"snippet":{}}}},"id":"invoke_search_tool \\n[server.py : 45_124]->/src/mcpOpenSearch/src/mcpOpenSearch/server.invoke_search_tool.invoke_search_tool_scope.....RuntimeError","sourceNodeId":"invoke_search_tool \\n[server.py : 45_124]","targetNodeId":"/src/mcpOpenSearch/src/mcpOpenSearch/server.invoke_search_tool.invoke_search_tool_scope.....RuntimeError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpOpenSearch/src/mcpOpenSearch/server.py"},"region":{"startLine":78,"startColumn":21,"endLine":80,"endColumn":10,"snippet":{}}}},"id":"invoke_search_tool \\n[server.py : 45_124]->syslib_from.httpx.AsyncHTTPTransport","sourceNodeId":"invoke_search_tool \\n[server.py : 45_124]","targetNodeId":"syslib_from.httpx.AsyncHTTPTransport"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpOpenSearch/src/mcpOpenSearch/server.py"},"region":{"startLine":83,"startColumn":44,"endLine":83,"endColumn":82,"snippet":{}}}},"id":"invoke_search_tool \\n[server.py : 45_124]->syslib_from.httpx.AsyncClient","sourceNodeId":"invoke_search_tool \\n[server.py : 45_124]","targetNodeId":"syslib_from.httpx.AsyncClient"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpOpenSearch/src/mcpOpenSearch/server.py"},"region":{"startLine":82,"startColumn":18,"endLine":83,"endColumn":83,"snippet":{}}}},"id":"invoke_search_tool \\n[server.py : 45_124]->syslib_from.openai.AsyncOpenAI","sourceNodeId":"invoke_search_tool \\n[server.py : 45_124]","targetNodeId":"syslib_from.openai.AsyncOpenAI"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpOpenSearch/src/mcpOpenSearch/server.py"},"region":{"startLine":86,"startColumn":21,"endLine":86,"endColumn":52,"snippet":{}}}},"id":"invoke_search_tool \\n[server.py : 45_124]->syslib_from.search_engine.SearchEngineApp","sourceNodeId":"invoke_search_tool \\n[server.py : 45_124]","targetNodeId":"syslib_from.search_engine.SearchEngineApp"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpOpenSearch/src/mcpOpenSearch/server.py"},"region":{"startLine":110,"startColumn":9,"endLine":110,"endColumn":94,"snippet":{}}}},"id":"invoke_search_tool \\n[server.py : 45_124]->aiologger.Logger(var name:any=__name__).info","sourceNodeId":"invoke_search_tool \\n[server.py : 45_124]","targetNodeId":"aiologger.Logger(var name:any=__name__).info"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpOpenSearch/src/mcpOpenSearch/server.py"},"region":{"startLine":98,"startColumn":56,"endLine":105,"endColumn":10,"snippet":{}}}},"id":"invoke_search_tool \\n[server.py : 45_124]->syslib_from.deep_research.research","sourceNodeId":"invoke_search_tool \\n[server.py : 45_124]","targetNodeId":"syslib_from.deep_research.research"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpOpenSearch/src/mcpOpenSearch/server.py"},"region":{"startLine":110,"startColumn":70,"endLine":110,"endColumn":93,"snippet":{}}}},"id":"invoke_search_tool \\n[server.py : 45_124]->join","sourceNodeId":"invoke_search_tool \\n[server.py : 45_124]","targetNodeId":"join"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpOpenSearch/src/mcpOpenSearch/server.py"},"region":{"startLine":110,"startColumn":41,"endLine":110,"endColumn":60,"snippet":{}}}},"id":"invoke_search_tool \\n[server.py : 45_124]->/src/mcpOpenSearch/src/mcpOpenSearch/server.invoke_search_tool.invoke_search_tool_scope..len","sourceNodeId":"invoke_search_tool \\n[server.py : 45_124]","targetNodeId":"/src/mcpOpenSearch/src/mcpOpenSearch/server.invoke_search_tool.invoke_search_tool_scope..len"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpOpenSearch/src/mcpOpenSearch/server.py"},"region":{"startLine":113,"startColumn":18,"endLine":117,"endColumn":39,"snippet":{}}}},"id":"invoke_search_tool \\n[server.py : 45_124]->syslib_from.deep_research.write_final_report","sourceNodeId":"invoke_search_tool \\n[server.py : 45_124]","targetNodeId":"syslib_from.deep_research.write_final_report"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpOpenSearch/src/mcpOpenSearch/server.py"},"region":{"startLine":119,"startColumn":9,"endLine":119,"endColumn":55,"snippet":{}}}},"id":"invoke_search_tool \\n[server.py : 45_124]->aiologger.Logger(var name:any=__name__).debug","sourceNodeId":"invoke_search_tool \\n[server.py : 45_124]","targetNodeId":"aiologger.Logger(var name:any=__name__).debug"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpOpenSearch/src/mcpOpenSearch/server.py"},"region":{"startLine":123,"startColumn":9,"endLine":123,"endColumn":45,"snippet":{}}}},"id":"invoke_search_tool \\n[server.py : 45_124]->aiologger.Logger(var name:any=__name__).error","sourceNodeId":"invoke_search_tool \\n[server.py : 45_124]","targetNodeId":"aiologger.Logger(var name:any=__name__).error"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpOpenSearch/src/mcpOpenSearch/server.py"},"region":{"startLine":272,"startColumn":27,"endLine":272,"endColumn":77,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 253_279]->deep_research_tool \\n[server.py : 187_204]","sourceNodeId":"handle_call_tool \\n[server.py : 253_279]","targetNodeId":"deep_research_tool \\n[server.py : 187_204]"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpOpenSearch/src/mcpOpenSearch/server.py"},"region":{"startLine":202,"startColumn":5,"endLine":202,"endColumn":152,"snippet":{}}}},"id":"deep_research_tool \\n[server.py : 187_204]->aiologger.Logger(var name:any=__name__).info","sourceNodeId":"deep_research_tool \\n[server.py : 187_204]","targetNodeId":"aiologger.Logger(var name:any=__name__).info"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpOpenSearch/src/mcpOpenSearch/server.py"},"region":{"startLine":202,"startColumn":116,"endLine":202,"endColumn":127,"snippet":{}}}},"id":"deep_research_tool \\n[server.py : 187_204]->syslib_from.time.time","sourceNodeId":"deep_research_tool \\n[server.py : 187_204]","targetNodeId":"syslib_from.time.time"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpOpenSearch/src/mcpOpenSearch/server.py"},"region":{"startLine":198,"startColumn":21,"endLine":198,"endColumn":103,"snippet":{}}}},"id":"deep_research_tool \\n[server.py : 187_204]->invoke_search_tool \\n[server.py : 45_124]","sourceNodeId":"deep_research_tool \\n[server.py : 187_204]","targetNodeId":"invoke_search_tool \\n[server.py : 45_124]"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpOpenSearch/src/mcpOpenSearch/server.py"},"region":{"startLine":276,"startColumn":19,"endLine":276,"endColumn":54,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 253_279]->/src/mcpOpenSearch/src/mcpOpenSearch/server.handle_call_tool.handle_call_tool_scope.....ValueError","sourceNodeId":"handle_call_tool \\n[server.py : 253_279]","targetNodeId":"/src/mcpOpenSearch/src/mcpOpenSearch/server.handle_call_tool.handle_call_tool_scope.....ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpOpenSearch/src/mcpOpenSearch/server.py"},"region":{"startLine":279,"startColumn":56,"endLine":279,"endColumn":64,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 253_279]->str","sourceNodeId":"handle_call_tool \\n[server.py : 253_279]","targetNodeId":"str"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpPaas/src/mcpPaas/server.py"},"region":{"startLine":126,"startColumn":1,"endLine":163,"endColumn":54,"snippet":{}}}},"id":"<__entry_point__>->handle_call_tool \\n[server.py : 126_163]","sourceNodeId":"<__entry_point__>","targetNodeId":"handle_call_tool \\n[server.py : 126_163]"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpPaas/src/mcpPaas/server.py"},"region":{"startLine":133,"startColumn":76,"endLine":133,"endColumn":119,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 126_163]->syslib_from.json.dumps","sourceNodeId":"handle_call_tool \\n[server.py : 126_163]","targetNodeId":"syslib_from.json.dumps"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpPaas/src/mcpPaas/server.py"},"region":{"startLine":133,"startColumn":5,"endLine":133,"endColumn":121,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 126_163]->paas_client.info_logger.info","sourceNodeId":"handle_call_tool \\n[server.py : 126_163]","targetNodeId":"paas_client.info_logger.info"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpPaas/src/mcpPaas/server.py"},"region":{"startLine":137,"startColumn":23,"endLine":137,"endColumn":62,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 126_163]->/src/mcpPaas/src/mcpPaas/server.handle_call_tool.handle_call_tool_scope....ValueError","sourceNodeId":"handle_call_tool \\n[server.py : 126_163]","targetNodeId":"/src/mcpPaas/src/mcpPaas/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpPaas/src/mcpPaas/server.py"},"region":{"startLine":138,"startColumn":27,"endLine":138,"endColumn":77,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 126_163]->paas_client.get_app_meta","sourceNodeId":"handle_call_tool \\n[server.py : 126_163]","targetNodeId":"paas_client.get_app_meta"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpPaas/src/mcpPaas/server.py"},"region":{"startLine":161,"startColumn":21,"endLine":161,"endColumn":74,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 126_163]->syslib_from.mcp/types.TextContent","sourceNodeId":"handle_call_tool \\n[server.py : 126_163]","targetNodeId":"syslib_from.mcp/types.TextContent"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpPaas/src/mcpPaas/server.py"},"region":{"startLine":142,"startColumn":23,"endLine":142,"endColumn":62,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 126_163]->/src/mcpPaas/src/mcpPaas/server.handle_call_tool.handle_call_tool_scope....ValueError","sourceNodeId":"handle_call_tool \\n[server.py : 126_163]","targetNodeId":"/src/mcpPaas/src/mcpPaas/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpPaas/src/mcpPaas/server.py"},"region":{"startLine":143,"startColumn":27,"endLine":143,"endColumn":76,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 126_163]->paas_client.get_app_pod","sourceNodeId":"handle_call_tool \\n[server.py : 126_163]","targetNodeId":"paas_client.get_app_pod"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpPaas/src/mcpPaas/server.py"},"region":{"startLine":147,"startColumn":23,"endLine":147,"endColumn":62,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 126_163]->/src/mcpPaas/src/mcpPaas/server.handle_call_tool.handle_call_tool_scope....ValueError","sourceNodeId":"handle_call_tool \\n[server.py : 126_163]","targetNodeId":"/src/mcpPaas/src/mcpPaas/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpPaas/src/mcpPaas/server.py"},"region":{"startLine":148,"startColumn":27,"endLine":148,"endColumn":82,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 126_163]->paas_client.get_app_pod_count","sourceNodeId":"handle_call_tool \\n[server.py : 126_163]","targetNodeId":"paas_client.get_app_pod_count"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpPaas/src/mcpPaas/server.py"},"region":{"startLine":152,"startColumn":23,"endLine":152,"endColumn":62,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 126_163]->/src/mcpPaas/src/mcpPaas/server.handle_call_tool.handle_call_tool_scope....ValueError","sourceNodeId":"handle_call_tool \\n[server.py : 126_163]","targetNodeId":"/src/mcpPaas/src/mcpPaas/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpPaas/src/mcpPaas/server.py"},"region":{"startLine":154,"startColumn":57,"endLine":154,"endColumn":93,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 126_163]->/src/mcpPaas/src/mcpPaas/server.handle_call_tool.arguments.get","sourceNodeId":"handle_call_tool \\n[server.py : 126_163]","targetNodeId":"/src/mcpPaas/src/mcpPaas/server.handle_call_tool.arguments.get"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpPaas/src/mcpPaas/server.py"},"region":{"startLine":153,"startColumn":27,"endLine":155,"endColumn":83,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 126_163]->get_app_baseline \\n[server.py : 26_51]","sourceNodeId":"handle_call_tool \\n[server.py : 126_163]","targetNodeId":"get_app_baseline \\n[server.py : 26_51]"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpPaas/src/mcpPaas/server.py"},"region":{"startLine":28,"startColumn":18,"endLine":28,"endColumn":35,"snippet":{}}}},"id":"get_app_baseline \\n[server.py : 26_51]->get_mcp_headers \\n[server.py : 14_23]","sourceNodeId":"get_app_baseline \\n[server.py : 26_51]","targetNodeId":"get_mcp_headers \\n[server.py : 14_23]"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpPaas/src/mcpPaas/server.py"},"region":{"startLine":15,"startColumn":19,"endLine":15,"endColumn":73,"snippet":{}}}},"id":"get_mcp_headers \\n[server.py : 14_23]->mcp.server.Server(mcp-paas).request_context.meta.model_extra.get","sourceNodeId":"get_mcp_headers \\n[server.py : 14_23]","targetNodeId":"mcp.server.Server(mcp-paas).request_context.meta.model_extra.get"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpPaas/src/mcpPaas/server.py"},"region":{"startLine":21,"startColumn":17,"endLine":21,"endColumn":34,"snippet":{}}}},"id":"get_mcp_headers \\n[server.py : 14_23]->mcp.server.Server(mcp-paas).request_context.meta.model_extra.get(headers).decode","sourceNodeId":"get_mcp_headers \\n[server.py : 14_23]","targetNodeId":"mcp.server.Server(mcp-paas).request_context.meta.model_extra.get(headers).decode"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpPaas/src/mcpPaas/server.py"},"region":{"startLine":20,"startColumn":15,"endLine":20,"endColumn":40,"snippet":{}}}},"id":"get_mcp_headers \\n[server.py : 14_23]->mcp.server.Server(mcp-paas).request_context.meta.model_extra.get(headers).decode(utf-8).lower","sourceNodeId":"get_mcp_headers \\n[server.py : 14_23]","targetNodeId":"mcp.server.Server(mcp-paas).request_context.meta.model_extra.get(headers).decode(utf-8).lower"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpPaas/src/mcpPaas/server.py"},"region":{"startLine":28,"startColumn":18,"endLine":28,"endColumn":55,"snippet":{}}}},"id":"get_app_baseline \\n[server.py : 26_51]->headers.get","sourceNodeId":"get_app_baseline \\n[server.py : 26_51]","targetNodeId":"headers.get"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpPaas/src/mcpPaas/server.py"},"region":{"startLine":30,"startColumn":19,"endLine":30,"endColumn":57,"snippet":{}}}},"id":"get_app_baseline \\n[server.py : 26_51]->/src/mcpPaas/src/mcpPaas/server.get_app_baseline.get_app_baseline_scope...Exception","sourceNodeId":"get_app_baseline \\n[server.py : 26_51]","targetNodeId":"/src/mcpPaas/src/mcpPaas/server.get_app_baseline.get_app_baseline_scope...Exception"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpPaas/src/mcpPaas/server.py"},"region":{"startLine":41,"startColumn":20,"endLine":43,"endColumn":44,"snippet":{}}}},"id":"get_app_baseline \\n[server.py : 26_51]->syslib_from.requests.get","sourceNodeId":"get_app_baseline \\n[server.py : 26_51]","targetNodeId":"syslib_from.requests.get"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpPaas/src/mcpPaas/server.py"},"region":{"startLine":44,"startColumn":9,"endLine":44,"endColumn":36,"snippet":{}}}},"id":"get_app_baseline \\n[server.py : 26_51]->syslib_from.requests.get(var url:any=https://unimetaservice.alipay.com/webapi/corsproxy/http://zappinfo-pool.global.alipay.com/genericBaseline/getAppBaselineView.json, var params:any=params, var heade...","sourceNodeId":"get_app_baseline \\n[server.py : 26_51]","targetNodeId":"syslib_from.requests.get(var url:any=https://unimetaservice.alipay.com/webapi/corsproxy/http://zappinfo-pool.global.alipay.com/genericBaseline/getAppBaselineView.json, var params:any=params, var heade..."},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpPaas/src/mcpPaas/server.py"},"region":{"startLine":45,"startColumn":18,"endLine":45,"endColumn":43,"snippet":{}}}},"id":"get_app_baseline \\n[server.py : 26_51]->syslib_from.json.loads","sourceNodeId":"get_app_baseline \\n[server.py : 26_51]","targetNodeId":"syslib_from.json.loads"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpPaas/src/mcpPaas/server.py"},"region":{"startLine":48,"startColumn":27,"endLine":48,"endColumn":51,"snippet":{}}}},"id":"get_app_baseline \\n[server.py : 26_51]->syslib_from.json.loads(response.text).get","sourceNodeId":"get_app_baseline \\n[server.py : 26_51]","targetNodeId":"syslib_from.json.loads(response.text).get"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpPaas/src/mcpPaas/server.py"},"region":{"startLine":47,"startColumn":19,"endLine":47,"endColumn":53,"snippet":{}}}},"id":"get_app_baseline \\n[server.py : 26_51]->/src/mcpPaas/src/mcpPaas/server.get_app_baseline.get_app_baseline_scope...Exception","sourceNodeId":"get_app_baseline \\n[server.py : 26_51]","targetNodeId":"/src/mcpPaas/src/mcpPaas/server.get_app_baseline.get_app_baseline_scope...Exception"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpPaas/src/mcpPaas/server.py"},"region":{"startLine":48,"startColumn":27,"endLine":48,"endColumn":63,"snippet":{}}}},"id":"get_app_baseline \\n[server.py : 26_51]->syslib_from.json.loads(response.text).get(resultView).get","sourceNodeId":"get_app_baseline \\n[server.py : 26_51]","targetNodeId":"syslib_from.json.loads(response.text).get(resultView).get"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpPaas/src/mcpPaas/server.py"},"region":{"startLine":48,"startColumn":16,"endLine":48,"endColumn":84,"snippet":{}}}},"id":"get_app_baseline \\n[server.py : 26_51]->syslib_from.json.dumps","sourceNodeId":"get_app_baseline \\n[server.py : 26_51]","targetNodeId":"syslib_from.json.dumps"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpPaas/src/mcpPaas/server.py"},"region":{"startLine":50,"startColumn":9,"endLine":50,"endColumn":88,"snippet":{}}}},"id":"get_app_baseline \\n[server.py : 26_51]->paas_client.info_logger.error","sourceNodeId":"get_app_baseline \\n[server.py : 26_51]","targetNodeId":"paas_client.info_logger.error"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpPaas/src/mcpPaas/server.py"},"region":{"startLine":51,"startColumn":15,"endLine":51,"endColumn":44,"snippet":{}}}},"id":"get_app_baseline \\n[server.py : 26_51]->/src/mcpPaas/src/mcpPaas/server.get_app_baseline.get_app_baseline_scope...Exception","sourceNodeId":"get_app_baseline \\n[server.py : 26_51]","targetNodeId":"/src/mcpPaas/src/mcpPaas/server.get_app_baseline.get_app_baseline_scope...Exception"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpPaas/src/mcpPaas/server.py"},"region":{"startLine":159,"startColumn":23,"endLine":159,"endColumn":61,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 126_163]->/src/mcpPaas/src/mcpPaas/server.handle_call_tool.handle_call_tool_scope....ValueError","sourceNodeId":"handle_call_tool \\n[server.py : 126_163]","targetNodeId":"/src/mcpPaas/src/mcpPaas/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpPaas/src/mcpPaas/server.py"},"region":{"startLine":160,"startColumn":27,"endLine":160,"endColumn":80,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 126_163]->paas_client.get_change_detail","sourceNodeId":"handle_call_tool \\n[server.py : 126_163]","targetNodeId":"paas_client.get_change_detail"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpPaas/src/mcpPaas/server.py"},"region":{"startLine":163,"startColumn":19,"endLine":163,"endColumn":54,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 126_163]->/src/mcpPaas/src/mcpPaas/server.handle_call_tool.handle_call_tool_scope...ValueError","sourceNodeId":"handle_call_tool \\n[server.py : 126_163]","targetNodeId":"/src/mcpPaas/src/mcpPaas/server.handle_call_tool.handle_call_tool_scope...ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpPackageSearch/src/mcpPackageSearch/server.py"},"region":{"startLine":132,"startColumn":1,"endLine":156,"endColumn":54,"snippet":{}}}},"id":"<__entry_point__>->handle_call_tool \\n[server.py : 132_156]","sourceNodeId":"<__entry_point__>","targetNodeId":"handle_call_tool \\n[server.py : 132_156]"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpPackageSearch/src/mcpPackageSearch/server.py"},"region":{"startLine":139,"startColumn":80,"endLine":139,"endColumn":123,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 132_156]->syslib_from.json.dumps","sourceNodeId":"handle_call_tool \\n[server.py : 132_156]","targetNodeId":"syslib_from.json.dumps"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpPackageSearch/src/mcpPackageSearch/server.py"},"region":{"startLine":139,"startColumn":5,"endLine":139,"endColumn":125,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 132_156]->syslib_from.logging.getLogger(mcp-server).info","sourceNodeId":"handle_call_tool \\n[server.py : 132_156]","targetNodeId":"syslib_from.logging.getLogger(mcp-server).info"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpPackageSearch/src/mcpPackageSearch/server.py"},"region":{"startLine":141,"startColumn":15,"endLine":141,"endColumn":48,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 132_156]->/src/mcpPackageSearch/src/mcpPackageSearch/server.handle_call_tool.handle_call_tool_scope...ValueError","sourceNodeId":"handle_call_tool \\n[server.py : 132_156]","targetNodeId":"/src/mcpPackageSearch/src/mcpPackageSearch/server.handle_call_tool.handle_call_tool_scope...ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpPackageSearch/src/mcpPackageSearch/server.py"},"region":{"startLine":146,"startColumn":23,"endLine":146,"endColumn":111,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 132_156]->/src/mcpPackageSearch/src/mcpPackageSearch/server.handle_call_tool.handle_call_tool_scope....ValueError","sourceNodeId":"handle_call_tool \\n[server.py : 132_156]","targetNodeId":"/src/mcpPackageSearch/src/mcpPackageSearch/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpPackageSearch/src/mcpPackageSearch/server.py"},"region":{"startLine":149,"startColumn":23,"endLine":149,"endColumn":65,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 132_156]->/src/mcpPackageSearch/src/mcpPackageSearch/server.handle_call_tool.arguments.get","sourceNodeId":"handle_call_tool \\n[server.py : 132_156]","targetNodeId":"/src/mcpPackageSearch/src/mcpPackageSearch/server.handle_call_tool.arguments.get"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpPackageSearch/src/mcpPackageSearch/server.py"},"region":{"startLine":150,"startColumn":19,"endLine":150,"endColumn":80,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 132_156]->app_caller_analysis \\n[server.py : 94_128]","sourceNodeId":"handle_call_tool \\n[server.py : 132_156]","targetNodeId":"app_caller_analysis \\n[server.py : 94_128]"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpPackageSearch/src/mcpPackageSearch/server.py"},"region":{"startLine":118,"startColumn":13,"endLine":118,"endColumn":113,"snippet":{}}}},"id":"app_caller_analysis \\n[server.py : 94_128]->syslib_from.logging.getLogger(mcp-server).info","sourceNodeId":"app_caller_analysis \\n[server.py : 94_128]","targetNodeId":"syslib_from.logging.getLogger(mcp-server).info"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpPackageSearch/src/mcpPackageSearch/server.py"},"region":{"startLine":100,"startColumn":20,"endLine":106,"endColumn":14,"snippet":{}}}},"id":"app_caller_analysis \\n[server.py : 94_128]->/src/mcpPackageSearch/src/mcpPackageSearch/server.app_caller_analysis.app_caller_analysis_scope..dict","sourceNodeId":"app_caller_analysis \\n[server.py : 94_128]","targetNodeId":"/src/mcpPackageSearch/src/mcpPackageSearch/server.app_caller_analysis.app_caller_analysis_scope..dict"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpPackageSearch/src/mcpPackageSearch/server.py"},"region":{"startLine":99,"startColumn":39,"endLine":107,"endColumn":10,"snippet":{}}}},"id":"app_caller_analysis \\n[server.py : 94_128]->mcp_common.remote.codeinsight.code_insight_api.mcp_server_backend_api","sourceNodeId":"app_caller_analysis \\n[server.py : 94_128]","targetNodeId":"mcp_common.remote.codeinsight.code_insight_api.mcp_server_backend_api"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpPackageSearch/src/mcpPackageSearch/server.py"},"region":{"startLine":121,"startColumn":35,"endLine":121,"endColumn":80,"snippet":{}}}},"id":"app_caller_analysis \\n[server.py : 94_128]->syslib_from.json.dumps","sourceNodeId":"app_caller_analysis \\n[server.py : 94_128]","targetNodeId":"syslib_from.json.dumps"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpPackageSearch/src/mcpPackageSearch/server.py"},"region":{"startLine":117,"startColumn":23,"endLine":117,"endColumn":63,"snippet":{}}}},"id":"app_caller_analysis \\n[server.py : 94_128]->mcp_common.remote.codeinsight.code_insight_api.mcp_server_backend_api(var params:any=dict(var name:any=Consts.APP_CALLER_ANALYSIS.name, var arguments:any=dict(var appName:any=app_name, var packageKeyw...","sourceNodeId":"app_caller_analysis \\n[server.py : 94_128]","targetNodeId":"mcp_common.remote.codeinsight.code_insight_api.mcp_server_backend_api(var params:any=dict(var name:any=Consts.APP_CALLER_ANALYSIS.name, var arguments:any=dict(var appName:any=app_name, var packageKeyw..."},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpPackageSearch/src/mcpPackageSearch/server.py"},"region":{"startLine":115,"startColumn":23,"endLine":115,"endColumn":61,"snippet":{}}}},"id":"app_caller_analysis \\n[server.py : 94_128]->format_dependency \\n[server.py : 74_91]","sourceNodeId":"app_caller_analysis \\n[server.py : 94_128]","targetNodeId":"format_dependency \\n[server.py : 74_91]"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpPackageSearch/src/mcpPackageSearch/server.py"},"region":{"startLine":84,"startColumn":31,"endLine":84,"endColumn":50,"snippet":{}}}},"id":"format_dependency \\n[server.py : 74_91]->/src/mcpPackageSearch/src/mcpPackageSearch/server.format_dependency.format_dependency_scope...enumerate","sourceNodeId":"format_dependency \\n[server.py : 74_91]","targetNodeId":"/src/mcpPackageSearch/src/mcpPackageSearch/server.format_dependency.format_dependency_scope...enumerate"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpPackageSearch/src/mcpPackageSearch/server.py"},"region":{"startLine":79,"startColumn":38,"endLine":79,"endColumn":50,"snippet":{}}}},"id":"format_dependency \\n[server.py : 74_91]->/src/mcpPackageSearch/src/mcpPackageSearch/server.format_dependency.format_dependency_scope...enumerate(data_list).items","sourceNodeId":"format_dependency \\n[server.py : 74_91]","targetNodeId":"/src/mcpPackageSearch/src/mcpPackageSearch/server.format_dependency.format_dependency_scope...enumerate(data_list).items"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpPackageSearch/src/mcpPackageSearch/server.py"},"region":{"startLine":87,"startColumn":9,"endLine":87,"endColumn":121,"snippet":{}}}},"id":"format_dependency \\n[server.py : 74_91]->syslib_from.logging.getLogger(mcp-server).info","sourceNodeId":"format_dependency \\n[server.py : 74_91]","targetNodeId":"syslib_from.logging.getLogger(mcp-server).info"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpPackageSearch/src/mcpPackageSearch/server.py"},"region":{"startLine":120,"startColumn":13,"endLine":121,"endColumn":82,"snippet":{}}}},"id":"app_caller_analysis \\n[server.py : 94_128]->syslib_from.logging.getLogger(mcp-server).warning","sourceNodeId":"app_caller_analysis \\n[server.py : 94_128]","targetNodeId":"syslib_from.logging.getLogger(mcp-server).warning"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpPackageSearch/src/mcpPackageSearch/server.py"},"region":{"startLine":124,"startColumn":9,"endLine":124,"endColumn":114,"snippet":{}}}},"id":"app_caller_analysis \\n[server.py : 94_128]->syslib_from.logging.getLogger(mcp-server).exception","sourceNodeId":"app_caller_analysis \\n[server.py : 94_128]","targetNodeId":"syslib_from.logging.getLogger(mcp-server).exception"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpPackageSearch/src/mcpPackageSearch/server.py"},"region":{"startLine":151,"startColumn":21,"endLine":154,"endColumn":14,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 132_156]->syslib_from.mcp/types.TextContent","sourceNodeId":"handle_call_tool \\n[server.py : 132_156]","targetNodeId":"syslib_from.mcp/types.TextContent"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpPackageSearch/src/mcpPackageSearch/server.py"},"region":{"startLine":156,"startColumn":19,"endLine":156,"endColumn":54,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 132_156]->/src/mcpPackageSearch/src/mcpPackageSearch/server.handle_call_tool.handle_call_tool_scope...ValueError","sourceNodeId":"handle_call_tool \\n[server.py : 132_156]","targetNodeId":"/src/mcpPackageSearch/src/mcpPackageSearch/server.handle_call_tool.handle_call_tool_scope...ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpQueryMultiAppMetrics/src/mcpQueryMultiAppMetrics/server.py"},"region":{"startLine":535,"startColumn":1,"endLine":556,"endColumn":28,"snippet":{}}}},"id":"<__entry_point__>->query_multi_app_metrics \\n[server.py : 535_556]","sourceNodeId":"<__entry_point__>","targetNodeId":"query_multi_app_metrics \\n[server.py : 535_556]"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpQueryMultiAppMetrics/src/mcpQueryMultiAppMetrics/server.py"},"region":{"startLine":537,"startColumn":63,"endLine":537,"endColumn":80,"snippet":{}}}},"id":"query_multi_app_metrics \\n[server.py : 535_556]->,.join","sourceNodeId":"query_multi_app_metrics \\n[server.py : 535_556]","targetNodeId":",.join"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpQueryMultiAppMetrics/src/mcpQueryMultiAppMetrics/server.py"},"region":{"startLine":537,"startColumn":9,"endLine":537,"endColumn":82,"snippet":{}}}},"id":"query_multi_app_metrics \\n[server.py : 535_556]->syslib_from.logging.getLogger(__name__).info","sourceNodeId":"query_multi_app_metrics \\n[server.py : 535_556]","targetNodeId":"syslib_from.logging.getLogger(__name__).info"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpQueryMultiAppMetrics/src/mcpQueryMultiAppMetrics/server.py"},"region":{"startLine":540,"startColumn":31,"endLine":540,"endColumn":43,"snippet":{}}}},"id":"query_multi_app_metrics \\n[server.py : 535_556]->/src/mcpQueryMultiAppMetrics/src/mcpQueryMultiAppMetrics/server.query_multi_app_metrics.zones.upper","sourceNodeId":"query_multi_app_metrics \\n[server.py : 535_556]","targetNodeId":"/src/mcpQueryMultiAppMetrics/src/mcpQueryMultiAppMetrics/server.query_multi_app_metrics.zones.upper"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpQueryMultiAppMetrics/src/mcpQueryMultiAppMetrics/server.py"},"region":{"startLine":546,"startColumn":91,"endLine":547,"endColumn":113,"snippet":{}}}},"id":"query_multi_app_metrics \\n[server.py : 535_556]->get_result \\n[server.py : 282_333]","sourceNodeId":"query_multi_app_metrics \\n[server.py : 535_556]","targetNodeId":"get_result \\n[server.py : 282_333]"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpQueryMultiAppMetrics/src/mcpQueryMultiAppMetrics/server.py"},"region":{"startLine":327,"startColumn":48,"endLine":327,"endColumn":97,"snippet":{}}}},"id":"get_result \\n[server.py : 282_333]->,.join","sourceNodeId":"get_result \\n[server.py : 282_333]","targetNodeId":",.join"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpQueryMultiAppMetrics/src/mcpQueryMultiAppMetrics/server.py"},"region":{"startLine":290,"startColumn":37,"endLine":290,"endColumn":49,"snippet":{}}}},"id":"get_result \\n[server.py : 282_333]->/src/mcpQueryMultiAppMetrics/src/mcpQueryMultiAppMetrics/server.query_multi_app_metrics.zones.upper().upper","sourceNodeId":"get_result \\n[server.py : 282_333]","targetNodeId":"/src/mcpQueryMultiAppMetrics/src/mcpQueryMultiAppMetrics/server.query_multi_app_metrics.zones.upper().upper"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpQueryMultiAppMetrics/src/mcpQueryMultiAppMetrics/server.py"},"region":{"startLine":293,"startColumn":11,"endLine":293,"endColumn":25,"snippet":{}}}},"id":"get_result \\n[server.py : 282_333]->datetime.datetime.now","sourceNodeId":"get_result \\n[server.py : 282_333]","targetNodeId":"datetime.datetime.now"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpQueryMultiAppMetrics/src/mcpQueryMultiAppMetrics/server.py"},"region":{"startLine":294,"startColumn":24,"endLine":294,"endColumn":41,"snippet":{}}}},"id":"get_result \\n[server.py : 282_333]->datetime.timedelta","sourceNodeId":"get_result \\n[server.py : 282_333]","targetNodeId":"datetime.timedelta"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpQueryMultiAppMetrics/src/mcpQueryMultiAppMetrics/server.py"},"region":{"startLine":296,"startColumn":13,"endLine":296,"endColumn":53,"snippet":{}}}},"id":"get_result \\n[server.py : 282_333]->start_time.strftime","sourceNodeId":"get_result \\n[server.py : 282_333]","targetNodeId":"start_time.strftime"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpQueryMultiAppMetrics/src/mcpQueryMultiAppMetrics/server.py"},"region":{"startLine":297,"startColumn":11,"endLine":297,"endColumn":44,"snippet":{}}}},"id":"get_result \\n[server.py : 282_333]->datetime.datetime.now().strftime","sourceNodeId":"get_result \\n[server.py : 282_333]","targetNodeId":"datetime.datetime.now().strftime"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpQueryMultiAppMetrics/src/mcpQueryMultiAppMetrics/server.py"},"region":{"startLine":321,"startColumn":27,"endLine":321,"endColumn":88,"snippet":{}}}},"id":"get_result \\n[server.py : 282_333]->get_app_result \\n[server.py : 174_194]","sourceNodeId":"get_result \\n[server.py : 282_333]","targetNodeId":"get_app_result \\n[server.py : 174_194]"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpQueryMultiAppMetrics/src/mcpQueryMultiAppMetrics/server.py"},"region":{"startLine":175,"startColumn":18,"endLine":175,"endColumn":70,"snippet":{}}}},"id":"get_app_result \\n[server.py : 174_194]->query \\n[server.py : 66_77]","sourceNodeId":"get_app_result \\n[server.py : 174_194]","targetNodeId":"query \\n[server.py : 66_77]"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpQueryMultiAppMetrics/src/mcpQueryMultiAppMetrics/server.py"},"region":{"startLine":73,"startColumn":5,"endLine":73,"endColumn":47,"snippet":{}}}},"id":"query \\n[server.py : 66_77]->syslib_from.logging.getLogger(__name__).info","sourceNodeId":"query \\n[server.py : 66_77]","targetNodeId":"syslib_from.logging.getLogger(__name__).info"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpQueryMultiAppMetrics/src/mcpQueryMultiAppMetrics/server.py"},"region":{"startLine":74,"startColumn":18,"endLine":74,"endColumn":56,"snippet":{}}}},"id":"query \\n[server.py : 66_77]->maas_service.MaasService().query_maas_by_sql_new_engine","sourceNodeId":"query \\n[server.py : 66_77]","targetNodeId":"maas_service.MaasService().query_maas_by_sql_new_engine"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpQueryMultiAppMetrics/src/mcpQueryMultiAppMetrics/server.py"},"region":{"startLine":76,"startColumn":15,"endLine":76,"endColumn":55,"snippet":{}}}},"id":"query \\n[server.py : 66_77]->/src/mcpQueryMultiAppMetrics/src/mcpQueryMultiAppMetrics/server.query.query_scope...Exception","sourceNodeId":"query \\n[server.py : 66_77]","targetNodeId":"/src/mcpQueryMultiAppMetrics/src/mcpQueryMultiAppMetrics/server.query.query_scope...Exception"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpQueryMultiAppMetrics/src/mcpQueryMultiAppMetrics/server.py"},"region":{"startLine":192,"startColumn":22,"endLine":192,"endColumn":48,"snippet":{}}}},"id":"get_app_result \\n[server.py : 174_194]->maas_service.MaasService().query_maas_by_sql_new_engine(sql).rows.replace","sourceNodeId":"get_app_result \\n[server.py : 174_194]","targetNodeId":"maas_service.MaasService().query_maas_by_sql_new_engine(sql).rows.replace"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpQueryMultiAppMetrics/src/mcpQueryMultiAppMetrics/server.py"},"region":{"startLine":183,"startColumn":57,"endLine":183,"endColumn":68,"snippet":{}}}},"id":"get_app_result \\n[server.py : 174_194]->/src/mcpQueryMultiAppMetrics/src/mcpQueryMultiAppMetrics/server.get_app_result.get_app_result_scope....str","sourceNodeId":"get_app_result \\n[server.py : 174_194]","targetNodeId":"/src/mcpQueryMultiAppMetrics/src/mcpQueryMultiAppMetrics/server.get_app_result.get_app_result_scope....str"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpQueryMultiAppMetrics/src/mcpQueryMultiAppMetrics/server.py"},"region":{"startLine":183,"startColumn":57,"endLine":183,"endColumn":86,"snippet":{}}}},"id":"get_app_result \\n[server.py : 174_194]->/src/mcpQueryMultiAppMetrics/src/mcpQueryMultiAppMetrics/server.get_app_result.get_app_result_scope....str(row.3).replace","sourceNodeId":"get_app_result \\n[server.py : 174_194]","targetNodeId":"/src/mcpQueryMultiAppMetrics/src/mcpQueryMultiAppMetrics/server.get_app_result.get_app_result_scope....str(row.3).replace"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpQueryMultiAppMetrics/src/mcpQueryMultiAppMetrics/server.py"},"region":{"startLine":185,"startColumn":12,"endLine":185,"endColumn":69,"snippet":{}}}},"id":"get_app_result \\n[server.py : 174_194]->query_gray \\n[server.py : 80_93]","sourceNodeId":"get_app_result \\n[server.py : 174_194]","targetNodeId":"query_gray \\n[server.py : 80_93]"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpQueryMultiAppMetrics/src/mcpQueryMultiAppMetrics/server.py"},"region":{"startLine":82,"startColumn":18,"endLine":82,"endColumn":83,"snippet":{}}}},"id":"query_gray \\n[server.py : 80_93]->map.key.table.replace","sourceNodeId":"query_gray \\n[server.py : 80_93]","targetNodeId":"map.key.table.replace"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpQueryMultiAppMetrics/src/mcpQueryMultiAppMetrics/server.py"},"region":{"startLine":89,"startColumn":5,"endLine":89,"endColumn":47,"snippet":{}}}},"id":"query_gray \\n[server.py : 80_93]->syslib_from.logging.getLogger(__name__).info","sourceNodeId":"query_gray \\n[server.py : 80_93]","targetNodeId":"syslib_from.logging.getLogger(__name__).info"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpQueryMultiAppMetrics/src/mcpQueryMultiAppMetrics/server.py"},"region":{"startLine":90,"startColumn":18,"endLine":90,"endColumn":56,"snippet":{}}}},"id":"query_gray \\n[server.py : 80_93]->maas_service.MaasService().query_maas_by_sql_new_engine","sourceNodeId":"query_gray \\n[server.py : 80_93]","targetNodeId":"maas_service.MaasService().query_maas_by_sql_new_engine"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpQueryMultiAppMetrics/src/mcpQueryMultiAppMetrics/server.py"},"region":{"startLine":92,"startColumn":15,"endLine":92,"endColumn":55,"snippet":{}}}},"id":"query_gray \\n[server.py : 80_93]->/src/mcpQueryMultiAppMetrics/src/mcpQueryMultiAppMetrics/server.query_gray.query_gray_scope...Exception","sourceNodeId":"query_gray \\n[server.py : 80_93]","targetNodeId":"/src/mcpQueryMultiAppMetrics/src/mcpQueryMultiAppMetrics/server.query_gray.query_gray_scope...Exception"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpQueryMultiAppMetrics/src/mcpQueryMultiAppMetrics/server.py"},"region":{"startLine":192,"startColumn":57,"endLine":192,"endColumn":68,"snippet":{}}}},"id":"get_app_result \\n[server.py : 174_194]->/src/mcpQueryMultiAppMetrics/src/mcpQueryMultiAppMetrics/server.get_app_result.get_app_result_scope....str","sourceNodeId":"get_app_result \\n[server.py : 174_194]","targetNodeId":"/src/mcpQueryMultiAppMetrics/src/mcpQueryMultiAppMetrics/server.get_app_result.get_app_result_scope....str"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpQueryMultiAppMetrics/src/mcpQueryMultiAppMetrics/server.py"},"region":{"startLine":192,"startColumn":57,"endLine":192,"endColumn":86,"snippet":{}}}},"id":"get_app_result \\n[server.py : 174_194]->/src/mcpQueryMultiAppMetrics/src/mcpQueryMultiAppMetrics/server.get_app_result.get_app_result_scope....str(row.3).replace","sourceNodeId":"get_app_result \\n[server.py : 174_194]","targetNodeId":"/src/mcpQueryMultiAppMetrics/src/mcpQueryMultiAppMetrics/server.get_app_result.get_app_result_scope....str(row.3).replace"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpQueryMultiAppMetrics/src/mcpQueryMultiAppMetrics/server.py"},"region":{"startLine":323,"startColumn":14,"endLine":323,"endColumn":19,"snippet":{}}}},"id":"get_result \\n[server.py : 282_333]->/src/mcpQueryMultiAppMetrics/src/mcpQueryMultiAppMetrics/server.get_result.get_result_scope..set","sourceNodeId":"get_result \\n[server.py : 282_333]","targetNodeId":"/src/mcpQueryMultiAppMetrics/src/mcpQueryMultiAppMetrics/server.get_result.get_result_scope..set"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpQueryMultiAppMetrics/src/mcpQueryMultiAppMetrics/server.py"},"region":{"startLine":324,"startColumn":18,"endLine":324,"endColumn":46,"snippet":{}}}},"id":"get_result \\n[server.py : 282_333]->app_and_zone_to_result.values","sourceNodeId":"get_result \\n[server.py : 282_333]","targetNodeId":"app_and_zone_to_result.values"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpQueryMultiAppMetrics/src/mcpQueryMultiAppMetrics/server.py"},"region":{"startLine":325,"startColumn":9,"endLine":325,"endColumn":29,"snippet":{}}}},"id":"get_result \\n[server.py : 282_333]->/src/mcpQueryMultiAppMetrics/src/mcpQueryMultiAppMetrics/server.get_result.get_result_scope..set().update","sourceNodeId":"get_result \\n[server.py : 282_333]","targetNodeId":"/src/mcpQueryMultiAppMetrics/src/mcpQueryMultiAppMetrics/server.get_result.get_result_scope..set().update"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpQueryMultiAppMetrics/src/mcpQueryMultiAppMetrics/server.py"},"region":{"startLine":326,"startColumn":27,"endLine":327,"endColumn":109,"snippet":{}}}},"id":"get_result \\n[server.py : 282_333]->query_topic_producer \\n[server.py : 96_116]","sourceNodeId":"get_result \\n[server.py : 282_333]","targetNodeId":"query_topic_producer \\n[server.py : 96_116]"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpQueryMultiAppMetrics/src/mcpQueryMultiAppMetrics/server.py"},"region":{"startLine":99,"startColumn":18,"endLine":104,"endColumn":9,"snippet":{}}}},"id":"query_topic_producer \\n[server.py : 96_116]->maas_service.MaasService().query_maas_by_sql_new_engine","sourceNodeId":"query_topic_producer \\n[server.py : 96_116]","targetNodeId":"maas_service.MaasService().query_maas_by_sql_new_engine"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpQueryMultiAppMetrics/src/mcpQueryMultiAppMetrics/server.py"},"region":{"startLine":106,"startColumn":15,"endLine":106,"endColumn":55,"snippet":{}}}},"id":"query_topic_producer \\n[server.py : 96_116]->/src/mcpQueryMultiAppMetrics/src/mcpQueryMultiAppMetrics/server.query_topic_producer.query_topic_producer_scope...Exception","sourceNodeId":"query_topic_producer \\n[server.py : 96_116]","targetNodeId":"/src/mcpQueryMultiAppMetrics/src/mcpQueryMultiAppMetrics/server.query_topic_producer.query_topic_producer_scope...Exception"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpQueryMultiAppMetrics/src/mcpQueryMultiAppMetrics/server.py"},"region":{"startLine":113,"startColumn":22,"endLine":113,"endColumn":48,"snippet":{}}}},"id":"query_topic_producer \\n[server.py : 96_116]->maas_service.MaasService().query_maas_by_sql_new_engine(","sourceNodeId":"query_topic_producer \\n[server.py : 96_116]","targetNodeId":"maas_service.MaasService().query_maas_by_sql_new_engine("},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpQueryMultiAppMetrics/src/mcpQueryMultiAppMetrics/server.py"},"region":{"startLine":328,"startColumn":26,"endLine":328,"endColumn":93,"snippet":{}}}},"id":"get_result \\n[server.py : 282_333]->find_sub_topic_source_app \\n[server.py : 197_208]","sourceNodeId":"get_result \\n[server.py : 282_333]","targetNodeId":"find_sub_topic_source_app \\n[server.py : 197_208]"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpQueryMultiAppMetrics/src/mcpQueryMultiAppMetrics/server.py"},"region":{"startLine":206,"startColumn":17,"endLine":206,"endColumn":66,"snippet":{}}}},"id":"find_sub_topic_source_app \\n[server.py : 197_208]->source_apps.extend","sourceNodeId":"find_sub_topic_source_app \\n[server.py : 197_208]","targetNodeId":"source_apps.extend"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpQueryMultiAppMetrics/src/mcpQueryMultiAppMetrics/server.py"},"region":{"startLine":207,"startColumn":33,"endLine":207,"endColumn":49,"snippet":{}}}},"id":"find_sub_topic_source_app \\n[server.py : 197_208]->/src/mcpQueryMultiAppMetrics/src/mcpQueryMultiAppMetrics/server.find_sub_topic_source_app.find_sub_topic_source_app_scope....set","sourceNodeId":"find_sub_topic_source_app \\n[server.py : 197_208]","targetNodeId":"/src/mcpQueryMultiAppMetrics/src/mcpQueryMultiAppMetrics/server.find_sub_topic_source_app.find_sub_topic_source_app_scope....set"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpQueryMultiAppMetrics/src/mcpQueryMultiAppMetrics/server.py"},"region":{"startLine":549,"startColumn":16,"endLine":554,"endColumn":113,"snippet":{}}}},"id":"query_multi_app_metrics \\n[server.py : 535_556]->print_multi_app_meta \\n[server.py : 336_430]","sourceNodeId":"query_multi_app_metrics \\n[server.py : 535_556]","targetNodeId":"print_multi_app_meta \\n[server.py : 336_430]"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpQueryMultiAppMetrics/src/mcpQueryMultiAppMetrics/server.py"},"region":{"startLine":348,"startColumn":5,"endLine":348,"endColumn":50,"snippet":{}}}},"id":"print_multi_app_meta \\n[server.py : 336_430]->| 风险状态 | app | 机房 | 风险详情 |.append","sourceNodeId":"print_multi_app_meta \\n[server.py : 336_430]","targetNodeId":"| 风险状态 | app | 机房 | 风险详情 |.append"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpQueryMultiAppMetrics/src/mcpQueryMultiAppMetrics/server.py"},"region":{"startLine":408,"startColumn":64,"endLine":408,"endColumn":98,"snippet":{}}}},"id":"print_multi_app_meta \\n[server.py : 336_430]->,.join","sourceNodeId":"print_multi_app_meta \\n[server.py : 336_430]","targetNodeId":",.join"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpQueryMultiAppMetrics/src/mcpQueryMultiAppMetrics/server.py"},"region":{"startLine":428,"startColumn":5,"endLine":428,"endColumn":32,"snippet":{}}}},"id":"print_multi_app_meta \\n[server.py : 336_430]->result_list.extend","sourceNodeId":"print_multi_app_meta \\n[server.py : 336_430]","targetNodeId":"result_list.extend"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpQueryMultiAppMetrics/src/mcpQueryMultiAppMetrics/server.py"},"region":{"startLine":430,"startColumn":12,"endLine":430,"endColumn":34,"snippet":{}}}},"id":"print_multi_app_meta \\n[server.py : 336_430]->join","sourceNodeId":"print_multi_app_meta \\n[server.py : 336_430]","targetNodeId":"join"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpQueryMultiAppMetrics/src/mcpQueryMultiAppMetrics/server.py"},"region":{"startLine":556,"startColumn":9,"endLine":556,"endColumn":28,"snippet":{}}}},"id":"query_multi_app_metrics \\n[server.py : 535_556]->syslib_from.logging.getLogger(__name__).exception","sourceNodeId":"query_multi_app_metrics \\n[server.py : 535_556]","targetNodeId":"syslib_from.logging.getLogger(__name__).exception"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpQueryMultiAppMetrics/src/mcpQueryMultiAppMetrics/server.py"},"region":{"startLine":560,"startColumn":1,"endLine":582,"endColumn":6,"snippet":{}}}},"id":"<__entry_point__>->handle_call_tool \\n[server.py : 560_582]","sourceNodeId":"<__entry_point__>","targetNodeId":"handle_call_tool \\n[server.py : 560_582]"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpQueryMultiAppMetrics/src/mcpQueryMultiAppMetrics/server.py"},"region":{"startLine":567,"startColumn":5,"endLine":567,"endColumn":52,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 560_582]->syslib_from.logging.getLogger(__name__).info","sourceNodeId":"handle_call_tool \\n[server.py : 560_582]","targetNodeId":"syslib_from.logging.getLogger(__name__).info"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpQueryMultiAppMetrics/src/mcpQueryMultiAppMetrics/server.py"},"region":{"startLine":569,"startColumn":15,"endLine":569,"endColumn":50,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 560_582]->/src/mcpQueryMultiAppMetrics/src/mcpQueryMultiAppMetrics/server.handle_call_tool.handle_call_tool_scope...ValueError","sourceNodeId":"handle_call_tool \\n[server.py : 560_582]","targetNodeId":"/src/mcpQueryMultiAppMetrics/src/mcpQueryMultiAppMetrics/server.handle_call_tool.handle_call_tool_scope...ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpQueryMultiAppMetrics/src/mcpQueryMultiAppMetrics/server.py"},"region":{"startLine":572,"startColumn":15,"endLine":572,"endColumn":56,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 560_582]->/src/mcpQueryMultiAppMetrics/src/mcpQueryMultiAppMetrics/server.handle_call_tool.handle_call_tool_scope...ValueError","sourceNodeId":"handle_call_tool \\n[server.py : 560_582]","targetNodeId":"/src/mcpQueryMultiAppMetrics/src/mcpQueryMultiAppMetrics/server.handle_call_tool.handle_call_tool_scope...ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpQueryMultiAppMetrics/src/mcpQueryMultiAppMetrics/server.py"},"region":{"startLine":534,"startColumn":2,"endLine":534,"endColumn":20,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 560_582]->.server.call_tool","sourceNodeId":"handle_call_tool \\n[server.py : 560_582]","targetNodeId":".server.call_tool"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpQueryMultiAppMetrics/src/mcpQueryMultiAppMetrics/server.py"},"region":{"startLine":575,"startColumn":15,"endLine":575,"endColumn":88,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 560_582]->query_multi_app_metrics \\n[server.py : 535_556]","sourceNodeId":"handle_call_tool \\n[server.py : 560_582]","targetNodeId":"query_multi_app_metrics \\n[server.py : 535_556]"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpQueryMultiAppMetrics/src/mcpQueryMultiAppMetrics/server.py"},"region":{"startLine":540,"startColumn":31,"endLine":540,"endColumn":43,"snippet":{}}}},"id":"query_multi_app_metrics \\n[server.py : 535_556]->/src/mcpQueryMultiAppMetrics/src/mcpQueryMultiAppMetrics/server.handle_call_tool.arguments.zones.upper","sourceNodeId":"query_multi_app_metrics \\n[server.py : 535_556]","targetNodeId":"/src/mcpQueryMultiAppMetrics/src/mcpQueryMultiAppMetrics/server.handle_call_tool.arguments.zones.upper"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpQueryMultiAppMetrics/src/mcpQueryMultiAppMetrics/server.py"},"region":{"startLine":290,"startColumn":37,"endLine":290,"endColumn":49,"snippet":{}}}},"id":"get_result \\n[server.py : 282_333]->/src/mcpQueryMultiAppMetrics/src/mcpQueryMultiAppMetrics/server.handle_call_tool.arguments.zones.upper().upper","sourceNodeId":"get_result \\n[server.py : 282_333]","targetNodeId":"/src/mcpQueryMultiAppMetrics/src/mcpQueryMultiAppMetrics/server.handle_call_tool.arguments.zones.upper().upper"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpQueryMultiAppMetrics/src/mcpQueryMultiAppMetrics/server.py"},"region":{"startLine":578,"startColumn":9,"endLine":581,"endColumn":10,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 560_582]->mcp.types.TextContent","sourceNodeId":"handle_call_tool \\n[server.py : 560_582]","targetNodeId":"mcp.types.TextContent"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpQueryRiskMerchantInfo/src/mcpQueryRiskMerchantInfo/server.py"},"region":{"startLine":39,"startColumn":1,"endLine":59,"endColumn":54,"snippet":{}}}},"id":"<__entry_point__>->handle_call_tool \\n[server.py : 39_59]","sourceNodeId":"<__entry_point__>","targetNodeId":"handle_call_tool \\n[server.py : 39_59]"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpQueryRiskMerchantInfo/src/mcpQueryRiskMerchantInfo/server.py"},"region":{"startLine":52,"startColumn":68,"endLine":52,"endColumn":108,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 39_59]->syslib_from.json.dumps","sourceNodeId":"handle_call_tool \\n[server.py : 39_59]","targetNodeId":"syslib_from.json.dumps"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpQueryRiskMerchantInfo/src/mcpQueryRiskMerchantInfo/server.py"},"region":{"startLine":52,"startColumn":17,"endLine":52,"endColumn":110,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 39_59]->syslib_from.logging.getLogger(__name__).info","sourceNodeId":"handle_call_tool \\n[server.py : 39_59]","targetNodeId":"syslib_from.logging.getLogger(__name__).info"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpQueryRiskMerchantInfo/src/mcpQueryRiskMerchantInfo/server.py"},"region":{"startLine":48,"startColumn":23,"endLine":48,"endColumn":55,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 39_59]->/src/mcpQueryRiskMerchantInfo/src/mcpQueryRiskMerchantInfo/server.handle_call_tool.handle_call_tool_scope....ValueError","sourceNodeId":"handle_call_tool \\n[server.py : 39_59]","targetNodeId":"/src/mcpQueryRiskMerchantInfo/src/mcpQueryRiskMerchantInfo/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpQueryRiskMerchantInfo/src/mcpQueryRiskMerchantInfo/server.py"},"region":{"startLine":51,"startColumn":26,"endLine":51,"endColumn":93,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 39_59]->syslib_from.merchant_client.query_risk_merchant_info","sourceNodeId":"handle_call_tool \\n[server.py : 39_59]","targetNodeId":"syslib_from.merchant_client.query_risk_merchant_info"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpQueryRiskMerchantInfo/src/mcpQueryRiskMerchantInfo/server.py"},"region":{"startLine":56,"startColumn":68,"endLine":56,"endColumn":76,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 39_59]->/src/mcpQueryRiskMerchantInfo/src/mcpQueryRiskMerchantInfo/server.handle_call_tool.handle_call_tool_scope....str","sourceNodeId":"handle_call_tool \\n[server.py : 39_59]","targetNodeId":"/src/mcpQueryRiskMerchantInfo/src/mcpQueryRiskMerchantInfo/server.handle_call_tool.handle_call_tool_scope....str"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpQueryRiskMerchantInfo/src/mcpQueryRiskMerchantInfo/server.py"},"region":{"startLine":55,"startColumn":17,"endLine":55,"endColumn":79,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 39_59]->syslib_from.logging.getLogger(__name__).error","sourceNodeId":"handle_call_tool \\n[server.py : 39_59]","targetNodeId":"syslib_from.logging.getLogger(__name__).error"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpQueryRiskMerchantInfo/src/mcpQueryRiskMerchantInfo/server.py"},"region":{"startLine":56,"startColumn":23,"endLine":56,"endColumn":78,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 39_59]->/src/mcpQueryRiskMerchantInfo/src/mcpQueryRiskMerchantInfo/server.handle_call_tool.handle_call_tool_scope....ValueError","sourceNodeId":"handle_call_tool \\n[server.py : 39_59]","targetNodeId":"/src/mcpQueryRiskMerchantInfo/src/mcpQueryRiskMerchantInfo/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpQueryRiskMerchantInfo/src/mcpQueryRiskMerchantInfo/server.py"},"region":{"startLine":59,"startColumn":19,"endLine":59,"endColumn":54,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 39_59]->/src/mcpQueryRiskMerchantInfo/src/mcpQueryRiskMerchantInfo/server.handle_call_tool.handle_call_tool_scope...ValueError","sourceNodeId":"handle_call_tool \\n[server.py : 39_59]","targetNodeId":"/src/mcpQueryRiskMerchantInfo/src/mcpQueryRiskMerchantInfo/server.handle_call_tool.handle_call_tool_scope...ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpQuerySingleAppMetrics/src/mcpQuerySingleAppMetrics/server.py"},"region":{"startLine":699,"startColumn":1,"endLine":761,"endColumn":46,"snippet":{}}}},"id":"<__entry_point__>->handle_call_tool \\n[server.py : 699_761]","sourceNodeId":"<__entry_point__>","targetNodeId":"handle_call_tool \\n[server.py : 699_761]"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpQuerySingleAppMetrics/src/mcpQuerySingleAppMetrics/server.py"},"region":{"startLine":706,"startColumn":5,"endLine":706,"endColumn":52,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 699_761]->syslib_from.logging.getLogger(__name__).info","sourceNodeId":"handle_call_tool \\n[server.py : 699_761]","targetNodeId":"syslib_from.logging.getLogger(__name__).info"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpQuerySingleAppMetrics/src/mcpQuerySingleAppMetrics/server.py"},"region":{"startLine":708,"startColumn":15,"endLine":708,"endColumn":55,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 699_761]->/src/mcpQuerySingleAppMetrics/src/mcpQuerySingleAppMetrics/server.handle_call_tool.handle_call_tool_scope...ValueError","sourceNodeId":"handle_call_tool \\n[server.py : 699_761]","targetNodeId":"/src/mcpQuerySingleAppMetrics/src/mcpQuerySingleAppMetrics/server.handle_call_tool.handle_call_tool_scope...ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpQuerySingleAppMetrics/src/mcpQuerySingleAppMetrics/server.py"},"region":{"startLine":711,"startColumn":19,"endLine":711,"endColumn":83,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 699_761]->query_single_app_em14_total_metrics \\n[server.py : 52_317]","sourceNodeId":"handle_call_tool \\n[server.py : 699_761]","targetNodeId":"query_single_app_em14_total_metrics \\n[server.py : 52_317]"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpQuerySingleAppMetrics/src/mcpQuerySingleAppMetrics/server.py"},"region":{"startLine":53,"startColumn":12,"endLine":53,"endColumn":25,"snippet":{}}}},"id":"query_single_app_em14_total_metrics \\n[server.py : 52_317]->maas_service.MaasService","sourceNodeId":"query_single_app_em14_total_metrics \\n[server.py : 52_317]","targetNodeId":"maas_service.MaasService"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpQuerySingleAppMetrics/src/mcpQuerySingleAppMetrics/server.py"},"region":{"startLine":54,"startColumn":11,"endLine":54,"endColumn":25,"snippet":{}}}},"id":"query_single_app_em14_total_metrics \\n[server.py : 52_317]->datetime.datetime.now","sourceNodeId":"query_single_app_em14_total_metrics \\n[server.py : 52_317]","targetNodeId":"datetime.datetime.now"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpQuerySingleAppMetrics/src/mcpQuerySingleAppMetrics/server.py"},"region":{"startLine":61,"startColumn":27,"endLine":61,"endColumn":48,"snippet":{}}}},"id":"query_single_app_em14_total_metrics \\n[server.py : 52_317]->datetime.timedelta","sourceNodeId":"query_single_app_em14_total_metrics \\n[server.py : 52_317]","targetNodeId":"datetime.timedelta"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpQuerySingleAppMetrics/src/mcpQuerySingleAppMetrics/server.py"},"region":{"startLine":59,"startColumn":22,"endLine":59,"endColumn":62,"snippet":{}}}},"id":"query_single_app_em14_total_metrics \\n[server.py : 52_317]->start_time.strftime","sourceNodeId":"query_single_app_em14_total_metrics \\n[server.py : 52_317]","targetNodeId":"start_time.strftime"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpQuerySingleAppMetrics/src/mcpQuerySingleAppMetrics/server.py"},"region":{"startLine":61,"startColumn":20,"endLine":61,"endColumn":79,"snippet":{}}}},"id":"query_single_app_em14_total_metrics \\n[server.py : 52_317]->strftime","sourceNodeId":"query_single_app_em14_total_metrics \\n[server.py : 52_317]","targetNodeId":"strftime"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpQuerySingleAppMetrics/src/mcpQuerySingleAppMetrics/server.py"},"region":{"startLine":173,"startColumn":18,"endLine":176,"endColumn":108,"snippet":{}}}},"id":"query_single_app_em14_total_metrics \\n[server.py : 52_317]->maas_service.MaasService().query_maas_by_sql_new_engine","sourceNodeId":"query_single_app_em14_total_metrics \\n[server.py : 52_317]","targetNodeId":"maas_service.MaasService().query_maas_by_sql_new_engine"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpQuerySingleAppMetrics/src/mcpQuerySingleAppMetrics/server.py"},"region":{"startLine":178,"startColumn":25,"endLine":178,"endColumn":55,"snippet":{}}}},"id":"query_single_app_em14_total_metrics \\n[server.py : 52_317]->mcpAntscheduler.client.get_job_list_by_app","sourceNodeId":"query_single_app_em14_total_metrics \\n[server.py : 52_317]","targetNodeId":"mcpAntscheduler.client.get_job_list_by_app"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpQuerySingleAppMetrics/src/mcpQuerySingleAppMetrics/server.py"},"region":{"startLine":181,"startColumn":17,"endLine":181,"endColumn":46,"snippet":{}}}},"id":"query_single_app_em14_total_metrics \\n[server.py : 52_317]->syslib_from.json.loads","sourceNodeId":"query_single_app_em14_total_metrics \\n[server.py : 52_317]","targetNodeId":"syslib_from.json.loads"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpQuerySingleAppMetrics/src/mcpQuerySingleAppMetrics/server.py"},"region":{"startLine":191,"startColumn":24,"endLine":191,"endColumn":33,"snippet":{}}}},"id":"query_single_app_em14_total_metrics \\n[server.py : 52_317]->/src/mcpQuerySingleAppMetrics/src/mcpQuerySingleAppMetrics/server.query_single_app_em14_total_metrics.query_single_app_em14_total_metrics_scope.....syslib_from.json.loads(antscheduler_task).get","sourceNodeId":"query_single_app_em14_total_metrics \\n[server.py : 52_317]","targetNodeId":"syslib_from.json.loads(antscheduler_task).get"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpQuerySingleAppMetrics/src/mcpQuerySingleAppMetrics/server.py"},"region":{"startLine":186,"startColumn":26,"endLine":186,"endColumn":50,"snippet":{}}}},"id":"query_single_app_em14_total_metrics \\n[server.py : 52_317]->syslib_from.json.loads(antscheduler_task).get(jobItems, {}).get","sourceNodeId":"query_single_app_em14_total_metrics \\n[server.py : 52_317]","targetNodeId":"syslib_from.json.loads(antscheduler_task).get(jobItems, {}).get"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpQuerySingleAppMetrics/src/mcpQuerySingleAppMetrics/server.py"},"region":{"startLine":185,"startColumn":24,"endLine":188,"endColumn":18,"snippet":{}}}},"id":"query_single_app_em14_total_metrics \\n[server.py : 52_317]->,.join","sourceNodeId":"query_single_app_em14_total_metrics \\n[server.py : 52_317]","targetNodeId":",.join"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpQuerySingleAppMetrics/src/mcpQuerySingleAppMetrics/server.py"},"region":{"startLine":190,"startColumn":28,"endLine":190,"endColumn":47,"snippet":{}}}},"id":"query_single_app_em14_total_metrics \\n[server.py : 52_317]->get","sourceNodeId":"query_single_app_em14_total_metrics \\n[server.py : 52_317]","targetNodeId":"get"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpQuerySingleAppMetrics/src/mcpQuerySingleAppMetrics/server.py"},"region":{"startLine":298,"startColumn":19,"endLine":298,"endColumn":56,"snippet":{}}}},"id":"query_single_app_em14_total_metrics \\n[server.py : 52_317]->get_em14_ldc_total \\n[server.py : 616_630]","sourceNodeId":"query_single_app_em14_total_metrics \\n[server.py : 52_317]","targetNodeId":"get_em14_ldc_total \\n[server.py : 616_630]"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpQuerySingleAppMetrics/src/mcpQuerySingleAppMetrics/server.py"},"region":{"startLine":302,"startColumn":116,"endLine":302,"endColumn":132,"snippet":{}}}},"id":"query_single_app_em14_total_metrics \\n[server.py : 52_317]->str","sourceNodeId":"query_single_app_em14_total_metrics \\n[server.py : 52_317]","targetNodeId":"str"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpQuerySingleAppMetrics/src/mcpQuerySingleAppMetrics/server.py"},"region":{"startLine":302,"startColumn":38,"endLine":302,"endColumn":134,"snippet":{}}}},"id":"query_single_app_em14_total_metrics \\n[server.py : 52_317]->|.join","sourceNodeId":"query_single_app_em14_total_metrics \\n[server.py : 52_317]","targetNodeId":"|.join"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpQuerySingleAppMetrics/src/mcpQuerySingleAppMetrics/server.py"},"region":{"startLine":302,"startColumn":24,"endLine":302,"endColumn":135,"snippet":{}}}},"id":"query_single_app_em14_total_metrics \\n[server.py : 52_317]->|{}|.format","sourceNodeId":"query_single_app_em14_total_metrics \\n[server.py : 52_317]","targetNodeId":"|{}|.format"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpQuerySingleAppMetrics/src/mcpQuerySingleAppMetrics/server.py"},"region":{"startLine":237,"startColumn":9,"endLine":238,"endColumn":132,"snippet":{}}}},"id":"query_single_app_em14_total_metrics \\n[server.py : 52_317]->|{}|.format(|.join({0:高风险‼️, 1:sofamq 订阅消息(mqsub), 2:调用量级是+str(mqsub_total)})).append","sourceNodeId":"query_single_app_em14_total_metrics \\n[server.py : 52_317]","targetNodeId":"|{}|.format(|.join({0:高风险‼️, 1:sofamq 订阅消息(mqsub), 2:调用量级是+str(mqsub_total)})).append"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpQuerySingleAppMetrics/src/mcpQuerySingleAppMetrics/server.py"},"region":{"startLine":302,"startColumn":9,"endLine":302,"endColumn":136,"snippet":{}}}},"id":"query_single_app_em14_total_metrics \\n[server.py : 52_317]->|{}|.format(|.join({0:无风险✅, 1:sofamq 订阅消息(mqsub), 2:调用量级是+str(mqsub_total)})).append","sourceNodeId":"query_single_app_em14_total_metrics \\n[server.py : 52_317]","targetNodeId":"|{}|.format(|.join({0:无风险✅, 1:sofamq 订阅消息(mqsub), 2:调用量级是+str(mqsub_total)})).append"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpQuerySingleAppMetrics/src/mcpQuerySingleAppMetrics/server.py"},"region":{"startLine":228,"startColumn":8,"endLine":228,"endColumn":35,"snippet":{}}}},"id":"query_single_app_em14_total_metrics \\n[server.py : 52_317]->/src/mcpQuerySingleAppMetrics/src/mcpQuerySingleAppMetrics/server.query_single_app_em14_total_metrics.query_single_app_em14_total_metrics_scope..len","sourceNodeId":"query_single_app_em14_total_metrics \\n[server.py : 52_317]","targetNodeId":"/src/mcpQuerySingleAppMetrics/src/mcpQuerySingleAppMetrics/server.query_single_app_em14_total_metrics.query_single_app_em14_total_metrics_scope..len"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpQuerySingleAppMetrics/src/mcpQuerySingleAppMetrics/server.py"},"region":{"startLine":230,"startColumn":72,"endLine":230,"endColumn":105,"snippet":{}}}},"id":"query_single_app_em14_total_metrics \\n[server.py : 52_317]->join","sourceNodeId":"query_single_app_em14_total_metrics \\n[server.py : 52_317]","targetNodeId":"join"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpQuerySingleAppMetrics/src/mcpQuerySingleAppMetrics/server.py"},"region":{"startLine":252,"startColumn":9,"endLine":252,"endColumn":130,"snippet":{}}}},"id":"query_single_app_em14_total_metrics \\n[server.py : 52_317]->|{}|.format(|.join({0:中风险❗️, 1:上游调用(service(MOSN)), 2:调用量级是+str(service_total)})).append","sourceNodeId":"query_single_app_em14_total_metrics \\n[server.py : 52_317]","targetNodeId":"|{}|.format(|.join({0:中风险❗️, 1:上游调用(service(MOSN)), 2:调用量级是+str(service_total)})).append"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpQuerySingleAppMetrics/src/mcpQuerySingleAppMetrics/server.py"},"region":{"startLine":300,"startColumn":9,"endLine":300,"endColumn":137,"snippet":{}}}},"id":"query_single_app_em14_total_metrics \\n[server.py : 52_317]->|{}|.format(|.join({0:低风险⚠️️, 1:调用下游 RPC(sal), 2:调用量级是+str(sal_total)})).append","sourceNodeId":"query_single_app_em14_total_metrics \\n[server.py : 52_317]","targetNodeId":"|{}|.format(|.join({0:低风险⚠️️, 1:调用下游 RPC(sal), 2:调用量级是+str(sal_total)})).append"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpQuerySingleAppMetrics/src/mcpQuerySingleAppMetrics/server.py"},"region":{"startLine":755,"startColumn":13,"endLine":758,"endColumn":14,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 699_761]->mcp.types.TextContent","sourceNodeId":"handle_call_tool \\n[server.py : 699_761]","targetNodeId":"mcp.types.TextContent"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpQuerySingleAppMetrics/src/mcpQuerySingleAppMetrics/server.py"},"region":{"startLine":720,"startColumn":16,"endLine":720,"endColumn":70,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 699_761]->query_single_app_em14_total_pod \\n[server.py : 603_613]","sourceNodeId":"handle_call_tool \\n[server.py : 699_761]","targetNodeId":"query_single_app_em14_total_pod \\n[server.py : 603_613]"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpQuerySingleAppMetrics/src/mcpQuerySingleAppMetrics/server.py"},"region":{"startLine":604,"startColumn":35,"endLine":604,"endColumn":80,"snippet":{}}}},"id":"query_single_app_em14_total_pod \\n[server.py : 603_613]->query_single_app_em14_total_pod_raw \\n[server.py : 561_600]","sourceNodeId":"query_single_app_em14_total_pod \\n[server.py : 603_613]","targetNodeId":"query_single_app_em14_total_pod_raw \\n[server.py : 561_600]"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpQuerySingleAppMetrics/src/mcpQuerySingleAppMetrics/server.py"},"region":{"startLine":562,"startColumn":12,"endLine":562,"endColumn":25,"snippet":{}}}},"id":"query_single_app_em14_total_pod_raw \\n[server.py : 561_600]->maas_service.MaasService","sourceNodeId":"query_single_app_em14_total_pod_raw \\n[server.py : 561_600]","targetNodeId":"maas_service.MaasService"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpQuerySingleAppMetrics/src/mcpQuerySingleAppMetrics/server.py"},"region":{"startLine":563,"startColumn":18,"endLine":563,"endColumn":48,"snippet":{}}}},"id":"query_single_app_em14_total_pod_raw \\n[server.py : 561_600]->get_start_end_time \\n[server.py : 499_507]","sourceNodeId":"query_single_app_em14_total_pod_raw \\n[server.py : 561_600]","targetNodeId":"get_start_end_time \\n[server.py : 499_507]"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpQuerySingleAppMetrics/src/mcpQuerySingleAppMetrics/server.py"},"region":{"startLine":500,"startColumn":11,"endLine":500,"endColumn":25,"snippet":{}}}},"id":"get_start_end_time \\n[server.py : 499_507]->datetime.datetime.now","sourceNodeId":"get_start_end_time \\n[server.py : 499_507]","targetNodeId":"datetime.datetime.now"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpQuerySingleAppMetrics/src/mcpQuerySingleAppMetrics/server.py"},"region":{"startLine":506,"startColumn":22,"endLine":506,"endColumn":43,"snippet":{}}}},"id":"get_start_end_time \\n[server.py : 499_507]->datetime.timedelta","sourceNodeId":"get_start_end_time \\n[server.py : 499_507]","targetNodeId":"datetime.timedelta"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpQuerySingleAppMetrics/src/mcpQuerySingleAppMetrics/server.py"},"region":{"startLine":504,"startColumn":17,"endLine":504,"endColumn":57,"snippet":{}}}},"id":"get_start_end_time \\n[server.py : 499_507]->start_time.strftime","sourceNodeId":"get_start_end_time \\n[server.py : 499_507]","targetNodeId":"start_time.strftime"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpQuerySingleAppMetrics/src/mcpQuerySingleAppMetrics/server.py"},"region":{"startLine":506,"startColumn":15,"endLine":506,"endColumn":74,"snippet":{}}}},"id":"get_start_end_time \\n[server.py : 499_507]->strftime","sourceNodeId":"get_start_end_time \\n[server.py : 499_507]","targetNodeId":"strftime"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpQuerySingleAppMetrics/src/mcpQuerySingleAppMetrics/server.py"},"region":{"startLine":582,"startColumn":23,"endLine":598,"endColumn":21,"snippet":{}}}},"id":"query_single_app_em14_total_pod_raw \\n[server.py : 561_600]->maas_service.MaasService().query_maas_by_sql_new_engine","sourceNodeId":"query_single_app_em14_total_pod_raw \\n[server.py : 561_600]","targetNodeId":"maas_service.MaasService().query_maas_by_sql_new_engine"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpQuerySingleAppMetrics/src/mcpQuerySingleAppMetrics/server.py"},"region":{"startLine":606,"startColumn":15,"endLine":606,"endColumn":55,"snippet":{}}}},"id":"query_single_app_em14_total_pod \\n[server.py : 603_613]->/src/mcpQuerySingleAppMetrics/src/mcpQuerySingleAppMetrics/server.query_single_app_em14_total_pod.query_single_app_em14_total_pod_scope...Exception","sourceNodeId":"query_single_app_em14_total_pod \\n[server.py : 603_613]","targetNodeId":"/src/mcpQuerySingleAppMetrics/src/mcpQuerySingleAppMetrics/server.query_single_app_em14_total_pod.query_single_app_em14_total_pod_scope...Exception"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpQuerySingleAppMetrics/src/mcpQuerySingleAppMetrics/server.py"},"region":{"startLine":610,"startColumn":70,"endLine":610,"endColumn":88,"snippet":{}}}},"id":"query_single_app_em14_total_pod \\n[server.py : 603_613]->/src/mcpQuerySingleAppMetrics/src/mcpQuerySingleAppMetrics/server.query_single_app_em14_total_pod.query_single_app_em14_total_pod_scope....s...","sourceNodeId":"query_single_app_em14_total_pod \\n[server.py : 603_613]","targetNodeId":"/src/mcpQuerySingleAppMetrics/src/mcpQuerySingleAppMetrics/server.query_single_app_em14_total_pod.query_single_app_em14_total_pod_scope....s..."},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpQuerySingleAppMetrics/src/mcpQuerySingleAppMetrics/server.py"},"region":{"startLine":612,"startColumn":70,"endLine":612,"endColumn":88,"snippet":{}}}},"id":"query_single_app_em14_total_pod \\n[server.py : 603_613]->/src/mcpQuerySingleAppMetrics/src/mcpQuerySingleAppMetrics/server.query_single_app_em14_total_pod.query_single_app_em14_total_pod_scope....s...","sourceNodeId":"query_single_app_em14_total_pod \\n[server.py : 603_613]","targetNodeId":"/src/mcpQuerySingleAppMetrics/src/mcpQuerySingleAppMetrics/server.query_single_app_em14_total_pod.query_single_app_em14_total_pod_scope....s..."},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpQuerySingleAppMetrics/src/mcpQuerySingleAppMetrics/server.py"},"region":{"startLine":751,"startColumn":9,"endLine":751,"endColumn":93,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 699_761]->syslib_from.logging.getLogger(__name__).error","sourceNodeId":"handle_call_tool \\n[server.py : 699_761]","targetNodeId":"syslib_from.logging.getLogger(__name__).error"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpQuerySingleAppMetrics/src/mcpQuerySingleAppMetrics/server.py"},"region":{"startLine":731,"startColumn":15,"endLine":731,"endColumn":72,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 699_761]->query_single_app_em14_mq_sub \\n[server.py : 510_558]","sourceNodeId":"handle_call_tool \\n[server.py : 699_761]","targetNodeId":"query_single_app_em14_mq_sub \\n[server.py : 510_558]"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpQuerySingleAppMetrics/src/mcpQuerySingleAppMetrics/server.py"},"region":{"startLine":512,"startColumn":22,"endLine":512,"endColumn":52,"snippet":{}}}},"id":"query_single_app_em14_mq_sub \\n[server.py : 510_558]->get_start_end_time \\n[server.py : 499_507]","sourceNodeId":"query_single_app_em14_mq_sub \\n[server.py : 510_558]","targetNodeId":"get_start_end_time \\n[server.py : 499_507]"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpQuerySingleAppMetrics/src/mcpQuerySingleAppMetrics/server.py"},"region":{"startLine":542,"startColumn":31,"endLine":542,"endColumn":72,"snippet":{}}}},"id":"query_single_app_em14_mq_sub \\n[server.py : 510_558]->get_app_result \\n[server.py : 349_367]","sourceNodeId":"query_single_app_em14_mq_sub \\n[server.py : 510_558]","targetNodeId":"get_app_result \\n[server.py : 349_367]"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpQuerySingleAppMetrics/src/mcpQuerySingleAppMetrics/server.py"},"region":{"startLine":350,"startColumn":18,"endLine":350,"endColumn":50,"snippet":{}}}},"id":"get_app_result \\n[server.py : 349_367]->query \\n[server.py : 335_346]","sourceNodeId":"get_app_result \\n[server.py : 349_367]","targetNodeId":"query \\n[server.py : 335_346]"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpQuerySingleAppMetrics/src/mcpQuerySingleAppMetrics/server.py"},"region":{"startLine":336,"startColumn":12,"endLine":336,"endColumn":25,"snippet":{}}}},"id":"query \\n[server.py : 335_346]->maas_service.MaasService","sourceNodeId":"query \\n[server.py : 335_346]","targetNodeId":"maas_service.MaasService"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpQuerySingleAppMetrics/src/mcpQuerySingleAppMetrics/server.py"},"region":{"startLine":343,"startColumn":18,"endLine":343,"endColumn":56,"snippet":{}}}},"id":"query \\n[server.py : 335_346]->maas_service.MaasService().query_maas_by_sql_new_engine","sourceNodeId":"query \\n[server.py : 335_346]","targetNodeId":"maas_service.MaasService().query_maas_by_sql_new_engine"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpQuerySingleAppMetrics/src/mcpQuerySingleAppMetrics/server.py"},"region":{"startLine":345,"startColumn":15,"endLine":345,"endColumn":86,"snippet":{}}}},"id":"query \\n[server.py : 335_346]->/src/mcpQuerySingleAppMetrics/src/mcpQuerySingleAppMetrics/server.query.query_scope...Exception","sourceNodeId":"query \\n[server.py : 335_346]","targetNodeId":"/src/mcpQuerySingleAppMetrics/src/mcpQuerySingleAppMetrics/server.query.query_scope...Exception"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpQuerySingleAppMetrics/src/mcpQuerySingleAppMetrics/server.py"},"region":{"startLine":357,"startColumn":22,"endLine":357,"endColumn":48,"snippet":{}}}},"id":"get_app_result \\n[server.py : 349_367]->maas_service.MaasService().query_maas_by_sql_new_engine(sql).rows.replace","sourceNodeId":"get_app_result \\n[server.py : 349_367]","targetNodeId":"maas_service.MaasService().query_maas_by_sql_new_engine(sql).rows.replace"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpQuerySingleAppMetrics/src/mcpQuerySingleAppMetrics/server.py"},"region":{"startLine":359,"startColumn":12,"endLine":359,"endColumn":49,"snippet":{}}}},"id":"get_app_result \\n[server.py : 349_367]->query_gray \\n[server.py : 320_332]","sourceNodeId":"get_app_result \\n[server.py : 349_367]","targetNodeId":"query_gray \\n[server.py : 320_332]"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpQuerySingleAppMetrics/src/mcpQuerySingleAppMetrics/server.py"},"region":{"startLine":321,"startColumn":12,"endLine":321,"endColumn":25,"snippet":{}}}},"id":"query_gray \\n[server.py : 320_332]->maas_service.MaasService","sourceNodeId":"query_gray \\n[server.py : 320_332]","targetNodeId":"maas_service.MaasService"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpQuerySingleAppMetrics/src/mcpQuerySingleAppMetrics/server.py"},"region":{"startLine":323,"startColumn":18,"endLine":323,"endColumn":83,"snippet":{}}}},"id":"query_gray \\n[server.py : 320_332]->map.key.table.replace","sourceNodeId":"query_gray \\n[server.py : 320_332]","targetNodeId":"map.key.table.replace"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpQuerySingleAppMetrics/src/mcpQuerySingleAppMetrics/server.py"},"region":{"startLine":324,"startColumn":18,"endLine":329,"endColumn":9,"snippet":{}}}},"id":"query_gray \\n[server.py : 320_332]->maas_service.MaasService().query_maas_by_sql_new_engine","sourceNodeId":"query_gray \\n[server.py : 320_332]","targetNodeId":"maas_service.MaasService().query_maas_by_sql_new_engine"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpQuerySingleAppMetrics/src/mcpQuerySingleAppMetrics/server.py"},"region":{"startLine":331,"startColumn":15,"endLine":331,"endColumn":53,"snippet":{}}}},"id":"query_gray \\n[server.py : 320_332]->/src/mcpQuerySingleAppMetrics/src/mcpQuerySingleAppMetrics/server.query_gray.query_gray_scope...Exception","sourceNodeId":"query_gray \\n[server.py : 320_332]","targetNodeId":"/src/mcpQuerySingleAppMetrics/src/mcpQuerySingleAppMetrics/server.query_gray.query_gray_scope...Exception"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpQuerySingleAppMetrics/src/mcpQuerySingleAppMetrics/server.py"},"region":{"startLine":365,"startColumn":22,"endLine":365,"endColumn":48,"snippet":{}}}},"id":"get_app_result \\n[server.py : 349_367]->maas_service.MaasService().query_maas_by_sql_new_engine(","sourceNodeId":"get_app_result \\n[server.py : 349_367]","targetNodeId":"maas_service.MaasService().query_maas_by_sql_new_engine("},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpQuerySingleAppMetrics/src/mcpQuerySingleAppMetrics/server.py"},"region":{"startLine":543,"startColumn":18,"endLine":543,"endColumn":23,"snippet":{}}}},"id":"query_single_app_em14_mq_sub \\n[server.py : 510_558]->/src/mcpQuerySingleAppMetrics/src/mcpQuerySingleAppMetrics/server.query_single_app_em14_mq_sub.query_single_app_em14_mq_sub_scope..set","sourceNodeId":"query_single_app_em14_mq_sub \\n[server.py : 510_558]","targetNodeId":"/src/mcpQuerySingleAppMetrics/src/mcpQuerySingleAppMetrics/server.query_single_app_em14_mq_sub.query_single_app_em14_mq_sub_scope..set"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpQuerySingleAppMetrics/src/mcpQuerySingleAppMetrics/server.py"},"region":{"startLine":544,"startColumn":22,"endLine":544,"endColumn":50,"snippet":{}}}},"id":"query_single_app_em14_mq_sub \\n[server.py : 510_558]->app_to_result.values","sourceNodeId":"query_single_app_em14_mq_sub \\n[server.py : 510_558]","targetNodeId":"app_to_result.values"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpQuerySingleAppMetrics/src/mcpQuerySingleAppMetrics/server.py"},"region":{"startLine":545,"startColumn":13,"endLine":545,"endColumn":33,"snippet":{}}}},"id":"query_single_app_em14_mq_sub \\n[server.py : 510_558]->/src/mcpQuerySingleAppMetrics/src/mcpQuerySingleAppMetrics/server.query_single_app_em14_mq_sub.query_single_app_em14_mq_sub_scope..set().update","sourceNodeId":"query_single_app_em14_mq_sub \\n[server.py : 510_558]","targetNodeId":"/src/mcpQuerySingleAppMetrics/src/mcpQuerySingleAppMetrics/server.query_single_app_em14_mq_sub.query_single_app_em14_mq_sub_scope..set().update"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpQuerySingleAppMetrics/src/mcpQuerySingleAppMetrics/server.py"},"region":{"startLine":547,"startColumn":35,"endLine":547,"endColumn":96,"snippet":{}}}},"id":"query_single_app_em14_mq_sub \\n[server.py : 510_558]->query_topic_producer \\n[server.py : 387_410]","sourceNodeId":"query_single_app_em14_mq_sub \\n[server.py : 510_558]","targetNodeId":"query_topic_producer \\n[server.py : 387_410]"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpQuerySingleAppMetrics/src/mcpQuerySingleAppMetrics/server.py"},"region":{"startLine":388,"startColumn":12,"endLine":388,"endColumn":25,"snippet":{}}}},"id":"query_topic_producer \\n[server.py : 387_410]->maas_service.MaasService","sourceNodeId":"query_topic_producer \\n[server.py : 387_410]","targetNodeId":"maas_service.MaasService"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpQuerySingleAppMetrics/src/mcpQuerySingleAppMetrics/server.py"},"region":{"startLine":398,"startColumn":18,"endLine":398,"endColumn":56,"snippet":{}}}},"id":"query_topic_producer \\n[server.py : 387_410]->maas_service.MaasService().query_maas_by_sql_new_engine","sourceNodeId":"query_topic_producer \\n[server.py : 387_410]","targetNodeId":"maas_service.MaasService().query_maas_by_sql_new_engine"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpQuerySingleAppMetrics/src/mcpQuerySingleAppMetrics/server.py"},"region":{"startLine":400,"startColumn":15,"endLine":400,"endColumn":84,"snippet":{}}}},"id":"query_topic_producer \\n[server.py : 387_410]->/src/mcpQuerySingleAppMetrics/src/mcpQuerySingleAppMetrics/server.query_topic_producer.query_topic_producer_scope...Exception","sourceNodeId":"query_topic_producer \\n[server.py : 387_410]","targetNodeId":"/src/mcpQuerySingleAppMetrics/src/mcpQuerySingleAppMetrics/server.query_topic_producer.query_topic_producer_scope...Exception"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpQuerySingleAppMetrics/src/mcpQuerySingleAppMetrics/server.py"},"region":{"startLine":407,"startColumn":22,"endLine":407,"endColumn":48,"snippet":{}}}},"id":"query_topic_producer \\n[server.py : 387_410]->maas_service.MaasService().query_maas_by_sql_new_engine(sql).rows.replace","sourceNodeId":"query_topic_producer \\n[server.py : 387_410]","targetNodeId":"maas_service.MaasService().query_maas_by_sql_new_engine(sql).rows.replace"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpQuerySingleAppMetrics/src/mcpQuerySingleAppMetrics/server.py"},"region":{"startLine":548,"startColumn":34,"endLine":548,"endColumn":101,"snippet":{}}}},"id":"query_single_app_em14_mq_sub \\n[server.py : 510_558]->find_sub_topic_source_app \\n[server.py : 370_381]","sourceNodeId":"query_single_app_em14_mq_sub \\n[server.py : 510_558]","targetNodeId":"find_sub_topic_source_app \\n[server.py : 370_381]"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpQuerySingleAppMetrics/src/mcpQuerySingleAppMetrics/server.py"},"region":{"startLine":379,"startColumn":17,"endLine":379,"endColumn":66,"snippet":{}}}},"id":"find_sub_topic_source_app \\n[server.py : 370_381]->source_apps.extend","sourceNodeId":"find_sub_topic_source_app \\n[server.py : 370_381]","targetNodeId":"source_apps.extend"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpQuerySingleAppMetrics/src/mcpQuerySingleAppMetrics/server.py"},"region":{"startLine":380,"startColumn":33,"endLine":380,"endColumn":49,"snippet":{}}}},"id":"find_sub_topic_source_app \\n[server.py : 370_381]->/src/mcpQuerySingleAppMetrics/src/mcpQuerySingleAppMetrics/server.find_sub_topic_source_app.find_sub_topic_source_app_scope....set","sourceNodeId":"find_sub_topic_source_app \\n[server.py : 370_381]","targetNodeId":"/src/mcpQuerySingleAppMetrics/src/mcpQuerySingleAppMetrics/server.find_sub_topic_source_app.find_sub_topic_source_app_scope....set"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpQuerySingleAppMetrics/src/mcpQuerySingleAppMetrics/server.py"},"region":{"startLine":550,"startColumn":22,"endLine":550,"endColumn":49,"snippet":{}}}},"id":"query_single_app_em14_mq_sub \\n[server.py : 510_558]->app_2_source_app.values","sourceNodeId":"query_single_app_em14_mq_sub \\n[server.py : 510_558]","targetNodeId":"app_2_source_app.values"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpQuerySingleAppMetrics/src/mcpQuerySingleAppMetrics/server.py"},"region":{"startLine":553,"startColumn":28,"endLine":553,"endColumn":52,"snippet":{}}}},"id":"query_single_app_em14_mq_sub \\n[server.py : 510_558]->rmc_utils.get_app_info","sourceNodeId":"query_single_app_em14_mq_sub \\n[server.py : 510_558]","targetNodeId":"rmc_utils.get_app_info"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpQuerySingleAppMetrics/src/mcpQuerySingleAppMetrics/server.py"},"region":{"startLine":558,"startColumn":15,"endLine":558,"endColumn":27,"snippet":{}}}},"id":"query_single_app_em14_mq_sub \\n[server.py : 510_558]->/src/mcpQuerySingleAppMetrics/src/mcpQuerySingleAppMetrics/server.query_single_app_em14_mq_sub.query_single_app_em14_mq_sub_scope...Exception","sourceNodeId":"query_single_app_em14_mq_sub \\n[server.py : 510_558]","targetNodeId":"/src/mcpQuerySingleAppMetrics/src/mcpQuerySingleAppMetrics/server.query_single_app_em14_mq_sub.query_single_app_em14_mq_sub_scope...Exception"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpQuerySingleAppMetrics/src/mcpQuerySingleAppMetrics/server.py"},"region":{"startLine":742,"startColumn":19,"endLine":742,"endColumn":81,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 699_761]->query_single_app_service_detail_in_em14 \\n[server.py : 413_468]","sourceNodeId":"handle_call_tool \\n[server.py : 699_761]","targetNodeId":"query_single_app_service_detail_in_em14 \\n[server.py : 413_468]"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpQuerySingleAppMetrics/src/mcpQuerySingleAppMetrics/server.py"},"region":{"startLine":416,"startColumn":18,"endLine":416,"endColumn":48,"snippet":{}}}},"id":"query_single_app_service_detail_in_em14 \\n[server.py : 413_468]->get_start_end_time \\n[server.py : 499_507]","sourceNodeId":"query_single_app_service_detail_in_em14 \\n[server.py : 413_468]","targetNodeId":"get_start_end_time \\n[server.py : 499_507]"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpQuerySingleAppMetrics/src/mcpQuerySingleAppMetrics/server.py"},"region":{"startLine":417,"startColumn":12,"endLine":417,"endColumn":25,"snippet":{}}}},"id":"query_single_app_service_detail_in_em14 \\n[server.py : 413_468]->maas_service.MaasService","sourceNodeId":"query_single_app_service_detail_in_em14 \\n[server.py : 413_468]","targetNodeId":"maas_service.MaasService"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpQuerySingleAppMetrics/src/mcpQuerySingleAppMetrics/server.py"},"region":{"startLine":448,"startColumn":19,"endLine":448,"endColumn":62,"snippet":{}}}},"id":"query_single_app_service_detail_in_em14 \\n[server.py : 413_468]->maas_service.MaasService().query_maas_by_sql_new_engine","sourceNodeId":"query_single_app_service_detail_in_em14 \\n[server.py : 413_468]","targetNodeId":"maas_service.MaasService().query_maas_by_sql_new_engine"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpQuerySingleAppMetrics/src/mcpQuerySingleAppMetrics/server.py"},"region":{"startLine":451,"startColumn":16,"endLine":451,"endColumn":36,"snippet":{}}}},"id":"query_single_app_service_detail_in_em14 \\n[server.py : 413_468]->rmc_utils.get_app_info","sourceNodeId":"query_single_app_service_detail_in_em14 \\n[server.py : 413_468]","targetNodeId":"rmc_utils.get_app_info"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpQuerySingleAppMetrics/src/mcpQuerySingleAppMetrics/server.py"},"region":{"startLine":455,"startColumn":43,"endLine":455,"endColumn":86,"snippet":{}}}},"id":"query_single_app_service_detail_in_em14 \\n[server.py : 413_468]->query_single_app_em14_total_pod_raw \\n[server.py : 561_600]","sourceNodeId":"query_single_app_service_detail_in_em14 \\n[server.py : 413_468]","targetNodeId":"query_single_app_em14_total_pod_raw \\n[server.py : 561_600]"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpQuerySingleAppMetrics/src/mcpQuerySingleAppMetrics/server.py"},"region":{"startLine":441,"startColumn":73,"endLine":441,"endColumn":84,"snippet":{}}}},"id":"query_single_app_service_detail_in_em14 \\n[server.py : 413_468]->/src/mcpQuerySingleAppMetrics/src/mcpQuerySingleAppMetrics/server.query_single_app_service_detail_in_em14.query_single_app_service_detail_in_em14_scope...../src/mcpQuerySingleAppMetrics/src/mcpQuerySingleAppMetrics/server.query_single_app_service_detail_in_em14.query_single_app_service_detail_in_em14_scope.....query_single_app_sal_detail_in_em14 \\n[server.py : 471_497]","sourceNodeId":"handle_call_tool \\n[server.py : 699_761]","targetNodeId":"query_single_app_sal_detail_in_em14 \\n[server.py : 471_497]"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpQuerySingleAppMetrics/src/mcpQuerySingleAppMetrics/server.py"},"region":{"startLine":472,"startColumn":18,"endLine":472,"endColumn":48,"snippet":{}}}},"id":"query_single_app_sal_detail_in_em14 \\n[server.py : 471_497]->get_start_end_time \\n[server.py : 499_507]","sourceNodeId":"query_single_app_sal_detail_in_em14 \\n[server.py : 471_497]","targetNodeId":"get_start_end_time \\n[server.py : 499_507]"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpQuerySingleAppMetrics/src/mcpQuerySingleAppMetrics/server.py"},"region":{"startLine":473,"startColumn":12,"endLine":473,"endColumn":25,"snippet":{}}}},"id":"query_single_app_sal_detail_in_em14 \\n[server.py : 471_497]->maas_service.MaasService","sourceNodeId":"query_single_app_sal_detail_in_em14 \\n[server.py : 471_497]","targetNodeId":"maas_service.MaasService"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpQuerySingleAppMetrics/src/mcpQuerySingleAppMetrics/server.py"},"region":{"startLine":492,"startColumn":19,"endLine":492,"endColumn":62,"snippet":{}}}},"id":"query_single_app_sal_detail_in_em14 \\n[server.py : 471_497]->maas_service.MaasService().query_maas_by_sql_new_engine","sourceNodeId":"query_single_app_sal_detail_in_em14 \\n[server.py : 471_497]","targetNodeId":"maas_service.MaasService().query_maas_by_sql_new_engine"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpQuerySingleAppMetrics/src/mcpQuerySingleAppMetrics/server.py"},"region":{"startLine":761,"startColumn":11,"endLine":761,"endColumn":46,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 699_761]->/src/mcpQuerySingleAppMetrics/src/mcpQuerySingleAppMetrics/server.handle_call_tool.handle_call_tool_scope..ValueError","sourceNodeId":"handle_call_tool \\n[server.py : 699_761]","targetNodeId":"/src/mcpQuerySingleAppMetrics/src/mcpQuerySingleAppMetrics/server.handle_call_tool.handle_call_tool_scope..ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpRepoInfo/src/mcpRepoInfo/server.py"},"region":{"startLine":486,"startColumn":1,"endLine":601,"endColumn":11,"snippet":{}}}},"id":"<__entry_point__>->handle_call_tool \\n[server.py : 486_601]","sourceNodeId":"<__entry_point__>","targetNodeId":"handle_call_tool \\n[server.py : 486_601]"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpRepoInfo/src/mcpRepoInfo/server.py"},"region":{"startLine":493,"startColumn":80,"endLine":493,"endColumn":123,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 486_601]->syslib_from.json.dumps","sourceNodeId":"handle_call_tool \\n[server.py : 486_601]","targetNodeId":"syslib_from.json.dumps"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpRepoInfo/src/mcpRepoInfo/server.py"},"region":{"startLine":493,"startColumn":5,"endLine":493,"endColumn":125,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 486_601]->syslib_from.logging.getLogger(mcp-server).info","sourceNodeId":"handle_call_tool \\n[server.py : 486_601]","targetNodeId":"syslib_from.logging.getLogger(mcp-server).info"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpRepoInfo/src/mcpRepoInfo/server.py"},"region":{"startLine":495,"startColumn":15,"endLine":495,"endColumn":48,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 486_601]->/src/mcpRepoInfo/src/mcpRepoInfo/server.handle_call_tool.handle_call_tool_scope...ValueError","sourceNodeId":"handle_call_tool \\n[server.py : 486_601]","targetNodeId":"/src/mcpRepoInfo/src/mcpRepoInfo/server.handle_call_tool.handle_call_tool_scope...ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpRepoInfo/src/mcpRepoInfo/server.py"},"region":{"startLine":501,"startColumn":27,"endLine":501,"endColumn":109,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 486_601]->/src/mcpRepoInfo/src/mcpRepoInfo/server.handle_call_tool.handle_call_tool_scope....ValueError","sourceNodeId":"handle_call_tool \\n[server.py : 486_601]","targetNodeId":"/src/mcpRepoInfo/src/mcpRepoInfo/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpRepoInfo/src/mcpRepoInfo/server.py"},"region":{"startLine":586,"startColumn":23,"endLine":586,"endColumn":63,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 486_601]->/src/mcpRepoInfo/src/mcpRepoInfo/server.handle_call_tool.arguments.get","sourceNodeId":"handle_call_tool \\n[server.py : 486_601]","targetNodeId":"/src/mcpRepoInfo/src/mcpRepoInfo/server.handle_call_tool.arguments.get"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpRepoInfo/src/mcpRepoInfo/server.py"},"region":{"startLine":507,"startColumn":23,"endLine":512,"endColumn":18,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 486_601]->get_pull_requests \\n[server.py : 219_272]","sourceNodeId":"handle_call_tool \\n[server.py : 486_601]","targetNodeId":"get_pull_requests \\n[server.py : 219_272]"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpRepoInfo/src/mcpRepoInfo/server.py"},"region":{"startLine":262,"startColumn":13,"endLine":262,"endColumn":111,"snippet":{}}}},"id":"get_pull_requests \\n[server.py : 219_272]->syslib_from.logging.getLogger(mcp-server).info","sourceNodeId":"get_pull_requests \\n[server.py : 219_272]","targetNodeId":"syslib_from.logging.getLogger(mcp-server).info"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpRepoInfo/src/mcpRepoInfo/server.py"},"region":{"startLine":231,"startColumn":20,"endLine":239,"endColumn":14,"snippet":{}}}},"id":"get_pull_requests \\n[server.py : 219_272]->/src/mcpRepoInfo/src/mcpRepoInfo/server.get_pull_requests.get_pull_requests_scope..dict","sourceNodeId":"get_pull_requests \\n[server.py : 219_272]","targetNodeId":"/src/mcpRepoInfo/src/mcpRepoInfo/server.get_pull_requests.get_pull_requests_scope..dict"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpRepoInfo/src/mcpRepoInfo/server.py"},"region":{"startLine":230,"startColumn":39,"endLine":240,"endColumn":10,"snippet":{}}}},"id":"get_pull_requests \\n[server.py : 219_272]->mcp_common.remote.codeinsight.code_insight_api.mcp_server_backend_api","sourceNodeId":"get_pull_requests \\n[server.py : 219_272]","targetNodeId":"mcp_common.remote.codeinsight.code_insight_api.mcp_server_backend_api"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpRepoInfo/src/mcpRepoInfo/server.py"},"region":{"startLine":265,"startColumn":35,"endLine":265,"endColumn":80,"snippet":{}}}},"id":"get_pull_requests \\n[server.py : 219_272]->syslib_from.json.dumps","sourceNodeId":"get_pull_requests \\n[server.py : 219_272]","targetNodeId":"syslib_from.json.dumps"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpRepoInfo/src/mcpRepoInfo/server.py"},"region":{"startLine":261,"startColumn":23,"endLine":261,"endColumn":63,"snippet":{}}}},"id":"get_pull_requests \\n[server.py : 219_272]->mcp_common.remote.codeinsight.code_insight_api.mcp_server_backend_api(var params:any=dict(var name:any=Consts.GET_PULL_REQUESTS.name, var arguments:any=dict(var appName:any=app_name, var limit:any=lim...","sourceNodeId":"get_pull_requests \\n[server.py : 219_272]","targetNodeId":"mcp_common.remote.codeinsight.code_insight_api.mcp_server_backend_api(var params:any=dict(var name:any=Consts.GET_PULL_REQUESTS.name, var arguments:any=dict(var appName:any=app_name, var limit:any=lim..."},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpRepoInfo/src/mcpRepoInfo/server.py"},"region":{"startLine":249,"startColumn":34,"endLine":249,"endColumn":52,"snippet":{}}}},"id":"get_pull_requests \\n[server.py : 219_272]->/src/mcpRepoInfo/src/mcpRepoInfo/server.get_pull_requests.get_pull_requests_scope.....enumerate","sourceNodeId":"get_pull_requests \\n[server.py : 219_272]","targetNodeId":"/src/mcpRepoInfo/src/mcpRepoInfo/server.get_pull_requests.get_pull_requests_scope.....enumerate"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpRepoInfo/src/mcpRepoInfo/server.py"},"region":{"startLine":257,"startColumn":39,"endLine":257,"endColumn":66,"snippet":{}}}},"id":"get_pull_requests \\n[server.py : 219_272]->/src/mcpRepoInfo/src/mcpRepoInfo/server.get_pull_requests.get_pull_requests_scope.....enumerate(pr_list).get","sourceNodeId":"get_pull_requests \\n[server.py : 219_272]","targetNodeId":"/src/mcpRepoInfo/src/mcpRepoInfo/server.get_pull_requests.get_pull_requests_scope.....enumerate(pr_list).get"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpRepoInfo/src/mcpRepoInfo/server.py"},"region":{"startLine":250,"startColumn":34,"endLine":258,"endColumn":22,"snippet":{}}}},"id":"get_pull_requests \\n[server.py : 219_272]->mcp_common.utils.consts.PR_PATTERN.format","sourceNodeId":"get_pull_requests \\n[server.py : 219_272]","targetNodeId":"mcp_common.utils.consts.PR_PATTERN.format"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpRepoInfo/src/mcpRepoInfo/server.py"},"region":{"startLine":264,"startColumn":13,"endLine":265,"endColumn":82,"snippet":{}}}},"id":"get_pull_requests \\n[server.py : 219_272]->syslib_from.logging.getLogger(mcp-server).warning","sourceNodeId":"get_pull_requests \\n[server.py : 219_272]","targetNodeId":"syslib_from.logging.getLogger(mcp-server).warning"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpRepoInfo/src/mcpRepoInfo/server.py"},"region":{"startLine":268,"startColumn":9,"endLine":268,"endColumn":112,"snippet":{}}}},"id":"get_pull_requests \\n[server.py : 219_272]->syslib_from.logging.getLogger(mcp-server).exception","sourceNodeId":"get_pull_requests \\n[server.py : 219_272]","targetNodeId":"syslib_from.logging.getLogger(mcp-server).exception"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpRepoInfo/src/mcpRepoInfo/server.py"},"region":{"startLine":598,"startColumn":17,"endLine":601,"endColumn":10,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 486_601]->syslib_from.mcp/types.TextContent","sourceNodeId":"handle_call_tool \\n[server.py : 486_601]","targetNodeId":"syslib_from.mcp/types.TextContent"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpRepoInfo/src/mcpRepoInfo/server.py"},"region":{"startLine":519,"startColumn":27,"endLine":519,"endColumn":109,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 486_601]->/src/mcpRepoInfo/src/mcpRepoInfo/server.handle_call_tool.handle_call_tool_scope....ValueError","sourceNodeId":"handle_call_tool \\n[server.py : 486_601]","targetNodeId":"/src/mcpRepoInfo/src/mcpRepoInfo/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpRepoInfo/src/mcpRepoInfo/server.py"},"region":{"startLine":523,"startColumn":31,"endLine":523,"endColumn":74,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 486_601]->/src/mcpRepoInfo/src/mcpRepoInfo/server.handle_call_tool.handle_call_tool_scope......ValueErro...","sourceNodeId":"handle_call_tool \\n[server.py : 486_601]","targetNodeId":"/src/mcpRepoInfo/src/mcpRepoInfo/server.handle_call_tool.handle_call_tool_scope......ValueErro..."},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpRepoInfo/src/mcpRepoInfo/server.py"},"region":{"startLine":529,"startColumn":23,"endLine":534,"endColumn":18,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 486_601]->get_commit_list \\n[server.py : 275_327]","sourceNodeId":"handle_call_tool \\n[server.py : 486_601]","targetNodeId":"get_commit_list \\n[server.py : 275_327]"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpRepoInfo/src/mcpRepoInfo/server.py"},"region":{"startLine":315,"startColumn":17,"endLine":315,"endColumn":113,"snippet":{}}}},"id":"get_commit_list \\n[server.py : 275_327]->syslib_from.logging.getLogger(mcp-server).info","sourceNodeId":"get_commit_list \\n[server.py : 275_327]","targetNodeId":"syslib_from.logging.getLogger(mcp-server).info"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpRepoInfo/src/mcpRepoInfo/server.py"},"region":{"startLine":288,"startColumn":24,"endLine":296,"endColumn":18,"snippet":{}}}},"id":"get_commit_list \\n[server.py : 275_327]->/src/mcpRepoInfo/src/mcpRepoInfo/server.get_commit_list.get_commit_list_scope...dict","sourceNodeId":"get_commit_list \\n[server.py : 275_327]","targetNodeId":"/src/mcpRepoInfo/src/mcpRepoInfo/server.get_commit_list.get_commit_list_scope...dict"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpRepoInfo/src/mcpRepoInfo/server.py"},"region":{"startLine":287,"startColumn":43,"endLine":297,"endColumn":14,"snippet":{}}}},"id":"get_commit_list \\n[server.py : 275_327]->mcp_common.remote.codeinsight.code_insight_api.mcp_server_backend_api","sourceNodeId":"get_commit_list \\n[server.py : 275_327]","targetNodeId":"mcp_common.remote.codeinsight.code_insight_api.mcp_server_backend_api"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpRepoInfo/src/mcpRepoInfo/server.py"},"region":{"startLine":318,"startColumn":39,"endLine":318,"endColumn":84,"snippet":{}}}},"id":"get_commit_list \\n[server.py : 275_327]->syslib_from.json.dumps","sourceNodeId":"get_commit_list \\n[server.py : 275_327]","targetNodeId":"syslib_from.json.dumps"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpRepoInfo/src/mcpRepoInfo/server.py"},"region":{"startLine":314,"startColumn":27,"endLine":314,"endColumn":67,"snippet":{}}}},"id":"get_commit_list \\n[server.py : 275_327]->mcp_common.remote.codeinsight.code_insight_api.mcp_server_backend_api(var params:any=dict(var name:any=Consts.GET_COMMIT_LIST.name, var arguments:any=dict(var appName:any=app_name, var type:any=query_...","sourceNodeId":"get_commit_list \\n[server.py : 275_327]","targetNodeId":"mcp_common.remote.codeinsight.code_insight_api.mcp_server_backend_api(var params:any=dict(var name:any=Consts.GET_COMMIT_LIST.name, var arguments:any=dict(var appName:any=app_name, var type:any=query_..."},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpRepoInfo/src/mcpRepoInfo/server.py"},"region":{"startLine":305,"startColumn":42,"endLine":305,"endColumn":64,"snippet":{}}}},"id":"get_commit_list \\n[server.py : 275_327]->/src/mcpRepoInfo/src/mcpRepoInfo/server.get_commit_list.get_commit_list_scope......enumerate","sourceNodeId":"get_commit_list \\n[server.py : 275_327]","targetNodeId":"/src/mcpRepoInfo/src/mcpRepoInfo/server.get_commit_list.get_commit_list_scope......enumerate"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpRepoInfo/src/mcpRepoInfo/server.py"},"region":{"startLine":310,"startColumn":40,"endLine":310,"endColumn":63,"snippet":{}}}},"id":"get_commit_list \\n[server.py : 275_327]->/src/mcpRepoInfo/src/mcpRepoInfo/server.get_commit_list.get_commit_list_scope......enumerate(co...","sourceNodeId":"get_commit_list \\n[server.py : 275_327]","targetNodeId":"/src/mcpRepoInfo/src/mcpRepoInfo/server.get_commit_list.get_commit_list_scope......enumerate(co..."},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpRepoInfo/src/mcpRepoInfo/server.py"},"region":{"startLine":306,"startColumn":39,"endLine":311,"endColumn":26,"snippet":{}}}},"id":"get_commit_list \\n[server.py : 275_327]->mcp_common.utils.consts.COMMIT_PATTERN.format","sourceNodeId":"get_commit_list \\n[server.py : 275_327]","targetNodeId":"mcp_common.utils.consts.COMMIT_PATTERN.format"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpRepoInfo/src/mcpRepoInfo/server.py"},"region":{"startLine":317,"startColumn":17,"endLine":318,"endColumn":86,"snippet":{}}}},"id":"get_commit_list \\n[server.py : 275_327]->syslib_from.logging.getLogger(mcp-server).warning","sourceNodeId":"get_commit_list \\n[server.py : 275_327]","targetNodeId":"syslib_from.logging.getLogger(mcp-server).warning"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpRepoInfo/src/mcpRepoInfo/server.py"},"region":{"startLine":321,"startColumn":13,"endLine":321,"endColumn":114,"snippet":{}}}},"id":"get_commit_list \\n[server.py : 275_327]->syslib_from.logging.getLogger(mcp-server).exception","sourceNodeId":"get_commit_list \\n[server.py : 275_327]","targetNodeId":"syslib_from.logging.getLogger(mcp-server).exception"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpRepoInfo/src/mcpRepoInfo/server.py"},"region":{"startLine":541,"startColumn":27,"endLine":541,"endColumn":109,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 486_601]->/src/mcpRepoInfo/src/mcpRepoInfo/server.handle_call_tool.handle_call_tool_scope....ValueError","sourceNodeId":"handle_call_tool \\n[server.py : 486_601]","targetNodeId":"/src/mcpRepoInfo/src/mcpRepoInfo/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpRepoInfo/src/mcpRepoInfo/server.py"},"region":{"startLine":544,"startColumn":27,"endLine":544,"endColumn":83,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 486_601]->/src/mcpRepoInfo/src/mcpRepoInfo/server.handle_call_tool.handle_call_tool_scope....ValueError","sourceNodeId":"handle_call_tool \\n[server.py : 486_601]","targetNodeId":"/src/mcpRepoInfo/src/mcpRepoInfo/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpRepoInfo/src/mcpRepoInfo/server.py"},"region":{"startLine":549,"startColumn":23,"endLine":553,"endColumn":18,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 486_601]->get_commit_info \\n[server.py : 330_408]","sourceNodeId":"handle_call_tool \\n[server.py : 486_601]","targetNodeId":"get_commit_info \\n[server.py : 330_408]"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpRepoInfo/src/mcpRepoInfo/server.py"},"region":{"startLine":401,"startColumn":9,"endLine":401,"endColumn":105,"snippet":{}}}},"id":"get_commit_info \\n[server.py : 330_408]->syslib_from.logging.getLogger(mcp-server).info","sourceNodeId":"get_commit_info \\n[server.py : 330_408]","targetNodeId":"syslib_from.logging.getLogger(mcp-server).info"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpRepoInfo/src/mcpRepoInfo/server.py"},"region":{"startLine":336,"startColumn":20,"endLine":343,"endColumn":14,"snippet":{}}}},"id":"get_commit_info \\n[server.py : 330_408]->/src/mcpRepoInfo/src/mcpRepoInfo/server.get_commit_info.get_commit_info_scope..dict","sourceNodeId":"get_commit_info \\n[server.py : 330_408]","targetNodeId":"/src/mcpRepoInfo/src/mcpRepoInfo/server.get_commit_info.get_commit_info_scope..dict"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpRepoInfo/src/mcpRepoInfo/server.py"},"region":{"startLine":335,"startColumn":39,"endLine":344,"endColumn":10,"snippet":{}}}},"id":"get_commit_info \\n[server.py : 330_408]->mcp_common.remote.codeinsight.code_insight_api.mcp_server_backend_api","sourceNodeId":"get_commit_info \\n[server.py : 330_408]","targetNodeId":"mcp_common.remote.codeinsight.code_insight_api.mcp_server_backend_api"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpRepoInfo/src/mcpRepoInfo/server.py"},"region":{"startLine":355,"startColumn":35,"endLine":355,"endColumn":80,"snippet":{}}}},"id":"get_commit_info \\n[server.py : 330_408]->syslib_from.json.dumps","sourceNodeId":"get_commit_info \\n[server.py : 330_408]","targetNodeId":"syslib_from.json.dumps"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpRepoInfo/src/mcpRepoInfo/server.py"},"region":{"startLine":370,"startColumn":24,"endLine":370,"endColumn":51,"snippet":{}}}},"id":"get_commit_info \\n[server.py : 330_408]->mcp_common.remote.codeinsight.code_insight_api.mcp_server_backend_api(var params:any=dict(var name:any=Consts.GET_COMMIT_INFO.name, var arguments:any=dict(var appName:any=app_name, var commitId:any=co...","sourceNodeId":"get_commit_info \\n[server.py : 330_408]","targetNodeId":"mcp_common.remote.codeinsight.code_insight_api.mcp_server_backend_api(var params:any=dict(var name:any=Consts.GET_COMMIT_INFO.name, var arguments:any=dict(var appName:any=app_name, var commitId:any=co..."},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpRepoInfo/src/mcpRepoInfo/server.py"},"region":{"startLine":373,"startColumn":13,"endLine":373,"endColumn":106,"snippet":{}}}},"id":"get_commit_info \\n[server.py : 330_408]->syslib_from.logging.getLogger(mcp-server).warning","sourceNodeId":"get_commit_info \\n[server.py : 330_408]","targetNodeId":"syslib_from.logging.getLogger(mcp-server).warning"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpRepoInfo/src/mcpRepoInfo/server.py"},"region":{"startLine":362,"startColumn":23,"endLine":367,"endColumn":10,"snippet":{}}}},"id":"get_commit_info \\n[server.py : 330_408]->mcp_common.utils.consts.COMMIT_PATTERN.format","sourceNodeId":"get_commit_info \\n[server.py : 330_408]","targetNodeId":"mcp_common.utils.consts.COMMIT_PATTERN.format"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpRepoInfo/src/mcpRepoInfo/server.py"},"region":{"startLine":377,"startColumn":28,"endLine":377,"endColumn":51,"snippet":{}}}},"id":"get_commit_info \\n[server.py : 330_408]->/src/mcpRepoInfo/src/mcpRepoInfo/server.get_commit_info.get_commit_info_scope...enumerate","sourceNodeId":"get_commit_info \\n[server.py : 330_408]","targetNodeId":"/src/mcpRepoInfo/src/mcpRepoInfo/server.get_commit_info.get_commit_info_scope...enumerate"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpRepoInfo/src/mcpRepoInfo/server.py"},"region":{"startLine":378,"startColumn":27,"endLine":378,"endColumn":70,"snippet":{}}}},"id":"get_commit_info \\n[server.py : 330_408]->mcp_common.utils.repo_util.parse_diff_change_type","sourceNodeId":"get_commit_info \\n[server.py : 330_408]","targetNodeId":"mcp_common.utils.repo_util.parse_diff_change_type"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpRepoInfo/src/mcpRepoInfo/server.py"},"region":{"startLine":399,"startColumn":30,"endLine":399,"endColumn":50,"snippet":{}}}},"id":"get_commit_info \\n[server.py : 330_408]->/src/mcpRepoInfo/src/mcpRepoInfo/server.get_commit_info.get_commit_info_scope...enumerate(commit_diffs).get","sourceNodeId":"get_commit_info \\n[server.py : 330_408]","targetNodeId":"/src/mcpRepoInfo/src/mcpRepoInfo/server.get_commit_info.get_commit_info_scope...enumerate(commit_diffs).get"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpRepoInfo/src/mcpRepoInfo/server.py"},"region":{"startLine":396,"startColumn":28,"endLine":400,"endColumn":22,"snippet":{}}}},"id":"get_commit_info \\n[server.py : 330_408]->mcp_common.utils.consts.DIFF_PATTERN.format","sourceNodeId":"get_commit_info \\n[server.py : 330_408]","targetNodeId":"mcp_common.utils.consts.DIFF_PATTERN.format"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpRepoInfo/src/mcpRepoInfo/server.py"},"region":{"startLine":404,"startColumn":9,"endLine":404,"endColumn":110,"snippet":{}}}},"id":"get_commit_info \\n[server.py : 330_408]->syslib_from.logging.getLogger(mcp-server).exception","sourceNodeId":"get_commit_info \\n[server.py : 330_408]","targetNodeId":"syslib_from.logging.getLogger(mcp-server).exception"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpRepoInfo/src/mcpRepoInfo/server.py"},"region":{"startLine":560,"startColumn":27,"endLine":560,"endColumn":82,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 486_601]->/src/mcpRepoInfo/src/mcpRepoInfo/server.handle_call_tool.handle_call_tool_scope....ValueError","sourceNodeId":"handle_call_tool \\n[server.py : 486_601]","targetNodeId":"/src/mcpRepoInfo/src/mcpRepoInfo/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpRepoInfo/src/mcpRepoInfo/server.py"},"region":{"startLine":563,"startColumn":23,"endLine":566,"endColumn":18,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 486_601]->get_repo_url \\n[server.py : 411_444]","sourceNodeId":"handle_call_tool \\n[server.py : 486_601]","targetNodeId":"get_repo_url \\n[server.py : 411_444]"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpRepoInfo/src/mcpRepoInfo/server.py"},"region":{"startLine":434,"startColumn":13,"endLine":434,"endColumn":106,"snippet":{}}}},"id":"get_repo_url \\n[server.py : 411_444]->syslib_from.logging.getLogger(mcp-server).info","sourceNodeId":"get_repo_url \\n[server.py : 411_444]","targetNodeId":"syslib_from.logging.getLogger(mcp-server).info"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpRepoInfo/src/mcpRepoInfo/server.py"},"region":{"startLine":417,"startColumn":20,"endLine":423,"endColumn":14,"snippet":{}}}},"id":"get_repo_url \\n[server.py : 411_444]->/src/mcpRepoInfo/src/mcpRepoInfo/server.get_repo_url.get_repo_url_scope..dict","sourceNodeId":"get_repo_url \\n[server.py : 411_444]","targetNodeId":"/src/mcpRepoInfo/src/mcpRepoInfo/server.get_repo_url.get_repo_url_scope..dict"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpRepoInfo/src/mcpRepoInfo/server.py"},"region":{"startLine":416,"startColumn":39,"endLine":424,"endColumn":10,"snippet":{}}}},"id":"get_repo_url \\n[server.py : 411_444]->mcp_common.remote.codeinsight.code_insight_api.mcp_server_backend_api","sourceNodeId":"get_repo_url \\n[server.py : 411_444]","targetNodeId":"mcp_common.remote.codeinsight.code_insight_api.mcp_server_backend_api"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpRepoInfo/src/mcpRepoInfo/server.py"},"region":{"startLine":437,"startColumn":35,"endLine":437,"endColumn":80,"snippet":{}}}},"id":"get_repo_url \\n[server.py : 411_444]->syslib_from.json.dumps","sourceNodeId":"get_repo_url \\n[server.py : 411_444]","targetNodeId":"syslib_from.json.dumps"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpRepoInfo/src/mcpRepoInfo/server.py"},"region":{"startLine":433,"startColumn":23,"endLine":433,"endColumn":63,"snippet":{}}}},"id":"get_repo_url \\n[server.py : 411_444]->mcp_common.remote.codeinsight.code_insight_api.mcp_server_backend_api(var params:any=dict(var name:any=Consts.GET_REPO_URL.name, var arguments:any=dict(var appName:any=app_name, var antCodeToken:any=a...","sourceNodeId":"get_repo_url \\n[server.py : 411_444]","targetNodeId":"mcp_common.remote.codeinsight.code_insight_api.mcp_server_backend_api(var params:any=dict(var name:any=Consts.GET_REPO_URL.name, var arguments:any=dict(var appName:any=app_name, var antCodeToken:any=a..."},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpRepoInfo/src/mcpRepoInfo/server.py"},"region":{"startLine":436,"startColumn":13,"endLine":437,"endColumn":82,"snippet":{}}}},"id":"get_repo_url \\n[server.py : 411_444]->syslib_from.logging.getLogger(mcp-server).warning","sourceNodeId":"get_repo_url \\n[server.py : 411_444]","targetNodeId":"syslib_from.logging.getLogger(mcp-server).warning"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpRepoInfo/src/mcpRepoInfo/server.py"},"region":{"startLine":440,"startColumn":9,"endLine":440,"endColumn":107,"snippet":{}}}},"id":"get_repo_url \\n[server.py : 411_444]->syslib_from.logging.getLogger(mcp-server).exception","sourceNodeId":"get_repo_url \\n[server.py : 411_444]","targetNodeId":"syslib_from.logging.getLogger(mcp-server).exception"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpRepoInfo/src/mcpRepoInfo/server.py"},"region":{"startLine":573,"startColumn":27,"endLine":573,"endColumn":82,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 486_601]->/src/mcpRepoInfo/src/mcpRepoInfo/server.handle_call_tool.handle_call_tool_scope....ValueError","sourceNodeId":"handle_call_tool \\n[server.py : 486_601]","targetNodeId":"/src/mcpRepoInfo/src/mcpRepoInfo/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpRepoInfo/src/mcpRepoInfo/server.py"},"region":{"startLine":576,"startColumn":23,"endLine":576,"endColumn":60,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 486_601]->get_app_list \\n[server.py : 447_482]","sourceNodeId":"handle_call_tool \\n[server.py : 486_601]","targetNodeId":"get_app_list \\n[server.py : 447_482]"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpRepoInfo/src/mcpRepoInfo/server.py"},"region":{"startLine":472,"startColumn":13,"endLine":472,"endColumn":113,"snippet":{}}}},"id":"get_app_list \\n[server.py : 447_482]->syslib_from.logging.getLogger(mcp-server).info","sourceNodeId":"get_app_list \\n[server.py : 447_482]","targetNodeId":"syslib_from.logging.getLogger(mcp-server).info"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpRepoInfo/src/mcpRepoInfo/server.py"},"region":{"startLine":453,"startColumn":20,"endLine":458,"endColumn":14,"snippet":{}}}},"id":"get_app_list \\n[server.py : 447_482]->/src/mcpRepoInfo/src/mcpRepoInfo/server.get_app_list.get_app_list_scope..dict","sourceNodeId":"get_app_list \\n[server.py : 447_482]","targetNodeId":"/src/mcpRepoInfo/src/mcpRepoInfo/server.get_app_list.get_app_list_scope..dict"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpRepoInfo/src/mcpRepoInfo/server.py"},"region":{"startLine":452,"startColumn":39,"endLine":459,"endColumn":10,"snippet":{}}}},"id":"get_app_list \\n[server.py : 447_482]->mcp_common.remote.codeinsight.code_insight_api.mcp_server_backend_api","sourceNodeId":"get_app_list \\n[server.py : 447_482]","targetNodeId":"mcp_common.remote.codeinsight.code_insight_api.mcp_server_backend_api"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpRepoInfo/src/mcpRepoInfo/server.py"},"region":{"startLine":475,"startColumn":35,"endLine":475,"endColumn":80,"snippet":{}}}},"id":"get_app_list \\n[server.py : 447_482]->syslib_from.json.dumps","sourceNodeId":"get_app_list \\n[server.py : 447_482]","targetNodeId":"syslib_from.json.dumps"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpRepoInfo/src/mcpRepoInfo/server.py"},"region":{"startLine":471,"startColumn":23,"endLine":471,"endColumn":63,"snippet":{}}}},"id":"get_app_list \\n[server.py : 447_482]->mcp_common.remote.codeinsight.code_insight_api.mcp_server_backend_api(var params:any=dict(var name:any=Consts.GET_DEPLOYMENT_UNIT.name, var arguments:any=dict(var repoUrl:any=repo_url))).get","sourceNodeId":"get_app_list \\n[server.py : 447_482]","targetNodeId":"mcp_common.remote.codeinsight.code_insight_api.mcp_server_backend_api(var params:any=dict(var name:any=Consts.GET_DEPLOYMENT_UNIT.name, var arguments:any=dict(var repoUrl:any=repo_url))).get"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpRepoInfo/src/mcpRepoInfo/server.py"},"region":{"startLine":468,"startColumn":39,"endLine":468,"endColumn":59,"snippet":{}}}},"id":"get_app_list \\n[server.py : 447_482]->/src/mcpRepoInfo/src/mcpRepoInfo/server.get_app_list.get_app_list_scope......enumerate","sourceNodeId":"get_app_list \\n[server.py : 447_482]","targetNodeId":"/src/mcpRepoInfo/src/mcpRepoInfo/server.get_app_list.get_app_list_scope......enumerate"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpRepoInfo/src/mcpRepoInfo/server.py"},"region":{"startLine":474,"startColumn":13,"endLine":475,"endColumn":82,"snippet":{}}}},"id":"get_app_list \\n[server.py : 447_482]->syslib_from.logging.getLogger(mcp-server).warning","sourceNodeId":"get_app_list \\n[server.py : 447_482]","targetNodeId":"syslib_from.logging.getLogger(mcp-server).warning"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpRepoInfo/src/mcpRepoInfo/server.py"},"region":{"startLine":478,"startColumn":9,"endLine":478,"endColumn":114,"snippet":{}}}},"id":"get_app_list \\n[server.py : 447_482]->syslib_from.logging.getLogger(mcp-server).exception","sourceNodeId":"get_app_list \\n[server.py : 447_482]","targetNodeId":"syslib_from.logging.getLogger(mcp-server).exception"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpRepoInfo/src/mcpRepoInfo/server.py"},"region":{"startLine":583,"startColumn":27,"endLine":583,"endColumn":111,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 486_601]->/src/mcpRepoInfo/src/mcpRepoInfo/server.handle_call_tool.handle_call_tool_scope....ValueError","sourceNodeId":"handle_call_tool \\n[server.py : 486_601]","targetNodeId":"/src/mcpRepoInfo/src/mcpRepoInfo/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpRepoInfo/src/mcpRepoInfo/server.py"},"region":{"startLine":594,"startColumn":23,"endLine":594,"endColumn":58,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 486_601]->/src/mcpRepoInfo/src/mcpRepoInfo/server.handle_call_tool.handle_call_tool_scope...ValueError","sourceNodeId":"handle_call_tool \\n[server.py : 486_601]","targetNodeId":"/src/mcpRepoInfo/src/mcpRepoInfo/server.handle_call_tool.handle_call_tool_scope...ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpRepoInfo/src/mcpRepoInfo/server.py"},"region":{"startLine":597,"startColumn":9,"endLine":597,"endColumn":41,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 486_601]->syslib_from.logging.getLogger(mcp-server).exception","sourceNodeId":"handle_call_tool \\n[server.py : 486_601]","targetNodeId":"syslib_from.logging.getLogger(mcp-server).exception"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpReportNotify/src/mcpReportNotify/server.py"},"region":{"startLine":46,"startColumn":1,"endLine":64,"endColumn":54,"snippet":{}}}},"id":"<__entry_point__>->handle_call_tool \\n[server.py : 46_64]","sourceNodeId":"<__entry_point__>","targetNodeId":"handle_call_tool \\n[server.py : 46_64]"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpReportNotify/src/mcpReportNotify/server.py"},"region":{"startLine":56,"startColumn":23,"endLine":56,"endColumn":53,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 46_64]->/src/mcpReportNotify/src/mcpReportNotify/server.handle_call_tool.handle_call_tool_scope....ValueError","sourceNodeId":"handle_call_tool \\n[server.py : 46_64]","targetNodeId":"/src/mcpReportNotify/src/mcpReportNotify/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpReportNotify/src/mcpReportNotify/server.py"},"region":{"startLine":58,"startColumn":23,"endLine":58,"endColumn":65,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 46_64]->/src/mcpReportNotify/src/mcpReportNotify/server.handle_call_tool.handle_call_tool_scope....ValueError","sourceNodeId":"handle_call_tool \\n[server.py : 46_64]","targetNodeId":"/src/mcpReportNotify/src/mcpReportNotify/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpReportNotify/src/mcpReportNotify/server.py"},"region":{"startLine":61,"startColumn":55,"endLine":61,"endColumn":81,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 46_64]->/src/mcpReportNotify/src/mcpReportNotify/server.handle_call_tool.arguments.get","sourceNodeId":"handle_call_tool \\n[server.py : 46_64]","targetNodeId":"/src/mcpReportNotify/src/mcpReportNotify/server.handle_call_tool.arguments.get"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpReportNotify/src/mcpReportNotify/server.py"},"region":{"startLine":59,"startColumn":22,"endLine":61,"endColumn":82,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 46_64]->/src/mcpReportNotify/src/mcpReportNotify/server.handle_call_tool.handle_call_tool_scope...ding_notify_text","sourceNodeId":"handle_call_tool \\n[server.py : 46_64]","targetNodeId":"/src/mcpReportNotify/src/mcpReportNotify/server.handle_call_tool.handle_call_tool_scope...ding_notify_text"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpReportNotify/src/mcpReportNotify/server.py"},"region":{"startLine":62,"startColumn":21,"endLine":62,"endColumn":64,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 46_64]->syslib_from.mcp/types.TextContent","sourceNodeId":"handle_call_tool \\n[server.py : 46_64]","targetNodeId":"syslib_from.mcp/types.TextContent"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpReportNotify/src/mcpReportNotify/server.py"},"region":{"startLine":64,"startColumn":19,"endLine":64,"endColumn":54,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 46_64]->/src/mcpReportNotify/src/mcpReportNotify/server.handle_call_tool.handle_call_tool_scope...ValueError","sourceNodeId":"handle_call_tool \\n[server.py : 46_64]","targetNodeId":"/src/mcpReportNotify/src/mcpReportNotify/server.handle_call_tool.handle_call_tool_scope...ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpRiskPunish/src/mcpRiskPunish/server.py"},"region":{"startLine":58,"startColumn":1,"endLine":91,"endColumn":54,"snippet":{}}}},"id":"<__entry_point__>->handle_call_tool \\n[server.py : 58_91]","sourceNodeId":"<__entry_point__>","targetNodeId":"handle_call_tool \\n[server.py : 58_91]"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpRiskPunish/src/mcpRiskPunish/server.py"},"region":{"startLine":68,"startColumn":23,"endLine":68,"endColumn":53,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 58_91]->/src/mcpRiskPunish/src/mcpRiskPunish/server.handle_call_tool.handle_call_tool_scope....ValueError","sourceNodeId":"handle_call_tool \\n[server.py : 58_91]","targetNodeId":"/src/mcpRiskPunish/src/mcpRiskPunish/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpRiskPunish/src/mcpRiskPunish/server.py"},"region":{"startLine":70,"startColumn":23,"endLine":70,"endColumn":61,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 58_91]->/src/mcpRiskPunish/src/mcpRiskPunish/server.handle_call_tool.handle_call_tool_scope....ValueError","sourceNodeId":"handle_call_tool \\n[server.py : 58_91]","targetNodeId":"/src/mcpRiskPunish/src/mcpRiskPunish/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpRiskPunish/src/mcpRiskPunish/server.py"},"region":{"startLine":72,"startColumn":23,"endLine":72,"endColumn":61,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 58_91]->/src/mcpRiskPunish/src/mcpRiskPunish/server.handle_call_tool.handle_call_tool_scope....ValueError","sourceNodeId":"handle_call_tool \\n[server.py : 58_91]","targetNodeId":"/src/mcpRiskPunish/src/mcpRiskPunish/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpRiskPunish/src/mcpRiskPunish/server.py"},"region":{"startLine":74,"startColumn":23,"endLine":74,"endColumn":61,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 58_91]->/src/mcpRiskPunish/src/mcpRiskPunish/server.handle_call_tool.handle_call_tool_scope....ValueError","sourceNodeId":"handle_call_tool \\n[server.py : 58_91]","targetNodeId":"/src/mcpRiskPunish/src/mcpRiskPunish/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpRiskPunish/src/mcpRiskPunish/server.py"},"region":{"startLine":76,"startColumn":23,"endLine":76,"endColumn":65,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 58_91]->/src/mcpRiskPunish/src/mcpRiskPunish/server.handle_call_tool.handle_call_tool_scope....ValueError","sourceNodeId":"handle_call_tool \\n[server.py : 58_91]","targetNodeId":"/src/mcpRiskPunish/src/mcpRiskPunish/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpRiskPunish/src/mcpRiskPunish/server.py"},"region":{"startLine":78,"startColumn":23,"endLine":78,"endColumn":70,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 58_91]->/src/mcpRiskPunish/src/mcpRiskPunish/server.handle_call_tool.handle_call_tool_scope....ValueError","sourceNodeId":"handle_call_tool \\n[server.py : 58_91]","targetNodeId":"/src/mcpRiskPunish/src/mcpRiskPunish/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpRiskPunish/src/mcpRiskPunish/server.py"},"region":{"startLine":80,"startColumn":23,"endLine":80,"endColumn":61,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 58_91]->/src/mcpRiskPunish/src/mcpRiskPunish/server.handle_call_tool.handle_call_tool_scope....ValueError","sourceNodeId":"handle_call_tool \\n[server.py : 58_91]","targetNodeId":"/src/mcpRiskPunish/src/mcpRiskPunish/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpRiskPunish/src/mcpRiskPunish/server.py"},"region":{"startLine":82,"startColumn":23,"endLine":82,"endColumn":63,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 58_91]->/src/mcpRiskPunish/src/mcpRiskPunish/server.handle_call_tool.handle_call_tool_scope....ValueError","sourceNodeId":"handle_call_tool \\n[server.py : 58_91]","targetNodeId":"/src/mcpRiskPunish/src/mcpRiskPunish/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpRiskPunish/src/mcpRiskPunish/server.py"},"region":{"startLine":88,"startColumn":55,"endLine":88,"endColumn":81,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 58_91]->/src/mcpRiskPunish/src/mcpRiskPunish/server.handle_call_tool.arguments.get","sourceNodeId":"handle_call_tool \\n[server.py : 58_91]","targetNodeId":"/src/mcpRiskPunish/src/mcpRiskPunish/server.handle_call_tool.arguments.get"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpRiskPunish/src/mcpRiskPunish/server.py"},"region":{"startLine":83,"startColumn":22,"endLine":88,"endColumn":82,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 58_91]->/src/mcpRiskPunish/src/mcpRiskPunish/server.handle_call_tool.handle_call_tool_scope...create_dima_link","sourceNodeId":"handle_call_tool \\n[server.py : 58_91]","targetNodeId":"/src/mcpRiskPunish/src/mcpRiskPunish/server.handle_call_tool.handle_call_tool_scope...create_dima_link"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpRiskPunish/src/mcpRiskPunish/server.py"},"region":{"startLine":89,"startColumn":21,"endLine":89,"endColumn":64,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 58_91]->syslib_from.mcp/types.TextContent","sourceNodeId":"handle_call_tool \\n[server.py : 58_91]","targetNodeId":"syslib_from.mcp/types.TextContent"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpRiskPunish/src/mcpRiskPunish/server.py"},"region":{"startLine":91,"startColumn":19,"endLine":91,"endColumn":54,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 58_91]->/src/mcpRiskPunish/src/mcpRiskPunish/server.handle_call_tool.handle_call_tool_scope...ValueError","sourceNodeId":"handle_call_tool \\n[server.py : 58_91]","targetNodeId":"/src/mcpRiskPunish/src/mcpRiskPunish/server.handle_call_tool.handle_call_tool_scope...ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpRopnTaskStatusAnalyse/src/mcpRopnTaskStatusAnalyse/server.py"},"region":{"startLine":132,"startColumn":1,"endLine":261,"endColumn":28,"snippet":{}}}},"id":"<__entry_point__>->handle_call_tool \\n[server.py : 132_261]","sourceNodeId":"<__entry_point__>","targetNodeId":"handle_call_tool \\n[server.py : 132_261]"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpRopnTaskStatusAnalyse/src/mcpRopnTaskStatusAnalyse/server.py"},"region":{"startLine":244,"startColumn":17,"endLine":244,"endColumn":92,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 132_261]->syslib_from.logging.getLogger(__name__).info","sourceNodeId":"handle_call_tool \\n[server.py : 132_261]","targetNodeId":"syslib_from.logging.getLogger(__name__).info"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpRopnTaskStatusAnalyse/src/mcpRopnTaskStatusAnalyse/server.py"},"region":{"startLine":144,"startColumn":76,"endLine":144,"endColumn":105,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 132_261]->/src/mcpRopnTaskStatusAnalyse/src/mcpRopnTaskStatusAnalyse/server.handle_call_tool.handle_call_tool_scope....str","sourceNodeId":"handle_call_tool \\n[server.py : 132_261]","targetNodeId":"/src/mcpRopnTaskStatusAnalyse/src/mcpRopnTaskStatusAnalyse/server.handle_call_tool.handle_call_tool_scope....str"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpRopnTaskStatusAnalyse/src/mcpRopnTaskStatusAnalyse/server.py"},"region":{"startLine":144,"startColumn":57,"endLine":144,"endColumn":66,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 132_261]->/src/mcpRopnTaskStatusAnalyse/src/mcpRopnTaskStatusAnalyse/server.handle_call_tool.handle_call_tool_scope....str(arguments.taskId_list).s...","sourceNodeId":"handle_call_tool \\n[server.py : 132_261]","targetNodeId":"/src/mcpRopnTaskStatusAnalyse/src/mcpRopnTaskStatusAnalyse/server.handle_call_tool.handle_call_tool_scope....str(arguments.taskId_list).s..."},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpRopnTaskStatusAnalyse/src/mcpRopnTaskStatusAnalyse/server.py"},"region":{"startLine":144,"startColumn":38,"endLine":144,"endColumn":118,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 132_261]->ropcn_utils.groupByTaskStatus","sourceNodeId":"handle_call_tool \\n[server.py : 132_261]","targetNodeId":"ropcn_utils.groupByTaskStatus"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpRopnTaskStatusAnalyse/src/mcpRopnTaskStatusAnalyse/server.py"},"region":{"startLine":243,"startColumn":31,"endLine":243,"endColumn":99,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 132_261]->syslib_from.json.dumps","sourceNodeId":"handle_call_tool \\n[server.py : 132_261]","targetNodeId":"syslib_from.json.dumps"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpRopnTaskStatusAnalyse/src/mcpRopnTaskStatusAnalyse/server.py"},"region":{"startLine":254,"startColumn":21,"endLine":257,"endColumn":22,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 132_261]->mcp.types.TextContent","sourceNodeId":"handle_call_tool \\n[server.py : 132_261]","targetNodeId":"mcp.types.TextContent"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpRopnTaskStatusAnalyse/src/mcpRopnTaskStatusAnalyse/server.py"},"region":{"startLine":156,"startColumn":58,"endLine":156,"endColumn":87,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 132_261]->/src/mcpRopnTaskStatusAnalyse/src/mcpRopnTaskStatusAnalyse/server.handle_call_tool.handle_call_tool_scope.....str","sourceNodeId":"handle_call_tool \\n[server.py : 132_261]","targetNodeId":"/src/mcpRopnTaskStatusAnalyse/src/mcpRopnTaskStatusAnalyse/server.handle_call_tool.handle_call_tool_scope.....str"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpRopnTaskStatusAnalyse/src/mcpRopnTaskStatusAnalyse/server.py"},"region":{"startLine":156,"startColumn":39,"endLine":156,"endColumn":48,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 132_261]->/src/mcpRopnTaskStatusAnalyse/src/mcpRopnTaskStatusAnalyse/server.handle_call_tool.handle_call_tool_scope.....str(arg...","sourceNodeId":"handle_call_tool \\n[server.py : 132_261]","targetNodeId":"/src/mcpRopnTaskStatusAnalyse/src/mcpRopnTaskStatusAnalyse/server.handle_call_tool.handle_call_tool_scope.....str(arg..."},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpRopnTaskStatusAnalyse/src/mcpRopnTaskStatusAnalyse/server.py"},"region":{"startLine":156,"startColumn":17,"endLine":156,"endColumn":100,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 132_261]->ropcn_utils.groupByTypeAndSource","sourceNodeId":"handle_call_tool \\n[server.py : 132_261]","targetNodeId":"ropcn_utils.groupByTypeAndSource"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpRopnTaskStatusAnalyse/src/mcpRopnTaskStatusAnalyse/server.py"},"region":{"startLine":169,"startColumn":47,"endLine":169,"endColumn":56,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 132_261]->/src/mcpRopnTaskStatusAnalyse/src/mcpRopnTaskStatusAnalyse/server.handle_call_tool.handle_call_tool_scope.........ropcn_utils.queryLatestOperateRecord","sourceNodeId":"handle_call_tool \\n[server.py : 132_261]","targetNodeId":"ropcn_utils.queryLatestOperateRecord"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpRopnTaskStatusAnalyse/src/mcpRopnTaskStatusAnalyse/server.py"},"region":{"startLine":261,"startColumn":9,"endLine":261,"endColumn":28,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 132_261]->syslib_from.logging.getLogger(__name__).exception","sourceNodeId":"handle_call_tool \\n[server.py : 132_261]","targetNodeId":"syslib_from.logging.getLogger(__name__).exception"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpRopnTaskStatusAnalyse/src/mcpRopnTaskStatusAnalyse/server.py"},"region":{"startLine":183,"startColumn":68,"endLine":183,"endColumn":92,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 132_261]->syslib_from.traceback.format_exc","sourceNodeId":"handle_call_tool \\n[server.py : 132_261]","targetNodeId":"syslib_from.traceback.format_exc"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpRopnTaskStatusAnalyse/src/mcpRopnTaskStatusAnalyse/server.py"},"region":{"startLine":194,"startColumn":17,"endLine":194,"endColumn":94,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 132_261]->/src/mcpRopnTaskStatusAnalyse/src/mcpRopnTaskStatusAnalyse/server.handle_call_tool.handle_call_tool_scope.........syslib_from.json.loads","sourceNodeId":"handle_call_tool \\n[server.py : 132_261]","targetNodeId":"syslib_from.json.loads"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpRopnTaskStatusAnalyse/src/mcpRopnTaskStatusAnalyse/server.py"},"region":{"startLine":194,"startColumn":21,"endLine":194,"endColumn":81,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 132_261]->datetime.datetime.strptime","sourceNodeId":"handle_call_tool \\n[server.py : 132_261]","targetNodeId":"datetime.datetime.strptime"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpRopnTaskStatusAnalyse/src/mcpRopnTaskStatusAnalyse/server.py"},"region":{"startLine":193,"startColumn":21,"endLine":193,"endColumn":95,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 132_261]->datetime.datetime.strptime(arguments.startTime, %Y-%m-%d %H:%M:%S).timestamp","sourceNodeId":"handle_call_tool \\n[server.py : 132_261]","targetNodeId":"datetime.datetime.strptime(arguments.startTime, %Y-%m-%d %H:%M:%S).timestamp"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpRopnTaskStatusAnalyse/src/mcpRopnTaskStatusAnalyse/server.py"},"region":{"startLine":194,"startColumn":21,"endLine":194,"endColumn":93,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 132_261]->datetime.datetime.strptime(arguments.endTime, %Y-%m-%d %H:%M:%S).timestamp","sourceNodeId":"handle_call_tool \\n[server.py : 132_261]","targetNodeId":"datetime.datetime.strptime(arguments.endTime, %Y-%m-%d %H:%M:%S).timestamp"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpRopnTaskStatusAnalyse/src/mcpRopnTaskStatusAnalyse/server.py"},"region":{"startLine":192,"startColumn":27,"endLine":195,"endColumn":25,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 132_261]->ropcn_utils.querySampleLogOpenInPontus","sourceNodeId":"handle_call_tool \\n[server.py : 132_261]","targetNodeId":"ropcn_utils.querySampleLogOpenInPontus"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpRopnTaskStatusAnalyse/src/mcpRopnTaskStatusAnalyse/server.py"},"region":{"startLine":243,"startColumn":54,"endLine":243,"endColumn":77,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 132_261]->/src/mcpRopnTaskStatusAnalyse/src/mcpRopnTaskStatusAnalyse/server.handle_call_tool.handle_call_tool_scope.........ropcn_utils.queryTaskScheduleStatist","sourceNodeId":"handle_call_tool \\n[server.py : 132_261]","targetNodeId":"ropcn_utils.queryTaskScheduleStatist"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpRopnTaskStatusAnalyse/src/mcpRopnTaskStatusAnalyse/server.py"},"region":{"startLine":220,"startColumn":17,"endLine":220,"endColumn":103,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 132_261]->ropcn_utils.queryActionDelayStatist","sourceNodeId":"handle_call_tool \\n[server.py : 132_261]","targetNodeId":"ropcn_utils.queryActionDelayStatist"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpRopnTaskStatusAnalyse/src/mcpRopnTaskStatusAnalyse/server.py"},"region":{"startLine":232,"startColumn":17,"endLine":232,"endColumn":95,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 132_261]->ropcn_utils.queryPolicyConf","sourceNodeId":"handle_call_tool \\n[server.py : 132_261]","targetNodeId":"ropcn_utils.queryPolicyConf"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpRopnTaskStatusAnalyse/src/mcpRopnTaskStatusAnalyse/server.py"},"region":{"startLine":243,"startColumn":42,"endLine":243,"endColumn":78,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 132_261]->ropcn_utils.codeGenChat","sourceNodeId":"handle_call_tool \\n[server.py : 132_261]","targetNodeId":"ropcn_utils.codeGenChat"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpRopnTaskStatusAnalyse/src/mcpRopnTaskStatusAnalyse/server.py"},"region":{"startLine":259,"startColumn":15,"endLine":259,"endColumn":50,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 132_261]->/src/mcpRopnTaskStatusAnalyse/src/mcpRopnTaskStatusAnalyse/server.handle_call_tool.handle_call_tool_scope..ValueError","sourceNodeId":"handle_call_tool \\n[server.py : 132_261]","targetNodeId":"/src/mcpRopnTaskStatusAnalyse/src/mcpRopnTaskStatusAnalyse/server.handle_call_tool.handle_call_tool_scope..ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpSemanticSearch/src/mcpSemanticSearch/server.py"},"region":{"startLine":137,"startColumn":1,"endLine":171,"endColumn":54,"snippet":{}}}},"id":"<__entry_point__>->handle_call_tool \\n[server.py : 137_171]","sourceNodeId":"<__entry_point__>","targetNodeId":"handle_call_tool \\n[server.py : 137_171]"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpSemanticSearch/src/mcpSemanticSearch/server.py"},"region":{"startLine":144,"startColumn":80,"endLine":144,"endColumn":123,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 137_171]->syslib_from.json.dumps","sourceNodeId":"handle_call_tool \\n[server.py : 137_171]","targetNodeId":"syslib_from.json.dumps"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpSemanticSearch/src/mcpSemanticSearch/server.py"},"region":{"startLine":144,"startColumn":5,"endLine":144,"endColumn":125,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 137_171]->syslib_from.logging.getLogger(mcp-server).info","sourceNodeId":"handle_call_tool \\n[server.py : 137_171]","targetNodeId":"syslib_from.logging.getLogger(mcp-server).info"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpSemanticSearch/src/mcpSemanticSearch/server.py"},"region":{"startLine":146,"startColumn":15,"endLine":146,"endColumn":48,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 137_171]->/src/mcpSemanticSearch/src/mcpSemanticSearch/server.handle_call_tool.handle_call_tool_scope...ValueError","sourceNodeId":"handle_call_tool \\n[server.py : 137_171]","targetNodeId":"/src/mcpSemanticSearch/src/mcpSemanticSearch/server.handle_call_tool.handle_call_tool_scope...ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpSemanticSearch/src/mcpSemanticSearch/server.py"},"region":{"startLine":151,"startColumn":23,"endLine":151,"endColumn":105,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 137_171]->/src/mcpSemanticSearch/src/mcpSemanticSearch/server.handle_call_tool.handle_call_tool_scope....ValueError","sourceNodeId":"handle_call_tool \\n[server.py : 137_171]","targetNodeId":"/src/mcpSemanticSearch/src/mcpSemanticSearch/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpSemanticSearch/src/mcpSemanticSearch/server.py"},"region":{"startLine":154,"startColumn":23,"endLine":154,"endColumn":75,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 137_171]->/src/mcpSemanticSearch/src/mcpSemanticSearch/server.handle_call_tool.handle_call_tool_scope....ValueError","sourceNodeId":"handle_call_tool \\n[server.py : 137_171]","targetNodeId":"/src/mcpSemanticSearch/src/mcpSemanticSearch/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpSemanticSearch/src/mcpSemanticSearch/server.py"},"region":{"startLine":159,"startColumn":21,"endLine":159,"endColumn":57,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 137_171]->/src/mcpSemanticSearch/src/mcpSemanticSearch/server.handle_call_tool.arguments.get","sourceNodeId":"handle_call_tool \\n[server.py : 137_171]","targetNodeId":"/src/mcpSemanticSearch/src/mcpSemanticSearch/server.handle_call_tool.arguments.get"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpSemanticSearch/src/mcpSemanticSearch/server.py"},"region":{"startLine":160,"startColumn":19,"endLine":165,"endColumn":14,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 137_171]->semantic_search \\n[server.py : 92_133]","sourceNodeId":"handle_call_tool \\n[server.py : 137_171]","targetNodeId":"semantic_search \\n[server.py : 92_133]"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpSemanticSearch/src/mcpSemanticSearch/server.py"},"region":{"startLine":123,"startColumn":13,"endLine":123,"endColumn":109,"snippet":{}}}},"id":"semantic_search \\n[server.py : 92_133]->syslib_from.logging.getLogger(mcp-server).info","sourceNodeId":"semantic_search \\n[server.py : 92_133]","targetNodeId":"syslib_from.logging.getLogger(mcp-server).info"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpSemanticSearch/src/mcpSemanticSearch/server.py"},"region":{"startLine":103,"startColumn":20,"endLine":111,"endColumn":14,"snippet":{}}}},"id":"semantic_search \\n[server.py : 92_133]->/src/mcpSemanticSearch/src/mcpSemanticSearch/server.semantic_search.semantic_search_scope..dict","sourceNodeId":"semantic_search \\n[server.py : 92_133]","targetNodeId":"/src/mcpSemanticSearch/src/mcpSemanticSearch/server.semantic_search.semantic_search_scope..dict"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpSemanticSearch/src/mcpSemanticSearch/server.py"},"region":{"startLine":102,"startColumn":39,"endLine":112,"endColumn":10,"snippet":{}}}},"id":"semantic_search \\n[server.py : 92_133]->mcp_common.remote.codeinsight.code_insight_api.mcp_server_backend_api","sourceNodeId":"semantic_search \\n[server.py : 92_133]","targetNodeId":"mcp_common.remote.codeinsight.code_insight_api.mcp_server_backend_api"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpSemanticSearch/src/mcpSemanticSearch/server.py"},"region":{"startLine":126,"startColumn":35,"endLine":126,"endColumn":80,"snippet":{}}}},"id":"semantic_search \\n[server.py : 92_133]->syslib_from.json.dumps","sourceNodeId":"semantic_search \\n[server.py : 92_133]","targetNodeId":"syslib_from.json.dumps"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpSemanticSearch/src/mcpSemanticSearch/server.py"},"region":{"startLine":122,"startColumn":23,"endLine":122,"endColumn":53,"snippet":{}}}},"id":"semantic_search \\n[server.py : 92_133]->mcp_common.remote.codeinsight.code_insight_api.mcp_server_backend_api(var params:any=dict(var name:any=Consts.SEMANTIC_SEARCH.name, var arguments:any=dict(var appName:any=app_name, var repoUrl:any=rep...","sourceNodeId":"semantic_search \\n[server.py : 92_133]","targetNodeId":"mcp_common.remote.codeinsight.code_insight_api.mcp_server_backend_api(var params:any=dict(var name:any=Consts.SEMANTIC_SEARCH.name, var arguments:any=dict(var appName:any=app_name, var repoUrl:any=rep..."},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpSemanticSearch/src/mcpSemanticSearch/server.py"},"region":{"startLine":120,"startColumn":23,"endLine":120,"endColumn":48,"snippet":{}}}},"id":"semantic_search \\n[server.py : 92_133]->format_content \\n[server.py : 72_89]","sourceNodeId":"semantic_search \\n[server.py : 92_133]","targetNodeId":"format_content \\n[server.py : 72_89]"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpSemanticSearch/src/mcpSemanticSearch/server.py"},"region":{"startLine":75,"startColumn":28,"endLine":75,"endColumn":48,"snippet":{}}}},"id":"format_content \\n[server.py : 72_89]->/src/mcpSemanticSearch/src/mcpSemanticSearch/server.format_content.format_content_scope...enumerate","sourceNodeId":"format_content \\n[server.py : 72_89]","targetNodeId":"/src/mcpSemanticSearch/src/mcpSemanticSearch/server.format_content.format_content_scope...enumerate"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpSemanticSearch/src/mcpSemanticSearch/server.py"},"region":{"startLine":79,"startColumn":20,"endLine":79,"endColumn":40,"snippet":{}}}},"id":"format_content \\n[server.py : 72_89]->/src/mcpSemanticSearch/src/mcpSemanticSearch/server.format_content.format_content_scope...enumerate(data_list).get","sourceNodeId":"format_content \\n[server.py : 72_89]","targetNodeId":"/src/mcpSemanticSearch/src/mcpSemanticSearch/server.format_content.format_content_scope...enumerate(data_list).get"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpSemanticSearch/src/mcpSemanticSearch/server.py"},"region":{"startLine":80,"startColumn":20,"endLine":84,"endColumn":14,"snippet":{}}}},"id":"format_content \\n[server.py : 72_89]->mcp_common.utils.consts.CODE_PATTERN.format","sourceNodeId":"format_content \\n[server.py : 72_89]","targetNodeId":"mcp_common.utils.consts.CODE_PATTERN.format"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpSemanticSearch/src/mcpSemanticSearch/server.py"},"region":{"startLine":87,"startColumn":9,"endLine":87,"endColumn":86,"snippet":{}}}},"id":"format_content \\n[server.py : 72_89]->syslib_from.logging.getLogger(mcp-server).exception","sourceNodeId":"format_content \\n[server.py : 72_89]","targetNodeId":"syslib_from.logging.getLogger(mcp-server).exception"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpSemanticSearch/src/mcpSemanticSearch/server.py"},"region":{"startLine":125,"startColumn":13,"endLine":126,"endColumn":82,"snippet":{}}}},"id":"semantic_search \\n[server.py : 92_133]->syslib_from.logging.getLogger(mcp-server).warning","sourceNodeId":"semantic_search \\n[server.py : 92_133]","targetNodeId":"syslib_from.logging.getLogger(mcp-server).warning"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpSemanticSearch/src/mcpSemanticSearch/server.py"},"region":{"startLine":129,"startColumn":9,"endLine":129,"endColumn":110,"snippet":{}}}},"id":"semantic_search \\n[server.py : 92_133]->syslib_from.logging.getLogger(mcp-server).exception","sourceNodeId":"semantic_search \\n[server.py : 92_133]","targetNodeId":"syslib_from.logging.getLogger(mcp-server).exception"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpSemanticSearch/src/mcpSemanticSearch/server.py"},"region":{"startLine":166,"startColumn":21,"endLine":169,"endColumn":14,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 137_171]->syslib_from.mcp/types.TextContent","sourceNodeId":"handle_call_tool \\n[server.py : 137_171]","targetNodeId":"syslib_from.mcp/types.TextContent"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpSemanticSearch/src/mcpSemanticSearch/server.py"},"region":{"startLine":171,"startColumn":19,"endLine":171,"endColumn":54,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 137_171]->/src/mcpSemanticSearch/src/mcpSemanticSearch/server.handle_call_tool.handle_call_tool_scope...ValueError","sourceNodeId":"handle_call_tool \\n[server.py : 137_171]","targetNodeId":"/src/mcpSemanticSearch/src/mcpSemanticSearch/server.handle_call_tool.handle_call_tool_scope...ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpSim/src/mcpSim/server.py"},"region":{"startLine":318,"startColumn":1,"endLine":373,"endColumn":54,"snippet":{}}}},"id":"<__entry_point__>->handle_call_tool \\n[server.py : 318_373]","sourceNodeId":"<__entry_point__>","targetNodeId":"handle_call_tool \\n[server.py : 318_373]"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpSim/src/mcpSim/server.py"},"region":{"startLine":325,"startColumn":75,"endLine":325,"endColumn":118,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 318_373]->syslib_from.json.dumps","sourceNodeId":"handle_call_tool \\n[server.py : 318_373]","targetNodeId":"syslib_from.json.dumps"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpSim/src/mcpSim/server.py"},"region":{"startLine":325,"startColumn":5,"endLine":325,"endColumn":120,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 318_373]->syslib_from.logging.getLogger(mcp-server).info","sourceNodeId":"handle_call_tool \\n[server.py : 318_373]","targetNodeId":"syslib_from.logging.getLogger(mcp-server).info"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpSim/src/mcpSim/server.py"},"region":{"startLine":329,"startColumn":23,"endLine":329,"endColumn":62,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 318_373]->/src/mcpSim/src/mcpSim/server.handle_call_tool.handle_call_tool_scope....ValueError","sourceNodeId":"handle_call_tool \\n[server.py : 318_373]","targetNodeId":"/src/mcpSim/src/mcpSim/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpSim/src/mcpSim/server.py"},"region":{"startLine":331,"startColumn":23,"endLine":331,"endColumn":60,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 318_373]->/src/mcpSim/src/mcpSim/server.handle_call_tool.handle_call_tool_scope....ValueError","sourceNodeId":"handle_call_tool \\n[server.py : 318_373]","targetNodeId":"/src/mcpSim/src/mcpSim/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpSim/src/mcpSim/server.py"},"region":{"startLine":332,"startColumn":27,"endLine":333,"endColumn":81,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 318_373]->get_node_trace_asset \\n[server.py : 17_45]","sourceNodeId":"handle_call_tool \\n[server.py : 318_373]","targetNodeId":"get_node_trace_asset \\n[server.py : 17_45]"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpSim/src/mcpSim/server.py"},"region":{"startLine":35,"startColumn":20,"endLine":35,"endColumn":81,"snippet":{}}}},"id":"get_node_trace_asset \\n[server.py : 17_45]->syslib_from.requests.post","sourceNodeId":"get_node_trace_asset \\n[server.py : 17_45]","targetNodeId":"syslib_from.requests.post"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpSim/src/mcpSim/server.py"},"region":{"startLine":36,"startColumn":9,"endLine":36,"endColumn":36,"snippet":{}}}},"id":"get_node_trace_asset \\n[server.py : 17_45]->syslib_from.requests.post(url, var headers:any=header, var json:any=params, var verify:any=false).raise_for_status","sourceNodeId":"get_node_trace_asset \\n[server.py : 17_45]","targetNodeId":"syslib_from.requests.post(url, var headers:any=header, var json:any=params, var verify:any=false).raise_for_status"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpSim/src/mcpSim/server.py"},"region":{"startLine":37,"startColumn":18,"endLine":37,"endColumn":33,"snippet":{}}}},"id":"get_node_trace_asset \\n[server.py : 17_45]->syslib_from.requests.post(url, var headers:any=header, var json:any=params, var verify:any=false).json","sourceNodeId":"get_node_trace_asset \\n[server.py : 17_45]","targetNodeId":"syslib_from.requests.post(url, var headers:any=header, var json:any=params, var verify:any=false).json"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpSim/src/mcpSim/server.py"},"region":{"startLine":40,"startColumn":20,"endLine":40,"endColumn":37,"snippet":{}}}},"id":"get_node_trace_asset \\n[server.py : 17_45]->syslib_from.requests.post(url, var headers:any=header, var json:any=params, var verify:any=false).json().get","sourceNodeId":"get_node_trace_asset \\n[server.py : 17_45]","targetNodeId":"syslib_from.requests.post(url, var headers:any=header, var json:any=params, var verify:any=false).json().get"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpSim/src/mcpSim/server.py"},"region":{"startLine":39,"startColumn":13,"endLine":39,"endColumn":97,"snippet":{}}}},"id":"get_node_trace_asset \\n[server.py : 17_45]->syslib_from.logging.getLogger(mcp-server).info","sourceNodeId":"get_node_trace_asset \\n[server.py : 17_45]","targetNodeId":"syslib_from.logging.getLogger(mcp-server).info"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpSim/src/mcpSim/server.py"},"region":{"startLine":41,"startColumn":9,"endLine":41,"endColumn":96,"snippet":{}}}},"id":"get_node_trace_asset \\n[server.py : 17_45]->syslib_from.logging.getLogger(mcp-server).warning","sourceNodeId":"get_node_trace_asset \\n[server.py : 17_45]","targetNodeId":"syslib_from.logging.getLogger(mcp-server).warning"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpSim/src/mcpSim/server.py"},"region":{"startLine":44,"startColumn":9,"endLine":44,"endColumn":89,"snippet":{}}}},"id":"get_node_trace_asset \\n[server.py : 17_45]->syslib_from.logging.getLogger(mcp-server).error","sourceNodeId":"get_node_trace_asset \\n[server.py : 17_45]","targetNodeId":"syslib_from.logging.getLogger(mcp-server).error"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpSim/src/mcpSim/server.py"},"region":{"startLine":45,"startColumn":45,"endLine":45,"endColumn":53,"snippet":{}}}},"id":"get_node_trace_asset \\n[server.py : 17_45]->/src/mcpSim/src/mcpSim/server.get_node_trace_asset.get_node_trace_asset_scope...str","sourceNodeId":"get_node_trace_asset \\n[server.py : 17_45]","targetNodeId":"/src/mcpSim/src/mcpSim/server.get_node_trace_asset.get_node_trace_asset_scope...str"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpSim/src/mcpSim/server.py"},"region":{"startLine":371,"startColumn":21,"endLine":371,"endColumn":69,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 318_373]->syslib_from.mcp/types.TextContent","sourceNodeId":"handle_call_tool \\n[server.py : 318_373]","targetNodeId":"syslib_from.mcp/types.TextContent"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpSim/src/mcpSim/server.py"},"region":{"startLine":337,"startColumn":23,"endLine":337,"endColumn":62,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 318_373]->/src/mcpSim/src/mcpSim/server.handle_call_tool.handle_call_tool_scope....ValueError","sourceNodeId":"handle_call_tool \\n[server.py : 318_373]","targetNodeId":"/src/mcpSim/src/mcpSim/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpSim/src/mcpSim/server.py"},"region":{"startLine":338,"startColumn":27,"endLine":338,"endColumn":78,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 318_373]->get_node_path \\n[server.py : 48_74]","sourceNodeId":"handle_call_tool \\n[server.py : 318_373]","targetNodeId":"get_node_path \\n[server.py : 48_74]"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpSim/src/mcpSim/server.py"},"region":{"startLine":64,"startColumn":20,"endLine":64,"endColumn":81,"snippet":{}}}},"id":"get_node_path \\n[server.py : 48_74]->syslib_from.requests.post","sourceNodeId":"get_node_path \\n[server.py : 48_74]","targetNodeId":"syslib_from.requests.post"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpSim/src/mcpSim/server.py"},"region":{"startLine":65,"startColumn":9,"endLine":65,"endColumn":36,"snippet":{}}}},"id":"get_node_path \\n[server.py : 48_74]->syslib_from.requests.post(url, var headers:any=header, var json:any=params, var verify:any=false).raise_for_status","sourceNodeId":"get_node_path \\n[server.py : 48_74]","targetNodeId":"syslib_from.requests.post(url, var headers:any=header, var json:any=params, var verify:any=false).raise_for_status"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpSim/src/mcpSim/server.py"},"region":{"startLine":66,"startColumn":18,"endLine":66,"endColumn":33,"snippet":{}}}},"id":"get_node_path \\n[server.py : 48_74]->syslib_from.requests.post(url, var headers:any=header, var json:any=params, var verify:any=false).json","sourceNodeId":"get_node_path \\n[server.py : 48_74]","targetNodeId":"syslib_from.requests.post(url, var headers:any=header, var json:any=params, var verify:any=false).json"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpSim/src/mcpSim/server.py"},"region":{"startLine":69,"startColumn":20,"endLine":69,"endColumn":37,"snippet":{}}}},"id":"get_node_path \\n[server.py : 48_74]->syslib_from.requests.post(url, var headers:any=header, var json:any=params, var verify:any=false).json().get","sourceNodeId":"get_node_path \\n[server.py : 48_74]","targetNodeId":"syslib_from.requests.post(url, var headers:any=header, var json:any=params, var verify:any=false).json().get"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpSim/src/mcpSim/server.py"},"region":{"startLine":68,"startColumn":13,"endLine":68,"endColumn":90,"snippet":{}}}},"id":"get_node_path \\n[server.py : 48_74]->syslib_from.logging.getLogger(mcp-server).info","sourceNodeId":"get_node_path \\n[server.py : 48_74]","targetNodeId":"syslib_from.logging.getLogger(mcp-server).info"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpSim/src/mcpSim/server.py"},"region":{"startLine":70,"startColumn":9,"endLine":70,"endColumn":89,"snippet":{}}}},"id":"get_node_path \\n[server.py : 48_74]->syslib_from.logging.getLogger(mcp-server).warning","sourceNodeId":"get_node_path \\n[server.py : 48_74]","targetNodeId":"syslib_from.logging.getLogger(mcp-server).warning"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpSim/src/mcpSim/server.py"},"region":{"startLine":73,"startColumn":9,"endLine":73,"endColumn":82,"snippet":{}}}},"id":"get_node_path \\n[server.py : 48_74]->syslib_from.logging.getLogger(mcp-server).error","sourceNodeId":"get_node_path \\n[server.py : 48_74]","targetNodeId":"syslib_from.logging.getLogger(mcp-server).error"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpSim/src/mcpSim/server.py"},"region":{"startLine":74,"startColumn":38,"endLine":74,"endColumn":46,"snippet":{}}}},"id":"get_node_path \\n[server.py : 48_74]->/src/mcpSim/src/mcpSim/server.get_node_path.get_node_path_scope...str","sourceNodeId":"get_node_path \\n[server.py : 48_74]","targetNodeId":"/src/mcpSim/src/mcpSim/server.get_node_path.get_node_path_scope...str"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpSim/src/mcpSim/server.py"},"region":{"startLine":342,"startColumn":23,"endLine":342,"endColumn":62,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 318_373]->/src/mcpSim/src/mcpSim/server.handle_call_tool.handle_call_tool_scope....ValueError","sourceNodeId":"handle_call_tool \\n[server.py : 318_373]","targetNodeId":"/src/mcpSim/src/mcpSim/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpSim/src/mcpSim/server.py"},"region":{"startLine":344,"startColumn":23,"endLine":344,"endColumn":60,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 318_373]->/src/mcpSim/src/mcpSim/server.handle_call_tool.handle_call_tool_scope....ValueError","sourceNodeId":"handle_call_tool \\n[server.py : 318_373]","targetNodeId":"/src/mcpSim/src/mcpSim/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpSim/src/mcpSim/server.py"},"region":{"startLine":345,"startColumn":27,"endLine":346,"endColumn":78,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 318_373]->get_node_rpc_call \\n[server.py : 76_104]","sourceNodeId":"handle_call_tool \\n[server.py : 318_373]","targetNodeId":"get_node_rpc_call \\n[server.py : 76_104]"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpSim/src/mcpSim/server.py"},"region":{"startLine":94,"startColumn":20,"endLine":94,"endColumn":81,"snippet":{}}}},"id":"get_node_rpc_call \\n[server.py : 76_104]->syslib_from.requests.post","sourceNodeId":"get_node_rpc_call \\n[server.py : 76_104]","targetNodeId":"syslib_from.requests.post"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpSim/src/mcpSim/server.py"},"region":{"startLine":95,"startColumn":9,"endLine":95,"endColumn":36,"snippet":{}}}},"id":"get_node_rpc_call \\n[server.py : 76_104]->syslib_from.requests.post(url, var headers:any=header, var json:any=params, var verify:any=false).raise_for_status","sourceNodeId":"get_node_rpc_call \\n[server.py : 76_104]","targetNodeId":"syslib_from.requests.post(url, var headers:any=header, var json:any=params, var verify:any=false).raise_for_status"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpSim/src/mcpSim/server.py"},"region":{"startLine":96,"startColumn":18,"endLine":96,"endColumn":33,"snippet":{}}}},"id":"get_node_rpc_call \\n[server.py : 76_104]->syslib_from.requests.post(url, var headers:any=header, var json:any=params, var verify:any=false).json","sourceNodeId":"get_node_rpc_call \\n[server.py : 76_104]","targetNodeId":"syslib_from.requests.post(url, var headers:any=header, var json:any=params, var verify:any=false).json"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpSim/src/mcpSim/server.py"},"region":{"startLine":99,"startColumn":20,"endLine":99,"endColumn":37,"snippet":{}}}},"id":"get_node_rpc_call \\n[server.py : 76_104]->syslib_from.requests.post(url, var headers:any=header, var json:any=params, var verify:any=false).json().get","sourceNodeId":"get_node_rpc_call \\n[server.py : 76_104]","targetNodeId":"syslib_from.requests.post(url, var headers:any=header, var json:any=params, var verify:any=false).json().get"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpSim/src/mcpSim/server.py"},"region":{"startLine":98,"startColumn":13,"endLine":98,"endColumn":97,"snippet":{}}}},"id":"get_node_rpc_call \\n[server.py : 76_104]->syslib_from.logging.getLogger(mcp-server).info","sourceNodeId":"get_node_rpc_call \\n[server.py : 76_104]","targetNodeId":"syslib_from.logging.getLogger(mcp-server).info"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpSim/src/mcpSim/server.py"},"region":{"startLine":100,"startColumn":9,"endLine":100,"endColumn":96,"snippet":{}}}},"id":"get_node_rpc_call \\n[server.py : 76_104]->syslib_from.logging.getLogger(mcp-server).warning","sourceNodeId":"get_node_rpc_call \\n[server.py : 76_104]","targetNodeId":"syslib_from.logging.getLogger(mcp-server).warning"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpSim/src/mcpSim/server.py"},"region":{"startLine":103,"startColumn":9,"endLine":103,"endColumn":89,"snippet":{}}}},"id":"get_node_rpc_call \\n[server.py : 76_104]->syslib_from.logging.getLogger(mcp-server).error","sourceNodeId":"get_node_rpc_call \\n[server.py : 76_104]","targetNodeId":"syslib_from.logging.getLogger(mcp-server).error"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpSim/src/mcpSim/server.py"},"region":{"startLine":104,"startColumn":42,"endLine":104,"endColumn":50,"snippet":{}}}},"id":"get_node_rpc_call \\n[server.py : 76_104]->/src/mcpSim/src/mcpSim/server.get_node_rpc_call.get_node_rpc_call_scope...str","sourceNodeId":"get_node_rpc_call \\n[server.py : 76_104]","targetNodeId":"/src/mcpSim/src/mcpSim/server.get_node_rpc_call.get_node_rpc_call_scope...str"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpSim/src/mcpSim/server.py"},"region":{"startLine":350,"startColumn":23,"endLine":350,"endColumn":62,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 318_373]->/src/mcpSim/src/mcpSim/server.handle_call_tool.handle_call_tool_scope....ValueError","sourceNodeId":"handle_call_tool \\n[server.py : 318_373]","targetNodeId":"/src/mcpSim/src/mcpSim/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpSim/src/mcpSim/server.py"},"region":{"startLine":352,"startColumn":23,"endLine":352,"endColumn":60,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 318_373]->/src/mcpSim/src/mcpSim/server.handle_call_tool.handle_call_tool_scope....ValueError","sourceNodeId":"handle_call_tool \\n[server.py : 318_373]","targetNodeId":"/src/mcpSim/src/mcpSim/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpSim/src/mcpSim/server.py"},"region":{"startLine":353,"startColumn":27,"endLine":354,"endColumn":78,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 318_373]->get_node_sub_call \\n[server.py : 107_135]","sourceNodeId":"handle_call_tool \\n[server.py : 318_373]","targetNodeId":"get_node_sub_call \\n[server.py : 107_135]"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpSim/src/mcpSim/server.py"},"region":{"startLine":125,"startColumn":20,"endLine":125,"endColumn":81,"snippet":{}}}},"id":"get_node_sub_call \\n[server.py : 107_135]->syslib_from.requests.post","sourceNodeId":"get_node_sub_call \\n[server.py : 107_135]","targetNodeId":"syslib_from.requests.post"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpSim/src/mcpSim/server.py"},"region":{"startLine":126,"startColumn":9,"endLine":126,"endColumn":36,"snippet":{}}}},"id":"get_node_sub_call \\n[server.py : 107_135]->syslib_from.requests.post(url, var headers:any=header, var json:any=params, var verify:any=false).raise_for_status","sourceNodeId":"get_node_sub_call \\n[server.py : 107_135]","targetNodeId":"syslib_from.requests.post(url, var headers:any=header, var json:any=params, var verify:any=false).raise_for_status"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpSim/src/mcpSim/server.py"},"region":{"startLine":127,"startColumn":18,"endLine":127,"endColumn":33,"snippet":{}}}},"id":"get_node_sub_call \\n[server.py : 107_135]->syslib_from.requests.post(url, var headers:any=header, var json:any=params, var verify:any=false).json","sourceNodeId":"get_node_sub_call \\n[server.py : 107_135]","targetNodeId":"syslib_from.requests.post(url, var headers:any=header, var json:any=params, var verify:any=false).json"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpSim/src/mcpSim/server.py"},"region":{"startLine":130,"startColumn":20,"endLine":130,"endColumn":37,"snippet":{}}}},"id":"get_node_sub_call \\n[server.py : 107_135]->syslib_from.requests.post(url, var headers:any=header, var json:any=params, var verify:any=false).json().get","sourceNodeId":"get_node_sub_call \\n[server.py : 107_135]","targetNodeId":"syslib_from.requests.post(url, var headers:any=header, var json:any=params, var verify:any=false).json().get"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpSim/src/mcpSim/server.py"},"region":{"startLine":129,"startColumn":13,"endLine":129,"endColumn":97,"snippet":{}}}},"id":"get_node_sub_call \\n[server.py : 107_135]->syslib_from.logging.getLogger(mcp-server).info","sourceNodeId":"get_node_sub_call \\n[server.py : 107_135]","targetNodeId":"syslib_from.logging.getLogger(mcp-server).info"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpSim/src/mcpSim/server.py"},"region":{"startLine":131,"startColumn":9,"endLine":131,"endColumn":96,"snippet":{}}}},"id":"get_node_sub_call \\n[server.py : 107_135]->syslib_from.logging.getLogger(mcp-server).warning","sourceNodeId":"get_node_sub_call \\n[server.py : 107_135]","targetNodeId":"syslib_from.logging.getLogger(mcp-server).warning"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpSim/src/mcpSim/server.py"},"region":{"startLine":134,"startColumn":9,"endLine":134,"endColumn":89,"snippet":{}}}},"id":"get_node_sub_call \\n[server.py : 107_135]->syslib_from.logging.getLogger(mcp-server).error","sourceNodeId":"get_node_sub_call \\n[server.py : 107_135]","targetNodeId":"syslib_from.logging.getLogger(mcp-server).error"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpSim/src/mcpSim/server.py"},"region":{"startLine":135,"startColumn":42,"endLine":135,"endColumn":50,"snippet":{}}}},"id":"get_node_sub_call \\n[server.py : 107_135]->/src/mcpSim/src/mcpSim/server.get_node_sub_call.get_node_sub_call_scope...str","sourceNodeId":"get_node_sub_call \\n[server.py : 107_135]","targetNodeId":"/src/mcpSim/src/mcpSim/server.get_node_sub_call.get_node_sub_call_scope...str"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpSim/src/mcpSim/server.py"},"region":{"startLine":358,"startColumn":23,"endLine":358,"endColumn":62,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 318_373]->/src/mcpSim/src/mcpSim/server.handle_call_tool.handle_call_tool_scope....ValueError","sourceNodeId":"handle_call_tool \\n[server.py : 318_373]","targetNodeId":"/src/mcpSim/src/mcpSim/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpSim/src/mcpSim/server.py"},"region":{"startLine":360,"startColumn":23,"endLine":360,"endColumn":60,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 318_373]->/src/mcpSim/src/mcpSim/server.handle_call_tool.handle_call_tool_scope....ValueError","sourceNodeId":"handle_call_tool \\n[server.py : 318_373]","targetNodeId":"/src/mcpSim/src/mcpSim/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpSim/src/mcpSim/server.py"},"region":{"startLine":361,"startColumn":27,"endLine":362,"endColumn":82,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 318_373]->get_node_sub_rpc_call \\n[server.py : 138_166]","sourceNodeId":"handle_call_tool \\n[server.py : 318_373]","targetNodeId":"get_node_sub_rpc_call \\n[server.py : 138_166]"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpSim/src/mcpSim/server.py"},"region":{"startLine":156,"startColumn":20,"endLine":156,"endColumn":81,"snippet":{}}}},"id":"get_node_sub_rpc_call \\n[server.py : 138_166]->syslib_from.requests.post","sourceNodeId":"get_node_sub_rpc_call \\n[server.py : 138_166]","targetNodeId":"syslib_from.requests.post"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpSim/src/mcpSim/server.py"},"region":{"startLine":157,"startColumn":9,"endLine":157,"endColumn":36,"snippet":{}}}},"id":"get_node_sub_rpc_call \\n[server.py : 138_166]->syslib_from.requests.post(url, var headers:any=header, var json:any=params, var verify:any=false).raise_for_status","sourceNodeId":"get_node_sub_rpc_call \\n[server.py : 138_166]","targetNodeId":"syslib_from.requests.post(url, var headers:any=header, var json:any=params, var verify:any=false).raise_for_status"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpSim/src/mcpSim/server.py"},"region":{"startLine":158,"startColumn":18,"endLine":158,"endColumn":33,"snippet":{}}}},"id":"get_node_sub_rpc_call \\n[server.py : 138_166]->syslib_from.requests.post(url, var headers:any=header, var json:any=params, var verify:any=false).json","sourceNodeId":"get_node_sub_rpc_call \\n[server.py : 138_166]","targetNodeId":"syslib_from.requests.post(url, var headers:any=header, var json:any=params, var verify:any=false).json"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpSim/src/mcpSim/server.py"},"region":{"startLine":161,"startColumn":20,"endLine":161,"endColumn":37,"snippet":{}}}},"id":"get_node_sub_rpc_call \\n[server.py : 138_166]->syslib_from.requests.post(url, var headers:any=header, var json:any=params, var verify:any=false).json().get","sourceNodeId":"get_node_sub_rpc_call \\n[server.py : 138_166]","targetNodeId":"syslib_from.requests.post(url, var headers:any=header, var json:any=params, var verify:any=false).json().get"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpSim/src/mcpSim/server.py"},"region":{"startLine":160,"startColumn":13,"endLine":160,"endColumn":101,"snippet":{}}}},"id":"get_node_sub_rpc_call \\n[server.py : 138_166]->syslib_from.logging.getLogger(mcp-server).info","sourceNodeId":"get_node_sub_rpc_call \\n[server.py : 138_166]","targetNodeId":"syslib_from.logging.getLogger(mcp-server).info"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpSim/src/mcpSim/server.py"},"region":{"startLine":162,"startColumn":9,"endLine":162,"endColumn":100,"snippet":{}}}},"id":"get_node_sub_rpc_call \\n[server.py : 138_166]->syslib_from.logging.getLogger(mcp-server).warning","sourceNodeId":"get_node_sub_rpc_call \\n[server.py : 138_166]","targetNodeId":"syslib_from.logging.getLogger(mcp-server).warning"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpSim/src/mcpSim/server.py"},"region":{"startLine":165,"startColumn":9,"endLine":165,"endColumn":93,"snippet":{}}}},"id":"get_node_sub_rpc_call \\n[server.py : 138_166]->syslib_from.logging.getLogger(mcp-server).error","sourceNodeId":"get_node_sub_rpc_call \\n[server.py : 138_166]","targetNodeId":"syslib_from.logging.getLogger(mcp-server).error"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpSim/src/mcpSim/server.py"},"region":{"startLine":166,"startColumn":46,"endLine":166,"endColumn":54,"snippet":{}}}},"id":"get_node_sub_rpc_call \\n[server.py : 138_166]->/src/mcpSim/src/mcpSim/server.get_node_sub_rpc_call.get_node_sub_rpc_call_scope...str","sourceNodeId":"get_node_sub_rpc_call \\n[server.py : 138_166]","targetNodeId":"/src/mcpSim/src/mcpSim/server.get_node_sub_rpc_call.get_node_sub_rpc_call_scope...str"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpSim/src/mcpSim/server.py"},"region":{"startLine":366,"startColumn":23,"endLine":366,"endColumn":62,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 318_373]->/src/mcpSim/src/mcpSim/server.handle_call_tool.handle_call_tool_scope....ValueError","sourceNodeId":"handle_call_tool \\n[server.py : 318_373]","targetNodeId":"/src/mcpSim/src/mcpSim/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpSim/src/mcpSim/server.py"},"region":{"startLine":368,"startColumn":23,"endLine":368,"endColumn":60,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 318_373]->/src/mcpSim/src/mcpSim/server.handle_call_tool.handle_call_tool_scope....ValueError","sourceNodeId":"handle_call_tool \\n[server.py : 318_373]","targetNodeId":"/src/mcpSim/src/mcpSim/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpSim/src/mcpSim/server.py"},"region":{"startLine":369,"startColumn":27,"endLine":370,"endColumn":86,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 318_373]->get_app_call_info \\n[server.py : 168_196]","sourceNodeId":"handle_call_tool \\n[server.py : 318_373]","targetNodeId":"get_app_call_info \\n[server.py : 168_196]"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpSim/src/mcpSim/server.py"},"region":{"startLine":373,"startColumn":19,"endLine":373,"endColumn":54,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 318_373]->/src/mcpSim/src/mcpSim/server.handle_call_tool.handle_call_tool_scope...ValueError","sourceNodeId":"handle_call_tool \\n[server.py : 318_373]","targetNodeId":"/src/mcpSim/src/mcpSim/server.handle_call_tool.handle_call_tool_scope...ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpSymbolAnalysis/src/mcpSymbolAnalysis/server.py"},"region":{"startLine":473,"startColumn":1,"endLine":580,"endColumn":54,"snippet":{}}}},"id":"<__entry_point__>->handle_call_tool \\n[server.py : 473_580]","sourceNodeId":"<__entry_point__>","targetNodeId":"handle_call_tool \\n[server.py : 473_580]"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpSymbolAnalysis/src/mcpSymbolAnalysis/server.py"},"region":{"startLine":480,"startColumn":80,"endLine":480,"endColumn":123,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 473_580]->syslib_from.json.dumps","sourceNodeId":"handle_call_tool \\n[server.py : 473_580]","targetNodeId":"syslib_from.json.dumps"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpSymbolAnalysis/src/mcpSymbolAnalysis/server.py"},"region":{"startLine":480,"startColumn":5,"endLine":480,"endColumn":125,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 473_580]->syslib_from.logging.getLogger(mcp-server).info","sourceNodeId":"handle_call_tool \\n[server.py : 473_580]","targetNodeId":"syslib_from.logging.getLogger(mcp-server).info"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpSymbolAnalysis/src/mcpSymbolAnalysis/server.py"},"region":{"startLine":482,"startColumn":15,"endLine":482,"endColumn":48,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 473_580]->/src/mcpSymbolAnalysis/src/mcpSymbolAnalysis/server.handle_call_tool.handle_call_tool_scope...ValueError","sourceNodeId":"handle_call_tool \\n[server.py : 473_580]","targetNodeId":"/src/mcpSymbolAnalysis/src/mcpSymbolAnalysis/server.handle_call_tool.handle_call_tool_scope...ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpSymbolAnalysis/src/mcpSymbolAnalysis/server.py"},"region":{"startLine":487,"startColumn":23,"endLine":487,"endColumn":105,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 473_580]->/src/mcpSymbolAnalysis/src/mcpSymbolAnalysis/server.handle_call_tool.handle_call_tool_scope....ValueError","sourceNodeId":"handle_call_tool \\n[server.py : 473_580]","targetNodeId":"/src/mcpSymbolAnalysis/src/mcpSymbolAnalysis/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpSymbolAnalysis/src/mcpSymbolAnalysis/server.py"},"region":{"startLine":490,"startColumn":23,"endLine":490,"endColumn":96,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 473_580]->/src/mcpSymbolAnalysis/src/mcpSymbolAnalysis/server.handle_call_tool.handle_call_tool_scope....ValueError","sourceNodeId":"handle_call_tool \\n[server.py : 473_580]","targetNodeId":"/src/mcpSymbolAnalysis/src/mcpSymbolAnalysis/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpSymbolAnalysis/src/mcpSymbolAnalysis/server.py"},"region":{"startLine":567,"startColumn":25,"endLine":567,"endColumn":61,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 473_580]->/src/mcpSymbolAnalysis/src/mcpSymbolAnalysis/server.handle_call_tool.arguments.get","sourceNodeId":"handle_call_tool \\n[server.py : 473_580]","targetNodeId":"/src/mcpSymbolAnalysis/src/mcpSymbolAnalysis/server.handle_call_tool.arguments.get"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpSymbolAnalysis/src/mcpSymbolAnalysis/server.py"},"region":{"startLine":496,"startColumn":19,"endLine":501,"endColumn":14,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 473_580]->get_class_methods \\n[server.py : 262_304]","sourceNodeId":"handle_call_tool \\n[server.py : 473_580]","targetNodeId":"get_class_methods \\n[server.py : 262_304]"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpSymbolAnalysis/src/mcpSymbolAnalysis/server.py"},"region":{"startLine":294,"startColumn":13,"endLine":294,"endColumn":111,"snippet":{}}}},"id":"get_class_methods \\n[server.py : 262_304]->syslib_from.logging.getLogger(mcp-server).info","sourceNodeId":"get_class_methods \\n[server.py : 262_304]","targetNodeId":"syslib_from.logging.getLogger(mcp-server).info"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpSymbolAnalysis/src/mcpSymbolAnalysis/server.py"},"region":{"startLine":274,"startColumn":20,"endLine":282,"endColumn":14,"snippet":{}}}},"id":"get_class_methods \\n[server.py : 262_304]->/src/mcpSymbolAnalysis/src/mcpSymbolAnalysis/server.get_class_methods.get_class_methods_scope..dict","sourceNodeId":"get_class_methods \\n[server.py : 262_304]","targetNodeId":"/src/mcpSymbolAnalysis/src/mcpSymbolAnalysis/server.get_class_methods.get_class_methods_scope..dict"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpSymbolAnalysis/src/mcpSymbolAnalysis/server.py"},"region":{"startLine":273,"startColumn":39,"endLine":283,"endColumn":10,"snippet":{}}}},"id":"get_class_methods \\n[server.py : 262_304]->mcp_common.remote.codeinsight.code_insight_api.mcp_server_backend_api","sourceNodeId":"get_class_methods \\n[server.py : 262_304]","targetNodeId":"mcp_common.remote.codeinsight.code_insight_api.mcp_server_backend_api"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpSymbolAnalysis/src/mcpSymbolAnalysis/server.py"},"region":{"startLine":297,"startColumn":35,"endLine":297,"endColumn":80,"snippet":{}}}},"id":"get_class_methods \\n[server.py : 262_304]->syslib_from.json.dumps","sourceNodeId":"get_class_methods \\n[server.py : 262_304]","targetNodeId":"syslib_from.json.dumps"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpSymbolAnalysis/src/mcpSymbolAnalysis/server.py"},"region":{"startLine":293,"startColumn":23,"endLine":293,"endColumn":63,"snippet":{}}}},"id":"get_class_methods \\n[server.py : 262_304]->mcp_common.remote.codeinsight.code_insight_api.mcp_server_backend_api(var params:any=dict(var name:any=Consts.GET_CLASS_METHODS.name, var arguments:any=dict(var appName:any=app_name, var fullyQualifie...","sourceNodeId":"get_class_methods \\n[server.py : 262_304]","targetNodeId":"mcp_common.remote.codeinsight.code_insight_api.mcp_server_backend_api(var params:any=dict(var name:any=Consts.GET_CLASS_METHODS.name, var arguments:any=dict(var appName:any=app_name, var fullyQualifie..."},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpSymbolAnalysis/src/mcpSymbolAnalysis/server.py"},"region":{"startLine":291,"startColumn":23,"endLine":291,"endColumn":58,"snippet":{}}}},"id":"get_class_methods \\n[server.py : 262_304]->format_content \\n[server.py : 238_259]","sourceNodeId":"get_class_methods \\n[server.py : 262_304]","targetNodeId":"format_content \\n[server.py : 238_259]"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpSymbolAnalysis/src/mcpSymbolAnalysis/server.py"},"region":{"startLine":241,"startColumn":28,"endLine":241,"endColumn":48,"snippet":{}}}},"id":"format_content \\n[server.py : 238_259]->/src/mcpSymbolAnalysis/src/mcpSymbolAnalysis/server.format_content.format_content_scope...enumerate","sourceNodeId":"format_content \\n[server.py : 238_259]","targetNodeId":"/src/mcpSymbolAnalysis/src/mcpSymbolAnalysis/server.format_content.format_content_scope...enumerate"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpSymbolAnalysis/src/mcpSymbolAnalysis/server.py"},"region":{"startLine":246,"startColumn":20,"endLine":246,"endColumn":43,"snippet":{}}}},"id":"format_content \\n[server.py : 238_259]->/src/mcpSymbolAnalysis/src/mcpSymbolAnalysis/server.format_content.format_content_scope...enumerate(data_list).get","sourceNodeId":"format_content \\n[server.py : 238_259]","targetNodeId":"/src/mcpSymbolAnalysis/src/mcpSymbolAnalysis/server.format_content.format_content_scope...enumerate(data_list).get"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpSymbolAnalysis/src/mcpSymbolAnalysis/server.py"},"region":{"startLine":243,"startColumn":36,"endLine":243,"endColumn":97,"snippet":{}}}},"id":"format_content \\n[server.py : 238_259]->/src/mcpSymbolAnalysis/src/mcpSymbolAnalysis/server.format_content.format_content_scope...enumerate(data_list).get(extra_data, {}).get","sourceNodeId":"format_content \\n[server.py : 238_259]","targetNodeId":"/src/mcpSymbolAnalysis/src/mcpSymbolAnalysis/server.format_content.format_content_scope...enumerate(data_list).get(extra_data, {}).get"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpSymbolAnalysis/src/mcpSymbolAnalysis/server.py"},"region":{"startLine":247,"startColumn":20,"endLine":251,"endColumn":14,"snippet":{}}}},"id":"format_content \\n[server.py : 238_259]->mcp_common.utils.consts.CODE_PATTERN.format","sourceNodeId":"format_content \\n[server.py : 238_259]","targetNodeId":"mcp_common.utils.consts.CODE_PATTERN.format"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpSymbolAnalysis/src/mcpSymbolAnalysis/server.py"},"region":{"startLine":257,"startColumn":9,"endLine":257,"endColumn":86,"snippet":{}}}},"id":"format_content \\n[server.py : 238_259]->syslib_from.logging.getLogger(mcp-server).exception","sourceNodeId":"format_content \\n[server.py : 238_259]","targetNodeId":"syslib_from.logging.getLogger(mcp-server).exception"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpSymbolAnalysis/src/mcpSymbolAnalysis/server.py"},"region":{"startLine":296,"startColumn":13,"endLine":297,"endColumn":82,"snippet":{}}}},"id":"get_class_methods \\n[server.py : 262_304]->syslib_from.logging.getLogger(mcp-server).warning","sourceNodeId":"get_class_methods \\n[server.py : 262_304]","targetNodeId":"syslib_from.logging.getLogger(mcp-server).warning"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpSymbolAnalysis/src/mcpSymbolAnalysis/server.py"},"region":{"startLine":300,"startColumn":9,"endLine":300,"endColumn":114,"snippet":{}}}},"id":"get_class_methods \\n[server.py : 262_304]->syslib_from.logging.getLogger(mcp-server).exception","sourceNodeId":"get_class_methods \\n[server.py : 262_304]","targetNodeId":"syslib_from.logging.getLogger(mcp-server).exception"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpSymbolAnalysis/src/mcpSymbolAnalysis/server.py"},"region":{"startLine":575,"startColumn":21,"endLine":578,"endColumn":14,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 473_580]->syslib_from.mcp/types.TextContent","sourceNodeId":"handle_call_tool \\n[server.py : 473_580]","targetNodeId":"syslib_from.mcp/types.TextContent"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpSymbolAnalysis/src/mcpSymbolAnalysis/server.py"},"region":{"startLine":508,"startColumn":23,"endLine":508,"endColumn":105,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 473_580]->/src/mcpSymbolAnalysis/src/mcpSymbolAnalysis/server.handle_call_tool.handle_call_tool_scope....ValueError","sourceNodeId":"handle_call_tool \\n[server.py : 473_580]","targetNodeId":"/src/mcpSymbolAnalysis/src/mcpSymbolAnalysis/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpSymbolAnalysis/src/mcpSymbolAnalysis/server.py"},"region":{"startLine":511,"startColumn":23,"endLine":511,"endColumn":97,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 473_580]->/src/mcpSymbolAnalysis/src/mcpSymbolAnalysis/server.handle_call_tool.handle_call_tool_scope....ValueError","sourceNodeId":"handle_call_tool \\n[server.py : 473_580]","targetNodeId":"/src/mcpSymbolAnalysis/src/mcpSymbolAnalysis/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpSymbolAnalysis/src/mcpSymbolAnalysis/server.py"},"region":{"startLine":518,"startColumn":19,"endLine":525,"endColumn":14,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 473_580]->analyze_method_call_chain \\n[server.py : 307_353]","sourceNodeId":"handle_call_tool \\n[server.py : 473_580]","targetNodeId":"analyze_method_call_chain \\n[server.py : 307_353]"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpSymbolAnalysis/src/mcpSymbolAnalysis/server.py"},"region":{"startLine":343,"startColumn":13,"endLine":343,"endColumn":119,"snippet":{}}}},"id":"analyze_method_call_chain \\n[server.py : 307_353]->syslib_from.logging.getLogger(mcp-server).info","sourceNodeId":"analyze_method_call_chain \\n[server.py : 307_353]","targetNodeId":"syslib_from.logging.getLogger(mcp-server).info"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpSymbolAnalysis/src/mcpSymbolAnalysis/server.py"},"region":{"startLine":321,"startColumn":20,"endLine":331,"endColumn":14,"snippet":{}}}},"id":"analyze_method_call_chain \\n[server.py : 307_353]->/src/mcpSymbolAnalysis/src/mcpSymbolAnalysis/server.analyze_method_call_chain.analyze_method_call_chain_scope..dict","sourceNodeId":"analyze_method_call_chain \\n[server.py : 307_353]","targetNodeId":"/src/mcpSymbolAnalysis/src/mcpSymbolAnalysis/server.analyze_method_call_chain.analyze_method_call_chain_scope..dict"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpSymbolAnalysis/src/mcpSymbolAnalysis/server.py"},"region":{"startLine":320,"startColumn":39,"endLine":332,"endColumn":10,"snippet":{}}}},"id":"analyze_method_call_chain \\n[server.py : 307_353]->mcp_common.remote.codeinsight.code_insight_api.mcp_server_backend_api","sourceNodeId":"analyze_method_call_chain \\n[server.py : 307_353]","targetNodeId":"mcp_common.remote.codeinsight.code_insight_api.mcp_server_backend_api"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpSymbolAnalysis/src/mcpSymbolAnalysis/server.py"},"region":{"startLine":346,"startColumn":35,"endLine":346,"endColumn":80,"snippet":{}}}},"id":"analyze_method_call_chain \\n[server.py : 307_353]->syslib_from.json.dumps","sourceNodeId":"analyze_method_call_chain \\n[server.py : 307_353]","targetNodeId":"syslib_from.json.dumps"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpSymbolAnalysis/src/mcpSymbolAnalysis/server.py"},"region":{"startLine":342,"startColumn":23,"endLine":342,"endColumn":63,"snippet":{}}}},"id":"analyze_method_call_chain \\n[server.py : 307_353]->mcp_common.remote.codeinsight.code_insight_api.mcp_server_backend_api(var params:any=dict(var name:any=Consts.ANALYZE_METHOD_CALL_CHAIN.name, var arguments:any=dict(var appName:any=app_name, var fully...","sourceNodeId":"analyze_method_call_chain \\n[server.py : 307_353]","targetNodeId":"mcp_common.remote.codeinsight.code_insight_api.mcp_server_backend_api(var params:any=dict(var name:any=Consts.ANALYZE_METHOD_CALL_CHAIN.name, var arguments:any=dict(var appName:any=app_name, var fully..."},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpSymbolAnalysis/src/mcpSymbolAnalysis/server.py"},"region":{"startLine":340,"startColumn":23,"endLine":340,"endColumn":58,"snippet":{}}}},"id":"analyze_method_call_chain \\n[server.py : 307_353]->format_content \\n[server.py : 238_259]","sourceNodeId":"analyze_method_call_chain \\n[server.py : 307_353]","targetNodeId":"format_content \\n[server.py : 238_259]"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpSymbolAnalysis/src/mcpSymbolAnalysis/server.py"},"region":{"startLine":345,"startColumn":13,"endLine":346,"endColumn":82,"snippet":{}}}},"id":"analyze_method_call_chain \\n[server.py : 307_353]->syslib_from.logging.getLogger(mcp-server).warning","sourceNodeId":"analyze_method_call_chain \\n[server.py : 307_353]","targetNodeId":"syslib_from.logging.getLogger(mcp-server).warning"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpSymbolAnalysis/src/mcpSymbolAnalysis/server.py"},"region":{"startLine":349,"startColumn":9,"endLine":349,"endColumn":120,"snippet":{}}}},"id":"analyze_method_call_chain \\n[server.py : 307_353]->syslib_from.logging.getLogger(mcp-server).exception","sourceNodeId":"analyze_method_call_chain \\n[server.py : 307_353]","targetNodeId":"syslib_from.logging.getLogger(mcp-server).exception"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpSymbolAnalysis/src/mcpSymbolAnalysis/server.py"},"region":{"startLine":532,"startColumn":23,"endLine":532,"endColumn":105,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 473_580]->/src/mcpSymbolAnalysis/src/mcpSymbolAnalysis/server.handle_call_tool.handle_call_tool_scope....ValueError","sourceNodeId":"handle_call_tool \\n[server.py : 473_580]","targetNodeId":"/src/mcpSymbolAnalysis/src/mcpSymbolAnalysis/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpSymbolAnalysis/src/mcpSymbolAnalysis/server.py"},"region":{"startLine":536,"startColumn":27,"endLine":536,"endColumn":69,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 473_580]->/src/mcpSymbolAnalysis/src/mcpSymbolAnalysis/server.handle_call_tool.handle_call_tool_scope.........resolve_method_reference \\n[server.py : 356_406]","sourceNodeId":"handle_call_tool \\n[server.py : 473_580]","targetNodeId":"resolve_method_reference \\n[server.py : 356_406]"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpSymbolAnalysis/src/mcpSymbolAnalysis/server.py"},"region":{"startLine":396,"startColumn":13,"endLine":396,"endColumn":118,"snippet":{}}}},"id":"resolve_method_reference \\n[server.py : 356_406]->syslib_from.logging.getLogger(mcp-server).info","sourceNodeId":"resolve_method_reference \\n[server.py : 356_406]","targetNodeId":"syslib_from.logging.getLogger(mcp-server).info"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpSymbolAnalysis/src/mcpSymbolAnalysis/server.py"},"region":{"startLine":373,"startColumn":20,"endLine":384,"endColumn":14,"snippet":{}}}},"id":"resolve_method_reference \\n[server.py : 356_406]->/src/mcpSymbolAnalysis/src/mcpSymbolAnalysis/server.resolve_method_reference.resolve_method_reference_scope..dict","sourceNodeId":"resolve_method_reference \\n[server.py : 356_406]","targetNodeId":"/src/mcpSymbolAnalysis/src/mcpSymbolAnalysis/server.resolve_method_reference.resolve_method_reference_scope..dict"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpSymbolAnalysis/src/mcpSymbolAnalysis/server.py"},"region":{"startLine":372,"startColumn":39,"endLine":385,"endColumn":10,"snippet":{}}}},"id":"resolve_method_reference \\n[server.py : 356_406]->mcp_common.remote.codeinsight.code_insight_api.mcp_server_backend_api","sourceNodeId":"resolve_method_reference \\n[server.py : 356_406]","targetNodeId":"mcp_common.remote.codeinsight.code_insight_api.mcp_server_backend_api"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpSymbolAnalysis/src/mcpSymbolAnalysis/server.py"},"region":{"startLine":399,"startColumn":35,"endLine":399,"endColumn":80,"snippet":{}}}},"id":"resolve_method_reference \\n[server.py : 356_406]->syslib_from.json.dumps","sourceNodeId":"resolve_method_reference \\n[server.py : 356_406]","targetNodeId":"syslib_from.json.dumps"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpSymbolAnalysis/src/mcpSymbolAnalysis/server.py"},"region":{"startLine":395,"startColumn":23,"endLine":395,"endColumn":63,"snippet":{}}}},"id":"resolve_method_reference \\n[server.py : 356_406]->mcp_common.remote.codeinsight.code_insight_api.mcp_server_backend_api(var params:any=dict(var name:any=Consts.RESOLVE_METHOD_REFERENCE.name, var arguments:any=dict(var appName:any=app_name, var fullyQ...","sourceNodeId":"resolve_method_reference \\n[server.py : 356_406]","targetNodeId":"mcp_common.remote.codeinsight.code_insight_api.mcp_server_backend_api(var params:any=dict(var name:any=Consts.RESOLVE_METHOD_REFERENCE.name, var arguments:any=dict(var appName:any=app_name, var fullyQ..."},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpSymbolAnalysis/src/mcpSymbolAnalysis/server.py"},"region":{"startLine":393,"startColumn":23,"endLine":393,"endColumn":58,"snippet":{}}}},"id":"resolve_method_reference \\n[server.py : 356_406]->format_content \\n[server.py : 238_259]","sourceNodeId":"resolve_method_reference \\n[server.py : 356_406]","targetNodeId":"format_content \\n[server.py : 238_259]"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpSymbolAnalysis/src/mcpSymbolAnalysis/server.py"},"region":{"startLine":398,"startColumn":13,"endLine":399,"endColumn":82,"snippet":{}}}},"id":"resolve_method_reference \\n[server.py : 356_406]->syslib_from.logging.getLogger(mcp-server).warning","sourceNodeId":"resolve_method_reference \\n[server.py : 356_406]","targetNodeId":"syslib_from.logging.getLogger(mcp-server).warning"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpSymbolAnalysis/src/mcpSymbolAnalysis/server.py"},"region":{"startLine":402,"startColumn":9,"endLine":402,"endColumn":119,"snippet":{}}}},"id":"resolve_method_reference \\n[server.py : 356_406]->syslib_from.logging.getLogger(mcp-server).exception","sourceNodeId":"resolve_method_reference \\n[server.py : 356_406]","targetNodeId":"syslib_from.logging.getLogger(mcp-server).exception"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpSymbolAnalysis/src/mcpSymbolAnalysis/server.py"},"region":{"startLine":558,"startColumn":23,"endLine":558,"endColumn":105,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 473_580]->/src/mcpSymbolAnalysis/src/mcpSymbolAnalysis/server.handle_call_tool.handle_call_tool_scope....ValueError","sourceNodeId":"handle_call_tool \\n[server.py : 473_580]","targetNodeId":"/src/mcpSymbolAnalysis/src/mcpSymbolAnalysis/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpSymbolAnalysis/src/mcpSymbolAnalysis/server.py"},"region":{"startLine":561,"startColumn":23,"endLine":561,"endColumn":96,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 473_580]->/src/mcpSymbolAnalysis/src/mcpSymbolAnalysis/server.handle_call_tool.handle_call_tool_scope....ValueError","sourceNodeId":"handle_call_tool \\n[server.py : 473_580]","targetNodeId":"/src/mcpSymbolAnalysis/src/mcpSymbolAnalysis/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpSymbolAnalysis/src/mcpSymbolAnalysis/server.py"},"region":{"startLine":568,"startColumn":19,"endLine":574,"endColumn":14,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 473_580]->resolve_method_callee \\n[server.py : 409_453]","sourceNodeId":"handle_call_tool \\n[server.py : 473_580]","targetNodeId":"resolve_method_callee \\n[server.py : 409_453]"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpSymbolAnalysis/src/mcpSymbolAnalysis/server.py"},"region":{"startLine":443,"startColumn":13,"endLine":443,"endColumn":115,"snippet":{}}}},"id":"resolve_method_callee \\n[server.py : 409_453]->syslib_from.logging.getLogger(mcp-server).info","sourceNodeId":"resolve_method_callee \\n[server.py : 409_453]","targetNodeId":"syslib_from.logging.getLogger(mcp-server).info"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpSymbolAnalysis/src/mcpSymbolAnalysis/server.py"},"region":{"startLine":422,"startColumn":20,"endLine":431,"endColumn":14,"snippet":{}}}},"id":"resolve_method_callee \\n[server.py : 409_453]->/src/mcpSymbolAnalysis/src/mcpSymbolAnalysis/server.resolve_method_callee.resolve_method_callee_scope..dict","sourceNodeId":"resolve_method_callee \\n[server.py : 409_453]","targetNodeId":"/src/mcpSymbolAnalysis/src/mcpSymbolAnalysis/server.resolve_method_callee.resolve_method_callee_scope..dict"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpSymbolAnalysis/src/mcpSymbolAnalysis/server.py"},"region":{"startLine":421,"startColumn":39,"endLine":432,"endColumn":10,"snippet":{}}}},"id":"resolve_method_callee \\n[server.py : 409_453]->mcp_common.remote.codeinsight.code_insight_api.mcp_server_backend_api","sourceNodeId":"resolve_method_callee \\n[server.py : 409_453]","targetNodeId":"mcp_common.remote.codeinsight.code_insight_api.mcp_server_backend_api"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpSymbolAnalysis/src/mcpSymbolAnalysis/server.py"},"region":{"startLine":446,"startColumn":35,"endLine":446,"endColumn":80,"snippet":{}}}},"id":"resolve_method_callee \\n[server.py : 409_453]->syslib_from.json.dumps","sourceNodeId":"resolve_method_callee \\n[server.py : 409_453]","targetNodeId":"syslib_from.json.dumps"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpSymbolAnalysis/src/mcpSymbolAnalysis/server.py"},"region":{"startLine":442,"startColumn":23,"endLine":442,"endColumn":63,"snippet":{}}}},"id":"resolve_method_callee \\n[server.py : 409_453]->mcp_common.remote.codeinsight.code_insight_api.mcp_server_backend_api(var params:any=dict(var name:any=Consts.RESOLVE_METHOD_CALLEE.name, var arguments:any=dict(var appName:any=app_name, var fullyQual...","sourceNodeId":"resolve_method_callee \\n[server.py : 409_453]","targetNodeId":"mcp_common.remote.codeinsight.code_insight_api.mcp_server_backend_api(var params:any=dict(var name:any=Consts.RESOLVE_METHOD_CALLEE.name, var arguments:any=dict(var appName:any=app_name, var fullyQual..."},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpSymbolAnalysis/src/mcpSymbolAnalysis/server.py"},"region":{"startLine":445,"startColumn":13,"endLine":446,"endColumn":82,"snippet":{}}}},"id":"resolve_method_callee \\n[server.py : 409_453]->syslib_from.logging.getLogger(mcp-server).warning","sourceNodeId":"resolve_method_callee \\n[server.py : 409_453]","targetNodeId":"syslib_from.logging.getLogger(mcp-server).warning"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpSymbolAnalysis/src/mcpSymbolAnalysis/server.py"},"region":{"startLine":449,"startColumn":9,"endLine":449,"endColumn":116,"snippet":{}}}},"id":"resolve_method_callee \\n[server.py : 409_453]->syslib_from.logging.getLogger(mcp-server).exception","sourceNodeId":"resolve_method_callee \\n[server.py : 409_453]","targetNodeId":"syslib_from.logging.getLogger(mcp-server).exception"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpSymbolAnalysis/src/mcpSymbolAnalysis/server.py"},"region":{"startLine":580,"startColumn":19,"endLine":580,"endColumn":54,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 473_580]->/src/mcpSymbolAnalysis/src/mcpSymbolAnalysis/server.handle_call_tool.handle_call_tool_scope...ValueError","sourceNodeId":"handle_call_tool \\n[server.py : 473_580]","targetNodeId":"/src/mcpSymbolAnalysis/src/mcpSymbolAnalysis/server.handle_call_tool.handle_call_tool_scope...ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpTemplate/src/mcpTemplate/server.py"},"region":{"startLine":7,"startColumn":1,"endLine":8,"endColumn":17,"snippet":{}}}},"id":"<__entry_point__>->add \\n[server.py : 7_8]","sourceNodeId":"<__entry_point__>","targetNodeId":"add \\n[server.py : 7_8]"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpTestAnalysis/src/mcpTestAnalysis/server.py"},"region":{"startLine":55,"startColumn":1,"endLine":77,"endColumn":67,"snippet":{}}}},"id":"<__entry_point__>->handle_call_tool \\n[server.py : 55_77]","sourceNodeId":"<__entry_point__>","targetNodeId":"handle_call_tool \\n[server.py : 55_77]"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpTestAnalysis/src/mcpTestAnalysis/server.py"},"region":{"startLine":69,"startColumn":23,"endLine":69,"endColumn":67,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 55_77]->/src/mcpTestAnalysis/src/mcpTestAnalysis/server.handle_call_tool.handle_call_tool_scope....ValueError","sourceNodeId":"handle_call_tool \\n[server.py : 55_77]","targetNodeId":"/src/mcpTestAnalysis/src/mcpTestAnalysis/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpTestAnalysis/src/mcpTestAnalysis/server.py"},"region":{"startLine":70,"startColumn":27,"endLine":70,"endColumn":86,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 55_77]->syslib_from.client.get_code_diffs","sourceNodeId":"handle_call_tool \\n[server.py : 55_77]","targetNodeId":"syslib_from.client.get_code_diffs"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpTestAnalysis/src/mcpTestAnalysis/server.py"},"region":{"startLine":76,"startColumn":19,"endLine":76,"endColumn":54,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 55_77]->/src/mcpTestAnalysis/src/mcpTestAnalysis/server.handle_call_tool.handle_call_tool_scope...ValueError","sourceNodeId":"handle_call_tool \\n[server.py : 55_77]","targetNodeId":"/src/mcpTestAnalysis/src/mcpTestAnalysis/server.handle_call_tool.handle_call_tool_scope...ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpTestAnalysisDocument/src/mcpTestAnalysisDocument/server.py"},"region":{"startLine":106,"startColumn":1,"endLine":153,"endColumn":54,"snippet":{}}}},"id":"<__entry_point__>->handle_call_tool \\n[server.py : 106_153]","sourceNodeId":"<__entry_point__>","targetNodeId":"handle_call_tool \\n[server.py : 106_153]"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpTestAnalysisDocument/src/mcpTestAnalysisDocument/server.py"},"region":{"startLine":116,"startColumn":23,"endLine":116,"endColumn":53,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 106_153]->/src/mcpTestAnalysisDocument/src/mcpTestAnalysisDocument/server.handle_call_tool.handle_call_tool_scope....ValueError","sourceNodeId":"handle_call_tool \\n[server.py : 106_153]","targetNodeId":"/src/mcpTestAnalysisDocument/src/mcpTestAnalysisDocument/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpTestAnalysisDocument/src/mcpTestAnalysisDocument/server.py"},"region":{"startLine":118,"startColumn":23,"endLine":118,"endColumn":61,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 106_153]->/src/mcpTestAnalysisDocument/src/mcpTestAnalysisDocument/server.handle_call_tool.handle_call_tool_scope....ValueError","sourceNodeId":"handle_call_tool \\n[server.py : 106_153]","targetNodeId":"/src/mcpTestAnalysisDocument/src/mcpTestAnalysisDocument/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpTestAnalysisDocument/src/mcpTestAnalysisDocument/server.py"},"region":{"startLine":119,"startColumn":27,"endLine":119,"endColumn":91,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 106_153]->syslib_from.report_client.write_document","sourceNodeId":"handle_call_tool \\n[server.py : 106_153]","targetNodeId":"syslib_from.report_client.write_document"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpTestAnalysisDocument/src/mcpTestAnalysisDocument/server.py"},"region":{"startLine":151,"startColumn":21,"endLine":151,"endColumn":74,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 106_153]->syslib_from.mcp/types.TextContent","sourceNodeId":"handle_call_tool \\n[server.py : 106_153]","targetNodeId":"syslib_from.mcp/types.TextContent"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpTestAnalysisDocument/src/mcpTestAnalysisDocument/server.py"},"region":{"startLine":123,"startColumn":23,"endLine":123,"endColumn":53,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 106_153]->/src/mcpTestAnalysisDocument/src/mcpTestAnalysisDocument/server.handle_call_tool.handle_call_tool_scope....ValueError","sourceNodeId":"handle_call_tool \\n[server.py : 106_153]","targetNodeId":"/src/mcpTestAnalysisDocument/src/mcpTestAnalysisDocument/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpTestAnalysisDocument/src/mcpTestAnalysisDocument/server.py"},"region":{"startLine":125,"startColumn":23,"endLine":125,"endColumn":62,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 106_153]->/src/mcpTestAnalysisDocument/src/mcpTestAnalysisDocument/server.handle_call_tool.handle_call_tool_scope....ValueError","sourceNodeId":"handle_call_tool \\n[server.py : 106_153]","targetNodeId":"/src/mcpTestAnalysisDocument/src/mcpTestAnalysisDocument/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpTestAnalysisDocument/src/mcpTestAnalysisDocument/server.py"},"region":{"startLine":126,"startColumn":27,"endLine":126,"endColumn":123,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 106_153]->syslib_from.yuque_markdown.fetch_yuque_document_split_block_remain_pic","sourceNodeId":"handle_call_tool \\n[server.py : 106_153]","targetNodeId":"syslib_from.yuque_markdown.fetch_yuque_document_split_block_remain_pic"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpTestAnalysisDocument/src/mcpTestAnalysisDocument/server.py"},"region":{"startLine":130,"startColumn":23,"endLine":130,"endColumn":53,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 106_153]->/src/mcpTestAnalysisDocument/src/mcpTestAnalysisDocument/server.handle_call_tool.handle_call_tool_scope....ValueError","sourceNodeId":"handle_call_tool \\n[server.py : 106_153]","targetNodeId":"/src/mcpTestAnalysisDocument/src/mcpTestAnalysisDocument/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpTestAnalysisDocument/src/mcpTestAnalysisDocument/server.py"},"region":{"startLine":132,"startColumn":23,"endLine":132,"endColumn":62,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 106_153]->/src/mcpTestAnalysisDocument/src/mcpTestAnalysisDocument/server.handle_call_tool.handle_call_tool_scope....ValueError","sourceNodeId":"handle_call_tool \\n[server.py : 106_153]","targetNodeId":"/src/mcpTestAnalysisDocument/src/mcpTestAnalysisDocument/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpTestAnalysisDocument/src/mcpTestAnalysisDocument/server.py"},"region":{"startLine":133,"startColumn":27,"endLine":133,"endColumn":93,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 106_153]->syslib_from.yuque_markdown.chat_with_pic","sourceNodeId":"handle_call_tool \\n[server.py : 106_153]","targetNodeId":"syslib_from.yuque_markdown.chat_with_pic"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpTestAnalysisDocument/src/mcpTestAnalysisDocument/server.py"},"region":{"startLine":137,"startColumn":23,"endLine":137,"endColumn":53,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 106_153]->/src/mcpTestAnalysisDocument/src/mcpTestAnalysisDocument/server.handle_call_tool.handle_call_tool_scope....ValueError","sourceNodeId":"handle_call_tool \\n[server.py : 106_153]","targetNodeId":"/src/mcpTestAnalysisDocument/src/mcpTestAnalysisDocument/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpTestAnalysisDocument/src/mcpTestAnalysisDocument/server.py"},"region":{"startLine":139,"startColumn":23,"endLine":139,"endColumn":61,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 106_153]->/src/mcpTestAnalysisDocument/src/mcpTestAnalysisDocument/server.handle_call_tool.handle_call_tool_scope....ValueError","sourceNodeId":"handle_call_tool \\n[server.py : 106_153]","targetNodeId":"/src/mcpTestAnalysisDocument/src/mcpTestAnalysisDocument/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpTestAnalysisDocument/src/mcpTestAnalysisDocument/server.py"},"region":{"startLine":140,"startColumn":27,"endLine":140,"endColumn":95,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 106_153]->syslib_from.yuque_markdown.get_dima_document","sourceNodeId":"handle_call_tool \\n[server.py : 106_153]","targetNodeId":"syslib_from.yuque_markdown.get_dima_document"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpTestAnalysisDocument/src/mcpTestAnalysisDocument/server.py"},"region":{"startLine":144,"startColumn":23,"endLine":144,"endColumn":67,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 106_153]->/src/mcpTestAnalysisDocument/src/mcpTestAnalysisDocument/server.handle_call_tool.handle_call_tool_scope....ValueError","sourceNodeId":"handle_call_tool \\n[server.py : 106_153]","targetNodeId":"/src/mcpTestAnalysisDocument/src/mcpTestAnalysisDocument/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpTestAnalysisDocument/src/mcpTestAnalysisDocument/server.py"},"region":{"startLine":145,"startColumn":27,"endLine":145,"endColumn":86,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 106_153]->syslib_from.client.get_code_diffs","sourceNodeId":"handle_call_tool \\n[server.py : 106_153]","targetNodeId":"syslib_from.client.get_code_diffs"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpTestAnalysisDocument/src/mcpTestAnalysisDocument/server.py"},"region":{"startLine":149,"startColumn":23,"endLine":149,"endColumn":71,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 106_153]->/src/mcpTestAnalysisDocument/src/mcpTestAnalysisDocument/server.handle_call_tool.handle_call_tool_scope....ValueError","sourceNodeId":"handle_call_tool \\n[server.py : 106_153]","targetNodeId":"/src/mcpTestAnalysisDocument/src/mcpTestAnalysisDocument/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpTestAnalysisDocument/src/mcpTestAnalysisDocument/server.py"},"region":{"startLine":150,"startColumn":27,"endLine":150,"endColumn":97,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 106_153]->syslib_from.client.get_branch_prompt","sourceNodeId":"handle_call_tool \\n[server.py : 106_153]","targetNodeId":"syslib_from.client.get_branch_prompt"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpTestAnalysisDocument/src/mcpTestAnalysisDocument/server.py"},"region":{"startLine":153,"startColumn":19,"endLine":153,"endColumn":54,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 106_153]->/src/mcpTestAnalysisDocument/src/mcpTestAnalysisDocument/server.handle_call_tool.handle_call_tool_scope...ValueError","sourceNodeId":"handle_call_tool \\n[server.py : 106_153]","targetNodeId":"/src/mcpTestAnalysisDocument/src/mcpTestAnalysisDocument/server.handle_call_tool.handle_call_tool_scope...ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpTvp/src/mcpTvp/server.py"},"region":{"startLine":79,"startColumn":1,"endLine":118,"endColumn":54,"snippet":{}}}},"id":"<__entry_point__>->handle_call_tool \\n[server.py : 79_118]","sourceNodeId":"<__entry_point__>","targetNodeId":"handle_call_tool \\n[server.py : 79_118]"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpTvp/src/mcpTvp/server.py"},"region":{"startLine":87,"startColumn":69,"endLine":87,"endColumn":112,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 79_118]->/src/mcpTvp/src/mcpTvp/server.handle_call_tool.handle_call_tool_scope..json.dumps","sourceNodeId":"handle_call_tool \\n[server.py : 79_118]","targetNodeId":"/src/mcpTvp/src/mcpTvp/server.handle_call_tool.handle_call_tool_scope..json.dumps"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpTvp/src/mcpTvp/server.py"},"region":{"startLine":86,"startColumn":5,"endLine":87,"endColumn":114,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 79_118]->/src/mcpTvp/src/mcpTvp/server.handle_call_tool.handle_call_tool_scope..info_logger.info","sourceNodeId":"handle_call_tool \\n[server.py : 79_118]","targetNodeId":"/src/mcpTvp/src/mcpTvp/server.handle_call_tool.handle_call_tool_scope..info_logger.info"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpTvp/src/mcpTvp/server.py"},"region":{"startLine":91,"startColumn":23,"endLine":91,"endColumn":53,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 79_118]->/src/mcpTvp/src/mcpTvp/server.handle_call_tool.handle_call_tool_scope....ValueError","sourceNodeId":"handle_call_tool \\n[server.py : 79_118]","targetNodeId":"/src/mcpTvp/src/mcpTvp/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpTvp/src/mcpTvp/server.py"},"region":{"startLine":93,"startColumn":23,"endLine":93,"endColumn":60,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 79_118]->/src/mcpTvp/src/mcpTvp/server.handle_call_tool.handle_call_tool_scope....ValueError","sourceNodeId":"handle_call_tool \\n[server.py : 79_118]","targetNodeId":"/src/mcpTvp/src/mcpTvp/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpTvp/src/mcpTvp/server.py"},"region":{"startLine":115,"startColumn":65,"endLine":115,"endColumn":89,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 79_118]->/src/mcpTvp/src/mcpTvp/server.handle_call_tool.arguments.get","sourceNodeId":"handle_call_tool \\n[server.py : 79_118]","targetNodeId":"/src/mcpTvp/src/mcpTvp/server.handle_call_tool.arguments.get"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpTvp/src/mcpTvp/server.py"},"region":{"startLine":94,"startColumn":23,"endLine":94,"endColumn":83,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 79_118]->/src/mcpTvp/src/mcpTvp/server.handle_call_tool.handle_call_tool_scope...execute_cypress_script","sourceNodeId":"handle_call_tool \\n[server.py : 79_118]","targetNodeId":"/src/mcpTvp/src/mcpTvp/server.handle_call_tool.handle_call_tool_scope...execute_cypress_script"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpTvp/src/mcpTvp/server.py"},"region":{"startLine":116,"startColumn":21,"endLine":116,"endColumn":65,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 79_118]->syslib_from.mcp/types.TextContent","sourceNodeId":"handle_call_tool \\n[server.py : 79_118]","targetNodeId":"syslib_from.mcp/types.TextContent"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpTvp/src/mcpTvp/server.py"},"region":{"startLine":98,"startColumn":23,"endLine":98,"endColumn":53,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 79_118]->/src/mcpTvp/src/mcpTvp/server.handle_call_tool.handle_call_tool_scope....ValueError","sourceNodeId":"handle_call_tool \\n[server.py : 79_118]","targetNodeId":"/src/mcpTvp/src/mcpTvp/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpTvp/src/mcpTvp/server.py"},"region":{"startLine":100,"startColumn":23,"endLine":100,"endColumn":60,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 79_118]->/src/mcpTvp/src/mcpTvp/server.handle_call_tool.handle_call_tool_scope....ValueError","sourceNodeId":"handle_call_tool \\n[server.py : 79_118]","targetNodeId":"/src/mcpTvp/src/mcpTvp/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpTvp/src/mcpTvp/server.py"},"region":{"startLine":101,"startColumn":23,"endLine":101,"endColumn":86,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 79_118]->/src/mcpTvp/src/mcpTvp/server.handle_call_tool.handle_call_tool_scope...execute_playwright_script","sourceNodeId":"handle_call_tool \\n[server.py : 79_118]","targetNodeId":"/src/mcpTvp/src/mcpTvp/server.handle_call_tool.handle_call_tool_scope...execute_playwright_script"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpTvp/src/mcpTvp/server.py"},"region":{"startLine":105,"startColumn":23,"endLine":105,"endColumn":53,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 79_118]->/src/mcpTvp/src/mcpTvp/server.handle_call_tool.handle_call_tool_scope....ValueError","sourceNodeId":"handle_call_tool \\n[server.py : 79_118]","targetNodeId":"/src/mcpTvp/src/mcpTvp/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpTvp/src/mcpTvp/server.py"},"region":{"startLine":107,"startColumn":23,"endLine":107,"endColumn":61,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 79_118]->/src/mcpTvp/src/mcpTvp/server.handle_call_tool.handle_call_tool_scope....ValueError","sourceNodeId":"handle_call_tool \\n[server.py : 79_118]","targetNodeId":"/src/mcpTvp/src/mcpTvp/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpTvp/src/mcpTvp/server.py"},"region":{"startLine":108,"startColumn":23,"endLine":108,"endColumn":90,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 79_118]->/src/mcpTvp/src/mcpTvp/server.handle_call_tool.handle_call_tool_scope...query_script_execute_status","sourceNodeId":"handle_call_tool \\n[server.py : 79_118]","targetNodeId":"/src/mcpTvp/src/mcpTvp/server.handle_call_tool.handle_call_tool_scope...query_script_execute_status"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpTvp/src/mcpTvp/server.py"},"region":{"startLine":112,"startColumn":23,"endLine":112,"endColumn":53,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 79_118]->/src/mcpTvp/src/mcpTvp/server.handle_call_tool.handle_call_tool_scope....ValueError","sourceNodeId":"handle_call_tool \\n[server.py : 79_118]","targetNodeId":"/src/mcpTvp/src/mcpTvp/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpTvp/src/mcpTvp/server.py"},"region":{"startLine":114,"startColumn":23,"endLine":114,"endColumn":61,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 79_118]->/src/mcpTvp/src/mcpTvp/server.handle_call_tool.handle_call_tool_scope....ValueError","sourceNodeId":"handle_call_tool \\n[server.py : 79_118]","targetNodeId":"/src/mcpTvp/src/mcpTvp/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpTvp/src/mcpTvp/server.py"},"region":{"startLine":115,"startColumn":23,"endLine":115,"endColumn":90,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 79_118]->/src/mcpTvp/src/mcpTvp/server.handle_call_tool.handle_call_tool_scope...query_script_execute_result","sourceNodeId":"handle_call_tool \\n[server.py : 79_118]","targetNodeId":"/src/mcpTvp/src/mcpTvp/server.handle_call_tool.handle_call_tool_scope...query_script_execute_result"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpTvp/src/mcpTvp/server.py"},"region":{"startLine":118,"startColumn":19,"endLine":118,"endColumn":54,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 79_118]->/src/mcpTvp/src/mcpTvp/server.handle_call_tool.handle_call_tool_scope...ValueError","sourceNodeId":"handle_call_tool \\n[server.py : 79_118]","targetNodeId":"/src/mcpTvp/src/mcpTvp/server.handle_call_tool.handle_call_tool_scope...ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpUtils/src/mcpUtils/server.py"},"region":{"startLine":35,"startColumn":1,"endLine":47,"endColumn":54,"snippet":{}}}},"id":"<__entry_point__>->handle_call_tool \\n[server.py : 35_47]","sourceNodeId":"<__entry_point__>","targetNodeId":"handle_call_tool \\n[server.py : 35_47]"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpUtils/src/mcpUtils/server.py"},"region":{"startLine":44,"startColumn":27,"endLine":44,"endColumn":51,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 35_47]->get_current_time \\n[server.py : 9_10]","sourceNodeId":"handle_call_tool \\n[server.py : 35_47]","targetNodeId":"get_current_time \\n[server.py : 9_10]"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpUtils/src/mcpUtils/server.py"},"region":{"startLine":10,"startColumn":12,"endLine":10,"endColumn":35,"snippet":{}}}},"id":"get_current_time \\n[server.py : 9_10]->syslib_from.datetime.datetime.now","sourceNodeId":"get_current_time \\n[server.py : 9_10]","targetNodeId":"syslib_from.datetime.datetime.now"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpUtils/src/mcpUtils/server.py"},"region":{"startLine":10,"startColumn":12,"endLine":10,"endColumn":65,"snippet":{}}}},"id":"get_current_time \\n[server.py : 9_10]->syslib_from.datetime.datetime.now().strftime","sourceNodeId":"get_current_time \\n[server.py : 9_10]","targetNodeId":"syslib_from.datetime.datetime.now().strftime"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpUtils/src/mcpUtils/server.py"},"region":{"startLine":45,"startColumn":21,"endLine":45,"endColumn":69,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 35_47]->syslib_from.mcp/types.TextContent","sourceNodeId":"handle_call_tool \\n[server.py : 35_47]","targetNodeId":"syslib_from.mcp/types.TextContent"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpUtils/src/mcpUtils/server.py"},"region":{"startLine":47,"startColumn":19,"endLine":47,"endColumn":54,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 35_47]->/src/mcpUtils/src/mcpUtils/server.handle_call_tool.handle_call_tool_scope...ValueError","sourceNodeId":"handle_call_tool \\n[server.py : 35_47]","targetNodeId":"/src/mcpUtils/src/mcpUtils/server.handle_call_tool.handle_call_tool_scope...ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpVarySearch/src/mcpVarySearch/server.py"},"region":{"startLine":41,"startColumn":1,"endLine":71,"endColumn":6,"snippet":{}}}},"id":"<__entry_point__>->handle_call_tool \\n[server.py : 41_71]","sourceNodeId":"<__entry_point__>","targetNodeId":"handle_call_tool \\n[server.py : 41_71]"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpVarySearch/src/mcpVarySearch/server.py"},"region":{"startLine":69,"startColumn":18,"endLine":69,"endColumn":54,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 41_71]->syslib_from.json.dumps","sourceNodeId":"handle_call_tool \\n[server.py : 41_71]","targetNodeId":"syslib_from.json.dumps"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpVarySearch/src/mcpVarySearch/server.py"},"region":{"startLine":48,"startColumn":5,"endLine":49,"endColumn":115,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 41_71]->syslib_from.logging.getLogger(mcp-server).info","sourceNodeId":"handle_call_tool \\n[server.py : 41_71]","targetNodeId":"syslib_from.logging.getLogger(mcp-server).info"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpVarySearch/src/mcpVarySearch/server.py"},"region":{"startLine":51,"startColumn":15,"endLine":51,"endColumn":50,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 41_71]->/src/mcpVarySearch/src/mcpVarySearch/server.handle_call_tool.handle_call_tool_scope...ValueError","sourceNodeId":"handle_call_tool \\n[server.py : 41_71]","targetNodeId":"/src/mcpVarySearch/src/mcpVarySearch/server.handle_call_tool.handle_call_tool_scope...ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpVarySearch/src/mcpVarySearch/server.py"},"region":{"startLine":54,"startColumn":15,"endLine":54,"endColumn":46,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 41_71]->/src/mcpVarySearch/src/mcpVarySearch/server.handle_call_tool.handle_call_tool_scope...ValueError","sourceNodeId":"handle_call_tool \\n[server.py : 41_71]","targetNodeId":"/src/mcpVarySearch/src/mcpVarySearch/server.handle_call_tool.handle_call_tool_scope...ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpVarySearch/src/mcpVarySearch/server.py"},"region":{"startLine":58,"startColumn":16,"endLine":58,"endColumn":41,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 41_71]->/src/mcpVarySearch/src/mcpVarySearch/server.handle_call_tool.arguments.get","sourceNodeId":"handle_call_tool \\n[server.py : 41_71]","targetNodeId":"/src/mcpVarySearch/src/mcpVarySearch/server.handle_call_tool.arguments.get"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpVarySearch/src/mcpVarySearch/server.py"},"region":{"startLine":61,"startColumn":15,"endLine":61,"endColumn":71,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 41_71]->/src/mcpVarySearch/src/mcpVarySearch/server.handle_call_tool.handle_call_tool_scope...ValueError","sourceNodeId":"handle_call_tool \\n[server.py : 41_71]","targetNodeId":"/src/mcpVarySearch/src/mcpVarySearch/server.handle_call_tool.handle_call_tool_scope...ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpVarySearch/src/mcpVarySearch/server.py"},"region":{"startLine":64,"startColumn":12,"endLine":64,"endColumn":90,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 41_71]->vary_search \\n[server.py : 91_130]","sourceNodeId":"handle_call_tool \\n[server.py : 41_71]","targetNodeId":"vary_search \\n[server.py : 91_130]"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpVarySearch/src/mcpVarySearch/server.py"},"region":{"startLine":108,"startColumn":19,"endLine":108,"endColumn":49,"snippet":{}}}},"id":"vary_search \\n[server.py : 91_130]->syslib_from.pytz.timezone","sourceNodeId":"vary_search \\n[server.py : 91_130]","targetNodeId":"syslib_from.pytz.timezone"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpVarySearch/src/mcpVarySearch/server.py"},"region":{"startLine":112,"startColumn":49,"endLine":112,"endColumn":80,"snippet":{}}}},"id":"vary_search \\n[server.py : 91_130]->datetime.datetime.strptime","sourceNodeId":"vary_search \\n[server.py : 91_130]","targetNodeId":"datetime.datetime.strptime"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpVarySearch/src/mcpVarySearch/server.py"},"region":{"startLine":112,"startColumn":28,"endLine":112,"endColumn":81,"snippet":{}}}},"id":"vary_search \\n[server.py : 91_130]->syslib_from.pytz.timezone(Asia/Shanghai).localize","sourceNodeId":"vary_search \\n[server.py : 91_130]","targetNodeId":"syslib_from.pytz.timezone(Asia/Shanghai).localize"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpVarySearch/src/mcpVarySearch/server.py"},"region":{"startLine":111,"startColumn":30,"endLine":111,"endColumn":97,"snippet":{}}}},"id":"vary_search \\n[server.py : 91_130]->syslib_from.pytz.timezone(Asia/Shanghai).localize(datetime.strptime(start_time, ft)).timestamp","sourceNodeId":"vary_search \\n[server.py : 91_130]","targetNodeId":"syslib_from.pytz.timezone(Asia/Shanghai).localize(datetime.strptime(start_time, ft)).timestamp"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpVarySearch/src/mcpVarySearch/server.py"},"region":{"startLine":112,"startColumn":24,"endLine":112,"endColumn":101,"snippet":{}}}},"id":"vary_search \\n[server.py : 91_130]->int","sourceNodeId":"vary_search \\n[server.py : 91_130]","targetNodeId":"int"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpVarySearch/src/mcpVarySearch/server.py"},"region":{"startLine":112,"startColumn":28,"endLine":112,"endColumn":93,"snippet":{}}}},"id":"vary_search \\n[server.py : 91_130]->syslib_from.pytz.timezone(Asia/Shanghai).localize(datetime.strptime(end_time, ft)).timestamp","sourceNodeId":"vary_search \\n[server.py : 91_130]","targetNodeId":"syslib_from.pytz.timezone(Asia/Shanghai).localize(datetime.strptime(end_time, ft)).timestamp"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpVarySearch/src/mcpVarySearch/server.py"},"region":{"startLine":116,"startColumn":20,"endLine":120,"endColumn":10,"snippet":{}}}},"id":"vary_search \\n[server.py : 91_130]->syslib_from.requests.post","sourceNodeId":"vary_search \\n[server.py : 91_130]","targetNodeId":"syslib_from.requests.post"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpVarySearch/src/mcpVarySearch/server.py"},"region":{"startLine":121,"startColumn":9,"endLine":121,"endColumn":36,"snippet":{}}}},"id":"vary_search \\n[server.py : 91_130]->syslib_from.requests.post(url, var headers:any=headers, var json:any=payload).raise_for_status","sourceNodeId":"vary_search \\n[server.py : 91_130]","targetNodeId":"syslib_from.requests.post(url, var headers:any=headers, var json:any=payload).raise_for_status"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpVarySearch/src/mcpVarySearch/server.py"},"region":{"startLine":122,"startColumn":18,"endLine":122,"endColumn":33,"snippet":{}}}},"id":"vary_search \\n[server.py : 91_130]->syslib_from.requests.post(url, var headers:any=headers, var json:any=payload).json","sourceNodeId":"vary_search \\n[server.py : 91_130]","targetNodeId":"syslib_from.requests.post(url, var headers:any=headers, var json:any=payload).json"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpVarySearch/src/mcpVarySearch/server.py"},"region":{"startLine":125,"startColumn":31,"endLine":125,"endColumn":51,"snippet":{}}}},"id":"vary_search \\n[server.py : 91_130]->syslib_from.requests.post(url, var headers:any=headers, var json:any=payload).json().get","sourceNodeId":"vary_search \\n[server.py : 91_130]","targetNodeId":"syslib_from.requests.post(url, var headers:any=headers, var json:any=payload).json().get"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpVarySearch/src/mcpVarySearch/server.py"},"region":{"startLine":124,"startColumn":13,"endLine":124,"endColumn":90,"snippet":{}}}},"id":"vary_search \\n[server.py : 91_130]->syslib_from.logging.getLogger(mcp-server).info","sourceNodeId":"vary_search \\n[server.py : 91_130]","targetNodeId":"syslib_from.logging.getLogger(mcp-server).info"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpVarySearch/src/mcpVarySearch/server.py"},"region":{"startLine":125,"startColumn":20,"endLine":125,"endColumn":72,"snippet":{}}}},"id":"vary_search \\n[server.py : 91_130]->payload.dumps","sourceNodeId":"vary_search \\n[server.py : 91_130]","targetNodeId":"payload.dumps"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpVarySearch/src/mcpVarySearch/server.py"},"region":{"startLine":126,"startColumn":9,"endLine":126,"endColumn":89,"snippet":{}}}},"id":"vary_search \\n[server.py : 91_130]->syslib_from.logging.getLogger(mcp-server).warning","sourceNodeId":"vary_search \\n[server.py : 91_130]","targetNodeId":"syslib_from.logging.getLogger(mcp-server).warning"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpVarySearch/src/mcpVarySearch/server.py"},"region":{"startLine":129,"startColumn":79,"endLine":129,"endColumn":87,"snippet":{}}}},"id":"vary_search \\n[server.py : 91_130]->/src/mcpVarySearch/src/mcpVarySearch/server.vary_search.vary_search_scope...str","sourceNodeId":"vary_search \\n[server.py : 91_130]","targetNodeId":"/src/mcpVarySearch/src/mcpVarySearch/server.vary_search.vary_search_scope...str"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpVarySearch/src/mcpVarySearch/server.py"},"region":{"startLine":129,"startColumn":9,"endLine":129,"endColumn":89,"snippet":{}}}},"id":"vary_search \\n[server.py : 91_130]->syslib_from.logging.getLogger(mcp-server).error","sourceNodeId":"vary_search \\n[server.py : 91_130]","targetNodeId":"syslib_from.logging.getLogger(mcp-server).error"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpVarySearch/src/mcpVarySearch/server.py"},"region":{"startLine":67,"startColumn":9,"endLine":70,"endColumn":10,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 41_71]->syslib_from.mcp/types.TextContent","sourceNodeId":"handle_call_tool \\n[server.py : 41_71]","targetNodeId":"syslib_from.mcp/types.TextContent"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpYuntu/src/mcpYuntu/server.py"},"region":{"startLine":170,"startColumn":1,"endLine":267,"endColumn":54,"snippet":{}}}},"id":"<__entry_point__>->handle_call_tool \\n[server.py : 170_267]","sourceNodeId":"<__entry_point__>","targetNodeId":"handle_call_tool \\n[server.py : 170_267]"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpYuntu/src/mcpYuntu/server.py"},"region":{"startLine":178,"startColumn":64,"endLine":178,"endColumn":107,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 170_267]->/src/mcpYuntu/src/mcpYuntu/server.handle_call_tool.handle_call_tool_scope..json.dumps","sourceNodeId":"handle_call_tool \\n[server.py : 170_267]","targetNodeId":"/src/mcpYuntu/src/mcpYuntu/server.handle_call_tool.handle_call_tool_scope..json.dumps"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpYuntu/src/mcpYuntu/server.py"},"region":{"startLine":177,"startColumn":5,"endLine":178,"endColumn":109,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 170_267]->/src/mcpYuntu/src/mcpYuntu/server.handle_call_tool.handle_call_tool_scope..info_logger.info","sourceNodeId":"handle_call_tool \\n[server.py : 170_267]","targetNodeId":"/src/mcpYuntu/src/mcpYuntu/server.handle_call_tool.handle_call_tool_scope..info_logger.info"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpYuntu/src/mcpYuntu/server.py"},"region":{"startLine":182,"startColumn":23,"endLine":182,"endColumn":53,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 170_267]->/src/mcpYuntu/src/mcpYuntu/server.handle_call_tool.handle_call_tool_scope....ValueError","sourceNodeId":"handle_call_tool \\n[server.py : 170_267]","targetNodeId":"/src/mcpYuntu/src/mcpYuntu/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpYuntu/src/mcpYuntu/server.py"},"region":{"startLine":184,"startColumn":23,"endLine":184,"endColumn":62,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 170_267]->/src/mcpYuntu/src/mcpYuntu/server.handle_call_tool.handle_call_tool_scope....ValueError","sourceNodeId":"handle_call_tool \\n[server.py : 170_267]","targetNodeId":"/src/mcpYuntu/src/mcpYuntu/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpYuntu/src/mcpYuntu/server.py"},"region":{"startLine":186,"startColumn":23,"endLine":186,"endColumn":64,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 170_267]->/src/mcpYuntu/src/mcpYuntu/server.handle_call_tool.handle_call_tool_scope....ValueError","sourceNodeId":"handle_call_tool \\n[server.py : 170_267]","targetNodeId":"/src/mcpYuntu/src/mcpYuntu/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpYuntu/src/mcpYuntu/server.py"},"region":{"startLine":187,"startColumn":27,"endLine":188,"endColumn":88,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 170_267]->/src/mcpYuntu/src/mcpYuntu/server.handle_call_tool.handle_call_tool_scope...get_yuntu_call_tree","sourceNodeId":"handle_call_tool \\n[server.py : 170_267]","targetNodeId":"/src/mcpYuntu/src/mcpYuntu/server.handle_call_tool.handle_call_tool_scope...get_yuntu_call_tree"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpYuntu/src/mcpYuntu/server.py"},"region":{"startLine":189,"startColumn":57,"endLine":189,"endColumn":82,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 170_267]->yuntu_util.sample_trace","sourceNodeId":"handle_call_tool \\n[server.py : 170_267]","targetNodeId":"yuntu_util.sample_trace"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpYuntu/src/mcpYuntu/server.py"},"region":{"startLine":265,"startColumn":21,"endLine":265,"endColumn":74,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 170_267]->syslib_from.mcp/types.TextContent","sourceNodeId":"handle_call_tool \\n[server.py : 170_267]","targetNodeId":"syslib_from.mcp/types.TextContent"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpYuntu/src/mcpYuntu/server.py"},"region":{"startLine":192,"startColumn":23,"endLine":192,"endColumn":53,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 170_267]->/src/mcpYuntu/src/mcpYuntu/server.handle_call_tool.handle_call_tool_scope....ValueError","sourceNodeId":"handle_call_tool \\n[server.py : 170_267]","targetNodeId":"/src/mcpYuntu/src/mcpYuntu/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpYuntu/src/mcpYuntu/server.py"},"region":{"startLine":194,"startColumn":23,"endLine":194,"endColumn":62,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 170_267]->/src/mcpYuntu/src/mcpYuntu/server.handle_call_tool.handle_call_tool_scope....ValueError","sourceNodeId":"handle_call_tool \\n[server.py : 170_267]","targetNodeId":"/src/mcpYuntu/src/mcpYuntu/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpYuntu/src/mcpYuntu/server.py"},"region":{"startLine":196,"startColumn":23,"endLine":196,"endColumn":64,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 170_267]->/src/mcpYuntu/src/mcpYuntu/server.handle_call_tool.handle_call_tool_scope....ValueError","sourceNodeId":"handle_call_tool \\n[server.py : 170_267]","targetNodeId":"/src/mcpYuntu/src/mcpYuntu/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpYuntu/src/mcpYuntu/server.py"},"region":{"startLine":197,"startColumn":27,"endLine":198,"endColumn":88,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 170_267]->/src/mcpYuntu/src/mcpYuntu/server.handle_call_tool.handle_call_tool_scope...get_yuntu_call_tree","sourceNodeId":"handle_call_tool \\n[server.py : 170_267]","targetNodeId":"/src/mcpYuntu/src/mcpYuntu/server.handle_call_tool.handle_call_tool_scope...get_yuntu_call_tree"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpYuntu/src/mcpYuntu/server.py"},"region":{"startLine":202,"startColumn":23,"endLine":202,"endColumn":53,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 170_267]->/src/mcpYuntu/src/mcpYuntu/server.handle_call_tool.handle_call_tool_scope....ValueError","sourceNodeId":"handle_call_tool \\n[server.py : 170_267]","targetNodeId":"/src/mcpYuntu/src/mcpYuntu/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpYuntu/src/mcpYuntu/server.py"},"region":{"startLine":204,"startColumn":23,"endLine":204,"endColumn":62,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 170_267]->/src/mcpYuntu/src/mcpYuntu/server.handle_call_tool.handle_call_tool_scope....ValueError","sourceNodeId":"handle_call_tool \\n[server.py : 170_267]","targetNodeId":"/src/mcpYuntu/src/mcpYuntu/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpYuntu/src/mcpYuntu/server.py"},"region":{"startLine":206,"startColumn":23,"endLine":206,"endColumn":64,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 170_267]->/src/mcpYuntu/src/mcpYuntu/server.handle_call_tool.handle_call_tool_scope....ValueError","sourceNodeId":"handle_call_tool \\n[server.py : 170_267]","targetNodeId":"/src/mcpYuntu/src/mcpYuntu/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpYuntu/src/mcpYuntu/server.py"},"region":{"startLine":208,"startColumn":23,"endLine":208,"endColumn":60,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 170_267]->/src/mcpYuntu/src/mcpYuntu/server.handle_call_tool.handle_call_tool_scope....ValueError","sourceNodeId":"handle_call_tool \\n[server.py : 170_267]","targetNodeId":"/src/mcpYuntu/src/mcpYuntu/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpYuntu/src/mcpYuntu/server.py"},"region":{"startLine":209,"startColumn":27,"endLine":211,"endColumn":94,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 170_267]->/src/mcpYuntu/src/mcpYuntu/server.handle_call_tool.handle_call_tool_scope...get_yuntu_call_sub_tree_by_rpc_id","sourceNodeId":"handle_call_tool \\n[server.py : 170_267]","targetNodeId":"/src/mcpYuntu/src/mcpYuntu/server.handle_call_tool.handle_call_tool_scope...get_yuntu_call_sub_tree_by_rpc_id"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpYuntu/src/mcpYuntu/server.py"},"region":{"startLine":215,"startColumn":23,"endLine":215,"endColumn":53,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 170_267]->/src/mcpYuntu/src/mcpYuntu/server.handle_call_tool.handle_call_tool_scope....ValueError","sourceNodeId":"handle_call_tool \\n[server.py : 170_267]","targetNodeId":"/src/mcpYuntu/src/mcpYuntu/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpYuntu/src/mcpYuntu/server.py"},"region":{"startLine":217,"startColumn":23,"endLine":217,"endColumn":62,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 170_267]->/src/mcpYuntu/src/mcpYuntu/server.handle_call_tool.handle_call_tool_scope....ValueError","sourceNodeId":"handle_call_tool \\n[server.py : 170_267]","targetNodeId":"/src/mcpYuntu/src/mcpYuntu/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpYuntu/src/mcpYuntu/server.py"},"region":{"startLine":219,"startColumn":23,"endLine":219,"endColumn":64,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 170_267]->/src/mcpYuntu/src/mcpYuntu/server.handle_call_tool.handle_call_tool_scope....ValueError","sourceNodeId":"handle_call_tool \\n[server.py : 170_267]","targetNodeId":"/src/mcpYuntu/src/mcpYuntu/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpYuntu/src/mcpYuntu/server.py"},"region":{"startLine":221,"startColumn":23,"endLine":221,"endColumn":62,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 170_267]->/src/mcpYuntu/src/mcpYuntu/server.handle_call_tool.handle_call_tool_scope....ValueError","sourceNodeId":"handle_call_tool \\n[server.py : 170_267]","targetNodeId":"/src/mcpYuntu/src/mcpYuntu/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpYuntu/src/mcpYuntu/server.py"},"region":{"startLine":222,"startColumn":27,"endLine":224,"endColumn":93,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 170_267]->/src/mcpYuntu/src/mcpYuntu/server.handle_call_tool.handle_call_tool_scope...get_yuntu_call_rpc_id_by_app","sourceNodeId":"handle_call_tool \\n[server.py : 170_267]","targetNodeId":"/src/mcpYuntu/src/mcpYuntu/server.handle_call_tool.handle_call_tool_scope...get_yuntu_call_rpc_id_by_app"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpYuntu/src/mcpYuntu/server.py"},"region":{"startLine":228,"startColumn":23,"endLine":228,"endColumn":53,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 170_267]->/src/mcpYuntu/src/mcpYuntu/server.handle_call_tool.handle_call_tool_scope....ValueError","sourceNodeId":"handle_call_tool \\n[server.py : 170_267]","targetNodeId":"/src/mcpYuntu/src/mcpYuntu/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpYuntu/src/mcpYuntu/server.py"},"region":{"startLine":230,"startColumn":23,"endLine":230,"endColumn":62,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 170_267]->/src/mcpYuntu/src/mcpYuntu/server.handle_call_tool.handle_call_tool_scope....ValueError","sourceNodeId":"handle_call_tool \\n[server.py : 170_267]","targetNodeId":"/src/mcpYuntu/src/mcpYuntu/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpYuntu/src/mcpYuntu/server.py"},"region":{"startLine":232,"startColumn":23,"endLine":232,"endColumn":64,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 170_267]->/src/mcpYuntu/src/mcpYuntu/server.handle_call_tool.handle_call_tool_scope....ValueError","sourceNodeId":"handle_call_tool \\n[server.py : 170_267]","targetNodeId":"/src/mcpYuntu/src/mcpYuntu/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpYuntu/src/mcpYuntu/server.py"},"region":{"startLine":234,"startColumn":23,"endLine":234,"endColumn":66,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 170_267]->/src/mcpYuntu/src/mcpYuntu/server.handle_call_tool.handle_call_tool_scope....ValueError","sourceNodeId":"handle_call_tool \\n[server.py : 170_267]","targetNodeId":"/src/mcpYuntu/src/mcpYuntu/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpYuntu/src/mcpYuntu/server.py"},"region":{"startLine":236,"startColumn":23,"endLine":236,"endColumn":65,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 170_267]->/src/mcpYuntu/src/mcpYuntu/server.handle_call_tool.handle_call_tool_scope....ValueError","sourceNodeId":"handle_call_tool \\n[server.py : 170_267]","targetNodeId":"/src/mcpYuntu/src/mcpYuntu/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpYuntu/src/mcpYuntu/server.py"},"region":{"startLine":237,"startColumn":27,"endLine":240,"endColumn":108,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 170_267]->/src/mcpYuntu/src/mcpYuntu/server.handle_call_tool.handle_call_tool_scope...get_yuntu_call_key_message_by_service","sourceNodeId":"handle_call_tool \\n[server.py : 170_267]","targetNodeId":"/src/mcpYuntu/src/mcpYuntu/server.handle_call_tool.handle_call_tool_scope...get_yuntu_call_key_message_by_service"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpYuntu/src/mcpYuntu/server.py"},"region":{"startLine":244,"startColumn":23,"endLine":244,"endColumn":53,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 170_267]->/src/mcpYuntu/src/mcpYuntu/server.handle_call_tool.handle_call_tool_scope....ValueError","sourceNodeId":"handle_call_tool \\n[server.py : 170_267]","targetNodeId":"/src/mcpYuntu/src/mcpYuntu/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpYuntu/src/mcpYuntu/server.py"},"region":{"startLine":246,"startColumn":23,"endLine":246,"endColumn":56,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 170_267]->/src/mcpYuntu/src/mcpYuntu/server.handle_call_tool.handle_call_tool_scope....ValueError","sourceNodeId":"handle_call_tool \\n[server.py : 170_267]","targetNodeId":"/src/mcpYuntu/src/mcpYuntu/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpYuntu/src/mcpYuntu/server.py"},"region":{"startLine":248,"startColumn":23,"endLine":248,"endColumn":57,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 170_267]->/src/mcpYuntu/src/mcpYuntu/server.handle_call_tool.handle_call_tool_scope....ValueError","sourceNodeId":"handle_call_tool \\n[server.py : 170_267]","targetNodeId":"/src/mcpYuntu/src/mcpYuntu/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpYuntu/src/mcpYuntu/server.py"},"region":{"startLine":251,"startColumn":27,"endLine":252,"endColumn":72,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 170_267]->/src/mcpYuntu/src/mcpYuntu/server.handle_call_tool.handle_call_tool_scope...execute_tool","sourceNodeId":"handle_call_tool \\n[server.py : 170_267]","targetNodeId":"/src/mcpYuntu/src/mcpYuntu/server.handle_call_tool.handle_call_tool_scope...execute_tool"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpYuntu/src/mcpYuntu/server.py"},"region":{"startLine":256,"startColumn":23,"endLine":256,"endColumn":53,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 170_267]->/src/mcpYuntu/src/mcpYuntu/server.handle_call_tool.handle_call_tool_scope....ValueError","sourceNodeId":"handle_call_tool \\n[server.py : 170_267]","targetNodeId":"/src/mcpYuntu/src/mcpYuntu/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpYuntu/src/mcpYuntu/server.py"},"region":{"startLine":258,"startColumn":23,"endLine":258,"endColumn":56,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 170_267]->/src/mcpYuntu/src/mcpYuntu/server.handle_call_tool.handle_call_tool_scope....ValueError","sourceNodeId":"handle_call_tool \\n[server.py : 170_267]","targetNodeId":"/src/mcpYuntu/src/mcpYuntu/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpYuntu/src/mcpYuntu/server.py"},"region":{"startLine":260,"startColumn":23,"endLine":260,"endColumn":62,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 170_267]->/src/mcpYuntu/src/mcpYuntu/server.handle_call_tool.handle_call_tool_scope....ValueError","sourceNodeId":"handle_call_tool \\n[server.py : 170_267]","targetNodeId":"/src/mcpYuntu/src/mcpYuntu/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpYuntu/src/mcpYuntu/server.py"},"region":{"startLine":263,"startColumn":27,"endLine":264,"endColumn":72,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 170_267]->/src/mcpYuntu/src/mcpYuntu/server.handle_call_tool.handle_call_tool_scope...execute_tool","sourceNodeId":"handle_call_tool \\n[server.py : 170_267]","targetNodeId":"/src/mcpYuntu/src/mcpYuntu/server.handle_call_tool.handle_call_tool_scope...execute_tool"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpYuntu/src/mcpYuntu/server.py"},"region":{"startLine":267,"startColumn":19,"endLine":267,"endColumn":54,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 170_267]->/src/mcpYuntu/src/mcpYuntu/server.handle_call_tool.handle_call_tool_scope...ValueError","sourceNodeId":"handle_call_tool \\n[server.py : 170_267]","targetNodeId":"/src/mcpYuntu/src/mcpYuntu/server.handle_call_tool.handle_call_tool_scope...ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpyuque/src/mcpyuque/server.py"},"region":{"startLine":75,"startColumn":23,"endLine":75,"endColumn":53,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 65_95]->/src/mcpyuque/src/mcpyuque/server.handle_call_tool.handle_call_tool_scope....ValueError","sourceNodeId":"handle_call_tool \\n[server.py : 65_95]","targetNodeId":"/src/mcpyuque/src/mcpyuque/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpyuque/src/mcpyuque/server.py"},"region":{"startLine":77,"startColumn":23,"endLine":77,"endColumn":61,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 65_95]->/src/mcpyuque/src/mcpyuque/server.handle_call_tool.handle_call_tool_scope....ValueError","sourceNodeId":"handle_call_tool \\n[server.py : 65_95]","targetNodeId":"/src/mcpyuque/src/mcpyuque/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpyuque/src/mcpyuque/server.py"},"region":{"startLine":78,"startColumn":27,"endLine":78,"endColumn":91,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 65_95]->write_document \\n[report_client.py : 40_72]","sourceNodeId":"handle_call_tool \\n[server.py : 65_95]","targetNodeId":"write_document \\n[report_client.py : 40_72]"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpyuque/src/mcpyuque/server.py"},"region":{"startLine":82,"startColumn":23,"endLine":82,"endColumn":53,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 65_95]->/src/mcpyuque/src/mcpyuque/server.handle_call_tool.handle_call_tool_scope....ValueError","sourceNodeId":"handle_call_tool \\n[server.py : 65_95]","targetNodeId":"/src/mcpyuque/src/mcpyuque/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpyuque/src/mcpyuque/server.py"},"region":{"startLine":84,"startColumn":23,"endLine":84,"endColumn":62,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 65_95]->/src/mcpyuque/src/mcpyuque/server.handle_call_tool.handle_call_tool_scope....ValueError","sourceNodeId":"handle_call_tool \\n[server.py : 65_95]","targetNodeId":"/src/mcpyuque/src/mcpyuque/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpyuque/src/mcpyuque/server.py"},"region":{"startLine":85,"startColumn":27,"endLine":85,"endColumn":100,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 65_95]->fetch_yuque_document \\n[yuque_markdown.py : 40_72]","sourceNodeId":"handle_call_tool \\n[server.py : 65_95]","targetNodeId":"fetch_yuque_document \\n[yuque_markdown.py : 40_72]"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpyuque/src/mcpyuque/yuque_markdown.py"},"region":{"startLine":41,"startColumn":14,"endLine":41,"endColumn":22,"snippet":{}}}},"id":"fetch_yuque_document \\n[yuque_markdown.py : 40_72]->Result :: __init__ \\n[yuque_markdown.py : 25_28]","sourceNodeId":"fetch_yuque_document \\n[yuque_markdown.py : 40_72]","targetNodeId":"Result :: __init__ \\n[yuque_markdown.py : 25_28]"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpyuque/src/mcpyuque/yuque_markdown.py"},"region":{"startLine":51,"startColumn":33,"endLine":51,"endColumn":43,"snippet":{}}}},"id":"fetch_yuque_document \\n[yuque_markdown.py : 40_72]->_headers \\n[yuque_markdown.py : 16_20]","sourceNodeId":"fetch_yuque_document \\n[yuque_markdown.py : 40_72]","targetNodeId":"_headers \\n[yuque_markdown.py : 16_20]"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpyuque/src/mcpyuque/yuque_markdown.py"},"region":{"startLine":49,"startColumn":20,"endLine":52,"endColumn":10,"snippet":{}}}},"id":"fetch_yuque_document \\n[yuque_markdown.py : 40_72]->mcp_common.request.http_client.AsyncRestClient","sourceNodeId":"fetch_yuque_document \\n[yuque_markdown.py : 40_72]","targetNodeId":"mcp_common.request.http_client.AsyncRestClient"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpyuque/src/mcpyuque/yuque_markdown.py"},"region":{"startLine":54,"startColumn":24,"endLine":54,"endColumn":83,"snippet":{}}}},"id":"fetch_yuque_document \\n[yuque_markdown.py : 40_72]->mcp_common.request.http_client.AsyncRestClient(var base_url:any=https://instemc.alipay.com/yuque, var default_headers:any=_headers()).post","sourceNodeId":"fetch_yuque_document \\n[yuque_markdown.py : 40_72]","targetNodeId":"mcp_common.request.http_client.AsyncRestClient(var base_url:any=https://instemc.alipay.com/yuque, var default_headers:any=_headers()).post"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpyuque/src/mcpyuque/yuque_markdown.py"},"region":{"startLine":62,"startColumn":30,"endLine":62,"endColumn":72,"snippet":{}}}},"id":"fetch_yuque_document \\n[yuque_markdown.py : 40_72]->mcp_common.request.http_client.AsyncRestClient(var base_url:any=https://instemc.alipay.com/yuque, var default_headers:any=_headers()).post(var endpoint:any=/yuque2markDown, var data:any=payload).get","sourceNodeId":"fetch_yuque_document \\n[yuque_markdown.py : 40_72]","targetNodeId":"mcp_common.request.http_client.AsyncRestClient(var base_url:any=https://instemc.alipay.com/yuque, var default_headers:any=_headers()).post(var endpoint:any=/yuque2markDown, var data:any=payload).get"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpyuque/src/mcpyuque/yuque_markdown.py"},"region":{"startLine":65,"startColumn":9,"endLine":65,"endColumn":62,"snippet":{}}}},"id":"fetch_yuque_document \\n[yuque_markdown.py : 40_72]->syslib_from.logging.getLogger(__name__).exception","sourceNodeId":"fetch_yuque_document \\n[yuque_markdown.py : 40_72]","targetNodeId":"syslib_from.logging.getLogger(__name__).exception"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpyuque/src/mcpyuque/yuque_markdown.py"},"region":{"startLine":66,"startColumn":62,"endLine":66,"endColumn":70,"snippet":{}}}},"id":"fetch_yuque_document \\n[yuque_markdown.py : 40_72]->/src/mcpyuque/src/mcpyuque/yuque_markdown.fetch_yuque_document.fetch_yuque_document_scope...str","sourceNodeId":"fetch_yuque_document \\n[yuque_markdown.py : 40_72]","targetNodeId":"/src/mcpyuque/src/mcpyuque/yuque_markdown.fetch_yuque_document.fetch_yuque_document_scope...str"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpyuque/src/mcpyuque/yuque_markdown.py"},"region":{"startLine":70,"startColumn":13,"endLine":70,"endColumn":53,"snippet":{}}}},"id":"fetch_yuque_document \\n[yuque_markdown.py : 40_72]->mcp_common.request.http_client.AsyncRestClient(var base_url:any=https://instemc.alipay.com/yuque, var default_headers:any=_headers()).__aexit__","sourceNodeId":"fetch_yuque_document \\n[yuque_markdown.py : 40_72]","targetNodeId":"mcp_common.request.http_client.AsyncRestClient(var base_url:any=https://instemc.alipay.com/yuque, var default_headers:any=_headers()).__aexit__"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpyuque/src/mcpyuque/yuque_markdown.py"},"region":{"startLine":72,"startColumn":12,"endLine":72,"endColumn":28,"snippet":{}}}},"id":"fetch_yuque_document \\n[yuque_markdown.py : 40_72]->Result :: to_dict \\n[yuque_markdown.py : 30_35]","sourceNodeId":"fetch_yuque_document \\n[yuque_markdown.py : 40_72]","targetNodeId":"Result :: to_dict \\n[yuque_markdown.py : 30_35]"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpyuque/src/mcpyuque/server.py"},"region":{"startLine":89,"startColumn":23,"endLine":89,"endColumn":53,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 65_95]->/src/mcpyuque/src/mcpyuque/server.handle_call_tool.handle_call_tool_scope....ValueError","sourceNodeId":"handle_call_tool \\n[server.py : 65_95]","targetNodeId":"/src/mcpyuque/src/mcpyuque/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpyuque/src/mcpyuque/server.py"},"region":{"startLine":91,"startColumn":23,"endLine":91,"endColumn":65,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 65_95]->/src/mcpyuque/src/mcpyuque/server.handle_call_tool.handle_call_tool_scope....ValueError","sourceNodeId":"handle_call_tool \\n[server.py : 65_95]","targetNodeId":"/src/mcpyuque/src/mcpyuque/server.handle_call_tool.handle_call_tool_scope....ValueError"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpyuque/src/mcpyuque/server.py"},"region":{"startLine":92,"startColumn":27,"endLine":92,"endColumn":112,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 65_95]->split_block_remain_pic_url \\n[yuque_markdown.py : 75_99]","sourceNodeId":"handle_call_tool \\n[server.py : 65_95]","targetNodeId":"split_block_remain_pic_url \\n[yuque_markdown.py : 75_99]"},{"location":{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpyuque/src/mcpyuque/server.py"},"region":{"startLine":95,"startColumn":19,"endLine":95,"endColumn":54,"snippet":{}}}},"id":"handle_call_tool \\n[server.py : 65_95]->/src/mcpyuque/src/mcpyuque/server.handle_call_tool.handle_call_tool_scope...ValueError","sourceNodeId":"handle_call_tool \\n[server.py : 65_95]","targetNodeId":"/src/mcpyuque/src/mcpyuque/server.handle_call_tool.handle_call_tool_scope...ValueError"}]}],"results":[{"message":{"text":"Python污点分析checker,不会使用CallGraph边界制作entrypoint,蚂蚁内部使用"},"level":"error","entrypoint":{"type":"functionCall","functionName":"handle_call_tool","filePath":"/src/mcpCloudinc/src/mcpCloudinc/server.py","attribute":"MCPTool","funcReceiverType":""},"sinkInfo":{"sinkRule":"requests.get","sinkAttribute":"PythonSSRF"},"codeFlows":[{"threadFlows":[{"locations":[{"location":{"message":{"text":"Step 0"},"physicalLocation":{"artifactLocation":{"uri":"file:///src/mcpCloudinc/src/mcpCloudinc/server.py"},"region":{"startLine":146,"startColumn":20,"endLine":146,"endColumn":29,"snippet":{"text":" /src/mcpCloudinc/src/mcpCloudinc/server.py\n AffectedNodeName: arguments\n 146: SOURCE: name: str, arguments: dict | None\n","affectedNodeName":"arguments"}}}}},{"location":{"message":{"text":"Step 1"},"physicalLocation":{"artifactLocation":{"uri":"file:///src/mcpCloudinc/src/mcpCloudinc/server.py"},"region":{"startLine":180,"startColumn":51,"endLine":180,"endColumn":71,"snippet":{"text":" /src/mcpCloudinc/src/mcpCloudinc/server.py\n AffectedNodeName: env\n 180: Var Pass: env=arguments[\"env\"])\n","affectedNodeName":"env"}}}}},{"location":{"message":{"text":"Step 2"},"physicalLocation":{"artifactLocation":{"uri":"file:///src/mcpCloudinc/src/mcpCloudinc/server.py"},"region":{"startLine":178,"startColumn":27,"endLine":180,"endColumn":72,"snippet":{"text":" /src/mcpCloudinc/src/mcpCloudinc/server.py\n AffectedNodeName: get_domain_by_ips\n 178: CALL: result_text = await get_domain_by_ips(ips=arguments[\"ips\"],\n 179: CALL: tenant=arguments[\"tenant\"],\n 180: CALL: env=arguments[\"env\"])\n","affectedNodeName":"get_domain_by_ips"}}}}},{"location":{"message":{"text":"Step 3"},"physicalLocation":{"artifactLocation":{"uri":"file:///src/mcpCloudinc/src/mcpCloudinc/server.py"},"region":{"startLine":299,"startColumn":29,"endLine":299,"endColumn":66,"snippet":{"text":" /src/mcpCloudinc/src/mcpCloudinc/server.py\n AffectedNodeName: env\n 299: ARG PASS: async def get_domain_by_ips(ips: list[str], tenant: str, env: str) -> Optional[str]:\n","affectedNodeName":"env"}}}}},{"location":{"message":{"text":"Step 4"},"physicalLocation":{"artifactLocation":{"uri":"file:///src/mcpCloudinc/src/mcpCloudinc/server.py"},"region":{"startLine":313,"startColumn":5,"endLine":313,"endColumn":52,"snippet":{"text":" /src/mcpCloudinc/src/mcpCloudinc/server.py\n AffectedNodeName: domain\n 313: Var Pass: domain = CLOUDINC_URL_DICT.get(tenant).get(env)\n","affectedNodeName":"domain"}}}}},{"location":{"message":{"text":"Step 5"},"physicalLocation":{"artifactLocation":{"uri":"file:///src/mcpCloudinc/src/mcpCloudinc/server.py"},"region":{"startLine":314,"startColumn":5,"endLine":314,"endColumn":70,"snippet":{"text":" /src/mcpCloudinc/src/mcpCloudinc/server.py\n AffectedNodeName: url\n 314: Var Pass: url = domain + '/antvip/rest/commondomain/queryDomainsByIps.json'\n","affectedNodeName":"url"}}}}},{"location":{"message":{"text":"Step 6"},"physicalLocation":{"artifactLocation":{"uri":"file:///src/mcpCloudinc/src/mcpCloudinc/server.py"},"region":{"startLine":320,"startColumn":20,"endLine":320,"endColumn":69,"snippet":{"text":" /src/mcpCloudinc/src/mcpCloudinc/server.py\n AffectedNodeName: requests.get\n 320: SINK: response = requests.get(url, headers=headers, params=params)\n","affectedNodeName":"requests.get"}}}}}]}]}],"locations":[{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpCloudinc/src/mcpCloudinc/server.py"},"region":{"startLine":320,"startColumn":20,"endLine":320,"endColumn":69,"snippet":{"text":"requests.get(url, var headers:any=headers, var params:any=params)"}}}}],"matchedSanitizerTags":""},{"message":{"text":"Python污点分析checker,不会使用CallGraph边界制作entrypoint,蚂蚁内部使用"},"level":"error","entrypoint":{"type":"functionCall","functionName":"handle_call_tool","filePath":"/src/mcpCloudinc/src/mcpCloudinc/server.py","attribute":"MCPTool","funcReceiverType":""},"sinkInfo":{"sinkRule":"requests.get","sinkAttribute":"PythonSSRF"},"codeFlows":[{"threadFlows":[{"locations":[{"location":{"message":{"text":"Step 0"},"physicalLocation":{"artifactLocation":{"uri":"file:///src/mcpCloudinc/src/mcpCloudinc/server.py"},"region":{"startLine":146,"startColumn":20,"endLine":146,"endColumn":29,"snippet":{"text":" /src/mcpCloudinc/src/mcpCloudinc/server.py\n AffectedNodeName: arguments\n 146: SOURCE: name: str, arguments: dict | None\n","affectedNodeName":"arguments"}}}}},{"location":{"message":{"text":"Step 1"},"physicalLocation":{"artifactLocation":{"uri":"file:///src/mcpCloudinc/src/mcpCloudinc/server.py"},"region":{"startLine":179,"startColumn":51,"endLine":179,"endColumn":77,"snippet":{"text":" /src/mcpCloudinc/src/mcpCloudinc/server.py\n AffectedNodeName: tenant\n 179: Var Pass: tenant=arguments[\"tenant\"],\n","affectedNodeName":"tenant"}}}}},{"location":{"message":{"text":"Step 2"},"physicalLocation":{"artifactLocation":{"uri":"file:///src/mcpCloudinc/src/mcpCloudinc/server.py"},"region":{"startLine":178,"startColumn":27,"endLine":180,"endColumn":72,"snippet":{"text":" /src/mcpCloudinc/src/mcpCloudinc/server.py\n AffectedNodeName: get_domain_by_ips\n 178: CALL: result_text = await get_domain_by_ips(ips=arguments[\"ips\"],\n 179: CALL: tenant=arguments[\"tenant\"],\n 180: CALL: env=arguments[\"env\"])\n","affectedNodeName":"get_domain_by_ips"}}}}},{"location":{"message":{"text":"Step 3"},"physicalLocation":{"artifactLocation":{"uri":"file:///src/mcpCloudinc/src/mcpCloudinc/server.py"},"region":{"startLine":299,"startColumn":29,"endLine":299,"endColumn":66,"snippet":{"text":" /src/mcpCloudinc/src/mcpCloudinc/server.py\n AffectedNodeName: tenant\n 299: ARG PASS: async def get_domain_by_ips(ips: list[str], tenant: str, env: str) -> Optional[str]:\n","affectedNodeName":"tenant"}}}}},{"location":{"message":{"text":"Step 4"},"physicalLocation":{"artifactLocation":{"uri":"file:///src/mcpCloudinc/src/mcpCloudinc/server.py"},"region":{"startLine":313,"startColumn":5,"endLine":313,"endColumn":52,"snippet":{"text":" /src/mcpCloudinc/src/mcpCloudinc/server.py\n AffectedNodeName: domain\n 313: Var Pass: domain = CLOUDINC_URL_DICT.get(tenant).get(env)\n","affectedNodeName":"domain"}}}}},{"location":{"message":{"text":"Step 5"},"physicalLocation":{"artifactLocation":{"uri":"file:///src/mcpCloudinc/src/mcpCloudinc/server.py"},"region":{"startLine":314,"startColumn":5,"endLine":314,"endColumn":70,"snippet":{"text":" /src/mcpCloudinc/src/mcpCloudinc/server.py\n AffectedNodeName: url\n 314: Var Pass: url = domain + '/antvip/rest/commondomain/queryDomainsByIps.json'\n","affectedNodeName":"url"}}}}},{"location":{"message":{"text":"Step 6"},"physicalLocation":{"artifactLocation":{"uri":"file:///src/mcpCloudinc/src/mcpCloudinc/server.py"},"region":{"startLine":320,"startColumn":20,"endLine":320,"endColumn":69,"snippet":{"text":" /src/mcpCloudinc/src/mcpCloudinc/server.py\n AffectedNodeName: requests.get\n 320: SINK: response = requests.get(url, headers=headers, params=params)\n","affectedNodeName":"requests.get"}}}}}]}]}],"locations":[{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpCloudinc/src/mcpCloudinc/server.py"},"region":{"startLine":320,"startColumn":20,"endLine":320,"endColumn":69,"snippet":{"text":"requests.get(url, var headers:any=headers, var params:any=params)"}}}}],"matchedSanitizerTags":""},{"message":{"text":"Python污点分析checker,不会使用CallGraph边界制作entrypoint,蚂蚁内部使用"},"level":"error","entrypoint":{"type":"functionCall","functionName":"handle_call_tool","filePath":"/src/mcpCloudinc/src/mcpCloudinc/server.py","attribute":"MCPTool","funcReceiverType":""},"sinkInfo":{"sinkRule":"requests.get","sinkAttribute":"PythonSSRF"},"codeFlows":[{"threadFlows":[{"locations":[{"location":{"message":{"text":"Step 0"},"physicalLocation":{"artifactLocation":{"uri":"file:///src/mcpCloudinc/src/mcpCloudinc/server.py"},"region":{"startLine":146,"startColumn":20,"endLine":146,"endColumn":29,"snippet":{"text":" /src/mcpCloudinc/src/mcpCloudinc/server.py\n AffectedNodeName: arguments\n 146: SOURCE: name: str, arguments: dict | None\n","affectedNodeName":"arguments"}}}}},{"location":{"message":{"text":"Step 1"},"physicalLocation":{"artifactLocation":{"uri":"file:///src/mcpCloudinc/src/mcpCloudinc/server.py"},"region":{"startLine":196,"startColumn":51,"endLine":196,"endColumn":71,"snippet":{"text":" /src/mcpCloudinc/src/mcpCloudinc/server.py\n AffectedNodeName: env\n 196: Var Pass: env=arguments[\"env\"])\n","affectedNodeName":"env"}}}}},{"location":{"message":{"text":"Step 2"},"physicalLocation":{"artifactLocation":{"uri":"file:///src/mcpCloudinc/src/mcpCloudinc/server.py"},"region":{"startLine":193,"startColumn":27,"endLine":196,"endColumn":72,"snippet":{"text":" /src/mcpCloudinc/src/mcpCloudinc/server.py\n AffectedNodeName: get_domain_detail\n 193: CALL: result_text = await get_domain_detail(domain_name=arguments[\"domain_name\"],\n 194: CALL: domain_env=arguments[\"domain_env\"],\n 195: CALL: tenant=arguments[\"tenant\"],\n 196: CALL: env=arguments[\"env\"])\n","affectedNodeName":"get_domain_detail"}}}}},{"location":{"message":{"text":"Step 3"},"physicalLocation":{"artifactLocation":{"uri":"file:///src/mcpCloudinc/src/mcpCloudinc/server.py"},"region":{"startLine":333,"startColumn":29,"endLine":333,"endColumn":85,"snippet":{"text":" /src/mcpCloudinc/src/mcpCloudinc/server.py\n AffectedNodeName: env\n 333: ARG PASS: async def get_domain_detail(domain_name: str, tenant: str, env: str, domain_env: str) -> Optional[str]:\n","affectedNodeName":"env"}}}}},{"location":{"message":{"text":"Step 4"},"physicalLocation":{"artifactLocation":{"uri":"file:///src/mcpCloudinc/src/mcpCloudinc/server.py"},"region":{"startLine":348,"startColumn":5,"endLine":348,"endColumn":52,"snippet":{"text":" /src/mcpCloudinc/src/mcpCloudinc/server.py\n AffectedNodeName: domain\n 348: Var Pass: domain = CLOUDINC_URL_DICT.get(tenant).get(env)\n","affectedNodeName":"domain"}}}}},{"location":{"message":{"text":"Step 5"},"physicalLocation":{"artifactLocation":{"uri":"file:///src/mcpCloudinc/src/mcpCloudinc/server.py"},"region":{"startLine":349,"startColumn":5,"endLine":349,"endColumn":64,"snippet":{"text":" /src/mcpCloudinc/src/mcpCloudinc/server.py\n AffectedNodeName: url\n 349: Var Pass: url = domain + '/antvip/rest/commondomain/queryDomain.json'\n","affectedNodeName":"url"}}}}},{"location":{"message":{"text":"Step 6"},"physicalLocation":{"artifactLocation":{"uri":"file:///src/mcpCloudinc/src/mcpCloudinc/server.py"},"region":{"startLine":355,"startColumn":20,"endLine":355,"endColumn":69,"snippet":{"text":" /src/mcpCloudinc/src/mcpCloudinc/server.py\n AffectedNodeName: requests.get\n 355: SINK: response = requests.get(url, headers=headers, params=params)\n","affectedNodeName":"requests.get"}}}}}]}]}],"locations":[{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpCloudinc/src/mcpCloudinc/server.py"},"region":{"startLine":355,"startColumn":20,"endLine":355,"endColumn":69,"snippet":{"text":"requests.get(url, var headers:any=headers, var params:any=params)"}}}}],"matchedSanitizerTags":""},{"message":{"text":"Python污点分析checker,不会使用CallGraph边界制作entrypoint,蚂蚁内部使用"},"level":"error","entrypoint":{"type":"functionCall","functionName":"handle_call_tool","filePath":"/src/mcpCloudinc/src/mcpCloudinc/server.py","attribute":"MCPTool","funcReceiverType":""},"sinkInfo":{"sinkRule":"requests.get","sinkAttribute":"PythonSSRF"},"codeFlows":[{"threadFlows":[{"locations":[{"location":{"message":{"text":"Step 0"},"physicalLocation":{"artifactLocation":{"uri":"file:///src/mcpCloudinc/src/mcpCloudinc/server.py"},"region":{"startLine":146,"startColumn":20,"endLine":146,"endColumn":29,"snippet":{"text":" /src/mcpCloudinc/src/mcpCloudinc/server.py\n AffectedNodeName: arguments\n 146: SOURCE: name: str, arguments: dict | None\n","affectedNodeName":"arguments"}}}}},{"location":{"message":{"text":"Step 1"},"physicalLocation":{"artifactLocation":{"uri":"file:///src/mcpCloudinc/src/mcpCloudinc/server.py"},"region":{"startLine":195,"startColumn":51,"endLine":195,"endColumn":77,"snippet":{"text":" /src/mcpCloudinc/src/mcpCloudinc/server.py\n AffectedNodeName: tenant\n 195: Var Pass: tenant=arguments[\"tenant\"],\n","affectedNodeName":"tenant"}}}}},{"location":{"message":{"text":"Step 2"},"physicalLocation":{"artifactLocation":{"uri":"file:///src/mcpCloudinc/src/mcpCloudinc/server.py"},"region":{"startLine":193,"startColumn":27,"endLine":196,"endColumn":72,"snippet":{"text":" /src/mcpCloudinc/src/mcpCloudinc/server.py\n AffectedNodeName: get_domain_detail\n 193: CALL: result_text = await get_domain_detail(domain_name=arguments[\"domain_name\"],\n 194: CALL: domain_env=arguments[\"domain_env\"],\n 195: CALL: tenant=arguments[\"tenant\"],\n 196: CALL: env=arguments[\"env\"])\n","affectedNodeName":"get_domain_detail"}}}}},{"location":{"message":{"text":"Step 3"},"physicalLocation":{"artifactLocation":{"uri":"file:///src/mcpCloudinc/src/mcpCloudinc/server.py"},"region":{"startLine":333,"startColumn":29,"endLine":333,"endColumn":85,"snippet":{"text":" /src/mcpCloudinc/src/mcpCloudinc/server.py\n AffectedNodeName: tenant\n 333: ARG PASS: async def get_domain_detail(domain_name: str, tenant: str, env: str, domain_env: str) -> Optional[str]:\n","affectedNodeName":"tenant"}}}}},{"location":{"message":{"text":"Step 4"},"physicalLocation":{"artifactLocation":{"uri":"file:///src/mcpCloudinc/src/mcpCloudinc/server.py"},"region":{"startLine":348,"startColumn":5,"endLine":348,"endColumn":52,"snippet":{"text":" /src/mcpCloudinc/src/mcpCloudinc/server.py\n AffectedNodeName: domain\n 348: Var Pass: domain = CLOUDINC_URL_DICT.get(tenant).get(env)\n","affectedNodeName":"domain"}}}}},{"location":{"message":{"text":"Step 5"},"physicalLocation":{"artifactLocation":{"uri":"file:///src/mcpCloudinc/src/mcpCloudinc/server.py"},"region":{"startLine":349,"startColumn":5,"endLine":349,"endColumn":64,"snippet":{"text":" /src/mcpCloudinc/src/mcpCloudinc/server.py\n AffectedNodeName: url\n 349: Var Pass: url = domain + '/antvip/rest/commondomain/queryDomain.json'\n","affectedNodeName":"url"}}}}},{"location":{"message":{"text":"Step 6"},"physicalLocation":{"artifactLocation":{"uri":"file:///src/mcpCloudinc/src/mcpCloudinc/server.py"},"region":{"startLine":355,"startColumn":20,"endLine":355,"endColumn":69,"snippet":{"text":" /src/mcpCloudinc/src/mcpCloudinc/server.py\n AffectedNodeName: requests.get\n 355: SINK: response = requests.get(url, headers=headers, params=params)\n","affectedNodeName":"requests.get"}}}}}]}]}],"locations":[{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpCloudinc/src/mcpCloudinc/server.py"},"region":{"startLine":355,"startColumn":20,"endLine":355,"endColumn":69,"snippet":{"text":"requests.get(url, var headers:any=headers, var params:any=params)"}}}}],"matchedSanitizerTags":""},{"message":{"text":"Python污点分析checker,不会使用CallGraph边界制作entrypoint,蚂蚁内部使用"},"level":"error","entrypoint":{"type":"functionCall","functionName":"handle_call_tool","filePath":"/src/mcpCloudinc/src/mcpCloudinc/server.py","attribute":"MCPTool","funcReceiverType":""},"sinkInfo":{"sinkRule":"requests.get","sinkAttribute":"PythonSSRF"},"codeFlows":[{"threadFlows":[{"locations":[{"location":{"message":{"text":"Step 0"},"physicalLocation":{"artifactLocation":{"uri":"file:///src/mcpCloudinc/src/mcpCloudinc/server.py"},"region":{"startLine":146,"startColumn":20,"endLine":146,"endColumn":29,"snippet":{"text":" /src/mcpCloudinc/src/mcpCloudinc/server.py\n AffectedNodeName: arguments\n 146: SOURCE: name: str, arguments: dict | None\n","affectedNodeName":"arguments"}}}}},{"location":{"message":{"text":"Step 1"},"physicalLocation":{"artifactLocation":{"uri":"file:///src/mcpCloudinc/src/mcpCloudinc/server.py"},"region":{"startLine":215,"startColumn":51,"endLine":215,"endColumn":69,"snippet":{"text":" /src/mcpCloudinc/src/mcpCloudinc/server.py\n AffectedNodeName: ip\n 215: Var Pass: ip=arguments[\"ip\"])\n","affectedNodeName":"ip"}}}}},{"location":{"message":{"text":"Step 2"},"physicalLocation":{"artifactLocation":{"uri":"file:///src/mcpCloudinc/src/mcpCloudinc/server.py"},"region":{"startLine":211,"startColumn":27,"endLine":215,"endColumn":70,"snippet":{"text":" /src/mcpCloudinc/src/mcpCloudinc/server.py\n AffectedNodeName: get_domain_labels\n 211: CALL: result_text = await get_domain_labels(domain_name=arguments[\"domain_name\"],\n 212: CALL: domain_env=arguments[\"domain_env\"],\n 213: CALL: tenant=arguments[\"tenant\"],\n 214: CALL: env=arguments[\"env\"],\n 215: CALL: ip=arguments[\"ip\"])\n","affectedNodeName":"get_domain_labels"}}}}},{"location":{"message":{"text":"Step 3"},"physicalLocation":{"artifactLocation":{"uri":"file:///src/mcpCloudinc/src/mcpCloudinc/server.py"},"region":{"startLine":368,"startColumn":29,"endLine":368,"endColumn":94,"snippet":{"text":" /src/mcpCloudinc/src/mcpCloudinc/server.py\n AffectedNodeName: ip\n 368: ARG PASS: async def get_domain_labels(domain_name: str, domain_env: str, tenant: str, env: str, ip: str) -> Optional[str]:\n","affectedNodeName":"ip"}}}}},{"location":{"message":{"text":"Step 4"},"physicalLocation":{"artifactLocation":{"uri":"file:///src/mcpCloudinc/src/mcpCloudinc/server.py"},"region":{"startLine":385,"startColumn":5,"endLine":385,"endColumn":94,"snippet":{"text":" /src/mcpCloudinc/src/mcpCloudinc/server.py\n AffectedNodeName: url\n 385: Var Pass: url = f\"{domain}/antvip/rest/api/v1/env/{domain_env}/domain/{domain_name}/ip/{ip}/labels\"\n","affectedNodeName":"url"}}}}},{"location":{"message":{"text":"Step 5"},"physicalLocation":{"artifactLocation":{"uri":"file:///src/mcpCloudinc/src/mcpCloudinc/server.py"},"region":{"startLine":390,"startColumn":20,"endLine":390,"endColumn":54,"snippet":{"text":" /src/mcpCloudinc/src/mcpCloudinc/server.py\n AffectedNodeName: requests.get\n 390: SINK: response = requests.get(url, headers=headers)\n","affectedNodeName":"requests.get"}}}}}]}]}],"locations":[{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpCloudinc/src/mcpCloudinc/server.py"},"region":{"startLine":390,"startColumn":20,"endLine":390,"endColumn":54,"snippet":{"text":"requests.get(url, var headers:any=headers)"}}}}],"matchedSanitizerTags":""},{"message":{"text":"Python污点分析checker,不会使用CallGraph边界制作entrypoint,蚂蚁内部使用"},"level":"error","entrypoint":{"type":"functionCall","functionName":"handle_call_tool","filePath":"/src/mcpCloudinc/src/mcpCloudinc/server.py","attribute":"MCPTool","funcReceiverType":""},"sinkInfo":{"sinkRule":"requests.get","sinkAttribute":"PythonSSRF"},"codeFlows":[{"threadFlows":[{"locations":[{"location":{"message":{"text":"Step 0"},"physicalLocation":{"artifactLocation":{"uri":"file:///src/mcpCloudinc/src/mcpCloudinc/server.py"},"region":{"startLine":146,"startColumn":20,"endLine":146,"endColumn":29,"snippet":{"text":" /src/mcpCloudinc/src/mcpCloudinc/server.py\n AffectedNodeName: arguments\n 146: SOURCE: name: str, arguments: dict | None\n","affectedNodeName":"arguments"}}}}},{"location":{"message":{"text":"Step 1"},"physicalLocation":{"artifactLocation":{"uri":"file:///src/mcpCloudinc/src/mcpCloudinc/server.py"},"region":{"startLine":211,"startColumn":51,"endLine":211,"endColumn":87,"snippet":{"text":" /src/mcpCloudinc/src/mcpCloudinc/server.py\n AffectedNodeName: domain_name\n 211: Var Pass: result_text = await get_domain_labels(domain_name=arguments[\"domain_name\"],\n","affectedNodeName":"domain_name"}}}}},{"location":{"message":{"text":"Step 2"},"physicalLocation":{"artifactLocation":{"uri":"file:///src/mcpCloudinc/src/mcpCloudinc/server.py"},"region":{"startLine":211,"startColumn":27,"endLine":215,"endColumn":70,"snippet":{"text":" /src/mcpCloudinc/src/mcpCloudinc/server.py\n AffectedNodeName: get_domain_labels\n 211: CALL: result_text = await get_domain_labels(domain_name=arguments[\"domain_name\"],\n 212: CALL: domain_env=arguments[\"domain_env\"],\n 213: CALL: tenant=arguments[\"tenant\"],\n 214: CALL: env=arguments[\"env\"],\n 215: CALL: ip=arguments[\"ip\"])\n","affectedNodeName":"get_domain_labels"}}}}},{"location":{"message":{"text":"Step 3"},"physicalLocation":{"artifactLocation":{"uri":"file:///src/mcpCloudinc/src/mcpCloudinc/server.py"},"region":{"startLine":368,"startColumn":29,"endLine":368,"endColumn":94,"snippet":{"text":" /src/mcpCloudinc/src/mcpCloudinc/server.py\n AffectedNodeName: domain_name\n 368: ARG PASS: async def get_domain_labels(domain_name: str, domain_env: str, tenant: str, env: str, ip: str) -> Optional[str]:\n","affectedNodeName":"domain_name"}}}}},{"location":{"message":{"text":"Step 4"},"physicalLocation":{"artifactLocation":{"uri":"file:///src/mcpCloudinc/src/mcpCloudinc/server.py"},"region":{"startLine":385,"startColumn":5,"endLine":385,"endColumn":94,"snippet":{"text":" /src/mcpCloudinc/src/mcpCloudinc/server.py\n AffectedNodeName: url\n 385: Var Pass: url = f\"{domain}/antvip/rest/api/v1/env/{domain_env}/domain/{domain_name}/ip/{ip}/labels\"\n","affectedNodeName":"url"}}}}},{"location":{"message":{"text":"Step 5"},"physicalLocation":{"artifactLocation":{"uri":"file:///src/mcpCloudinc/src/mcpCloudinc/server.py"},"region":{"startLine":390,"startColumn":20,"endLine":390,"endColumn":54,"snippet":{"text":" /src/mcpCloudinc/src/mcpCloudinc/server.py\n AffectedNodeName: requests.get\n 390: SINK: response = requests.get(url, headers=headers)\n","affectedNodeName":"requests.get"}}}}}]}]}],"locations":[{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpCloudinc/src/mcpCloudinc/server.py"},"region":{"startLine":390,"startColumn":20,"endLine":390,"endColumn":54,"snippet":{"text":"requests.get(url, var headers:any=headers)"}}}}],"matchedSanitizerTags":""},{"message":{"text":"Python污点分析checker,不会使用CallGraph边界制作entrypoint,蚂蚁内部使用"},"level":"error","entrypoint":{"type":"functionCall","functionName":"handle_call_tool","filePath":"/src/mcpCloudinc/src/mcpCloudinc/server.py","attribute":"MCPTool","funcReceiverType":""},"sinkInfo":{"sinkRule":"requests.get","sinkAttribute":"PythonSSRF"},"codeFlows":[{"threadFlows":[{"locations":[{"location":{"message":{"text":"Step 0"},"physicalLocation":{"artifactLocation":{"uri":"file:///src/mcpCloudinc/src/mcpCloudinc/server.py"},"region":{"startLine":146,"startColumn":20,"endLine":146,"endColumn":29,"snippet":{"text":" /src/mcpCloudinc/src/mcpCloudinc/server.py\n AffectedNodeName: arguments\n 146: SOURCE: name: str, arguments: dict | None\n","affectedNodeName":"arguments"}}}}},{"location":{"message":{"text":"Step 1"},"physicalLocation":{"artifactLocation":{"uri":"file:///src/mcpCloudinc/src/mcpCloudinc/server.py"},"region":{"startLine":212,"startColumn":51,"endLine":212,"endColumn":85,"snippet":{"text":" /src/mcpCloudinc/src/mcpCloudinc/server.py\n AffectedNodeName: domain_env\n 212: Var Pass: domain_env=arguments[\"domain_env\"],\n","affectedNodeName":"domain_env"}}}}},{"location":{"message":{"text":"Step 2"},"physicalLocation":{"artifactLocation":{"uri":"file:///src/mcpCloudinc/src/mcpCloudinc/server.py"},"region":{"startLine":211,"startColumn":27,"endLine":215,"endColumn":70,"snippet":{"text":" /src/mcpCloudinc/src/mcpCloudinc/server.py\n AffectedNodeName: get_domain_labels\n 211: CALL: result_text = await get_domain_labels(domain_name=arguments[\"domain_name\"],\n 212: CALL: domain_env=arguments[\"domain_env\"],\n 213: CALL: tenant=arguments[\"tenant\"],\n 214: CALL: env=arguments[\"env\"],\n 215: CALL: ip=arguments[\"ip\"])\n","affectedNodeName":"get_domain_labels"}}}}},{"location":{"message":{"text":"Step 3"},"physicalLocation":{"artifactLocation":{"uri":"file:///src/mcpCloudinc/src/mcpCloudinc/server.py"},"region":{"startLine":368,"startColumn":29,"endLine":368,"endColumn":94,"snippet":{"text":" /src/mcpCloudinc/src/mcpCloudinc/server.py\n AffectedNodeName: domain_env\n 368: ARG PASS: async def get_domain_labels(domain_name: str, domain_env: str, tenant: str, env: str, ip: str) -> Optional[str]:\n","affectedNodeName":"domain_env"}}}}},{"location":{"message":{"text":"Step 4"},"physicalLocation":{"artifactLocation":{"uri":"file:///src/mcpCloudinc/src/mcpCloudinc/server.py"},"region":{"startLine":385,"startColumn":5,"endLine":385,"endColumn":94,"snippet":{"text":" /src/mcpCloudinc/src/mcpCloudinc/server.py\n AffectedNodeName: url\n 385: Var Pass: url = f\"{domain}/antvip/rest/api/v1/env/{domain_env}/domain/{domain_name}/ip/{ip}/labels\"\n","affectedNodeName":"url"}}}}},{"location":{"message":{"text":"Step 5"},"physicalLocation":{"artifactLocation":{"uri":"file:///src/mcpCloudinc/src/mcpCloudinc/server.py"},"region":{"startLine":390,"startColumn":20,"endLine":390,"endColumn":54,"snippet":{"text":" /src/mcpCloudinc/src/mcpCloudinc/server.py\n AffectedNodeName: requests.get\n 390: SINK: response = requests.get(url, headers=headers)\n","affectedNodeName":"requests.get"}}}}}]}]}],"locations":[{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpCloudinc/src/mcpCloudinc/server.py"},"region":{"startLine":390,"startColumn":20,"endLine":390,"endColumn":54,"snippet":{"text":"requests.get(url, var headers:any=headers)"}}}}],"matchedSanitizerTags":""},{"message":{"text":"Python污点分析checker,不会使用CallGraph边界制作entrypoint,蚂蚁内部使用"},"level":"error","entrypoint":{"type":"functionCall","functionName":"handle_call_tool","filePath":"/src/mcpCloudinc/src/mcpCloudinc/server.py","attribute":"MCPTool","funcReceiverType":""},"sinkInfo":{"sinkRule":"requests.get","sinkAttribute":"PythonSSRF"},"codeFlows":[{"threadFlows":[{"locations":[{"location":{"message":{"text":"Step 0"},"physicalLocation":{"artifactLocation":{"uri":"file:///src/mcpCloudinc/src/mcpCloudinc/server.py"},"region":{"startLine":146,"startColumn":20,"endLine":146,"endColumn":29,"snippet":{"text":" /src/mcpCloudinc/src/mcpCloudinc/server.py\n AffectedNodeName: arguments\n 146: SOURCE: name: str, arguments: dict | None\n","affectedNodeName":"arguments"}}}}},{"location":{"message":{"text":"Step 1"},"physicalLocation":{"artifactLocation":{"uri":"file:///src/mcpCloudinc/src/mcpCloudinc/server.py"},"region":{"startLine":214,"startColumn":51,"endLine":214,"endColumn":71,"snippet":{"text":" /src/mcpCloudinc/src/mcpCloudinc/server.py\n AffectedNodeName: env\n 214: Var Pass: env=arguments[\"env\"],\n","affectedNodeName":"env"}}}}},{"location":{"message":{"text":"Step 2"},"physicalLocation":{"artifactLocation":{"uri":"file:///src/mcpCloudinc/src/mcpCloudinc/server.py"},"region":{"startLine":211,"startColumn":27,"endLine":215,"endColumn":70,"snippet":{"text":" /src/mcpCloudinc/src/mcpCloudinc/server.py\n AffectedNodeName: get_domain_labels\n 211: CALL: result_text = await get_domain_labels(domain_name=arguments[\"domain_name\"],\n 212: CALL: domain_env=arguments[\"domain_env\"],\n 213: CALL: tenant=arguments[\"tenant\"],\n 214: CALL: env=arguments[\"env\"],\n 215: CALL: ip=arguments[\"ip\"])\n","affectedNodeName":"get_domain_labels"}}}}},{"location":{"message":{"text":"Step 3"},"physicalLocation":{"artifactLocation":{"uri":"file:///src/mcpCloudinc/src/mcpCloudinc/server.py"},"region":{"startLine":368,"startColumn":29,"endLine":368,"endColumn":94,"snippet":{"text":" /src/mcpCloudinc/src/mcpCloudinc/server.py\n AffectedNodeName: env\n 368: ARG PASS: async def get_domain_labels(domain_name: str, domain_env: str, tenant: str, env: str, ip: str) -> Optional[str]:\n","affectedNodeName":"env"}}}}},{"location":{"message":{"text":"Step 4"},"physicalLocation":{"artifactLocation":{"uri":"file:///src/mcpCloudinc/src/mcpCloudinc/server.py"},"region":{"startLine":384,"startColumn":5,"endLine":384,"endColumn":52,"snippet":{"text":" /src/mcpCloudinc/src/mcpCloudinc/server.py\n AffectedNodeName: domain\n 384: Var Pass: domain = CLOUDINC_URL_DICT.get(tenant).get(env)\n","affectedNodeName":"domain"}}}}},{"location":{"message":{"text":"Step 5"},"physicalLocation":{"artifactLocation":{"uri":"file:///src/mcpCloudinc/src/mcpCloudinc/server.py"},"region":{"startLine":385,"startColumn":5,"endLine":385,"endColumn":94,"snippet":{"text":" /src/mcpCloudinc/src/mcpCloudinc/server.py\n AffectedNodeName: url\n 385: Var Pass: url = f\"{domain}/antvip/rest/api/v1/env/{domain_env}/domain/{domain_name}/ip/{ip}/labels\"\n","affectedNodeName":"url"}}}}},{"location":{"message":{"text":"Step 6"},"physicalLocation":{"artifactLocation":{"uri":"file:///src/mcpCloudinc/src/mcpCloudinc/server.py"},"region":{"startLine":390,"startColumn":20,"endLine":390,"endColumn":54,"snippet":{"text":" /src/mcpCloudinc/src/mcpCloudinc/server.py\n AffectedNodeName: requests.get\n 390: SINK: response = requests.get(url, headers=headers)\n","affectedNodeName":"requests.get"}}}}}]}]}],"locations":[{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpCloudinc/src/mcpCloudinc/server.py"},"region":{"startLine":390,"startColumn":20,"endLine":390,"endColumn":54,"snippet":{"text":"requests.get(url, var headers:any=headers)"}}}}],"matchedSanitizerTags":""},{"message":{"text":"Python污点分析checker,不会使用CallGraph边界制作entrypoint,蚂蚁内部使用"},"level":"error","entrypoint":{"type":"functionCall","functionName":"handle_call_tool","filePath":"/src/mcpCloudinc/src/mcpCloudinc/server.py","attribute":"MCPTool","funcReceiverType":""},"sinkInfo":{"sinkRule":"requests.get","sinkAttribute":"PythonSSRF"},"codeFlows":[{"threadFlows":[{"locations":[{"location":{"message":{"text":"Step 0"},"physicalLocation":{"artifactLocation":{"uri":"file:///src/mcpCloudinc/src/mcpCloudinc/server.py"},"region":{"startLine":146,"startColumn":20,"endLine":146,"endColumn":29,"snippet":{"text":" /src/mcpCloudinc/src/mcpCloudinc/server.py\n AffectedNodeName: arguments\n 146: SOURCE: name: str, arguments: dict | None\n","affectedNodeName":"arguments"}}}}},{"location":{"message":{"text":"Step 1"},"physicalLocation":{"artifactLocation":{"uri":"file:///src/mcpCloudinc/src/mcpCloudinc/server.py"},"region":{"startLine":213,"startColumn":51,"endLine":213,"endColumn":77,"snippet":{"text":" /src/mcpCloudinc/src/mcpCloudinc/server.py\n AffectedNodeName: tenant\n 213: Var Pass: tenant=arguments[\"tenant\"],\n","affectedNodeName":"tenant"}}}}},{"location":{"message":{"text":"Step 2"},"physicalLocation":{"artifactLocation":{"uri":"file:///src/mcpCloudinc/src/mcpCloudinc/server.py"},"region":{"startLine":211,"startColumn":27,"endLine":215,"endColumn":70,"snippet":{"text":" /src/mcpCloudinc/src/mcpCloudinc/server.py\n AffectedNodeName: get_domain_labels\n 211: CALL: result_text = await get_domain_labels(domain_name=arguments[\"domain_name\"],\n 212: CALL: domain_env=arguments[\"domain_env\"],\n 213: CALL: tenant=arguments[\"tenant\"],\n 214: CALL: env=arguments[\"env\"],\n 215: CALL: ip=arguments[\"ip\"])\n","affectedNodeName":"get_domain_labels"}}}}},{"location":{"message":{"text":"Step 3"},"physicalLocation":{"artifactLocation":{"uri":"file:///src/mcpCloudinc/src/mcpCloudinc/server.py"},"region":{"startLine":368,"startColumn":29,"endLine":368,"endColumn":94,"snippet":{"text":" /src/mcpCloudinc/src/mcpCloudinc/server.py\n AffectedNodeName: tenant\n 368: ARG PASS: async def get_domain_labels(domain_name: str, domain_env: str, tenant: str, env: str, ip: str) -> Optional[str]:\n","affectedNodeName":"tenant"}}}}},{"location":{"message":{"text":"Step 4"},"physicalLocation":{"artifactLocation":{"uri":"file:///src/mcpCloudinc/src/mcpCloudinc/server.py"},"region":{"startLine":384,"startColumn":5,"endLine":384,"endColumn":52,"snippet":{"text":" /src/mcpCloudinc/src/mcpCloudinc/server.py\n AffectedNodeName: domain\n 384: Var Pass: domain = CLOUDINC_URL_DICT.get(tenant).get(env)\n","affectedNodeName":"domain"}}}}},{"location":{"message":{"text":"Step 5"},"physicalLocation":{"artifactLocation":{"uri":"file:///src/mcpCloudinc/src/mcpCloudinc/server.py"},"region":{"startLine":385,"startColumn":5,"endLine":385,"endColumn":94,"snippet":{"text":" /src/mcpCloudinc/src/mcpCloudinc/server.py\n AffectedNodeName: url\n 385: Var Pass: url = f\"{domain}/antvip/rest/api/v1/env/{domain_env}/domain/{domain_name}/ip/{ip}/labels\"\n","affectedNodeName":"url"}}}}},{"location":{"message":{"text":"Step 6"},"physicalLocation":{"artifactLocation":{"uri":"file:///src/mcpCloudinc/src/mcpCloudinc/server.py"},"region":{"startLine":390,"startColumn":20,"endLine":390,"endColumn":54,"snippet":{"text":" /src/mcpCloudinc/src/mcpCloudinc/server.py\n AffectedNodeName: requests.get\n 390: SINK: response = requests.get(url, headers=headers)\n","affectedNodeName":"requests.get"}}}}}]}]}],"locations":[{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpCloudinc/src/mcpCloudinc/server.py"},"region":{"startLine":390,"startColumn":20,"endLine":390,"endColumn":54,"snippet":{"text":"requests.get(url, var headers:any=headers)"}}}}],"matchedSanitizerTags":""},{"message":{"text":"Python污点分析checker,不会使用CallGraph边界制作entrypoint,蚂蚁内部使用"},"level":"error","entrypoint":{"type":"functionCall","functionName":"query_specific_db","filePath":"/src/mcpDbQueryPrivate/src/mcpDbQueryPrivate/server.py","attribute":"MCPTool","funcReceiverType":""},"sinkInfo":{"sinkRule":"cursor.execute","sinkAttribute":"PythonSqlInjection"},"codeFlows":[{"threadFlows":[{"locations":[{"location":{"message":{"text":"Step 0"},"physicalLocation":{"artifactLocation":{"uri":"file:///src/mcpDbQueryPrivate/src/mcpDbQueryPrivate/server.py"},"region":{"startLine":27,"startColumn":29,"endLine":27,"endColumn":32,"snippet":{"text":" /src/mcpDbQueryPrivate/src/mcpDbQueryPrivate/server.py\n AffectedNodeName: sql\n 27: SOURCE: async def query_specific_db(sql: str, database: str):\n","affectedNodeName":"sql"}}}}},{"location":{"message":{"text":"Step 1"},"physicalLocation":{"artifactLocation":{"uri":"file:///src/mcpDbQueryPrivate/src/mcpDbQueryPrivate/server.py"},"region":{"startLine":35,"startColumn":93,"endLine":35,"endColumn":100,"snippet":{"text":" /src/mcpDbQueryPrivate/src/mcpDbQueryPrivate/server.py\n AffectedNodeName: sql\n 35: Var Pass: return await _query_physic_db(db_name=database, db_arn=WHITE_PROD_DB.get(database), sql=sql,\n","affectedNodeName":"sql"}}}}},{"location":{"message":{"text":"Step 2"},"physicalLocation":{"artifactLocation":{"uri":"file:///src/mcpDbQueryPrivate/src/mcpDbQueryPrivate/server.py"},"region":{"startLine":35,"startColumn":16,"endLine":36,"endColumn":72,"snippet":{"text":" /src/mcpDbQueryPrivate/src/mcpDbQueryPrivate/server.py\n AffectedNodeName: _query_physic_db\n 35: CALL: return await _query_physic_db(db_name=database, db_arn=WHITE_PROD_DB.get(database), sql=sql,\n 36: CALL: db_config=DB_CONFIG, params=None)\n","affectedNodeName":"_query_physic_db"}}}}},{"location":{"message":{"text":"Step 3"},"physicalLocation":{"artifactLocation":{"uri":"file:///src/mcpDbQueryPrivate/src/mcpDbQueryPrivate/server.py"},"region":{"startLine":64,"startColumn":28,"endLine":64,"endColumn":93,"snippet":{"text":" /src/mcpDbQueryPrivate/src/mcpDbQueryPrivate/server.py\n AffectedNodeName: sql\n 64: ARG PASS: async def _query_physic_db(db_name: str, db_arn: str, sql: str, db_config: dict, params=None):\n","affectedNodeName":"sql"}}}}},{"location":{"message":{"text":"Step 4"},"physicalLocation":{"artifactLocation":{"uri":"file:///src/mcpDbQueryPrivate/src/mcpDbQueryPrivate/server.py"},"region":{"startLine":78,"startColumn":17,"endLine":78,"endColumn":50,"snippet":{"text":" /src/mcpDbQueryPrivate/src/mcpDbQueryPrivate/server.py\n AffectedNodeName: cursor.execute\n 78: SINK: cursor.execute(sql, params or ())\n","affectedNodeName":"cursor.execute"}}}}}]}]}],"locations":[{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDbQueryPrivate/src/mcpDbQueryPrivate/server.py"},"region":{"startLine":78,"startColumn":17,"endLine":78,"endColumn":50,"snippet":{"text":"cursor.execute(sql, params||())"}}}}],"matchedSanitizerTags":""},{"message":{"text":"Python污点分析checker,不会使用CallGraph边界制作entrypoint,蚂蚁内部使用"},"level":"error","entrypoint":{"type":"functionCall","functionName":"query_layotto_db","filePath":"/src/mcpDbQueryPrivate/src/mcpDbQueryPrivate/server.py","attribute":"MCPTool","funcReceiverType":""},"sinkInfo":{"sinkRule":"cursor.execute","sinkAttribute":"PythonSqlInjection"},"codeFlows":[{"threadFlows":[{"locations":[{"location":{"message":{"text":"Step 0"},"physicalLocation":{"artifactLocation":{"uri":"file:///src/mcpDbQueryPrivate/src/mcpDbQueryPrivate/server.py"},"region":{"startLine":42,"startColumn":28,"endLine":42,"endColumn":31,"snippet":{"text":" /src/mcpDbQueryPrivate/src/mcpDbQueryPrivate/server.py\n AffectedNodeName: sql\n 42: SOURCE: async def query_layotto_db(sql: str, database: str):\n","affectedNodeName":"sql"}}}}},{"location":{"message":{"text":"Step 1"},"physicalLocation":{"artifactLocation":{"uri":"file:///src/mcpDbQueryPrivate/src/mcpDbQueryPrivate/server.py"},"region":{"startLine":49,"startColumn":36,"endLine":49,"endColumn":43,"snippet":{"text":" /src/mcpDbQueryPrivate/src/mcpDbQueryPrivate/server.py\n AffectedNodeName: sql\n 49: Var Pass: return await _query_layotto_db(sql=sql, database=database)\n","affectedNodeName":"sql"}}}}},{"location":{"message":{"text":"Step 2"},"physicalLocation":{"artifactLocation":{"uri":"file:///src/mcpDbQueryPrivate/src/mcpDbQueryPrivate/server.py"},"region":{"startLine":49,"startColumn":12,"endLine":49,"endColumn":63,"snippet":{"text":" /src/mcpDbQueryPrivate/src/mcpDbQueryPrivate/server.py\n AffectedNodeName: _query_layotto_db\n 49: CALL: return await _query_layotto_db(sql=sql, database=database)\n","affectedNodeName":"_query_layotto_db"}}}}},{"location":{"message":{"text":"Step 3"},"physicalLocation":{"artifactLocation":{"uri":"file:///src/mcpDbQueryPrivate/src/mcpDbQueryPrivate/server.py"},"region":{"startLine":52,"startColumn":29,"endLine":52,"endColumn":52,"snippet":{"text":" /src/mcpDbQueryPrivate/src/mcpDbQueryPrivate/server.py\n AffectedNodeName: sql\n 52: ARG PASS: async def _query_layotto_db(sql: str, database: str):\n","affectedNodeName":"sql"}}}}},{"location":{"message":{"text":"Step 4"},"physicalLocation":{"artifactLocation":{"uri":"file:///src/mcpDbQueryPrivate/src/mcpDbQueryPrivate/server.py"},"region":{"startLine":57,"startColumn":13,"endLine":57,"endColumn":32,"snippet":{"text":" /src/mcpDbQueryPrivate/src/mcpDbQueryPrivate/server.py\n AffectedNodeName: cursor.execute\n 57: SINK: cursor.execute(sql)\n","affectedNodeName":"cursor.execute"}}}}}]}]}],"locations":[{"physicalLocation":{"artifactLocation":{"uri":"/Users/jiufo/PythonProject/mcp_server/src/mcpDbQueryPrivate/src/mcpDbQueryPrivate/server.py"},"region":{"startLine":57,"startColumn":13,"endLine":57,"endColumn":32,"snippet":{"text":"cursor.execute(sql)"}}}}],"matchedSanitizerTags":""}]}],"version":"2.1.0"} diff --git a/src/resolver/common/type-related-info-resolver.ts b/src/resolver/common/type-related-info-resolver.ts index d6955d1b..d3175672 100644 --- a/src/resolver/common/type-related-info-resolver.ts +++ b/src/resolver/common/type-related-info-resolver.ts @@ -12,6 +12,8 @@ const astUtil = require('../../util/ast-util') const MemSpace = require('../../engine/analyzer/common/memSpace') const { prettyPrint } = require('../../util/ast-util') const { getValueFromPackageByQid } = require('../../engine/util/value-util') +const QidUnifyUtil = require('../../util/qid-unify-util') +const Config = require('../../config') /** * resolve type, declarations, invocations after preprocess @@ -31,7 +33,7 @@ export default class TypeRelatedInfoResolver extends MemSpace { this.classHierarchyMap = this.findClassHierarchy(analyzer, analyzer.initState(analyzer.topScope)) Object.entries(analyzer.funcSymbolTable).forEach(([, funcSymbol]) => { const funcSymbolAny = funcSymbol as any - if (funcSymbolAny.vtype === 'fclos' && funcSymbolAny.ast) { + if (funcSymbolAny.vtype === 'fclos' && funcSymbolAny.ast.node) { const targetAstAndScopeArray = this.findTargetUastNodeInScope(funcSymbolAny) for (const targetAstAndScope of targetAstAndScopeArray) { const thisScope = @@ -105,17 +107,53 @@ export default class TypeRelatedInfoResolver extends MemSpace { const resultArray: TypeRelatedInfoResult[] = [] let val + let funcDef let defScopeType: string = '' const defScope = this.getDefScope(scope, node) if (defScope) { if (['class', 'package'].includes(defScope.vtype)) { - defScopeType = defScope._qid + defScopeType = defScope.logicalQid + } + val = this.getMemberValueNoCreate(defScope, node, state, 1) + if ( + Config.loadContextEnvironmentId?.startsWith('jdk8') && + (val?.vtype === 'undefine' || defScope.qid === '') + ) { + const langScope = getValueFromPackageByQid(analyzer.topScope.context.packages, 'java.lang') + val = this.getMemberValueNoCreate(langScope, node, state, 1) } - val = this.getMemberValueNoCreate(defScope, node, 1) } if (val?.vtype !== 'undefine') { if (['class', 'package'].includes(val.vtype)) { - resultArray.push(this.assembleTypeResult(node, 0, node.name, val._qid, val, val.ast, defScope, defScopeType)) + if (this.checkDefineInLocalScope(scope, node)) { + let declScope = scope + while (declScope) { + if (declScope.declarationMap?.has(node.name)) { + const { type } = declScope.declarationMap.get(node.name) + resultArray.push(this.assembleTypeResult(node, 0, node.name, type, undefined, undefined, undefined, '')) + break + } + if (declScope.scope?.declarationMap?.has(node.name)) { + const { type } = declScope.scope.declarationMap.get(node.name) + resultArray.push(this.assembleTypeResult(node, 0, node.name, type, undefined, undefined, undefined, '')) + break + } + declScope = declScope.parent + } + } else { + resultArray.push( + this.assembleTypeResult( + node, + 0, + node.name, + QidUnifyUtil.qidUnifyByRemoveAngleAndPrefix(val.qid), + val, + val.ast, + defScope, + defScopeType + ) + ) + } } else if (val.rtype?.definiteType && !val.rtype?.vagueType) { resultArray.push( this.assembleTypeResult( @@ -124,19 +162,19 @@ export default class TypeRelatedInfoResolver extends MemSpace { node.name, prettyPrint(val.rtype.definiteType), val, - val.ast, + val.ast?.node, defScope, defScopeType ) ) - } else if (val.vtype === 'fclos' && val.overloaded?.length > 0 && Array.isArray(state.argumentTypes)) { - const funcDef = this.findMatchedFuncDef(val, state.argumentTypes) + } else if (val.vtype === 'fclos' && val.overloaded.length > 0 && Array.isArray(state.argumentTypes)) { + funcDef = this.findMatchedFuncDef(val, state.argumentTypes) const funcReturnTypeArray = this.resolveInstruction(analyzer, scope, funcDef.returnType, state) for (const funcReturnType of funcReturnTypeArray) { const finalTypeResult: TypeRelatedInfoResult = this.assembleTypeResult( node, funcReturnType.index, - funcReturnType.name, + node.name, funcReturnType.type, val, funcDef, @@ -149,8 +187,8 @@ export default class TypeRelatedInfoResolver extends MemSpace { } else { let declScope = scope while (declScope) { - if (scope.declarationMap?.has(node.name)) { - const { type } = scope.declarationMap.get(node.name) + if (declScope.scope?.declarationMap?.has(node.name)) { + const { type } = declScope.scope.declarationMap.get(node.name) resultArray.push(this.assembleTypeResult(node, 0, node.name, type, undefined, undefined, undefined, '')) break } @@ -162,7 +200,9 @@ export default class TypeRelatedInfoResolver extends MemSpace { if (state.allOrigin) { resultArray.push(this.assembleTypeResult(node, 0, node.name, node.name, undefined, undefined, undefined, '')) } else { - resultArray.push(this.assembleTypeResult(node, 0, node.name, '', val, val?.ast, defScope, defScopeType)) + resultArray.push( + this.assembleTypeResult(node, 0, node.name, '', val, funcDef || val?.ast?.node, defScope, defScopeType) + ) } } @@ -233,10 +273,10 @@ export default class TypeRelatedInfoResolver extends MemSpace { declSite: node, nodeScope: state.nodeScope, } - if (!(state.nodeScope.declarationMap instanceof Map)) { - state.nodeScope.declarationMap = new Map() + if (!(state.nodeScope.scope.declarationMap instanceof Map)) { + state.nodeScope.scope.declarationMap = new Map() } - state.nodeScope.declarationMap.set(nameArray[i], declaration) + state.nodeScope.scope.declarationMap.set(nameArray[i], declaration) } } @@ -260,13 +300,29 @@ export default class TypeRelatedInfoResolver extends MemSpace { if (objTypeResultArray.length === 1) { const objTypeResult: TypeRelatedInfoResult = objTypeResultArray[0] objScopeType = objTypeResult.type + if (objTypeResult.type?.endsWith('[]')) { + resultArray.push( + this.assembleTypeResult( + node, + 0, + '', + objTypeResult.type.substring(0, objTypeResult.type.length - 2), + objTypeResult.value, + objTypeResult.valueNode, + objTypeResult.valueDefScope, + objTypeResult.valueDefScopeType + ) + ) + return resultArray + } + if (['class', 'package'].includes(objTypeResult.value?.vtype)) { objScope = objTypeResult.value } else if (objTypeResult.type !== '') { if (objTypeResult.type.includes('.')) { - objScope = getValueFromPackageByQid(analyzer.topScope.packageManager, objTypeResult.type) + objScope = getValueFromPackageByQid(analyzer.topScope.context.packages, objTypeResult.type) } else { - objScope = this.getMemberValueNoCreate(scope, UastSpec.identifier(objTypeResult.type)) + objScope = this.getMemberValueNoCreate(scope, UastSpec.identifier(objTypeResult.type), state) } } } @@ -374,12 +430,14 @@ export default class TypeRelatedInfoResolver extends MemSpace { callSite: node, fromScope: state.nodeScope, fromScopeAst: state.nodeScopeAst, - toScope: returnTypeResult.value, - toScopeAst: returnTypeResult.valueNode, + toScope: returnTypeResult.value?.vtype === 'fclos' ? returnTypeResult.value : undefined, + toScopeAst: + returnTypeResult.valueNode?.type === 'FunctionDefinition' ? returnTypeResult.valueNode : undefined, } if (node?._meta?.nodehash) { this.addInvocationToScope(state.nodeScope, node?._meta?.nodehash, invocation) - if (invocation.calleeType !== '') { + const invokeSuper = node.callee?.type === 'MemberAccess' && node.callee.object?.type === 'SuperExpression' + if (invocation.calleeType !== '' && !invokeSuper) { const polyInvocationArray = this.findPolymorphismInvocation(invocation, state) this.addInvocationToScope(state.nodeScope, node?._meta?.nodehash, polyInvocationArray) } @@ -606,26 +664,23 @@ export default class TypeRelatedInfoResolver extends MemSpace { const fclos = this.getMemberValueNoCreate(classVal, UastSpec.identifier('_CTOR_'), state, 1) if (fclos?.vtype === 'fclos') { const funcDef = this.findMatchedFuncDef(fclos, calleeArgumentTypes) - const funcReturnTypeArray = this.resolveInstruction(analyzer, scope, funcDef.returnType, state) - for (const funcReturnType of funcReturnTypeArray) { - const finalTypeResult: TypeRelatedInfoResult = this.assembleTypeResult( - node, - funcReturnType.index, - funcReturnType.name, - funcReturnType.type, - fclos, - funcDef, - classVal, - classVal._qid - ) - resultArray.push(finalTypeResult) - } + const finalTypeResult: TypeRelatedInfoResult = this.assembleTypeResult( + node, + 0, + '', + classVal.logicalQid, + fclos, + funcDef, + classVal, + classVal.logicalQid + ) + resultArray.push(finalTypeResult) if (state.nodeScope) { const invocation: Invocation = { callSiteLiteral: prettyPrint(node.callee), - calleeType: classVal._qid, - fsig: fclos._sid, + calleeType: classVal.logicalQid, + fsig: fclos.sid, argTypes: calleeArgumentTypes, callSite: node, fromScope: state.nodeScope, @@ -638,9 +693,21 @@ export default class TypeRelatedInfoResolver extends MemSpace { } } } else if (state.nodeScope) { + const finalTypeResult: TypeRelatedInfoResult = this.assembleTypeResult( + node, + 0, + '', + classVal.logicalQid, + undefined, + undefined, + classVal, + classVal.logicalQid + ) + resultArray.push(finalTypeResult) + const invocation: Invocation = { callSiteLiteral: prettyPrint(node.callee), - calleeType: classVal._qid, + calleeType: classVal.logicalQid, fsig: prettyPrint(node.callee), argTypes: calleeArgumentTypes, callSite: node, @@ -670,6 +737,20 @@ export default class TypeRelatedInfoResolver extends MemSpace { } } + if (resultArray.length === 0) { + const finalTypeResult: TypeRelatedInfoResult = this.assembleTypeResult( + node, + 0, + '', + prettyPrint(node.callee), + undefined, + undefined, + undefined, + prettyPrint(node.callee) + ) + resultArray.push(finalTypeResult) + } + return resultArray } @@ -805,7 +886,16 @@ export default class TypeRelatedInfoResolver extends MemSpace { const resultArray: TypeRelatedInfoResult[] = [] if (scope.parent?.vtype === 'class') { resultArray.push( - this.assembleTypeResult(node, 0, '', scope.parent._qid, scope.parent, scope.parent.ast, scope.parent.parent, '') + this.assembleTypeResult( + node, + 0, + '', + scope.parent.logicalQid, + scope.parent, + scope.parent.ast?.node, + scope.parent.parent, + '' + ) ) } return resultArray @@ -827,14 +917,15 @@ export default class TypeRelatedInfoResolver extends MemSpace { node, 0, '', - scope.parent.super._qid, + scope.parent.super.logicalQid, scope.parent.super, - scope.parent.super.ast, + scope.parent.super.ast?.node, scope.parent.super.parent, '' ) ) } + return resultArray } @@ -871,6 +962,39 @@ export default class TypeRelatedInfoResolver extends MemSpace { return resultArray } + /** + * ArrayType + * @param analyzer + * @param scope + * @param node + * @param state + * @returns {TypeRelatedInfoResult[]} + */ + resolveArrayType(analyzer: any, scope: any, node: any, state: any): TypeRelatedInfoResult[] { + const resultArray: TypeRelatedInfoResult[] = [] + + const newState = lodash.clone(state) + newState.parent = state + newState.allOrigin = true + + const elementTypeResultArray = this.resolveInstruction(analyzer, scope, node.element, state) + for (const elementTypeResult of elementTypeResultArray) { + const finalTypeResult: TypeRelatedInfoResult = this.assembleTypeResult( + node, + elementTypeResult.index, + elementTypeResult.name !== '' ? `${elementTypeResult.name}[]` : elementTypeResult.name, + elementTypeResult.type !== '' ? `${elementTypeResult.type}[]` : elementTypeResult.type, + elementTypeResult.value, + elementTypeResult.valueNode, + elementTypeResult.valueDefScope, + elementTypeResult.valueDefScopeType + ) + resultArray.push(finalTypeResult) + } + + return resultArray + } + /** * PointerType * @param analyzer @@ -948,12 +1072,12 @@ export default class TypeRelatedInfoResolver extends MemSpace { findTargetUastNodeInScope(funcSymbol: any): any[] { const resultArray: AstAndScope[] = [] - if (funcSymbol.vtype !== 'fclos' || !Array.isArray(funcSymbol.overloaded)) { + if (funcSymbol.vtype !== 'fclos' || !funcSymbol.overloaded?.length) { return resultArray } const typeResolverASTVisitor = new TypeResolverASTVisitor() - for (const funcDef of funcSymbol.overloaded) { + for (const funcDef of funcSymbol.overloaded.filter(() => true)) { typeResolverASTVisitor.nodeScope = funcSymbol typeResolverASTVisitor.nodeScopeAst = funcDef typeResolverASTVisitor.astAndScopeArray = [] @@ -1028,6 +1152,34 @@ export default class TypeRelatedInfoResolver extends MemSpace { return resultArray } + /** + * find baseTypes + * @param typeInfo + * @param typeDeclaration + * @returns {string[]} + */ + findBaseTypes(typeInfo: ClassHierarchy, typeDeclaration?: string): string[] { + const resultArray: string[] = [] + if (!typeInfo) { + return resultArray + } + + for (const extendsTypeInfo of typeInfo.extends) { + if (!typeDeclaration || typeDeclaration === extendsTypeInfo.typeDeclaration) { + resultArray.push(extendsTypeInfo.type) + } + resultArray.push(...this.findBaseTypes(extendsTypeInfo, typeDeclaration)) + } + for (const implementsTypeInfo of typeInfo.implements) { + if (!typeDeclaration || typeDeclaration === implementsTypeInfo.typeDeclaration) { + resultArray.push(implementsTypeInfo.type) + } + resultArray.push(...this.findBaseTypes(implementsTypeInfo, typeDeclaration)) + } + + return resultArray + } + /** * find invoke by polymorphism * @param invocation @@ -1051,9 +1203,10 @@ export default class TypeRelatedInfoResolver extends MemSpace { continue } const fclos = this.getMemberValueNoCreate(subClassHierarchy.value, UastSpec.identifier(invocation.fsig), state, 1) - if (fclos?.vtype !== 'fclos' || !Array.isArray(fclos.overloaded)) { + if (fclos?.vtype !== 'fclos' || fclos.func?.inherited) { continue } + if (!fclos.overloaded?.length) continue let polyFuncDef for (const funcDef of fclos.overloaded) { if (funcDef.parameters.length === invocation.argTypes.length) { @@ -1103,20 +1256,26 @@ export default class TypeRelatedInfoResolver extends MemSpace { * @returns {*} */ findMatchedFuncDef(fclos: any, argumentTypes: string[]): any { - if (fclos?.vtype !== 'fclos' || !Array.isArray(fclos.overloaded) || fclos.overloaded.length === 0) { + if (fclos?.vtype !== 'fclos' || !fclos.overloaded?.length) { return undefined } - let funcDef = fclos.overloaded[0] + let funcDef = fclos.overloaded.get(0) for (const f of fclos.overloaded) { - const paramLength = Array.isArray(f.parameters) ? f.parameters.length : f.parameters.parameters.length - if (paramLength !== argumentTypes.length) { + if (!Array.isArray(f.parameters)) { continue } - funcDef = f - if (this.checkFuncParamTypeMatch(f.parameters, argumentTypes)) { + if ( + f.parameters.length === argumentTypes.length || + (f.parameters.length < argumentTypes.length && + f.parameters.length > 0 && + f.parameters[f.parameters.length - 1].varType?._meta?.varargs) + ) { funcDef = f - break + if (this.checkFuncParamTypeMatch(f.parameters, argumentTypes)) { + funcDef = f + break + } } } @@ -1130,23 +1289,53 @@ export default class TypeRelatedInfoResolver extends MemSpace { * @returns {boolean} */ checkFuncParamTypeMatch(parameters: any, argumentTypes: string[]): boolean { - const paramLength = Array.isArray(parameters) ? parameters.length : parameters.parameters.length - if (paramLength !== argumentTypes.length) { + if (!Array.isArray(parameters)) { return false } - let typeMatch = true - for (let i = 0; i < paramLength; i++) { - if ( - argumentTypes[i] === '' || - parameters[i].varType?.id?.name === argumentTypes[i] || - argumentTypes[i].endsWith(`.${parameters[i].varType?.id?.name}`) - ) { - continue + + if (parameters.length === argumentTypes.length) { + let typeMatch = true + for (let i = 0; i < argumentTypes.length; i++) { + if (!argumentTypes[i] || argumentTypes[i] === '') { + continue + } + const paramAst = parameters[i] + const paramType = paramAst.varType?.id?.name + let argType = argumentTypes[i] + if (argType.endsWith('[]')) { + argType = argType.substring(0, argType.length - 2) + } + if (paramType === argType || argType.endsWith(`.${paramType}`)) { + continue + } + typeMatch = false } - typeMatch = false + return typeMatch } - - return typeMatch + if ( + parameters.length < argumentTypes.length && + parameters.length > 0 && + parameters[parameters.length - 1]?.varType?._meta?.varargs + ) { + let typeMatch = true + for (let i = 0; i < argumentTypes.length; i++) { + if (!argumentTypes[i] || argumentTypes[i] === '') { + continue + } + const paramAst = i < parameters.length ? parameters[i] : parameters[parameters.length - 1] + const paramType = paramAst.varType?.id?.name + let argType = argumentTypes[i] + if (argType.endsWith('[]')) { + argType = argType.substring(0, argType.length - 2) + } + if (paramType === argType || argType.endsWith(`.${paramType}`)) { + continue + } + typeMatch = false + } + return typeMatch + } + return false } /** @@ -1194,4 +1383,22 @@ export default class TypeRelatedInfoResolver extends MemSpace { return load(this) } + + /** + * check if identifer define in local scope + * @param scope + */ + checkDefineInLocalScope(scope: any, node: any) { + if (!node || node.type !== 'Identifier') { + return false + } + let declScope = scope + while (declScope) { + if (declScope.declarationMap?.has(node.name) || declScope.scope?.declarationMap?.has(node.name)) { + return true + } + declScope = declScope.parent + } + return false + } } diff --git a/src/resolver/go/go-type-related-info-resolver.ts b/src/resolver/go/go-type-related-info-resolver.ts index 6ac12246..2d62b987 100644 --- a/src/resolver/go/go-type-related-info-resolver.ts +++ b/src/resolver/go/go-type-related-info-resolver.ts @@ -11,7 +11,7 @@ export default class GoTypeRelatedInfoResolver extends TypeRelatedInfoResolver { * @param state * @returns {Map} */ - findClassHierarchy(analyzer: any, state: any): Map { + override findClassHierarchy(analyzer: any, state: any): Map { // TODO return new Map() } diff --git a/src/resolver/java/java-type-related-info-resolver.ts b/src/resolver/java/java-type-related-info-resolver.ts index 971f4036..2fccddbd 100644 --- a/src/resolver/java/java-type-related-info-resolver.ts +++ b/src/resolver/java/java-type-related-info-resolver.ts @@ -1,52 +1,80 @@ import TypeRelatedInfoResolver from '../common/type-related-info-resolver' import type { ClassHierarchy } from '../common/value/class-hierarchy' +const QidUnifyUtil = require('../../util/qid-unify-util') +const { getValueFromPackageByQid } = require('../../engine/util/value-util') + /** * JavaTypeRelatedInfoResolver */ export default class JavaTypeRelatedInfoResolver extends TypeRelatedInfoResolver { + /** + * + * @param analyzer + */ + override resolve(analyzer: any) { + super.resolve(analyzer) + + for (const classVal of analyzer.classMap.values()) { + if (!classVal.super || !classVal.members?.size) { + continue + } + for (const [key, element] of classVal.members.entries() as any[]) { + if (key === 'super' || !element || element.vtype !== 'fclos' || !element.func?.inherited) { + continue + } + const baseVal = element._base?.members?.get(key) + if (baseVal?.vtype === 'fclos') { + element.scope.declarationMap = baseVal.scope.declarationMap + element.invocationMap = baseVal.invocationMap + } + } + } + } + /** * find class hierarchy * @param analyzer * @param state * @returns {Map} */ - findClassHierarchy(analyzer: any, state: any): Map { + override findClassHierarchy(analyzer: any, state: any): Map { const resultMap: Map = new Map() if (!analyzer.classMap) { return resultMap } - for (const classVal of analyzer.classMap.values()) { - if (!classVal.ast) { + for (const classValUuid of analyzer.classMap.values()) { + const classVal = analyzer.symbolTable.get(classValUuid) + if (!classVal.ast.node) { continue } - let classHierarchy = resultMap.get(classVal._qid) + let classHierarchy = resultMap.get(classVal.logicalQid) if (!classHierarchy) { classHierarchy = { - typeDeclaration: classVal.ast._meta?.typeDeclaration ? classVal.ast._meta.typeDeclaration : 'class', - type: classVal._qid, + typeDeclaration: classVal.ast.node._meta?.typeDeclaration ? classVal.ast.node._meta.typeDeclaration : 'class', + type: classVal.logicalQid, value: classVal, extends: [], extendedBy: [], implements: [], implementedBy: [], } - resultMap.set(classVal._qid, classHierarchy) + resultMap.set(classVal.logicalQid, classHierarchy) } - if (!Array.isArray(classVal.ast?.supers) || classVal.ast.supers.length === 0) { + if (!Array.isArray(classVal.ast?.node?.supers) || classVal.ast.node.supers.length === 0) { continue } - for (const superAst of classVal.ast.supers) { + for (const superAst of classVal.ast.node.supers) { const superClsVal = this.getMemberValueNoCreate(classVal, superAst, state) - const superClsName = superClsVal ? superClsVal._qid : superAst.name + const superClsName = superClsVal ? superClsVal.logicalQid : superAst.name let superClassHierarchy = resultMap.get(superClsName) if (!superClassHierarchy) { superClassHierarchy = { - typeDeclaration: superClsVal?.ast?._meta?.typeDeclaration ? superClsVal.ast._meta.typeDeclaration : 'class', + typeDeclaration: superClsVal?.ast?.node?._meta?.typeDeclaration ? superClsVal.ast.node._meta.typeDeclaration : 'class', type: superClsName, value: superClsVal, extends: [], @@ -67,6 +95,60 @@ export default class JavaTypeRelatedInfoResolver extends TypeRelatedInfoResolver } } + for (const classValUuid of analyzer.classMap.values()) { + const classVal = analyzer.symbolTable.get(classValUuid) + if (!classVal) { + continue + } + const fullClassName = classVal.logicalQid + if (!analyzer.extraClassHierarchyByNameMap?.has(fullClassName)) { + continue + } + let classHierarchy = resultMap.get(classVal.logicalQid) + if (!classHierarchy) { + classHierarchy = { + typeDeclaration: 'class', + type: classVal.logicalQid, + value: classVal, + extends: [], + extendedBy: [], + implements: [], + implementedBy: [], + } + resultMap.set(fullClassName, classHierarchy) + } + const subTypes = this.findSubTypes(classHierarchy) + for (const superClsName of analyzer.extraClassHierarchyByNameMap.get(fullClassName)) { + if (subTypes.includes(superClsName)) { + continue + } + const superClsVal = getValueFromPackageByQid(analyzer?.topScope?.context?.packages, superClsName) + if (superClsVal?.vtype === 'class') { + let superClassHierarchy = resultMap.get(superClsName) + if (!superClassHierarchy) { + superClassHierarchy = { + typeDeclaration: 'class', + type: superClsName, + value: superClsVal, + extends: [], + extendedBy: [], + implements: [], + implementedBy: [], + } + resultMap.set(superClsName, superClassHierarchy) + } + + if (classHierarchy.typeDeclaration === 'class' && superClassHierarchy.typeDeclaration === 'interface') { + classHierarchy.implements.push(superClassHierarchy) + superClassHierarchy.implementedBy.push(classHierarchy) + } else { + classHierarchy.extends.push(superClassHierarchy) + superClassHierarchy.extendedBy.push(classHierarchy) + } + } + } + } + return resultMap } } diff --git a/src/types/analyzer.ts b/src/types/analyzer.ts new file mode 100644 index 00000000..a588ba5c --- /dev/null +++ b/src/types/analyzer.ts @@ -0,0 +1,84 @@ +// Analyzer 相关类型定义 + +/** + * 作用域 + */ +export interface Scope { + qid: string; + [key: string]: any; +} + +/** + * 分析状态 + * + * 核心字段由 initState() 创建,运行时字段在 executeFdeclOrExecute 等处追加。 + * 索引签名暂时保留,待所有消费方迁移完成后删除。 + */ +export interface State { + // 核心(initState 创建) + pcond: any[]; + callstack: any[]; + brs: string; + binfo: Record; + einfo: Record; + this?: any; + + // 运行时(executeFdeclOrExecute / memState 追加) + callsites?: any[]; + parent?: State; + br_index?: number; + + // 语言特有(动态添加/删除) + throwstack?: any[]; + throwstackScopeAndState?: Array<{ scope: any; state: State }>; + entryPointStartTimestamp?: number; + findIdInCurScope?: boolean; + tid?: string; + + // 过渡:待消除 + [key: string]: any; +} + +/** + * 分析值 - 从 value.ts 导出强类型 + */ +export type { + Value, + ValueBase, + PrimitiveValue, + ObjectValue, + ScopedValue, + FunctionValue, + UndefinedValue, + UninitializedValue, + UnknownValue, + UnionValue, + SymbolValue, + BVTValue, + PackageValue, + TypedValue, + TaintedValue, + VoidValue, + SpreadValue, + BinaryExprValue, + UnaryExprValue, + MemberExprValue, + CallExprValue, + IdentifierRefValue, + // 类型守卫 + isPrimitive, + isObject, + isScoped, + isFunction, + isUndefined, + isUninitialized, + isUnknown, + isUnion, + isSymbol, + isBVT, + isPackage, + isTyped, + isTainted, + isVoid, + isSpread, +} from './value'; diff --git a/src/types/uast.ts b/src/types/uast.ts new file mode 100644 index 00000000..0b92c074 --- /dev/null +++ b/src/types/uast.ts @@ -0,0 +1,134 @@ +// ===== UAST 三层继承类型系统 ===== +// 结构: BaseNode → 6大分类基类 → 具体节点 + +// 运行时属性扩展(UAST walker 在运行时添加的属性) +declare module '@ant-yasa/uast-spec' { + interface BaseNode { + parent?: BaseNode | null + } + interface ExprBase { + name?: string + } + interface StmtBase { + name?: string + } + interface DeclBase { + name?: string + } +} + +// 第1层: BaseNode +export type { BaseNode } from '@ant-yasa/uast-spec' + +// 第2层: 6大分类基类 (extends BaseNode) +export type { + CompileUnitBase, // CompileUnit基类 + StmtBase, // Stmt基类 (控制流语句) + ExprBase, // Expr基类 (表达式) + DeclBase, // Decl基类 (声明) + TypeBase, // Type基类 (类型系统) + NameBase, // Name基类 (标识符) +} from '@ant-yasa/uast-spec' + +// 第2层: 6大分类联合类型 +export type { + Node, // 所有节点 + CompileUnit, // 翻译单元 + Stmt, // 控制流语句 (17个) + Expr, // 表达式 (21个) + Decl, // 声明 (4个) + Type, // 类型 (10个) + Name, // 标识符 (1个) +} from '@ant-yasa/uast-spec' + +// 类型守卫 +export { isCompileUnit, isStmt, isExpr, isDecl, isType, isName } from '@ant-yasa/uast-spec' + +// 第3层: 具体节点 (通过交叉类型继承对应的基类) +export type { + // Stmt (17个) - 都继承 StmtBase + Noop, + IfStatement, + SwitchStatement, + CaseClause, + ForStatement, + WhileStatement, + RangeStatement, + BreakStatement, + ContinueStatement, + ReturnStatement, + ThrowStatement, + ScopedStatement, + TryStatement, + CatchClause, + LabeledStatement, + ExpressionStatement, + ExportStatement, + + // Expr (21个) - 都继承 ExprBase + Literal, + ThisExpression, + SuperExpression, + UnaryExpression, + BinaryExpression, + AssignmentExpression, + ConditionalExpression, + CallExpression, + NewExpression, + MemberAccess, + SliceExpression, + CastExpression, + ImportExpression, + YieldExpression, + TupleExpression, + ObjectExpression, + ObjectProperty, + SpreadElement, + Sequence, + DereferenceExpression, + ReferenceExpression, + + // Decl (4个) - 都继承 DeclBase + FunctionDefinition, + ClassDefinition, + VariableDeclaration, + PackageDeclaration, + + // Type (10个) - 都继承 TypeBase + PrimitiveType, + DynamicType, + VoidType, + ArrayType, + TupleType, + MapType, + PointerType, + ScopedType, + FuncType, + ChanType, + + // Name (1个) - 继承 NameBase + Identifier, +} from '@ant-yasa/uast-spec' + +// ===== 使用示例 ===== +// +// // 类型安全的函数签名 +// function getValue(expr: Expr): Value { +// // expr 必须是 Expr 类型,编译时检查 +// return processExpr(expr); +// } +// +// function executeStmt(stmt: Stmt): void { +// // stmt 必须是 Stmt 类型 +// processStmt(stmt); +// } +// +// // 类型守卫 +// function analyze(node: BaseNode) { +// if (isExpr(node)) { +// getValue(node); // node 类型收窄为 Expr +// } +// if (isStmt(node)) { +// executeStmt(node); // node 类型收窄为 Stmt +// } +// } diff --git a/src/types/value.ts b/src/types/value.ts new file mode 100644 index 00000000..51bddbf6 --- /dev/null +++ b/src/types/value.ts @@ -0,0 +1,198 @@ +/** + * Value 类型系统 - 导出层 + * + * 职责:重新导出 value/ 文件夹中的实现类 + * 实现:engine/analyzer/common/value/*.ts + * + * 注意:export class 既导出值(构造函数)也导出类型 + */ + +// ===== 引用类型 ===== +export { ValueRef } from '../engine/analyzer/common/value/value-ref' +export { ValueRefMap } from '../engine/analyzer/common/value/value-ref-map' +export { ValueRefList } from '../engine/analyzer/common/value/value-ref-list' +export type { ValueStore, ValueRegistry } from '../engine/analyzer/common/value/value-ref-map' +export { AstRef } from '../engine/analyzer/common/value/ast-ref' + +// ===== 基类 ===== +export { SentinelValue } from '../engine/analyzer/common/value/sentinel-value' +export { DataValue } from '../engine/analyzer/common/value/data-value' +export { EntityValue } from '../engine/analyzer/common/value/entity-value' + +// ===== 表达式类型(ExprValue 子类)===== +export { ExprValue } from '../engine/analyzer/common/value/expr-value' +export { BinaryExprValue } from '../engine/analyzer/common/value/binary-expr' +export { UnaryExprValue } from '../engine/analyzer/common/value/unary-expr' +export { MemberExprValue } from '../engine/analyzer/common/value/member-expr' +export { CallExprValue } from '../engine/analyzer/common/value/call-expr' +export { IdentifierRefValue } from '../engine/analyzer/common/value/identifier-ref' + +// ===== 导出所有 Value 类(既是值也是类型)===== +export { PrimitiveValue } from '../engine/analyzer/common/value/primitive' +export { ObjectValue } from '../engine/analyzer/common/value/object' +export { Scoped as ScopedValue } from '../engine/analyzer/common/value/scoped' +export { FunctionValue } from '../engine/analyzer/common/value/function' +export { UndefinedValue } from '../engine/analyzer/common/value/undefine' +export { UninitializedValue } from '../engine/analyzer/common/value/uninit' +export { UnknownValue } from '../engine/analyzer/common/value/unkown' +export { UnionValue } from '../engine/analyzer/common/value/union' +export { SymbolValue } from '../engine/analyzer/common/value/symbolic' +export { BVTValue } from '../engine/analyzer/common/value/bvt' +export { PackageValue } from '../engine/analyzer/common/value/package' +export { VoidValue } from '../engine/analyzer/common/value/void' +export { TypedValue } from '../engine/analyzer/common/value/typed' +export { TaintedValue } from '../engine/analyzer/common/value/tainted' +export { SpreadValue } from '../engine/analyzer/common/value/spread' +export { ClassValue } from '../engine/analyzer/common/value/class' + +// ===== 导入类(用于 instanceof 和类型定义)===== +// ExprValue 子类:需要运行时值(instanceof),用 import 而非 import type +import { ExprValue } from '../engine/analyzer/common/value/expr-value' +import { BinaryExprValue } from '../engine/analyzer/common/value/binary-expr' +import { UnaryExprValue } from '../engine/analyzer/common/value/unary-expr' +import { MemberExprValue } from '../engine/analyzer/common/value/member-expr' +import { CallExprValue } from '../engine/analyzer/common/value/call-expr' +import { IdentifierRefValue } from '../engine/analyzer/common/value/identifier-ref' + +// 其他 Value 类:仅用于类型定义,用 import type +import type { PrimitiveValue } from '../engine/analyzer/common/value/primitive' +import type { ObjectValue } from '../engine/analyzer/common/value/object' +import type { Scoped } from '../engine/analyzer/common/value/scoped' +import type { FunctionValue } from '../engine/analyzer/common/value/function' +import type { UndefinedValue } from '../engine/analyzer/common/value/undefine' +import type { UninitializedValue } from '../engine/analyzer/common/value/uninit' +import type { UnknownValue } from '../engine/analyzer/common/value/unkown' +import type { UnionValue } from '../engine/analyzer/common/value/union' +import type { SymbolValue } from '../engine/analyzer/common/value/symbolic' +import type { BVTValue } from '../engine/analyzer/common/value/bvt' +import type { PackageValue } from '../engine/analyzer/common/value/package' +import type { VoidValue } from '../engine/analyzer/common/value/void' +import type { TypedValue } from '../engine/analyzer/common/value/typed' +import type { TaintedValue } from '../engine/analyzer/common/value/tainted' +import type { SpreadValue } from '../engine/analyzer/common/value/spread' +import type { ClassValue } from '../engine/analyzer/common/value/class' + +// ===== 基类和联合类型 ===== +export type ValueBase = any // Unit 基类 + +// 前向声明(用于伪 Value 类型的循环引用) +export type Value = + | PrimitiveValue + | ObjectValue + | Scoped + | FunctionValue + | UndefinedValue + | UninitializedValue + | UnknownValue + | UnionValue + | SymbolValue + | BVTValue + | PackageValue + | VoidValue + | TypedValue + | TaintedValue + | SpreadValue + | ClassValue + | ExprValue + | BinaryExprValue + | UnaryExprValue + | MemberExprValue + | CallExprValue + | IdentifierRefValue + +// ===== 类型守卫 ===== +export function isPrimitive(v: any): v is PrimitiveValue { + return v?.vtype === 'primitive' +} + +export function isObject(v: any): v is ObjectValue { + return v?.vtype === 'object' +} + +export function isScoped(v: any): v is Scoped { + return v?.vtype === 'scope' +} + +export function isFunction(v: any): v is FunctionValue { + return v?.vtype === 'fclos' +} + +export function isUndefined(v: any): v is UndefinedValue { + return v?.vtype === 'undefine' +} + +export function isUninitialized(v: any): v is UninitializedValue { + return v?.vtype === 'uninitialized' +} + +export function isUnknown(v: any): v is UnknownValue { + return v?.vtype === 'unknown' +} + +export function isUnion(v: any): v is UnionValue { + return v?.vtype === 'union' +} + +export function isSymbol(v: any): v is SymbolValue { + return v?.vtype === 'symbol' +} + +export function isBVT(v: any): v is BVTValue { + return v?.vtype === 'BVT' +} + +export function isPackage(v: any): v is PackageValue { + return v?.vtype === 'package' +} + +// ===== 兼容性导出(旧接口名称)===== + +export function isClass(v: any): v is ClassValue { + return v?.vtype === 'class' +} + +export function isVoid(v: any): v is VoidValue { + return v?.vtype === 'void' +} + +export function isTyped(v: any): boolean { + return v?.vtype === 'typed' +} + +export function isTainted(v: any): boolean { + return v?.vtype === 'tainted' +} + +export function isSpread(v: any): boolean { + return v?.vtype === 'spread' +} + +// ===== ExprValue 类型守卫 ===== + +/** + * 判断是否为 ExprValue 子类(BinaryExprValue, UnaryExprValue, MemberExprValue, CallExprValue, IdentifierRefValue) + * 注意:旧的 SymbolValue 不是 ExprValue 子类 + */ +export function isExpr(v: any): v is ExprValue { + return v instanceof ExprValue +} + +export function isBinaryExpr(v: any): v is BinaryExprValue { + return v instanceof BinaryExprValue +} + +export function isUnaryExpr(v: any): v is UnaryExprValue { + return v instanceof UnaryExprValue +} + +export function isMemberExpr(v: any): v is MemberExprValue { + return v instanceof MemberExprValue +} + +export function isCallExpr(v: any): v is CallExprValue { + return v instanceof CallExprValue +} + +export function isIdentifierRef(v: any): v is IdentifierRefValue { + return v instanceof IdentifierRefValue +} diff --git a/src/util/ast-util.ts b/src/util/ast-util.ts index b556c27d..d34ff4c6 100644 --- a/src/util/ast-util.ts +++ b/src/util/ast-util.ts @@ -1,12 +1,20 @@ let sourcefile: string | null +let skipSourcefile: boolean = false const _ = require('lodash') const UastSpec = require('@ant-yasa/uast-spec') const config = require('../config') const varUtil = require('./variable-util') const BasicRuleHandler = require('../checker/common/rules-basic-handler') const { md5 } = require('./hash-util') +const { setGlobalASTManager, getGlobalASTManager, setGlobalSymbolTable, getGlobalSymbolTable } = require('./global-registry') +const Unit: typeof import('../engine/analyzer/common/value/unit') = require('../engine/analyzer/common/value/unit') let getCodeByLocation: ((loc: any) => string) | null = null + +/** + * 获取 getCodeByLocation 函数 + * @returns {Function} getCodeByLocation 函数 + */ function getGetCodeByLocation(): (loc: any) => string { if (!getCodeByLocation) { const sourceLine = require('../engine/analyzer/common/source-line') @@ -18,7 +26,20 @@ function getGetCodeByLocation(): (loc: any) => string { return getCodeByLocation } +/** + * 默认过滤器函数 + * @param nd 节点 + * @param prop 属性名 + * @param from 来源节点 + * @returns {boolean} 是否通过过滤 + */ +// eslint-disable-next-line complexity const defaultFilter = (nd: any, prop: string, from: any): boolean => { + /** + * 检查对象是否有 CallExpression、BinaryExpression 或 Tag + * @param obj 对象 + * @returns {boolean} 是否有相关表达式或标签 + */ function objHasCallExpressionOrBinaryExpressionOrTag(obj: any): boolean { if (!obj) { return false @@ -26,9 +47,9 @@ const defaultFilter = (nd: any, prop: string, from: any): boolean => { if ( (obj.type === 'CallExpression' || obj.type === 'BinaryExpression' || - obj._tags !== undefined || + (obj instanceof Unit && obj.taint?.hasTags()) || obj.vtype === 'object') && - obj._has_tags + obj instanceof Unit && obj.taint.isTainted ) { return true } @@ -38,14 +59,17 @@ const defaultFilter = (nd: any, prop: string, from: any): boolean => { return false } + // nd.taint 访问需要确认 nd 是 Unit 实例 + const ndTainted = nd instanceof Unit && nd.taint.isTainted + const ndHasTags = nd instanceof Unit && nd.taint?.hasTags() return ( - !(nd.type === 'MemberAccess' && prop === 'object' && nd._tags !== undefined) && + !(nd.type === 'MemberAccess' && prop === 'object' && ndHasTags) && !( nd.type === 'MemberAccess' && prop === 'object' && - (!nd._has_tags || from.type !== 'CallExpression') && - (!nd._has_tags || from.type !== 'BinaryExpression') && - (!nd._has_tags || + (!ndTainted || from.type !== 'CallExpression') && + (!ndTainted || from.type !== 'BinaryExpression') && + (!ndTainted || (nd.object.type !== 'CallExpression' && nd.object.value.T === undefined && nd.object.value.F === undefined && @@ -69,47 +93,57 @@ function adjustASTNode(sourceunit: any): void { const worklist = [sourceunit] // 使用索引访问元素,避免 shift() 的 O(n) 开销 let index = 0 - + while (index < worklist.length) { const node = worklist[index++] - + // 直接使用 for...in 遍历属性,避免 Object.keys() 创建数组的开销 for (const prop in node) { // 跳过原型链上的属性 if (!Object.prototype.hasOwnProperty.call(node, prop)) continue - - const sub_node = node[prop] + + const subNode = node[prop] // 跳过 null、undefined、非对象类型 - if (!sub_node || typeof sub_node !== 'object') continue - - if (sub_node.type) { - const nodeType = sub_node.type + if (!subNode || typeof subNode !== 'object') continue + + if (subNode.type) { + const nodeType = subNode.type if (nodeType === 'FunctionDefinition') { - sub_node.name = sub_node.id?.name ?? `` + subNode.name = + subNode.id?.name ?? + `` } else if (nodeType === 'ClassDefinition') { - sub_node.name = sub_node.id?.name ?? '' + subNode.name = + subNode.id?.name ?? + `` } - + // 使用 visited Set 避免重复处理已访问的节点 - if (!visited.has(sub_node)) { - sub_node.parent = node - if (!sub_node.loc) { - sub_node.loc = {} + if (!visited.has(subNode)) { + subNode.parent = node + if (!subNode.loc) { + subNode.loc = {} + } + // 只在需要时设置 sourcefile(不跳过且 sourcefile 不为 null) + if (!skipSourcefile && sourcefile !== null) { + subNode.loc.sourcefile = sourcefile } - sub_node.loc.sourcefile = sourcefile - worklist.push(sub_node) - visited.add(sub_node) + worklist.push(subNode) + visited.add(subNode) } - } else if (Array.isArray(sub_node)) { - const arrLen = sub_node.length + } else if (Array.isArray(subNode)) { + const arrLen = subNode.length for (let i = 0; i < arrLen; i++) { - const sn = sub_node[i] + const sn = subNode[i] if (sn?.type && !visited.has(sn)) { sn.parent = node if (!sn.loc) { sn.loc = {} } - sn.loc.sourcefile = sourcefile + // 只在需要时设置 sourcefile(不跳过且 sourcefile 不为 null) + if (!skipSourcefile && sourcefile !== null) { + sn.loc.sourcefile = sourcefile + } worklist.push(sn) visited.add(sn) } @@ -120,7 +154,8 @@ function adjustASTNode(sourceunit: any): void { } interface AnnotateOptions { - sourcefile?: string + sourcefile?: string | null + skipSourcefile?: boolean // 是否跳过设置 sourcefile(用于外部工具已设置的情况) [key: string]: any } @@ -131,8 +166,10 @@ interface AnnotateOptions { */ function annotateAST(node: any, options?: AnnotateOptions): void { sourcefile = null + skipSourcefile = false if (options) { - if (options.sourcefile) sourcefile = options.sourcefile + if (options.sourcefile !== undefined) sourcefile = options.sourcefile + if (options.skipSourcefile) skipSourcefile = true } adjustASTNode(node) } @@ -145,14 +182,20 @@ function annotateAST(node: any, options?: AnnotateOptions): void { */ function addNodeHash(obj: any, visited?: WeakSet): void { if (!obj) return - + if (!visited) { visited = new WeakSet() } - + addNodeHashInternal(obj, visited) } +/** + * 内部递归函数,用于计算节点 hash + * @param obj AST 节点 + * @param visited 已访问节点集合 + */ +// eslint-disable-next-line complexity function addNodeHashInternal(obj: any, visited: WeakSet): void { if (Array.isArray(obj)) { const arrLen = obj.length @@ -165,33 +208,34 @@ function addNodeHashInternal(obj: any, visited: WeakSet): void { } return } - + if (typeof obj !== 'object') return - + // visited WeakSet 避免重复处理循环引用或共享节点 if (visited.has(obj)) return visited.add(obj) - + if (obj.type) { - let content = '' - const loc = obj.loc - if (loc && loc.sourcefile && loc.start && loc.end) { - const getCode = getGetCodeByLocation() - content = getCode(loc) - } - if (content === '') { - content = prettyPrint(obj) + const { loc } = obj + let content = getRawCode(obj) + + // 非常重要的性能优化,尽量保留,对于特殊程序,如(content超过4000字符),可能快 10 倍 + const MAX_CONTENT_LENGTH = 128 + if (content?.length > MAX_CONTENT_LENGTH) { + const firstTen = content.substring(0, 64) + const lastTen = content.substring(content.length - 64) + content = `${firstTen}...${lastTen}` } - + let relateFilePath = obj.loc?.sourcefile if (relateFilePath && config.maindirPrefix && relateFilePath.startsWith(config.maindirPrefix)) { relateFilePath = relateFilePath.substring(config.maindirPrefix.length) } - + if (!obj._meta) { obj._meta = {} } - + // 使用数组 join() 替代多次字符串拼接,减少中间对象创建 const parentHash = obj.parent?._meta?.nodehash || '' const hashParts = [ @@ -204,21 +248,54 @@ function addNodeHashInternal(obj: any, visited: WeakSet): void { obj.type, parentHash, ] - - obj._meta.nodehash = md5(hashParts.join('_')) + + const baseNodehash = md5(hashParts.join('_')) + let nodehash = baseNodehash + + // 如果设置了全局 AST 管理器,检查 nodehash 是否已存在 + // 如果已存在,则通过添加后缀来生成新的 nodehash,确保不替换原有对象 + // TODO 符号值重构todo:现在的并行方式globalASTManager获取不到 + const astManager = getGlobalASTManager() + if (astManager) { + let suffix = 0 + while (astManager.has(nodehash)) { + suffix++ + nodehash = `${baseNodehash}_${suffix}` + } + obj._meta.nodehash = nodehash + astManager.register(obj) + } else { + // 如果没有全局 AST 管理器,直接使用计算出的 nodehash + obj._meta.nodehash = nodehash + } } - + // 使用 for...in 直接遍历,避免 Object.keys() 创建新数组 for (const key in obj) { // 跳过 parent 和 _meta - // _meta 对象本身没有 type 属性,不会进入 if (obj.type) 分支处理 - if (key === 'parent' || key === '_meta') continue - if (!Object.prototype.hasOwnProperty.call(obj, key)) continue - - const subObj = obj[key] - if (!subObj || typeof subObj !== 'object') continue - - addNodeHashInternal(subObj, visited) + // 注意_meta中有decorators,还不能直接跳过 + // TODO Java需要统一到decorators + if ( + key === 'parent' || + (key === '_meta' && + (!Array.isArray(obj._meta?.decorators) || + (Array.isArray(obj._meta?.decorators) && obj._meta?.decorators?.length === 0)) && + (!Array.isArray(obj._meta?.annotations) || + (Array.isArray(obj._meta?.annotations) && obj._meta?.annotations?.length === 0))) + ) { + continue + } else if (key === '_meta' && Array.isArray(obj._meta?.annotations) && obj._meta?.annotations?.length > 0) { + addNodeHashInternal(obj._meta?.annotations, visited) + } else if (key === '_meta' && Array.isArray(obj._meta?.decorators) && obj._meta?.decorators?.length > 0) { + addNodeHashInternal(obj._meta?.decorators, visited) + } else { + if (!Object.prototype.hasOwnProperty.call(obj, key)) continue + + const subObj = obj[key] + if (!subObj || typeof subObj !== 'object') continue + + addNodeHashInternal(subObj, visited) + } } } @@ -308,11 +385,16 @@ function satisfy( const fromlist = [node] const depthlist = [1] const parentMap = new WeakMap() - while (worklist.length) { - node = worklist.shift() - const from = fromlist.shift() - const depth = depthlist.shift() - if (!node || visited.has(node)) continue + // 使用索引替代 shift() 操作,提高性能 + let worklistIndex = 0 + while (worklistIndex < worklist.length) { + node = worklist[worklistIndex] + const from = fromlist[worklistIndex] + const depth = depthlist[worklistIndex] + worklistIndex++ + if (!node || visited.has(node)) { + continue + } visited.add(node) if (Array.isArray(node)) { node.forEach((child: any) => { @@ -348,28 +430,39 @@ function satisfy( if ( [ 'parent', + '_parentRef', + 'uuid', 'rrefs', 'trace', 'updates', 'type', 'operator', - 'id', 'ast', 'loc', - 'sort', - '_tags', + '_owner', 'uninit', 'callnode', 'names', '_this', - '__this', + '_thisRef', 'cdef', 'fdef', 'packageScope', + '_packageScopeRef', 'fileScope', 'exports', + '__exportsUuid', + '__fileScopeUuid', + '_superRef', + '_scopeCtx', + 'sid', + 'qid', + '_declsNodehashMap', + '_ast', + 'decls', + '_isConstructing', + 'overloaded', '_sid', - '_id', '_qid', 'vtype', '_meta', @@ -377,20 +470,48 @@ function satisfy( ) { continue } + if (prop.includes('__yasa')) { + continue + } if (filter && !filter(node, prop, from)) continue - if (prop === 'field') { + if (prop === '_field') { const sub_field = node[prop] for (const p in sub_field) { if (!Object.prototype.hasOwnProperty.call(sub_field, p)) continue - worklist.push(sub_field[p]) + let fieldValue = sub_field[p] + + // 如果属性值是以 symuuid_ 开头的字符串,从符号表中查找对应的符号值 + if (typeof fieldValue === 'string' && fieldValue.startsWith('symuuid_')) { + const symbolTable = getGlobalSymbolTable() + if (symbolTable) { + // 优化:使用单次 get 替代 has + get,减少一次哈希查找 + const resolved = symbolTable.get(fieldValue) + if (resolved) { + fieldValue = resolved + } + } + } + worklist.push(fieldValue) fromlist.push(sub_field) depthlist.push((depth || 0) + 1) - if (sub_field[p] && typeof sub_field[p] === 'object') { - parentMap.set(sub_field[p], node) + if (fieldValue && typeof fieldValue === 'object') { + parentMap.set(fieldValue, node) } } } else { - const v = node[prop] + let v = node[prop] + + // 如果属性值是以 symuuid_ 开头的字符串,从符号表中查找对应的符号值 + if (typeof v === 'string' && v.startsWith('symuuid_')) { + const symbolTable = getGlobalSymbolTable() + if (symbolTable) { + // 优化:使用单次 get 替代 has + get,减少一次哈希查找 + const resolved = symbolTable.get(v) + if (resolved) { + v = resolved + } + } + } worklist.push(v) fromlist.push(node) depthlist.push((depth || 0) + 1) @@ -408,9 +529,15 @@ function satisfy( * @param targetAttribute */ function hasTag(symVal: any, targetAttribute?: any): boolean { - if (config.makeAllCG || !BasicRuleHandler.getPreprocessReady()) return false + if ( + config.makeAllCG || + !BasicRuleHandler.getPreprocessReady() || + config.saveContextEnvironment || + config.miniSaveContextEnvironment + ) + return false const checkRawProps = ['arguments', 'left', 'right', 'expression', 'object'] - const checkFieldsProps = ['field', 'children', 'misc_'] + const checkFieldsProps = ['_field', 'children', 'misc_'] /** * @@ -439,12 +566,12 @@ function hasTag(symVal: any, targetAttribute?: any): boolean { targetAttribute && targetAttribute !== '' && !Array.isArray(symVal) && - symVal?._has_tags && + symVal instanceof Unit && symVal.taint.isTainted && varUtil.isNotEmpty(symVal) ) { return true } - if (!Array.isArray(symVal) && symVal?._has_tags) { + if (!Array.isArray(symVal) && symVal instanceof Unit && symVal.taint.isTainted) { return true } @@ -471,8 +598,8 @@ function hasTag(symVal: any, targetAttribute?: any): boolean { for (const key in symVal?.[fieldProp]) { const eleVal = symVal?.[fieldProp][key] if ( - typeof eleVal?._qid === 'string' && - (eleVal?._qid?.includes('Egg.Context') || eleVal?._qid?.includes('Egg.Application.service')) + typeof eleVal?.qid === 'string' && + (eleVal?.qid?.includes('Egg.Context { - const tags = nd?._tags - if (_.isFunction(tags?.has) && tags.has(attribute)) { + if (nd instanceof Unit && nd.taint?.containsTag(attribute)) { return true } }, @@ -606,9 +737,28 @@ function prettyPrintAST(node: any): string { } return res } - return prettyPrint(node.ast || node.decl || node.fdecl || node) + return prettyPrint(node.ast?.node || node.fdecl || node) } +/** + * + * @param node + */ +function getRawCode(node: any): string { + let content = '' + if (!node) { + return content + } + const { loc } = node + if (loc && loc.sourcefile && loc.start && loc.end) { + const getCode = getGetCodeByLocation() + content = getCode(loc) + } + if (content === '') { + content = prettyPrint(node) + } + return content +} /** * Pretty-print AST nodes * @param node @@ -980,10 +1130,14 @@ module.exports = { prettyPrintAST, annotateAST, addNodeHash, + setGlobalASTManager, + getGlobalASTManager, + setGlobalSymbolTable, + getGlobalSymbolTable, typeToQualifiedName, getAncestor, qualifiedNameToMemberAccess, - + getRawCode, visit, satisfy, hasTag, diff --git a/src/util/clone-util.ts b/src/util/clone-util.ts index e64393e1..e178f8d1 100644 --- a/src/util/clone-util.ts +++ b/src/util/clone-util.ts @@ -1,34 +1,351 @@ -import * as _ from 'lodash' -import { checkMemoryUsage } from './memory-util' +const _ = require('lodash') +import { RAW_TARGET } from '../engine/analyzer/common/value/symbols' + +let _instanceCounter = 0 +import { ObjectValue } from '../engine/analyzer/common/value/object' +import { SymbolValue } from '../engine/analyzer/common/value/symbolic' +import { PackageValue } from '../engine/analyzer/common/value/package' +import { FunctionValue } from '../engine/analyzer/common/value/function' +import { Scoped } from '../engine/analyzer/common/value/scoped' /** - * 带深度限制的深拷贝 - * @param {T} obj - 要拷贝的对象 - * @param {number} maxDepth - 最大拷贝深度,默认为1 - * @param {number} currentDepth - 当前深度(内部使用) - * @returns {T} 拷贝后的对象 + * 浅拷贝值,不触发 getter/setter + * Value 类型委托到 value.clone(),其他类型(数组/Map/Set/plain object)手动拷贝 + * @param value */ -function cloneWithDepth(obj: T, maxDepth: number = 1, currentDepth: number = 0): T { - // 如果达到最大深度或不是对象/数组,直接返回浅拷贝 - if (currentDepth >= maxDepth || typeof obj !== 'object' || !obj || Object.keys(obj).length === 0) { - return obj - } - const val = _.clone(obj) - const filterKey = ['ast', 'sort', '_sid', '_qid', '_id', 'decl', 'name', 'vtype', 'rtype', 'decls'] - - if (checkMemoryUsage()) { - // 对下一层递归处理 - for (const key in val) { - if (filterKey.includes(key)) { +function shallowCopyValue(value: any, _visited?: WeakSet): any { + // 基本类型直接返回 + if (value === null || value === undefined || typeof value !== 'object') { + return value + } + + // Value 类型:委托到 clone() + if (typeof value.clone === 'function') { + return value.clone() + } + + // 循环引用检测 + if (!_visited) _visited = new WeakSet() + if (_visited.has(value)) return value + _visited.add(value) + + // 数组:创建新数组,直接复制元素 + if (Array.isArray(value)) { + const arrCopy: any[] = [] + for (let i = 0; i < value.length; i++) { + arrCopy[i] = shallowCopyValue(value[i], _visited) + } + return arrCopy + } + + // Map 类型:通过原型链创建新 Map,复制键值对(对键和值都运行 shallowCopyValue) + if (value instanceof Map || (typeof value.entries === 'function' && value.constructor !== Object)) { + try { + const MapConstructor = Object.getPrototypeOf(value).constructor || Map + const mapCopy = new MapConstructor() + if (typeof mapCopy.set === 'function') { + for (const [key, val] of value.entries()) { + mapCopy.set(key, shallowCopyValue(val, _visited)) + } + return mapCopy + } + } catch (e) { + // 如果创建失败,继续后续处理 + } + } + + // Set 类型:通过原型链创建新 Set,复制元素(对元素都运行 shallowCopyValue) + if (value instanceof Set || (typeof value.values === 'function' && value.constructor !== Object)) { + try { + const SetConstructor = Object.getPrototypeOf(value).constructor || Set + const setCopy = new SetConstructor() + if (typeof setCopy.add === 'function') { + for (const item of value.values()) { + setCopy.add(shallowCopyValue(item, _visited)) + } + return setCopy + } + } catch (e) { + // 如果创建失败,继续后续处理 + } + } + + // Plain object: 创建新对象,直接复制属性值 + const objCopy: any = {} + for (const key in value) { + if (Object.prototype.hasOwnProperty.call(value, key)) { + objCopy[key] = value[key] + } + } + return objCopy +} + +/** + * 本质是带深度的拷贝,将field下的内容也创建新的实例 + * @param analyzer + * @param originalObj + * @param originalObj + * @param node + * @param scope + * @param f + * @param f1 + * @param f2 + * @param recursiveDepth + * @param options + * @param options.skipTagTraceMap + */ +// 根据原始对象类型选择构造函数(默认 ObjectValue) +const INSTANCE_CTOR_MAP: Record = { + ObjectValue, + SymbolValue, + FunctionValue, + PackageValue, + Scoped, +} + +function buildNewValueInstance( + analyzer: any, + originalObj: any, + node: any, + scope: any, + f1: any, + f2: any, + recursiveDepth = 1, + options?: { skipTagTraceMap?: boolean; qidSuffix?: string; forceVtype?: string } +): any { + const qidSuffix = options?.qidSuffix || '' + const forceVtype = options?.forceVtype + const opts = { ...originalObj, vtype: forceVtype || 'object' } + delete opts._field + opts._field = {} + // taint 由构造函数创建,删除 opts.taint 让构造函数创建空实例 + delete opts.taint + let sig = '' + if ( + node?.loc && + node?.loc?.sourcefile && + node?.loc?.start?.line && + node?.loc?.start?.column && + node?.loc?.end?.line && + node?.loc?.end?.column + ) { + const filename = node.loc.sourcefile.split('/').pop() + sig = `${filename.substring(0, filename.lastIndexOf('.') > 0 ? filename.lastIndexOf('.') : filename.length)}_${node.loc?.start?.line}_${node.loc?.start?.column}_${node.loc?.end?.line}_${node.loc?.end?.column}` + } else if ( + node?.callee?.loc && + node?.callee?.loc?.sourcefile && + node?.callee?.loc?.start?.line && + node?.callee?.loc?.start?.column && + node?.callee?.loc?.end?.line && + node?.callee?.loc?.end?.column + ) { + const filename = node.callee.loc.sourcefile.split('/').pop() + sig = `${filename.substring(0, filename.lastIndexOf('.') > 0 ? filename.lastIndexOf('.') : filename.length)}_${node.callee.loc?.start?.line}_${node.callee.loc?.start?.column}_${node.callee.loc?.end?.line}_${node.callee.loc?.end?.column}` + } else { + sig = `` + } + opts._sid = `${originalObj.sid}` + opts._qid = `${originalObj.qid}${qidSuffix}` + opts._skipRegister = false + const CtorClass = (!forceVtype || forceVtype === 'object') ? ObjectValue : (INSTANCE_CTOR_MAP[originalObj.constructor?.name] || ObjectValue) + const obj = new CtorClass(opts) + obj.reset() + + obj._this = obj + if (obj.parent?.sid === '') { + obj.parent = scope + } + if (typeof originalObj.value === 'object') { + const instanceTag = `` + const visited = new WeakSet() + const MAX_RECURSION_DEPTH = recursiveDepth // 最大递归层数,默认往下1层,总共2层 + + /** + * 递归处理符号值,为其添加 instance 标记 + * @param val 要处理的符号值 + * @param parentObj 父对象 + * @param key 父对象value中的索引 + * @param depth 当前递归深度 + */ + const addInstanceTagRecursive = (val: any, parentObj: any, key: any, depth: number): void => { + // 检查递归深度限制 + if (depth >= MAX_RECURSION_DEPTH) { + return + } + + if (!val || typeof val !== 'object') { + return + } + + // 避免循环引用 + if (visited.has(val)) { + return + } + visited.add(val) + const newVal = shallowCopyValue(val) + // skipTagTraceMap 时清空 taint 而非删除引用 + if (options?.skipTagTraceMap && newVal.taint) { + newVal.taint.clear() + } + // 如果是符号值(有 vtype 和 qid 属性),添加 instance 标记 + if (newVal.vtype && newVal.qid && typeof newVal.qid === 'string') { + // 如果 qid 还没有这个标记,添加它 + if (!newVal.qid.includes(instanceTag)) { + let newQid = newVal.qid + + // 如果父对象有 qid 且包含 instanceTag,需要在正确位置插入 + if (parentObj && parentObj.qid && typeof parentObj.qid === 'string' && parentObj.qid.includes(instanceTag)) { + // 找到父对象 qid 中 instanceTag 的位置 + const parentQidWithTag = parentObj.qid + const parentQidWithoutTag = parentQidWithTag.replace(instanceTag, '') + + // 如果子对象的 qid 以父对象的 qid(不含 tag)开头 + if (newVal.qid.startsWith(parentQidWithoutTag)) { + // 提取子对象相对于父对象的部分 + const relativePart = newVal.qid.substring(parentQidWithoutTag.length) + // 如果 relativePart 以 . 开头,去掉开头的 . + const suffix = relativePart.startsWith('.') ? relativePart.substring(1) : relativePart + // 构造新的 qid: parentQidWithTag + '.' + suffix + newQid = suffix ? `${parentQidWithTag}.${suffix}` : parentQidWithTag + } else { + // 如果子对象的 qid 不以父对象的 qid 开头,直接在末尾添加 + newQid = `${newVal.qid}${instanceTag}` + } + } else { + // 如果父对象没有 instanceTag,直接在末尾添加 + newQid = `${newVal.qid}${instanceTag}` + } + newVal._qid = newQid + newVal._logicalQid = undefined + newVal._this = parentObj + newVal.parent = parentObj + parentObj.value[key] = newVal + } + } + + // 递归处理 value 属性(如果存在且是对象) + if (newVal.value && typeof newVal.value === 'object' && newVal.value !== newVal._field) { + if (Array.isArray(newVal.value)) { + for (let i = 0; i < newVal.value.length; i++) { + const item = newVal.value[i] + if (item && typeof item === 'object') { + addInstanceTagRecursive(item, newVal, i, depth + 1) + } + } + } else { + for (const vkey in newVal.value) { + if (Object.prototype.hasOwnProperty.call(newVal.value, vkey)) { + const item = newVal.value[vkey] + addInstanceTagRecursive(item, newVal, vkey, depth + 1) + } + } + } + } + + // 递归处理 _field 中的值 + if (newVal._field && typeof newVal._field === 'object') { + const fieldTarget = (newVal._field as any)[RAW_TARGET] || newVal._field + + // 如果是数组(union 类型) + if (Array.isArray(fieldTarget)) { + for (let i = 0; i < fieldTarget.length; i++) { + const element = fieldTarget[i] + // 如果是 UUID,从符号表中获取实际对象并递归处理 + if (typeof element === 'string' && element.startsWith('symuuid_')) { + const unit = analyzer.symbolTable.get(element) + if (unit) { + addInstanceTagRecursive(unit, newVal, i, depth + 1) + } + } else if (element && typeof element === 'object') { + addInstanceTagRecursive(element, newVal, i, depth + 1) + } + } + } + // 如果是普通对象 + else { + for (const fieldKey in fieldTarget) { + if (Object.prototype.hasOwnProperty.call(fieldTarget, fieldKey)) { + const fieldValue = fieldTarget[fieldKey] + // 如果是 UUID,从符号表中获取实际对象并递归处理 + if (typeof fieldValue === 'string' && fieldValue.startsWith('symuuid_')) { + const unit = analyzer.symbolTable.get(fieldValue) + if (unit) { + addInstanceTagRecursive(unit, newVal, fieldKey, depth + 1) + } + } else if (fieldValue && typeof fieldValue === 'object') { + addInstanceTagRecursive(fieldValue, newVal, fieldKey, depth + 1) + } + } + } + } + } + } + + // 处理下层的 value + for (const x in originalObj.value) { + if (f1(x)) { + continue + } + const v = originalObj.value[x] + if (f2(v)) { continue } - if (Object.prototype.hasOwnProperty.call(val, key)) { - val[key] = cloneWithDepth(val[key], maxDepth, currentDepth + 1) + if (typeof v === 'object') { + // 递归处理 v_copy 及其嵌套的 value,从深度0开始 + addInstanceTagRecursive(v, obj, x, 0) } } } + return obj +} + +/** + * + * @param analyzer + * @param value + * @param tag + */ +function buildNewCopiedWithTag(analyzer: any, value: any, tag: string) { + const copiedTag = `` + let targetUuid = analyzer.symbolTable.calculateUUID(value, copiedTag) + let suffix = 0 + let newTag = copiedTag + while (analyzer.symbolTable.has(targetUuid)) { + suffix++ + newTag = `` + targetUuid = analyzer.symbolTable.calculateUUID(value, newTag) + } + const newVal = shallowCopyValue(value) + newVal._qid += newTag + newVal._logicalQid = undefined + newVal.uuid = null + if (typeof newVal.calculateAndRegisterUUID === 'function') { + newVal.calculateAndRegisterUUID() + } + return newVal +} - return val +/** + * Alias-clone a Value and assign a new UUID (cloned tag). + * Uses value.cloneAlias() for shallow clone that shares _field Proxy, + * then appends a timestamp+random tag to qid and re-registers in symbolTable. + * @param value + */ +function lodashCloneWithTag(value: any) { + const newVal = typeof value?.cloneAlias === 'function' ? value.cloneAlias() : _.clone(value) + if (newVal.qid) { + const timestamp = Date.now().toString().slice(-8) + const random = Math.floor(Math.random() * 10000) + .toString() + .padStart(4, '0') + const copiedTag = `` + newVal._qid += copiedTag + newVal._logicalQid = undefined + newVal.uuid = null + newVal.calculateAndRegisterUUID() + } + return newVal } -export { cloneWithDepth } +// eslint-disable-next-line import/prefer-default-export +export { shallowCopyValue, buildNewValueInstance, buildNewCopiedWithTag, lodashCloneWithTag } diff --git a/src/util/common-util.ts b/src/util/common-util.ts index 36b61ff6..91cf51dc 100644 --- a/src/util/common-util.ts +++ b/src/util/common-util.ts @@ -1,3 +1,6 @@ +const _ = require('lodash') +const QidUnifyUtil = require('./qid-unify-util') + const varUtil = require('./variable-util') const config = require('../config') @@ -58,21 +61,20 @@ function getTaintRec(s: any, stack: number, visited: Set): Set { let res = new Set() // s为空或者没有污点标志,或者污点标志为false // 超过递归深度 - if (s == null || !s?.hasTagRec || stack > 5) return res + if (s == null || !s?.taint.isTaintedRec || stack > 5) return res // 如果s本身污点不为空 返回s自身的污点 visited.add(s) - if (s && varUtil.isNotEmpty(s._tags)) { - const res = s._tags instanceof Set ? s._tags : new Set(s._tags) - if (res.size > 0) return res + if (s && s.taint?.hasTags()) { + return new Set(s.taint.getTags()) } // 遍历s的field中的符号值,若s的field不存在直接返回 - const fields = s && s?.field - if (!fields) return res - for (const key in fields) { - // 防止循环引用重复遍历 - if (visited.has(fields[key])) continue - res = getTaintRec(fields[key], stack + 1, visited) - if (res?.size > 0) return res + if (s.members) { + for (const key of s.members.keys()) { + const val = s.members.get(key) + if (visited.has(val)) continue + res = getTaintRec(val, stack + 1, visited) + if (res?.size > 0) return res + } } return res } @@ -200,11 +202,10 @@ function shallowEqual(objA: any, objB: any): boolean { * @returns {string} */ function getSymbolRef(argval: any): string { - // TODO 维护uuid,本质是生成符号值的签名 + // 这里不能直接用符号值uuid,因为受astnodehash影响,相同qid的uuid会不一样 const ref: Record = {} - ref.id = argval.id ref.sid = argval.sid - ref.qid = argval.qid + ref.qid = argval.logicalQid ref.vtype = argval.vtype ref.type = argval.type // raw_value 只能是原始值本身,不能是对象,union符号值中的raw_value竟然存储了对象,不可思议。。。 @@ -222,7 +223,7 @@ function getSymbolRef(argval: any): string { * @param f */ function getDataFromScopeWithFilter(scope: any, f: any): any { - if (!scope?.field) return scope + if (!scope?.members && !scope?.value) return scope if (!f) return scope.getRawValue() return Object.values(scope.getRawValue()).filter((symVal: any) => f(symVal)) } @@ -240,7 +241,7 @@ function getDataFromScope(scope: any): any { * @param symVal */ function filterDataFromScope(symVal: any): boolean { - return !(symVal?.vtype === 'fclos' && symVal?.execute) && symVal?.sid !== 'prototype' + return !(symVal?.vtype === 'fclos' && symVal?.runtime?.execute) && symVal?.sid !== 'prototype' } /** @@ -256,11 +257,11 @@ function filterDataFromScope(symVal: any): boolean { */ function getAnonymousFunctionName(fclos: any) { // 检查函数闭包是否有位置信息 - if (fclos?.ast?.loc === undefined) return undefined + if (fclos?.ast?.node?.loc === undefined) return undefined // 使用函数定义的起始行和结束行生成唯一标识符 // 格式: - return `` + return `` } /** @@ -275,7 +276,7 @@ function getAnonymousFunctionName(fclos: any) { */ function getFclosFromScope(valExport: any, func: any): any { let valFunc - const fdef = valExport?.fdef || valExport?.ast + const fdef = valExport?.ast.fdef || valExport?.ast?.node if (fdef && fdef?.type === 'FunctionDefinition') { // 具名函数匹配 if (fdef.id?.name === func) { @@ -292,20 +293,22 @@ function getFclosFromScope(valExport: any, func: any): any { } } else { // 从作用域的字段中直接查找 - valFunc = valExport?.field[func] + valFunc = valExport?.members?.get(func) // 如果直接查找失败 if (!valFunc) { // 尝试在默认导出中查找 - if (valExport?.field?.default) { - valFunc = getFclosFromScope(valExport.field.default, func) + const defaultVal = valExport?.members?.get('default') + if (defaultVal) { + valFunc = getFclosFromScope(defaultVal, func) } else if (!func.includes('.')) { // 遍历作用域字段,查找类中的方法 - for (const i in valExport.field) { - if (valExport.field[i] && valExport.field[i].vtype === 'class') { - valFunc = getFclosFromScope(valExport.field[i], func) - if (valFunc) { - break + if (valExport?.members) { + for (const i of valExport.members.keys()) { + const fieldVal = valExport.members.get(i) + if (fieldVal && fieldVal.vtype === 'class') { + valFunc = getFclosFromScope(fieldVal, func) + if (valFunc) break } } } @@ -315,7 +318,7 @@ function getFclosFromScope(valExport: any, func: any): any { let fieldT = valExport // 沿着路径逐级查找 arr.forEach((path: any) => { - fieldT = fieldT?.field[path] + fieldT = fieldT?.members?.get(path) }) if (fieldT) { valFunc = fieldT @@ -339,37 +342,36 @@ function fillSourceScope(fclos: any, sourceScope: any): void { if (sourceScope.complete) return const scopeValue = sourceScope.value - let notComplete = false - // 检查是否有未完成位置信息的规则 - for (const item of scopeValue) { - if (item.locStart === undefined && item.locEnd === undefined) { - notComplete = true - break - } - } - - // 如果所有规则位置信息都已完善,标记为完成 - if (!notComplete) { - sourceScope.complete = true - return - } + // let notComplete = false + // // 检查是否有未完成位置信息的规则 + // for (const item of scopeValue) { + // if (item.locStart === undefined && item.locEnd === undefined) { + // notComplete = true + // break + // } + // } + // // 如果所有规则位置信息都已完善,标记为完成 + // if (!notComplete) { + // sourceScope.complete = true + // return + // } // 确定函数名(处理匿名函数) let scpFunc - if (fclos.ast?.name === '') { + if (fclos.ast?.node?.name.includes(' 0 ? fclos.ast.parameters[0].loc?.start?.line : fclos.ast?.loc?.start?.line + fclos.ast?.node?.parameters?.length > 0 ? fclos.ast.node.parameters[0].loc?.start?.line : fclos.ast?.node?.loc?.start?.line // 计算结束行(优先使用参数位置) - const locEnd = fclos.ast?.loc?.end?.line + const locEnd = fclos.ast?.node?.loc?.end?.line // 关键位置信息缺失则返回 if (scpPath === undefined || locStart === undefined || locEnd === undefined) { @@ -391,10 +393,17 @@ function fillSourceScope(fclos: any, sourceScope: any): void { if (item.scopeFile === relativePath && item.scopeFunc === scpFunc) { // 仅填充未完善的规则 if (item.locStart !== undefined && item.locEnd !== undefined) { + if (sourceScope.fillLineValues.includes(item)) { + const copiedItem = _.clone(item) + copiedItem.locStart = locStart + copiedItem.locEnd = locEnd + sourceScope.value.push(copiedItem) + } return } item.locStart = locStart item.locEnd = locEnd + sourceScope.fillLineValues.push(item) } // 规则2:匹配整个文件 else if (item.scopeFile === relativePath && item.scopeFunc === 'all') { diff --git a/src/util/constant.ts b/src/util/constant.ts index d51805b7..e8baef52 100644 --- a/src/util/constant.ts +++ b/src/util/constant.ts @@ -1,3 +1,41 @@ +/* eslint-disable @typescript-eslint/no-require-imports, @typescript-eslint/no-var-requires */ +const fs = require('fs') +const path = require('path') + export const ENGIN_START_FUNCALL = 'functionCall' export const ENGIN_START_FILE_BEGIN = 'fileBegin' export const YASA_DEFAULT = 'YASADefault' + +// 基础版本号 +const BASE_VERSION = '0.2.19-inner-dev' + +/** + * 尝试读取构建时生成的版本信息文件 + * @returns {string} 完整版本号字符串 + */ +function getBuildVersion(): string { + try { + // 在编译后的 dist 目录中查找版本文件 + const versionFile = path.join(__dirname, '../build-version.json') + if (fs.existsSync(versionFile)) { + const versionInfo = JSON.parse(fs.readFileSync(versionFile, 'utf-8')) + return `${BASE_VERSION} (build ${versionInfo.buildDate}, commit ${versionInfo.commitHash})` + } + } catch (error) { + // 忽略错误,使用基础版本 + } + return BASE_VERSION +} + +export const YASA_VERSION = getBuildVersion() + +// 同时支持 CommonJS require +/* eslint-disable @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-member-access */ +if (typeof module !== 'undefined' && module.exports) { + module.exports = { + ENGIN_START_FUNCALL, + ENGIN_START_FILE_BEGIN, + YASA_DEFAULT, + YASA_VERSION, + } +} diff --git a/src/util/diagnostics-log-util.ts b/src/util/diagnostics-log-util.ts index 61052498..a7e4441c 100644 --- a/src/util/diagnostics-log-util.ts +++ b/src/util/diagnostics-log-util.ts @@ -1,29 +1,47 @@ -import fs from 'fs' -import path from 'path' +/* eslint-disable @typescript-eslint/no-require-imports, import/no-commonjs */ +const fs = require('fs') +const path = require('path') +const os = require('os') const Config = require('../config') +const { loadJSONfile } = require('./file-util') +const { YASA_VERSION } = require('./constant') // 保持文件句柄打开,避免频繁开关影响性能 let logFileDescriptor: number | null = null let currentReportDir: string | null = null // 记录当前使用的 reportDir -// 获取日志文件路径(从 Config.reportDir 动态获取) -function getLogFilePath(): string { +/** + * 获取报告目录路径(从 Config.reportDir 动态获取) + * @returns {string} 报告目录的完整路径 + */ +function getReportDir(): string { // 从 Config 获取 reportDir,如果不存在或为空,使用默认值 let reportDir = Config.reportDir || './report/' - + // 如果是相对路径,转换为绝对路径 if (!path.isAbsolute(reportDir)) { reportDir = path.resolve(process.cwd(), reportDir) } - - return path.join(reportDir, 'yasa-diagnostics-log.txt') + + return reportDir } -// 确保文件句柄打开 +/** + * 获取日志文件路径(从 Config.reportDir 动态获取) + * @returns {string} 日志文件的完整路径 + */ +function getLogFilePath(): string { + return path.join(getReportDir(), 'yasa-diagnostics-log.txt') +} + +/** + * 确保文件句柄打开 + * @returns {number} 文件描述符 + */ function ensureFileOpen(): number { const logFilePath = getLogFilePath() const reportDir = path.dirname(logFilePath) - + // 如果 reportDir 改变了,需要关闭旧文件并打开新文件 if (logFileDescriptor !== null && currentReportDir !== reportDir) { try { @@ -34,7 +52,7 @@ function ensureFileOpen(): number { logFileDescriptor = null currentReportDir = null } - + if (logFileDescriptor === null) { // 确保 report 目录存在 try { @@ -62,47 +80,12 @@ function ensureFileOpen(): number { throw error } } - return logFileDescriptor -} - -/** - * 关闭日志文件句柄 - * 在进程退出时调用,确保文件句柄被正确关闭 - */ -function closeLogFile(): void { - if (logFileDescriptor !== null) { - try { - fs.closeSync(logFileDescriptor) - logFileDescriptor = null - } catch (error) { - // 忽略关闭时的错误 - } + if (logFileDescriptor === null) { + throw new Error('Failed to open log file: file descriptor is null') } + return logFileDescriptor } -/** - * 注册进程退出处理器,确保文件句柄被正确关闭 - * - * 注意:在进程正常退出、接收到 SIGINT(Ctrl+C)或 SIGTERM 信号时, - * 都会调用 closeLogFile 确保文件句柄被正确关闭,避免资源泄漏。 - */ -// 进程退出时关闭文件句柄 -process.on('exit', () => { - closeLogFile() -}) - -// 进程异常退出时也关闭文件句柄(SIGINT:Ctrl+C) -process.on('SIGINT', () => { - closeLogFile() - process.exit(0) -}) - -// 进程终止时也关闭文件句柄(SIGTERM:kill 命令发送的终止信号) -process.on('SIGTERM', () => { - closeLogFile() - process.exit(0) -}) - /** * 通用诊断日志工具 * @param log_key - 日志类型/名称(必需) @@ -141,7 +124,11 @@ function logDiagnostics( const number2 = options?.number2 ?? null const number3 = options?.number3 ?? null - // 格式化当前时间为 yyyy-mm-dd hh:mm:ss + /** + * 格式化当前时间为 yyyy-mm-dd hh:mm:ss + * @param date - 日期对象或时间戳 + * @returns {string} 格式化后的日期时间字符串 + */ function formatDateTime(date: Date | number): string { // 如果传入的是数字(时间戳),转换为 Date 对象 const dateObj = date instanceof Date ? date : new Date(date) @@ -154,7 +141,11 @@ function logDiagnostics( return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}` } - // 辅助函数:处理日期格式化,消除重复代码 + /** + * 辅助函数:处理日期格式化,消除重复代码 + * @param dateValue - 日期值 + * @returns {string | null} 格式化后的日期字符串或null + */ function formatDateIfPresent(dateValue: Date | number | null | undefined): string | null { if (dateValue !== null && dateValue !== undefined) { return formatDateTime(dateValue) @@ -166,13 +157,13 @@ function logDiagnostics( const date1 = formatDateIfPresent(options?.date1) const date2 = formatDateIfPresent(options?.date2) - // 记录当前时间作为 log_time - const log_time = formatDateTime(new Date()) + // 记录当前时间作为 logTime + const logTime = formatDateTime(new Date()) // 构建日志对象 const logEntry = { log_key, - log_time, + log_time: logTime, string1, string2, string3, @@ -184,7 +175,7 @@ function logDiagnostics( } // 将日志对象转换为JSON格式(每行一个JSON对象) - const logLine = JSON.stringify(logEntry) + '\n' + const logLine = `${JSON.stringify(logEntry)}\n` // 写入日志并立即 flush(文件句柄保持打开,提升性能) try { @@ -205,16 +196,350 @@ function logDiagnostics( } // 记录错误并尝试再次写入 console.error(`Failed to write diagnostics log: ${error}`) + const fd = ensureFileOpen() + fs.writeSync(fd, logLine) + fs.fsyncSync(fd) + } +} + +/** + * 获取项目名称(从项目路径获取最后一个文件夹名,单文件用文件名) + * @param projectPath - 项目路径 + * @returns {string} 项目名称 + */ +function getProjectName(projectPath: string | null | undefined): string { + if (!projectPath) { + return 'unknown' + } + const normalizedPath = projectPath.replace(/\\/g, '/') + const parts = normalizedPath.split('/').filter((p) => p) + if (parts.length === 0) { + return 'unknown' + } + const lastPart = parts[parts.length - 1] + // 如果是文件,返回文件名(不含扩展名) + if (lastPart.includes('.')) { + return path.basename(lastPart, path.extname(lastPart)) + } + // 如果是目录,返回目录名 + return lastPart +} + +/** + * 获取 ruleconfig 全文 + * @returns {string} ruleconfig 的 JSON 字符串,如果不存在则返回空字符串 + */ +function getRuleConfigContent(): string { + try { + if (Config.ruleConfigFile && Config.ruleConfigFile !== '') { + const ruleConfig = loadJSONfile(Config.ruleConfigFile) + return JSON.stringify(ruleConfig) + } + } catch (error) { + // 忽略错误,返回空字符串 + } + return '' +} + +/** + * 生成扫描摘要(紧凑的 JSON 字符串) + * @param analyzer - analyzer 对象 + * @param performanceTracker - performance tracker 对象 + * @param programStartTime - 整个程序开始时间(端到端时间) + * @param programEndTime - 整个程序结束时间(端到端时间) + * @returns {string} 紧凑的 JSON 字符串 + */ +// eslint-disable-next-line complexity +function generateScanSummary( + analyzer: any, + performanceTracker: any, + programStartTime?: Date | number | null, + programEndTime?: Date | number | null +): string { + const timings = performanceTracker?.getTimings?.() || {} + // 使用 performanceTracker 的 collectAnalysisOverview 获取完整数据 + const analysisData = + analyzer && performanceTracker?.collectAnalysisOverview + ? performanceTracker.collectAnalysisOverview(analyzer, timings) + : null + + // 获取项目路径 + const projectPath = + analyzer?.options?.sourcePath || + analyzer?.options?.sourceFile || + Config.sourcePath || + (Config.single && Config.maindir ? Config.maindir : null) || + Config.maindir || + process.cwd() + + // 从 constant 文件获取版本号 + const yasaVersion = YASA_VERSION && typeof YASA_VERSION === 'string' ? YASA_VERSION : 'unknown' + + // 计算实际的 worker 数量:如果 Config.workerCount > 0 则使用配置值,否则自动计算 + let parallelCount = 0 + if (Config.workerCount && Config.workerCount > 0) { + parallelCount = Config.workerCount + } else { + // 自动计算:min(CPU核心数 * 0.4, 16) try { - const fd = ensureFileOpen() - fs.writeSync(fd, logLine) - fs.fsyncSync(fd) - } catch (retryError) { - throw retryError + const cpuCount = os.cpus().length + const physicalCores = Math.ceil(cpuCount * 0.4) + parallelCount = Math.min(physicalCores, 16) + // 确保至少为 1(如果 CPU 核心数很少) + if (parallelCount === 0 && cpuCount > 0) { + parallelCount = 1 + } + } catch (error) { + // 如果获取 CPU 信息失败,使用默认值 1 + parallelCount = 1 } } + const cgAlgo = Config.cgAlgo || 'unknown' + const dumpAllCG = Config.dumpAllCG || false + const dumpAST = Config.dumpAST || false + + // 使用传入的端到端时间,如果没有则从 performanceTracker 计算 + let startTime: number | null = null + let endTime: number | null = null + let totalTime = 0 + + if (programStartTime && programEndTime) { + // 使用端到端时间 + startTime = programStartTime instanceof Date ? programStartTime.getTime() : programStartTime + endTime = programEndTime instanceof Date ? programEndTime.getTime() : programEndTime + totalTime = endTime - startTime + } else if (timings.total) { + // 回退到从 performanceTracker 计算 + startTime = Date.now() - (timings.total || 0) + endTime = Date.now() + totalTime = timings.total + } + + // 获取 parse 相关时间 + const parseTime = timings.preProcess || 0 + const parseCodeTime = timings['preProcess.parseCode'] || 0 + const preloadTime = timings['preProcess.preload'] || 0 + const processModuleTime = timings['preProcess.processModule'] || 0 + + // 获取其他时间 + const startAnalyzeTime = timings.startAnalyze || 0 + const symbolInterpretTime = timings.symbolInterpret || 0 + + // 构建扫描摘要对象(使用简写:exec=Execution, inst=Instruction) + const scanSummary: Record = { + projectName: getProjectName(projectPath), + projectPath: projectPath || '', + yasaVersion, + parallelWorkers: parallelCount, + cgAlgorithm: cgAlgo, + dumpAllCG, + dumpAST, + scanStartTime: startTime ? new Date(startTime).toISOString() : null, + scanEndTime: endTime ? new Date(endTime).toISOString() : null, + findingCount: analysisData?.findingCount || 0, + language: analysisData?.language || Config.language || 'unknown', + fileCount: analysisData?.fileCount || 0, + lineCount: analysisData?.lineCount || 0, + totalTimeMs: totalTime, + markedSourceCount: analysisData?.markedSourceCount || 0, + matchedSinkCount: analysisData?.matchedSinkCount || 0, + entryPointCount: analysisData?.entryPointCount || 0, + parseMs: parseTime, + parseCodeMs: parseCodeTime, + preloadMs: preloadTime, + processModuleMs: processModuleTime, + startAnalyzeMs: startAnalyzeTime, + symbolInterpretMs: symbolInterpretTime, + execCount: analysisData?.executionCount || 0, + execInstCount: analysisData?.executedInstruction || 0, + avgExecTimePerInst: analysisData?.avgExecutionTimePerInstruction || 0, + avgInstExecCount: analysisData?.avgInstructionExecutionCount || 0, + execTimeP70Ms: analysisData?.executionTime70Percent || 0, + execTimeP99Ms: analysisData?.executionTime99Percent || 0, + execTimeP100Ms: analysisData?.executionTime100Percent || 0, + execTimesP70: analysisData?.executionTimes70Percent || 0, + execTimesP99: analysisData?.executionTimes99Percent || 0, + execTimesP100: analysisData?.executionTimes100Percent || 0, + } + + // 返回紧凑的 JSON 字符串(无空格) + return JSON.stringify(scanSummary) +} + +/** + * 计算开始和结束时间 + * @param performanceTracker - performance tracker 对象 + * @param startTime - 开始时间(Date 或 number 时间戳) + * @param endTime - 结束时间(Date 或 number 时间戳) + * @returns {Object} 包含 finalStartTime 和 finalEndTime 的对象 + */ +function calculateTimes( + performanceTracker: any, + startTime?: Date | number | null, + endTime?: Date | number | null +): { finalStartTime: Date | number | null; finalEndTime: Date | number | null } { + let finalStartTime: Date | number | null = startTime !== undefined ? startTime : null + let finalEndTime: Date | number | null = endTime !== undefined ? endTime : null + + if (!finalStartTime || !finalEndTime) { + const timings = performanceTracker?.getTimings?.() || {} + if (timings.total) { + const totalTime = timings.total + if (!finalEndTime) { + finalEndTime = Date.now() + } + if (!finalStartTime) { + finalStartTime = (finalEndTime as number) - totalTime + } + } + } + + return { finalStartTime, finalEndTime } +} + +/** + * 记录扫描初始化信息 + * @param performanceTracker - performance tracker 对象 + */ +function logScanInit(performanceTracker: any): void { + const projectPath = + Config.sourcePath || + (Config.single && Config.maindir ? Config.maindir : null) || + Config.maindir || + process.cwd() + const projectName = getProjectName(projectPath) + const yasaVersion = YASA_VERSION && typeof YASA_VERSION === 'string' ? YASA_VERSION : 'unknown' + const { finalStartTime } = calculateTimes(performanceTracker) + const scanStartTime = finalStartTime + ? new Date(finalStartTime instanceof Date ? finalStartTime.getTime() : finalStartTime).toISOString() + : new Date().toISOString() + const language = Config.language || 'unknown' + + logDiagnostics('scan_init', { + string1: yasaVersion, + string2: projectName, + string3: language, + number1: null, + number2: null, + number3: null, + date1: null, + date2: null, + }) +} + +/** + * 生成 scan_summary.json 文件 + * @param scanSummary - 扫描摘要 JSON 字符串 + * @param ruleConfigContent - 规则配置 JSON 字符串 + */ +function writeScanSummaryJson(scanSummary: string, ruleConfigContent: string): void { + try { + const reportDir = getReportDir() + // 确保目录存在 + if (!fs.existsSync(reportDir)) { + fs.mkdirSync(reportDir, { recursive: true }) + } + + // 解析扫描摘要 + let scanSummaryObj: any = {} + let ruleConfigObj: any = null + + try { + scanSummaryObj = JSON.parse(scanSummary) + } catch (e) { + // 如果解析失败,使用空对象 + console.error(`Failed to parse scanSummary JSON: ${e}`) + } + + if (ruleConfigContent) { + try { + ruleConfigObj = JSON.parse(ruleConfigContent) + } catch (e) { + // 如果解析失败,保持为 null + console.error(`Failed to parse ruleConfigContent JSON: ${e}`) + } + } + + // 合并对象:scanSummary 在前,ruleConfig 在后 + const summaryJson = { + ...scanSummaryObj, + ruleConfig: ruleConfigObj, + } + + // 写入 JSON 文件(格式化,2 空格缩进) + const summaryFilePath = path.join(reportDir, 'scan_summary.json') + fs.writeFileSync(summaryFilePath, JSON.stringify(summaryJson, null, 2), 'utf8') + } catch (error) { + // 如果生成 JSON 文件失败,记录错误但不影响主流程 + console.error(`Failed to write scan_summary.json: ${error}`) + if (error instanceof Error) { + console.error(`Error stack: ${error.stack}`) + } + } +} + +/** + * 生成并记录扫描摘要日志 + * @param analyzer - analyzer 对象 + * @param performanceTracker - performance tracker 对象 + * @param startTime - 开始时间(Date 或 number 时间戳) + * @param endTime - 结束时间(Date 或 number 时间戳) + */ +function logScanSummary( + analyzer: any, + performanceTracker: any, + startTime?: Date | number | null, + endTime?: Date | number | null +): void { + // 获取项目路径 + const projectPath = + analyzer?.options?.sourcePath || + analyzer?.options?.sourceFile || + Config.sourcePath || + (Config.single && Config.maindir ? Config.maindir : null) || + Config.maindir || + process.cwd() + + const projectName = getProjectName(projectPath) + const scanSummary = generateScanSummary(analyzer, performanceTracker, startTime, endTime) + const ruleConfigContent = getRuleConfigContent() + const { finalStartTime, finalEndTime } = calculateTimes(performanceTracker, startTime, endTime) + + // 解析 scanSummary 获取关键字段 + let yasaVersion = 'unknown' + let totalTime = 0 + let lineCount = 0 + let findingCount = 0 + + try { + const summaryObj = JSON.parse(scanSummary) + yasaVersion = summaryObj.yasaVersion || 'unknown' + totalTime = summaryObj.totalTimeMs || 0 + lineCount = summaryObj.lineCount || 0 + findingCount = summaryObj.findingCount || 0 + } catch (e) { + // 解析失败时使用默认值 + } + + // 记录到诊断日志(不包含 ruleConfig) + logDiagnostics('scan_summary', { + string1: yasaVersion, + string2: projectName, + string3: scanSummary, + number1: totalTime, + number2: lineCount, + number3: findingCount, + date1: finalStartTime || null, + date2: finalEndTime || null, + }) + + // 生成 scan_summary.json 文件(包含 ruleConfig) + writeScanSummaryJson(scanSummary, ruleConfigContent) } +// eslint-disable-next-line import/no-commonjs module.exports = { logDiagnostics, + logScanSummary, + logScanInit, } diff --git a/src/util/error-code.ts b/src/util/error-code.ts index 8a8e9fbf..0282e769 100644 --- a/src/util/error-code.ts +++ b/src/util/error-code.ts @@ -163,7 +163,7 @@ function genClass(err: ErrorConfig): ErrorConstructor { /** * */ - toString(): string { + override toString(): string { return this.message === this.description ? this.message : `${this.description} : ${this.message}` } } diff --git a/src/util/file-util.ts b/src/util/file-util.ts index 85f75425..e637634c 100644 --- a/src/util/file-util.ts +++ b/src/util/file-util.ts @@ -5,8 +5,11 @@ import _ from 'lodash' import globby from 'fast-glob' import stat from './statistics' +const { yasaLog, yasaWarning } = require('./format-util') const logger = require('./logger')(__filename) +const RESOLVE_UAST_BINARY_STAGE = 'preProcess.parseCode' + interface LineInfo { line: number code: string @@ -30,9 +33,10 @@ const { handleException } = require('../engine/analyzer/common/exception-handler // e.g. for printing source lines /** - * - * @param filename - * @param lineNumbers + * 读取文件的指定行 + * @param filename - 文件名 + * @param lineNumbers - 行号数组 + * @returns {LineInfo[]} 行信息数组 */ function readLinesSync(filename: string, lineNumbers: number[]): LineInfo[] { const lines: LineInfo[] = [] @@ -75,62 +79,13 @@ function readLinesSync(filename: string, lineNumbers: number[]): LineInfo[] { //* ***************************** Text file *********************************** -/** - * recursively load the bodies of all the files under the current path/file - * @param filename file or directory to load. - * If directory, recur and load all files not excluded by nameFilter - * @param nameFilter: array of strings that the filename should end with - * @param dirFilter: array of strings that the directory shouldn't contained - * @param extExcludes: array of strings that the filename should not end with - * @param nameFilter - * @param dirFilter - * @param extExcludes - * @returns list of records of the form { fileName , fileContent } - */ -function loadAllFileText( - filename: string, - nameFilter: string[], - dirFilter: string[], - extExcludes: string[] -): FileContent[] { - const res: FileContent[] = [] - const parsingStart = new Date().getTime() - loadFileTextRec(filename, nameFilter, dirFilter, res, extExcludes) - const parsingEnd = new Date().getTime() - stat.parsingTime += parsingEnd - parsingStart - return res -} - -// globby version of load all file text -/** - * - * @param srcFilter - * @param cwd - */ -function loadAllFileTextGlobby(srcFilter: string[], cwd: string): FileContent[] { - const res: FileContent[] = [] - - const parsingStart = new Date().getTime() - const files = globby.sync(srcFilter, { cwd }) - for (const file of files) { - const filepath = path.join(cwd, file) - const content = fs.readFileSync(filepath, 'utf8') - res.push({ file: filepath, content }) - } - - stat.parsingTime += new Date().getTime() - parsingStart - return res -} - /** * load the source recursively (by going into subdirectories) * @param filename the file to be considered (may be a directory or proper file) * @param nameFilter if the file doesn't ends in one of these strings, skip it - * @param dirFilter: if the directory in there strings, skip it - * @param extExcludes: if the file ends in one of these strings, skip it, prior than nameFilter - * @param dirFilter + * @param dirFilter - if the directory in there strings, skip it + * @param extExcludes - if the file ends in one of these strings, skip it, prior than nameFilter * @param res accumulator list. Added to by side-effect - * @param extExcludes */ function loadFileTextRec( filename: string, @@ -178,36 +133,114 @@ function loadFileTextRec( } } else contents = fs.readFileSync(filename, 'utf8') res.push({ file: filename, content: contents }) - } catch (e) {} + } catch (e) { + // 忽略读取错误 + } } } +/** + * recursively load the bodies of all the files under the current path/file + * @param filename file or directory to load. + * If directory, recur and load all files not excluded by nameFilter + * @param nameFilter - array of strings that the filename should end with + * @param dirFilter - array of strings that the directory shouldn't contained + * @param extExcludes - array of strings that the filename should not end with + * @returns {FileContent[]} list of records of the form { fileName , fileContent } + */ +function loadAllFileText( + filename: string, + nameFilter: string[], + dirFilter: string[], + extExcludes: string[] +): FileContent[] { + const res: FileContent[] = [] + const parsingStart = new Date().getTime() + loadFileTextRec(filename, nameFilter, dirFilter, res, extExcludes) + const parsingEnd = new Date().getTime() + stat.parsingTime += parsingEnd - parsingStart + return res +} + +// globby version of load all file text +/** + * 使用 globby 加载所有文件文本 + * @param srcFilter - 源文件过滤模式 + * @param cwd - 当前工作目录 + * @returns {FileContent[]} 文件内容数组 + */ +function loadAllFileTextGlobby(srcFilter: string[], cwd: string): FileContent[] { + const res: FileContent[] = [] + + const parsingStart = new Date().getTime() + const files = globby.sync(srcFilter, { cwd }) + for (const file of files) { + const filepath = path.join(cwd, file) + try { + const content = fs.readFileSync(filepath, 'utf8') + res.push({ file: filepath, content }) + } catch (err) { + logger.warn(`Failed to read file: ${filepath}, error: ${(err as Error).message}`) + } + } + + stat.parsingTime += new Date().getTime() - parsingStart + return res +} + //* ***************************** Source in JSON *********************************** +// from file to memory +/** + * 从文件加载 JSON + * @param filename - 文件名 + * @returns {any} 解析后的 JSON 对象 + */ +function loadJSONfile(filename: string): any { + if (!fs.existsSync(filename)) { + handleException( + null, + `loading JSON file error: ${filename}. File does not exist`, + `loading JSON file error: ${filename}. File does not exist` + ) + process.exit(1) + } + try { + return jsonfile.readFileSync(filename) + } catch (e) { + handleException(e, `jsonfile parse error:${filename}`, `jsonfile parse error:${filename}`) + process.exit(1) + } +} + // load and parse JSON files /** - * - * @param filename + * 加载并解析 JSON 文件 AST(未使用) + * @param filename - 文件名 + * @returns {ASTFileUnit[] | ASTFileUnit} AST 文件单元或数组 */ +// eslint-disable-next-line @typescript-eslint/no-unused-vars function loadJsonFileAsts(filename: string): ASTFileUnit[] | ASTFileUnit { - const path_string = filename + const pathString = filename let fileStat let ast try { - fileStat = fs.lstatSync(path_string) - } catch (e) {} + fileStat = fs.lstatSync(pathString) + } catch (e) { + // 忽略错误 + } if (fileStat && fileStat.isDirectory()) { - // logger.info('path: ' + path_string); - const dir = path_string + // logger.info('path: ' + pathString); + const dir = pathString let res: ASTFileUnit[] = [] const files = fs.readdirSync(dir) for (let i = 0; i < files.length; i++) { const name = `${dir}/${files[i]}` if (fs.statSync(name).isDirectory()) { // go into the subdirectories - const sub_res = loadJsonFileAsts(name) - res = res.concat(sub_res) + const subRes = loadJsonFileAsts(name) + res = res.concat(subRes) continue } @@ -229,7 +262,7 @@ function loadJsonFileAsts(filename: string): ASTFileUnit[] | ASTFileUnit { } return res } - // logger.info('file: ' + path_string); + // logger.info('file: ' + pathString); if (filename.indexOf('.json') === -1) { filename += '.json' } @@ -251,38 +284,215 @@ function loadJsonFileAsts(filename: string): ASTFileUnit[] | ASTFileUnit { // write JSON into a file /** - * - * @param filename - * @param value + * 将 JSON 写入文件 + * @param filename - 文件名 + * @param value - 要写入的值 */ function writeJSONfile(filename: string, value: any): void { // logger.info('writing JSON file: ' + filename); try { + // 检测循环引用的函数 + const detectCircularRefs = ( + obj: any, + path: string[] = [], + visited: WeakMap = new WeakMap() + ): string[] => { + const circularPaths: string[] = [] + + if (obj == null || typeof obj !== 'object') { + return circularPaths + } + + // 检查是否已经访问过这个对象 + const previousPath = visited.get(obj) + if (previousPath) { + // 找到循环引用,记录完整路径 + const currentPathStr = path.join('.') + const previousPathStr = previousPath.join('.') + circularPaths.push(`Circular reference: ${currentPathStr} -> ${previousPathStr}`) + return circularPaths + } + + // 记录当前路径 + visited.set(obj, path) + + // 处理普通对象 + if (!Array.isArray(obj)) { + for (const key in obj) { + if (Object.prototype.hasOwnProperty.call(obj, key)) { + // 跳过内部属性 + if (key.startsWith('__') || key === 'symbolTable' || key === 'astManager') { + continue + } + + try { + const val = obj[key] + if (val != null && typeof val === 'object') { + const newPath = [...path, key] + const subCircular = detectCircularRefs(val, newPath, visited) + circularPaths.push(...subCircular) + } + } catch (e) { + // 忽略访问器错误 + } + } + } + } else { + // 处理数组 + for (let i = 0; i < obj.length; i++) { + const item = obj[i] + if (item != null && typeof item === 'object') { + const newPath = [...path, `[${i}]`] + const subCircular = detectCircularRefs(item, newPath, visited) + circularPaths.push(...subCircular) + } + } + } + + return circularPaths + } + + // 在序列化前检测循环引用 + const circularPaths = detectCircularRefs(value, ['root']) + if (circularPaths.length > 0) { + logger.error('=== Circular References Detected ===') + circularPaths.forEach((path, index) => { + logger.error(`${index + 1}. ${path}`) + }) + logger.error('====================================') + + // 尝试打印第一个循环引用的详细信息 + if (circularPaths.length > 0) { + logger.error('Detailed analysis of first circular reference:') + const visited = new WeakMap() + const findFirstCircular = (obj: any, path: string[]): any => { + if (obj == null || typeof obj !== 'object') { + return null + } + + const previousPath = visited.get(obj) + if (previousPath) { + logger.error(` Current path: ${path.join('.')}`) + logger.error(` Previous path: ${previousPath.join('.')}`) + logger.error(` Object type: ${obj.constructor?.name || 'Object'}`) + if (obj.vtype) logger.error(` vtype: ${obj.vtype}`) + if (obj.qid) logger.error(` qid: ${obj.qid}`) + if (obj.uuid) logger.error(` uuid: ${obj.uuid}`) + if (obj.sid) logger.error(` sid: ${obj.sid}`) + return obj + } + + visited.set(obj, path) + + if (!Array.isArray(obj)) { + for (const key in obj) { + if (Object.prototype.hasOwnProperty.call(obj, key)) { + if (key.startsWith('__') || key === 'symbolTable' || key === 'astManager') { + continue + } + try { + const result = findFirstCircular(obj[key], [...path, key]) + if (result) return result + } catch (e) { + // 忽略访问器错误 + } + } + } + } else { + for (let i = 0; i < obj.length; i++) { + const result = findFirstCircular(obj[i], [...path, `[${i}]`]) + if (result) return result + } + } + + return null + } + + findFirstCircular(value, ['root']) + } + } + jsonfile.writeFileSync(filename, value, {}) - } catch (err) { - handleException(err, 'Error occurred in file-util.writeJSONfile', 'Error occurred in file-util.writeJSONfile') - } -} + } catch (err: any) { + // 如果错误是循环引用相关的,进行详细诊断 + if ( + err.message && + (err.message.includes('circular') || + err.message.includes('Converting circular structure') || + err.message.includes('circular reference')) + ) { + logger.error('=== JSON Serialization Error: Circular Reference ===') + logger.error(`Error message: ${err.message}`) + logger.error('Attempting to locate circular reference...') -// from file to memory -/** - * - * @param filename - */ -function loadJSONfile(filename: string): any { - if (!fs.existsSync(filename)) { - handleException( - null, - `loading JSON file error: ${filename}. File does not exist`, - `loading JSON file error: ${filename}. File does not exist` - ) - process.exit(1) - } - try { - return jsonfile.readFileSync(filename) - } catch (e) { - handleException(e, `jsonfile parse error:${filename}`, `jsonfile parse error:${filename}`) - process.exit(1) + const visited = new WeakMap() + const circularInfo: Array<{ current: string; previous: string; obj: any }> = [] + + const findCircular = (obj: any, path: string[]): void => { + if (obj == null || typeof obj !== 'object') { + return + } + + const previousPath = visited.get(obj) + if (previousPath) { + circularInfo.push({ + current: path.join('.'), + previous: previousPath.join('.'), + obj, + }) + return + } + + visited.set(obj, path) + + if (!Array.isArray(obj)) { + for (const key in obj) { + if (Object.prototype.hasOwnProperty.call(obj, key)) { + if (key.startsWith('__') || key === 'symbolTable' || key === 'astManager') { + continue + } + try { + findCircular(obj[key], [...path, key]) + } catch (e) { + // 忽略访问器错误 + } + } + } + } else { + for (let i = 0; i < obj.length; i++) { + findCircular(obj[i], [...path, `[${i}]`]) + } + } + } + + findCircular(value, ['root']) + + if (circularInfo.length > 0) { + logger.error(`Found ${circularInfo.length} circular reference(s):`) + circularInfo.forEach((info, index) => { + logger.error(`\n${index + 1}. Circular Reference:`) + logger.error(` Current path: ${info.current}`) + logger.error(` Previous path: ${info.previous}`) + logger.error(` Object type: ${info.obj.constructor?.name || 'Object'}`) + if (info.obj.vtype) logger.error(` vtype: ${info.obj.vtype}`) + if (info.obj.qid) logger.error(` qid: ${info.obj.qid}`) + if (info.obj.uuid) logger.error(` uuid: ${info.obj.uuid}`) + if (info.obj.sid) logger.error(` sid: ${info.obj.sid}`) + + // 打印对象的关键属性(前10个) + const keys = Object.keys(info.obj).slice(0, 10) + if (keys.length > 0) { + logger.error(` Sample keys: ${keys.join(', ')}`) + } + }) + } else { + logger.error('Could not locate circular reference (may be in getter/setter)') + } + + logger.error('====================================================') + } + + handleException(err, 'Error occurred in file-util.writeJSONfile', 'Error occurred in file-util.writeJSONfile') } } @@ -290,10 +500,11 @@ function loadJSONfile(filename: string): any { // Recurse into a directory to find a file with the given name /** - * - * @param rootdir - * @param tofind - * @param subdir + * 递归查找文件 + * @param rootdir - 根目录 + * @param tofind - 要查找的文件名或正则表达式 + * @param subdir - 子目录 + * @returns {boolean} 是否找到 */ function findfile(rootdir: string, tofind: string | RegExp, subdir?: string): boolean { const abspath = subdir ? path.join(rootdir, subdir) : rootdir @@ -305,10 +516,13 @@ function findfile(rootdir: string, tofind: string | RegExp, subdir?: string): bo } else if (filename === tofind) return true const filepath = path.join(abspath, filename) try { - if (fs.statSync(filepath).isDirectory()) { - if (findfile(rootdir, tofind, path.join(subdir || '', filename || ''))) return true + const fileStat = fs.statSync(filepath) + if (fileStat.isDirectory() && findfile(rootdir, tofind, path.join(subdir || '', filename || ''))) { + return true } - } catch (e) {} + } catch (e) { + // 忽略错误 + } } return false } @@ -316,11 +530,13 @@ function findfile(rootdir: string, tofind: string | RegExp, subdir?: string): bo // FIXME: share code with above functions // obtain recursively the files with the given extension and not included in the given list /** - * - * @param absPath - * @param file_ex - * @param excluded + * 获取目录中的文件列表 + * @param absPath - 绝对路径 + * @param file_ex - 文件扩展名 + * @param excluded - 排除的目录列表 + * @returns {string[] | undefined} 文件路径数组 */ +// eslint-disable-next-line complexity, sonarjs/cognitive-complexity function getFilesInDirectory(absPath: string, file_ex: string, excluded: string[]): string[] | undefined { const sourcePath = absPath let fileStat @@ -337,18 +553,18 @@ function getFilesInDirectory(absPath: string, file_ex: string, excluded: string[ for (const i in files) { const name = `${sourcePath}/${files[i]}` - const stat = fs.lstatSync(name) - if (stat.isSymbolicLink()) continue - if (stat.isDirectory()) { + const fileStatItem = fs.lstatSync(name) + if (fileStatItem.isSymbolicLink()) continue + if (fileStatItem.isDirectory()) { // go into the subdirectories if (excluded && excluded.indexOf(files[i]) !== -1) continue - const sub_res = getFilesInDirectory(name, file_ex, excluded) - if (sub_res) res = res.concat(sub_res) + const subRes = getFilesInDirectory(name, file_ex, excluded) + if (subRes) res = res.concat(subRes) continue } const j = name.lastIndexOf('.') - if (j == -1 || j == name.length - 1) { + if (j === -1 || j === name.length - 1) { continue } const fileExtension = name.substring(j + 1) @@ -359,7 +575,7 @@ function getFilesInDirectory(absPath: string, file_ex: string, excluded: string[ } // logger.info('File to analyze: ' + sourcePath); const i = sourcePath.lastIndexOf('.') - if (i == -1 || i == sourcePath.length - 1) return + if (i === -1 || i === sourcePath.length - 1) return const fileExtension = sourcePath.substring(i + 1) if (fileExtension !== file_ex) return return [sourcePath] @@ -367,10 +583,10 @@ function getFilesInDirectory(absPath: string, file_ex: string, excluded: string[ } /** - * - * @param absdirs - * @param options - * @returns {Array} + * 加载源代码文件 + * @param absdirs - 绝对目录路径数组 + * @param options - 选项对象 + * @returns {any[]} 文件列表 */ function loadSource(absdirs: string[], options: Record): any[] { let srcFilter = ['**/*.sol'] @@ -386,7 +602,7 @@ function loadSource(absdirs: string[], options: Record): any[] { case 'js': srcFilter = [ '**/*.(js|ts|mjs|cjs)', - '!**/*.test.(js|ts|mjs|cjs|jsx)', + '!**/*.test.(js|ts|mjs|cjs|jsx|tsx)', '!**/node_modules', '!**/app/public', '!**/*.d.ts', @@ -395,11 +611,17 @@ function loadSource(absdirs: string[], options: Record): any[] { // ext_excludes.push(...['.test.js', '.test.ts', '.test.mjs', '.test.cjs', '.test.jsx']); // dirFilter.push("node_modules"); break + default: + // 默认使用 .sol + break } const res: any[] = [] for (const dir of absdirs) { const files = globby.sync(srcFilter, { cwd: dir }) - files.length + // 计算文件数量(用于统计) + const fileCount = files.length + // eslint-disable-next-line @typescript-eslint/no-unused-expressions + fileCount } // const res = []; @@ -415,9 +637,58 @@ function loadSource(absdirs: string[], options: Record): any[] { } /** - * - * @param fullString - * @param subString + * 移除第一个斜杠之前的内容 + * @param str - 字符串 + * @returns {string} 处理后的字符串 + */ +function removeBeforeFirstSlash(str: string): string { + // 找到第一个'/'的索引 + const index = str.indexOf('/') + + // 如果找到了'/',则从该位置开始截取字符串;否则返回原字符串 + if (index !== -1) { + return str.substring(index) + } + return str // 如果没有找到'/',则返回原始字符串 +} + +/** + * 自定义路径拼接 + * @param segments - 路径片段数组 + * @returns {string} 拼接后的路径 + */ +function customJoin(...segments: string[]): string { + // 处理路径数组并展开所有分段 + const parts: string[] = [] + segments.forEach((segment) => { + parts.push(...segment.split(path.sep)) + }) + + const finalStack: string[] = [] + + for (const part of parts) { + if (part === '' || part === '.') { + continue + } else if (part.startsWith('..')) { + // 自定义逻辑处理 `..` 或更多点层级 + for (let i = 0; i < part.length - 1; i++) { + finalStack.pop() + } + } else { + // 普通目录,压入到最终路径的栈中 + finalStack.push(part) + } + } + + // 使用 path.join() 生成标准化的路径 + return `/${path.join(...finalStack)}` +} + +/** + * 提取子字符串之后的内容 + * @param fullString - 完整字符串 + * @param subString - 子字符串 + * @returns {string} 提取后的字符串 */ function extractAfterSubstring(fullString: string, subString: string): string { if (fullString) { @@ -433,9 +704,10 @@ function extractAfterSubstring(fullString: string, subString: string): string { } /** - * - * @param fullPath - * @param dir + * 提取相对路径 + * @param fullPath - 完整路径 + * @param dir - 目录路径 + * @returns {string | null} 相对路径 */ function extractRelativePath(fullPath: string, dir: string): string | null { if (!fullPath) { @@ -452,11 +724,13 @@ function extractRelativePath(fullPath: string, dir: string): string | null { } /** - * - * @param relativePath - * @param dir + * 组装完整路径 + * @param relativePath - 相对路径 + * @param dir - 目录路径 + * @returns {string} 完整路径 */ function assembleFullPath(relativePath: string, dir: string): string { + if (!relativePath) return dir || '' if (relativePath.startsWith(dir)) { return relativePath } @@ -467,24 +741,10 @@ function assembleFullPath(relativePath: string, dir: string): string { } /** - * - * @param str - */ -function removeBeforeFirstSlash(str: string): string { - // 找到第一个'/'的索引 - const index = str.indexOf('/') - - // 如果找到了'/',则从该位置开始截取字符串;否则返回原字符串 - if (index !== -1) { - return str.substring(index) - } - return str // 如果没有找到'/',则返回原始字符串 -} - -/** - * - * @param sourcefile - * @param fname + * 规范化并拼接路径 + * @param sourcefile - 源文件路径 + * @param fname - 文件名 + * @returns {string} 规范化后的路径 */ function normalizeAndJoin(sourcefile: string, fname: string): string { if (fname.startsWith('.')) { @@ -498,55 +758,23 @@ function normalizeAndJoin(sourcefile: string, fname: string): string { return path.resolve(config.maindir, fname) } -/** - * - * @param {...any} segments - */ -function customJoin(...segments: string[]): string { - // 处理路径数组并展开所有分段 - const parts: string[] = [] - segments.forEach((segment) => { - parts.push(...segment.split(path.sep)) - }) - - const finalStack: string[] = [] - - for (const part of parts) { - if (part === '' || part === '.') { - continue - } else if (part.startsWith('..')) { - // 自定义逻辑处理 `..` 或更多点层级 - for (let i = 0; i < part.length - 1; i++) { - finalStack.pop() - } - } else { - // 普通目录,压入到最终路径的栈中 - finalStack.push(part) - } - } - - // 使用 path.join() 生成标准化的路径 - return `/${path.join(...finalStack)}` -} - /** * remove the shared prefix of the file paths - * @param original - * @param path_prefix - * @returns {*} + * @param original - 原始路径 + * @param path_prefix - 路径前缀 + * @returns {string} 缩短后的路径 */ function shortenSourceFile(original: string, path_prefix: string): string { - if (path_prefix) { - if (original.startsWith(path_prefix)) { - return original.substring(path_prefix.length) - } + if (path_prefix && original.startsWith(path_prefix)) { + return original.substring(path_prefix.length) } return original } /** - * - * @param p + * 获取绝对路径 + * @param p - 路径 + * @returns {string} 绝对路径 */ function getAbsolutePath(p: string): string { if (path.isAbsolute(p)) { @@ -561,21 +789,139 @@ function getAbsolutePath(p: string): string { } /** - * - * @param fname + * 从缓存中移除文件 + * @param fname - 文件名 */ function removeFileFromCache(fname: string): void { if (useASTCache) delete astCache[fname] } /** - * - * @param mainFile + * 检查是否在 pkg 打包环境中 + * @param mainFile - 主文件路径 + * @returns {boolean} 是否在 pkg 环境中 */ function isPkgEnv(mainFile: string): boolean { return !!(process as any).pkg || !!(mainFile && mainFile.replace(/\\/g, '/').includes('/snapshot/')) } +/** + * 解析项目根目录(支持打包环境) + * @returns {string} 项目根目录路径 + */ +function resolveProjectRoot(): string { + const mainFile = require.main?.filename || process.execPath + const isPkg = isPkgEnv(mainFile) + let projectRoot = process.cwd() + if (isPkg) { + const distIdx = mainFile.indexOf('/dist/') + if (distIdx > 0) { + projectRoot = mainFile.slice(0, distIdx) // /snapshot/ + } else { + // 兜底:取主文件目录再回退一级 + projectRoot = path.resolve(path.dirname(mainFile), '..') + } + } + return projectRoot +} + +function resolveBinaryFromDir(baseDir: string, binaryName: string): string | null { + const candidate = path.join(baseDir, binaryName, binaryName) + if (fs.existsSync(candidate)) return candidate + return null +} + +/** + * 将 pkg 资产中的二进制文件解压到真实文件系统中 + * @param snapshotBinaryPath - /snapshot 下的二进制路径 + * @param binaryName - 二进制名称(用于生成缓存文件名) + * @param execBase - pkg 实际执行目录 + * @returns {string | null} 可执行文件的真实路径 + */ +function extractBinaryFromSnapshot(snapshotBinaryPath: string, binaryName: string, execBase: string): string | null { + try { + if (!fs.existsSync(snapshotBinaryPath)) return null + const targetDir = path.join(execBase, 'deps-runtime', binaryName) + const targetPath = path.join(targetDir, binaryName) + if (fs.existsSync(targetPath)) { + try { + fs.chmodSync(targetPath, 0o755) + } catch (e) { + yasaWarning(`chmod existing ${binaryName} failed: ${(e as Error).message}`, RESOLVE_UAST_BINARY_STAGE) + } + return targetPath + } + fs.mkdirSync(targetDir, { recursive: true }) + fs.copyFileSync(snapshotBinaryPath, targetPath) + fs.chmodSync(targetPath, 0o755) + yasaLog(`Materialized ${binaryName} into ${targetPath}`, RESOLVE_UAST_BINARY_STAGE) + return targetPath + } catch (err) { + yasaWarning(`extract binary failed for ${binaryName}: ${(err as Error).message}`, RESOLVE_UAST_BINARY_STAGE) + return null + } +} + +/** + * 统一解析 UAST 二进制文件路径(Python 和 Go 共用) + * 在 pkg 打包环境中,从 /snapshot 资产中解压到运行目录(execBase/deps-runtime/) + * @param options - 选项对象 + * @param options.uastSDKPath - 用户指定的 SDK 路径 + * @param options.binaryName - 二进制文件名('uast4py' 或 'uast4go') + * @param options.devPath - 开发环境路径 + * @returns {string | null} 二进制文件路径,如果不存在返回 null + */ +function resolveUastBinaryPath(options: { + uastSDKPath?: string + binaryName: 'uast4py' | 'uast4go' + devPath: string +}): string | null { + const { uastSDKPath, binaryName, devPath } = options + + // 优先级1: 用户指定的路径 + if (uastSDKPath && uastSDKPath !== '') { + if (fs.existsSync(uastSDKPath)) { + const stats = fs.statSync(uastSDKPath) + if (stats.isDirectory()) { + const resolvedFromDir = resolveBinaryFromDir(uastSDKPath, binaryName) + if (resolvedFromDir) return resolvedFromDir + } else { + return uastSDKPath + } + } + return null + } + + // 优先级2: pkg 打包环境 - 从 /snapshot 资产解压到运行目录 + const mainFile = require.main?.filename || process.execPath + const isPkg = isPkgEnv(mainFile) + if (isPkg) { + const execBase = path.dirname(process.execPath) + const snapshotBinaryPath = resolveBinaryFromDir(path.join(resolveProjectRoot(), 'deps'), binaryName) + yasaLog(`extracting ${binaryName} from snapshot to ${execBase}/deps-runtime/`, RESOLVE_UAST_BINARY_STAGE) + if (snapshotBinaryPath) { + const extractedPath = extractBinaryFromSnapshot(snapshotBinaryPath, binaryName, execBase) + if (extractedPath) { + return extractedPath + } + } + yasaWarning(`Failed to extract ${binaryName} from snapshot`, RESOLVE_UAST_BINARY_STAGE) + } + + // 优先级3: 开发环境路径 + if (fs.existsSync(devPath)) { + return devPath + } + + // 优先级4: 当前工作目录 + const cwdPath = resolveBinaryFromDir(path.join(process.cwd(), 'deps'), binaryName) + if (cwdPath && fs.existsSync(cwdPath)) { + return cwdPath + } + + return null +} + //* ***************************** exports ************************** export { @@ -596,4 +942,6 @@ export { getAbsolutePath, removeFileFromCache, isPkgEnv, + resolveProjectRoot, + resolveUastBinaryPath, } diff --git a/src/util/finding-util.ts b/src/util/finding-util.ts index 2987eb78..1ed9f207 100644 --- a/src/util/finding-util.ts +++ b/src/util/finding-util.ts @@ -29,15 +29,15 @@ function getBwdTrace(root: any, lines: TraceItem[], tagName?: string): void { const node = worklist.shift() if (!node || visited.has(node)) continue visited.add(node) - const { trace } = node - if (trace) { + const trace = node.taint.getFirstTrace() + if (trace && trace.length > 0) { for (let i = trace.length - 1; i >= 0; i--) { const item = trace[i] const prev_item = lines[lines.length - 1] if (!prev_item || prev_item.file !== item.file || prev_item.line !== item.line || prev_item.tag !== item.tag) lines.push(item) } - if (tagName && node?._tags.has(tagName)) { + if (tagName && node?.taint.containsTag(tagName)) { return } } @@ -51,7 +51,7 @@ function getBwdTrace(root: any, lines: TraceItem[], tagName?: string): void { } if (!node.type) continue - if (!node.hasTagRec) continue + if (!node.taint?.isTaintedRec) continue switch (node.type) { case 'MemberAccess': { @@ -59,7 +59,7 @@ function getBwdTrace(root: any, lines: TraceItem[], tagName?: string): void { worklist.push(node.property) break } - case 'BinaryOperation': { + case 'BinaryExpression': { worklist.push(node.left) worklist.push(node.right) break diff --git a/src/util/format-util.ts b/src/util/format-util.ts index e9136e4f..4a9ce5b8 100644 --- a/src/util/format-util.ts +++ b/src/util/format-util.ts @@ -119,7 +119,7 @@ function yasaLogInternal( const coloredMessage = `${colorFn(prefix)} ${message}` const getLogger = require('./logger') - const logger = getLogger('console') + const logger = getLogger('yasa') logger[level](plainMessage) outputStream.write(`${coloredMessage}\n`) diff --git a/src/util/framework-util.ts b/src/util/framework-util.ts index 7a6816f9..088603fb 100644 --- a/src/util/framework-util.ts +++ b/src/util/framework-util.ts @@ -2,6 +2,7 @@ import path from 'path' import fs from 'fs-extra' const logger = require('./logger')(__filename) +const FileUtil = require('./file-util') /** egg sanity check, must follow the convention below @@ -47,12 +48,10 @@ function detectAnalyzer(language: string, dir: string): string { if (language === 'java') { // 检查 Maven/Gradle 配置文件 - const pomPath = path.join(dir, 'pom.xml') - const gradlePath = path.join(dir, 'build.gradle') - let content = '' - try { - if (fs.existsSync(pomPath)) { - content = fs.readFileSync(pomPath, 'utf8') + const mavenOrGradleFiles = FileUtil.loadAllFileTextGlobby(['**/pom.xml', '**/build.gradle'], dir) + for (const mavenOrGradleFile of mavenOrGradleFiles) { + try { + const { content } = mavenOrGradleFile if ( (content && content.trim() !== '' && @@ -62,22 +61,9 @@ function detectAnalyzer(language: string, dir: string): string { (content.includes('sofaboot') || content.includes('sofa-boot') || content.includes('sofa.web.mvc'))) ) { analyzer = 'SpringAnalyzer' + break } - } else if (fs.existsSync(gradlePath)) { - content = fs.readFileSync(gradlePath, 'utf8') - if ( - (content && - content.trim() !== '' && - content.includes('org.springframework') && - (content.includes('spring-web') || content.includes('spring-boot'))) || - (content.includes('com.alipay.sofa') && - (content.includes('sofaboot') || content.includes('sofa-boot') || content.includes('sofa.web.mvc'))) - ) { - analyzer = 'SpringAnalyzer' - } - } - } catch (e) { - logger.info("detect Java's Analyzer failed, use default JavaAnalyzer") + } catch (e) {} } if (analyzer === '') { analyzer = 'JavaAnalyzer' diff --git a/src/util/global-registry.ts b/src/util/global-registry.ts new file mode 100644 index 00000000..597f1fcb --- /dev/null +++ b/src/util/global-registry.ts @@ -0,0 +1,28 @@ +// 全局注册表:AST 管理器 + 符号表管理器 +// 从 ast-util.ts 提取,打破 unit.ts ↔ ast-util.ts 循环依赖 + +let globalASTManager: any = null +let globalSymbolTable: any = null + +function setGlobalASTManager(astManager: any): void { + globalASTManager = astManager +} + +function getGlobalASTManager(): any { + return globalASTManager +} + +function setGlobalSymbolTable(symbolTable: any): void { + globalSymbolTable = symbolTable +} + +function getGlobalSymbolTable(): any { + return globalSymbolTable +} + +module.exports = { + setGlobalASTManager, + getGlobalASTManager, + setGlobalSymbolTable, + getGlobalSymbolTable, +} diff --git a/src/util/graph.ts b/src/util/graph.ts index e4c7b24b..e2a40d1b 100644 --- a/src/util/graph.ts +++ b/src/util/graph.ts @@ -1,3 +1,5 @@ +const QidUnifyUtil = require('./qid-unify-util') + interface GraphNode { id: string opts: any @@ -31,13 +33,14 @@ class GraphClass { * @param node_id * @param opts */ - addNode(node_id: string | undefined, opts: any): GraphNode { + addNode(node_id: string, opts: any): GraphNode { if (node_id === undefined) { node_id = 'undefined' } if (node_id === 'hasOwnProperty') { node_id = '[hasOwnProperty]' } + node_id = QidUnifyUtil.qidUnifyByRemoveAngleAndPrefix(node_id) const node: GraphNode = { id: node_id, opts } this.nodes.set(node_id, node) return node @@ -76,14 +79,21 @@ class GraphClass { /** * 将callgraph的内容dump出去 + * @param astManager AST 管理器,用于从 nodehash 还原 AST 对象 + * @param symbolTable 符号表管理器,用于从 UUID 还原符号值对象 */ - dumpGraph(): { nodes: Record; edges: Record } { + dumpGraph(astManager?: any, symbolTable?: any): { nodes: Record; edges: Record } { const newEdges = [...this.edges.entries()] .filter(([key, value]) => !key.includes('entry_point')) .reduce( (acc, [key, value]) => { const { opts, ...otherField } = value - const { callSite, ...rest } = opts + // 从 callSiteNodehash 还原 callSite + // eslint-disable-next-line prefer-const + let { callSite, ...rest } = opts + if (opts.callSiteNodehash && astManager) { + callSite = astManager.get(opts.callSiteNodehash) + } acc[key] = { ...otherField, callSite: { loc: callSite?.loc }, ...rest } return acc }, @@ -94,11 +104,19 @@ class GraphClass { .reduce( (acc, [key, value]) => { const { opts, ...otherField } = value - const { funcDef, funcSymbol } = opts + // 从 nodehash 和 UUID 还原 funcDef 和 funcSymbol + let { funcDef } = opts + let { funcSymbol } = opts + if (opts.funcDefNodehash && astManager) { + funcDef = astManager.get(opts.funcDefNodehash) + } + if (opts.funcSymbolUuid && symbolTable) { + funcSymbol = symbolTable.get(opts.funcSymbolUuid) + } acc[key] = { ...otherField, - funcDef: { loc: funcDef?.loc, name: funcDef?.name }, - fullName: funcSymbol?._qid ? funcSymbol?._qid : key, + funcDef: funcDef?.loc ? { loc: funcDef?.loc, name: funcDef?.name } : undefined, + fullName: funcSymbol?.qid && funcDef ? funcSymbol?.logicalQid : key, } return acc }, diff --git a/src/util/logger.ts b/src/util/logger.ts index cd615928..5b06fe14 100644 --- a/src/util/logger.ts +++ b/src/util/logger.ts @@ -4,7 +4,7 @@ const process = require('process') const log4jsLogger = require('log4js') const configLogger = require('../config') -interface Logger { +export interface Logger { trace(...args: any[]): void debug(...args: any[]): void info(...args: any[]): void @@ -48,7 +48,7 @@ log4jsLogger.configure({ alwaysIncludePattern: true, layout: { type: 'pattern', - pattern: '%d{yyyy-MM-dd hh:mm:ss.SSS} %p %c %m', + pattern: '%d{yyyy-MM-dd hh:mm:ss.SSS} %p %m', timezone: 'Asia/Shanghai', }, compress: true, @@ -60,7 +60,7 @@ log4jsLogger.configure({ alwaysIncludePattern: true, layout: { type: 'pattern', - pattern: '%d{yyyy-MM-dd hh:mm:ss.SSS} %p %c %m', + pattern: '%d{yyyy-MM-dd hh:mm:ss.SSS} %p %m', timezone: 'Asia/Shanghai', }, compress: true, @@ -75,8 +75,8 @@ log4jsLogger.configure({ }, categories: { default: { appenders: ['stdoutFilter', 'infoFilter', 'errFilter'], level: logLevel }, - // YASA 日志 category:只写入文件,不输出到控制台,使用默认的 file appender 保证顺序一致 - console: { appenders: ['yasaFileOnly', 'yasaErrorFileOnly'], level: logLevel }, + // YASA 日志 category:只写入文件,不输出到控制台 + yasa: { appenders: ['yasaFileOnly', 'yasaErrorFileOnly'], level: logLevel }, }, }) diff --git a/src/util/performance-tracker.ts b/src/util/performance-tracker.ts index 168540ac..7c5c7131 100644 --- a/src/util/performance-tracker.ts +++ b/src/util/performance-tracker.ts @@ -1,7 +1,5 @@ /* eslint-disable @typescript-eslint/no-require-imports, import/no-commonjs */ -const { logDiagnostics } = require('./diagnostics-log-util') const { yasaLog, yasaWarning, yasaSeparator } = require('./format-util') -/* eslint-enable @typescript-eslint/no-require-imports, import/no-commonjs */ /** * 性能追踪器接口 @@ -11,14 +9,15 @@ export interface IPerformanceTracker { start(stage?: string): void end(stage: string): void // 累加模式:如果在 start/end 之间调用,会自动转换为 record 模式 - record(stage: string, duration: number): void + record(stage: string, duration?: number): void | { start: () => void; end: () => void } setEnableDetailedInstructionStats(enabled?: boolean): void startInstructionMonitor(): void startInstruction(): void endInstructionAndUpdateStats(node: any, getLocationKey: (node: any, instructionType: string) => string): void - logPerformance(analyzer: any): void + collectAnalysisData(analyzer: any): void + outputPerformanceReport(): void getTimings(): Record } @@ -30,12 +29,31 @@ export interface IPerformanceTracker { class PerformanceTracker { private static readonly OTHER_COST_LABEL = 'other cost' + private static readonly OVERVIEW_LABELS = [ + 'Language', + 'Files analyzed', + 'Lines of code', + 'Total time', + 'Total instruction', + 'Executed instruction', + 'Execution count', + 'Valid entrypoints', + 'Avg execution time per instruction', + 'Avg instruction execution count', + 'Execution time 70%/99%/100%', + 'Execution times 70%/99%/100%', + ] + private startTime: number = 0 private enableDetailedInstructionStats: boolean = false private hasTotalStage: boolean = false + private hasLoggedPerformance: boolean = false + + private cachedAnalysisOverview: ReturnType | null = null + private stages: { [key: string]: { startTime: number @@ -46,6 +64,8 @@ class PerformanceTracker { } } = {} + private timers: Map void; end: () => void }> = new Map() + private instructionStats: { instructionTimes: Map // 总执行时间(包含嵌套调用) instructionCounts: Map @@ -181,19 +201,33 @@ class PerformanceTracker { this.endStage(stage) } + /** + * 获取内存使用情况的格式化字符串 + * @returns {string} 格式化的内存使用字符串,如 "heap: 1024/4096 MB" + */ + private getMemoryUsageString(): string { + const memUsage = process.memoryUsage() + const heapUsedMB = Math.round((memUsage.heapUsed / 1024 / 1024) * 100) / 100 + const heapTotalMB = Math.round((memUsage.heapTotal / 1024 / 1024) * 100) / 100 + const rssMB = Math.round((memUsage.rss / 1024 / 1024) * 100) / 100 + const arrayBuffersMB = Math.round((memUsage.arrayBuffers / 1024 / 1024) * 100) / 100 + return `heap: ${heapUsedMB}/${heapTotalMB} MB, rss: ${rssMB} MB, arrayBuffers: ${arrayBuffersMB} MB` + } + /** * 输出阶段结束日志 * @param stage - 阶段名称 * @param duration - 耗时(毫秒) */ private logStageEnd(stage: string, duration: number): void { + const memoryInfo = this.getMemoryUsageString() if (stage === 'total') { - yasaLog(`Execution completed, cost: ${duration}ms`) + yasaLog(`Execution completed, cost: ${duration}ms, ${memoryInfo}`) } else { const leafName = this.getStageLeafName(stage) if (leafName && leafName !== 'undefined') { const stages = this.getStageArray(stage) - yasaLog(`Completed ${leafName}, cost: ${duration}ms`, stages) + yasaLog(`Completed ${leafName}, cost: ${duration}ms, ${memoryInfo}`, stages) } } } @@ -249,23 +283,61 @@ class PerformanceTracker { * 记录一段时间的耗时(用于累加场景) * 混合模式:start() 后调用 record() 自动转换为 record 模式,end() 时使用 record 累加的 totalTime * @param stage - 阶段名称 - * @param duration - 耗时(毫秒) + * @param duration - 可选,耗时(毫秒)。如果不传,返回一个计时器对象,可以调用 start() 和 end() + * @returns {void | {start: () => void; end: () => void}} 如果 duration 未提供,返回包含 start() 和 end() 方法的对象;否则返回 void */ - record(stage: string, duration: number): void { - this.initStage(stage) - const stageData = this.stages[stage] - stageData.totalTime += duration - stageData.hasRecorded = true + record(stage: string, duration?: number): void | { start: () => void; end: () => void } { + // 如果提供了 duration,使用原有的记录方式 + if (duration !== undefined) { + this.initStage(stage) + const stageData = this.stages[stage] + stageData.totalTime += duration + stageData.hasRecorded = true - // 如果正在 start/end 计时,停止计时并转换为 record 模式 - if (stageData.currentStartTime > 0) { - stageData.currentStartTime = 0 + // 如果正在 start/end 计时,停止计时并转换为 record 模式 + if (stageData.currentStartTime > 0) { + stageData.currentStartTime = 0 + } + + if (stageData.startTime === 0) { + stageData.startTime = Date.now() + } + stageData.endTime = Date.now() + return } - if (stageData.startTime === 0) { - stageData.startTime = Date.now() + // 如果没有提供 duration,返回一个计时器对象(每个 stage 共享同一个计时器) + if (!this.timers.has(stage)) { + let startTime: number | null = null + const timer = { + start: () => { + startTime = Date.now() + }, + end: () => { + if (startTime === null) { + return + } + const elapsed = Date.now() - startTime + this.initStage(stage) + const stageData = this.stages[stage] + stageData.totalTime += elapsed + stageData.hasRecorded = true + + // 如果正在 start/end 计时,停止计时并转换为 record 模式 + if (stageData.currentStartTime > 0) { + stageData.currentStartTime = 0 + } + + if (stageData.startTime === 0) { + stageData.startTime = startTime + } + stageData.endTime = Date.now() + startTime = null + }, + } + this.timers.set(stage, timer) } - stageData.endTime = Date.now() + return this.timers.get(stage)! } /** @@ -278,7 +350,7 @@ class PerformanceTracker { this.initStage(stage) const stageData = this.stages[stage] - // forceEnd 为 true 时,强制结束正在运行的阶段(仅在 logPerformance 时使用) + // forceEnd 为 true 时,强制结束正在运行的阶段(仅在 outputPerformanceReport 时使用) if (forceEnd && stageData.currentStartTime > 0) { this.end(stage) return this.getStageTime(stage, false) @@ -307,7 +379,7 @@ class PerformanceTracker { * @returns {Object} 分析概览数据对象 */ // eslint-disable-next-line complexity, sonarjs/cognitive-complexity - private collectAnalysisOverview( + collectAnalysisOverview( analyzer: any, timings: Record ): { @@ -317,13 +389,13 @@ class PerformanceTracker { lineCount: number // summary2 totalTime: number - totalInstruction: number executedInstruction: number executionCount: number // configure - sourceCount: number - sinkCount: number + markedSourceCount: number + matchedSinkCount: number entryPointCount: number + findingCount: number // symbolInterpretDetail1 avgExecutionTimePerInstruction: number avgInstructionExecutionCount: number @@ -340,14 +412,26 @@ class PerformanceTracker { const language = analyzer?.options?.language || Config.language || 'unknown' - // 获取要统计的文件列表(单文件分析时只统计匹配的文件) - let filesToCount: string[] = [] - if (analyzer?.fileManager) { + // 使用 sourceCodeCache 获取精确的文件数量和代码行数 + let fileCount = 0 + let totalLines = 0 + + if (analyzer?.sourceCodeCache && analyzer.sourceCodeCache instanceof Map) { + // 直接从 sourceCodeCache 获取精确数据 + fileCount = analyzer.sourceCodeCache.size + for (const lines of analyzer.sourceCodeCache.values()) { + if (Array.isArray(lines)) { + totalLines += lines.length + } + } + } else if (analyzer?.fileManager) { + // 回退到旧的统计方式 const sourcePath = analyzer?.options?.sourcePath || analyzer?.options?.sourceFile || Config.sourcePath || (Config.single && Config.maindir ? Config.maindir : null) + let filesToCount: string[] = [] if (sourcePath && Config.single) { const sourcePathNormalized = sourcePath.replace(/\\/g, '/') const allFiles = Object.keys(analyzer.fileManager) @@ -361,35 +445,16 @@ class PerformanceTracker { } else { filesToCount = Object.keys(analyzer.fileManager) } - } - - let fileCount = filesToCount.length - if (fileCount === 0) { - const Statistics = require('./statistics') - fileCount = Statistics.numProcessedFiles || 0 - } - let totalLines = 0 - try { - const SourceLine = require('../engine/analyzer/common/source-line') - if (analyzer?.fileManager && SourceLine.getCodeBySourceFile) { - for (const filename of filesToCount) { - try { - const code = SourceLine.getCodeBySourceFile(filename) - if (code) { - totalLines += code.split('\n').length - } - } catch (e) { - // 忽略单个文件的错误 - } - } + fileCount = filesToCount.length + if (fileCount === 0) { + const Statistics = require('./statistics') + fileCount = Statistics.numProcessedFiles || 0 } - } catch (e) { - // SourceLine 可能不存在,使用 AST 估算作为后备 - } - if (totalLines === 0 && analyzer?.fileManager) { + + // 使用 AST 估算代码行数 for (const filename of filesToCount) { - const { ast } = analyzer.fileManager[filename] || {} + const { ast } = analyzer.symbolTable.get(analyzer.fileManager[filename]) || {} if (ast) { if (ast.loc?.end?.line) { totalLines += ast.loc.end.line @@ -400,15 +465,14 @@ class PerformanceTracker { } } - // 使用被执行的指令位置数量作为总指令数的近似值 + // 统计逻辑统一:都是按节点数量统计 + // executedInstruction: 执行过的不同指令位置数量(节点数量,通过执行时记录) const executedInstruction = this.instructionStats.instructionCounts.size + // executionCount: 所有指令执行次数的总和(同一节点可能执行多次) let executionCount = 0 for (const count of this.instructionStats.instructionCounts.values()) { executionCount += count } - const totalInstruction = executedInstruction - let sourceCount = 0 - let sinkCount = 0 let entryPointCount = 0 if (analyzer?.checkerManager) { const { checkerManager } = analyzer @@ -425,17 +489,6 @@ class PerformanceTracker { } } - for (const checker of checkers) { - const checkerAny = checker as any - const { checkerRuleConfigContent } = checkerAny || {} - if (checkerRuleConfigContent?.sources) { - sourceCount += this.countConfigItems(checkerRuleConfigContent.sources) - } - if (checkerRuleConfigContent?.sinks) { - sinkCount += this.countConfigItems(checkerRuleConfigContent.sinks) - } - } - if (analyzer.entryPoints && Array.isArray(analyzer.entryPoints)) { entryPointCount = analyzer.entryPoints.length } else if (analyzer.mainEntryPoints && Array.isArray(analyzer.mainEntryPoints)) { @@ -451,19 +504,43 @@ class PerformanceTracker { } } + // 获取 findings 数量(只统计 taintflow,不包括 callgraph) + let findingCount = 0 + if (analyzer?.checkerManager?.resultManager) { + const findings = analyzer.checkerManager.resultManager.getFindings?.() || {} + // 只统计实际的 findings,排除 callgraph(callgraph 是调用图数据,不是 findings) + for (const key in findings) { + if (key !== 'callgraph' && Array.isArray(findings[key])) { + findingCount += findings[key].length + } + } + } + const instructionDetails = this.getInstructionDetails() + // 获取实际标记的 source 和匹配的 sink 数量(延迟加载以避免循环依赖) + let markedSourceCount = 0 + let matchedSinkCount = 0 + try { + const sourceUtil = require('../checker/taint/common-kit/source-util') + const sinkUtil = require('../checker/taint/common-kit/sink-util') + markedSourceCount = sourceUtil?.getMarkedSourceCount ? sourceUtil.getMarkedSourceCount() : 0 + matchedSinkCount = sinkUtil?.getMatchedSinkCount ? sinkUtil.getMatchedSinkCount() : 0 + } catch (e) { + // 模块可能不存在或循环依赖,忽略 + } + return { language, fileCount, lineCount: totalLines, totalTime: timings.total || 0, - totalInstruction, executedInstruction, executionCount, - sourceCount, - sinkCount, + markedSourceCount, + matchedSinkCount, entryPointCount, + findingCount, avgExecutionTimePerInstruction: instructionDetails.avgExecutionTimePerInstruction, avgInstructionExecutionCount: instructionDetails.avgInstructionExecutionCount, executionTime70Percent: instructionDetails.executionTime70Percent, @@ -476,11 +553,20 @@ class PerformanceTracker { } /** - * 记录性能数据并输出摘要 - * @param analyzer - 可选的 analyzer 对象 + * 从 analyzer 收集分析概览数据 + * @param analyzer - analyzer 对象 + */ + collectAnalysisData(analyzer: any): void { + const timings = this.getTimings() + this.cachedAnalysisOverview = this.collectAnalysisOverview(analyzer, timings) + this.hasLoggedPerformance = true + } + + /** + * 输出性能报告(包括 overview 和 summary) + * 如果之前执行过 collectAnalysisData(analyzer),则输出 overview,否则只输出 summary */ - // eslint-disable-next-line complexity, sonarjs/cognitive-complexity - logPerformance(analyzer?: any): void { + outputPerformanceReport(): void { if (!this.hasTotalStage) { this.start() } @@ -496,110 +582,10 @@ class PerformanceTracker { this.end('total') } - const timings = this.getTimings() - const analysisOverview = analyzer ? this.collectAnalysisOverview(analyzer, timings) : null - if (analysisOverview) { - logDiagnostics('summary1', { - string1: analysisOverview.language, - string2: 'fileCount', - string3: 'lineCount', - number1: analysisOverview.fileCount, - number2: analysisOverview.lineCount > 0 ? analysisOverview.lineCount : null, - number3: null, - }) - - logDiagnostics('summary2', { - string1: 'totalTime', - string2: 'totalInstruction', - string3: 'executedInstruction', - number1: analysisOverview.totalTime, - number2: analysisOverview.totalInstruction, - number3: analysisOverview.executedInstruction, - }) - - logDiagnostics('configure', { - string1: 'sourceCount', - string2: 'sinkCount', - string3: 'entryPoints', - number1: analysisOverview.sourceCount, - number2: analysisOverview.sinkCount, - number3: analysisOverview.entryPointCount, - }) - } - - logDiagnostics('stageTime', { - string1: 'preProcessTime', - string2: 'preAnalyzeTime', - string3: 'symbolInterpretTime', - number1: timings.preProcess || 0, - number2: timings.startAnalyze || 0, - number3: timings.symbolInterpret || 0, - }) - - const parseCodeStage = this.stages['preProcess.parseCode'] - const preloadStage = this.stages['preProcess.preload'] - const processModuleStage = this.stages['preProcess.processModule'] - logDiagnostics('preprocessDetail1', { - string1: 'parseTime', - string2: 'preloadTime', - string3: 'processModuleTime', - number1: parseCodeStage?.totalTime || 0, - number2: preloadStage?.totalTime || 0, - number3: processModuleStage?.totalTime || 0, - }) - - if (analysisOverview) { - logDiagnostics('symbolInterpretDetail1', { - string1: 'executionCount', - string2: 'avgExecutionTimePerInstruction', - string3: 'avgInstructionExecutionCount', - number1: analysisOverview.executionCount, - number2: analysisOverview.avgExecutionTimePerInstruction, - number3: analysisOverview.avgInstructionExecutionCount, - }) - - logDiagnostics('symbolInterpretDetail2', { - string1: 'executionTime70Percent', - string2: 'executionTime99Percent', - string3: 'executionTime100Percent', - number1: analysisOverview.executionTime70Percent, - number2: analysisOverview.executionTime99Percent, - number3: analysisOverview.executionTime100Percent, - }) - - logDiagnostics('symbolInterpretDetail3', { - string1: 'executionTimes70Percent', - string2: 'executionTimes99Percent', - string3: 'executionTimes100Percent', - number1: analysisOverview.executionTimes70Percent, - number2: analysisOverview.executionTimes99Percent, - number3: analysisOverview.executionTimes100Percent, - }) - } - - let unifiedMaxLabelLength = 0 - if (analyzer && analysisOverview) { - const labels = [ - 'Language', - 'Files analyzed', - 'Lines of code', - 'Total time', - 'Total instruction', - 'Executed instruction', - 'Execution count', - 'Sources configured', - 'Sinks configured', - 'Valid entrypoints', - 'Avg execution time per instruction', - 'Avg instruction execution count', - 'Execution time 70%/99%/100%', - 'Execution times 70%/99%/100%', - ] - unifiedMaxLabelLength = Math.max(...labels.map((label) => label.length)) + 1 - } - - if (analyzer && analysisOverview) { - this.outputOverview(analysisOverview, unifiedMaxLabelLength) + // 如果之前执行过 collectAnalysisData(analyzer),则输出 overview + if (this.hasLoggedPerformance && this.cachedAnalysisOverview) { + const unifiedMaxLabelLength = Math.max(...PerformanceTracker.OVERVIEW_LABELS.map((label) => label.length)) + 1 + this.outputOverview(this.cachedAnalysisOverview, unifiedMaxLabelLength) } this.outputSummary() @@ -634,14 +620,14 @@ class PerformanceTracker { maxLabelLength ) - this.outputOverviewLine('Total time', `${analysisOverview.totalTime}ms`, maxLabelLength) - this.outputOverviewLine('Total instruction', String(analysisOverview.totalInstruction), maxLabelLength) + this.outputOverviewLine('Total time', this.formatTime(analysisOverview.totalTime), maxLabelLength) this.outputOverviewLine('Executed instruction', String(analysisOverview.executedInstruction), maxLabelLength) this.outputOverviewLine('Execution count', String(analysisOverview.executionCount), maxLabelLength) - this.outputOverviewLine('Sources configured', String(analysisOverview.sourceCount), maxLabelLength) - this.outputOverviewLine('Sinks configured', String(analysisOverview.sinkCount), maxLabelLength) + this.outputOverviewLine('Sources marked', String(analysisOverview.markedSourceCount), maxLabelLength) + this.outputOverviewLine('Sinks matched', String(analysisOverview.matchedSinkCount), maxLabelLength) this.outputOverviewLine('Valid entrypoints', String(analysisOverview.entryPointCount), maxLabelLength) + this.outputOverviewLine('Findings', String(analysisOverview.findingCount), maxLabelLength) this.outputOverviewLine( 'Avg execution time per instruction', @@ -671,23 +657,30 @@ class PerformanceTracker { /** 输出性能统计(树形结构,自动计算 other cost) */ // eslint-disable-next-line complexity - outputSummary(): void { + private outputSummary(): void { const timings = this.getTimings() yasaSeparator('Performance Statistics') - const rootStages = Object.keys(this.stages).filter((stage) => { - return !this.getParentStage(stage) && stage !== 'total' - }) + const rootStages = Object.keys(this.stages) + .filter((stage) => { + return !this.getParentStage(stage) && stage !== 'total' + }) + .sort((a, b) => { + // 按照 startTime 排序 + return this.stages[a].startTime - this.stages[b].startTime + }) if (this.hasTotalStage && timings.total != null) { - console.log(`total cost: ${timings.total}ms`) + console.log(`total cost: ${this.formatTime(timings.total)}`) } const maxDepth = Infinity rootStages.forEach((stage) => { if (timings[stage] != null) { - this.outputStageTree(stage, timings, 0, maxDepth) + // 根阶段的父时间是 total + const parentTime = this.hasTotalStage && timings.total != null ? timings.total : null + this.outputStageTree(stage, timings, 0, maxDepth, parentTime) } }) @@ -701,7 +694,8 @@ class PerformanceTracker { const otherTime = totalTime - allStagesTotal if (otherTime > 0) { - console.log(`${PerformanceTracker.OTHER_COST_LABEL}: ${otherTime}ms`) + const percentage = ((otherTime / totalTime) * 100).toFixed(1) + console.log(`${PerformanceTracker.OTHER_COST_LABEL}: ${this.formatTime(otherTime)} (${percentage}%)`) } } @@ -718,12 +712,14 @@ class PerformanceTracker { * @param timings - 所有阶段的耗时数据 * @param indent - 缩进级别 * @param maxDepth - 最大深度 + * @param parentTime - 父阶段的耗时(用于计算百分比) */ private outputStageTree( stage: string, timings: Record, indent: number, - maxDepth: number = Infinity + maxDepth: number = Infinity, + parentTime: number | null = null ): void { if (indent >= maxDepth) { return @@ -735,19 +731,31 @@ class PerformanceTracker { const indentStr = ' '.repeat(indent) const leafName = this.getStageLeafName(stage) - console.log(`${indentStr}${leafName} cost: ${stageTime}ms`) + + // 如果有父阶段时间,计算并显示百分比 + let percentageStr = '' + if (parentTime != null && parentTime > 0) { + const percentage = ((stageTime / parentTime) * 100).toFixed(1) + percentageStr = ` (${percentage}%)` + } + + console.log(`${indentStr}${leafName} cost: ${this.formatTime(stageTime)}${percentageStr}`) const childStages = this.getChildStages(stage) .filter((childStage) => { const childTime = timings[childStage] return childTime != null && childTime > 0 }) - .sort() + .sort((a, b) => { + // 按照 startTime 排序 + return this.stages[a].startTime - this.stages[b].startTime + }) if (childStages.length > 0) { if (indent + 1 < maxDepth) { childStages.forEach((childStage) => { - this.outputStageTree(childStage, timings, indent + 1, maxDepth) + // 子阶段的父时间是当前阶段的时间 + this.outputStageTree(childStage, timings, indent + 1, maxDepth, stageTime) }) } @@ -759,11 +767,31 @@ class PerformanceTracker { // 计算 other cost(父阶段时间减去所有子阶段时间) const otherCost = stageTime - subTotal if (otherCost > 0) { - console.log(`${indentStr} ${PerformanceTracker.OTHER_COST_LABEL}: ${otherCost}ms`) + const percentage = ((otherCost / stageTime) * 100).toFixed(1) + console.log( + `${indentStr} ${PerformanceTracker.OTHER_COST_LABEL}: ${this.formatTime(otherCost)} (${percentage}%)` + ) } } } + /** + * Format milliseconds to international standard format (minutes:seconds.milliseconds) + * @param ms - Milliseconds + * @returns {string} Formatted time string, e.g. "0m12s203ms" or "12s203ms" + */ + private formatTime(ms: number): string { + const totalSeconds = Math.floor(ms / 1000) + const minutes = Math.floor(totalSeconds / 60) + const seconds = totalSeconds % 60 + const milliseconds = ms % 1000 + + if (minutes > 0) { + return `${minutes}m${seconds}s${milliseconds}ms` + } + return `${seconds}s${milliseconds}ms` + } + /** * 统计配置项数量(sources 或 sinks) * @param items - 配置项对象 @@ -846,8 +874,8 @@ class PerformanceTracker { const avgInstructionExecutionCount = totalInstructionLocations > 0 ? totalInstructions / totalInstructionLocations : 0 - // 注意:不再在这里输出日志,避免与 logPerformance 中的输出重复 - // 日志输出统一在 logPerformance 方法中处理 + // 注意:不再在这里输出日志,避免与 outputPerformanceReport 中的输出重复 + // 日志输出统一在 outputPerformanceReport 方法中处理 // 计算所有指令执行时间的分位数(基于净执行时间) const allExecutionTimes: number[] = [] @@ -1138,7 +1166,10 @@ class PerformanceTracker { } } -// eslint-disable-next-line import/no-commonjs +// 创建单例实例 +const performanceTrackerInstance = new PerformanceTracker() + module.exports = { PerformanceTracker, + performanceTracker: performanceTrackerInstance, // 导出单例实例 } diff --git a/src/util/qid-unify-util.ts b/src/util/qid-unify-util.ts new file mode 100644 index 00000000..7596089a --- /dev/null +++ b/src/util/qid-unify-util.ts @@ -0,0 +1,241 @@ +interface SymbolLike { + qid?: string + vtype?: string + sid?: string + [key: string]: any +} + +/** + * 统一各语言的qid + */ +class QidUnifyUtil { + symbol: SymbolLike | undefined + + value: string + + /** + * 构造函数:可以接受 SymbolLike 对象或字符串 + * @param symbolOrValue SymbolLike 对象或字符串 + */ + constructor(symbolOrValue?: SymbolLike | string) { + if (typeof symbolOrValue === 'string') { + // 如果传入的是字符串,直接使用 + this.symbol = undefined + this.value = symbolOrValue + } else { + // 如果传入的是 SymbolLike 对象 + this.symbol = symbolOrValue + this.value = symbolOrValue?.qid || '' + } + } + + /** + * 统一路径形式,将开头的"/"去掉,并将每一层目录替换成".", 即 /tp/2.func ==> tp.2.func + */ + removePath(): QidUnifyUtil { + this.value = this.value?.replace(/^\//, '').replace(/\//g, '.') + return this + } + + /** + * python中找不到import时,会以"syslib_from."开头 + */ + removeSyslibFrom(): QidUnifyUtil { + if (this.value.startsWith('syslib_from.')) { + this.value = this.value.replace('syslib_from.', '') + } + return this + } + + /** + * js-chair框架会将agg替换成Egg.Application,将ctx替换成Egg.Context,替换回来 + */ + removeChair(): QidUnifyUtil { + this.value = this.value.replace('Egg.Application', 'app') + this.value = this.value.replace('Egg.Context', 'ctx') + return this + } + + /** + * 去除所有的括号及括号内内容(包括嵌套)——更通用的情况 + */ + removeParentheses(): QidUnifyUtil { + let result = '' + let level = 0 + for (const char of this.value) { + if (char === '(') { + level++ + } else if (char === ')') { + if (level > 0) level-- + } else if (level === 0) { + result += char + } + } + this.value = result + return this + } + + /** + * remove *_scope.写法,即1.calculate.calculate_scope..process ==> 1.calculate.process + */ + removeBlock(): QidUnifyUtil { + if ( + !this.value.includes(' 0 ? temp[i - 1] : 'NaN' + if (curStr === `${preStr}_scope`) { + continue + } + // 移除掉多余的 + if ( + curStr.startsWith('.,去掉instance标签 + */ + removeInstance(): QidUnifyUtil { + // 匹配以 结尾的字符串(中间可能包含 >,但不包含 .) + // 使用非贪婪匹配 [^.]*? 来匹配最短的从 的内容,排除 . + this.value = this.value.replace(//g, '') + return this + } + + /** + * 流敏感给不同符号值制作拷贝时会添加标签 + */ + removeCopied(): QidUnifyUtil { + this.value = this.value.replace(//g, '') + return this + } + + /** + * 统一去掉cloned + */ + removeCloned(): QidUnifyUtil { + this.value = this.value.replace(//g, '') + return this + } + + /** + * 统一去掉 + */ + removeGlobal(): QidUnifyUtil { + this.value = this.value + .replace('.', '') + .replace('packageManager.', '') + .replace('moduleManager.', '') + .replace('fileManager.', '') + return this + } + + /** + * 获取当前的值 + */ + get(): string { + return this.value + } + + /** + * 静态方法,用于在QL中格式化qid + * @param symbolOrValue SymbolLike 对象或字符串 + */ + static qidUnifyForQL(symbolOrValue?: SymbolLike | string): string { + if (typeof symbolOrValue === 'string') { + // 如果传入的是字符串,直接处理 + return new QidUnifyUtil(symbolOrValue) + .removePath() + .removeChair() + .removeParentheses() + .removeBlock() + .removeInstance() + .removeCopied() + .removeGlobal() + .removeCloned() + .removeSyslibFrom() + .get() + } + let unifyID = symbolOrValue?.qid || '' + if (symbolOrValue?.vtype !== 'primitive' && symbolOrValue?.vtype !== 'uninitialized') { + unifyID = new QidUnifyUtil(symbolOrValue) + .removePath() + .removeChair() + .removeParentheses() + .removeBlock() + .removeInstance() + .removeCopied() + .removeCloned() + .removeGlobal() + .removeSyslibFrom() + .get() + } + return unifyID + } + + /** + * 静态方法,用于在yasa中格式化qid + * @param symbolOrValue SymbolLike 对象或字符串 + */ + static qidUnifyByRemoveAngleAndPrefix(symbolOrValue?: SymbolLike | string): string { + if (typeof symbolOrValue === 'string') { + // 如果传入的是字符串,直接处理 + return new QidUnifyUtil(symbolOrValue) + .removeBlock() + .removeInstance() + .removeCopied() + .removeGlobal() + .removeSyslibFrom() + .removeCloned() + .get() + } + let unifyID = symbolOrValue?.qid || '' + if (symbolOrValue?.vtype !== 'primitive' && symbolOrValue?.vtype !== 'uninitialized') { + unifyID = new QidUnifyUtil(symbolOrValue) + .removeBlock() + .removeInstance() + .removeCopied() + .removeGlobal() + .removeSyslibFrom() + .removeCloned() + .get() + } + return unifyID + } + + /** + * 静态方法,用于去掉字符串中的 instance 标签 + * @param value 要处理的字符串 + * @returns 处理后的字符串 + */ + static removeInstanceFromString(value: string): string { + return new QidUnifyUtil(value).removeInstance().removeCopied().get() + } +} + +module.exports = QidUnifyUtil diff --git a/src/util/value-formatter.ts b/src/util/value-formatter.ts deleted file mode 100644 index 4efc6c5d..00000000 --- a/src/util/value-formatter.ts +++ /dev/null @@ -1,457 +0,0 @@ -const logger = require('./logger')(__filename) -import _ from 'lodash' -import escodegenValueFormatter from 'escodegen' - -// const logger = console; // require('../util/logger')(__filename); -// const _ = require('lodash'); - -// *** - -// const printFieldFilters = ['id', 'name', 'value', 'type', 'operator', 'left', 'right', 'elements', -// 'argument', 'callee', 'arguments', 'object', 'params', 'property', -// 'ast', 'taint', 'info', 'trace', 'pscope', 'modifiers', 'code', '_this']; - -//* ***************************** other utilities ******************************************** - -/** - * - * @param object - * @param match - */ -function deepMatch(object: any, match: any): boolean { - if (object === match) return true - if (typeof object !== typeof match) return false - if (typeof object === 'object') { - if (Array.isArray(object)) { - if (!Array.isArray(match)) return false - if (object.length !== match.length) return false - var isMatch = true - for (var i = 0; i < match.length; i++) { - if (!deepMatch(object[i], match[i])) { - isMatch = false - break - } - } - return isMatch - } - const objKeys = Object.keys(match) - var isMatch = true - for (var i = 0; i < objKeys.length; i++) { - const prop = objKeys[i] - if (prop === 'loc' || prop === 'info') continue - if (!deepMatch(object[prop], match[prop])) { - isMatch = false - break - } - } - return isMatch - } - return object === match -} - -/** - * - * @param scope - */ -function shallowCloneScope(scope: any): Record { - const res: Record = {} - for (const field in scope) { - res[field] = scope[field] - } - return res -} - -/** - * set the id's value in a scope; the id "x.y.z" is of format [x, y, z] - * @param scope - * @param ids - * @param value: the value to be assigned - * @param value - */ -function setFieldValue(scope: any, ids: any, value: any): void { - let scp = scope - for (let i = 0; i < ids.length - 1; i++) { - const field = ids[i] - const scp1 = scp.value[field] - if (!scp1) scp.value[field] = { value: {} } - scp = scp.value[field] - } - scp.value[ids[ids.length - 1]] = value -} - -/** - * set the value only if the first id can be found in the scope chain - * @param scope - * @param ids - * @param value - */ -function setFieldValueIfExists(scope: any, ids: any, value: any): void { - const first = ids[0] - let right_scope = scope - while (right_scope && !_.has(right_scope.value, first)) right_scope = right_scope.parent - if (right_scope) setFieldValue(right_scope, ids, value) -} - -/// ** -// * resolve specific internal values -// * @param val -// */ -// function resolveValue(value) { -// if (!value) return value; -// if (value.vtype === 'fork') { -// const okey = value.okey; -// if (okey) { -// const v = value.value[okey]; -// if (v) return v; -// } -// } -// return value; -// } - -/** - * resolve specific internal values - * @param val - * @param value - */ -function resolveForkedValue(value: any): any { - if (!value) return value - if (value.vtype === 'fork') { - let tnode = value.btree - value = value.value - while (tnode) { - const okey = tnode.index - if (value.hasOwnProperty(okey)) return value[okey] - tnode = tnode.parent - } - } - return value -} - -/** - * obtain the id's value in a scope; the id "x.y.z" is of format [x, y, z] - * @param scope - * @param ids - * @returns {*} - */ -function getFieldValue(scope: any, ids: string | string[]): any { - if (!scope || !scope.value || !ids) return - if (!Array.isArray(ids)) { - ids = ids.split('.') - } - const fieldIds = ids - const end = ids.length - 1 - let scp = scope - for (let i = 0; i < end; i++) { - scp = scp.value[fieldIds[i]] - if (!scp) return - } - if (!scp.value) return - const res = scp.value[fieldIds[end]] - return resolveForkedValue(res) -} - -/** - * get the value only if the first id can be found in the scope chain - * @param scope - * @param ids - */ -function getFieldValueInScopeChain(scope: any, ids: string | string[]): any { - if (!Array.isArray(ids)) { - ids = ids.split('.') - } - const first = ids[0] - let right_scope = scope - while (right_scope && right_scope.value && !_.has(right_scope.value, first)) right_scope = right_scope.parent - if (right_scope) return getFieldValue(right_scope, ids) -} - -//* ***************************** for Debugging ******************************************** - -// for pretty printing -/** - * - * @param key - * @param value - */ -function JSON_scope_replacer(key: any, value: any): any { - if ( - key === 'parent' || - key === 'pscope' || - key === 'loc' || - key === 'body' || - key === 'defaults' || - key === 'generator' || - key === 'sourcefile' || - key === 'modifiers' || - key === 'code' || - key === '_this' || - key === 'astparent' || - key === 'trace' || - key === 'ast' || - key === 'decl_scope' || - key === 'rrefs' || - key === 'extra' - ) { - return undefined - } - if (key === 'cdef') { - return `{${value.fqdn}}` - } - if (value) { - if (value.type === 'Literal') return value.raw - if (value.type === 'Identifier') return `<${value.name}>` - // else if (value.type === 'MemberExpression') { - // var obj = formatScope(value.object); - // var prop = formatScope(value.property); - // return obj.replace('\"','') + '[' + prop.replace('\"','') + ']'; - // } - } - return value -} - -// for debugging -/** - * - * @param scope - * @param delimit - */ -function formatScope(scope: any, delimit?: any): string { - // return JSON.stringify(scope, JSON_scope_replacer, 2); - return JSON.stringify(scope, JSON_scope_replacer, delimit) -} - -// for pretty printing -/** - * - * @param key - * @param value - */ -function JSON_scope_replacer2(key: any, value: any): any { - if (value && value.ast) return value.ast - return JSON_scope_replacer(key, value) -} - -/** - * - * @param node - */ -function formatNode(node: any): string { - try { - return JSON.stringify(node, JSON_scope_replacer) - } catch (e) { - return '{...}' - } -} - -/** - * - * @param node - */ -function formatScope2(node: any): string | any { - try { - return JSON.stringify(node, JSON_scope_replacer2) - } catch (e) { - return node - } -} - -/** - * - * @param value - */ -function valueToAST(value: any): any { - // logger.info('visit: ' + formatScope(value)); - if (!value) return value - if (value.vtype === 'object') { - if (value.ast && _.isEmpty(value.value)) { - return value.ast - } - var props: any[] = [] - for (const field in value.value) { - const prop = { - type: 'Property', - key: { type: 'Literal', value: field, raw: field }, - value: valueToAST(value.value[field]), - } - props.push(prop) - } - return { type: 'ObjectExpression', properties: props } - } - if (value.vtype === 'fclos') { - if (value.fdef) return value.fdef - } else if (value.vtype === 'union') { - return value - } else if (Array.isArray(value)) { - const res: any[] = [] - value.forEach(function (el: any) { - res.push(valueToAST(el)) - }) - return { type: 'ArrayExpression', elements: res } - } - - if (!value.type) return value - switch (value.type) { - case 'Literal': - case 'Identifier': - case 'ThisExpression': - case 'FunctionDeclaration': - return value - case 'MemberAccess': { - return { - type: 'MemberAccess', - expression: valueToAST(value.expression), - property: valueToAST(value.property), - } - } - case 'ArrayExpression': { - const elements: any[] = [] - value.elements.forEach(function (el: any) { - elements.push(valueToAST(el)) - }) - return { type: 'ArrayExpression', elements } - } - case 'ObjectExpression': { - var props: any[] = [] - value.properties.forEach(function (property: any) { - const name = property.key.type == 'Literal' ? property.key.value : property.key.name - const prop = { type: 'Property', key: property.key, value: valueToAST(property.value) } - props.push(prop) - }) - return { type: 'ObjectExpression', properties: props } - } - case 'UnaryOperation': - return { - type: value.type, - operator: value.operator, - prefix: value.prefix, - argument: valueToAST(value.argument), - } - case 'BinaryOperation': - case 'AssignmentExpression': - return { - type: value.type, - operator: value.operator, - left: valueToAST(value.left), - right: valueToAST(value.right), - } - case 'Conditional': - return { - type: value.type, - test: valueToAST(value.test), - alternate: valueToAST(value.alternate), - consequent: valueToAST(value.consequent), - } - case 'NewExpression': - case 'CallExpression': { - const args: any[] = [] - value.arguments.forEach(function (el: any) { - args.push(valueToAST(el)) - }) - return { type: value.type, callee: valueToAST(value.callee), arguments: args } - } - default: - if (logger.isTraceEnabled()) logger.trace(`warning: valueToAST: unkown exp ${formatNode(value)}`) - } - return value -} - -/** - * - * @param value - */ -function formatValue(value: any): any { - if (typeof value !== 'object') return value - - let str: any - try { - str = valueToAST(value) - // logger.info('ASTstr: ' + formatScope(str)); - // logger.info('ASTstr: ' + JSON.stringify(str)); - if (str.type == 'Literal') return str.value - str = escodegenValueFormatter.generate(str) - } catch (e) { - str = formatScope2(value) - } - return str -} - -/** - * - * @param scope - */ -function printScope(scope: any): void { - if (scope.id) logger.info(`----------------------${scope.id}---------------------------`) - const { value } = scope - if (scope.ast) logger.info(`-- ast: ${scope.ast}${scope.taint ? ' (tainted)' : ''}`) - logger.info('-- value: ') - logger.info(formatScope(value, 2)) -} - -/** - * - * @param scopes - */ -function printVarScopes(scopes: any): void { - logger.info('*************************** VAR SCOPES ***************************') - if (scopes && Array.isArray(scopes)) { - scopes.forEach(printScope) - } - logger.info('*************************** VAR SCOPES END ***********************') -} - -//* ***************************** value format conversion ****************************** - -/** - * convert engine internal data into javascript format - * @param val - * @returns {*} - */ -function engineValueToJSValue(val: any): any { - if (typeof val !== 'object') return val - if (Array.isArray(val)) { - return val.map(engineValueToJSValue) - } - switch (val.type) { - case 'Literal': - return val.value - } - switch (val.vtype) { - case 'object': { - const res: Record = {} - for (const v in val.value) { - res[v] = engineValueToJSValue(val.value[v]) - } - return res - } - case 'fclos': { - return val.fdef - } - case 'union': { - return { - vtype: 'union', - value: engineValueToJSValue(val), - } - } - } - return val -} - -//* ***************************** exports ******************************************** - -export { - deepMatch, - setFieldValue as setField, - setFieldValueIfExists as setFieldIfExists, - getFieldValue as getField, - getFieldValueInScopeChain as getFieldInScopeChain, - resolveForkedValue as resolveValue, - printScope, - printVarScopes, - JSON_scope_replacer, - formatScope, - formatScope2, - formatNode, - formatValue, - valueToAST, - engineValueToJSValue, -} diff --git a/src/util/variable-util.ts b/src/util/variable-util.ts index 43a41ec2..755c301f 100644 --- a/src/util/variable-util.ts +++ b/src/util/variable-util.ts @@ -1,3 +1,5 @@ +import { handleException } from '../engine/analyzer/common/exception-handler' + /** * * variable @@ -16,4 +18,38 @@ function isNotEmpty(variable: unknown): boolean { return typeof variable !== 'undefined' } -export { isEmpty, isNotEmpty } +/** + * + * @param value + */ +function primitiveToString(value: any): string { + // 判断是否是数组 + if (Array.isArray(value)) { + // 对每个元素调用 primitiveToString,然后用 _ 连接 + return value.map((item) => primitiveToString(item)).join('_') + } + + // 判断是否是基本类型(primitive) + if (value === null) { + return 'null' + } + + const type = typeof value + + switch (type) { + case 'string': + return value // 已经是字符串 + case 'number': + case 'boolean': + case 'bigint': + case 'symbol': + return `` // 转换为字符串 + case 'undefined': + return 'undefined' + default: + handleException(null, '', 'Error:primitiveToString, but not a primitive type') + // 对象类型,可以选择抛出错误或特殊处理 + return '' + } +} +export { isEmpty, isNotEmpty, primitiveToString } diff --git a/test/callargs/test-callargs.ts b/test/callargs/test-callargs.ts new file mode 100644 index 00000000..2594ceee --- /dev/null +++ b/test/callargs/test-callargs.ts @@ -0,0 +1,482 @@ +/** + * callargs 体系单元测试 + * + * callArgs 将函数调用参数结构化为 CallArg(含 kind/name/value),支持 positional / keyword / + * spread / kwspread 四种参数类型,替代旧的位置数组 argvalues。数据流分三层: + * + * 调用侧构建 形参绑定 checker 消费 + * buildCallArgs ──→ bindCallArgs ──→ prepareArgs(normalizeSelectors) + * ↓ ↓ ↓ + * CallArgs BoundCall 筛选出的 value[] + * + * 测试围绕这三层设计: + * 1. call-args.ts 工具函数 — CallInfo 字段提取与向后兼容 + * 2. Analyzer 方法 — buildCallArgs 构建 + bindCallArgs 绑定(positional/keyword/vararg/varkw/receiver) + * 3. prepareArgs — 按 selector(position/keyword/all)从 CallArgs 中筛选参数,供 checker 使用 + * + * fixture 设计:一个 callInfo 同时包含 positional + keyword + receiver + boundCall, + * 各用例通过不同 rule 组合验证筛选行为。 + */ +import { describe, it } from 'mocha' +import * as assert from 'assert' +import { + getLegacyArgValues, + getExplicitArgCount, + getCallArgsFromInfo, + getBoundCallFromInfo, + type CallInfo, + type CallArgs, + type BoundCall, +} from '../../src/engine/analyzer/common/call-args' + +const Analyzer = require('../../src/engine/analyzer/common/analyzer') +const { prepareArgs } = require('../../src/checker/common/rules-basic-handler') +const { matchSinkAtFuncCall } = require('../../src/checker/taint/common-kit/sink-util') + +// ========================= 测试 fixture ========================= + +/** 模拟 f(val_0, data=val_1, val_2, key=val_3) 的调用参数 */ +function makeCallArgs(): CallArgs { + return { + receiver: { sid: 'self_obj' }, + args: [ + { index: 0, value: 'val_0', kind: 'positional' }, + { index: 1, value: 'val_1', name: 'data', kind: 'keyword' }, + { index: 2, value: 'val_2', kind: 'positional' }, + { index: 3, value: 'val_3', name: 'key', kind: 'keyword' }, + ], + } +} + +/** 模拟 def f(a, data, b, **kwargs) 绑定后的 boundCall */ +function makeBoundCall(): BoundCall { + return { + receiver: { sid: 'self_obj' }, + params: [ + { index: 0, name: 'a', value: 'val_0', provided: true, argIndexes: [0] }, + { index: 1, name: 'data', value: 'val_1', provided: true, argIndexes: [1] }, + { index: 2, name: 'b', value: 'val_2', provided: true, argIndexes: [2] }, + { index: 3, name: 'kwargs', value: { key: 'val_3' }, provided: true, argIndexes: [3] }, + ], + } +} + +function makeCallInfo(): CallInfo { + return { callArgs: makeCallArgs(), boundCall: makeBoundCall() } +} + +/** 含 spread 的 callArgs:f(val_0, *[val_s1, val_s2], key=val_k) */ +function makeCallArgsWithSpread(): CallArgs { + return { + args: [ + { index: 0, value: 'val_0', kind: 'positional' }, + { index: 1, value: ['val_s1', 'val_s2'], kind: 'spread' }, + { index: 2, value: 'val_k', name: 'key', kind: 'keyword' }, + ], + } +} + +// ========================= 第 1 层:call-args.ts 工具函数 ========================= +// CallInfo 的字段提取与向后兼容(getLegacyArgValues / getExplicitArgCount 等) + +describe('call-args 工具函数', function () { + describe('getLegacyArgValues', function () { + it('callInfo undefined → 空数组', function () { + assert.deepStrictEqual(getLegacyArgValues(undefined), []) + }) + + it('callInfo.callArgs undefined → 空数组', function () { + assert.deepStrictEqual(getLegacyArgValues({} as CallInfo), []) + }) + + it('正常 callArgs → 提取 value 数组', function () { + const info = makeCallInfo() + assert.deepStrictEqual(getLegacyArgValues(info), ['val_0', 'val_1', 'val_2', 'val_3']) + }) + + it('传入数组(旧路径已移除) → 空数组', function () { + const arr = ['a', 'b'] + assert.deepStrictEqual(getLegacyArgValues(arr as any), []) + }) + }) + + describe('getExplicitArgCount', function () { + it('undefined → 0', function () { + assert.strictEqual(getExplicitArgCount(undefined), 0) + }) + + it('4 个 positional+keyword → 4', function () { + assert.strictEqual(getExplicitArgCount(makeCallInfo()), 4) + }) + + it('含 spread → 排除 spread/kwspread', function () { + const info: CallInfo = { callArgs: makeCallArgsWithSpread() } + // 3 个 args 中 1 个 spread → 排除 → 2 + assert.strictEqual(getExplicitArgCount(info), 2) + }) + }) + + describe('getCallArgsFromInfo / getBoundCallFromInfo', function () { + it('undefined → undefined', function () { + assert.strictEqual(getCallArgsFromInfo(undefined), undefined) + assert.strictEqual(getBoundCallFromInfo(undefined), undefined) + }) + + it('正常 → 返回对应字段', function () { + const info = makeCallInfo() + assert.strictEqual(getCallArgsFromInfo(info), info.callArgs) + assert.strictEqual(getBoundCallFromInfo(info), info.boundCall) + }) + }) +}) + +// ========================= 第 2 层:Analyzer 构建与绑定 ========================= +// buildCallArgs: node + argvalues → CallArgs(标记 kind/name) +// bindCallArgs: CallArgs + fdecl.parameters → BoundCall(形参绑定) +// getParamKind: 判定形参类型(vararg/varkw/keyword_only 等),决定绑定策略 +// resolveSpreadValues / resolveKwSpreadEntries: 展开 *args/**kwargs 值 + +describe('Analyzer callargs 方法', function () { + let analyzer: any + + before(function () { + analyzer = new Analyzer(null) + }) + + describe('buildCallArgs', function () { + it('positional 参数 → kind=positional', function () { + const node = { arguments: [{ type: 'Literal' }] } + const result = analyzer.buildCallArgs(node, ['v1'], {}) + assert.strictEqual(result.args.length, 1) + assert.strictEqual(result.args[0].kind, 'positional') + assert.strictEqual(result.args[0].value, 'v1') + assert.strictEqual(result.args[0].index, 0) + }) + + it('keyword 参数(node.names) → kind=keyword + name', function () { + const node = { arguments: [{ type: 'Literal' }, { type: 'Literal' }], names: [undefined, 'data'] } + const result = analyzer.buildCallArgs(node, ['v1', 'v2'], {}) + assert.strictEqual(result.args[0].kind, 'positional') + assert.strictEqual(result.args[1].kind, 'keyword') + assert.strictEqual(result.args[1].name, 'data') + }) + + it('MemberAccess → receiver 绑定', function () { + const node = { callee: { type: 'MemberAccess' }, arguments: [] } + const fclos = { _this: { sid: 'obj' } } + const result = analyzer.buildCallArgs(node, [], fclos) + assert.deepStrictEqual(result.receiver, { sid: 'obj' }) + }) + + it('非 MemberAccess → receiver undefined', function () { + const node = { callee: { type: 'Identifier' }, arguments: [] } + const result = analyzer.buildCallArgs(node, [], {}) + assert.strictEqual(result.receiver, undefined) + }) + }) + + describe('getParamKind', function () { + it('普通参数 → positional_or_keyword', function () { + assert.strictEqual(analyzer.getParamKind({ id: { name: 'x' } }), 'positional_or_keyword') + }) + + it('_meta.varkw → varkw', function () { + assert.strictEqual(analyzer.getParamKind({ _meta: { varkw: true } }), 'varkw') + }) + + it('_meta.isRestElement → vararg', function () { + assert.strictEqual(analyzer.getParamKind({ _meta: { isRestElement: true } }), 'vararg') + }) + + it('_meta.keyword_only → keyword_only', function () { + assert.strictEqual(analyzer.getParamKind({ _meta: { keyword_only: true } }), 'keyword_only') + }) + + it('_meta.positional_only → positional_only', function () { + assert.strictEqual(analyzer.getParamKind({ _meta: { positional_only: true } }), 'positional_only') + }) + + it('_meta.parameterKind 优先', function () { + assert.strictEqual(analyzer.getParamKind({ _meta: { parameterKind: 'vararg', varkw: true } }), 'vararg') + }) + + it('Java varargs via varType._meta.varargs → vararg', function () { + assert.strictEqual( + analyzer.getParamKind({ id: { name: 'params' }, varType: { _meta: { varargs: true } } }), + 'vararg' + ) + }) + }) + + describe('bindCallArgs', function () { + it('positional 参数按顺序绑定', function () { + const node = {} + const fclos = {} + const fdecl = { parameters: [{ id: { name: 'a' } }, { id: { name: 'b' } }] } + const callInfo: CallInfo = { + callArgs: { args: [ + { index: 0, value: 'v1', kind: 'positional' }, + { index: 1, value: 'v2', kind: 'positional' }, + ] }, + } + const bound = analyzer.bindCallArgs(node, fclos, fdecl, callInfo) + assert.strictEqual(bound.params[0].value, 'v1') + assert.strictEqual(bound.params[0].provided, true) + assert.strictEqual(bound.params[1].value, 'v2') + }) + + it('keyword 参数按名绑定', function () { + const fdecl = { parameters: [{ id: { name: 'a' } }, { id: { name: 'data' } }] } + const callInfo: CallInfo = { + callArgs: { args: [ + { index: 0, value: 'v_data', name: 'data', kind: 'keyword' }, + ] }, + } + const bound = analyzer.bindCallArgs({}, {}, fdecl, callInfo) + assert.strictEqual(bound.params[0].provided, false) // a 未提供 + assert.strictEqual(bound.params[1].value, 'v_data') // data 按名绑定 + assert.strictEqual(bound.params[1].provided, true) + }) + + it('vararg 参数收集为数组', function () { + const fdecl = { parameters: [ + { id: { name: 'a' } }, + { id: { name: 'args' }, _meta: { isRestElement: true } }, + ] } + const callInfo: CallInfo = { + callArgs: { args: [ + { index: 0, value: 'v1', kind: 'positional' }, + { index: 1, value: 'v2', kind: 'positional' }, + { index: 2, value: 'v3', kind: 'positional' }, + ] }, + } + const bound = analyzer.bindCallArgs({}, {}, fdecl, callInfo) + assert.strictEqual(bound.params[0].value, 'v1') + assert.deepStrictEqual(bound.params[1].value, ['v2', 'v3']) + }) + + it('varkw 参数收集 keyword 为对象', function () { + const fdecl = { parameters: [ + { id: { name: 'a' } }, + { id: { name: 'kwargs' }, _meta: { varkw: true } }, + ] } + const callInfo: CallInfo = { + callArgs: { args: [ + { index: 0, value: 'v1', kind: 'positional' }, + { index: 1, value: 'v_data', name: 'data', kind: 'keyword' }, + { index: 2, value: 'v_key', name: 'key', kind: 'keyword' }, + ] }, + } + const bound = analyzer.bindCallArgs({}, {}, fdecl, callInfo) + assert.strictEqual(bound.params[0].value, 'v1') + assert.strictEqual(bound.params[1].provided, true) + assert.strictEqual(bound.params[1].value.data, 'v_data') + assert.strictEqual(bound.params[1].value.key, 'v_key') + }) + + it('receiver 绑定到 self 参数', function () { + const fdecl = { parameters: [{ id: { name: 'self' } }, { id: { name: 'x' } }] } + const callInfo: CallInfo = { + callArgs: { + receiver: { sid: 'self_obj' }, + args: [{ index: 0, value: 'v1', kind: 'positional' }], + }, + } + const bound = analyzer.bindCallArgs({}, {}, fdecl, callInfo) + assert.deepStrictEqual(bound.params[0].value, { sid: 'self_obj' }) + assert.strictEqual(bound.params[1].value, 'v1') // positional 从 index 1 开始 + }) + + it('fdecl.parameters 为空 → 空 boundCall', function () { + const bound = analyzer.bindCallArgs({}, {}, {}, { callArgs: { args: [] } }) + assert.strictEqual(bound.params.length, 0) + }) + }) + + describe('resolveSpreadValues', function () { + it('数组 → 原样', function () { + assert.deepStrictEqual(analyzer.resolveSpreadValues([1, 2]), [1, 2]) + }) + + it('_field 为数组 → 返回 _field', function () { + assert.deepStrictEqual(analyzer.resolveSpreadValues({ _field: [1, 2] }), [1, 2]) + }) + + it('_field 为对象(数字键) → 按数字键排序', function () { + assert.deepStrictEqual(analyzer.resolveSpreadValues({ _field: { '0': 'a', '1': 'b' } }), ['a', 'b']) + }) + + it('其他 → 包装为单元素数组', function () { + assert.deepStrictEqual(analyzer.resolveSpreadValues('x'), ['x']) + }) + }) + + describe('resolveKwSpreadEntries', function () { + it('undefined → 空数组', function () { + assert.deepStrictEqual(analyzer.resolveKwSpreadEntries(undefined), []) + }) + + it('对象 → [key, value] 对', function () { + const entries = analyzer.resolveKwSpreadEntries({ a: 1, b: 2 }) + assert.deepStrictEqual(entries, [['a', 1], ['b', 2]]) + }) + + it('_field 对象 → 展开 _field', function () { + const entries = analyzer.resolveKwSpreadEntries({ _field: { x: 10, y: 20 } }) + assert.deepStrictEqual(entries, [['x', 10], ['y', 20]]) + }) + }) +}) + +// ========================= 第 3 层:checker 消费端 ========================= +// normalizeSelectors: 统一 rule 中的 selectors/args/positions/keywordNames/includeReceiver 为标准格式 +// prepareArgs: 按 selector 从 callArgs.args 筛选参数值,供 sink/source/sanitizer checker 使用 +// 支持 position(按索引)/ keyword(按参数名)/ all(全部)三种筛选模式 + paramNames 兼容路径 + +describe('prepareArgs(含 normalizeSelectors 间接覆盖)', function () { + const callInfo = makeCallInfo() + const fclos = { getThisObj: () => ({ sid: 'this_obj' }) } + + it('keyword selector → 按参数名筛选', function () { + const rule = { selectors: [{ type: 'keyword', name: 'data' }] } + assert.deepStrictEqual(prepareArgs(callInfo, fclos, rule), ['val_1']) + }) + + it('keyword selector 多个 → 各自匹配', function () { + const rule = { selectors: [{ type: 'keyword', name: 'data' }, { type: 'keyword', name: 'key' }] } + assert.deepStrictEqual(prepareArgs(callInfo, fclos, rule), ['val_1', 'val_3']) + }) + + it('keyword selector 不存在的名字 → 空', function () { + const rule = { selectors: [{ type: 'keyword', name: 'nonexist' }] } + assert.deepStrictEqual(prepareArgs(callInfo, fclos, rule), []) + }) + + it('position selector → 按索引筛选', function () { + const rule = { selectors: [{ type: 'position', index: 0 }] } + assert.deepStrictEqual(prepareArgs(callInfo, fclos, rule), ['val_0']) + }) + + it('position selector 多个 → 各自匹配', function () { + const rule = { selectors: [{ type: 'position', index: 0 }, { type: 'position', index: 2 }] } + assert.deepStrictEqual(prepareArgs(callInfo, fclos, rule), ['val_0', 'val_2']) + }) + + it('all selector (index=*) → 全部参数', function () { + const rule = { selectors: [{ type: 'position', index: '*' }] } + assert.deepStrictEqual(prepareArgs(callInfo, fclos, rule), ['val_0', 'val_1', 'val_2', 'val_3']) + }) + + it('receiver (includeReceiver) → callArgs.receiver', function () { + const rule = { includeReceiver: true } + const result = prepareArgs(callInfo, fclos, rule) + assert.deepStrictEqual(result, [{ sid: 'self_obj' }]) + }) + + it('旧格式 args 数字索引 → 按位置筛选', function () { + const rule = { args: ['0', '2'] } + assert.deepStrictEqual(prepareArgs(callInfo, fclos, rule), ['val_0', 'val_2']) + }) + + it('旧格式 args 通配 → 全部', function () { + const rule = { args: ['*'] } + assert.deepStrictEqual(prepareArgs(callInfo, fclos, rule), ['val_0', 'val_1', 'val_2', 'val_3']) + }) + + it('keywordNames → 按 keyword 追加', function () { + const rule = { keywordNames: ['key'] } + assert.deepStrictEqual(prepareArgs(callInfo, fclos, rule), ['val_3']) + }) + + it('paramNames 兼容路径 → 通过 boundCall 形参名匹配', function () { + const rule = { paramNames: ['data'] } + assert.deepStrictEqual(prepareArgs(callInfo, fclos, rule), ['val_1']) + }) + + it('paramNames self → 返回 receiver', function () { + const rule = { paramNames: ['self'] } + const result = prepareArgs(callInfo, fclos, rule) + assert.deepStrictEqual(result, [{ sid: 'self_obj' }]) + }) + + it('callInfo undefined → 空数组', function () { + assert.deepStrictEqual(prepareArgs(undefined, fclos, { args: ['*'] }), []) + }) + + it('空 rule → 空数组', function () { + assert.deepStrictEqual(prepareArgs(callInfo, fclos, {}), []) + }) + + it('混合 selectors + keywordNames → 合并去重', function () { + const rule = { + selectors: [{ type: 'keyword', name: 'data' }], + keywordNames: ['data', 'key'], + } + const result = prepareArgs(callInfo, fclos, rule) + // data 被 selectors 和 keywordNames 都选中,但去重 + assert.deepStrictEqual(result, ['val_1', 'val_3']) + }) + + it('receiver 回退到 fclos.getThisObj', function () { + const noReceiverInfo: CallInfo = { callArgs: { args: [] } } + const rule = { includeReceiver: true } + const result = prepareArgs(noReceiverInfo, fclos, rule) + assert.deepStrictEqual(result, [{ sid: 'this_obj' }]) + }) + + it('旧格式数组(legacy)→ 空数组(不再支持)', function () { + const legacyArray = [{ sid: 'v1' }, { sid: 'v2' }] + assert.deepStrictEqual(prepareArgs(legacyArray, fclos, { args: ['*'] }), []) + assert.deepStrictEqual(prepareArgs(legacyArray, fclos, { args: [0] }), []) + }) + + it('position selector 结果不受 boundCall 有无影响', function () { + const withBound = makeCallInfo() + const withoutBound: CallInfo = { callArgs: makeCallArgs() } + const rule = { selectors: [{ type: 'position', index: 0 }] } + assert.deepStrictEqual(prepareArgs(withBound, fclos, rule), ['val_0']) + assert.deepStrictEqual(prepareArgs(withoutBound, fclos, rule), ['val_0']) + }) +}) + +// ========================= 第 4 层:sink 匹配 ========================= +// matchSinkAtFuncCall: 按 fsig + argNum 匹配 sink 规则 + +describe('matchSinkAtFuncCall', function () { + it('argNum 按显式参数数量匹配(不含 boundCall slots)', function () { + const callInfo: CallInfo = { + callArgs: { + receiver: { sid: 'receiver' }, + args: [{ index: 0, value: true, name: 'core_mode', kind: 'keyword' as const }], + }, + boundCall: { + params: [ + { index: 0, name: 'self', value: { sid: 'receiver' }, provided: true, argIndexes: [] }, + { index: 1, name: 'config_path', provided: false, argIndexes: [] }, + { index: 2, name: 'core_mode', value: true, provided: true, argIndexes: [0] }, + ], + }, + } + // 显式参数 1 个(不含 spread/kwspread),argNum=1 应匹配 + const matched = matchSinkAtFuncCall( + { callee: { type: 'Identifier', name: 'start' } }, + { sid: 'start' }, + [{ fsig: 'start', argNum: 1 }], + callInfo + ) + assert.strictEqual(matched.length, 1) + }) + + it('argNum 不匹配时跳过', function () { + const callInfo: CallInfo = { + callArgs: { args: [{ index: 0, value: 'v1', kind: 'positional' as const }] }, + } + const matched = matchSinkAtFuncCall( + { callee: { type: 'Identifier', name: 'fn' } }, + { sid: 'fn' }, + [{ fsig: 'fn', argNum: 3 }], + callInfo + ) + assert.strictEqual(matched.length, 0) + }) +}) diff --git a/test/callchain/expect/callchain-go-expect.json b/test/callchain/expect/callchain-go-expect.json new file mode 100644 index 00000000..d1a7c472 --- /dev/null +++ b/test/callchain/expect/callchain-go-expect.json @@ -0,0 +1,591 @@ +{ + "version": "1.0", + "totalFindings": 9, + "findings": [ + { + "entrypoint": { + "type": "functionCall", + "functionName": "main", + "filePath": "/test_callchain.go", + "attribute": "HTTP", + "isPreProcess": false + }, + "sinkInfo": { + "sinkRule": "Query", + "sinkAttribute": "GoSQLInjection", + "callSite": { + "code": "\tdb.Query(query)", + "file": "/test_callchain.go", + "line": 16, + "column": 2 + } + }, + "callstack": [ + { + "type": 0, + "nodeHash": "c10072d6b34256e184c793600265c86f", + "fullName": "__unknown_module__.main", + "function": "main", + "file": "/test_callchain.go", + "line": 31, + "column": 1 + }, + { + "type": 0, + "nodeHash": "a7a3febd7ecda24769b4056b47e02d69", + "fullName": "__unknown_module__.TestSqlInjection", + "function": "TestSqlInjection", + "file": "/test_callchain.go", + "line": 10, + "column": 1 + }, + { + "type": 1, + "nodeHash": "75c72e930bc84cb3810f1655c45924b2", + "fullName": "database/sql.Open(\"mysql\", \"user:password@/dbname\").Query", + "function": "Query", + "file": "/test_callchain.go", + "line": 16, + "column": 2 + } + ], + "callsites": [ + { + "code": "func main() {\n\tTestSqlInjection(\"admin\")\n\tTestCommandInjection(\"ls -la\")\n}", + "nodeHash": "c10072d6b34256e184c793600265c86f", + "file": "/test_callchain.go", + "line": 31, + "column": 1 + }, + { + "code": "\tTestSqlInjection(\"admin\")", + "nodeHash": "efe72c79a72096166c0de4cee8548a75", + "file": "/test_callchain.go", + "line": 32, + "column": 2 + }, + { + "code": "\tdb.Query(query)", + "nodeHash": "75c72e930bc84cb3810f1655c45924b2", + "file": "/test_callchain.go", + "line": 16, + "column": 2 + } + ] + }, + { + "entrypoint": { + "type": "functionCall", + "functionName": "main", + "filePath": "/test_callchain.go", + "attribute": "HTTP", + "isPreProcess": false + }, + "sinkInfo": { + "sinkRule": "Exec", + "sinkAttribute": "GoSQLInjection", + "callSite": { + "code": "\tdb.Exec(query)", + "file": "/test_callchain.go", + "line": 17, + "column": 2 + } + }, + "callstack": [ + { + "type": 0, + "nodeHash": "c10072d6b34256e184c793600265c86f", + "fullName": "__unknown_module__.main", + "function": "main", + "file": "/test_callchain.go", + "line": 31, + "column": 1 + }, + { + "type": 0, + "nodeHash": "a7a3febd7ecda24769b4056b47e02d69", + "fullName": "__unknown_module__.TestSqlInjection", + "function": "TestSqlInjection", + "file": "/test_callchain.go", + "line": 10, + "column": 1 + }, + { + "type": 1, + "nodeHash": "81e78d839150dd301eee354b73974a2a", + "fullName": "database/sql.Open(\"mysql\", \"user:password@/dbname\").Exec", + "function": "Exec", + "file": "/test_callchain.go", + "line": 17, + "column": 2 + } + ], + "callsites": [ + { + "code": "func main() {\n\tTestSqlInjection(\"admin\")\n\tTestCommandInjection(\"ls -la\")\n}", + "nodeHash": "c10072d6b34256e184c793600265c86f", + "file": "/test_callchain.go", + "line": 31, + "column": 1 + }, + { + "code": "\tTestSqlInjection(\"admin\")", + "nodeHash": "efe72c79a72096166c0de4cee8548a75", + "file": "/test_callchain.go", + "line": 32, + "column": 2 + }, + { + "code": "\tdb.Exec(query)", + "nodeHash": "81e78d839150dd301eee354b73974a2a", + "file": "/test_callchain.go", + "line": 17, + "column": 2 + } + ] + }, + { + "entrypoint": { + "type": "functionCall", + "functionName": "main", + "filePath": "/test_callchain.go", + "attribute": "HTTP", + "isPreProcess": false + }, + "sinkInfo": { + "sinkRule": "exec.Command", + "sinkAttribute": "GoCommandInjection", + "callSite": { + "code": "\tcmd := exec.Command(\"sh\", \"-c\", command)", + "file": "/test_callchain.go", + "line": 23, + "column": 9 + } + }, + "callstack": [ + { + "type": 0, + "nodeHash": "c10072d6b34256e184c793600265c86f", + "fullName": "__unknown_module__.main", + "function": "main", + "file": "/test_callchain.go", + "line": 31, + "column": 1 + }, + { + "type": 0, + "nodeHash": "cc0d33162f6ed0524bd8e5c93c55df67", + "fullName": "__unknown_module__.TestCommandInjection", + "function": "TestCommandInjection", + "file": "/test_callchain.go", + "line": 21, + "column": 1 + }, + { + "type": 1, + "nodeHash": "cc56e8815b5be039850a931768bffb2e", + "fullName": "os/exec.Command", + "function": "Command", + "file": "/test_callchain.go", + "line": 23, + "column": 9 + } + ], + "callsites": [ + { + "code": "func main() {\n\tTestSqlInjection(\"admin\")\n\tTestCommandInjection(\"ls -la\")\n}", + "nodeHash": "c10072d6b34256e184c793600265c86f", + "file": "/test_callchain.go", + "line": 31, + "column": 1 + }, + { + "code": "\tTestCommandInjection(\"ls -la\")", + "nodeHash": "867fdc99e03efd4a9f03e7c151222691", + "file": "/test_callchain.go", + "line": 33, + "column": 2 + }, + { + "code": "\tcmd := exec.Command(\"sh\", \"-c\", command)", + "nodeHash": "cc56e8815b5be039850a931768bffb2e", + "file": "/test_callchain.go", + "line": 23, + "column": 9 + } + ] + }, + { + "entrypoint": { + "type": "functionCall", + "functionName": "main", + "filePath": "/test_callchain.go", + "attribute": "fullCallGraphMade", + "funcReceiverType": "" + }, + "sinkInfo": { + "sinkRule": "Query", + "sinkAttribute": "GoSQLInjection", + "callSite": { + "code": "\tdb.Query(query)", + "file": "/test_callchain.go", + "line": 16, + "column": 2 + } + }, + "callstack": [ + { + "type": 0, + "nodeHash": "c10072d6b34256e184c793600265c86f", + "fullName": "__unknown_module__.main", + "function": "main", + "file": "/test_callchain.go", + "line": 31, + "column": 1 + }, + { + "type": 0, + "nodeHash": "a7a3febd7ecda24769b4056b47e02d69", + "fullName": "__unknown_module__.TestSqlInjection", + "function": "TestSqlInjection", + "file": "/test_callchain.go", + "line": 10, + "column": 1 + }, + { + "type": 1, + "nodeHash": "75c72e930bc84cb3810f1655c45924b2", + "fullName": "database/sql.Open(\"mysql\", \"user:password@/dbname\").Query", + "function": "Query", + "file": "/test_callchain.go", + "line": 16, + "column": 2 + } + ], + "callsites": [ + { + "code": "func main() {\n\tTestSqlInjection(\"admin\")\n\tTestCommandInjection(\"ls -la\")\n}", + "nodeHash": "c10072d6b34256e184c793600265c86f", + "file": "/test_callchain.go", + "line": 31, + "column": 1 + }, + { + "code": "\tTestSqlInjection(\"admin\")", + "nodeHash": "efe72c79a72096166c0de4cee8548a75", + "file": "/test_callchain.go", + "line": 32, + "column": 2 + }, + { + "code": "\tdb.Query(query)", + "nodeHash": "75c72e930bc84cb3810f1655c45924b2", + "file": "/test_callchain.go", + "line": 16, + "column": 2 + } + ] + }, + { + "entrypoint": { + "type": "functionCall", + "functionName": "main", + "filePath": "/test_callchain.go", + "attribute": "fullCallGraphMade", + "funcReceiverType": "" + }, + "sinkInfo": { + "sinkRule": "Exec", + "sinkAttribute": "GoSQLInjection", + "callSite": { + "code": "\tdb.Exec(query)", + "file": "/test_callchain.go", + "line": 17, + "column": 2 + } + }, + "callstack": [ + { + "type": 0, + "nodeHash": "c10072d6b34256e184c793600265c86f", + "fullName": "__unknown_module__.main", + "function": "main", + "file": "/test_callchain.go", + "line": 31, + "column": 1 + }, + { + "type": 0, + "nodeHash": "a7a3febd7ecda24769b4056b47e02d69", + "fullName": "__unknown_module__.TestSqlInjection", + "function": "TestSqlInjection", + "file": "/test_callchain.go", + "line": 10, + "column": 1 + }, + { + "type": 1, + "nodeHash": "81e78d839150dd301eee354b73974a2a", + "fullName": "database/sql.Open(\"mysql\", \"user:password@/dbname\").Exec", + "function": "Exec", + "file": "/test_callchain.go", + "line": 17, + "column": 2 + } + ], + "callsites": [ + { + "code": "func main() {\n\tTestSqlInjection(\"admin\")\n\tTestCommandInjection(\"ls -la\")\n}", + "nodeHash": "c10072d6b34256e184c793600265c86f", + "file": "/test_callchain.go", + "line": 31, + "column": 1 + }, + { + "code": "\tTestSqlInjection(\"admin\")", + "nodeHash": "efe72c79a72096166c0de4cee8548a75", + "file": "/test_callchain.go", + "line": 32, + "column": 2 + }, + { + "code": "\tdb.Exec(query)", + "nodeHash": "81e78d839150dd301eee354b73974a2a", + "file": "/test_callchain.go", + "line": 17, + "column": 2 + } + ] + }, + { + "entrypoint": { + "type": "functionCall", + "functionName": "main", + "filePath": "/test_callchain.go", + "attribute": "fullCallGraphMade", + "funcReceiverType": "" + }, + "sinkInfo": { + "sinkRule": "exec.Command", + "sinkAttribute": "GoCommandInjection", + "callSite": { + "code": "\tcmd := exec.Command(\"sh\", \"-c\", command)", + "file": "/test_callchain.go", + "line": 23, + "column": 9 + } + }, + "callstack": [ + { + "type": 0, + "nodeHash": "c10072d6b34256e184c793600265c86f", + "fullName": "__unknown_module__.main", + "function": "main", + "file": "/test_callchain.go", + "line": 31, + "column": 1 + }, + { + "type": 0, + "nodeHash": "cc0d33162f6ed0524bd8e5c93c55df67", + "fullName": "__unknown_module__.TestCommandInjection", + "function": "TestCommandInjection", + "file": "/test_callchain.go", + "line": 21, + "column": 1 + }, + { + "type": 1, + "nodeHash": "cc56e8815b5be039850a931768bffb2e", + "fullName": "os/exec.Command", + "function": "Command", + "file": "/test_callchain.go", + "line": 23, + "column": 9 + } + ], + "callsites": [ + { + "code": "func main() {\n\tTestSqlInjection(\"admin\")\n\tTestCommandInjection(\"ls -la\")\n}", + "nodeHash": "c10072d6b34256e184c793600265c86f", + "file": "/test_callchain.go", + "line": 31, + "column": 1 + }, + { + "code": "\tTestCommandInjection(\"ls -la\")", + "nodeHash": "867fdc99e03efd4a9f03e7c151222691", + "file": "/test_callchain.go", + "line": 33, + "column": 2 + }, + { + "code": "\tcmd := exec.Command(\"sh\", \"-c\", command)", + "nodeHash": "cc56e8815b5be039850a931768bffb2e", + "file": "/test_callchain.go", + "line": 23, + "column": 9 + } + ] + }, + { + "entrypoint": { + "type": "functionCall", + "functionName": "TestSqlInjection", + "filePath": "test_callchain.go" + }, + "sinkInfo": { + "sinkRule": "Query", + "sinkAttribute": "GoSQLInjection", + "callSite": { + "code": "\tdb.Query(query)", + "file": "/test_callchain.go", + "line": 16, + "column": 2 + } + }, + "callstack": [ + { + "type": 0, + "nodeHash": "a7a3febd7ecda24769b4056b47e02d69", + "fullName": "__unknown_module__.TestSqlInjection", + "function": "TestSqlInjection", + "file": "/test_callchain.go", + "line": 10, + "column": 1 + }, + { + "type": 1, + "nodeHash": "75c72e930bc84cb3810f1655c45924b2", + "fullName": "database/sql.Open(\"mysql\", \"user:password@/dbname\").Query", + "function": "Query", + "file": "/test_callchain.go", + "line": 16, + "column": 2 + } + ], + "callsites": [ + { + "code": "func TestSqlInjection(userInput string) {\n\tdb, _ := sql.Open(\"mysql\", \"user:password@/dbname\")\n\tdefe", + "nodeHash": "a7a3febd7ecda24769b4056b47e02d69", + "file": "/test_callchain.go", + "line": 10, + "column": 1 + }, + { + "code": "\tdb.Query(query)", + "nodeHash": "75c72e930bc84cb3810f1655c45924b2", + "file": "/test_callchain.go", + "line": 16, + "column": 2 + } + ] + }, + { + "entrypoint": { + "type": "functionCall", + "functionName": "TestSqlInjection", + "filePath": "test_callchain.go" + }, + "sinkInfo": { + "sinkRule": "Exec", + "sinkAttribute": "GoSQLInjection", + "callSite": { + "code": "\tdb.Exec(query)", + "file": "/test_callchain.go", + "line": 17, + "column": 2 + } + }, + "callstack": [ + { + "type": 0, + "nodeHash": "a7a3febd7ecda24769b4056b47e02d69", + "fullName": "__unknown_module__.TestSqlInjection", + "function": "TestSqlInjection", + "file": "/test_callchain.go", + "line": 10, + "column": 1 + }, + { + "type": 1, + "nodeHash": "81e78d839150dd301eee354b73974a2a", + "fullName": "database/sql.Open(\"mysql\", \"user:password@/dbname\").Exec", + "function": "Exec", + "file": "/test_callchain.go", + "line": 17, + "column": 2 + } + ], + "callsites": [ + { + "code": "func TestSqlInjection(userInput string) {\n\tdb, _ := sql.Open(\"mysql\", \"user:password@/dbname\")\n\tdefe", + "nodeHash": "a7a3febd7ecda24769b4056b47e02d69", + "file": "/test_callchain.go", + "line": 10, + "column": 1 + }, + { + "code": "\tdb.Exec(query)", + "nodeHash": "81e78d839150dd301eee354b73974a2a", + "file": "/test_callchain.go", + "line": 17, + "column": 2 + } + ] + }, + { + "entrypoint": { + "type": "functionCall", + "functionName": "TestCommandInjection", + "filePath": "test_callchain.go" + }, + "sinkInfo": { + "sinkRule": "exec.Command", + "sinkAttribute": "GoCommandInjection", + "callSite": { + "code": "\tcmd := exec.Command(\"sh\", \"-c\", command)", + "file": "/test_callchain.go", + "line": 23, + "column": 9 + } + }, + "callstack": [ + { + "type": 0, + "nodeHash": "cc0d33162f6ed0524bd8e5c93c55df67", + "fullName": "__unknown_module__.TestCommandInjection", + "function": "TestCommandInjection", + "file": "/test_callchain.go", + "line": 21, + "column": 1 + }, + { + "type": 1, + "nodeHash": "cc56e8815b5be039850a931768bffb2e", + "fullName": "os/exec.Command", + "function": "Command", + "file": "/test_callchain.go", + "line": 23, + "column": 9 + } + ], + "callsites": [ + { + "code": "func TestCommandInjection(command string) {\n\t// This should be detected as a sink match\n\tcmd := exec", + "nodeHash": "cc0d33162f6ed0524bd8e5c93c55df67", + "file": "/test_callchain.go", + "line": 21, + "column": 1 + }, + { + "code": "\tcmd := exec.Command(\"sh\", \"-c\", command)", + "nodeHash": "cc56e8815b5be039850a931768bffb2e", + "file": "/test_callchain.go", + "line": 23, + "column": 9 + } + ] + } + ] +} diff --git a/test/callchain/expect/callchain-java-expect.json b/test/callchain/expect/callchain-java-expect.json new file mode 100644 index 00000000..37a6c991 --- /dev/null +++ b/test/callchain/expect/callchain-java-expect.json @@ -0,0 +1,116 @@ +{ + "version": "1.0", + "totalFindings": 2, + "findings": [ + { + "entrypoint": { + "type": "functionCall", + "functionName": "testSqlInjection", + "filePath": "TestCallchain.java", + "attribute": "HTTP", + "funcReceiverType": "" + }, + "sinkInfo": { + "sinkRule": "executeQuery", + "sinkAttribute": "JavaSQLInjection", + "callSite": { + "code": " stmt.executeQuery(query);", + "file": "/TestCallchain.java", + "line": 13, + "column": 13 + } + }, + "callstack": [ + { + "type": 0, + "nodeHash": "0287980e93c5e5bb427549aa7d0014ad", + "fullName": ".TestCallchain.testSqlInjection", + "function": "testSqlInjection", + "file": "/TestCallchain.java", + "line": 7, + "column": 5 + }, + { + "type": 1, + "nodeHash": "fcc4805fc859481fd6668a8f788e4299", + "fullName": "java.sql.DriverManager.getConnection(jdbc:mysql://localhost:3306/test).createStatement().executeQuery", + "function": "executeQuery", + "file": "/TestCallchain.java", + "line": 13, + "column": 13 + } + ], + "callsites": [ + { + "code": " public void testSqlInjection(String userInput) {\n try {\n Connection conn = Dri", + "nodeHash": "0287980e93c5e5bb427549aa7d0014ad", + "file": "/TestCallchain.java", + "line": 7, + "column": 5 + }, + { + "code": " stmt.executeQuery(query);", + "nodeHash": "fcc4805fc859481fd6668a8f788e4299", + "file": "/TestCallchain.java", + "line": 13, + "column": 13 + } + ] + }, + { + "entrypoint": { + "type": "functionCall", + "functionName": "testCommandInjection", + "filePath": "TestCallchain.java", + "attribute": "HTTP", + "funcReceiverType": "" + }, + "sinkInfo": { + "sinkRule": "exec", + "sinkAttribute": "JavaCommandExec", + "callSite": { + "code": " Runtime.getRuntime().exec(command);", + "file": "/TestCallchain.java", + "line": 22, + "column": 13 + } + }, + "callstack": [ + { + "type": 0, + "nodeHash": "b33ac74e457afbdd5ec2789deab7ebb5", + "fullName": ".TestCallchain.testCommandInjection", + "function": "testCommandInjection", + "file": "/TestCallchain.java", + "line": 19, + "column": 5 + }, + { + "type": 1, + "nodeHash": "1c8eb52ecc103ecf9528e82ff6ff736a", + "fullName": "Runtime.getRuntime().exec", + "function": "exec", + "file": "/TestCallchain.java", + "line": 22, + "column": 13 + } + ], + "callsites": [ + { + "code": " public void testCommandInjection(String command) {\n try {\n // This should be d", + "nodeHash": "b33ac74e457afbdd5ec2789deab7ebb5", + "file": "/TestCallchain.java", + "line": 19, + "column": 5 + }, + { + "code": " Runtime.getRuntime().exec(command);", + "nodeHash": "1c8eb52ecc103ecf9528e82ff6ff736a", + "file": "/TestCallchain.java", + "line": 22, + "column": 13 + } + ] + } + ] +} diff --git a/test/callchain/expect/callchain-js-expect.json b/test/callchain/expect/callchain-js-expect.json new file mode 100644 index 00000000..18e5e96e --- /dev/null +++ b/test/callchain/expect/callchain-js-expect.json @@ -0,0 +1,495 @@ +{ + "version": "1.0", + "totalFindings": 9, + "findings": [ + { + "entrypoint": { + "filePath": "YASADefault", + "functionName": "YASADefault", + "attribute": "YASADefault", + "funcReceiverType": "YASADefault" + }, + "sinkInfo": { + "sinkRule": "connection.query", + "sinkAttribute": "JSSQLInjection", + "callSite": { + "code": " connection.query(query, function (error, results, fields) {", + "file": "/test_callchain.js", + "line": 19, + "column": 5 + } + }, + "callstack": [ + { + "type": 0, + "nodeHash": "bb4f27bcf467d15bc6c2637fa9544dd0", + "fullName": "/test_callchain.testSqlInjection", + "function": "testSqlInjection", + "file": "/test_callchain.js", + "line": 7, + "column": 1 + }, + { + "type": 1, + "nodeHash": "c0dcaa8aa340b4b76b204d21f7bdf1f2", + "fullName": "mysql.createConnection({host:localhost, user:root, password:password, database:test}).query", + "function": "query", + "file": "/test_callchain.js", + "line": 19, + "column": 5 + } + ], + "callsites": [ + { + "code": "testSqlInjection('admin');", + "nodeHash": "d8f75b31bb792f2c25272bf6d2cb8bfb", + "file": "/test_callchain.js", + "line": 51, + "column": 1 + }, + { + "code": " connection.query(query, function (error, results, fields) {\n if (error) throw error;\n ", + "nodeHash": "c0dcaa8aa340b4b76b204d21f7bdf1f2", + "file": "/test_callchain.js", + "line": 19, + "column": 5 + } + ] + }, + { + "entrypoint": { + "filePath": "YASADefault", + "functionName": "YASADefault", + "attribute": "YASADefault", + "funcReceiverType": "YASADefault" + }, + "sinkInfo": { + "sinkRule": "child_process.exec", + "sinkAttribute": "JSCommandExec", + "callSite": { + "code": " exec(command, (error, stdout, stderr) => {", + "file": "/test_callchain.js", + "line": 32, + "column": 5 + } + }, + "callstack": [ + { + "type": 0, + "nodeHash": "176a70c2f8672528cc8cdb9b08b3fed2", + "fullName": "/test_callchain.testCommandInjection", + "function": "testCommandInjection", + "file": "/test_callchain.js", + "line": 30, + "column": 1 + }, + { + "type": 1, + "nodeHash": "7f45db454226c3e3132def6605c7007a", + "fullName": "child_process.exec", + "function": "exec", + "file": "/test_callchain.js", + "line": 32, + "column": 5 + } + ], + "callsites": [ + { + "code": "testCommandInjection('ls -la');", + "nodeHash": "a79005a1148a94a1b66cf30f6d24aee3", + "file": "/test_callchain.js", + "line": 52, + "column": 1 + }, + { + "code": " exec(command, (error, stdout, stderr) => {\n if (error) {\n console.error(`exec ", + "nodeHash": "7f45db454226c3e3132def6605c7007a", + "file": "/test_callchain.js", + "line": 32, + "column": 5 + } + ] + }, + { + "entrypoint": { + "filePath": "YASADefault", + "functionName": "YASADefault", + "attribute": "YASADefault", + "funcReceiverType": "YASADefault" + }, + "sinkInfo": { + "sinkRule": "eval", + "sinkAttribute": "JSEvalInjection", + "callSite": { + "code": " eval(code);", + "file": "/test_callchain.js", + "line": 47, + "column": 5 + } + }, + "callstack": [ + { + "type": 0, + "nodeHash": "ba6b76b84719810d6d28ec51048f8162", + "fullName": "/test_callchain.testEvalInjection", + "function": "testEvalInjection", + "file": "/test_callchain.js", + "line": 45, + "column": 1 + }, + { + "type": 1, + "nodeHash": "8bf38db1a0288bc4c4ab1c7bc8cc280a", + "fullName": "/test_callchain.testEvalInjection.eval", + "function": "eval", + "file": "/test_callchain.js", + "line": 47, + "column": 5 + } + ], + "callsites": [ + { + "code": "testEvalInjection('console.log(\"test\")');", + "nodeHash": "4953778979b01df31240e67bc3980b63", + "file": "/test_callchain.js", + "line": 53, + "column": 1 + }, + { + "code": " eval(code);", + "nodeHash": "8bf38db1a0288bc4c4ab1c7bc8cc280a", + "file": "/test_callchain.js", + "line": 47, + "column": 5 + } + ] + }, + { + "entrypoint": { + "type": "functionCall", + "functionName": "testSqlInjection", + "filePath": "/test_callchain.js", + "attribute": "fullCallGraphMade", + "funcReceiverType": "" + }, + "sinkInfo": { + "sinkRule": "connection.query", + "sinkAttribute": "JSSQLInjection", + "callSite": { + "code": " connection.query(query, function (error, results, fields) {", + "file": "/test_callchain.js", + "line": 19, + "column": 5 + } + }, + "callstack": [ + { + "type": 0, + "nodeHash": "bb4f27bcf467d15bc6c2637fa9544dd0", + "fullName": "/test_callchain.testSqlInjection", + "function": "testSqlInjection", + "file": "/test_callchain.js", + "line": 7, + "column": 1 + }, + { + "type": 1, + "nodeHash": "c0dcaa8aa340b4b76b204d21f7bdf1f2", + "fullName": "mysql.createConnection({host:localhost, user:root, password:password, database:test}).query", + "function": "query", + "file": "/test_callchain.js", + "line": 19, + "column": 5 + } + ], + "callsites": [ + { + "code": "function testSqlInjection(userInput) {\n const connection = mysql.createConnection({\n host:", + "nodeHash": "bb4f27bcf467d15bc6c2637fa9544dd0", + "file": "/test_callchain.js", + "line": 7, + "column": 1 + }, + { + "code": " connection.query(query, function (error, results, fields) {\n if (error) throw error;\n ", + "nodeHash": "c0dcaa8aa340b4b76b204d21f7bdf1f2", + "file": "/test_callchain.js", + "line": 19, + "column": 5 + } + ] + }, + { + "entrypoint": { + "type": "functionCall", + "functionName": "testCommandInjection", + "filePath": "/test_callchain.js", + "attribute": "fullCallGraphMade", + "funcReceiverType": "" + }, + "sinkInfo": { + "sinkRule": "child_process.exec", + "sinkAttribute": "JSCommandExec", + "callSite": { + "code": " exec(command, (error, stdout, stderr) => {", + "file": "/test_callchain.js", + "line": 32, + "column": 5 + } + }, + "callstack": [ + { + "type": 0, + "nodeHash": "176a70c2f8672528cc8cdb9b08b3fed2", + "fullName": "/test_callchain.testCommandInjection", + "function": "testCommandInjection", + "file": "/test_callchain.js", + "line": 30, + "column": 1 + }, + { + "type": 1, + "nodeHash": "7f45db454226c3e3132def6605c7007a", + "fullName": "child_process.exec", + "function": "exec", + "file": "/test_callchain.js", + "line": 32, + "column": 5 + } + ], + "callsites": [ + { + "code": "function testCommandInjection(command) {\n // This should be detected as a sink match\n exec(com", + "nodeHash": "176a70c2f8672528cc8cdb9b08b3fed2", + "file": "/test_callchain.js", + "line": 30, + "column": 1 + }, + { + "code": " exec(command, (error, stdout, stderr) => {\n if (error) {\n console.error(`exec ", + "nodeHash": "7f45db454226c3e3132def6605c7007a", + "file": "/test_callchain.js", + "line": 32, + "column": 5 + } + ] + }, + { + "entrypoint": { + "type": "functionCall", + "functionName": "testEvalInjection", + "filePath": "/test_callchain.js", + "attribute": "fullCallGraphMade", + "funcReceiverType": "" + }, + "sinkInfo": { + "sinkRule": "eval", + "sinkAttribute": "JSEvalInjection", + "callSite": { + "code": " eval(code);", + "file": "/test_callchain.js", + "line": 47, + "column": 5 + } + }, + "callstack": [ + { + "type": 0, + "nodeHash": "ba6b76b84719810d6d28ec51048f8162", + "fullName": "/test_callchain.testEvalInjection", + "function": "testEvalInjection", + "file": "/test_callchain.js", + "line": 45, + "column": 1 + }, + { + "type": 1, + "nodeHash": "8bf38db1a0288bc4c4ab1c7bc8cc280a", + "fullName": "/test_callchain.testEvalInjection.eval", + "function": "eval", + "file": "/test_callchain.js", + "line": 47, + "column": 5 + } + ], + "callsites": [ + { + "code": "function testEvalInjection(code) {\n // This should be detected as a sink match\n eval(code);\n}", + "nodeHash": "ba6b76b84719810d6d28ec51048f8162", + "file": "/test_callchain.js", + "line": 45, + "column": 1 + }, + { + "code": " eval(code);", + "nodeHash": "8bf38db1a0288bc4c4ab1c7bc8cc280a", + "file": "/test_callchain.js", + "line": 47, + "column": 5 + } + ] + }, + { + "entrypoint": { + "type": "fileBegin", + "filePath": "test/callchain/js/test_callchain.js", + "attribute": "fullfileManagerMade", + "funcReceiverType": "" + }, + "sinkInfo": { + "sinkRule": "connection.query", + "sinkAttribute": "JSSQLInjection", + "callSite": { + "code": " connection.query(query, function (error, results, fields) {", + "file": "/test_callchain.js", + "line": 19, + "column": 5 + } + }, + "callstack": [ + { + "type": 0, + "nodeHash": "bb4f27bcf467d15bc6c2637fa9544dd0", + "fullName": "/test_callchain.module.exports.testSqlInjection", + "function": "testSqlInjection", + "file": "/test_callchain.js", + "line": 7, + "column": 1 + }, + { + "type": 1, + "nodeHash": "c0dcaa8aa340b4b76b204d21f7bdf1f2", + "fullName": "mysql.createConnection({host:localhost, user:root, password:password, database:test}).query", + "function": "query", + "file": "/test_callchain.js", + "line": 19, + "column": 5 + } + ], + "callsites": [ + { + "code": "testSqlInjection('admin');", + "nodeHash": "d8f75b31bb792f2c25272bf6d2cb8bfb", + "file": "/test_callchain.js", + "line": 51, + "column": 1 + }, + { + "code": " connection.query(query, function (error, results, fields) {\n if (error) throw error;\n ", + "nodeHash": "c0dcaa8aa340b4b76b204d21f7bdf1f2", + "file": "/test_callchain.js", + "line": 19, + "column": 5 + } + ] + }, + { + "entrypoint": { + "type": "fileBegin", + "filePath": "test/callchain/js/test_callchain.js", + "attribute": "fullfileManagerMade", + "funcReceiverType": "" + }, + "sinkInfo": { + "sinkRule": "child_process.exec", + "sinkAttribute": "JSCommandExec", + "callSite": { + "code": " exec(command, (error, stdout, stderr) => {", + "file": "/test_callchain.js", + "line": 32, + "column": 5 + } + }, + "callstack": [ + { + "type": 0, + "nodeHash": "176a70c2f8672528cc8cdb9b08b3fed2", + "fullName": "/test_callchain.module.exports.testCommandInjection", + "function": "testCommandInjection", + "file": "/test_callchain.js", + "line": 30, + "column": 1 + }, + { + "type": 1, + "nodeHash": "7f45db454226c3e3132def6605c7007a", + "fullName": "child_process.exec", + "function": "exec", + "file": "/test_callchain.js", + "line": 32, + "column": 5 + } + ], + "callsites": [ + { + "code": "testCommandInjection('ls -la');", + "nodeHash": "a79005a1148a94a1b66cf30f6d24aee3", + "file": "/test_callchain.js", + "line": 52, + "column": 1 + }, + { + "code": " exec(command, (error, stdout, stderr) => {\n if (error) {\n console.error(`exec ", + "nodeHash": "7f45db454226c3e3132def6605c7007a", + "file": "/test_callchain.js", + "line": 32, + "column": 5 + } + ] + }, + { + "entrypoint": { + "type": "fileBegin", + "filePath": "test/callchain/js/test_callchain.js", + "attribute": "fullfileManagerMade", + "funcReceiverType": "" + }, + "sinkInfo": { + "sinkRule": "eval", + "sinkAttribute": "JSEvalInjection", + "callSite": { + "code": " eval(code);", + "file": "/test_callchain.js", + "line": 47, + "column": 5 + } + }, + "callstack": [ + { + "type": 0, + "nodeHash": "ba6b76b84719810d6d28ec51048f8162", + "fullName": "/test_callchain.module.exports.testEvalInjection", + "function": "testEvalInjection", + "file": "/test_callchain.js", + "line": 45, + "column": 1 + }, + { + "type": 1, + "nodeHash": "8bf38db1a0288bc4c4ab1c7bc8cc280a", + "fullName": "/test_callchain.module.exports.testEvalInjection.eval", + "function": "eval", + "file": "/test_callchain.js", + "line": 47, + "column": 5 + } + ], + "callsites": [ + { + "code": "testEvalInjection('console.log(\"test\")');", + "nodeHash": "4953778979b01df31240e67bc3980b63", + "file": "/test_callchain.js", + "line": 53, + "column": 1 + }, + { + "code": " eval(code);", + "nodeHash": "8bf38db1a0288bc4c4ab1c7bc8cc280a", + "file": "/test_callchain.js", + "line": 47, + "column": 5 + } + ] + } + ] +} diff --git a/test/callchain/expect/callchain-python-expect.json b/test/callchain/expect/callchain-python-expect.json new file mode 100644 index 00000000..9b29b238 --- /dev/null +++ b/test/callchain/expect/callchain-python-expect.json @@ -0,0 +1,222 @@ +{ + "version": "1.0", + "totalFindings": 4, + "findings": [ + { + "entrypoint": { + "filePath": "YASADefault", + "functionName": "YASADefault", + "attribute": "YASADefault", + "funcReceiverType": "YASADefault" + }, + "sinkInfo": { + "sinkRule": "cursor.execute", + "sinkAttribute": "PythonSQLInjection", + "callSite": { + "code": " cursor.execute(query)", + "file": "/test_callchain.py", + "line": 12, + "column": 5 + } + }, + "callstack": [ + { + "type": 0, + "nodeHash": "6fda1970db53b647788cbea43d3e9733", + "fullName": "/test_callchain.test_sql_injection", + "function": "test_sql_injection", + "file": "/test_callchain.py", + "line": 5, + "column": 1 + }, + { + "type": 1, + "nodeHash": "1076abfa513d8b01b102f4f0f8baf707", + "fullName": "sqlite3.connect(test.db).cursor().execute", + "function": "execute", + "file": "/test_callchain.py", + "line": 12, + "column": 5 + } + ], + "callsites": [ + { + "code": " test_sql_injection('admin')", + "nodeHash": "c8725dc0188e14dd3ffa58b6458f1532", + "file": "/test_callchain.py", + "line": 35, + "column": 5 + }, + { + "code": " cursor.execute(query)", + "nodeHash": "1076abfa513d8b01b102f4f0f8baf707", + "file": "/test_callchain.py", + "line": 12, + "column": 5 + } + ] + }, + { + "entrypoint": { + "filePath": "YASADefault", + "functionName": "YASADefault", + "attribute": "YASADefault", + "funcReceiverType": "YASADefault" + }, + "sinkInfo": { + "sinkRule": "subprocess.call", + "sinkAttribute": "PythonCommandExec", + "callSite": { + "code": " result = subprocess.call(command, shell=True)", + "file": "/test_callchain.py", + "line": 21, + "column": 14 + } + }, + "callstack": [ + { + "type": 0, + "nodeHash": "7de4f7a9120a09f17d5b658042ad55df", + "fullName": "/test_callchain.test_command_injection", + "function": "test_command_injection", + "file": "/test_callchain.py", + "line": 18, + "column": 1 + }, + { + "type": 1, + "nodeHash": "6176cfcc804a61cfcce676067defab7d", + "fullName": "subprocess.call", + "function": "call", + "file": "/test_callchain.py", + "line": 21, + "column": 14 + } + ], + "callsites": [ + { + "code": " test_command_injection('ls -la')", + "nodeHash": "87f49f13be0816ed54137c0737248b24", + "file": "/test_callchain.py", + "line": 36, + "column": 5 + }, + { + "code": " result = subprocess.call(command, shell=True)", + "nodeHash": "6176cfcc804a61cfcce676067defab7d", + "file": "/test_callchain.py", + "line": 21, + "column": 14 + } + ] + }, + { + "entrypoint": { + "filePath": "YASADefault", + "functionName": "YASADefault", + "attribute": "YASADefault", + "funcReceiverType": "YASADefault" + }, + "sinkInfo": { + "sinkRule": "os.system", + "sinkAttribute": "PythonCommandExec", + "callSite": { + "code": " os.system(command)", + "file": "/test_callchain.py", + "line": 27, + "column": 5 + } + }, + "callstack": [ + { + "type": 0, + "nodeHash": "c2cc326f3b0f3de34a2836e0376f9fe6", + "fullName": "/test_callchain.test_os_system", + "function": "test_os_system", + "file": "/test_callchain.py", + "line": 24, + "column": 1 + }, + { + "type": 1, + "nodeHash": "d17bd906b52cfc2c9be23dd2ec51fe17", + "fullName": "os.system", + "function": "system", + "file": "/test_callchain.py", + "line": 27, + "column": 5 + } + ], + "callsites": [ + { + "code": " test_os_system('pwd')", + "nodeHash": "aee3febb13019a7491f1b7249531af09", + "file": "/test_callchain.py", + "line": 37, + "column": 5 + }, + { + "code": " os.system(command)", + "nodeHash": "d17bd906b52cfc2c9be23dd2ec51fe17", + "file": "/test_callchain.py", + "line": 27, + "column": 5 + } + ] + }, + { + "entrypoint": { + "filePath": "YASADefault", + "functionName": "YASADefault", + "attribute": "YASADefault", + "funcReceiverType": "YASADefault" + }, + "sinkInfo": { + "sinkRule": "eval", + "sinkAttribute": "PythonEvalInjection", + "callSite": { + "code": " eval(code)", + "file": "/test_callchain.py", + "line": 32, + "column": 5 + } + }, + "callstack": [ + { + "type": 0, + "nodeHash": "ee1a8a934bdab2904279179b42c45a79", + "fullName": "/test_callchain.test_eval_injection", + "function": "test_eval_injection", + "file": "/test_callchain.py", + "line": 29, + "column": 1 + }, + { + "type": 1, + "nodeHash": "55a5ffe66c3c571108a506ddba2b7417", + "fullName": "/test_callchain.test_eval_injection.eval", + "function": "eval", + "file": "/test_callchain.py", + "line": 32, + "column": 5 + } + ], + "callsites": [ + { + "code": " test_eval_injection('print(\"test\")')", + "nodeHash": "a22125941d6912650dd41587d29887a9", + "file": "/test_callchain.py", + "line": 38, + "column": 5 + }, + { + "code": " eval(code)", + "nodeHash": "55a5ffe66c3c571108a506ddba2b7417", + "file": "/test_callchain.py", + "line": 32, + "column": 5 + } + ] + } + ] +} diff --git a/test/callchain/go/test_callchain.go b/test/callchain/go/test_callchain.go new file mode 100644 index 00000000..72d59b64 --- /dev/null +++ b/test/callchain/go/test_callchain.go @@ -0,0 +1,34 @@ +package main + +import ( + "database/sql" + "fmt" + "os/exec" +) + +// TestSqlInjection tests SQL injection sink detection +func TestSqlInjection(userInput string) { + db, _ := sql.Open("mysql", "user:password@/dbname") + defer db.Close() + + // This should be detected as a sink match + query := "SELECT * FROM users WHERE name = '" + userInput + "'" + db.Query(query) + db.Exec(query) +} + +// TestCommandInjection tests command injection sink detection +func TestCommandInjection(command string) { + // This should be detected as a sink match + cmd := exec.Command("sh", "-c", command) + output, err := cmd.Output() + if err != nil { + panic(err) + } + fmt.Println(string(output)) +} + +func main() { + TestSqlInjection("admin") + TestCommandInjection("ls -la") +} diff --git a/test/callchain/java/TestCallchain.java b/test/callchain/java/TestCallchain.java new file mode 100644 index 00000000..a3bcefb6 --- /dev/null +++ b/test/callchain/java/TestCallchain.java @@ -0,0 +1,33 @@ +import java.sql.Connection; +import java.sql.DriverManager; +import java.sql.Statement; + +public class TestCallchain { + + public void testSqlInjection(String userInput) { + try { + Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/test"); + Statement stmt = conn.createStatement(); + // This should be detected as a sink match + String query = "SELECT * FROM users WHERE name = '" + userInput + "'"; + stmt.executeQuery(query); + } catch (Exception e) { + e.printStackTrace(); + } + } + + public void testCommandInjection(String command) { + try { + // This should be detected as a sink match + Runtime.getRuntime().exec(command); + } catch (Exception e) { + e.printStackTrace(); + } + } + + public static void main(String[] args) { + TestCallchain test = new TestCallchain(); + test.testSqlInjection("admin"); + test.testCommandInjection("ls -la"); + } +} diff --git a/test/callchain/js/test_callchain.js b/test/callchain/js/test_callchain.js new file mode 100644 index 00000000..b94823fd --- /dev/null +++ b/test/callchain/js/test_callchain.js @@ -0,0 +1,53 @@ +const { exec } = require('child_process'); +const mysql = require('mysql'); + +/** + * Test SQL injection sink detection + */ +function testSqlInjection(userInput) { + const connection = mysql.createConnection({ + host: 'localhost', + user: 'root', + password: 'password', + database: 'test' + }); + + connection.connect(); + + // This should be detected as a sink match + const query = "SELECT * FROM users WHERE name = '" + userInput + "'"; + connection.query(query, function (error, results, fields) { + if (error) throw error; + console.log(results); + }); + + connection.end(); +} + +/** + * Test command injection sink detection + */ +function testCommandInjection(command) { + // This should be detected as a sink match + exec(command, (error, stdout, stderr) => { + if (error) { + console.error(`exec error: ${error}`); + return; + } + console.log(`stdout: ${stdout}`); + console.error(`stderr: ${stderr}`); + }); +} + +/** + * Test eval sink detection + */ +function testEvalInjection(code) { + // This should be detected as a sink match + eval(code); +} + +// Main execution +testSqlInjection('admin'); +testCommandInjection('ls -la'); +testEvalInjection('console.log("test")'); diff --git a/test/callchain/python/test_callchain.py b/test/callchain/python/test_callchain.py new file mode 100644 index 00000000..528fe8be --- /dev/null +++ b/test/callchain/python/test_callchain.py @@ -0,0 +1,38 @@ +import os +import sqlite3 +import subprocess + +def test_sql_injection(user_input): + """Test SQL injection sink detection""" + conn = sqlite3.connect('test.db') + cursor = conn.cursor() + + # This should be detected as a sink match + query = f"SELECT * FROM users WHERE name = '{user_input}'" + cursor.execute(query) + + results = cursor.fetchall() + conn.close() + return results + +def test_command_injection(command): + """Test command injection sink detection""" + # This should be detected as a sink match + result = subprocess.call(command, shell=True) + return result + +def test_os_system(command): + """Test os.system sink detection""" + # This should be detected as a sink match + os.system(command) + +def test_eval_injection(code): + """Test eval sink detection""" + # This should be detected as a sink match + eval(code) + +if __name__ == '__main__': + test_sql_injection('admin') + test_command_injection('ls -la') + test_os_system('pwd') + test_eval_injection('print("test")') diff --git a/test/callchain/rule_config_callchain_go.json b/test/callchain/rule_config_callchain_go.json new file mode 100644 index 00000000..e1f269e7 --- /dev/null +++ b/test/callchain/rule_config_callchain_go.json @@ -0,0 +1,52 @@ +[ + { + "checkerIds": [ + "callchain_go" + ], + "sources": {}, + "sinks": { + "FuncCallTaintSink": [ + { + "args": ["*"], + "attribute": "GoCommandInjection", + "calleeType": "", + "fsig": "exec.Command" + }, + { + "args": ["*"], + "attribute": "GoSQLInjection", + "calleeType": "*sql.DB", + "fsig": "Query" + }, + { + "args": ["*"], + "attribute": "GoSQLInjection", + "calleeType": "*database/sql.DB", + "fsig": "Query" + }, + { + "args": ["*"], + "attribute": "GoSQLInjection", + "calleeType": "*sql.DB", + "fsig": "Exec" + }, + { + "args": ["*"], + "attribute": "GoSQLInjection", + "calleeType": "*database/sql.DB", + "fsig": "Exec" + } + ] + }, + "entrypoints": [ + { + "filePath": "test_callchain.go", + "functionName": "TestSqlInjection" + }, + { + "filePath": "test_callchain.go", + "functionName": "TestCommandInjection" + } + ] + } +] diff --git a/test/callchain/rule_config_callchain_java.json b/test/callchain/rule_config_callchain_java.json new file mode 100644 index 00000000..3b4d00a5 --- /dev/null +++ b/test/callchain/rule_config_callchain_java.json @@ -0,0 +1,48 @@ +[ + { + "checkerIds": [ + "callchain_java" + ], + "sources": {}, + "sinks": { + "FuncCallTaintSink": [ + { + "args": ["0"], + "attribute": "JavaCommandExec", + "calleeType": "Runtime", + "fsig": "exec" + }, + { + "args": [ + "0" + ], + "attribute": "JavaCommandExec", + "calleeType": "Runtime.getRuntime()", + "fsig": "exec" + }, + { + "args": ["0"], + "attribute": "JavaSQLInjection", + "calleeType": "Statement", + "fsig": "executeQuery" + }, + { + "args": ["0"], + "attribute": "JavaSQLInjection", + "calleeType": "Statement", + "fsig": "execute" + } + ] + }, + "entrypoints": [ + { + "filePath": "TestCallchain.java", + "functionName": "testSqlInjection" + }, + { + "filePath": "TestCallchain.java", + "functionName": "testCommandInjection" + } + ] + } +] diff --git a/test/callchain/rule_config_callchain_js.json b/test/callchain/rule_config_callchain_js.json new file mode 100644 index 00000000..8b5e5d09 --- /dev/null +++ b/test/callchain/rule_config_callchain_js.json @@ -0,0 +1,41 @@ +[ + { + "checkerIds": [ + "callchain_js" + ], + "sources": {}, + "sinks": { + "FuncCallTaintSink": [ + { + "args": ["0"], + "attribute": "JSCommandExec", + "fsig": "child_process.exec" + }, + { + "args": ["0"], + "attribute": "JSEvalInjection", + "fsig": "eval" + }, + { + "args": ["0"], + "attribute": "JSSQLInjection", + "fsig": "connection.query" + } + ] + }, + "entrypoints": [ + { + "filePath": "test_callchain.js", + "functionName": "testSqlInjection" + }, + { + "filePath": "test_callchain.js", + "functionName": "testCommandInjection" + }, + { + "filePath": "test_callchain.js", + "functionName": "testEvalInjection" + } + ] + } +] diff --git a/test/callchain/rule_config_callchain_python.json b/test/callchain/rule_config_callchain_python.json new file mode 100644 index 00000000..e79a13c5 --- /dev/null +++ b/test/callchain/rule_config_callchain_python.json @@ -0,0 +1,35 @@ +[ + { + "checkerIds": [ + "callchain_python" + ], + "sources": {}, + "sinks": { + "FuncCallTaintSink": [ + { + "args": ["0"], + "attribute": "PythonCommandExec", + "fsig": "subprocess.call" + }, + { + "args": ["0"], + "attribute": "PythonCommandExec", + "fsig": "os.system" + }, + { + "args": ["0"], + "attribute": "PythonEvalInjection", + "fsig": "eval" + }, + { + "args": ["0"], + "attribute": "PythonSQLInjection", + "fsig": "cursor.execute" + } + ] + }, + "entrypoints": [ + + ] + } +] diff --git a/test/callchain/test-all-callchain.ts b/test/callchain/test-all-callchain.ts new file mode 100644 index 00000000..47d8de4e --- /dev/null +++ b/test/callchain/test-all-callchain.ts @@ -0,0 +1,127 @@ +import * as path from 'path' +const { execute } = require('../../src/interface/starter') +const logger = require('../../src/util/logger')(__filename) + +interface TestConfig { + name: string + testDir: string + ruleConfigFile: string + analyzer: string + checkerPackId: string +} + +const tests: TestConfig[] = [ + { + name: 'Java', + testDir: path.join(__dirname, 'java'), + ruleConfigFile: path.join(__dirname, 'rule_config_callchain_java.json'), + analyzer: 'JavaAnalyzer', + checkerPackId: 'callchain-java', + }, + { + name: 'Go', + testDir: path.join(__dirname, 'go'), + ruleConfigFile: path.join(__dirname, 'rule_config_callchain_go.json'), + analyzer: 'GoAnalyzer', + checkerPackId: 'callchain-go', + }, + { + name: 'JavaScript', + testDir: path.join(__dirname, 'js'), + ruleConfigFile: path.join(__dirname, 'rule_config_callchain_js.json'), + analyzer: 'JavaScriptAnalyzer', + checkerPackId: 'callchain-js', + }, + { + name: 'Python', + testDir: path.join(__dirname, 'python'), + ruleConfigFile: path.join(__dirname, 'rule_config_callchain_python.json'), + analyzer: 'PythonAnalyzer', + checkerPackId: 'callchain-python', + }, +] + +async function runCallchainTest(config: TestConfig): Promise { + console.log(`\n${'='.repeat(60)}`) + console.log(`Testing ${config.name} Callchain Checker`) + console.log(`${'='.repeat(60)}`) + console.log(`Test directory: ${config.testDir}`) + console.log(`Rule config: ${config.ruleConfigFile}`) + + try { + const args = [ + config.testDir, + '--ruleConfigFile', + config.ruleConfigFile, + '--analyzer', + config.analyzer, + '--reportDir', + path.join(config.testDir, 'report'), + '--entryPointMode', + 'ONLY_CUSTOM', + '--checkerPackIds', + config.checkerPackId, + ] + + const result = await execute(null, args) + + console.log(`\n✓ ${config.name} Callchain test completed successfully`) + if (result) { + console.log(` Found ${Object.keys(result).length} finding categories`) + if (result.callchain) { + console.log(` - Callchain findings: ${result.callchain.length}`) + } + } + } catch (error) { + console.error(`\n✗ ${config.name} Callchain test failed:`, error) + throw error + } +} + +async function runAllTests(): Promise { + console.log('\n' + '='.repeat(60)) + console.log('Running All Callchain Checker Tests') + console.log('='.repeat(60)) + + const results: Array<{ name: string; success: boolean; error?: any }> = [] + + for (const test of tests) { + try { + await runCallchainTest(test) + results.push({ name: test.name, success: true }) + } catch (error) { + results.push({ name: test.name, success: false, error }) + } + } + + console.log('\n' + '='.repeat(60)) + console.log('Test Results Summary') + console.log('='.repeat(60)) + + results.forEach((result) => { + const status = result.success ? '✓ PASS' : '✗ FAIL' + console.log(`${status} - ${result.name}`) + if (!result.success && result.error) { + console.log(` Error: ${result.error.message || result.error}`) + } + }) + + const failedCount = results.filter((r) => !r.success).length + const passedCount = results.filter((r) => r.success).length + + console.log(`\nTotal: ${results.length} | Passed: ${passedCount} | Failed: ${failedCount}`) + + if (failedCount > 0) { + throw new Error(`${failedCount} test(s) failed`) + } +} + +runAllTests() + .then(() => { + console.log('\n✓ All Callchain tests passed!') + process.exit(0) + }) + .catch((error) => { + console.error('\n✗ Some Callchain tests failed!') + process.exit(1) + }) diff --git a/test/callchain/test-callchain-benchmark.ts b/test/callchain/test-callchain-benchmark.ts new file mode 100644 index 00000000..a6ee7617 --- /dev/null +++ b/test/callchain/test-callchain-benchmark.ts @@ -0,0 +1,216 @@ +import * as path from 'path' +import * as fs from 'fs' +import { execFileSync } from 'child_process' +import { describe, it, before } from 'mocha' +import * as assert from 'assert' +const logger = require('../../src/util/logger')(__filename) + +// ========================= 工具函数 ========================= + +const WORKSPACE_ROOT = path.resolve(__dirname, '../..') + '/' +const REPORT_FILE = path.resolve(WORKSPACE_ROOT, 'report', 'callchain-report.json') + +/** + * 将 JSON 中所有绝对路径替换为相对路径,确保跨机器可比 + */ +function normalizeJson(obj: any): any { + const str = JSON.stringify(obj, null, 2) + return JSON.parse(str.split(WORKSPACE_ROOT).join('')) +} + +/** + * 递归比较两个 JSON 对象,返回所有差异的描述 + */ +function jsonDiff(expected: any, actual: any, currentPath: string = ''): string[] { + const diffs: string[] = [] + if (expected === actual) return diffs + + if (expected === null || actual === null || expected === undefined || actual === undefined) { + diffs.push(`${currentPath || ''}: expected=${JSON.stringify(expected)}, actual=${JSON.stringify(actual)}`) + return diffs + } + if (typeof expected !== typeof actual) { + diffs.push(`${currentPath || ''}: type mismatch, expected ${typeof expected}, actual ${typeof actual}`) + return diffs + } + if (Array.isArray(expected) && Array.isArray(actual)) { + if (expected.length !== actual.length) { + diffs.push(`${currentPath}: array length expected=${expected.length}, actual=${actual.length}`) + } + const maxLen = Math.max(expected.length, actual.length) + for (let i = 0; i < maxLen; i++) { + if (i >= expected.length) { + diffs.push(`${currentPath}[${i}]: 新增元素: ${JSON.stringify(actual[i]).slice(0, 200)}`) + } else if (i >= actual.length) { + diffs.push(`${currentPath}[${i}]: 缺失元素: ${JSON.stringify(expected[i]).slice(0, 200)}`) + } else { + diffs.push(...jsonDiff(expected[i], actual[i], `${currentPath}[${i}]`)) + } + } + return diffs + } + if (typeof expected === 'object') { + const allKeys = new Set([...Object.keys(expected), ...Object.keys(actual)]) + for (const key of allKeys) { + const keyPath = currentPath ? `${currentPath}.${key}` : key + if (!(key in expected)) { + diffs.push(`${keyPath}: 新增字段, value=${JSON.stringify(actual[key]).slice(0, 200)}`) + } else if (!(key in actual)) { + diffs.push(`${keyPath}: 缺失字段, expected=${JSON.stringify(expected[key]).slice(0, 200)}`) + } else { + diffs.push(...jsonDiff(expected[key], actual[key], keyPath)) + } + } + return diffs + } + if (expected !== actual) { + diffs.push(`${currentPath || ''}: expected=${JSON.stringify(expected).slice(0, 200)}, actual=${JSON.stringify(actual).slice(0, 200)}`) + } + return diffs +} + +// ========================= 测试配置 ========================= + +interface TestConfig { + name: string + runner: string // 已有的独立测试脚本路径 + expectFile: string + expectedFindingsCount: number +} + +const configs: TestConfig[] = [ + { + name: 'Java', + runner: path.resolve(__dirname, 'test-callchain-java.ts'), + expectFile: path.resolve(__dirname, 'expect', 'callchain-java-expect.json'), + expectedFindingsCount: 2, + }, + { + name: 'Go', + runner: path.resolve(__dirname, 'test-callchain-go.ts'), + expectFile: path.resolve(__dirname, 'expect', 'callchain-go-expect.json'), + expectedFindingsCount: 9, + }, + { + name: 'JavaScript', + runner: path.resolve(__dirname, 'test-callchain-js.ts'), + expectFile: path.resolve(__dirname, 'expect', 'callchain-js-expect.json'), + expectedFindingsCount: 9, + }, + { + name: 'Python', + runner: path.resolve(__dirname, 'test-callchain-python.ts'), + expectFile: path.resolve(__dirname, 'expect', 'callchain-python-expect.json'), + expectedFindingsCount: 4, + }, +] + +// ========================= Mocha 测试 ========================= + +describe('Callchain Checker Regression Tests', function () { + this.timeout(0) + + for (const config of configs) { + // 同步预读 expect 文件,用于注册测试用例 + let expectedFindings: any[] = [] + let expectedJson: any = null + if (fs.existsSync(config.expectFile)) { + expectedJson = JSON.parse(fs.readFileSync(config.expectFile, 'utf-8')) + expectedFindings = expectedJson.findings || [] + } + + describe(`${config.name} Callchain`, function () { + let actualJson: any + let benchmarkReady = false + + before(function () { + // 在子进程中运行各语言测试脚本,避免 Config 单例污染 + // 每个 test-callchain-.ts 会写入 report/callchain-report.json + try { + execFileSync('npx', ['tsx', config.runner], { + cwd: WORKSPACE_ROOT, + stdio: 'pipe', + timeout: 120000, + }) + } catch (e: any) { + logger.info(`[${config.name}] 子进程执行出错: ${e.message || e}`) + if (e.stdout) logger.info(`stdout: ${e.stdout.toString().slice(-500)}`) + if (e.stderr) logger.info(`stderr: ${e.stderr.toString().slice(-500)}`) + } + + // 读取子进程生成的 report 并标准化 + if (fs.existsSync(REPORT_FILE)) { + const rawJson = JSON.parse(fs.readFileSync(REPORT_FILE, 'utf-8')) + actualJson = normalizeJson(rawJson) + benchmarkReady = true + } + + // UPDATE_EXPECT=1 时保存当前输出为新 expect + if (process.env.UPDATE_EXPECT === '1' && actualJson) { + fs.mkdirSync(path.dirname(config.expectFile), { recursive: true }) + fs.writeFileSync(config.expectFile, JSON.stringify(actualJson, null, 2) + '\n', 'utf-8') + logger.info(`Updated: ${config.expectFile}`) + expectedJson = actualJson + expectedFindings = actualJson.findings || [] + } + }) + + it(`should produce report`, function () { + assert.ok(benchmarkReady, `${config.name}: callchain-report.json 未生成`) + }) + + it(`should have expect file`, function () { + assert.ok( + fs.existsSync(config.expectFile), + `未找到expect文件: ${config.expectFile}\n请执行: UPDATE_EXPECT=1 npm run test-callchain` + ) + }) + + it(`total findings count: ${expectedFindings.length}`, function () { + if (!benchmarkReady) { this.skip(); return } + assert.ok(expectedJson, 'expect文件不存在') + assert.strictEqual( + actualJson.totalFindings, + expectedJson.totalFindings, + `检出数量不一致: 预期 ${expectedJson.totalFindings}, 实际 ${actualJson.totalFindings}` + ) + }) + + // 为每个预期 finding 注册独立测试 + expectedFindings.forEach((expected: any, index: number) => { + const sinkRule = expected.sinkInfo?.sinkRule || 'unknown' + const file = expected.sinkInfo?.callSite?.file || '?' + const line = expected.sinkInfo?.callSite?.line || '?' + const entryFunc = expected.entrypoint?.functionName || 'N/A' + + it(`${index + 1}-finding:[${sinkRule}] at ${file}:${line} (entry:${entryFunc})`, function () { + if (!benchmarkReady) { this.skip(); return } + const actual = actualJson?.findings?.[index] + if (!actual) { + assert.fail(`第${index + 1}个finding缺失(实际仅${actualJson?.findings?.length || 0}个)`) + return + } + const diffs = jsonDiff(expected, actual) + if (diffs.length > 0) { + const diffReport = diffs.map((d, i) => ` [${i + 1}] ${d}`).join('\n') + logger.info(`Finding ${index + 1} expected:\n${JSON.stringify(expected, null, 2)}`) + logger.info(`Finding ${index + 1} actual:\n${JSON.stringify(actual, null, 2)}`) + assert.fail(`第${index + 1}个finding有${diffs.length}处差异:\n${diffReport}`) + } + }) + }) + + it(`no extra findings`, function () { + if (!benchmarkReady) { this.skip(); return } + if (!actualJson?.findings || !expectedJson?.findings) return + if (actualJson.findings.length > expectedJson.findings.length) { + const extras = actualJson.findings.slice(expectedJson.findings.length) + const desc = extras + .map((f: any, i: number) => ` [${expectedJson.findings.length + i + 1}] ${f.sinkInfo?.sinkRule || '?'} at ${f.sinkInfo?.callSite?.file || '?'}:${f.sinkInfo?.callSite?.line || '?'}`) + .join('\n') + assert.fail(`多出${extras.length}个finding:\n${desc}\n请执行 UPDATE_EXPECT=1 npm run test-callchain 更新`) + } + }) + }) + } +}) diff --git a/test/callchain/test-callchain-go.ts b/test/callchain/test-callchain-go.ts new file mode 100644 index 00000000..b7dc1ce2 --- /dev/null +++ b/test/callchain/test-callchain-go.ts @@ -0,0 +1,52 @@ +import * as path from 'path' +const { execute } = require('../../src/interface/starter') +const logger = require('../../src/util/logger')(__filename) + +async function testGoCallchain(): Promise { + const testDir = path.join(__dirname, 'go') + const ruleConfigFile = path.join(__dirname, 'rule_config_callchain_go.json') + + console.log('\n========== Testing Go Callchain Checker ==========') + console.log(`Test directory: ${testDir}`) + console.log(`Rule config: ${ruleConfigFile}`) + + try { + const args = [ + testDir, + '--ruleConfigFile', + ruleConfigFile, + '--analyzer', + 'GoAnalyzer', + '--reportDir', + path.join(__dirname, 'go'), + '--entryPointMode', + 'BOTH', + '--checkerPackIds', + 'callchain-go', + '--uastSDKPath', + path.join(__dirname, '../../deps'), + ] + + const result = await execute(null, args) + + console.log('\n✓ Go Callchain test completed') + if (result) { + console.log(`Found ${Object.keys(result).length} finding categories`) + if (result.callchain) { + console.log(` - Callchain findings: ${result.callchain.length}`) + } + } + } catch (error) { + console.error('\n✗ Go Callchain test failed:', error) + throw error + } +} + +testGoCallchain() + .then(() => { + console.log('\nAll Go Callchain tests passed!') + }) + .catch((error) => { + console.error('\nGo Callchain tests failed!') + process.exit(1) + }) diff --git a/test/callchain/test-callchain-java.ts b/test/callchain/test-callchain-java.ts new file mode 100644 index 00000000..a84187be --- /dev/null +++ b/test/callchain/test-callchain-java.ts @@ -0,0 +1,51 @@ +import * as path from 'path' +const { execute } = require('../../src/interface/starter') +const logger = require('../../src/util/logger')(__filename) + +async function testJavaCallchain(): Promise { + const testDir = path.resolve(__dirname, 'java') + const ruleConfigFile = path.resolve(__dirname, 'rule_config_callchain_java.json') + const reportDir = path.resolve(__dirname, 'java') + + console.log('\n========== Testing Java Callchain Checker ==========') + console.log(`Test directory: ${testDir}`) + console.log(`Rule config: ${ruleConfigFile}`) + + try { + const args = [ + testDir, + '--ruleConfigFile', + ruleConfigFile, + '--analyzer', + 'JavaAnalyzer', + '--reportDir', + reportDir, + '--entryPointMode', + 'ONLY_CUSTOM', + '--checkerPackIds', + 'callchain-java', + ] + + const result = await execute(null, args) + + console.log('\n✓ Java Callchain test completed') + if (result) { + console.log(`Found ${Object.keys(result).length} finding categories`) + if (result.callchain) { + console.log(` - Callchain findings: ${result.callchain.length}`) + } + } + } catch (error) { + console.error('\n✗ Java Callchain test failed:', error) + throw error + } +} + +testJavaCallchain() + .then(() => { + console.log('\nAll Java Callchain tests passed!') + }) + .catch((error) => { + console.error('\nJava Callchain tests failed!') + process.exit(1) + }) diff --git a/test/callchain/test-callchain-js.ts b/test/callchain/test-callchain-js.ts new file mode 100644 index 00000000..eecf6760 --- /dev/null +++ b/test/callchain/test-callchain-js.ts @@ -0,0 +1,50 @@ +import * as path from 'path' +const { execute } = require('../../src/interface/starter') +const logger = require('../../src/util/logger')(__filename) + +async function testJsCallchain(): Promise { + const testDir = path.join(__dirname, 'js') + const ruleConfigFile = path.join(__dirname, 'rule_config_callchain_js.json') + + console.log('\n========== Testing JavaScript Callchain Checker ==========') + console.log(`Test directory: ${testDir}`) + console.log(`Rule config: ${ruleConfigFile}`) + + try { + const args = [ + testDir, + '--ruleConfigFile', + ruleConfigFile, + '--analyzer', + 'JavaScriptAnalyzer', + '--reportDir', + path.join(__dirname, 'js'), + '--entryPointMode', + 'ONLY_CUSTOM', + '--checkerPackIds', + 'callchain-js', + ] + + const result = await execute(null, args) + + console.log('\n✓ JavaScript Callchain test completed') + if (result) { + console.log(`Found ${Object.keys(result).length} finding categories`) + if (result.callchain) { + console.log(` - Callchain findings: ${result.callchain.length}`) + } + } + } catch (error) { + console.error('\n✗ JavaScript Callchain test failed:', error) + throw error + } +} + +testJsCallchain() + .then(() => { + console.log('\nAll JavaScript Callchain tests passed!') + }) + .catch((error) => { + console.error('\nJavaScript Callchain tests failed!') + process.exit(1) + }) diff --git a/test/callchain/test-callchain-python.ts b/test/callchain/test-callchain-python.ts new file mode 100644 index 00000000..ef58893b --- /dev/null +++ b/test/callchain/test-callchain-python.ts @@ -0,0 +1,52 @@ +import * as path from 'path' +const { execute } = require('../../src/interface/starter') +const logger = require('../../src/util/logger')(__filename) + +async function testPythonCallchain(): Promise { + const testDir = path.join(__dirname, 'python') + const ruleConfigFile = path.join(__dirname, 'rule_config_callchain_python.json') + + console.log('\n========== Testing Python Callchain Checker ==========') + console.log(`Test directory: ${testDir}`) + console.log(`Rule config: ${ruleConfigFile}`) + + try { + const args = [ + testDir, + '--ruleConfigFile', + ruleConfigFile, + '--analyzer', + 'PythonAnalyzer', + '--reportDir', + path.join(__dirname, 'python'), + '--entryPointMode', + 'BOTH', + '--checkerPackIds', + 'callchain-python', + '--uastSDKPath', + path.join(__dirname, '../../deps'), + ] + + const result = await execute(null, args) + + console.log('\n✓ Python Callchain test completed') + if (result) { + console.log(`Found ${Object.keys(result).length} finding categories`) + if (result.callchain) { + console.log(` - Callchain findings: ${result.callchain.length}`) + } + } + } catch (error) { + console.error('\n✗ Python Callchain test failed:', error) + throw error + } +} + +testPythonCallchain() + .then(() => { + console.log('\nAll Python Callchain tests passed!') + }) + .catch((error) => { + console.error('\nPython Callchain tests failed!') + process.exit(1) + }) diff --git a/test/go/expect/gobenchmark-expect.json b/test/go/expect/gobenchmark-expect.json index 0b6dce8b..ab85266b 100644 --- a/test/go/expect/gobenchmark-expect.json +++ b/test/go/expect/gobenchmark-expect.json @@ -1 +1 @@ -{"/benchmarks/sast-go/cases/accuracy/context_sensitive/argument_return_value_passing/argument_passing_reference_001_F/argument_passing_reference_001_F":"======================== Findings ========================\nNo findings!\n==========================================================","/benchmarks/sast-go/cases/accuracy/context_sensitive/argument_return_value_passing/argument_passing_reference_002_T/argument_passing_reference_002_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/sast-go/cases/accuracy/context_sensitive/argument_return_value_passing/argument_passing_reference_002_T/argument_passing_reference_002_T.go\nLine 17: __taint_sink(obj.\"data\")\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/sast-go/cases/accuracy/context_sensitive/argument_return_value_passing/argument_passing_reference_002_T/argument_passing_reference_002_T.go\",\"functionName\":\"main\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /sast-go/cases/accuracy/context_sensitive/argument_return_value_passing/argument_passing_reference_002_T/argument_passing_reference_002_T.go\n AffectedNodeName: __taint_src\n 28: SOURCE: argument_passing_reference_002_T(__taint_src)\n /sast-go/cases/accuracy/context_sensitive/argument_return_value_passing/argument_passing_reference_002_T/argument_passing_reference_002_T.go\n AffectedNodeName: argument_passing_reference_002_T\n 28: CALL: argument_passing_reference_002_T(__taint_src)\n /sast-go/cases/accuracy/context_sensitive/argument_return_value_passing/argument_passing_reference_002_T/argument_passing_reference_002_T.go\n AffectedNodeName: __taint_src\n 12: ARG PASS: func argument_passing_reference_002_T(__taint_src interface{}) {\n /sast-go/cases/accuracy/context_sensitive/argument_return_value_passing/argument_passing_reference_002_T/argument_passing_reference_002_T.go\n AffectedNodeName: process\n 16: CALL: \tprocess(obj, __taint_src)\n /sast-go/cases/accuracy/context_sensitive/argument_return_value_passing/argument_passing_reference_002_T/argument_passing_reference_002_T.go\n AffectedNodeName: src\n 20: ARG PASS: func process(obj map[string]interface{}, src interface{}) {\n /sast-go/cases/accuracy/context_sensitive/argument_return_value_passing/argument_passing_reference_002_T/argument_passing_reference_002_T.go\n AffectedNodeName: obj[\"data\"]\n 21: Var Pass: \tobj[\"data\"] = src\n /sast-go/cases/accuracy/context_sensitive/argument_return_value_passing/argument_passing_reference_002_T/argument_passing_reference_002_T.go\n AffectedNodeName: __taint_sink\n 17: SINK: \t__taint_sink(obj[\"data\"])\n==========================================================\n #Total-findings:1\n==========================================================","/benchmarks/sast-go/cases/accuracy/context_sensitive/argument_return_value_passing/argument_passing_reference_003_F/argument_passing_reference_003_F":"======================== Findings ========================\nNo findings!\n==========================================================","/benchmarks/sast-go/cases/accuracy/context_sensitive/argument_return_value_passing/argument_passing_reference_004_T/argument_passing_reference_004_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/sast-go/cases/accuracy/context_sensitive/argument_return_value_passing/argument_passing_reference_004_T/argument_passing_reference_004_T.go\nLine 15: __taint_sink(arr)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/sast-go/cases/accuracy/context_sensitive/argument_return_value_passing/argument_passing_reference_004_T/argument_passing_reference_004_T.go\",\"functionName\":\"main\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /sast-go/cases/accuracy/context_sensitive/argument_return_value_passing/argument_passing_reference_004_T/argument_passing_reference_004_T.go\n AffectedNodeName: __taint_src\n 26: SOURCE: argument_passing_reference_005_T(__taint_src)\n /sast-go/cases/accuracy/context_sensitive/argument_return_value_passing/argument_passing_reference_004_T/argument_passing_reference_004_T.go\n AffectedNodeName: argument_passing_reference_005_T\n 26: CALL: argument_passing_reference_005_T(__taint_src)\n /sast-go/cases/accuracy/context_sensitive/argument_return_value_passing/argument_passing_reference_004_T/argument_passing_reference_004_T.go\n AffectedNodeName: __taint_src\n 12: ARG PASS: func argument_passing_reference_005_T(__taint_src interface{}) {\n /sast-go/cases/accuracy/context_sensitive/argument_return_value_passing/argument_passing_reference_004_T/argument_passing_reference_004_T.go\n AffectedNodeName: process\n 14: CALL: \tprocess(arr, __taint_src)\n /sast-go/cases/accuracy/context_sensitive/argument_return_value_passing/argument_passing_reference_004_T/argument_passing_reference_004_T.go\n AffectedNodeName: src\n 18: ARG PASS: func process(inputArr []interface{}, src interface{}) {\n /sast-go/cases/accuracy/context_sensitive/argument_return_value_passing/argument_passing_reference_004_T/argument_passing_reference_004_T.go\n AffectedNodeName: inputArr[0]\n 19: Var Pass: \tinputArr[0] = src\n /sast-go/cases/accuracy/context_sensitive/argument_return_value_passing/argument_passing_reference_004_T/argument_passing_reference_004_T.go\n AffectedNodeName: __taint_sink\n 15: SINK: \t__taint_sink(arr)\n==========================================================\n #Total-findings:1\n==========================================================","/benchmarks/sast-go/cases/accuracy/context_sensitive/argument_return_value_passing/argument_passing_reference_005_F/argument_passing_reference_005_F":"======================== Findings ========================\nNo findings!\n==========================================================","/benchmarks/sast-go/cases/accuracy/context_sensitive/argument_return_value_passing/argument_passing_reference_006_T/argument_passing_reference_006_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/sast-go/cases/accuracy/context_sensitive/argument_return_value_passing/argument_passing_reference_006_T/argument_passing_reference_006_T.go\nLine 17: __taint_sink(objB.\"name\")\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/sast-go/cases/accuracy/context_sensitive/argument_return_value_passing/argument_passing_reference_006_T/argument_passing_reference_006_T.go\",\"functionName\":\"main\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /sast-go/cases/accuracy/context_sensitive/argument_return_value_passing/argument_passing_reference_006_T/argument_passing_reference_006_T.go\n AffectedNodeName: __taint_src\n 30: SOURCE: argument_passing_reference_006_T(__taint_src)\n /sast-go/cases/accuracy/context_sensitive/argument_return_value_passing/argument_passing_reference_006_T/argument_passing_reference_006_T.go\n AffectedNodeName: argument_passing_reference_006_T\n 30: CALL: argument_passing_reference_006_T(__taint_src)\n /sast-go/cases/accuracy/context_sensitive/argument_return_value_passing/argument_passing_reference_006_T/argument_passing_reference_006_T.go\n AffectedNodeName: __taint_src\n 12: ARG PASS: func argument_passing_reference_006_T(__taint_src interface{}) {\n /sast-go/cases/accuracy/context_sensitive/argument_return_value_passing/argument_passing_reference_006_T/argument_passing_reference_006_T.go\n AffectedNodeName: objA\n 13: Var Pass: \tobjA := map[string]interface{}{\"name\": __taint_src}\n /sast-go/cases/accuracy/context_sensitive/argument_return_value_passing/argument_passing_reference_006_T/argument_passing_reference_006_T.go\n AffectedNodeName: swap\n 16: CALL: \tswap(objA, objB)\n /sast-go/cases/accuracy/context_sensitive/argument_return_value_passing/argument_passing_reference_006_T/argument_passing_reference_006_T.go\n AffectedNodeName: obj1\n 20: ARG PASS: func swap(obj1, obj2 map[string]interface{}) {\n /sast-go/cases/accuracy/context_sensitive/argument_return_value_passing/argument_passing_reference_006_T/argument_passing_reference_006_T.go\n AffectedNodeName: temp\n 21: Var Pass: \ttemp := obj1[\"name\"]\n /sast-go/cases/accuracy/context_sensitive/argument_return_value_passing/argument_passing_reference_006_T/argument_passing_reference_006_T.go\n AffectedNodeName: obj2[\"name\"]\n 23: Var Pass: \tobj2[\"name\"] = temp\n /sast-go/cases/accuracy/context_sensitive/argument_return_value_passing/argument_passing_reference_006_T/argument_passing_reference_006_T.go\n AffectedNodeName: __taint_sink\n 17: SINK: \t__taint_sink(objB[\"name\"])\n==========================================================\n #Total-findings:1\n==========================================================","/benchmarks/sast-go/cases/accuracy/context_sensitive/argument_return_value_passing/argument_passing_reference_007_T/argument_passing_reference_007_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/sast-go/cases/accuracy/context_sensitive/argument_return_value_passing/argument_passing_reference_007_T/argument_passing_reference_007_T.go\nLine 20: __taint_sink(&person.GetNamePointer())\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/sast-go/cases/accuracy/context_sensitive/argument_return_value_passing/argument_passing_reference_007_T/argument_passing_reference_007_T.go\",\"functionName\":\"main\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /sast-go/cases/accuracy/context_sensitive/argument_return_value_passing/argument_passing_reference_007_T/argument_passing_reference_007_T.go\n AffectedNodeName: __taint_src\n 34: SOURCE: argument_passing_reference_007_T(__taint_src)\n /sast-go/cases/accuracy/context_sensitive/argument_return_value_passing/argument_passing_reference_007_T/argument_passing_reference_007_T.go\n AffectedNodeName: argument_passing_reference_007_T\n 34: CALL: argument_passing_reference_007_T(__taint_src)\n /sast-go/cases/accuracy/context_sensitive/argument_return_value_passing/argument_passing_reference_007_T/argument_passing_reference_007_T.go\n AffectedNodeName: __taint_src\n 16: ARG PASS: func argument_passing_reference_007_T(__taint_src string) {\n /sast-go/cases/accuracy/context_sensitive/argument_return_value_passing/argument_passing_reference_007_T/argument_passing_reference_007_T.go\n AffectedNodeName: UpdateNamePointer\n 19: CALL: \t(&person).UpdateNamePointer(__taint_src)\n /sast-go/cases/accuracy/context_sensitive/argument_return_value_passing/argument_passing_reference_007_T/argument_passing_reference_007_T.go\n AffectedNodeName: newName\n 23: ARG PASS: func (p *Person) UpdateNamePointer(newName string) {\n /sast-go/cases/accuracy/context_sensitive/argument_return_value_passing/argument_passing_reference_007_T/argument_passing_reference_007_T.go\n AffectedNodeName: [p.Name]\n 24: Var Pass: \tp.Name = newName\n /sast-go/cases/accuracy/context_sensitive/argument_return_value_passing/argument_passing_reference_007_T/argument_passing_reference_007_T.go\n AffectedNodeName: GetNamePointer\n 20: CALL: \t__taint_sink((&person).GetNamePointer())\n /sast-go/cases/accuracy/context_sensitive/argument_return_value_passing/argument_passing_reference_007_T/argument_passing_reference_007_T.go\n 20: ARG PASS: \t__taint_sink((&person).GetNamePointer())\n /sast-go/cases/accuracy/context_sensitive/argument_return_value_passing/argument_passing_reference_007_T/argument_passing_reference_007_T.go\n AffectedNodeName: [return value]\n 28: Return Value: \treturn p.Name\n /sast-go/cases/accuracy/context_sensitive/argument_return_value_passing/argument_passing_reference_007_T/argument_passing_reference_007_T.go\n AffectedNodeName: GetNamePointer\n 20: CALL RETURN: \t__taint_sink((&person).GetNamePointer())\n /sast-go/cases/accuracy/context_sensitive/argument_return_value_passing/argument_passing_reference_007_T/argument_passing_reference_007_T.go\n AffectedNodeName: __taint_sink\n 20: SINK: \t__taint_sink((&person).GetNamePointer())\n==========================================================\n #Total-findings:1\n==========================================================","/benchmarks/sast-go/cases/accuracy/context_sensitive/argument_return_value_passing/argument_passing_reference_008_F/argument_passing_reference_008_F":"======================== Findings ========================\nNo findings!\n==========================================================","/benchmarks/sast-go/cases/accuracy/context_sensitive/argument_return_value_passing/argument_passing_value_011_F/argument_passing_value_011_F":"======================== Findings ========================\nNo findings!\n==========================================================","/benchmarks/sast-go/cases/accuracy/context_sensitive/argument_return_value_passing/argument_passing_value_012_T/argument_passing_value_012_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/sast-go/cases/accuracy/context_sensitive/argument_return_value_passing/argument_passing_value_012_T/argument_passing_value_012_T.go\nLine 16: __taint_sink(arg)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/sast-go/cases/accuracy/context_sensitive/argument_return_value_passing/argument_passing_value_012_T/argument_passing_value_012_T.go\",\"functionName\":\"main\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /sast-go/cases/accuracy/context_sensitive/argument_return_value_passing/argument_passing_value_012_T/argument_passing_value_012_T.go\n AffectedNodeName: __taint_src\n 23: SOURCE: argument_passing_value_012_T(__taint_src)\n /sast-go/cases/accuracy/context_sensitive/argument_return_value_passing/argument_passing_value_012_T/argument_passing_value_012_T.go\n AffectedNodeName: argument_passing_value_012_T\n 23: CALL: argument_passing_value_012_T(__taint_src)\n /sast-go/cases/accuracy/context_sensitive/argument_return_value_passing/argument_passing_value_012_T/argument_passing_value_012_T.go\n AffectedNodeName: __taint_src\n 11: ARG PASS: func argument_passing_value_012_T(__taint_src string) {\n /sast-go/cases/accuracy/context_sensitive/argument_return_value_passing/argument_passing_value_012_T/argument_passing_value_012_T.go\n AffectedNodeName: process\n 12: CALL: \tprocess(__taint_src)\n /sast-go/cases/accuracy/context_sensitive/argument_return_value_passing/argument_passing_value_012_T/argument_passing_value_012_T.go\n AffectedNodeName: arg\n 15: ARG PASS: func process(arg string) {\n /sast-go/cases/accuracy/context_sensitive/argument_return_value_passing/argument_passing_value_012_T/argument_passing_value_012_T.go\n AffectedNodeName: __taint_sink\n 16: SINK: \t__taint_sink(arg)\n==========================================================\n #Total-findings:1\n==========================================================","/benchmarks/sast-go/cases/accuracy/context_sensitive/argument_return_value_passing/argument_passing_value_013_F/argument_passing_value_013_F":"======================== Findings ========================\nNo findings!\n==========================================================","/benchmarks/sast-go/cases/accuracy/context_sensitive/argument_return_value_passing/argument_passing_value_014_T/argument_passing_value_014_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/sast-go/cases/accuracy/context_sensitive/argument_return_value_passing/argument_passing_value_014_T/argument_passing_value_014_T.go\nLine 18: __taint_sink(arg)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/sast-go/cases/accuracy/context_sensitive/argument_return_value_passing/argument_passing_value_014_T/argument_passing_value_014_T.go\",\"functionName\":\"main\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /sast-go/cases/accuracy/context_sensitive/argument_return_value_passing/argument_passing_value_014_T/argument_passing_value_014_T.go\n AffectedNodeName: __taint_src\n 28: SOURCE: argument_passing_value_014_T(__taint_src)\n /sast-go/cases/accuracy/context_sensitive/argument_return_value_passing/argument_passing_value_014_T/argument_passing_value_014_T.go\n AffectedNodeName: argument_passing_value_014_T\n 28: CALL: argument_passing_value_014_T(__taint_src)\n /sast-go/cases/accuracy/context_sensitive/argument_return_value_passing/argument_passing_value_014_T/argument_passing_value_014_T.go\n AffectedNodeName: __taint_src\n 11: ARG PASS: func argument_passing_value_014_T(__taint_src interface{}) {\n /sast-go/cases/accuracy/context_sensitive/argument_return_value_passing/argument_passing_value_014_T/argument_passing_value_014_T.go\n AffectedNodeName: process1\n 14: CALL: \tprocess1(__taint_src)\n /sast-go/cases/accuracy/context_sensitive/argument_return_value_passing/argument_passing_value_014_T/argument_passing_value_014_T.go\n AffectedNodeName: arg\n 17: ARG PASS: func process1(arg interface{}) {\n /sast-go/cases/accuracy/context_sensitive/argument_return_value_passing/argument_passing_value_014_T/argument_passing_value_014_T.go\n AffectedNodeName: __taint_sink\n 18: SINK: \t__taint_sink(arg)\n==========================================================\n #Total-findings:1\n==========================================================","/benchmarks/sast-go/cases/accuracy/context_sensitive/argument_return_value_passing/argument_passing_value_015_F/argument_passing_value_015_F":"======================== Findings ========================\nNo findings!\n==========================================================","/benchmarks/sast-go/cases/accuracy/context_sensitive/argument_return_value_passing/argument_passing_value_016_T/argument_passing_value_016_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/sast-go/cases/accuracy/context_sensitive/argument_return_value_passing/argument_passing_value_016_T/argument_passing_value_016_T.go\nLine 16: __taint_sink(arg1)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/sast-go/cases/accuracy/context_sensitive/argument_return_value_passing/argument_passing_value_016_T/argument_passing_value_016_T.go\",\"functionName\":\"main\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /sast-go/cases/accuracy/context_sensitive/argument_return_value_passing/argument_passing_value_016_T/argument_passing_value_016_T.go\n AffectedNodeName: __taint_src\n 22: SOURCE: argument_passing_value_016_T(__taint_src)\n /sast-go/cases/accuracy/context_sensitive/argument_return_value_passing/argument_passing_value_016_T/argument_passing_value_016_T.go\n AffectedNodeName: argument_passing_value_016_T\n 22: CALL: argument_passing_value_016_T(__taint_src)\n /sast-go/cases/accuracy/context_sensitive/argument_return_value_passing/argument_passing_value_016_T/argument_passing_value_016_T.go\n AffectedNodeName: __taint_src\n 11: ARG PASS: func argument_passing_value_016_T(__taint_src string) {\n /sast-go/cases/accuracy/context_sensitive/argument_return_value_passing/argument_passing_value_016_T/argument_passing_value_016_T.go\n AffectedNodeName: process\n 12: CALL: \tprocess(__taint_src, \"_\")\n /sast-go/cases/accuracy/context_sensitive/argument_return_value_passing/argument_passing_value_016_T/argument_passing_value_016_T.go\n AffectedNodeName: arg1\n 15: ARG PASS: func process(arg1 string, arg2 string) {\n /sast-go/cases/accuracy/context_sensitive/argument_return_value_passing/argument_passing_value_016_T/argument_passing_value_016_T.go\n AffectedNodeName: __taint_sink\n 16: SINK: \t__taint_sink(arg1)\n==========================================================\n #Total-findings:1\n==========================================================","/benchmarks/sast-go/cases/accuracy/context_sensitive/argument_return_value_passing/multiple_return_001_F/multiple_return_001_F":"======================== Findings ========================\nNo findings!\n==========================================================","/benchmarks/sast-go/cases/accuracy/context_sensitive/argument_return_value_passing/multiple_return_002_T/multiple_return_002_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/sast-go/cases/accuracy/context_sensitive/argument_return_value_passing/multiple_return_002_T/multiple_return_002_T.go\nLine 17: __taint_sink(ret1)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/sast-go/cases/accuracy/context_sensitive/argument_return_value_passing/multiple_return_002_T/multiple_return_002_T.go\",\"functionName\":\"main\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /sast-go/cases/accuracy/context_sensitive/argument_return_value_passing/multiple_return_002_T/multiple_return_002_T.go\n AffectedNodeName: __taint_src\n 27: SOURCE: multiple_return_002_T(__taint_src)\n /sast-go/cases/accuracy/context_sensitive/argument_return_value_passing/multiple_return_002_T/multiple_return_002_T.go\n AffectedNodeName: multiple_return_002_T\n 27: CALL: multiple_return_002_T(__taint_src)\n /sast-go/cases/accuracy/context_sensitive/argument_return_value_passing/multiple_return_002_T/multiple_return_002_T.go\n AffectedNodeName: __taint_src\n 12: ARG PASS: func multiple_return_002_T(__taint_src interface{}) {\n /sast-go/cases/accuracy/context_sensitive/argument_return_value_passing/multiple_return_002_T/multiple_return_002_T.go\n AffectedNodeName: processData\n 15: CALL: \tret1, ret2 := processData(__taint_src, a)\n /sast-go/cases/accuracy/context_sensitive/argument_return_value_passing/multiple_return_002_T/multiple_return_002_T.go\n AffectedNodeName: s\n 20: ARG PASS: func processData(s interface{}, i interface{}) (interface{}, interface{}) {\n /sast-go/cases/accuracy/context_sensitive/argument_return_value_passing/multiple_return_002_T/multiple_return_002_T.go\n AffectedNodeName: [return value]\n 21: Return Value: \treturn s, i\n /sast-go/cases/accuracy/context_sensitive/argument_return_value_passing/multiple_return_002_T/multiple_return_002_T.go\n AffectedNodeName: processData\n 15: CALL RETURN: \tret1, ret2 := processData(__taint_src, a)\n /sast-go/cases/accuracy/context_sensitive/argument_return_value_passing/multiple_return_002_T/multiple_return_002_T.go\n 15: Var Pass: \tret1, ret2 := processData(__taint_src, a)\n /sast-go/cases/accuracy/context_sensitive/argument_return_value_passing/multiple_return_002_T/multiple_return_002_T.go\n AffectedNodeName: __taint_sink\n 17: SINK: \t__taint_sink(ret1)\n==========================================================\n #Total-findings:1\n==========================================================","/benchmarks/sast-go/cases/accuracy/context_sensitive/argument_return_value_passing/multiple_return_003_F/multiple_return_003_F":"======================== Findings ========================\nNo findings!\n==========================================================","/benchmarks/sast-go/cases/accuracy/context_sensitive/argument_return_value_passing/multiple_return_004_T/multiple_return_004_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/sast-go/cases/accuracy/context_sensitive/argument_return_value_passing/multiple_return_004_T/multiple_return_004_T.go\nLine 17: __taint_sink(ret2)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/sast-go/cases/accuracy/context_sensitive/argument_return_value_passing/multiple_return_004_T/multiple_return_004_T.go\",\"functionName\":\"main\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /sast-go/cases/accuracy/context_sensitive/argument_return_value_passing/multiple_return_004_T/multiple_return_004_T.go\n AffectedNodeName: __taint_src\n 27: SOURCE: multiple_return_004_T(__taint_src)\n /sast-go/cases/accuracy/context_sensitive/argument_return_value_passing/multiple_return_004_T/multiple_return_004_T.go\n AffectedNodeName: multiple_return_004_T\n 27: CALL: multiple_return_004_T(__taint_src)\n /sast-go/cases/accuracy/context_sensitive/argument_return_value_passing/multiple_return_004_T/multiple_return_004_T.go\n AffectedNodeName: __taint_src\n 12: ARG PASS: func multiple_return_004_T(__taint_src interface{}) {\n /sast-go/cases/accuracy/context_sensitive/argument_return_value_passing/multiple_return_004_T/multiple_return_004_T.go\n AffectedNodeName: processData\n 15: CALL: \tret1, ret2 := processData(__taint_src, a)\n /sast-go/cases/accuracy/context_sensitive/argument_return_value_passing/multiple_return_004_T/multiple_return_004_T.go\n AffectedNodeName: s\n 20: ARG PASS: func processData(s interface{}, i interface{}) (interface{}, interface{}) {\n /sast-go/cases/accuracy/context_sensitive/argument_return_value_passing/multiple_return_004_T/multiple_return_004_T.go\n AffectedNodeName: [return value]\n 21: Return Value: \treturn i, s\n /sast-go/cases/accuracy/context_sensitive/argument_return_value_passing/multiple_return_004_T/multiple_return_004_T.go\n AffectedNodeName: processData\n 15: CALL RETURN: \tret1, ret2 := processData(__taint_src, a)\n /sast-go/cases/accuracy/context_sensitive/argument_return_value_passing/multiple_return_004_T/multiple_return_004_T.go\n 15: Var Pass: \tret1, ret2 := processData(__taint_src, a)\n /sast-go/cases/accuracy/context_sensitive/argument_return_value_passing/multiple_return_004_T/multiple_return_004_T.go\n AffectedNodeName: __taint_sink\n 17: SINK: \t__taint_sink(ret2)\n==========================================================\n #Total-findings:1\n==========================================================","/benchmarks/sast-go/cases/accuracy/context_sensitive/argument_return_value_passing/named_return_001_F/named_return_001_F":"======================== Findings ========================\nNo findings!\n==========================================================","/benchmarks/sast-go/cases/accuracy/context_sensitive/argument_return_value_passing/named_return_002_T/named_return_002_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/sast-go/cases/accuracy/context_sensitive/argument_return_value_passing/named_return_002_T/named_return_002_T.go\nLine 15: __taint_sink(ret)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/sast-go/cases/accuracy/context_sensitive/argument_return_value_passing/named_return_002_T/named_return_002_T.go\",\"functionName\":\"main\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /sast-go/cases/accuracy/context_sensitive/argument_return_value_passing/named_return_002_T/named_return_002_T.go\n AffectedNodeName: __taint_src\n 26: SOURCE: named_return_002_T(__taint_src)\n /sast-go/cases/accuracy/context_sensitive/argument_return_value_passing/named_return_002_T/named_return_002_T.go\n AffectedNodeName: named_return_002_T\n 26: CALL: named_return_002_T(__taint_src)\n /sast-go/cases/accuracy/context_sensitive/argument_return_value_passing/named_return_002_T/named_return_002_T.go\n AffectedNodeName: __taint_src\n 11: ARG PASS: func named_return_002_T(__taint_src interface{}) {\n /sast-go/cases/accuracy/context_sensitive/argument_return_value_passing/named_return_002_T/named_return_002_T.go\n AffectedNodeName: processData\n 14: CALL: \tret := processData(__taint_src, a)\n /sast-go/cases/accuracy/context_sensitive/argument_return_value_passing/named_return_002_T/named_return_002_T.go\n AffectedNodeName: s\n 18: ARG PASS: func processData(s interface{}, i interface{}) (ret interface{}) {\n /sast-go/cases/accuracy/context_sensitive/argument_return_value_passing/named_return_002_T/named_return_002_T.go\n AffectedNodeName: ret\n 19: Var Pass: \tret = s\n /sast-go/cases/accuracy/context_sensitive/argument_return_value_passing/named_return_002_T/named_return_002_T.go\n AffectedNodeName: [return value]\n 20: Return Value: \treturn\n /sast-go/cases/accuracy/context_sensitive/argument_return_value_passing/named_return_002_T/named_return_002_T.go\n AffectedNodeName: processData\n 14: CALL RETURN: \tret := processData(__taint_src, a)\n /sast-go/cases/accuracy/context_sensitive/argument_return_value_passing/named_return_002_T/named_return_002_T.go\n AffectedNodeName: ret\n 14: Var Pass: \tret := processData(__taint_src, a)\n /sast-go/cases/accuracy/context_sensitive/argument_return_value_passing/named_return_002_T/named_return_002_T.go\n AffectedNodeName: __taint_sink\n 15: SINK: \t__taint_sink(ret)\n==========================================================\n #Total-findings:1\n==========================================================","/benchmarks/sast-go/cases/accuracy/context_sensitive/argument_return_value_passing/return_value_passing_001_F/return_value_passing_001_F":"======================== Findings ========================\nNo findings!\n==========================================================","/benchmarks/sast-go/cases/accuracy/context_sensitive/argument_return_value_passing/return_value_passing_002_T/return_value_passing_002_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/sast-go/cases/accuracy/context_sensitive/argument_return_value_passing/return_value_passing_002_T/return_value_passing_002_T.go\nLine 13: __taint_sink(data)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/sast-go/cases/accuracy/context_sensitive/argument_return_value_passing/return_value_passing_002_T/return_value_passing_002_T.go\",\"functionName\":\"main\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /sast-go/cases/accuracy/context_sensitive/argument_return_value_passing/return_value_passing_002_T/return_value_passing_002_T.go\n AffectedNodeName: __taint_src\n 24: SOURCE: return_value_passing_002_T(__taint_src)\n /sast-go/cases/accuracy/context_sensitive/argument_return_value_passing/return_value_passing_002_T/return_value_passing_002_T.go\n AffectedNodeName: return_value_passing_002_T\n 24: CALL: return_value_passing_002_T(__taint_src)\n /sast-go/cases/accuracy/context_sensitive/argument_return_value_passing/return_value_passing_002_T/return_value_passing_002_T.go\n AffectedNodeName: __taint_src\n 11: ARG PASS: func return_value_passing_002_T(__taint_src interface{}) {\n /sast-go/cases/accuracy/context_sensitive/argument_return_value_passing/return_value_passing_002_T/return_value_passing_002_T.go\n AffectedNodeName: process\n 12: CALL: \tdata := process(__taint_src)\n /sast-go/cases/accuracy/context_sensitive/argument_return_value_passing/return_value_passing_002_T/return_value_passing_002_T.go\n AffectedNodeName: __taint_src\n 19: ARG PASS: func process(__taint_src interface{}) interface{} {\n /sast-go/cases/accuracy/context_sensitive/argument_return_value_passing/return_value_passing_002_T/return_value_passing_002_T.go\n AffectedNodeName: [return value]\n 20: Return Value: \treturn __taint_src\n /sast-go/cases/accuracy/context_sensitive/argument_return_value_passing/return_value_passing_002_T/return_value_passing_002_T.go\n AffectedNodeName: process\n 12: CALL RETURN: \tdata := process(__taint_src)\n /sast-go/cases/accuracy/context_sensitive/argument_return_value_passing/return_value_passing_002_T/return_value_passing_002_T.go\n AffectedNodeName: data\n 12: Var Pass: \tdata := process(__taint_src)\n /sast-go/cases/accuracy/context_sensitive/argument_return_value_passing/return_value_passing_002_T/return_value_passing_002_T.go\n AffectedNodeName: __taint_sink\n 13: SINK: \t__taint_sink(data)\n==========================================================\n #Total-findings:1\n==========================================================","/benchmarks/sast-go/cases/accuracy/context_sensitive/multi_invoke/multi_invoke_001_F/multi_invoke_001_F":"======================== Findings ========================\nNo findings!\n==========================================================","/benchmarks/sast-go/cases/accuracy/context_sensitive/multi_invoke/multi_invoke_002_T/multi_invoke_002_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/sast-go/cases/accuracy/context_sensitive/multi_invoke/multi_invoke_002_T/multi_invoke_002_T.go\nLine 16: __taint_sink(a)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/sast-go/cases/accuracy/context_sensitive/multi_invoke/multi_invoke_002_T/multi_invoke_002_T.go\",\"functionName\":\"main\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /sast-go/cases/accuracy/context_sensitive/multi_invoke/multi_invoke_002_T/multi_invoke_002_T.go\n AffectedNodeName: __taint_src\n 27: SOURCE: multi_invoke_002_T(__taint_src)\n /sast-go/cases/accuracy/context_sensitive/multi_invoke/multi_invoke_002_T/multi_invoke_002_T.go\n AffectedNodeName: multi_invoke_002_T\n 27: CALL: multi_invoke_002_T(__taint_src)\n /sast-go/cases/accuracy/context_sensitive/multi_invoke/multi_invoke_002_T/multi_invoke_002_T.go\n AffectedNodeName: __taint_src\n 12: ARG PASS: func multi_invoke_002_T(__taint_src string) {\n /sast-go/cases/accuracy/context_sensitive/multi_invoke/multi_invoke_002_T/multi_invoke_002_T.go\n AffectedNodeName: process\n 13: CALL: \ta := process(__taint_src)\n /sast-go/cases/accuracy/context_sensitive/multi_invoke/multi_invoke_002_T/multi_invoke_002_T.go\n AffectedNodeName: arg\n 19: ARG PASS: func process(arg string) string {\n /sast-go/cases/accuracy/context_sensitive/multi_invoke/multi_invoke_002_T/multi_invoke_002_T.go\n AffectedNodeName: [return value]\n 20: Return Value: \treturn arg\n /sast-go/cases/accuracy/context_sensitive/multi_invoke/multi_invoke_002_T/multi_invoke_002_T.go\n AffectedNodeName: process\n 13: CALL RETURN: \ta := process(__taint_src)\n /sast-go/cases/accuracy/context_sensitive/multi_invoke/multi_invoke_002_T/multi_invoke_002_T.go\n AffectedNodeName: a\n 13: Var Pass: \ta := process(__taint_src)\n /sast-go/cases/accuracy/context_sensitive/multi_invoke/multi_invoke_002_T/multi_invoke_002_T.go\n AffectedNodeName: __taint_sink\n 16: SINK: \t__taint_sink(a)\n==========================================================\n #Total-findings:1\n==========================================================","/benchmarks/sast-go/cases/accuracy/context_sensitive/polymorphism/polymorphism_001_T/polymorphism_001_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/sast-go/cases/accuracy/context_sensitive/polymorphism/polymorphism_001_T/polymorphism_001_T.go\nLine 15: __taint_sink(sub.call(__taint_src))\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/sast-go/cases/accuracy/context_sensitive/polymorphism/polymorphism_001_T/polymorphism_001_T.go\",\"functionName\":\"main\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /sast-go/cases/accuracy/context_sensitive/polymorphism/polymorphism_001_T/polymorphism_001_T.go\n AffectedNodeName: __taint_src\n 38: SOURCE: polymorphism_001_T(__taint_src)\n /sast-go/cases/accuracy/context_sensitive/polymorphism/polymorphism_001_T/polymorphism_001_T.go\n AffectedNodeName: polymorphism_001_T\n 38: CALL: polymorphism_001_T(__taint_src)\n /sast-go/cases/accuracy/context_sensitive/polymorphism/polymorphism_001_T/polymorphism_001_T.go\n AffectedNodeName: __taint_src\n 12: ARG PASS: func polymorphism_001_T(__taint_src interface{}) {\n /sast-go/cases/accuracy/context_sensitive/polymorphism/polymorphism_001_T/polymorphism_001_T.go\n AffectedNodeName: call\n 15: CALL: \t__taint_sink(sub.call(__taint_src))\n /sast-go/cases/accuracy/context_sensitive/polymorphism/polymorphism_001_T/polymorphism_001_T.go\n AffectedNodeName: src\n 24: ARG PASS: func (s Sub1) call(src interface{}) interface{} {\n /sast-go/cases/accuracy/context_sensitive/polymorphism/polymorphism_001_T/polymorphism_001_T.go\n AffectedNodeName: [return value]\n 25: Return Value: \treturn src\n /sast-go/cases/accuracy/context_sensitive/polymorphism/polymorphism_001_T/polymorphism_001_T.go\n AffectedNodeName: call\n 15: CALL RETURN: \t__taint_sink(sub.call(__taint_src))\n /sast-go/cases/accuracy/context_sensitive/polymorphism/polymorphism_001_T/polymorphism_001_T.go\n AffectedNodeName: __taint_sink\n 15: SINK: \t__taint_sink(sub.call(__taint_src))\n==========================================================\n #Total-findings:1\n==========================================================","/benchmarks/sast-go/cases/accuracy/context_sensitive/polymorphism/polymorphism_002_F/polymorphism_002_F":"======================== Findings ========================\nNo findings!\n==========================================================","/benchmarks/sast-go/cases/accuracy/context_sensitive/polymorphism/polymorphism_003_T/polymorphism_003_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/sast-go/cases/accuracy/context_sensitive/polymorphism/polymorphism_003_T/polymorphism_003_T.go\nLine 15: __taint_sink(student.Run())\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/sast-go/cases/accuracy/context_sensitive/polymorphism/polymorphism_003_T/polymorphism_003_T.go\",\"functionName\":\"main\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /sast-go/cases/accuracy/context_sensitive/polymorphism/polymorphism_003_T/polymorphism_003_T.go\n AffectedNodeName: __taint_src\n 46: SOURCE: polymorphism_003_T(__taint_src)\n /sast-go/cases/accuracy/context_sensitive/polymorphism/polymorphism_003_T/polymorphism_003_T.go\n AffectedNodeName: polymorphism_003_T\n 46: CALL: polymorphism_003_T(__taint_src)\n /sast-go/cases/accuracy/context_sensitive/polymorphism/polymorphism_003_T/polymorphism_003_T.go\n AffectedNodeName: __taint_src\n 11: ARG PASS: func polymorphism_003_T(__taint_src string) {\n /sast-go/cases/accuracy/context_sensitive/polymorphism/polymorphism_003_T/polymorphism_003_T.go\n AffectedNodeName: student\n 12: Var Pass: \tvar student Person = &Student{Name: __taint_src, Age: 20, GPA: 3.8}\n /sast-go/cases/accuracy/context_sensitive/polymorphism/polymorphism_003_T/polymorphism_003_T.go\n AffectedNodeName: Run\n 15: CALL: \t__taint_sink(student.Run())\n /sast-go/cases/accuracy/context_sensitive/polymorphism/polymorphism_003_T/polymorphism_003_T.go\n AffectedNodeName: student\n 15: ARG PASS: \t__taint_sink(student.Run())\n /sast-go/cases/accuracy/context_sensitive/polymorphism/polymorphism_003_T/polymorphism_003_T.go\n AffectedNodeName: [return value]\n 29: Return Value: \treturn s.Name\n /sast-go/cases/accuracy/context_sensitive/polymorphism/polymorphism_003_T/polymorphism_003_T.go\n AffectedNodeName: Run\n 15: CALL RETURN: \t__taint_sink(student.Run())\n /sast-go/cases/accuracy/context_sensitive/polymorphism/polymorphism_003_T/polymorphism_003_T.go\n AffectedNodeName: __taint_sink\n 15: SINK: \t__taint_sink(student.Run())\n==========================================================\n #Total-findings:1\n==========================================================","/benchmarks/sast-go/cases/accuracy/context_sensitive/polymorphism/polymorphism_004_F/polymorphism_004_F":"======================== Findings ========================\nNo findings!\n==========================================================","/benchmarks/sast-go/cases/accuracy/field_sensitive/multidimensional_collection/array_index_005_T/array_index_005_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/sast-go/cases/accuracy/field_sensitive/multidimensional_collection/array_index_005_T/array_index_005_T.go\nLine 14: __taint_sink(str.0.0)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/sast-go/cases/accuracy/field_sensitive/multidimensional_collection/array_index_005_T/array_index_005_T.go\",\"functionName\":\"main\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /sast-go/cases/accuracy/field_sensitive/multidimensional_collection/array_index_005_T/array_index_005_T.go\n AffectedNodeName: __taint_src\n 21: SOURCE: array_index_005_T(__taint_src)\n /sast-go/cases/accuracy/field_sensitive/multidimensional_collection/array_index_005_T/array_index_005_T.go\n AffectedNodeName: array_index_005_T\n 21: CALL: array_index_005_T(__taint_src)\n /sast-go/cases/accuracy/field_sensitive/multidimensional_collection/array_index_005_T/array_index_005_T.go\n AffectedNodeName: __taint_src\n 12: ARG PASS: func array_index_005_T(__taint_src string) {\n /sast-go/cases/accuracy/field_sensitive/multidimensional_collection/array_index_005_T/array_index_005_T.go\n AffectedNodeName: str\n 13: Var Pass: \tvar str = [3][1]string{[1]string{__taint_src}, [1]string{\"b\"}, [1]string{\"c\"}}\n /sast-go/cases/accuracy/field_sensitive/multidimensional_collection/array_index_005_T/array_index_005_T.go\n AffectedNodeName: __taint_sink\n 14: SINK: \t__taint_sink(str[0][0])\n==========================================================\n #Total-findings:1\n==========================================================","/benchmarks/sast-go/cases/accuracy/field_sensitive/multidimensional_collection/array_index_006_F/array_index_006_F":"======================== Findings ========================\nNo findings!\n==========================================================","/benchmarks/sast-go/cases/accuracy/field_sensitive/multidimensional_collection/slice_index_003_T/slice_index_003_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/sast-go/cases/accuracy/field_sensitive/multidimensional_collection/slice_index_003_T/slice_index_003_T.go\nLine 18: __taint_sink(s.2.2)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/sast-go/cases/accuracy/field_sensitive/multidimensional_collection/slice_index_003_T/slice_index_003_T.go\",\"functionName\":\"main\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /sast-go/cases/accuracy/field_sensitive/multidimensional_collection/slice_index_003_T/slice_index_003_T.go\n AffectedNodeName: __taint_src\n 25: SOURCE: slice_index_003_T(__taint_src)\n /sast-go/cases/accuracy/field_sensitive/multidimensional_collection/slice_index_003_T/slice_index_003_T.go\n AffectedNodeName: slice_index_003_T\n 25: CALL: slice_index_003_T(__taint_src)\n /sast-go/cases/accuracy/field_sensitive/multidimensional_collection/slice_index_003_T/slice_index_003_T.go\n AffectedNodeName: __taint_src\n 12: ARG PASS: func slice_index_003_T(__taint_src string) {\n /sast-go/cases/accuracy/field_sensitive/multidimensional_collection/slice_index_003_T/slice_index_003_T.go\n AffectedNodeName: s\n 13: Var Pass: \ts := [][]string{\n 14: Var Pass: \t\t[]string{\"a\"},\n 15: Var Pass: \t\t[]string{\"b\", \"c\"},\n 16: Var Pass: \t\t[]string{\"d\", \"e\", __taint_src},\n 17: Var Pass: \t}\n /sast-go/cases/accuracy/field_sensitive/multidimensional_collection/slice_index_003_T/slice_index_003_T.go\n AffectedNodeName: __taint_sink\n 18: SINK: \t__taint_sink(s[2][2])\n==========================================================\n #Total-findings:1\n==========================================================","/benchmarks/sast-go/cases/accuracy/field_sensitive/multidimensional_collection/slice_index_004_F/slice_index_004_F":"======================== Findings ========================\nNo findings!\n==========================================================","/benchmarks/sast-go/cases/accuracy/field_sensitive/one_dimensional_collection/numeric_index_state_no_solver/array_index_001_T/array_index_001_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/sast-go/cases/accuracy/field_sensitive/one_dimensional_collection/numeric_index_state_no_solver/array_index_001_T/array_index_001_T.go\nLine 14: __taint_sink(str.0)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/sast-go/cases/accuracy/field_sensitive/one_dimensional_collection/numeric_index_state_no_solver/array_index_001_T/array_index_001_T.go\",\"functionName\":\"main\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /sast-go/cases/accuracy/field_sensitive/one_dimensional_collection/numeric_index_state_no_solver/array_index_001_T/array_index_001_T.go\n AffectedNodeName: __taint_src\n 21: SOURCE: array_index_001_T(__taint_src)\n /sast-go/cases/accuracy/field_sensitive/one_dimensional_collection/numeric_index_state_no_solver/array_index_001_T/array_index_001_T.go\n AffectedNodeName: array_index_001_T\n 21: CALL: array_index_001_T(__taint_src)\n /sast-go/cases/accuracy/field_sensitive/one_dimensional_collection/numeric_index_state_no_solver/array_index_001_T/array_index_001_T.go\n AffectedNodeName: __taint_src\n 12: ARG PASS: func array_index_001_T(__taint_src string) {\n /sast-go/cases/accuracy/field_sensitive/one_dimensional_collection/numeric_index_state_no_solver/array_index_001_T/array_index_001_T.go\n AffectedNodeName: str\n 13: Var Pass: \tvar str = [3]string{__taint_src, \"b\", \"c\"}\n /sast-go/cases/accuracy/field_sensitive/one_dimensional_collection/numeric_index_state_no_solver/array_index_001_T/array_index_001_T.go\n AffectedNodeName: __taint_sink\n 14: SINK: \t__taint_sink(str[0])\n==========================================================\n #Total-findings:1\n==========================================================","/benchmarks/sast-go/cases/accuracy/field_sensitive/one_dimensional_collection/numeric_index_state_no_solver/array_index_002_F/array_index_002_F":"======================== Findings ========================\nNo findings!\n==========================================================","/benchmarks/sast-go/cases/accuracy/field_sensitive/one_dimensional_collection/numeric_index_state_no_solver/array_index_003_T/array_index_003_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/sast-go/cases/accuracy/field_sensitive/one_dimensional_collection/numeric_index_state_no_solver/array_index_003_T/array_index_003_T.go\nLine 15: __taint_sink(str)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/sast-go/cases/accuracy/field_sensitive/one_dimensional_collection/numeric_index_state_no_solver/array_index_003_T/array_index_003_T.go\",\"functionName\":\"main\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /sast-go/cases/accuracy/field_sensitive/one_dimensional_collection/numeric_index_state_no_solver/array_index_003_T/array_index_003_T.go\n AffectedNodeName: __taint_src\n 22: SOURCE: array_index_003_T(__taint_src)\n /sast-go/cases/accuracy/field_sensitive/one_dimensional_collection/numeric_index_state_no_solver/array_index_003_T/array_index_003_T.go\n AffectedNodeName: array_index_003_T\n 22: CALL: array_index_003_T(__taint_src)\n /sast-go/cases/accuracy/field_sensitive/one_dimensional_collection/numeric_index_state_no_solver/array_index_003_T/array_index_003_T.go\n AffectedNodeName: __taint_src\n 12: ARG PASS: func array_index_003_T(__taint_src string) {\n /sast-go/cases/accuracy/field_sensitive/one_dimensional_collection/numeric_index_state_no_solver/array_index_003_T/array_index_003_T.go\n AffectedNodeName: str\n 13: Var Pass: \tvar str = [3]string{__taint_src, \"b\", \"c\"}\n /sast-go/cases/accuracy/field_sensitive/one_dimensional_collection/numeric_index_state_no_solver/array_index_003_T/array_index_003_T.go\n AffectedNodeName: __taint_sink\n 15: SINK: \t__taint_sink(str)\n==========================================================\n #Total-findings:1\n==========================================================","/benchmarks/sast-go/cases/accuracy/field_sensitive/one_dimensional_collection/numeric_index_state_no_solver/array_index_004_F/array_index_004_F":"======================== Findings ========================\nNo findings!\n==========================================================","/benchmarks/sast-go/cases/accuracy/field_sensitive/one_dimensional_collection/numeric_index_state_no_solver/map_field_sensitive_001_T/map_field_sensitive_001_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/sast-go/cases/accuracy/field_sensitive/one_dimensional_collection/numeric_index_state_no_solver/map_field_sensitive_001_T/map_field_sensitive_001_T.go\nLine 16: __taint_sink(m.\"key1\")\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/sast-go/cases/accuracy/field_sensitive/one_dimensional_collection/numeric_index_state_no_solver/map_field_sensitive_001_T/map_field_sensitive_001_T.go\",\"functionName\":\"main\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /sast-go/cases/accuracy/field_sensitive/one_dimensional_collection/numeric_index_state_no_solver/map_field_sensitive_001_T/map_field_sensitive_001_T.go\n AffectedNodeName: __taint_src\n 23: SOURCE: map_field_sensitive_001_T(__taint_src)\n /sast-go/cases/accuracy/field_sensitive/one_dimensional_collection/numeric_index_state_no_solver/map_field_sensitive_001_T/map_field_sensitive_001_T.go\n AffectedNodeName: map_field_sensitive_001_T\n 23: CALL: map_field_sensitive_001_T(__taint_src)\n /sast-go/cases/accuracy/field_sensitive/one_dimensional_collection/numeric_index_state_no_solver/map_field_sensitive_001_T/map_field_sensitive_001_T.go\n AffectedNodeName: __taint_src\n 12: ARG PASS: func map_field_sensitive_001_T(__taint_src string) {\n /sast-go/cases/accuracy/field_sensitive/one_dimensional_collection/numeric_index_state_no_solver/map_field_sensitive_001_T/map_field_sensitive_001_T.go\n AffectedNodeName: m[\"key1\"]\n 14: Var Pass: \tm[\"key1\"] = __taint_src\n /sast-go/cases/accuracy/field_sensitive/one_dimensional_collection/numeric_index_state_no_solver/map_field_sensitive_001_T/map_field_sensitive_001_T.go\n AffectedNodeName: __taint_sink\n 16: SINK: \t__taint_sink(m[\"key1\"])\n==========================================================\n #Total-findings:1\n==========================================================","/benchmarks/sast-go/cases/accuracy/field_sensitive/one_dimensional_collection/numeric_index_state_no_solver/map_field_sensitive_002_F/map_field_sensitive_002_F":"======================== Findings ========================\nNo findings!\n==========================================================","/benchmarks/sast-go/cases/accuracy/field_sensitive/one_dimensional_collection/numeric_index_state_no_solver/map_field_sensitive_003_F/map_field_sensitive_003_F":"======================== Findings ========================\nNo findings!\n==========================================================","/benchmarks/sast-go/cases/accuracy/field_sensitive/one_dimensional_collection/numeric_index_state_no_solver/map_field_sensitive_004_T/map_field_sensitive_004_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/sast-go/cases/accuracy/field_sensitive/one_dimensional_collection/numeric_index_state_no_solver/map_field_sensitive_004_T/map_field_sensitive_004_T.go\nLine 18: __taint_sink(m.\"key2\")\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/sast-go/cases/accuracy/field_sensitive/one_dimensional_collection/numeric_index_state_no_solver/map_field_sensitive_004_T/map_field_sensitive_004_T.go\",\"functionName\":\"main\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /sast-go/cases/accuracy/field_sensitive/one_dimensional_collection/numeric_index_state_no_solver/map_field_sensitive_004_T/map_field_sensitive_004_T.go\n AffectedNodeName: __taint_src\n 25: SOURCE: map_field_sensitive_004_T(__taint_src)\n /sast-go/cases/accuracy/field_sensitive/one_dimensional_collection/numeric_index_state_no_solver/map_field_sensitive_004_T/map_field_sensitive_004_T.go\n AffectedNodeName: map_field_sensitive_004_T\n 25: CALL: map_field_sensitive_004_T(__taint_src)\n /sast-go/cases/accuracy/field_sensitive/one_dimensional_collection/numeric_index_state_no_solver/map_field_sensitive_004_T/map_field_sensitive_004_T.go\n AffectedNodeName: __taint_src\n 12: ARG PASS: func map_field_sensitive_004_T(__taint_src string) {\n /sast-go/cases/accuracy/field_sensitive/one_dimensional_collection/numeric_index_state_no_solver/map_field_sensitive_004_T/map_field_sensitive_004_T.go\n AffectedNodeName: m[\"key2\"]\n 16: Var Pass: \tm[\"key2\"] = __taint_src\n /sast-go/cases/accuracy/field_sensitive/one_dimensional_collection/numeric_index_state_no_solver/map_field_sensitive_004_T/map_field_sensitive_004_T.go\n AffectedNodeName: __taint_sink\n 18: SINK: \t__taint_sink(m[\"key2\"])\n==========================================================\n #Total-findings:1\n==========================================================","/benchmarks/sast-go/cases/accuracy/field_sensitive/one_dimensional_collection/numeric_index_state_no_solver/map_field_sensitive_005_F/map_field_sensitive_005_F":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/sast-go/cases/accuracy/field_sensitive/one_dimensional_collection/numeric_index_state_no_solver/map_field_sensitive_005_F/map_field_sensitive_005_F.go\nLine 17: __taint_sink(m.\"key1\")\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/sast-go/cases/accuracy/field_sensitive/one_dimensional_collection/numeric_index_state_no_solver/map_field_sensitive_005_F/map_field_sensitive_005_F.go\",\"functionName\":\"main\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /sast-go/cases/accuracy/field_sensitive/one_dimensional_collection/numeric_index_state_no_solver/map_field_sensitive_005_F/map_field_sensitive_005_F.go\n AffectedNodeName: __taint_src\n 24: SOURCE: map_field_sensitive_005_F(__taint_src)\n /sast-go/cases/accuracy/field_sensitive/one_dimensional_collection/numeric_index_state_no_solver/map_field_sensitive_005_F/map_field_sensitive_005_F.go\n AffectedNodeName: map_field_sensitive_005_F\n 24: CALL: map_field_sensitive_005_F(__taint_src)\n /sast-go/cases/accuracy/field_sensitive/one_dimensional_collection/numeric_index_state_no_solver/map_field_sensitive_005_F/map_field_sensitive_005_F.go\n AffectedNodeName: __taint_src\n 12: ARG PASS: func map_field_sensitive_005_F(__taint_src string) {\n /sast-go/cases/accuracy/field_sensitive/one_dimensional_collection/numeric_index_state_no_solver/map_field_sensitive_005_F/map_field_sensitive_005_F.go\n AffectedNodeName: m[\"key1\"]\n 14: Var Pass: \tm[\"key1\"] = __taint_src\n /sast-go/cases/accuracy/field_sensitive/one_dimensional_collection/numeric_index_state_no_solver/map_field_sensitive_005_F/map_field_sensitive_005_F.go\n AffectedNodeName: __taint_sink\n 17: SINK: \t__taint_sink(m[\"key1\"])\n==========================================================\n #Total-findings:1\n==========================================================","/benchmarks/sast-go/cases/accuracy/field_sensitive/one_dimensional_collection/numeric_index_state_no_solver/slice_index_001_T/slice_index_001_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/sast-go/cases/accuracy/field_sensitive/one_dimensional_collection/numeric_index_state_no_solver/slice_index_001_T/slice_index_001_T.go\nLine 14: __taint_sink(s.0)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/sast-go/cases/accuracy/field_sensitive/one_dimensional_collection/numeric_index_state_no_solver/slice_index_001_T/slice_index_001_T.go\",\"functionName\":\"main\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /sast-go/cases/accuracy/field_sensitive/one_dimensional_collection/numeric_index_state_no_solver/slice_index_001_T/slice_index_001_T.go\n AffectedNodeName: __taint_src\n 21: SOURCE: slice_index_001_T(__taint_src)\n /sast-go/cases/accuracy/field_sensitive/one_dimensional_collection/numeric_index_state_no_solver/slice_index_001_T/slice_index_001_T.go\n AffectedNodeName: slice_index_001_T\n 21: CALL: slice_index_001_T(__taint_src)\n /sast-go/cases/accuracy/field_sensitive/one_dimensional_collection/numeric_index_state_no_solver/slice_index_001_T/slice_index_001_T.go\n AffectedNodeName: __taint_src\n 12: ARG PASS: func slice_index_001_T(__taint_src string) {\n /sast-go/cases/accuracy/field_sensitive/one_dimensional_collection/numeric_index_state_no_solver/slice_index_001_T/slice_index_001_T.go\n AffectedNodeName: s\n 13: Var Pass: \tvar s []string = []string{__taint_src, \"b\", \"c\"}\n /sast-go/cases/accuracy/field_sensitive/one_dimensional_collection/numeric_index_state_no_solver/slice_index_001_T/slice_index_001_T.go\n AffectedNodeName: __taint_sink\n 14: SINK: \t__taint_sink(s[0])\n==========================================================\n #Total-findings:1\n==========================================================","/benchmarks/sast-go/cases/accuracy/field_sensitive/one_dimensional_collection/numeric_index_state_no_solver/slice_index_002_F/slice_index_002_F":"======================== Findings ========================\nNo findings!\n==========================================================","/benchmarks/sast-go/cases/accuracy/field_sensitive/one_dimensional_collection/numeric_index_state_no_solver/slice_index_005_T/slice_index_005_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/sast-go/cases/accuracy/field_sensitive/one_dimensional_collection/numeric_index_state_no_solver/slice_index_005_T/slice_index_005_T.go\nLine 16: __taint_sink(s.0)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/sast-go/cases/accuracy/field_sensitive/one_dimensional_collection/numeric_index_state_no_solver/slice_index_005_T/slice_index_005_T.go\",\"functionName\":\"main\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /sast-go/cases/accuracy/field_sensitive/one_dimensional_collection/numeric_index_state_no_solver/slice_index_005_T/slice_index_005_T.go\n AffectedNodeName: __taint_src\n 23: SOURCE: slice_index_005_T(__taint_src)\n /sast-go/cases/accuracy/field_sensitive/one_dimensional_collection/numeric_index_state_no_solver/slice_index_005_T/slice_index_005_T.go\n AffectedNodeName: slice_index_005_T\n 23: CALL: slice_index_005_T(__taint_src)\n /sast-go/cases/accuracy/field_sensitive/one_dimensional_collection/numeric_index_state_no_solver/slice_index_005_T/slice_index_005_T.go\n AffectedNodeName: __taint_src\n 12: ARG PASS: func slice_index_005_T(__taint_src string) {\n /sast-go/cases/accuracy/field_sensitive/one_dimensional_collection/numeric_index_state_no_solver/slice_index_005_T/slice_index_005_T.go\n AffectedNodeName: arr\n 13: Var Pass: \tvar arr [3]string = [3]string{__taint_src, \"b\", \"c\"}\n /sast-go/cases/accuracy/field_sensitive/one_dimensional_collection/numeric_index_state_no_solver/slice_index_005_T/slice_index_005_T.go\n AffectedNodeName: s\n 15: Var Pass: \ts = arr[:]\n /sast-go/cases/accuracy/field_sensitive/one_dimensional_collection/numeric_index_state_no_solver/slice_index_005_T/slice_index_005_T.go\n AffectedNodeName: __taint_sink\n 16: SINK: \t__taint_sink(s[0])\n==========================================================\n #Total-findings:1\n==========================================================","/benchmarks/sast-go/cases/accuracy/field_sensitive/one_dimensional_collection/numeric_index_state_no_solver/slice_index_006_F/slice_index_006_F":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/sast-go/cases/accuracy/field_sensitive/one_dimensional_collection/numeric_index_state_no_solver/slice_index_006_F/slice_index_006_F.go\nLine 16: __taint_sink(s.0)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/sast-go/cases/accuracy/field_sensitive/one_dimensional_collection/numeric_index_state_no_solver/slice_index_006_F/slice_index_006_F.go\",\"functionName\":\"main\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /sast-go/cases/accuracy/field_sensitive/one_dimensional_collection/numeric_index_state_no_solver/slice_index_006_F/slice_index_006_F.go\n AffectedNodeName: __taint_src\n 23: SOURCE: slice_index_006_F(__taint_src)\n /sast-go/cases/accuracy/field_sensitive/one_dimensional_collection/numeric_index_state_no_solver/slice_index_006_F/slice_index_006_F.go\n AffectedNodeName: slice_index_006_F\n 23: CALL: slice_index_006_F(__taint_src)\n /sast-go/cases/accuracy/field_sensitive/one_dimensional_collection/numeric_index_state_no_solver/slice_index_006_F/slice_index_006_F.go\n AffectedNodeName: __taint_src\n 12: ARG PASS: func slice_index_006_F(__taint_src string) {\n /sast-go/cases/accuracy/field_sensitive/one_dimensional_collection/numeric_index_state_no_solver/slice_index_006_F/slice_index_006_F.go\n AffectedNodeName: arr\n 13: Var Pass: \tvar arr [3]string = [3]string{__taint_src, \"b\", \"c\"}\n /sast-go/cases/accuracy/field_sensitive/one_dimensional_collection/numeric_index_state_no_solver/slice_index_006_F/slice_index_006_F.go\n AffectedNodeName: s\n 15: Var Pass: \ts = arr[1:]\n /sast-go/cases/accuracy/field_sensitive/one_dimensional_collection/numeric_index_state_no_solver/slice_index_006_F/slice_index_006_F.go\n AffectedNodeName: __taint_sink\n 16: SINK: \t__taint_sink(s[0])\n==========================================================\n #Total-findings:1\n==========================================================","/benchmarks/sast-go/cases/accuracy/field_sensitive/one_dimensional_collection/numeric_index_state_solver/array_index_007_T/array_index_007_T":"======================== Findings ========================\nNo findings!\n==========================================================","/benchmarks/sast-go/cases/accuracy/field_sensitive/one_dimensional_collection/numeric_index_state_solver/array_index_008_F/array_index_008_F":"======================== Findings ========================\nNo findings!\n==========================================================","/benchmarks/sast-go/cases/accuracy/field_sensitive/struct/field_len_001_T/field_len_001_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/sast-go/cases/accuracy/field_sensitive/struct/field_len_001_T/field_len_001_T.go\nLine 30: __taint_sink(c.b.a.data)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/sast-go/cases/accuracy/field_sensitive/struct/field_len_001_T/field_len_001_T.go\",\"functionName\":\"main\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /sast-go/cases/accuracy/field_sensitive/struct/field_len_001_T/field_len_001_T.go\n AffectedNodeName: __taint_src\n 37: SOURCE: field_len_001_T(__taint_src)\n /sast-go/cases/accuracy/field_sensitive/struct/field_len_001_T/field_len_001_T.go\n AffectedNodeName: field_len_001_T\n 37: CALL: field_len_001_T(__taint_src)\n /sast-go/cases/accuracy/field_sensitive/struct/field_len_001_T/field_len_001_T.go\n AffectedNodeName: __taint_src\n 22: ARG PASS: func field_len_001_T(__taint_src string) {\n /sast-go/cases/accuracy/field_sensitive/struct/field_len_001_T/field_len_001_T.go\n AffectedNodeName: pa\n 23: Var Pass: \tpa := A{\n 24: Var Pass: \t\tdata: __taint_src,\n 25: Var Pass: \t}\n /sast-go/cases/accuracy/field_sensitive/struct/field_len_001_T/field_len_001_T.go\n AffectedNodeName: [b.a]\n 27: Var Pass: \tb.a = pa\n /sast-go/cases/accuracy/field_sensitive/struct/field_len_001_T/field_len_001_T.go\n AffectedNodeName: [c.b]\n 29: Var Pass: \tc.b = b\n /sast-go/cases/accuracy/field_sensitive/struct/field_len_001_T/field_len_001_T.go\n AffectedNodeName: __taint_sink\n 30: SINK: \t__taint_sink(c.b.a.data)\n==========================================================\n #Total-findings:1\n==========================================================","/benchmarks/sast-go/cases/accuracy/field_sensitive/struct/field_len_002_F/field_len_002_F":"======================== Findings ========================\nNo findings!\n==========================================================","/benchmarks/sast-go/cases/accuracy/field_sensitive/struct/field_len_003_T/field_len_003_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/sast-go/cases/accuracy/field_sensitive/struct/field_len_003_T/field_len_003_T.go\nLine 100: __taint_sink(q.p.o.n.m.l.k.j.i.h.g.f.e.d.c.b.a.data)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/sast-go/cases/accuracy/field_sensitive/struct/field_len_003_T/field_len_003_T.go\",\"functionName\":\"main\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /sast-go/cases/accuracy/field_sensitive/struct/field_len_003_T/field_len_003_T.go\n AffectedNodeName: __taint_src\n 107: SOURCE: field_len_003_T(__taint_src)\n /sast-go/cases/accuracy/field_sensitive/struct/field_len_003_T/field_len_003_T.go\n AffectedNodeName: field_len_003_T\n 107: CALL: field_len_003_T(__taint_src)\n /sast-go/cases/accuracy/field_sensitive/struct/field_len_003_T/field_len_003_T.go\n AffectedNodeName: __taint_src\n 64: ARG PASS: func field_len_003_T(__taint_src string) {\n /sast-go/cases/accuracy/field_sensitive/struct/field_len_003_T/field_len_003_T.go\n AffectedNodeName: pa\n 65: Var Pass: \tpa := A{\n 66: Var Pass: \t\tdata: __taint_src,\n 67: Var Pass: \t}\n /sast-go/cases/accuracy/field_sensitive/struct/field_len_003_T/field_len_003_T.go\n AffectedNodeName: [b.a]\n 69: Var Pass: \tb.a = pa\n /sast-go/cases/accuracy/field_sensitive/struct/field_len_003_T/field_len_003_T.go\n AffectedNodeName: [c.b]\n 71: Var Pass: \tc.b = b\n /sast-go/cases/accuracy/field_sensitive/struct/field_len_003_T/field_len_003_T.go\n AffectedNodeName: [d.c]\n 73: Var Pass: \td.c = c\n /sast-go/cases/accuracy/field_sensitive/struct/field_len_003_T/field_len_003_T.go\n AffectedNodeName: [e.d]\n 75: Var Pass: \te.d = d\n /sast-go/cases/accuracy/field_sensitive/struct/field_len_003_T/field_len_003_T.go\n AffectedNodeName: [f.e]\n 77: Var Pass: \tf.e = e\n /sast-go/cases/accuracy/field_sensitive/struct/field_len_003_T/field_len_003_T.go\n AffectedNodeName: [g.f]\n 79: Var Pass: \tg.f = f\n /sast-go/cases/accuracy/field_sensitive/struct/field_len_003_T/field_len_003_T.go\n AffectedNodeName: [h.g]\n 81: Var Pass: \th.g = g\n /sast-go/cases/accuracy/field_sensitive/struct/field_len_003_T/field_len_003_T.go\n AffectedNodeName: [i.h]\n 83: Var Pass: \ti.h = h\n /sast-go/cases/accuracy/field_sensitive/struct/field_len_003_T/field_len_003_T.go\n AffectedNodeName: [j.i]\n 85: Var Pass: \tj.i = i\n /sast-go/cases/accuracy/field_sensitive/struct/field_len_003_T/field_len_003_T.go\n AffectedNodeName: [k.j]\n 87: Var Pass: \tk.j = j\n /sast-go/cases/accuracy/field_sensitive/struct/field_len_003_T/field_len_003_T.go\n AffectedNodeName: [l.k]\n 89: Var Pass: \tl.k = k\n /sast-go/cases/accuracy/field_sensitive/struct/field_len_003_T/field_len_003_T.go\n AffectedNodeName: [m.l]\n 91: Var Pass: \tm.l = l\n /sast-go/cases/accuracy/field_sensitive/struct/field_len_003_T/field_len_003_T.go\n AffectedNodeName: [n.m]\n 93: Var Pass: \tn.m = m\n /sast-go/cases/accuracy/field_sensitive/struct/field_len_003_T/field_len_003_T.go\n AffectedNodeName: [o.n]\n 95: Var Pass: \to.n = n\n /sast-go/cases/accuracy/field_sensitive/struct/field_len_003_T/field_len_003_T.go\n AffectedNodeName: [p.o]\n 97: Var Pass: \tp.o = o\n /sast-go/cases/accuracy/field_sensitive/struct/field_len_003_T/field_len_003_T.go\n AffectedNodeName: [q.p]\n 99: Var Pass: \tq.p = p\n /sast-go/cases/accuracy/field_sensitive/struct/field_len_003_T/field_len_003_T.go\n AffectedNodeName: __taint_sink\n 100: SINK: \t__taint_sink(q.p.o.n.m.l.k.j.i.h.g.f.e.d.c.b.a.data)\n==========================================================\n #Total-findings:1\n==========================================================","/benchmarks/sast-go/cases/accuracy/field_sensitive/struct/field_len_004_F/field_len_004_F":"======================== Findings ========================\nNo findings!\n==========================================================","/benchmarks/sast-go/cases/accuracy/field_sensitive/struct/field_len_005_T/field_len_005_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/sast-go/cases/accuracy/field_sensitive/struct/field_len_005_T/field_len_005_T.go\nLine 47: __taint_sink(q)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/sast-go/cases/accuracy/field_sensitive/struct/field_len_005_T/field_len_005_T.go\",\"functionName\":\"main\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /sast-go/cases/accuracy/field_sensitive/struct/field_len_005_T/field_len_005_T.go\n AffectedNodeName: __taint_src\n 54: SOURCE: field_len_005_T(__taint_src)\n /sast-go/cases/accuracy/field_sensitive/struct/field_len_005_T/field_len_005_T.go\n AffectedNodeName: field_len_005_T\n 54: CALL: field_len_005_T(__taint_src)\n /sast-go/cases/accuracy/field_sensitive/struct/field_len_005_T/field_len_005_T.go\n AffectedNodeName: __taint_src\n 31: ARG PASS: func field_len_005_T(__taint_src string) {\n /sast-go/cases/accuracy/field_sensitive/struct/field_len_005_T/field_len_005_T.go\n AffectedNodeName: pa\n 32: Var Pass: \tpa := A{\n 33: Var Pass: \t\tdata: __taint_src,\n 34: Var Pass: \t}\n /sast-go/cases/accuracy/field_sensitive/struct/field_len_005_T/field_len_005_T.go\n AffectedNodeName: [b.a]\n 36: Var Pass: \tb.a = pa\n /sast-go/cases/accuracy/field_sensitive/struct/field_len_005_T/field_len_005_T.go\n AffectedNodeName: [c.b]\n 38: Var Pass: \tc.b = b\n /sast-go/cases/accuracy/field_sensitive/struct/field_len_005_T/field_len_005_T.go\n AffectedNodeName: [d.c]\n 40: Var Pass: \td.c = c\n /sast-go/cases/accuracy/field_sensitive/struct/field_len_005_T/field_len_005_T.go\n AffectedNodeName: [e.d]\n 42: Var Pass: \te.d = d\n /sast-go/cases/accuracy/field_sensitive/struct/field_len_005_T/field_len_005_T.go\n AffectedNodeName: [f.e]\n 44: Var Pass: \tf.e = e\n /sast-go/cases/accuracy/field_sensitive/struct/field_len_005_T/field_len_005_T.go\n AffectedNodeName: p\n 45: Var Pass: \tp := f.e.d.c\n /sast-go/cases/accuracy/field_sensitive/struct/field_len_005_T/field_len_005_T.go\n AffectedNodeName: q\n 46: Var Pass: \tq := p.b.a.data\n /sast-go/cases/accuracy/field_sensitive/struct/field_len_005_T/field_len_005_T.go\n AffectedNodeName: __taint_sink\n 47: SINK: \t__taint_sink(q)\n==========================================================\n #Total-findings:1\n==========================================================","/benchmarks/sast-go/cases/accuracy/field_sensitive/struct/field_len_006_F/field_len_006_F":"======================== Findings ========================\nNo findings!\n==========================================================","/benchmarks/sast-go/cases/accuracy/field_sensitive/struct/struct_field_001_T/struct_field_001_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/sast-go/cases/accuracy/field_sensitive/struct/struct_field_001_T/struct_field_001_T.go\nLine 22: __taint_sink(p.data)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/sast-go/cases/accuracy/field_sensitive/struct/struct_field_001_T/struct_field_001_T.go\",\"functionName\":\"main\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /sast-go/cases/accuracy/field_sensitive/struct/struct_field_001_T/struct_field_001_T.go\n AffectedNodeName: __taint_src\n 29: SOURCE: struct_field_001_T(__taint_src)\n /sast-go/cases/accuracy/field_sensitive/struct/struct_field_001_T/struct_field_001_T.go\n AffectedNodeName: struct_field_001_T\n 29: CALL: struct_field_001_T(__taint_src)\n /sast-go/cases/accuracy/field_sensitive/struct/struct_field_001_T/struct_field_001_T.go\n AffectedNodeName: __taint_src\n 17: ARG PASS: func struct_field_001_T(__taint_src string) {\n /sast-go/cases/accuracy/field_sensitive/struct/struct_field_001_T/struct_field_001_T.go\n AffectedNodeName: p\n 18: Var Pass: \tp := A{\n 19: Var Pass: \t\tdata: __taint_src,\n 20: Var Pass: \t\tsani: \"_\",\n 21: Var Pass: \t}\n /sast-go/cases/accuracy/field_sensitive/struct/struct_field_001_T/struct_field_001_T.go\n AffectedNodeName: __taint_sink\n 22: SINK: \t__taint_sink(p.data)\n==========================================================\n #Total-findings:1\n==========================================================","/benchmarks/sast-go/cases/accuracy/field_sensitive/struct/struct_field_002_F/struct_field_002_F":"======================== Findings ========================\nNo findings!\n==========================================================","/benchmarks/sast-go/cases/accuracy/field_sensitive/struct/struct_field_003_T/struct_field_003_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/sast-go/cases/accuracy/field_sensitive/struct/struct_field_003_T/struct_field_003_T.go\nLine 21: __taint_sink(p1.data)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/sast-go/cases/accuracy/field_sensitive/struct/struct_field_003_T/struct_field_003_T.go\",\"functionName\":\"main\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /sast-go/cases/accuracy/field_sensitive/struct/struct_field_003_T/struct_field_003_T.go\n AffectedNodeName: __taint_src\n 28: SOURCE: struct_field_003_T(__taint_src)\n /sast-go/cases/accuracy/field_sensitive/struct/struct_field_003_T/struct_field_003_T.go\n AffectedNodeName: struct_field_003_T\n 28: CALL: struct_field_003_T(__taint_src)\n /sast-go/cases/accuracy/field_sensitive/struct/struct_field_003_T/struct_field_003_T.go\n AffectedNodeName: __taint_src\n 17: ARG PASS: func struct_field_003_T(__taint_src string) {\n /sast-go/cases/accuracy/field_sensitive/struct/struct_field_003_T/struct_field_003_T.go\n AffectedNodeName: [p1.data]\n 19: Var Pass: \tp1.data = __taint_src\n /sast-go/cases/accuracy/field_sensitive/struct/struct_field_003_T/struct_field_003_T.go\n AffectedNodeName: __taint_sink\n 21: SINK: \t__taint_sink(p1.data)\n==========================================================\n #Total-findings:1\n==========================================================","/benchmarks/sast-go/cases/accuracy/field_sensitive/struct/struct_field_004_F/struct_field_004_F":"======================== Findings ========================\nNo findings!\n==========================================================","/benchmarks/sast-go/cases/accuracy/field_sensitive/struct/struct_field_005_T/struct_field_005_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/sast-go/cases/accuracy/field_sensitive/struct/struct_field_005_T/struct_field_005_T.go\nLine 19: __taint_sink(p1.string)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/sast-go/cases/accuracy/field_sensitive/struct/struct_field_005_T/struct_field_005_T.go\",\"functionName\":\"main\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /sast-go/cases/accuracy/field_sensitive/struct/struct_field_005_T/struct_field_005_T.go\n AffectedNodeName: __taint_src\n 26: SOURCE: struct_field_005_T(__taint_src)\n /sast-go/cases/accuracy/field_sensitive/struct/struct_field_005_T/struct_field_005_T.go\n AffectedNodeName: struct_field_005_T\n 26: CALL: struct_field_005_T(__taint_src)\n /sast-go/cases/accuracy/field_sensitive/struct/struct_field_005_T/struct_field_005_T.go\n AffectedNodeName: __taint_src\n 16: ARG PASS: func struct_field_005_T(__taint_src string) {\n /sast-go/cases/accuracy/field_sensitive/struct/struct_field_005_T/struct_field_005_T.go\n AffectedNodeName: [p1.string]\n 18: Var Pass: \tp1.string = __taint_src\n /sast-go/cases/accuracy/field_sensitive/struct/struct_field_005_T/struct_field_005_T.go\n AffectedNodeName: __taint_sink\n 19: SINK: \t__taint_sink(p1.string)\n==========================================================\n #Total-findings:1\n==========================================================","/benchmarks/sast-go/cases/accuracy/field_sensitive/struct/struct_field_006_F/struct_field_006_F":"======================== Findings ========================\nNo findings!\n==========================================================","/benchmarks/sast-go/cases/accuracy/flow_sensitive/asynchronous/asynchronous_execution_001_T/asynchronous_execution_001_T":"======================== Findings ========================\nNo findings!\n==========================================================","/benchmarks/sast-go/cases/accuracy/flow_sensitive/asynchronous/asynchronous_execution_002_F/asynchronous_execution_002_F":"======================== Findings ========================\nNo findings!\n==========================================================","/benchmarks/sast-go/cases/accuracy/flow_sensitive/defer_exectution/defer_exectution_001_T/defer_exectution_001_T":"======================== Findings ========================\nNo findings!\n==========================================================","/benchmarks/sast-go/cases/accuracy/flow_sensitive/defer_exectution/defer_exectution_002_F/defer_exectution_002_F":"======================== Findings ========================\nNo findings!\n==========================================================","/benchmarks/sast-go/cases/accuracy/flow_sensitive/loop_stmt/for_001_T/for_001_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/sast-go/cases/accuracy/flow_sensitive/loop_stmt/for_001_T/for_001_T.go\nLine 16: __taint_sink(res)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/sast-go/cases/accuracy/flow_sensitive/loop_stmt/for_001_T/for_001_T.go\",\"functionName\":\"main\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /sast-go/cases/accuracy/flow_sensitive/loop_stmt/for_001_T/for_001_T.go\n AffectedNodeName: __taint_src\n 23: SOURCE: for_001_T(__taint_src)\n /sast-go/cases/accuracy/flow_sensitive/loop_stmt/for_001_T/for_001_T.go\n AffectedNodeName: for_001_T\n 23: CALL: for_001_T(__taint_src)\n /sast-go/cases/accuracy/flow_sensitive/loop_stmt/for_001_T/for_001_T.go\n AffectedNodeName: __taint_src\n 12: ARG PASS: func for_001_T(__taint_src string) {\n /sast-go/cases/accuracy/flow_sensitive/loop_stmt/for_001_T/for_001_T.go\n AffectedNodeName: res\n 15: Var Pass: \t\tres = __taint_src\n /sast-go/cases/accuracy/flow_sensitive/loop_stmt/for_001_T/for_001_T.go\n AffectedNodeName: __taint_sink\n 16: SINK: \t\t__taint_sink(res)\n==========================================================\n #Total-findings:1\n==========================================================","/benchmarks/sast-go/cases/accuracy/flow_sensitive/loop_stmt/for_002_F/for_002_F":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/sast-go/cases/accuracy/flow_sensitive/loop_stmt/for_002_F/for_002_F.go\nLine 15: __taint_sink(res)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/sast-go/cases/accuracy/flow_sensitive/loop_stmt/for_002_F/for_002_F.go\",\"functionName\":\"main\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /sast-go/cases/accuracy/flow_sensitive/loop_stmt/for_002_F/for_002_F.go\n AffectedNodeName: __taint_src\n 23: SOURCE: for_002_F(__taint_src)\n /sast-go/cases/accuracy/flow_sensitive/loop_stmt/for_002_F/for_002_F.go\n AffectedNodeName: for_002_F\n 23: CALL: for_002_F(__taint_src)\n /sast-go/cases/accuracy/flow_sensitive/loop_stmt/for_002_F/for_002_F.go\n AffectedNodeName: __taint_src\n 12: ARG PASS: func for_002_F(__taint_src string) {\n /sast-go/cases/accuracy/flow_sensitive/loop_stmt/for_002_F/for_002_F.go\n AffectedNodeName: res\n 16: Var Pass: \t\tres = __taint_src\n /sast-go/cases/accuracy/flow_sensitive/loop_stmt/for_002_F/for_002_F.go\n AffectedNodeName: __taint_sink\n 15: SINK: \t\t__taint_sink(res)\n==========================================================\n #Total-findings:1\n==========================================================","/benchmarks/sast-go/cases/accuracy/flow_sensitive/loop_stmt/for_003_T/for_003_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/sast-go/cases/accuracy/flow_sensitive/loop_stmt/for_003_T/for_003_T.go\nLine 16: __taint_sink(res)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/sast-go/cases/accuracy/flow_sensitive/loop_stmt/for_003_T/for_003_T.go\",\"functionName\":\"main\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /sast-go/cases/accuracy/flow_sensitive/loop_stmt/for_003_T/for_003_T.go\n AffectedNodeName: __taint_src\n 23: SOURCE: for_003_T(__taint_src)\n /sast-go/cases/accuracy/flow_sensitive/loop_stmt/for_003_T/for_003_T.go\n AffectedNodeName: for_003_T\n 23: CALL: for_003_T(__taint_src)\n /sast-go/cases/accuracy/flow_sensitive/loop_stmt/for_003_T/for_003_T.go\n AffectedNodeName: __taint_src\n 12: ARG PASS: func for_003_T(__taint_src string) {\n /sast-go/cases/accuracy/flow_sensitive/loop_stmt/for_003_T/for_003_T.go\n AffectedNodeName: res\n 15: Var Pass: \tfor res = __taint_src; i < 1; i++ {\n /sast-go/cases/accuracy/flow_sensitive/loop_stmt/for_003_T/for_003_T.go\n AffectedNodeName: __taint_sink\n 16: SINK: \t\t__taint_sink(res)\n==========================================================\n #Total-findings:1\n==========================================================","/benchmarks/sast-go/cases/accuracy/flow_sensitive/loop_stmt/for_004_F/for_004_F":"======================== Findings ========================\nNo findings!\n==========================================================","/benchmarks/sast-go/cases/accuracy/object_sensitive/collection/array_obj_sensitive_001_T/array_obj_sensitive_001_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/sast-go/cases/accuracy/object_sensitive/collection/array_obj_sensitive_001_T/array_obj_sensitive_001_T.go\nLine 16: __taint_sink(str)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/sast-go/cases/accuracy/object_sensitive/collection/array_obj_sensitive_001_T/array_obj_sensitive_001_T.go\",\"functionName\":\"main\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /sast-go/cases/accuracy/object_sensitive/collection/array_obj_sensitive_001_T/array_obj_sensitive_001_T.go\n AffectedNodeName: __taint_src\n 23: SOURCE: array_obj_sensitive_001_T(__taint_src)\n /sast-go/cases/accuracy/object_sensitive/collection/array_obj_sensitive_001_T/array_obj_sensitive_001_T.go\n AffectedNodeName: array_obj_sensitive_001_T\n 23: CALL: array_obj_sensitive_001_T(__taint_src)\n /sast-go/cases/accuracy/object_sensitive/collection/array_obj_sensitive_001_T/array_obj_sensitive_001_T.go\n AffectedNodeName: __taint_src\n 12: ARG PASS: func array_obj_sensitive_001_T(__taint_src string) {\n /sast-go/cases/accuracy/object_sensitive/collection/array_obj_sensitive_001_T/array_obj_sensitive_001_T.go\n AffectedNodeName: str\n 13: Var Pass: \tvar str = [3]string{__taint_src, \"b\", \"c\"}\n /sast-go/cases/accuracy/object_sensitive/collection/array_obj_sensitive_001_T/array_obj_sensitive_001_T.go\n AffectedNodeName: __taint_sink\n 16: SINK: \t__taint_sink(str)\n==========================================================\n #Total-findings:1\n==========================================================","/benchmarks/sast-go/cases/accuracy/object_sensitive/collection/array_obj_sensitive_002_F/array_obj_sensitive_002_F":"======================== Findings ========================\nNo findings!\n==========================================================","/benchmarks/sast-go/cases/accuracy/object_sensitive/collection/array_obj_sensitive_003_T/array_obj_sensitive_003_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/sast-go/cases/accuracy/object_sensitive/collection/array_obj_sensitive_003_T/array_obj_sensitive_003_T.go\nLine 16: __taint_sink(str)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/sast-go/cases/accuracy/object_sensitive/collection/array_obj_sensitive_003_T/array_obj_sensitive_003_T.go\",\"functionName\":\"main\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /sast-go/cases/accuracy/object_sensitive/collection/array_obj_sensitive_003_T/array_obj_sensitive_003_T.go\n AffectedNodeName: __taint_src\n 23: SOURCE: array_obj_sensitive_003_T(__taint_src)\n /sast-go/cases/accuracy/object_sensitive/collection/array_obj_sensitive_003_T/array_obj_sensitive_003_T.go\n AffectedNodeName: array_obj_sensitive_003_T\n 23: CALL: array_obj_sensitive_003_T(__taint_src)\n /sast-go/cases/accuracy/object_sensitive/collection/array_obj_sensitive_003_T/array_obj_sensitive_003_T.go\n AffectedNodeName: __taint_src\n 12: ARG PASS: func array_obj_sensitive_003_T(__taint_src string) {\n /sast-go/cases/accuracy/object_sensitive/collection/array_obj_sensitive_003_T/array_obj_sensitive_003_T.go\n AffectedNodeName: str\n 13: Var Pass: \tvar str = [3][1]string{[1]string{__taint_src}, [1]string{\"b\"}, [1]string{\"c\"}}\n /sast-go/cases/accuracy/object_sensitive/collection/array_obj_sensitive_003_T/array_obj_sensitive_003_T.go\n AffectedNodeName: __taint_sink\n 16: SINK: \t__taint_sink(str)\n==========================================================\n #Total-findings:1\n==========================================================","/benchmarks/sast-go/cases/accuracy/object_sensitive/collection/array_obj_sensitive_004_F/array_obj_sensitive_004_F":"======================== Findings ========================\nNo findings!\n==========================================================","/benchmarks/sast-go/cases/accuracy/object_sensitive/collection/array_obj_sensitive_007_T/array_obj_sensitive_007_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/sast-go/cases/accuracy/object_sensitive/collection/array_obj_sensitive_007_T/array_obj_sensitive_007_T.go\nLine 16: __taint_sink(str)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/sast-go/cases/accuracy/object_sensitive/collection/array_obj_sensitive_007_T/array_obj_sensitive_007_T.go\",\"functionName\":\"main\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /sast-go/cases/accuracy/object_sensitive/collection/array_obj_sensitive_007_T/array_obj_sensitive_007_T.go\n AffectedNodeName: __taint_src\n 22: SOURCE: array_obj_sensitive_007_T(__taint_src)\n /sast-go/cases/accuracy/object_sensitive/collection/array_obj_sensitive_007_T/array_obj_sensitive_007_T.go\n AffectedNodeName: array_obj_sensitive_007_T\n 22: CALL: array_obj_sensitive_007_T(__taint_src)\n /sast-go/cases/accuracy/object_sensitive/collection/array_obj_sensitive_007_T/array_obj_sensitive_007_T.go\n AffectedNodeName: __taint_src\n 12: ARG PASS: func array_obj_sensitive_007_T(__taint_src string) {\n /sast-go/cases/accuracy/object_sensitive/collection/array_obj_sensitive_007_T/array_obj_sensitive_007_T.go\n AffectedNodeName: str\n 13: Var Pass: \tvar str = [...]string{__taint_src, \"b\", \"c\"}\n /sast-go/cases/accuracy/object_sensitive/collection/array_obj_sensitive_007_T/array_obj_sensitive_007_T.go\n AffectedNodeName: __taint_sink\n 16: SINK: \t__taint_sink(str)\n==========================================================\n #Total-findings:1\n==========================================================","/benchmarks/sast-go/cases/accuracy/object_sensitive/collection/array_obj_sensitive_008_F/array_obj_sensitive_008_F":"======================== Findings ========================\nNo findings!\n==========================================================","/benchmarks/sast-go/cases/accuracy/object_sensitive/collection/map_obj_sensitive_001_T/map_obj_sensitive_001_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/sast-go/cases/accuracy/object_sensitive/collection/map_obj_sensitive_001_T/map_obj_sensitive_001_T.go\nLine 17: __taint_sink(m)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/sast-go/cases/accuracy/object_sensitive/collection/map_obj_sensitive_001_T/map_obj_sensitive_001_T.go\",\"functionName\":\"main\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /sast-go/cases/accuracy/object_sensitive/collection/map_obj_sensitive_001_T/map_obj_sensitive_001_T.go\n AffectedNodeName: __taint_src\n 24: SOURCE: map_obj_sensitive_001_T(__taint_src)\n /sast-go/cases/accuracy/object_sensitive/collection/map_obj_sensitive_001_T/map_obj_sensitive_001_T.go\n AffectedNodeName: map_obj_sensitive_001_T\n 24: CALL: map_obj_sensitive_001_T(__taint_src)\n /sast-go/cases/accuracy/object_sensitive/collection/map_obj_sensitive_001_T/map_obj_sensitive_001_T.go\n AffectedNodeName: __taint_src\n 12: ARG PASS: func map_obj_sensitive_001_T(__taint_src string) {\n /sast-go/cases/accuracy/object_sensitive/collection/map_obj_sensitive_001_T/map_obj_sensitive_001_T.go\n AffectedNodeName: m[\"key1\"]\n 15: Var Pass: \tm[\"key1\"] = __taint_src\n /sast-go/cases/accuracy/object_sensitive/collection/map_obj_sensitive_001_T/map_obj_sensitive_001_T.go\n AffectedNodeName: __taint_sink\n 17: SINK: \t__taint_sink(m)\n==========================================================\n #Total-findings:1\n==========================================================","/benchmarks/sast-go/cases/accuracy/object_sensitive/collection/map_obj_sensitive_002_T/map_obj_sensitive_002_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/sast-go/cases/accuracy/object_sensitive/collection/map_obj_sensitive_002_T/map_obj_sensitive_002_T.go\nLine 15: __taint_sink(m)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/sast-go/cases/accuracy/object_sensitive/collection/map_obj_sensitive_002_T/map_obj_sensitive_002_T.go\",\"functionName\":\"main\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /sast-go/cases/accuracy/object_sensitive/collection/map_obj_sensitive_002_T/map_obj_sensitive_002_T.go\n AffectedNodeName: __taint_src\n 22: SOURCE: map_obj_sensitive_002_T(__taint_src)\n /sast-go/cases/accuracy/object_sensitive/collection/map_obj_sensitive_002_T/map_obj_sensitive_002_T.go\n AffectedNodeName: map_obj_sensitive_002_T\n 22: CALL: map_obj_sensitive_002_T(__taint_src)\n /sast-go/cases/accuracy/object_sensitive/collection/map_obj_sensitive_002_T/map_obj_sensitive_002_T.go\n AffectedNodeName: __taint_src\n 12: ARG PASS: func map_obj_sensitive_002_T(__taint_src string) {\n /sast-go/cases/accuracy/object_sensitive/collection/map_obj_sensitive_002_T/map_obj_sensitive_002_T.go\n AffectedNodeName: __taint_sink\n 15: SINK: \t__taint_sink(m)\n==========================================================\n #Total-findings:1\n==========================================================","/benchmarks/sast-go/cases/accuracy/object_sensitive/collection/map_obj_sensitive_003_F/map_obj_sensitive_003_F":"======================== Findings ========================\nNo findings!\n==========================================================","/benchmarks/sast-go/cases/accuracy/object_sensitive/collection/map_obj_sensitive_004_T/map_obj_sensitive_004_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/sast-go/cases/accuracy/object_sensitive/collection/map_obj_sensitive_004_T/map_obj_sensitive_004_T.go\nLine 20: __taint_sink(m)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/sast-go/cases/accuracy/object_sensitive/collection/map_obj_sensitive_004_T/map_obj_sensitive_004_T.go\",\"functionName\":\"main\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /sast-go/cases/accuracy/object_sensitive/collection/map_obj_sensitive_004_T/map_obj_sensitive_004_T.go\n AffectedNodeName: __taint_src\n 27: SOURCE: map_obj_sensitive_004_T(__taint_src)\n /sast-go/cases/accuracy/object_sensitive/collection/map_obj_sensitive_004_T/map_obj_sensitive_004_T.go\n AffectedNodeName: map_obj_sensitive_004_T\n 27: CALL: map_obj_sensitive_004_T(__taint_src)\n /sast-go/cases/accuracy/object_sensitive/collection/map_obj_sensitive_004_T/map_obj_sensitive_004_T.go\n AffectedNodeName: __taint_src\n 12: ARG PASS: func map_obj_sensitive_004_T(__taint_src string) {\n /sast-go/cases/accuracy/object_sensitive/collection/map_obj_sensitive_004_T/map_obj_sensitive_004_T.go\n AffectedNodeName: m\n 13: Var Pass: \tm := map[string]string{\n 14: Var Pass: \t\t\"key1\": __taint_src,\n 15: Var Pass: \t}\n /sast-go/cases/accuracy/object_sensitive/collection/map_obj_sensitive_004_T/map_obj_sensitive_004_T.go\n AffectedNodeName: __taint_sink\n 20: SINK: \t__taint_sink(m)\n==========================================================\n #Total-findings:1\n==========================================================","/benchmarks/sast-go/cases/accuracy/object_sensitive/collection/map_obj_sensitive_005_F/map_obj_sensitive_005_F":"======================== Findings ========================\nNo findings!\n==========================================================","/benchmarks/sast-go/cases/accuracy/object_sensitive/collection/slice_obj_sensitive_001_T/slice_obj_sensitive_001_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/sast-go/cases/accuracy/object_sensitive/collection/slice_obj_sensitive_001_T/slice_obj_sensitive_001_T.go\nLine 18: __taint_sink(s)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/sast-go/cases/accuracy/object_sensitive/collection/slice_obj_sensitive_001_T/slice_obj_sensitive_001_T.go\",\"functionName\":\"main\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /sast-go/cases/accuracy/object_sensitive/collection/slice_obj_sensitive_001_T/slice_obj_sensitive_001_T.go\n AffectedNodeName: __taint_src\n 25: SOURCE: slice_001slice_obj_sensitive_001_T_T(__taint_src)\n /sast-go/cases/accuracy/object_sensitive/collection/slice_obj_sensitive_001_T/slice_obj_sensitive_001_T.go\n AffectedNodeName: slice_001slice_obj_sensitive_001_T_T\n 25: CALL: slice_001slice_obj_sensitive_001_T_T(__taint_src)\n /sast-go/cases/accuracy/object_sensitive/collection/slice_obj_sensitive_001_T/slice_obj_sensitive_001_T.go\n AffectedNodeName: __taint_src\n 12: ARG PASS: func slice_001slice_obj_sensitive_001_T_T(__taint_src string) {\n /sast-go/cases/accuracy/object_sensitive/collection/slice_obj_sensitive_001_T/slice_obj_sensitive_001_T.go\n AffectedNodeName: arr\n 13: Var Pass: \tvar arr [3]string = [3]string{__taint_src, \"b\", \"c\"}\n /sast-go/cases/accuracy/object_sensitive/collection/slice_obj_sensitive_001_T/slice_obj_sensitive_001_T.go\n AffectedNodeName: s\n 17: Var Pass: \ts = arr[:]\n /sast-go/cases/accuracy/object_sensitive/collection/slice_obj_sensitive_001_T/slice_obj_sensitive_001_T.go\n AffectedNodeName: __taint_sink\n 18: SINK: \t__taint_sink(s)\n==========================================================\n #Total-findings:1\n==========================================================","/benchmarks/sast-go/cases/accuracy/object_sensitive/collection/slice_obj_sensitive_002_F/slice_obj_sensitive_002_F":"======================== Findings ========================\nNo findings!\n==========================================================","/benchmarks/sast-go/cases/accuracy/object_sensitive/collection/slice_obj_sensitive_003_T/slice_obj_sensitive_003_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/sast-go/cases/accuracy/object_sensitive/collection/slice_obj_sensitive_003_T/slice_obj_sensitive_003_T.go\nLine 24: __taint_sink(s)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/sast-go/cases/accuracy/object_sensitive/collection/slice_obj_sensitive_003_T/slice_obj_sensitive_003_T.go\",\"functionName\":\"main\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /sast-go/cases/accuracy/object_sensitive/collection/slice_obj_sensitive_003_T/slice_obj_sensitive_003_T.go\n AffectedNodeName: __taint_src\n 31: SOURCE: slice_obj_sensitive_003_T(__taint_src)\n /sast-go/cases/accuracy/object_sensitive/collection/slice_obj_sensitive_003_T/slice_obj_sensitive_003_T.go\n AffectedNodeName: slice_obj_sensitive_003_T\n 31: CALL: slice_obj_sensitive_003_T(__taint_src)\n /sast-go/cases/accuracy/object_sensitive/collection/slice_obj_sensitive_003_T/slice_obj_sensitive_003_T.go\n AffectedNodeName: __taint_src\n 12: ARG PASS: func slice_obj_sensitive_003_T(__taint_src string) {\n /sast-go/cases/accuracy/object_sensitive/collection/slice_obj_sensitive_003_T/slice_obj_sensitive_003_T.go\n AffectedNodeName: s\n 13: Var Pass: \ts := [][]string{\n 14: Var Pass: \t\t[]string{\"a\"},\n 15: Var Pass: \t\t[]string{\"b\", \"c\"},\n 16: Var Pass: \t\t[]string{\"d\", \"e\", __taint_src},\n 17: Var Pass: \t}\n /sast-go/cases/accuracy/object_sensitive/collection/slice_obj_sensitive_003_T/slice_obj_sensitive_003_T.go\n AffectedNodeName: __taint_sink\n 24: SINK: \t__taint_sink(s)\n==========================================================\n #Total-findings:1\n==========================================================","/benchmarks/sast-go/cases/accuracy/object_sensitive/collection/slice_obj_sensitive_004_F/slice_obj_sensitive_004_F":"======================== Findings ========================\nNo findings!\n==========================================================","/benchmarks/sast-go/cases/accuracy/object_sensitive/interface_class/interface_class_001_F/interface_class_001_F":"======================== Findings ========================\nNo findings!\n==========================================================","/benchmarks/sast-go/cases/accuracy/object_sensitive/interface_class/interface_class_002_T/interface_class_002_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/sast-go/cases/accuracy/object_sensitive/interface_class/interface_class_002_T/interface_class_002_T.go\nLine 41: __taint_sink(res)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/sast-go/cases/accuracy/object_sensitive/interface_class/interface_class_002_T/interface_class_002_T.go\",\"functionName\":\"main\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /sast-go/cases/accuracy/object_sensitive/interface_class/interface_class_002_T/interface_class_002_T.go\n AffectedNodeName: __taint_src\n 48: SOURCE: interface_class_002_T(__taint_src)\n /sast-go/cases/accuracy/object_sensitive/interface_class/interface_class_002_T/interface_class_002_T.go\n AffectedNodeName: interface_class_002_T\n 48: CALL: interface_class_002_T(__taint_src)\n /sast-go/cases/accuracy/object_sensitive/interface_class/interface_class_002_T/interface_class_002_T.go\n AffectedNodeName: __taint_src\n 38: ARG PASS: func interface_class_002_T(__taint_src string) {\n /sast-go/cases/accuracy/object_sensitive/interface_class/interface_class_002_T/interface_class_002_T.go\n AffectedNodeName: process\n 40: CALL: \tres := iTestService.process(__taint_src)\n /sast-go/cases/accuracy/object_sensitive/interface_class/interface_class_002_T/interface_class_002_T.go\n AffectedNodeName: data\n 20: ARG PASS: func (c TestService) process(data string) string {\n /sast-go/cases/accuracy/object_sensitive/interface_class/interface_class_002_T/interface_class_002_T.go\n AffectedNodeName: [return value]\n 21: Return Value: \treturn data\n /sast-go/cases/accuracy/object_sensitive/interface_class/interface_class_002_T/interface_class_002_T.go\n AffectedNodeName: process\n 40: CALL RETURN: \tres := iTestService.process(__taint_src)\n /sast-go/cases/accuracy/object_sensitive/interface_class/interface_class_002_T/interface_class_002_T.go\n AffectedNodeName: res\n 40: Var Pass: \tres := iTestService.process(__taint_src)\n /sast-go/cases/accuracy/object_sensitive/interface_class/interface_class_002_T/interface_class_002_T.go\n AffectedNodeName: __taint_sink\n 41: SINK: \t__taint_sink(res)\n==========================================================\n #Total-findings:1\n==========================================================","/benchmarks/sast-go/cases/accuracy/object_sensitive/interface_class/interface_class_003_F/interface_class_003_F":"======================== Findings ========================\nNo findings!\n==========================================================","/benchmarks/sast-go/cases/accuracy/object_sensitive/interface_class/interface_class_004_T/interface_class_004_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/sast-go/cases/accuracy/object_sensitive/interface_class/interface_class_004_T/interface_class_004_T.go\nLine 47: __taint_sink(res)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/sast-go/cases/accuracy/object_sensitive/interface_class/interface_class_004_T/interface_class_004_T.go\",\"functionName\":\"main\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /sast-go/cases/accuracy/object_sensitive/interface_class/interface_class_004_T/interface_class_004_T.go\n AffectedNodeName: __taint_src\n 54: SOURCE: interface_class_004_T(__taint_src)\n /sast-go/cases/accuracy/object_sensitive/interface_class/interface_class_004_T/interface_class_004_T.go\n AffectedNodeName: interface_class_004_T\n 54: CALL: interface_class_004_T(__taint_src)\n /sast-go/cases/accuracy/object_sensitive/interface_class/interface_class_004_T/interface_class_004_T.go\n AffectedNodeName: __taint_src\n 44: ARG PASS: func interface_class_004_T(__taint_src string) {\n /sast-go/cases/accuracy/object_sensitive/interface_class/interface_class_004_T/interface_class_004_T.go\n AffectedNodeName: process\n 46: CALL: \tres := iTestService.process(__taint_src)\n /sast-go/cases/accuracy/object_sensitive/interface_class/interface_class_004_T/interface_class_004_T.go\n AffectedNodeName: data\n 25: ARG PASS: func (c TestService) process(data string) string {\n /sast-go/cases/accuracy/object_sensitive/interface_class/interface_class_004_T/interface_class_004_T.go\n AffectedNodeName: [return value]\n 26: Return Value: \treturn data\n /sast-go/cases/accuracy/object_sensitive/interface_class/interface_class_004_T/interface_class_004_T.go\n AffectedNodeName: process\n 46: CALL RETURN: \tres := iTestService.process(__taint_src)\n /sast-go/cases/accuracy/object_sensitive/interface_class/interface_class_004_T/interface_class_004_T.go\n AffectedNodeName: res\n 46: Var Pass: \tres := iTestService.process(__taint_src)\n /sast-go/cases/accuracy/object_sensitive/interface_class/interface_class_004_T/interface_class_004_T.go\n AffectedNodeName: __taint_sink\n 47: SINK: \t__taint_sink(res)\n==========================================================\n #Total-findings:1\n==========================================================","/benchmarks/sast-go/cases/accuracy/object_sensitive/interface_class/interface_class_005_F/interface_class_005_F":"======================== Findings ========================\nNo findings!\n==========================================================","/benchmarks/sast-go/cases/accuracy/object_sensitive/interface_class/interface_class_006_T/interface_class_006_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/sast-go/cases/accuracy/object_sensitive/interface_class/interface_class_006_T/interface_class_006_T.go\nLine 39: __taint_sink(res)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/sast-go/cases/accuracy/object_sensitive/interface_class/interface_class_006_T/interface_class_006_T.go\",\"functionName\":\"main\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /sast-go/cases/accuracy/object_sensitive/interface_class/interface_class_006_T/interface_class_006_T.go\n AffectedNodeName: __taint_src\n 46: SOURCE: interface_class_006_T(__taint_src)\n /sast-go/cases/accuracy/object_sensitive/interface_class/interface_class_006_T/interface_class_006_T.go\n AffectedNodeName: interface_class_006_T\n 46: CALL: interface_class_006_T(__taint_src)\n /sast-go/cases/accuracy/object_sensitive/interface_class/interface_class_006_T/interface_class_006_T.go\n AffectedNodeName: __taint_src\n 36: ARG PASS: func interface_class_006_T(__taint_src string) {\n /sast-go/cases/accuracy/object_sensitive/interface_class/interface_class_006_T/interface_class_006_T.go\n AffectedNodeName: process\n 38: CALL: \tres := iTestService.process(__taint_src)\n /sast-go/cases/accuracy/object_sensitive/interface_class/interface_class_006_T/interface_class_006_T.go\n AffectedNodeName: data\n 24: ARG PASS: func (c TestService) process(data string) string {\n /sast-go/cases/accuracy/object_sensitive/interface_class/interface_class_006_T/interface_class_006_T.go\n AffectedNodeName: [return value]\n 25: Return Value: \treturn data\n /sast-go/cases/accuracy/object_sensitive/interface_class/interface_class_006_T/interface_class_006_T.go\n AffectedNodeName: process\n 38: CALL RETURN: \tres := iTestService.process(__taint_src)\n /sast-go/cases/accuracy/object_sensitive/interface_class/interface_class_006_T/interface_class_006_T.go\n AffectedNodeName: res\n 38: Var Pass: \tres := iTestService.process(__taint_src)\n /sast-go/cases/accuracy/object_sensitive/interface_class/interface_class_006_T/interface_class_006_T.go\n AffectedNodeName: __taint_sink\n 39: SINK: \t__taint_sink(res)\n==========================================================\n #Total-findings:1\n==========================================================","/benchmarks/sast-go/cases/accuracy/object_sensitive/interface_class/interface_class_007_F/interface_class_007_F":"======================== Findings ========================\nNo findings!\n==========================================================","/benchmarks/sast-go/cases/accuracy/object_sensitive/interface_class/interface_class_008_T/interface_class_008_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/sast-go/cases/accuracy/object_sensitive/interface_class/interface_class_008_T/interface_class_008_T.go\nLine 34: __taint_sink(res)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/sast-go/cases/accuracy/object_sensitive/interface_class/interface_class_008_T/interface_class_008_T.go\",\"functionName\":\"main\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /sast-go/cases/accuracy/object_sensitive/interface_class/interface_class_008_T/interface_class_008_T.go\n AffectedNodeName: __taint_src\n 41: SOURCE: interface_class_008_T(__taint_src)\n /sast-go/cases/accuracy/object_sensitive/interface_class/interface_class_008_T/interface_class_008_T.go\n AffectedNodeName: interface_class_008_T\n 41: CALL: interface_class_008_T(__taint_src)\n /sast-go/cases/accuracy/object_sensitive/interface_class/interface_class_008_T/interface_class_008_T.go\n AffectedNodeName: __taint_src\n 31: ARG PASS: func interface_class_008_T(__taint_src string) {\n /sast-go/cases/accuracy/object_sensitive/interface_class/interface_class_008_T/interface_class_008_T.go\n AffectedNodeName: process\n 33: CALL: \tres := iTestService.process(__taint_src)\n /sast-go/cases/accuracy/object_sensitive/interface_class/interface_class_008_T/interface_class_008_T.go\n AffectedNodeName: data\n 23: ARG PASS: func (c TestService) process(data string) string {\n /sast-go/cases/accuracy/object_sensitive/interface_class/interface_class_008_T/interface_class_008_T.go\n AffectedNodeName: [return value]\n 24: Return Value: \treturn data\n /sast-go/cases/accuracy/object_sensitive/interface_class/interface_class_008_T/interface_class_008_T.go\n AffectedNodeName: process\n 33: CALL RETURN: \tres := iTestService.process(__taint_src)\n /sast-go/cases/accuracy/object_sensitive/interface_class/interface_class_008_T/interface_class_008_T.go\n AffectedNodeName: res\n 33: Var Pass: \tres := iTestService.process(__taint_src)\n /sast-go/cases/accuracy/object_sensitive/interface_class/interface_class_008_T/interface_class_008_T.go\n AffectedNodeName: __taint_sink\n 34: SINK: \t__taint_sink(res)\n==========================================================\n #Total-findings:1\n==========================================================","/benchmarks/sast-go/cases/accuracy/object_sensitive/interface_class/interface_class_009_F/interface_class_009_F":"======================== Findings ========================\nNo findings!\n==========================================================","/benchmarks/sast-go/cases/accuracy/object_sensitive/interface_class/interface_class_010_T/interface_class_010_T":"======================== Findings ========================\nNo findings!\n==========================================================","/benchmarks/sast-go/cases/accuracy/object_sensitive/interface_class/interface_class_011_F/interface_class_011_F":"======================== Findings ========================\nNo findings!\n==========================================================","/benchmarks/sast-go/cases/accuracy/object_sensitive/interface_class/interface_class_012_T/interface_class_012_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/sast-go/cases/accuracy/object_sensitive/interface_class/interface_class_012_T/interface_class_012_T.go\nLine 46: __taint_sink(res)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/sast-go/cases/accuracy/object_sensitive/interface_class/interface_class_012_T/interface_class_012_T.go\",\"functionName\":\"interface_class_012_T\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /sast-go/cases/accuracy/object_sensitive/interface_class/interface_class_012_T/interface_class_012_T.go\n AffectedNodeName: __taint_src\n 43: SOURCE: func interface_class_012_T(__taint_src string) {\n /sast-go/cases/accuracy/object_sensitive/interface_class/interface_class_012_T/interface_class_012_T.go\n AffectedNodeName: processArg\n 45: CALL: \tres := processArg(iTestService, __taint_src)\n /sast-go/cases/accuracy/object_sensitive/interface_class/interface_class_012_T/interface_class_012_T.go\n AffectedNodeName: data\n 39: ARG PASS: func processArg(foo ITestService, data string) string {\n /sast-go/cases/accuracy/object_sensitive/interface_class/interface_class_012_T/interface_class_012_T.go\n AffectedNodeName: process\n 40: CALL: \treturn foo.process(data)\n /sast-go/cases/accuracy/object_sensitive/interface_class/interface_class_012_T/interface_class_012_T.go\n AffectedNodeName: data\n 20: ARG PASS: func (c TestService) process(data string) string {\n /sast-go/cases/accuracy/object_sensitive/interface_class/interface_class_012_T/interface_class_012_T.go\n AffectedNodeName: [return value]\n 21: Return Value: \treturn data\n /sast-go/cases/accuracy/object_sensitive/interface_class/interface_class_012_T/interface_class_012_T.go\n AffectedNodeName: process\n 40: CALL RETURN: \treturn foo.process(data)\n /sast-go/cases/accuracy/object_sensitive/interface_class/interface_class_012_T/interface_class_012_T.go\n AffectedNodeName: [return value]\n 40: Return Value: \treturn foo.process(data)\n /sast-go/cases/accuracy/object_sensitive/interface_class/interface_class_012_T/interface_class_012_T.go\n AffectedNodeName: processArg\n 45: CALL RETURN: \tres := processArg(iTestService, __taint_src)\n /sast-go/cases/accuracy/object_sensitive/interface_class/interface_class_012_T/interface_class_012_T.go\n AffectedNodeName: res\n 45: Var Pass: \tres := processArg(iTestService, __taint_src)\n /sast-go/cases/accuracy/object_sensitive/interface_class/interface_class_012_T/interface_class_012_T.go\n AffectedNodeName: __taint_sink\n 46: SINK: \t__taint_sink(res)\n==========================================================\n #Total-findings:1\n==========================================================","/benchmarks/sast-go/cases/accuracy/object_sensitive/struct/struct_007_T/struct_007_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/sast-go/cases/accuracy/object_sensitive/struct/struct_007_T/struct_007_T.go\nLine 24: __taint_sink(p)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/sast-go/cases/accuracy/object_sensitive/struct/struct_007_T/struct_007_T.go\",\"functionName\":\"main\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /sast-go/cases/accuracy/object_sensitive/struct/struct_007_T/struct_007_T.go\n AffectedNodeName: __taint_src\n 31: SOURCE: struct_007_T(__taint_src)\n /sast-go/cases/accuracy/object_sensitive/struct/struct_007_T/struct_007_T.go\n AffectedNodeName: struct_007_T\n 31: CALL: struct_007_T(__taint_src)\n /sast-go/cases/accuracy/object_sensitive/struct/struct_007_T/struct_007_T.go\n AffectedNodeName: __taint_src\n 16: ARG PASS: func struct_007_T(__taint_src string) {\n /sast-go/cases/accuracy/object_sensitive/struct/struct_007_T/struct_007_T.go\n AffectedNodeName: p\n 17: Var Pass: \tp := A{\n 18: Var Pass: \t\tdata: __taint_src,\n 19: Var Pass: \t}\n /sast-go/cases/accuracy/object_sensitive/struct/struct_007_T/struct_007_T.go\n AffectedNodeName: __taint_sink\n 24: SINK: \t__taint_sink(p)\n==========================================================\n #Total-findings:1\n==========================================================","/benchmarks/sast-go/cases/accuracy/object_sensitive/struct/struct_008_F/struct_008_F":"======================== Findings ========================\nNo findings!\n==========================================================","/benchmarks/sast-go/cases/accuracy/object_sensitive/struct/struct_deep10_001_T/struct_deep10_001_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/sast-go/cases/accuracy/object_sensitive/struct/struct_deep10_001_T/struct_deep10_001_T.go\nLine 57: __taint_sink(obj1)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/sast-go/cases/accuracy/object_sensitive/struct/struct_deep10_001_T/struct_deep10_001_T.go\",\"functionName\":\"main\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /sast-go/cases/accuracy/object_sensitive/struct/struct_deep10_001_T/struct_deep10_001_T.go\n AffectedNodeName: __taint_src\n 65: SOURCE: struct_deep10_001_T(__taint_src)\n /sast-go/cases/accuracy/object_sensitive/struct/struct_deep10_001_T/struct_deep10_001_T.go\n AffectedNodeName: struct_deep10_001_T\n 65: CALL: struct_deep10_001_T(__taint_src)\n /sast-go/cases/accuracy/object_sensitive/struct/struct_deep10_001_T/struct_deep10_001_T.go\n AffectedNodeName: __taint_src\n 50: ARG PASS: func struct_deep10_001_T(__taint_src string) {\n /sast-go/cases/accuracy/object_sensitive/struct/struct_deep10_001_T/struct_deep10_001_T.go\n AffectedNodeName: .deepA08].deepA09].deepA10].deepA11]\n 55: Var Pass: \tobj1.deepA02.deepA03.deepA04.deepA05.deepA06.deepA07.deepA08.deepA09.deepA10.deepA11 = __taint_src\n /sast-go/cases/accuracy/object_sensitive/struct/struct_deep10_001_T/struct_deep10_001_T.go\n AffectedNodeName: __taint_sink\n 57: SINK: \t__taint_sink(obj1)\n==========================================================\n #Total-findings:1\n==========================================================","/benchmarks/sast-go/cases/accuracy/object_sensitive/struct/struct_deep10_002_F/struct_deep10_002_F":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/sast-go/cases/accuracy/object_sensitive/struct/struct_deep10_002_F/struct_deep10_002_F.go\nLine 57: __taint_sink(obj2)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/sast-go/cases/accuracy/object_sensitive/struct/struct_deep10_002_F/struct_deep10_002_F.go\",\"functionName\":\"main\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /sast-go/cases/accuracy/object_sensitive/struct/struct_deep10_002_F/struct_deep10_002_F.go\n AffectedNodeName: __taint_src\n 65: SOURCE: struct_deep10_002_F(__taint_src)\n /sast-go/cases/accuracy/object_sensitive/struct/struct_deep10_002_F/struct_deep10_002_F.go\n AffectedNodeName: struct_deep10_002_F\n 65: CALL: struct_deep10_002_F(__taint_src)\n /sast-go/cases/accuracy/object_sensitive/struct/struct_deep10_002_F/struct_deep10_002_F.go\n AffectedNodeName: __taint_src\n 50: ARG PASS: func struct_deep10_002_F(__taint_src string) {\n /sast-go/cases/accuracy/object_sensitive/struct/struct_deep10_002_F/struct_deep10_002_F.go\n AffectedNodeName: .deepA08].deepA09].deepA10].deepA11]\n 55: Var Pass: \tobj1.deepA02.deepA03.deepA04.deepA05.deepA06.deepA07.deepA08.deepA09.deepA10.deepA11 = __taint_src\n /sast-go/cases/accuracy/object_sensitive/struct/struct_deep10_002_F/struct_deep10_002_F.go\n AffectedNodeName: __taint_sink\n 57: SINK: \t__taint_sink(obj2)\n==========================================================\n #Total-findings:1\n==========================================================","/benchmarks/sast-go/cases/accuracy/object_sensitive/struct/struct_deep3_001_T/struct_deep3_001_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/sast-go/cases/accuracy/object_sensitive/struct/struct_deep3_001_T/struct_deep3_001_T.go\nLine 31: __taint_sink(obj1)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/sast-go/cases/accuracy/object_sensitive/struct/struct_deep3_001_T/struct_deep3_001_T.go\",\"functionName\":\"main\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /sast-go/cases/accuracy/object_sensitive/struct/struct_deep3_001_T/struct_deep3_001_T.go\n AffectedNodeName: __taint_src\n 39: SOURCE: struct_deep3_001_T(__taint_src)\n /sast-go/cases/accuracy/object_sensitive/struct/struct_deep3_001_T/struct_deep3_001_T.go\n AffectedNodeName: struct_deep3_001_T\n 39: CALL: struct_deep3_001_T(__taint_src)\n /sast-go/cases/accuracy/object_sensitive/struct/struct_deep3_001_T/struct_deep3_001_T.go\n AffectedNodeName: __taint_src\n 24: ARG PASS: func struct_deep3_001_T(__taint_src string) {\n /sast-go/cases/accuracy/object_sensitive/struct/struct_deep3_001_T/struct_deep3_001_T.go\n AffectedNodeName: [[[obj1.deepC02].deepC03].deepC04]\n 29: Var Pass: \tobj1.deepC02.deepC03.deepC04 = __taint_src\n /sast-go/cases/accuracy/object_sensitive/struct/struct_deep3_001_T/struct_deep3_001_T.go\n AffectedNodeName: __taint_sink\n 31: SINK: \t__taint_sink(obj1)\n==========================================================\n #Total-findings:1\n==========================================================","/benchmarks/sast-go/cases/accuracy/object_sensitive/struct/struct_deep3_002_F/struct_deep3_002_F":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/sast-go/cases/accuracy/object_sensitive/struct/struct_deep3_002_F/struct_deep3_002_F.go\nLine 30: __taint_sink(obj2)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/sast-go/cases/accuracy/object_sensitive/struct/struct_deep3_002_F/struct_deep3_002_F.go\",\"functionName\":\"main\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /sast-go/cases/accuracy/object_sensitive/struct/struct_deep3_002_F/struct_deep3_002_F.go\n AffectedNodeName: __taint_src\n 38: SOURCE: struct_deep3_002_F(__taint_src)\n /sast-go/cases/accuracy/object_sensitive/struct/struct_deep3_002_F/struct_deep3_002_F.go\n AffectedNodeName: struct_deep3_002_F\n 38: CALL: struct_deep3_002_F(__taint_src)\n /sast-go/cases/accuracy/object_sensitive/struct/struct_deep3_002_F/struct_deep3_002_F.go\n AffectedNodeName: __taint_src\n 24: ARG PASS: func struct_deep3_002_F(__taint_src string) {\n /sast-go/cases/accuracy/object_sensitive/struct/struct_deep3_002_F/struct_deep3_002_F.go\n AffectedNodeName: [[[obj1.deepC02].deepC03].deepC04]\n 29: Var Pass: \tobj1.deepC02.deepC03.deepC04 = __taint_src\n /sast-go/cases/accuracy/object_sensitive/struct/struct_deep3_002_F/struct_deep3_002_F.go\n AffectedNodeName: __taint_sink\n 30: SINK: \t__taint_sink(obj2)\n==========================================================\n #Total-findings:1\n==========================================================","/benchmarks/sast-go/cases/accuracy/object_sensitive/struct/struct_deep3_003_T/struct_deep3_003_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/sast-go/cases/accuracy/object_sensitive/struct/struct_deep3_003_T/struct_deep3_003_T.go\nLine 34: __taint_sink(obj1)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/sast-go/cases/accuracy/object_sensitive/struct/struct_deep3_003_T/struct_deep3_003_T.go\",\"functionName\":\"main\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /sast-go/cases/accuracy/object_sensitive/struct/struct_deep3_003_T/struct_deep3_003_T.go\n AffectedNodeName: __taint_src\n 42: SOURCE: struct_deep3_003_T(__taint_src)\n /sast-go/cases/accuracy/object_sensitive/struct/struct_deep3_003_T/struct_deep3_003_T.go\n AffectedNodeName: struct_deep3_003_T\n 42: CALL: struct_deep3_003_T(__taint_src)\n /sast-go/cases/accuracy/object_sensitive/struct/struct_deep3_003_T/struct_deep3_003_T.go\n AffectedNodeName: __taint_src\n 24: ARG PASS: func struct_deep3_003_T(__taint_src string) {\n /sast-go/cases/accuracy/object_sensitive/struct/struct_deep3_003_T/struct_deep3_003_T.go\n AffectedNodeName: deepC03\n 29: Var Pass: \tdeepC03 := DeepC03{\n 30: Var Pass: \t\tdeepC04: __taint_src,\n 31: Var Pass: \t}\n /sast-go/cases/accuracy/object_sensitive/struct/struct_deep3_003_T/struct_deep3_003_T.go\n AffectedNodeName: [[obj1.deepC02].deepC03]\n 32: Var Pass: \tobj1.deepC02.deepC03 = deepC03\n /sast-go/cases/accuracy/object_sensitive/struct/struct_deep3_003_T/struct_deep3_003_T.go\n AffectedNodeName: __taint_sink\n 34: SINK: \t__taint_sink(obj1)\n==========================================================\n #Total-findings:1\n==========================================================","/benchmarks/sast-go/cases/accuracy/object_sensitive/struct/struct_deep3_004_F/struct_deep3_004_F":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/sast-go/cases/accuracy/object_sensitive/struct/struct_deep3_004_F/struct_deep3_004_F.go\nLine 34: __taint_sink(obj2)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/sast-go/cases/accuracy/object_sensitive/struct/struct_deep3_004_F/struct_deep3_004_F.go\",\"functionName\":\"main\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /sast-go/cases/accuracy/object_sensitive/struct/struct_deep3_004_F/struct_deep3_004_F.go\n AffectedNodeName: __taint_src\n 42: SOURCE: struct_deep3_004_F(__taint_src)\n /sast-go/cases/accuracy/object_sensitive/struct/struct_deep3_004_F/struct_deep3_004_F.go\n AffectedNodeName: struct_deep3_004_F\n 42: CALL: struct_deep3_004_F(__taint_src)\n /sast-go/cases/accuracy/object_sensitive/struct/struct_deep3_004_F/struct_deep3_004_F.go\n AffectedNodeName: __taint_src\n 24: ARG PASS: func struct_deep3_004_F(__taint_src string) {\n /sast-go/cases/accuracy/object_sensitive/struct/struct_deep3_004_F/struct_deep3_004_F.go\n AffectedNodeName: deepC03\n 29: Var Pass: \tdeepC03 := DeepC03{\n 30: Var Pass: \t\tdeepC04: __taint_src,\n 31: Var Pass: \t}\n /sast-go/cases/accuracy/object_sensitive/struct/struct_deep3_004_F/struct_deep3_004_F.go\n AffectedNodeName: [[obj1.deepC02].deepC03]\n 32: Var Pass: \tobj1.deepC02.deepC03 = deepC03\n /sast-go/cases/accuracy/object_sensitive/struct/struct_deep3_004_F/struct_deep3_004_F.go\n AffectedNodeName: __taint_sink\n 34: SINK: \t__taint_sink(obj2)\n==========================================================\n #Total-findings:1\n==========================================================","/benchmarks/sast-go/cases/accuracy/object_sensitive/struct/struct_deep5_001_T/struct_deep5_001_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/sast-go/cases/accuracy/object_sensitive/struct/struct_deep5_001_T/struct_deep5_001_T.go\nLine 35: __taint_sink(obj1)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/sast-go/cases/accuracy/object_sensitive/struct/struct_deep5_001_T/struct_deep5_001_T.go\",\"functionName\":\"main\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /sast-go/cases/accuracy/object_sensitive/struct/struct_deep5_001_T/struct_deep5_001_T.go\n AffectedNodeName: __taint_src\n 43: SOURCE: struct_deep5_001_T(__taint_src)\n /sast-go/cases/accuracy/object_sensitive/struct/struct_deep5_001_T/struct_deep5_001_T.go\n AffectedNodeName: struct_deep5_001_T\n 43: CALL: struct_deep5_001_T(__taint_src)\n /sast-go/cases/accuracy/object_sensitive/struct/struct_deep5_001_T/struct_deep5_001_T.go\n AffectedNodeName: __taint_src\n 28: ARG PASS: func struct_deep5_001_T(__taint_src string) {\n /sast-go/cases/accuracy/object_sensitive/struct/struct_deep5_001_T/struct_deep5_001_T.go\n AffectedNodeName: .deepB02].deepB03].deepB04].deepB05]\n 33: Var Pass: \tobj1.deepB02.deepB03.deepB04.deepB05 = __taint_src\n /sast-go/cases/accuracy/object_sensitive/struct/struct_deep5_001_T/struct_deep5_001_T.go\n AffectedNodeName: __taint_sink\n 35: SINK: \t__taint_sink(obj1)\n==========================================================\n #Total-findings:1\n==========================================================","/benchmarks/sast-go/cases/accuracy/object_sensitive/struct/struct_deep5_002_F/struct_deep5_002_F":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/sast-go/cases/accuracy/object_sensitive/struct/struct_deep5_002_F/struct_deep5_002_F.go\nLine 35: __taint_sink(obj2)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/sast-go/cases/accuracy/object_sensitive/struct/struct_deep5_002_F/struct_deep5_002_F.go\",\"functionName\":\"main\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /sast-go/cases/accuracy/object_sensitive/struct/struct_deep5_002_F/struct_deep5_002_F.go\n AffectedNodeName: __taint_src\n 43: SOURCE: struct_deep5_002_F(__taint_src)\n /sast-go/cases/accuracy/object_sensitive/struct/struct_deep5_002_F/struct_deep5_002_F.go\n AffectedNodeName: struct_deep5_002_F\n 43: CALL: struct_deep5_002_F(__taint_src)\n /sast-go/cases/accuracy/object_sensitive/struct/struct_deep5_002_F/struct_deep5_002_F.go\n AffectedNodeName: __taint_src\n 28: ARG PASS: func struct_deep5_002_F(__taint_src string) {\n /sast-go/cases/accuracy/object_sensitive/struct/struct_deep5_002_F/struct_deep5_002_F.go\n AffectedNodeName: .deepB02].deepB03].deepB04].deepB05]\n 33: Var Pass: \tobj1.deepB02.deepB03.deepB04.deepB05 = __taint_src\n /sast-go/cases/accuracy/object_sensitive/struct/struct_deep5_002_F/struct_deep5_002_F.go\n AffectedNodeName: __taint_sink\n 35: SINK: \t__taint_sink(obj2)\n==========================================================\n #Total-findings:1\n==========================================================","/benchmarks/sast-go/cases/accuracy/object_sensitive/struct/struct_deep5_003_T/struct_deep5_003_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/sast-go/cases/accuracy/object_sensitive/struct/struct_deep5_003_T/struct_deep5_003_T.go\nLine 42: __taint_sink(obj1)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/sast-go/cases/accuracy/object_sensitive/struct/struct_deep5_003_T/struct_deep5_003_T.go\",\"functionName\":\"main\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /sast-go/cases/accuracy/object_sensitive/struct/struct_deep5_003_T/struct_deep5_003_T.go\n AffectedNodeName: __taint_src\n 50: SOURCE: struct_deep5_003_T(__taint_src)\n /sast-go/cases/accuracy/object_sensitive/struct/struct_deep5_003_T/struct_deep5_003_T.go\n AffectedNodeName: struct_deep5_003_T\n 50: CALL: struct_deep5_003_T(__taint_src)\n /sast-go/cases/accuracy/object_sensitive/struct/struct_deep5_003_T/struct_deep5_003_T.go\n AffectedNodeName: __taint_src\n 32: ARG PASS: func struct_deep5_003_T(__taint_src string) {\n /sast-go/cases/accuracy/object_sensitive/struct/struct_deep5_003_T/struct_deep5_003_T.go\n AffectedNodeName: deepB05\n 37: Var Pass: \tdeepB05 := DeepB05{\n 38: Var Pass: \t\tdeepB06: __taint_src,\n 39: Var Pass: \t}\n /sast-go/cases/accuracy/object_sensitive/struct/struct_deep5_003_T/struct_deep5_003_T.go\n AffectedNodeName: .deepB02].deepB03].deepB04].deepB05]\n 40: Var Pass: \tobj1.deepB02.deepB03.deepB04.deepB05 = deepB05\n /sast-go/cases/accuracy/object_sensitive/struct/struct_deep5_003_T/struct_deep5_003_T.go\n AffectedNodeName: __taint_sink\n 42: SINK: \t__taint_sink(obj1)\n==========================================================\n #Total-findings:1\n==========================================================","/benchmarks/sast-go/cases/accuracy/object_sensitive/struct/struct_deep5_004_F/struct_deep5_004_F":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/sast-go/cases/accuracy/object_sensitive/struct/struct_deep5_004_F/struct_deep5_004_F.go\nLine 42: __taint_sink(obj2)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/sast-go/cases/accuracy/object_sensitive/struct/struct_deep5_004_F/struct_deep5_004_F.go\",\"functionName\":\"main\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /sast-go/cases/accuracy/object_sensitive/struct/struct_deep5_004_F/struct_deep5_004_F.go\n AffectedNodeName: __taint_src\n 50: SOURCE: struct_deep5_004_F(__taint_src)\n /sast-go/cases/accuracy/object_sensitive/struct/struct_deep5_004_F/struct_deep5_004_F.go\n AffectedNodeName: struct_deep5_004_F\n 50: CALL: struct_deep5_004_F(__taint_src)\n /sast-go/cases/accuracy/object_sensitive/struct/struct_deep5_004_F/struct_deep5_004_F.go\n AffectedNodeName: __taint_src\n 32: ARG PASS: func struct_deep5_004_F(__taint_src string) {\n /sast-go/cases/accuracy/object_sensitive/struct/struct_deep5_004_F/struct_deep5_004_F.go\n AffectedNodeName: deepB05\n 37: Var Pass: \tdeepB05 := DeepB05{\n 38: Var Pass: \t\tdeepB06: __taint_src,\n 39: Var Pass: \t}\n /sast-go/cases/accuracy/object_sensitive/struct/struct_deep5_004_F/struct_deep5_004_F.go\n AffectedNodeName: .deepB02].deepB03].deepB04].deepB05]\n 40: Var Pass: \tobj1.deepB02.deepB03.deepB04.deepB05 = deepB05\n /sast-go/cases/accuracy/object_sensitive/struct/struct_deep5_004_F/struct_deep5_004_F.go\n AffectedNodeName: __taint_sink\n 42: SINK: \t__taint_sink(obj2)\n==========================================================\n #Total-findings:1\n==========================================================","/benchmarks/sast-go/cases/accuracy/path_sensitive/explicit_jump_control/break_003_T/break_003_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/sast-go/cases/accuracy/path_sensitive/explicit_jump_control/break_003_T/break_003_T.go\nLine 18: __taint_sink(res)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/sast-go/cases/accuracy/path_sensitive/explicit_jump_control/break_003_T/break_003_T.go\",\"functionName\":\"main\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /sast-go/cases/accuracy/path_sensitive/explicit_jump_control/break_003_T/break_003_T.go\n AffectedNodeName: __taint_src\n 25: SOURCE: break_003_T(__taint_src)\n /sast-go/cases/accuracy/path_sensitive/explicit_jump_control/break_003_T/break_003_T.go\n AffectedNodeName: break_003_T\n 25: CALL: break_003_T(__taint_src)\n /sast-go/cases/accuracy/path_sensitive/explicit_jump_control/break_003_T/break_003_T.go\n AffectedNodeName: __taint_src\n 12: ARG PASS: func break_003_T(__taint_src string) {\n /sast-go/cases/accuracy/path_sensitive/explicit_jump_control/break_003_T/break_003_T.go\n AffectedNodeName: res\n 16: Var Pass: \t\t\tres = __taint_src\n /sast-go/cases/accuracy/path_sensitive/explicit_jump_control/break_003_T/break_003_T.go\n AffectedNodeName: __taint_sink\n 18: SINK: \t\t__taint_sink(res)\n==========================================================\n #Total-findings:1\n==========================================================","/benchmarks/sast-go/cases/accuracy/path_sensitive/explicit_jump_control/break_004_F/break_004_F":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/sast-go/cases/accuracy/path_sensitive/explicit_jump_control/break_004_F/break_004_F.go\nLine 19: __taint_sink(res)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/sast-go/cases/accuracy/path_sensitive/explicit_jump_control/break_004_F/break_004_F.go\",\"functionName\":\"main\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /sast-go/cases/accuracy/path_sensitive/explicit_jump_control/break_004_F/break_004_F.go\n AffectedNodeName: __taint_src\n 26: SOURCE: break_004_F(__taint_src)\n /sast-go/cases/accuracy/path_sensitive/explicit_jump_control/break_004_F/break_004_F.go\n AffectedNodeName: break_004_F\n 26: CALL: break_004_F(__taint_src)\n /sast-go/cases/accuracy/path_sensitive/explicit_jump_control/break_004_F/break_004_F.go\n AffectedNodeName: __taint_src\n 12: ARG PASS: func break_004_F(__taint_src string) {\n /sast-go/cases/accuracy/path_sensitive/explicit_jump_control/break_004_F/break_004_F.go\n AffectedNodeName: res\n 16: Var Pass: \t\t\tres = __taint_src\n /sast-go/cases/accuracy/path_sensitive/explicit_jump_control/break_004_F/break_004_F.go\n AffectedNodeName: __taint_sink\n 19: SINK: \t\t__taint_sink(res)\n==========================================================\n #Total-findings:1\n==========================================================","/benchmarks/sast-go/cases/accuracy/path_sensitive/explicit_jump_control/break_label_003_T/break_label_003_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/sast-go/cases/accuracy/path_sensitive/explicit_jump_control/break_label_003_T/break_label_003_T.go\nLine 21: __taint_sink(res)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/sast-go/cases/accuracy/path_sensitive/explicit_jump_control/break_label_003_T/break_label_003_T.go\",\"functionName\":\"main\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /sast-go/cases/accuracy/path_sensitive/explicit_jump_control/break_label_003_T/break_label_003_T.go\n AffectedNodeName: __taint_src\n 27: SOURCE: break_label_003_T(__taint_src)\n /sast-go/cases/accuracy/path_sensitive/explicit_jump_control/break_label_003_T/break_label_003_T.go\n AffectedNodeName: break_label_003_T\n 27: CALL: break_label_003_T(__taint_src)\n /sast-go/cases/accuracy/path_sensitive/explicit_jump_control/break_label_003_T/break_label_003_T.go\n AffectedNodeName: __taint_src\n 12: ARG PASS: func break_label_003_T(__taint_src string) {\n /sast-go/cases/accuracy/path_sensitive/explicit_jump_control/break_label_003_T/break_label_003_T.go\n AffectedNodeName: res\n 17: Var Pass: \t\tres = __taint_src\n /sast-go/cases/accuracy/path_sensitive/explicit_jump_control/break_label_003_T/break_label_003_T.go\n AffectedNodeName: __taint_sink\n 21: SINK: \t__taint_sink(res)\n==========================================================\n #Total-findings:1\n==========================================================","/benchmarks/sast-go/cases/accuracy/path_sensitive/explicit_jump_control/break_label_004_F/break_label_004_F":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/sast-go/cases/accuracy/path_sensitive/explicit_jump_control/break_label_004_F/break_label_004_F.go\nLine 21: __taint_sink(res)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/sast-go/cases/accuracy/path_sensitive/explicit_jump_control/break_label_004_F/break_label_004_F.go\",\"functionName\":\"main\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /sast-go/cases/accuracy/path_sensitive/explicit_jump_control/break_label_004_F/break_label_004_F.go\n AffectedNodeName: __taint_src\n 27: SOURCE: break_label_004_F(__taint_src)\n /sast-go/cases/accuracy/path_sensitive/explicit_jump_control/break_label_004_F/break_label_004_F.go\n AffectedNodeName: break_label_004_F\n 27: CALL: break_label_004_F(__taint_src)\n /sast-go/cases/accuracy/path_sensitive/explicit_jump_control/break_label_004_F/break_label_004_F.go\n AffectedNodeName: __taint_src\n 12: ARG PASS: func break_label_004_F(__taint_src string) {\n /sast-go/cases/accuracy/path_sensitive/explicit_jump_control/break_label_004_F/break_label_004_F.go\n AffectedNodeName: res\n 18: Var Pass: \t\tres = __taint_src\n /sast-go/cases/accuracy/path_sensitive/explicit_jump_control/break_label_004_F/break_label_004_F.go\n AffectedNodeName: __taint_sink\n 21: SINK: \t__taint_sink(res)\n==========================================================\n #Total-findings:1\n==========================================================","/benchmarks/sast-go/cases/accuracy/path_sensitive/explicit_jump_control/continue_003_T/continue_003_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/sast-go/cases/accuracy/path_sensitive/explicit_jump_control/continue_003_T/continue_003_T.go\nLine 20: __taint_sink(res)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/sast-go/cases/accuracy/path_sensitive/explicit_jump_control/continue_003_T/continue_003_T.go\",\"functionName\":\"main\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /sast-go/cases/accuracy/path_sensitive/explicit_jump_control/continue_003_T/continue_003_T.go\n AffectedNodeName: __taint_src\n 26: SOURCE: continue_003_T(__taint_src)\n /sast-go/cases/accuracy/path_sensitive/explicit_jump_control/continue_003_T/continue_003_T.go\n AffectedNodeName: continue_003_T\n 26: CALL: continue_003_T(__taint_src)\n /sast-go/cases/accuracy/path_sensitive/explicit_jump_control/continue_003_T/continue_003_T.go\n AffectedNodeName: __taint_src\n 12: ARG PASS: func continue_003_T(__taint_src string) {\n /sast-go/cases/accuracy/path_sensitive/explicit_jump_control/continue_003_T/continue_003_T.go\n AffectedNodeName: res\n 16: Var Pass: \t\t\tres = __taint_src\n /sast-go/cases/accuracy/path_sensitive/explicit_jump_control/continue_003_T/continue_003_T.go\n AffectedNodeName: __taint_sink\n 20: SINK: \t__taint_sink(res)\n==========================================================\n #Total-findings:1\n==========================================================","/benchmarks/sast-go/cases/accuracy/path_sensitive/explicit_jump_control/continue_004_F/continue_004_F":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/sast-go/cases/accuracy/path_sensitive/explicit_jump_control/continue_004_F/continue_004_F.go\nLine 18: __taint_sink(res)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/sast-go/cases/accuracy/path_sensitive/explicit_jump_control/continue_004_F/continue_004_F.go\",\"functionName\":\"main\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /sast-go/cases/accuracy/path_sensitive/explicit_jump_control/continue_004_F/continue_004_F.go\n AffectedNodeName: __taint_src\n 26: SOURCE: continue_004_F(__taint_src)\n /sast-go/cases/accuracy/path_sensitive/explicit_jump_control/continue_004_F/continue_004_F.go\n AffectedNodeName: continue_004_F\n 26: CALL: continue_004_F(__taint_src)\n /sast-go/cases/accuracy/path_sensitive/explicit_jump_control/continue_004_F/continue_004_F.go\n AffectedNodeName: __taint_src\n 12: ARG PASS: func continue_004_F(__taint_src string) {\n /sast-go/cases/accuracy/path_sensitive/explicit_jump_control/continue_004_F/continue_004_F.go\n AffectedNodeName: res\n 16: Var Pass: \t\t\tres = __taint_src\n /sast-go/cases/accuracy/path_sensitive/explicit_jump_control/continue_004_F/continue_004_F.go\n AffectedNodeName: __taint_sink\n 18: SINK: \t\t\t__taint_sink(res)\n==========================================================\n #Total-findings:1\n==========================================================","/benchmarks/sast-go/cases/accuracy/path_sensitive/explicit_jump_control/fallthrough_003_T/fallthrough_003_T":"======================== Findings ========================\nNo findings!\n==========================================================","/benchmarks/sast-go/cases/accuracy/path_sensitive/explicit_jump_control/fallthrough_004_F/fallthrough_004_F":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/sast-go/cases/accuracy/path_sensitive/explicit_jump_control/fallthrough_004_F/fallthrough_004_F.go\nLine 24: __taint_sink(res)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/sast-go/cases/accuracy/path_sensitive/explicit_jump_control/fallthrough_004_F/fallthrough_004_F.go\",\"functionName\":\"main\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /sast-go/cases/accuracy/path_sensitive/explicit_jump_control/fallthrough_004_F/fallthrough_004_F.go\n AffectedNodeName: __taint_src\n 30: SOURCE: fallthrough_004_F(__taint_src)\n /sast-go/cases/accuracy/path_sensitive/explicit_jump_control/fallthrough_004_F/fallthrough_004_F.go\n AffectedNodeName: fallthrough_004_F\n 30: CALL: fallthrough_004_F(__taint_src)\n /sast-go/cases/accuracy/path_sensitive/explicit_jump_control/fallthrough_004_F/fallthrough_004_F.go\n AffectedNodeName: __taint_src\n 12: ARG PASS: func fallthrough_004_F(__taint_src string) {\n /sast-go/cases/accuracy/path_sensitive/explicit_jump_control/fallthrough_004_F/fallthrough_004_F.go\n AffectedNodeName: res\n 18: Var Pass: \t\tres = __taint_src\n /sast-go/cases/accuracy/path_sensitive/explicit_jump_control/fallthrough_004_F/fallthrough_004_F.go\n AffectedNodeName: __taint_sink\n 24: SINK: \t__taint_sink(res)\n==========================================================\n #Total-findings:1\n==========================================================","/benchmarks/sast-go/cases/accuracy/path_sensitive/explicit_jump_control/goto_003_T/goto_003_T":"======================== Findings ========================\nNo findings!\n==========================================================","/benchmarks/sast-go/cases/accuracy/path_sensitive/explicit_jump_control/goto_004_F/goto_004_F":"======================== Findings ========================\nNo findings!\n==========================================================","/benchmarks/sast-go/cases/accuracy/path_sensitive/explicit_jump_control/return_003_T/return_003_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/sast-go/cases/accuracy/path_sensitive/explicit_jump_control/return_003_T/return_003_T.go\nLine 16: __taint_sink(__taint_src)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/sast-go/cases/accuracy/path_sensitive/explicit_jump_control/return_003_T/return_003_T.go\",\"functionName\":\"main\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /sast-go/cases/accuracy/path_sensitive/explicit_jump_control/return_003_T/return_003_T.go\n AffectedNodeName: __taint_src\n 23: SOURCE: return_003_T(__taint_src)\n /sast-go/cases/accuracy/path_sensitive/explicit_jump_control/return_003_T/return_003_T.go\n AffectedNodeName: return_003_T\n 23: CALL: return_003_T(__taint_src)\n /sast-go/cases/accuracy/path_sensitive/explicit_jump_control/return_003_T/return_003_T.go\n AffectedNodeName: __taint_src\n 12: ARG PASS: func return_003_T(__taint_src string) string {\n /sast-go/cases/accuracy/path_sensitive/explicit_jump_control/return_003_T/return_003_T.go\n AffectedNodeName: __taint_sink\n 16: SINK: \t__taint_sink(__taint_src)\n==========================================================\n #Total-findings:1\n==========================================================","/benchmarks/sast-go/cases/accuracy/path_sensitive/explicit_jump_control/return_004_F/return_004_F":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/sast-go/cases/accuracy/path_sensitive/explicit_jump_control/return_004_F/return_004_F.go\nLine 16: __taint_sink(__taint_src)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/sast-go/cases/accuracy/path_sensitive/explicit_jump_control/return_004_F/return_004_F.go\",\"functionName\":\"main\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /sast-go/cases/accuracy/path_sensitive/explicit_jump_control/return_004_F/return_004_F.go\n AffectedNodeName: __taint_src\n 23: SOURCE: return_004_F(__taint_src)\n /sast-go/cases/accuracy/path_sensitive/explicit_jump_control/return_004_F/return_004_F.go\n AffectedNodeName: return_004_F\n 23: CALL: return_004_F(__taint_src)\n /sast-go/cases/accuracy/path_sensitive/explicit_jump_control/return_004_F/return_004_F.go\n AffectedNodeName: __taint_src\n 12: ARG PASS: func return_004_F(__taint_src string) string {\n /sast-go/cases/accuracy/path_sensitive/explicit_jump_control/return_004_F/return_004_F.go\n AffectedNodeName: __taint_sink\n 16: SINK: \t__taint_sink(__taint_src)\n==========================================================\n #Total-findings:1\n==========================================================","/benchmarks/sast-go/cases/accuracy/path_sensitive/loop_conditional_stmt/no_solver/conditional_if_005_F/conditional_if_005_F":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/sast-go/cases/accuracy/path_sensitive/loop_conditional_stmt/no_solver/conditional_if_005_F/conditional_if_005_F.go\nLine 17: __taint_sink(res)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/sast-go/cases/accuracy/path_sensitive/loop_conditional_stmt/no_solver/conditional_if_005_F/conditional_if_005_F.go\",\"functionName\":\"main\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /sast-go/cases/accuracy/path_sensitive/loop_conditional_stmt/no_solver/conditional_if_005_F/conditional_if_005_F.go\n AffectedNodeName: __taint_src\n 24: SOURCE: conditional_if_005_F(__taint_src)\n /sast-go/cases/accuracy/path_sensitive/loop_conditional_stmt/no_solver/conditional_if_005_F/conditional_if_005_F.go\n AffectedNodeName: conditional_if_005_F\n 24: CALL: conditional_if_005_F(__taint_src)\n /sast-go/cases/accuracy/path_sensitive/loop_conditional_stmt/no_solver/conditional_if_005_F/conditional_if_005_F.go\n AffectedNodeName: __taint_src\n 12: ARG PASS: func conditional_if_005_F(__taint_src string) {\n /sast-go/cases/accuracy/path_sensitive/loop_conditional_stmt/no_solver/conditional_if_005_F/conditional_if_005_F.go\n AffectedNodeName: res\n 15: Var Pass: \t\tres = __taint_src\n /sast-go/cases/accuracy/path_sensitive/loop_conditional_stmt/no_solver/conditional_if_005_F/conditional_if_005_F.go\n AffectedNodeName: __taint_sink\n 17: SINK: \t\t__taint_sink(res)\n==========================================================\n #Total-findings:1\n==========================================================","/benchmarks/sast-go/cases/accuracy/path_sensitive/loop_conditional_stmt/no_solver/conditional_if_006_F/conditional_if_006_F":"======================== Findings ========================\nNo findings!\n==========================================================","/benchmarks/sast-go/cases/accuracy/path_sensitive/loop_conditional_stmt/no_solver/conditional_if_007_T/conditional_if_007_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/sast-go/cases/accuracy/path_sensitive/loop_conditional_stmt/no_solver/conditional_if_007_T/conditional_if_007_T.go\nLine 19: __taint_sink(res)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/sast-go/cases/accuracy/path_sensitive/loop_conditional_stmt/no_solver/conditional_if_007_T/conditional_if_007_T.go\",\"functionName\":\"main\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /sast-go/cases/accuracy/path_sensitive/loop_conditional_stmt/no_solver/conditional_if_007_T/conditional_if_007_T.go\n AffectedNodeName: __taint_src\n 25: SOURCE: conditional_if_007_T(__taint_src)\n /sast-go/cases/accuracy/path_sensitive/loop_conditional_stmt/no_solver/conditional_if_007_T/conditional_if_007_T.go\n AffectedNodeName: conditional_if_007_T\n 25: CALL: conditional_if_007_T(__taint_src)\n /sast-go/cases/accuracy/path_sensitive/loop_conditional_stmt/no_solver/conditional_if_007_T/conditional_if_007_T.go\n AffectedNodeName: __taint_src\n 12: ARG PASS: func conditional_if_007_T(__taint_src string) {\n /sast-go/cases/accuracy/path_sensitive/loop_conditional_stmt/no_solver/conditional_if_007_T/conditional_if_007_T.go\n AffectedNodeName: res\n 15: Var Pass: \t\tres = __taint_src\n /sast-go/cases/accuracy/path_sensitive/loop_conditional_stmt/no_solver/conditional_if_007_T/conditional_if_007_T.go\n AffectedNodeName: __taint_sink\n 19: SINK: \t__taint_sink(res)\n==========================================================\n #Total-findings:1\n==========================================================","/benchmarks/sast-go/cases/accuracy/path_sensitive/loop_conditional_stmt/no_solver/conditional_if_008_F/conditional_if_008_F":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/sast-go/cases/accuracy/path_sensitive/loop_conditional_stmt/no_solver/conditional_if_008_F/conditional_if_008_F.go\nLine 19: __taint_sink(res)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/sast-go/cases/accuracy/path_sensitive/loop_conditional_stmt/no_solver/conditional_if_008_F/conditional_if_008_F.go\",\"functionName\":\"main\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /sast-go/cases/accuracy/path_sensitive/loop_conditional_stmt/no_solver/conditional_if_008_F/conditional_if_008_F.go\n AffectedNodeName: __taint_src\n 25: SOURCE: conditional_if_008_F(__taint_src)\n /sast-go/cases/accuracy/path_sensitive/loop_conditional_stmt/no_solver/conditional_if_008_F/conditional_if_008_F.go\n AffectedNodeName: conditional_if_008_F\n 25: CALL: conditional_if_008_F(__taint_src)\n /sast-go/cases/accuracy/path_sensitive/loop_conditional_stmt/no_solver/conditional_if_008_F/conditional_if_008_F.go\n AffectedNodeName: __taint_src\n 12: ARG PASS: func conditional_if_008_F(__taint_src string) {\n /sast-go/cases/accuracy/path_sensitive/loop_conditional_stmt/no_solver/conditional_if_008_F/conditional_if_008_F.go\n AffectedNodeName: res\n 17: Var Pass: \t\tres = __taint_src\n /sast-go/cases/accuracy/path_sensitive/loop_conditional_stmt/no_solver/conditional_if_008_F/conditional_if_008_F.go\n AffectedNodeName: __taint_sink\n 19: SINK: \t__taint_sink(res)\n==========================================================\n #Total-findings:1\n==========================================================","/benchmarks/sast-go/cases/accuracy/path_sensitive/loop_conditional_stmt/no_solver/conditional_switch_stmt_003_F/conditional_switch_stmt_003_F":"======================== Findings ========================\nNo findings!\n==========================================================","/benchmarks/sast-go/cases/accuracy/path_sensitive/loop_conditional_stmt/no_solver/conditional_switch_stmt_004_F/conditional_switch_stmt_004_F":"======================== Findings ========================\nNo findings!\n==========================================================","/benchmarks/sast-go/cases/accuracy/path_sensitive/loop_conditional_stmt/no_solver/conditional_switch_stmt_005_T/conditional_switch_stmt_005_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/sast-go/cases/accuracy/path_sensitive/loop_conditional_stmt/no_solver/conditional_switch_stmt_005_T/conditional_switch_stmt_005_T.go\nLine 20: __taint_sink(res)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/sast-go/cases/accuracy/path_sensitive/loop_conditional_stmt/no_solver/conditional_switch_stmt_005_T/conditional_switch_stmt_005_T.go\",\"functionName\":\"main\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /sast-go/cases/accuracy/path_sensitive/loop_conditional_stmt/no_solver/conditional_switch_stmt_005_T/conditional_switch_stmt_005_T.go\n AffectedNodeName: __taint_src\n 26: SOURCE: conditional_switch_stmt_005_T(__taint_src)\n /sast-go/cases/accuracy/path_sensitive/loop_conditional_stmt/no_solver/conditional_switch_stmt_005_T/conditional_switch_stmt_005_T.go\n AffectedNodeName: conditional_switch_stmt_005_T\n 26: CALL: conditional_switch_stmt_005_T(__taint_src)\n /sast-go/cases/accuracy/path_sensitive/loop_conditional_stmt/no_solver/conditional_switch_stmt_005_T/conditional_switch_stmt_005_T.go\n AffectedNodeName: __taint_src\n 12: ARG PASS: func conditional_switch_stmt_005_T(__taint_src string) {\n /sast-go/cases/accuracy/path_sensitive/loop_conditional_stmt/no_solver/conditional_switch_stmt_005_T/conditional_switch_stmt_005_T.go\n AffectedNodeName: res\n 18: Var Pass: \t\tres = __taint_src\n /sast-go/cases/accuracy/path_sensitive/loop_conditional_stmt/no_solver/conditional_switch_stmt_005_T/conditional_switch_stmt_005_T.go\n AffectedNodeName: __taint_sink\n 20: SINK: \t__taint_sink(res)\n==========================================================\n #Total-findings:1\n==========================================================","/benchmarks/sast-go/cases/accuracy/path_sensitive/loop_conditional_stmt/no_solver/conditional_switch_stmt_006_F/conditional_switch_stmt_006_F":"======================== Findings ========================\nNo findings!\n==========================================================","/benchmarks/sast-go/cases/accuracy/path_sensitive/loop_conditional_stmt/solver/conditional_if_009_T/conditional_if_009_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/sast-go/cases/accuracy/path_sensitive/loop_conditional_stmt/solver/conditional_if_009_T/conditional_if_009_T.go\nLine 19: __taint_sink(res)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/sast-go/cases/accuracy/path_sensitive/loop_conditional_stmt/solver/conditional_if_009_T/conditional_if_009_T.go\",\"functionName\":\"main\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /sast-go/cases/accuracy/path_sensitive/loop_conditional_stmt/solver/conditional_if_009_T/conditional_if_009_T.go\n AffectedNodeName: __taint_src\n 25: SOURCE: conditional_if_009_T(__taint_src)\n /sast-go/cases/accuracy/path_sensitive/loop_conditional_stmt/solver/conditional_if_009_T/conditional_if_009_T.go\n AffectedNodeName: conditional_if_009_T\n 25: CALL: conditional_if_009_T(__taint_src)\n /sast-go/cases/accuracy/path_sensitive/loop_conditional_stmt/solver/conditional_if_009_T/conditional_if_009_T.go\n AffectedNodeName: __taint_src\n 12: ARG PASS: func conditional_if_009_T(__taint_src string) {\n /sast-go/cases/accuracy/path_sensitive/loop_conditional_stmt/solver/conditional_if_009_T/conditional_if_009_T.go\n AffectedNodeName: res\n 15: Var Pass: \t\tres = __taint_src\n /sast-go/cases/accuracy/path_sensitive/loop_conditional_stmt/solver/conditional_if_009_T/conditional_if_009_T.go\n AffectedNodeName: __taint_sink\n 19: SINK: \t__taint_sink(res)\n==========================================================\n #Total-findings:1\n==========================================================","/benchmarks/sast-go/cases/accuracy/path_sensitive/loop_conditional_stmt/solver/conditional_if_010_F/conditional_if_010_F":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/sast-go/cases/accuracy/path_sensitive/loop_conditional_stmt/solver/conditional_if_010_F/conditional_if_010_F.go\nLine 19: __taint_sink(res)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/sast-go/cases/accuracy/path_sensitive/loop_conditional_stmt/solver/conditional_if_010_F/conditional_if_010_F.go\",\"functionName\":\"main\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /sast-go/cases/accuracy/path_sensitive/loop_conditional_stmt/solver/conditional_if_010_F/conditional_if_010_F.go\n AffectedNodeName: __taint_src\n 25: SOURCE: conditional_if_010_F(__taint_src)\n /sast-go/cases/accuracy/path_sensitive/loop_conditional_stmt/solver/conditional_if_010_F/conditional_if_010_F.go\n AffectedNodeName: conditional_if_010_F\n 25: CALL: conditional_if_010_F(__taint_src)\n /sast-go/cases/accuracy/path_sensitive/loop_conditional_stmt/solver/conditional_if_010_F/conditional_if_010_F.go\n AffectedNodeName: __taint_src\n 12: ARG PASS: func conditional_if_010_F(__taint_src string) {\n /sast-go/cases/accuracy/path_sensitive/loop_conditional_stmt/solver/conditional_if_010_F/conditional_if_010_F.go\n AffectedNodeName: res\n 17: Var Pass: \t\tres = __taint_src\n /sast-go/cases/accuracy/path_sensitive/loop_conditional_stmt/solver/conditional_if_010_F/conditional_if_010_F.go\n AffectedNodeName: __taint_sink\n 19: SINK: \t__taint_sink(res)\n==========================================================\n #Total-findings:1\n==========================================================","/benchmarks/sast-go/cases/accuracy/path_sensitive/loop_conditional_stmt/solver/conditional_switch_stmt_007_T/conditional_switch_stmt_007_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/sast-go/cases/accuracy/path_sensitive/loop_conditional_stmt/solver/conditional_switch_stmt_007_T/conditional_switch_stmt_007_T.go\nLine 20: __taint_sink(res)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/sast-go/cases/accuracy/path_sensitive/loop_conditional_stmt/solver/conditional_switch_stmt_007_T/conditional_switch_stmt_007_T.go\",\"functionName\":\"main\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /sast-go/cases/accuracy/path_sensitive/loop_conditional_stmt/solver/conditional_switch_stmt_007_T/conditional_switch_stmt_007_T.go\n AffectedNodeName: __taint_src\n 26: SOURCE: conditional_switch_stmt_007_T(__taint_src)\n /sast-go/cases/accuracy/path_sensitive/loop_conditional_stmt/solver/conditional_switch_stmt_007_T/conditional_switch_stmt_007_T.go\n AffectedNodeName: conditional_switch_stmt_007_T\n 26: CALL: conditional_switch_stmt_007_T(__taint_src)\n /sast-go/cases/accuracy/path_sensitive/loop_conditional_stmt/solver/conditional_switch_stmt_007_T/conditional_switch_stmt_007_T.go\n AffectedNodeName: __taint_src\n 12: ARG PASS: func conditional_switch_stmt_007_T(__taint_src string) {\n /sast-go/cases/accuracy/path_sensitive/loop_conditional_stmt/solver/conditional_switch_stmt_007_T/conditional_switch_stmt_007_T.go\n AffectedNodeName: res\n 16: Var Pass: \t\tres = __taint_src\n /sast-go/cases/accuracy/path_sensitive/loop_conditional_stmt/solver/conditional_switch_stmt_007_T/conditional_switch_stmt_007_T.go\n AffectedNodeName: __taint_sink\n 20: SINK: \t__taint_sink(res)\n==========================================================\n #Total-findings:1\n==========================================================","/benchmarks/sast-go/cases/accuracy/path_sensitive/loop_conditional_stmt/solver/conditional_switch_stmt_008_F/conditional_switch_stmt_008_F":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/sast-go/cases/accuracy/path_sensitive/loop_conditional_stmt/solver/conditional_switch_stmt_008_F/conditional_switch_stmt_008_F.go\nLine 20: __taint_sink(res)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/sast-go/cases/accuracy/path_sensitive/loop_conditional_stmt/solver/conditional_switch_stmt_008_F/conditional_switch_stmt_008_F.go\",\"functionName\":\"main\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /sast-go/cases/accuracy/path_sensitive/loop_conditional_stmt/solver/conditional_switch_stmt_008_F/conditional_switch_stmt_008_F.go\n AffectedNodeName: __taint_src\n 26: SOURCE: conditional_switch_stmt_008_F(__taint_src)\n /sast-go/cases/accuracy/path_sensitive/loop_conditional_stmt/solver/conditional_switch_stmt_008_F/conditional_switch_stmt_008_F.go\n AffectedNodeName: conditional_switch_stmt_008_F\n 26: CALL: conditional_switch_stmt_008_F(__taint_src)\n /sast-go/cases/accuracy/path_sensitive/loop_conditional_stmt/solver/conditional_switch_stmt_008_F/conditional_switch_stmt_008_F.go\n AffectedNodeName: __taint_src\n 12: ARG PASS: func conditional_switch_stmt_008_F(__taint_src string) {\n /sast-go/cases/accuracy/path_sensitive/loop_conditional_stmt/solver/conditional_switch_stmt_008_F/conditional_switch_stmt_008_F.go\n AffectedNodeName: res\n 16: Var Pass: \t\tres = __taint_src\n /sast-go/cases/accuracy/path_sensitive/loop_conditional_stmt/solver/conditional_switch_stmt_008_F/conditional_switch_stmt_008_F.go\n AffectedNodeName: __taint_sink\n 20: SINK: \t__taint_sink(res)\n==========================================================\n #Total-findings:1\n==========================================================","/benchmarks/sast-go/cases/accuracy/path_sensitive/loop_conditional_stmt/solver/for_body_003_T/for_body_003_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/sast-go/cases/accuracy/path_sensitive/loop_conditional_stmt/solver/for_body_003_T/for_body_003_T.go\nLine 17: __taint_sink(res)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/sast-go/cases/accuracy/path_sensitive/loop_conditional_stmt/solver/for_body_003_T/for_body_003_T.go\",\"functionName\":\"main\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /sast-go/cases/accuracy/path_sensitive/loop_conditional_stmt/solver/for_body_003_T/for_body_003_T.go\n AffectedNodeName: __taint_src\n 23: SOURCE: for_body_003_T(__taint_src)\n /sast-go/cases/accuracy/path_sensitive/loop_conditional_stmt/solver/for_body_003_T/for_body_003_T.go\n AffectedNodeName: for_body_003_T\n 23: CALL: for_body_003_T(__taint_src)\n /sast-go/cases/accuracy/path_sensitive/loop_conditional_stmt/solver/for_body_003_T/for_body_003_T.go\n AffectedNodeName: __taint_src\n 12: ARG PASS: func for_body_003_T(__taint_src string) {\n /sast-go/cases/accuracy/path_sensitive/loop_conditional_stmt/solver/for_body_003_T/for_body_003_T.go\n AffectedNodeName: res\n 15: Var Pass: \t\tres = __taint_src\n /sast-go/cases/accuracy/path_sensitive/loop_conditional_stmt/solver/for_body_003_T/for_body_003_T.go\n AffectedNodeName: __taint_sink\n 17: SINK: \t__taint_sink(res)\n==========================================================\n #Total-findings:1\n==========================================================","/benchmarks/sast-go/cases/accuracy/path_sensitive/loop_conditional_stmt/solver/for_body_004_F/for_body_004_F":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/sast-go/cases/accuracy/path_sensitive/loop_conditional_stmt/solver/for_body_004_F/for_body_004_F.go\nLine 16: __taint_sink(res)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/sast-go/cases/accuracy/path_sensitive/loop_conditional_stmt/solver/for_body_004_F/for_body_004_F.go\",\"functionName\":\"main\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /sast-go/cases/accuracy/path_sensitive/loop_conditional_stmt/solver/for_body_004_F/for_body_004_F.go\n AffectedNodeName: __taint_src\n 22: SOURCE: for_body_004_F(__taint_src)\n /sast-go/cases/accuracy/path_sensitive/loop_conditional_stmt/solver/for_body_004_F/for_body_004_F.go\n AffectedNodeName: for_body_004_F\n 22: CALL: for_body_004_F(__taint_src)\n /sast-go/cases/accuracy/path_sensitive/loop_conditional_stmt/solver/for_body_004_F/for_body_004_F.go\n AffectedNodeName: __taint_src\n 11: ARG PASS: func for_body_004_F(__taint_src string) {\n /sast-go/cases/accuracy/path_sensitive/loop_conditional_stmt/solver/for_body_004_F/for_body_004_F.go\n AffectedNodeName: res\n 14: Var Pass: \t\tres = __taint_src\n /sast-go/cases/accuracy/path_sensitive/loop_conditional_stmt/solver/for_body_004_F/for_body_004_F.go\n AffectedNodeName: __taint_sink\n 16: SINK: \t__taint_sink(res)\n==========================================================\n #Total-findings:1\n==========================================================","/benchmarks/sast-go/cases/completeness/dynamic_tracing/reflect_call/reflect_call_001_T/reflect_call_001_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/sast-go/cases/completeness/dynamic_tracing/reflect_call/reflect_call_001_T/reflect_call_001_T.go\nLine 26: __taint_sink(s.Field(i))\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/sast-go/cases/completeness/dynamic_tracing/reflect_call/reflect_call_001_T/reflect_call_001_T.go\",\"functionName\":\"main\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /sast-go/cases/completeness/dynamic_tracing/reflect_call/reflect_call_001_T/reflect_call_001_T.go\n AffectedNodeName: __taint_src\n 34: SOURCE: reflect_call_001_T(__taint_src)\n /sast-go/cases/completeness/dynamic_tracing/reflect_call/reflect_call_001_T/reflect_call_001_T.go\n AffectedNodeName: reflect_call_001_T\n 34: CALL: reflect_call_001_T(__taint_src)\n /sast-go/cases/completeness/dynamic_tracing/reflect_call/reflect_call_001_T/reflect_call_001_T.go\n AffectedNodeName: __taint_src\n 21: ARG PASS: func reflect_call_001_T(__taint_src string) {\n /sast-go/cases/completeness/dynamic_tracing/reflect_call/reflect_call_001_T/reflect_call_001_T.go\n AffectedNodeName: t\n 22: Var Pass: \tt := T{123, __taint_src}\n /sast-go/cases/completeness/dynamic_tracing/reflect_call/reflect_call_001_T/reflect_call_001_T.go\n AffectedNodeName: s\n 23: Var Pass: \ts := reflect.ValueOf(t)\n /sast-go/cases/completeness/dynamic_tracing/reflect_call/reflect_call_001_T/reflect_call_001_T.go\n AffectedNodeName: __taint_sink\n 26: SINK: \t\t__taint_sink(s.Field(i))\n\n------------- 2: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/sast-go/cases/completeness/dynamic_tracing/reflect_call/reflect_call_001_T/reflect_call_001_T.go\nLine 26: __taint_sink(s.Field(i))\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/sast-go/cases/completeness/dynamic_tracing/reflect_call/reflect_call_001_T/reflect_call_001_T.go\",\"functionName\":\"main\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /sast-go/cases/completeness/dynamic_tracing/reflect_call/reflect_call_001_T/reflect_call_001_T.go\n AffectedNodeName: __taint_src\n 34: SOURCE: reflect_call_001_T(__taint_src)\n /sast-go/cases/completeness/dynamic_tracing/reflect_call/reflect_call_001_T/reflect_call_001_T.go\n AffectedNodeName: reflect_call_001_T\n 34: CALL: reflect_call_001_T(__taint_src)\n /sast-go/cases/completeness/dynamic_tracing/reflect_call/reflect_call_001_T/reflect_call_001_T.go\n AffectedNodeName: __taint_src\n 21: ARG PASS: func reflect_call_001_T(__taint_src string) {\n /sast-go/cases/completeness/dynamic_tracing/reflect_call/reflect_call_001_T/reflect_call_001_T.go\n AffectedNodeName: t\n 22: Var Pass: \tt := T{123, __taint_src}\n /sast-go/cases/completeness/dynamic_tracing/reflect_call/reflect_call_001_T/reflect_call_001_T.go\n AffectedNodeName: s\n 23: Var Pass: \ts := reflect.ValueOf(t)\n /sast-go/cases/completeness/dynamic_tracing/reflect_call/reflect_call_001_T/reflect_call_001_T.go\n AffectedNodeName: __taint_sink\n 26: CALL: \t\t__taint_sink(s.Field(i))\n /sast-go/cases/completeness/dynamic_tracing/reflect_call/reflect_call_001_T/reflect_call_001_T.go\n AffectedNodeName: o\n 30: ARG PASS: func __taint_sink(o interface{}) {\n /sast-go/cases/completeness/dynamic_tracing/reflect_call/reflect_call_001_T/reflect_call_001_T.go\n AffectedNodeName: __taint_sink\n 26: SINK: \t\t__taint_sink(s.Field(i))\n==========================================================\n #Total-findings:2\n==========================================================","/benchmarks/sast-go/cases/completeness/dynamic_tracing/reflect_call/reflect_call_002_F/reflect_call_002_F":"======================== Findings ========================\nNo findings!\n==========================================================","/benchmarks/sast-go/cases/completeness/single_app_tracing/alias/alias_001_F/alias_001_F":"======================== Findings ========================\nNo findings!\n==========================================================","/benchmarks/sast-go/cases/completeness/single_app_tracing/alias/alias_002_T/alias_002_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/sast-go/cases/completeness/single_app_tracing/alias/alias_002_T/alias_002_T.go\nLine 21: __taint_sink(a.Value)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/sast-go/cases/completeness/single_app_tracing/alias/alias_002_T/alias_002_T.go\",\"functionName\":\"main\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /sast-go/cases/completeness/single_app_tracing/alias/alias_002_T/alias_002_T.go\n AffectedNodeName: __taint_src\n 28: SOURCE: alias_002_T(__taint_src)\n /sast-go/cases/completeness/single_app_tracing/alias/alias_002_T/alias_002_T.go\n AffectedNodeName: alias_002_T\n 28: CALL: alias_002_T(__taint_src)\n /sast-go/cases/completeness/single_app_tracing/alias/alias_002_T/alias_002_T.go\n AffectedNodeName: __taint_src\n 12: ARG PASS: func alias_002_T(__taint_src string) {\n /sast-go/cases/completeness/single_app_tracing/alias/alias_002_T/alias_002_T.go\n AffectedNodeName: [b.Value]\n 19: Var Pass: \tb.Value = __taint_src\n /sast-go/cases/completeness/single_app_tracing/alias/alias_002_T/alias_002_T.go\n AffectedNodeName: __taint_sink\n 21: SINK: \t__taint_sink(a.Value)\n==========================================================\n #Total-findings:1\n==========================================================","/benchmarks/sast-go/cases/completeness/single_app_tracing/asynchronous_tracing/multi_thread/asynchronous_goroutine_channel_001_T/asynchronous_goroutine_channel_001_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/sast-go/cases/completeness/single_app_tracing/asynchronous_tracing/multi_thread/asynchronous_goroutine_channel_001_T/asynchronous_goroutine_channel_001_T.go\nLine 17: __taint_sink(popch)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/sast-go/cases/completeness/single_app_tracing/asynchronous_tracing/multi_thread/asynchronous_goroutine_channel_001_T/asynchronous_goroutine_channel_001_T.go\",\"functionName\":\"main\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /sast-go/cases/completeness/single_app_tracing/asynchronous_tracing/multi_thread/asynchronous_goroutine_channel_001_T/asynchronous_goroutine_channel_001_T.go\n AffectedNodeName: __taint_src\n 24: SOURCE: asynchronous_goroutine_channel_001_T(__taint_src)\n /sast-go/cases/completeness/single_app_tracing/asynchronous_tracing/multi_thread/asynchronous_goroutine_channel_001_T/asynchronous_goroutine_channel_001_T.go\n AffectedNodeName: asynchronous_goroutine_channel_001_T\n 24: CALL: asynchronous_goroutine_channel_001_T(__taint_src)\n /sast-go/cases/completeness/single_app_tracing/asynchronous_tracing/multi_thread/asynchronous_goroutine_channel_001_T/asynchronous_goroutine_channel_001_T.go\n AffectedNodeName: __taint_src\n 12: ARG PASS: func asynchronous_goroutine_channel_001_T(__taint_src string) {\n /sast-go/cases/completeness/single_app_tracing/asynchronous_tracing/multi_thread/asynchronous_goroutine_channel_001_T/asynchronous_goroutine_channel_001_T.go\n AffectedNodeName: __taint_sink\n 17: SINK: \t__taint_sink(<-ch)\n==========================================================\n #Total-findings:1\n==========================================================","/benchmarks/sast-go/cases/completeness/single_app_tracing/asynchronous_tracing/multi_thread/asynchronous_goroutine_channel_002_F/asynchronous_goroutine_channel_002_F":"======================== Findings ========================\nNo findings!\n==========================================================","/benchmarks/sast-go/cases/completeness/single_app_tracing/asynchronous_tracing/multi_thread/asynchronous_goroutine_channel_003_T/asynchronous_goroutine_channel_003_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/sast-go/cases/completeness/single_app_tracing/asynchronous_tracing/multi_thread/asynchronous_goroutine_channel_003_T/asynchronous_goroutine_channel_003_T.go\nLine 30: __taint_sink(message)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/sast-go/cases/completeness/single_app_tracing/asynchronous_tracing/multi_thread/asynchronous_goroutine_channel_003_T/asynchronous_goroutine_channel_003_T.go\",\"functionName\":\"main\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /sast-go/cases/completeness/single_app_tracing/asynchronous_tracing/multi_thread/asynchronous_goroutine_channel_003_T/asynchronous_goroutine_channel_003_T.go\n AffectedNodeName: __taint_src\n 40: SOURCE: asynchronous_goroutine_channel_003_T(__taint_src)\n /sast-go/cases/completeness/single_app_tracing/asynchronous_tracing/multi_thread/asynchronous_goroutine_channel_003_T/asynchronous_goroutine_channel_003_T.go\n AffectedNodeName: asynchronous_goroutine_channel_003_T\n 40: CALL: asynchronous_goroutine_channel_003_T(__taint_src)\n /sast-go/cases/completeness/single_app_tracing/asynchronous_tracing/multi_thread/asynchronous_goroutine_channel_003_T/asynchronous_goroutine_channel_003_T.go\n AffectedNodeName: __taint_src\n 16: ARG PASS: func asynchronous_goroutine_channel_003_T(__taint_src string) {\n /sast-go/cases/completeness/single_app_tracing/asynchronous_tracing/multi_thread/asynchronous_goroutine_channel_003_T/asynchronous_goroutine_channel_003_T.go\n AffectedNodeName: __taint_sink\n 30: SINK: \t\t__taint_sink(message)\n==========================================================\n #Total-findings:1\n==========================================================","/benchmarks/sast-go/cases/completeness/single_app_tracing/asynchronous_tracing/multi_thread/asynchronous_goroutine_channel_004_F/asynchronous_goroutine_channel_004_F":"======================== Findings ========================\nNo findings!\n==========================================================","/benchmarks/sast-go/cases/completeness/single_app_tracing/asynchronous_tracing/multi_thread/asynchronous_multiple_select_001_T/asynchronous_multiple_select_001_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/sast-go/cases/completeness/single_app_tracing/asynchronous_tracing/multi_thread/asynchronous_multiple_select_001_T/asynchronous_multiple_select_001_T.go\nLine 33: __taint_sink(result)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/sast-go/cases/completeness/single_app_tracing/asynchronous_tracing/multi_thread/asynchronous_multiple_select_001_T/asynchronous_multiple_select_001_T.go\",\"functionName\":\"main\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /sast-go/cases/completeness/single_app_tracing/asynchronous_tracing/multi_thread/asynchronous_multiple_select_001_T/asynchronous_multiple_select_001_T.go\n AffectedNodeName: __taint_src\n 45: SOURCE: asynchronous_multiple_select_001_T(__taint_src)\n /sast-go/cases/completeness/single_app_tracing/asynchronous_tracing/multi_thread/asynchronous_multiple_select_001_T/asynchronous_multiple_select_001_T.go\n AffectedNodeName: asynchronous_multiple_select_001_T\n 45: CALL: asynchronous_multiple_select_001_T(__taint_src)\n /sast-go/cases/completeness/single_app_tracing/asynchronous_tracing/multi_thread/asynchronous_multiple_select_001_T/asynchronous_multiple_select_001_T.go\n AffectedNodeName: __taint_src\n 17: ARG PASS: func asynchronous_multiple_select_001_T(__taint_src string) {\n /sast-go/cases/completeness/single_app_tracing/asynchronous_tracing/multi_thread/asynchronous_multiple_select_001_T/asynchronous_multiple_select_001_T.go\n AffectedNodeName: result\n 22: Var Pass: \t\tresult := __taint_src\n /sast-go/cases/completeness/single_app_tracing/asynchronous_tracing/multi_thread/asynchronous_multiple_select_001_T/asynchronous_multiple_select_001_T.go\n AffectedNodeName: __taint_sink\n 33: SINK: \t\t__taint_sink(result)\n==========================================================\n #Total-findings:1\n==========================================================","/benchmarks/sast-go/cases/completeness/single_app_tracing/asynchronous_tracing/multi_thread/asynchronous_multiple_select_002_F/asynchronous_multiple_select_002_F":"======================== Findings ========================\nNo findings!\n==========================================================","/benchmarks/sast-go/cases/completeness/single_app_tracing/asynchronous_tracing/multi_thread/asynchronous_select_001_T/asynchronous_select_001_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/sast-go/cases/completeness/single_app_tracing/asynchronous_tracing/multi_thread/asynchronous_select_001_T/asynchronous_select_001_T.go\nLine 26: __taint_sink(result)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/sast-go/cases/completeness/single_app_tracing/asynchronous_tracing/multi_thread/asynchronous_select_001_T/asynchronous_select_001_T.go\",\"functionName\":\"main\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /sast-go/cases/completeness/single_app_tracing/asynchronous_tracing/multi_thread/asynchronous_select_001_T/asynchronous_select_001_T.go\n AffectedNodeName: __taint_src\n 36: SOURCE: asynchronous_select_001_T(__taint_src)\n /sast-go/cases/completeness/single_app_tracing/asynchronous_tracing/multi_thread/asynchronous_select_001_T/asynchronous_select_001_T.go\n AffectedNodeName: asynchronous_select_001_T\n 36: CALL: asynchronous_select_001_T(__taint_src)\n /sast-go/cases/completeness/single_app_tracing/asynchronous_tracing/multi_thread/asynchronous_select_001_T/asynchronous_select_001_T.go\n AffectedNodeName: __taint_src\n 17: ARG PASS: func asynchronous_select_001_T(__taint_src string) {\n /sast-go/cases/completeness/single_app_tracing/asynchronous_tracing/multi_thread/asynchronous_select_001_T/asynchronous_select_001_T.go\n AffectedNodeName: __taint_sink\n 26: SINK: \t\t__taint_sink(result)\n==========================================================\n #Total-findings:1\n==========================================================","/benchmarks/sast-go/cases/completeness/single_app_tracing/asynchronous_tracing/multi_thread/asynchronous_select_002_F/asynchronous_select_002_F":"======================== Findings ========================\nNo findings!\n==========================================================","/benchmarks/sast-go/cases/completeness/single_app_tracing/asynchronous_tracing/synchronization_primitive/synchronization_primitive_001_T/synchronization_primitive_001_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/sast-go/cases/completeness/single_app_tracing/asynchronous_tracing/synchronization_primitive/synchronization_primitive_001_T/synchronization_primitive_001_T.go\nLine 16: __taint_sink(result)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/sast-go/cases/completeness/single_app_tracing/asynchronous_tracing/synchronization_primitive/synchronization_primitive_001_T/synchronization_primitive_001_T.go\",\"functionName\":\"main\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /sast-go/cases/completeness/single_app_tracing/asynchronous_tracing/synchronization_primitive/synchronization_primitive_001_T/synchronization_primitive_001_T.go\n AffectedNodeName: __taint_src\n 22: SOURCE: synchronization_primitive_001_T(__taint_src)\n /sast-go/cases/completeness/single_app_tracing/asynchronous_tracing/synchronization_primitive/synchronization_primitive_001_T/synchronization_primitive_001_T.go\n AffectedNodeName: synchronization_primitive_001_T\n 22: CALL: synchronization_primitive_001_T(__taint_src)\n /sast-go/cases/completeness/single_app_tracing/asynchronous_tracing/synchronization_primitive/synchronization_primitive_001_T/synchronization_primitive_001_T.go\n AffectedNodeName: __taint_src\n 12: ARG PASS: func synchronization_primitive_001_T(__taint_src string) {\n /sast-go/cases/completeness/single_app_tracing/asynchronous_tracing/synchronization_primitive/synchronization_primitive_001_T/synchronization_primitive_001_T.go\n AffectedNodeName: __taint_sink\n 16: SINK: \t__taint_sink(result)\n==========================================================\n #Total-findings:1\n==========================================================","/benchmarks/sast-go/cases/completeness/single_app_tracing/asynchronous_tracing/synchronization_primitive/synchronization_primitive_002_F/synchronization_primitive_002_F":"======================== Findings ========================\nNo findings!\n==========================================================","/benchmarks/sast-go/cases/completeness/single_app_tracing/asynchronous_tracing/synchronization_primitive/synchronization_primitive_003_T/synchronization_primitive_003_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/sast-go/cases/completeness/single_app_tracing/asynchronous_tracing/synchronization_primitive/synchronization_primitive_003_T/synchronization_primitive_003_T.go\nLine 19: __taint_sink(result)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/sast-go/cases/completeness/single_app_tracing/asynchronous_tracing/synchronization_primitive/synchronization_primitive_003_T/synchronization_primitive_003_T.go\",\"functionName\":\"main\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /sast-go/cases/completeness/single_app_tracing/asynchronous_tracing/synchronization_primitive/synchronization_primitive_003_T/synchronization_primitive_003_T.go\n AffectedNodeName: __taint_src\n 25: SOURCE: synchronization_primitive_003_T(__taint_src)\n /sast-go/cases/completeness/single_app_tracing/asynchronous_tracing/synchronization_primitive/synchronization_primitive_003_T/synchronization_primitive_003_T.go\n AffectedNodeName: synchronization_primitive_003_T\n 25: CALL: synchronization_primitive_003_T(__taint_src)\n /sast-go/cases/completeness/single_app_tracing/asynchronous_tracing/synchronization_primitive/synchronization_primitive_003_T/synchronization_primitive_003_T.go\n AffectedNodeName: __taint_src\n 12: ARG PASS: func synchronization_primitive_003_T(__taint_src string) {\n /sast-go/cases/completeness/single_app_tracing/asynchronous_tracing/synchronization_primitive/synchronization_primitive_003_T/synchronization_primitive_003_T.go\n AffectedNodeName: __taint_sink\n 19: SINK: \t__taint_sink(result)\n==========================================================\n #Total-findings:1\n==========================================================","/benchmarks/sast-go/cases/completeness/single_app_tracing/asynchronous_tracing/synchronization_primitive/synchronization_primitive_004_F/synchronization_primitive_004_F":"======================== Findings ========================\nNo findings!\n==========================================================","/benchmarks/sast-go/cases/completeness/single_app_tracing/control_flow/conditional_stmt/conditional_if_001_T/conditional_if_001_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/sast-go/cases/completeness/single_app_tracing/control_flow/conditional_stmt/conditional_if_001_T/conditional_if_001_T.go\nLine 14: __taint_sink(__taint_src)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/sast-go/cases/completeness/single_app_tracing/control_flow/conditional_stmt/conditional_if_001_T/conditional_if_001_T.go\",\"functionName\":\"main\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /sast-go/cases/completeness/single_app_tracing/control_flow/conditional_stmt/conditional_if_001_T/conditional_if_001_T.go\n AffectedNodeName: __taint_src\n 21: SOURCE: conditional_if_001_T(__taint_src)\n /sast-go/cases/completeness/single_app_tracing/control_flow/conditional_stmt/conditional_if_001_T/conditional_if_001_T.go\n AffectedNodeName: conditional_if_001_T\n 21: CALL: conditional_if_001_T(__taint_src)\n /sast-go/cases/completeness/single_app_tracing/control_flow/conditional_stmt/conditional_if_001_T/conditional_if_001_T.go\n AffectedNodeName: __taint_src\n 12: ARG PASS: func conditional_if_001_T(__taint_src string) {\n /sast-go/cases/completeness/single_app_tracing/control_flow/conditional_stmt/conditional_if_001_T/conditional_if_001_T.go\n AffectedNodeName: __taint_sink\n 14: SINK: \t\t__taint_sink(__taint_src)\n==========================================================\n #Total-findings:1\n==========================================================","/benchmarks/sast-go/cases/completeness/single_app_tracing/control_flow/conditional_stmt/conditional_if_002_F/conditional_if_002_F":"======================== Findings ========================\nNo findings!\n==========================================================","/benchmarks/sast-go/cases/completeness/single_app_tracing/control_flow/conditional_stmt/conditional_if_003_T/conditional_if_003_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/sast-go/cases/completeness/single_app_tracing/control_flow/conditional_stmt/conditional_if_003_T/conditional_if_003_T.go\nLine 16: __taint_sink(__taint_src)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/sast-go/cases/completeness/single_app_tracing/control_flow/conditional_stmt/conditional_if_003_T/conditional_if_003_T.go\",\"functionName\":\"main\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /sast-go/cases/completeness/single_app_tracing/control_flow/conditional_stmt/conditional_if_003_T/conditional_if_003_T.go\n AffectedNodeName: __taint_src\n 25: SOURCE: conditional_if_003_T(__taint_src)\n /sast-go/cases/completeness/single_app_tracing/control_flow/conditional_stmt/conditional_if_003_T/conditional_if_003_T.go\n AffectedNodeName: conditional_if_003_T\n 25: CALL: conditional_if_003_T(__taint_src)\n /sast-go/cases/completeness/single_app_tracing/control_flow/conditional_stmt/conditional_if_003_T/conditional_if_003_T.go\n AffectedNodeName: __taint_src\n 12: ARG PASS: func conditional_if_003_T(__taint_src string) {\n /sast-go/cases/completeness/single_app_tracing/control_flow/conditional_stmt/conditional_if_003_T/conditional_if_003_T.go\n AffectedNodeName: __taint_sink\n 16: SINK: \t\t__taint_sink(__taint_src)\n==========================================================\n #Total-findings:1\n==========================================================","/benchmarks/sast-go/cases/completeness/single_app_tracing/control_flow/conditional_stmt/conditional_if_004_F/conditional_if_004_F":"======================== Findings ========================\nNo findings!\n==========================================================","/benchmarks/sast-go/cases/completeness/single_app_tracing/control_flow/conditional_stmt/conditional_switch_001_T/conditional_switch_001_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/sast-go/cases/completeness/single_app_tracing/control_flow/conditional_stmt/conditional_switch_001_T/conditional_switch_001_T.go\nLine 15: __taint_sink(__taint_src)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/sast-go/cases/completeness/single_app_tracing/control_flow/conditional_stmt/conditional_switch_001_T/conditional_switch_001_T.go\",\"functionName\":\"main\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /sast-go/cases/completeness/single_app_tracing/control_flow/conditional_stmt/conditional_switch_001_T/conditional_switch_001_T.go\n AffectedNodeName: __taint_src\n 22: SOURCE: conditional_switch_001_T(__taint_src)\n /sast-go/cases/completeness/single_app_tracing/control_flow/conditional_stmt/conditional_switch_001_T/conditional_switch_001_T.go\n AffectedNodeName: conditional_switch_001_T\n 22: CALL: conditional_switch_001_T(__taint_src)\n /sast-go/cases/completeness/single_app_tracing/control_flow/conditional_stmt/conditional_switch_001_T/conditional_switch_001_T.go\n AffectedNodeName: __taint_src\n 12: ARG PASS: func conditional_switch_001_T(__taint_src string) {\n /sast-go/cases/completeness/single_app_tracing/control_flow/conditional_stmt/conditional_switch_001_T/conditional_switch_001_T.go\n AffectedNodeName: __taint_sink\n 15: SINK: \t\t__taint_sink(__taint_src)\n==========================================================\n #Total-findings:1\n==========================================================","/benchmarks/sast-go/cases/completeness/single_app_tracing/control_flow/conditional_stmt/conditional_switch_002_F/conditional_switch_002_F":"======================== Findings ========================\nNo findings!\n==========================================================","/benchmarks/sast-go/cases/completeness/single_app_tracing/control_flow/conditional_stmt/conditional_switch_003_T/conditional_switch_003_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/sast-go/cases/completeness/single_app_tracing/control_flow/conditional_stmt/conditional_switch_003_T/conditional_switch_003_T.go\nLine 16: __taint_sink(data)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/sast-go/cases/completeness/single_app_tracing/control_flow/conditional_stmt/conditional_switch_003_T/conditional_switch_003_T.go\",\"functionName\":\"main\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /sast-go/cases/completeness/single_app_tracing/control_flow/conditional_stmt/conditional_switch_003_T/conditional_switch_003_T.go\n AffectedNodeName: __taint_src\n 23: SOURCE: conditional_switch_003_T(__taint_src)\n /sast-go/cases/completeness/single_app_tracing/control_flow/conditional_stmt/conditional_switch_003_T/conditional_switch_003_T.go\n AffectedNodeName: conditional_switch_003_T\n 23: CALL: conditional_switch_003_T(__taint_src)\n /sast-go/cases/completeness/single_app_tracing/control_flow/conditional_stmt/conditional_switch_003_T/conditional_switch_003_T.go\n AffectedNodeName: __taint_src\n 12: ARG PASS: func conditional_switch_003_T(__taint_src string) {\n /sast-go/cases/completeness/single_app_tracing/control_flow/conditional_stmt/conditional_switch_003_T/conditional_switch_003_T.go\n AffectedNodeName: data\n 14: Var Pass: \tswitch data := __taint_src; data {\n /sast-go/cases/completeness/single_app_tracing/control_flow/conditional_stmt/conditional_switch_003_T/conditional_switch_003_T.go\n AffectedNodeName: __taint_sink\n 16: SINK: \t\t__taint_sink(data)\n==========================================================\n #Total-findings:1\n==========================================================","/benchmarks/sast-go/cases/completeness/single_app_tracing/control_flow/conditional_stmt/conditional_switch_004_F/conditional_switch_004_F":"======================== Findings ========================\nNo findings!\n==========================================================","/benchmarks/sast-go/cases/completeness/single_app_tracing/control_flow/conditional_stmt/conditional_switch_005_T/conditional_switch_005_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/sast-go/cases/completeness/single_app_tracing/control_flow/conditional_stmt/conditional_switch_005_T/conditional_switch_005_T.go\nLine 22: __taint_sink(__taint_src)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/sast-go/cases/completeness/single_app_tracing/control_flow/conditional_stmt/conditional_switch_005_T/conditional_switch_005_T.go\",\"functionName\":\"main\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /sast-go/cases/completeness/single_app_tracing/control_flow/conditional_stmt/conditional_switch_005_T/conditional_switch_005_T.go\n AffectedNodeName: __taint_src\n 30: SOURCE: conditional_switch_005_T(__taint_src)\n /sast-go/cases/completeness/single_app_tracing/control_flow/conditional_stmt/conditional_switch_005_T/conditional_switch_005_T.go\n AffectedNodeName: conditional_switch_005_T\n 30: CALL: conditional_switch_005_T(__taint_src)\n /sast-go/cases/completeness/single_app_tracing/control_flow/conditional_stmt/conditional_switch_005_T/conditional_switch_005_T.go\n AffectedNodeName: __taint_src\n 12: ARG PASS: func conditional_switch_005_T(__taint_src string) {\n /sast-go/cases/completeness/single_app_tracing/control_flow/conditional_stmt/conditional_switch_005_T/conditional_switch_005_T.go\n AffectedNodeName: __taint_sink\n 22: SINK: \t\t\t__taint_sink(__taint_src)\n==========================================================\n #Total-findings:1\n==========================================================","/benchmarks/sast-go/cases/completeness/single_app_tracing/control_flow/conditional_stmt/conditional_switch_006_F/conditional_switch_006_F":"======================== Findings ========================\nNo findings!\n==========================================================","/benchmarks/sast-go/cases/completeness/single_app_tracing/control_flow/conditional_stmt/select_001_T/select_001_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/sast-go/cases/completeness/single_app_tracing/control_flow/conditional_stmt/select_001_T/select_001_T.go\nLine 18: __taint_sink(data)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/sast-go/cases/completeness/single_app_tracing/control_flow/conditional_stmt/select_001_T/select_001_T.go\",\"functionName\":\"main\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /sast-go/cases/completeness/single_app_tracing/control_flow/conditional_stmt/select_001_T/select_001_T.go\n AffectedNodeName: __taint_src\n 27: SOURCE: select_001_T(__taint_src)\n /sast-go/cases/completeness/single_app_tracing/control_flow/conditional_stmt/select_001_T/select_001_T.go\n AffectedNodeName: select_001_T\n 27: CALL: select_001_T(__taint_src)\n /sast-go/cases/completeness/single_app_tracing/control_flow/conditional_stmt/select_001_T/select_001_T.go\n AffectedNodeName: __taint_src\n 12: ARG PASS: func select_001_T(__taint_src string) {\n /sast-go/cases/completeness/single_app_tracing/control_flow/conditional_stmt/select_001_T/select_001_T.go\n AffectedNodeName: __taint_sink\n 18: SINK: \t\t__taint_sink(data)\n==========================================================\n #Total-findings:1\n==========================================================","/benchmarks/sast-go/cases/completeness/single_app_tracing/control_flow/conditional_stmt/select_002_F/select_002_F":"======================== Findings ========================\nNo findings!\n==========================================================","/benchmarks/sast-go/cases/completeness/single_app_tracing/control_flow/loop_stmt/for_body_001_T/for_body_001_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/sast-go/cases/completeness/single_app_tracing/control_flow/loop_stmt/for_body_001_T/for_body_001_T.go\nLine 18: __taint_sink(res)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/sast-go/cases/completeness/single_app_tracing/control_flow/loop_stmt/for_body_001_T/for_body_001_T.go\",\"functionName\":\"main\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /sast-go/cases/completeness/single_app_tracing/control_flow/loop_stmt/for_body_001_T/for_body_001_T.go\n AffectedNodeName: __taint_src\n 24: SOURCE: for_body_001_T(__taint_src)\n /sast-go/cases/completeness/single_app_tracing/control_flow/loop_stmt/for_body_001_T/for_body_001_T.go\n AffectedNodeName: for_body_001_T\n 24: CALL: for_body_001_T(__taint_src)\n /sast-go/cases/completeness/single_app_tracing/control_flow/loop_stmt/for_body_001_T/for_body_001_T.go\n AffectedNodeName: __taint_src\n 12: ARG PASS: func for_body_001_T(__taint_src string) {\n /sast-go/cases/completeness/single_app_tracing/control_flow/loop_stmt/for_body_001_T/for_body_001_T.go\n AffectedNodeName: res\n 16: Var Pass: \t\tres = __taint_src\n /sast-go/cases/completeness/single_app_tracing/control_flow/loop_stmt/for_body_001_T/for_body_001_T.go\n AffectedNodeName: __taint_sink\n 18: SINK: \t__taint_sink(res)\n==========================================================\n #Total-findings:1\n==========================================================","/benchmarks/sast-go/cases/completeness/single_app_tracing/control_flow/loop_stmt/for_body_002_F/for_body_002_F":"======================== Findings ========================\nNo findings!\n==========================================================","/benchmarks/sast-go/cases/completeness/single_app_tracing/control_flow/loop_stmt/for_init_001_T/for_init_001_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/sast-go/cases/completeness/single_app_tracing/control_flow/loop_stmt/for_init_001_T/for_init_001_T.go\nLine 19: __taint_sink(res)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/sast-go/cases/completeness/single_app_tracing/control_flow/loop_stmt/for_init_001_T/for_init_001_T.go\",\"functionName\":\"main\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /sast-go/cases/completeness/single_app_tracing/control_flow/loop_stmt/for_init_001_T/for_init_001_T.go\n AffectedNodeName: __taint_src\n 25: SOURCE: for_init_001_T(__taint_src)\n /sast-go/cases/completeness/single_app_tracing/control_flow/loop_stmt/for_init_001_T/for_init_001_T.go\n AffectedNodeName: for_init_001_T\n 25: CALL: for_init_001_T(__taint_src)\n /sast-go/cases/completeness/single_app_tracing/control_flow/loop_stmt/for_init_001_T/for_init_001_T.go\n AffectedNodeName: __taint_src\n 12: ARG PASS: func for_init_001_T(__taint_src int) {\n /sast-go/cases/completeness/single_app_tracing/control_flow/loop_stmt/for_init_001_T/for_init_001_T.go\n AffectedNodeName: ini\n 16: Var Pass: \tfor ini = __taint_src; j < 10; j++ {\n /sast-go/cases/completeness/single_app_tracing/control_flow/loop_stmt/for_init_001_T/for_init_001_T.go\n AffectedNodeName: res\n 17: Var Pass: \t\tres = res + ini\n /sast-go/cases/completeness/single_app_tracing/control_flow/loop_stmt/for_init_001_T/for_init_001_T.go\n AffectedNodeName: __taint_sink\n 19: SINK: \t__taint_sink(res)\n==========================================================\n #Total-findings:1\n==========================================================","/benchmarks/sast-go/cases/completeness/single_app_tracing/control_flow/loop_stmt/for_init_002_F/for_init_002_F":"======================== Findings ========================\nNo findings!\n==========================================================","/benchmarks/sast-go/cases/completeness/single_app_tracing/control_flow/loop_stmt/for_range_001_T/for_range_001_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/sast-go/cases/completeness/single_app_tracing/control_flow/loop_stmt/for_range_001_T/for_range_001_T.go\nLine 15: __taint_sink(res)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/sast-go/cases/completeness/single_app_tracing/control_flow/loop_stmt/for_range_001_T/for_range_001_T.go\",\"functionName\":\"main\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /sast-go/cases/completeness/single_app_tracing/control_flow/loop_stmt/for_range_001_T/for_range_001_T.go\n AffectedNodeName: __taint_src\n 22: SOURCE: for_range_001_T(__taint_src)\n /sast-go/cases/completeness/single_app_tracing/control_flow/loop_stmt/for_range_001_T/for_range_001_T.go\n AffectedNodeName: for_range_001_T\n 22: CALL: for_range_001_T(__taint_src)\n /sast-go/cases/completeness/single_app_tracing/control_flow/loop_stmt/for_range_001_T/for_range_001_T.go\n AffectedNodeName: __taint_src\n 12: ARG PASS: func for_range_001_T(__taint_src string) {\n /sast-go/cases/completeness/single_app_tracing/control_flow/loop_stmt/for_range_001_T/for_range_001_T.go\n AffectedNodeName: m\n 13: Var Pass: \tvar m = map[string]string{\"a\": __taint_src, \"b\": \"2\"}\n /sast-go/cases/completeness/single_app_tracing/control_flow/loop_stmt/for_range_001_T/for_range_001_T.go\n AffectedNodeName: __taint_sink\n 15: SINK: \t\t__taint_sink(res)\n==========================================================\n #Total-findings:1\n==========================================================","/benchmarks/sast-go/cases/completeness/single_app_tracing/control_flow/loop_stmt/for_range_002_F/for_range_002_F":"======================== Findings ========================\nNo findings!\n==========================================================","/benchmarks/sast-go/cases/completeness/single_app_tracing/control_flow/loop_stmt/for_update_001_T/for_update_001_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/sast-go/cases/completeness/single_app_tracing/control_flow/loop_stmt/for_update_001_T/for_update_001_T.go\nLine 20: __taint_sink(res)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/sast-go/cases/completeness/single_app_tracing/control_flow/loop_stmt/for_update_001_T/for_update_001_T.go\",\"functionName\":\"main\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /sast-go/cases/completeness/single_app_tracing/control_flow/loop_stmt/for_update_001_T/for_update_001_T.go\n AffectedNodeName: __taint_src\n 26: SOURCE: for_update_001_T(__taint_src)\n /sast-go/cases/completeness/single_app_tracing/control_flow/loop_stmt/for_update_001_T/for_update_001_T.go\n AffectedNodeName: for_update_001_T\n 26: CALL: for_update_001_T(__taint_src)\n /sast-go/cases/completeness/single_app_tracing/control_flow/loop_stmt/for_update_001_T/for_update_001_T.go\n AffectedNodeName: __taint_src\n 12: ARG PASS: func for_update_001_T(__taint_src int) {\n /sast-go/cases/completeness/single_app_tracing/control_flow/loop_stmt/for_update_001_T/for_update_001_T.go\n AffectedNodeName: j\n 16: Var Pass: \tfor ; ini < 2; j = __taint_src {\n /sast-go/cases/completeness/single_app_tracing/control_flow/loop_stmt/for_update_001_T/for_update_001_T.go\n AffectedNodeName: res\n 17: Var Pass: \t\tres = j\n /sast-go/cases/completeness/single_app_tracing/control_flow/loop_stmt/for_update_001_T/for_update_001_T.go\n AffectedNodeName: __taint_sink\n 20: SINK: \t__taint_sink(res)\n==========================================================\n #Total-findings:1\n==========================================================","/benchmarks/sast-go/cases/completeness/single_app_tracing/control_flow/loop_stmt/for_update_002_F/for_update_002_F":"======================== Findings ========================\nNo findings!\n==========================================================","/benchmarks/sast-go/cases/completeness/single_app_tracing/datatype/array/array_001_T/array_001_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/sast-go/cases/completeness/single_app_tracing/datatype/array/array_001_T/array_001_T.go\nLine 14: __taint_sink(str)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/sast-go/cases/completeness/single_app_tracing/datatype/array/array_001_T/array_001_T.go\",\"functionName\":\"main\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /sast-go/cases/completeness/single_app_tracing/datatype/array/array_001_T/array_001_T.go\n AffectedNodeName: __taint_src\n 21: SOURCE: array_001_T(__taint_src)\n /sast-go/cases/completeness/single_app_tracing/datatype/array/array_001_T/array_001_T.go\n AffectedNodeName: array_001_T\n 21: CALL: array_001_T(__taint_src)\n /sast-go/cases/completeness/single_app_tracing/datatype/array/array_001_T/array_001_T.go\n AffectedNodeName: __taint_src\n 12: ARG PASS: func array_001_T(__taint_src string) {\n /sast-go/cases/completeness/single_app_tracing/datatype/array/array_001_T/array_001_T.go\n AffectedNodeName: str\n 13: Var Pass: \tvar str = [3]string{__taint_src, \"b\", \"c\"}\n /sast-go/cases/completeness/single_app_tracing/datatype/array/array_001_T/array_001_T.go\n AffectedNodeName: __taint_sink\n 14: SINK: \t__taint_sink(str)\n==========================================================\n #Total-findings:1\n==========================================================","/benchmarks/sast-go/cases/completeness/single_app_tracing/datatype/array/array_002_F/array_002_F":"======================== Findings ========================\nNo findings!\n==========================================================","/benchmarks/sast-go/cases/completeness/single_app_tracing/datatype/array/array_003_T/array_003_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/sast-go/cases/completeness/single_app_tracing/datatype/array/array_003_T/array_003_T.go\nLine 14: __taint_sink(str)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/sast-go/cases/completeness/single_app_tracing/datatype/array/array_003_T/array_003_T.go\",\"functionName\":\"main\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /sast-go/cases/completeness/single_app_tracing/datatype/array/array_003_T/array_003_T.go\n AffectedNodeName: __taint_src\n 21: SOURCE: array_003_T(__taint_src)\n /sast-go/cases/completeness/single_app_tracing/datatype/array/array_003_T/array_003_T.go\n AffectedNodeName: array_003_T\n 21: CALL: array_003_T(__taint_src)\n /sast-go/cases/completeness/single_app_tracing/datatype/array/array_003_T/array_003_T.go\n AffectedNodeName: __taint_src\n 12: ARG PASS: func array_003_T(__taint_src string) {\n /sast-go/cases/completeness/single_app_tracing/datatype/array/array_003_T/array_003_T.go\n AffectedNodeName: str\n 13: Var Pass: \tvar str = [3][1]string{[1]string{__taint_src}, [1]string{\"b\"}, [1]string{\"c\"}}\n /sast-go/cases/completeness/single_app_tracing/datatype/array/array_003_T/array_003_T.go\n AffectedNodeName: __taint_sink\n 14: SINK: \t__taint_sink(str)\n==========================================================\n #Total-findings:1\n==========================================================","/benchmarks/sast-go/cases/completeness/single_app_tracing/datatype/array/array_004_F/array_004_F":"======================== Findings ========================\nNo findings!\n==========================================================","/benchmarks/sast-go/cases/completeness/single_app_tracing/datatype/array/array_005_T/array_005_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/sast-go/cases/completeness/single_app_tracing/datatype/array/array_005_T/array_005_T.go\nLine 13: __taint_sink(__taint_src)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/sast-go/cases/completeness/single_app_tracing/datatype/array/array_005_T/array_005_T.go\",\"functionName\":\"main\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /sast-go/cases/completeness/single_app_tracing/datatype/array/array_005_T/array_005_T.go\n AffectedNodeName: __taint_src\n 20: SOURCE: array_005_T(__taint_src)\n /sast-go/cases/completeness/single_app_tracing/datatype/array/array_005_T/array_005_T.go\n AffectedNodeName: array_005_T\n 20: CALL: array_005_T(__taint_src)\n /sast-go/cases/completeness/single_app_tracing/datatype/array/array_005_T/array_005_T.go\n AffectedNodeName: __taint_src\n 12: ARG PASS: func array_005_T(__taint_src [3]string) {\n /sast-go/cases/completeness/single_app_tracing/datatype/array/array_005_T/array_005_T.go\n AffectedNodeName: __taint_sink\n 13: SINK: \t__taint_sink(__taint_src)\n==========================================================\n #Total-findings:1\n==========================================================","/benchmarks/sast-go/cases/completeness/single_app_tracing/datatype/array/array_006_F/array_006_F":"======================== Findings ========================\nNo findings!\n==========================================================","/benchmarks/sast-go/cases/completeness/single_app_tracing/datatype/array/array_007_T/array_007_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/sast-go/cases/completeness/single_app_tracing/datatype/array/array_007_T/array_007_T.go\nLine 14: __taint_sink(str)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/sast-go/cases/completeness/single_app_tracing/datatype/array/array_007_T/array_007_T.go\",\"functionName\":\"main\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /sast-go/cases/completeness/single_app_tracing/datatype/array/array_007_T/array_007_T.go\n AffectedNodeName: __taint_src\n 20: SOURCE: array_007_T(__taint_src)\n /sast-go/cases/completeness/single_app_tracing/datatype/array/array_007_T/array_007_T.go\n AffectedNodeName: array_007_T\n 20: CALL: array_007_T(__taint_src)\n /sast-go/cases/completeness/single_app_tracing/datatype/array/array_007_T/array_007_T.go\n AffectedNodeName: __taint_src\n 12: ARG PASS: func array_007_T(__taint_src string) {\n /sast-go/cases/completeness/single_app_tracing/datatype/array/array_007_T/array_007_T.go\n AffectedNodeName: str\n 13: Var Pass: \tvar str = [...]string{__taint_src, \"b\", \"c\"}\n /sast-go/cases/completeness/single_app_tracing/datatype/array/array_007_T/array_007_T.go\n AffectedNodeName: __taint_sink\n 14: SINK: \t__taint_sink(str)\n==========================================================\n #Total-findings:1\n==========================================================","/benchmarks/sast-go/cases/completeness/single_app_tracing/datatype/array/array_008_F/array_008_F":"======================== Findings ========================\nNo findings!\n==========================================================","/benchmarks/sast-go/cases/completeness/single_app_tracing/datatype/generics/generics_001_T/generics_001_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/sast-go/cases/completeness/single_app_tracing/datatype/generics/generics_001_T/generics_001_T.go\nLine 16: __taint_sink(s)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/sast-go/cases/completeness/single_app_tracing/datatype/generics/generics_001_T/generics_001_T.go\",\"functionName\":\"main\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /sast-go/cases/completeness/single_app_tracing/datatype/generics/generics_001_T/generics_001_T.go\n AffectedNodeName: __taint_src\n 23: SOURCE: generics_001_T(__taint_src)\n /sast-go/cases/completeness/single_app_tracing/datatype/generics/generics_001_T/generics_001_T.go\n AffectedNodeName: generics_001_T\n 23: CALL: generics_001_T(__taint_src)\n /sast-go/cases/completeness/single_app_tracing/datatype/generics/generics_001_T/generics_001_T.go\n AffectedNodeName: __taint_src\n 14: ARG PASS: func generics_001_T(__taint_src string) {\n /sast-go/cases/completeness/single_app_tracing/datatype/generics/generics_001_T/generics_001_T.go\n AffectedNodeName: s\n 15: Var Pass: \tvar s Slice[string] = []string{\"a\", \"b\", __taint_src}\n /sast-go/cases/completeness/single_app_tracing/datatype/generics/generics_001_T/generics_001_T.go\n AffectedNodeName: __taint_sink\n 16: SINK: \t__taint_sink(s)\n==========================================================\n #Total-findings:1\n==========================================================","/benchmarks/sast-go/cases/completeness/single_app_tracing/datatype/generics/generics_002_F/generics_002_F":"======================== Findings ========================\nNo findings!\n==========================================================","/benchmarks/sast-go/cases/completeness/single_app_tracing/datatype/map/map_001_T/map_001_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/sast-go/cases/completeness/single_app_tracing/datatype/map/map_001_T/map_001_T.go\nLine 15: __taint_sink(m)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/sast-go/cases/completeness/single_app_tracing/datatype/map/map_001_T/map_001_T.go\",\"functionName\":\"main\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /sast-go/cases/completeness/single_app_tracing/datatype/map/map_001_T/map_001_T.go\n AffectedNodeName: __taint_src\n 22: SOURCE: map_001_T(__taint_src)\n /sast-go/cases/completeness/single_app_tracing/datatype/map/map_001_T/map_001_T.go\n AffectedNodeName: map_001_T\n 22: CALL: map_001_T(__taint_src)\n /sast-go/cases/completeness/single_app_tracing/datatype/map/map_001_T/map_001_T.go\n AffectedNodeName: __taint_src\n 12: ARG PASS: func map_001_T(__taint_src string) {\n /sast-go/cases/completeness/single_app_tracing/datatype/map/map_001_T/map_001_T.go\n AffectedNodeName: m[\"key1\"]\n 14: Var Pass: \tm[\"key1\"] = __taint_src\n /sast-go/cases/completeness/single_app_tracing/datatype/map/map_001_T/map_001_T.go\n AffectedNodeName: __taint_sink\n 15: SINK: \t__taint_sink(m)\n==========================================================\n #Total-findings:1\n==========================================================","/benchmarks/sast-go/cases/completeness/single_app_tracing/datatype/map/map_002_F/map_002_F":"======================== Findings ========================\nNo findings!\n==========================================================","/benchmarks/sast-go/cases/completeness/single_app_tracing/datatype/map/map_003_T/map_003_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/sast-go/cases/completeness/single_app_tracing/datatype/map/map_003_T/map_003_T.go\nLine 16: __taint_sink(m)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/sast-go/cases/completeness/single_app_tracing/datatype/map/map_003_T/map_003_T.go\",\"functionName\":\"main\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /sast-go/cases/completeness/single_app_tracing/datatype/map/map_003_T/map_003_T.go\n AffectedNodeName: __taint_src\n 23: SOURCE: map_003_T(__taint_src)\n /sast-go/cases/completeness/single_app_tracing/datatype/map/map_003_T/map_003_T.go\n AffectedNodeName: map_003_T\n 23: CALL: map_003_T(__taint_src)\n /sast-go/cases/completeness/single_app_tracing/datatype/map/map_003_T/map_003_T.go\n AffectedNodeName: __taint_src\n 12: ARG PASS: func map_003_T(__taint_src string) {\n /sast-go/cases/completeness/single_app_tracing/datatype/map/map_003_T/map_003_T.go\n AffectedNodeName: m\n 13: Var Pass: \tm := map[string]string{\n 14: Var Pass: \t\t\"key1\": __taint_src,\n 15: Var Pass: \t}\n /sast-go/cases/completeness/single_app_tracing/datatype/map/map_003_T/map_003_T.go\n AffectedNodeName: __taint_sink\n 16: SINK: \t__taint_sink(m)\n==========================================================\n #Total-findings:1\n==========================================================","/benchmarks/sast-go/cases/completeness/single_app_tracing/datatype/map/map_004_F/map_004_F":"======================== Findings ========================\nNo findings!\n==========================================================","/benchmarks/sast-go/cases/completeness/single_app_tracing/datatype/pointer/pointer_001_T/pointer_001_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/sast-go/cases/completeness/single_app_tracing/datatype/pointer/pointer_001_T/pointer_001_T.go\nLine 14: __taint_sink(*ps)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/sast-go/cases/completeness/single_app_tracing/datatype/pointer/pointer_001_T/pointer_001_T.go\",\"functionName\":\"main\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /sast-go/cases/completeness/single_app_tracing/datatype/pointer/pointer_001_T/pointer_001_T.go\n AffectedNodeName: __taint_src\n 21: SOURCE: pointer_001_T(__taint_src)\n /sast-go/cases/completeness/single_app_tracing/datatype/pointer/pointer_001_T/pointer_001_T.go\n AffectedNodeName: pointer_001_T\n 21: CALL: pointer_001_T(__taint_src)\n /sast-go/cases/completeness/single_app_tracing/datatype/pointer/pointer_001_T/pointer_001_T.go\n AffectedNodeName: __taint_src\n 12: ARG PASS: func pointer_001_T(__taint_src string) {\n /sast-go/cases/completeness/single_app_tracing/datatype/pointer/pointer_001_T/pointer_001_T.go\n AffectedNodeName: ps\n 13: Var Pass: \tps := &__taint_src\n /sast-go/cases/completeness/single_app_tracing/datatype/pointer/pointer_001_T/pointer_001_T.go\n AffectedNodeName: __taint_sink\n 14: SINK: \t__taint_sink(*ps)\n==========================================================\n #Total-findings:1\n==========================================================","/benchmarks/sast-go/cases/completeness/single_app_tracing/datatype/pointer/pointer_002_F/pointer_002_F":"======================== Findings ========================\nNo findings!\n==========================================================","/benchmarks/sast-go/cases/completeness/single_app_tracing/datatype/pointer/pointer_new_001_T/pointer_new_001_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/sast-go/cases/completeness/single_app_tracing/datatype/pointer/pointer_new_001_T/pointer_new_001_T.go\nLine 16: __taint_sink(*ps)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/sast-go/cases/completeness/single_app_tracing/datatype/pointer/pointer_new_001_T/pointer_new_001_T.go\",\"functionName\":\"main\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /sast-go/cases/completeness/single_app_tracing/datatype/pointer/pointer_new_001_T/pointer_new_001_T.go\n AffectedNodeName: __taint_src\n 23: SOURCE: pointer_new_001_T(__taint_src)\n /sast-go/cases/completeness/single_app_tracing/datatype/pointer/pointer_new_001_T/pointer_new_001_T.go\n AffectedNodeName: pointer_new_001_T\n 23: CALL: pointer_new_001_T(__taint_src)\n /sast-go/cases/completeness/single_app_tracing/datatype/pointer/pointer_new_001_T/pointer_new_001_T.go\n AffectedNodeName: __taint_src\n 12: ARG PASS: func pointer_new_001_T(__taint_src string) {\n /sast-go/cases/completeness/single_app_tracing/datatype/pointer/pointer_new_001_T/pointer_new_001_T.go\n 15: Var Pass: \t*ps = __taint_src\n /sast-go/cases/completeness/single_app_tracing/datatype/pointer/pointer_new_001_T/pointer_new_001_T.go\n AffectedNodeName: __taint_sink\n 16: SINK: \t__taint_sink(*ps)\n==========================================================\n #Total-findings:1\n==========================================================","/benchmarks/sast-go/cases/completeness/single_app_tracing/datatype/pointer/pointer_new_002_F/pointer_new_002_F":"======================== Findings ========================\nNo findings!\n==========================================================","/benchmarks/sast-go/cases/completeness/single_app_tracing/datatype/primitives/primitives_bool_001_T/primitives_bool_001_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/sast-go/cases/completeness/single_app_tracing/datatype/primitives/primitives_bool_001_T/primitives_bool_001_T.go\nLine 13: __taint_sink(__taint_src)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/sast-go/cases/completeness/single_app_tracing/datatype/primitives/primitives_bool_001_T/primitives_bool_001_T.go\",\"functionName\":\"main\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /sast-go/cases/completeness/single_app_tracing/datatype/primitives/primitives_bool_001_T/primitives_bool_001_T.go\n AffectedNodeName: __taint_src\n 19: SOURCE: primitives_bool_001_T(__taint_src)\n /sast-go/cases/completeness/single_app_tracing/datatype/primitives/primitives_bool_001_T/primitives_bool_001_T.go\n AffectedNodeName: primitives_bool_001_T\n 19: CALL: primitives_bool_001_T(__taint_src)\n /sast-go/cases/completeness/single_app_tracing/datatype/primitives/primitives_bool_001_T/primitives_bool_001_T.go\n AffectedNodeName: __taint_src\n 12: ARG PASS: func primitives_bool_001_T(__taint_src bool) {\n /sast-go/cases/completeness/single_app_tracing/datatype/primitives/primitives_bool_001_T/primitives_bool_001_T.go\n AffectedNodeName: __taint_sink\n 13: SINK: \t__taint_sink(__taint_src)\n==========================================================\n #Total-findings:1\n==========================================================","/benchmarks/sast-go/cases/completeness/single_app_tracing/datatype/primitives/primitives_bool_002_F/primitives_bool_002_F":"======================== Findings ========================\nNo findings!\n==========================================================","/benchmarks/sast-go/cases/completeness/single_app_tracing/datatype/primitives/primitives_complex_001_T/primitives_complex_001_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/sast-go/cases/completeness/single_app_tracing/datatype/primitives/primitives_complex_001_T/primitives_complex_001_T.go\nLine 13: __taint_sink(__taint_src)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/sast-go/cases/completeness/single_app_tracing/datatype/primitives/primitives_complex_001_T/primitives_complex_001_T.go\",\"functionName\":\"main\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /sast-go/cases/completeness/single_app_tracing/datatype/primitives/primitives_complex_001_T/primitives_complex_001_T.go\n AffectedNodeName: __taint_src\n 20: SOURCE: primitives_complex_001_T(__taint_src)\n /sast-go/cases/completeness/single_app_tracing/datatype/primitives/primitives_complex_001_T/primitives_complex_001_T.go\n AffectedNodeName: primitives_complex_001_T\n 20: CALL: primitives_complex_001_T(__taint_src)\n /sast-go/cases/completeness/single_app_tracing/datatype/primitives/primitives_complex_001_T/primitives_complex_001_T.go\n AffectedNodeName: __taint_src\n 12: ARG PASS: func primitives_complex_001_T(__taint_src complex64) {\n /sast-go/cases/completeness/single_app_tracing/datatype/primitives/primitives_complex_001_T/primitives_complex_001_T.go\n AffectedNodeName: __taint_sink\n 13: SINK: \t__taint_sink(__taint_src)\n==========================================================\n #Total-findings:1\n==========================================================","/benchmarks/sast-go/cases/completeness/single_app_tracing/datatype/primitives/primitives_complex_002_F/primitives_complex_002_F":"======================== Findings ========================\nNo findings!\n==========================================================","/benchmarks/sast-go/cases/completeness/single_app_tracing/datatype/primitives/primitives_float_001_T/primitives_float_001_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/sast-go/cases/completeness/single_app_tracing/datatype/primitives/primitives_float_001_T/primitives_float_001_T.go\nLine 13: __taint_sink(__taint_src)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/sast-go/cases/completeness/single_app_tracing/datatype/primitives/primitives_float_001_T/primitives_float_001_T.go\",\"functionName\":\"main\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /sast-go/cases/completeness/single_app_tracing/datatype/primitives/primitives_float_001_T/primitives_float_001_T.go\n AffectedNodeName: __taint_src\n 20: SOURCE: primitives_float_001_T(__taint_src)\n /sast-go/cases/completeness/single_app_tracing/datatype/primitives/primitives_float_001_T/primitives_float_001_T.go\n AffectedNodeName: primitives_float_001_T\n 20: CALL: primitives_float_001_T(__taint_src)\n /sast-go/cases/completeness/single_app_tracing/datatype/primitives/primitives_float_001_T/primitives_float_001_T.go\n AffectedNodeName: __taint_src\n 12: ARG PASS: func primitives_float_001_T(__taint_src float64) {\n /sast-go/cases/completeness/single_app_tracing/datatype/primitives/primitives_float_001_T/primitives_float_001_T.go\n AffectedNodeName: __taint_sink\n 13: SINK: \t__taint_sink(__taint_src)\n==========================================================\n #Total-findings:1\n==========================================================","/benchmarks/sast-go/cases/completeness/single_app_tracing/datatype/primitives/primitives_float_002_F/primitives_float_002_F":"======================== Findings ========================\nNo findings!\n==========================================================","/benchmarks/sast-go/cases/completeness/single_app_tracing/datatype/primitives/primitives_int_001_T/primitives_int_001_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/sast-go/cases/completeness/single_app_tracing/datatype/primitives/primitives_int_001_T/primitives_int_001_T.go\nLine 13: __taint_sink(__taint_src)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/sast-go/cases/completeness/single_app_tracing/datatype/primitives/primitives_int_001_T/primitives_int_001_T.go\",\"functionName\":\"main\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /sast-go/cases/completeness/single_app_tracing/datatype/primitives/primitives_int_001_T/primitives_int_001_T.go\n AffectedNodeName: __taint_src\n 20: SOURCE: primitives_int_001_T(__taint_src)\n /sast-go/cases/completeness/single_app_tracing/datatype/primitives/primitives_int_001_T/primitives_int_001_T.go\n AffectedNodeName: primitives_int_001_T\n 20: CALL: primitives_int_001_T(__taint_src)\n /sast-go/cases/completeness/single_app_tracing/datatype/primitives/primitives_int_001_T/primitives_int_001_T.go\n AffectedNodeName: __taint_src\n 12: ARG PASS: func primitives_int_001_T(__taint_src int) {\n /sast-go/cases/completeness/single_app_tracing/datatype/primitives/primitives_int_001_T/primitives_int_001_T.go\n AffectedNodeName: __taint_sink\n 13: SINK: \t__taint_sink(__taint_src)\n==========================================================\n #Total-findings:1\n==========================================================","/benchmarks/sast-go/cases/completeness/single_app_tracing/datatype/primitives/primitives_int_002_F/primitives_int_002_F":"======================== Findings ========================\nNo findings!\n==========================================================","/benchmarks/sast-go/cases/completeness/single_app_tracing/datatype/slice/slice_001_T/slice_001_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/sast-go/cases/completeness/single_app_tracing/datatype/slice/slice_001_T/slice_001_T.go\nLine 14: __taint_sink(s)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/sast-go/cases/completeness/single_app_tracing/datatype/slice/slice_001_T/slice_001_T.go\",\"functionName\":\"main\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /sast-go/cases/completeness/single_app_tracing/datatype/slice/slice_001_T/slice_001_T.go\n AffectedNodeName: __taint_src\n 20: SOURCE: slice_001_T(__taint_src)\n /sast-go/cases/completeness/single_app_tracing/datatype/slice/slice_001_T/slice_001_T.go\n AffectedNodeName: slice_001_T\n 20: CALL: slice_001_T(__taint_src)\n /sast-go/cases/completeness/single_app_tracing/datatype/slice/slice_001_T/slice_001_T.go\n AffectedNodeName: __taint_src\n 12: ARG PASS: func slice_001_T(__taint_src string) {\n /sast-go/cases/completeness/single_app_tracing/datatype/slice/slice_001_T/slice_001_T.go\n AffectedNodeName: s\n 13: Var Pass: \tvar s []string = []string{__taint_src, \"b\", \"c\"}\n /sast-go/cases/completeness/single_app_tracing/datatype/slice/slice_001_T/slice_001_T.go\n AffectedNodeName: __taint_sink\n 14: SINK: \t__taint_sink(s)\n==========================================================\n #Total-findings:1\n==========================================================","/benchmarks/sast-go/cases/completeness/single_app_tracing/datatype/slice/slice_002_F/slice_002_F":"======================== Findings ========================\nNo findings!\n==========================================================","/benchmarks/sast-go/cases/completeness/single_app_tracing/datatype/slice/slice_003_T/slice_003_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/sast-go/cases/completeness/single_app_tracing/datatype/slice/slice_003_T/slice_003_T.go\nLine 15: __taint_sink(s)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/sast-go/cases/completeness/single_app_tracing/datatype/slice/slice_003_T/slice_003_T.go\",\"functionName\":\"main\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /sast-go/cases/completeness/single_app_tracing/datatype/slice/slice_003_T/slice_003_T.go\n AffectedNodeName: __taint_src\n 22: SOURCE: slice_003_T(__taint_src)\n /sast-go/cases/completeness/single_app_tracing/datatype/slice/slice_003_T/slice_003_T.go\n AffectedNodeName: slice_003_T\n 22: CALL: slice_003_T(__taint_src)\n /sast-go/cases/completeness/single_app_tracing/datatype/slice/slice_003_T/slice_003_T.go\n AffectedNodeName: __taint_src\n 12: ARG PASS: func slice_003_T(__taint_src string) {\n /sast-go/cases/completeness/single_app_tracing/datatype/slice/slice_003_T/slice_003_T.go\n AffectedNodeName: s\n 14: Var Pass: \ts = append(s, __taint_src)\n /sast-go/cases/completeness/single_app_tracing/datatype/slice/slice_003_T/slice_003_T.go\n AffectedNodeName: __taint_sink\n 15: SINK: \t__taint_sink(s)\n==========================================================\n #Total-findings:1\n==========================================================","/benchmarks/sast-go/cases/completeness/single_app_tracing/datatype/slice/slice_004_F/slice_004_F":"======================== Findings ========================\nNo findings!\n==========================================================","/benchmarks/sast-go/cases/completeness/single_app_tracing/datatype/slice/slice_005_T/slice_005_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/sast-go/cases/completeness/single_app_tracing/datatype/slice/slice_005_T/slice_005_T.go\nLine 18: __taint_sink(s)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/sast-go/cases/completeness/single_app_tracing/datatype/slice/slice_005_T/slice_005_T.go\",\"functionName\":\"main\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /sast-go/cases/completeness/single_app_tracing/datatype/slice/slice_005_T/slice_005_T.go\n AffectedNodeName: __taint_src\n 25: SOURCE: slice_005_T(__taint_src)\n /sast-go/cases/completeness/single_app_tracing/datatype/slice/slice_005_T/slice_005_T.go\n AffectedNodeName: slice_005_T\n 25: CALL: slice_005_T(__taint_src)\n /sast-go/cases/completeness/single_app_tracing/datatype/slice/slice_005_T/slice_005_T.go\n AffectedNodeName: __taint_src\n 12: ARG PASS: func slice_005_T(__taint_src string) {\n /sast-go/cases/completeness/single_app_tracing/datatype/slice/slice_005_T/slice_005_T.go\n AffectedNodeName: s\n 13: Var Pass: \ts := [][]string{\n 14: Var Pass: \t\t[]string{\"a\"},\n 15: Var Pass: \t\t[]string{\"b\", \"c\"},\n 16: Var Pass: \t\t[]string{\"d\", \"e\", __taint_src},\n 17: Var Pass: \t}\n /sast-go/cases/completeness/single_app_tracing/datatype/slice/slice_005_T/slice_005_T.go\n AffectedNodeName: __taint_sink\n 18: SINK: \t__taint_sink(s)\n==========================================================\n #Total-findings:1\n==========================================================","/benchmarks/sast-go/cases/completeness/single_app_tracing/datatype/slice/slice_006_F/slice_006_F":"======================== Findings ========================\nNo findings!\n==========================================================","/benchmarks/sast-go/cases/completeness/single_app_tracing/datatype/slice/slice_007_T/slice_007_T":"======================== Findings ========================\nNo findings!\n==========================================================","/benchmarks/sast-go/cases/completeness/single_app_tracing/datatype/slice/slice_008_F/slice_008_F":"======================== Findings ========================\nNo findings!\n==========================================================","/benchmarks/sast-go/cases/completeness/single_app_tracing/datatype/specialtype/channel_001_T/channel_001_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/sast-go/cases/completeness/single_app_tracing/datatype/specialtype/channel_001_T/channel_001_T.go\nLine 17: __taint_sink(c)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/sast-go/cases/completeness/single_app_tracing/datatype/specialtype/channel_001_T/channel_001_T.go\",\"functionName\":\"main\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /sast-go/cases/completeness/single_app_tracing/datatype/specialtype/channel_001_T/channel_001_T.go\n AffectedNodeName: __taint_src\n 23: SOURCE: channel_001_T(__taint_src)\n /sast-go/cases/completeness/single_app_tracing/datatype/specialtype/channel_001_T/channel_001_T.go\n AffectedNodeName: channel_001_T\n 23: CALL: channel_001_T(__taint_src)\n /sast-go/cases/completeness/single_app_tracing/datatype/specialtype/channel_001_T/channel_001_T.go\n AffectedNodeName: __taint_src\n 12: ARG PASS: func channel_001_T(__taint_src string) {\n /sast-go/cases/completeness/single_app_tracing/datatype/specialtype/channel_001_T/channel_001_T.go\n AffectedNodeName: __taint_sink\n 17: SINK: \t__taint_sink(c)\n==========================================================\n #Total-findings:1\n==========================================================","/benchmarks/sast-go/cases/completeness/single_app_tracing/datatype/specialtype/channel_002_F/channel_002_F":"======================== Findings ========================\nNo findings!\n==========================================================","/benchmarks/sast-go/cases/completeness/single_app_tracing/datatype/string/string_001_T/string_001_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/sast-go/cases/completeness/single_app_tracing/datatype/string/string_001_T/string_001_T.go\nLine 13: __taint_sink(__taint_src)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/sast-go/cases/completeness/single_app_tracing/datatype/string/string_001_T/string_001_T.go\",\"functionName\":\"main\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /sast-go/cases/completeness/single_app_tracing/datatype/string/string_001_T/string_001_T.go\n AffectedNodeName: __taint_src\n 20: SOURCE: string_001_T(__taint_src)\n /sast-go/cases/completeness/single_app_tracing/datatype/string/string_001_T/string_001_T.go\n AffectedNodeName: string_001_T\n 20: CALL: string_001_T(__taint_src)\n /sast-go/cases/completeness/single_app_tracing/datatype/string/string_001_T/string_001_T.go\n AffectedNodeName: __taint_src\n 12: ARG PASS: func string_001_T(__taint_src string) {\n /sast-go/cases/completeness/single_app_tracing/datatype/string/string_001_T/string_001_T.go\n AffectedNodeName: __taint_sink\n 13: SINK: \t__taint_sink(__taint_src)\n==========================================================\n #Total-findings:1\n==========================================================","/benchmarks/sast-go/cases/completeness/single_app_tracing/datatype/string/string_002_F/string_002_F":"======================== Findings ========================\nNo findings!\n==========================================================","/benchmarks/sast-go/cases/completeness/single_app_tracing/datatype/struct/complex_struct_001_T/complex_struct_001_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/sast-go/cases/completeness/single_app_tracing/datatype/struct/complex_struct_001_T/complex_struct_001_T.go\nLine 30: __taint_sink(c)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/sast-go/cases/completeness/single_app_tracing/datatype/struct/complex_struct_001_T/complex_struct_001_T.go\",\"functionName\":\"main\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /sast-go/cases/completeness/single_app_tracing/datatype/struct/complex_struct_001_T/complex_struct_001_T.go\n AffectedNodeName: __taint_src\n 37: SOURCE: complex_struct_001_T(__taint_src)\n /sast-go/cases/completeness/single_app_tracing/datatype/struct/complex_struct_001_T/complex_struct_001_T.go\n AffectedNodeName: complex_struct_001_T\n 37: CALL: complex_struct_001_T(__taint_src)\n /sast-go/cases/completeness/single_app_tracing/datatype/struct/complex_struct_001_T/complex_struct_001_T.go\n AffectedNodeName: __taint_src\n 13: ARG PASS: func complex_struct_001_T(__taint_src interface{}) {\n /sast-go/cases/completeness/single_app_tracing/datatype/struct/complex_struct_001_T/complex_struct_001_T.go\n AffectedNodeName: Say\n 16: CALL: \ta.b.Say(__taint_src)\n /sast-go/cases/completeness/single_app_tracing/datatype/struct/complex_struct_001_T/complex_struct_001_T.go\n AffectedNodeName: c\n 29: ARG PASS: func (b B) Say(c interface{}) {\n /sast-go/cases/completeness/single_app_tracing/datatype/struct/complex_struct_001_T/complex_struct_001_T.go\n AffectedNodeName: __taint_sink\n 30: SINK: \t__taint_sink(c)\n==========================================================\n #Total-findings:1\n==========================================================","/benchmarks/sast-go/cases/completeness/single_app_tracing/datatype/struct/complex_struct_002_F/complex_struct_002_F":"======================== Findings ========================\nNo findings!\n==========================================================","/benchmarks/sast-go/cases/completeness/single_app_tracing/datatype/struct/struct_001_T/struct_001_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/sast-go/cases/completeness/single_app_tracing/datatype/struct/struct_001_T/struct_001_T.go\nLine 20: __taint_sink(p)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/sast-go/cases/completeness/single_app_tracing/datatype/struct/struct_001_T/struct_001_T.go\",\"functionName\":\"main\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /sast-go/cases/completeness/single_app_tracing/datatype/struct/struct_001_T/struct_001_T.go\n AffectedNodeName: __taint_src\n 27: SOURCE: struct_001_T(__taint_src)\n /sast-go/cases/completeness/single_app_tracing/datatype/struct/struct_001_T/struct_001_T.go\n AffectedNodeName: struct_001_T\n 27: CALL: struct_001_T(__taint_src)\n /sast-go/cases/completeness/single_app_tracing/datatype/struct/struct_001_T/struct_001_T.go\n AffectedNodeName: __taint_src\n 16: ARG PASS: func struct_001_T(__taint_src string) {\n /sast-go/cases/completeness/single_app_tracing/datatype/struct/struct_001_T/struct_001_T.go\n AffectedNodeName: p\n 17: Var Pass: \tp := A{\n 18: Var Pass: \t\tdata: __taint_src,\n 19: Var Pass: \t}\n /sast-go/cases/completeness/single_app_tracing/datatype/struct/struct_001_T/struct_001_T.go\n AffectedNodeName: __taint_sink\n 20: SINK: \t__taint_sink(p)\n==========================================================\n #Total-findings:1\n==========================================================","/benchmarks/sast-go/cases/completeness/single_app_tracing/datatype/struct/struct_002_F/struct_002_F":"======================== Findings ========================\nNo findings!\n==========================================================","/benchmarks/sast-go/cases/completeness/single_app_tracing/datatype/struct/struct_003_T/struct_003_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/sast-go/cases/completeness/single_app_tracing/datatype/struct/struct_003_T/struct_003_T.go\nLine 19: __taint_sink(p)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/sast-go/cases/completeness/single_app_tracing/datatype/struct/struct_003_T/struct_003_T.go\",\"functionName\":\"main\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /sast-go/cases/completeness/single_app_tracing/datatype/struct/struct_003_T/struct_003_T.go\n AffectedNodeName: __taint_src\n 26: SOURCE: struct_003_T(__taint_src)\n /sast-go/cases/completeness/single_app_tracing/datatype/struct/struct_003_T/struct_003_T.go\n AffectedNodeName: struct_003_T\n 26: CALL: struct_003_T(__taint_src)\n /sast-go/cases/completeness/single_app_tracing/datatype/struct/struct_003_T/struct_003_T.go\n AffectedNodeName: __taint_src\n 16: ARG PASS: func struct_003_T(__taint_src string) {\n /sast-go/cases/completeness/single_app_tracing/datatype/struct/struct_003_T/struct_003_T.go\n AffectedNodeName: [p.data]\n 18: Var Pass: \tp.data = __taint_src\n /sast-go/cases/completeness/single_app_tracing/datatype/struct/struct_003_T/struct_003_T.go\n AffectedNodeName: __taint_sink\n 19: SINK: \t__taint_sink(p)\n==========================================================\n #Total-findings:1\n==========================================================","/benchmarks/sast-go/cases/completeness/single_app_tracing/datatype/struct/struct_004_F/struct_004_F":"======================== Findings ========================\nNo findings!\n==========================================================","/benchmarks/sast-go/cases/completeness/single_app_tracing/datatype/struct/struct_005_T/struct_005_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/sast-go/cases/completeness/single_app_tracing/datatype/struct/struct_005_T/struct_005_T.go\nLine 18: __taint_sink(p.data)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/sast-go/cases/completeness/single_app_tracing/datatype/struct/struct_005_T/struct_005_T.go\",\"functionName\":\"main\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /sast-go/cases/completeness/single_app_tracing/datatype/struct/struct_005_T/struct_005_T.go\n AffectedNodeName: __taint_src\n 24: SOURCE: struct_005_T(__taint_src)\n /sast-go/cases/completeness/single_app_tracing/datatype/struct/struct_005_T/struct_005_T.go\n AffectedNodeName: struct_005_T\n 24: CALL: struct_005_T(__taint_src)\n /sast-go/cases/completeness/single_app_tracing/datatype/struct/struct_005_T/struct_005_T.go\n AffectedNodeName: __taint_src\n 16: ARG PASS: func struct_005_T(__taint_src string) {\n /sast-go/cases/completeness/single_app_tracing/datatype/struct/struct_005_T/struct_005_T.go\n AffectedNodeName: p\n 17: Var Pass: \tp := A{__taint_src}\n /sast-go/cases/completeness/single_app_tracing/datatype/struct/struct_005_T/struct_005_T.go\n AffectedNodeName: __taint_sink\n 18: SINK: \t__taint_sink(p.data)\n==========================================================\n #Total-findings:1\n==========================================================","/benchmarks/sast-go/cases/completeness/single_app_tracing/datatype/struct/struct_006_F/struct_006_F":"======================== Findings ========================\nNo findings!\n==========================================================","/benchmarks/sast-go/cases/completeness/single_app_tracing/datatype/struct/struct_cross_001_T/struct_cross_001_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/sast-go/cases/completeness/single_app_tracing/datatype/struct/struct_cross_001_T/struct_cross_001_T.go\nLine 25: __taint_sink(pb)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/sast-go/cases/completeness/single_app_tracing/datatype/struct/struct_cross_001_T/struct_cross_001_T.go\",\"functionName\":\"main\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /sast-go/cases/completeness/single_app_tracing/datatype/struct/struct_cross_001_T/struct_cross_001_T.go\n AffectedNodeName: __taint_src\n 32: SOURCE: struct_cross_001_T(__taint_src)\n /sast-go/cases/completeness/single_app_tracing/datatype/struct/struct_cross_001_T/struct_cross_001_T.go\n AffectedNodeName: struct_cross_001_T\n 32: CALL: struct_cross_001_T(__taint_src)\n /sast-go/cases/completeness/single_app_tracing/datatype/struct/struct_cross_001_T/struct_cross_001_T.go\n AffectedNodeName: __taint_src\n 19: ARG PASS: func struct_cross_001_T(__taint_src string) {\n /sast-go/cases/completeness/single_app_tracing/datatype/struct/struct_cross_001_T/struct_cross_001_T.go\n AffectedNodeName: pa\n 20: Var Pass: \tpa := A{\n 21: Var Pass: \t\tdata: __taint_src,\n 22: Var Pass: \t}\n /sast-go/cases/completeness/single_app_tracing/datatype/struct/struct_cross_001_T/struct_cross_001_T.go\n AffectedNodeName: [pb.data]\n 24: Var Pass: \tpb.data = pa.data\n /sast-go/cases/completeness/single_app_tracing/datatype/struct/struct_cross_001_T/struct_cross_001_T.go\n AffectedNodeName: __taint_sink\n 25: SINK: \t__taint_sink(pb)\n==========================================================\n #Total-findings:1\n==========================================================","/benchmarks/sast-go/cases/completeness/single_app_tracing/datatype/struct/struct_cross_002_F/struct_cross_002_F":"======================== Findings ========================\nNo findings!\n==========================================================","/benchmarks/sast-go/cases/completeness/single_app_tracing/datatype/struct/struct_cross_003_T/struct_cross_003_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/sast-go/cases/completeness/single_app_tracing/datatype/struct/struct_cross_003_T/struct_cross_003_T.go\nLine 24: __taint_sink(p)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/sast-go/cases/completeness/single_app_tracing/datatype/struct/struct_cross_003_T/struct_cross_003_T.go\",\"functionName\":\"main\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /sast-go/cases/completeness/single_app_tracing/datatype/struct/struct_cross_003_T/struct_cross_003_T.go\n AffectedNodeName: __taint_src\n 30: SOURCE: struct_cross_003_T(__taint_src)\n /sast-go/cases/completeness/single_app_tracing/datatype/struct/struct_cross_003_T/struct_cross_003_T.go\n AffectedNodeName: struct_cross_003_T\n 30: CALL: struct_cross_003_T(__taint_src)\n /sast-go/cases/completeness/single_app_tracing/datatype/struct/struct_cross_003_T/struct_cross_003_T.go\n AffectedNodeName: __taint_src\n 20: ARG PASS: func struct_cross_003_T(__taint_src string) {\n /sast-go/cases/completeness/single_app_tracing/datatype/struct/struct_cross_003_T/struct_cross_003_T.go\n AffectedNodeName: p\n 21: Var Pass: \tp := B{A{\n 22: Var Pass: \t\tdata: __taint_src,\n 23: Var Pass: \t}, \"_\"}\n /sast-go/cases/completeness/single_app_tracing/datatype/struct/struct_cross_003_T/struct_cross_003_T.go\n AffectedNodeName: __taint_sink\n 24: SINK: \t__taint_sink(p)\n==========================================================\n #Total-findings:1\n==========================================================","/benchmarks/sast-go/cases/completeness/single_app_tracing/datatype/struct/struct_cross_004_F/struct_cross_004_F":"======================== Findings ========================\nNo findings!\n==========================================================","/benchmarks/sast-go/cases/completeness/single_app_tracing/exception_error/exception_throw/exception_throw_001_T/exception_throw_001_T":"======================== Findings ========================\nNo findings!\n==========================================================","/benchmarks/sast-go/cases/completeness/single_app_tracing/exception_error/exception_throw/exception_throw_002_F/exception_throw_002_F":"======================== Findings ========================\nNo findings!\n==========================================================","/benchmarks/sast-go/cases/completeness/single_app_tracing/expression/basic_expression_operation/assign_expression_001_T/assign_expression_001_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/sast-go/cases/completeness/single_app_tracing/expression/basic_expression_operation/assign_expression_001_T/assign_expression_001_T.go\nLine 14: __taint_sink(result)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/sast-go/cases/completeness/single_app_tracing/expression/basic_expression_operation/assign_expression_001_T/assign_expression_001_T.go\",\"functionName\":\"main\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /sast-go/cases/completeness/single_app_tracing/expression/basic_expression_operation/assign_expression_001_T/assign_expression_001_T.go\n AffectedNodeName: __taint_src\n 20: SOURCE: assign_expression_001_T(__taint_src)\n /sast-go/cases/completeness/single_app_tracing/expression/basic_expression_operation/assign_expression_001_T/assign_expression_001_T.go\n AffectedNodeName: assign_expression_001_T\n 20: CALL: assign_expression_001_T(__taint_src)\n /sast-go/cases/completeness/single_app_tracing/expression/basic_expression_operation/assign_expression_001_T/assign_expression_001_T.go\n AffectedNodeName: __taint_src\n 12: ARG PASS: func assign_expression_001_T(__taint_src string) {\n /sast-go/cases/completeness/single_app_tracing/expression/basic_expression_operation/assign_expression_001_T/assign_expression_001_T.go\n AffectedNodeName: result\n 13: Var Pass: \tresult := __taint_src\n /sast-go/cases/completeness/single_app_tracing/expression/basic_expression_operation/assign_expression_001_T/assign_expression_001_T.go\n AffectedNodeName: __taint_sink\n 14: SINK: \t__taint_sink(result)\n==========================================================\n #Total-findings:1\n==========================================================","/benchmarks/sast-go/cases/completeness/single_app_tracing/expression/basic_expression_operation/assign_expression_002_F/assign_expression_002_F":"======================== Findings ========================\nNo findings!\n==========================================================","/benchmarks/sast-go/cases/completeness/single_app_tracing/expression/basic_expression_operation/binary_expression_add_001_T/binary_expression_add_001_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/sast-go/cases/completeness/single_app_tracing/expression/basic_expression_operation/binary_expression_add_001_T/binary_expression_add_001_T.go\nLine 14: __taint_sink(result)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/sast-go/cases/completeness/single_app_tracing/expression/basic_expression_operation/binary_expression_add_001_T/binary_expression_add_001_T.go\",\"functionName\":\"main\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /sast-go/cases/completeness/single_app_tracing/expression/basic_expression_operation/binary_expression_add_001_T/binary_expression_add_001_T.go\n AffectedNodeName: __taint_src\n 20: SOURCE: binary_expression_add_001_T(__taint_src)\n /sast-go/cases/completeness/single_app_tracing/expression/basic_expression_operation/binary_expression_add_001_T/binary_expression_add_001_T.go\n AffectedNodeName: binary_expression_add_001_T\n 20: CALL: binary_expression_add_001_T(__taint_src)\n /sast-go/cases/completeness/single_app_tracing/expression/basic_expression_operation/binary_expression_add_001_T/binary_expression_add_001_T.go\n AffectedNodeName: __taint_src\n 12: ARG PASS: func binary_expression_add_001_T(__taint_src string) {\n /sast-go/cases/completeness/single_app_tracing/expression/basic_expression_operation/binary_expression_add_001_T/binary_expression_add_001_T.go\n AffectedNodeName: result\n 13: Var Pass: \tresult := __taint_src + \"_\"\n /sast-go/cases/completeness/single_app_tracing/expression/basic_expression_operation/binary_expression_add_001_T/binary_expression_add_001_T.go\n AffectedNodeName: __taint_sink\n 14: SINK: \t__taint_sink(result)\n==========================================================\n #Total-findings:1\n==========================================================","/benchmarks/sast-go/cases/completeness/single_app_tracing/expression/basic_expression_operation/binary_expression_add_002_F/binary_expression_add_002_F":"======================== Findings ========================\nNo findings!\n==========================================================","/benchmarks/sast-go/cases/completeness/single_app_tracing/expression/basic_expression_operation/binary_expression_add_assignment_001_T/binary_expression_add_assignment_001_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/sast-go/cases/completeness/single_app_tracing/expression/basic_expression_operation/binary_expression_add_assignment_001_T/binary_expression_add_assignment_001_T.go\nLine 15: __taint_sink(result)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/sast-go/cases/completeness/single_app_tracing/expression/basic_expression_operation/binary_expression_add_assignment_001_T/binary_expression_add_assignment_001_T.go\",\"functionName\":\"main\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /sast-go/cases/completeness/single_app_tracing/expression/basic_expression_operation/binary_expression_add_assignment_001_T/binary_expression_add_assignment_001_T.go\n AffectedNodeName: __taint_src\n 21: SOURCE: binary_expression_add_assignment_001_T(__taint_src)\n /sast-go/cases/completeness/single_app_tracing/expression/basic_expression_operation/binary_expression_add_assignment_001_T/binary_expression_add_assignment_001_T.go\n AffectedNodeName: binary_expression_add_assignment_001_T\n 21: CALL: binary_expression_add_assignment_001_T(__taint_src)\n /sast-go/cases/completeness/single_app_tracing/expression/basic_expression_operation/binary_expression_add_assignment_001_T/binary_expression_add_assignment_001_T.go\n AffectedNodeName: __taint_src\n 12: ARG PASS: func binary_expression_add_assignment_001_T(__taint_src string) {\n /sast-go/cases/completeness/single_app_tracing/expression/basic_expression_operation/binary_expression_add_assignment_001_T/binary_expression_add_assignment_001_T.go\n AffectedNodeName: __taint_sink\n 15: SINK: \t__taint_sink(result)\n==========================================================\n #Total-findings:1\n==========================================================","/benchmarks/sast-go/cases/completeness/single_app_tracing/expression/basic_expression_operation/binary_expression_add_assignment_002_F/binary_expression_add_assignment_002_F":"======================== Findings ========================\nNo findings!\n==========================================================","/benchmarks/sast-go/cases/completeness/single_app_tracing/expression/basic_expression_operation/bitwise_expression_and_001_T/bitwise_expression_and_001_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/sast-go/cases/completeness/single_app_tracing/expression/basic_expression_operation/bitwise_expression_and_001_T/bitwise_expression_and_001_T.go\nLine 14: __taint_sink(result)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/sast-go/cases/completeness/single_app_tracing/expression/basic_expression_operation/bitwise_expression_and_001_T/bitwise_expression_and_001_T.go\",\"functionName\":\"main\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /sast-go/cases/completeness/single_app_tracing/expression/basic_expression_operation/bitwise_expression_and_001_T/bitwise_expression_and_001_T.go\n AffectedNodeName: __taint_src\n 20: SOURCE: bitwise_expression_and_001_T(__taint_src)\n /sast-go/cases/completeness/single_app_tracing/expression/basic_expression_operation/bitwise_expression_and_001_T/bitwise_expression_and_001_T.go\n AffectedNodeName: bitwise_expression_and_001_T\n 20: CALL: bitwise_expression_and_001_T(__taint_src)\n /sast-go/cases/completeness/single_app_tracing/expression/basic_expression_operation/bitwise_expression_and_001_T/bitwise_expression_and_001_T.go\n AffectedNodeName: __taint_src\n 12: ARG PASS: func bitwise_expression_and_001_T(__taint_src int) {\n /sast-go/cases/completeness/single_app_tracing/expression/basic_expression_operation/bitwise_expression_and_001_T/bitwise_expression_and_001_T.go\n AffectedNodeName: result\n 13: Var Pass: \tresult := __taint_src & 1\n /sast-go/cases/completeness/single_app_tracing/expression/basic_expression_operation/bitwise_expression_and_001_T/bitwise_expression_and_001_T.go\n AffectedNodeName: __taint_sink\n 14: SINK: \t__taint_sink(result)\n==========================================================\n #Total-findings:1\n==========================================================","/benchmarks/sast-go/cases/completeness/single_app_tracing/expression/basic_expression_operation/bitwise_expression_and_002_F/bitwise_expression_and_002_F":"======================== Findings ========================\nNo findings!\n==========================================================","/benchmarks/sast-go/cases/completeness/single_app_tracing/expression/basic_expression_operation/bitwise_expression_lsh_001_T/bitwise_expression_lsh_001_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/sast-go/cases/completeness/single_app_tracing/expression/basic_expression_operation/bitwise_expression_lsh_001_T/bitwise_expression_lsh_001_T.go\nLine 14: __taint_sink(result)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/sast-go/cases/completeness/single_app_tracing/expression/basic_expression_operation/bitwise_expression_lsh_001_T/bitwise_expression_lsh_001_T.go\",\"functionName\":\"main\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /sast-go/cases/completeness/single_app_tracing/expression/basic_expression_operation/bitwise_expression_lsh_001_T/bitwise_expression_lsh_001_T.go\n AffectedNodeName: __taint_src\n 20: SOURCE: bitwise_expression_lsh_001_T(__taint_src)\n /sast-go/cases/completeness/single_app_tracing/expression/basic_expression_operation/bitwise_expression_lsh_001_T/bitwise_expression_lsh_001_T.go\n AffectedNodeName: bitwise_expression_lsh_001_T\n 20: CALL: bitwise_expression_lsh_001_T(__taint_src)\n /sast-go/cases/completeness/single_app_tracing/expression/basic_expression_operation/bitwise_expression_lsh_001_T/bitwise_expression_lsh_001_T.go\n AffectedNodeName: __taint_src\n 12: ARG PASS: func bitwise_expression_lsh_001_T(__taint_src int) {\n /sast-go/cases/completeness/single_app_tracing/expression/basic_expression_operation/bitwise_expression_lsh_001_T/bitwise_expression_lsh_001_T.go\n AffectedNodeName: result\n 13: Var Pass: \tresult := __taint_src << 1\n /sast-go/cases/completeness/single_app_tracing/expression/basic_expression_operation/bitwise_expression_lsh_001_T/bitwise_expression_lsh_001_T.go\n AffectedNodeName: __taint_sink\n 14: SINK: \t__taint_sink(result)\n==========================================================\n #Total-findings:1\n==========================================================","/benchmarks/sast-go/cases/completeness/single_app_tracing/expression/basic_expression_operation/bitwise_expression_lsh_002_F/bitwise_expression_lsh_002_F":"======================== Findings ========================\nNo findings!\n==========================================================","/benchmarks/sast-go/cases/completeness/single_app_tracing/expression/basic_expression_operation/bitwise_expression_not_001_T/bitwise_expression_not_001_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/sast-go/cases/completeness/single_app_tracing/expression/basic_expression_operation/bitwise_expression_not_001_T/bitwise_expression_not_001_T.go\nLine 14: __taint_sink(result)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/sast-go/cases/completeness/single_app_tracing/expression/basic_expression_operation/bitwise_expression_not_001_T/bitwise_expression_not_001_T.go\",\"functionName\":\"main\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /sast-go/cases/completeness/single_app_tracing/expression/basic_expression_operation/bitwise_expression_not_001_T/bitwise_expression_not_001_T.go\n AffectedNodeName: __taint_src\n 20: SOURCE: bitwise_expression_not_001_T(__taint_src)\n /sast-go/cases/completeness/single_app_tracing/expression/basic_expression_operation/bitwise_expression_not_001_T/bitwise_expression_not_001_T.go\n AffectedNodeName: bitwise_expression_not_001_T\n 20: CALL: bitwise_expression_not_001_T(__taint_src)\n /sast-go/cases/completeness/single_app_tracing/expression/basic_expression_operation/bitwise_expression_not_001_T/bitwise_expression_not_001_T.go\n AffectedNodeName: __taint_src\n 12: ARG PASS: func bitwise_expression_not_001_T(__taint_src int) {\n /sast-go/cases/completeness/single_app_tracing/expression/basic_expression_operation/bitwise_expression_not_001_T/bitwise_expression_not_001_T.go\n AffectedNodeName: __taint_sink\n 14: SINK: \t__taint_sink(result)\n==========================================================\n #Total-findings:1\n==========================================================","/benchmarks/sast-go/cases/completeness/single_app_tracing/expression/basic_expression_operation/bitwise_expression_not_002_F/bitwise_expression_not_002_F":"======================== Findings ========================\nNo findings!\n==========================================================","/benchmarks/sast-go/cases/completeness/single_app_tracing/expression/basic_expression_operation/bitwise_expression_or_001_T/bitwise_expression_or_001_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/sast-go/cases/completeness/single_app_tracing/expression/basic_expression_operation/bitwise_expression_or_001_T/bitwise_expression_or_001_T.go\nLine 14: __taint_sink(result)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/sast-go/cases/completeness/single_app_tracing/expression/basic_expression_operation/bitwise_expression_or_001_T/bitwise_expression_or_001_T.go\",\"functionName\":\"main\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /sast-go/cases/completeness/single_app_tracing/expression/basic_expression_operation/bitwise_expression_or_001_T/bitwise_expression_or_001_T.go\n AffectedNodeName: __taint_src\n 20: SOURCE: bitwise_expression_or_001_T(__taint_src)\n /sast-go/cases/completeness/single_app_tracing/expression/basic_expression_operation/bitwise_expression_or_001_T/bitwise_expression_or_001_T.go\n AffectedNodeName: bitwise_expression_or_001_T\n 20: CALL: bitwise_expression_or_001_T(__taint_src)\n /sast-go/cases/completeness/single_app_tracing/expression/basic_expression_operation/bitwise_expression_or_001_T/bitwise_expression_or_001_T.go\n AffectedNodeName: __taint_src\n 12: ARG PASS: func bitwise_expression_or_001_T(__taint_src int) {\n /sast-go/cases/completeness/single_app_tracing/expression/basic_expression_operation/bitwise_expression_or_001_T/bitwise_expression_or_001_T.go\n AffectedNodeName: result\n 13: Var Pass: \tresult := __taint_src | 1\n /sast-go/cases/completeness/single_app_tracing/expression/basic_expression_operation/bitwise_expression_or_001_T/bitwise_expression_or_001_T.go\n AffectedNodeName: __taint_sink\n 14: SINK: \t__taint_sink(result)\n==========================================================\n #Total-findings:1\n==========================================================","/benchmarks/sast-go/cases/completeness/single_app_tracing/expression/basic_expression_operation/bitwise_expression_or_002_F/bitwise_expression_or_002_F":"======================== Findings ========================\nNo findings!\n==========================================================","/benchmarks/sast-go/cases/completeness/single_app_tracing/expression/basic_expression_operation/bitwise_expression_rsh_001_T/bitwise_expression_rsh_001_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/sast-go/cases/completeness/single_app_tracing/expression/basic_expression_operation/bitwise_expression_rsh_001_T/bitwise_expression_rsh_001_T.go\nLine 14: __taint_sink(result)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/sast-go/cases/completeness/single_app_tracing/expression/basic_expression_operation/bitwise_expression_rsh_001_T/bitwise_expression_rsh_001_T.go\",\"functionName\":\"main\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /sast-go/cases/completeness/single_app_tracing/expression/basic_expression_operation/bitwise_expression_rsh_001_T/bitwise_expression_rsh_001_T.go\n AffectedNodeName: __taint_src\n 20: SOURCE: bitwise_expression_rsh_001_T(__taint_src)\n /sast-go/cases/completeness/single_app_tracing/expression/basic_expression_operation/bitwise_expression_rsh_001_T/bitwise_expression_rsh_001_T.go\n AffectedNodeName: bitwise_expression_rsh_001_T\n 20: CALL: bitwise_expression_rsh_001_T(__taint_src)\n /sast-go/cases/completeness/single_app_tracing/expression/basic_expression_operation/bitwise_expression_rsh_001_T/bitwise_expression_rsh_001_T.go\n AffectedNodeName: __taint_src\n 12: ARG PASS: func bitwise_expression_rsh_001_T(__taint_src int) {\n /sast-go/cases/completeness/single_app_tracing/expression/basic_expression_operation/bitwise_expression_rsh_001_T/bitwise_expression_rsh_001_T.go\n AffectedNodeName: result\n 13: Var Pass: \tresult := __taint_src >> 1\n /sast-go/cases/completeness/single_app_tracing/expression/basic_expression_operation/bitwise_expression_rsh_001_T/bitwise_expression_rsh_001_T.go\n AffectedNodeName: __taint_sink\n 14: SINK: \t__taint_sink(result)\n==========================================================\n #Total-findings:1\n==========================================================","/benchmarks/sast-go/cases/completeness/single_app_tracing/expression/basic_expression_operation/bitwise_expression_rsh_002_F/bitwise_expression_rsh_002_F":"======================== Findings ========================\nNo findings!\n==========================================================","/benchmarks/sast-go/cases/completeness/single_app_tracing/expression/basic_expression_operation/bitwise_expression_xor_001_T/bitwise_expression_xor_001_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/sast-go/cases/completeness/single_app_tracing/expression/basic_expression_operation/bitwise_expression_xor_001_T/bitwise_expression_xor_001_T.go\nLine 14: __taint_sink(result)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/sast-go/cases/completeness/single_app_tracing/expression/basic_expression_operation/bitwise_expression_xor_001_T/bitwise_expression_xor_001_T.go\",\"functionName\":\"main\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /sast-go/cases/completeness/single_app_tracing/expression/basic_expression_operation/bitwise_expression_xor_001_T/bitwise_expression_xor_001_T.go\n AffectedNodeName: __taint_src\n 21: SOURCE: bitwise_expression_xor_001_T(__taint_src)\n /sast-go/cases/completeness/single_app_tracing/expression/basic_expression_operation/bitwise_expression_xor_001_T/bitwise_expression_xor_001_T.go\n AffectedNodeName: bitwise_expression_xor_001_T\n 21: CALL: bitwise_expression_xor_001_T(__taint_src)\n /sast-go/cases/completeness/single_app_tracing/expression/basic_expression_operation/bitwise_expression_xor_001_T/bitwise_expression_xor_001_T.go\n AffectedNodeName: __taint_src\n 12: ARG PASS: func bitwise_expression_xor_001_T(__taint_src int) {\n /sast-go/cases/completeness/single_app_tracing/expression/basic_expression_operation/bitwise_expression_xor_001_T/bitwise_expression_xor_001_T.go\n AffectedNodeName: result\n 13: Var Pass: \tresult := __taint_src ^ 1\n /sast-go/cases/completeness/single_app_tracing/expression/basic_expression_operation/bitwise_expression_xor_001_T/bitwise_expression_xor_001_T.go\n AffectedNodeName: __taint_sink\n 14: SINK: \t__taint_sink(result)\n==========================================================\n #Total-findings:1\n==========================================================","/benchmarks/sast-go/cases/completeness/single_app_tracing/expression/basic_expression_operation/bitwise_expression_xor_002_F/bitwise_expression_xor_002_F":"======================== Findings ========================\nNo findings!\n==========================================================","/benchmarks/sast-go/cases/completeness/single_app_tracing/expression/basic_expression_operation/logic_expression_and_001_T/logic_expression_and_001_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/sast-go/cases/completeness/single_app_tracing/expression/basic_expression_operation/logic_expression_and_001_T/logic_expression_and_001_T.go\nLine 14: __taint_sink(result)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/sast-go/cases/completeness/single_app_tracing/expression/basic_expression_operation/logic_expression_and_001_T/logic_expression_and_001_T.go\",\"functionName\":\"main\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /sast-go/cases/completeness/single_app_tracing/expression/basic_expression_operation/logic_expression_and_001_T/logic_expression_and_001_T.go\n AffectedNodeName: __taint_src\n 20: SOURCE: logic_expression_and_001_T(__taint_src)\n /sast-go/cases/completeness/single_app_tracing/expression/basic_expression_operation/logic_expression_and_001_T/logic_expression_and_001_T.go\n AffectedNodeName: logic_expression_and_001_T\n 20: CALL: logic_expression_and_001_T(__taint_src)\n /sast-go/cases/completeness/single_app_tracing/expression/basic_expression_operation/logic_expression_and_001_T/logic_expression_and_001_T.go\n AffectedNodeName: __taint_src\n 12: ARG PASS: func logic_expression_and_001_T(__taint_src bool) {\n /sast-go/cases/completeness/single_app_tracing/expression/basic_expression_operation/logic_expression_and_001_T/logic_expression_and_001_T.go\n AffectedNodeName: result\n 13: Var Pass: \tresult := __taint_src && true\n /sast-go/cases/completeness/single_app_tracing/expression/basic_expression_operation/logic_expression_and_001_T/logic_expression_and_001_T.go\n AffectedNodeName: __taint_sink\n 14: SINK: \t__taint_sink(result)\n==========================================================\n #Total-findings:1\n==========================================================","/benchmarks/sast-go/cases/completeness/single_app_tracing/expression/basic_expression_operation/logic_expression_and_002_F/logic_expression_and_002_F":"======================== Findings ========================\nNo findings!\n==========================================================","/benchmarks/sast-go/cases/completeness/single_app_tracing/expression/basic_expression_operation/logic_expression_or_001_T/logic_expression_or_001_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/sast-go/cases/completeness/single_app_tracing/expression/basic_expression_operation/logic_expression_or_001_T/logic_expression_or_001_T.go\nLine 14: __taint_sink(result)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/sast-go/cases/completeness/single_app_tracing/expression/basic_expression_operation/logic_expression_or_001_T/logic_expression_or_001_T.go\",\"functionName\":\"main\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /sast-go/cases/completeness/single_app_tracing/expression/basic_expression_operation/logic_expression_or_001_T/logic_expression_or_001_T.go\n AffectedNodeName: __taint_src\n 20: SOURCE: logic_expression_or_001_T(__taint_src)\n /sast-go/cases/completeness/single_app_tracing/expression/basic_expression_operation/logic_expression_or_001_T/logic_expression_or_001_T.go\n AffectedNodeName: logic_expression_or_001_T\n 20: CALL: logic_expression_or_001_T(__taint_src)\n /sast-go/cases/completeness/single_app_tracing/expression/basic_expression_operation/logic_expression_or_001_T/logic_expression_or_001_T.go\n AffectedNodeName: __taint_src\n 12: ARG PASS: func logic_expression_or_001_T(__taint_src bool) {\n /sast-go/cases/completeness/single_app_tracing/expression/basic_expression_operation/logic_expression_or_001_T/logic_expression_or_001_T.go\n AffectedNodeName: result\n 13: Var Pass: \tresult := false || __taint_src\n /sast-go/cases/completeness/single_app_tracing/expression/basic_expression_operation/logic_expression_or_001_T/logic_expression_or_001_T.go\n AffectedNodeName: __taint_sink\n 14: SINK: \t__taint_sink(result)\n==========================================================\n #Total-findings:1\n==========================================================","/benchmarks/sast-go/cases/completeness/single_app_tracing/expression/basic_expression_operation/logic_expression_or_002_F/logic_expression_or_002_F":"======================== Findings ========================\nNo findings!\n==========================================================","/benchmarks/sast-go/cases/completeness/single_app_tracing/expression/basic_expression_operation/relation_expression_equal_001_T/relation_expression_equal_001_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/sast-go/cases/completeness/single_app_tracing/expression/basic_expression_operation/relation_expression_equal_001_T/relation_expression_equal_001_T.go\nLine 14: __taint_sink(result)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/sast-go/cases/completeness/single_app_tracing/expression/basic_expression_operation/relation_expression_equal_001_T/relation_expression_equal_001_T.go\",\"functionName\":\"main\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /sast-go/cases/completeness/single_app_tracing/expression/basic_expression_operation/relation_expression_equal_001_T/relation_expression_equal_001_T.go\n AffectedNodeName: __taint_src\n 21: SOURCE: relation_expression_equal_001_T(__taint_src)\n /sast-go/cases/completeness/single_app_tracing/expression/basic_expression_operation/relation_expression_equal_001_T/relation_expression_equal_001_T.go\n AffectedNodeName: relation_expression_equal_001_T\n 21: CALL: relation_expression_equal_001_T(__taint_src)\n /sast-go/cases/completeness/single_app_tracing/expression/basic_expression_operation/relation_expression_equal_001_T/relation_expression_equal_001_T.go\n AffectedNodeName: __taint_src\n 12: ARG PASS: func relation_expression_equal_001_T(__taint_src string) {\n /sast-go/cases/completeness/single_app_tracing/expression/basic_expression_operation/relation_expression_equal_001_T/relation_expression_equal_001_T.go\n AffectedNodeName: result\n 13: Var Pass: \tresult := __taint_src == \"__taint_src\"\n /sast-go/cases/completeness/single_app_tracing/expression/basic_expression_operation/relation_expression_equal_001_T/relation_expression_equal_001_T.go\n AffectedNodeName: __taint_sink\n 14: SINK: \t__taint_sink(result)\n==========================================================\n #Total-findings:1\n==========================================================","/benchmarks/sast-go/cases/completeness/single_app_tracing/expression/basic_expression_operation/relation_expression_equal_002_F/relation_expression_equal_002_F":"======================== Findings ========================\nNo findings!\n==========================================================","/benchmarks/sast-go/cases/completeness/single_app_tracing/expression/special_expression/blank_identifier_001_T/blank_identifier_001_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/sast-go/cases/completeness/single_app_tracing/expression/special_expression/blank_identifier_001_T/blank_identifier_001_T.go\nLine 14: __taint_sink(a)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/sast-go/cases/completeness/single_app_tracing/expression/special_expression/blank_identifier_001_T/blank_identifier_001_T.go\",\"functionName\":\"main\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /sast-go/cases/completeness/single_app_tracing/expression/special_expression/blank_identifier_001_T/blank_identifier_001_T.go\n AffectedNodeName: __taint_src\n 25: SOURCE: blank_identifier_001_T(__taint_src)\n /sast-go/cases/completeness/single_app_tracing/expression/special_expression/blank_identifier_001_T/blank_identifier_001_T.go\n AffectedNodeName: blank_identifier_001_T\n 25: CALL: blank_identifier_001_T(__taint_src)\n /sast-go/cases/completeness/single_app_tracing/expression/special_expression/blank_identifier_001_T/blank_identifier_001_T.go\n AffectedNodeName: __taint_src\n 12: ARG PASS: func blank_identifier_001_T(__taint_src string) {\n /sast-go/cases/completeness/single_app_tracing/expression/special_expression/blank_identifier_001_T/blank_identifier_001_T.go\n AffectedNodeName: getData\n 13: CALL: \ta, _ := getData(__taint_src)\n /sast-go/cases/completeness/single_app_tracing/expression/special_expression/blank_identifier_001_T/blank_identifier_001_T.go\n AffectedNodeName: __taint_src\n 17: ARG PASS: func getData(__taint_src string) (string, string) {\n /sast-go/cases/completeness/single_app_tracing/expression/special_expression/blank_identifier_001_T/blank_identifier_001_T.go\n AffectedNodeName: [return value]\n 18: Return Value: \treturn __taint_src, \"\"\n /sast-go/cases/completeness/single_app_tracing/expression/special_expression/blank_identifier_001_T/blank_identifier_001_T.go\n AffectedNodeName: getData\n 13: CALL RETURN: \ta, _ := getData(__taint_src)\n /sast-go/cases/completeness/single_app_tracing/expression/special_expression/blank_identifier_001_T/blank_identifier_001_T.go\n 13: Var Pass: \ta, _ := getData(__taint_src)\n /sast-go/cases/completeness/single_app_tracing/expression/special_expression/blank_identifier_001_T/blank_identifier_001_T.go\n AffectedNodeName: __taint_sink\n 14: SINK: \t__taint_sink(a)\n==========================================================\n #Total-findings:1\n==========================================================","/benchmarks/sast-go/cases/completeness/single_app_tracing/expression/special_expression/blank_identifier_002_F/blank_identifier_002_F":"======================== Findings ========================\nNo findings!\n==========================================================","/benchmarks/sast-go/cases/completeness/single_app_tracing/expression/special_expression/multiple_assignment_001_T/multiple_assignment_001_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/sast-go/cases/completeness/single_app_tracing/expression/special_expression/multiple_assignment_001_T/multiple_assignment_001_T.go\nLine 14: __taint_sink(result)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/sast-go/cases/completeness/single_app_tracing/expression/special_expression/multiple_assignment_001_T/multiple_assignment_001_T.go\",\"functionName\":\"main\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /sast-go/cases/completeness/single_app_tracing/expression/special_expression/multiple_assignment_001_T/multiple_assignment_001_T.go\n AffectedNodeName: __taint_src\n 21: SOURCE: multiple_assignment_001_T(__taint_src)\n /sast-go/cases/completeness/single_app_tracing/expression/special_expression/multiple_assignment_001_T/multiple_assignment_001_T.go\n AffectedNodeName: multiple_assignment_001_T\n 21: CALL: multiple_assignment_001_T(__taint_src)\n /sast-go/cases/completeness/single_app_tracing/expression/special_expression/multiple_assignment_001_T/multiple_assignment_001_T.go\n AffectedNodeName: __taint_src\n 12: ARG PASS: func multiple_assignment_001_T(__taint_src string) {\n /sast-go/cases/completeness/single_app_tracing/expression/special_expression/multiple_assignment_001_T/multiple_assignment_001_T.go\n AffectedNodeName: __taint_sink\n 14: SINK: \t__taint_sink(result)\n==========================================================\n #Total-findings:1\n==========================================================","/benchmarks/sast-go/cases/completeness/single_app_tracing/expression/special_expression/multiple_assignment_002_F/multiple_assignment_002_F":"======================== Findings ========================\nNo findings!\n==========================================================","/benchmarks/sast-go/cases/completeness/single_app_tracing/expression/special_expression/rest_parameter_001_T/rest_parameter_001_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/sast-go/cases/completeness/single_app_tracing/expression/special_expression/rest_parameter_001_T/rest_parameter_001_T.go\nLine 17: __taint_sink(args)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/sast-go/cases/completeness/single_app_tracing/expression/special_expression/rest_parameter_001_T/rest_parameter_001_T.go\",\"functionName\":\"main\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /sast-go/cases/completeness/single_app_tracing/expression/special_expression/rest_parameter_001_T/rest_parameter_001_T.go\n AffectedNodeName: __taint_src\n 24: SOURCE: rest_parameter_001_T(__taint_src)\n /sast-go/cases/completeness/single_app_tracing/expression/special_expression/rest_parameter_001_T/rest_parameter_001_T.go\n AffectedNodeName: rest_parameter_001_T\n 24: CALL: rest_parameter_001_T(__taint_src)\n /sast-go/cases/completeness/single_app_tracing/expression/special_expression/rest_parameter_001_T/rest_parameter_001_T.go\n AffectedNodeName: __taint_src\n 12: ARG PASS: func rest_parameter_001_T(__taint_src string) {\n /sast-go/cases/completeness/single_app_tracing/expression/special_expression/rest_parameter_001_T/rest_parameter_001_T.go\n AffectedNodeName: collectArgs\n 13: CALL: \tcollectArgs(\"prefix\", __taint_src, \"suffix\")\n /sast-go/cases/completeness/single_app_tracing/expression/special_expression/rest_parameter_001_T/rest_parameter_001_T.go\n AffectedNodeName: args\n 16: ARG PASS: func collectArgs(args ...interface{}) {\n /sast-go/cases/completeness/single_app_tracing/expression/special_expression/rest_parameter_001_T/rest_parameter_001_T.go\n AffectedNodeName: __taint_sink\n 17: SINK: \t__taint_sink(args)\n==========================================================\n #Total-findings:1\n==========================================================","/benchmarks/sast-go/cases/completeness/single_app_tracing/expression/special_expression/rest_parameter_002_F/rest_parameter_002_F":"======================== Findings ========================\nNo findings!\n==========================================================","/benchmarks/sast-go/cases/completeness/single_app_tracing/expression/special_expression/spread_operator_001_T/spread_operator_001_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/sast-go/cases/completeness/single_app_tracing/expression/special_expression/spread_operator_001_T/spread_operator_001_T.go\nLine 15: __taint_sink(array)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/sast-go/cases/completeness/single_app_tracing/expression/special_expression/spread_operator_001_T/spread_operator_001_T.go\",\"functionName\":\"main\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /sast-go/cases/completeness/single_app_tracing/expression/special_expression/spread_operator_001_T/spread_operator_001_T.go\n AffectedNodeName: __taint_src\n 22: SOURCE: spread_operator_001_T(__taint_src)\n /sast-go/cases/completeness/single_app_tracing/expression/special_expression/spread_operator_001_T/spread_operator_001_T.go\n AffectedNodeName: spread_operator_001_T\n 22: CALL: spread_operator_001_T(__taint_src)\n /sast-go/cases/completeness/single_app_tracing/expression/special_expression/spread_operator_001_T/spread_operator_001_T.go\n AffectedNodeName: __taint_src\n 12: ARG PASS: func spread_operator_001_T(__taint_src string) {\n /sast-go/cases/completeness/single_app_tracing/expression/special_expression/spread_operator_001_T/spread_operator_001_T.go\n AffectedNodeName: array1\n 13: Var Pass: \tarray1 := []string{\"a\", \"b\", __taint_src}\n /sast-go/cases/completeness/single_app_tracing/expression/special_expression/spread_operator_001_T/spread_operator_001_T.go\n AffectedNodeName: array\n 14: Var Pass: \tarray := append([]string{\"c\"}, array1...)\n /sast-go/cases/completeness/single_app_tracing/expression/special_expression/spread_operator_001_T/spread_operator_001_T.go\n AffectedNodeName: __taint_sink\n 15: SINK: \t__taint_sink(array)\n==========================================================\n #Total-findings:1\n==========================================================","/benchmarks/sast-go/cases/completeness/single_app_tracing/expression/special_expression/spread_operator_002_F/spread_operator_002_F":"======================== Findings ========================\nNo findings!\n==========================================================","/benchmarks/sast-go/cases/completeness/single_app_tracing/expression/type_cast/type_cast_001_T/type_cast_001_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/sast-go/cases/completeness/single_app_tracing/expression/type_cast/type_cast_001_T/type_cast_001_T.go\nLine 14: __taint_sink(result)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/sast-go/cases/completeness/single_app_tracing/expression/type_cast/type_cast_001_T/type_cast_001_T.go\",\"functionName\":\"main\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /sast-go/cases/completeness/single_app_tracing/expression/type_cast/type_cast_001_T/type_cast_001_T.go\n AffectedNodeName: __taint_src\n 21: SOURCE: type_cast_001_T(__taint_src)\n /sast-go/cases/completeness/single_app_tracing/expression/type_cast/type_cast_001_T/type_cast_001_T.go\n AffectedNodeName: type_cast_001_T\n 21: CALL: type_cast_001_T(__taint_src)\n /sast-go/cases/completeness/single_app_tracing/expression/type_cast/type_cast_001_T/type_cast_001_T.go\n AffectedNodeName: __taint_src\n 12: ARG PASS: func type_cast_001_T(__taint_src int) {\n /sast-go/cases/completeness/single_app_tracing/expression/type_cast/type_cast_001_T/type_cast_001_T.go\n AffectedNodeName: result\n 13: Var Pass: \tresult := float64(__taint_src)\n /sast-go/cases/completeness/single_app_tracing/expression/type_cast/type_cast_001_T/type_cast_001_T.go\n AffectedNodeName: __taint_sink\n 14: SINK: \t__taint_sink(result)\n==========================================================\n #Total-findings:1\n==========================================================","/benchmarks/sast-go/cases/completeness/single_app_tracing/expression/type_cast/type_cast_002_F/type_cast_002_F":"======================== Findings ========================\nNo findings!\n==========================================================","/benchmarks/sast-go/cases/completeness/single_app_tracing/expression/type_cast/type_cast_003_T/type_cast_003_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/sast-go/cases/completeness/single_app_tracing/expression/type_cast/type_cast_003_T/type_cast_003_T.go\nLine 15: __taint_sink(result)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/sast-go/cases/completeness/single_app_tracing/expression/type_cast/type_cast_003_T/type_cast_003_T.go\",\"functionName\":\"main\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /sast-go/cases/completeness/single_app_tracing/expression/type_cast/type_cast_003_T/type_cast_003_T.go\n AffectedNodeName: __taint_src\n 22: SOURCE: type_cast_003_T(__taint_src)\n /sast-go/cases/completeness/single_app_tracing/expression/type_cast/type_cast_003_T/type_cast_003_T.go\n AffectedNodeName: type_cast_003_T\n 22: CALL: type_cast_003_T(__taint_src)\n /sast-go/cases/completeness/single_app_tracing/expression/type_cast/type_cast_003_T/type_cast_003_T.go\n AffectedNodeName: __taint_src\n 12: ARG PASS: func type_cast_003_T(__taint_src interface{}) {\n /sast-go/cases/completeness/single_app_tracing/expression/type_cast/type_cast_003_T/type_cast_003_T.go\n 13: Var Pass: \tresult, ok := __taint_src.(string)\n /sast-go/cases/completeness/single_app_tracing/expression/type_cast/type_cast_003_T/type_cast_003_T.go\n AffectedNodeName: __taint_sink\n 15: SINK: \t__taint_sink(result)\n==========================================================\n #Total-findings:1\n==========================================================","/benchmarks/sast-go/cases/completeness/single_app_tracing/expression/type_cast/type_cast_004_F/type_cast_004_F":"======================== Findings ========================\nNo findings!\n==========================================================","/benchmarks/sast-go/cases/completeness/single_app_tracing/function_call/anonymous_function_closure/anonymous_function_001_F/anonymous_function_001_F":"======================== Findings ========================\nNo findings!\n==========================================================","/benchmarks/sast-go/cases/completeness/single_app_tracing/function_call/anonymous_function_closure/anonymous_function_002_T/anonymous_function_002_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/sast-go/cases/completeness/single_app_tracing/function_call/anonymous_function_closure/anonymous_function_002_T/anonymous_function_002_T.go\nLine 16: __taint_sink(process(__taint_src, \"foo\"))\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/sast-go/cases/completeness/single_app_tracing/function_call/anonymous_function_closure/anonymous_function_002_T/anonymous_function_002_T.go\",\"functionName\":\"main\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /sast-go/cases/completeness/single_app_tracing/function_call/anonymous_function_closure/anonymous_function_002_T/anonymous_function_002_T.go\n AffectedNodeName: __taint_src\n 23: SOURCE: anonymous_function_002_T(__taint_src)\n /sast-go/cases/completeness/single_app_tracing/function_call/anonymous_function_closure/anonymous_function_002_T/anonymous_function_002_T.go\n AffectedNodeName: anonymous_function_002_T\n 23: CALL: anonymous_function_002_T(__taint_src)\n /sast-go/cases/completeness/single_app_tracing/function_call/anonymous_function_closure/anonymous_function_002_T/anonymous_function_002_T.go\n AffectedNodeName: __taint_src\n 12: ARG PASS: func anonymous_function_002_T(__taint_src string) {\n /sast-go/cases/completeness/single_app_tracing/function_call/anonymous_function_closure/anonymous_function_002_T/anonymous_function_002_T.go\n AffectedNodeName: \n 16: CALL: \t__taint_sink(process(__taint_src, \"foo\"))\n /sast-go/cases/completeness/single_app_tracing/function_call/anonymous_function_closure/anonymous_function_002_T/anonymous_function_002_T.go\n AffectedNodeName: a\n 13: ARG PASS: \tprocess := func(a string, b string) string {\n /sast-go/cases/completeness/single_app_tracing/function_call/anonymous_function_closure/anonymous_function_002_T/anonymous_function_002_T.go\n AffectedNodeName: [return value]\n 14: Return Value: \t\treturn a + b\n /sast-go/cases/completeness/single_app_tracing/function_call/anonymous_function_closure/anonymous_function_002_T/anonymous_function_002_T.go\n AffectedNodeName: \n 16: CALL RETURN: \t__taint_sink(process(__taint_src, \"foo\"))\n /sast-go/cases/completeness/single_app_tracing/function_call/anonymous_function_closure/anonymous_function_002_T/anonymous_function_002_T.go\n AffectedNodeName: __taint_sink\n 16: SINK: \t__taint_sink(process(__taint_src, \"foo\"))\n==========================================================\n #Total-findings:1\n==========================================================","/benchmarks/sast-go/cases/completeness/single_app_tracing/function_call/anonymous_function_closure/anonymous_function_003_F/anonymous_function_003_F":"======================== Findings ========================\nNo findings!\n==========================================================","/benchmarks/sast-go/cases/completeness/single_app_tracing/function_call/anonymous_function_closure/anonymous_function_004_T/anonymous_function_004_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/sast-go/cases/completeness/single_app_tracing/function_call/anonymous_function_closure/anonymous_function_004_T/anonymous_function_004_T.go\nLine 15: __taint_sink(input)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/sast-go/cases/completeness/single_app_tracing/function_call/anonymous_function_closure/anonymous_function_004_T/anonymous_function_004_T.go\",\"functionName\":\"main\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /sast-go/cases/completeness/single_app_tracing/function_call/anonymous_function_closure/anonymous_function_004_T/anonymous_function_004_T.go\n AffectedNodeName: __taint_src\n 25: SOURCE: anonymous_function_004_T(__taint_src)\n /sast-go/cases/completeness/single_app_tracing/function_call/anonymous_function_closure/anonymous_function_004_T/anonymous_function_004_T.go\n AffectedNodeName: anonymous_function_004_T\n 25: CALL: anonymous_function_004_T(__taint_src)\n /sast-go/cases/completeness/single_app_tracing/function_call/anonymous_function_closure/anonymous_function_004_T/anonymous_function_004_T.go\n AffectedNodeName: __taint_src\n 12: ARG PASS: func anonymous_function_004_T(__taint_src interface{}) {\n /sast-go/cases/completeness/single_app_tracing/function_call/anonymous_function_closure/anonymous_function_004_T/anonymous_function_004_T.go\n AffectedNodeName: \n 18: CALL: \tprocess(__taint_src)\n /sast-go/cases/completeness/single_app_tracing/function_call/anonymous_function_closure/anonymous_function_004_T/anonymous_function_004_T.go\n AffectedNodeName: input\n 14: ARG PASS: \tprocess := func(input interface{}) {\n /sast-go/cases/completeness/single_app_tracing/function_call/anonymous_function_closure/anonymous_function_004_T/anonymous_function_004_T.go\n AffectedNodeName: __taint_sink\n 15: SINK: \t\t__taint_sink(input)\n==========================================================\n #Total-findings:1\n==========================================================","/benchmarks/sast-go/cases/completeness/single_app_tracing/function_call/anonymous_function_closure/anonymous_function_005_F/anonymous_function_005_F":"======================== Findings ========================\nNo findings!\n==========================================================","/benchmarks/sast-go/cases/completeness/single_app_tracing/function_call/anonymous_function_closure/anonymous_function_006_T/anonymous_function_006_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/sast-go/cases/completeness/single_app_tracing/function_call/anonymous_function_closure/anonymous_function_006_T/anonymous_function_006_T.go\nLine 14: __taint_sink(__taint_src)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/sast-go/cases/completeness/single_app_tracing/function_call/anonymous_function_closure/anonymous_function_006_T/anonymous_function_006_T.go\",\"functionName\":\"main\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /sast-go/cases/completeness/single_app_tracing/function_call/anonymous_function_closure/anonymous_function_006_T/anonymous_function_006_T.go\n AffectedNodeName: __taint_src\n 22: SOURCE: anonymous_function_006_T(__taint_src)\n /sast-go/cases/completeness/single_app_tracing/function_call/anonymous_function_closure/anonymous_function_006_T/anonymous_function_006_T.go\n AffectedNodeName: anonymous_function_006_T\n 22: CALL: anonymous_function_006_T(__taint_src)\n /sast-go/cases/completeness/single_app_tracing/function_call/anonymous_function_closure/anonymous_function_006_T/anonymous_function_006_T.go\n AffectedNodeName: __taint_src\n 12: ARG PASS: func anonymous_function_006_T(__taint_src interface{}) {\n /sast-go/cases/completeness/single_app_tracing/function_call/anonymous_function_closure/anonymous_function_006_T/anonymous_function_006_T.go\n AffectedNodeName: __taint_sink\n 14: SINK: \t\t__taint_sink(__taint_src)\n==========================================================\n #Total-findings:1\n==========================================================","/benchmarks/sast-go/cases/completeness/single_app_tracing/function_call/anonymous_function_closure/closure_function_001_F/closure_function_001_F":"======================== Findings ========================\nNo findings!\n==========================================================","/benchmarks/sast-go/cases/completeness/single_app_tracing/function_call/anonymous_function_closure/closure_function_002_T/closure_function_002_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/sast-go/cases/completeness/single_app_tracing/function_call/anonymous_function_closure/closure_function_002_T/closure_function_002_T.go\nLine 14: __taint_sink(__taint_src)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/sast-go/cases/completeness/single_app_tracing/function_call/anonymous_function_closure/closure_function_002_T/closure_function_002_T.go\",\"functionName\":\"main\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /sast-go/cases/completeness/single_app_tracing/function_call/anonymous_function_closure/closure_function_002_T/closure_function_002_T.go\n AffectedNodeName: __taint_src\n 23: SOURCE: closure_function_002_T(__taint_src)\n /sast-go/cases/completeness/single_app_tracing/function_call/anonymous_function_closure/closure_function_002_T/closure_function_002_T.go\n AffectedNodeName: closure_function_002_T\n 23: CALL: closure_function_002_T(__taint_src)\n /sast-go/cases/completeness/single_app_tracing/function_call/anonymous_function_closure/closure_function_002_T/closure_function_002_T.go\n AffectedNodeName: __taint_src\n 12: ARG PASS: func closure_function_002_T(__taint_src interface{}) {\n /sast-go/cases/completeness/single_app_tracing/function_call/anonymous_function_closure/closure_function_002_T/closure_function_002_T.go\n AffectedNodeName: __taint_sink\n 14: SINK: \t\t__taint_sink(__taint_src)\n==========================================================\n #Total-findings:1\n==========================================================","/benchmarks/sast-go/cases/completeness/single_app_tracing/function_call/anonymous_function_closure/closure_function_003_F/closure_function_003_F":"======================== Findings ========================\nNo findings!\n==========================================================","/benchmarks/sast-go/cases/completeness/single_app_tracing/function_call/anonymous_function_closure/closure_function_004_T/closure_function_004_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/sast-go/cases/completeness/single_app_tracing/function_call/anonymous_function_closure/closure_function_004_T/closure_function_004_T.go\nLine 15: __taint_sink(__taint_src)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/sast-go/cases/completeness/single_app_tracing/function_call/anonymous_function_closure/closure_function_004_T/closure_function_004_T.go\",\"functionName\":\"main\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /sast-go/cases/completeness/single_app_tracing/function_call/anonymous_function_closure/closure_function_004_T/closure_function_004_T.go\n AffectedNodeName: __taint_src\n 26: SOURCE: closure_function_004_T(__taint_src)\n /sast-go/cases/completeness/single_app_tracing/function_call/anonymous_function_closure/closure_function_004_T/closure_function_004_T.go\n AffectedNodeName: closure_function_004_T\n 26: CALL: closure_function_004_T(__taint_src)\n /sast-go/cases/completeness/single_app_tracing/function_call/anonymous_function_closure/closure_function_004_T/closure_function_004_T.go\n AffectedNodeName: __taint_src\n 12: ARG PASS: func closure_function_004_T(__taint_src interface{}) {\n /sast-go/cases/completeness/single_app_tracing/function_call/anonymous_function_closure/closure_function_004_T/closure_function_004_T.go\n AffectedNodeName: __taint_sink\n 15: SINK: \t\t\t__taint_sink(__taint_src)\n==========================================================\n #Total-findings:1\n==========================================================","/benchmarks/sast-go/cases/completeness/single_app_tracing/function_call/anonymous_function_closure/closure_function_005_F/closure_function_005_F":"======================== Findings ========================\nNo findings!\n==========================================================","/benchmarks/sast-go/cases/completeness/single_app_tracing/function_call/anonymous_function_closure/closure_function_006_T/closure_function_006_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/sast-go/cases/completeness/single_app_tracing/function_call/anonymous_function_closure/closure_function_006_T/closure_function_006_T.go\nLine 35: __taint_sink(a.update())\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/sast-go/cases/completeness/single_app_tracing/function_call/anonymous_function_closure/closure_function_006_T/closure_function_006_T.go\",\"functionName\":\"main\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /sast-go/cases/completeness/single_app_tracing/function_call/anonymous_function_closure/closure_function_006_T/closure_function_006_T.go\n AffectedNodeName: __taint_src\n 42: SOURCE: closure_function_006_T(__taint_src)\n /sast-go/cases/completeness/single_app_tracing/function_call/anonymous_function_closure/closure_function_006_T/closure_function_006_T.go\n AffectedNodeName: closure_function_006_T\n 42: CALL: closure_function_006_T(__taint_src)\n /sast-go/cases/completeness/single_app_tracing/function_call/anonymous_function_closure/closure_function_006_T/closure_function_006_T.go\n AffectedNodeName: __taint_src\n 13: ARG PASS: func closure_function_006_T(__taint_src string) {\n /sast-go/cases/completeness/single_app_tracing/function_call/anonymous_function_closure/closure_function_006_T/closure_function_006_T.go\n AffectedNodeName: source\n 25: Var Pass: \t\t\t\tsource = __taint_src\n /sast-go/cases/completeness/single_app_tracing/function_call/anonymous_function_closure/closure_function_006_T/closure_function_006_T.go\n AffectedNodeName: [return value]\n 26: Return Value: \t\t\t\treturn source\n /sast-go/cases/completeness/single_app_tracing/function_call/anonymous_function_closure/closure_function_006_T/closure_function_006_T.go\n AffectedNodeName: \n 35: CALL RETURN: \t__taint_sink(a.update())\n /sast-go/cases/completeness/single_app_tracing/function_call/anonymous_function_closure/closure_function_006_T/closure_function_006_T.go\n AffectedNodeName: __taint_sink\n 35: SINK: \t__taint_sink(a.update())\n==========================================================\n #Total-findings:1\n==========================================================","/benchmarks/sast-go/cases/completeness/single_app_tracing/function_call/anonymous_function_closure/closure_function_007_F/closure_function_007_F":"======================== Findings ========================\nNo findings!\n==========================================================","/benchmarks/sast-go/cases/completeness/single_app_tracing/function_call/anonymous_function_closure/closure_function_008_T/closure_function_008_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/sast-go/cases/completeness/single_app_tracing/function_call/anonymous_function_closure/closure_function_008_T/closure_function_008_T.go\nLine 20: __taint_sink(middleVar)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/sast-go/cases/completeness/single_app_tracing/function_call/anonymous_function_closure/closure_function_008_T/closure_function_008_T.go\",\"functionName\":\"main\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /sast-go/cases/completeness/single_app_tracing/function_call/anonymous_function_closure/closure_function_008_T/closure_function_008_T.go\n AffectedNodeName: __taint_src\n 38: SOURCE: closure_function_008_T(__taint_src)\n /sast-go/cases/completeness/single_app_tracing/function_call/anonymous_function_closure/closure_function_008_T/closure_function_008_T.go\n AffectedNodeName: closure_function_008_T\n 38: CALL: closure_function_008_T(__taint_src)\n /sast-go/cases/completeness/single_app_tracing/function_call/anonymous_function_closure/closure_function_008_T/closure_function_008_T.go\n AffectedNodeName: __taint_src\n 12: ARG PASS: func closure_function_008_T(__taint_src interface{}) {\n /sast-go/cases/completeness/single_app_tracing/function_call/anonymous_function_closure/closure_function_008_T/closure_function_008_T.go\n AffectedNodeName: outerVar\n 14: Var Pass: \t\touterVar := __taint_src\n /sast-go/cases/completeness/single_app_tracing/function_call/anonymous_function_closure/closure_function_008_T/closure_function_008_T.go\n AffectedNodeName: middleVar\n 17: Var Pass: \t\t\tmiddleVar := outerVar\n /sast-go/cases/completeness/single_app_tracing/function_call/anonymous_function_closure/closure_function_008_T/closure_function_008_T.go\n AffectedNodeName: __taint_sink\n 20: SINK: \t\t\t\t__taint_sink(middleVar)\n==========================================================\n #Total-findings:1\n==========================================================","/benchmarks/sast-go/cases/completeness/single_app_tracing/function_call/anonymous_function_closure/closure_function_009_F/closure_function_009_F":"======================== Findings ========================\nNo findings!\n==========================================================","/benchmarks/sast-go/cases/completeness/single_app_tracing/function_call/anonymous_function_closure/closure_function_010_T/closure_function_010_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/sast-go/cases/completeness/single_app_tracing/function_call/anonymous_function_closure/closure_function_010_T/closure_function_010_T.go\nLine 18: __taint_sink(outerVar)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/sast-go/cases/completeness/single_app_tracing/function_call/anonymous_function_closure/closure_function_010_T/closure_function_010_T.go\",\"functionName\":\"main\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /sast-go/cases/completeness/single_app_tracing/function_call/anonymous_function_closure/closure_function_010_T/closure_function_010_T.go\n AffectedNodeName: __taint_src\n 36: SOURCE: closure_function_010_T(__taint_src)\n /sast-go/cases/completeness/single_app_tracing/function_call/anonymous_function_closure/closure_function_010_T/closure_function_010_T.go\n AffectedNodeName: closure_function_010_T\n 36: CALL: closure_function_010_T(__taint_src)\n /sast-go/cases/completeness/single_app_tracing/function_call/anonymous_function_closure/closure_function_010_T/closure_function_010_T.go\n AffectedNodeName: __taint_src\n 12: ARG PASS: func closure_function_010_T(__taint_src interface{}) {\n /sast-go/cases/completeness/single_app_tracing/function_call/anonymous_function_closure/closure_function_010_T/closure_function_010_T.go\n AffectedNodeName: outerVar\n 14: Var Pass: \t\touterVar := __taint_src\n /sast-go/cases/completeness/single_app_tracing/function_call/anonymous_function_closure/closure_function_010_T/closure_function_010_T.go\n AffectedNodeName: __taint_sink\n 18: SINK: \t\t\t\t__taint_sink(outerVar)\n==========================================================\n #Total-findings:1\n==========================================================","/benchmarks/sast-go/cases/completeness/single_app_tracing/function_call/argument_passing/argument_passing_value_001_F/argument_passing_value_001_F":"======================== Findings ========================\nNo findings!\n==========================================================","/benchmarks/sast-go/cases/completeness/single_app_tracing/function_call/argument_passing/argument_passing_value_002_T/argument_passing_value_002_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/sast-go/cases/completeness/single_app_tracing/function_call/argument_passing/argument_passing_value_002_T/argument_passing_value_002_T.go\nLine 17: __taint_sink(arg)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/sast-go/cases/completeness/single_app_tracing/function_call/argument_passing/argument_passing_value_002_T/argument_passing_value_002_T.go\",\"functionName\":\"main\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /sast-go/cases/completeness/single_app_tracing/function_call/argument_passing/argument_passing_value_002_T/argument_passing_value_002_T.go\n AffectedNodeName: __taint_src\n 24: SOURCE: argument_passing_value_002_T(__taint_src)\n /sast-go/cases/completeness/single_app_tracing/function_call/argument_passing/argument_passing_value_002_T/argument_passing_value_002_T.go\n AffectedNodeName: argument_passing_value_002_T\n 24: CALL: argument_passing_value_002_T(__taint_src)\n /sast-go/cases/completeness/single_app_tracing/function_call/argument_passing/argument_passing_value_002_T/argument_passing_value_002_T.go\n AffectedNodeName: __taint_src\n 12: ARG PASS: func argument_passing_value_002_T(__taint_src string) {\n /sast-go/cases/completeness/single_app_tracing/function_call/argument_passing/argument_passing_value_002_T/argument_passing_value_002_T.go\n AffectedNodeName: process\n 13: CALL: \tprocess(__taint_src)\n /sast-go/cases/completeness/single_app_tracing/function_call/argument_passing/argument_passing_value_002_T/argument_passing_value_002_T.go\n AffectedNodeName: arg\n 16: ARG PASS: func process(arg string) {\n /sast-go/cases/completeness/single_app_tracing/function_call/argument_passing/argument_passing_value_002_T/argument_passing_value_002_T.go\n AffectedNodeName: __taint_sink\n 17: SINK: \t__taint_sink(arg)\n==========================================================\n #Total-findings:1\n==========================================================","/benchmarks/sast-go/cases/completeness/single_app_tracing/function_call/argument_passing/argument_passing_value_003_F/argument_passing_value_003_F":"======================== Findings ========================\nNo findings!\n==========================================================","/benchmarks/sast-go/cases/completeness/single_app_tracing/function_call/argument_passing/argument_passing_value_004_T/argument_passing_value_004_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/sast-go/cases/completeness/single_app_tracing/function_call/argument_passing/argument_passing_value_004_T/argument_passing_value_004_T.go\nLine 19: __taint_sink(arg)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/sast-go/cases/completeness/single_app_tracing/function_call/argument_passing/argument_passing_value_004_T/argument_passing_value_004_T.go\",\"functionName\":\"main\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /sast-go/cases/completeness/single_app_tracing/function_call/argument_passing/argument_passing_value_004_T/argument_passing_value_004_T.go\n AffectedNodeName: __taint_src\n 29: SOURCE: argument_passing_value_004_T(__taint_src)\n /sast-go/cases/completeness/single_app_tracing/function_call/argument_passing/argument_passing_value_004_T/argument_passing_value_004_T.go\n AffectedNodeName: argument_passing_value_004_T\n 29: CALL: argument_passing_value_004_T(__taint_src)\n /sast-go/cases/completeness/single_app_tracing/function_call/argument_passing/argument_passing_value_004_T/argument_passing_value_004_T.go\n AffectedNodeName: __taint_src\n 12: ARG PASS: func argument_passing_value_004_T(__taint_src interface{}) {\n /sast-go/cases/completeness/single_app_tracing/function_call/argument_passing/argument_passing_value_004_T/argument_passing_value_004_T.go\n AffectedNodeName: process1\n 15: CALL: \tprocess1(__taint_src)\n /sast-go/cases/completeness/single_app_tracing/function_call/argument_passing/argument_passing_value_004_T/argument_passing_value_004_T.go\n AffectedNodeName: arg\n 18: ARG PASS: func process1(arg interface{}) {\n /sast-go/cases/completeness/single_app_tracing/function_call/argument_passing/argument_passing_value_004_T/argument_passing_value_004_T.go\n AffectedNodeName: __taint_sink\n 19: SINK: \t__taint_sink(arg)\n==========================================================\n #Total-findings:1\n==========================================================","/benchmarks/sast-go/cases/completeness/single_app_tracing/function_call/argument_passing/argument_passing_value_005_F/argument_passing_value_005_F":"======================== Findings ========================\nNo findings!\n==========================================================","/benchmarks/sast-go/cases/completeness/single_app_tracing/function_call/argument_passing/argument_passing_value_006_T/argument_passing_value_006_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/sast-go/cases/completeness/single_app_tracing/function_call/argument_passing/argument_passing_value_006_T/argument_passing_value_006_T.go\nLine 17: __taint_sink(arg1)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/sast-go/cases/completeness/single_app_tracing/function_call/argument_passing/argument_passing_value_006_T/argument_passing_value_006_T.go\",\"functionName\":\"main\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /sast-go/cases/completeness/single_app_tracing/function_call/argument_passing/argument_passing_value_006_T/argument_passing_value_006_T.go\n AffectedNodeName: __taint_src\n 23: SOURCE: argument_passing_value_006_T(__taint_src)\n /sast-go/cases/completeness/single_app_tracing/function_call/argument_passing/argument_passing_value_006_T/argument_passing_value_006_T.go\n AffectedNodeName: argument_passing_value_006_T\n 23: CALL: argument_passing_value_006_T(__taint_src)\n /sast-go/cases/completeness/single_app_tracing/function_call/argument_passing/argument_passing_value_006_T/argument_passing_value_006_T.go\n AffectedNodeName: __taint_src\n 12: ARG PASS: func argument_passing_value_006_T(__taint_src string) {\n /sast-go/cases/completeness/single_app_tracing/function_call/argument_passing/argument_passing_value_006_T/argument_passing_value_006_T.go\n AffectedNodeName: process\n 13: CALL: \tprocess(__taint_src, \"_\")\n /sast-go/cases/completeness/single_app_tracing/function_call/argument_passing/argument_passing_value_006_T/argument_passing_value_006_T.go\n AffectedNodeName: arg1\n 16: ARG PASS: func process(arg1 string, arg2 string) {\n /sast-go/cases/completeness/single_app_tracing/function_call/argument_passing/argument_passing_value_006_T/argument_passing_value_006_T.go\n AffectedNodeName: __taint_sink\n 17: SINK: \t__taint_sink(arg1)\n==========================================================\n #Total-findings:1\n==========================================================","/benchmarks/sast-go/cases/completeness/single_app_tracing/function_call/argument_passing/argument_passing_value_007_F/argument_passing_value_007_F":"======================== Findings ========================\nNo findings!\n==========================================================","/benchmarks/sast-go/cases/completeness/single_app_tracing/function_call/argument_passing/argument_passing_value_008_T/argument_passing_value_008_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/sast-go/cases/completeness/single_app_tracing/function_call/argument_passing/argument_passing_value_008_T/argument_passing_value_008_T.go\nLine 15: __taint_sink(innerInput)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/sast-go/cases/completeness/single_app_tracing/function_call/argument_passing/argument_passing_value_008_T/argument_passing_value_008_T.go\",\"functionName\":\"main\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /sast-go/cases/completeness/single_app_tracing/function_call/argument_passing/argument_passing_value_008_T/argument_passing_value_008_T.go\n AffectedNodeName: __taint_src\n 27: SOURCE: argument_passing_value_008_T(__taint_src)\n /sast-go/cases/completeness/single_app_tracing/function_call/argument_passing/argument_passing_value_008_T/argument_passing_value_008_T.go\n AffectedNodeName: argument_passing_value_008_T\n 27: CALL: argument_passing_value_008_T(__taint_src)\n /sast-go/cases/completeness/single_app_tracing/function_call/argument_passing/argument_passing_value_008_T/argument_passing_value_008_T.go\n AffectedNodeName: __taint_src\n 12: ARG PASS: func argument_passing_value_008_T(__taint_src string) {\n /sast-go/cases/completeness/single_app_tracing/function_call/argument_passing/argument_passing_value_008_T/argument_passing_value_008_T.go\n AffectedNodeName: \n 21: CALL: \touter(__taint_src)\n /sast-go/cases/completeness/single_app_tracing/function_call/argument_passing/argument_passing_value_008_T/argument_passing_value_008_T.go\n AffectedNodeName: input\n 13: ARG PASS: \touter := func(input string) {\n /sast-go/cases/completeness/single_app_tracing/function_call/argument_passing/argument_passing_value_008_T/argument_passing_value_008_T.go\n AffectedNodeName: \n 18: CALL: \t\tinner(input)\n /sast-go/cases/completeness/single_app_tracing/function_call/argument_passing/argument_passing_value_008_T/argument_passing_value_008_T.go\n AffectedNodeName: innerInput\n 14: ARG PASS: \t\tinner := func(innerInput interface{}) {\n /sast-go/cases/completeness/single_app_tracing/function_call/argument_passing/argument_passing_value_008_T/argument_passing_value_008_T.go\n AffectedNodeName: __taint_sink\n 15: SINK: \t\t\t__taint_sink(innerInput)\n==========================================================\n #Total-findings:1\n==========================================================","/benchmarks/sast-go/cases/completeness/single_app_tracing/function_call/argument_passing/argument_passing_value_009_T/argument_passing_value_009_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/sast-go/cases/completeness/single_app_tracing/function_call/argument_passing/argument_passing_value_009_T/argument_passing_value_009_T.go\nLine 20: __taint_sink(person.GetNamePointer())\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/sast-go/cases/completeness/single_app_tracing/function_call/argument_passing/argument_passing_value_009_T/argument_passing_value_009_T.go\",\"functionName\":\"main\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /sast-go/cases/completeness/single_app_tracing/function_call/argument_passing/argument_passing_value_009_T/argument_passing_value_009_T.go\n AffectedNodeName: __taint_src\n 35: SOURCE: argument_passing_value_009_T(__taint_src)\n /sast-go/cases/completeness/single_app_tracing/function_call/argument_passing/argument_passing_value_009_T/argument_passing_value_009_T.go\n AffectedNodeName: argument_passing_value_009_T\n 35: CALL: argument_passing_value_009_T(__taint_src)\n /sast-go/cases/completeness/single_app_tracing/function_call/argument_passing/argument_passing_value_009_T/argument_passing_value_009_T.go\n AffectedNodeName: __taint_src\n 16: ARG PASS: func argument_passing_value_009_T(__taint_src string) {\n /sast-go/cases/completeness/single_app_tracing/function_call/argument_passing/argument_passing_value_009_T/argument_passing_value_009_T.go\n AffectedNodeName: person\n 17: Var Pass: \tperson := Person{Name: __taint_src}\n /sast-go/cases/completeness/single_app_tracing/function_call/argument_passing/argument_passing_value_009_T/argument_passing_value_009_T.go\n AffectedNodeName: UpdateNamePointer\n 19: CALL: \tperson.UpdateNamePointer(\"safe\")\n /sast-go/cases/completeness/single_app_tracing/function_call/argument_passing/argument_passing_value_009_T/argument_passing_value_009_T.go\n AffectedNodeName: person\n 19: ARG PASS: \tperson.UpdateNamePointer(\"safe\")\n /sast-go/cases/completeness/single_app_tracing/function_call/argument_passing/argument_passing_value_009_T/argument_passing_value_009_T.go\n AffectedNodeName: GetNamePointer\n 20: CALL: \t__taint_sink(person.GetNamePointer())\n /sast-go/cases/completeness/single_app_tracing/function_call/argument_passing/argument_passing_value_009_T/argument_passing_value_009_T.go\n AffectedNodeName: person\n 20: ARG PASS: \t__taint_sink(person.GetNamePointer())\n /sast-go/cases/completeness/single_app_tracing/function_call/argument_passing/argument_passing_value_009_T/argument_passing_value_009_T.go\n AffectedNodeName: [return value]\n 28: Return Value: \treturn p.Name\n /sast-go/cases/completeness/single_app_tracing/function_call/argument_passing/argument_passing_value_009_T/argument_passing_value_009_T.go\n AffectedNodeName: GetNamePointer\n 20: CALL RETURN: \t__taint_sink(person.GetNamePointer())\n /sast-go/cases/completeness/single_app_tracing/function_call/argument_passing/argument_passing_value_009_T/argument_passing_value_009_T.go\n AffectedNodeName: __taint_sink\n 20: SINK: \t__taint_sink(person.GetNamePointer())\n==========================================================\n #Total-findings:1\n==========================================================","/benchmarks/sast-go/cases/completeness/single_app_tracing/function_call/argument_passing/argument_passing_value_010_F/argument_passing_value_010_F":"======================== Findings ========================\nNo findings!\n==========================================================","/benchmarks/sast-go/cases/completeness/single_app_tracing/function_call/chained_call/chained_call_001_F/chained_call_001_F":"======================== Findings ========================\nNo findings!\n==========================================================","/benchmarks/sast-go/cases/completeness/single_app_tracing/function_call/chained_call/chained_call_002_T/chained_call_002_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/sast-go/cases/completeness/single_app_tracing/function_call/chained_call/chained_call_002_T/chained_call_002_T.go\nLine 31: __taint_sink(a.name)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/sast-go/cases/completeness/single_app_tracing/function_call/chained_call/chained_call_002_T/chained_call_002_T.go\",\"functionName\":\"main\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /sast-go/cases/completeness/single_app_tracing/function_call/chained_call/chained_call_002_T/chained_call_002_T.go\n AffectedNodeName: __taint_src\n 37: SOURCE: chained_call_002_T(__taint_src)\n /sast-go/cases/completeness/single_app_tracing/function_call/chained_call/chained_call_002_T/chained_call_002_T.go\n AffectedNodeName: chained_call_002_T\n 37: CALL: chained_call_002_T(__taint_src)\n /sast-go/cases/completeness/single_app_tracing/function_call/chained_call/chained_call_002_T/chained_call_002_T.go\n AffectedNodeName: __taint_src\n 12: ARG PASS: func chained_call_002_T(__taint_src string) {\n /sast-go/cases/completeness/single_app_tracing/function_call/chained_call/chained_call_002_T/chained_call_002_T.go\n AffectedNodeName: setName\n 13: CALL: \tnew(A).setName(\"_\").clearName().setName(__taint_src).process()\n /sast-go/cases/completeness/single_app_tracing/function_call/chained_call/chained_call_002_T/chained_call_002_T.go\n AffectedNodeName: name\n 20: ARG PASS: func (a *A) setName(name string) *A {\n /sast-go/cases/completeness/single_app_tracing/function_call/chained_call/chained_call_002_T/chained_call_002_T.go\n AffectedNodeName: [a.name]\n 21: Var Pass: \ta.name = name\n /sast-go/cases/completeness/single_app_tracing/function_call/chained_call/chained_call_002_T/chained_call_002_T.go\n AffectedNodeName: [return value]\n 22: Return Value: \treturn a\n /sast-go/cases/completeness/single_app_tracing/function_call/chained_call/chained_call_002_T/chained_call_002_T.go\n AffectedNodeName: setName\n 13: CALL RETURN: \tnew(A).setName(\"_\").clearName().setName(__taint_src).process()\n /sast-go/cases/completeness/single_app_tracing/function_call/chained_call/chained_call_002_T/chained_call_002_T.go\n 13: ARG PASS: \tnew(A).setName(\"_\").clearName().setName(__taint_src).process()\n /sast-go/cases/completeness/single_app_tracing/function_call/chained_call/chained_call_002_T/chained_call_002_T.go\n AffectedNodeName: __taint_sink\n 31: SINK: \t__taint_sink(a.name)\n==========================================================\n #Total-findings:1\n==========================================================","/benchmarks/sast-go/cases/completeness/single_app_tracing/function_call/chained_call/chained_call_003_F/chained_call_003_F":"======================== Findings ========================\nNo findings!\n==========================================================","/benchmarks/sast-go/cases/completeness/single_app_tracing/function_call/chained_call/chained_call_004_T/chained_call_004_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/sast-go/cases/completeness/single_app_tracing/function_call/chained_call/chained_call_004_T/chained_call_004_T.go\nLine 39: __taint_sink(b.name)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/sast-go/cases/completeness/single_app_tracing/function_call/chained_call/chained_call_004_T/chained_call_004_T.go\",\"functionName\":\"main\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /sast-go/cases/completeness/single_app_tracing/function_call/chained_call/chained_call_004_T/chained_call_004_T.go\n AffectedNodeName: __taint_src\n 46: SOURCE: chained_call_004_T(__taint_src)\n /sast-go/cases/completeness/single_app_tracing/function_call/chained_call/chained_call_004_T/chained_call_004_T.go\n AffectedNodeName: chained_call_004_T\n 46: CALL: chained_call_004_T(__taint_src)\n /sast-go/cases/completeness/single_app_tracing/function_call/chained_call/chained_call_004_T/chained_call_004_T.go\n AffectedNodeName: __taint_src\n 12: ARG PASS: func chained_call_004_T(__taint_src string) {\n /sast-go/cases/completeness/single_app_tracing/function_call/chained_call/chained_call_004_T/chained_call_004_T.go\n AffectedNodeName: SetName\n 13: CALL: \tNewB().SetName(__taint_src).SetOther().Process()\n /sast-go/cases/completeness/single_app_tracing/function_call/chained_call/chained_call_004_T/chained_call_004_T.go\n AffectedNodeName: name\n 24: ARG PASS: func (b *B) SetName(name string) *B {\n /sast-go/cases/completeness/single_app_tracing/function_call/chained_call/chained_call_004_T/chained_call_004_T.go\n AffectedNodeName: [b.name]\n 25: Var Pass: \tb.name = name\n /sast-go/cases/completeness/single_app_tracing/function_call/chained_call/chained_call_004_T/chained_call_004_T.go\n AffectedNodeName: [return value]\n 26: Return Value: \treturn b\n /sast-go/cases/completeness/single_app_tracing/function_call/chained_call/chained_call_004_T/chained_call_004_T.go\n AffectedNodeName: SetName\n 13: CALL RETURN: \tNewB().SetName(__taint_src).SetOther().Process()\n /sast-go/cases/completeness/single_app_tracing/function_call/chained_call/chained_call_004_T/chained_call_004_T.go\n 13: ARG PASS: \tNewB().SetName(__taint_src).SetOther().Process()\n /sast-go/cases/completeness/single_app_tracing/function_call/chained_call/chained_call_004_T/chained_call_004_T.go\n AffectedNodeName: [return value]\n 35: Return Value: \treturn b\n /sast-go/cases/completeness/single_app_tracing/function_call/chained_call/chained_call_004_T/chained_call_004_T.go\n AffectedNodeName: __taint_sink\n 39: SINK: \t__taint_sink(b.name)\n==========================================================\n #Total-findings:1\n==========================================================","/benchmarks/sast-go/cases/completeness/single_app_tracing/function_call/higher_order_function/higher_order_function_001_F/higher_order_function_001_F":"======================== Findings ========================\nNo findings!\n==========================================================","/benchmarks/sast-go/cases/completeness/single_app_tracing/function_call/higher_order_function/higher_order_function_002_T/higher_order_function_002_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/sast-go/cases/completeness/single_app_tracing/function_call/higher_order_function/higher_order_function_002_T/higher_order_function_002_T.go\nLine 20: __taint_sink(f(__taint_src, \"_\")())\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/sast-go/cases/completeness/single_app_tracing/function_call/higher_order_function/higher_order_function_002_T/higher_order_function_002_T.go\",\"functionName\":\"main\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /sast-go/cases/completeness/single_app_tracing/function_call/higher_order_function/higher_order_function_002_T/higher_order_function_002_T.go\n AffectedNodeName: __taint_src\n 27: SOURCE: higher_order_function_002_T(__taint_src)\n /sast-go/cases/completeness/single_app_tracing/function_call/higher_order_function/higher_order_function_002_T/higher_order_function_002_T.go\n AffectedNodeName: higher_order_function_002_T\n 27: CALL: higher_order_function_002_T(__taint_src)\n /sast-go/cases/completeness/single_app_tracing/function_call/higher_order_function/higher_order_function_002_T/higher_order_function_002_T.go\n AffectedNodeName: __taint_src\n 12: ARG PASS: func higher_order_function_002_T(__taint_src string) {\n /sast-go/cases/completeness/single_app_tracing/function_call/higher_order_function/higher_order_function_002_T/higher_order_function_002_T.go\n AffectedNodeName: \n 20: CALL: \t__taint_sink(f(__taint_src, \"_\")())\n /sast-go/cases/completeness/single_app_tracing/function_call/higher_order_function/higher_order_function_002_T/higher_order_function_002_T.go\n AffectedNodeName: a\n 13: ARG PASS: \tf := func(a string, b string) func() string {\n /sast-go/cases/completeness/single_app_tracing/function_call/higher_order_function/higher_order_function_002_T/higher_order_function_002_T.go\n AffectedNodeName: [return value]\n 16: Return Value: \t\t\treturn a + b + c\n /sast-go/cases/completeness/single_app_tracing/function_call/higher_order_function/higher_order_function_002_T/higher_order_function_002_T.go\n AffectedNodeName: \n 20: CALL RETURN: \t__taint_sink(f(__taint_src, \"_\")())\n /sast-go/cases/completeness/single_app_tracing/function_call/higher_order_function/higher_order_function_002_T/higher_order_function_002_T.go\n AffectedNodeName: __taint_sink\n 20: SINK: \t__taint_sink(f(__taint_src, \"_\")())\n==========================================================\n #Total-findings:1\n==========================================================","/benchmarks/sast-go/cases/completeness/single_app_tracing/function_call/higher_order_function/higher_order_function_003_F/higher_order_function_003_F":"======================== Findings ========================\nNo findings!\n==========================================================","/benchmarks/sast-go/cases/completeness/single_app_tracing/function_call/higher_order_function/higher_order_function_004_T/higher_order_function_004_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/sast-go/cases/completeness/single_app_tracing/function_call/higher_order_function/higher_order_function_004_T/higher_order_function_004_T.go\nLine 24: __taint_sink(f(g, __taint_src, \"_\"))\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/sast-go/cases/completeness/single_app_tracing/function_call/higher_order_function/higher_order_function_004_T/higher_order_function_004_T.go\",\"functionName\":\"main\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /sast-go/cases/completeness/single_app_tracing/function_call/higher_order_function/higher_order_function_004_T/higher_order_function_004_T.go\n AffectedNodeName: __taint_src\n 31: SOURCE: higher_order_function_004_T(__taint_src)\n /sast-go/cases/completeness/single_app_tracing/function_call/higher_order_function/higher_order_function_004_T/higher_order_function_004_T.go\n AffectedNodeName: higher_order_function_004_T\n 31: CALL: higher_order_function_004_T(__taint_src)\n /sast-go/cases/completeness/single_app_tracing/function_call/higher_order_function/higher_order_function_004_T/higher_order_function_004_T.go\n AffectedNodeName: __taint_src\n 12: ARG PASS: func higher_order_function_004_T(__taint_src string) {\n /sast-go/cases/completeness/single_app_tracing/function_call/higher_order_function/higher_order_function_004_T/higher_order_function_004_T.go\n AffectedNodeName: \n 24: CALL: \t__taint_sink(f(g, __taint_src, \"_\"))\n /sast-go/cases/completeness/single_app_tracing/function_call/higher_order_function/higher_order_function_004_T/higher_order_function_004_T.go\n AffectedNodeName: a\n 13: ARG PASS: \tf := func(g func(string, string) func() string, a string, b string) string {\n /sast-go/cases/completeness/single_app_tracing/function_call/higher_order_function/higher_order_function_004_T/higher_order_function_004_T.go\n AffectedNodeName: \n 14: CALL: \t\treturn g(a, b)()\n /sast-go/cases/completeness/single_app_tracing/function_call/higher_order_function/higher_order_function_004_T/higher_order_function_004_T.go\n AffectedNodeName: a\n 17: ARG PASS: \tg := func(a string, b string) func() string {\n /sast-go/cases/completeness/single_app_tracing/function_call/higher_order_function/higher_order_function_004_T/higher_order_function_004_T.go\n AffectedNodeName: [return value]\n 20: Return Value: \t\t\treturn a + b + c\n /sast-go/cases/completeness/single_app_tracing/function_call/higher_order_function/higher_order_function_004_T/higher_order_function_004_T.go\n AffectedNodeName: \n 14: CALL RETURN: \t\treturn g(a, b)()\n /sast-go/cases/completeness/single_app_tracing/function_call/higher_order_function/higher_order_function_004_T/higher_order_function_004_T.go\n AffectedNodeName: [return value]\n 14: Return Value: \t\treturn g(a, b)()\n /sast-go/cases/completeness/single_app_tracing/function_call/higher_order_function/higher_order_function_004_T/higher_order_function_004_T.go\n AffectedNodeName: \n 24: CALL RETURN: \t__taint_sink(f(g, __taint_src, \"_\"))\n /sast-go/cases/completeness/single_app_tracing/function_call/higher_order_function/higher_order_function_004_T/higher_order_function_004_T.go\n AffectedNodeName: __taint_sink\n 24: SINK: \t__taint_sink(f(g, __taint_src, \"_\"))\n==========================================================\n #Total-findings:1\n==========================================================","/benchmarks/sast-go/cases/completeness/single_app_tracing/function_call/higher_order_function/higher_order_function_005_F/higher_order_function_005_F":"======================== Findings ========================\nNo findings!\n==========================================================","/benchmarks/sast-go/cases/completeness/single_app_tracing/function_call/higher_order_function/higher_order_function_006_T/higher_order_function_006_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/sast-go/cases/completeness/single_app_tracing/function_call/higher_order_function/higher_order_function_006_T/higher_order_function_006_T.go\nLine 13: __taint_sink(f(g, u, __taint_src, \"_\")())\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/sast-go/cases/completeness/single_app_tracing/function_call/higher_order_function/higher_order_function_006_T/higher_order_function_006_T.go\",\"functionName\":\"main\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /sast-go/cases/completeness/single_app_tracing/function_call/higher_order_function/higher_order_function_006_T/higher_order_function_006_T.go\n AffectedNodeName: __taint_src\n 35: SOURCE: higher_order_function_006_T(__taint_src)\n /sast-go/cases/completeness/single_app_tracing/function_call/higher_order_function/higher_order_function_006_T/higher_order_function_006_T.go\n AffectedNodeName: higher_order_function_006_T\n 35: CALL: higher_order_function_006_T(__taint_src)\n /sast-go/cases/completeness/single_app_tracing/function_call/higher_order_function/higher_order_function_006_T/higher_order_function_006_T.go\n AffectedNodeName: __taint_src\n 12: ARG PASS: func higher_order_function_006_T(__taint_src interface{}) {\n /sast-go/cases/completeness/single_app_tracing/function_call/higher_order_function/higher_order_function_006_T/higher_order_function_006_T.go\n AffectedNodeName: f\n 13: CALL: \t__taint_sink(f(g, u, __taint_src, \"_\")())\n /sast-go/cases/completeness/single_app_tracing/function_call/higher_order_function/higher_order_function_006_T/higher_order_function_006_T.go\n AffectedNodeName: a\n 16: ARG PASS: func f(g func(func(string, string, string) func() string, string, string) func() string, u func(string, string, string) func() string, a interface{}, b string) func() string {\n /sast-go/cases/completeness/single_app_tracing/function_call/higher_order_function/higher_order_function_006_T/higher_order_function_006_T.go\n AffectedNodeName: g\n 17: CALL: \treturn g(u, a.(string), b)\n /sast-go/cases/completeness/single_app_tracing/function_call/higher_order_function/higher_order_function_006_T/higher_order_function_006_T.go\n AffectedNodeName: a\n 20: ARG PASS: func g(u func(string, string, string) func() string, a string, b string) func() string {\n /sast-go/cases/completeness/single_app_tracing/function_call/higher_order_function/higher_order_function_006_T/higher_order_function_006_T.go\n AffectedNodeName: u\n 22: CALL: \treturn u(a, b, c)\n /sast-go/cases/completeness/single_app_tracing/function_call/higher_order_function/higher_order_function_006_T/higher_order_function_006_T.go\n AffectedNodeName: a\n 25: ARG PASS: func u(a string, b string, c string) func() string {\n /sast-go/cases/completeness/single_app_tracing/function_call/higher_order_function/higher_order_function_006_T/higher_order_function_006_T.go\n AffectedNodeName: [return value]\n 27: Return Value: \t\treturn a + b + c\n /sast-go/cases/completeness/single_app_tracing/function_call/higher_order_function/higher_order_function_006_T/higher_order_function_006_T.go\n AffectedNodeName: \n 13: CALL RETURN: \t__taint_sink(f(g, u, __taint_src, \"_\")())\n /sast-go/cases/completeness/single_app_tracing/function_call/higher_order_function/higher_order_function_006_T/higher_order_function_006_T.go\n AffectedNodeName: __taint_sink\n 13: SINK: \t__taint_sink(f(g, u, __taint_src, \"_\")())\n==========================================================\n #Total-findings:1\n==========================================================","/benchmarks/sast-go/cases/completeness/single_app_tracing/function_call/higher_order_function/higher_order_function_007_F/higher_order_function_007_F":"======================== Findings ========================\nNo findings!\n==========================================================","/benchmarks/sast-go/cases/completeness/single_app_tracing/function_call/higher_order_function/higher_order_function_008_T/higher_order_function_008_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/sast-go/cases/completeness/single_app_tracing/function_call/higher_order_function/higher_order_function_008_T/higher_order_function_008_T.go\nLine 16: __taint_sink(result)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/sast-go/cases/completeness/single_app_tracing/function_call/higher_order_function/higher_order_function_008_T/higher_order_function_008_T.go\",\"functionName\":\"main\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /sast-go/cases/completeness/single_app_tracing/function_call/higher_order_function/higher_order_function_008_T/higher_order_function_008_T.go\n AffectedNodeName: __taint_src\n 27: SOURCE: higher_order_function_008_T(__taint_src)\n /sast-go/cases/completeness/single_app_tracing/function_call/higher_order_function/higher_order_function_008_T/higher_order_function_008_T.go\n AffectedNodeName: higher_order_function_008_T\n 27: CALL: higher_order_function_008_T(__taint_src)\n /sast-go/cases/completeness/single_app_tracing/function_call/higher_order_function/higher_order_function_008_T/higher_order_function_008_T.go\n AffectedNodeName: __taint_src\n 12: ARG PASS: func higher_order_function_008_T(__taint_src string) {\n /sast-go/cases/completeness/single_app_tracing/function_call/higher_order_function/higher_order_function_008_T/higher_order_function_008_T.go\n AffectedNodeName: higher_order_function_008_Function\n 13: CALL: \tresult := higher_order_function_008_Function(func(a string, b string) string {\n 14: CALL: \t\treturn a + b\n 15: CALL: \t}, __taint_src)\n /sast-go/cases/completeness/single_app_tracing/function_call/higher_order_function/higher_order_function_008_T/higher_order_function_008_T.go\n AffectedNodeName: src\n 19: ARG PASS: func higher_order_function_008_Function(callback func(a string, b string) string, src string) string {\n /sast-go/cases/completeness/single_app_tracing/function_call/higher_order_function/higher_order_function_008_T/higher_order_function_008_T.go\n AffectedNodeName: \n 20: CALL: \treturn callback(src, \"_\")\n /sast-go/cases/completeness/single_app_tracing/function_call/higher_order_function/higher_order_function_008_T/higher_order_function_008_T.go\n AffectedNodeName: a\n 13: ARG PASS: \tresult := higher_order_function_008_Function(func(a string, b string) string {\n /sast-go/cases/completeness/single_app_tracing/function_call/higher_order_function/higher_order_function_008_T/higher_order_function_008_T.go\n AffectedNodeName: [return value]\n 14: Return Value: \t\treturn a + b\n /sast-go/cases/completeness/single_app_tracing/function_call/higher_order_function/higher_order_function_008_T/higher_order_function_008_T.go\n AffectedNodeName: \n 20: CALL RETURN: \treturn callback(src, \"_\")\n /sast-go/cases/completeness/single_app_tracing/function_call/higher_order_function/higher_order_function_008_T/higher_order_function_008_T.go\n AffectedNodeName: [return value]\n 20: Return Value: \treturn callback(src, \"_\")\n /sast-go/cases/completeness/single_app_tracing/function_call/higher_order_function/higher_order_function_008_T/higher_order_function_008_T.go\n AffectedNodeName: higher_order_function_008_Function\n 13: CALL RETURN: \tresult := higher_order_function_008_Function(func(a string, b string) string {\n 14: CALL RETURN: \t\treturn a + b\n 15: CALL RETURN: \t}, __taint_src)\n /sast-go/cases/completeness/single_app_tracing/function_call/higher_order_function/higher_order_function_008_T/higher_order_function_008_T.go\n AffectedNodeName: result\n 13: Var Pass: \tresult := higher_order_function_008_Function(func(a string, b string) string {\n 14: Var Pass: \t\treturn a + b\n 15: Var Pass: \t}, __taint_src)\n /sast-go/cases/completeness/single_app_tracing/function_call/higher_order_function/higher_order_function_008_T/higher_order_function_008_T.go\n AffectedNodeName: __taint_sink\n 16: SINK: \t__taint_sink(result)\n==========================================================\n #Total-findings:1\n==========================================================","/benchmarks/sast-go/cases/completeness/single_app_tracing/function_call/library_function/arg_arg_001_T/arg_arg_001_T":"======================== Findings ========================\nNo findings!\n==========================================================","/benchmarks/sast-go/cases/completeness/single_app_tracing/function_call/library_function/arg_arg_002_F/arg_arg_002_F":"======================== Findings ========================\nNo findings!\n==========================================================","/benchmarks/sast-go/cases/completeness/single_app_tracing/function_call/library_function/arg_return_001_T/arg_return_001_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/sast-go/cases/completeness/single_app_tracing/function_call/library_function/arg_return_001_T/arg_return_001_T.go\nLine 16: __taint_sink(result)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/sast-go/cases/completeness/single_app_tracing/function_call/library_function/arg_return_001_T/arg_return_001_T.go\",\"functionName\":\"main\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /sast-go/cases/completeness/single_app_tracing/function_call/library_function/arg_return_001_T/arg_return_001_T.go\n AffectedNodeName: __taint_src\n 28: SOURCE: arg_return_001_T(__taint_src)\n /sast-go/cases/completeness/single_app_tracing/function_call/library_function/arg_return_001_T/arg_return_001_T.go\n AffectedNodeName: arg_return_001_T\n 28: CALL: arg_return_001_T(__taint_src)\n /sast-go/cases/completeness/single_app_tracing/function_call/library_function/arg_return_001_T/arg_return_001_T.go\n AffectedNodeName: __taint_src\n 12: ARG PASS: func arg_return_001_T(__taint_src string) {\n /sast-go/cases/completeness/single_app_tracing/function_call/library_function/arg_return_001_T/arg_return_001_T.go\n AffectedNodeName: taintedData\n 13: Var Pass: \ttaintedData := __taint_src\n /sast-go/cases/completeness/single_app_tracing/function_call/library_function/arg_return_001_T/arg_return_001_T.go\n AffectedNodeName: appendTaint\n 15: CALL: \tresult := appendTaint(sList, taintedData)\n /sast-go/cases/completeness/single_app_tracing/function_call/library_function/arg_return_001_T/arg_return_001_T.go\n AffectedNodeName: newTaint\n 19: ARG PASS: func appendTaint(taintSrc []string, newTaint string) []string {\n /sast-go/cases/completeness/single_app_tracing/function_call/library_function/arg_return_001_T/arg_return_001_T.go\n AffectedNodeName: b\n 20: Var Pass: \tb := append(taintSrc, newTaint) // 从参数传播到返回值\n /sast-go/cases/completeness/single_app_tracing/function_call/library_function/arg_return_001_T/arg_return_001_T.go\n AffectedNodeName: [return value]\n 21: Return Value: \treturn b\n /sast-go/cases/completeness/single_app_tracing/function_call/library_function/arg_return_001_T/arg_return_001_T.go\n AffectedNodeName: appendTaint\n 15: CALL RETURN: \tresult := appendTaint(sList, taintedData)\n /sast-go/cases/completeness/single_app_tracing/function_call/library_function/arg_return_001_T/arg_return_001_T.go\n AffectedNodeName: result\n 15: Var Pass: \tresult := appendTaint(sList, taintedData)\n /sast-go/cases/completeness/single_app_tracing/function_call/library_function/arg_return_001_T/arg_return_001_T.go\n AffectedNodeName: __taint_sink\n 16: SINK: \t__taint_sink(result)\n==========================================================\n #Total-findings:1\n==========================================================","/benchmarks/sast-go/cases/completeness/single_app_tracing/function_call/library_function/arg_return_002_F/arg_return_002_F":"======================== Findings ========================\nNo findings!\n==========================================================","/benchmarks/sast-go/cases/completeness/single_app_tracing/function_call/library_function/arg_return_003_T/arg_return_003_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/sast-go/cases/completeness/single_app_tracing/function_call/library_function/arg_return_003_T/arg_return_003_T.go\nLine 17: __taint_sink(result)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/sast-go/cases/completeness/single_app_tracing/function_call/library_function/arg_return_003_T/arg_return_003_T.go\",\"functionName\":\"main\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /sast-go/cases/completeness/single_app_tracing/function_call/library_function/arg_return_003_T/arg_return_003_T.go\n AffectedNodeName: __taint_src\n 29: SOURCE: arg_return_003_T(__taint_src)\n /sast-go/cases/completeness/single_app_tracing/function_call/library_function/arg_return_003_T/arg_return_003_T.go\n AffectedNodeName: arg_return_003_T\n 29: CALL: arg_return_003_T(__taint_src)\n /sast-go/cases/completeness/single_app_tracing/function_call/library_function/arg_return_003_T/arg_return_003_T.go\n AffectedNodeName: __taint_src\n 14: ARG PASS: func arg_return_003_T(__taint_src int) {\n /sast-go/cases/completeness/single_app_tracing/function_call/library_function/arg_return_003_T/arg_return_003_T.go\n AffectedNodeName: taintedData\n 15: Var Pass: \ttaintedData := __taint_src\n /sast-go/cases/completeness/single_app_tracing/function_call/library_function/arg_return_003_T/arg_return_003_T.go\n AffectedNodeName: itoaTaint\n 16: CALL: \tresult := itoaTaint(taintedData)\n /sast-go/cases/completeness/single_app_tracing/function_call/library_function/arg_return_003_T/arg_return_003_T.go\n AffectedNodeName: taintSrc\n 23: ARG PASS: func itoaTaint(taintSrc int) string {\n /sast-go/cases/completeness/single_app_tracing/function_call/library_function/arg_return_003_T/arg_return_003_T.go\n AffectedNodeName: b\n 24: Var Pass: \tb := strconv.Itoa(taintSrc)\n /sast-go/cases/completeness/single_app_tracing/function_call/library_function/arg_return_003_T/arg_return_003_T.go\n AffectedNodeName: [return value]\n 25: Return Value: \treturn b\n /sast-go/cases/completeness/single_app_tracing/function_call/library_function/arg_return_003_T/arg_return_003_T.go\n AffectedNodeName: itoaTaint\n 16: CALL RETURN: \tresult := itoaTaint(taintedData)\n /sast-go/cases/completeness/single_app_tracing/function_call/library_function/arg_return_003_T/arg_return_003_T.go\n AffectedNodeName: result\n 16: Var Pass: \tresult := itoaTaint(taintedData)\n /sast-go/cases/completeness/single_app_tracing/function_call/library_function/arg_return_003_T/arg_return_003_T.go\n AffectedNodeName: __taint_sink\n 17: SINK: \t__taint_sink(result)\n==========================================================\n #Total-findings:1\n==========================================================","/benchmarks/sast-go/cases/completeness/single_app_tracing/function_call/library_function/arg_return_004_F/arg_return_004_F":"======================== Findings ========================\nNo findings!\n==========================================================","/benchmarks/sast-go/cases/completeness/single_app_tracing/function_call/library_function/this_return_001_T/this_return_001_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/sast-go/cases/completeness/single_app_tracing/function_call/library_function/this_return_001_T/this_return_001_T.go\nLine 15: __taint_sink(result)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/sast-go/cases/completeness/single_app_tracing/function_call/library_function/this_return_001_T/this_return_001_T.go\",\"functionName\":\"main\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /sast-go/cases/completeness/single_app_tracing/function_call/library_function/this_return_001_T/this_return_001_T.go\n AffectedNodeName: __taint_src\n 27: SOURCE: this_return_001_T(__taint_src)\n /sast-go/cases/completeness/single_app_tracing/function_call/library_function/this_return_001_T/this_return_001_T.go\n AffectedNodeName: this_return_001_T\n 27: CALL: this_return_001_T(__taint_src)\n /sast-go/cases/completeness/single_app_tracing/function_call/library_function/this_return_001_T/this_return_001_T.go\n AffectedNodeName: __taint_src\n 12: ARG PASS: func this_return_001_T(__taint_src string) {\n /sast-go/cases/completeness/single_app_tracing/function_call/library_function/this_return_001_T/this_return_001_T.go\n AffectedNodeName: taintedData\n 13: Var Pass: \ttaintedData := __taint_src\n /sast-go/cases/completeness/single_app_tracing/function_call/library_function/this_return_001_T/this_return_001_T.go\n AffectedNodeName: taintToString\n 14: CALL: \tresult := taintToString(taintedData)\n /sast-go/cases/completeness/single_app_tracing/function_call/library_function/this_return_001_T/this_return_001_T.go\n AffectedNodeName: s\n 18: ARG PASS: func taintToString(s interface{}) string {\n /sast-go/cases/completeness/single_app_tracing/function_call/library_function/this_return_001_T/this_return_001_T.go\n AffectedNodeName: b\n 19: Var Pass: \tb := s.(string)\n /sast-go/cases/completeness/single_app_tracing/function_call/library_function/this_return_001_T/this_return_001_T.go\n AffectedNodeName: [return value]\n 20: Return Value: \treturn b\n /sast-go/cases/completeness/single_app_tracing/function_call/library_function/this_return_001_T/this_return_001_T.go\n AffectedNodeName: taintToString\n 14: CALL RETURN: \tresult := taintToString(taintedData)\n /sast-go/cases/completeness/single_app_tracing/function_call/library_function/this_return_001_T/this_return_001_T.go\n AffectedNodeName: result\n 14: Var Pass: \tresult := taintToString(taintedData)\n /sast-go/cases/completeness/single_app_tracing/function_call/library_function/this_return_001_T/this_return_001_T.go\n AffectedNodeName: __taint_sink\n 15: SINK: \t__taint_sink(result)\n==========================================================\n #Total-findings:1\n==========================================================","/benchmarks/sast-go/cases/completeness/single_app_tracing/function_call/library_function/this_return_002_F/this_return_002_F":"======================== Findings ========================\nNo findings!\n==========================================================","/benchmarks/sast-go/cases/completeness/single_app_tracing/function_call/override/polymorphism_override_001_T/polymorphism_override_001_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/sast-go/cases/completeness/single_app_tracing/function_call/override/polymorphism_override_001_T/polymorphism_override_001_T.go\nLine 14: __taint_sink(sub.call(__taint_src))\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/sast-go/cases/completeness/single_app_tracing/function_call/override/polymorphism_override_001_T/polymorphism_override_001_T.go\",\"functionName\":\"main\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /sast-go/cases/completeness/single_app_tracing/function_call/override/polymorphism_override_001_T/polymorphism_override_001_T.go\n AffectedNodeName: __taint_src\n 37: SOURCE: polymorphism_override_001_T(__taint_src)\n /sast-go/cases/completeness/single_app_tracing/function_call/override/polymorphism_override_001_T/polymorphism_override_001_T.go\n AffectedNodeName: polymorphism_override_001_T\n 37: CALL: polymorphism_override_001_T(__taint_src)\n /sast-go/cases/completeness/single_app_tracing/function_call/override/polymorphism_override_001_T/polymorphism_override_001_T.go\n AffectedNodeName: __taint_src\n 11: ARG PASS: func polymorphism_override_001_T(__taint_src interface{}) {\n /sast-go/cases/completeness/single_app_tracing/function_call/override/polymorphism_override_001_T/polymorphism_override_001_T.go\n AffectedNodeName: call\n 14: CALL: \t__taint_sink(sub.call(__taint_src))\n /sast-go/cases/completeness/single_app_tracing/function_call/override/polymorphism_override_001_T/polymorphism_override_001_T.go\n AffectedNodeName: src\n 23: ARG PASS: func (s Sub1) call(src interface{}) interface{} {\n /sast-go/cases/completeness/single_app_tracing/function_call/override/polymorphism_override_001_T/polymorphism_override_001_T.go\n AffectedNodeName: [return value]\n 24: Return Value: \treturn src\n /sast-go/cases/completeness/single_app_tracing/function_call/override/polymorphism_override_001_T/polymorphism_override_001_T.go\n AffectedNodeName: call\n 14: CALL RETURN: \t__taint_sink(sub.call(__taint_src))\n /sast-go/cases/completeness/single_app_tracing/function_call/override/polymorphism_override_001_T/polymorphism_override_001_T.go\n AffectedNodeName: __taint_sink\n 14: SINK: \t__taint_sink(sub.call(__taint_src))\n==========================================================\n #Total-findings:1\n==========================================================","/benchmarks/sast-go/cases/completeness/single_app_tracing/function_call/override/polymorphism_override_002_F/polymorphism_override_002_F":"======================== Findings ========================\nNo findings!\n==========================================================","/benchmarks/sast-go/cases/completeness/single_app_tracing/function_call/override/polymorphism_override_003_T/polymorphism_override_003_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/sast-go/cases/completeness/single_app_tracing/function_call/override/polymorphism_override_003_T/polymorphism_override_003_T.go\nLine 15: __taint_sink(student.Run())\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/sast-go/cases/completeness/single_app_tracing/function_call/override/polymorphism_override_003_T/polymorphism_override_003_T.go\",\"functionName\":\"main\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /sast-go/cases/completeness/single_app_tracing/function_call/override/polymorphism_override_003_T/polymorphism_override_003_T.go\n AffectedNodeName: __taint_src\n 46: SOURCE: polymorphism_override_003_T(__taint_src)\n /sast-go/cases/completeness/single_app_tracing/function_call/override/polymorphism_override_003_T/polymorphism_override_003_T.go\n AffectedNodeName: polymorphism_override_003_T\n 46: CALL: polymorphism_override_003_T(__taint_src)\n /sast-go/cases/completeness/single_app_tracing/function_call/override/polymorphism_override_003_T/polymorphism_override_003_T.go\n AffectedNodeName: __taint_src\n 11: ARG PASS: func polymorphism_override_003_T(__taint_src string) {\n /sast-go/cases/completeness/single_app_tracing/function_call/override/polymorphism_override_003_T/polymorphism_override_003_T.go\n AffectedNodeName: student\n 12: Var Pass: \tvar student Person = &Student{Name: __taint_src, Age: 20, GPA: 3.8}\n /sast-go/cases/completeness/single_app_tracing/function_call/override/polymorphism_override_003_T/polymorphism_override_003_T.go\n AffectedNodeName: Run\n 15: CALL: \t__taint_sink(student.Run())\n /sast-go/cases/completeness/single_app_tracing/function_call/override/polymorphism_override_003_T/polymorphism_override_003_T.go\n AffectedNodeName: student\n 15: ARG PASS: \t__taint_sink(student.Run())\n /sast-go/cases/completeness/single_app_tracing/function_call/override/polymorphism_override_003_T/polymorphism_override_003_T.go\n AffectedNodeName: [return value]\n 29: Return Value: \treturn s.Name\n /sast-go/cases/completeness/single_app_tracing/function_call/override/polymorphism_override_003_T/polymorphism_override_003_T.go\n AffectedNodeName: Run\n 15: CALL RETURN: \t__taint_sink(student.Run())\n /sast-go/cases/completeness/single_app_tracing/function_call/override/polymorphism_override_003_T/polymorphism_override_003_T.go\n AffectedNodeName: __taint_sink\n 15: SINK: \t__taint_sink(student.Run())\n==========================================================\n #Total-findings:1\n==========================================================","/benchmarks/sast-go/cases/completeness/single_app_tracing/function_call/override/polymorphism_override_004_F/polymorphism_override_004_F":"======================== Findings ========================\nNo findings!\n==========================================================","/benchmarks/sast-go/cases/completeness/single_app_tracing/function_call/return_value_passing/multiple_return_005_F/multiple_return_005_F":"======================== Findings ========================\nNo findings!\n==========================================================","/benchmarks/sast-go/cases/completeness/single_app_tracing/function_call/return_value_passing/multiple_return_006_T/multiple_return_006_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/sast-go/cases/completeness/single_app_tracing/function_call/return_value_passing/multiple_return_006_T/multiple_return_006_T.go\nLine 17: __taint_sink(ret1)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/sast-go/cases/completeness/single_app_tracing/function_call/return_value_passing/multiple_return_006_T/multiple_return_006_T.go\",\"functionName\":\"main\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /sast-go/cases/completeness/single_app_tracing/function_call/return_value_passing/multiple_return_006_T/multiple_return_006_T.go\n AffectedNodeName: __taint_src\n 27: SOURCE: multiple_return_006_T(__taint_src)\n /sast-go/cases/completeness/single_app_tracing/function_call/return_value_passing/multiple_return_006_T/multiple_return_006_T.go\n AffectedNodeName: multiple_return_006_T\n 27: CALL: multiple_return_006_T(__taint_src)\n /sast-go/cases/completeness/single_app_tracing/function_call/return_value_passing/multiple_return_006_T/multiple_return_006_T.go\n AffectedNodeName: __taint_src\n 12: ARG PASS: func multiple_return_006_T(__taint_src interface{}) {\n /sast-go/cases/completeness/single_app_tracing/function_call/return_value_passing/multiple_return_006_T/multiple_return_006_T.go\n AffectedNodeName: processData\n 15: CALL: \tret1, ret2 := processData(__taint_src, a)\n /sast-go/cases/completeness/single_app_tracing/function_call/return_value_passing/multiple_return_006_T/multiple_return_006_T.go\n AffectedNodeName: s\n 20: ARG PASS: func processData(s interface{}, i interface{}) (interface{}, interface{}) {\n /sast-go/cases/completeness/single_app_tracing/function_call/return_value_passing/multiple_return_006_T/multiple_return_006_T.go\n AffectedNodeName: [return value]\n 21: Return Value: \treturn s, i\n /sast-go/cases/completeness/single_app_tracing/function_call/return_value_passing/multiple_return_006_T/multiple_return_006_T.go\n AffectedNodeName: processData\n 15: CALL RETURN: \tret1, ret2 := processData(__taint_src, a)\n /sast-go/cases/completeness/single_app_tracing/function_call/return_value_passing/multiple_return_006_T/multiple_return_006_T.go\n 15: Var Pass: \tret1, ret2 := processData(__taint_src, a)\n /sast-go/cases/completeness/single_app_tracing/function_call/return_value_passing/multiple_return_006_T/multiple_return_006_T.go\n AffectedNodeName: __taint_sink\n 17: SINK: \t__taint_sink(ret1)\n==========================================================\n #Total-findings:1\n==========================================================","/benchmarks/sast-go/cases/completeness/single_app_tracing/function_call/return_value_passing/named_return_003_F/named_return_003_F":"======================== Findings ========================\nNo findings!\n==========================================================","/benchmarks/sast-go/cases/completeness/single_app_tracing/function_call/return_value_passing/named_return_004_T/named_return_004_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/sast-go/cases/completeness/single_app_tracing/function_call/return_value_passing/named_return_004_T/named_return_004_T.go\nLine 16: __taint_sink(ret)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/sast-go/cases/completeness/single_app_tracing/function_call/return_value_passing/named_return_004_T/named_return_004_T.go\",\"functionName\":\"main\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /sast-go/cases/completeness/single_app_tracing/function_call/return_value_passing/named_return_004_T/named_return_004_T.go\n AffectedNodeName: __taint_src\n 27: SOURCE: named_return_004_T(__taint_src)\n /sast-go/cases/completeness/single_app_tracing/function_call/return_value_passing/named_return_004_T/named_return_004_T.go\n AffectedNodeName: named_return_004_T\n 27: CALL: named_return_004_T(__taint_src)\n /sast-go/cases/completeness/single_app_tracing/function_call/return_value_passing/named_return_004_T/named_return_004_T.go\n AffectedNodeName: __taint_src\n 12: ARG PASS: func named_return_004_T(__taint_src interface{}) {\n /sast-go/cases/completeness/single_app_tracing/function_call/return_value_passing/named_return_004_T/named_return_004_T.go\n AffectedNodeName: processData\n 15: CALL: \tret := processData(__taint_src, a)\n /sast-go/cases/completeness/single_app_tracing/function_call/return_value_passing/named_return_004_T/named_return_004_T.go\n AffectedNodeName: s\n 19: ARG PASS: func processData(s interface{}, i interface{}) (ret interface{}) {\n /sast-go/cases/completeness/single_app_tracing/function_call/return_value_passing/named_return_004_T/named_return_004_T.go\n AffectedNodeName: ret\n 20: Var Pass: \tret = s\n /sast-go/cases/completeness/single_app_tracing/function_call/return_value_passing/named_return_004_T/named_return_004_T.go\n AffectedNodeName: [return value]\n 21: Return Value: \treturn\n /sast-go/cases/completeness/single_app_tracing/function_call/return_value_passing/named_return_004_T/named_return_004_T.go\n AffectedNodeName: processData\n 15: CALL RETURN: \tret := processData(__taint_src, a)\n /sast-go/cases/completeness/single_app_tracing/function_call/return_value_passing/named_return_004_T/named_return_004_T.go\n AffectedNodeName: ret\n 15: Var Pass: \tret := processData(__taint_src, a)\n /sast-go/cases/completeness/single_app_tracing/function_call/return_value_passing/named_return_004_T/named_return_004_T.go\n AffectedNodeName: __taint_sink\n 16: SINK: \t__taint_sink(ret)\n==========================================================\n #Total-findings:1\n==========================================================","/benchmarks/sast-go/cases/completeness/single_app_tracing/function_call/return_value_passing/return_value_passing_003_F/return_value_passing_003_F":"======================== Findings ========================\nNo findings!\n==========================================================","/benchmarks/sast-go/cases/completeness/single_app_tracing/function_call/return_value_passing/return_value_passing_004_T/return_value_passing_004_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/sast-go/cases/completeness/single_app_tracing/function_call/return_value_passing/return_value_passing_004_T/return_value_passing_004_T.go\nLine 14: __taint_sink(data)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/sast-go/cases/completeness/single_app_tracing/function_call/return_value_passing/return_value_passing_004_T/return_value_passing_004_T.go\",\"functionName\":\"main\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /sast-go/cases/completeness/single_app_tracing/function_call/return_value_passing/return_value_passing_004_T/return_value_passing_004_T.go\n AffectedNodeName: __taint_src\n 25: SOURCE: return_value_passing_004_T(__taint_src)\n /sast-go/cases/completeness/single_app_tracing/function_call/return_value_passing/return_value_passing_004_T/return_value_passing_004_T.go\n AffectedNodeName: return_value_passing_004_T\n 25: CALL: return_value_passing_004_T(__taint_src)\n /sast-go/cases/completeness/single_app_tracing/function_call/return_value_passing/return_value_passing_004_T/return_value_passing_004_T.go\n AffectedNodeName: __taint_src\n 12: ARG PASS: func return_value_passing_004_T(__taint_src string) {\n /sast-go/cases/completeness/single_app_tracing/function_call/return_value_passing/return_value_passing_004_T/return_value_passing_004_T.go\n AffectedNodeName: process\n 13: CALL: \tdata := process(__taint_src)\n /sast-go/cases/completeness/single_app_tracing/function_call/return_value_passing/return_value_passing_004_T/return_value_passing_004_T.go\n AffectedNodeName: __taint_src\n 20: ARG PASS: func process(__taint_src string) interface{} {\n /sast-go/cases/completeness/single_app_tracing/function_call/return_value_passing/return_value_passing_004_T/return_value_passing_004_T.go\n AffectedNodeName: [return value]\n 21: Return Value: \treturn __taint_src\n /sast-go/cases/completeness/single_app_tracing/function_call/return_value_passing/return_value_passing_004_T/return_value_passing_004_T.go\n AffectedNodeName: process\n 13: CALL RETURN: \tdata := process(__taint_src)\n /sast-go/cases/completeness/single_app_tracing/function_call/return_value_passing/return_value_passing_004_T/return_value_passing_004_T.go\n AffectedNodeName: data\n 13: Var Pass: \tdata := process(__taint_src)\n /sast-go/cases/completeness/single_app_tracing/function_call/return_value_passing/return_value_passing_004_T/return_value_passing_004_T.go\n AffectedNodeName: __taint_sink\n 14: SINK: \t__taint_sink(data)\n==========================================================\n #Total-findings:1\n==========================================================","/benchmarks/sast-go/cases/completeness/single_app_tracing/interface_class/interface_implementation/interface_class_001_c_T/interface_class_001_c_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/sast-go/cases/completeness/single_app_tracing/interface_class/interface_implementation/interface_class_001_c_T/interface_class_001_c_T.go\nLine 20: __taint_sink(result)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/sast-go/cases/completeness/single_app_tracing/interface_class/interface_implementation/interface_class_001_c_T/interface_class_001_c_T.go\",\"functionName\":\"main\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /sast-go/cases/completeness/single_app_tracing/interface_class/interface_implementation/interface_class_001_c_T/interface_class_001_c_T.go\n AffectedNodeName: __taint_src\n 58: SOURCE: interface_class_001_c_T(__taint_src)\n /sast-go/cases/completeness/single_app_tracing/interface_class/interface_implementation/interface_class_001_c_T/interface_class_001_c_T.go\n AffectedNodeName: interface_class_001_c_T\n 58: CALL: interface_class_001_c_T(__taint_src)\n /sast-go/cases/completeness/single_app_tracing/interface_class/interface_implementation/interface_class_001_c_T/interface_class_001_c_T.go\n AffectedNodeName: __taint_src\n 11: ARG PASS: func interface_class_001_c_T(__taint_src string) {\n /sast-go/cases/completeness/single_app_tracing/interface_class/interface_implementation/interface_class_001_c_T/interface_class_001_c_T.go\n AffectedNodeName: GetTest\n 19: CALL: \tresult, _ := testAPI.GetTest(__taint_src)\n /sast-go/cases/completeness/single_app_tracing/interface_class/interface_implementation/interface_class_001_c_T/interface_class_001_c_T.go\n AffectedNodeName: taint_src\n 44: ARG PASS: func (e *IctestAPI) GetTest(taint_src string) (interface{}, error) {\n /sast-go/cases/completeness/single_app_tracing/interface_class/interface_implementation/interface_class_001_c_T/interface_class_001_c_T.go\n AffectedNodeName: test\n 45: CALL: \treturn e._test_svc.test(taint_src)\n /sast-go/cases/completeness/single_app_tracing/interface_class/interface_implementation/interface_class_001_c_T/interface_class_001_c_T.go\n AffectedNodeName: taint_src\n 52: ARG PASS: func (s *IctestImpl) test(taint_src string) (interface{}, error) {\n /sast-go/cases/completeness/single_app_tracing/interface_class/interface_implementation/interface_class_001_c_T/interface_class_001_c_T.go\n AffectedNodeName: [return value]\n 54: Return Value: \treturn taint_src, nil\n /sast-go/cases/completeness/single_app_tracing/interface_class/interface_implementation/interface_class_001_c_T/interface_class_001_c_T.go\n AffectedNodeName: test\n 45: CALL RETURN: \treturn e._test_svc.test(taint_src)\n /sast-go/cases/completeness/single_app_tracing/interface_class/interface_implementation/interface_class_001_c_T/interface_class_001_c_T.go\n AffectedNodeName: [return value]\n 45: Return Value: \treturn e._test_svc.test(taint_src)\n /sast-go/cases/completeness/single_app_tracing/interface_class/interface_implementation/interface_class_001_c_T/interface_class_001_c_T.go\n AffectedNodeName: GetTest\n 19: CALL RETURN: \tresult, _ := testAPI.GetTest(__taint_src)\n /sast-go/cases/completeness/single_app_tracing/interface_class/interface_implementation/interface_class_001_c_T/interface_class_001_c_T.go\n 19: Var Pass: \tresult, _ := testAPI.GetTest(__taint_src)\n /sast-go/cases/completeness/single_app_tracing/interface_class/interface_implementation/interface_class_001_c_T/interface_class_001_c_T.go\n AffectedNodeName: __taint_sink\n 20: SINK: \t__taint_sink(result)\n==========================================================\n #Total-findings:1\n==========================================================","/benchmarks/sast-go/cases/completeness/single_app_tracing/interface_class/interface_implementation/interface_class_002_c_F/interface_class_002_c_F":"======================== Findings ========================\nNo findings!\n=========================================================="} \ No newline at end of file +{"/benchmarks/sast-go/cases/accuracy/context_sensitive/argument_return_value_passing/argument_passing_reference_001_F/argument_passing_reference_001_F":"======================== Findings ========================\nNo findings!\n==========================================================","/benchmarks/sast-go/cases/accuracy/context_sensitive/argument_return_value_passing/argument_passing_reference_002_T/argument_passing_reference_002_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/sast-go/cases/accuracy/context_sensitive/argument_return_value_passing/argument_passing_reference_002_T/argument_passing_reference_002_T.go\nLine 17: __taint_sink(obj.\"data\")\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/sast-go/cases/accuracy/context_sensitive/argument_return_value_passing/argument_passing_reference_002_T/argument_passing_reference_002_T.go\",\"functionName\":\"main\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /sast-go/cases/accuracy/context_sensitive/argument_return_value_passing/argument_passing_reference_002_T/argument_passing_reference_002_T.go\n AffectedNodeName: __taint_src\n 28: SOURCE: argument_passing_reference_002_T(__taint_src)\n /sast-go/cases/accuracy/context_sensitive/argument_return_value_passing/argument_passing_reference_002_T/argument_passing_reference_002_T.go\n AffectedNodeName: argument_passing_reference_002_T\n 28: CALL: argument_passing_reference_002_T(__taint_src)\n /sast-go/cases/accuracy/context_sensitive/argument_return_value_passing/argument_passing_reference_002_T/argument_passing_reference_002_T.go\n AffectedNodeName: __taint_src\n 12: ARG PASS: func argument_passing_reference_002_T(__taint_src interface{}) {\n /sast-go/cases/accuracy/context_sensitive/argument_return_value_passing/argument_passing_reference_002_T/argument_passing_reference_002_T.go\n AffectedNodeName: process\n 16: CALL: \tprocess(obj, __taint_src)\n /sast-go/cases/accuracy/context_sensitive/argument_return_value_passing/argument_passing_reference_002_T/argument_passing_reference_002_T.go\n AffectedNodeName: __taint_sink\n 17: SINK: \t__taint_sink(obj[\"data\"])\n==========================================================\n #Total-findings:1\n==========================================================","/benchmarks/sast-go/cases/accuracy/context_sensitive/argument_return_value_passing/argument_passing_reference_003_F/argument_passing_reference_003_F":"======================== Findings ========================\nNo findings!\n==========================================================","/benchmarks/sast-go/cases/accuracy/context_sensitive/argument_return_value_passing/argument_passing_reference_004_T/argument_passing_reference_004_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/sast-go/cases/accuracy/context_sensitive/argument_return_value_passing/argument_passing_reference_004_T/argument_passing_reference_004_T.go\nLine 15: __taint_sink(arr)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/sast-go/cases/accuracy/context_sensitive/argument_return_value_passing/argument_passing_reference_004_T/argument_passing_reference_004_T.go\",\"functionName\":\"main\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /sast-go/cases/accuracy/context_sensitive/argument_return_value_passing/argument_passing_reference_004_T/argument_passing_reference_004_T.go\n AffectedNodeName: __taint_src\n 26: SOURCE: argument_passing_reference_005_T(__taint_src)\n /sast-go/cases/accuracy/context_sensitive/argument_return_value_passing/argument_passing_reference_004_T/argument_passing_reference_004_T.go\n AffectedNodeName: argument_passing_reference_005_T\n 26: CALL: argument_passing_reference_005_T(__taint_src)\n /sast-go/cases/accuracy/context_sensitive/argument_return_value_passing/argument_passing_reference_004_T/argument_passing_reference_004_T.go\n AffectedNodeName: __taint_src\n 12: ARG PASS: func argument_passing_reference_005_T(__taint_src interface{}) {\n /sast-go/cases/accuracy/context_sensitive/argument_return_value_passing/argument_passing_reference_004_T/argument_passing_reference_004_T.go\n AffectedNodeName: process\n 14: CALL: \tprocess(arr, __taint_src)\n /sast-go/cases/accuracy/context_sensitive/argument_return_value_passing/argument_passing_reference_004_T/argument_passing_reference_004_T.go\n AffectedNodeName: __taint_sink\n 15: SINK: \t__taint_sink(arr)\n==========================================================\n #Total-findings:1\n==========================================================","/benchmarks/sast-go/cases/accuracy/context_sensitive/argument_return_value_passing/argument_passing_reference_005_F/argument_passing_reference_005_F":"======================== Findings ========================\nNo findings!\n==========================================================","/benchmarks/sast-go/cases/accuracy/context_sensitive/argument_return_value_passing/argument_passing_reference_006_T/argument_passing_reference_006_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/sast-go/cases/accuracy/context_sensitive/argument_return_value_passing/argument_passing_reference_006_T/argument_passing_reference_006_T.go\nLine 17: __taint_sink(objB.\"name\")\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/sast-go/cases/accuracy/context_sensitive/argument_return_value_passing/argument_passing_reference_006_T/argument_passing_reference_006_T.go\",\"functionName\":\"main\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /sast-go/cases/accuracy/context_sensitive/argument_return_value_passing/argument_passing_reference_006_T/argument_passing_reference_006_T.go\n AffectedNodeName: __taint_src\n 30: SOURCE: argument_passing_reference_006_T(__taint_src)\n /sast-go/cases/accuracy/context_sensitive/argument_return_value_passing/argument_passing_reference_006_T/argument_passing_reference_006_T.go\n AffectedNodeName: argument_passing_reference_006_T\n 30: CALL: argument_passing_reference_006_T(__taint_src)\n /sast-go/cases/accuracy/context_sensitive/argument_return_value_passing/argument_passing_reference_006_T/argument_passing_reference_006_T.go\n AffectedNodeName: __taint_src\n 12: ARG PASS: func argument_passing_reference_006_T(__taint_src interface{}) {\n /sast-go/cases/accuracy/context_sensitive/argument_return_value_passing/argument_passing_reference_006_T/argument_passing_reference_006_T.go\n AffectedNodeName: objA\n 13: Var Pass: \tobjA := map[string]interface{}{\"name\": __taint_src}\n /sast-go/cases/accuracy/context_sensitive/argument_return_value_passing/argument_passing_reference_006_T/argument_passing_reference_006_T.go\n AffectedNodeName: swap\n 16: CALL: \tswap(objA, objB)\n /sast-go/cases/accuracy/context_sensitive/argument_return_value_passing/argument_passing_reference_006_T/argument_passing_reference_006_T.go\n AffectedNodeName: __taint_sink\n 17: SINK: \t__taint_sink(objB[\"name\"])\n==========================================================\n #Total-findings:1\n==========================================================","/benchmarks/sast-go/cases/accuracy/context_sensitive/argument_return_value_passing/argument_passing_reference_007_T/argument_passing_reference_007_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/sast-go/cases/accuracy/context_sensitive/argument_return_value_passing/argument_passing_reference_007_T/argument_passing_reference_007_T.go\nLine 20: __taint_sink(&person.GetNamePointer())\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/sast-go/cases/accuracy/context_sensitive/argument_return_value_passing/argument_passing_reference_007_T/argument_passing_reference_007_T.go\",\"functionName\":\"main\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /sast-go/cases/accuracy/context_sensitive/argument_return_value_passing/argument_passing_reference_007_T/argument_passing_reference_007_T.go\n AffectedNodeName: __taint_src\n 34: SOURCE: argument_passing_reference_007_T(__taint_src)\n /sast-go/cases/accuracy/context_sensitive/argument_return_value_passing/argument_passing_reference_007_T/argument_passing_reference_007_T.go\n AffectedNodeName: argument_passing_reference_007_T\n 34: CALL: argument_passing_reference_007_T(__taint_src)\n /sast-go/cases/accuracy/context_sensitive/argument_return_value_passing/argument_passing_reference_007_T/argument_passing_reference_007_T.go\n AffectedNodeName: __taint_src\n 16: ARG PASS: func argument_passing_reference_007_T(__taint_src string) {\n /sast-go/cases/accuracy/context_sensitive/argument_return_value_passing/argument_passing_reference_007_T/argument_passing_reference_007_T.go\n AffectedNodeName: UpdateNamePointer\n 19: CALL: \t(&person).UpdateNamePointer(__taint_src)\n /sast-go/cases/accuracy/context_sensitive/argument_return_value_passing/argument_passing_reference_007_T/argument_passing_reference_007_T.go\n AffectedNodeName: GetNamePointer\n 20: CALL: \t__taint_sink((&person).GetNamePointer())\n /sast-go/cases/accuracy/context_sensitive/argument_return_value_passing/argument_passing_reference_007_T/argument_passing_reference_007_T.go\n AffectedNodeName: &person\n 20: ARG PASS: \t__taint_sink((&person).GetNamePointer())\n /sast-go/cases/accuracy/context_sensitive/argument_return_value_passing/argument_passing_reference_007_T/argument_passing_reference_007_T.go\n AffectedNodeName: GetNamePointer\n 20: CALL: \t__taint_sink((&person).GetNamePointer())\n /sast-go/cases/accuracy/context_sensitive/argument_return_value_passing/argument_passing_reference_007_T/argument_passing_reference_007_T.go\n AffectedNodeName: &person\n 20: ARG PASS: \t__taint_sink((&person).GetNamePointer())\n /sast-go/cases/accuracy/context_sensitive/argument_return_value_passing/argument_passing_reference_007_T/argument_passing_reference_007_T.go\n AffectedNodeName: GetNamePointer\n 20: CALL RETURN: \t__taint_sink((&person).GetNamePointer())\n /sast-go/cases/accuracy/context_sensitive/argument_return_value_passing/argument_passing_reference_007_T/argument_passing_reference_007_T.go\n AffectedNodeName: __taint_sink\n 20: SINK: \t__taint_sink((&person).GetNamePointer())\n==========================================================\n #Total-findings:1\n==========================================================","/benchmarks/sast-go/cases/accuracy/context_sensitive/argument_return_value_passing/argument_passing_reference_008_F/argument_passing_reference_008_F":"======================== Findings ========================\nNo findings!\n==========================================================","/benchmarks/sast-go/cases/accuracy/context_sensitive/argument_return_value_passing/argument_passing_value_011_F/argument_passing_value_011_F":"======================== Findings ========================\nNo findings!\n==========================================================","/benchmarks/sast-go/cases/accuracy/context_sensitive/argument_return_value_passing/argument_passing_value_012_T/argument_passing_value_012_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/sast-go/cases/accuracy/context_sensitive/argument_return_value_passing/argument_passing_value_012_T/argument_passing_value_012_T.go\nLine 16: __taint_sink(arg)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/sast-go/cases/accuracy/context_sensitive/argument_return_value_passing/argument_passing_value_012_T/argument_passing_value_012_T.go\",\"functionName\":\"main\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /sast-go/cases/accuracy/context_sensitive/argument_return_value_passing/argument_passing_value_012_T/argument_passing_value_012_T.go\n AffectedNodeName: __taint_src\n 23: SOURCE: argument_passing_value_012_T(__taint_src)\n /sast-go/cases/accuracy/context_sensitive/argument_return_value_passing/argument_passing_value_012_T/argument_passing_value_012_T.go\n AffectedNodeName: argument_passing_value_012_T\n 23: CALL: argument_passing_value_012_T(__taint_src)\n /sast-go/cases/accuracy/context_sensitive/argument_return_value_passing/argument_passing_value_012_T/argument_passing_value_012_T.go\n AffectedNodeName: __taint_src\n 11: ARG PASS: func argument_passing_value_012_T(__taint_src string) {\n /sast-go/cases/accuracy/context_sensitive/argument_return_value_passing/argument_passing_value_012_T/argument_passing_value_012_T.go\n AffectedNodeName: process\n 12: CALL: \tprocess(__taint_src)\n /sast-go/cases/accuracy/context_sensitive/argument_return_value_passing/argument_passing_value_012_T/argument_passing_value_012_T.go\n AffectedNodeName: arg\n 15: ARG PASS: func process(arg string) {\n /sast-go/cases/accuracy/context_sensitive/argument_return_value_passing/argument_passing_value_012_T/argument_passing_value_012_T.go\n AffectedNodeName: __taint_sink\n 16: SINK: \t__taint_sink(arg)\n==========================================================\n #Total-findings:1\n==========================================================","/benchmarks/sast-go/cases/accuracy/context_sensitive/argument_return_value_passing/argument_passing_value_013_F/argument_passing_value_013_F":"======================== Findings ========================\nNo findings!\n==========================================================","/benchmarks/sast-go/cases/accuracy/context_sensitive/argument_return_value_passing/argument_passing_value_014_T/argument_passing_value_014_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/sast-go/cases/accuracy/context_sensitive/argument_return_value_passing/argument_passing_value_014_T/argument_passing_value_014_T.go\nLine 18: __taint_sink(arg)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/sast-go/cases/accuracy/context_sensitive/argument_return_value_passing/argument_passing_value_014_T/argument_passing_value_014_T.go\",\"functionName\":\"main\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /sast-go/cases/accuracy/context_sensitive/argument_return_value_passing/argument_passing_value_014_T/argument_passing_value_014_T.go\n AffectedNodeName: __taint_src\n 28: SOURCE: argument_passing_value_014_T(__taint_src)\n /sast-go/cases/accuracy/context_sensitive/argument_return_value_passing/argument_passing_value_014_T/argument_passing_value_014_T.go\n AffectedNodeName: argument_passing_value_014_T\n 28: CALL: argument_passing_value_014_T(__taint_src)\n /sast-go/cases/accuracy/context_sensitive/argument_return_value_passing/argument_passing_value_014_T/argument_passing_value_014_T.go\n AffectedNodeName: __taint_src\n 11: ARG PASS: func argument_passing_value_014_T(__taint_src interface{}) {\n /sast-go/cases/accuracy/context_sensitive/argument_return_value_passing/argument_passing_value_014_T/argument_passing_value_014_T.go\n AffectedNodeName: process1\n 14: CALL: \tprocess1(__taint_src)\n /sast-go/cases/accuracy/context_sensitive/argument_return_value_passing/argument_passing_value_014_T/argument_passing_value_014_T.go\n AffectedNodeName: arg\n 17: ARG PASS: func process1(arg interface{}) {\n /sast-go/cases/accuracy/context_sensitive/argument_return_value_passing/argument_passing_value_014_T/argument_passing_value_014_T.go\n AffectedNodeName: __taint_sink\n 18: SINK: \t__taint_sink(arg)\n==========================================================\n #Total-findings:1\n==========================================================","/benchmarks/sast-go/cases/accuracy/context_sensitive/argument_return_value_passing/argument_passing_value_015_F/argument_passing_value_015_F":"======================== Findings ========================\nNo findings!\n==========================================================","/benchmarks/sast-go/cases/accuracy/context_sensitive/argument_return_value_passing/argument_passing_value_016_T/argument_passing_value_016_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/sast-go/cases/accuracy/context_sensitive/argument_return_value_passing/argument_passing_value_016_T/argument_passing_value_016_T.go\nLine 16: __taint_sink(arg1)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/sast-go/cases/accuracy/context_sensitive/argument_return_value_passing/argument_passing_value_016_T/argument_passing_value_016_T.go\",\"functionName\":\"main\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /sast-go/cases/accuracy/context_sensitive/argument_return_value_passing/argument_passing_value_016_T/argument_passing_value_016_T.go\n AffectedNodeName: __taint_src\n 22: SOURCE: argument_passing_value_016_T(__taint_src)\n /sast-go/cases/accuracy/context_sensitive/argument_return_value_passing/argument_passing_value_016_T/argument_passing_value_016_T.go\n AffectedNodeName: argument_passing_value_016_T\n 22: CALL: argument_passing_value_016_T(__taint_src)\n /sast-go/cases/accuracy/context_sensitive/argument_return_value_passing/argument_passing_value_016_T/argument_passing_value_016_T.go\n AffectedNodeName: __taint_src\n 11: ARG PASS: func argument_passing_value_016_T(__taint_src string) {\n /sast-go/cases/accuracy/context_sensitive/argument_return_value_passing/argument_passing_value_016_T/argument_passing_value_016_T.go\n AffectedNodeName: process\n 12: CALL: \tprocess(__taint_src, \"_\")\n /sast-go/cases/accuracy/context_sensitive/argument_return_value_passing/argument_passing_value_016_T/argument_passing_value_016_T.go\n AffectedNodeName: arg1\n 15: ARG PASS: func process(arg1 string, arg2 string) {\n /sast-go/cases/accuracy/context_sensitive/argument_return_value_passing/argument_passing_value_016_T/argument_passing_value_016_T.go\n AffectedNodeName: __taint_sink\n 16: SINK: \t__taint_sink(arg1)\n==========================================================\n #Total-findings:1\n==========================================================","/benchmarks/sast-go/cases/accuracy/context_sensitive/argument_return_value_passing/multiple_return_001_F/multiple_return_001_F":"======================== Findings ========================\nNo findings!\n==========================================================","/benchmarks/sast-go/cases/accuracy/context_sensitive/argument_return_value_passing/multiple_return_002_T/multiple_return_002_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/sast-go/cases/accuracy/context_sensitive/argument_return_value_passing/multiple_return_002_T/multiple_return_002_T.go\nLine 17: __taint_sink(ret1)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/sast-go/cases/accuracy/context_sensitive/argument_return_value_passing/multiple_return_002_T/multiple_return_002_T.go\",\"functionName\":\"main\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /sast-go/cases/accuracy/context_sensitive/argument_return_value_passing/multiple_return_002_T/multiple_return_002_T.go\n AffectedNodeName: __taint_src\n 27: SOURCE: multiple_return_002_T(__taint_src)\n /sast-go/cases/accuracy/context_sensitive/argument_return_value_passing/multiple_return_002_T/multiple_return_002_T.go\n AffectedNodeName: multiple_return_002_T\n 27: CALL: multiple_return_002_T(__taint_src)\n /sast-go/cases/accuracy/context_sensitive/argument_return_value_passing/multiple_return_002_T/multiple_return_002_T.go\n AffectedNodeName: __taint_src\n 12: ARG PASS: func multiple_return_002_T(__taint_src interface{}) {\n /sast-go/cases/accuracy/context_sensitive/argument_return_value_passing/multiple_return_002_T/multiple_return_002_T.go\n AffectedNodeName: processData\n 15: CALL: \tret1, ret2 := processData(__taint_src, a)\n /sast-go/cases/accuracy/context_sensitive/argument_return_value_passing/multiple_return_002_T/multiple_return_002_T.go\n AffectedNodeName: processData\n 15: CALL RETURN: \tret1, ret2 := processData(__taint_src, a)\n /sast-go/cases/accuracy/context_sensitive/argument_return_value_passing/multiple_return_002_T/multiple_return_002_T.go\n 15: Var Pass: \tret1, ret2 := processData(__taint_src, a)\n /sast-go/cases/accuracy/context_sensitive/argument_return_value_passing/multiple_return_002_T/multiple_return_002_T.go\n AffectedNodeName: __taint_sink\n 17: SINK: \t__taint_sink(ret1)\n==========================================================\n #Total-findings:1\n==========================================================","/benchmarks/sast-go/cases/accuracy/context_sensitive/argument_return_value_passing/multiple_return_003_F/multiple_return_003_F":"======================== Findings ========================\nNo findings!\n==========================================================","/benchmarks/sast-go/cases/accuracy/context_sensitive/argument_return_value_passing/multiple_return_004_T/multiple_return_004_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/sast-go/cases/accuracy/context_sensitive/argument_return_value_passing/multiple_return_004_T/multiple_return_004_T.go\nLine 17: __taint_sink(ret2)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/sast-go/cases/accuracy/context_sensitive/argument_return_value_passing/multiple_return_004_T/multiple_return_004_T.go\",\"functionName\":\"main\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /sast-go/cases/accuracy/context_sensitive/argument_return_value_passing/multiple_return_004_T/multiple_return_004_T.go\n AffectedNodeName: __taint_src\n 27: SOURCE: multiple_return_004_T(__taint_src)\n /sast-go/cases/accuracy/context_sensitive/argument_return_value_passing/multiple_return_004_T/multiple_return_004_T.go\n AffectedNodeName: multiple_return_004_T\n 27: CALL: multiple_return_004_T(__taint_src)\n /sast-go/cases/accuracy/context_sensitive/argument_return_value_passing/multiple_return_004_T/multiple_return_004_T.go\n AffectedNodeName: __taint_src\n 12: ARG PASS: func multiple_return_004_T(__taint_src interface{}) {\n /sast-go/cases/accuracy/context_sensitive/argument_return_value_passing/multiple_return_004_T/multiple_return_004_T.go\n AffectedNodeName: processData\n 15: CALL: \tret1, ret2 := processData(__taint_src, a)\n /sast-go/cases/accuracy/context_sensitive/argument_return_value_passing/multiple_return_004_T/multiple_return_004_T.go\n AffectedNodeName: processData\n 15: CALL RETURN: \tret1, ret2 := processData(__taint_src, a)\n /sast-go/cases/accuracy/context_sensitive/argument_return_value_passing/multiple_return_004_T/multiple_return_004_T.go\n 15: Var Pass: \tret1, ret2 := processData(__taint_src, a)\n /sast-go/cases/accuracy/context_sensitive/argument_return_value_passing/multiple_return_004_T/multiple_return_004_T.go\n AffectedNodeName: __taint_sink\n 17: SINK: \t__taint_sink(ret2)\n==========================================================\n #Total-findings:1\n==========================================================","/benchmarks/sast-go/cases/accuracy/context_sensitive/argument_return_value_passing/named_return_001_F/named_return_001_F":"======================== Findings ========================\nNo findings!\n==========================================================","/benchmarks/sast-go/cases/accuracy/context_sensitive/argument_return_value_passing/named_return_002_T/named_return_002_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/sast-go/cases/accuracy/context_sensitive/argument_return_value_passing/named_return_002_T/named_return_002_T.go\nLine 15: __taint_sink(ret)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/sast-go/cases/accuracy/context_sensitive/argument_return_value_passing/named_return_002_T/named_return_002_T.go\",\"functionName\":\"main\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /sast-go/cases/accuracy/context_sensitive/argument_return_value_passing/named_return_002_T/named_return_002_T.go\n AffectedNodeName: __taint_src\n 26: SOURCE: named_return_002_T(__taint_src)\n /sast-go/cases/accuracy/context_sensitive/argument_return_value_passing/named_return_002_T/named_return_002_T.go\n AffectedNodeName: named_return_002_T\n 26: CALL: named_return_002_T(__taint_src)\n /sast-go/cases/accuracy/context_sensitive/argument_return_value_passing/named_return_002_T/named_return_002_T.go\n AffectedNodeName: __taint_src\n 11: ARG PASS: func named_return_002_T(__taint_src interface{}) {\n /sast-go/cases/accuracy/context_sensitive/argument_return_value_passing/named_return_002_T/named_return_002_T.go\n AffectedNodeName: processData\n 14: CALL: \tret := processData(__taint_src, a)\n /sast-go/cases/accuracy/context_sensitive/argument_return_value_passing/named_return_002_T/named_return_002_T.go\n AffectedNodeName: processData\n 14: CALL RETURN: \tret := processData(__taint_src, a)\n /sast-go/cases/accuracy/context_sensitive/argument_return_value_passing/named_return_002_T/named_return_002_T.go\n AffectedNodeName: ret\n 14: Var Pass: \tret := processData(__taint_src, a)\n /sast-go/cases/accuracy/context_sensitive/argument_return_value_passing/named_return_002_T/named_return_002_T.go\n AffectedNodeName: __taint_sink\n 15: SINK: \t__taint_sink(ret)\n==========================================================\n #Total-findings:1\n==========================================================","/benchmarks/sast-go/cases/accuracy/context_sensitive/argument_return_value_passing/return_value_passing_001_F/return_value_passing_001_F":"======================== Findings ========================\nNo findings!\n==========================================================","/benchmarks/sast-go/cases/accuracy/context_sensitive/argument_return_value_passing/return_value_passing_002_T/return_value_passing_002_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/sast-go/cases/accuracy/context_sensitive/argument_return_value_passing/return_value_passing_002_T/return_value_passing_002_T.go\nLine 13: __taint_sink(data)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/sast-go/cases/accuracy/context_sensitive/argument_return_value_passing/return_value_passing_002_T/return_value_passing_002_T.go\",\"functionName\":\"main\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /sast-go/cases/accuracy/context_sensitive/argument_return_value_passing/return_value_passing_002_T/return_value_passing_002_T.go\n AffectedNodeName: __taint_src\n 24: SOURCE: return_value_passing_002_T(__taint_src)\n /sast-go/cases/accuracy/context_sensitive/argument_return_value_passing/return_value_passing_002_T/return_value_passing_002_T.go\n AffectedNodeName: return_value_passing_002_T\n 24: CALL: return_value_passing_002_T(__taint_src)\n /sast-go/cases/accuracy/context_sensitive/argument_return_value_passing/return_value_passing_002_T/return_value_passing_002_T.go\n AffectedNodeName: __taint_src\n 11: ARG PASS: func return_value_passing_002_T(__taint_src interface{}) {\n /sast-go/cases/accuracy/context_sensitive/argument_return_value_passing/return_value_passing_002_T/return_value_passing_002_T.go\n AffectedNodeName: process\n 12: CALL: \tdata := process(__taint_src)\n /sast-go/cases/accuracy/context_sensitive/argument_return_value_passing/return_value_passing_002_T/return_value_passing_002_T.go\n AffectedNodeName: process\n 12: CALL RETURN: \tdata := process(__taint_src)\n /sast-go/cases/accuracy/context_sensitive/argument_return_value_passing/return_value_passing_002_T/return_value_passing_002_T.go\n AffectedNodeName: data\n 12: Var Pass: \tdata := process(__taint_src)\n /sast-go/cases/accuracy/context_sensitive/argument_return_value_passing/return_value_passing_002_T/return_value_passing_002_T.go\n AffectedNodeName: __taint_sink\n 13: SINK: \t__taint_sink(data)\n==========================================================\n #Total-findings:1\n==========================================================","/benchmarks/sast-go/cases/accuracy/context_sensitive/multi_invoke/multi_invoke_001_F/multi_invoke_001_F":"======================== Findings ========================\nNo findings!\n==========================================================","/benchmarks/sast-go/cases/accuracy/context_sensitive/multi_invoke/multi_invoke_002_T/multi_invoke_002_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/sast-go/cases/accuracy/context_sensitive/multi_invoke/multi_invoke_002_T/multi_invoke_002_T.go\nLine 16: __taint_sink(a)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/sast-go/cases/accuracy/context_sensitive/multi_invoke/multi_invoke_002_T/multi_invoke_002_T.go\",\"functionName\":\"main\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /sast-go/cases/accuracy/context_sensitive/multi_invoke/multi_invoke_002_T/multi_invoke_002_T.go\n AffectedNodeName: __taint_src\n 27: SOURCE: multi_invoke_002_T(__taint_src)\n /sast-go/cases/accuracy/context_sensitive/multi_invoke/multi_invoke_002_T/multi_invoke_002_T.go\n AffectedNodeName: multi_invoke_002_T\n 27: CALL: multi_invoke_002_T(__taint_src)\n /sast-go/cases/accuracy/context_sensitive/multi_invoke/multi_invoke_002_T/multi_invoke_002_T.go\n AffectedNodeName: __taint_src\n 12: ARG PASS: func multi_invoke_002_T(__taint_src string) {\n /sast-go/cases/accuracy/context_sensitive/multi_invoke/multi_invoke_002_T/multi_invoke_002_T.go\n AffectedNodeName: process\n 13: CALL: \ta := process(__taint_src)\n /sast-go/cases/accuracy/context_sensitive/multi_invoke/multi_invoke_002_T/multi_invoke_002_T.go\n AffectedNodeName: process\n 13: CALL RETURN: \ta := process(__taint_src)\n /sast-go/cases/accuracy/context_sensitive/multi_invoke/multi_invoke_002_T/multi_invoke_002_T.go\n AffectedNodeName: a\n 13: Var Pass: \ta := process(__taint_src)\n /sast-go/cases/accuracy/context_sensitive/multi_invoke/multi_invoke_002_T/multi_invoke_002_T.go\n AffectedNodeName: __taint_sink\n 16: SINK: \t__taint_sink(a)\n==========================================================\n #Total-findings:1\n==========================================================","/benchmarks/sast-go/cases/accuracy/context_sensitive/polymorphism/polymorphism_001_T/polymorphism_001_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/sast-go/cases/accuracy/context_sensitive/polymorphism/polymorphism_001_T/polymorphism_001_T.go\nLine 15: __taint_sink(sub.call(__taint_src))\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/sast-go/cases/accuracy/context_sensitive/polymorphism/polymorphism_001_T/polymorphism_001_T.go\",\"functionName\":\"main\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /sast-go/cases/accuracy/context_sensitive/polymorphism/polymorphism_001_T/polymorphism_001_T.go\n AffectedNodeName: __taint_src\n 38: SOURCE: polymorphism_001_T(__taint_src)\n /sast-go/cases/accuracy/context_sensitive/polymorphism/polymorphism_001_T/polymorphism_001_T.go\n AffectedNodeName: polymorphism_001_T\n 38: CALL: polymorphism_001_T(__taint_src)\n /sast-go/cases/accuracy/context_sensitive/polymorphism/polymorphism_001_T/polymorphism_001_T.go\n AffectedNodeName: __taint_src\n 12: ARG PASS: func polymorphism_001_T(__taint_src interface{}) {\n /sast-go/cases/accuracy/context_sensitive/polymorphism/polymorphism_001_T/polymorphism_001_T.go\n AffectedNodeName: call\n 15: CALL: \t__taint_sink(sub.call(__taint_src))\n /sast-go/cases/accuracy/context_sensitive/polymorphism/polymorphism_001_T/polymorphism_001_T.go\n AffectedNodeName: call\n 15: CALL RETURN: \t__taint_sink(sub.call(__taint_src))\n /sast-go/cases/accuracy/context_sensitive/polymorphism/polymorphism_001_T/polymorphism_001_T.go\n AffectedNodeName: __taint_sink\n 15: SINK: \t__taint_sink(sub.call(__taint_src))\n==========================================================\n #Total-findings:1\n==========================================================","/benchmarks/sast-go/cases/accuracy/context_sensitive/polymorphism/polymorphism_002_F/polymorphism_002_F":"======================== Findings ========================\nNo findings!\n==========================================================","/benchmarks/sast-go/cases/accuracy/context_sensitive/polymorphism/polymorphism_003_T/polymorphism_003_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/sast-go/cases/accuracy/context_sensitive/polymorphism/polymorphism_003_T/polymorphism_003_T.go\nLine 15: __taint_sink(student.Run())\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/sast-go/cases/accuracy/context_sensitive/polymorphism/polymorphism_003_T/polymorphism_003_T.go\",\"functionName\":\"main\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /sast-go/cases/accuracy/context_sensitive/polymorphism/polymorphism_003_T/polymorphism_003_T.go\n AffectedNodeName: __taint_src\n 46: SOURCE: polymorphism_003_T(__taint_src)\n /sast-go/cases/accuracy/context_sensitive/polymorphism/polymorphism_003_T/polymorphism_003_T.go\n AffectedNodeName: polymorphism_003_T\n 46: CALL: polymorphism_003_T(__taint_src)\n /sast-go/cases/accuracy/context_sensitive/polymorphism/polymorphism_003_T/polymorphism_003_T.go\n AffectedNodeName: __taint_src\n 11: ARG PASS: func polymorphism_003_T(__taint_src string) {\n /sast-go/cases/accuracy/context_sensitive/polymorphism/polymorphism_003_T/polymorphism_003_T.go\n AffectedNodeName: student\n 12: Var Pass: \tvar student Person = &Student{Name: __taint_src, Age: 20, GPA: 3.8}\n /sast-go/cases/accuracy/context_sensitive/polymorphism/polymorphism_003_T/polymorphism_003_T.go\n AffectedNodeName: Run\n 15: CALL: \t__taint_sink(student.Run())\n /sast-go/cases/accuracy/context_sensitive/polymorphism/polymorphism_003_T/polymorphism_003_T.go\n AffectedNodeName: student\n 15: ARG PASS: \t__taint_sink(student.Run())\n /sast-go/cases/accuracy/context_sensitive/polymorphism/polymorphism_003_T/polymorphism_003_T.go\n AffectedNodeName: Run\n 15: CALL: \t__taint_sink(student.Run())\n /sast-go/cases/accuracy/context_sensitive/polymorphism/polymorphism_003_T/polymorphism_003_T.go\n AffectedNodeName: student\n 15: ARG PASS: \t__taint_sink(student.Run())\n /sast-go/cases/accuracy/context_sensitive/polymorphism/polymorphism_003_T/polymorphism_003_T.go\n AffectedNodeName: Run\n 15: CALL RETURN: \t__taint_sink(student.Run())\n /sast-go/cases/accuracy/context_sensitive/polymorphism/polymorphism_003_T/polymorphism_003_T.go\n AffectedNodeName: __taint_sink\n 15: SINK: \t__taint_sink(student.Run())\n==========================================================\n #Total-findings:1\n==========================================================","/benchmarks/sast-go/cases/accuracy/context_sensitive/polymorphism/polymorphism_004_F/polymorphism_004_F":"======================== Findings ========================\nNo findings!\n==========================================================","/benchmarks/sast-go/cases/accuracy/field_sensitive/multidimensional_collection/array_index_005_T/array_index_005_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/sast-go/cases/accuracy/field_sensitive/multidimensional_collection/array_index_005_T/array_index_005_T.go\nLine 14: __taint_sink(str.0.0)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/sast-go/cases/accuracy/field_sensitive/multidimensional_collection/array_index_005_T/array_index_005_T.go\",\"functionName\":\"main\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /sast-go/cases/accuracy/field_sensitive/multidimensional_collection/array_index_005_T/array_index_005_T.go\n AffectedNodeName: __taint_src\n 21: SOURCE: array_index_005_T(__taint_src)\n /sast-go/cases/accuracy/field_sensitive/multidimensional_collection/array_index_005_T/array_index_005_T.go\n AffectedNodeName: array_index_005_T\n 21: CALL: array_index_005_T(__taint_src)\n /sast-go/cases/accuracy/field_sensitive/multidimensional_collection/array_index_005_T/array_index_005_T.go\n AffectedNodeName: __taint_src\n 12: ARG PASS: func array_index_005_T(__taint_src string) {\n /sast-go/cases/accuracy/field_sensitive/multidimensional_collection/array_index_005_T/array_index_005_T.go\n AffectedNodeName: str\n 13: Var Pass: \tvar str = [3][1]string{[1]string{__taint_src}, [1]string{\"b\"}, [1]string{\"c\"}}\n /sast-go/cases/accuracy/field_sensitive/multidimensional_collection/array_index_005_T/array_index_005_T.go\n AffectedNodeName: __taint_sink\n 14: SINK: \t__taint_sink(str[0][0])\n==========================================================\n #Total-findings:1\n==========================================================","/benchmarks/sast-go/cases/accuracy/field_sensitive/multidimensional_collection/array_index_006_F/array_index_006_F":"======================== Findings ========================\nNo findings!\n==========================================================","/benchmarks/sast-go/cases/accuracy/field_sensitive/multidimensional_collection/slice_index_003_T/slice_index_003_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/sast-go/cases/accuracy/field_sensitive/multidimensional_collection/slice_index_003_T/slice_index_003_T.go\nLine 18: __taint_sink(s.2.2)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/sast-go/cases/accuracy/field_sensitive/multidimensional_collection/slice_index_003_T/slice_index_003_T.go\",\"functionName\":\"main\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /sast-go/cases/accuracy/field_sensitive/multidimensional_collection/slice_index_003_T/slice_index_003_T.go\n AffectedNodeName: __taint_src\n 25: SOURCE: slice_index_003_T(__taint_src)\n /sast-go/cases/accuracy/field_sensitive/multidimensional_collection/slice_index_003_T/slice_index_003_T.go\n AffectedNodeName: slice_index_003_T\n 25: CALL: slice_index_003_T(__taint_src)\n /sast-go/cases/accuracy/field_sensitive/multidimensional_collection/slice_index_003_T/slice_index_003_T.go\n AffectedNodeName: __taint_src\n 12: ARG PASS: func slice_index_003_T(__taint_src string) {\n /sast-go/cases/accuracy/field_sensitive/multidimensional_collection/slice_index_003_T/slice_index_003_T.go\n AffectedNodeName: s\n 13: Var Pass: \ts := [][]string{\n 14: Var Pass: \t\t[]string{\"a\"},\n 15: Var Pass: \t\t[]string{\"b\", \"c\"},\n 16: Var Pass: \t\t[]string{\"d\", \"e\", __taint_src},\n 17: Var Pass: \t}\n /sast-go/cases/accuracy/field_sensitive/multidimensional_collection/slice_index_003_T/slice_index_003_T.go\n AffectedNodeName: __taint_sink\n 18: SINK: \t__taint_sink(s[2][2])\n==========================================================\n #Total-findings:1\n==========================================================","/benchmarks/sast-go/cases/accuracy/field_sensitive/multidimensional_collection/slice_index_004_F/slice_index_004_F":"======================== Findings ========================\nNo findings!\n==========================================================","/benchmarks/sast-go/cases/accuracy/field_sensitive/one_dimensional_collection/numeric_index_state_no_solver/array_index_001_T/array_index_001_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/sast-go/cases/accuracy/field_sensitive/one_dimensional_collection/numeric_index_state_no_solver/array_index_001_T/array_index_001_T.go\nLine 14: __taint_sink(str.0)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/sast-go/cases/accuracy/field_sensitive/one_dimensional_collection/numeric_index_state_no_solver/array_index_001_T/array_index_001_T.go\",\"functionName\":\"main\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /sast-go/cases/accuracy/field_sensitive/one_dimensional_collection/numeric_index_state_no_solver/array_index_001_T/array_index_001_T.go\n AffectedNodeName: __taint_src\n 21: SOURCE: array_index_001_T(__taint_src)\n /sast-go/cases/accuracy/field_sensitive/one_dimensional_collection/numeric_index_state_no_solver/array_index_001_T/array_index_001_T.go\n AffectedNodeName: array_index_001_T\n 21: CALL: array_index_001_T(__taint_src)\n /sast-go/cases/accuracy/field_sensitive/one_dimensional_collection/numeric_index_state_no_solver/array_index_001_T/array_index_001_T.go\n AffectedNodeName: __taint_src\n 12: ARG PASS: func array_index_001_T(__taint_src string) {\n /sast-go/cases/accuracy/field_sensitive/one_dimensional_collection/numeric_index_state_no_solver/array_index_001_T/array_index_001_T.go\n AffectedNodeName: str\n 13: Var Pass: \tvar str = [3]string{__taint_src, \"b\", \"c\"}\n /sast-go/cases/accuracy/field_sensitive/one_dimensional_collection/numeric_index_state_no_solver/array_index_001_T/array_index_001_T.go\n AffectedNodeName: __taint_sink\n 14: SINK: \t__taint_sink(str[0])\n==========================================================\n #Total-findings:1\n==========================================================","/benchmarks/sast-go/cases/accuracy/field_sensitive/one_dimensional_collection/numeric_index_state_no_solver/array_index_002_F/array_index_002_F":"======================== Findings ========================\nNo findings!\n==========================================================","/benchmarks/sast-go/cases/accuracy/field_sensitive/one_dimensional_collection/numeric_index_state_no_solver/array_index_003_T/array_index_003_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/sast-go/cases/accuracy/field_sensitive/one_dimensional_collection/numeric_index_state_no_solver/array_index_003_T/array_index_003_T.go\nLine 15: __taint_sink(str)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/sast-go/cases/accuracy/field_sensitive/one_dimensional_collection/numeric_index_state_no_solver/array_index_003_T/array_index_003_T.go\",\"functionName\":\"main\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /sast-go/cases/accuracy/field_sensitive/one_dimensional_collection/numeric_index_state_no_solver/array_index_003_T/array_index_003_T.go\n AffectedNodeName: __taint_src\n 22: SOURCE: array_index_003_T(__taint_src)\n /sast-go/cases/accuracy/field_sensitive/one_dimensional_collection/numeric_index_state_no_solver/array_index_003_T/array_index_003_T.go\n AffectedNodeName: array_index_003_T\n 22: CALL: array_index_003_T(__taint_src)\n /sast-go/cases/accuracy/field_sensitive/one_dimensional_collection/numeric_index_state_no_solver/array_index_003_T/array_index_003_T.go\n AffectedNodeName: __taint_src\n 12: ARG PASS: func array_index_003_T(__taint_src string) {\n /sast-go/cases/accuracy/field_sensitive/one_dimensional_collection/numeric_index_state_no_solver/array_index_003_T/array_index_003_T.go\n AffectedNodeName: str\n 13: Var Pass: \tvar str = [3]string{__taint_src, \"b\", \"c\"}\n /sast-go/cases/accuracy/field_sensitive/one_dimensional_collection/numeric_index_state_no_solver/array_index_003_T/array_index_003_T.go\n AffectedNodeName: __taint_sink\n 15: SINK: \t__taint_sink(str)\n==========================================================\n #Total-findings:1\n==========================================================","/benchmarks/sast-go/cases/accuracy/field_sensitive/one_dimensional_collection/numeric_index_state_no_solver/array_index_004_F/array_index_004_F":"======================== Findings ========================\nNo findings!\n==========================================================","/benchmarks/sast-go/cases/accuracy/field_sensitive/one_dimensional_collection/numeric_index_state_no_solver/map_field_sensitive_001_T/map_field_sensitive_001_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/sast-go/cases/accuracy/field_sensitive/one_dimensional_collection/numeric_index_state_no_solver/map_field_sensitive_001_T/map_field_sensitive_001_T.go\nLine 16: __taint_sink(m.\"key1\")\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/sast-go/cases/accuracy/field_sensitive/one_dimensional_collection/numeric_index_state_no_solver/map_field_sensitive_001_T/map_field_sensitive_001_T.go\",\"functionName\":\"main\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /sast-go/cases/accuracy/field_sensitive/one_dimensional_collection/numeric_index_state_no_solver/map_field_sensitive_001_T/map_field_sensitive_001_T.go\n AffectedNodeName: __taint_src\n 23: SOURCE: map_field_sensitive_001_T(__taint_src)\n /sast-go/cases/accuracy/field_sensitive/one_dimensional_collection/numeric_index_state_no_solver/map_field_sensitive_001_T/map_field_sensitive_001_T.go\n AffectedNodeName: map_field_sensitive_001_T\n 23: CALL: map_field_sensitive_001_T(__taint_src)\n /sast-go/cases/accuracy/field_sensitive/one_dimensional_collection/numeric_index_state_no_solver/map_field_sensitive_001_T/map_field_sensitive_001_T.go\n AffectedNodeName: __taint_src\n 12: ARG PASS: func map_field_sensitive_001_T(__taint_src string) {\n /sast-go/cases/accuracy/field_sensitive/one_dimensional_collection/numeric_index_state_no_solver/map_field_sensitive_001_T/map_field_sensitive_001_T.go\n AffectedNodeName: m[\"key1\"]\n 14: Var Pass: \tm[\"key1\"] = __taint_src\n /sast-go/cases/accuracy/field_sensitive/one_dimensional_collection/numeric_index_state_no_solver/map_field_sensitive_001_T/map_field_sensitive_001_T.go\n AffectedNodeName: __taint_sink\n 16: SINK: \t__taint_sink(m[\"key1\"])\n==========================================================\n #Total-findings:1\n==========================================================","/benchmarks/sast-go/cases/accuracy/field_sensitive/one_dimensional_collection/numeric_index_state_no_solver/map_field_sensitive_002_F/map_field_sensitive_002_F":"======================== Findings ========================\nNo findings!\n==========================================================","/benchmarks/sast-go/cases/accuracy/field_sensitive/one_dimensional_collection/numeric_index_state_no_solver/map_field_sensitive_003_F/map_field_sensitive_003_F":"======================== Findings ========================\nNo findings!\n==========================================================","/benchmarks/sast-go/cases/accuracy/field_sensitive/one_dimensional_collection/numeric_index_state_no_solver/map_field_sensitive_004_T/map_field_sensitive_004_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/sast-go/cases/accuracy/field_sensitive/one_dimensional_collection/numeric_index_state_no_solver/map_field_sensitive_004_T/map_field_sensitive_004_T.go\nLine 18: __taint_sink(m.\"key2\")\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/sast-go/cases/accuracy/field_sensitive/one_dimensional_collection/numeric_index_state_no_solver/map_field_sensitive_004_T/map_field_sensitive_004_T.go\",\"functionName\":\"main\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /sast-go/cases/accuracy/field_sensitive/one_dimensional_collection/numeric_index_state_no_solver/map_field_sensitive_004_T/map_field_sensitive_004_T.go\n AffectedNodeName: __taint_src\n 25: SOURCE: map_field_sensitive_004_T(__taint_src)\n /sast-go/cases/accuracy/field_sensitive/one_dimensional_collection/numeric_index_state_no_solver/map_field_sensitive_004_T/map_field_sensitive_004_T.go\n AffectedNodeName: map_field_sensitive_004_T\n 25: CALL: map_field_sensitive_004_T(__taint_src)\n /sast-go/cases/accuracy/field_sensitive/one_dimensional_collection/numeric_index_state_no_solver/map_field_sensitive_004_T/map_field_sensitive_004_T.go\n AffectedNodeName: __taint_src\n 12: ARG PASS: func map_field_sensitive_004_T(__taint_src string) {\n /sast-go/cases/accuracy/field_sensitive/one_dimensional_collection/numeric_index_state_no_solver/map_field_sensitive_004_T/map_field_sensitive_004_T.go\n AffectedNodeName: m[\"key2\"]\n 16: Var Pass: \tm[\"key2\"] = __taint_src\n /sast-go/cases/accuracy/field_sensitive/one_dimensional_collection/numeric_index_state_no_solver/map_field_sensitive_004_T/map_field_sensitive_004_T.go\n AffectedNodeName: __taint_sink\n 18: SINK: \t__taint_sink(m[\"key2\"])\n==========================================================\n #Total-findings:1\n==========================================================","/benchmarks/sast-go/cases/accuracy/field_sensitive/one_dimensional_collection/numeric_index_state_no_solver/map_field_sensitive_005_F/map_field_sensitive_005_F":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/sast-go/cases/accuracy/field_sensitive/one_dimensional_collection/numeric_index_state_no_solver/map_field_sensitive_005_F/map_field_sensitive_005_F.go\nLine 17: __taint_sink(m.\"key1\")\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/sast-go/cases/accuracy/field_sensitive/one_dimensional_collection/numeric_index_state_no_solver/map_field_sensitive_005_F/map_field_sensitive_005_F.go\",\"functionName\":\"main\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /sast-go/cases/accuracy/field_sensitive/one_dimensional_collection/numeric_index_state_no_solver/map_field_sensitive_005_F/map_field_sensitive_005_F.go\n AffectedNodeName: __taint_src\n 24: SOURCE: map_field_sensitive_005_F(__taint_src)\n /sast-go/cases/accuracy/field_sensitive/one_dimensional_collection/numeric_index_state_no_solver/map_field_sensitive_005_F/map_field_sensitive_005_F.go\n AffectedNodeName: map_field_sensitive_005_F\n 24: CALL: map_field_sensitive_005_F(__taint_src)\n /sast-go/cases/accuracy/field_sensitive/one_dimensional_collection/numeric_index_state_no_solver/map_field_sensitive_005_F/map_field_sensitive_005_F.go\n AffectedNodeName: __taint_src\n 12: ARG PASS: func map_field_sensitive_005_F(__taint_src string) {\n /sast-go/cases/accuracy/field_sensitive/one_dimensional_collection/numeric_index_state_no_solver/map_field_sensitive_005_F/map_field_sensitive_005_F.go\n AffectedNodeName: m[\"key1\"]\n 14: Var Pass: \tm[\"key1\"] = __taint_src\n /sast-go/cases/accuracy/field_sensitive/one_dimensional_collection/numeric_index_state_no_solver/map_field_sensitive_005_F/map_field_sensitive_005_F.go\n AffectedNodeName: __taint_sink\n 17: SINK: \t__taint_sink(m[\"key1\"])\n==========================================================\n #Total-findings:1\n==========================================================","/benchmarks/sast-go/cases/accuracy/field_sensitive/one_dimensional_collection/numeric_index_state_no_solver/slice_index_001_T/slice_index_001_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/sast-go/cases/accuracy/field_sensitive/one_dimensional_collection/numeric_index_state_no_solver/slice_index_001_T/slice_index_001_T.go\nLine 14: __taint_sink(s.0)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/sast-go/cases/accuracy/field_sensitive/one_dimensional_collection/numeric_index_state_no_solver/slice_index_001_T/slice_index_001_T.go\",\"functionName\":\"main\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /sast-go/cases/accuracy/field_sensitive/one_dimensional_collection/numeric_index_state_no_solver/slice_index_001_T/slice_index_001_T.go\n AffectedNodeName: __taint_src\n 21: SOURCE: slice_index_001_T(__taint_src)\n /sast-go/cases/accuracy/field_sensitive/one_dimensional_collection/numeric_index_state_no_solver/slice_index_001_T/slice_index_001_T.go\n AffectedNodeName: slice_index_001_T\n 21: CALL: slice_index_001_T(__taint_src)\n /sast-go/cases/accuracy/field_sensitive/one_dimensional_collection/numeric_index_state_no_solver/slice_index_001_T/slice_index_001_T.go\n AffectedNodeName: __taint_src\n 12: ARG PASS: func slice_index_001_T(__taint_src string) {\n /sast-go/cases/accuracy/field_sensitive/one_dimensional_collection/numeric_index_state_no_solver/slice_index_001_T/slice_index_001_T.go\n AffectedNodeName: s\n 13: Var Pass: \tvar s []string = []string{__taint_src, \"b\", \"c\"}\n /sast-go/cases/accuracy/field_sensitive/one_dimensional_collection/numeric_index_state_no_solver/slice_index_001_T/slice_index_001_T.go\n AffectedNodeName: __taint_sink\n 14: SINK: \t__taint_sink(s[0])\n==========================================================\n #Total-findings:1\n==========================================================","/benchmarks/sast-go/cases/accuracy/field_sensitive/one_dimensional_collection/numeric_index_state_no_solver/slice_index_002_F/slice_index_002_F":"======================== Findings ========================\nNo findings!\n==========================================================","/benchmarks/sast-go/cases/accuracy/field_sensitive/one_dimensional_collection/numeric_index_state_no_solver/slice_index_005_T/slice_index_005_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/sast-go/cases/accuracy/field_sensitive/one_dimensional_collection/numeric_index_state_no_solver/slice_index_005_T/slice_index_005_T.go\nLine 16: __taint_sink(s.0)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/sast-go/cases/accuracy/field_sensitive/one_dimensional_collection/numeric_index_state_no_solver/slice_index_005_T/slice_index_005_T.go\",\"functionName\":\"main\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /sast-go/cases/accuracy/field_sensitive/one_dimensional_collection/numeric_index_state_no_solver/slice_index_005_T/slice_index_005_T.go\n AffectedNodeName: __taint_src\n 23: SOURCE: slice_index_005_T(__taint_src)\n /sast-go/cases/accuracy/field_sensitive/one_dimensional_collection/numeric_index_state_no_solver/slice_index_005_T/slice_index_005_T.go\n AffectedNodeName: slice_index_005_T\n 23: CALL: slice_index_005_T(__taint_src)\n /sast-go/cases/accuracy/field_sensitive/one_dimensional_collection/numeric_index_state_no_solver/slice_index_005_T/slice_index_005_T.go\n AffectedNodeName: __taint_src\n 12: ARG PASS: func slice_index_005_T(__taint_src string) {\n /sast-go/cases/accuracy/field_sensitive/one_dimensional_collection/numeric_index_state_no_solver/slice_index_005_T/slice_index_005_T.go\n AffectedNodeName: arr\n 13: Var Pass: \tvar arr [3]string = [3]string{__taint_src, \"b\", \"c\"}\n /sast-go/cases/accuracy/field_sensitive/one_dimensional_collection/numeric_index_state_no_solver/slice_index_005_T/slice_index_005_T.go\n AffectedNodeName: s\n 15: Var Pass: \ts = arr[:]\n /sast-go/cases/accuracy/field_sensitive/one_dimensional_collection/numeric_index_state_no_solver/slice_index_005_T/slice_index_005_T.go\n AffectedNodeName: __taint_sink\n 16: SINK: \t__taint_sink(s[0])\n==========================================================\n #Total-findings:1\n==========================================================","/benchmarks/sast-go/cases/accuracy/field_sensitive/one_dimensional_collection/numeric_index_state_no_solver/slice_index_006_F/slice_index_006_F":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/sast-go/cases/accuracy/field_sensitive/one_dimensional_collection/numeric_index_state_no_solver/slice_index_006_F/slice_index_006_F.go\nLine 16: __taint_sink(s.0)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/sast-go/cases/accuracy/field_sensitive/one_dimensional_collection/numeric_index_state_no_solver/slice_index_006_F/slice_index_006_F.go\",\"functionName\":\"main\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /sast-go/cases/accuracy/field_sensitive/one_dimensional_collection/numeric_index_state_no_solver/slice_index_006_F/slice_index_006_F.go\n AffectedNodeName: __taint_src\n 23: SOURCE: slice_index_006_F(__taint_src)\n /sast-go/cases/accuracy/field_sensitive/one_dimensional_collection/numeric_index_state_no_solver/slice_index_006_F/slice_index_006_F.go\n AffectedNodeName: slice_index_006_F\n 23: CALL: slice_index_006_F(__taint_src)\n /sast-go/cases/accuracy/field_sensitive/one_dimensional_collection/numeric_index_state_no_solver/slice_index_006_F/slice_index_006_F.go\n AffectedNodeName: __taint_src\n 12: ARG PASS: func slice_index_006_F(__taint_src string) {\n /sast-go/cases/accuracy/field_sensitive/one_dimensional_collection/numeric_index_state_no_solver/slice_index_006_F/slice_index_006_F.go\n AffectedNodeName: arr\n 13: Var Pass: \tvar arr [3]string = [3]string{__taint_src, \"b\", \"c\"}\n /sast-go/cases/accuracy/field_sensitive/one_dimensional_collection/numeric_index_state_no_solver/slice_index_006_F/slice_index_006_F.go\n AffectedNodeName: s\n 15: Var Pass: \ts = arr[1:]\n /sast-go/cases/accuracy/field_sensitive/one_dimensional_collection/numeric_index_state_no_solver/slice_index_006_F/slice_index_006_F.go\n AffectedNodeName: __taint_sink\n 16: SINK: \t__taint_sink(s[0])\n==========================================================\n #Total-findings:1\n==========================================================","/benchmarks/sast-go/cases/accuracy/field_sensitive/one_dimensional_collection/numeric_index_state_solver/array_index_007_T/array_index_007_T":"======================== Findings ========================\nNo findings!\n==========================================================","/benchmarks/sast-go/cases/accuracy/field_sensitive/one_dimensional_collection/numeric_index_state_solver/array_index_008_F/array_index_008_F":"======================== Findings ========================\nNo findings!\n==========================================================","/benchmarks/sast-go/cases/accuracy/field_sensitive/struct/field_len_001_T/field_len_001_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/sast-go/cases/accuracy/field_sensitive/struct/field_len_001_T/field_len_001_T.go\nLine 30: __taint_sink(c.b.a.data)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/sast-go/cases/accuracy/field_sensitive/struct/field_len_001_T/field_len_001_T.go\",\"functionName\":\"main\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /sast-go/cases/accuracy/field_sensitive/struct/field_len_001_T/field_len_001_T.go\n AffectedNodeName: __taint_src\n 37: SOURCE: field_len_001_T(__taint_src)\n /sast-go/cases/accuracy/field_sensitive/struct/field_len_001_T/field_len_001_T.go\n AffectedNodeName: field_len_001_T\n 37: CALL: field_len_001_T(__taint_src)\n /sast-go/cases/accuracy/field_sensitive/struct/field_len_001_T/field_len_001_T.go\n AffectedNodeName: __taint_src\n 22: ARG PASS: func field_len_001_T(__taint_src string) {\n /sast-go/cases/accuracy/field_sensitive/struct/field_len_001_T/field_len_001_T.go\n AffectedNodeName: pa\n 23: Var Pass: \tpa := A{\n 24: Var Pass: \t\tdata: __taint_src,\n 25: Var Pass: \t}\n /sast-go/cases/accuracy/field_sensitive/struct/field_len_001_T/field_len_001_T.go\n AffectedNodeName: b.a\n 27: Var Pass: \tb.a = pa\n /sast-go/cases/accuracy/field_sensitive/struct/field_len_001_T/field_len_001_T.go\n AffectedNodeName: c.b\n 29: Var Pass: \tc.b = b\n /sast-go/cases/accuracy/field_sensitive/struct/field_len_001_T/field_len_001_T.go\n AffectedNodeName: __taint_sink\n 30: SINK: \t__taint_sink(c.b.a.data)\n==========================================================\n #Total-findings:1\n==========================================================","/benchmarks/sast-go/cases/accuracy/field_sensitive/struct/field_len_002_F/field_len_002_F":"======================== Findings ========================\nNo findings!\n==========================================================","/benchmarks/sast-go/cases/accuracy/field_sensitive/struct/field_len_003_T/field_len_003_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/sast-go/cases/accuracy/field_sensitive/struct/field_len_003_T/field_len_003_T.go\nLine 100: __taint_sink(q.p.o.n.m.l.k.j.i.h.g.f.e.d.c.b.a.data)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/sast-go/cases/accuracy/field_sensitive/struct/field_len_003_T/field_len_003_T.go\",\"functionName\":\"main\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /sast-go/cases/accuracy/field_sensitive/struct/field_len_003_T/field_len_003_T.go\n AffectedNodeName: __taint_src\n 107: SOURCE: field_len_003_T(__taint_src)\n /sast-go/cases/accuracy/field_sensitive/struct/field_len_003_T/field_len_003_T.go\n AffectedNodeName: field_len_003_T\n 107: CALL: field_len_003_T(__taint_src)\n /sast-go/cases/accuracy/field_sensitive/struct/field_len_003_T/field_len_003_T.go\n AffectedNodeName: __taint_src\n 64: ARG PASS: func field_len_003_T(__taint_src string) {\n /sast-go/cases/accuracy/field_sensitive/struct/field_len_003_T/field_len_003_T.go\n AffectedNodeName: pa\n 65: Var Pass: \tpa := A{\n 66: Var Pass: \t\tdata: __taint_src,\n 67: Var Pass: \t}\n /sast-go/cases/accuracy/field_sensitive/struct/field_len_003_T/field_len_003_T.go\n AffectedNodeName: b.a\n 69: Var Pass: \tb.a = pa\n /sast-go/cases/accuracy/field_sensitive/struct/field_len_003_T/field_len_003_T.go\n AffectedNodeName: c.b\n 71: Var Pass: \tc.b = b\n /sast-go/cases/accuracy/field_sensitive/struct/field_len_003_T/field_len_003_T.go\n AffectedNodeName: d.c\n 73: Var Pass: \td.c = c\n /sast-go/cases/accuracy/field_sensitive/struct/field_len_003_T/field_len_003_T.go\n AffectedNodeName: e.d\n 75: Var Pass: \te.d = d\n /sast-go/cases/accuracy/field_sensitive/struct/field_len_003_T/field_len_003_T.go\n AffectedNodeName: f.e\n 77: Var Pass: \tf.e = e\n /sast-go/cases/accuracy/field_sensitive/struct/field_len_003_T/field_len_003_T.go\n AffectedNodeName: g.f\n 79: Var Pass: \tg.f = f\n /sast-go/cases/accuracy/field_sensitive/struct/field_len_003_T/field_len_003_T.go\n AffectedNodeName: h.g\n 81: Var Pass: \th.g = g\n /sast-go/cases/accuracy/field_sensitive/struct/field_len_003_T/field_len_003_T.go\n AffectedNodeName: i.h\n 83: Var Pass: \ti.h = h\n /sast-go/cases/accuracy/field_sensitive/struct/field_len_003_T/field_len_003_T.go\n AffectedNodeName: j.i\n 85: Var Pass: \tj.i = i\n /sast-go/cases/accuracy/field_sensitive/struct/field_len_003_T/field_len_003_T.go\n AffectedNodeName: k.j\n 87: Var Pass: \tk.j = j\n /sast-go/cases/accuracy/field_sensitive/struct/field_len_003_T/field_len_003_T.go\n AffectedNodeName: l.k\n 89: Var Pass: \tl.k = k\n /sast-go/cases/accuracy/field_sensitive/struct/field_len_003_T/field_len_003_T.go\n AffectedNodeName: m.l\n 91: Var Pass: \tm.l = l\n /sast-go/cases/accuracy/field_sensitive/struct/field_len_003_T/field_len_003_T.go\n AffectedNodeName: n.m\n 93: Var Pass: \tn.m = m\n /sast-go/cases/accuracy/field_sensitive/struct/field_len_003_T/field_len_003_T.go\n AffectedNodeName: o.n\n 95: Var Pass: \to.n = n\n /sast-go/cases/accuracy/field_sensitive/struct/field_len_003_T/field_len_003_T.go\n AffectedNodeName: p.o\n 97: Var Pass: \tp.o = o\n /sast-go/cases/accuracy/field_sensitive/struct/field_len_003_T/field_len_003_T.go\n AffectedNodeName: q.p\n 99: Var Pass: \tq.p = p\n /sast-go/cases/accuracy/field_sensitive/struct/field_len_003_T/field_len_003_T.go\n AffectedNodeName: __taint_sink\n 100: SINK: \t__taint_sink(q.p.o.n.m.l.k.j.i.h.g.f.e.d.c.b.a.data)\n==========================================================\n #Total-findings:1\n==========================================================","/benchmarks/sast-go/cases/accuracy/field_sensitive/struct/field_len_004_F/field_len_004_F":"======================== Findings ========================\nNo findings!\n==========================================================","/benchmarks/sast-go/cases/accuracy/field_sensitive/struct/field_len_005_T/field_len_005_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/sast-go/cases/accuracy/field_sensitive/struct/field_len_005_T/field_len_005_T.go\nLine 47: __taint_sink(q)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/sast-go/cases/accuracy/field_sensitive/struct/field_len_005_T/field_len_005_T.go\",\"functionName\":\"main\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /sast-go/cases/accuracy/field_sensitive/struct/field_len_005_T/field_len_005_T.go\n AffectedNodeName: __taint_src\n 54: SOURCE: field_len_005_T(__taint_src)\n /sast-go/cases/accuracy/field_sensitive/struct/field_len_005_T/field_len_005_T.go\n AffectedNodeName: field_len_005_T\n 54: CALL: field_len_005_T(__taint_src)\n /sast-go/cases/accuracy/field_sensitive/struct/field_len_005_T/field_len_005_T.go\n AffectedNodeName: __taint_src\n 31: ARG PASS: func field_len_005_T(__taint_src string) {\n /sast-go/cases/accuracy/field_sensitive/struct/field_len_005_T/field_len_005_T.go\n AffectedNodeName: pa\n 32: Var Pass: \tpa := A{\n 33: Var Pass: \t\tdata: __taint_src,\n 34: Var Pass: \t}\n /sast-go/cases/accuracy/field_sensitive/struct/field_len_005_T/field_len_005_T.go\n AffectedNodeName: b.a\n 36: Var Pass: \tb.a = pa\n /sast-go/cases/accuracy/field_sensitive/struct/field_len_005_T/field_len_005_T.go\n AffectedNodeName: c.b\n 38: Var Pass: \tc.b = b\n /sast-go/cases/accuracy/field_sensitive/struct/field_len_005_T/field_len_005_T.go\n AffectedNodeName: d.c\n 40: Var Pass: \td.c = c\n /sast-go/cases/accuracy/field_sensitive/struct/field_len_005_T/field_len_005_T.go\n AffectedNodeName: e.d\n 42: Var Pass: \te.d = d\n /sast-go/cases/accuracy/field_sensitive/struct/field_len_005_T/field_len_005_T.go\n AffectedNodeName: f.e\n 44: Var Pass: \tf.e = e\n /sast-go/cases/accuracy/field_sensitive/struct/field_len_005_T/field_len_005_T.go\n AffectedNodeName: p\n 45: Var Pass: \tp := f.e.d.c\n /sast-go/cases/accuracy/field_sensitive/struct/field_len_005_T/field_len_005_T.go\n AffectedNodeName: q\n 46: Var Pass: \tq := p.b.a.data\n /sast-go/cases/accuracy/field_sensitive/struct/field_len_005_T/field_len_005_T.go\n AffectedNodeName: __taint_sink\n 47: SINK: \t__taint_sink(q)\n==========================================================\n #Total-findings:1\n==========================================================","/benchmarks/sast-go/cases/accuracy/field_sensitive/struct/field_len_006_F/field_len_006_F":"======================== Findings ========================\nNo findings!\n==========================================================","/benchmarks/sast-go/cases/accuracy/field_sensitive/struct/struct_field_001_T/struct_field_001_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/sast-go/cases/accuracy/field_sensitive/struct/struct_field_001_T/struct_field_001_T.go\nLine 22: __taint_sink(p.data)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/sast-go/cases/accuracy/field_sensitive/struct/struct_field_001_T/struct_field_001_T.go\",\"functionName\":\"main\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /sast-go/cases/accuracy/field_sensitive/struct/struct_field_001_T/struct_field_001_T.go\n AffectedNodeName: __taint_src\n 29: SOURCE: struct_field_001_T(__taint_src)\n /sast-go/cases/accuracy/field_sensitive/struct/struct_field_001_T/struct_field_001_T.go\n AffectedNodeName: struct_field_001_T\n 29: CALL: struct_field_001_T(__taint_src)\n /sast-go/cases/accuracy/field_sensitive/struct/struct_field_001_T/struct_field_001_T.go\n AffectedNodeName: __taint_src\n 17: ARG PASS: func struct_field_001_T(__taint_src string) {\n /sast-go/cases/accuracy/field_sensitive/struct/struct_field_001_T/struct_field_001_T.go\n AffectedNodeName: p\n 18: Var Pass: \tp := A{\n 19: Var Pass: \t\tdata: __taint_src,\n 20: Var Pass: \t\tsani: \"_\",\n 21: Var Pass: \t}\n /sast-go/cases/accuracy/field_sensitive/struct/struct_field_001_T/struct_field_001_T.go\n AffectedNodeName: __taint_sink\n 22: SINK: \t__taint_sink(p.data)\n==========================================================\n #Total-findings:1\n==========================================================","/benchmarks/sast-go/cases/accuracy/field_sensitive/struct/struct_field_002_F/struct_field_002_F":"======================== Findings ========================\nNo findings!\n==========================================================","/benchmarks/sast-go/cases/accuracy/field_sensitive/struct/struct_field_003_T/struct_field_003_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/sast-go/cases/accuracy/field_sensitive/struct/struct_field_003_T/struct_field_003_T.go\nLine 21: __taint_sink(p1.data)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/sast-go/cases/accuracy/field_sensitive/struct/struct_field_003_T/struct_field_003_T.go\",\"functionName\":\"main\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /sast-go/cases/accuracy/field_sensitive/struct/struct_field_003_T/struct_field_003_T.go\n AffectedNodeName: __taint_src\n 28: SOURCE: struct_field_003_T(__taint_src)\n /sast-go/cases/accuracy/field_sensitive/struct/struct_field_003_T/struct_field_003_T.go\n AffectedNodeName: struct_field_003_T\n 28: CALL: struct_field_003_T(__taint_src)\n /sast-go/cases/accuracy/field_sensitive/struct/struct_field_003_T/struct_field_003_T.go\n AffectedNodeName: __taint_src\n 17: ARG PASS: func struct_field_003_T(__taint_src string) {\n /sast-go/cases/accuracy/field_sensitive/struct/struct_field_003_T/struct_field_003_T.go\n AffectedNodeName: p1.data\n 19: Var Pass: \tp1.data = __taint_src\n /sast-go/cases/accuracy/field_sensitive/struct/struct_field_003_T/struct_field_003_T.go\n AffectedNodeName: __taint_sink\n 21: SINK: \t__taint_sink(p1.data)\n==========================================================\n #Total-findings:1\n==========================================================","/benchmarks/sast-go/cases/accuracy/field_sensitive/struct/struct_field_004_F/struct_field_004_F":"======================== Findings ========================\nNo findings!\n==========================================================","/benchmarks/sast-go/cases/accuracy/field_sensitive/struct/struct_field_005_T/struct_field_005_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/sast-go/cases/accuracy/field_sensitive/struct/struct_field_005_T/struct_field_005_T.go\nLine 19: __taint_sink(p1.string)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/sast-go/cases/accuracy/field_sensitive/struct/struct_field_005_T/struct_field_005_T.go\",\"functionName\":\"main\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /sast-go/cases/accuracy/field_sensitive/struct/struct_field_005_T/struct_field_005_T.go\n AffectedNodeName: __taint_src\n 26: SOURCE: struct_field_005_T(__taint_src)\n /sast-go/cases/accuracy/field_sensitive/struct/struct_field_005_T/struct_field_005_T.go\n AffectedNodeName: struct_field_005_T\n 26: CALL: struct_field_005_T(__taint_src)\n /sast-go/cases/accuracy/field_sensitive/struct/struct_field_005_T/struct_field_005_T.go\n AffectedNodeName: __taint_src\n 16: ARG PASS: func struct_field_005_T(__taint_src string) {\n /sast-go/cases/accuracy/field_sensitive/struct/struct_field_005_T/struct_field_005_T.go\n AffectedNodeName: p1.string\n 18: Var Pass: \tp1.string = __taint_src\n /sast-go/cases/accuracy/field_sensitive/struct/struct_field_005_T/struct_field_005_T.go\n AffectedNodeName: __taint_sink\n 19: SINK: \t__taint_sink(p1.string)\n==========================================================\n #Total-findings:1\n==========================================================","/benchmarks/sast-go/cases/accuracy/field_sensitive/struct/struct_field_006_F/struct_field_006_F":"======================== Findings ========================\nNo findings!\n==========================================================","/benchmarks/sast-go/cases/accuracy/flow_sensitive/asynchronous/asynchronous_execution_001_T/asynchronous_execution_001_T":"======================== Findings ========================\nNo findings!\n==========================================================","/benchmarks/sast-go/cases/accuracy/flow_sensitive/asynchronous/asynchronous_execution_002_F/asynchronous_execution_002_F":"======================== Findings ========================\nNo findings!\n==========================================================","/benchmarks/sast-go/cases/accuracy/flow_sensitive/defer_exectution/defer_exectution_001_T/defer_exectution_001_T":"======================== Findings ========================\nNo findings!\n==========================================================","/benchmarks/sast-go/cases/accuracy/flow_sensitive/defer_exectution/defer_exectution_002_F/defer_exectution_002_F":"======================== Findings ========================\nNo findings!\n==========================================================","/benchmarks/sast-go/cases/accuracy/flow_sensitive/loop_stmt/for_001_T/for_001_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/sast-go/cases/accuracy/flow_sensitive/loop_stmt/for_001_T/for_001_T.go\nLine 16: __taint_sink(res)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/sast-go/cases/accuracy/flow_sensitive/loop_stmt/for_001_T/for_001_T.go\",\"functionName\":\"main\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /sast-go/cases/accuracy/flow_sensitive/loop_stmt/for_001_T/for_001_T.go\n AffectedNodeName: __taint_src\n 23: SOURCE: for_001_T(__taint_src)\n /sast-go/cases/accuracy/flow_sensitive/loop_stmt/for_001_T/for_001_T.go\n AffectedNodeName: for_001_T\n 23: CALL: for_001_T(__taint_src)\n /sast-go/cases/accuracy/flow_sensitive/loop_stmt/for_001_T/for_001_T.go\n AffectedNodeName: __taint_src\n 12: ARG PASS: func for_001_T(__taint_src string) {\n /sast-go/cases/accuracy/flow_sensitive/loop_stmt/for_001_T/for_001_T.go\n AffectedNodeName: res\n 15: Var Pass: \t\tres = __taint_src\n /sast-go/cases/accuracy/flow_sensitive/loop_stmt/for_001_T/for_001_T.go\n AffectedNodeName: __taint_sink\n 16: SINK: \t\t__taint_sink(res)\n==========================================================\n #Total-findings:1\n==========================================================","/benchmarks/sast-go/cases/accuracy/flow_sensitive/loop_stmt/for_002_F/for_002_F":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/sast-go/cases/accuracy/flow_sensitive/loop_stmt/for_002_F/for_002_F.go\nLine 15: __taint_sink(res)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/sast-go/cases/accuracy/flow_sensitive/loop_stmt/for_002_F/for_002_F.go\",\"functionName\":\"main\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /sast-go/cases/accuracy/flow_sensitive/loop_stmt/for_002_F/for_002_F.go\n AffectedNodeName: __taint_src\n 23: SOURCE: for_002_F(__taint_src)\n /sast-go/cases/accuracy/flow_sensitive/loop_stmt/for_002_F/for_002_F.go\n AffectedNodeName: for_002_F\n 23: CALL: for_002_F(__taint_src)\n /sast-go/cases/accuracy/flow_sensitive/loop_stmt/for_002_F/for_002_F.go\n AffectedNodeName: __taint_src\n 12: ARG PASS: func for_002_F(__taint_src string) {\n /sast-go/cases/accuracy/flow_sensitive/loop_stmt/for_002_F/for_002_F.go\n AffectedNodeName: res\n 16: Var Pass: \t\tres = __taint_src\n /sast-go/cases/accuracy/flow_sensitive/loop_stmt/for_002_F/for_002_F.go\n AffectedNodeName: __taint_sink\n 15: SINK: \t\t__taint_sink(res)\n==========================================================\n #Total-findings:1\n==========================================================","/benchmarks/sast-go/cases/accuracy/flow_sensitive/loop_stmt/for_003_T/for_003_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/sast-go/cases/accuracy/flow_sensitive/loop_stmt/for_003_T/for_003_T.go\nLine 16: __taint_sink(res)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/sast-go/cases/accuracy/flow_sensitive/loop_stmt/for_003_T/for_003_T.go\",\"functionName\":\"main\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /sast-go/cases/accuracy/flow_sensitive/loop_stmt/for_003_T/for_003_T.go\n AffectedNodeName: __taint_src\n 23: SOURCE: for_003_T(__taint_src)\n /sast-go/cases/accuracy/flow_sensitive/loop_stmt/for_003_T/for_003_T.go\n AffectedNodeName: for_003_T\n 23: CALL: for_003_T(__taint_src)\n /sast-go/cases/accuracy/flow_sensitive/loop_stmt/for_003_T/for_003_T.go\n AffectedNodeName: __taint_src\n 12: ARG PASS: func for_003_T(__taint_src string) {\n /sast-go/cases/accuracy/flow_sensitive/loop_stmt/for_003_T/for_003_T.go\n AffectedNodeName: res\n 15: Var Pass: \tfor res = __taint_src; i < 1; i++ {\n /sast-go/cases/accuracy/flow_sensitive/loop_stmt/for_003_T/for_003_T.go\n AffectedNodeName: __taint_sink\n 16: SINK: \t\t__taint_sink(res)\n==========================================================\n #Total-findings:1\n==========================================================","/benchmarks/sast-go/cases/accuracy/flow_sensitive/loop_stmt/for_004_F/for_004_F":"======================== Findings ========================\nNo findings!\n==========================================================","/benchmarks/sast-go/cases/accuracy/object_sensitive/collection/array_obj_sensitive_001_T/array_obj_sensitive_001_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/sast-go/cases/accuracy/object_sensitive/collection/array_obj_sensitive_001_T/array_obj_sensitive_001_T.go\nLine 16: __taint_sink(str)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/sast-go/cases/accuracy/object_sensitive/collection/array_obj_sensitive_001_T/array_obj_sensitive_001_T.go\",\"functionName\":\"main\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /sast-go/cases/accuracy/object_sensitive/collection/array_obj_sensitive_001_T/array_obj_sensitive_001_T.go\n AffectedNodeName: __taint_src\n 23: SOURCE: array_obj_sensitive_001_T(__taint_src)\n /sast-go/cases/accuracy/object_sensitive/collection/array_obj_sensitive_001_T/array_obj_sensitive_001_T.go\n AffectedNodeName: array_obj_sensitive_001_T\n 23: CALL: array_obj_sensitive_001_T(__taint_src)\n /sast-go/cases/accuracy/object_sensitive/collection/array_obj_sensitive_001_T/array_obj_sensitive_001_T.go\n AffectedNodeName: __taint_src\n 12: ARG PASS: func array_obj_sensitive_001_T(__taint_src string) {\n /sast-go/cases/accuracy/object_sensitive/collection/array_obj_sensitive_001_T/array_obj_sensitive_001_T.go\n AffectedNodeName: str\n 13: Var Pass: \tvar str = [3]string{__taint_src, \"b\", \"c\"}\n /sast-go/cases/accuracy/object_sensitive/collection/array_obj_sensitive_001_T/array_obj_sensitive_001_T.go\n AffectedNodeName: __taint_sink\n 16: SINK: \t__taint_sink(str)\n==========================================================\n #Total-findings:1\n==========================================================","/benchmarks/sast-go/cases/accuracy/object_sensitive/collection/array_obj_sensitive_002_F/array_obj_sensitive_002_F":"======================== Findings ========================\nNo findings!\n==========================================================","/benchmarks/sast-go/cases/accuracy/object_sensitive/collection/array_obj_sensitive_003_T/array_obj_sensitive_003_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/sast-go/cases/accuracy/object_sensitive/collection/array_obj_sensitive_003_T/array_obj_sensitive_003_T.go\nLine 16: __taint_sink(str)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/sast-go/cases/accuracy/object_sensitive/collection/array_obj_sensitive_003_T/array_obj_sensitive_003_T.go\",\"functionName\":\"main\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /sast-go/cases/accuracy/object_sensitive/collection/array_obj_sensitive_003_T/array_obj_sensitive_003_T.go\n AffectedNodeName: __taint_src\n 23: SOURCE: array_obj_sensitive_003_T(__taint_src)\n /sast-go/cases/accuracy/object_sensitive/collection/array_obj_sensitive_003_T/array_obj_sensitive_003_T.go\n AffectedNodeName: array_obj_sensitive_003_T\n 23: CALL: array_obj_sensitive_003_T(__taint_src)\n /sast-go/cases/accuracy/object_sensitive/collection/array_obj_sensitive_003_T/array_obj_sensitive_003_T.go\n AffectedNodeName: __taint_src\n 12: ARG PASS: func array_obj_sensitive_003_T(__taint_src string) {\n /sast-go/cases/accuracy/object_sensitive/collection/array_obj_sensitive_003_T/array_obj_sensitive_003_T.go\n AffectedNodeName: str\n 13: Var Pass: \tvar str = [3][1]string{[1]string{__taint_src}, [1]string{\"b\"}, [1]string{\"c\"}}\n /sast-go/cases/accuracy/object_sensitive/collection/array_obj_sensitive_003_T/array_obj_sensitive_003_T.go\n AffectedNodeName: __taint_sink\n 16: SINK: \t__taint_sink(str)\n==========================================================\n #Total-findings:1\n==========================================================","/benchmarks/sast-go/cases/accuracy/object_sensitive/collection/array_obj_sensitive_004_F/array_obj_sensitive_004_F":"======================== Findings ========================\nNo findings!\n==========================================================","/benchmarks/sast-go/cases/accuracy/object_sensitive/collection/array_obj_sensitive_007_T/array_obj_sensitive_007_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/sast-go/cases/accuracy/object_sensitive/collection/array_obj_sensitive_007_T/array_obj_sensitive_007_T.go\nLine 16: __taint_sink(str)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/sast-go/cases/accuracy/object_sensitive/collection/array_obj_sensitive_007_T/array_obj_sensitive_007_T.go\",\"functionName\":\"main\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /sast-go/cases/accuracy/object_sensitive/collection/array_obj_sensitive_007_T/array_obj_sensitive_007_T.go\n AffectedNodeName: __taint_src\n 22: SOURCE: array_obj_sensitive_007_T(__taint_src)\n /sast-go/cases/accuracy/object_sensitive/collection/array_obj_sensitive_007_T/array_obj_sensitive_007_T.go\n AffectedNodeName: array_obj_sensitive_007_T\n 22: CALL: array_obj_sensitive_007_T(__taint_src)\n /sast-go/cases/accuracy/object_sensitive/collection/array_obj_sensitive_007_T/array_obj_sensitive_007_T.go\n AffectedNodeName: __taint_src\n 12: ARG PASS: func array_obj_sensitive_007_T(__taint_src string) {\n /sast-go/cases/accuracy/object_sensitive/collection/array_obj_sensitive_007_T/array_obj_sensitive_007_T.go\n AffectedNodeName: str\n 13: Var Pass: \tvar str = [...]string{__taint_src, \"b\", \"c\"}\n /sast-go/cases/accuracy/object_sensitive/collection/array_obj_sensitive_007_T/array_obj_sensitive_007_T.go\n AffectedNodeName: __taint_sink\n 16: SINK: \t__taint_sink(str)\n==========================================================\n #Total-findings:1\n==========================================================","/benchmarks/sast-go/cases/accuracy/object_sensitive/collection/array_obj_sensitive_008_F/array_obj_sensitive_008_F":"======================== Findings ========================\nNo findings!\n==========================================================","/benchmarks/sast-go/cases/accuracy/object_sensitive/collection/map_obj_sensitive_001_T/map_obj_sensitive_001_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/sast-go/cases/accuracy/object_sensitive/collection/map_obj_sensitive_001_T/map_obj_sensitive_001_T.go\nLine 17: __taint_sink(m)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/sast-go/cases/accuracy/object_sensitive/collection/map_obj_sensitive_001_T/map_obj_sensitive_001_T.go\",\"functionName\":\"main\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /sast-go/cases/accuracy/object_sensitive/collection/map_obj_sensitive_001_T/map_obj_sensitive_001_T.go\n AffectedNodeName: __taint_src\n 24: SOURCE: map_obj_sensitive_001_T(__taint_src)\n /sast-go/cases/accuracy/object_sensitive/collection/map_obj_sensitive_001_T/map_obj_sensitive_001_T.go\n AffectedNodeName: map_obj_sensitive_001_T\n 24: CALL: map_obj_sensitive_001_T(__taint_src)\n /sast-go/cases/accuracy/object_sensitive/collection/map_obj_sensitive_001_T/map_obj_sensitive_001_T.go\n AffectedNodeName: __taint_src\n 12: ARG PASS: func map_obj_sensitive_001_T(__taint_src string) {\n /sast-go/cases/accuracy/object_sensitive/collection/map_obj_sensitive_001_T/map_obj_sensitive_001_T.go\n AffectedNodeName: m[\"key1\"]\n 15: Var Pass: \tm[\"key1\"] = __taint_src\n /sast-go/cases/accuracy/object_sensitive/collection/map_obj_sensitive_001_T/map_obj_sensitive_001_T.go\n AffectedNodeName: __taint_sink\n 17: SINK: \t__taint_sink(m)\n==========================================================\n #Total-findings:1\n==========================================================","/benchmarks/sast-go/cases/accuracy/object_sensitive/collection/map_obj_sensitive_002_T/map_obj_sensitive_002_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/sast-go/cases/accuracy/object_sensitive/collection/map_obj_sensitive_002_T/map_obj_sensitive_002_T.go\nLine 15: __taint_sink(m)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/sast-go/cases/accuracy/object_sensitive/collection/map_obj_sensitive_002_T/map_obj_sensitive_002_T.go\",\"functionName\":\"main\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /sast-go/cases/accuracy/object_sensitive/collection/map_obj_sensitive_002_T/map_obj_sensitive_002_T.go\n AffectedNodeName: __taint_src\n 22: SOURCE: map_obj_sensitive_002_T(__taint_src)\n /sast-go/cases/accuracy/object_sensitive/collection/map_obj_sensitive_002_T/map_obj_sensitive_002_T.go\n AffectedNodeName: map_obj_sensitive_002_T\n 22: CALL: map_obj_sensitive_002_T(__taint_src)\n /sast-go/cases/accuracy/object_sensitive/collection/map_obj_sensitive_002_T/map_obj_sensitive_002_T.go\n AffectedNodeName: __taint_src\n 12: ARG PASS: func map_obj_sensitive_002_T(__taint_src string) {\n /sast-go/cases/accuracy/object_sensitive/collection/map_obj_sensitive_002_T/map_obj_sensitive_002_T.go\n AffectedNodeName: __taint_sink\n 15: SINK: \t__taint_sink(m)\n==========================================================\n #Total-findings:1\n==========================================================","/benchmarks/sast-go/cases/accuracy/object_sensitive/collection/map_obj_sensitive_003_F/map_obj_sensitive_003_F":"======================== Findings ========================\nNo findings!\n==========================================================","/benchmarks/sast-go/cases/accuracy/object_sensitive/collection/map_obj_sensitive_004_T/map_obj_sensitive_004_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/sast-go/cases/accuracy/object_sensitive/collection/map_obj_sensitive_004_T/map_obj_sensitive_004_T.go\nLine 20: __taint_sink(m)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/sast-go/cases/accuracy/object_sensitive/collection/map_obj_sensitive_004_T/map_obj_sensitive_004_T.go\",\"functionName\":\"main\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /sast-go/cases/accuracy/object_sensitive/collection/map_obj_sensitive_004_T/map_obj_sensitive_004_T.go\n AffectedNodeName: __taint_src\n 27: SOURCE: map_obj_sensitive_004_T(__taint_src)\n /sast-go/cases/accuracy/object_sensitive/collection/map_obj_sensitive_004_T/map_obj_sensitive_004_T.go\n AffectedNodeName: map_obj_sensitive_004_T\n 27: CALL: map_obj_sensitive_004_T(__taint_src)\n /sast-go/cases/accuracy/object_sensitive/collection/map_obj_sensitive_004_T/map_obj_sensitive_004_T.go\n AffectedNodeName: __taint_src\n 12: ARG PASS: func map_obj_sensitive_004_T(__taint_src string) {\n /sast-go/cases/accuracy/object_sensitive/collection/map_obj_sensitive_004_T/map_obj_sensitive_004_T.go\n AffectedNodeName: m\n 13: Var Pass: \tm := map[string]string{\n 14: Var Pass: \t\t\"key1\": __taint_src,\n 15: Var Pass: \t}\n /sast-go/cases/accuracy/object_sensitive/collection/map_obj_sensitive_004_T/map_obj_sensitive_004_T.go\n AffectedNodeName: __taint_sink\n 20: SINK: \t__taint_sink(m)\n==========================================================\n #Total-findings:1\n==========================================================","/benchmarks/sast-go/cases/accuracy/object_sensitive/collection/map_obj_sensitive_005_F/map_obj_sensitive_005_F":"======================== Findings ========================\nNo findings!\n==========================================================","/benchmarks/sast-go/cases/accuracy/object_sensitive/collection/slice_obj_sensitive_001_T/slice_obj_sensitive_001_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/sast-go/cases/accuracy/object_sensitive/collection/slice_obj_sensitive_001_T/slice_obj_sensitive_001_T.go\nLine 18: __taint_sink(s)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/sast-go/cases/accuracy/object_sensitive/collection/slice_obj_sensitive_001_T/slice_obj_sensitive_001_T.go\",\"functionName\":\"main\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /sast-go/cases/accuracy/object_sensitive/collection/slice_obj_sensitive_001_T/slice_obj_sensitive_001_T.go\n AffectedNodeName: __taint_src\n 25: SOURCE: slice_001slice_obj_sensitive_001_T_T(__taint_src)\n /sast-go/cases/accuracy/object_sensitive/collection/slice_obj_sensitive_001_T/slice_obj_sensitive_001_T.go\n AffectedNodeName: slice_001slice_obj_sensitive_001_T_T\n 25: CALL: slice_001slice_obj_sensitive_001_T_T(__taint_src)\n /sast-go/cases/accuracy/object_sensitive/collection/slice_obj_sensitive_001_T/slice_obj_sensitive_001_T.go\n AffectedNodeName: __taint_src\n 12: ARG PASS: func slice_001slice_obj_sensitive_001_T_T(__taint_src string) {\n /sast-go/cases/accuracy/object_sensitive/collection/slice_obj_sensitive_001_T/slice_obj_sensitive_001_T.go\n AffectedNodeName: arr\n 13: Var Pass: \tvar arr [3]string = [3]string{__taint_src, \"b\", \"c\"}\n /sast-go/cases/accuracy/object_sensitive/collection/slice_obj_sensitive_001_T/slice_obj_sensitive_001_T.go\n AffectedNodeName: s\n 17: Var Pass: \ts = arr[:]\n /sast-go/cases/accuracy/object_sensitive/collection/slice_obj_sensitive_001_T/slice_obj_sensitive_001_T.go\n AffectedNodeName: __taint_sink\n 18: SINK: \t__taint_sink(s)\n==========================================================\n #Total-findings:1\n==========================================================","/benchmarks/sast-go/cases/accuracy/object_sensitive/collection/slice_obj_sensitive_002_F/slice_obj_sensitive_002_F":"======================== Findings ========================\nNo findings!\n==========================================================","/benchmarks/sast-go/cases/accuracy/object_sensitive/collection/slice_obj_sensitive_003_T/slice_obj_sensitive_003_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/sast-go/cases/accuracy/object_sensitive/collection/slice_obj_sensitive_003_T/slice_obj_sensitive_003_T.go\nLine 24: __taint_sink(s)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/sast-go/cases/accuracy/object_sensitive/collection/slice_obj_sensitive_003_T/slice_obj_sensitive_003_T.go\",\"functionName\":\"main\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /sast-go/cases/accuracy/object_sensitive/collection/slice_obj_sensitive_003_T/slice_obj_sensitive_003_T.go\n AffectedNodeName: __taint_src\n 31: SOURCE: slice_obj_sensitive_003_T(__taint_src)\n /sast-go/cases/accuracy/object_sensitive/collection/slice_obj_sensitive_003_T/slice_obj_sensitive_003_T.go\n AffectedNodeName: slice_obj_sensitive_003_T\n 31: CALL: slice_obj_sensitive_003_T(__taint_src)\n /sast-go/cases/accuracy/object_sensitive/collection/slice_obj_sensitive_003_T/slice_obj_sensitive_003_T.go\n AffectedNodeName: __taint_src\n 12: ARG PASS: func slice_obj_sensitive_003_T(__taint_src string) {\n /sast-go/cases/accuracy/object_sensitive/collection/slice_obj_sensitive_003_T/slice_obj_sensitive_003_T.go\n AffectedNodeName: s\n 13: Var Pass: \ts := [][]string{\n 14: Var Pass: \t\t[]string{\"a\"},\n 15: Var Pass: \t\t[]string{\"b\", \"c\"},\n 16: Var Pass: \t\t[]string{\"d\", \"e\", __taint_src},\n 17: Var Pass: \t}\n /sast-go/cases/accuracy/object_sensitive/collection/slice_obj_sensitive_003_T/slice_obj_sensitive_003_T.go\n AffectedNodeName: __taint_sink\n 24: SINK: \t__taint_sink(s)\n==========================================================\n #Total-findings:1\n==========================================================","/benchmarks/sast-go/cases/accuracy/object_sensitive/collection/slice_obj_sensitive_004_F/slice_obj_sensitive_004_F":"======================== Findings ========================\nNo findings!\n==========================================================","/benchmarks/sast-go/cases/accuracy/object_sensitive/interface_class/interface_class_001_F/interface_class_001_F":"======================== Findings ========================\nNo findings!\n==========================================================","/benchmarks/sast-go/cases/accuracy/object_sensitive/interface_class/interface_class_002_T/interface_class_002_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/sast-go/cases/accuracy/object_sensitive/interface_class/interface_class_002_T/interface_class_002_T.go\nLine 41: __taint_sink(res)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/sast-go/cases/accuracy/object_sensitive/interface_class/interface_class_002_T/interface_class_002_T.go\",\"functionName\":\"main\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /sast-go/cases/accuracy/object_sensitive/interface_class/interface_class_002_T/interface_class_002_T.go\n AffectedNodeName: __taint_src\n 48: SOURCE: interface_class_002_T(__taint_src)\n /sast-go/cases/accuracy/object_sensitive/interface_class/interface_class_002_T/interface_class_002_T.go\n AffectedNodeName: interface_class_002_T\n 48: CALL: interface_class_002_T(__taint_src)\n /sast-go/cases/accuracy/object_sensitive/interface_class/interface_class_002_T/interface_class_002_T.go\n AffectedNodeName: __taint_src\n 38: ARG PASS: func interface_class_002_T(__taint_src string) {\n /sast-go/cases/accuracy/object_sensitive/interface_class/interface_class_002_T/interface_class_002_T.go\n AffectedNodeName: process\n 40: CALL: \tres := iTestService.process(__taint_src)\n /sast-go/cases/accuracy/object_sensitive/interface_class/interface_class_002_T/interface_class_002_T.go\n AffectedNodeName: process\n 40: CALL RETURN: \tres := iTestService.process(__taint_src)\n /sast-go/cases/accuracy/object_sensitive/interface_class/interface_class_002_T/interface_class_002_T.go\n AffectedNodeName: res\n 40: Var Pass: \tres := iTestService.process(__taint_src)\n /sast-go/cases/accuracy/object_sensitive/interface_class/interface_class_002_T/interface_class_002_T.go\n AffectedNodeName: __taint_sink\n 41: SINK: \t__taint_sink(res)\n==========================================================\n #Total-findings:1\n==========================================================","/benchmarks/sast-go/cases/accuracy/object_sensitive/interface_class/interface_class_003_F/interface_class_003_F":"======================== Findings ========================\nNo findings!\n==========================================================","/benchmarks/sast-go/cases/accuracy/object_sensitive/interface_class/interface_class_004_T/interface_class_004_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/sast-go/cases/accuracy/object_sensitive/interface_class/interface_class_004_T/interface_class_004_T.go\nLine 47: __taint_sink(res)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/sast-go/cases/accuracy/object_sensitive/interface_class/interface_class_004_T/interface_class_004_T.go\",\"functionName\":\"main\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /sast-go/cases/accuracy/object_sensitive/interface_class/interface_class_004_T/interface_class_004_T.go\n AffectedNodeName: __taint_src\n 54: SOURCE: interface_class_004_T(__taint_src)\n /sast-go/cases/accuracy/object_sensitive/interface_class/interface_class_004_T/interface_class_004_T.go\n AffectedNodeName: interface_class_004_T\n 54: CALL: interface_class_004_T(__taint_src)\n /sast-go/cases/accuracy/object_sensitive/interface_class/interface_class_004_T/interface_class_004_T.go\n AffectedNodeName: __taint_src\n 44: ARG PASS: func interface_class_004_T(__taint_src string) {\n /sast-go/cases/accuracy/object_sensitive/interface_class/interface_class_004_T/interface_class_004_T.go\n AffectedNodeName: process\n 46: CALL: \tres := iTestService.process(__taint_src)\n /sast-go/cases/accuracy/object_sensitive/interface_class/interface_class_004_T/interface_class_004_T.go\n AffectedNodeName: process\n 46: CALL RETURN: \tres := iTestService.process(__taint_src)\n /sast-go/cases/accuracy/object_sensitive/interface_class/interface_class_004_T/interface_class_004_T.go\n AffectedNodeName: res\n 46: Var Pass: \tres := iTestService.process(__taint_src)\n /sast-go/cases/accuracy/object_sensitive/interface_class/interface_class_004_T/interface_class_004_T.go\n AffectedNodeName: __taint_sink\n 47: SINK: \t__taint_sink(res)\n==========================================================\n #Total-findings:1\n==========================================================","/benchmarks/sast-go/cases/accuracy/object_sensitive/interface_class/interface_class_005_F/interface_class_005_F":"======================== Findings ========================\nNo findings!\n==========================================================","/benchmarks/sast-go/cases/accuracy/object_sensitive/interface_class/interface_class_006_T/interface_class_006_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/sast-go/cases/accuracy/object_sensitive/interface_class/interface_class_006_T/interface_class_006_T.go\nLine 39: __taint_sink(res)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/sast-go/cases/accuracy/object_sensitive/interface_class/interface_class_006_T/interface_class_006_T.go\",\"functionName\":\"main\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /sast-go/cases/accuracy/object_sensitive/interface_class/interface_class_006_T/interface_class_006_T.go\n AffectedNodeName: __taint_src\n 46: SOURCE: interface_class_006_T(__taint_src)\n /sast-go/cases/accuracy/object_sensitive/interface_class/interface_class_006_T/interface_class_006_T.go\n AffectedNodeName: interface_class_006_T\n 46: CALL: interface_class_006_T(__taint_src)\n /sast-go/cases/accuracy/object_sensitive/interface_class/interface_class_006_T/interface_class_006_T.go\n AffectedNodeName: __taint_src\n 36: ARG PASS: func interface_class_006_T(__taint_src string) {\n /sast-go/cases/accuracy/object_sensitive/interface_class/interface_class_006_T/interface_class_006_T.go\n AffectedNodeName: process\n 38: CALL: \tres := iTestService.process(__taint_src)\n /sast-go/cases/accuracy/object_sensitive/interface_class/interface_class_006_T/interface_class_006_T.go\n AffectedNodeName: process\n 38: CALL RETURN: \tres := iTestService.process(__taint_src)\n /sast-go/cases/accuracy/object_sensitive/interface_class/interface_class_006_T/interface_class_006_T.go\n AffectedNodeName: res\n 38: Var Pass: \tres := iTestService.process(__taint_src)\n /sast-go/cases/accuracy/object_sensitive/interface_class/interface_class_006_T/interface_class_006_T.go\n AffectedNodeName: __taint_sink\n 39: SINK: \t__taint_sink(res)\n==========================================================\n #Total-findings:1\n==========================================================","/benchmarks/sast-go/cases/accuracy/object_sensitive/interface_class/interface_class_007_F/interface_class_007_F":"======================== Findings ========================\nNo findings!\n==========================================================","/benchmarks/sast-go/cases/accuracy/object_sensitive/interface_class/interface_class_008_T/interface_class_008_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/sast-go/cases/accuracy/object_sensitive/interface_class/interface_class_008_T/interface_class_008_T.go\nLine 34: __taint_sink(res)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/sast-go/cases/accuracy/object_sensitive/interface_class/interface_class_008_T/interface_class_008_T.go\",\"functionName\":\"main\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /sast-go/cases/accuracy/object_sensitive/interface_class/interface_class_008_T/interface_class_008_T.go\n AffectedNodeName: __taint_src\n 41: SOURCE: interface_class_008_T(__taint_src)\n /sast-go/cases/accuracy/object_sensitive/interface_class/interface_class_008_T/interface_class_008_T.go\n AffectedNodeName: interface_class_008_T\n 41: CALL: interface_class_008_T(__taint_src)\n /sast-go/cases/accuracy/object_sensitive/interface_class/interface_class_008_T/interface_class_008_T.go\n AffectedNodeName: __taint_src\n 31: ARG PASS: func interface_class_008_T(__taint_src string) {\n /sast-go/cases/accuracy/object_sensitive/interface_class/interface_class_008_T/interface_class_008_T.go\n AffectedNodeName: process\n 33: CALL: \tres := iTestService.process(__taint_src)\n /sast-go/cases/accuracy/object_sensitive/interface_class/interface_class_008_T/interface_class_008_T.go\n AffectedNodeName: process\n 33: CALL RETURN: \tres := iTestService.process(__taint_src)\n /sast-go/cases/accuracy/object_sensitive/interface_class/interface_class_008_T/interface_class_008_T.go\n AffectedNodeName: res\n 33: Var Pass: \tres := iTestService.process(__taint_src)\n /sast-go/cases/accuracy/object_sensitive/interface_class/interface_class_008_T/interface_class_008_T.go\n AffectedNodeName: __taint_sink\n 34: SINK: \t__taint_sink(res)\n==========================================================\n #Total-findings:1\n==========================================================","/benchmarks/sast-go/cases/accuracy/object_sensitive/interface_class/interface_class_009_F/interface_class_009_F":"======================== Findings ========================\nNo findings!\n==========================================================","/benchmarks/sast-go/cases/accuracy/object_sensitive/interface_class/interface_class_010_T/interface_class_010_T":"======================== Findings ========================\nNo findings!\n==========================================================","/benchmarks/sast-go/cases/accuracy/object_sensitive/interface_class/interface_class_011_F/interface_class_011_F":"======================== Findings ========================\nNo findings!\n==========================================================","/benchmarks/sast-go/cases/accuracy/object_sensitive/interface_class/interface_class_012_T/interface_class_012_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/sast-go/cases/accuracy/object_sensitive/interface_class/interface_class_012_T/interface_class_012_T.go\nLine 46: __taint_sink(res)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/sast-go/cases/accuracy/object_sensitive/interface_class/interface_class_012_T/interface_class_012_T.go\",\"functionName\":\"interface_class_012_T\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /sast-go/cases/accuracy/object_sensitive/interface_class/interface_class_012_T/interface_class_012_T.go\n AffectedNodeName: __taint_src\n 43: SOURCE: func interface_class_012_T(__taint_src string) {\n /sast-go/cases/accuracy/object_sensitive/interface_class/interface_class_012_T/interface_class_012_T.go\n AffectedNodeName: processArg\n 45: CALL: \tres := processArg(iTestService, __taint_src)\n /sast-go/cases/accuracy/object_sensitive/interface_class/interface_class_012_T/interface_class_012_T.go\n AffectedNodeName: processArg\n 45: CALL RETURN: \tres := processArg(iTestService, __taint_src)\n /sast-go/cases/accuracy/object_sensitive/interface_class/interface_class_012_T/interface_class_012_T.go\n AffectedNodeName: res\n 45: Var Pass: \tres := processArg(iTestService, __taint_src)\n /sast-go/cases/accuracy/object_sensitive/interface_class/interface_class_012_T/interface_class_012_T.go\n AffectedNodeName: __taint_sink\n 46: SINK: \t__taint_sink(res)\n==========================================================\n #Total-findings:1\n==========================================================","/benchmarks/sast-go/cases/accuracy/object_sensitive/struct/struct_007_T/struct_007_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/sast-go/cases/accuracy/object_sensitive/struct/struct_007_T/struct_007_T.go\nLine 24: __taint_sink(p)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/sast-go/cases/accuracy/object_sensitive/struct/struct_007_T/struct_007_T.go\",\"functionName\":\"main\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /sast-go/cases/accuracy/object_sensitive/struct/struct_007_T/struct_007_T.go\n AffectedNodeName: __taint_src\n 31: SOURCE: struct_007_T(__taint_src)\n /sast-go/cases/accuracy/object_sensitive/struct/struct_007_T/struct_007_T.go\n AffectedNodeName: struct_007_T\n 31: CALL: struct_007_T(__taint_src)\n /sast-go/cases/accuracy/object_sensitive/struct/struct_007_T/struct_007_T.go\n AffectedNodeName: __taint_src\n 16: ARG PASS: func struct_007_T(__taint_src string) {\n /sast-go/cases/accuracy/object_sensitive/struct/struct_007_T/struct_007_T.go\n AffectedNodeName: p\n 17: Var Pass: \tp := A{\n 18: Var Pass: \t\tdata: __taint_src,\n 19: Var Pass: \t}\n /sast-go/cases/accuracy/object_sensitive/struct/struct_007_T/struct_007_T.go\n AffectedNodeName: __taint_sink\n 24: SINK: \t__taint_sink(p)\n==========================================================\n #Total-findings:1\n==========================================================","/benchmarks/sast-go/cases/accuracy/object_sensitive/struct/struct_008_F/struct_008_F":"======================== Findings ========================\nNo findings!\n==========================================================","/benchmarks/sast-go/cases/accuracy/object_sensitive/struct/struct_deep10_001_T/struct_deep10_001_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/sast-go/cases/accuracy/object_sensitive/struct/struct_deep10_001_T/struct_deep10_001_T.go\nLine 57: __taint_sink(obj1)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/sast-go/cases/accuracy/object_sensitive/struct/struct_deep10_001_T/struct_deep10_001_T.go\",\"functionName\":\"main\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /sast-go/cases/accuracy/object_sensitive/struct/struct_deep10_001_T/struct_deep10_001_T.go\n AffectedNodeName: __taint_src\n 65: SOURCE: struct_deep10_001_T(__taint_src)\n /sast-go/cases/accuracy/object_sensitive/struct/struct_deep10_001_T/struct_deep10_001_T.go\n AffectedNodeName: struct_deep10_001_T\n 65: CALL: struct_deep10_001_T(__taint_src)\n /sast-go/cases/accuracy/object_sensitive/struct/struct_deep10_001_T/struct_deep10_001_T.go\n AffectedNodeName: __taint_src\n 50: ARG PASS: func struct_deep10_001_T(__taint_src string) {\n /sast-go/cases/accuracy/object_sensitive/struct/struct_deep10_001_T/struct_deep10_001_T.go\n AffectedNodeName: obj1.deepA02.deepA03.deepA04.deepA05.deepA06.deepA07.deepA08.deepA09.deepA10.deepA11\n 55: Var Pass: \tobj1.deepA02.deepA03.deepA04.deepA05.deepA06.deepA07.deepA08.deepA09.deepA10.deepA11 = __taint_src\n /sast-go/cases/accuracy/object_sensitive/struct/struct_deep10_001_T/struct_deep10_001_T.go\n AffectedNodeName: __taint_sink\n 57: SINK: \t__taint_sink(obj1)\n==========================================================\n #Total-findings:1\n==========================================================","/benchmarks/sast-go/cases/accuracy/object_sensitive/struct/struct_deep10_002_F/struct_deep10_002_F":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/sast-go/cases/accuracy/object_sensitive/struct/struct_deep10_002_F/struct_deep10_002_F.go\nLine 57: __taint_sink(obj2)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/sast-go/cases/accuracy/object_sensitive/struct/struct_deep10_002_F/struct_deep10_002_F.go\",\"functionName\":\"main\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /sast-go/cases/accuracy/object_sensitive/struct/struct_deep10_002_F/struct_deep10_002_F.go\n AffectedNodeName: __taint_src\n 65: SOURCE: struct_deep10_002_F(__taint_src)\n /sast-go/cases/accuracy/object_sensitive/struct/struct_deep10_002_F/struct_deep10_002_F.go\n AffectedNodeName: struct_deep10_002_F\n 65: CALL: struct_deep10_002_F(__taint_src)\n /sast-go/cases/accuracy/object_sensitive/struct/struct_deep10_002_F/struct_deep10_002_F.go\n AffectedNodeName: __taint_src\n 50: ARG PASS: func struct_deep10_002_F(__taint_src string) {\n /sast-go/cases/accuracy/object_sensitive/struct/struct_deep10_002_F/struct_deep10_002_F.go\n AffectedNodeName: obj1.deepA02.deepA03.deepA04.deepA05.deepA06.deepA07.deepA08.deepA09.deepA10.deepA11\n 55: Var Pass: \tobj1.deepA02.deepA03.deepA04.deepA05.deepA06.deepA07.deepA08.deepA09.deepA10.deepA11 = __taint_src\n /sast-go/cases/accuracy/object_sensitive/struct/struct_deep10_002_F/struct_deep10_002_F.go\n AffectedNodeName: __taint_sink\n 57: SINK: \t__taint_sink(obj2)\n==========================================================\n #Total-findings:1\n==========================================================","/benchmarks/sast-go/cases/accuracy/object_sensitive/struct/struct_deep3_001_T/struct_deep3_001_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/sast-go/cases/accuracy/object_sensitive/struct/struct_deep3_001_T/struct_deep3_001_T.go\nLine 31: __taint_sink(obj1)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/sast-go/cases/accuracy/object_sensitive/struct/struct_deep3_001_T/struct_deep3_001_T.go\",\"functionName\":\"main\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /sast-go/cases/accuracy/object_sensitive/struct/struct_deep3_001_T/struct_deep3_001_T.go\n AffectedNodeName: __taint_src\n 39: SOURCE: struct_deep3_001_T(__taint_src)\n /sast-go/cases/accuracy/object_sensitive/struct/struct_deep3_001_T/struct_deep3_001_T.go\n AffectedNodeName: struct_deep3_001_T\n 39: CALL: struct_deep3_001_T(__taint_src)\n /sast-go/cases/accuracy/object_sensitive/struct/struct_deep3_001_T/struct_deep3_001_T.go\n AffectedNodeName: __taint_src\n 24: ARG PASS: func struct_deep3_001_T(__taint_src string) {\n /sast-go/cases/accuracy/object_sensitive/struct/struct_deep3_001_T/struct_deep3_001_T.go\n AffectedNodeName: obj1.deepC02.deepC03.deepC04\n 29: Var Pass: \tobj1.deepC02.deepC03.deepC04 = __taint_src\n /sast-go/cases/accuracy/object_sensitive/struct/struct_deep3_001_T/struct_deep3_001_T.go\n AffectedNodeName: __taint_sink\n 31: SINK: \t__taint_sink(obj1)\n==========================================================\n #Total-findings:1\n==========================================================","/benchmarks/sast-go/cases/accuracy/object_sensitive/struct/struct_deep3_002_F/struct_deep3_002_F":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/sast-go/cases/accuracy/object_sensitive/struct/struct_deep3_002_F/struct_deep3_002_F.go\nLine 30: __taint_sink(obj2)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/sast-go/cases/accuracy/object_sensitive/struct/struct_deep3_002_F/struct_deep3_002_F.go\",\"functionName\":\"main\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /sast-go/cases/accuracy/object_sensitive/struct/struct_deep3_002_F/struct_deep3_002_F.go\n AffectedNodeName: __taint_src\n 38: SOURCE: struct_deep3_002_F(__taint_src)\n /sast-go/cases/accuracy/object_sensitive/struct/struct_deep3_002_F/struct_deep3_002_F.go\n AffectedNodeName: struct_deep3_002_F\n 38: CALL: struct_deep3_002_F(__taint_src)\n /sast-go/cases/accuracy/object_sensitive/struct/struct_deep3_002_F/struct_deep3_002_F.go\n AffectedNodeName: __taint_src\n 24: ARG PASS: func struct_deep3_002_F(__taint_src string) {\n /sast-go/cases/accuracy/object_sensitive/struct/struct_deep3_002_F/struct_deep3_002_F.go\n AffectedNodeName: obj1.deepC02.deepC03.deepC04\n 29: Var Pass: \tobj1.deepC02.deepC03.deepC04 = __taint_src\n /sast-go/cases/accuracy/object_sensitive/struct/struct_deep3_002_F/struct_deep3_002_F.go\n AffectedNodeName: __taint_sink\n 30: SINK: \t__taint_sink(obj2)\n==========================================================\n #Total-findings:1\n==========================================================","/benchmarks/sast-go/cases/accuracy/object_sensitive/struct/struct_deep3_003_T/struct_deep3_003_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/sast-go/cases/accuracy/object_sensitive/struct/struct_deep3_003_T/struct_deep3_003_T.go\nLine 34: __taint_sink(obj1)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/sast-go/cases/accuracy/object_sensitive/struct/struct_deep3_003_T/struct_deep3_003_T.go\",\"functionName\":\"main\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /sast-go/cases/accuracy/object_sensitive/struct/struct_deep3_003_T/struct_deep3_003_T.go\n AffectedNodeName: __taint_src\n 42: SOURCE: struct_deep3_003_T(__taint_src)\n /sast-go/cases/accuracy/object_sensitive/struct/struct_deep3_003_T/struct_deep3_003_T.go\n AffectedNodeName: struct_deep3_003_T\n 42: CALL: struct_deep3_003_T(__taint_src)\n /sast-go/cases/accuracy/object_sensitive/struct/struct_deep3_003_T/struct_deep3_003_T.go\n AffectedNodeName: __taint_src\n 24: ARG PASS: func struct_deep3_003_T(__taint_src string) {\n /sast-go/cases/accuracy/object_sensitive/struct/struct_deep3_003_T/struct_deep3_003_T.go\n AffectedNodeName: deepC03\n 29: Var Pass: \tdeepC03 := DeepC03{\n 30: Var Pass: \t\tdeepC04: __taint_src,\n 31: Var Pass: \t}\n /sast-go/cases/accuracy/object_sensitive/struct/struct_deep3_003_T/struct_deep3_003_T.go\n AffectedNodeName: obj1.deepC02.deepC03\n 32: Var Pass: \tobj1.deepC02.deepC03 = deepC03\n /sast-go/cases/accuracy/object_sensitive/struct/struct_deep3_003_T/struct_deep3_003_T.go\n AffectedNodeName: __taint_sink\n 34: SINK: \t__taint_sink(obj1)\n==========================================================\n #Total-findings:1\n==========================================================","/benchmarks/sast-go/cases/accuracy/object_sensitive/struct/struct_deep3_004_F/struct_deep3_004_F":"======================== Findings ========================\nNo findings!\n==========================================================","/benchmarks/sast-go/cases/accuracy/object_sensitive/struct/struct_deep5_001_T/struct_deep5_001_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/sast-go/cases/accuracy/object_sensitive/struct/struct_deep5_001_T/struct_deep5_001_T.go\nLine 35: __taint_sink(obj1)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/sast-go/cases/accuracy/object_sensitive/struct/struct_deep5_001_T/struct_deep5_001_T.go\",\"functionName\":\"main\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /sast-go/cases/accuracy/object_sensitive/struct/struct_deep5_001_T/struct_deep5_001_T.go\n AffectedNodeName: __taint_src\n 43: SOURCE: struct_deep5_001_T(__taint_src)\n /sast-go/cases/accuracy/object_sensitive/struct/struct_deep5_001_T/struct_deep5_001_T.go\n AffectedNodeName: struct_deep5_001_T\n 43: CALL: struct_deep5_001_T(__taint_src)\n /sast-go/cases/accuracy/object_sensitive/struct/struct_deep5_001_T/struct_deep5_001_T.go\n AffectedNodeName: __taint_src\n 28: ARG PASS: func struct_deep5_001_T(__taint_src string) {\n /sast-go/cases/accuracy/object_sensitive/struct/struct_deep5_001_T/struct_deep5_001_T.go\n AffectedNodeName: obj1.deepB02.deepB03.deepB04.deepB05\n 33: Var Pass: \tobj1.deepB02.deepB03.deepB04.deepB05 = __taint_src\n /sast-go/cases/accuracy/object_sensitive/struct/struct_deep5_001_T/struct_deep5_001_T.go\n AffectedNodeName: __taint_sink\n 35: SINK: \t__taint_sink(obj1)\n==========================================================\n #Total-findings:1\n==========================================================","/benchmarks/sast-go/cases/accuracy/object_sensitive/struct/struct_deep5_002_F/struct_deep5_002_F":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/sast-go/cases/accuracy/object_sensitive/struct/struct_deep5_002_F/struct_deep5_002_F.go\nLine 35: __taint_sink(obj2)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/sast-go/cases/accuracy/object_sensitive/struct/struct_deep5_002_F/struct_deep5_002_F.go\",\"functionName\":\"main\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /sast-go/cases/accuracy/object_sensitive/struct/struct_deep5_002_F/struct_deep5_002_F.go\n AffectedNodeName: __taint_src\n 43: SOURCE: struct_deep5_002_F(__taint_src)\n /sast-go/cases/accuracy/object_sensitive/struct/struct_deep5_002_F/struct_deep5_002_F.go\n AffectedNodeName: struct_deep5_002_F\n 43: CALL: struct_deep5_002_F(__taint_src)\n /sast-go/cases/accuracy/object_sensitive/struct/struct_deep5_002_F/struct_deep5_002_F.go\n AffectedNodeName: __taint_src\n 28: ARG PASS: func struct_deep5_002_F(__taint_src string) {\n /sast-go/cases/accuracy/object_sensitive/struct/struct_deep5_002_F/struct_deep5_002_F.go\n AffectedNodeName: obj1.deepB02.deepB03.deepB04.deepB05\n 33: Var Pass: \tobj1.deepB02.deepB03.deepB04.deepB05 = __taint_src\n /sast-go/cases/accuracy/object_sensitive/struct/struct_deep5_002_F/struct_deep5_002_F.go\n AffectedNodeName: __taint_sink\n 35: SINK: \t__taint_sink(obj2)\n==========================================================\n #Total-findings:1\n==========================================================","/benchmarks/sast-go/cases/accuracy/object_sensitive/struct/struct_deep5_003_T/struct_deep5_003_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/sast-go/cases/accuracy/object_sensitive/struct/struct_deep5_003_T/struct_deep5_003_T.go\nLine 42: __taint_sink(obj1)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/sast-go/cases/accuracy/object_sensitive/struct/struct_deep5_003_T/struct_deep5_003_T.go\",\"functionName\":\"main\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /sast-go/cases/accuracy/object_sensitive/struct/struct_deep5_003_T/struct_deep5_003_T.go\n AffectedNodeName: __taint_src\n 50: SOURCE: struct_deep5_003_T(__taint_src)\n /sast-go/cases/accuracy/object_sensitive/struct/struct_deep5_003_T/struct_deep5_003_T.go\n AffectedNodeName: struct_deep5_003_T\n 50: CALL: struct_deep5_003_T(__taint_src)\n /sast-go/cases/accuracy/object_sensitive/struct/struct_deep5_003_T/struct_deep5_003_T.go\n AffectedNodeName: __taint_src\n 32: ARG PASS: func struct_deep5_003_T(__taint_src string) {\n /sast-go/cases/accuracy/object_sensitive/struct/struct_deep5_003_T/struct_deep5_003_T.go\n AffectedNodeName: deepB05\n 37: Var Pass: \tdeepB05 := DeepB05{\n 38: Var Pass: \t\tdeepB06: __taint_src,\n 39: Var Pass: \t}\n /sast-go/cases/accuracy/object_sensitive/struct/struct_deep5_003_T/struct_deep5_003_T.go\n AffectedNodeName: obj1.deepB02.deepB03.deepB04.deepB05\n 40: Var Pass: \tobj1.deepB02.deepB03.deepB04.deepB05 = deepB05\n /sast-go/cases/accuracy/object_sensitive/struct/struct_deep5_003_T/struct_deep5_003_T.go\n AffectedNodeName: __taint_sink\n 42: SINK: \t__taint_sink(obj1)\n==========================================================\n #Total-findings:1\n==========================================================","/benchmarks/sast-go/cases/accuracy/object_sensitive/struct/struct_deep5_004_F/struct_deep5_004_F":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/sast-go/cases/accuracy/object_sensitive/struct/struct_deep5_004_F/struct_deep5_004_F.go\nLine 42: __taint_sink(obj2)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/sast-go/cases/accuracy/object_sensitive/struct/struct_deep5_004_F/struct_deep5_004_F.go\",\"functionName\":\"main\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /sast-go/cases/accuracy/object_sensitive/struct/struct_deep5_004_F/struct_deep5_004_F.go\n AffectedNodeName: __taint_src\n 50: SOURCE: struct_deep5_004_F(__taint_src)\n /sast-go/cases/accuracy/object_sensitive/struct/struct_deep5_004_F/struct_deep5_004_F.go\n AffectedNodeName: struct_deep5_004_F\n 50: CALL: struct_deep5_004_F(__taint_src)\n /sast-go/cases/accuracy/object_sensitive/struct/struct_deep5_004_F/struct_deep5_004_F.go\n AffectedNodeName: __taint_src\n 32: ARG PASS: func struct_deep5_004_F(__taint_src string) {\n /sast-go/cases/accuracy/object_sensitive/struct/struct_deep5_004_F/struct_deep5_004_F.go\n AffectedNodeName: deepB05\n 37: Var Pass: \tdeepB05 := DeepB05{\n 38: Var Pass: \t\tdeepB06: __taint_src,\n 39: Var Pass: \t}\n /sast-go/cases/accuracy/object_sensitive/struct/struct_deep5_004_F/struct_deep5_004_F.go\n AffectedNodeName: obj1.deepB02.deepB03.deepB04.deepB05\n 40: Var Pass: \tobj1.deepB02.deepB03.deepB04.deepB05 = deepB05\n /sast-go/cases/accuracy/object_sensitive/struct/struct_deep5_004_F/struct_deep5_004_F.go\n AffectedNodeName: __taint_sink\n 42: SINK: \t__taint_sink(obj2)\n==========================================================\n #Total-findings:1\n==========================================================","/benchmarks/sast-go/cases/accuracy/path_sensitive/explicit_jump_control/break_003_T/break_003_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/sast-go/cases/accuracy/path_sensitive/explicit_jump_control/break_003_T/break_003_T.go\nLine 18: __taint_sink(res)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/sast-go/cases/accuracy/path_sensitive/explicit_jump_control/break_003_T/break_003_T.go\",\"functionName\":\"main\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /sast-go/cases/accuracy/path_sensitive/explicit_jump_control/break_003_T/break_003_T.go\n AffectedNodeName: __taint_src\n 25: SOURCE: break_003_T(__taint_src)\n /sast-go/cases/accuracy/path_sensitive/explicit_jump_control/break_003_T/break_003_T.go\n AffectedNodeName: break_003_T\n 25: CALL: break_003_T(__taint_src)\n /sast-go/cases/accuracy/path_sensitive/explicit_jump_control/break_003_T/break_003_T.go\n AffectedNodeName: __taint_src\n 12: ARG PASS: func break_003_T(__taint_src string) {\n /sast-go/cases/accuracy/path_sensitive/explicit_jump_control/break_003_T/break_003_T.go\n AffectedNodeName: res\n 16: Var Pass: \t\t\tres = __taint_src\n /sast-go/cases/accuracy/path_sensitive/explicit_jump_control/break_003_T/break_003_T.go\n AffectedNodeName: __taint_sink\n 18: SINK: \t\t__taint_sink(res)\n\n------------- 2: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/sast-go/cases/accuracy/path_sensitive/explicit_jump_control/break_003_T/break_003_T.go\nLine 18: __taint_sink(res)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/sast-go/cases/accuracy/path_sensitive/explicit_jump_control/break_003_T/break_003_T.go\",\"functionName\":\"main\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /sast-go/cases/accuracy/path_sensitive/explicit_jump_control/break_003_T/break_003_T.go\n AffectedNodeName: __taint_src\n 25: SOURCE: break_003_T(__taint_src)\n /sast-go/cases/accuracy/path_sensitive/explicit_jump_control/break_003_T/break_003_T.go\n AffectedNodeName: break_003_T\n 25: CALL: break_003_T(__taint_src)\n /sast-go/cases/accuracy/path_sensitive/explicit_jump_control/break_003_T/break_003_T.go\n AffectedNodeName: __taint_src\n 12: ARG PASS: func break_003_T(__taint_src string) {\n /sast-go/cases/accuracy/path_sensitive/explicit_jump_control/break_003_T/break_003_T.go\n AffectedNodeName: res\n 16: Var Pass: \t\t\tres = __taint_src\n /sast-go/cases/accuracy/path_sensitive/explicit_jump_control/break_003_T/break_003_T.go\n AffectedNodeName: __taint_sink\n 18: CALL: \t\t__taint_sink(res)\n /sast-go/cases/accuracy/path_sensitive/explicit_jump_control/break_003_T/break_003_T.go\n AffectedNodeName: __taint_sink\n 18: SINK: \t\t__taint_sink(res)\n==========================================================\n #Total-findings:2\n==========================================================","/benchmarks/sast-go/cases/accuracy/path_sensitive/explicit_jump_control/break_004_F/break_004_F":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/sast-go/cases/accuracy/path_sensitive/explicit_jump_control/break_004_F/break_004_F.go\nLine 19: __taint_sink(res)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/sast-go/cases/accuracy/path_sensitive/explicit_jump_control/break_004_F/break_004_F.go\",\"functionName\":\"main\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /sast-go/cases/accuracy/path_sensitive/explicit_jump_control/break_004_F/break_004_F.go\n AffectedNodeName: __taint_src\n 26: SOURCE: break_004_F(__taint_src)\n /sast-go/cases/accuracy/path_sensitive/explicit_jump_control/break_004_F/break_004_F.go\n AffectedNodeName: break_004_F\n 26: CALL: break_004_F(__taint_src)\n /sast-go/cases/accuracy/path_sensitive/explicit_jump_control/break_004_F/break_004_F.go\n AffectedNodeName: __taint_src\n 12: ARG PASS: func break_004_F(__taint_src string) {\n /sast-go/cases/accuracy/path_sensitive/explicit_jump_control/break_004_F/break_004_F.go\n AffectedNodeName: res\n 16: Var Pass: \t\t\tres = __taint_src\n /sast-go/cases/accuracy/path_sensitive/explicit_jump_control/break_004_F/break_004_F.go\n AffectedNodeName: __taint_sink\n 19: SINK: \t\t__taint_sink(res)\n\n------------- 2: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/sast-go/cases/accuracy/path_sensitive/explicit_jump_control/break_004_F/break_004_F.go\nLine 19: __taint_sink(res)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/sast-go/cases/accuracy/path_sensitive/explicit_jump_control/break_004_F/break_004_F.go\",\"functionName\":\"main\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /sast-go/cases/accuracy/path_sensitive/explicit_jump_control/break_004_F/break_004_F.go\n AffectedNodeName: __taint_src\n 26: SOURCE: break_004_F(__taint_src)\n /sast-go/cases/accuracy/path_sensitive/explicit_jump_control/break_004_F/break_004_F.go\n AffectedNodeName: break_004_F\n 26: CALL: break_004_F(__taint_src)\n /sast-go/cases/accuracy/path_sensitive/explicit_jump_control/break_004_F/break_004_F.go\n AffectedNodeName: __taint_src\n 12: ARG PASS: func break_004_F(__taint_src string) {\n /sast-go/cases/accuracy/path_sensitive/explicit_jump_control/break_004_F/break_004_F.go\n AffectedNodeName: res\n 16: Var Pass: \t\t\tres = __taint_src\n /sast-go/cases/accuracy/path_sensitive/explicit_jump_control/break_004_F/break_004_F.go\n AffectedNodeName: __taint_sink\n 19: CALL: \t\t__taint_sink(res)\n /sast-go/cases/accuracy/path_sensitive/explicit_jump_control/break_004_F/break_004_F.go\n AffectedNodeName: __taint_sink\n 19: SINK: \t\t__taint_sink(res)\n==========================================================\n #Total-findings:2\n==========================================================","/benchmarks/sast-go/cases/accuracy/path_sensitive/explicit_jump_control/break_label_003_T/break_label_003_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/sast-go/cases/accuracy/path_sensitive/explicit_jump_control/break_label_003_T/break_label_003_T.go\nLine 21: __taint_sink(res)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/sast-go/cases/accuracy/path_sensitive/explicit_jump_control/break_label_003_T/break_label_003_T.go\",\"functionName\":\"main\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /sast-go/cases/accuracy/path_sensitive/explicit_jump_control/break_label_003_T/break_label_003_T.go\n AffectedNodeName: __taint_src\n 27: SOURCE: break_label_003_T(__taint_src)\n /sast-go/cases/accuracy/path_sensitive/explicit_jump_control/break_label_003_T/break_label_003_T.go\n AffectedNodeName: break_label_003_T\n 27: CALL: break_label_003_T(__taint_src)\n /sast-go/cases/accuracy/path_sensitive/explicit_jump_control/break_label_003_T/break_label_003_T.go\n AffectedNodeName: __taint_src\n 12: ARG PASS: func break_label_003_T(__taint_src string) {\n /sast-go/cases/accuracy/path_sensitive/explicit_jump_control/break_label_003_T/break_label_003_T.go\n AffectedNodeName: res\n 17: Var Pass: \t\tres = __taint_src\n /sast-go/cases/accuracy/path_sensitive/explicit_jump_control/break_label_003_T/break_label_003_T.go\n AffectedNodeName: __taint_sink\n 21: SINK: \t__taint_sink(res)\n==========================================================\n #Total-findings:1\n==========================================================","/benchmarks/sast-go/cases/accuracy/path_sensitive/explicit_jump_control/break_label_004_F/break_label_004_F":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/sast-go/cases/accuracy/path_sensitive/explicit_jump_control/break_label_004_F/break_label_004_F.go\nLine 21: __taint_sink(res)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/sast-go/cases/accuracy/path_sensitive/explicit_jump_control/break_label_004_F/break_label_004_F.go\",\"functionName\":\"main\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /sast-go/cases/accuracy/path_sensitive/explicit_jump_control/break_label_004_F/break_label_004_F.go\n AffectedNodeName: __taint_src\n 27: SOURCE: break_label_004_F(__taint_src)\n /sast-go/cases/accuracy/path_sensitive/explicit_jump_control/break_label_004_F/break_label_004_F.go\n AffectedNodeName: break_label_004_F\n 27: CALL: break_label_004_F(__taint_src)\n /sast-go/cases/accuracy/path_sensitive/explicit_jump_control/break_label_004_F/break_label_004_F.go\n AffectedNodeName: __taint_src\n 12: ARG PASS: func break_label_004_F(__taint_src string) {\n /sast-go/cases/accuracy/path_sensitive/explicit_jump_control/break_label_004_F/break_label_004_F.go\n AffectedNodeName: res\n 18: Var Pass: \t\tres = __taint_src\n /sast-go/cases/accuracy/path_sensitive/explicit_jump_control/break_label_004_F/break_label_004_F.go\n AffectedNodeName: __taint_sink\n 21: SINK: \t__taint_sink(res)\n==========================================================\n #Total-findings:1\n==========================================================","/benchmarks/sast-go/cases/accuracy/path_sensitive/explicit_jump_control/continue_003_T/continue_003_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/sast-go/cases/accuracy/path_sensitive/explicit_jump_control/continue_003_T/continue_003_T.go\nLine 20: __taint_sink(res)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/sast-go/cases/accuracy/path_sensitive/explicit_jump_control/continue_003_T/continue_003_T.go\",\"functionName\":\"main\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /sast-go/cases/accuracy/path_sensitive/explicit_jump_control/continue_003_T/continue_003_T.go\n AffectedNodeName: __taint_src\n 26: SOURCE: continue_003_T(__taint_src)\n /sast-go/cases/accuracy/path_sensitive/explicit_jump_control/continue_003_T/continue_003_T.go\n AffectedNodeName: continue_003_T\n 26: CALL: continue_003_T(__taint_src)\n /sast-go/cases/accuracy/path_sensitive/explicit_jump_control/continue_003_T/continue_003_T.go\n AffectedNodeName: __taint_src\n 12: ARG PASS: func continue_003_T(__taint_src string) {\n /sast-go/cases/accuracy/path_sensitive/explicit_jump_control/continue_003_T/continue_003_T.go\n AffectedNodeName: res\n 16: Var Pass: \t\t\tres = __taint_src\n /sast-go/cases/accuracy/path_sensitive/explicit_jump_control/continue_003_T/continue_003_T.go\n AffectedNodeName: __taint_sink\n 20: SINK: \t__taint_sink(res)\n==========================================================\n #Total-findings:1\n==========================================================","/benchmarks/sast-go/cases/accuracy/path_sensitive/explicit_jump_control/continue_004_F/continue_004_F":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/sast-go/cases/accuracy/path_sensitive/explicit_jump_control/continue_004_F/continue_004_F.go\nLine 18: __taint_sink(res)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/sast-go/cases/accuracy/path_sensitive/explicit_jump_control/continue_004_F/continue_004_F.go\",\"functionName\":\"main\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /sast-go/cases/accuracy/path_sensitive/explicit_jump_control/continue_004_F/continue_004_F.go\n AffectedNodeName: __taint_src\n 26: SOURCE: continue_004_F(__taint_src)\n /sast-go/cases/accuracy/path_sensitive/explicit_jump_control/continue_004_F/continue_004_F.go\n AffectedNodeName: continue_004_F\n 26: CALL: continue_004_F(__taint_src)\n /sast-go/cases/accuracy/path_sensitive/explicit_jump_control/continue_004_F/continue_004_F.go\n AffectedNodeName: __taint_src\n 12: ARG PASS: func continue_004_F(__taint_src string) {\n /sast-go/cases/accuracy/path_sensitive/explicit_jump_control/continue_004_F/continue_004_F.go\n AffectedNodeName: res\n 16: Var Pass: \t\t\tres = __taint_src\n /sast-go/cases/accuracy/path_sensitive/explicit_jump_control/continue_004_F/continue_004_F.go\n AffectedNodeName: __taint_sink\n 18: SINK: \t\t\t__taint_sink(res)\n==========================================================\n #Total-findings:1\n==========================================================","/benchmarks/sast-go/cases/accuracy/path_sensitive/explicit_jump_control/fallthrough_003_T/fallthrough_003_T":"======================== Findings ========================\nNo findings!\n==========================================================","/benchmarks/sast-go/cases/accuracy/path_sensitive/explicit_jump_control/fallthrough_004_F/fallthrough_004_F":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/sast-go/cases/accuracy/path_sensitive/explicit_jump_control/fallthrough_004_F/fallthrough_004_F.go\nLine 24: __taint_sink(res)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/sast-go/cases/accuracy/path_sensitive/explicit_jump_control/fallthrough_004_F/fallthrough_004_F.go\",\"functionName\":\"main\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /sast-go/cases/accuracy/path_sensitive/explicit_jump_control/fallthrough_004_F/fallthrough_004_F.go\n AffectedNodeName: __taint_src\n 30: SOURCE: fallthrough_004_F(__taint_src)\n /sast-go/cases/accuracy/path_sensitive/explicit_jump_control/fallthrough_004_F/fallthrough_004_F.go\n AffectedNodeName: fallthrough_004_F\n 30: CALL: fallthrough_004_F(__taint_src)\n /sast-go/cases/accuracy/path_sensitive/explicit_jump_control/fallthrough_004_F/fallthrough_004_F.go\n AffectedNodeName: __taint_src\n 12: ARG PASS: func fallthrough_004_F(__taint_src string) {\n /sast-go/cases/accuracy/path_sensitive/explicit_jump_control/fallthrough_004_F/fallthrough_004_F.go\n AffectedNodeName: res\n 18: Var Pass: \t\tres = __taint_src\n /sast-go/cases/accuracy/path_sensitive/explicit_jump_control/fallthrough_004_F/fallthrough_004_F.go\n AffectedNodeName: __taint_sink\n 24: SINK: \t__taint_sink(res)\n==========================================================\n #Total-findings:1\n==========================================================","/benchmarks/sast-go/cases/accuracy/path_sensitive/explicit_jump_control/goto_003_T/goto_003_T":"======================== Findings ========================\nNo findings!\n==========================================================","/benchmarks/sast-go/cases/accuracy/path_sensitive/explicit_jump_control/goto_004_F/goto_004_F":"======================== Findings ========================\nNo findings!\n==========================================================","/benchmarks/sast-go/cases/accuracy/path_sensitive/explicit_jump_control/return_003_T/return_003_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/sast-go/cases/accuracy/path_sensitive/explicit_jump_control/return_003_T/return_003_T.go\nLine 16: __taint_sink(__taint_src)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/sast-go/cases/accuracy/path_sensitive/explicit_jump_control/return_003_T/return_003_T.go\",\"functionName\":\"main\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /sast-go/cases/accuracy/path_sensitive/explicit_jump_control/return_003_T/return_003_T.go\n AffectedNodeName: __taint_src\n 23: SOURCE: return_003_T(__taint_src)\n /sast-go/cases/accuracy/path_sensitive/explicit_jump_control/return_003_T/return_003_T.go\n AffectedNodeName: return_003_T\n 23: CALL: return_003_T(__taint_src)\n /sast-go/cases/accuracy/path_sensitive/explicit_jump_control/return_003_T/return_003_T.go\n AffectedNodeName: __taint_src\n 12: ARG PASS: func return_003_T(__taint_src string) string {\n /sast-go/cases/accuracy/path_sensitive/explicit_jump_control/return_003_T/return_003_T.go\n AffectedNodeName: __taint_sink\n 16: SINK: \t__taint_sink(__taint_src)\n==========================================================\n #Total-findings:1\n==========================================================","/benchmarks/sast-go/cases/accuracy/path_sensitive/explicit_jump_control/return_004_F/return_004_F":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/sast-go/cases/accuracy/path_sensitive/explicit_jump_control/return_004_F/return_004_F.go\nLine 16: __taint_sink(__taint_src)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/sast-go/cases/accuracy/path_sensitive/explicit_jump_control/return_004_F/return_004_F.go\",\"functionName\":\"main\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /sast-go/cases/accuracy/path_sensitive/explicit_jump_control/return_004_F/return_004_F.go\n AffectedNodeName: __taint_src\n 23: SOURCE: return_004_F(__taint_src)\n /sast-go/cases/accuracy/path_sensitive/explicit_jump_control/return_004_F/return_004_F.go\n AffectedNodeName: return_004_F\n 23: CALL: return_004_F(__taint_src)\n /sast-go/cases/accuracy/path_sensitive/explicit_jump_control/return_004_F/return_004_F.go\n AffectedNodeName: __taint_src\n 12: ARG PASS: func return_004_F(__taint_src string) string {\n /sast-go/cases/accuracy/path_sensitive/explicit_jump_control/return_004_F/return_004_F.go\n AffectedNodeName: __taint_sink\n 16: SINK: \t__taint_sink(__taint_src)\n==========================================================\n #Total-findings:1\n==========================================================","/benchmarks/sast-go/cases/accuracy/path_sensitive/loop_conditional_stmt/no_solver/conditional_if_005_F/conditional_if_005_F":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/sast-go/cases/accuracy/path_sensitive/loop_conditional_stmt/no_solver/conditional_if_005_F/conditional_if_005_F.go\nLine 17: __taint_sink(res)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/sast-go/cases/accuracy/path_sensitive/loop_conditional_stmt/no_solver/conditional_if_005_F/conditional_if_005_F.go\",\"functionName\":\"main\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /sast-go/cases/accuracy/path_sensitive/loop_conditional_stmt/no_solver/conditional_if_005_F/conditional_if_005_F.go\n AffectedNodeName: __taint_src\n 24: SOURCE: conditional_if_005_F(__taint_src)\n /sast-go/cases/accuracy/path_sensitive/loop_conditional_stmt/no_solver/conditional_if_005_F/conditional_if_005_F.go\n AffectedNodeName: conditional_if_005_F\n 24: CALL: conditional_if_005_F(__taint_src)\n /sast-go/cases/accuracy/path_sensitive/loop_conditional_stmt/no_solver/conditional_if_005_F/conditional_if_005_F.go\n AffectedNodeName: __taint_src\n 12: ARG PASS: func conditional_if_005_F(__taint_src string) {\n /sast-go/cases/accuracy/path_sensitive/loop_conditional_stmt/no_solver/conditional_if_005_F/conditional_if_005_F.go\n AffectedNodeName: res\n 15: Var Pass: \t\tres = __taint_src\n /sast-go/cases/accuracy/path_sensitive/loop_conditional_stmt/no_solver/conditional_if_005_F/conditional_if_005_F.go\n AffectedNodeName: __taint_sink\n 17: SINK: \t\t__taint_sink(res)\n==========================================================\n #Total-findings:1\n==========================================================","/benchmarks/sast-go/cases/accuracy/path_sensitive/loop_conditional_stmt/no_solver/conditional_if_006_F/conditional_if_006_F":"======================== Findings ========================\nNo findings!\n==========================================================","/benchmarks/sast-go/cases/accuracy/path_sensitive/loop_conditional_stmt/no_solver/conditional_if_007_T/conditional_if_007_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/sast-go/cases/accuracy/path_sensitive/loop_conditional_stmt/no_solver/conditional_if_007_T/conditional_if_007_T.go\nLine 19: __taint_sink(res)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/sast-go/cases/accuracy/path_sensitive/loop_conditional_stmt/no_solver/conditional_if_007_T/conditional_if_007_T.go\",\"functionName\":\"main\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /sast-go/cases/accuracy/path_sensitive/loop_conditional_stmt/no_solver/conditional_if_007_T/conditional_if_007_T.go\n AffectedNodeName: __taint_src\n 25: SOURCE: conditional_if_007_T(__taint_src)\n /sast-go/cases/accuracy/path_sensitive/loop_conditional_stmt/no_solver/conditional_if_007_T/conditional_if_007_T.go\n AffectedNodeName: conditional_if_007_T\n 25: CALL: conditional_if_007_T(__taint_src)\n /sast-go/cases/accuracy/path_sensitive/loop_conditional_stmt/no_solver/conditional_if_007_T/conditional_if_007_T.go\n AffectedNodeName: __taint_src\n 12: ARG PASS: func conditional_if_007_T(__taint_src string) {\n /sast-go/cases/accuracy/path_sensitive/loop_conditional_stmt/no_solver/conditional_if_007_T/conditional_if_007_T.go\n AffectedNodeName: res\n 15: Var Pass: \t\tres = __taint_src\n /sast-go/cases/accuracy/path_sensitive/loop_conditional_stmt/no_solver/conditional_if_007_T/conditional_if_007_T.go\n AffectedNodeName: __taint_sink\n 19: SINK: \t__taint_sink(res)\n==========================================================\n #Total-findings:1\n==========================================================","/benchmarks/sast-go/cases/accuracy/path_sensitive/loop_conditional_stmt/no_solver/conditional_if_008_F/conditional_if_008_F":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/sast-go/cases/accuracy/path_sensitive/loop_conditional_stmt/no_solver/conditional_if_008_F/conditional_if_008_F.go\nLine 19: __taint_sink(res)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/sast-go/cases/accuracy/path_sensitive/loop_conditional_stmt/no_solver/conditional_if_008_F/conditional_if_008_F.go\",\"functionName\":\"main\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /sast-go/cases/accuracy/path_sensitive/loop_conditional_stmt/no_solver/conditional_if_008_F/conditional_if_008_F.go\n AffectedNodeName: __taint_src\n 25: SOURCE: conditional_if_008_F(__taint_src)\n /sast-go/cases/accuracy/path_sensitive/loop_conditional_stmt/no_solver/conditional_if_008_F/conditional_if_008_F.go\n AffectedNodeName: conditional_if_008_F\n 25: CALL: conditional_if_008_F(__taint_src)\n /sast-go/cases/accuracy/path_sensitive/loop_conditional_stmt/no_solver/conditional_if_008_F/conditional_if_008_F.go\n AffectedNodeName: __taint_src\n 12: ARG PASS: func conditional_if_008_F(__taint_src string) {\n /sast-go/cases/accuracy/path_sensitive/loop_conditional_stmt/no_solver/conditional_if_008_F/conditional_if_008_F.go\n AffectedNodeName: res\n 17: Var Pass: \t\tres = __taint_src\n /sast-go/cases/accuracy/path_sensitive/loop_conditional_stmt/no_solver/conditional_if_008_F/conditional_if_008_F.go\n AffectedNodeName: __taint_sink\n 19: SINK: \t__taint_sink(res)\n==========================================================\n #Total-findings:1\n==========================================================","/benchmarks/sast-go/cases/accuracy/path_sensitive/loop_conditional_stmt/no_solver/conditional_switch_stmt_003_F/conditional_switch_stmt_003_F":"======================== Findings ========================\nNo findings!\n==========================================================","/benchmarks/sast-go/cases/accuracy/path_sensitive/loop_conditional_stmt/no_solver/conditional_switch_stmt_004_F/conditional_switch_stmt_004_F":"======================== Findings ========================\nNo findings!\n==========================================================","/benchmarks/sast-go/cases/accuracy/path_sensitive/loop_conditional_stmt/no_solver/conditional_switch_stmt_005_T/conditional_switch_stmt_005_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/sast-go/cases/accuracy/path_sensitive/loop_conditional_stmt/no_solver/conditional_switch_stmt_005_T/conditional_switch_stmt_005_T.go\nLine 20: __taint_sink(res)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/sast-go/cases/accuracy/path_sensitive/loop_conditional_stmt/no_solver/conditional_switch_stmt_005_T/conditional_switch_stmt_005_T.go\",\"functionName\":\"main\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /sast-go/cases/accuracy/path_sensitive/loop_conditional_stmt/no_solver/conditional_switch_stmt_005_T/conditional_switch_stmt_005_T.go\n AffectedNodeName: __taint_src\n 26: SOURCE: conditional_switch_stmt_005_T(__taint_src)\n /sast-go/cases/accuracy/path_sensitive/loop_conditional_stmt/no_solver/conditional_switch_stmt_005_T/conditional_switch_stmt_005_T.go\n AffectedNodeName: conditional_switch_stmt_005_T\n 26: CALL: conditional_switch_stmt_005_T(__taint_src)\n /sast-go/cases/accuracy/path_sensitive/loop_conditional_stmt/no_solver/conditional_switch_stmt_005_T/conditional_switch_stmt_005_T.go\n AffectedNodeName: __taint_src\n 12: ARG PASS: func conditional_switch_stmt_005_T(__taint_src string) {\n /sast-go/cases/accuracy/path_sensitive/loop_conditional_stmt/no_solver/conditional_switch_stmt_005_T/conditional_switch_stmt_005_T.go\n AffectedNodeName: res\n 18: Var Pass: \t\tres = __taint_src\n /sast-go/cases/accuracy/path_sensitive/loop_conditional_stmt/no_solver/conditional_switch_stmt_005_T/conditional_switch_stmt_005_T.go\n AffectedNodeName: __taint_sink\n 20: SINK: \t__taint_sink(res)\n==========================================================\n #Total-findings:1\n==========================================================","/benchmarks/sast-go/cases/accuracy/path_sensitive/loop_conditional_stmt/no_solver/conditional_switch_stmt_006_F/conditional_switch_stmt_006_F":"======================== Findings ========================\nNo findings!\n==========================================================","/benchmarks/sast-go/cases/accuracy/path_sensitive/loop_conditional_stmt/solver/conditional_if_009_T/conditional_if_009_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/sast-go/cases/accuracy/path_sensitive/loop_conditional_stmt/solver/conditional_if_009_T/conditional_if_009_T.go\nLine 19: __taint_sink(res)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/sast-go/cases/accuracy/path_sensitive/loop_conditional_stmt/solver/conditional_if_009_T/conditional_if_009_T.go\",\"functionName\":\"main\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /sast-go/cases/accuracy/path_sensitive/loop_conditional_stmt/solver/conditional_if_009_T/conditional_if_009_T.go\n AffectedNodeName: __taint_src\n 25: SOURCE: conditional_if_009_T(__taint_src)\n /sast-go/cases/accuracy/path_sensitive/loop_conditional_stmt/solver/conditional_if_009_T/conditional_if_009_T.go\n AffectedNodeName: conditional_if_009_T\n 25: CALL: conditional_if_009_T(__taint_src)\n /sast-go/cases/accuracy/path_sensitive/loop_conditional_stmt/solver/conditional_if_009_T/conditional_if_009_T.go\n AffectedNodeName: __taint_src\n 12: ARG PASS: func conditional_if_009_T(__taint_src string) {\n /sast-go/cases/accuracy/path_sensitive/loop_conditional_stmt/solver/conditional_if_009_T/conditional_if_009_T.go\n AffectedNodeName: res\n 15: Var Pass: \t\tres = __taint_src\n /sast-go/cases/accuracy/path_sensitive/loop_conditional_stmt/solver/conditional_if_009_T/conditional_if_009_T.go\n AffectedNodeName: __taint_sink\n 19: SINK: \t__taint_sink(res)\n==========================================================\n #Total-findings:1\n==========================================================","/benchmarks/sast-go/cases/accuracy/path_sensitive/loop_conditional_stmt/solver/conditional_if_010_F/conditional_if_010_F":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/sast-go/cases/accuracy/path_sensitive/loop_conditional_stmt/solver/conditional_if_010_F/conditional_if_010_F.go\nLine 19: __taint_sink(res)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/sast-go/cases/accuracy/path_sensitive/loop_conditional_stmt/solver/conditional_if_010_F/conditional_if_010_F.go\",\"functionName\":\"main\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /sast-go/cases/accuracy/path_sensitive/loop_conditional_stmt/solver/conditional_if_010_F/conditional_if_010_F.go\n AffectedNodeName: __taint_src\n 25: SOURCE: conditional_if_010_F(__taint_src)\n /sast-go/cases/accuracy/path_sensitive/loop_conditional_stmt/solver/conditional_if_010_F/conditional_if_010_F.go\n AffectedNodeName: conditional_if_010_F\n 25: CALL: conditional_if_010_F(__taint_src)\n /sast-go/cases/accuracy/path_sensitive/loop_conditional_stmt/solver/conditional_if_010_F/conditional_if_010_F.go\n AffectedNodeName: __taint_src\n 12: ARG PASS: func conditional_if_010_F(__taint_src string) {\n /sast-go/cases/accuracy/path_sensitive/loop_conditional_stmt/solver/conditional_if_010_F/conditional_if_010_F.go\n AffectedNodeName: res\n 17: Var Pass: \t\tres = __taint_src\n /sast-go/cases/accuracy/path_sensitive/loop_conditional_stmt/solver/conditional_if_010_F/conditional_if_010_F.go\n AffectedNodeName: __taint_sink\n 19: SINK: \t__taint_sink(res)\n==========================================================\n #Total-findings:1\n==========================================================","/benchmarks/sast-go/cases/accuracy/path_sensitive/loop_conditional_stmt/solver/conditional_switch_stmt_007_T/conditional_switch_stmt_007_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/sast-go/cases/accuracy/path_sensitive/loop_conditional_stmt/solver/conditional_switch_stmt_007_T/conditional_switch_stmt_007_T.go\nLine 20: __taint_sink(res)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/sast-go/cases/accuracy/path_sensitive/loop_conditional_stmt/solver/conditional_switch_stmt_007_T/conditional_switch_stmt_007_T.go\",\"functionName\":\"main\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /sast-go/cases/accuracy/path_sensitive/loop_conditional_stmt/solver/conditional_switch_stmt_007_T/conditional_switch_stmt_007_T.go\n AffectedNodeName: __taint_src\n 26: SOURCE: conditional_switch_stmt_007_T(__taint_src)\n /sast-go/cases/accuracy/path_sensitive/loop_conditional_stmt/solver/conditional_switch_stmt_007_T/conditional_switch_stmt_007_T.go\n AffectedNodeName: conditional_switch_stmt_007_T\n 26: CALL: conditional_switch_stmt_007_T(__taint_src)\n /sast-go/cases/accuracy/path_sensitive/loop_conditional_stmt/solver/conditional_switch_stmt_007_T/conditional_switch_stmt_007_T.go\n AffectedNodeName: __taint_src\n 12: ARG PASS: func conditional_switch_stmt_007_T(__taint_src string) {\n /sast-go/cases/accuracy/path_sensitive/loop_conditional_stmt/solver/conditional_switch_stmt_007_T/conditional_switch_stmt_007_T.go\n AffectedNodeName: res\n 16: Var Pass: \t\tres = __taint_src\n /sast-go/cases/accuracy/path_sensitive/loop_conditional_stmt/solver/conditional_switch_stmt_007_T/conditional_switch_stmt_007_T.go\n AffectedNodeName: __taint_sink\n 20: SINK: \t__taint_sink(res)\n==========================================================\n #Total-findings:1\n==========================================================","/benchmarks/sast-go/cases/accuracy/path_sensitive/loop_conditional_stmt/solver/conditional_switch_stmt_008_F/conditional_switch_stmt_008_F":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/sast-go/cases/accuracy/path_sensitive/loop_conditional_stmt/solver/conditional_switch_stmt_008_F/conditional_switch_stmt_008_F.go\nLine 20: __taint_sink(res)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/sast-go/cases/accuracy/path_sensitive/loop_conditional_stmt/solver/conditional_switch_stmt_008_F/conditional_switch_stmt_008_F.go\",\"functionName\":\"main\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /sast-go/cases/accuracy/path_sensitive/loop_conditional_stmt/solver/conditional_switch_stmt_008_F/conditional_switch_stmt_008_F.go\n AffectedNodeName: __taint_src\n 26: SOURCE: conditional_switch_stmt_008_F(__taint_src)\n /sast-go/cases/accuracy/path_sensitive/loop_conditional_stmt/solver/conditional_switch_stmt_008_F/conditional_switch_stmt_008_F.go\n AffectedNodeName: conditional_switch_stmt_008_F\n 26: CALL: conditional_switch_stmt_008_F(__taint_src)\n /sast-go/cases/accuracy/path_sensitive/loop_conditional_stmt/solver/conditional_switch_stmt_008_F/conditional_switch_stmt_008_F.go\n AffectedNodeName: __taint_src\n 12: ARG PASS: func conditional_switch_stmt_008_F(__taint_src string) {\n /sast-go/cases/accuracy/path_sensitive/loop_conditional_stmt/solver/conditional_switch_stmt_008_F/conditional_switch_stmt_008_F.go\n AffectedNodeName: res\n 16: Var Pass: \t\tres = __taint_src\n /sast-go/cases/accuracy/path_sensitive/loop_conditional_stmt/solver/conditional_switch_stmt_008_F/conditional_switch_stmt_008_F.go\n AffectedNodeName: __taint_sink\n 20: SINK: \t__taint_sink(res)\n==========================================================\n #Total-findings:1\n==========================================================","/benchmarks/sast-go/cases/accuracy/path_sensitive/loop_conditional_stmt/solver/for_body_003_T/for_body_003_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/sast-go/cases/accuracy/path_sensitive/loop_conditional_stmt/solver/for_body_003_T/for_body_003_T.go\nLine 17: __taint_sink(res)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/sast-go/cases/accuracy/path_sensitive/loop_conditional_stmt/solver/for_body_003_T/for_body_003_T.go\",\"functionName\":\"main\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /sast-go/cases/accuracy/path_sensitive/loop_conditional_stmt/solver/for_body_003_T/for_body_003_T.go\n AffectedNodeName: __taint_src\n 23: SOURCE: for_body_003_T(__taint_src)\n /sast-go/cases/accuracy/path_sensitive/loop_conditional_stmt/solver/for_body_003_T/for_body_003_T.go\n AffectedNodeName: for_body_003_T\n 23: CALL: for_body_003_T(__taint_src)\n /sast-go/cases/accuracy/path_sensitive/loop_conditional_stmt/solver/for_body_003_T/for_body_003_T.go\n AffectedNodeName: __taint_src\n 12: ARG PASS: func for_body_003_T(__taint_src string) {\n /sast-go/cases/accuracy/path_sensitive/loop_conditional_stmt/solver/for_body_003_T/for_body_003_T.go\n AffectedNodeName: res\n 15: Var Pass: \t\tres = __taint_src\n /sast-go/cases/accuracy/path_sensitive/loop_conditional_stmt/solver/for_body_003_T/for_body_003_T.go\n AffectedNodeName: __taint_sink\n 17: SINK: \t__taint_sink(res)\n==========================================================\n #Total-findings:1\n==========================================================","/benchmarks/sast-go/cases/accuracy/path_sensitive/loop_conditional_stmt/solver/for_body_004_F/for_body_004_F":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/sast-go/cases/accuracy/path_sensitive/loop_conditional_stmt/solver/for_body_004_F/for_body_004_F.go\nLine 16: __taint_sink(res)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/sast-go/cases/accuracy/path_sensitive/loop_conditional_stmt/solver/for_body_004_F/for_body_004_F.go\",\"functionName\":\"main\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /sast-go/cases/accuracy/path_sensitive/loop_conditional_stmt/solver/for_body_004_F/for_body_004_F.go\n AffectedNodeName: __taint_src\n 22: SOURCE: for_body_004_F(__taint_src)\n /sast-go/cases/accuracy/path_sensitive/loop_conditional_stmt/solver/for_body_004_F/for_body_004_F.go\n AffectedNodeName: for_body_004_F\n 22: CALL: for_body_004_F(__taint_src)\n /sast-go/cases/accuracy/path_sensitive/loop_conditional_stmt/solver/for_body_004_F/for_body_004_F.go\n AffectedNodeName: __taint_src\n 11: ARG PASS: func for_body_004_F(__taint_src string) {\n /sast-go/cases/accuracy/path_sensitive/loop_conditional_stmt/solver/for_body_004_F/for_body_004_F.go\n AffectedNodeName: res\n 14: Var Pass: \t\tres = __taint_src\n /sast-go/cases/accuracy/path_sensitive/loop_conditional_stmt/solver/for_body_004_F/for_body_004_F.go\n AffectedNodeName: __taint_sink\n 16: SINK: \t__taint_sink(res)\n==========================================================\n #Total-findings:1\n==========================================================","/benchmarks/sast-go/cases/completeness/dynamic_tracing/reflect_call/reflect_call_001_T/reflect_call_001_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/sast-go/cases/completeness/dynamic_tracing/reflect_call/reflect_call_001_T/reflect_call_001_T.go\nLine 26: __taint_sink(s.Field(i))\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/sast-go/cases/completeness/dynamic_tracing/reflect_call/reflect_call_001_T/reflect_call_001_T.go\",\"functionName\":\"main\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /sast-go/cases/completeness/dynamic_tracing/reflect_call/reflect_call_001_T/reflect_call_001_T.go\n AffectedNodeName: __taint_src\n 34: SOURCE: reflect_call_001_T(__taint_src)\n /sast-go/cases/completeness/dynamic_tracing/reflect_call/reflect_call_001_T/reflect_call_001_T.go\n AffectedNodeName: reflect_call_001_T\n 34: CALL: reflect_call_001_T(__taint_src)\n /sast-go/cases/completeness/dynamic_tracing/reflect_call/reflect_call_001_T/reflect_call_001_T.go\n AffectedNodeName: __taint_src\n 21: ARG PASS: func reflect_call_001_T(__taint_src string) {\n /sast-go/cases/completeness/dynamic_tracing/reflect_call/reflect_call_001_T/reflect_call_001_T.go\n AffectedNodeName: t\n 22: Var Pass: \tt := T{123, __taint_src}\n /sast-go/cases/completeness/dynamic_tracing/reflect_call/reflect_call_001_T/reflect_call_001_T.go\n AffectedNodeName: s\n 23: Var Pass: \ts := reflect.ValueOf(t)\n /sast-go/cases/completeness/dynamic_tracing/reflect_call/reflect_call_001_T/reflect_call_001_T.go\n AffectedNodeName: __taint_sink\n 26: SINK: \t\t__taint_sink(s.Field(i))\n\n------------- 2: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/sast-go/cases/completeness/dynamic_tracing/reflect_call/reflect_call_001_T/reflect_call_001_T.go\nLine 26: __taint_sink(s.Field(i))\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/sast-go/cases/completeness/dynamic_tracing/reflect_call/reflect_call_001_T/reflect_call_001_T.go\",\"functionName\":\"main\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /sast-go/cases/completeness/dynamic_tracing/reflect_call/reflect_call_001_T/reflect_call_001_T.go\n AffectedNodeName: __taint_src\n 34: SOURCE: reflect_call_001_T(__taint_src)\n /sast-go/cases/completeness/dynamic_tracing/reflect_call/reflect_call_001_T/reflect_call_001_T.go\n AffectedNodeName: reflect_call_001_T\n 34: CALL: reflect_call_001_T(__taint_src)\n /sast-go/cases/completeness/dynamic_tracing/reflect_call/reflect_call_001_T/reflect_call_001_T.go\n AffectedNodeName: __taint_src\n 21: ARG PASS: func reflect_call_001_T(__taint_src string) {\n /sast-go/cases/completeness/dynamic_tracing/reflect_call/reflect_call_001_T/reflect_call_001_T.go\n AffectedNodeName: t\n 22: Var Pass: \tt := T{123, __taint_src}\n /sast-go/cases/completeness/dynamic_tracing/reflect_call/reflect_call_001_T/reflect_call_001_T.go\n AffectedNodeName: s\n 23: Var Pass: \ts := reflect.ValueOf(t)\n /sast-go/cases/completeness/dynamic_tracing/reflect_call/reflect_call_001_T/reflect_call_001_T.go\n AffectedNodeName: __taint_sink\n 26: CALL: \t\t__taint_sink(s.Field(i))\n /sast-go/cases/completeness/dynamic_tracing/reflect_call/reflect_call_001_T/reflect_call_001_T.go\n AffectedNodeName: __taint_sink\n 26: SINK: \t\t__taint_sink(s.Field(i))\n==========================================================\n #Total-findings:2\n==========================================================","/benchmarks/sast-go/cases/completeness/dynamic_tracing/reflect_call/reflect_call_002_F/reflect_call_002_F":"======================== Findings ========================\nNo findings!\n==========================================================","/benchmarks/sast-go/cases/completeness/single_app_tracing/alias/alias_001_F/alias_001_F":"======================== Findings ========================\nNo findings!\n==========================================================","/benchmarks/sast-go/cases/completeness/single_app_tracing/alias/alias_002_T/alias_002_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/sast-go/cases/completeness/single_app_tracing/alias/alias_002_T/alias_002_T.go\nLine 21: __taint_sink(a.Value)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/sast-go/cases/completeness/single_app_tracing/alias/alias_002_T/alias_002_T.go\",\"functionName\":\"main\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /sast-go/cases/completeness/single_app_tracing/alias/alias_002_T/alias_002_T.go\n AffectedNodeName: __taint_src\n 28: SOURCE: alias_002_T(__taint_src)\n /sast-go/cases/completeness/single_app_tracing/alias/alias_002_T/alias_002_T.go\n AffectedNodeName: alias_002_T\n 28: CALL: alias_002_T(__taint_src)\n /sast-go/cases/completeness/single_app_tracing/alias/alias_002_T/alias_002_T.go\n AffectedNodeName: __taint_src\n 12: ARG PASS: func alias_002_T(__taint_src string) {\n /sast-go/cases/completeness/single_app_tracing/alias/alias_002_T/alias_002_T.go\n AffectedNodeName: b.Value\n 19: Var Pass: \tb.Value = __taint_src\n /sast-go/cases/completeness/single_app_tracing/alias/alias_002_T/alias_002_T.go\n AffectedNodeName: __taint_sink\n 21: SINK: \t__taint_sink(a.Value)\n==========================================================\n #Total-findings:1\n==========================================================","/benchmarks/sast-go/cases/completeness/single_app_tracing/asynchronous_tracing/multi_thread/asynchronous_goroutine_channel_001_T/asynchronous_goroutine_channel_001_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/sast-go/cases/completeness/single_app_tracing/asynchronous_tracing/multi_thread/asynchronous_goroutine_channel_001_T/asynchronous_goroutine_channel_001_T.go\nLine 17: __taint_sink(popch)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/sast-go/cases/completeness/single_app_tracing/asynchronous_tracing/multi_thread/asynchronous_goroutine_channel_001_T/asynchronous_goroutine_channel_001_T.go\",\"functionName\":\"main\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /sast-go/cases/completeness/single_app_tracing/asynchronous_tracing/multi_thread/asynchronous_goroutine_channel_001_T/asynchronous_goroutine_channel_001_T.go\n AffectedNodeName: __taint_src\n 24: SOURCE: asynchronous_goroutine_channel_001_T(__taint_src)\n /sast-go/cases/completeness/single_app_tracing/asynchronous_tracing/multi_thread/asynchronous_goroutine_channel_001_T/asynchronous_goroutine_channel_001_T.go\n AffectedNodeName: asynchronous_goroutine_channel_001_T\n 24: CALL: asynchronous_goroutine_channel_001_T(__taint_src)\n /sast-go/cases/completeness/single_app_tracing/asynchronous_tracing/multi_thread/asynchronous_goroutine_channel_001_T/asynchronous_goroutine_channel_001_T.go\n AffectedNodeName: __taint_src\n 12: ARG PASS: func asynchronous_goroutine_channel_001_T(__taint_src string) {\n /sast-go/cases/completeness/single_app_tracing/asynchronous_tracing/multi_thread/asynchronous_goroutine_channel_001_T/asynchronous_goroutine_channel_001_T.go\n AffectedNodeName: __taint_sink\n 17: SINK: \t__taint_sink(<-ch)\n==========================================================\n #Total-findings:1\n==========================================================","/benchmarks/sast-go/cases/completeness/single_app_tracing/asynchronous_tracing/multi_thread/asynchronous_goroutine_channel_002_F/asynchronous_goroutine_channel_002_F":"======================== Findings ========================\nNo findings!\n==========================================================","/benchmarks/sast-go/cases/completeness/single_app_tracing/asynchronous_tracing/multi_thread/asynchronous_goroutine_channel_003_T/asynchronous_goroutine_channel_003_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/sast-go/cases/completeness/single_app_tracing/asynchronous_tracing/multi_thread/asynchronous_goroutine_channel_003_T/asynchronous_goroutine_channel_003_T.go\nLine 30: __taint_sink(message)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/sast-go/cases/completeness/single_app_tracing/asynchronous_tracing/multi_thread/asynchronous_goroutine_channel_003_T/asynchronous_goroutine_channel_003_T.go\",\"functionName\":\"main\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /sast-go/cases/completeness/single_app_tracing/asynchronous_tracing/multi_thread/asynchronous_goroutine_channel_003_T/asynchronous_goroutine_channel_003_T.go\n AffectedNodeName: __taint_src\n 40: SOURCE: asynchronous_goroutine_channel_003_T(__taint_src)\n /sast-go/cases/completeness/single_app_tracing/asynchronous_tracing/multi_thread/asynchronous_goroutine_channel_003_T/asynchronous_goroutine_channel_003_T.go\n AffectedNodeName: asynchronous_goroutine_channel_003_T\n 40: CALL: asynchronous_goroutine_channel_003_T(__taint_src)\n /sast-go/cases/completeness/single_app_tracing/asynchronous_tracing/multi_thread/asynchronous_goroutine_channel_003_T/asynchronous_goroutine_channel_003_T.go\n AffectedNodeName: __taint_src\n 16: ARG PASS: func asynchronous_goroutine_channel_003_T(__taint_src string) {\n /sast-go/cases/completeness/single_app_tracing/asynchronous_tracing/multi_thread/asynchronous_goroutine_channel_003_T/asynchronous_goroutine_channel_003_T.go\n AffectedNodeName: __taint_sink\n 30: SINK: \t\t__taint_sink(message)\n==========================================================\n #Total-findings:1\n==========================================================","/benchmarks/sast-go/cases/completeness/single_app_tracing/asynchronous_tracing/multi_thread/asynchronous_goroutine_channel_004_F/asynchronous_goroutine_channel_004_F":"======================== Findings ========================\nNo findings!\n==========================================================","/benchmarks/sast-go/cases/completeness/single_app_tracing/asynchronous_tracing/multi_thread/asynchronous_multiple_select_001_T/asynchronous_multiple_select_001_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/sast-go/cases/completeness/single_app_tracing/asynchronous_tracing/multi_thread/asynchronous_multiple_select_001_T/asynchronous_multiple_select_001_T.go\nLine 33: __taint_sink(result)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/sast-go/cases/completeness/single_app_tracing/asynchronous_tracing/multi_thread/asynchronous_multiple_select_001_T/asynchronous_multiple_select_001_T.go\",\"functionName\":\"main\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /sast-go/cases/completeness/single_app_tracing/asynchronous_tracing/multi_thread/asynchronous_multiple_select_001_T/asynchronous_multiple_select_001_T.go\n AffectedNodeName: __taint_src\n 45: SOURCE: asynchronous_multiple_select_001_T(__taint_src)\n /sast-go/cases/completeness/single_app_tracing/asynchronous_tracing/multi_thread/asynchronous_multiple_select_001_T/asynchronous_multiple_select_001_T.go\n AffectedNodeName: asynchronous_multiple_select_001_T\n 45: CALL: asynchronous_multiple_select_001_T(__taint_src)\n /sast-go/cases/completeness/single_app_tracing/asynchronous_tracing/multi_thread/asynchronous_multiple_select_001_T/asynchronous_multiple_select_001_T.go\n AffectedNodeName: __taint_src\n 17: ARG PASS: func asynchronous_multiple_select_001_T(__taint_src string) {\n /sast-go/cases/completeness/single_app_tracing/asynchronous_tracing/multi_thread/asynchronous_multiple_select_001_T/asynchronous_multiple_select_001_T.go\n AffectedNodeName: result\n 22: Var Pass: \t\tresult := __taint_src\n /sast-go/cases/completeness/single_app_tracing/asynchronous_tracing/multi_thread/asynchronous_multiple_select_001_T/asynchronous_multiple_select_001_T.go\n AffectedNodeName: __taint_sink\n 33: SINK: \t\t__taint_sink(result)\n==========================================================\n #Total-findings:1\n==========================================================","/benchmarks/sast-go/cases/completeness/single_app_tracing/asynchronous_tracing/multi_thread/asynchronous_multiple_select_002_F/asynchronous_multiple_select_002_F":"======================== Findings ========================\nNo findings!\n==========================================================","/benchmarks/sast-go/cases/completeness/single_app_tracing/asynchronous_tracing/multi_thread/asynchronous_select_001_T/asynchronous_select_001_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/sast-go/cases/completeness/single_app_tracing/asynchronous_tracing/multi_thread/asynchronous_select_001_T/asynchronous_select_001_T.go\nLine 26: __taint_sink(result)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/sast-go/cases/completeness/single_app_tracing/asynchronous_tracing/multi_thread/asynchronous_select_001_T/asynchronous_select_001_T.go\",\"functionName\":\"main\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /sast-go/cases/completeness/single_app_tracing/asynchronous_tracing/multi_thread/asynchronous_select_001_T/asynchronous_select_001_T.go\n AffectedNodeName: __taint_src\n 36: SOURCE: asynchronous_select_001_T(__taint_src)\n /sast-go/cases/completeness/single_app_tracing/asynchronous_tracing/multi_thread/asynchronous_select_001_T/asynchronous_select_001_T.go\n AffectedNodeName: asynchronous_select_001_T\n 36: CALL: asynchronous_select_001_T(__taint_src)\n /sast-go/cases/completeness/single_app_tracing/asynchronous_tracing/multi_thread/asynchronous_select_001_T/asynchronous_select_001_T.go\n AffectedNodeName: __taint_src\n 17: ARG PASS: func asynchronous_select_001_T(__taint_src string) {\n /sast-go/cases/completeness/single_app_tracing/asynchronous_tracing/multi_thread/asynchronous_select_001_T/asynchronous_select_001_T.go\n AffectedNodeName: __taint_sink\n 26: SINK: \t\t__taint_sink(result)\n==========================================================\n #Total-findings:1\n==========================================================","/benchmarks/sast-go/cases/completeness/single_app_tracing/asynchronous_tracing/multi_thread/asynchronous_select_002_F/asynchronous_select_002_F":"======================== Findings ========================\nNo findings!\n==========================================================","/benchmarks/sast-go/cases/completeness/single_app_tracing/asynchronous_tracing/synchronization_primitive/synchronization_primitive_001_T/synchronization_primitive_001_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/sast-go/cases/completeness/single_app_tracing/asynchronous_tracing/synchronization_primitive/synchronization_primitive_001_T/synchronization_primitive_001_T.go\nLine 16: __taint_sink(result)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/sast-go/cases/completeness/single_app_tracing/asynchronous_tracing/synchronization_primitive/synchronization_primitive_001_T/synchronization_primitive_001_T.go\",\"functionName\":\"main\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /sast-go/cases/completeness/single_app_tracing/asynchronous_tracing/synchronization_primitive/synchronization_primitive_001_T/synchronization_primitive_001_T.go\n AffectedNodeName: __taint_src\n 22: SOURCE: synchronization_primitive_001_T(__taint_src)\n /sast-go/cases/completeness/single_app_tracing/asynchronous_tracing/synchronization_primitive/synchronization_primitive_001_T/synchronization_primitive_001_T.go\n AffectedNodeName: synchronization_primitive_001_T\n 22: CALL: synchronization_primitive_001_T(__taint_src)\n /sast-go/cases/completeness/single_app_tracing/asynchronous_tracing/synchronization_primitive/synchronization_primitive_001_T/synchronization_primitive_001_T.go\n AffectedNodeName: __taint_src\n 12: ARG PASS: func synchronization_primitive_001_T(__taint_src string) {\n /sast-go/cases/completeness/single_app_tracing/asynchronous_tracing/synchronization_primitive/synchronization_primitive_001_T/synchronization_primitive_001_T.go\n AffectedNodeName: __taint_sink\n 16: SINK: \t__taint_sink(result)\n==========================================================\n #Total-findings:1\n==========================================================","/benchmarks/sast-go/cases/completeness/single_app_tracing/asynchronous_tracing/synchronization_primitive/synchronization_primitive_002_F/synchronization_primitive_002_F":"======================== Findings ========================\nNo findings!\n==========================================================","/benchmarks/sast-go/cases/completeness/single_app_tracing/asynchronous_tracing/synchronization_primitive/synchronization_primitive_003_T/synchronization_primitive_003_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/sast-go/cases/completeness/single_app_tracing/asynchronous_tracing/synchronization_primitive/synchronization_primitive_003_T/synchronization_primitive_003_T.go\nLine 19: __taint_sink(result)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/sast-go/cases/completeness/single_app_tracing/asynchronous_tracing/synchronization_primitive/synchronization_primitive_003_T/synchronization_primitive_003_T.go\",\"functionName\":\"main\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /sast-go/cases/completeness/single_app_tracing/asynchronous_tracing/synchronization_primitive/synchronization_primitive_003_T/synchronization_primitive_003_T.go\n AffectedNodeName: __taint_src\n 25: SOURCE: synchronization_primitive_003_T(__taint_src)\n /sast-go/cases/completeness/single_app_tracing/asynchronous_tracing/synchronization_primitive/synchronization_primitive_003_T/synchronization_primitive_003_T.go\n AffectedNodeName: synchronization_primitive_003_T\n 25: CALL: synchronization_primitive_003_T(__taint_src)\n /sast-go/cases/completeness/single_app_tracing/asynchronous_tracing/synchronization_primitive/synchronization_primitive_003_T/synchronization_primitive_003_T.go\n AffectedNodeName: __taint_src\n 12: ARG PASS: func synchronization_primitive_003_T(__taint_src string) {\n /sast-go/cases/completeness/single_app_tracing/asynchronous_tracing/synchronization_primitive/synchronization_primitive_003_T/synchronization_primitive_003_T.go\n AffectedNodeName: __taint_sink\n 19: SINK: \t__taint_sink(result)\n==========================================================\n #Total-findings:1\n==========================================================","/benchmarks/sast-go/cases/completeness/single_app_tracing/asynchronous_tracing/synchronization_primitive/synchronization_primitive_004_F/synchronization_primitive_004_F":"======================== Findings ========================\nNo findings!\n==========================================================","/benchmarks/sast-go/cases/completeness/single_app_tracing/control_flow/conditional_stmt/conditional_if_001_T/conditional_if_001_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/sast-go/cases/completeness/single_app_tracing/control_flow/conditional_stmt/conditional_if_001_T/conditional_if_001_T.go\nLine 14: __taint_sink(__taint_src)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/sast-go/cases/completeness/single_app_tracing/control_flow/conditional_stmt/conditional_if_001_T/conditional_if_001_T.go\",\"functionName\":\"main\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /sast-go/cases/completeness/single_app_tracing/control_flow/conditional_stmt/conditional_if_001_T/conditional_if_001_T.go\n AffectedNodeName: __taint_src\n 21: SOURCE: conditional_if_001_T(__taint_src)\n /sast-go/cases/completeness/single_app_tracing/control_flow/conditional_stmt/conditional_if_001_T/conditional_if_001_T.go\n AffectedNodeName: conditional_if_001_T\n 21: CALL: conditional_if_001_T(__taint_src)\n /sast-go/cases/completeness/single_app_tracing/control_flow/conditional_stmt/conditional_if_001_T/conditional_if_001_T.go\n AffectedNodeName: __taint_src\n 12: ARG PASS: func conditional_if_001_T(__taint_src string) {\n /sast-go/cases/completeness/single_app_tracing/control_flow/conditional_stmt/conditional_if_001_T/conditional_if_001_T.go\n AffectedNodeName: __taint_sink\n 14: SINK: \t\t__taint_sink(__taint_src)\n==========================================================\n #Total-findings:1\n==========================================================","/benchmarks/sast-go/cases/completeness/single_app_tracing/control_flow/conditional_stmt/conditional_if_002_F/conditional_if_002_F":"======================== Findings ========================\nNo findings!\n==========================================================","/benchmarks/sast-go/cases/completeness/single_app_tracing/control_flow/conditional_stmt/conditional_if_003_T/conditional_if_003_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/sast-go/cases/completeness/single_app_tracing/control_flow/conditional_stmt/conditional_if_003_T/conditional_if_003_T.go\nLine 16: __taint_sink(__taint_src)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/sast-go/cases/completeness/single_app_tracing/control_flow/conditional_stmt/conditional_if_003_T/conditional_if_003_T.go\",\"functionName\":\"main\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /sast-go/cases/completeness/single_app_tracing/control_flow/conditional_stmt/conditional_if_003_T/conditional_if_003_T.go\n AffectedNodeName: __taint_src\n 25: SOURCE: conditional_if_003_T(__taint_src)\n /sast-go/cases/completeness/single_app_tracing/control_flow/conditional_stmt/conditional_if_003_T/conditional_if_003_T.go\n AffectedNodeName: conditional_if_003_T\n 25: CALL: conditional_if_003_T(__taint_src)\n /sast-go/cases/completeness/single_app_tracing/control_flow/conditional_stmt/conditional_if_003_T/conditional_if_003_T.go\n AffectedNodeName: __taint_src\n 12: ARG PASS: func conditional_if_003_T(__taint_src string) {\n /sast-go/cases/completeness/single_app_tracing/control_flow/conditional_stmt/conditional_if_003_T/conditional_if_003_T.go\n AffectedNodeName: __taint_sink\n 16: SINK: \t\t__taint_sink(__taint_src)\n==========================================================\n #Total-findings:1\n==========================================================","/benchmarks/sast-go/cases/completeness/single_app_tracing/control_flow/conditional_stmt/conditional_if_004_F/conditional_if_004_F":"======================== Findings ========================\nNo findings!\n==========================================================","/benchmarks/sast-go/cases/completeness/single_app_tracing/control_flow/conditional_stmt/conditional_switch_001_T/conditional_switch_001_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/sast-go/cases/completeness/single_app_tracing/control_flow/conditional_stmt/conditional_switch_001_T/conditional_switch_001_T.go\nLine 15: __taint_sink(__taint_src)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/sast-go/cases/completeness/single_app_tracing/control_flow/conditional_stmt/conditional_switch_001_T/conditional_switch_001_T.go\",\"functionName\":\"main\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /sast-go/cases/completeness/single_app_tracing/control_flow/conditional_stmt/conditional_switch_001_T/conditional_switch_001_T.go\n AffectedNodeName: __taint_src\n 22: SOURCE: conditional_switch_001_T(__taint_src)\n /sast-go/cases/completeness/single_app_tracing/control_flow/conditional_stmt/conditional_switch_001_T/conditional_switch_001_T.go\n AffectedNodeName: conditional_switch_001_T\n 22: CALL: conditional_switch_001_T(__taint_src)\n /sast-go/cases/completeness/single_app_tracing/control_flow/conditional_stmt/conditional_switch_001_T/conditional_switch_001_T.go\n AffectedNodeName: __taint_src\n 12: ARG PASS: func conditional_switch_001_T(__taint_src string) {\n /sast-go/cases/completeness/single_app_tracing/control_flow/conditional_stmt/conditional_switch_001_T/conditional_switch_001_T.go\n AffectedNodeName: __taint_sink\n 15: SINK: \t\t__taint_sink(__taint_src)\n==========================================================\n #Total-findings:1\n==========================================================","/benchmarks/sast-go/cases/completeness/single_app_tracing/control_flow/conditional_stmt/conditional_switch_002_F/conditional_switch_002_F":"======================== Findings ========================\nNo findings!\n==========================================================","/benchmarks/sast-go/cases/completeness/single_app_tracing/control_flow/conditional_stmt/conditional_switch_003_T/conditional_switch_003_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/sast-go/cases/completeness/single_app_tracing/control_flow/conditional_stmt/conditional_switch_003_T/conditional_switch_003_T.go\nLine 16: __taint_sink(data)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/sast-go/cases/completeness/single_app_tracing/control_flow/conditional_stmt/conditional_switch_003_T/conditional_switch_003_T.go\",\"functionName\":\"main\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /sast-go/cases/completeness/single_app_tracing/control_flow/conditional_stmt/conditional_switch_003_T/conditional_switch_003_T.go\n AffectedNodeName: __taint_src\n 23: SOURCE: conditional_switch_003_T(__taint_src)\n /sast-go/cases/completeness/single_app_tracing/control_flow/conditional_stmt/conditional_switch_003_T/conditional_switch_003_T.go\n AffectedNodeName: conditional_switch_003_T\n 23: CALL: conditional_switch_003_T(__taint_src)\n /sast-go/cases/completeness/single_app_tracing/control_flow/conditional_stmt/conditional_switch_003_T/conditional_switch_003_T.go\n AffectedNodeName: __taint_src\n 12: ARG PASS: func conditional_switch_003_T(__taint_src string) {\n /sast-go/cases/completeness/single_app_tracing/control_flow/conditional_stmt/conditional_switch_003_T/conditional_switch_003_T.go\n AffectedNodeName: data\n 14: Var Pass: \tswitch data := __taint_src; data {\n /sast-go/cases/completeness/single_app_tracing/control_flow/conditional_stmt/conditional_switch_003_T/conditional_switch_003_T.go\n AffectedNodeName: __taint_sink\n 16: SINK: \t\t__taint_sink(data)\n==========================================================\n #Total-findings:1\n==========================================================","/benchmarks/sast-go/cases/completeness/single_app_tracing/control_flow/conditional_stmt/conditional_switch_004_F/conditional_switch_004_F":"======================== Findings ========================\nNo findings!\n==========================================================","/benchmarks/sast-go/cases/completeness/single_app_tracing/control_flow/conditional_stmt/conditional_switch_005_T/conditional_switch_005_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/sast-go/cases/completeness/single_app_tracing/control_flow/conditional_stmt/conditional_switch_005_T/conditional_switch_005_T.go\nLine 22: __taint_sink(__taint_src)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/sast-go/cases/completeness/single_app_tracing/control_flow/conditional_stmt/conditional_switch_005_T/conditional_switch_005_T.go\",\"functionName\":\"main\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /sast-go/cases/completeness/single_app_tracing/control_flow/conditional_stmt/conditional_switch_005_T/conditional_switch_005_T.go\n AffectedNodeName: __taint_src\n 30: SOURCE: conditional_switch_005_T(__taint_src)\n /sast-go/cases/completeness/single_app_tracing/control_flow/conditional_stmt/conditional_switch_005_T/conditional_switch_005_T.go\n AffectedNodeName: conditional_switch_005_T\n 30: CALL: conditional_switch_005_T(__taint_src)\n /sast-go/cases/completeness/single_app_tracing/control_flow/conditional_stmt/conditional_switch_005_T/conditional_switch_005_T.go\n AffectedNodeName: __taint_src\n 12: ARG PASS: func conditional_switch_005_T(__taint_src string) {\n /sast-go/cases/completeness/single_app_tracing/control_flow/conditional_stmt/conditional_switch_005_T/conditional_switch_005_T.go\n AffectedNodeName: __taint_sink\n 22: SINK: \t\t\t__taint_sink(__taint_src)\n==========================================================\n #Total-findings:1\n==========================================================","/benchmarks/sast-go/cases/completeness/single_app_tracing/control_flow/conditional_stmt/conditional_switch_006_F/conditional_switch_006_F":"======================== Findings ========================\nNo findings!\n==========================================================","/benchmarks/sast-go/cases/completeness/single_app_tracing/control_flow/conditional_stmt/select_001_T/select_001_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/sast-go/cases/completeness/single_app_tracing/control_flow/conditional_stmt/select_001_T/select_001_T.go\nLine 18: __taint_sink(data)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/sast-go/cases/completeness/single_app_tracing/control_flow/conditional_stmt/select_001_T/select_001_T.go\",\"functionName\":\"main\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /sast-go/cases/completeness/single_app_tracing/control_flow/conditional_stmt/select_001_T/select_001_T.go\n AffectedNodeName: __taint_src\n 27: SOURCE: select_001_T(__taint_src)\n /sast-go/cases/completeness/single_app_tracing/control_flow/conditional_stmt/select_001_T/select_001_T.go\n AffectedNodeName: select_001_T\n 27: CALL: select_001_T(__taint_src)\n /sast-go/cases/completeness/single_app_tracing/control_flow/conditional_stmt/select_001_T/select_001_T.go\n AffectedNodeName: __taint_src\n 12: ARG PASS: func select_001_T(__taint_src string) {\n /sast-go/cases/completeness/single_app_tracing/control_flow/conditional_stmt/select_001_T/select_001_T.go\n AffectedNodeName: __taint_sink\n 18: SINK: \t\t__taint_sink(data)\n==========================================================\n #Total-findings:1\n==========================================================","/benchmarks/sast-go/cases/completeness/single_app_tracing/control_flow/conditional_stmt/select_002_F/select_002_F":"======================== Findings ========================\nNo findings!\n==========================================================","/benchmarks/sast-go/cases/completeness/single_app_tracing/control_flow/loop_stmt/for_body_001_T/for_body_001_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/sast-go/cases/completeness/single_app_tracing/control_flow/loop_stmt/for_body_001_T/for_body_001_T.go\nLine 18: __taint_sink(res)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/sast-go/cases/completeness/single_app_tracing/control_flow/loop_stmt/for_body_001_T/for_body_001_T.go\",\"functionName\":\"main\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /sast-go/cases/completeness/single_app_tracing/control_flow/loop_stmt/for_body_001_T/for_body_001_T.go\n AffectedNodeName: __taint_src\n 24: SOURCE: for_body_001_T(__taint_src)\n /sast-go/cases/completeness/single_app_tracing/control_flow/loop_stmt/for_body_001_T/for_body_001_T.go\n AffectedNodeName: for_body_001_T\n 24: CALL: for_body_001_T(__taint_src)\n /sast-go/cases/completeness/single_app_tracing/control_flow/loop_stmt/for_body_001_T/for_body_001_T.go\n AffectedNodeName: __taint_src\n 12: ARG PASS: func for_body_001_T(__taint_src string) {\n /sast-go/cases/completeness/single_app_tracing/control_flow/loop_stmt/for_body_001_T/for_body_001_T.go\n AffectedNodeName: res\n 16: Var Pass: \t\tres = __taint_src\n /sast-go/cases/completeness/single_app_tracing/control_flow/loop_stmt/for_body_001_T/for_body_001_T.go\n AffectedNodeName: __taint_sink\n 18: SINK: \t__taint_sink(res)\n==========================================================\n #Total-findings:1\n==========================================================","/benchmarks/sast-go/cases/completeness/single_app_tracing/control_flow/loop_stmt/for_body_002_F/for_body_002_F":"======================== Findings ========================\nNo findings!\n==========================================================","/benchmarks/sast-go/cases/completeness/single_app_tracing/control_flow/loop_stmt/for_init_001_T/for_init_001_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/sast-go/cases/completeness/single_app_tracing/control_flow/loop_stmt/for_init_001_T/for_init_001_T.go\nLine 19: __taint_sink(res)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/sast-go/cases/completeness/single_app_tracing/control_flow/loop_stmt/for_init_001_T/for_init_001_T.go\",\"functionName\":\"main\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /sast-go/cases/completeness/single_app_tracing/control_flow/loop_stmt/for_init_001_T/for_init_001_T.go\n AffectedNodeName: __taint_src\n 25: SOURCE: for_init_001_T(__taint_src)\n /sast-go/cases/completeness/single_app_tracing/control_flow/loop_stmt/for_init_001_T/for_init_001_T.go\n AffectedNodeName: for_init_001_T\n 25: CALL: for_init_001_T(__taint_src)\n /sast-go/cases/completeness/single_app_tracing/control_flow/loop_stmt/for_init_001_T/for_init_001_T.go\n AffectedNodeName: __taint_src\n 12: ARG PASS: func for_init_001_T(__taint_src int) {\n /sast-go/cases/completeness/single_app_tracing/control_flow/loop_stmt/for_init_001_T/for_init_001_T.go\n AffectedNodeName: ini\n 16: Var Pass: \tfor ini = __taint_src; j < 10; j++ {\n /sast-go/cases/completeness/single_app_tracing/control_flow/loop_stmt/for_init_001_T/for_init_001_T.go\n AffectedNodeName: res\n 17: Var Pass: \t\tres = res + ini\n /sast-go/cases/completeness/single_app_tracing/control_flow/loop_stmt/for_init_001_T/for_init_001_T.go\n AffectedNodeName: __taint_sink\n 19: SINK: \t__taint_sink(res)\n==========================================================\n #Total-findings:1\n==========================================================","/benchmarks/sast-go/cases/completeness/single_app_tracing/control_flow/loop_stmt/for_init_002_F/for_init_002_F":"======================== Findings ========================\nNo findings!\n==========================================================","/benchmarks/sast-go/cases/completeness/single_app_tracing/control_flow/loop_stmt/for_range_001_T/for_range_001_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/sast-go/cases/completeness/single_app_tracing/control_flow/loop_stmt/for_range_001_T/for_range_001_T.go\nLine 15: __taint_sink(res)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/sast-go/cases/completeness/single_app_tracing/control_flow/loop_stmt/for_range_001_T/for_range_001_T.go\",\"functionName\":\"main\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /sast-go/cases/completeness/single_app_tracing/control_flow/loop_stmt/for_range_001_T/for_range_001_T.go\n AffectedNodeName: __taint_src\n 22: SOURCE: for_range_001_T(__taint_src)\n /sast-go/cases/completeness/single_app_tracing/control_flow/loop_stmt/for_range_001_T/for_range_001_T.go\n AffectedNodeName: for_range_001_T\n 22: CALL: for_range_001_T(__taint_src)\n /sast-go/cases/completeness/single_app_tracing/control_flow/loop_stmt/for_range_001_T/for_range_001_T.go\n AffectedNodeName: __taint_src\n 12: ARG PASS: func for_range_001_T(__taint_src string) {\n /sast-go/cases/completeness/single_app_tracing/control_flow/loop_stmt/for_range_001_T/for_range_001_T.go\n AffectedNodeName: m\n 13: Var Pass: \tvar m = map[string]string{\"a\": __taint_src, \"b\": \"2\"}\n /sast-go/cases/completeness/single_app_tracing/control_flow/loop_stmt/for_range_001_T/for_range_001_T.go\n AffectedNodeName: __taint_sink\n 15: SINK: \t\t__taint_sink(res)\n==========================================================\n #Total-findings:1\n==========================================================","/benchmarks/sast-go/cases/completeness/single_app_tracing/control_flow/loop_stmt/for_range_002_F/for_range_002_F":"======================== Findings ========================\nNo findings!\n==========================================================","/benchmarks/sast-go/cases/completeness/single_app_tracing/control_flow/loop_stmt/for_update_001_T/for_update_001_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/sast-go/cases/completeness/single_app_tracing/control_flow/loop_stmt/for_update_001_T/for_update_001_T.go\nLine 20: __taint_sink(res)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/sast-go/cases/completeness/single_app_tracing/control_flow/loop_stmt/for_update_001_T/for_update_001_T.go\",\"functionName\":\"main\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /sast-go/cases/completeness/single_app_tracing/control_flow/loop_stmt/for_update_001_T/for_update_001_T.go\n AffectedNodeName: __taint_src\n 26: SOURCE: for_update_001_T(__taint_src)\n /sast-go/cases/completeness/single_app_tracing/control_flow/loop_stmt/for_update_001_T/for_update_001_T.go\n AffectedNodeName: for_update_001_T\n 26: CALL: for_update_001_T(__taint_src)\n /sast-go/cases/completeness/single_app_tracing/control_flow/loop_stmt/for_update_001_T/for_update_001_T.go\n AffectedNodeName: __taint_src\n 12: ARG PASS: func for_update_001_T(__taint_src int) {\n /sast-go/cases/completeness/single_app_tracing/control_flow/loop_stmt/for_update_001_T/for_update_001_T.go\n AffectedNodeName: j\n 16: Var Pass: \tfor ; ini < 2; j = __taint_src {\n /sast-go/cases/completeness/single_app_tracing/control_flow/loop_stmt/for_update_001_T/for_update_001_T.go\n AffectedNodeName: res\n 17: Var Pass: \t\tres = j\n /sast-go/cases/completeness/single_app_tracing/control_flow/loop_stmt/for_update_001_T/for_update_001_T.go\n AffectedNodeName: __taint_sink\n 20: SINK: \t__taint_sink(res)\n==========================================================\n #Total-findings:1\n==========================================================","/benchmarks/sast-go/cases/completeness/single_app_tracing/control_flow/loop_stmt/for_update_002_F/for_update_002_F":"======================== Findings ========================\nNo findings!\n==========================================================","/benchmarks/sast-go/cases/completeness/single_app_tracing/datatype/array/array_001_T/array_001_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/sast-go/cases/completeness/single_app_tracing/datatype/array/array_001_T/array_001_T.go\nLine 14: __taint_sink(str)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/sast-go/cases/completeness/single_app_tracing/datatype/array/array_001_T/array_001_T.go\",\"functionName\":\"main\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /sast-go/cases/completeness/single_app_tracing/datatype/array/array_001_T/array_001_T.go\n AffectedNodeName: __taint_src\n 21: SOURCE: array_001_T(__taint_src)\n /sast-go/cases/completeness/single_app_tracing/datatype/array/array_001_T/array_001_T.go\n AffectedNodeName: array_001_T\n 21: CALL: array_001_T(__taint_src)\n /sast-go/cases/completeness/single_app_tracing/datatype/array/array_001_T/array_001_T.go\n AffectedNodeName: __taint_src\n 12: ARG PASS: func array_001_T(__taint_src string) {\n /sast-go/cases/completeness/single_app_tracing/datatype/array/array_001_T/array_001_T.go\n AffectedNodeName: str\n 13: Var Pass: \tvar str = [3]string{__taint_src, \"b\", \"c\"}\n /sast-go/cases/completeness/single_app_tracing/datatype/array/array_001_T/array_001_T.go\n AffectedNodeName: __taint_sink\n 14: SINK: \t__taint_sink(str)\n==========================================================\n #Total-findings:1\n==========================================================","/benchmarks/sast-go/cases/completeness/single_app_tracing/datatype/array/array_002_F/array_002_F":"======================== Findings ========================\nNo findings!\n==========================================================","/benchmarks/sast-go/cases/completeness/single_app_tracing/datatype/array/array_003_T/array_003_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/sast-go/cases/completeness/single_app_tracing/datatype/array/array_003_T/array_003_T.go\nLine 14: __taint_sink(str)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/sast-go/cases/completeness/single_app_tracing/datatype/array/array_003_T/array_003_T.go\",\"functionName\":\"main\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /sast-go/cases/completeness/single_app_tracing/datatype/array/array_003_T/array_003_T.go\n AffectedNodeName: __taint_src\n 21: SOURCE: array_003_T(__taint_src)\n /sast-go/cases/completeness/single_app_tracing/datatype/array/array_003_T/array_003_T.go\n AffectedNodeName: array_003_T\n 21: CALL: array_003_T(__taint_src)\n /sast-go/cases/completeness/single_app_tracing/datatype/array/array_003_T/array_003_T.go\n AffectedNodeName: __taint_src\n 12: ARG PASS: func array_003_T(__taint_src string) {\n /sast-go/cases/completeness/single_app_tracing/datatype/array/array_003_T/array_003_T.go\n AffectedNodeName: str\n 13: Var Pass: \tvar str = [3][1]string{[1]string{__taint_src}, [1]string{\"b\"}, [1]string{\"c\"}}\n /sast-go/cases/completeness/single_app_tracing/datatype/array/array_003_T/array_003_T.go\n AffectedNodeName: __taint_sink\n 14: SINK: \t__taint_sink(str)\n==========================================================\n #Total-findings:1\n==========================================================","/benchmarks/sast-go/cases/completeness/single_app_tracing/datatype/array/array_004_F/array_004_F":"======================== Findings ========================\nNo findings!\n==========================================================","/benchmarks/sast-go/cases/completeness/single_app_tracing/datatype/array/array_005_T/array_005_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/sast-go/cases/completeness/single_app_tracing/datatype/array/array_005_T/array_005_T.go\nLine 13: __taint_sink(__taint_src)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/sast-go/cases/completeness/single_app_tracing/datatype/array/array_005_T/array_005_T.go\",\"functionName\":\"main\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /sast-go/cases/completeness/single_app_tracing/datatype/array/array_005_T/array_005_T.go\n AffectedNodeName: __taint_src\n 20: SOURCE: array_005_T(__taint_src)\n /sast-go/cases/completeness/single_app_tracing/datatype/array/array_005_T/array_005_T.go\n AffectedNodeName: array_005_T\n 20: CALL: array_005_T(__taint_src)\n /sast-go/cases/completeness/single_app_tracing/datatype/array/array_005_T/array_005_T.go\n AffectedNodeName: __taint_src\n 12: ARG PASS: func array_005_T(__taint_src [3]string) {\n /sast-go/cases/completeness/single_app_tracing/datatype/array/array_005_T/array_005_T.go\n AffectedNodeName: __taint_sink\n 13: SINK: \t__taint_sink(__taint_src)\n==========================================================\n #Total-findings:1\n==========================================================","/benchmarks/sast-go/cases/completeness/single_app_tracing/datatype/array/array_006_F/array_006_F":"======================== Findings ========================\nNo findings!\n==========================================================","/benchmarks/sast-go/cases/completeness/single_app_tracing/datatype/array/array_007_T/array_007_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/sast-go/cases/completeness/single_app_tracing/datatype/array/array_007_T/array_007_T.go\nLine 14: __taint_sink(str)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/sast-go/cases/completeness/single_app_tracing/datatype/array/array_007_T/array_007_T.go\",\"functionName\":\"main\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /sast-go/cases/completeness/single_app_tracing/datatype/array/array_007_T/array_007_T.go\n AffectedNodeName: __taint_src\n 20: SOURCE: array_007_T(__taint_src)\n /sast-go/cases/completeness/single_app_tracing/datatype/array/array_007_T/array_007_T.go\n AffectedNodeName: array_007_T\n 20: CALL: array_007_T(__taint_src)\n /sast-go/cases/completeness/single_app_tracing/datatype/array/array_007_T/array_007_T.go\n AffectedNodeName: __taint_src\n 12: ARG PASS: func array_007_T(__taint_src string) {\n /sast-go/cases/completeness/single_app_tracing/datatype/array/array_007_T/array_007_T.go\n AffectedNodeName: str\n 13: Var Pass: \tvar str = [...]string{__taint_src, \"b\", \"c\"}\n /sast-go/cases/completeness/single_app_tracing/datatype/array/array_007_T/array_007_T.go\n AffectedNodeName: __taint_sink\n 14: SINK: \t__taint_sink(str)\n==========================================================\n #Total-findings:1\n==========================================================","/benchmarks/sast-go/cases/completeness/single_app_tracing/datatype/array/array_008_F/array_008_F":"======================== Findings ========================\nNo findings!\n==========================================================","/benchmarks/sast-go/cases/completeness/single_app_tracing/datatype/generics/generics_001_T/generics_001_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/sast-go/cases/completeness/single_app_tracing/datatype/generics/generics_001_T/generics_001_T.go\nLine 16: __taint_sink(s)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/sast-go/cases/completeness/single_app_tracing/datatype/generics/generics_001_T/generics_001_T.go\",\"functionName\":\"main\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /sast-go/cases/completeness/single_app_tracing/datatype/generics/generics_001_T/generics_001_T.go\n AffectedNodeName: __taint_src\n 23: SOURCE: generics_001_T(__taint_src)\n /sast-go/cases/completeness/single_app_tracing/datatype/generics/generics_001_T/generics_001_T.go\n AffectedNodeName: generics_001_T\n 23: CALL: generics_001_T(__taint_src)\n /sast-go/cases/completeness/single_app_tracing/datatype/generics/generics_001_T/generics_001_T.go\n AffectedNodeName: __taint_src\n 14: ARG PASS: func generics_001_T(__taint_src string) {\n /sast-go/cases/completeness/single_app_tracing/datatype/generics/generics_001_T/generics_001_T.go\n AffectedNodeName: s\n 15: Var Pass: \tvar s Slice[string] = []string{\"a\", \"b\", __taint_src}\n /sast-go/cases/completeness/single_app_tracing/datatype/generics/generics_001_T/generics_001_T.go\n AffectedNodeName: __taint_sink\n 16: SINK: \t__taint_sink(s)\n==========================================================\n #Total-findings:1\n==========================================================","/benchmarks/sast-go/cases/completeness/single_app_tracing/datatype/generics/generics_002_F/generics_002_F":"======================== Findings ========================\nNo findings!\n==========================================================","/benchmarks/sast-go/cases/completeness/single_app_tracing/datatype/map/map_001_T/map_001_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/sast-go/cases/completeness/single_app_tracing/datatype/map/map_001_T/map_001_T.go\nLine 15: __taint_sink(m)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/sast-go/cases/completeness/single_app_tracing/datatype/map/map_001_T/map_001_T.go\",\"functionName\":\"main\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /sast-go/cases/completeness/single_app_tracing/datatype/map/map_001_T/map_001_T.go\n AffectedNodeName: __taint_src\n 22: SOURCE: map_001_T(__taint_src)\n /sast-go/cases/completeness/single_app_tracing/datatype/map/map_001_T/map_001_T.go\n AffectedNodeName: map_001_T\n 22: CALL: map_001_T(__taint_src)\n /sast-go/cases/completeness/single_app_tracing/datatype/map/map_001_T/map_001_T.go\n AffectedNodeName: __taint_src\n 12: ARG PASS: func map_001_T(__taint_src string) {\n /sast-go/cases/completeness/single_app_tracing/datatype/map/map_001_T/map_001_T.go\n AffectedNodeName: m[\"key1\"]\n 14: Var Pass: \tm[\"key1\"] = __taint_src\n /sast-go/cases/completeness/single_app_tracing/datatype/map/map_001_T/map_001_T.go\n AffectedNodeName: __taint_sink\n 15: SINK: \t__taint_sink(m)\n==========================================================\n #Total-findings:1\n==========================================================","/benchmarks/sast-go/cases/completeness/single_app_tracing/datatype/map/map_002_F/map_002_F":"======================== Findings ========================\nNo findings!\n==========================================================","/benchmarks/sast-go/cases/completeness/single_app_tracing/datatype/map/map_003_T/map_003_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/sast-go/cases/completeness/single_app_tracing/datatype/map/map_003_T/map_003_T.go\nLine 16: __taint_sink(m)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/sast-go/cases/completeness/single_app_tracing/datatype/map/map_003_T/map_003_T.go\",\"functionName\":\"main\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /sast-go/cases/completeness/single_app_tracing/datatype/map/map_003_T/map_003_T.go\n AffectedNodeName: __taint_src\n 23: SOURCE: map_003_T(__taint_src)\n /sast-go/cases/completeness/single_app_tracing/datatype/map/map_003_T/map_003_T.go\n AffectedNodeName: map_003_T\n 23: CALL: map_003_T(__taint_src)\n /sast-go/cases/completeness/single_app_tracing/datatype/map/map_003_T/map_003_T.go\n AffectedNodeName: __taint_src\n 12: ARG PASS: func map_003_T(__taint_src string) {\n /sast-go/cases/completeness/single_app_tracing/datatype/map/map_003_T/map_003_T.go\n AffectedNodeName: m\n 13: Var Pass: \tm := map[string]string{\n 14: Var Pass: \t\t\"key1\": __taint_src,\n 15: Var Pass: \t}\n /sast-go/cases/completeness/single_app_tracing/datatype/map/map_003_T/map_003_T.go\n AffectedNodeName: __taint_sink\n 16: SINK: \t__taint_sink(m)\n==========================================================\n #Total-findings:1\n==========================================================","/benchmarks/sast-go/cases/completeness/single_app_tracing/datatype/map/map_004_F/map_004_F":"======================== Findings ========================\nNo findings!\n==========================================================","/benchmarks/sast-go/cases/completeness/single_app_tracing/datatype/pointer/pointer_001_T/pointer_001_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/sast-go/cases/completeness/single_app_tracing/datatype/pointer/pointer_001_T/pointer_001_T.go\nLine 14: __taint_sink(*ps)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/sast-go/cases/completeness/single_app_tracing/datatype/pointer/pointer_001_T/pointer_001_T.go\",\"functionName\":\"main\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /sast-go/cases/completeness/single_app_tracing/datatype/pointer/pointer_001_T/pointer_001_T.go\n AffectedNodeName: __taint_src\n 21: SOURCE: pointer_001_T(__taint_src)\n /sast-go/cases/completeness/single_app_tracing/datatype/pointer/pointer_001_T/pointer_001_T.go\n AffectedNodeName: pointer_001_T\n 21: CALL: pointer_001_T(__taint_src)\n /sast-go/cases/completeness/single_app_tracing/datatype/pointer/pointer_001_T/pointer_001_T.go\n AffectedNodeName: __taint_src\n 12: ARG PASS: func pointer_001_T(__taint_src string) {\n /sast-go/cases/completeness/single_app_tracing/datatype/pointer/pointer_001_T/pointer_001_T.go\n AffectedNodeName: ps\n 13: Var Pass: \tps := &__taint_src\n /sast-go/cases/completeness/single_app_tracing/datatype/pointer/pointer_001_T/pointer_001_T.go\n AffectedNodeName: __taint_sink\n 14: SINK: \t__taint_sink(*ps)\n==========================================================\n #Total-findings:1\n==========================================================","/benchmarks/sast-go/cases/completeness/single_app_tracing/datatype/pointer/pointer_002_F/pointer_002_F":"======================== Findings ========================\nNo findings!\n==========================================================","/benchmarks/sast-go/cases/completeness/single_app_tracing/datatype/pointer/pointer_new_001_T/pointer_new_001_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/sast-go/cases/completeness/single_app_tracing/datatype/pointer/pointer_new_001_T/pointer_new_001_T.go\nLine 16: __taint_sink(*ps)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/sast-go/cases/completeness/single_app_tracing/datatype/pointer/pointer_new_001_T/pointer_new_001_T.go\",\"functionName\":\"main\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /sast-go/cases/completeness/single_app_tracing/datatype/pointer/pointer_new_001_T/pointer_new_001_T.go\n AffectedNodeName: __taint_src\n 23: SOURCE: pointer_new_001_T(__taint_src)\n /sast-go/cases/completeness/single_app_tracing/datatype/pointer/pointer_new_001_T/pointer_new_001_T.go\n AffectedNodeName: pointer_new_001_T\n 23: CALL: pointer_new_001_T(__taint_src)\n /sast-go/cases/completeness/single_app_tracing/datatype/pointer/pointer_new_001_T/pointer_new_001_T.go\n AffectedNodeName: __taint_src\n 12: ARG PASS: func pointer_new_001_T(__taint_src string) {\n /sast-go/cases/completeness/single_app_tracing/datatype/pointer/pointer_new_001_T/pointer_new_001_T.go\n 15: Var Pass: \t*ps = __taint_src\n /sast-go/cases/completeness/single_app_tracing/datatype/pointer/pointer_new_001_T/pointer_new_001_T.go\n AffectedNodeName: __taint_sink\n 16: SINK: \t__taint_sink(*ps)\n==========================================================\n #Total-findings:1\n==========================================================","/benchmarks/sast-go/cases/completeness/single_app_tracing/datatype/pointer/pointer_new_002_F/pointer_new_002_F":"======================== Findings ========================\nNo findings!\n==========================================================","/benchmarks/sast-go/cases/completeness/single_app_tracing/datatype/primitives/primitives_bool_001_T/primitives_bool_001_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/sast-go/cases/completeness/single_app_tracing/datatype/primitives/primitives_bool_001_T/primitives_bool_001_T.go\nLine 13: __taint_sink(__taint_src)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/sast-go/cases/completeness/single_app_tracing/datatype/primitives/primitives_bool_001_T/primitives_bool_001_T.go\",\"functionName\":\"main\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /sast-go/cases/completeness/single_app_tracing/datatype/primitives/primitives_bool_001_T/primitives_bool_001_T.go\n AffectedNodeName: __taint_src\n 19: SOURCE: primitives_bool_001_T(__taint_src)\n /sast-go/cases/completeness/single_app_tracing/datatype/primitives/primitives_bool_001_T/primitives_bool_001_T.go\n AffectedNodeName: primitives_bool_001_T\n 19: CALL: primitives_bool_001_T(__taint_src)\n /sast-go/cases/completeness/single_app_tracing/datatype/primitives/primitives_bool_001_T/primitives_bool_001_T.go\n AffectedNodeName: __taint_src\n 12: ARG PASS: func primitives_bool_001_T(__taint_src bool) {\n /sast-go/cases/completeness/single_app_tracing/datatype/primitives/primitives_bool_001_T/primitives_bool_001_T.go\n AffectedNodeName: __taint_sink\n 13: SINK: \t__taint_sink(__taint_src)\n==========================================================\n #Total-findings:1\n==========================================================","/benchmarks/sast-go/cases/completeness/single_app_tracing/datatype/primitives/primitives_bool_002_F/primitives_bool_002_F":"======================== Findings ========================\nNo findings!\n==========================================================","/benchmarks/sast-go/cases/completeness/single_app_tracing/datatype/primitives/primitives_complex_001_T/primitives_complex_001_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/sast-go/cases/completeness/single_app_tracing/datatype/primitives/primitives_complex_001_T/primitives_complex_001_T.go\nLine 13: __taint_sink(__taint_src)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/sast-go/cases/completeness/single_app_tracing/datatype/primitives/primitives_complex_001_T/primitives_complex_001_T.go\",\"functionName\":\"main\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /sast-go/cases/completeness/single_app_tracing/datatype/primitives/primitives_complex_001_T/primitives_complex_001_T.go\n AffectedNodeName: __taint_src\n 20: SOURCE: primitives_complex_001_T(__taint_src)\n /sast-go/cases/completeness/single_app_tracing/datatype/primitives/primitives_complex_001_T/primitives_complex_001_T.go\n AffectedNodeName: primitives_complex_001_T\n 20: CALL: primitives_complex_001_T(__taint_src)\n /sast-go/cases/completeness/single_app_tracing/datatype/primitives/primitives_complex_001_T/primitives_complex_001_T.go\n AffectedNodeName: __taint_src\n 12: ARG PASS: func primitives_complex_001_T(__taint_src complex64) {\n /sast-go/cases/completeness/single_app_tracing/datatype/primitives/primitives_complex_001_T/primitives_complex_001_T.go\n AffectedNodeName: __taint_sink\n 13: SINK: \t__taint_sink(__taint_src)\n==========================================================\n #Total-findings:1\n==========================================================","/benchmarks/sast-go/cases/completeness/single_app_tracing/datatype/primitives/primitives_complex_002_F/primitives_complex_002_F":"======================== Findings ========================\nNo findings!\n==========================================================","/benchmarks/sast-go/cases/completeness/single_app_tracing/datatype/primitives/primitives_float_001_T/primitives_float_001_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/sast-go/cases/completeness/single_app_tracing/datatype/primitives/primitives_float_001_T/primitives_float_001_T.go\nLine 13: __taint_sink(__taint_src)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/sast-go/cases/completeness/single_app_tracing/datatype/primitives/primitives_float_001_T/primitives_float_001_T.go\",\"functionName\":\"main\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /sast-go/cases/completeness/single_app_tracing/datatype/primitives/primitives_float_001_T/primitives_float_001_T.go\n AffectedNodeName: __taint_src\n 20: SOURCE: primitives_float_001_T(__taint_src)\n /sast-go/cases/completeness/single_app_tracing/datatype/primitives/primitives_float_001_T/primitives_float_001_T.go\n AffectedNodeName: primitives_float_001_T\n 20: CALL: primitives_float_001_T(__taint_src)\n /sast-go/cases/completeness/single_app_tracing/datatype/primitives/primitives_float_001_T/primitives_float_001_T.go\n AffectedNodeName: __taint_src\n 12: ARG PASS: func primitives_float_001_T(__taint_src float64) {\n /sast-go/cases/completeness/single_app_tracing/datatype/primitives/primitives_float_001_T/primitives_float_001_T.go\n AffectedNodeName: __taint_sink\n 13: SINK: \t__taint_sink(__taint_src)\n==========================================================\n #Total-findings:1\n==========================================================","/benchmarks/sast-go/cases/completeness/single_app_tracing/datatype/primitives/primitives_float_002_F/primitives_float_002_F":"======================== Findings ========================\nNo findings!\n==========================================================","/benchmarks/sast-go/cases/completeness/single_app_tracing/datatype/primitives/primitives_int_001_T/primitives_int_001_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/sast-go/cases/completeness/single_app_tracing/datatype/primitives/primitives_int_001_T/primitives_int_001_T.go\nLine 13: __taint_sink(__taint_src)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/sast-go/cases/completeness/single_app_tracing/datatype/primitives/primitives_int_001_T/primitives_int_001_T.go\",\"functionName\":\"main\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /sast-go/cases/completeness/single_app_tracing/datatype/primitives/primitives_int_001_T/primitives_int_001_T.go\n AffectedNodeName: __taint_src\n 20: SOURCE: primitives_int_001_T(__taint_src)\n /sast-go/cases/completeness/single_app_tracing/datatype/primitives/primitives_int_001_T/primitives_int_001_T.go\n AffectedNodeName: primitives_int_001_T\n 20: CALL: primitives_int_001_T(__taint_src)\n /sast-go/cases/completeness/single_app_tracing/datatype/primitives/primitives_int_001_T/primitives_int_001_T.go\n AffectedNodeName: __taint_src\n 12: ARG PASS: func primitives_int_001_T(__taint_src int) {\n /sast-go/cases/completeness/single_app_tracing/datatype/primitives/primitives_int_001_T/primitives_int_001_T.go\n AffectedNodeName: __taint_sink\n 13: SINK: \t__taint_sink(__taint_src)\n==========================================================\n #Total-findings:1\n==========================================================","/benchmarks/sast-go/cases/completeness/single_app_tracing/datatype/primitives/primitives_int_002_F/primitives_int_002_F":"======================== Findings ========================\nNo findings!\n==========================================================","/benchmarks/sast-go/cases/completeness/single_app_tracing/datatype/slice/slice_001_T/slice_001_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/sast-go/cases/completeness/single_app_tracing/datatype/slice/slice_001_T/slice_001_T.go\nLine 14: __taint_sink(s)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/sast-go/cases/completeness/single_app_tracing/datatype/slice/slice_001_T/slice_001_T.go\",\"functionName\":\"main\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /sast-go/cases/completeness/single_app_tracing/datatype/slice/slice_001_T/slice_001_T.go\n AffectedNodeName: __taint_src\n 20: SOURCE: slice_001_T(__taint_src)\n /sast-go/cases/completeness/single_app_tracing/datatype/slice/slice_001_T/slice_001_T.go\n AffectedNodeName: slice_001_T\n 20: CALL: slice_001_T(__taint_src)\n /sast-go/cases/completeness/single_app_tracing/datatype/slice/slice_001_T/slice_001_T.go\n AffectedNodeName: __taint_src\n 12: ARG PASS: func slice_001_T(__taint_src string) {\n /sast-go/cases/completeness/single_app_tracing/datatype/slice/slice_001_T/slice_001_T.go\n AffectedNodeName: s\n 13: Var Pass: \tvar s []string = []string{__taint_src, \"b\", \"c\"}\n /sast-go/cases/completeness/single_app_tracing/datatype/slice/slice_001_T/slice_001_T.go\n AffectedNodeName: __taint_sink\n 14: SINK: \t__taint_sink(s)\n==========================================================\n #Total-findings:1\n==========================================================","/benchmarks/sast-go/cases/completeness/single_app_tracing/datatype/slice/slice_002_F/slice_002_F":"======================== Findings ========================\nNo findings!\n==========================================================","/benchmarks/sast-go/cases/completeness/single_app_tracing/datatype/slice/slice_003_T/slice_003_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/sast-go/cases/completeness/single_app_tracing/datatype/slice/slice_003_T/slice_003_T.go\nLine 15: __taint_sink(s)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/sast-go/cases/completeness/single_app_tracing/datatype/slice/slice_003_T/slice_003_T.go\",\"functionName\":\"main\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /sast-go/cases/completeness/single_app_tracing/datatype/slice/slice_003_T/slice_003_T.go\n AffectedNodeName: __taint_src\n 22: SOURCE: slice_003_T(__taint_src)\n /sast-go/cases/completeness/single_app_tracing/datatype/slice/slice_003_T/slice_003_T.go\n AffectedNodeName: slice_003_T\n 22: CALL: slice_003_T(__taint_src)\n /sast-go/cases/completeness/single_app_tracing/datatype/slice/slice_003_T/slice_003_T.go\n AffectedNodeName: __taint_src\n 12: ARG PASS: func slice_003_T(__taint_src string) {\n /sast-go/cases/completeness/single_app_tracing/datatype/slice/slice_003_T/slice_003_T.go\n AffectedNodeName: s\n 14: Var Pass: \ts = append(s, __taint_src)\n /sast-go/cases/completeness/single_app_tracing/datatype/slice/slice_003_T/slice_003_T.go\n AffectedNodeName: __taint_sink\n 15: SINK: \t__taint_sink(s)\n==========================================================\n #Total-findings:1\n==========================================================","/benchmarks/sast-go/cases/completeness/single_app_tracing/datatype/slice/slice_004_F/slice_004_F":"======================== Findings ========================\nNo findings!\n==========================================================","/benchmarks/sast-go/cases/completeness/single_app_tracing/datatype/slice/slice_005_T/slice_005_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/sast-go/cases/completeness/single_app_tracing/datatype/slice/slice_005_T/slice_005_T.go\nLine 18: __taint_sink(s)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/sast-go/cases/completeness/single_app_tracing/datatype/slice/slice_005_T/slice_005_T.go\",\"functionName\":\"main\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /sast-go/cases/completeness/single_app_tracing/datatype/slice/slice_005_T/slice_005_T.go\n AffectedNodeName: __taint_src\n 25: SOURCE: slice_005_T(__taint_src)\n /sast-go/cases/completeness/single_app_tracing/datatype/slice/slice_005_T/slice_005_T.go\n AffectedNodeName: slice_005_T\n 25: CALL: slice_005_T(__taint_src)\n /sast-go/cases/completeness/single_app_tracing/datatype/slice/slice_005_T/slice_005_T.go\n AffectedNodeName: __taint_src\n 12: ARG PASS: func slice_005_T(__taint_src string) {\n /sast-go/cases/completeness/single_app_tracing/datatype/slice/slice_005_T/slice_005_T.go\n AffectedNodeName: s\n 13: Var Pass: \ts := [][]string{\n 14: Var Pass: \t\t[]string{\"a\"},\n 15: Var Pass: \t\t[]string{\"b\", \"c\"},\n 16: Var Pass: \t\t[]string{\"d\", \"e\", __taint_src},\n 17: Var Pass: \t}\n /sast-go/cases/completeness/single_app_tracing/datatype/slice/slice_005_T/slice_005_T.go\n AffectedNodeName: __taint_sink\n 18: SINK: \t__taint_sink(s)\n==========================================================\n #Total-findings:1\n==========================================================","/benchmarks/sast-go/cases/completeness/single_app_tracing/datatype/slice/slice_006_F/slice_006_F":"======================== Findings ========================\nNo findings!\n==========================================================","/benchmarks/sast-go/cases/completeness/single_app_tracing/datatype/slice/slice_007_T/slice_007_T":"======================== Findings ========================\nNo findings!\n==========================================================","/benchmarks/sast-go/cases/completeness/single_app_tracing/datatype/slice/slice_008_F/slice_008_F":"======================== Findings ========================\nNo findings!\n==========================================================","/benchmarks/sast-go/cases/completeness/single_app_tracing/datatype/specialtype/channel_001_T/channel_001_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/sast-go/cases/completeness/single_app_tracing/datatype/specialtype/channel_001_T/channel_001_T.go\nLine 17: __taint_sink(c)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/sast-go/cases/completeness/single_app_tracing/datatype/specialtype/channel_001_T/channel_001_T.go\",\"functionName\":\"main\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /sast-go/cases/completeness/single_app_tracing/datatype/specialtype/channel_001_T/channel_001_T.go\n AffectedNodeName: __taint_src\n 23: SOURCE: channel_001_T(__taint_src)\n /sast-go/cases/completeness/single_app_tracing/datatype/specialtype/channel_001_T/channel_001_T.go\n AffectedNodeName: channel_001_T\n 23: CALL: channel_001_T(__taint_src)\n /sast-go/cases/completeness/single_app_tracing/datatype/specialtype/channel_001_T/channel_001_T.go\n AffectedNodeName: __taint_src\n 12: ARG PASS: func channel_001_T(__taint_src string) {\n /sast-go/cases/completeness/single_app_tracing/datatype/specialtype/channel_001_T/channel_001_T.go\n AffectedNodeName: __taint_sink\n 17: SINK: \t__taint_sink(c)\n==========================================================\n #Total-findings:1\n==========================================================","/benchmarks/sast-go/cases/completeness/single_app_tracing/datatype/specialtype/channel_002_F/channel_002_F":"======================== Findings ========================\nNo findings!\n==========================================================","/benchmarks/sast-go/cases/completeness/single_app_tracing/datatype/string/string_001_T/string_001_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/sast-go/cases/completeness/single_app_tracing/datatype/string/string_001_T/string_001_T.go\nLine 13: __taint_sink(__taint_src)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/sast-go/cases/completeness/single_app_tracing/datatype/string/string_001_T/string_001_T.go\",\"functionName\":\"main\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /sast-go/cases/completeness/single_app_tracing/datatype/string/string_001_T/string_001_T.go\n AffectedNodeName: __taint_src\n 20: SOURCE: string_001_T(__taint_src)\n /sast-go/cases/completeness/single_app_tracing/datatype/string/string_001_T/string_001_T.go\n AffectedNodeName: string_001_T\n 20: CALL: string_001_T(__taint_src)\n /sast-go/cases/completeness/single_app_tracing/datatype/string/string_001_T/string_001_T.go\n AffectedNodeName: __taint_src\n 12: ARG PASS: func string_001_T(__taint_src string) {\n /sast-go/cases/completeness/single_app_tracing/datatype/string/string_001_T/string_001_T.go\n AffectedNodeName: __taint_sink\n 13: SINK: \t__taint_sink(__taint_src)\n==========================================================\n #Total-findings:1\n==========================================================","/benchmarks/sast-go/cases/completeness/single_app_tracing/datatype/string/string_002_F/string_002_F":"======================== Findings ========================\nNo findings!\n==========================================================","/benchmarks/sast-go/cases/completeness/single_app_tracing/datatype/struct/complex_struct_001_T/complex_struct_001_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/sast-go/cases/completeness/single_app_tracing/datatype/struct/complex_struct_001_T/complex_struct_001_T.go\nLine 30: __taint_sink(c)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/sast-go/cases/completeness/single_app_tracing/datatype/struct/complex_struct_001_T/complex_struct_001_T.go\",\"functionName\":\"main\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /sast-go/cases/completeness/single_app_tracing/datatype/struct/complex_struct_001_T/complex_struct_001_T.go\n AffectedNodeName: __taint_src\n 37: SOURCE: complex_struct_001_T(__taint_src)\n /sast-go/cases/completeness/single_app_tracing/datatype/struct/complex_struct_001_T/complex_struct_001_T.go\n AffectedNodeName: complex_struct_001_T\n 37: CALL: complex_struct_001_T(__taint_src)\n /sast-go/cases/completeness/single_app_tracing/datatype/struct/complex_struct_001_T/complex_struct_001_T.go\n AffectedNodeName: __taint_src\n 13: ARG PASS: func complex_struct_001_T(__taint_src interface{}) {\n /sast-go/cases/completeness/single_app_tracing/datatype/struct/complex_struct_001_T/complex_struct_001_T.go\n AffectedNodeName: Say\n 16: CALL: \ta.b.Say(__taint_src)\n /sast-go/cases/completeness/single_app_tracing/datatype/struct/complex_struct_001_T/complex_struct_001_T.go\n AffectedNodeName: c\n 29: ARG PASS: func (b B) Say(c interface{}) {\n /sast-go/cases/completeness/single_app_tracing/datatype/struct/complex_struct_001_T/complex_struct_001_T.go\n AffectedNodeName: __taint_sink\n 30: SINK: \t__taint_sink(c)\n==========================================================\n #Total-findings:1\n==========================================================","/benchmarks/sast-go/cases/completeness/single_app_tracing/datatype/struct/complex_struct_002_F/complex_struct_002_F":"======================== Findings ========================\nNo findings!\n==========================================================","/benchmarks/sast-go/cases/completeness/single_app_tracing/datatype/struct/struct_001_T/struct_001_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/sast-go/cases/completeness/single_app_tracing/datatype/struct/struct_001_T/struct_001_T.go\nLine 20: __taint_sink(p)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/sast-go/cases/completeness/single_app_tracing/datatype/struct/struct_001_T/struct_001_T.go\",\"functionName\":\"main\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /sast-go/cases/completeness/single_app_tracing/datatype/struct/struct_001_T/struct_001_T.go\n AffectedNodeName: __taint_src\n 27: SOURCE: struct_001_T(__taint_src)\n /sast-go/cases/completeness/single_app_tracing/datatype/struct/struct_001_T/struct_001_T.go\n AffectedNodeName: struct_001_T\n 27: CALL: struct_001_T(__taint_src)\n /sast-go/cases/completeness/single_app_tracing/datatype/struct/struct_001_T/struct_001_T.go\n AffectedNodeName: __taint_src\n 16: ARG PASS: func struct_001_T(__taint_src string) {\n /sast-go/cases/completeness/single_app_tracing/datatype/struct/struct_001_T/struct_001_T.go\n AffectedNodeName: p\n 17: Var Pass: \tp := A{\n 18: Var Pass: \t\tdata: __taint_src,\n 19: Var Pass: \t}\n /sast-go/cases/completeness/single_app_tracing/datatype/struct/struct_001_T/struct_001_T.go\n AffectedNodeName: __taint_sink\n 20: SINK: \t__taint_sink(p)\n==========================================================\n #Total-findings:1\n==========================================================","/benchmarks/sast-go/cases/completeness/single_app_tracing/datatype/struct/struct_002_F/struct_002_F":"======================== Findings ========================\nNo findings!\n==========================================================","/benchmarks/sast-go/cases/completeness/single_app_tracing/datatype/struct/struct_003_T/struct_003_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/sast-go/cases/completeness/single_app_tracing/datatype/struct/struct_003_T/struct_003_T.go\nLine 19: __taint_sink(p)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/sast-go/cases/completeness/single_app_tracing/datatype/struct/struct_003_T/struct_003_T.go\",\"functionName\":\"main\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /sast-go/cases/completeness/single_app_tracing/datatype/struct/struct_003_T/struct_003_T.go\n AffectedNodeName: __taint_src\n 26: SOURCE: struct_003_T(__taint_src)\n /sast-go/cases/completeness/single_app_tracing/datatype/struct/struct_003_T/struct_003_T.go\n AffectedNodeName: struct_003_T\n 26: CALL: struct_003_T(__taint_src)\n /sast-go/cases/completeness/single_app_tracing/datatype/struct/struct_003_T/struct_003_T.go\n AffectedNodeName: __taint_src\n 16: ARG PASS: func struct_003_T(__taint_src string) {\n /sast-go/cases/completeness/single_app_tracing/datatype/struct/struct_003_T/struct_003_T.go\n AffectedNodeName: p.data\n 18: Var Pass: \tp.data = __taint_src\n /sast-go/cases/completeness/single_app_tracing/datatype/struct/struct_003_T/struct_003_T.go\n AffectedNodeName: __taint_sink\n 19: SINK: \t__taint_sink(p)\n==========================================================\n #Total-findings:1\n==========================================================","/benchmarks/sast-go/cases/completeness/single_app_tracing/datatype/struct/struct_004_F/struct_004_F":"======================== Findings ========================\nNo findings!\n==========================================================","/benchmarks/sast-go/cases/completeness/single_app_tracing/datatype/struct/struct_005_T/struct_005_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/sast-go/cases/completeness/single_app_tracing/datatype/struct/struct_005_T/struct_005_T.go\nLine 18: __taint_sink(p.data)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/sast-go/cases/completeness/single_app_tracing/datatype/struct/struct_005_T/struct_005_T.go\",\"functionName\":\"main\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /sast-go/cases/completeness/single_app_tracing/datatype/struct/struct_005_T/struct_005_T.go\n AffectedNodeName: __taint_src\n 24: SOURCE: struct_005_T(__taint_src)\n /sast-go/cases/completeness/single_app_tracing/datatype/struct/struct_005_T/struct_005_T.go\n AffectedNodeName: struct_005_T\n 24: CALL: struct_005_T(__taint_src)\n /sast-go/cases/completeness/single_app_tracing/datatype/struct/struct_005_T/struct_005_T.go\n AffectedNodeName: __taint_src\n 16: ARG PASS: func struct_005_T(__taint_src string) {\n /sast-go/cases/completeness/single_app_tracing/datatype/struct/struct_005_T/struct_005_T.go\n AffectedNodeName: p\n 17: Var Pass: \tp := A{__taint_src}\n /sast-go/cases/completeness/single_app_tracing/datatype/struct/struct_005_T/struct_005_T.go\n AffectedNodeName: __taint_sink\n 18: SINK: \t__taint_sink(p.data)\n==========================================================\n #Total-findings:1\n==========================================================","/benchmarks/sast-go/cases/completeness/single_app_tracing/datatype/struct/struct_006_F/struct_006_F":"======================== Findings ========================\nNo findings!\n==========================================================","/benchmarks/sast-go/cases/completeness/single_app_tracing/datatype/struct/struct_cross_001_T/struct_cross_001_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/sast-go/cases/completeness/single_app_tracing/datatype/struct/struct_cross_001_T/struct_cross_001_T.go\nLine 25: __taint_sink(pb)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/sast-go/cases/completeness/single_app_tracing/datatype/struct/struct_cross_001_T/struct_cross_001_T.go\",\"functionName\":\"main\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /sast-go/cases/completeness/single_app_tracing/datatype/struct/struct_cross_001_T/struct_cross_001_T.go\n AffectedNodeName: __taint_src\n 32: SOURCE: struct_cross_001_T(__taint_src)\n /sast-go/cases/completeness/single_app_tracing/datatype/struct/struct_cross_001_T/struct_cross_001_T.go\n AffectedNodeName: struct_cross_001_T\n 32: CALL: struct_cross_001_T(__taint_src)\n /sast-go/cases/completeness/single_app_tracing/datatype/struct/struct_cross_001_T/struct_cross_001_T.go\n AffectedNodeName: __taint_src\n 19: ARG PASS: func struct_cross_001_T(__taint_src string) {\n /sast-go/cases/completeness/single_app_tracing/datatype/struct/struct_cross_001_T/struct_cross_001_T.go\n AffectedNodeName: pa\n 20: Var Pass: \tpa := A{\n 21: Var Pass: \t\tdata: __taint_src,\n 22: Var Pass: \t}\n /sast-go/cases/completeness/single_app_tracing/datatype/struct/struct_cross_001_T/struct_cross_001_T.go\n AffectedNodeName: pb.data\n 24: Var Pass: \tpb.data = pa.data\n /sast-go/cases/completeness/single_app_tracing/datatype/struct/struct_cross_001_T/struct_cross_001_T.go\n AffectedNodeName: __taint_sink\n 25: SINK: \t__taint_sink(pb)\n==========================================================\n #Total-findings:1\n==========================================================","/benchmarks/sast-go/cases/completeness/single_app_tracing/datatype/struct/struct_cross_002_F/struct_cross_002_F":"======================== Findings ========================\nNo findings!\n==========================================================","/benchmarks/sast-go/cases/completeness/single_app_tracing/datatype/struct/struct_cross_003_T/struct_cross_003_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/sast-go/cases/completeness/single_app_tracing/datatype/struct/struct_cross_003_T/struct_cross_003_T.go\nLine 24: __taint_sink(p)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/sast-go/cases/completeness/single_app_tracing/datatype/struct/struct_cross_003_T/struct_cross_003_T.go\",\"functionName\":\"main\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /sast-go/cases/completeness/single_app_tracing/datatype/struct/struct_cross_003_T/struct_cross_003_T.go\n AffectedNodeName: __taint_src\n 30: SOURCE: struct_cross_003_T(__taint_src)\n /sast-go/cases/completeness/single_app_tracing/datatype/struct/struct_cross_003_T/struct_cross_003_T.go\n AffectedNodeName: struct_cross_003_T\n 30: CALL: struct_cross_003_T(__taint_src)\n /sast-go/cases/completeness/single_app_tracing/datatype/struct/struct_cross_003_T/struct_cross_003_T.go\n AffectedNodeName: __taint_src\n 20: ARG PASS: func struct_cross_003_T(__taint_src string) {\n /sast-go/cases/completeness/single_app_tracing/datatype/struct/struct_cross_003_T/struct_cross_003_T.go\n AffectedNodeName: p\n 21: Var Pass: \tp := B{A{\n 22: Var Pass: \t\tdata: __taint_src,\n 23: Var Pass: \t}, \"_\"}\n /sast-go/cases/completeness/single_app_tracing/datatype/struct/struct_cross_003_T/struct_cross_003_T.go\n AffectedNodeName: __taint_sink\n 24: SINK: \t__taint_sink(p)\n==========================================================\n #Total-findings:1\n==========================================================","/benchmarks/sast-go/cases/completeness/single_app_tracing/datatype/struct/struct_cross_004_F/struct_cross_004_F":"======================== Findings ========================\nNo findings!\n==========================================================","/benchmarks/sast-go/cases/completeness/single_app_tracing/exception_error/exception_throw/exception_throw_001_T/exception_throw_001_T":"======================== Findings ========================\nNo findings!\n==========================================================","/benchmarks/sast-go/cases/completeness/single_app_tracing/exception_error/exception_throw/exception_throw_002_F/exception_throw_002_F":"======================== Findings ========================\nNo findings!\n==========================================================","/benchmarks/sast-go/cases/completeness/single_app_tracing/expression/basic_expression_operation/assign_expression_001_T/assign_expression_001_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/sast-go/cases/completeness/single_app_tracing/expression/basic_expression_operation/assign_expression_001_T/assign_expression_001_T.go\nLine 14: __taint_sink(result)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/sast-go/cases/completeness/single_app_tracing/expression/basic_expression_operation/assign_expression_001_T/assign_expression_001_T.go\",\"functionName\":\"main\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /sast-go/cases/completeness/single_app_tracing/expression/basic_expression_operation/assign_expression_001_T/assign_expression_001_T.go\n AffectedNodeName: __taint_src\n 20: SOURCE: assign_expression_001_T(__taint_src)\n /sast-go/cases/completeness/single_app_tracing/expression/basic_expression_operation/assign_expression_001_T/assign_expression_001_T.go\n AffectedNodeName: assign_expression_001_T\n 20: CALL: assign_expression_001_T(__taint_src)\n /sast-go/cases/completeness/single_app_tracing/expression/basic_expression_operation/assign_expression_001_T/assign_expression_001_T.go\n AffectedNodeName: __taint_src\n 12: ARG PASS: func assign_expression_001_T(__taint_src string) {\n /sast-go/cases/completeness/single_app_tracing/expression/basic_expression_operation/assign_expression_001_T/assign_expression_001_T.go\n AffectedNodeName: result\n 13: Var Pass: \tresult := __taint_src\n /sast-go/cases/completeness/single_app_tracing/expression/basic_expression_operation/assign_expression_001_T/assign_expression_001_T.go\n AffectedNodeName: __taint_sink\n 14: SINK: \t__taint_sink(result)\n==========================================================\n #Total-findings:1\n==========================================================","/benchmarks/sast-go/cases/completeness/single_app_tracing/expression/basic_expression_operation/assign_expression_002_F/assign_expression_002_F":"======================== Findings ========================\nNo findings!\n==========================================================","/benchmarks/sast-go/cases/completeness/single_app_tracing/expression/basic_expression_operation/binary_expression_add_001_T/binary_expression_add_001_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/sast-go/cases/completeness/single_app_tracing/expression/basic_expression_operation/binary_expression_add_001_T/binary_expression_add_001_T.go\nLine 14: __taint_sink(result)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/sast-go/cases/completeness/single_app_tracing/expression/basic_expression_operation/binary_expression_add_001_T/binary_expression_add_001_T.go\",\"functionName\":\"main\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /sast-go/cases/completeness/single_app_tracing/expression/basic_expression_operation/binary_expression_add_001_T/binary_expression_add_001_T.go\n AffectedNodeName: __taint_src\n 20: SOURCE: binary_expression_add_001_T(__taint_src)\n /sast-go/cases/completeness/single_app_tracing/expression/basic_expression_operation/binary_expression_add_001_T/binary_expression_add_001_T.go\n AffectedNodeName: binary_expression_add_001_T\n 20: CALL: binary_expression_add_001_T(__taint_src)\n /sast-go/cases/completeness/single_app_tracing/expression/basic_expression_operation/binary_expression_add_001_T/binary_expression_add_001_T.go\n AffectedNodeName: __taint_src\n 12: ARG PASS: func binary_expression_add_001_T(__taint_src string) {\n /sast-go/cases/completeness/single_app_tracing/expression/basic_expression_operation/binary_expression_add_001_T/binary_expression_add_001_T.go\n AffectedNodeName: result\n 13: Var Pass: \tresult := __taint_src + \"_\"\n /sast-go/cases/completeness/single_app_tracing/expression/basic_expression_operation/binary_expression_add_001_T/binary_expression_add_001_T.go\n AffectedNodeName: __taint_sink\n 14: SINK: \t__taint_sink(result)\n==========================================================\n #Total-findings:1\n==========================================================","/benchmarks/sast-go/cases/completeness/single_app_tracing/expression/basic_expression_operation/binary_expression_add_002_F/binary_expression_add_002_F":"======================== Findings ========================\nNo findings!\n==========================================================","/benchmarks/sast-go/cases/completeness/single_app_tracing/expression/basic_expression_operation/binary_expression_add_assignment_001_T/binary_expression_add_assignment_001_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/sast-go/cases/completeness/single_app_tracing/expression/basic_expression_operation/binary_expression_add_assignment_001_T/binary_expression_add_assignment_001_T.go\nLine 15: __taint_sink(result)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/sast-go/cases/completeness/single_app_tracing/expression/basic_expression_operation/binary_expression_add_assignment_001_T/binary_expression_add_assignment_001_T.go\",\"functionName\":\"main\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /sast-go/cases/completeness/single_app_tracing/expression/basic_expression_operation/binary_expression_add_assignment_001_T/binary_expression_add_assignment_001_T.go\n AffectedNodeName: __taint_src\n 21: SOURCE: binary_expression_add_assignment_001_T(__taint_src)\n /sast-go/cases/completeness/single_app_tracing/expression/basic_expression_operation/binary_expression_add_assignment_001_T/binary_expression_add_assignment_001_T.go\n AffectedNodeName: binary_expression_add_assignment_001_T\n 21: CALL: binary_expression_add_assignment_001_T(__taint_src)\n /sast-go/cases/completeness/single_app_tracing/expression/basic_expression_operation/binary_expression_add_assignment_001_T/binary_expression_add_assignment_001_T.go\n AffectedNodeName: __taint_src\n 12: ARG PASS: func binary_expression_add_assignment_001_T(__taint_src string) {\n /sast-go/cases/completeness/single_app_tracing/expression/basic_expression_operation/binary_expression_add_assignment_001_T/binary_expression_add_assignment_001_T.go\n AffectedNodeName: __taint_sink\n 15: SINK: \t__taint_sink(result)\n==========================================================\n #Total-findings:1\n==========================================================","/benchmarks/sast-go/cases/completeness/single_app_tracing/expression/basic_expression_operation/binary_expression_add_assignment_002_F/binary_expression_add_assignment_002_F":"======================== Findings ========================\nNo findings!\n==========================================================","/benchmarks/sast-go/cases/completeness/single_app_tracing/expression/basic_expression_operation/bitwise_expression_and_001_T/bitwise_expression_and_001_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/sast-go/cases/completeness/single_app_tracing/expression/basic_expression_operation/bitwise_expression_and_001_T/bitwise_expression_and_001_T.go\nLine 14: __taint_sink(result)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/sast-go/cases/completeness/single_app_tracing/expression/basic_expression_operation/bitwise_expression_and_001_T/bitwise_expression_and_001_T.go\",\"functionName\":\"main\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /sast-go/cases/completeness/single_app_tracing/expression/basic_expression_operation/bitwise_expression_and_001_T/bitwise_expression_and_001_T.go\n AffectedNodeName: __taint_src\n 20: SOURCE: bitwise_expression_and_001_T(__taint_src)\n /sast-go/cases/completeness/single_app_tracing/expression/basic_expression_operation/bitwise_expression_and_001_T/bitwise_expression_and_001_T.go\n AffectedNodeName: bitwise_expression_and_001_T\n 20: CALL: bitwise_expression_and_001_T(__taint_src)\n /sast-go/cases/completeness/single_app_tracing/expression/basic_expression_operation/bitwise_expression_and_001_T/bitwise_expression_and_001_T.go\n AffectedNodeName: __taint_src\n 12: ARG PASS: func bitwise_expression_and_001_T(__taint_src int) {\n /sast-go/cases/completeness/single_app_tracing/expression/basic_expression_operation/bitwise_expression_and_001_T/bitwise_expression_and_001_T.go\n AffectedNodeName: result\n 13: Var Pass: \tresult := __taint_src & 1\n /sast-go/cases/completeness/single_app_tracing/expression/basic_expression_operation/bitwise_expression_and_001_T/bitwise_expression_and_001_T.go\n AffectedNodeName: __taint_sink\n 14: SINK: \t__taint_sink(result)\n==========================================================\n #Total-findings:1\n==========================================================","/benchmarks/sast-go/cases/completeness/single_app_tracing/expression/basic_expression_operation/bitwise_expression_and_002_F/bitwise_expression_and_002_F":"======================== Findings ========================\nNo findings!\n==========================================================","/benchmarks/sast-go/cases/completeness/single_app_tracing/expression/basic_expression_operation/bitwise_expression_lsh_001_T/bitwise_expression_lsh_001_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/sast-go/cases/completeness/single_app_tracing/expression/basic_expression_operation/bitwise_expression_lsh_001_T/bitwise_expression_lsh_001_T.go\nLine 14: __taint_sink(result)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/sast-go/cases/completeness/single_app_tracing/expression/basic_expression_operation/bitwise_expression_lsh_001_T/bitwise_expression_lsh_001_T.go\",\"functionName\":\"main\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /sast-go/cases/completeness/single_app_tracing/expression/basic_expression_operation/bitwise_expression_lsh_001_T/bitwise_expression_lsh_001_T.go\n AffectedNodeName: __taint_src\n 20: SOURCE: bitwise_expression_lsh_001_T(__taint_src)\n /sast-go/cases/completeness/single_app_tracing/expression/basic_expression_operation/bitwise_expression_lsh_001_T/bitwise_expression_lsh_001_T.go\n AffectedNodeName: bitwise_expression_lsh_001_T\n 20: CALL: bitwise_expression_lsh_001_T(__taint_src)\n /sast-go/cases/completeness/single_app_tracing/expression/basic_expression_operation/bitwise_expression_lsh_001_T/bitwise_expression_lsh_001_T.go\n AffectedNodeName: __taint_src\n 12: ARG PASS: func bitwise_expression_lsh_001_T(__taint_src int) {\n /sast-go/cases/completeness/single_app_tracing/expression/basic_expression_operation/bitwise_expression_lsh_001_T/bitwise_expression_lsh_001_T.go\n AffectedNodeName: result\n 13: Var Pass: \tresult := __taint_src << 1\n /sast-go/cases/completeness/single_app_tracing/expression/basic_expression_operation/bitwise_expression_lsh_001_T/bitwise_expression_lsh_001_T.go\n AffectedNodeName: __taint_sink\n 14: SINK: \t__taint_sink(result)\n==========================================================\n #Total-findings:1\n==========================================================","/benchmarks/sast-go/cases/completeness/single_app_tracing/expression/basic_expression_operation/bitwise_expression_lsh_002_F/bitwise_expression_lsh_002_F":"======================== Findings ========================\nNo findings!\n==========================================================","/benchmarks/sast-go/cases/completeness/single_app_tracing/expression/basic_expression_operation/bitwise_expression_not_001_T/bitwise_expression_not_001_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/sast-go/cases/completeness/single_app_tracing/expression/basic_expression_operation/bitwise_expression_not_001_T/bitwise_expression_not_001_T.go\nLine 14: __taint_sink(result)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/sast-go/cases/completeness/single_app_tracing/expression/basic_expression_operation/bitwise_expression_not_001_T/bitwise_expression_not_001_T.go\",\"functionName\":\"main\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /sast-go/cases/completeness/single_app_tracing/expression/basic_expression_operation/bitwise_expression_not_001_T/bitwise_expression_not_001_T.go\n AffectedNodeName: __taint_src\n 20: SOURCE: bitwise_expression_not_001_T(__taint_src)\n /sast-go/cases/completeness/single_app_tracing/expression/basic_expression_operation/bitwise_expression_not_001_T/bitwise_expression_not_001_T.go\n AffectedNodeName: bitwise_expression_not_001_T\n 20: CALL: bitwise_expression_not_001_T(__taint_src)\n /sast-go/cases/completeness/single_app_tracing/expression/basic_expression_operation/bitwise_expression_not_001_T/bitwise_expression_not_001_T.go\n AffectedNodeName: __taint_src\n 12: ARG PASS: func bitwise_expression_not_001_T(__taint_src int) {\n /sast-go/cases/completeness/single_app_tracing/expression/basic_expression_operation/bitwise_expression_not_001_T/bitwise_expression_not_001_T.go\n AffectedNodeName: __taint_sink\n 14: SINK: \t__taint_sink(result)\n==========================================================\n #Total-findings:1\n==========================================================","/benchmarks/sast-go/cases/completeness/single_app_tracing/expression/basic_expression_operation/bitwise_expression_not_002_F/bitwise_expression_not_002_F":"======================== Findings ========================\nNo findings!\n==========================================================","/benchmarks/sast-go/cases/completeness/single_app_tracing/expression/basic_expression_operation/bitwise_expression_or_001_T/bitwise_expression_or_001_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/sast-go/cases/completeness/single_app_tracing/expression/basic_expression_operation/bitwise_expression_or_001_T/bitwise_expression_or_001_T.go\nLine 14: __taint_sink(result)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/sast-go/cases/completeness/single_app_tracing/expression/basic_expression_operation/bitwise_expression_or_001_T/bitwise_expression_or_001_T.go\",\"functionName\":\"main\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /sast-go/cases/completeness/single_app_tracing/expression/basic_expression_operation/bitwise_expression_or_001_T/bitwise_expression_or_001_T.go\n AffectedNodeName: __taint_src\n 20: SOURCE: bitwise_expression_or_001_T(__taint_src)\n /sast-go/cases/completeness/single_app_tracing/expression/basic_expression_operation/bitwise_expression_or_001_T/bitwise_expression_or_001_T.go\n AffectedNodeName: bitwise_expression_or_001_T\n 20: CALL: bitwise_expression_or_001_T(__taint_src)\n /sast-go/cases/completeness/single_app_tracing/expression/basic_expression_operation/bitwise_expression_or_001_T/bitwise_expression_or_001_T.go\n AffectedNodeName: __taint_src\n 12: ARG PASS: func bitwise_expression_or_001_T(__taint_src int) {\n /sast-go/cases/completeness/single_app_tracing/expression/basic_expression_operation/bitwise_expression_or_001_T/bitwise_expression_or_001_T.go\n AffectedNodeName: result\n 13: Var Pass: \tresult := __taint_src | 1\n /sast-go/cases/completeness/single_app_tracing/expression/basic_expression_operation/bitwise_expression_or_001_T/bitwise_expression_or_001_T.go\n AffectedNodeName: __taint_sink\n 14: SINK: \t__taint_sink(result)\n==========================================================\n #Total-findings:1\n==========================================================","/benchmarks/sast-go/cases/completeness/single_app_tracing/expression/basic_expression_operation/bitwise_expression_or_002_F/bitwise_expression_or_002_F":"======================== Findings ========================\nNo findings!\n==========================================================","/benchmarks/sast-go/cases/completeness/single_app_tracing/expression/basic_expression_operation/bitwise_expression_rsh_001_T/bitwise_expression_rsh_001_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/sast-go/cases/completeness/single_app_tracing/expression/basic_expression_operation/bitwise_expression_rsh_001_T/bitwise_expression_rsh_001_T.go\nLine 14: __taint_sink(result)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/sast-go/cases/completeness/single_app_tracing/expression/basic_expression_operation/bitwise_expression_rsh_001_T/bitwise_expression_rsh_001_T.go\",\"functionName\":\"main\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /sast-go/cases/completeness/single_app_tracing/expression/basic_expression_operation/bitwise_expression_rsh_001_T/bitwise_expression_rsh_001_T.go\n AffectedNodeName: __taint_src\n 20: SOURCE: bitwise_expression_rsh_001_T(__taint_src)\n /sast-go/cases/completeness/single_app_tracing/expression/basic_expression_operation/bitwise_expression_rsh_001_T/bitwise_expression_rsh_001_T.go\n AffectedNodeName: bitwise_expression_rsh_001_T\n 20: CALL: bitwise_expression_rsh_001_T(__taint_src)\n /sast-go/cases/completeness/single_app_tracing/expression/basic_expression_operation/bitwise_expression_rsh_001_T/bitwise_expression_rsh_001_T.go\n AffectedNodeName: __taint_src\n 12: ARG PASS: func bitwise_expression_rsh_001_T(__taint_src int) {\n /sast-go/cases/completeness/single_app_tracing/expression/basic_expression_operation/bitwise_expression_rsh_001_T/bitwise_expression_rsh_001_T.go\n AffectedNodeName: result\n 13: Var Pass: \tresult := __taint_src >> 1\n /sast-go/cases/completeness/single_app_tracing/expression/basic_expression_operation/bitwise_expression_rsh_001_T/bitwise_expression_rsh_001_T.go\n AffectedNodeName: __taint_sink\n 14: SINK: \t__taint_sink(result)\n==========================================================\n #Total-findings:1\n==========================================================","/benchmarks/sast-go/cases/completeness/single_app_tracing/expression/basic_expression_operation/bitwise_expression_rsh_002_F/bitwise_expression_rsh_002_F":"======================== Findings ========================\nNo findings!\n==========================================================","/benchmarks/sast-go/cases/completeness/single_app_tracing/expression/basic_expression_operation/bitwise_expression_xor_001_T/bitwise_expression_xor_001_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/sast-go/cases/completeness/single_app_tracing/expression/basic_expression_operation/bitwise_expression_xor_001_T/bitwise_expression_xor_001_T.go\nLine 14: __taint_sink(result)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/sast-go/cases/completeness/single_app_tracing/expression/basic_expression_operation/bitwise_expression_xor_001_T/bitwise_expression_xor_001_T.go\",\"functionName\":\"main\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /sast-go/cases/completeness/single_app_tracing/expression/basic_expression_operation/bitwise_expression_xor_001_T/bitwise_expression_xor_001_T.go\n AffectedNodeName: __taint_src\n 21: SOURCE: bitwise_expression_xor_001_T(__taint_src)\n /sast-go/cases/completeness/single_app_tracing/expression/basic_expression_operation/bitwise_expression_xor_001_T/bitwise_expression_xor_001_T.go\n AffectedNodeName: bitwise_expression_xor_001_T\n 21: CALL: bitwise_expression_xor_001_T(__taint_src)\n /sast-go/cases/completeness/single_app_tracing/expression/basic_expression_operation/bitwise_expression_xor_001_T/bitwise_expression_xor_001_T.go\n AffectedNodeName: __taint_src\n 12: ARG PASS: func bitwise_expression_xor_001_T(__taint_src int) {\n /sast-go/cases/completeness/single_app_tracing/expression/basic_expression_operation/bitwise_expression_xor_001_T/bitwise_expression_xor_001_T.go\n AffectedNodeName: result\n 13: Var Pass: \tresult := __taint_src ^ 1\n /sast-go/cases/completeness/single_app_tracing/expression/basic_expression_operation/bitwise_expression_xor_001_T/bitwise_expression_xor_001_T.go\n AffectedNodeName: __taint_sink\n 14: SINK: \t__taint_sink(result)\n==========================================================\n #Total-findings:1\n==========================================================","/benchmarks/sast-go/cases/completeness/single_app_tracing/expression/basic_expression_operation/bitwise_expression_xor_002_F/bitwise_expression_xor_002_F":"======================== Findings ========================\nNo findings!\n==========================================================","/benchmarks/sast-go/cases/completeness/single_app_tracing/expression/basic_expression_operation/logic_expression_and_001_T/logic_expression_and_001_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/sast-go/cases/completeness/single_app_tracing/expression/basic_expression_operation/logic_expression_and_001_T/logic_expression_and_001_T.go\nLine 14: __taint_sink(result)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/sast-go/cases/completeness/single_app_tracing/expression/basic_expression_operation/logic_expression_and_001_T/logic_expression_and_001_T.go\",\"functionName\":\"main\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /sast-go/cases/completeness/single_app_tracing/expression/basic_expression_operation/logic_expression_and_001_T/logic_expression_and_001_T.go\n AffectedNodeName: __taint_src\n 20: SOURCE: logic_expression_and_001_T(__taint_src)\n /sast-go/cases/completeness/single_app_tracing/expression/basic_expression_operation/logic_expression_and_001_T/logic_expression_and_001_T.go\n AffectedNodeName: logic_expression_and_001_T\n 20: CALL: logic_expression_and_001_T(__taint_src)\n /sast-go/cases/completeness/single_app_tracing/expression/basic_expression_operation/logic_expression_and_001_T/logic_expression_and_001_T.go\n AffectedNodeName: __taint_src\n 12: ARG PASS: func logic_expression_and_001_T(__taint_src bool) {\n /sast-go/cases/completeness/single_app_tracing/expression/basic_expression_operation/logic_expression_and_001_T/logic_expression_and_001_T.go\n AffectedNodeName: result\n 13: Var Pass: \tresult := __taint_src && true\n /sast-go/cases/completeness/single_app_tracing/expression/basic_expression_operation/logic_expression_and_001_T/logic_expression_and_001_T.go\n AffectedNodeName: __taint_sink\n 14: SINK: \t__taint_sink(result)\n==========================================================\n #Total-findings:1\n==========================================================","/benchmarks/sast-go/cases/completeness/single_app_tracing/expression/basic_expression_operation/logic_expression_and_002_F/logic_expression_and_002_F":"======================== Findings ========================\nNo findings!\n==========================================================","/benchmarks/sast-go/cases/completeness/single_app_tracing/expression/basic_expression_operation/logic_expression_or_001_T/logic_expression_or_001_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/sast-go/cases/completeness/single_app_tracing/expression/basic_expression_operation/logic_expression_or_001_T/logic_expression_or_001_T.go\nLine 14: __taint_sink(result)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/sast-go/cases/completeness/single_app_tracing/expression/basic_expression_operation/logic_expression_or_001_T/logic_expression_or_001_T.go\",\"functionName\":\"main\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /sast-go/cases/completeness/single_app_tracing/expression/basic_expression_operation/logic_expression_or_001_T/logic_expression_or_001_T.go\n AffectedNodeName: __taint_src\n 20: SOURCE: logic_expression_or_001_T(__taint_src)\n /sast-go/cases/completeness/single_app_tracing/expression/basic_expression_operation/logic_expression_or_001_T/logic_expression_or_001_T.go\n AffectedNodeName: logic_expression_or_001_T\n 20: CALL: logic_expression_or_001_T(__taint_src)\n /sast-go/cases/completeness/single_app_tracing/expression/basic_expression_operation/logic_expression_or_001_T/logic_expression_or_001_T.go\n AffectedNodeName: __taint_src\n 12: ARG PASS: func logic_expression_or_001_T(__taint_src bool) {\n /sast-go/cases/completeness/single_app_tracing/expression/basic_expression_operation/logic_expression_or_001_T/logic_expression_or_001_T.go\n AffectedNodeName: result\n 13: Var Pass: \tresult := false || __taint_src\n /sast-go/cases/completeness/single_app_tracing/expression/basic_expression_operation/logic_expression_or_001_T/logic_expression_or_001_T.go\n AffectedNodeName: __taint_sink\n 14: SINK: \t__taint_sink(result)\n==========================================================\n #Total-findings:1\n==========================================================","/benchmarks/sast-go/cases/completeness/single_app_tracing/expression/basic_expression_operation/logic_expression_or_002_F/logic_expression_or_002_F":"======================== Findings ========================\nNo findings!\n==========================================================","/benchmarks/sast-go/cases/completeness/single_app_tracing/expression/basic_expression_operation/relation_expression_equal_001_T/relation_expression_equal_001_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/sast-go/cases/completeness/single_app_tracing/expression/basic_expression_operation/relation_expression_equal_001_T/relation_expression_equal_001_T.go\nLine 14: __taint_sink(result)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/sast-go/cases/completeness/single_app_tracing/expression/basic_expression_operation/relation_expression_equal_001_T/relation_expression_equal_001_T.go\",\"functionName\":\"main\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /sast-go/cases/completeness/single_app_tracing/expression/basic_expression_operation/relation_expression_equal_001_T/relation_expression_equal_001_T.go\n AffectedNodeName: __taint_src\n 21: SOURCE: relation_expression_equal_001_T(__taint_src)\n /sast-go/cases/completeness/single_app_tracing/expression/basic_expression_operation/relation_expression_equal_001_T/relation_expression_equal_001_T.go\n AffectedNodeName: relation_expression_equal_001_T\n 21: CALL: relation_expression_equal_001_T(__taint_src)\n /sast-go/cases/completeness/single_app_tracing/expression/basic_expression_operation/relation_expression_equal_001_T/relation_expression_equal_001_T.go\n AffectedNodeName: __taint_src\n 12: ARG PASS: func relation_expression_equal_001_T(__taint_src string) {\n /sast-go/cases/completeness/single_app_tracing/expression/basic_expression_operation/relation_expression_equal_001_T/relation_expression_equal_001_T.go\n AffectedNodeName: result\n 13: Var Pass: \tresult := __taint_src == \"__taint_src\"\n /sast-go/cases/completeness/single_app_tracing/expression/basic_expression_operation/relation_expression_equal_001_T/relation_expression_equal_001_T.go\n AffectedNodeName: __taint_sink\n 14: SINK: \t__taint_sink(result)\n==========================================================\n #Total-findings:1\n==========================================================","/benchmarks/sast-go/cases/completeness/single_app_tracing/expression/basic_expression_operation/relation_expression_equal_002_F/relation_expression_equal_002_F":"======================== Findings ========================\nNo findings!\n==========================================================","/benchmarks/sast-go/cases/completeness/single_app_tracing/expression/special_expression/blank_identifier_001_T/blank_identifier_001_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/sast-go/cases/completeness/single_app_tracing/expression/special_expression/blank_identifier_001_T/blank_identifier_001_T.go\nLine 14: __taint_sink(a)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/sast-go/cases/completeness/single_app_tracing/expression/special_expression/blank_identifier_001_T/blank_identifier_001_T.go\",\"functionName\":\"main\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /sast-go/cases/completeness/single_app_tracing/expression/special_expression/blank_identifier_001_T/blank_identifier_001_T.go\n AffectedNodeName: __taint_src\n 25: SOURCE: blank_identifier_001_T(__taint_src)\n /sast-go/cases/completeness/single_app_tracing/expression/special_expression/blank_identifier_001_T/blank_identifier_001_T.go\n AffectedNodeName: blank_identifier_001_T\n 25: CALL: blank_identifier_001_T(__taint_src)\n /sast-go/cases/completeness/single_app_tracing/expression/special_expression/blank_identifier_001_T/blank_identifier_001_T.go\n AffectedNodeName: __taint_src\n 12: ARG PASS: func blank_identifier_001_T(__taint_src string) {\n /sast-go/cases/completeness/single_app_tracing/expression/special_expression/blank_identifier_001_T/blank_identifier_001_T.go\n AffectedNodeName: getData\n 13: CALL: \ta, _ := getData(__taint_src)\n /sast-go/cases/completeness/single_app_tracing/expression/special_expression/blank_identifier_001_T/blank_identifier_001_T.go\n AffectedNodeName: getData\n 13: CALL RETURN: \ta, _ := getData(__taint_src)\n /sast-go/cases/completeness/single_app_tracing/expression/special_expression/blank_identifier_001_T/blank_identifier_001_T.go\n 13: Var Pass: \ta, _ := getData(__taint_src)\n /sast-go/cases/completeness/single_app_tracing/expression/special_expression/blank_identifier_001_T/blank_identifier_001_T.go\n AffectedNodeName: __taint_sink\n 14: SINK: \t__taint_sink(a)\n==========================================================\n #Total-findings:1\n==========================================================","/benchmarks/sast-go/cases/completeness/single_app_tracing/expression/special_expression/blank_identifier_002_F/blank_identifier_002_F":"======================== Findings ========================\nNo findings!\n==========================================================","/benchmarks/sast-go/cases/completeness/single_app_tracing/expression/special_expression/multiple_assignment_001_T/multiple_assignment_001_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/sast-go/cases/completeness/single_app_tracing/expression/special_expression/multiple_assignment_001_T/multiple_assignment_001_T.go\nLine 14: __taint_sink(result)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/sast-go/cases/completeness/single_app_tracing/expression/special_expression/multiple_assignment_001_T/multiple_assignment_001_T.go\",\"functionName\":\"main\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /sast-go/cases/completeness/single_app_tracing/expression/special_expression/multiple_assignment_001_T/multiple_assignment_001_T.go\n AffectedNodeName: __taint_src\n 21: SOURCE: multiple_assignment_001_T(__taint_src)\n /sast-go/cases/completeness/single_app_tracing/expression/special_expression/multiple_assignment_001_T/multiple_assignment_001_T.go\n AffectedNodeName: multiple_assignment_001_T\n 21: CALL: multiple_assignment_001_T(__taint_src)\n /sast-go/cases/completeness/single_app_tracing/expression/special_expression/multiple_assignment_001_T/multiple_assignment_001_T.go\n AffectedNodeName: __taint_src\n 12: ARG PASS: func multiple_assignment_001_T(__taint_src string) {\n /sast-go/cases/completeness/single_app_tracing/expression/special_expression/multiple_assignment_001_T/multiple_assignment_001_T.go\n AffectedNodeName: __taint_sink\n 14: SINK: \t__taint_sink(result)\n==========================================================\n #Total-findings:1\n==========================================================","/benchmarks/sast-go/cases/completeness/single_app_tracing/expression/special_expression/multiple_assignment_002_F/multiple_assignment_002_F":"======================== Findings ========================\nNo findings!\n==========================================================","/benchmarks/sast-go/cases/completeness/single_app_tracing/expression/special_expression/rest_parameter_001_T/rest_parameter_001_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/sast-go/cases/completeness/single_app_tracing/expression/special_expression/rest_parameter_001_T/rest_parameter_001_T.go\nLine 17: __taint_sink(args)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/sast-go/cases/completeness/single_app_tracing/expression/special_expression/rest_parameter_001_T/rest_parameter_001_T.go\",\"functionName\":\"main\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /sast-go/cases/completeness/single_app_tracing/expression/special_expression/rest_parameter_001_T/rest_parameter_001_T.go\n AffectedNodeName: __taint_src\n 24: SOURCE: rest_parameter_001_T(__taint_src)\n /sast-go/cases/completeness/single_app_tracing/expression/special_expression/rest_parameter_001_T/rest_parameter_001_T.go\n AffectedNodeName: rest_parameter_001_T\n 24: CALL: rest_parameter_001_T(__taint_src)\n /sast-go/cases/completeness/single_app_tracing/expression/special_expression/rest_parameter_001_T/rest_parameter_001_T.go\n AffectedNodeName: __taint_src\n 12: ARG PASS: func rest_parameter_001_T(__taint_src string) {\n /sast-go/cases/completeness/single_app_tracing/expression/special_expression/rest_parameter_001_T/rest_parameter_001_T.go\n AffectedNodeName: collectArgs\n 13: CALL: \tcollectArgs(\"prefix\", __taint_src, \"suffix\")\n /sast-go/cases/completeness/single_app_tracing/expression/special_expression/rest_parameter_001_T/rest_parameter_001_T.go\n AffectedNodeName: args\n 16: ARG PASS: func collectArgs(args ...interface{}) {\n /sast-go/cases/completeness/single_app_tracing/expression/special_expression/rest_parameter_001_T/rest_parameter_001_T.go\n AffectedNodeName: __taint_sink\n 17: SINK: \t__taint_sink(args)\n==========================================================\n #Total-findings:1\n==========================================================","/benchmarks/sast-go/cases/completeness/single_app_tracing/expression/special_expression/rest_parameter_002_F/rest_parameter_002_F":"======================== Findings ========================\nNo findings!\n==========================================================","/benchmarks/sast-go/cases/completeness/single_app_tracing/expression/special_expression/spread_operator_001_T/spread_operator_001_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/sast-go/cases/completeness/single_app_tracing/expression/special_expression/spread_operator_001_T/spread_operator_001_T.go\nLine 15: __taint_sink(array)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/sast-go/cases/completeness/single_app_tracing/expression/special_expression/spread_operator_001_T/spread_operator_001_T.go\",\"functionName\":\"main\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /sast-go/cases/completeness/single_app_tracing/expression/special_expression/spread_operator_001_T/spread_operator_001_T.go\n AffectedNodeName: __taint_src\n 22: SOURCE: spread_operator_001_T(__taint_src)\n /sast-go/cases/completeness/single_app_tracing/expression/special_expression/spread_operator_001_T/spread_operator_001_T.go\n AffectedNodeName: spread_operator_001_T\n 22: CALL: spread_operator_001_T(__taint_src)\n /sast-go/cases/completeness/single_app_tracing/expression/special_expression/spread_operator_001_T/spread_operator_001_T.go\n AffectedNodeName: __taint_src\n 12: ARG PASS: func spread_operator_001_T(__taint_src string) {\n /sast-go/cases/completeness/single_app_tracing/expression/special_expression/spread_operator_001_T/spread_operator_001_T.go\n AffectedNodeName: array1\n 13: Var Pass: \tarray1 := []string{\"a\", \"b\", __taint_src}\n /sast-go/cases/completeness/single_app_tracing/expression/special_expression/spread_operator_001_T/spread_operator_001_T.go\n AffectedNodeName: array\n 14: Var Pass: \tarray := append([]string{\"c\"}, array1...)\n /sast-go/cases/completeness/single_app_tracing/expression/special_expression/spread_operator_001_T/spread_operator_001_T.go\n AffectedNodeName: __taint_sink\n 15: SINK: \t__taint_sink(array)\n==========================================================\n #Total-findings:1\n==========================================================","/benchmarks/sast-go/cases/completeness/single_app_tracing/expression/special_expression/spread_operator_002_F/spread_operator_002_F":"======================== Findings ========================\nNo findings!\n==========================================================","/benchmarks/sast-go/cases/completeness/single_app_tracing/expression/type_cast/type_cast_001_T/type_cast_001_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/sast-go/cases/completeness/single_app_tracing/expression/type_cast/type_cast_001_T/type_cast_001_T.go\nLine 14: __taint_sink(result)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/sast-go/cases/completeness/single_app_tracing/expression/type_cast/type_cast_001_T/type_cast_001_T.go\",\"functionName\":\"main\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /sast-go/cases/completeness/single_app_tracing/expression/type_cast/type_cast_001_T/type_cast_001_T.go\n AffectedNodeName: __taint_src\n 21: SOURCE: type_cast_001_T(__taint_src)\n /sast-go/cases/completeness/single_app_tracing/expression/type_cast/type_cast_001_T/type_cast_001_T.go\n AffectedNodeName: type_cast_001_T\n 21: CALL: type_cast_001_T(__taint_src)\n /sast-go/cases/completeness/single_app_tracing/expression/type_cast/type_cast_001_T/type_cast_001_T.go\n AffectedNodeName: __taint_src\n 12: ARG PASS: func type_cast_001_T(__taint_src int) {\n /sast-go/cases/completeness/single_app_tracing/expression/type_cast/type_cast_001_T/type_cast_001_T.go\n AffectedNodeName: result\n 13: Var Pass: \tresult := float64(__taint_src)\n /sast-go/cases/completeness/single_app_tracing/expression/type_cast/type_cast_001_T/type_cast_001_T.go\n AffectedNodeName: __taint_sink\n 14: SINK: \t__taint_sink(result)\n==========================================================\n #Total-findings:1\n==========================================================","/benchmarks/sast-go/cases/completeness/single_app_tracing/expression/type_cast/type_cast_002_F/type_cast_002_F":"======================== Findings ========================\nNo findings!\n==========================================================","/benchmarks/sast-go/cases/completeness/single_app_tracing/expression/type_cast/type_cast_003_T/type_cast_003_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/sast-go/cases/completeness/single_app_tracing/expression/type_cast/type_cast_003_T/type_cast_003_T.go\nLine 15: __taint_sink(result)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/sast-go/cases/completeness/single_app_tracing/expression/type_cast/type_cast_003_T/type_cast_003_T.go\",\"functionName\":\"main\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /sast-go/cases/completeness/single_app_tracing/expression/type_cast/type_cast_003_T/type_cast_003_T.go\n AffectedNodeName: __taint_src\n 22: SOURCE: type_cast_003_T(__taint_src)\n /sast-go/cases/completeness/single_app_tracing/expression/type_cast/type_cast_003_T/type_cast_003_T.go\n AffectedNodeName: type_cast_003_T\n 22: CALL: type_cast_003_T(__taint_src)\n /sast-go/cases/completeness/single_app_tracing/expression/type_cast/type_cast_003_T/type_cast_003_T.go\n AffectedNodeName: __taint_src\n 12: ARG PASS: func type_cast_003_T(__taint_src interface{}) {\n /sast-go/cases/completeness/single_app_tracing/expression/type_cast/type_cast_003_T/type_cast_003_T.go\n 13: Var Pass: \tresult, ok := __taint_src.(string)\n /sast-go/cases/completeness/single_app_tracing/expression/type_cast/type_cast_003_T/type_cast_003_T.go\n AffectedNodeName: __taint_sink\n 15: SINK: \t__taint_sink(result)\n==========================================================\n #Total-findings:1\n==========================================================","/benchmarks/sast-go/cases/completeness/single_app_tracing/expression/type_cast/type_cast_004_F/type_cast_004_F":"======================== Findings ========================\nNo findings!\n==========================================================","/benchmarks/sast-go/cases/completeness/single_app_tracing/function_call/anonymous_function_closure/anonymous_function_001_F/anonymous_function_001_F":"======================== Findings ========================\nNo findings!\n==========================================================","/benchmarks/sast-go/cases/completeness/single_app_tracing/function_call/anonymous_function_closure/anonymous_function_002_T/anonymous_function_002_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/sast-go/cases/completeness/single_app_tracing/function_call/anonymous_function_closure/anonymous_function_002_T/anonymous_function_002_T.go\nLine 16: __taint_sink(process(__taint_src, \"foo\"))\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/sast-go/cases/completeness/single_app_tracing/function_call/anonymous_function_closure/anonymous_function_002_T/anonymous_function_002_T.go\",\"functionName\":\"main\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /sast-go/cases/completeness/single_app_tracing/function_call/anonymous_function_closure/anonymous_function_002_T/anonymous_function_002_T.go\n AffectedNodeName: __taint_src\n 23: SOURCE: anonymous_function_002_T(__taint_src)\n /sast-go/cases/completeness/single_app_tracing/function_call/anonymous_function_closure/anonymous_function_002_T/anonymous_function_002_T.go\n AffectedNodeName: anonymous_function_002_T\n 23: CALL: anonymous_function_002_T(__taint_src)\n /sast-go/cases/completeness/single_app_tracing/function_call/anonymous_function_closure/anonymous_function_002_T/anonymous_function_002_T.go\n AffectedNodeName: __taint_src\n 12: ARG PASS: func anonymous_function_002_T(__taint_src string) {\n /sast-go/cases/completeness/single_app_tracing/function_call/anonymous_function_closure/anonymous_function_002_T/anonymous_function_002_T.go\n AffectedNodeName: \n 16: CALL: \t__taint_sink(process(__taint_src, \"foo\"))\n /sast-go/cases/completeness/single_app_tracing/function_call/anonymous_function_closure/anonymous_function_002_T/anonymous_function_002_T.go\n AffectedNodeName: a\n 13: ARG PASS: \tprocess := func(a string, b string) string {\n /sast-go/cases/completeness/single_app_tracing/function_call/anonymous_function_closure/anonymous_function_002_T/anonymous_function_002_T.go\n AffectedNodeName: [return value]\n 14: Return Value: \t\treturn a + b\n /sast-go/cases/completeness/single_app_tracing/function_call/anonymous_function_closure/anonymous_function_002_T/anonymous_function_002_T.go\n AffectedNodeName: \n 16: CALL RETURN: \t__taint_sink(process(__taint_src, \"foo\"))\n /sast-go/cases/completeness/single_app_tracing/function_call/anonymous_function_closure/anonymous_function_002_T/anonymous_function_002_T.go\n AffectedNodeName: __taint_sink\n 16: SINK: \t__taint_sink(process(__taint_src, \"foo\"))\n==========================================================\n #Total-findings:1\n==========================================================","/benchmarks/sast-go/cases/completeness/single_app_tracing/function_call/anonymous_function_closure/anonymous_function_003_F/anonymous_function_003_F":"======================== Findings ========================\nNo findings!\n==========================================================","/benchmarks/sast-go/cases/completeness/single_app_tracing/function_call/anonymous_function_closure/anonymous_function_004_T/anonymous_function_004_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/sast-go/cases/completeness/single_app_tracing/function_call/anonymous_function_closure/anonymous_function_004_T/anonymous_function_004_T.go\nLine 15: __taint_sink(input)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/sast-go/cases/completeness/single_app_tracing/function_call/anonymous_function_closure/anonymous_function_004_T/anonymous_function_004_T.go\",\"functionName\":\"main\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /sast-go/cases/completeness/single_app_tracing/function_call/anonymous_function_closure/anonymous_function_004_T/anonymous_function_004_T.go\n AffectedNodeName: __taint_src\n 25: SOURCE: anonymous_function_004_T(__taint_src)\n /sast-go/cases/completeness/single_app_tracing/function_call/anonymous_function_closure/anonymous_function_004_T/anonymous_function_004_T.go\n AffectedNodeName: anonymous_function_004_T\n 25: CALL: anonymous_function_004_T(__taint_src)\n /sast-go/cases/completeness/single_app_tracing/function_call/anonymous_function_closure/anonymous_function_004_T/anonymous_function_004_T.go\n AffectedNodeName: __taint_src\n 12: ARG PASS: func anonymous_function_004_T(__taint_src interface{}) {\n /sast-go/cases/completeness/single_app_tracing/function_call/anonymous_function_closure/anonymous_function_004_T/anonymous_function_004_T.go\n AffectedNodeName: \n 18: CALL: \tprocess(__taint_src)\n /sast-go/cases/completeness/single_app_tracing/function_call/anonymous_function_closure/anonymous_function_004_T/anonymous_function_004_T.go\n AffectedNodeName: input\n 14: ARG PASS: \tprocess := func(input interface{}) {\n /sast-go/cases/completeness/single_app_tracing/function_call/anonymous_function_closure/anonymous_function_004_T/anonymous_function_004_T.go\n AffectedNodeName: __taint_sink\n 15: SINK: \t\t__taint_sink(input)\n==========================================================\n #Total-findings:1\n==========================================================","/benchmarks/sast-go/cases/completeness/single_app_tracing/function_call/anonymous_function_closure/anonymous_function_005_F/anonymous_function_005_F":"======================== Findings ========================\nNo findings!\n==========================================================","/benchmarks/sast-go/cases/completeness/single_app_tracing/function_call/anonymous_function_closure/anonymous_function_006_T/anonymous_function_006_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/sast-go/cases/completeness/single_app_tracing/function_call/anonymous_function_closure/anonymous_function_006_T/anonymous_function_006_T.go\nLine 14: __taint_sink(__taint_src)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/sast-go/cases/completeness/single_app_tracing/function_call/anonymous_function_closure/anonymous_function_006_T/anonymous_function_006_T.go\",\"functionName\":\"main\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /sast-go/cases/completeness/single_app_tracing/function_call/anonymous_function_closure/anonymous_function_006_T/anonymous_function_006_T.go\n AffectedNodeName: __taint_src\n 22: SOURCE: anonymous_function_006_T(__taint_src)\n /sast-go/cases/completeness/single_app_tracing/function_call/anonymous_function_closure/anonymous_function_006_T/anonymous_function_006_T.go\n AffectedNodeName: anonymous_function_006_T\n 22: CALL: anonymous_function_006_T(__taint_src)\n /sast-go/cases/completeness/single_app_tracing/function_call/anonymous_function_closure/anonymous_function_006_T/anonymous_function_006_T.go\n AffectedNodeName: __taint_src\n 12: ARG PASS: func anonymous_function_006_T(__taint_src interface{}) {\n /sast-go/cases/completeness/single_app_tracing/function_call/anonymous_function_closure/anonymous_function_006_T/anonymous_function_006_T.go\n AffectedNodeName: __taint_sink\n 14: SINK: \t\t__taint_sink(__taint_src)\n==========================================================\n #Total-findings:1\n==========================================================","/benchmarks/sast-go/cases/completeness/single_app_tracing/function_call/anonymous_function_closure/closure_function_001_F/closure_function_001_F":"======================== Findings ========================\nNo findings!\n==========================================================","/benchmarks/sast-go/cases/completeness/single_app_tracing/function_call/anonymous_function_closure/closure_function_002_T/closure_function_002_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/sast-go/cases/completeness/single_app_tracing/function_call/anonymous_function_closure/closure_function_002_T/closure_function_002_T.go\nLine 14: __taint_sink(__taint_src)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/sast-go/cases/completeness/single_app_tracing/function_call/anonymous_function_closure/closure_function_002_T/closure_function_002_T.go\",\"functionName\":\"main\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /sast-go/cases/completeness/single_app_tracing/function_call/anonymous_function_closure/closure_function_002_T/closure_function_002_T.go\n AffectedNodeName: __taint_src\n 23: SOURCE: closure_function_002_T(__taint_src)\n /sast-go/cases/completeness/single_app_tracing/function_call/anonymous_function_closure/closure_function_002_T/closure_function_002_T.go\n AffectedNodeName: closure_function_002_T\n 23: CALL: closure_function_002_T(__taint_src)\n /sast-go/cases/completeness/single_app_tracing/function_call/anonymous_function_closure/closure_function_002_T/closure_function_002_T.go\n AffectedNodeName: __taint_src\n 12: ARG PASS: func closure_function_002_T(__taint_src interface{}) {\n /sast-go/cases/completeness/single_app_tracing/function_call/anonymous_function_closure/closure_function_002_T/closure_function_002_T.go\n AffectedNodeName: __taint_sink\n 14: SINK: \t\t__taint_sink(__taint_src)\n==========================================================\n #Total-findings:1\n==========================================================","/benchmarks/sast-go/cases/completeness/single_app_tracing/function_call/anonymous_function_closure/closure_function_003_F/closure_function_003_F":"======================== Findings ========================\nNo findings!\n==========================================================","/benchmarks/sast-go/cases/completeness/single_app_tracing/function_call/anonymous_function_closure/closure_function_004_T/closure_function_004_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/sast-go/cases/completeness/single_app_tracing/function_call/anonymous_function_closure/closure_function_004_T/closure_function_004_T.go\nLine 15: __taint_sink(__taint_src)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/sast-go/cases/completeness/single_app_tracing/function_call/anonymous_function_closure/closure_function_004_T/closure_function_004_T.go\",\"functionName\":\"main\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /sast-go/cases/completeness/single_app_tracing/function_call/anonymous_function_closure/closure_function_004_T/closure_function_004_T.go\n AffectedNodeName: __taint_src\n 26: SOURCE: closure_function_004_T(__taint_src)\n /sast-go/cases/completeness/single_app_tracing/function_call/anonymous_function_closure/closure_function_004_T/closure_function_004_T.go\n AffectedNodeName: closure_function_004_T\n 26: CALL: closure_function_004_T(__taint_src)\n /sast-go/cases/completeness/single_app_tracing/function_call/anonymous_function_closure/closure_function_004_T/closure_function_004_T.go\n AffectedNodeName: __taint_src\n 12: ARG PASS: func closure_function_004_T(__taint_src interface{}) {\n /sast-go/cases/completeness/single_app_tracing/function_call/anonymous_function_closure/closure_function_004_T/closure_function_004_T.go\n AffectedNodeName: __taint_sink\n 15: SINK: \t\t\t__taint_sink(__taint_src)\n==========================================================\n #Total-findings:1\n==========================================================","/benchmarks/sast-go/cases/completeness/single_app_tracing/function_call/anonymous_function_closure/closure_function_005_F/closure_function_005_F":"======================== Findings ========================\nNo findings!\n==========================================================","/benchmarks/sast-go/cases/completeness/single_app_tracing/function_call/anonymous_function_closure/closure_function_006_T/closure_function_006_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/sast-go/cases/completeness/single_app_tracing/function_call/anonymous_function_closure/closure_function_006_T/closure_function_006_T.go\nLine 35: __taint_sink(a.update())\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/sast-go/cases/completeness/single_app_tracing/function_call/anonymous_function_closure/closure_function_006_T/closure_function_006_T.go\",\"functionName\":\"main\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /sast-go/cases/completeness/single_app_tracing/function_call/anonymous_function_closure/closure_function_006_T/closure_function_006_T.go\n AffectedNodeName: __taint_src\n 42: SOURCE: closure_function_006_T(__taint_src)\n /sast-go/cases/completeness/single_app_tracing/function_call/anonymous_function_closure/closure_function_006_T/closure_function_006_T.go\n AffectedNodeName: closure_function_006_T\n 42: CALL: closure_function_006_T(__taint_src)\n /sast-go/cases/completeness/single_app_tracing/function_call/anonymous_function_closure/closure_function_006_T/closure_function_006_T.go\n AffectedNodeName: __taint_src\n 13: ARG PASS: func closure_function_006_T(__taint_src string) {\n /sast-go/cases/completeness/single_app_tracing/function_call/anonymous_function_closure/closure_function_006_T/closure_function_006_T.go\n AffectedNodeName: source\n 25: Var Pass: \t\t\t\tsource = __taint_src\n /sast-go/cases/completeness/single_app_tracing/function_call/anonymous_function_closure/closure_function_006_T/closure_function_006_T.go\n AffectedNodeName: [return value]\n 26: Return Value: \t\t\t\treturn source\n /sast-go/cases/completeness/single_app_tracing/function_call/anonymous_function_closure/closure_function_006_T/closure_function_006_T.go\n AffectedNodeName: \n 35: CALL RETURN: \t__taint_sink(a.update())\n /sast-go/cases/completeness/single_app_tracing/function_call/anonymous_function_closure/closure_function_006_T/closure_function_006_T.go\n AffectedNodeName: __taint_sink\n 35: SINK: \t__taint_sink(a.update())\n==========================================================\n #Total-findings:1\n==========================================================","/benchmarks/sast-go/cases/completeness/single_app_tracing/function_call/anonymous_function_closure/closure_function_007_F/closure_function_007_F":"======================== Findings ========================\nNo findings!\n==========================================================","/benchmarks/sast-go/cases/completeness/single_app_tracing/function_call/anonymous_function_closure/closure_function_008_T/closure_function_008_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/sast-go/cases/completeness/single_app_tracing/function_call/anonymous_function_closure/closure_function_008_T/closure_function_008_T.go\nLine 20: __taint_sink(middleVar)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/sast-go/cases/completeness/single_app_tracing/function_call/anonymous_function_closure/closure_function_008_T/closure_function_008_T.go\",\"functionName\":\"main\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /sast-go/cases/completeness/single_app_tracing/function_call/anonymous_function_closure/closure_function_008_T/closure_function_008_T.go\n AffectedNodeName: __taint_src\n 38: SOURCE: closure_function_008_T(__taint_src)\n /sast-go/cases/completeness/single_app_tracing/function_call/anonymous_function_closure/closure_function_008_T/closure_function_008_T.go\n AffectedNodeName: closure_function_008_T\n 38: CALL: closure_function_008_T(__taint_src)\n /sast-go/cases/completeness/single_app_tracing/function_call/anonymous_function_closure/closure_function_008_T/closure_function_008_T.go\n AffectedNodeName: __taint_src\n 12: ARG PASS: func closure_function_008_T(__taint_src interface{}) {\n /sast-go/cases/completeness/single_app_tracing/function_call/anonymous_function_closure/closure_function_008_T/closure_function_008_T.go\n AffectedNodeName: outerVar\n 14: Var Pass: \t\touterVar := __taint_src\n /sast-go/cases/completeness/single_app_tracing/function_call/anonymous_function_closure/closure_function_008_T/closure_function_008_T.go\n AffectedNodeName: middleVar\n 17: Var Pass: \t\t\tmiddleVar := outerVar\n /sast-go/cases/completeness/single_app_tracing/function_call/anonymous_function_closure/closure_function_008_T/closure_function_008_T.go\n AffectedNodeName: __taint_sink\n 20: SINK: \t\t\t\t__taint_sink(middleVar)\n==========================================================\n #Total-findings:1\n==========================================================","/benchmarks/sast-go/cases/completeness/single_app_tracing/function_call/anonymous_function_closure/closure_function_009_F/closure_function_009_F":"======================== Findings ========================\nNo findings!\n==========================================================","/benchmarks/sast-go/cases/completeness/single_app_tracing/function_call/anonymous_function_closure/closure_function_010_T/closure_function_010_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/sast-go/cases/completeness/single_app_tracing/function_call/anonymous_function_closure/closure_function_010_T/closure_function_010_T.go\nLine 18: __taint_sink(outerVar)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/sast-go/cases/completeness/single_app_tracing/function_call/anonymous_function_closure/closure_function_010_T/closure_function_010_T.go\",\"functionName\":\"main\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /sast-go/cases/completeness/single_app_tracing/function_call/anonymous_function_closure/closure_function_010_T/closure_function_010_T.go\n AffectedNodeName: __taint_src\n 36: SOURCE: closure_function_010_T(__taint_src)\n /sast-go/cases/completeness/single_app_tracing/function_call/anonymous_function_closure/closure_function_010_T/closure_function_010_T.go\n AffectedNodeName: closure_function_010_T\n 36: CALL: closure_function_010_T(__taint_src)\n /sast-go/cases/completeness/single_app_tracing/function_call/anonymous_function_closure/closure_function_010_T/closure_function_010_T.go\n AffectedNodeName: __taint_src\n 12: ARG PASS: func closure_function_010_T(__taint_src interface{}) {\n /sast-go/cases/completeness/single_app_tracing/function_call/anonymous_function_closure/closure_function_010_T/closure_function_010_T.go\n AffectedNodeName: outerVar\n 14: Var Pass: \t\touterVar := __taint_src\n /sast-go/cases/completeness/single_app_tracing/function_call/anonymous_function_closure/closure_function_010_T/closure_function_010_T.go\n AffectedNodeName: __taint_sink\n 18: SINK: \t\t\t\t__taint_sink(outerVar)\n==========================================================\n #Total-findings:1\n==========================================================","/benchmarks/sast-go/cases/completeness/single_app_tracing/function_call/argument_passing/argument_passing_value_001_F/argument_passing_value_001_F":"======================== Findings ========================\nNo findings!\n==========================================================","/benchmarks/sast-go/cases/completeness/single_app_tracing/function_call/argument_passing/argument_passing_value_002_T/argument_passing_value_002_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/sast-go/cases/completeness/single_app_tracing/function_call/argument_passing/argument_passing_value_002_T/argument_passing_value_002_T.go\nLine 17: __taint_sink(arg)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/sast-go/cases/completeness/single_app_tracing/function_call/argument_passing/argument_passing_value_002_T/argument_passing_value_002_T.go\",\"functionName\":\"main\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /sast-go/cases/completeness/single_app_tracing/function_call/argument_passing/argument_passing_value_002_T/argument_passing_value_002_T.go\n AffectedNodeName: __taint_src\n 24: SOURCE: argument_passing_value_002_T(__taint_src)\n /sast-go/cases/completeness/single_app_tracing/function_call/argument_passing/argument_passing_value_002_T/argument_passing_value_002_T.go\n AffectedNodeName: argument_passing_value_002_T\n 24: CALL: argument_passing_value_002_T(__taint_src)\n /sast-go/cases/completeness/single_app_tracing/function_call/argument_passing/argument_passing_value_002_T/argument_passing_value_002_T.go\n AffectedNodeName: __taint_src\n 12: ARG PASS: func argument_passing_value_002_T(__taint_src string) {\n /sast-go/cases/completeness/single_app_tracing/function_call/argument_passing/argument_passing_value_002_T/argument_passing_value_002_T.go\n AffectedNodeName: process\n 13: CALL: \tprocess(__taint_src)\n /sast-go/cases/completeness/single_app_tracing/function_call/argument_passing/argument_passing_value_002_T/argument_passing_value_002_T.go\n AffectedNodeName: arg\n 16: ARG PASS: func process(arg string) {\n /sast-go/cases/completeness/single_app_tracing/function_call/argument_passing/argument_passing_value_002_T/argument_passing_value_002_T.go\n AffectedNodeName: __taint_sink\n 17: SINK: \t__taint_sink(arg)\n==========================================================\n #Total-findings:1\n==========================================================","/benchmarks/sast-go/cases/completeness/single_app_tracing/function_call/argument_passing/argument_passing_value_003_F/argument_passing_value_003_F":"======================== Findings ========================\nNo findings!\n==========================================================","/benchmarks/sast-go/cases/completeness/single_app_tracing/function_call/argument_passing/argument_passing_value_004_T/argument_passing_value_004_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/sast-go/cases/completeness/single_app_tracing/function_call/argument_passing/argument_passing_value_004_T/argument_passing_value_004_T.go\nLine 19: __taint_sink(arg)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/sast-go/cases/completeness/single_app_tracing/function_call/argument_passing/argument_passing_value_004_T/argument_passing_value_004_T.go\",\"functionName\":\"main\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /sast-go/cases/completeness/single_app_tracing/function_call/argument_passing/argument_passing_value_004_T/argument_passing_value_004_T.go\n AffectedNodeName: __taint_src\n 29: SOURCE: argument_passing_value_004_T(__taint_src)\n /sast-go/cases/completeness/single_app_tracing/function_call/argument_passing/argument_passing_value_004_T/argument_passing_value_004_T.go\n AffectedNodeName: argument_passing_value_004_T\n 29: CALL: argument_passing_value_004_T(__taint_src)\n /sast-go/cases/completeness/single_app_tracing/function_call/argument_passing/argument_passing_value_004_T/argument_passing_value_004_T.go\n AffectedNodeName: __taint_src\n 12: ARG PASS: func argument_passing_value_004_T(__taint_src interface{}) {\n /sast-go/cases/completeness/single_app_tracing/function_call/argument_passing/argument_passing_value_004_T/argument_passing_value_004_T.go\n AffectedNodeName: process1\n 15: CALL: \tprocess1(__taint_src)\n /sast-go/cases/completeness/single_app_tracing/function_call/argument_passing/argument_passing_value_004_T/argument_passing_value_004_T.go\n AffectedNodeName: arg\n 18: ARG PASS: func process1(arg interface{}) {\n /sast-go/cases/completeness/single_app_tracing/function_call/argument_passing/argument_passing_value_004_T/argument_passing_value_004_T.go\n AffectedNodeName: __taint_sink\n 19: SINK: \t__taint_sink(arg)\n==========================================================\n #Total-findings:1\n==========================================================","/benchmarks/sast-go/cases/completeness/single_app_tracing/function_call/argument_passing/argument_passing_value_005_F/argument_passing_value_005_F":"======================== Findings ========================\nNo findings!\n==========================================================","/benchmarks/sast-go/cases/completeness/single_app_tracing/function_call/argument_passing/argument_passing_value_006_T/argument_passing_value_006_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/sast-go/cases/completeness/single_app_tracing/function_call/argument_passing/argument_passing_value_006_T/argument_passing_value_006_T.go\nLine 17: __taint_sink(arg1)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/sast-go/cases/completeness/single_app_tracing/function_call/argument_passing/argument_passing_value_006_T/argument_passing_value_006_T.go\",\"functionName\":\"main\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /sast-go/cases/completeness/single_app_tracing/function_call/argument_passing/argument_passing_value_006_T/argument_passing_value_006_T.go\n AffectedNodeName: __taint_src\n 23: SOURCE: argument_passing_value_006_T(__taint_src)\n /sast-go/cases/completeness/single_app_tracing/function_call/argument_passing/argument_passing_value_006_T/argument_passing_value_006_T.go\n AffectedNodeName: argument_passing_value_006_T\n 23: CALL: argument_passing_value_006_T(__taint_src)\n /sast-go/cases/completeness/single_app_tracing/function_call/argument_passing/argument_passing_value_006_T/argument_passing_value_006_T.go\n AffectedNodeName: __taint_src\n 12: ARG PASS: func argument_passing_value_006_T(__taint_src string) {\n /sast-go/cases/completeness/single_app_tracing/function_call/argument_passing/argument_passing_value_006_T/argument_passing_value_006_T.go\n AffectedNodeName: process\n 13: CALL: \tprocess(__taint_src, \"_\")\n /sast-go/cases/completeness/single_app_tracing/function_call/argument_passing/argument_passing_value_006_T/argument_passing_value_006_T.go\n AffectedNodeName: arg1\n 16: ARG PASS: func process(arg1 string, arg2 string) {\n /sast-go/cases/completeness/single_app_tracing/function_call/argument_passing/argument_passing_value_006_T/argument_passing_value_006_T.go\n AffectedNodeName: __taint_sink\n 17: SINK: \t__taint_sink(arg1)\n==========================================================\n #Total-findings:1\n==========================================================","/benchmarks/sast-go/cases/completeness/single_app_tracing/function_call/argument_passing/argument_passing_value_007_F/argument_passing_value_007_F":"======================== Findings ========================\nNo findings!\n==========================================================","/benchmarks/sast-go/cases/completeness/single_app_tracing/function_call/argument_passing/argument_passing_value_008_T/argument_passing_value_008_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/sast-go/cases/completeness/single_app_tracing/function_call/argument_passing/argument_passing_value_008_T/argument_passing_value_008_T.go\nLine 15: __taint_sink(innerInput)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/sast-go/cases/completeness/single_app_tracing/function_call/argument_passing/argument_passing_value_008_T/argument_passing_value_008_T.go\",\"functionName\":\"main\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /sast-go/cases/completeness/single_app_tracing/function_call/argument_passing/argument_passing_value_008_T/argument_passing_value_008_T.go\n AffectedNodeName: __taint_src\n 27: SOURCE: argument_passing_value_008_T(__taint_src)\n /sast-go/cases/completeness/single_app_tracing/function_call/argument_passing/argument_passing_value_008_T/argument_passing_value_008_T.go\n AffectedNodeName: argument_passing_value_008_T\n 27: CALL: argument_passing_value_008_T(__taint_src)\n /sast-go/cases/completeness/single_app_tracing/function_call/argument_passing/argument_passing_value_008_T/argument_passing_value_008_T.go\n AffectedNodeName: __taint_src\n 12: ARG PASS: func argument_passing_value_008_T(__taint_src string) {\n /sast-go/cases/completeness/single_app_tracing/function_call/argument_passing/argument_passing_value_008_T/argument_passing_value_008_T.go\n AffectedNodeName: \n 21: CALL: \touter(__taint_src)\n /sast-go/cases/completeness/single_app_tracing/function_call/argument_passing/argument_passing_value_008_T/argument_passing_value_008_T.go\n AffectedNodeName: input\n 13: ARG PASS: \touter := func(input string) {\n /sast-go/cases/completeness/single_app_tracing/function_call/argument_passing/argument_passing_value_008_T/argument_passing_value_008_T.go\n AffectedNodeName: \n 18: CALL: \t\tinner(input)\n /sast-go/cases/completeness/single_app_tracing/function_call/argument_passing/argument_passing_value_008_T/argument_passing_value_008_T.go\n AffectedNodeName: innerInput\n 14: ARG PASS: \t\tinner := func(innerInput interface{}) {\n /sast-go/cases/completeness/single_app_tracing/function_call/argument_passing/argument_passing_value_008_T/argument_passing_value_008_T.go\n AffectedNodeName: __taint_sink\n 15: SINK: \t\t\t__taint_sink(innerInput)\n==========================================================\n #Total-findings:1\n==========================================================","/benchmarks/sast-go/cases/completeness/single_app_tracing/function_call/argument_passing/argument_passing_value_009_T/argument_passing_value_009_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/sast-go/cases/completeness/single_app_tracing/function_call/argument_passing/argument_passing_value_009_T/argument_passing_value_009_T.go\nLine 20: __taint_sink(person.GetNamePointer())\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/sast-go/cases/completeness/single_app_tracing/function_call/argument_passing/argument_passing_value_009_T/argument_passing_value_009_T.go\",\"functionName\":\"main\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /sast-go/cases/completeness/single_app_tracing/function_call/argument_passing/argument_passing_value_009_T/argument_passing_value_009_T.go\n AffectedNodeName: __taint_src\n 35: SOURCE: argument_passing_value_009_T(__taint_src)\n /sast-go/cases/completeness/single_app_tracing/function_call/argument_passing/argument_passing_value_009_T/argument_passing_value_009_T.go\n AffectedNodeName: argument_passing_value_009_T\n 35: CALL: argument_passing_value_009_T(__taint_src)\n /sast-go/cases/completeness/single_app_tracing/function_call/argument_passing/argument_passing_value_009_T/argument_passing_value_009_T.go\n AffectedNodeName: __taint_src\n 16: ARG PASS: func argument_passing_value_009_T(__taint_src string) {\n /sast-go/cases/completeness/single_app_tracing/function_call/argument_passing/argument_passing_value_009_T/argument_passing_value_009_T.go\n AffectedNodeName: person\n 17: Var Pass: \tperson := Person{Name: __taint_src}\n /sast-go/cases/completeness/single_app_tracing/function_call/argument_passing/argument_passing_value_009_T/argument_passing_value_009_T.go\n AffectedNodeName: UpdateNamePointer\n 19: CALL: \tperson.UpdateNamePointer(\"safe\")\n /sast-go/cases/completeness/single_app_tracing/function_call/argument_passing/argument_passing_value_009_T/argument_passing_value_009_T.go\n AffectedNodeName: person\n 19: ARG PASS: \tperson.UpdateNamePointer(\"safe\")\n /sast-go/cases/completeness/single_app_tracing/function_call/argument_passing/argument_passing_value_009_T/argument_passing_value_009_T.go\n AffectedNodeName: GetNamePointer\n 20: CALL: \t__taint_sink(person.GetNamePointer())\n /sast-go/cases/completeness/single_app_tracing/function_call/argument_passing/argument_passing_value_009_T/argument_passing_value_009_T.go\n AffectedNodeName: person\n 20: ARG PASS: \t__taint_sink(person.GetNamePointer())\n /sast-go/cases/completeness/single_app_tracing/function_call/argument_passing/argument_passing_value_009_T/argument_passing_value_009_T.go\n AffectedNodeName: GetNamePointer\n 20: CALL: \t__taint_sink(person.GetNamePointer())\n /sast-go/cases/completeness/single_app_tracing/function_call/argument_passing/argument_passing_value_009_T/argument_passing_value_009_T.go\n AffectedNodeName: person\n 20: ARG PASS: \t__taint_sink(person.GetNamePointer())\n /sast-go/cases/completeness/single_app_tracing/function_call/argument_passing/argument_passing_value_009_T/argument_passing_value_009_T.go\n AffectedNodeName: GetNamePointer\n 20: CALL RETURN: \t__taint_sink(person.GetNamePointer())\n /sast-go/cases/completeness/single_app_tracing/function_call/argument_passing/argument_passing_value_009_T/argument_passing_value_009_T.go\n AffectedNodeName: __taint_sink\n 20: SINK: \t__taint_sink(person.GetNamePointer())\n==========================================================\n #Total-findings:1\n==========================================================","/benchmarks/sast-go/cases/completeness/single_app_tracing/function_call/argument_passing/argument_passing_value_010_F/argument_passing_value_010_F":"======================== Findings ========================\nNo findings!\n==========================================================","/benchmarks/sast-go/cases/completeness/single_app_tracing/function_call/chained_call/chained_call_001_F/chained_call_001_F":"======================== Findings ========================\nNo findings!\n==========================================================","/benchmarks/sast-go/cases/completeness/single_app_tracing/function_call/chained_call/chained_call_002_T/chained_call_002_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/sast-go/cases/completeness/single_app_tracing/function_call/chained_call/chained_call_002_T/chained_call_002_T.go\nLine 31: __taint_sink(a.name)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/sast-go/cases/completeness/single_app_tracing/function_call/chained_call/chained_call_002_T/chained_call_002_T.go\",\"functionName\":\"main\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /sast-go/cases/completeness/single_app_tracing/function_call/chained_call/chained_call_002_T/chained_call_002_T.go\n AffectedNodeName: __taint_src\n 37: SOURCE: chained_call_002_T(__taint_src)\n /sast-go/cases/completeness/single_app_tracing/function_call/chained_call/chained_call_002_T/chained_call_002_T.go\n AffectedNodeName: chained_call_002_T\n 37: CALL: chained_call_002_T(__taint_src)\n /sast-go/cases/completeness/single_app_tracing/function_call/chained_call/chained_call_002_T/chained_call_002_T.go\n AffectedNodeName: __taint_src\n 12: ARG PASS: func chained_call_002_T(__taint_src string) {\n /sast-go/cases/completeness/single_app_tracing/function_call/chained_call/chained_call_002_T/chained_call_002_T.go\n AffectedNodeName: setName\n 13: CALL: \tnew(A).setName(\"_\").clearName().setName(__taint_src).process()\n /sast-go/cases/completeness/single_app_tracing/function_call/chained_call/chained_call_002_T/chained_call_002_T.go\n AffectedNodeName: setName\n 13: CALL RETURN: \tnew(A).setName(\"_\").clearName().setName(__taint_src).process()\n /sast-go/cases/completeness/single_app_tracing/function_call/chained_call/chained_call_002_T/chained_call_002_T.go\n AffectedNodeName: process\n 13: CALL: \tnew(A).setName(\"_\").clearName().setName(__taint_src).process()\n /sast-go/cases/completeness/single_app_tracing/function_call/chained_call/chained_call_002_T/chained_call_002_T.go\n AffectedNodeName: new A().setName(\"_\").clearName().setName(__taint_s\n 13: ARG PASS: \tnew(A).setName(\"_\").clearName().setName(__taint_src).process()\n /sast-go/cases/completeness/single_app_tracing/function_call/chained_call/chained_call_002_T/chained_call_002_T.go\n AffectedNodeName: __taint_sink\n 31: SINK: \t__taint_sink(a.name)\n==========================================================\n #Total-findings:1\n==========================================================","/benchmarks/sast-go/cases/completeness/single_app_tracing/function_call/chained_call/chained_call_003_F/chained_call_003_F":"======================== Findings ========================\nNo findings!\n==========================================================","/benchmarks/sast-go/cases/completeness/single_app_tracing/function_call/chained_call/chained_call_004_T/chained_call_004_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/sast-go/cases/completeness/single_app_tracing/function_call/chained_call/chained_call_004_T/chained_call_004_T.go\nLine 39: __taint_sink(b.name)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/sast-go/cases/completeness/single_app_tracing/function_call/chained_call/chained_call_004_T/chained_call_004_T.go\",\"functionName\":\"main\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /sast-go/cases/completeness/single_app_tracing/function_call/chained_call/chained_call_004_T/chained_call_004_T.go\n AffectedNodeName: __taint_src\n 46: SOURCE: chained_call_004_T(__taint_src)\n /sast-go/cases/completeness/single_app_tracing/function_call/chained_call/chained_call_004_T/chained_call_004_T.go\n AffectedNodeName: chained_call_004_T\n 46: CALL: chained_call_004_T(__taint_src)\n /sast-go/cases/completeness/single_app_tracing/function_call/chained_call/chained_call_004_T/chained_call_004_T.go\n AffectedNodeName: __taint_src\n 12: ARG PASS: func chained_call_004_T(__taint_src string) {\n /sast-go/cases/completeness/single_app_tracing/function_call/chained_call/chained_call_004_T/chained_call_004_T.go\n AffectedNodeName: SetName\n 13: CALL: \tNewB().SetName(__taint_src).SetOther().Process()\n /sast-go/cases/completeness/single_app_tracing/function_call/chained_call/chained_call_004_T/chained_call_004_T.go\n AffectedNodeName: SetName\n 13: CALL RETURN: \tNewB().SetName(__taint_src).SetOther().Process()\n /sast-go/cases/completeness/single_app_tracing/function_call/chained_call/chained_call_004_T/chained_call_004_T.go\n AffectedNodeName: SetOther\n 13: CALL: \tNewB().SetName(__taint_src).SetOther().Process()\n /sast-go/cases/completeness/single_app_tracing/function_call/chained_call/chained_call_004_T/chained_call_004_T.go\n AffectedNodeName: NewB().SetName(__taint_src)\n 13: ARG PASS: \tNewB().SetName(__taint_src).SetOther().Process()\n /sast-go/cases/completeness/single_app_tracing/function_call/chained_call/chained_call_004_T/chained_call_004_T.go\n AffectedNodeName: SetOther\n 13: CALL RETURN: \tNewB().SetName(__taint_src).SetOther().Process()\n /sast-go/cases/completeness/single_app_tracing/function_call/chained_call/chained_call_004_T/chained_call_004_T.go\n AffectedNodeName: Process\n 13: CALL: \tNewB().SetName(__taint_src).SetOther().Process()\n /sast-go/cases/completeness/single_app_tracing/function_call/chained_call/chained_call_004_T/chained_call_004_T.go\n AffectedNodeName: NewB().SetName(__taint_src).SetOther()\n 13: ARG PASS: \tNewB().SetName(__taint_src).SetOther().Process()\n /sast-go/cases/completeness/single_app_tracing/function_call/chained_call/chained_call_004_T/chained_call_004_T.go\n AffectedNodeName: __taint_sink\n 39: SINK: \t__taint_sink(b.name)\n==========================================================\n #Total-findings:1\n==========================================================","/benchmarks/sast-go/cases/completeness/single_app_tracing/function_call/higher_order_function/higher_order_function_001_F/higher_order_function_001_F":"======================== Findings ========================\nNo findings!\n==========================================================","/benchmarks/sast-go/cases/completeness/single_app_tracing/function_call/higher_order_function/higher_order_function_002_T/higher_order_function_002_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/sast-go/cases/completeness/single_app_tracing/function_call/higher_order_function/higher_order_function_002_T/higher_order_function_002_T.go\nLine 20: __taint_sink(f(__taint_src, \"_\")())\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/sast-go/cases/completeness/single_app_tracing/function_call/higher_order_function/higher_order_function_002_T/higher_order_function_002_T.go\",\"functionName\":\"main\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /sast-go/cases/completeness/single_app_tracing/function_call/higher_order_function/higher_order_function_002_T/higher_order_function_002_T.go\n AffectedNodeName: __taint_src\n 27: SOURCE: higher_order_function_002_T(__taint_src)\n /sast-go/cases/completeness/single_app_tracing/function_call/higher_order_function/higher_order_function_002_T/higher_order_function_002_T.go\n AffectedNodeName: higher_order_function_002_T\n 27: CALL: higher_order_function_002_T(__taint_src)\n /sast-go/cases/completeness/single_app_tracing/function_call/higher_order_function/higher_order_function_002_T/higher_order_function_002_T.go\n AffectedNodeName: __taint_src\n 12: ARG PASS: func higher_order_function_002_T(__taint_src string) {\n /sast-go/cases/completeness/single_app_tracing/function_call/higher_order_function/higher_order_function_002_T/higher_order_function_002_T.go\n AffectedNodeName: \n 20: CALL: \t__taint_sink(f(__taint_src, \"_\")())\n /sast-go/cases/completeness/single_app_tracing/function_call/higher_order_function/higher_order_function_002_T/higher_order_function_002_T.go\n AffectedNodeName: a\n 13: ARG PASS: \tf := func(a string, b string) func() string {\n /sast-go/cases/completeness/single_app_tracing/function_call/higher_order_function/higher_order_function_002_T/higher_order_function_002_T.go\n AffectedNodeName: [return value]\n 16: Return Value: \t\t\treturn a + b + c\n /sast-go/cases/completeness/single_app_tracing/function_call/higher_order_function/higher_order_function_002_T/higher_order_function_002_T.go\n AffectedNodeName: \n 20: CALL RETURN: \t__taint_sink(f(__taint_src, \"_\")())\n /sast-go/cases/completeness/single_app_tracing/function_call/higher_order_function/higher_order_function_002_T/higher_order_function_002_T.go\n AffectedNodeName: __taint_sink\n 20: SINK: \t__taint_sink(f(__taint_src, \"_\")())\n==========================================================\n #Total-findings:1\n==========================================================","/benchmarks/sast-go/cases/completeness/single_app_tracing/function_call/higher_order_function/higher_order_function_003_F/higher_order_function_003_F":"======================== Findings ========================\nNo findings!\n==========================================================","/benchmarks/sast-go/cases/completeness/single_app_tracing/function_call/higher_order_function/higher_order_function_004_T/higher_order_function_004_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/sast-go/cases/completeness/single_app_tracing/function_call/higher_order_function/higher_order_function_004_T/higher_order_function_004_T.go\nLine 24: __taint_sink(f(g, __taint_src, \"_\"))\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/sast-go/cases/completeness/single_app_tracing/function_call/higher_order_function/higher_order_function_004_T/higher_order_function_004_T.go\",\"functionName\":\"main\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /sast-go/cases/completeness/single_app_tracing/function_call/higher_order_function/higher_order_function_004_T/higher_order_function_004_T.go\n AffectedNodeName: __taint_src\n 31: SOURCE: higher_order_function_004_T(__taint_src)\n /sast-go/cases/completeness/single_app_tracing/function_call/higher_order_function/higher_order_function_004_T/higher_order_function_004_T.go\n AffectedNodeName: higher_order_function_004_T\n 31: CALL: higher_order_function_004_T(__taint_src)\n /sast-go/cases/completeness/single_app_tracing/function_call/higher_order_function/higher_order_function_004_T/higher_order_function_004_T.go\n AffectedNodeName: __taint_src\n 12: ARG PASS: func higher_order_function_004_T(__taint_src string) {\n /sast-go/cases/completeness/single_app_tracing/function_call/higher_order_function/higher_order_function_004_T/higher_order_function_004_T.go\n AffectedNodeName: \n 24: CALL: \t__taint_sink(f(g, __taint_src, \"_\"))\n /sast-go/cases/completeness/single_app_tracing/function_call/higher_order_function/higher_order_function_004_T/higher_order_function_004_T.go\n AffectedNodeName: a\n 13: ARG PASS: \tf := func(g func(string, string) func() string, a string, b string) string {\n /sast-go/cases/completeness/single_app_tracing/function_call/higher_order_function/higher_order_function_004_T/higher_order_function_004_T.go\n AffectedNodeName: \n 14: CALL: \t\treturn g(a, b)()\n /sast-go/cases/completeness/single_app_tracing/function_call/higher_order_function/higher_order_function_004_T/higher_order_function_004_T.go\n AffectedNodeName: a\n 17: ARG PASS: \tg := func(a string, b string) func() string {\n /sast-go/cases/completeness/single_app_tracing/function_call/higher_order_function/higher_order_function_004_T/higher_order_function_004_T.go\n AffectedNodeName: [return value]\n 20: Return Value: \t\t\treturn a + b + c\n /sast-go/cases/completeness/single_app_tracing/function_call/higher_order_function/higher_order_function_004_T/higher_order_function_004_T.go\n AffectedNodeName: \n 14: CALL RETURN: \t\treturn g(a, b)()\n /sast-go/cases/completeness/single_app_tracing/function_call/higher_order_function/higher_order_function_004_T/higher_order_function_004_T.go\n AffectedNodeName: [return value]\n 14: Return Value: \t\treturn g(a, b)()\n /sast-go/cases/completeness/single_app_tracing/function_call/higher_order_function/higher_order_function_004_T/higher_order_function_004_T.go\n AffectedNodeName: \n 24: CALL RETURN: \t__taint_sink(f(g, __taint_src, \"_\"))\n /sast-go/cases/completeness/single_app_tracing/function_call/higher_order_function/higher_order_function_004_T/higher_order_function_004_T.go\n AffectedNodeName: __taint_sink\n 24: SINK: \t__taint_sink(f(g, __taint_src, \"_\"))\n==========================================================\n #Total-findings:1\n==========================================================","/benchmarks/sast-go/cases/completeness/single_app_tracing/function_call/higher_order_function/higher_order_function_005_F/higher_order_function_005_F":"======================== Findings ========================\nNo findings!\n==========================================================","/benchmarks/sast-go/cases/completeness/single_app_tracing/function_call/higher_order_function/higher_order_function_006_T/higher_order_function_006_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/sast-go/cases/completeness/single_app_tracing/function_call/higher_order_function/higher_order_function_006_T/higher_order_function_006_T.go\nLine 13: __taint_sink(f(g, u, __taint_src, \"_\")())\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/sast-go/cases/completeness/single_app_tracing/function_call/higher_order_function/higher_order_function_006_T/higher_order_function_006_T.go\",\"functionName\":\"main\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /sast-go/cases/completeness/single_app_tracing/function_call/higher_order_function/higher_order_function_006_T/higher_order_function_006_T.go\n AffectedNodeName: __taint_src\n 35: SOURCE: higher_order_function_006_T(__taint_src)\n /sast-go/cases/completeness/single_app_tracing/function_call/higher_order_function/higher_order_function_006_T/higher_order_function_006_T.go\n AffectedNodeName: higher_order_function_006_T\n 35: CALL: higher_order_function_006_T(__taint_src)\n /sast-go/cases/completeness/single_app_tracing/function_call/higher_order_function/higher_order_function_006_T/higher_order_function_006_T.go\n AffectedNodeName: __taint_src\n 12: ARG PASS: func higher_order_function_006_T(__taint_src interface{}) {\n /sast-go/cases/completeness/single_app_tracing/function_call/higher_order_function/higher_order_function_006_T/higher_order_function_006_T.go\n AffectedNodeName: f\n 13: CALL: \t__taint_sink(f(g, u, __taint_src, \"_\")())\n /sast-go/cases/completeness/single_app_tracing/function_call/higher_order_function/higher_order_function_006_T/higher_order_function_006_T.go\n AffectedNodeName: \n 13: CALL RETURN: \t__taint_sink(f(g, u, __taint_src, \"_\")())\n /sast-go/cases/completeness/single_app_tracing/function_call/higher_order_function/higher_order_function_006_T/higher_order_function_006_T.go\n AffectedNodeName: __taint_sink\n 13: SINK: \t__taint_sink(f(g, u, __taint_src, \"_\")())\n==========================================================\n #Total-findings:1\n==========================================================","/benchmarks/sast-go/cases/completeness/single_app_tracing/function_call/higher_order_function/higher_order_function_007_F/higher_order_function_007_F":"======================== Findings ========================\nNo findings!\n==========================================================","/benchmarks/sast-go/cases/completeness/single_app_tracing/function_call/higher_order_function/higher_order_function_008_T/higher_order_function_008_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/sast-go/cases/completeness/single_app_tracing/function_call/higher_order_function/higher_order_function_008_T/higher_order_function_008_T.go\nLine 16: __taint_sink(result)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/sast-go/cases/completeness/single_app_tracing/function_call/higher_order_function/higher_order_function_008_T/higher_order_function_008_T.go\",\"functionName\":\"main\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /sast-go/cases/completeness/single_app_tracing/function_call/higher_order_function/higher_order_function_008_T/higher_order_function_008_T.go\n AffectedNodeName: __taint_src\n 27: SOURCE: higher_order_function_008_T(__taint_src)\n /sast-go/cases/completeness/single_app_tracing/function_call/higher_order_function/higher_order_function_008_T/higher_order_function_008_T.go\n AffectedNodeName: higher_order_function_008_T\n 27: CALL: higher_order_function_008_T(__taint_src)\n /sast-go/cases/completeness/single_app_tracing/function_call/higher_order_function/higher_order_function_008_T/higher_order_function_008_T.go\n AffectedNodeName: __taint_src\n 12: ARG PASS: func higher_order_function_008_T(__taint_src string) {\n /sast-go/cases/completeness/single_app_tracing/function_call/higher_order_function/higher_order_function_008_T/higher_order_function_008_T.go\n AffectedNodeName: higher_order_function_008_Function\n 13: CALL: \tresult := higher_order_function_008_Function(func(a string, b string) string {\n 14: CALL: \t\treturn a + b\n 15: CALL: \t}, __taint_src)\n /sast-go/cases/completeness/single_app_tracing/function_call/higher_order_function/higher_order_function_008_T/higher_order_function_008_T.go\n AffectedNodeName: a\n 13: ARG PASS: \tresult := higher_order_function_008_Function(func(a string, b string) string {\n /sast-go/cases/completeness/single_app_tracing/function_call/higher_order_function/higher_order_function_008_T/higher_order_function_008_T.go\n AffectedNodeName: [return value]\n 14: Return Value: \t\treturn a + b\n /sast-go/cases/completeness/single_app_tracing/function_call/higher_order_function/higher_order_function_008_T/higher_order_function_008_T.go\n AffectedNodeName: higher_order_function_008_Function\n 13: CALL RETURN: \tresult := higher_order_function_008_Function(func(a string, b string) string {\n 14: CALL RETURN: \t\treturn a + b\n 15: CALL RETURN: \t}, __taint_src)\n /sast-go/cases/completeness/single_app_tracing/function_call/higher_order_function/higher_order_function_008_T/higher_order_function_008_T.go\n AffectedNodeName: result\n 13: Var Pass: \tresult := higher_order_function_008_Function(func(a string, b string) string {\n 14: Var Pass: \t\treturn a + b\n 15: Var Pass: \t}, __taint_src)\n /sast-go/cases/completeness/single_app_tracing/function_call/higher_order_function/higher_order_function_008_T/higher_order_function_008_T.go\n AffectedNodeName: __taint_sink\n 16: SINK: \t__taint_sink(result)\n==========================================================\n #Total-findings:1\n==========================================================","/benchmarks/sast-go/cases/completeness/single_app_tracing/function_call/library_function/arg_arg_001_T/arg_arg_001_T":"======================== Findings ========================\nNo findings!\n==========================================================","/benchmarks/sast-go/cases/completeness/single_app_tracing/function_call/library_function/arg_arg_002_F/arg_arg_002_F":"======================== Findings ========================\nNo findings!\n==========================================================","/benchmarks/sast-go/cases/completeness/single_app_tracing/function_call/library_function/arg_return_001_T/arg_return_001_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/sast-go/cases/completeness/single_app_tracing/function_call/library_function/arg_return_001_T/arg_return_001_T.go\nLine 16: __taint_sink(result)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/sast-go/cases/completeness/single_app_tracing/function_call/library_function/arg_return_001_T/arg_return_001_T.go\",\"functionName\":\"main\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /sast-go/cases/completeness/single_app_tracing/function_call/library_function/arg_return_001_T/arg_return_001_T.go\n AffectedNodeName: __taint_src\n 28: SOURCE: arg_return_001_T(__taint_src)\n /sast-go/cases/completeness/single_app_tracing/function_call/library_function/arg_return_001_T/arg_return_001_T.go\n AffectedNodeName: arg_return_001_T\n 28: CALL: arg_return_001_T(__taint_src)\n /sast-go/cases/completeness/single_app_tracing/function_call/library_function/arg_return_001_T/arg_return_001_T.go\n AffectedNodeName: __taint_src\n 12: ARG PASS: func arg_return_001_T(__taint_src string) {\n /sast-go/cases/completeness/single_app_tracing/function_call/library_function/arg_return_001_T/arg_return_001_T.go\n AffectedNodeName: taintedData\n 13: Var Pass: \ttaintedData := __taint_src\n /sast-go/cases/completeness/single_app_tracing/function_call/library_function/arg_return_001_T/arg_return_001_T.go\n AffectedNodeName: appendTaint\n 15: CALL: \tresult := appendTaint(sList, taintedData)\n /sast-go/cases/completeness/single_app_tracing/function_call/library_function/arg_return_001_T/arg_return_001_T.go\n AffectedNodeName: appendTaint\n 15: CALL RETURN: \tresult := appendTaint(sList, taintedData)\n /sast-go/cases/completeness/single_app_tracing/function_call/library_function/arg_return_001_T/arg_return_001_T.go\n AffectedNodeName: result\n 15: Var Pass: \tresult := appendTaint(sList, taintedData)\n /sast-go/cases/completeness/single_app_tracing/function_call/library_function/arg_return_001_T/arg_return_001_T.go\n AffectedNodeName: __taint_sink\n 16: SINK: \t__taint_sink(result)\n==========================================================\n #Total-findings:1\n==========================================================","/benchmarks/sast-go/cases/completeness/single_app_tracing/function_call/library_function/arg_return_002_F/arg_return_002_F":"======================== Findings ========================\nNo findings!\n==========================================================","/benchmarks/sast-go/cases/completeness/single_app_tracing/function_call/library_function/arg_return_003_T/arg_return_003_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/sast-go/cases/completeness/single_app_tracing/function_call/library_function/arg_return_003_T/arg_return_003_T.go\nLine 17: __taint_sink(result)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/sast-go/cases/completeness/single_app_tracing/function_call/library_function/arg_return_003_T/arg_return_003_T.go\",\"functionName\":\"main\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /sast-go/cases/completeness/single_app_tracing/function_call/library_function/arg_return_003_T/arg_return_003_T.go\n AffectedNodeName: __taint_src\n 29: SOURCE: arg_return_003_T(__taint_src)\n /sast-go/cases/completeness/single_app_tracing/function_call/library_function/arg_return_003_T/arg_return_003_T.go\n AffectedNodeName: arg_return_003_T\n 29: CALL: arg_return_003_T(__taint_src)\n /sast-go/cases/completeness/single_app_tracing/function_call/library_function/arg_return_003_T/arg_return_003_T.go\n AffectedNodeName: __taint_src\n 14: ARG PASS: func arg_return_003_T(__taint_src int) {\n /sast-go/cases/completeness/single_app_tracing/function_call/library_function/arg_return_003_T/arg_return_003_T.go\n AffectedNodeName: taintedData\n 15: Var Pass: \ttaintedData := __taint_src\n /sast-go/cases/completeness/single_app_tracing/function_call/library_function/arg_return_003_T/arg_return_003_T.go\n AffectedNodeName: itoaTaint\n 16: CALL: \tresult := itoaTaint(taintedData)\n /sast-go/cases/completeness/single_app_tracing/function_call/library_function/arg_return_003_T/arg_return_003_T.go\n AffectedNodeName: itoaTaint\n 16: CALL RETURN: \tresult := itoaTaint(taintedData)\n /sast-go/cases/completeness/single_app_tracing/function_call/library_function/arg_return_003_T/arg_return_003_T.go\n AffectedNodeName: result\n 16: Var Pass: \tresult := itoaTaint(taintedData)\n /sast-go/cases/completeness/single_app_tracing/function_call/library_function/arg_return_003_T/arg_return_003_T.go\n AffectedNodeName: __taint_sink\n 17: SINK: \t__taint_sink(result)\n==========================================================\n #Total-findings:1\n==========================================================","/benchmarks/sast-go/cases/completeness/single_app_tracing/function_call/library_function/arg_return_004_F/arg_return_004_F":"======================== Findings ========================\nNo findings!\n==========================================================","/benchmarks/sast-go/cases/completeness/single_app_tracing/function_call/library_function/this_return_001_T/this_return_001_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/sast-go/cases/completeness/single_app_tracing/function_call/library_function/this_return_001_T/this_return_001_T.go\nLine 15: __taint_sink(result)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/sast-go/cases/completeness/single_app_tracing/function_call/library_function/this_return_001_T/this_return_001_T.go\",\"functionName\":\"main\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /sast-go/cases/completeness/single_app_tracing/function_call/library_function/this_return_001_T/this_return_001_T.go\n AffectedNodeName: __taint_src\n 27: SOURCE: this_return_001_T(__taint_src)\n /sast-go/cases/completeness/single_app_tracing/function_call/library_function/this_return_001_T/this_return_001_T.go\n AffectedNodeName: this_return_001_T\n 27: CALL: this_return_001_T(__taint_src)\n /sast-go/cases/completeness/single_app_tracing/function_call/library_function/this_return_001_T/this_return_001_T.go\n AffectedNodeName: __taint_src\n 12: ARG PASS: func this_return_001_T(__taint_src string) {\n /sast-go/cases/completeness/single_app_tracing/function_call/library_function/this_return_001_T/this_return_001_T.go\n AffectedNodeName: taintedData\n 13: Var Pass: \ttaintedData := __taint_src\n /sast-go/cases/completeness/single_app_tracing/function_call/library_function/this_return_001_T/this_return_001_T.go\n AffectedNodeName: taintToString\n 14: CALL: \tresult := taintToString(taintedData)\n /sast-go/cases/completeness/single_app_tracing/function_call/library_function/this_return_001_T/this_return_001_T.go\n AffectedNodeName: taintToString\n 14: CALL RETURN: \tresult := taintToString(taintedData)\n /sast-go/cases/completeness/single_app_tracing/function_call/library_function/this_return_001_T/this_return_001_T.go\n AffectedNodeName: result\n 14: Var Pass: \tresult := taintToString(taintedData)\n /sast-go/cases/completeness/single_app_tracing/function_call/library_function/this_return_001_T/this_return_001_T.go\n AffectedNodeName: __taint_sink\n 15: SINK: \t__taint_sink(result)\n==========================================================\n #Total-findings:1\n==========================================================","/benchmarks/sast-go/cases/completeness/single_app_tracing/function_call/library_function/this_return_002_F/this_return_002_F":"======================== Findings ========================\nNo findings!\n==========================================================","/benchmarks/sast-go/cases/completeness/single_app_tracing/function_call/override/polymorphism_override_001_T/polymorphism_override_001_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/sast-go/cases/completeness/single_app_tracing/function_call/override/polymorphism_override_001_T/polymorphism_override_001_T.go\nLine 14: __taint_sink(sub.call(__taint_src))\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/sast-go/cases/completeness/single_app_tracing/function_call/override/polymorphism_override_001_T/polymorphism_override_001_T.go\",\"functionName\":\"main\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /sast-go/cases/completeness/single_app_tracing/function_call/override/polymorphism_override_001_T/polymorphism_override_001_T.go\n AffectedNodeName: __taint_src\n 37: SOURCE: polymorphism_override_001_T(__taint_src)\n /sast-go/cases/completeness/single_app_tracing/function_call/override/polymorphism_override_001_T/polymorphism_override_001_T.go\n AffectedNodeName: polymorphism_override_001_T\n 37: CALL: polymorphism_override_001_T(__taint_src)\n /sast-go/cases/completeness/single_app_tracing/function_call/override/polymorphism_override_001_T/polymorphism_override_001_T.go\n AffectedNodeName: __taint_src\n 11: ARG PASS: func polymorphism_override_001_T(__taint_src interface{}) {\n /sast-go/cases/completeness/single_app_tracing/function_call/override/polymorphism_override_001_T/polymorphism_override_001_T.go\n AffectedNodeName: call\n 14: CALL: \t__taint_sink(sub.call(__taint_src))\n /sast-go/cases/completeness/single_app_tracing/function_call/override/polymorphism_override_001_T/polymorphism_override_001_T.go\n AffectedNodeName: call\n 14: CALL RETURN: \t__taint_sink(sub.call(__taint_src))\n /sast-go/cases/completeness/single_app_tracing/function_call/override/polymorphism_override_001_T/polymorphism_override_001_T.go\n AffectedNodeName: __taint_sink\n 14: SINK: \t__taint_sink(sub.call(__taint_src))\n==========================================================\n #Total-findings:1\n==========================================================","/benchmarks/sast-go/cases/completeness/single_app_tracing/function_call/override/polymorphism_override_002_F/polymorphism_override_002_F":"======================== Findings ========================\nNo findings!\n==========================================================","/benchmarks/sast-go/cases/completeness/single_app_tracing/function_call/override/polymorphism_override_003_T/polymorphism_override_003_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/sast-go/cases/completeness/single_app_tracing/function_call/override/polymorphism_override_003_T/polymorphism_override_003_T.go\nLine 15: __taint_sink(student.Run())\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/sast-go/cases/completeness/single_app_tracing/function_call/override/polymorphism_override_003_T/polymorphism_override_003_T.go\",\"functionName\":\"main\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /sast-go/cases/completeness/single_app_tracing/function_call/override/polymorphism_override_003_T/polymorphism_override_003_T.go\n AffectedNodeName: __taint_src\n 46: SOURCE: polymorphism_override_003_T(__taint_src)\n /sast-go/cases/completeness/single_app_tracing/function_call/override/polymorphism_override_003_T/polymorphism_override_003_T.go\n AffectedNodeName: polymorphism_override_003_T\n 46: CALL: polymorphism_override_003_T(__taint_src)\n /sast-go/cases/completeness/single_app_tracing/function_call/override/polymorphism_override_003_T/polymorphism_override_003_T.go\n AffectedNodeName: __taint_src\n 11: ARG PASS: func polymorphism_override_003_T(__taint_src string) {\n /sast-go/cases/completeness/single_app_tracing/function_call/override/polymorphism_override_003_T/polymorphism_override_003_T.go\n AffectedNodeName: student\n 12: Var Pass: \tvar student Person = &Student{Name: __taint_src, Age: 20, GPA: 3.8}\n /sast-go/cases/completeness/single_app_tracing/function_call/override/polymorphism_override_003_T/polymorphism_override_003_T.go\n AffectedNodeName: Run\n 15: CALL: \t__taint_sink(student.Run())\n /sast-go/cases/completeness/single_app_tracing/function_call/override/polymorphism_override_003_T/polymorphism_override_003_T.go\n AffectedNodeName: student\n 15: ARG PASS: \t__taint_sink(student.Run())\n /sast-go/cases/completeness/single_app_tracing/function_call/override/polymorphism_override_003_T/polymorphism_override_003_T.go\n AffectedNodeName: Run\n 15: CALL: \t__taint_sink(student.Run())\n /sast-go/cases/completeness/single_app_tracing/function_call/override/polymorphism_override_003_T/polymorphism_override_003_T.go\n AffectedNodeName: student\n 15: ARG PASS: \t__taint_sink(student.Run())\n /sast-go/cases/completeness/single_app_tracing/function_call/override/polymorphism_override_003_T/polymorphism_override_003_T.go\n AffectedNodeName: Run\n 15: CALL RETURN: \t__taint_sink(student.Run())\n /sast-go/cases/completeness/single_app_tracing/function_call/override/polymorphism_override_003_T/polymorphism_override_003_T.go\n AffectedNodeName: __taint_sink\n 15: SINK: \t__taint_sink(student.Run())\n==========================================================\n #Total-findings:1\n==========================================================","/benchmarks/sast-go/cases/completeness/single_app_tracing/function_call/override/polymorphism_override_004_F/polymorphism_override_004_F":"======================== Findings ========================\nNo findings!\n==========================================================","/benchmarks/sast-go/cases/completeness/single_app_tracing/function_call/return_value_passing/multiple_return_005_F/multiple_return_005_F":"======================== Findings ========================\nNo findings!\n==========================================================","/benchmarks/sast-go/cases/completeness/single_app_tracing/function_call/return_value_passing/multiple_return_006_T/multiple_return_006_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/sast-go/cases/completeness/single_app_tracing/function_call/return_value_passing/multiple_return_006_T/multiple_return_006_T.go\nLine 17: __taint_sink(ret1)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/sast-go/cases/completeness/single_app_tracing/function_call/return_value_passing/multiple_return_006_T/multiple_return_006_T.go\",\"functionName\":\"main\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /sast-go/cases/completeness/single_app_tracing/function_call/return_value_passing/multiple_return_006_T/multiple_return_006_T.go\n AffectedNodeName: __taint_src\n 27: SOURCE: multiple_return_006_T(__taint_src)\n /sast-go/cases/completeness/single_app_tracing/function_call/return_value_passing/multiple_return_006_T/multiple_return_006_T.go\n AffectedNodeName: multiple_return_006_T\n 27: CALL: multiple_return_006_T(__taint_src)\n /sast-go/cases/completeness/single_app_tracing/function_call/return_value_passing/multiple_return_006_T/multiple_return_006_T.go\n AffectedNodeName: __taint_src\n 12: ARG PASS: func multiple_return_006_T(__taint_src interface{}) {\n /sast-go/cases/completeness/single_app_tracing/function_call/return_value_passing/multiple_return_006_T/multiple_return_006_T.go\n AffectedNodeName: processData\n 15: CALL: \tret1, ret2 := processData(__taint_src, a)\n /sast-go/cases/completeness/single_app_tracing/function_call/return_value_passing/multiple_return_006_T/multiple_return_006_T.go\n AffectedNodeName: processData\n 15: CALL RETURN: \tret1, ret2 := processData(__taint_src, a)\n /sast-go/cases/completeness/single_app_tracing/function_call/return_value_passing/multiple_return_006_T/multiple_return_006_T.go\n 15: Var Pass: \tret1, ret2 := processData(__taint_src, a)\n /sast-go/cases/completeness/single_app_tracing/function_call/return_value_passing/multiple_return_006_T/multiple_return_006_T.go\n AffectedNodeName: __taint_sink\n 17: SINK: \t__taint_sink(ret1)\n==========================================================\n #Total-findings:1\n==========================================================","/benchmarks/sast-go/cases/completeness/single_app_tracing/function_call/return_value_passing/named_return_003_F/named_return_003_F":"======================== Findings ========================\nNo findings!\n==========================================================","/benchmarks/sast-go/cases/completeness/single_app_tracing/function_call/return_value_passing/named_return_004_T/named_return_004_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/sast-go/cases/completeness/single_app_tracing/function_call/return_value_passing/named_return_004_T/named_return_004_T.go\nLine 16: __taint_sink(ret)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/sast-go/cases/completeness/single_app_tracing/function_call/return_value_passing/named_return_004_T/named_return_004_T.go\",\"functionName\":\"main\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /sast-go/cases/completeness/single_app_tracing/function_call/return_value_passing/named_return_004_T/named_return_004_T.go\n AffectedNodeName: __taint_src\n 27: SOURCE: named_return_004_T(__taint_src)\n /sast-go/cases/completeness/single_app_tracing/function_call/return_value_passing/named_return_004_T/named_return_004_T.go\n AffectedNodeName: named_return_004_T\n 27: CALL: named_return_004_T(__taint_src)\n /sast-go/cases/completeness/single_app_tracing/function_call/return_value_passing/named_return_004_T/named_return_004_T.go\n AffectedNodeName: __taint_src\n 12: ARG PASS: func named_return_004_T(__taint_src interface{}) {\n /sast-go/cases/completeness/single_app_tracing/function_call/return_value_passing/named_return_004_T/named_return_004_T.go\n AffectedNodeName: processData\n 15: CALL: \tret := processData(__taint_src, a)\n /sast-go/cases/completeness/single_app_tracing/function_call/return_value_passing/named_return_004_T/named_return_004_T.go\n AffectedNodeName: processData\n 15: CALL RETURN: \tret := processData(__taint_src, a)\n /sast-go/cases/completeness/single_app_tracing/function_call/return_value_passing/named_return_004_T/named_return_004_T.go\n AffectedNodeName: ret\n 15: Var Pass: \tret := processData(__taint_src, a)\n /sast-go/cases/completeness/single_app_tracing/function_call/return_value_passing/named_return_004_T/named_return_004_T.go\n AffectedNodeName: __taint_sink\n 16: SINK: \t__taint_sink(ret)\n==========================================================\n #Total-findings:1\n==========================================================","/benchmarks/sast-go/cases/completeness/single_app_tracing/function_call/return_value_passing/return_value_passing_003_F/return_value_passing_003_F":"======================== Findings ========================\nNo findings!\n==========================================================","/benchmarks/sast-go/cases/completeness/single_app_tracing/function_call/return_value_passing/return_value_passing_004_T/return_value_passing_004_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/sast-go/cases/completeness/single_app_tracing/function_call/return_value_passing/return_value_passing_004_T/return_value_passing_004_T.go\nLine 14: __taint_sink(data)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/sast-go/cases/completeness/single_app_tracing/function_call/return_value_passing/return_value_passing_004_T/return_value_passing_004_T.go\",\"functionName\":\"main\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /sast-go/cases/completeness/single_app_tracing/function_call/return_value_passing/return_value_passing_004_T/return_value_passing_004_T.go\n AffectedNodeName: __taint_src\n 25: SOURCE: return_value_passing_004_T(__taint_src)\n /sast-go/cases/completeness/single_app_tracing/function_call/return_value_passing/return_value_passing_004_T/return_value_passing_004_T.go\n AffectedNodeName: return_value_passing_004_T\n 25: CALL: return_value_passing_004_T(__taint_src)\n /sast-go/cases/completeness/single_app_tracing/function_call/return_value_passing/return_value_passing_004_T/return_value_passing_004_T.go\n AffectedNodeName: __taint_src\n 12: ARG PASS: func return_value_passing_004_T(__taint_src string) {\n /sast-go/cases/completeness/single_app_tracing/function_call/return_value_passing/return_value_passing_004_T/return_value_passing_004_T.go\n AffectedNodeName: process\n 13: CALL: \tdata := process(__taint_src)\n /sast-go/cases/completeness/single_app_tracing/function_call/return_value_passing/return_value_passing_004_T/return_value_passing_004_T.go\n AffectedNodeName: process\n 13: CALL RETURN: \tdata := process(__taint_src)\n /sast-go/cases/completeness/single_app_tracing/function_call/return_value_passing/return_value_passing_004_T/return_value_passing_004_T.go\n AffectedNodeName: data\n 13: Var Pass: \tdata := process(__taint_src)\n /sast-go/cases/completeness/single_app_tracing/function_call/return_value_passing/return_value_passing_004_T/return_value_passing_004_T.go\n AffectedNodeName: __taint_sink\n 14: SINK: \t__taint_sink(data)\n==========================================================\n #Total-findings:1\n==========================================================","/benchmarks/sast-go/cases/completeness/single_app_tracing/interface_class/interface_implementation/interface_class_001_c_T/interface_class_001_c_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/sast-go/cases/completeness/single_app_tracing/interface_class/interface_implementation/interface_class_001_c_T/interface_class_001_c_T.go\nLine 20: __taint_sink(result)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/sast-go/cases/completeness/single_app_tracing/interface_class/interface_implementation/interface_class_001_c_T/interface_class_001_c_T.go\",\"functionName\":\"main\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /sast-go/cases/completeness/single_app_tracing/interface_class/interface_implementation/interface_class_001_c_T/interface_class_001_c_T.go\n AffectedNodeName: __taint_src\n 58: SOURCE: interface_class_001_c_T(__taint_src)\n /sast-go/cases/completeness/single_app_tracing/interface_class/interface_implementation/interface_class_001_c_T/interface_class_001_c_T.go\n AffectedNodeName: interface_class_001_c_T\n 58: CALL: interface_class_001_c_T(__taint_src)\n /sast-go/cases/completeness/single_app_tracing/interface_class/interface_implementation/interface_class_001_c_T/interface_class_001_c_T.go\n AffectedNodeName: __taint_src\n 11: ARG PASS: func interface_class_001_c_T(__taint_src string) {\n /sast-go/cases/completeness/single_app_tracing/interface_class/interface_implementation/interface_class_001_c_T/interface_class_001_c_T.go\n AffectedNodeName: GetTest\n 19: CALL: \tresult, _ := testAPI.GetTest(__taint_src)\n /sast-go/cases/completeness/single_app_tracing/interface_class/interface_implementation/interface_class_001_c_T/interface_class_001_c_T.go\n AffectedNodeName: GetTest\n 19: CALL RETURN: \tresult, _ := testAPI.GetTest(__taint_src)\n /sast-go/cases/completeness/single_app_tracing/interface_class/interface_implementation/interface_class_001_c_T/interface_class_001_c_T.go\n 19: Var Pass: \tresult, _ := testAPI.GetTest(__taint_src)\n /sast-go/cases/completeness/single_app_tracing/interface_class/interface_implementation/interface_class_001_c_T/interface_class_001_c_T.go\n AffectedNodeName: __taint_sink\n 20: SINK: \t__taint_sink(result)\n==========================================================\n #Total-findings:1\n==========================================================","/benchmarks/sast-go/cases/completeness/single_app_tracing/interface_class/interface_implementation/interface_class_002_c_F/interface_class_002_c_F":"======================== Findings ========================\nNo findings!\n=========================================================="} \ No newline at end of file diff --git a/test/go/test-go-benchmark.ts b/test/go/test-go-benchmark.ts index 9ee8c438..3e3fa338 100644 --- a/test/go/test-go-benchmark.ts +++ b/test/go/test-go-benchmark.ts @@ -158,7 +158,7 @@ function runSingleTest(casePath: string, actualResMap: Map, outputS config.ruleConfigFile = __dirname + '/rule_config.json' config.checkerIds = ['taint_flow_test'] - config.uastSDKPath = path.join(__dirname, '../../deps/uast4go/uast4go') + config.uastSDKPath = path.join(__dirname, '../../deps') config.language = 'golang' config.maindirPrefix = __dirname + '/benchmarks' diff --git a/test/java/expect/sast-java-expect.result b/test/java/expect/sast-java-expect.result index c9e1efe7..95390b87 100644 --- a/test/java/expect/sast-java-expect.result +++ b/test/java/expect/sast-java-expect.result @@ -52,6 +52,28 @@ Trace: ------------- 3: taint_flow_java_input_inner------------- Description:Java污点分析checker,不会使用CallGraph边界制作entrypoint,蚂蚁内部使用 +File:/src/main/java/com/sast/astbenchmark/common/utils/CmdUtil.java +Line 7: Runtime.getRuntime().exec(cmd) +SINK RULE:Runtime.getRuntime().exec +SINK Attribute:JavaCommandExec +entrypoint: +{"filePath":"/src/main/java/com/sast/astbenchmark/case_language_maturity/completeness/dynamic_tracing/dynamic_call/Expression_Reflection_001_T.java","functionName":"aTaintCase0134","attribute":"HTTP","type":"functionCall"} +Trace: + /src/main/java/com/sast/astbenchmark/case_language_maturity/completeness/dynamic_tracing/dynamic_call/Expression_Reflection_001_T.java + AffectedNodeName: cmd + 24: SOURCE: public Map aTaintCase0134(@PathVariable String cmd) { + /src/main/java/com/sast/astbenchmark/case_language_maturity/completeness/dynamic_tracing/dynamic_call/Expression_Reflection_001_T.java + AffectedNodeName: run + 35: CALL: method.invoke(null, cmd); + /src/main/java/com/sast/astbenchmark/common/utils/CmdUtil.java + AffectedNodeName: cmd + 5: ARG PASS: public static void run(String cmd) { + /src/main/java/com/sast/astbenchmark/common/utils/CmdUtil.java + AffectedNodeName: Runtime.getRuntime().exec + 7: SINK: Runtime.getRuntime().exec(cmd); + +------------- 4: taint_flow_java_input_inner------------- +Description:Java污点分析checker,不会使用CallGraph边界制作entrypoint,蚂蚁内部使用 File:/src/main/java/com/sast/astbenchmark/case_language_maturity/completeness/single_app_tracing/alias/FieldUnAlias_002_T.java Line 34: Runtime.getRuntime().exec(b2.attr.b) SINK RULE:Runtime.getRuntime().exec @@ -63,25 +85,16 @@ Trace: AffectedNodeName: cmd 24: SOURCE: public Map testcase(@RequestParam String cmd) { /src/main/java/com/sast/astbenchmark/case_language_maturity/completeness/single_app_tracing/alias/FieldUnAlias_002_T.java - AffectedNodeName: [[b1.attr].b] + AffectedNodeName: b1.attr.b 30: Var Pass: b1.attr.b = cmd; /src/main/java/com/sast/astbenchmark/case_language_maturity/completeness/single_app_tracing/alias/FieldUnAlias_002_T.java AffectedNodeName: doUnalias 31: CALL: Invoke.doUnalias(b1); - /src/main/java/com/sast/astbenchmark/model/alias/Invoke.java - AffectedNodeName: b - 50: ARG PASS: public static void doUnalias(B b) { - /src/main/java/com/sast/astbenchmark/model/alias/Invoke.java - AffectedNodeName: setAttr - 51: CALL: b.setAttr(new A()); - /src/main/java/com/sast/astbenchmark/model/alias/Invoke.java - AffectedNodeName: b - 51: ARG PASS: b.setAttr(new A()); /src/main/java/com/sast/astbenchmark/case_language_maturity/completeness/single_app_tracing/alias/FieldUnAlias_002_T.java AffectedNodeName: Runtime.getRuntime().exec 34: SINK: Runtime.getRuntime().exec(b2.attr.b); -------------- 4: taint_flow_java_input_inner------------- +------------- 5: taint_flow_java_input_inner------------- Description:Java污点分析checker,不会使用CallGraph边界制作entrypoint,蚂蚁内部使用 File:/src/main/java/com/sast/astbenchmark/case_language_maturity/completeness/single_app_tracing/alias/FieldUnAlias_003_T.java Line 36: Runtime.getRuntime().exec(b1.attr.b) @@ -94,40 +107,19 @@ Trace: AffectedNodeName: cmd 26: SOURCE: public Map testcase(@RequestParam String cmd) { /src/main/java/com/sast/astbenchmark/case_language_maturity/completeness/single_app_tracing/alias/FieldUnAlias_003_T.java - AffectedNodeName: [[b1.attr].b] + AffectedNodeName: b1.attr.b 30: Var Pass: b1.attr.b = cmd; /src/main/java/com/sast/astbenchmark/case_language_maturity/completeness/single_app_tracing/alias/FieldUnAlias_003_T.java AffectedNodeName: alias 32: CALL: Invoke.alias(b1, b2); - /src/main/java/com/sast/astbenchmark/model/alias/Invoke.java - AffectedNodeName: b1 - 42: ARG PASS: public static void alias(B b1, B b2) { - /src/main/java/com/sast/astbenchmark/model/alias/Invoke.java - AffectedNodeName: setAttr - 43: CALL: b2.setAttr(b1.attr); - /src/main/java/com/sast/astbenchmark/model/alias/B.java - AffectedNodeName: attr - 10: ARG PASS: public void setAttr(A attr) { - /src/main/java/com/sast/astbenchmark/model/alias/B.java - AffectedNodeName: [this.attr] - 11: Var Pass: this.attr = attr; /src/main/java/com/sast/astbenchmark/case_language_maturity/completeness/single_app_tracing/alias/FieldUnAlias_003_T.java AffectedNodeName: doUnalias 33: CALL: Invoke.doUnalias(b2); - /src/main/java/com/sast/astbenchmark/model/alias/Invoke.java - AffectedNodeName: b - 50: ARG PASS: public static void doUnalias(B b) { - /src/main/java/com/sast/astbenchmark/model/alias/Invoke.java - AffectedNodeName: setAttr - 51: CALL: b.setAttr(new A()); - /src/main/java/com/sast/astbenchmark/model/alias/Invoke.java - AffectedNodeName: b - 51: ARG PASS: b.setAttr(new A()); /src/main/java/com/sast/astbenchmark/case_language_maturity/completeness/single_app_tracing/alias/FieldUnAlias_003_T.java AffectedNodeName: Runtime.getRuntime().exec 36: SINK: Runtime.getRuntime().exec(b1.attr.b); -------------- 5: taint_flow_java_input_inner------------- +------------- 6: taint_flow_java_input_inner------------- Description:Java污点分析checker,不会使用CallGraph边界制作entrypoint,蚂蚁内部使用 File:/src/main/java/com/sast/astbenchmark/case_language_maturity/completeness/single_app_tracing/alias/HeapOverwriteAlias_001_T.java Line 31: Runtime.getRuntime().exec(a1.b) @@ -140,13 +132,13 @@ Trace: AffectedNodeName: cmd 23: SOURCE: public Map testcase(@RequestParam String cmd) { /src/main/java/com/sast/astbenchmark/case_language_maturity/completeness/single_app_tracing/alias/HeapOverwriteAlias_001_T.java - AffectedNodeName: [a1.b] + AffectedNodeName: a1.b 28: Var Pass: a1.b = cmd; /src/main/java/com/sast/astbenchmark/case_language_maturity/completeness/single_app_tracing/alias/HeapOverwriteAlias_001_T.java AffectedNodeName: Runtime.getRuntime().exec 31: SINK: Runtime.getRuntime().exec(a1.b); -------------- 6: taint_flow_java_input_inner------------- +------------- 7: taint_flow_java_input_inner------------- Description:Java污点分析checker,不会使用CallGraph边界制作entrypoint,蚂蚁内部使用 File:/src/main/java/com/sast/astbenchmark/case_language_maturity/completeness/single_app_tracing/alias/HeapOverwriteAlias_003_T.java Line 30: Runtime.getRuntime().exec(a1.b) @@ -159,13 +151,13 @@ Trace: AffectedNodeName: cmd 23: SOURCE: public Map testcase(@RequestParam String cmd) { /src/main/java/com/sast/astbenchmark/case_language_maturity/completeness/single_app_tracing/alias/HeapOverwriteAlias_003_T.java - AffectedNodeName: [a1.b] + AffectedNodeName: a1.b 28: Var Pass: a1.b = cmd; /src/main/java/com/sast/astbenchmark/case_language_maturity/completeness/single_app_tracing/alias/HeapOverwriteAlias_003_T.java AffectedNodeName: Runtime.getRuntime().exec 30: SINK: Runtime.getRuntime().exec(a1.b); -------------- 7: taint_flow_java_input_inner------------- +------------- 8: taint_flow_java_input_inner------------- Description:Java污点分析checker,不会使用CallGraph边界制作entrypoint,蚂蚁内部使用 File:/src/main/java/com/sast/astbenchmark/case_language_maturity/completeness/single_app_tracing/alias/HeapPointsToSelfAlias_001_T.java Line 39: Runtime.getRuntime().exec(l1.data) @@ -178,13 +170,13 @@ Trace: AffectedNodeName: cmd 23: SOURCE: public Map testcase(@RequestParam String cmd) { /src/main/java/com/sast/astbenchmark/case_language_maturity/completeness/single_app_tracing/alias/HeapPointsToSelfAlias_001_T.java - AffectedNodeName: [cycle.data] + AffectedNodeName: cycle.data 38: Var Pass: cycle.data = cmd; /src/main/java/com/sast/astbenchmark/case_language_maturity/completeness/single_app_tracing/alias/HeapPointsToSelfAlias_001_T.java AffectedNodeName: Runtime.getRuntime().exec 39: SINK: Runtime.getRuntime().exec(l1.data); -------------- 8: taint_flow_java_input_inner------------- +------------- 9: taint_flow_java_input_inner------------- Description:Java污点分析checker,不会使用CallGraph边界制作entrypoint,蚂蚁内部使用 File:/src/main/java/com/sast/astbenchmark/case_language_maturity/completeness/single_app_tracing/alias/InnerClassAlias_001_T.java Line 35: Runtime.getRuntime().exec(s) @@ -199,21 +191,12 @@ Trace: /src/main/java/com/sast/astbenchmark/case_language_maturity/completeness/single_app_tracing/alias/InnerClassAlias_001_T.java AffectedNodeName: set 32: CALL: a.obj.set(cmd); - /src/main/java/com/sast/astbenchmark/model/alias/Inner1.java - AffectedNodeName: v - 8: ARG PASS: public void set(String v) { - /src/main/java/com/sast/astbenchmark/model/alias/Inner1.java - AffectedNodeName: data - 9: Var Pass: data = v; /src/main/java/com/sast/astbenchmark/case_language_maturity/completeness/single_app_tracing/alias/InnerClassAlias_001_T.java AffectedNodeName: get 33: CALL: String s = a.get(); // tainted /src/main/java/com/sast/astbenchmark/case_language_maturity/completeness/single_app_tracing/alias/InnerClassAlias_001_T.java AffectedNodeName: a 33: ARG PASS: String s = a.get(); // tainted - /src/main/java/com/sast/astbenchmark/model/alias/Inner1.java - AffectedNodeName: [return value] - 16: Return Value: return obj.data; /src/main/java/com/sast/astbenchmark/case_language_maturity/completeness/single_app_tracing/alias/InnerClassAlias_001_T.java AffectedNodeName: get 33: CALL RETURN: String s = a.get(); // tainted @@ -224,7 +207,7 @@ Trace: AffectedNodeName: Runtime.getRuntime().exec 35: SINK: Runtime.getRuntime().exec(s); -------------- 9: taint_flow_java_input_inner------------- +------------- 10: taint_flow_java_input_inner------------- Description:Java污点分析checker,不会使用CallGraph边界制作entrypoint,蚂蚁内部使用 File:/src/main/java/com/sast/astbenchmark/case_language_maturity/completeness/single_app_tracing/alias/InnerClassAlias_005_T.java Line 35: Runtime.getRuntime().exec(s) @@ -239,20 +222,12 @@ Trace: /src/main/java/com/sast/astbenchmark/case_language_maturity/completeness/single_app_tracing/alias/InnerClassAlias_005_T.java AffectedNodeName: set 32: CALL: a.obj.set(cmd); - /src/main/java/com/sast/astbenchmark/model/alias/Inner1b.java - AffectedNodeName: v - 8: ARG PASS: public void set(String v) { - /src/main/java/com/sast/astbenchmark/model/alias/Inner1b.java - AffectedNodeName: [obj.data] - 9: Var Pass: obj.data = v; /src/main/java/com/sast/astbenchmark/case_language_maturity/completeness/single_app_tracing/alias/InnerClassAlias_005_T.java AffectedNodeName: get 33: CALL: String s = a.obj.get(); // tainted /src/main/java/com/sast/astbenchmark/case_language_maturity/completeness/single_app_tracing/alias/InnerClassAlias_005_T.java + AffectedNodeName: a.obj 33: ARG PASS: String s = a.obj.get(); // tainted - /src/main/java/com/sast/astbenchmark/model/alias/Inner1b.java - AffectedNodeName: [return value] - 13: Return Value: return obj.data; /src/main/java/com/sast/astbenchmark/case_language_maturity/completeness/single_app_tracing/alias/InnerClassAlias_005_T.java AffectedNodeName: get 33: CALL RETURN: String s = a.obj.get(); // tainted @@ -263,7 +238,7 @@ Trace: AffectedNodeName: Runtime.getRuntime().exec 35: SINK: Runtime.getRuntime().exec(s); -------------- 10: taint_flow_java_input_inner------------- +------------- 11: taint_flow_java_input_inner------------- Description:Java污点分析checker,不会使用CallGraph边界制作entrypoint,蚂蚁内部使用 File:/src/main/java/com/sast/astbenchmark/case_language_maturity/completeness/single_app_tracing/alias/InnerClassAlias_006_T.java Line 35: Runtime.getRuntime().exec(s) @@ -278,15 +253,6 @@ Trace: /src/main/java/com/sast/astbenchmark/case_language_maturity/completeness/single_app_tracing/alias/InnerClassAlias_006_T.java AffectedNodeName: set 32: CALL: a.obj.set(cmd); - /src/main/java/com/sast/astbenchmark/model/alias/Inner1b.java - AffectedNodeName: v - 8: ARG PASS: public void set(String v) { - /src/main/java/com/sast/astbenchmark/model/alias/Inner1b.java - AffectedNodeName: [obj.data] - 9: Var Pass: obj.data = v; - /src/main/java/com/sast/astbenchmark/model/alias/Inner1b.java - AffectedNodeName: [return value] - 13: Return Value: return obj.data; /src/main/java/com/sast/astbenchmark/case_language_maturity/completeness/single_app_tracing/alias/InnerClassAlias_006_T.java AffectedNodeName: get 33: CALL RETURN: String s = b.obj.get(); // tainted @@ -297,7 +263,7 @@ Trace: AffectedNodeName: Runtime.getRuntime().exec 35: SINK: Runtime.getRuntime().exec(s); -------------- 11: taint_flow_java_input_inner------------- +------------- 12: taint_flow_java_input_inner------------- Description:Java污点分析checker,不会使用CallGraph边界制作entrypoint,蚂蚁内部使用 File:/src/main/java/com/sast/astbenchmark/case_language_maturity/completeness/single_app_tracing/alias/InnerClassAlias_007_T.java Line 35: Runtime.getRuntime().exec(s) @@ -312,21 +278,12 @@ Trace: /src/main/java/com/sast/astbenchmark/case_language_maturity/completeness/single_app_tracing/alias/InnerClassAlias_007_T.java AffectedNodeName: set 32: CALL: a.obj2.foo.set(cmd); - /src/main/java/com/sast/astbenchmark/model/alias/Inner3.java - AffectedNodeName: p - 15: ARG PASS: public void set(String p) { - /src/main/java/com/sast/astbenchmark/model/alias/Inner3.java - AffectedNodeName: data - 16: Var Pass: data = p; /src/main/java/com/sast/astbenchmark/case_language_maturity/completeness/single_app_tracing/alias/InnerClassAlias_007_T.java AffectedNodeName: get 33: CALL: String s = b.get(); // tainted /src/main/java/com/sast/astbenchmark/case_language_maturity/completeness/single_app_tracing/alias/InnerClassAlias_007_T.java AffectedNodeName: b 33: ARG PASS: String s = b.get(); // tainted - /src/main/java/com/sast/astbenchmark/model/alias/Inner3.java - AffectedNodeName: [return value] - 24: Return Value: return data; /src/main/java/com/sast/astbenchmark/case_language_maturity/completeness/single_app_tracing/alias/InnerClassAlias_007_T.java AffectedNodeName: get 33: CALL RETURN: String s = b.get(); // tainted @@ -337,7 +294,7 @@ Trace: AffectedNodeName: Runtime.getRuntime().exec 35: SINK: Runtime.getRuntime().exec(s); -------------- 12: taint_flow_java_input_inner------------- +------------- 13: taint_flow_java_input_inner------------- Description:Java污点分析checker,不会使用CallGraph边界制作entrypoint,蚂蚁内部使用 File:/src/main/java/com/sast/astbenchmark/case_language_maturity/completeness/single_app_tracing/alias/InnerClassAlias_009_T.java Line 36: Runtime.getRuntime().exec(inner.getParent()) @@ -350,11 +307,8 @@ Trace: AffectedNodeName: cmd 23: SOURCE: public Map testcase(@RequestParam String cmd) { /src/main/java/com/sast/astbenchmark/case_language_maturity/completeness/single_app_tracing/alias/InnerClassAlias_009_T.java - AffectedNodeName: [a.parentData] + AffectedNodeName: a.parentData 28: Var Pass: a.parentData = cmd; - /src/main/java/com/sast/astbenchmark/model/alias/Inner1b.java - AffectedNodeName: [return value] - 17: Return Value: return parentData; /src/main/java/com/sast/astbenchmark/case_language_maturity/completeness/single_app_tracing/alias/InnerClassAlias_009_T.java AffectedNodeName: getParent 36: CALL RETURN: Runtime.getRuntime().exec(inner.getParent()); @@ -362,7 +316,7 @@ Trace: AffectedNodeName: Runtime.getRuntime().exec 36: SINK: Runtime.getRuntime().exec(inner.getParent()); -------------- 13: taint_flow_java_input_inner------------- +------------- 14: taint_flow_java_input_inner------------- Description:Java污点分析checker,不会使用CallGraph边界制作entrypoint,蚂蚁内部使用 File:/src/main/java/com/sast/astbenchmark/case_language_maturity/completeness/single_app_tracing/alias/NullAlias_001_T.java Line 39: Runtime.getRuntime().exec(dc3.next.data) @@ -378,13 +332,13 @@ Trace: AffectedNodeName: a 35: Var Pass: String a = cmd; /src/main/java/com/sast/astbenchmark/case_language_maturity/completeness/single_app_tracing/alias/NullAlias_001_T.java - AffectedNodeName: [dc.data] + AffectedNodeName: dc.data 36: Var Pass: dc.data = a; /src/main/java/com/sast/astbenchmark/case_language_maturity/completeness/single_app_tracing/alias/NullAlias_001_T.java AffectedNodeName: Runtime.getRuntime().exec 39: SINK: Runtime.getRuntime().exec(dc3.next.data); -------------- 14: taint_flow_java_input_inner------------- +------------- 15: taint_flow_java_input_inner------------- Description:Java污点分析checker,不会使用CallGraph边界制作entrypoint,蚂蚁内部使用 File:/src/main/java/com/sast/astbenchmark/case_language_maturity/completeness/single_app_tracing/alias/PrimitiveFieldAccess_001_T.java Line 32: Runtime.getRuntime().exec(cat /some/path/+b.attr.i+.png) @@ -400,13 +354,13 @@ Trace: AffectedNodeName: id 27: Var Pass: id = id + 100; /src/main/java/com/sast/astbenchmark/case_language_maturity/completeness/single_app_tracing/alias/PrimitiveFieldAccess_001_T.java - AffectedNodeName: [a.i] + AffectedNodeName: a.i 31: Var Pass: a.i = id; /src/main/java/com/sast/astbenchmark/case_language_maturity/completeness/single_app_tracing/alias/PrimitiveFieldAccess_001_T.java AffectedNodeName: Runtime.getRuntime().exec 32: SINK: Runtime.getRuntime().exec("cat /some/path/" + b.attr.i + ".png"); -------------- 15: taint_flow_java_input_inner------------- +------------- 16: taint_flow_java_input_inner------------- Description:Java污点分析checker,不会使用CallGraph边界制作entrypoint,蚂蚁内部使用 File:/src/main/java/com/sast/astbenchmark/case_language_maturity/completeness/single_app_tracing/alias/PrimitiveFieldAccess_003_T.java Line 30: Runtime.getRuntime().exec(cat /some/path/+i.intData+.png) @@ -424,17 +378,11 @@ Trace: /src/main/java/com/sast/astbenchmark/case_language_maturity/completeness/single_app_tracing/alias/PrimitiveFieldAccess_003_T.java AffectedNodeName: setIntData 29: CALL: b.setIntData(id); - /src/main/java/com/sast/astbenchmark/model/alias/PrimitiveData.java - AffectedNodeName: p - 6: ARG PASS: public void setIntData(int p) { - /src/main/java/com/sast/astbenchmark/model/alias/PrimitiveData.java - AffectedNodeName: [this.intData] - 7: Var Pass: this.intData = p; /src/main/java/com/sast/astbenchmark/case_language_maturity/completeness/single_app_tracing/alias/PrimitiveFieldAccess_003_T.java AffectedNodeName: Runtime.getRuntime().exec 30: SINK: Runtime.getRuntime().exec("cat /some/path/" + i.intData + ".png"); -------------- 16: taint_flow_java_input_inner------------- +------------- 17: taint_flow_java_input_inner------------- Description:Java污点分析checker,不会使用CallGraph边界制作entrypoint,蚂蚁内部使用 File:/src/main/java/com/sast/astbenchmark/case_language_maturity/completeness/single_app_tracing/alias/ReturnAlias_001_T.java Line 34: Runtime.getRuntime().exec(a.b) @@ -450,13 +398,13 @@ Trace: AffectedNodeName: tainted 28: Var Pass: String tainted = cmd; /src/main/java/com/sast/astbenchmark/case_language_maturity/completeness/single_app_tracing/alias/ReturnAlias_001_T.java - AffectedNodeName: [[b.attr].b] + AffectedNodeName: b.attr.b 32: Var Pass: b.attr.b = tainted; /src/main/java/com/sast/astbenchmark/case_language_maturity/completeness/single_app_tracing/alias/ReturnAlias_001_T.java AffectedNodeName: Runtime.getRuntime().exec 34: SINK: Runtime.getRuntime().exec(a.b); -------------- 17: taint_flow_java_input_inner------------- +------------- 18: taint_flow_java_input_inner------------- Description:Java污点分析checker,不会使用CallGraph边界制作entrypoint,蚂蚁内部使用 File:/src/main/java/com/sast/astbenchmark/case_language_maturity/completeness/single_app_tracing/alias/ReturnAlias_003_T.java Line 34: Runtime.getRuntime().exec(e.b) @@ -469,13 +417,13 @@ Trace: AffectedNodeName: cmd 24: SOURCE: public Map testcase(@RequestParam String cmd) { /src/main/java/com/sast/astbenchmark/case_language_maturity/completeness/single_app_tracing/alias/ReturnAlias_003_T.java - AffectedNodeName: [a.b] + AffectedNodeName: a.b 32: Var Pass: a.b = cmd; /src/main/java/com/sast/astbenchmark/case_language_maturity/completeness/single_app_tracing/alias/ReturnAlias_003_T.java AffectedNodeName: Runtime.getRuntime().exec 34: SINK: Runtime.getRuntime().exec(e.b); -------------- 18: taint_flow_java_input_inner------------- +------------- 19: taint_flow_java_input_inner------------- Description:Java污点分析checker,不会使用CallGraph边界制作entrypoint,蚂蚁内部使用 File:/src/main/java/com/sast/astbenchmark/case_language_maturity/completeness/single_app_tracing/alias/SameArgumentAlias_001_T.java Line 37: Runtime.getRuntime().exec(s) @@ -488,20 +436,11 @@ Trace: AffectedNodeName: cmd 25: SOURCE: public Map testcase(@RequestParam String cmd) { /src/main/java/com/sast/astbenchmark/case_language_maturity/completeness/single_app_tracing/alias/SameArgumentAlias_001_T.java - AffectedNodeName: [a.b] + AffectedNodeName: a.b 32: Var Pass: a.b = cmd; /src/main/java/com/sast/astbenchmark/case_language_maturity/completeness/single_app_tracing/alias/SameArgumentAlias_001_T.java AffectedNodeName: bar 35: CALL: String s = sa.bar(a).b; - /src/main/java/com/sast/astbenchmark/model/alias/SimpleAlias.java - AffectedNodeName: a - 12: ARG PASS: public A bar(A a) { - /src/main/java/com/sast/astbenchmark/model/alias/SimpleAlias.java - AffectedNodeName: [[this.b1].attr] - 13: Var Pass: this.b1.attr = a; - /src/main/java/com/sast/astbenchmark/model/alias/SimpleAlias.java - AffectedNodeName: [return value] - 14: Return Value: return this.b2.attr; /src/main/java/com/sast/astbenchmark/case_language_maturity/completeness/single_app_tracing/alias/SameArgumentAlias_001_T.java AffectedNodeName: bar 35: CALL RETURN: String s = sa.bar(a).b; @@ -512,7 +451,7 @@ Trace: AffectedNodeName: Runtime.getRuntime().exec 37: SINK: Runtime.getRuntime().exec(s); -------------- 19: taint_flow_java_input_inner------------- +------------- 20: taint_flow_java_input_inner------------- Description:Java污点分析checker,不会使用CallGraph边界制作entrypoint,蚂蚁内部使用 File:/src/main/java/com/sast/astbenchmark/case_language_maturity/completeness/single_app_tracing/alias/SingleFieldAccessAlias_001_T.java Line 32: Runtime.getRuntime().exec(b.b) @@ -525,13 +464,13 @@ Trace: AffectedNodeName: cmd 24: SOURCE: public Map testcase(@RequestParam String cmd) { /src/main/java/com/sast/astbenchmark/case_language_maturity/completeness/single_app_tracing/alias/SingleFieldAccessAlias_001_T.java - AffectedNodeName: [a.b] + AffectedNodeName: a.b 30: Var Pass: a.b = cmd; /src/main/java/com/sast/astbenchmark/case_language_maturity/completeness/single_app_tracing/alias/SingleFieldAccessAlias_001_T.java AffectedNodeName: Runtime.getRuntime().exec 32: SINK: Runtime.getRuntime().exec(b.b); -------------- 20: taint_flow_java_input_inner------------- +------------- 21: taint_flow_java_input_inner------------- Description:Java污点分析checker,不会使用CallGraph边界制作entrypoint,蚂蚁内部使用 File:/src/main/java/com/sast/astbenchmark/case_language_maturity/completeness/single_app_tracing/alias/StaticFieldAlias_001_T.java Line 32: Runtime.getRuntime().exec(StaticData.staticB1.attr.b) @@ -544,13 +483,13 @@ Trace: AffectedNodeName: cmd 24: SOURCE: public Map testcase(@RequestParam String cmd) { /src/main/java/com/sast/astbenchmark/case_language_maturity/completeness/single_app_tracing/alias/StaticFieldAlias_001_T.java - AffectedNodeName: [[[StaticData.staticB2].attr].b] + AffectedNodeName: StaticData.staticB2.attr.b 30: Var Pass: StaticData.staticB2.attr.b = cmd; /src/main/java/com/sast/astbenchmark/case_language_maturity/completeness/single_app_tracing/alias/StaticFieldAlias_001_T.java AffectedNodeName: Runtime.getRuntime().exec 32: SINK: Runtime.getRuntime().exec(StaticData.staticB1.attr.b); -------------- 21: taint_flow_java_input_inner------------- +------------- 22: taint_flow_java_input_inner------------- Description:Java污点分析checker,不会使用CallGraph边界制作entrypoint,蚂蚁内部使用 File:/src/main/java/com/sast/astbenchmark/case_language_maturity/accuracy/object_field_sensitive/field_sensitive_interface_class/AccessPathChainAlias_001_T.java Line 32: Runtime.getRuntime().exec(myTree.left.right.left.left.right.left.data) @@ -563,13 +502,13 @@ Trace: AffectedNodeName: cmd 23: SOURCE: public Map testcase(@RequestParam String cmd) { /src/main/java/com/sast/astbenchmark/case_language_maturity/accuracy/object_field_sensitive/field_sensitive_interface_class/AccessPathChainAlias_001_T.java - AffectedNodeName: [myTree.data] + AffectedNodeName: myTree.data 31: Var Pass: myTree.data = cmd; /src/main/java/com/sast/astbenchmark/case_language_maturity/accuracy/object_field_sensitive/field_sensitive_interface_class/AccessPathChainAlias_001_T.java AffectedNodeName: Runtime.getRuntime().exec 32: SINK: Runtime.getRuntime().exec(myTree.left.right.left.left.right.left.data); -------------- 22: taint_flow_java_input_inner------------- +------------- 23: taint_flow_java_input_inner------------- Description:Java污点分析checker,不会使用CallGraph边界制作entrypoint,蚂蚁内部使用 File:/src/main/java/com/sast/astbenchmark/case_language_maturity/accuracy/object_field_sensitive/field_sensitive_interface_class/AccessPathChainAlias_003_T.java Line 32: Runtime.getRuntime().exec(last.b) @@ -582,7 +521,7 @@ Trace: AffectedNodeName: cmd 25: SOURCE: public Map testcase(@RequestParam String cmd) { /src/main/java/com/sast/astbenchmark/case_language_maturity/accuracy/object_field_sensitive/field_sensitive_interface_class/AccessPathChainAlias_003_T.java - AffectedNodeName: [a.b] + AffectedNodeName: a.b 30: Var Pass: a.b = cmd; /src/main/java/com/sast/astbenchmark/case_language_maturity/accuracy/object_field_sensitive/field_sensitive_interface_class/AccessPathChainAlias_003_T.java AffectedNodeName: last @@ -591,7 +530,7 @@ Trace: AffectedNodeName: Runtime.getRuntime().exec 32: SINK: Runtime.getRuntime().exec(last.b); -------------- 23: taint_flow_java_input_inner------------- +------------- 24: taint_flow_java_input_inner------------- Description:Java污点分析checker,不会使用CallGraph边界制作entrypoint,蚂蚁内部使用 File:/src/main/java/com/sast/astbenchmark/case_language_maturity/accuracy/object_field_sensitive/field_sensitive_interface_class/PropertyIsTaintOrNot_Object_001_T.java Line 29: Runtime.getRuntime().exec(simpleBean.getCmd()) @@ -606,12 +545,6 @@ Trace: /src/main/java/com/sast/astbenchmark/case_language_maturity/accuracy/object_field_sensitive/field_sensitive_interface_class/PropertyIsTaintOrNot_Object_001_T.java AffectedNodeName: setCmd 27: CALL: simpleBean.setCmd(cmd); - /src/main/java/com/sast/astbenchmark/model/CmdObject.java - AffectedNodeName: cmd - 8: ARG PASS: public void setCmd(String cmd) { - /src/main/java/com/sast/astbenchmark/model/CmdObject.java - AffectedNodeName: [this.cmd1] - 9: Var Pass: this.cmd1 = cmd; /src/main/java/com/sast/astbenchmark/case_language_maturity/accuracy/object_field_sensitive/field_sensitive_interface_class/PropertyIsTaintOrNot_Object_001_T.java AffectedNodeName: setCmd2 28: CALL: simpleBean.setCmd2("cd /"); @@ -624,9 +557,6 @@ Trace: /src/main/java/com/sast/astbenchmark/case_language_maturity/accuracy/object_field_sensitive/field_sensitive_interface_class/PropertyIsTaintOrNot_Object_001_T.java AffectedNodeName: simpleBean 29: ARG PASS: Runtime.getRuntime().exec(simpleBean.getCmd()); - /src/main/java/com/sast/astbenchmark/model/CmdObject.java - AffectedNodeName: [return value] - 17: Return Value: return cmd1; /src/main/java/com/sast/astbenchmark/case_language_maturity/accuracy/object_field_sensitive/field_sensitive_interface_class/PropertyIsTaintOrNot_Object_001_T.java AffectedNodeName: getCmd 29: CALL RETURN: Runtime.getRuntime().exec(simpleBean.getCmd()); @@ -634,7 +564,7 @@ Trace: AffectedNodeName: Runtime.getRuntime().exec 29: SINK: Runtime.getRuntime().exec(simpleBean.getCmd()); -------------- 24: taint_flow_java_input_inner------------- +------------- 25: taint_flow_java_input_inner------------- Description:Java污点分析checker,不会使用CallGraph边界制作entrypoint,蚂蚁内部使用 File:/src/main/java/com/sast/astbenchmark/case_language_maturity/accuracy/object_field_sensitive/field_sensitive_muilt_collection/Array_index_muilt_collection_001_T.java Line 26: Runtime.getRuntime().exec(arr.0.0) @@ -653,7 +583,7 @@ Trace: AffectedNodeName: Runtime.getRuntime().exec 26: SINK: Runtime.getRuntime().exec(arr[0][0]); -------------- 25: taint_flow_java_input_inner------------- +------------- 26: taint_flow_java_input_inner------------- Description:Java污点分析checker,不会使用CallGraph边界制作entrypoint,蚂蚁内部使用 File:/src/main/java/com/sast/astbenchmark/common/utils/HttpUtil.java Line 44: httpclient.execute(httpGet) @@ -671,21 +601,12 @@ Trace: /src/main/java/com/sast/astbenchmark/case_language_maturity/accuracy/object_field_sensitive/field_sensitive_muilt_collection/MapPutGet_muilt_collection_001_T.java AffectedNodeName: setModelMap 34: CALL: xCmdObject.setModelMap(paramMap); - /src/main/java/com/sast/astbenchmark/model/XCmdObject.java - AffectedNodeName: map - 13: ARG PASS: public void setModelMap(Map map) { - /src/main/java/com/sast/astbenchmark/model/XCmdObject.java - AffectedNodeName: [this.modelMap] - 14: Var Pass: this.modelMap = map; /src/main/java/com/sast/astbenchmark/case_language_maturity/accuracy/object_field_sensitive/field_sensitive_muilt_collection/MapPutGet_muilt_collection_001_T.java AffectedNodeName: getModelMap 35: CALL: HttpUtil.doGet(xCmdObject.getModelMap().get("url1")); /src/main/java/com/sast/astbenchmark/case_language_maturity/accuracy/object_field_sensitive/field_sensitive_muilt_collection/MapPutGet_muilt_collection_001_T.java AffectedNodeName: xCmdObject 35: ARG PASS: HttpUtil.doGet(xCmdObject.getModelMap().get("url1")); - /src/main/java/com/sast/astbenchmark/model/XCmdObject.java - AffectedNodeName: [return value] - 22: Return Value: return modelMap; /src/main/java/com/sast/astbenchmark/case_language_maturity/accuracy/object_field_sensitive/field_sensitive_muilt_collection/MapPutGet_muilt_collection_001_T.java AffectedNodeName: getModelMap 35: CALL RETURN: HttpUtil.doGet(xCmdObject.getModelMap().get("url1")); @@ -714,7 +635,7 @@ Trace: AffectedNodeName: httpclient.execute 44: SINK: response = httpclient.execute(httpGet); -------------- 26: taint_flow_java_input_inner------------- +------------- 27: taint_flow_java_input_inner------------- Description:Java污点分析checker,不会使用CallGraph边界制作entrypoint,蚂蚁内部使用 File:/src/main/java/com/sast/astbenchmark/case_language_maturity/accuracy/object_field_sensitive/object_sensitive/ArrayElementOverwrite_001_T.java Line 30: Runtime.getRuntime().exec(c.1) @@ -736,7 +657,7 @@ Trace: AffectedNodeName: Runtime.getRuntime().exec 30: SINK: Runtime.getRuntime().exec(c[1]); -------------- 27: taint_flow_java_input_inner------------- +------------- 28: taint_flow_java_input_inner------------- Description:Java污点分析checker,不会使用CallGraph边界制作entrypoint,蚂蚁内部使用 File:/src/main/java/com/sast/astbenchmark/case_language_maturity/accuracy/object_field_sensitive/object_sensitive/ArrayElementOverwrite_003_T.java Line 32: Runtime.getRuntime().exec(c.get(0)) @@ -758,7 +679,7 @@ Trace: AffectedNodeName: Runtime.getRuntime().exec 32: SINK: Runtime.getRuntime().exec(c.get(0)); -------------- 28: taint_flow_java_input_inner------------- +------------- 29: taint_flow_java_input_inner------------- Description:Java污点分析checker,不会使用CallGraph边界制作entrypoint,蚂蚁内部使用 File:/src/main/java/com/sast/astbenchmark/case_language_maturity/accuracy/object_field_sensitive/object_sensitive/Map_obj_sensitive_001_T.java Line 28: SinkUtil.sink(m) @@ -777,7 +698,7 @@ Trace: AffectedNodeName: SinkUtil.sink 28: SINK: SinkUtil.sink(m); -------------- 29: taint_flow_java_input_inner------------- +------------- 30: taint_flow_java_input_inner------------- Description:Java污点分析checker,不会使用CallGraph边界制作entrypoint,蚂蚁内部使用 File:/src/main/java/com/sast/astbenchmark/case_language_maturity/accuracy/object_field_sensitive/object_sensitive/Map_obj_sensitive_003_T.java Line 29: SinkUtil.sink(m) @@ -796,7 +717,7 @@ Trace: AffectedNodeName: SinkUtil.sink 29: SINK: SinkUtil.sink(m); -------------- 30: taint_flow_java_input_inner------------- +------------- 31: taint_flow_java_input_inner------------- Description:Java污点分析checker,不会使用CallGraph边界制作entrypoint,蚂蚁内部使用 File:/src/main/java/com/sast/astbenchmark/case_language_maturity/accuracy/object_field_sensitive/object_sensitive/Map_obj_sensitive_005_T.java Line 30: SinkUtil.sink(m) @@ -815,7 +736,7 @@ Trace: AffectedNodeName: SinkUtil.sink 30: SINK: SinkUtil.sink(m); -------------- 31: taint_flow_java_input_inner------------- +------------- 32: taint_flow_java_input_inner------------- Description:Java污点分析checker,不会使用CallGraph边界制作entrypoint,蚂蚁内部使用 File:/src/main/java/com/sast/astbenchmark/case_language_maturity/accuracy/object_field_sensitive/object_sensitive/ObjectDiffAttribute_001_T.java Line 30: Runtime.getRuntime().exec(a.getCmd()) @@ -830,21 +751,12 @@ Trace: /src/main/java/com/sast/astbenchmark/case_language_maturity/accuracy/object_field_sensitive/object_sensitive/ObjectDiffAttribute_001_T.java AffectedNodeName: setCmd 28: CALL: a.setCmd(cmd); - /src/main/java/com/sast/astbenchmark/model/CmdObject.java - AffectedNodeName: cmd - 8: ARG PASS: public void setCmd(String cmd) { - /src/main/java/com/sast/astbenchmark/model/CmdObject.java - AffectedNodeName: [this.cmd1] - 9: Var Pass: this.cmd1 = cmd; /src/main/java/com/sast/astbenchmark/case_language_maturity/accuracy/object_field_sensitive/object_sensitive/ObjectDiffAttribute_001_T.java AffectedNodeName: getCmd 30: CALL: Runtime.getRuntime().exec(a.getCmd()); /src/main/java/com/sast/astbenchmark/case_language_maturity/accuracy/object_field_sensitive/object_sensitive/ObjectDiffAttribute_001_T.java AffectedNodeName: a 30: ARG PASS: Runtime.getRuntime().exec(a.getCmd()); - /src/main/java/com/sast/astbenchmark/model/CmdObject.java - AffectedNodeName: [return value] - 17: Return Value: return cmd1; /src/main/java/com/sast/astbenchmark/case_language_maturity/accuracy/object_field_sensitive/object_sensitive/ObjectDiffAttribute_001_T.java AffectedNodeName: getCmd 30: CALL RETURN: Runtime.getRuntime().exec(a.getCmd()); @@ -852,7 +764,7 @@ Trace: AffectedNodeName: Runtime.getRuntime().exec 30: SINK: Runtime.getRuntime().exec(a.getCmd()); -------------- 32: taint_flow_java_input_inner------------- +------------- 33: taint_flow_java_input_inner------------- Description:Java污点分析checker,不会使用CallGraph边界制作entrypoint,蚂蚁内部使用 File:/src/main/java/com/sast/astbenchmark/common/utils/HttpUtil.java Line 44: httpclient.execute(httpGet) @@ -889,7 +801,7 @@ Trace: AffectedNodeName: httpclient.execute 44: SINK: response = httpclient.execute(httpGet); -------------- 33: taint_flow_java_input_inner------------- +------------- 34: taint_flow_java_input_inner------------- Description:Java污点分析checker,不会使用CallGraph边界制作entrypoint,蚂蚁内部使用 File:/src/main/java/com/sast/astbenchmark/case_language_maturity/accuracy/context_sensitive/argument_return_value_passing/DifferentParamsPassing_001_T.java Line 27: Runtime.getRuntime().exec(a) @@ -904,12 +816,6 @@ Trace: /src/main/java/com/sast/astbenchmark/case_language_maturity/accuracy/context_sensitive/argument_return_value_passing/DifferentParamsPassing_001_T.java AffectedNodeName: chooseOne 26: CALL: String a = Invoke.chooseOne(3, "a", "b", "c", cmd, "e"); - /src/main/java/com/sast/astbenchmark/case_language_maturity/accuracy/context_sensitive/argument_return_value_passing/DifferentParamsPassing_001_T.java - AffectedNodeName: params - 36: ARG PASS: private static String chooseOne(int i, String... params) { - /src/main/java/com/sast/astbenchmark/case_language_maturity/accuracy/context_sensitive/argument_return_value_passing/DifferentParamsPassing_001_T.java - AffectedNodeName: [return value] - 37: Return Value: return params[i]; /src/main/java/com/sast/astbenchmark/case_language_maturity/accuracy/context_sensitive/argument_return_value_passing/DifferentParamsPassing_001_T.java AffectedNodeName: chooseOne 26: CALL RETURN: String a = Invoke.chooseOne(3, "a", "b", "c", cmd, "e"); @@ -920,7 +826,7 @@ Trace: AffectedNodeName: Runtime.getRuntime().exec 27: SINK: Runtime.getRuntime().exec(a); -------------- 34: taint_flow_java_input_inner------------- +------------- 35: taint_flow_java_input_inner------------- Description:Java污点分析checker,不会使用CallGraph边界制作entrypoint,蚂蚁内部使用 File:/src/main/java/com/sast/astbenchmark/common/utils/CmdUtil.java Line 7: Runtime.getRuntime().exec(cmd) @@ -942,7 +848,7 @@ Trace: AffectedNodeName: Runtime.getRuntime().exec 7: SINK: Runtime.getRuntime().exec(cmd); -------------- 35: taint_flow_java_input_inner------------- +------------- 36: taint_flow_java_input_inner------------- Description:Java污点分析checker,不会使用CallGraph边界制作entrypoint,蚂蚁内部使用 File:/src/main/java/com/sast/astbenchmark/common/utils/CmdUtil.java Line 7: Runtime.getRuntime().exec(cmd) @@ -964,7 +870,7 @@ Trace: AffectedNodeName: Runtime.getRuntime().exec 7: SINK: Runtime.getRuntime().exec(cmd); -------------- 36: taint_flow_java_input_inner------------- +------------- 37: taint_flow_java_input_inner------------- Description:Java污点分析checker,不会使用CallGraph边界制作entrypoint,蚂蚁内部使用 File:/src/main/java/com/sast/astbenchmark/case_language_maturity/accuracy/context_sensitive/argument_return_value_passing/return_value_passing_001_T.java Line 34: Runtime.getRuntime().exec(o) @@ -979,15 +885,6 @@ Trace: /src/main/java/com/sast/astbenchmark/case_language_maturity/accuracy/context_sensitive/argument_return_value_passing/return_value_passing_001_T.java AffectedNodeName: process 23: CALL: String data = process(__taint_src); - /src/main/java/com/sast/astbenchmark/case_language_maturity/accuracy/context_sensitive/argument_return_value_passing/return_value_passing_001_T.java - AffectedNodeName: __taint_src - 27: ARG PASS: private static String process(String __taint_src) { - /src/main/java/com/sast/astbenchmark/case_language_maturity/accuracy/context_sensitive/argument_return_value_passing/return_value_passing_001_T.java - AffectedNodeName: tmp - 28: Var Pass: String tmp = __taint_src; - /src/main/java/com/sast/astbenchmark/case_language_maturity/accuracy/context_sensitive/argument_return_value_passing/return_value_passing_001_T.java - AffectedNodeName: [return value] - 29: Return Value: return tmp; /src/main/java/com/sast/astbenchmark/case_language_maturity/accuracy/context_sensitive/argument_return_value_passing/return_value_passing_001_T.java AffectedNodeName: process 23: CALL RETURN: String data = process(__taint_src); @@ -1004,7 +901,7 @@ Trace: AffectedNodeName: Runtime.getRuntime().exec 34: SINK: Runtime.getRuntime().exec(o); -------------- 37: taint_flow_java_input_inner------------- +------------- 38: taint_flow_java_input_inner------------- Description:Java污点分析checker,不会使用CallGraph边界制作entrypoint,蚂蚁内部使用 File:/src/main/java/com/sast/astbenchmark/case_language_maturity/accuracy/context_sensitive/polymorphism/Expression_Polymorphism_001_T.java Line 28: Runtime.getRuntime().exec(ps.getCmd()) @@ -1019,35 +916,15 @@ Trace: /src/main/java/com/sast/astbenchmark/case_language_maturity/accuracy/context_sensitive/polymorphism/Expression_Polymorphism_001_T.java AffectedNodeName: _CTOR_ 27: CALL: PS ps = new PS(cmd, "~"); - /src/main/java/com/sast/astbenchmark/model/custom/PS.java - AffectedNodeName: cmd - 6: ARG PASS: public PS(String cmd, String cmd2) { - /src/main/java/com/sast/astbenchmark/model/custom/PS.java - AffectedNodeName: _CTOR_ - 7: CALL: super(cmd); - /src/main/java/com/sast/astbenchmark/model/custom/P.java - AffectedNodeName: cmd - 8: ARG PASS: public P(String cmd) { - /src/main/java/com/sast/astbenchmark/model/custom/P.java - AffectedNodeName: [this.cmd] - 9: Var Pass: this.cmd = cmd; /src/main/java/com/sast/astbenchmark/case_language_maturity/accuracy/context_sensitive/polymorphism/Expression_Polymorphism_001_T.java AffectedNodeName: ps 27: Var Pass: PS ps = new PS(cmd, "~"); - /src/main/java/com/sast/astbenchmark/model/custom/PS.java - AffectedNodeName: getCmd - 12: CALL: return super.getCmd() + this.cmd2; - /src/main/java/com/sast/astbenchmark/model/custom/PS.java - 12: ARG PASS: return super.getCmd() + this.cmd2; - /src/main/java/com/sast/astbenchmark/model/custom/P.java - AffectedNodeName: [return value] - 13: Return Value: return this.cmd; - /src/main/java/com/sast/astbenchmark/model/custom/PS.java + /src/main/java/com/sast/astbenchmark/case_language_maturity/accuracy/context_sensitive/polymorphism/Expression_Polymorphism_001_T.java AffectedNodeName: getCmd - 12: CALL RETURN: return super.getCmd() + this.cmd2; - /src/main/java/com/sast/astbenchmark/model/custom/PS.java - AffectedNodeName: [return value] - 12: Return Value: return super.getCmd() + this.cmd2; + 28: CALL: Runtime.getRuntime().exec(ps.getCmd()); + /src/main/java/com/sast/astbenchmark/case_language_maturity/accuracy/context_sensitive/polymorphism/Expression_Polymorphism_001_T.java + AffectedNodeName: ps + 28: ARG PASS: Runtime.getRuntime().exec(ps.getCmd()); /src/main/java/com/sast/astbenchmark/case_language_maturity/accuracy/context_sensitive/polymorphism/Expression_Polymorphism_001_T.java AffectedNodeName: getCmd 28: CALL RETURN: Runtime.getRuntime().exec(ps.getCmd()); @@ -1055,7 +932,7 @@ Trace: AffectedNodeName: Runtime.getRuntime().exec 28: SINK: Runtime.getRuntime().exec(ps.getCmd()); -------------- 38: taint_flow_java_input_inner------------- +------------- 39: taint_flow_java_input_inner------------- Description:Java污点分析checker,不会使用CallGraph边界制作entrypoint,蚂蚁内部使用 File:/src/main/java/com/sast/astbenchmark/model/custom/T.java Line 16: Runtime.getRuntime().exec(this.cmd) @@ -1070,12 +947,6 @@ Trace: /src/main/java/com/sast/astbenchmark/case_language_maturity/accuracy/flow_sensitive/asynchronous/Async_Multithread_001_T.java AffectedNodeName: _CTOR_ 24: CALL: T t = new T(cmd); - /src/main/java/com/sast/astbenchmark/model/custom/T.java - AffectedNodeName: cmd - 10: ARG PASS: public T(String cmd) { - /src/main/java/com/sast/astbenchmark/model/custom/T.java - AffectedNodeName: [this.cmd] - 11: Var Pass: this.cmd = cmd; /src/main/java/com/sast/astbenchmark/case_language_maturity/accuracy/flow_sensitive/asynchronous/Async_Multithread_001_T.java AffectedNodeName: t 24: Var Pass: T t = new T(cmd); @@ -1089,7 +960,7 @@ Trace: AffectedNodeName: Runtime.getRuntime().exec 16: SINK: Runtime.getRuntime().exec(this.cmd); -------------- 39: taint_flow_java_input_inner------------- +------------- 40: taint_flow_java_input_inner------------- Description:Java污点分析checker,不会使用CallGraph边界制作entrypoint,蚂蚁内部使用 File:/src/main/java/com/sast/astbenchmark/case_language_maturity/accuracy/flow_sensitive/asynchronous/Async_Multithread_003_T.java Line 30: Runtime.getRuntime().exec(cmd) @@ -1105,7 +976,7 @@ Trace: AffectedNodeName: Runtime.getRuntime().exec 30: SINK: Runtime.getRuntime().exec(cmd); -------------- 40: taint_flow_java_input_inner------------- +------------- 41: taint_flow_java_input_inner------------- Description:Java污点分析checker,不会使用CallGraph边界制作entrypoint,蚂蚁内部使用 File:/src/main/java/com/sast/astbenchmark/model/custom/R.java Line 16: Runtime.getRuntime().exec(this.cmd) @@ -1120,25 +991,20 @@ Trace: /src/main/java/com/sast/astbenchmark/case_language_maturity/accuracy/flow_sensitive/asynchronous/Async_Multithread_005_T.java AffectedNodeName: _CTOR_ 25: CALL: R r = new R(cmd); - /src/main/java/com/sast/astbenchmark/model/custom/R.java - AffectedNodeName: cmd - 10: ARG PASS: public R(String cmd) { - /src/main/java/com/sast/astbenchmark/model/custom/R.java - AffectedNodeName: [this.cmd] - 11: Var Pass: this.cmd = cmd; /src/main/java/com/sast/astbenchmark/case_language_maturity/accuracy/flow_sensitive/asynchronous/Async_Multithread_005_T.java AffectedNodeName: r 25: Var Pass: R r = new R(cmd); /src/main/java/com/sast/astbenchmark/case_language_maturity/accuracy/flow_sensitive/asynchronous/Async_Multithread_005_T.java - AffectedNodeName: execute + AffectedNodeName: run 26: CALL: Executors.newCachedThreadPool().execute(r); /src/main/java/com/sast/astbenchmark/case_language_maturity/accuracy/flow_sensitive/asynchronous/Async_Multithread_005_T.java + AffectedNodeName: Executors.newCachedThreadPool() 26: ARG PASS: Executors.newCachedThreadPool().execute(r); /src/main/java/com/sast/astbenchmark/model/custom/R.java AffectedNodeName: Runtime.getRuntime().exec 16: SINK: Runtime.getRuntime().exec(this.cmd); -------------- 41: taint_flow_java_input_inner------------- +------------- 42: taint_flow_java_input_inner------------- Description:Java污点分析checker,不会使用CallGraph边界制作entrypoint,蚂蚁内部使用 File:/src/main/java/com/sast/astbenchmark/model/custom/TT.java Line 18: Runtime.getRuntime().exec(this.cmd) @@ -1153,17 +1019,11 @@ Trace: /src/main/java/com/sast/astbenchmark/case_language_maturity/accuracy/flow_sensitive/asynchronous/Async_Multithread_007_T.java AffectedNodeName: _CTOR_ 26: CALL: TT tt = new TT(cmd); - /src/main/java/com/sast/astbenchmark/model/custom/TT.java - AffectedNodeName: cmd - 12: ARG PASS: public TT(String cmd) { - /src/main/java/com/sast/astbenchmark/model/custom/TT.java - AffectedNodeName: [this.cmd] - 13: Var Pass: this.cmd = cmd; /src/main/java/com/sast/astbenchmark/case_language_maturity/accuracy/flow_sensitive/asynchronous/Async_Multithread_007_T.java AffectedNodeName: tt 26: Var Pass: TT tt = new TT(cmd); /src/main/java/com/sast/astbenchmark/case_language_maturity/accuracy/flow_sensitive/asynchronous/Async_Multithread_007_T.java - AffectedNodeName: schedule + AffectedNodeName: run 27: CALL: timer.schedule(tt, 2000); /src/main/java/com/sast/astbenchmark/case_language_maturity/accuracy/flow_sensitive/asynchronous/Async_Multithread_007_T.java AffectedNodeName: timer @@ -1172,7 +1032,7 @@ Trace: AffectedNodeName: Runtime.getRuntime().exec 18: SINK: Runtime.getRuntime().exec(this.cmd); -------------- 42: taint_flow_java_input_inner------------- +------------- 43: taint_flow_java_input_inner------------- Description:Java污点分析checker,不会使用CallGraph边界制作entrypoint,蚂蚁内部使用 File:/src/main/java/com/sast/astbenchmark/case_language_maturity/accuracy/flow_sensitive/asynchronous/Async_Multithread_009_T.java Line 39: Runtime.getRuntime().exec(obj.a) @@ -1185,13 +1045,13 @@ Trace: AffectedNodeName: cmd 26: SOURCE: public Map testcase(@RequestParam String cmd) { /src/main/java/com/sast/astbenchmark/case_language_maturity/accuracy/flow_sensitive/asynchronous/Async_Multithread_009_T.java - AffectedNodeName: [obj.a] + AffectedNodeName: obj.a 32: Var Pass: obj.a = cmd; /src/main/java/com/sast/astbenchmark/case_language_maturity/accuracy/flow_sensitive/asynchronous/Async_Multithread_009_T.java AffectedNodeName: Runtime.getRuntime().exec 39: SINK: Runtime.getRuntime().exec(obj.a); -------------- 43: taint_flow_java_input_inner------------- +------------- 44: taint_flow_java_input_inner------------- Description:Java污点分析checker,不会使用CallGraph边界制作entrypoint,蚂蚁内部使用 File:/src/main/java/com/sast/astbenchmark/case_language_maturity/accuracy/flow_sensitive/asynchronous/CompletableFuture_asynchronous_001_T.java Line 44: Runtime.getRuntime().exec(result.get()) @@ -1210,7 +1070,7 @@ Trace: AffectedNodeName: Runtime.getRuntime().exec 44: SINK: Runtime.getRuntime().exec(result.get()); -------------- 44: taint_flow_java_input_inner------------- +------------- 45: taint_flow_java_input_inner------------- Description:Java污点分析checker,不会使用CallGraph边界制作entrypoint,蚂蚁内部使用 File:/src/main/java/com/sast/astbenchmark/case_language_maturity/accuracy/flow_sensitive/normal_stmt/AssignObjectAttribute_002_T.java Line 31: Runtime.getRuntime().exec(b.getCmd()) @@ -1228,21 +1088,12 @@ Trace: /src/main/java/com/sast/astbenchmark/case_language_maturity/accuracy/flow_sensitive/normal_stmt/AssignObjectAttribute_002_T.java AffectedNodeName: setCmd 29: CALL: b.setCmd(a); - /src/main/java/com/sast/astbenchmark/model/CmdObject.java - AffectedNodeName: cmd - 8: ARG PASS: public void setCmd(String cmd) { - /src/main/java/com/sast/astbenchmark/model/CmdObject.java - AffectedNodeName: [this.cmd1] - 9: Var Pass: this.cmd1 = cmd; /src/main/java/com/sast/astbenchmark/case_language_maturity/accuracy/flow_sensitive/normal_stmt/AssignObjectAttribute_002_T.java AffectedNodeName: getCmd 31: CALL: Runtime.getRuntime().exec(b.getCmd()); /src/main/java/com/sast/astbenchmark/case_language_maturity/accuracy/flow_sensitive/normal_stmt/AssignObjectAttribute_002_T.java AffectedNodeName: b 31: ARG PASS: Runtime.getRuntime().exec(b.getCmd()); - /src/main/java/com/sast/astbenchmark/model/CmdObject.java - AffectedNodeName: [return value] - 17: Return Value: return cmd1; /src/main/java/com/sast/astbenchmark/case_language_maturity/accuracy/flow_sensitive/normal_stmt/AssignObjectAttribute_002_T.java AffectedNodeName: getCmd 31: CALL RETURN: Runtime.getRuntime().exec(b.getCmd()); @@ -1250,7 +1101,7 @@ Trace: AffectedNodeName: Runtime.getRuntime().exec 31: SINK: Runtime.getRuntime().exec(b.getCmd()); -------------- 45: taint_flow_java_input_inner------------- +------------- 46: taint_flow_java_input_inner------------- Description:Java污点分析checker,不会使用CallGraph边界制作entrypoint,蚂蚁内部使用 File:/src/main/java/com/sast/astbenchmark/case_language_maturity/accuracy/flow_sensitive/normal_stmt/AssignedByFixedValue_002_T.java Line 25: Runtime.getRuntime().exec(cmd) @@ -1266,7 +1117,7 @@ Trace: AffectedNodeName: Runtime.getRuntime().exec 25: SINK: Runtime.getRuntime().exec(cmd); -------------- 46: taint_flow_java_input_inner------------- +------------- 47: taint_flow_java_input_inner------------- Description:Java污点分析checker,不会使用CallGraph边界制作entrypoint,蚂蚁内部使用 File:/src/main/java/com/sast/astbenchmark/case_language_maturity/accuracy/flow_sensitive/normal_stmt/AssignedByVariable_002_T.java Line 28: Runtime.getRuntime().exec(a) @@ -1285,7 +1136,7 @@ Trace: AffectedNodeName: Runtime.getRuntime().exec 28: SINK: Runtime.getRuntime().exec(a); -------------- 47: taint_flow_java_input_inner------------- +------------- 48: taint_flow_java_input_inner------------- Description:Java污点分析checker,不会使用CallGraph边界制作entrypoint,蚂蚁内部使用 File:/src/main/java/com/sast/astbenchmark/case_language_maturity/accuracy/flow_sensitive/normal_stmt/FlowSensitiveAlias_001_T.java Line 32: Runtime.getRuntime().exec(dc2.data) @@ -1300,29 +1151,14 @@ Trace: /src/main/java/com/sast/astbenchmark/case_language_maturity/accuracy/flow_sensitive/normal_stmt/FlowSensitiveAlias_001_T.java AffectedNodeName: taintMe 29: CALL: Invoke.taintMe(dc1, cmd); - /src/main/java/com/sast/astbenchmark/model/alias/Invoke.java - AffectedNodeName: taint - 23: ARG PASS: public static void taintMe(DataClass dc, String taint) { - /src/main/java/com/sast/astbenchmark/model/alias/Invoke.java - AffectedNodeName: tainted - 24: Var Pass: String tainted = taint; - /src/main/java/com/sast/astbenchmark/model/alias/Invoke.java - AffectedNodeName: [dc.data] - 25: Var Pass: dc.data = tainted; /src/main/java/com/sast/astbenchmark/case_language_maturity/accuracy/flow_sensitive/normal_stmt/FlowSensitiveAlias_001_T.java AffectedNodeName: copy 30: CALL: Invoke.copy(dc1, dc2); - /src/main/java/com/sast/astbenchmark/model/alias/Invoke.java - AffectedNodeName: dc1 - 7: ARG PASS: public static void copy(DataClass dc1, DataClass dc2) { - /src/main/java/com/sast/astbenchmark/model/alias/Invoke.java - AffectedNodeName: [dc2.data] - 8: Var Pass: dc2.data = dc1.data; /src/main/java/com/sast/astbenchmark/case_language_maturity/accuracy/flow_sensitive/normal_stmt/FlowSensitiveAlias_001_T.java AffectedNodeName: Runtime.getRuntime().exec 32: SINK: Runtime.getRuntime().exec(dc2.data); -------------- 48: taint_flow_java_input_inner------------- +------------- 49: taint_flow_java_input_inner------------- Description:Java污点分析checker,不会使用CallGraph边界制作entrypoint,蚂蚁内部使用 File:/src/main/java/com/sast/astbenchmark/case_language_maturity/accuracy/flow_sensitive/normal_stmt/FlowSensitiveAlias_003_T.java Line 32: Runtime.getRuntime().exec(b.attr.b) @@ -1335,29 +1171,87 @@ Trace: AffectedNodeName: cmd 25: SOURCE: public Map testcase(@RequestParam String cmd) { /src/main/java/com/sast/astbenchmark/case_language_maturity/accuracy/flow_sensitive/normal_stmt/FlowSensitiveAlias_003_T.java - AffectedNodeName: [a.b] + AffectedNodeName: a.b 31: Var Pass: a.b = cmd; /src/main/java/com/sast/astbenchmark/case_language_maturity/accuracy/flow_sensitive/normal_stmt/FlowSensitiveAlias_003_T.java AffectedNodeName: Runtime.getRuntime().exec 32: SINK: Runtime.getRuntime().exec(b.attr.b); -------------- 49: taint_flow_java_input_inner------------- +------------- 50: taint_flow_java_input_inner------------- Description:Java污点分析checker,不会使用CallGraph边界制作entrypoint,蚂蚁内部使用 -File:/src/main/java/com/sast/astbenchmark/case_language_maturity/accuracy/path_sensitive/exception_throw/Statement_TryStatement_002_F.java -Line 27: Runtime.getRuntime().exec(cmd) +File:/src/main/java/com/sast/astbenchmark/case_language_maturity/accuracy/path_sensitive/exception_throw/Statement_TryStatement_001_T.java +Line 30: Runtime.getRuntime().exec(cmd) SINK RULE:Runtime.getRuntime().exec SINK Attribute:JavaCommandExec entrypoint: -{"filePath":"/src/main/java/com/sast/astbenchmark/case_language_maturity/accuracy/path_sensitive/exception_throw/Statement_TryStatement_002_F.java","functionName":"testcase","attribute":"HTTP","type":"functionCall"} +{"filePath":"/src/main/java/com/sast/astbenchmark/case_language_maturity/accuracy/path_sensitive/exception_throw/Statement_TryStatement_001_T.java","functionName":"testcase","attribute":"HTTP","type":"functionCall"} Trace: - /src/main/java/com/sast/astbenchmark/case_language_maturity/accuracy/path_sensitive/exception_throw/Statement_TryStatement_002_F.java + /src/main/java/com/sast/astbenchmark/case_language_maturity/accuracy/path_sensitive/exception_throw/Statement_TryStatement_001_T.java AffectedNodeName: cmd 22: SOURCE: public Map testcase(@PathVariable String cmd) { - /src/main/java/com/sast/astbenchmark/case_language_maturity/accuracy/path_sensitive/exception_throw/Statement_TryStatement_002_F.java + /src/main/java/com/sast/astbenchmark/case_language_maturity/accuracy/path_sensitive/exception_throw/Statement_TryStatement_001_T.java AffectedNodeName: Runtime.getRuntime().exec - 27: SINK: Runtime.getRuntime().exec(cmd); + 30: SINK: Runtime.getRuntime().exec(cmd); -------------- 50: taint_flow_java_input_inner------------- +------------- 51: taint_flow_java_input_inner------------- +Description:Java污点分析checker,不会使用CallGraph边界制作entrypoint,蚂蚁内部使用 +File:/src/main/java/com/sast/astbenchmark/case_language_maturity/accuracy/path_sensitive/exception_throw/Statement_TryStatement_003_T.java +Line 28: Runtime.getRuntime().exec(ex.getMessage()) +SINK RULE:Runtime.getRuntime().exec +SINK Attribute:JavaCommandExec +entrypoint: +{"filePath":"/src/main/java/com/sast/astbenchmark/case_language_maturity/accuracy/path_sensitive/exception_throw/Statement_TryStatement_003_T.java","functionName":"testcase","attribute":"HTTP","type":"functionCall"} +Trace: + /src/main/java/com/sast/astbenchmark/case_language_maturity/accuracy/path_sensitive/exception_throw/Statement_TryStatement_003_T.java + AffectedNodeName: cmd + 22: SOURCE: public Map testcase(@PathVariable String cmd) { + /src/main/java/com/sast/astbenchmark/case_language_maturity/accuracy/path_sensitive/exception_throw/Statement_TryStatement_003_T.java + AffectedNodeName: new RuntimeException(cmd) + 25: Throw Pass: throw new RuntimeException(cmd); + /src/main/java/com/sast/astbenchmark/case_language_maturity/accuracy/path_sensitive/exception_throw/Statement_TryStatement_003_T.java + AffectedNodeName: ex + 26: Var Pass: } catch (RuntimeException ex) { + 27: Var Pass: try { + 28: Var Pass: Runtime.getRuntime().exec(ex.getMessage()); + 29: Var Pass: modelMap.put("status", "success"); + 30: Var Pass: } catch (Exception e) { + 31: Var Pass: modelMap.put("status", "error"); + 32: Var Pass: } + 33: Var Pass: } + /src/main/java/com/sast/astbenchmark/case_language_maturity/accuracy/path_sensitive/exception_throw/Statement_TryStatement_003_T.java + AffectedNodeName: Runtime.getRuntime().exec + 28: SINK: Runtime.getRuntime().exec(ex.getMessage()); + +------------- 52: taint_flow_java_input_inner------------- +Description:Java污点分析checker,不会使用CallGraph边界制作entrypoint,蚂蚁内部使用 +File:/src/main/java/com/sast/astbenchmark/case_language_maturity/accuracy/path_sensitive/exception_throw/Statement_TryStatement_005_T.java +Line 30: Runtime.getRuntime().exec(ex.getMessage()) +SINK RULE:Runtime.getRuntime().exec +SINK Attribute:JavaCommandExec +entrypoint: +{"filePath":"/src/main/java/com/sast/astbenchmark/case_language_maturity/accuracy/path_sensitive/exception_throw/Statement_TryStatement_005_T.java","functionName":"testcase","attribute":"HTTP","type":"functionCall"} +Trace: + /src/main/java/com/sast/astbenchmark/case_language_maturity/accuracy/path_sensitive/exception_throw/Statement_TryStatement_005_T.java + AffectedNodeName: cmd + 23: SOURCE: public Map testcase(@PathVariable String cmd) { + /src/main/java/com/sast/astbenchmark/case_language_maturity/accuracy/path_sensitive/exception_throw/Statement_TryStatement_005_T.java + AffectedNodeName: new IOException(cmd) + 27: Throw Pass: throw new IOException(cmd); + /src/main/java/com/sast/astbenchmark/case_language_maturity/accuracy/path_sensitive/exception_throw/Statement_TryStatement_005_T.java + AffectedNodeName: ex + 28: Var Pass: } catch (IndexOutOfBoundsException | IOException ex) { + 29: Var Pass: try { + 30: Var Pass: Runtime.getRuntime().exec(ex.getMessage()); + 31: Var Pass: modelMap.put("status", "success"); + 32: Var Pass: } catch (Exception e) { + 33: Var Pass: modelMap.put("status", "error"); + 34: Var Pass: } + 35: Var Pass: } + /src/main/java/com/sast/astbenchmark/case_language_maturity/accuracy/path_sensitive/exception_throw/Statement_TryStatement_005_T.java + AffectedNodeName: Runtime.getRuntime().exec + 30: SINK: Runtime.getRuntime().exec(ex.getMessage()); + +------------- 53: taint_flow_java_input_inner------------- Description:Java污点分析checker,不会使用CallGraph边界制作entrypoint,蚂蚁内部使用 File:/src/main/java/com/sast/astbenchmark/case_language_maturity/accuracy/path_sensitive/explicit_jump_control/Statement_InterruptStatement_001_T.java Line 33: Runtime.getRuntime().exec(a) @@ -1376,7 +1270,26 @@ Trace: AffectedNodeName: Runtime.getRuntime().exec 33: SINK: Runtime.getRuntime().exec(a); -------------- 51: taint_flow_java_input_inner------------- +------------- 54: taint_flow_java_input_inner------------- +Description:Java污点分析checker,不会使用CallGraph边界制作entrypoint,蚂蚁内部使用 +File:/src/main/java/com/sast/astbenchmark/case_language_maturity/accuracy/path_sensitive/explicit_jump_control/Statement_InterruptStatement_002_F.java +Line 33: Runtime.getRuntime().exec(a) +SINK RULE:Runtime.getRuntime().exec +SINK Attribute:JavaCommandExec +entrypoint: +{"filePath":"/src/main/java/com/sast/astbenchmark/case_language_maturity/accuracy/path_sensitive/explicit_jump_control/Statement_InterruptStatement_002_F.java","functionName":"testcase","attribute":"HTTP","type":"functionCall"} +Trace: + /src/main/java/com/sast/astbenchmark/case_language_maturity/accuracy/path_sensitive/explicit_jump_control/Statement_InterruptStatement_002_F.java + AffectedNodeName: cmd + 22: SOURCE: public Map testcase(@PathVariable String cmd) { + /src/main/java/com/sast/astbenchmark/case_language_maturity/accuracy/path_sensitive/explicit_jump_control/Statement_InterruptStatement_002_F.java + AffectedNodeName: a + 27: Var Pass: a = cmd + "|"; + /src/main/java/com/sast/astbenchmark/case_language_maturity/accuracy/path_sensitive/explicit_jump_control/Statement_InterruptStatement_002_F.java + AffectedNodeName: Runtime.getRuntime().exec + 33: SINK: Runtime.getRuntime().exec(a); + +------------- 55: taint_flow_java_input_inner------------- Description:Java污点分析checker,不会使用CallGraph边界制作entrypoint,蚂蚁内部使用 File:/src/main/java/com/sast/astbenchmark/case_language_maturity/accuracy/path_sensitive/explicit_jump_control/Statement_InterruptStatement_003_T.java Line 36: Runtime.getRuntime().exec(a) @@ -1395,66 +1308,161 @@ Trace: AffectedNodeName: Runtime.getRuntime().exec 36: SINK: Runtime.getRuntime().exec(a); -------------- 52: taint_flow_java_input_inner------------- +------------- 56: taint_flow_java_input_inner------------- Description:Java污点分析checker,不会使用CallGraph边界制作entrypoint,蚂蚁内部使用 -File:/src/main/java/com/sast/astbenchmark/case_language_maturity/completeness/single_app_tracing/datatype/array/Base_ArrayAccess_001_T.java -Line 28: Runtime.getRuntime().exec(cmdStr) +File:/src/main/java/com/sast/astbenchmark/case_language_maturity/accuracy/path_sensitive/explicit_jump_control/Statement_InterruptStatement_004_F.java +Line 36: Runtime.getRuntime().exec(a) SINK RULE:Runtime.getRuntime().exec SINK Attribute:JavaCommandExec entrypoint: -{"filePath":"/src/main/java/com/sast/astbenchmark/case_language_maturity/completeness/single_app_tracing/datatype/array/Base_ArrayAccess_001_T.java","functionName":"aTaintCase0110","attribute":"HTTP","type":"functionCall"} +{"filePath":"/src/main/java/com/sast/astbenchmark/case_language_maturity/accuracy/path_sensitive/explicit_jump_control/Statement_InterruptStatement_004_F.java","functionName":"testcase","attribute":"HTTP","type":"functionCall"} Trace: - /src/main/java/com/sast/astbenchmark/case_language_maturity/completeness/single_app_tracing/datatype/array/Base_ArrayAccess_001_T.java - AffectedNodeName: request - 24: SOURCE: public Map aTaintCase0110(@RequestParam("cmd") String cmd, HttpServletRequest request) { - /src/main/java/com/sast/astbenchmark/case_language_maturity/completeness/single_app_tracing/datatype/array/Base_ArrayAccess_001_T.java - AffectedNodeName: cmdStr - 27: Var Pass: String cmdStr = request.getParameterMap().get("cmd")[0]; - /src/main/java/com/sast/astbenchmark/case_language_maturity/completeness/single_app_tracing/datatype/array/Base_ArrayAccess_001_T.java + /src/main/java/com/sast/astbenchmark/case_language_maturity/accuracy/path_sensitive/explicit_jump_control/Statement_InterruptStatement_004_F.java + AffectedNodeName: cmd + 22: SOURCE: public Map testcase(@PathVariable String cmd) { + /src/main/java/com/sast/astbenchmark/case_language_maturity/accuracy/path_sensitive/explicit_jump_control/Statement_InterruptStatement_004_F.java + AffectedNodeName: a + 29: Var Pass: a = cmd + "|"; + /src/main/java/com/sast/astbenchmark/case_language_maturity/accuracy/path_sensitive/explicit_jump_control/Statement_InterruptStatement_004_F.java AffectedNodeName: Runtime.getRuntime().exec - 28: SINK: Runtime.getRuntime().exec(cmdStr); + 36: SINK: Runtime.getRuntime().exec(a); -------------- 53: taint_flow_java_input_inner------------- +------------- 57: taint_flow_java_input_inner------------- Description:Java污点分析checker,不会使用CallGraph边界制作entrypoint,蚂蚁内部使用 -File:/src/main/java/com/sast/astbenchmark/case_language_maturity/completeness/single_app_tracing/datatype/array/Base_ArrayAccess_003_T.java -Line 28: Runtime.getRuntime().exec(cookies.0.getName()) +File:/src/main/java/com/sast/astbenchmark/case_language_maturity/accuracy/path_sensitive/explicit_jump_control/Statement_InterruptStatement_005_T.java +Line 33: Runtime.getRuntime().exec(a) SINK RULE:Runtime.getRuntime().exec SINK Attribute:JavaCommandExec entrypoint: -{"filePath":"/src/main/java/com/sast/astbenchmark/case_language_maturity/completeness/single_app_tracing/datatype/array/Base_ArrayAccess_003_T.java","functionName":"aTaintCase0111","attribute":"HTTP","type":"functionCall"} +{"filePath":"/src/main/java/com/sast/astbenchmark/case_language_maturity/accuracy/path_sensitive/explicit_jump_control/Statement_InterruptStatement_005_T.java","functionName":"testcase","attribute":"HTTP","type":"functionCall"} Trace: - /src/main/java/com/sast/astbenchmark/case_language_maturity/completeness/single_app_tracing/datatype/array/Base_ArrayAccess_003_T.java - AffectedNodeName: request - 24: SOURCE: public Map aTaintCase0111(HttpServletRequest request) { - /src/main/java/com/sast/astbenchmark/case_language_maturity/completeness/single_app_tracing/datatype/array/Base_ArrayAccess_003_T.java - AffectedNodeName: cookies - 27: Var Pass: Cookie[] cookies = request.getCookies(); - /src/main/java/com/sast/astbenchmark/case_language_maturity/completeness/single_app_tracing/datatype/array/Base_ArrayAccess_003_T.java + /src/main/java/com/sast/astbenchmark/case_language_maturity/accuracy/path_sensitive/explicit_jump_control/Statement_InterruptStatement_005_T.java + AffectedNodeName: cmd + 22: SOURCE: public Map testcase(@PathVariable String cmd) { + /src/main/java/com/sast/astbenchmark/case_language_maturity/accuracy/path_sensitive/explicit_jump_control/Statement_InterruptStatement_005_T.java + AffectedNodeName: a + 27: Var Pass: a = cmd + "|"; + /src/main/java/com/sast/astbenchmark/case_language_maturity/accuracy/path_sensitive/explicit_jump_control/Statement_InterruptStatement_005_T.java AffectedNodeName: Runtime.getRuntime().exec - 28: SINK: Runtime.getRuntime().exec(cookies[0].getName()); + 33: SINK: Runtime.getRuntime().exec(a); -------------- 54: taint_flow_java_input_inner------------- +------------- 58: taint_flow_java_input_inner------------- Description:Java污点分析checker,不会使用CallGraph边界制作entrypoint,蚂蚁内部使用 -File:/src/main/java/com/sast/astbenchmark/case_language_maturity/completeness/single_app_tracing/datatype/array/Base_ArrayAccess_005_T.java -Line 27: Runtime.getRuntime().exec(arr) +File:/src/main/java/com/sast/astbenchmark/case_language_maturity/accuracy/path_sensitive/explicit_jump_control/Statement_InterruptStatement_006_F.java +Line 33: Runtime.getRuntime().exec(a) SINK RULE:Runtime.getRuntime().exec SINK Attribute:JavaCommandExec entrypoint: -{"filePath":"/src/main/java/com/sast/astbenchmark/case_language_maturity/completeness/single_app_tracing/datatype/array/Base_ArrayAccess_005_T.java","functionName":"testcase","attribute":"HTTP","type":"functionCall"} +{"filePath":"/src/main/java/com/sast/astbenchmark/case_language_maturity/accuracy/path_sensitive/explicit_jump_control/Statement_InterruptStatement_006_F.java","functionName":"testcase","attribute":"HTTP","type":"functionCall"} Trace: - /src/main/java/com/sast/astbenchmark/case_language_maturity/completeness/single_app_tracing/datatype/array/Base_ArrayAccess_005_T.java + /src/main/java/com/sast/astbenchmark/case_language_maturity/accuracy/path_sensitive/explicit_jump_control/Statement_InterruptStatement_006_F.java AffectedNodeName: cmd - 22: SOURCE: public Map testcase(@RequestParam String cmd) { - /src/main/java/com/sast/astbenchmark/case_language_maturity/completeness/single_app_tracing/datatype/array/Base_ArrayAccess_005_T.java - AffectedNodeName: arr[1] - 26: Var Pass: arr[1] = cmd; - /src/main/java/com/sast/astbenchmark/case_language_maturity/completeness/single_app_tracing/datatype/array/Base_ArrayAccess_005_T.java + 22: SOURCE: public Map testcase(@PathVariable String cmd) { + /src/main/java/com/sast/astbenchmark/case_language_maturity/accuracy/path_sensitive/explicit_jump_control/Statement_InterruptStatement_006_F.java + AffectedNodeName: a + 27: Var Pass: a = cmd + "|"; + /src/main/java/com/sast/astbenchmark/case_language_maturity/accuracy/path_sensitive/explicit_jump_control/Statement_InterruptStatement_006_F.java AffectedNodeName: Runtime.getRuntime().exec - 27: SINK: Runtime.getRuntime().exec(arr); + 33: SINK: Runtime.getRuntime().exec(a); -------------- 55: taint_flow_java_input_inner------------- +------------- 59: taint_flow_java_input_inner------------- Description:Java污点分析checker,不会使用CallGraph边界制作entrypoint,蚂蚁内部使用 -File:/src/main/java/com/sast/astbenchmark/case_language_maturity/completeness/single_app_tracing/datatype/array/Base_ArrayAccess_007_T.java +File:/src/main/java/com/sast/astbenchmark/case_language_maturity/accuracy/path_sensitive/explicit_jump_control/Statement_InterruptStatement_007_T.java +Line 36: Runtime.getRuntime().exec(a) +SINK RULE:Runtime.getRuntime().exec +SINK Attribute:JavaCommandExec +entrypoint: +{"filePath":"/src/main/java/com/sast/astbenchmark/case_language_maturity/accuracy/path_sensitive/explicit_jump_control/Statement_InterruptStatement_007_T.java","functionName":"testcase","attribute":"HTTP","type":"functionCall"} +Trace: + /src/main/java/com/sast/astbenchmark/case_language_maturity/accuracy/path_sensitive/explicit_jump_control/Statement_InterruptStatement_007_T.java + AffectedNodeName: cmd + 22: SOURCE: public Map testcase(@PathVariable String cmd) { + /src/main/java/com/sast/astbenchmark/case_language_maturity/accuracy/path_sensitive/explicit_jump_control/Statement_InterruptStatement_007_T.java + AffectedNodeName: a + 29: Var Pass: a = cmd + "|"; + /src/main/java/com/sast/astbenchmark/case_language_maturity/accuracy/path_sensitive/explicit_jump_control/Statement_InterruptStatement_007_T.java + AffectedNodeName: Runtime.getRuntime().exec + 36: SINK: Runtime.getRuntime().exec(a); + +------------- 60: taint_flow_java_input_inner------------- +Description:Java污点分析checker,不会使用CallGraph边界制作entrypoint,蚂蚁内部使用 +File:/src/main/java/com/sast/astbenchmark/case_language_maturity/accuracy/path_sensitive/explicit_jump_control/Statement_InterruptStatement_008_F.java +Line 36: Runtime.getRuntime().exec(a) +SINK RULE:Runtime.getRuntime().exec +SINK Attribute:JavaCommandExec +entrypoint: +{"filePath":"/src/main/java/com/sast/astbenchmark/case_language_maturity/accuracy/path_sensitive/explicit_jump_control/Statement_InterruptStatement_008_F.java","functionName":"testcase","attribute":"HTTP","type":"functionCall"} +Trace: + /src/main/java/com/sast/astbenchmark/case_language_maturity/accuracy/path_sensitive/explicit_jump_control/Statement_InterruptStatement_008_F.java + AffectedNodeName: cmd + 22: SOURCE: public Map testcase(@PathVariable String cmd) { + /src/main/java/com/sast/astbenchmark/case_language_maturity/accuracy/path_sensitive/explicit_jump_control/Statement_InterruptStatement_008_F.java + AffectedNodeName: a + 29: Var Pass: a = cmd + "|"; + /src/main/java/com/sast/astbenchmark/case_language_maturity/accuracy/path_sensitive/explicit_jump_control/Statement_InterruptStatement_008_F.java + AffectedNodeName: Runtime.getRuntime().exec + 36: SINK: Runtime.getRuntime().exec(a); + +------------- 61: taint_flow_java_input_inner------------- +Description:Java污点分析checker,不会使用CallGraph边界制作entrypoint,蚂蚁内部使用 +File:/src/main/java/com/sast/astbenchmark/case_language_maturity/completeness/single_app_tracing/datatype/array/Base_ArrayAccess_001_T.java +Line 28: Runtime.getRuntime().exec(cmdStr) +SINK RULE:Runtime.getRuntime().exec +SINK Attribute:JavaCommandExec +entrypoint: +{"filePath":"/src/main/java/com/sast/astbenchmark/case_language_maturity/completeness/single_app_tracing/datatype/array/Base_ArrayAccess_001_T.java","functionName":"aTaintCase0110","attribute":"HTTP","type":"functionCall"} +Trace: + /src/main/java/com/sast/astbenchmark/case_language_maturity/completeness/single_app_tracing/datatype/array/Base_ArrayAccess_001_T.java + AffectedNodeName: request + 24: SOURCE: public Map aTaintCase0110(@RequestParam("cmd") String cmd, HttpServletRequest request) { + /src/main/java/com/sast/astbenchmark/case_language_maturity/completeness/single_app_tracing/datatype/array/Base_ArrayAccess_001_T.java + AffectedNodeName: cmdStr + 27: Var Pass: String cmdStr = request.getParameterMap().get("cmd")[0]; + /src/main/java/com/sast/astbenchmark/case_language_maturity/completeness/single_app_tracing/datatype/array/Base_ArrayAccess_001_T.java + AffectedNodeName: Runtime.getRuntime().exec + 28: SINK: Runtime.getRuntime().exec(cmdStr); + +------------- 62: taint_flow_java_input_inner------------- +Description:Java污点分析checker,不会使用CallGraph边界制作entrypoint,蚂蚁内部使用 +File:/src/main/java/com/sast/astbenchmark/case_language_maturity/completeness/single_app_tracing/datatype/array/Base_ArrayAccess_003_T.java +Line 28: Runtime.getRuntime().exec(cookies.0.getName()) +SINK RULE:Runtime.getRuntime().exec +SINK Attribute:JavaCommandExec +entrypoint: +{"filePath":"/src/main/java/com/sast/astbenchmark/case_language_maturity/completeness/single_app_tracing/datatype/array/Base_ArrayAccess_003_T.java","functionName":"aTaintCase0111","attribute":"HTTP","type":"functionCall"} +Trace: + /src/main/java/com/sast/astbenchmark/case_language_maturity/completeness/single_app_tracing/datatype/array/Base_ArrayAccess_003_T.java + AffectedNodeName: request + 24: SOURCE: public Map aTaintCase0111(HttpServletRequest request) { + /src/main/java/com/sast/astbenchmark/case_language_maturity/completeness/single_app_tracing/datatype/array/Base_ArrayAccess_003_T.java + AffectedNodeName: cookies + 27: Var Pass: Cookie[] cookies = request.getCookies(); + /src/main/java/com/sast/astbenchmark/case_language_maturity/completeness/single_app_tracing/datatype/array/Base_ArrayAccess_003_T.java + AffectedNodeName: Runtime.getRuntime().exec + 28: SINK: Runtime.getRuntime().exec(cookies[0].getName()); + +------------- 63: taint_flow_java_input_inner------------- +Description:Java污点分析checker,不会使用CallGraph边界制作entrypoint,蚂蚁内部使用 +File:/src/main/java/com/sast/astbenchmark/case_language_maturity/completeness/single_app_tracing/datatype/array/Base_ArrayAccess_005_T.java +Line 27: Runtime.getRuntime().exec(arr) +SINK RULE:Runtime.getRuntime().exec +SINK Attribute:JavaCommandExec +entrypoint: +{"filePath":"/src/main/java/com/sast/astbenchmark/case_language_maturity/completeness/single_app_tracing/datatype/array/Base_ArrayAccess_005_T.java","functionName":"testcase","attribute":"HTTP","type":"functionCall"} +Trace: + /src/main/java/com/sast/astbenchmark/case_language_maturity/completeness/single_app_tracing/datatype/array/Base_ArrayAccess_005_T.java + AffectedNodeName: cmd + 22: SOURCE: public Map testcase(@RequestParam String cmd) { + /src/main/java/com/sast/astbenchmark/case_language_maturity/completeness/single_app_tracing/datatype/array/Base_ArrayAccess_005_T.java + AffectedNodeName: arr[1] + 26: Var Pass: arr[1] = cmd; + /src/main/java/com/sast/astbenchmark/case_language_maturity/completeness/single_app_tracing/datatype/array/Base_ArrayAccess_005_T.java + AffectedNodeName: Runtime.getRuntime().exec + 27: SINK: Runtime.getRuntime().exec(arr); + +------------- 64: taint_flow_java_input_inner------------- +Description:Java污点分析checker,不会使用CallGraph边界制作entrypoint,蚂蚁内部使用 +File:/src/main/java/com/sast/astbenchmark/case_language_maturity/completeness/single_app_tracing/datatype/array/Base_ArrayAccess_007_T.java Line 28: Runtime.getRuntime().exec(data.0.0) SINK RULE:Runtime.getRuntime().exec SINK Attribute:JavaCommandExec @@ -1471,7 +1479,7 @@ Trace: AffectedNodeName: Runtime.getRuntime().exec 28: SINK: Runtime.getRuntime().exec(data[0][0]); -------------- 56: taint_flow_java_input_inner------------- +------------- 65: taint_flow_java_input_inner------------- Description:Java污点分析checker,不会使用CallGraph边界制作entrypoint,蚂蚁内部使用 File:/src/main/java/com/sast/astbenchmark/case_language_maturity/completeness/single_app_tracing/datatype/array/Base_ArrayAccess_009_T.java Line 29: Runtime.getRuntime().exec(s) @@ -1493,7 +1501,7 @@ Trace: AffectedNodeName: Runtime.getRuntime().exec 29: SINK: Runtime.getRuntime().exec(s); -------------- 57: taint_flow_java_input_inner------------- +------------- 66: taint_flow_java_input_inner------------- Description:Java污点分析checker,不会使用CallGraph边界制作entrypoint,蚂蚁内部使用 File:/src/main/java/com/sast/astbenchmark/case_language_maturity/completeness/single_app_tracing/datatype/collections/Base_List_001_T.java Line 33: Runtime.getRuntime().exec(cmd.get(0)) @@ -1509,7 +1517,7 @@ Trace: AffectedNodeName: Runtime.getRuntime().exec 33: SINK: Runtime.getRuntime().exec(cmd.get(0)); -------------- 58: taint_flow_java_input_inner------------- +------------- 67: taint_flow_java_input_inner------------- Description:Java污点分析checker,不会使用CallGraph边界制作entrypoint,蚂蚁内部使用 File:/src/main/java/com/sast/astbenchmark/case_language_maturity/completeness/single_app_tracing/datatype/collections/Base_List_003_T.java Line 32: SinkUtil.sink(cmd) @@ -1525,7 +1533,7 @@ Trace: AffectedNodeName: SinkUtil.sink 32: SINK: SinkUtil.sink(cmd); -------------- 59: taint_flow_java_input_inner------------- +------------- 68: taint_flow_java_input_inner------------- Description:Java污点分析checker,不会使用CallGraph边界制作entrypoint,蚂蚁内部使用 File:/src/main/java/com/sast/astbenchmark/case_language_maturity/completeness/single_app_tracing/datatype/collections/Base_List_005_T.java Line 32: SinkUtil.sink(list) @@ -1544,7 +1552,7 @@ Trace: AffectedNodeName: SinkUtil.sink 32: SINK: SinkUtil.sink(list); -------------- 60: taint_flow_java_input_inner------------- +------------- 69: taint_flow_java_input_inner------------- Description:Java污点分析checker,不会使用CallGraph边界制作entrypoint,蚂蚁内部使用 File:/src/main/java/com/sast/astbenchmark/case_language_maturity/completeness/single_app_tracing/datatype/collections/Base_List_007_T.java Line 32: SinkUtil.sink(list) @@ -1563,7 +1571,7 @@ Trace: AffectedNodeName: SinkUtil.sink 32: SINK: SinkUtil.sink(list); -------------- 61: taint_flow_java_input_inner------------- +------------- 70: taint_flow_java_input_inner------------- Description:Java污点分析checker,不会使用CallGraph边界制作entrypoint,蚂蚁内部使用 File:/src/main/java/com/sast/astbenchmark/case_language_maturity/completeness/single_app_tracing/datatype/collections/Base_Queue_001_T.java Line 39: SinkUtil.sink(queue) @@ -1582,7 +1590,7 @@ Trace: AffectedNodeName: SinkUtil.sink 39: SINK: SinkUtil.sink(queue); -------------- 62: taint_flow_java_input_inner------------- +------------- 71: taint_flow_java_input_inner------------- Description:Java污点分析checker,不会使用CallGraph边界制作entrypoint,蚂蚁内部使用 File:/src/main/java/com/sast/astbenchmark/case_language_maturity/completeness/single_app_tracing/datatype/collections/Base_Queue_003_T.java Line 37: Runtime.getRuntime().exec(queue.peek()) @@ -1601,7 +1609,7 @@ Trace: AffectedNodeName: Runtime.getRuntime().exec 37: SINK: Runtime.getRuntime().exec(queue.peek()); -------------- 63: taint_flow_java_input_inner------------- +------------- 72: taint_flow_java_input_inner------------- Description:Java污点分析checker,不会使用CallGraph边界制作entrypoint,蚂蚁内部使用 File:/src/main/java/com/sast/astbenchmark/case_language_maturity/completeness/single_app_tracing/datatype/collections/Base_Queue_005_T.java Line 32: SinkUtil.sink(queue) @@ -1620,7 +1628,7 @@ Trace: AffectedNodeName: SinkUtil.sink 32: SINK: SinkUtil.sink(queue); -------------- 64: taint_flow_java_input_inner------------- +------------- 73: taint_flow_java_input_inner------------- Description:Java污点分析checker,不会使用CallGraph边界制作entrypoint,蚂蚁内部使用 File:/src/main/java/com/sast/astbenchmark/case_language_maturity/completeness/single_app_tracing/datatype/collections/Base_Set_001_T.java Line 38: SinkUtil.sink(stringSet) @@ -1639,23 +1647,7 @@ Trace: AffectedNodeName: SinkUtil.sink 38: SINK: SinkUtil.sink(stringSet); -------------- 65: taint_flow_java_input_inner------------- -Description:Java污点分析checker,不会使用CallGraph边界制作entrypoint,蚂蚁内部使用 -File:/src/main/java/com/sast/astbenchmark/case_language_maturity/completeness/single_app_tracing/datatype/collections/Base_Set_001_T.java -Line 38: SinkUtil.sink(stringSet) -SINK RULE:SinkUtil.sink -SINK Attribute:JavaCommandExec -entrypoint: -{"filePath":"/src/main/java/com/sast/astbenchmark/case_language_maturity/completeness/single_app_tracing/datatype/collections/Base_Set_001_T.java","functionName":"aTaintCase0143","attribute":"HTTP","type":"functionCall"} -Trace: - /src/main/java/com/sast/astbenchmark/case_language_maturity/completeness/single_app_tracing/datatype/collections/Base_Set_001_T.java - AffectedNodeName: cmd - 31: SOURCE: public Map aTaintCase0143(@RequestBody List cmd) { - /src/main/java/com/sast/astbenchmark/case_language_maturity/completeness/single_app_tracing/datatype/collections/Base_Set_001_T.java - AffectedNodeName: SinkUtil.sink - 38: SINK: SinkUtil.sink(stringSet); - -------------- 66: taint_flow_java_input_inner------------- +------------- 74: taint_flow_java_input_inner------------- Description:Java污点分析checker,不会使用CallGraph边界制作entrypoint,蚂蚁内部使用 File:/src/main/java/com/sast/astbenchmark/case_language_maturity/completeness/single_app_tracing/datatype/collections/Base_Set_003_T.java Line 37: Runtime.getRuntime().exec(stringSet.stream().iterator().next()) @@ -1674,23 +1666,7 @@ Trace: AffectedNodeName: Runtime.getRuntime().exec 37: SINK: Runtime.getRuntime().exec(stringSet.stream().iterator().next()); -------------- 67: taint_flow_java_input_inner------------- -Description:Java污点分析checker,不会使用CallGraph边界制作entrypoint,蚂蚁内部使用 -File:/src/main/java/com/sast/astbenchmark/case_language_maturity/completeness/single_app_tracing/datatype/collections/Base_Set_003_T.java -Line 37: Runtime.getRuntime().exec(stringSet.stream().iterator().next()) -SINK RULE:Runtime.getRuntime().exec -SINK Attribute:JavaCommandExec -entrypoint: -{"filePath":"/src/main/java/com/sast/astbenchmark/case_language_maturity/completeness/single_app_tracing/datatype/collections/Base_Set_003_T.java","functionName":"aTaintCase0143","attribute":"HTTP","type":"functionCall"} -Trace: - /src/main/java/com/sast/astbenchmark/case_language_maturity/completeness/single_app_tracing/datatype/collections/Base_Set_003_T.java - AffectedNodeName: cmd - 28: SOURCE: public Map aTaintCase0143(@RequestBody List cmd) { - /src/main/java/com/sast/astbenchmark/case_language_maturity/completeness/single_app_tracing/datatype/collections/Base_Set_003_T.java - AffectedNodeName: Runtime.getRuntime().exec - 37: SINK: Runtime.getRuntime().exec(stringSet.stream().iterator().next()); - -------------- 68: taint_flow_java_input_inner------------- +------------- 75: taint_flow_java_input_inner------------- Description:Java污点分析checker,不会使用CallGraph边界制作entrypoint,蚂蚁内部使用 File:/src/main/java/com/sast/astbenchmark/case_language_maturity/completeness/single_app_tracing/datatype/collections/Base_Set_005_T.java Line 32: SinkUtil.sink(stringSet) @@ -1709,7 +1685,7 @@ Trace: AffectedNodeName: SinkUtil.sink 32: SINK: SinkUtil.sink(stringSet); -------------- 69: taint_flow_java_input_inner------------- +------------- 76: taint_flow_java_input_inner------------- Description:Java污点分析checker,不会使用CallGraph边界制作entrypoint,蚂蚁内部使用 File:/src/main/java/com/sast/astbenchmark/case_language_maturity/completeness/single_app_tracing/datatype/generics/CallExpression_CustomCode_Class_generics_001_T.java Line 28: Runtime.getRuntime().exec(a.getCmd()) @@ -1724,12 +1700,6 @@ Trace: /src/main/java/com/sast/astbenchmark/case_language_maturity/completeness/single_app_tracing/datatype/generics/CallExpression_CustomCode_Class_generics_001_T.java AffectedNodeName: _CTOR_ 27: CALL: G a = new G<>(cmd); - /src/main/java/com/sast/astbenchmark/model/custom/G.java - AffectedNodeName: cmd - 6: ARG PASS: public G(T cmd) { - /src/main/java/com/sast/astbenchmark/model/custom/G.java - AffectedNodeName: [this.cmd] - 7: Var Pass: this.cmd = cmd; /src/main/java/com/sast/astbenchmark/case_language_maturity/completeness/single_app_tracing/datatype/generics/CallExpression_CustomCode_Class_generics_001_T.java AffectedNodeName: a 27: Var Pass: G a = new G<>(cmd); @@ -1739,9 +1709,6 @@ Trace: /src/main/java/com/sast/astbenchmark/case_language_maturity/completeness/single_app_tracing/datatype/generics/CallExpression_CustomCode_Class_generics_001_T.java AffectedNodeName: a 28: ARG PASS: Runtime.getRuntime().exec(a.getCmd()); - /src/main/java/com/sast/astbenchmark/model/custom/G.java - AffectedNodeName: [return value] - 11: Return Value: return this.cmd; /src/main/java/com/sast/astbenchmark/case_language_maturity/completeness/single_app_tracing/datatype/generics/CallExpression_CustomCode_Class_generics_001_T.java AffectedNodeName: getCmd 28: CALL RETURN: Runtime.getRuntime().exec(a.getCmd()); @@ -1749,7 +1716,7 @@ Trace: AffectedNodeName: Runtime.getRuntime().exec 28: SINK: Runtime.getRuntime().exec(a.getCmd()); -------------- 70: taint_flow_java_input_inner------------- +------------- 77: taint_flow_java_input_inner------------- Description:Java污点分析checker,不会使用CallGraph边界制作entrypoint,蚂蚁内部使用 File:/src/main/java/com/sast/astbenchmark/case_language_maturity/completeness/single_app_tracing/datatype/generics/CallExpression_CustomCode_Class_generics_003_T.java Line 28: Runtime.getRuntime().exec((String)a.getCmd()) @@ -1764,12 +1731,6 @@ Trace: /src/main/java/com/sast/astbenchmark/case_language_maturity/completeness/single_app_tracing/datatype/generics/CallExpression_CustomCode_Class_generics_003_T.java AffectedNodeName: _CTOR_ 26: CALL: G a = new G<>(cmd); - /src/main/java/com/sast/astbenchmark/model/custom/G.java - AffectedNodeName: cmd - 6: ARG PASS: public G(T cmd) { - /src/main/java/com/sast/astbenchmark/model/custom/G.java - AffectedNodeName: [this.cmd] - 7: Var Pass: this.cmd = cmd; /src/main/java/com/sast/astbenchmark/case_language_maturity/completeness/single_app_tracing/datatype/generics/CallExpression_CustomCode_Class_generics_003_T.java AffectedNodeName: a 26: Var Pass: G a = new G<>(cmd); @@ -1779,9 +1740,6 @@ Trace: /src/main/java/com/sast/astbenchmark/case_language_maturity/completeness/single_app_tracing/datatype/generics/CallExpression_CustomCode_Class_generics_003_T.java AffectedNodeName: a 28: ARG PASS: Runtime.getRuntime().exec((String) a.getCmd()); - /src/main/java/com/sast/astbenchmark/model/custom/G.java - AffectedNodeName: [return value] - 11: Return Value: return this.cmd; /src/main/java/com/sast/astbenchmark/case_language_maturity/completeness/single_app_tracing/datatype/generics/CallExpression_CustomCode_Class_generics_003_T.java AffectedNodeName: getCmd 28: CALL RETURN: Runtime.getRuntime().exec((String) a.getCmd()); @@ -1789,7 +1747,7 @@ Trace: AffectedNodeName: Runtime.getRuntime().exec 28: SINK: Runtime.getRuntime().exec((String) a.getCmd()); -------------- 71: taint_flow_java_input_inner------------- +------------- 78: taint_flow_java_input_inner------------- Description:Java污点分析checker,不会使用CallGraph边界制作entrypoint,蚂蚁内部使用 File:/src/main/java/com/sast/astbenchmark/case_language_maturity/completeness/single_app_tracing/datatype/map/Base_Map_001_T.java Line 33: SinkUtil.sink(cmd) @@ -1805,7 +1763,7 @@ Trace: AffectedNodeName: SinkUtil.sink 33: SINK: SinkUtil.sink(cmd); -------------- 72: taint_flow_java_input_inner------------- +------------- 79: taint_flow_java_input_inner------------- Description:Java污点分析checker,不会使用CallGraph边界制作entrypoint,蚂蚁内部使用 File:/src/main/java/com/sast/astbenchmark/case_language_maturity/completeness/single_app_tracing/datatype/map/Base_Map_003_T.java Line 31: Runtime.getRuntime().exec(String.valueOf(cmd)) @@ -1821,7 +1779,7 @@ Trace: AffectedNodeName: Runtime.getRuntime().exec 31: SINK: Runtime.getRuntime().exec(String.valueOf(cmd)); -------------- 73: taint_flow_java_input_inner------------- +------------- 80: taint_flow_java_input_inner------------- Description:Java污点分析checker,不会使用CallGraph边界制作entrypoint,蚂蚁内部使用 File:/src/main/java/com/sast/astbenchmark/case_language_maturity/completeness/single_app_tracing/datatype/primitives/Base_ByteArray_001_T.java Line 33: SinkUtil.sink(cmd) @@ -1837,7 +1795,7 @@ Trace: AffectedNodeName: SinkUtil.sink 33: SINK: SinkUtil.sink(cmd); -------------- 74: taint_flow_java_input_inner------------- +------------- 81: taint_flow_java_input_inner------------- Description:Java污点分析checker,不会使用CallGraph边界制作entrypoint,蚂蚁内部使用 File:/src/main/java/com/sast/astbenchmark/case_language_maturity/completeness/single_app_tracing/datatype/primitives/Base_ByteArray_003_T.java Line 31: Runtime.getRuntime().exec(String.valueOf(cmd)) @@ -1853,7 +1811,7 @@ Trace: AffectedNodeName: Runtime.getRuntime().exec 31: SINK: Runtime.getRuntime().exec(String.valueOf(cmd)); -------------- 75: taint_flow_java_input_inner------------- +------------- 82: taint_flow_java_input_inner------------- Description:Java污点分析checker,不会使用CallGraph边界制作entrypoint,蚂蚁内部使用 File:/src/main/java/com/sast/astbenchmark/case_language_maturity/completeness/single_app_tracing/datatype/primitives/Base_Byte_001_T.java Line 29: SinkUtil.sink(cmd) @@ -1869,7 +1827,7 @@ Trace: AffectedNodeName: SinkUtil.sink 29: SINK: SinkUtil.sink(cmd); -------------- 76: taint_flow_java_input_inner------------- +------------- 83: taint_flow_java_input_inner------------- Description:Java污点分析checker,不会使用CallGraph边界制作entrypoint,蚂蚁内部使用 File:/src/main/java/com/sast/astbenchmark/case_language_maturity/completeness/single_app_tracing/datatype/primitives/Base_Byte_003_T.java Line 33: SinkUtil.sink(cmd) @@ -1885,7 +1843,7 @@ Trace: AffectedNodeName: SinkUtil.sink 33: SINK: SinkUtil.sink(cmd); -------------- 77: taint_flow_java_input_inner------------- +------------- 84: taint_flow_java_input_inner------------- Description:Java污点分析checker,不会使用CallGraph边界制作entrypoint,蚂蚁内部使用 File:/src/main/java/com/sast/astbenchmark/case_language_maturity/completeness/single_app_tracing/datatype/primitives/Base_Byte_005_T.java Line 27: Runtime.getRuntime().exec(String.valueOf(cmd)) @@ -1901,7 +1859,7 @@ Trace: AffectedNodeName: Runtime.getRuntime().exec 27: SINK: Runtime.getRuntime().exec(String.valueOf(cmd)); -------------- 78: taint_flow_java_input_inner------------- +------------- 85: taint_flow_java_input_inner------------- Description:Java污点分析checker,不会使用CallGraph边界制作entrypoint,蚂蚁内部使用 File:/src/main/java/com/sast/astbenchmark/case_language_maturity/completeness/single_app_tracing/datatype/primitives/Base_Byte_007_T.java Line 31: Runtime.getRuntime().exec(String.valueOf(cmd)) @@ -1917,7 +1875,7 @@ Trace: AffectedNodeName: Runtime.getRuntime().exec 31: SINK: Runtime.getRuntime().exec(String.valueOf(cmd)); -------------- 79: taint_flow_java_input_inner------------- +------------- 86: taint_flow_java_input_inner------------- Description:Java污点分析checker,不会使用CallGraph边界制作entrypoint,蚂蚁内部使用 File:/src/main/java/com/sast/astbenchmark/case_language_maturity/completeness/single_app_tracing/datatype/primitives/Base_CharArray_001_T.java Line 33: SinkUtil.sink(cmd) @@ -1933,7 +1891,7 @@ Trace: AffectedNodeName: SinkUtil.sink 33: SINK: SinkUtil.sink(cmd); -------------- 80: taint_flow_java_input_inner------------- +------------- 87: taint_flow_java_input_inner------------- Description:Java污点分析checker,不会使用CallGraph边界制作entrypoint,蚂蚁内部使用 File:/src/main/java/com/sast/astbenchmark/case_language_maturity/completeness/single_app_tracing/datatype/primitives/Base_CharArray_003_T.java Line 31: Runtime.getRuntime().exec(String.valueOf(cmd)) @@ -1949,7 +1907,7 @@ Trace: AffectedNodeName: Runtime.getRuntime().exec 31: SINK: Runtime.getRuntime().exec(String.valueOf(cmd)); -------------- 81: taint_flow_java_input_inner------------- +------------- 88: taint_flow_java_input_inner------------- Description:Java污点分析checker,不会使用CallGraph边界制作entrypoint,蚂蚁内部使用 File:/src/main/java/com/sast/astbenchmark/case_language_maturity/completeness/single_app_tracing/datatype/primitives/Base_Char_001_T.java Line 29: SinkUtil.sink(cmd) @@ -1965,7 +1923,7 @@ Trace: AffectedNodeName: SinkUtil.sink 29: SINK: SinkUtil.sink(cmd); -------------- 82: taint_flow_java_input_inner------------- +------------- 89: taint_flow_java_input_inner------------- Description:Java污点分析checker,不会使用CallGraph边界制作entrypoint,蚂蚁内部使用 File:/src/main/java/com/sast/astbenchmark/case_language_maturity/completeness/single_app_tracing/datatype/primitives/Base_Char_003_T.java Line 33: SinkUtil.sink(cmd) @@ -1981,7 +1939,7 @@ Trace: AffectedNodeName: SinkUtil.sink 33: SINK: SinkUtil.sink(cmd); -------------- 83: taint_flow_java_input_inner------------- +------------- 90: taint_flow_java_input_inner------------- Description:Java污点分析checker,不会使用CallGraph边界制作entrypoint,蚂蚁内部使用 File:/src/main/java/com/sast/astbenchmark/case_language_maturity/completeness/single_app_tracing/datatype/primitives/Base_Char_005_T.java Line 26: Runtime.getRuntime().exec(String.valueOf(cmd)) @@ -1997,7 +1955,7 @@ Trace: AffectedNodeName: Runtime.getRuntime().exec 26: SINK: Runtime.getRuntime().exec(String.valueOf(cmd)); -------------- 84: taint_flow_java_input_inner------------- +------------- 91: taint_flow_java_input_inner------------- Description:Java污点分析checker,不会使用CallGraph边界制作entrypoint,蚂蚁内部使用 File:/src/main/java/com/sast/astbenchmark/case_language_maturity/completeness/single_app_tracing/datatype/primitives/Base_Char_007_T.java Line 31: Runtime.getRuntime().exec(String.valueOf(cmd)) @@ -2013,7 +1971,7 @@ Trace: AffectedNodeName: Runtime.getRuntime().exec 31: SINK: Runtime.getRuntime().exec(String.valueOf(cmd)); -------------- 85: taint_flow_java_input_inner------------- +------------- 92: taint_flow_java_input_inner------------- Description:Java污点分析checker,不会使用CallGraph边界制作entrypoint,蚂蚁内部使用 File:/src/main/java/com/sast/astbenchmark/case_language_maturity/completeness/single_app_tracing/datatype/primitives/Base_Double_001_T.java Line 29: SinkUtil.sink(cmd) @@ -2029,7 +1987,7 @@ Trace: AffectedNodeName: SinkUtil.sink 29: SINK: SinkUtil.sink(cmd); -------------- 86: taint_flow_java_input_inner------------- +------------- 93: taint_flow_java_input_inner------------- Description:Java污点分析checker,不会使用CallGraph边界制作entrypoint,蚂蚁内部使用 File:/src/main/java/com/sast/astbenchmark/case_language_maturity/completeness/single_app_tracing/datatype/primitives/Base_Double_003_T.java Line 30: Runtime.getRuntime().exec(String.valueOf(cmd)) @@ -2045,7 +2003,7 @@ Trace: AffectedNodeName: Runtime.getRuntime().exec 30: SINK: Runtime.getRuntime().exec(String.valueOf(cmd)); -------------- 87: taint_flow_java_input_inner------------- +------------- 94: taint_flow_java_input_inner------------- Description:Java污点分析checker,不会使用CallGraph边界制作entrypoint,蚂蚁内部使用 File:/src/main/java/com/sast/astbenchmark/case_language_maturity/completeness/single_app_tracing/datatype/primitives/Base_Float_001_T.java Line 29: SinkUtil.sink(cmd) @@ -2061,7 +2019,7 @@ Trace: AffectedNodeName: SinkUtil.sink 29: SINK: SinkUtil.sink(cmd); -------------- 88: taint_flow_java_input_inner------------- +------------- 95: taint_flow_java_input_inner------------- Description:Java污点分析checker,不会使用CallGraph边界制作entrypoint,蚂蚁内部使用 File:/src/main/java/com/sast/astbenchmark/case_language_maturity/completeness/single_app_tracing/datatype/primitives/Base_Float_003_T.java Line 30: Runtime.getRuntime().exec(String.valueOf(cmd)) @@ -2077,7 +2035,7 @@ Trace: AffectedNodeName: Runtime.getRuntime().exec 30: SINK: Runtime.getRuntime().exec(String.valueOf(cmd)); -------------- 89: taint_flow_java_input_inner------------- +------------- 96: taint_flow_java_input_inner------------- Description:Java污点分析checker,不会使用CallGraph边界制作entrypoint,蚂蚁内部使用 File:/src/main/java/com/sast/astbenchmark/case_language_maturity/completeness/single_app_tracing/datatype/primitives/Base_Integer_001_T.java Line 33: SinkUtil.sink(cmd) @@ -2093,7 +2051,7 @@ Trace: AffectedNodeName: SinkUtil.sink 33: SINK: SinkUtil.sink(cmd); -------------- 90: taint_flow_java_input_inner------------- +------------- 97: taint_flow_java_input_inner------------- Description:Java污点分析checker,不会使用CallGraph边界制作entrypoint,蚂蚁内部使用 File:/src/main/java/com/sast/astbenchmark/case_language_maturity/completeness/single_app_tracing/datatype/primitives/Base_Integer_003_T.java Line 31: Runtime.getRuntime().exec(String.valueOf(cmd)) @@ -2109,7 +2067,7 @@ Trace: AffectedNodeName: Runtime.getRuntime().exec 31: SINK: Runtime.getRuntime().exec(String.valueOf(cmd)); -------------- 91: taint_flow_java_input_inner------------- +------------- 98: taint_flow_java_input_inner------------- Description:Java污点分析checker,不会使用CallGraph边界制作entrypoint,蚂蚁内部使用 File:/src/main/java/com/sast/astbenchmark/case_language_maturity/completeness/single_app_tracing/datatype/primitives/Base_Integer_005_T.java Line 26: SinkUtil.sink(cmd) @@ -2125,7 +2083,7 @@ Trace: AffectedNodeName: SinkUtil.sink 26: SINK: SinkUtil.sink(cmd); -------------- 92: taint_flow_java_input_inner------------- +------------- 99: taint_flow_java_input_inner------------- Description:Java污点分析checker,不会使用CallGraph边界制作entrypoint,蚂蚁内部使用 File:/src/main/java/com/sast/astbenchmark/case_language_maturity/completeness/single_app_tracing/datatype/primitives/Base_Integer_007_T.java Line 26: Runtime.getRuntime().exec(String.valueOf(cmd)) @@ -2141,7 +2099,7 @@ Trace: AffectedNodeName: Runtime.getRuntime().exec 26: SINK: Runtime.getRuntime().exec(String.valueOf(cmd)); -------------- 93: taint_flow_java_input_inner------------- +------------- 100: taint_flow_java_input_inner------------- Description:Java污点分析checker,不会使用CallGraph边界制作entrypoint,蚂蚁内部使用 File:/src/main/java/com/sast/astbenchmark/case_language_maturity/completeness/single_app_tracing/datatype/primitives/Base_Long_001_T.java Line 29: SinkUtil.sink(cmd) @@ -2157,7 +2115,7 @@ Trace: AffectedNodeName: SinkUtil.sink 29: SINK: SinkUtil.sink(cmd); -------------- 94: taint_flow_java_input_inner------------- +------------- 101: taint_flow_java_input_inner------------- Description:Java污点分析checker,不会使用CallGraph边界制作entrypoint,蚂蚁内部使用 File:/src/main/java/com/sast/astbenchmark/case_language_maturity/completeness/single_app_tracing/datatype/primitives/Base_Long_003_T.java Line 33: SinkUtil.sink(cmd) @@ -2173,7 +2131,7 @@ Trace: AffectedNodeName: SinkUtil.sink 33: SINK: SinkUtil.sink(cmd); -------------- 95: taint_flow_java_input_inner------------- +------------- 102: taint_flow_java_input_inner------------- Description:Java污点分析checker,不会使用CallGraph边界制作entrypoint,蚂蚁内部使用 File:/src/main/java/com/sast/astbenchmark/case_language_maturity/completeness/single_app_tracing/datatype/primitives/Base_Long_005_T.java Line 27: Runtime.getRuntime().exec(String.valueOf(cmd)) @@ -2189,7 +2147,7 @@ Trace: AffectedNodeName: Runtime.getRuntime().exec 27: SINK: Runtime.getRuntime().exec(String.valueOf(cmd)); -------------- 96: taint_flow_java_input_inner------------- +------------- 103: taint_flow_java_input_inner------------- Description:Java污点分析checker,不会使用CallGraph边界制作entrypoint,蚂蚁内部使用 File:/src/main/java/com/sast/astbenchmark/case_language_maturity/completeness/single_app_tracing/datatype/primitives/Base_Long_007_T.java Line 31: Runtime.getRuntime().exec(String.valueOf(cmd)) @@ -2205,7 +2163,7 @@ Trace: AffectedNodeName: Runtime.getRuntime().exec 31: SINK: Runtime.getRuntime().exec(String.valueOf(cmd)); -------------- 97: taint_flow_java_input_inner------------- +------------- 104: taint_flow_java_input_inner------------- Description:Java污点分析checker,不会使用CallGraph边界制作entrypoint,蚂蚁内部使用 File:/src/main/java/com/sast/astbenchmark/case_language_maturity/completeness/single_app_tracing/datatype/string/Base_StringArray_001_T.java Line 31: Runtime.getRuntime().exec(cmd.0) @@ -2221,7 +2179,7 @@ Trace: AffectedNodeName: Runtime.getRuntime().exec 31: SINK: Runtime.getRuntime().exec(cmd[0]); -------------- 98: taint_flow_java_input_inner------------- +------------- 105: taint_flow_java_input_inner------------- Description:Java污点分析checker,不会使用CallGraph边界制作entrypoint,蚂蚁内部使用 File:/src/main/java/com/sast/astbenchmark/case_language_maturity/completeness/single_app_tracing/datatype/string/Base_StringBuffer_001_T.java Line 33: Runtime.getRuntime().exec(data.toString()) @@ -2240,7 +2198,7 @@ Trace: AffectedNodeName: Runtime.getRuntime().exec 33: SINK: Runtime.getRuntime().exec(data.toString()); -------------- 99: taint_flow_java_input_inner------------- +------------- 106: taint_flow_java_input_inner------------- Description:Java污点分析checker,不会使用CallGraph边界制作entrypoint,蚂蚁内部使用 File:/src/main/java/com/sast/astbenchmark/case_language_maturity/completeness/single_app_tracing/datatype/string/Base_StringBuilder_001_T.java Line 33: Runtime.getRuntime().exec(data.toString()) @@ -2259,7 +2217,7 @@ Trace: AffectedNodeName: Runtime.getRuntime().exec 33: SINK: Runtime.getRuntime().exec(data.toString()); -------------- 100: taint_flow_java_input_inner------------- +------------- 107: taint_flow_java_input_inner------------- Description:Java污点分析checker,不会使用CallGraph边界制作entrypoint,蚂蚁内部使用 File:/src/main/java/com/sast/astbenchmark/case_language_maturity/completeness/single_app_tracing/datatype/string/Base_String_001_T.java Line 31: Runtime.getRuntime().exec(cmd) @@ -2275,7 +2233,7 @@ Trace: AffectedNodeName: Runtime.getRuntime().exec 31: SINK: Runtime.getRuntime().exec(cmd); -------------- 101: taint_flow_java_input_inner------------- +------------- 108: taint_flow_java_input_inner------------- Description:Java污点分析checker,不会使用CallGraph边界制作entrypoint,蚂蚁内部使用 File:/src/main/java/com/sast/astbenchmark/case_language_maturity/completeness/single_app_tracing/interface_class/abstract_class/CallExpression_CustomCode_abstract_class_001_T.java Line 32: Runtime.getRuntime().exec(ac.getCmd()) @@ -2290,15 +2248,6 @@ Trace: /src/main/java/com/sast/astbenchmark/case_language_maturity/completeness/single_app_tracing/interface_class/abstract_class/CallExpression_CustomCode_abstract_class_001_T.java AffectedNodeName: setCmd 31: CALL: ac.setCmd(cmd); - /src/main/java/com/sast/astbenchmark/model/custom/ABS.java - AffectedNodeName: cmd - 5: ARG PASS: public void setCmd(String cmd){ - /src/main/java/com/sast/astbenchmark/model/custom/ABS.java - AffectedNodeName: [this.cmd] - 6: Var Pass: this.cmd = cmd; - /src/main/java/com/sast/astbenchmark/model/custom/AC.java - AffectedNodeName: [return value] - 6: Return Value: return super.cmd; /src/main/java/com/sast/astbenchmark/case_language_maturity/completeness/single_app_tracing/interface_class/abstract_class/CallExpression_CustomCode_abstract_class_001_T.java AffectedNodeName: getCmd 32: CALL RETURN: Runtime.getRuntime().exec(ac.getCmd()); @@ -2306,7 +2255,7 @@ Trace: AffectedNodeName: Runtime.getRuntime().exec 32: SINK: Runtime.getRuntime().exec(ac.getCmd()); -------------- 102: taint_flow_java_input_inner------------- +------------- 109: taint_flow_java_input_inner------------- Description:Java污点分析checker,不会使用CallGraph边界制作entrypoint,蚂蚁内部使用 File:/src/main/java/com/sast/astbenchmark/case_language_maturity/completeness/single_app_tracing/interface_class/anonymous_object/CallExpression_CustomCode_anonymous_object_001_T.java Line 35: Runtime.getRuntime().exec(ac.getCmd()) @@ -2321,12 +2270,6 @@ Trace: /src/main/java/com/sast/astbenchmark/case_language_maturity/completeness/single_app_tracing/interface_class/anonymous_object/CallExpression_CustomCode_anonymous_object_001_T.java AffectedNodeName: setCmd 34: CALL: ac.setCmd(cmd); - /src/main/java/com/sast/astbenchmark/model/custom/ABS.java - AffectedNodeName: cmd - 5: ARG PASS: public void setCmd(String cmd){ - /src/main/java/com/sast/astbenchmark/model/custom/ABS.java - AffectedNodeName: [this.cmd] - 6: Var Pass: this.cmd = cmd; /src/main/java/com/sast/astbenchmark/case_language_maturity/completeness/single_app_tracing/interface_class/anonymous_object/CallExpression_CustomCode_anonymous_object_001_T.java AffectedNodeName: getCmd 35: CALL: Runtime.getRuntime().exec(ac.getCmd()); @@ -2343,7 +2286,7 @@ Trace: AffectedNodeName: Runtime.getRuntime().exec 35: SINK: Runtime.getRuntime().exec(ac.getCmd()); -------------- 103: taint_flow_java_input_inner------------- +------------- 110: taint_flow_java_input_inner------------- Description:Java污点分析checker,不会使用CallGraph边界制作entrypoint,蚂蚁内部使用 File:/src/main/java/com/sast/astbenchmark/case_language_maturity/completeness/single_app_tracing/interface_class/complex_object/CallExpression_CustomCode_Class_001_T.java Line 28: Runtime.getRuntime().exec(a.getCmd()) @@ -2358,12 +2301,6 @@ Trace: /src/main/java/com/sast/astbenchmark/case_language_maturity/completeness/single_app_tracing/interface_class/complex_object/CallExpression_CustomCode_Class_001_T.java AffectedNodeName: _CTOR_ 26: CALL: O a = new O(cmd); - /src/main/java/com/sast/astbenchmark/model/custom/O.java - AffectedNodeName: cmd - 6: ARG PASS: public O(String cmd){ - /src/main/java/com/sast/astbenchmark/model/custom/O.java - AffectedNodeName: [this.cmd] - 7: Var Pass: this.cmd = cmd; /src/main/java/com/sast/astbenchmark/case_language_maturity/completeness/single_app_tracing/interface_class/complex_object/CallExpression_CustomCode_Class_001_T.java AffectedNodeName: a 26: Var Pass: O a = new O(cmd); @@ -2373,15 +2310,6 @@ Trace: /src/main/java/com/sast/astbenchmark/case_language_maturity/completeness/single_app_tracing/interface_class/complex_object/CallExpression_CustomCode_Class_001_T.java AffectedNodeName: a 28: ARG PASS: Runtime.getRuntime().exec(a.getCmd()); - /src/main/java/com/sast/astbenchmark/model/custom/O.java - AffectedNodeName: [return value] - 12: Return Value: return O.this.cmd; - /src/main/java/com/sast/astbenchmark/model/custom/O.java - AffectedNodeName: getCmd - 18: CALL RETURN: return i.getCmd(); - /src/main/java/com/sast/astbenchmark/model/custom/O.java - AffectedNodeName: [return value] - 18: Return Value: return i.getCmd(); /src/main/java/com/sast/astbenchmark/case_language_maturity/completeness/single_app_tracing/interface_class/complex_object/CallExpression_CustomCode_Class_001_T.java AffectedNodeName: getCmd 28: CALL RETURN: Runtime.getRuntime().exec(a.getCmd()); @@ -2389,7 +2317,7 @@ Trace: AffectedNodeName: Runtime.getRuntime().exec 28: SINK: Runtime.getRuntime().exec(a.getCmd()); -------------- 104: taint_flow_java_input_inner------------- +------------- 111: taint_flow_java_input_inner------------- Description:Java污点分析checker,不会使用CallGraph边界制作entrypoint,蚂蚁内部使用 File:/src/main/java/com/sast/astbenchmark/case_language_maturity/completeness/single_app_tracing/interface_class/complex_object/CallExpression_CustomCode_Class_003_T.java Line 26: Runtime.getRuntime().exec(local(cmd)) @@ -2404,18 +2332,6 @@ Trace: /src/main/java/com/sast/astbenchmark/case_language_maturity/completeness/single_app_tracing/interface_class/complex_object/CallExpression_CustomCode_Class_003_T.java AffectedNodeName: local 26: CALL: Runtime.getRuntime().exec(local(cmd)); - /src/main/java/com/sast/astbenchmark/case_language_maturity/completeness/single_app_tracing/interface_class/complex_object/CallExpression_CustomCode_Class_003_T.java - AffectedNodeName: cmd - 34: ARG PASS: public static String local(String cmd) { - /src/main/java/com/sast/astbenchmark/case_language_maturity/completeness/single_app_tracing/interface_class/complex_object/CallExpression_CustomCode_Class_003_T.java - AffectedNodeName: [return value] - 37: Return Value: return cmd; - /src/main/java/com/sast/astbenchmark/case_language_maturity/completeness/single_app_tracing/interface_class/complex_object/CallExpression_CustomCode_Class_003_T.java - AffectedNodeName: getCmd - 41: CALL RETURN: return local.getCmd(); - /src/main/java/com/sast/astbenchmark/case_language_maturity/completeness/single_app_tracing/interface_class/complex_object/CallExpression_CustomCode_Class_003_T.java - AffectedNodeName: [return value] - 41: Return Value: return local.getCmd(); /src/main/java/com/sast/astbenchmark/case_language_maturity/completeness/single_app_tracing/interface_class/complex_object/CallExpression_CustomCode_Class_003_T.java AffectedNodeName: local 26: CALL RETURN: Runtime.getRuntime().exec(local(cmd)); @@ -2423,7 +2339,7 @@ Trace: AffectedNodeName: Runtime.getRuntime().exec 26: SINK: Runtime.getRuntime().exec(local(cmd)); -------------- 105: taint_flow_java_input_inner------------- +------------- 112: taint_flow_java_input_inner------------- Description:Java污点分析checker,不会使用CallGraph边界制作entrypoint,蚂蚁内部使用 File:/src/main/java/com/sast/astbenchmark/case_language_maturity/completeness/single_app_tracing/interface_class/complex_object/CallExpression_CustomCode_Interface_001_T.java Line 28: Runtime.getRuntime().exec(s.getCmd(ls, cmd)) @@ -2436,19 +2352,19 @@ Trace: AffectedNodeName: cmd 24: SOURCE: public Map testcase(@PathVariable String cmd) { /src/main/java/com/sast/astbenchmark/case_language_maturity/completeness/single_app_tracing/interface_class/complex_object/CallExpression_CustomCode_Interface_001_T.java - AffectedNodeName: + AffectedNodeName: 28: CALL: Runtime.getRuntime().exec(s.getCmd("ls", cmd)); /src/main/java/com/sast/astbenchmark/case_language_maturity/completeness/single_app_tracing/interface_class/complex_object/CallExpression_CustomCode_Interface_001_T.java AffectedNodeName: b 27: ARG PASS: Inter s = (Serializable & Inter) (a, b) -> a + b; /src/main/java/com/sast/astbenchmark/case_language_maturity/completeness/single_app_tracing/interface_class/complex_object/CallExpression_CustomCode_Interface_001_T.java - AffectedNodeName: + AffectedNodeName: 28: CALL RETURN: Runtime.getRuntime().exec(s.getCmd("ls", cmd)); /src/main/java/com/sast/astbenchmark/case_language_maturity/completeness/single_app_tracing/interface_class/complex_object/CallExpression_CustomCode_Interface_001_T.java AffectedNodeName: Runtime.getRuntime().exec 28: SINK: Runtime.getRuntime().exec(s.getCmd("ls", cmd)); -------------- 106: taint_flow_java_input_inner------------- +------------- 113: taint_flow_java_input_inner------------- Description:Java污点分析checker,不会使用CallGraph边界制作entrypoint,蚂蚁内部使用 File:/src/main/java/com/sast/astbenchmark/case_language_maturity/completeness/single_app_tracing/interface_class/simple_object/simple_object_001_T.java Line 29: SinkUtil.sink(a) @@ -2463,12 +2379,6 @@ Trace: /src/main/java/com/sast/astbenchmark/case_language_maturity/completeness/single_app_tracing/interface_class/simple_object/simple_object_001_T.java AffectedNodeName: _CTOR_ 27: CALL: O a = new O(cmd); - /src/main/java/com/sast/astbenchmark/model/custom/O.java - AffectedNodeName: cmd - 6: ARG PASS: public O(String cmd){ - /src/main/java/com/sast/astbenchmark/model/custom/O.java - AffectedNodeName: [this.cmd] - 7: Var Pass: this.cmd = cmd; /src/main/java/com/sast/astbenchmark/case_language_maturity/completeness/single_app_tracing/interface_class/simple_object/simple_object_001_T.java AffectedNodeName: a 27: Var Pass: O a = new O(cmd); @@ -2476,7 +2386,7 @@ Trace: AffectedNodeName: SinkUtil.sink 29: SINK: SinkUtil.sink(a); -------------- 107: taint_flow_java_input_inner------------- +------------- 114: taint_flow_java_input_inner------------- Description:Java污点分析checker,不会使用CallGraph边界制作entrypoint,蚂蚁内部使用 File:/src/main/java/com/sast/astbenchmark/case_language_maturity/completeness/single_app_tracing/variable_scope/static_variable/static_variable_001_T.java Line 29: SinkUtil.sink(P.t) @@ -2489,13 +2399,13 @@ Trace: AffectedNodeName: cmd 25: SOURCE: public Map testcase(@RequestParam String cmd) { /src/main/java/com/sast/astbenchmark/case_language_maturity/completeness/single_app_tracing/variable_scope/static_variable/static_variable_001_T.java - AffectedNodeName: [P.t] + AffectedNodeName: P.t 27: Var Pass: P.t = cmd; /src/main/java/com/sast/astbenchmark/case_language_maturity/completeness/single_app_tracing/variable_scope/static_variable/static_variable_001_T.java AffectedNodeName: SinkUtil.sink 29: SINK: SinkUtil.sink(P.t); -------------- 108: taint_flow_java_input_inner------------- +------------- 115: taint_flow_java_input_inner------------- Description:Java污点分析checker,不会使用CallGraph边界制作entrypoint,蚂蚁内部使用 File:/src/main/java/com/sast/astbenchmark/model/custom/T.java Line 16: Runtime.getRuntime().exec(this.cmd) @@ -2510,12 +2420,6 @@ Trace: /src/main/java/com/sast/astbenchmark/case_language_maturity/completeness/single_app_tracing/asynchronous_tracing/multi_thread/Async_Multithreading_001_T.java AffectedNodeName: _CTOR_ 24: CALL: T t = new T(cmd); - /src/main/java/com/sast/astbenchmark/model/custom/T.java - AffectedNodeName: cmd - 10: ARG PASS: public T(String cmd) { - /src/main/java/com/sast/astbenchmark/model/custom/T.java - AffectedNodeName: [this.cmd] - 11: Var Pass: this.cmd = cmd; /src/main/java/com/sast/astbenchmark/case_language_maturity/completeness/single_app_tracing/asynchronous_tracing/multi_thread/Async_Multithreading_001_T.java AffectedNodeName: t 24: Var Pass: T t = new T(cmd); @@ -2529,7 +2433,7 @@ Trace: AffectedNodeName: Runtime.getRuntime().exec 16: SINK: Runtime.getRuntime().exec(this.cmd); -------------- 109: taint_flow_java_input_inner------------- +------------- 116: taint_flow_java_input_inner------------- Description:Java污点分析checker,不会使用CallGraph边界制作entrypoint,蚂蚁内部使用 File:/src/main/java/com/sast/astbenchmark/case_language_maturity/completeness/single_app_tracing/asynchronous_tracing/multi_thread/Async_Multithreading_003_T.java Line 30: Runtime.getRuntime().exec(cmd) @@ -2545,7 +2449,7 @@ Trace: AffectedNodeName: Runtime.getRuntime().exec 30: SINK: Runtime.getRuntime().exec(cmd); -------------- 110: taint_flow_java_input_inner------------- +------------- 117: taint_flow_java_input_inner------------- Description:Java污点分析checker,不会使用CallGraph边界制作entrypoint,蚂蚁内部使用 File:/src/main/java/com/sast/astbenchmark/model/custom/R.java Line 16: Runtime.getRuntime().exec(this.cmd) @@ -2560,25 +2464,20 @@ Trace: /src/main/java/com/sast/astbenchmark/case_language_maturity/completeness/single_app_tracing/asynchronous_tracing/multi_thread/Async_Multithreading_005_T.java AffectedNodeName: _CTOR_ 25: CALL: R r = new R(cmd); - /src/main/java/com/sast/astbenchmark/model/custom/R.java - AffectedNodeName: cmd - 10: ARG PASS: public R(String cmd) { - /src/main/java/com/sast/astbenchmark/model/custom/R.java - AffectedNodeName: [this.cmd] - 11: Var Pass: this.cmd = cmd; /src/main/java/com/sast/astbenchmark/case_language_maturity/completeness/single_app_tracing/asynchronous_tracing/multi_thread/Async_Multithreading_005_T.java AffectedNodeName: r 25: Var Pass: R r = new R(cmd); /src/main/java/com/sast/astbenchmark/case_language_maturity/completeness/single_app_tracing/asynchronous_tracing/multi_thread/Async_Multithreading_005_T.java - AffectedNodeName: execute + AffectedNodeName: run 26: CALL: Executors.newCachedThreadPool().execute(r); /src/main/java/com/sast/astbenchmark/case_language_maturity/completeness/single_app_tracing/asynchronous_tracing/multi_thread/Async_Multithreading_005_T.java + AffectedNodeName: Executors.newCachedThreadPool() 26: ARG PASS: Executors.newCachedThreadPool().execute(r); /src/main/java/com/sast/astbenchmark/model/custom/R.java AffectedNodeName: Runtime.getRuntime().exec 16: SINK: Runtime.getRuntime().exec(this.cmd); -------------- 111: taint_flow_java_input_inner------------- +------------- 118: taint_flow_java_input_inner------------- Description:Java污点分析checker,不会使用CallGraph边界制作entrypoint,蚂蚁内部使用 File:/src/main/java/com/sast/astbenchmark/model/custom/TT.java Line 18: Runtime.getRuntime().exec(this.cmd) @@ -2593,17 +2492,11 @@ Trace: /src/main/java/com/sast/astbenchmark/case_language_maturity/completeness/single_app_tracing/asynchronous_tracing/multi_thread/Async_Multithreading_007_T.java AffectedNodeName: _CTOR_ 26: CALL: TT tt = new TT(cmd); - /src/main/java/com/sast/astbenchmark/model/custom/TT.java - AffectedNodeName: cmd - 12: ARG PASS: public TT(String cmd) { - /src/main/java/com/sast/astbenchmark/model/custom/TT.java - AffectedNodeName: [this.cmd] - 13: Var Pass: this.cmd = cmd; /src/main/java/com/sast/astbenchmark/case_language_maturity/completeness/single_app_tracing/asynchronous_tracing/multi_thread/Async_Multithreading_007_T.java AffectedNodeName: tt 26: Var Pass: TT tt = new TT(cmd); /src/main/java/com/sast/astbenchmark/case_language_maturity/completeness/single_app_tracing/asynchronous_tracing/multi_thread/Async_Multithreading_007_T.java - AffectedNodeName: schedule + AffectedNodeName: run 27: CALL: timer.schedule(tt, 2000); /src/main/java/com/sast/astbenchmark/case_language_maturity/completeness/single_app_tracing/asynchronous_tracing/multi_thread/Async_Multithreading_007_T.java AffectedNodeName: timer @@ -2612,7 +2505,7 @@ Trace: AffectedNodeName: Runtime.getRuntime().exec 18: SINK: Runtime.getRuntime().exec(this.cmd); -------------- 112: taint_flow_java_input_inner------------- +------------- 119: taint_flow_java_input_inner------------- Description:Java污点分析checker,不会使用CallGraph边界制作entrypoint,蚂蚁内部使用 File:/src/main/java/com/sast/astbenchmark/case_language_maturity/completeness/single_app_tracing/asynchronous_tracing/multi_thread/Async_Multithreading_009_T.java Line 39: Runtime.getRuntime().exec(obj.a) @@ -2625,13 +2518,13 @@ Trace: AffectedNodeName: cmd 26: SOURCE: public Map testcase(@RequestParam String cmd) { /src/main/java/com/sast/astbenchmark/case_language_maturity/completeness/single_app_tracing/asynchronous_tracing/multi_thread/Async_Multithreading_009_T.java - AffectedNodeName: [obj.a] + AffectedNodeName: obj.a 32: Var Pass: obj.a = cmd; /src/main/java/com/sast/astbenchmark/case_language_maturity/completeness/single_app_tracing/asynchronous_tracing/multi_thread/Async_Multithreading_009_T.java AffectedNodeName: Runtime.getRuntime().exec 39: SINK: Runtime.getRuntime().exec(obj.a); -------------- 113: taint_flow_java_input_inner------------- +------------- 120: taint_flow_java_input_inner------------- Description:Java污点分析checker,不会使用CallGraph边界制作entrypoint,蚂蚁内部使用 File:/src/main/java/com/sast/astbenchmark/case_language_maturity/completeness/single_app_tracing/asynchronous_tracing/promise_callback_await/CompletableFuture_001_T.java Line 44: Runtime.getRuntime().exec(result.get()) @@ -2650,7 +2543,7 @@ Trace: AffectedNodeName: Runtime.getRuntime().exec 44: SINK: Runtime.getRuntime().exec(result.get()); -------------- 114: taint_flow_java_input_inner------------- +------------- 121: taint_flow_java_input_inner------------- Description:Java污点分析checker,不会使用CallGraph边界制作entrypoint,蚂蚁内部使用 File:/src/main/java/com/sast/astbenchmark/case_language_maturity/completeness/single_app_tracing/asynchronous_tracing/promise_callback_await/CompletableFuture_003_T.java Line 47: Runtime.getRuntime().exec(notCleanedResult) @@ -2669,7 +2562,7 @@ Trace: AffectedNodeName: [return value] 37: Return Value: return "Task completed with input: " + result.get(); /src/main/java/com/sast/astbenchmark/case_language_maturity/completeness/single_app_tracing/asynchronous_tracing/promise_callback_await/CompletableFuture_003_T.java - AffectedNodeName: + AffectedNodeName: 33: CALL RETURN: CompletableFuture future = CompletableFuture.supplyAsync(() -> { 34: CALL RETURN: // 异步任务开始 35: CALL RETURN: try { @@ -2683,7 +2576,7 @@ Trace: AffectedNodeName: [return value] 43: Return Value: return result.get(); /src/main/java/com/sast/astbenchmark/case_language_maturity/completeness/single_app_tracing/asynchronous_tracing/promise_callback_await/CompletableFuture_003_T.java - AffectedNodeName: + AffectedNodeName: 41: CALL RETURN: }, executorService).thenApply(output -> { 42: CALL RETURN: // 处理结果 43: CALL RETURN: return result.get(); @@ -2692,7 +2585,52 @@ Trace: AffectedNodeName: Runtime.getRuntime().exec 47: SINK: Runtime.getRuntime().exec(notCleanedResult); -------------- 115: taint_flow_java_input_inner------------- +------------- 122: taint_flow_java_input_inner------------- +Description:Java污点分析checker,不会使用CallGraph边界制作entrypoint,蚂蚁内部使用 +File:/src/main/java/com/sast/astbenchmark/case_language_maturity/completeness/single_app_tracing/asynchronous_tracing/promise_callback_await/CompletableFuture_003_T.java +Line 47: Runtime.getRuntime().exec(notCleanedResult) +SINK RULE:Runtime.getRuntime().exec +SINK Attribute:JavaCommandExec +entrypoint: +{"filePath":"/src/main/java/com/sast/astbenchmark/case_language_maturity/completeness/single_app_tracing/asynchronous_tracing/promise_callback_await/CompletableFuture_003_T.java","functionName":"testcase","attribute":"HTTP","type":"functionCall"} +Trace: + /src/main/java/com/sast/astbenchmark/case_language_maturity/completeness/single_app_tracing/asynchronous_tracing/promise_callback_await/CompletableFuture_003_T.java + AffectedNodeName: cmd + 28: SOURCE: public Map testcase(@RequestParam String cmd) { + /src/main/java/com/sast/astbenchmark/case_language_maturity/completeness/single_app_tracing/asynchronous_tracing/promise_callback_await/CompletableFuture_003_T.java + AffectedNodeName: result + 30: Var Pass: AtomicReference result = new AtomicReference<>(cmd); + /src/main/java/com/sast/astbenchmark/case_language_maturity/completeness/single_app_tracing/asynchronous_tracing/promise_callback_await/CompletableFuture_003_T.java + AffectedNodeName: [return value] + 37: Return Value: return "Task completed with input: " + result.get(); + /src/main/java/com/sast/astbenchmark/case_language_maturity/completeness/single_app_tracing/asynchronous_tracing/promise_callback_await/CompletableFuture_003_T.java + AffectedNodeName: + 33: CALL RETURN: CompletableFuture future = CompletableFuture.supplyAsync(() -> { + 34: CALL RETURN: // 异步任务开始 + 35: CALL RETURN: try { + 36: CALL RETURN: Thread.sleep(2000); // 模拟长时间任务 + 37: CALL RETURN: return "Task completed with input: " + result.get(); + 38: CALL RETURN: } catch (InterruptedException e) { + 39: CALL RETURN: throw new RuntimeException(e); + 40: CALL RETURN: } + 41: CALL RETURN: }, executorService).thenApply(output -> { + /src/main/java/com/sast/astbenchmark/case_language_maturity/completeness/single_app_tracing/asynchronous_tracing/promise_callback_await/CompletableFuture_003_T.java + AffectedNodeName: [return value] + 43: Return Value: return result.get(); + /src/main/java/com/sast/astbenchmark/case_language_maturity/completeness/single_app_tracing/asynchronous_tracing/promise_callback_await/CompletableFuture_003_T.java + AffectedNodeName: + 41: CALL RETURN: }, executorService).thenApply(output -> { + 42: CALL RETURN: // 处理结果 + 43: CALL RETURN: return result.get(); + 44: CALL RETURN: }).thenAccept(notCleanedResult -> { + /src/main/java/com/sast/astbenchmark/case_language_maturity/completeness/single_app_tracing/asynchronous_tracing/promise_callback_await/CompletableFuture_003_T.java + AffectedNodeName: Runtime.getRuntime() + 47: Var Pass: Runtime.getRuntime().exec(notCleanedResult); + /src/main/java/com/sast/astbenchmark/case_language_maturity/completeness/single_app_tracing/asynchronous_tracing/promise_callback_await/CompletableFuture_003_T.java + AffectedNodeName: Runtime.getRuntime().exec + 47: SINK: Runtime.getRuntime().exec(notCleanedResult); + +------------- 123: taint_flow_java_input_inner------------- Description:Java污点分析checker,不会使用CallGraph边界制作entrypoint,蚂蚁内部使用 File:/src/main/java/com/sast/astbenchmark/case_language_maturity/completeness/single_app_tracing/asynchronous_tracing/promise_callback_await/CompletableFuture_003_T.java Line 47: Runtime.getRuntime().exec(notCleanedResult) @@ -2711,7 +2649,7 @@ Trace: AffectedNodeName: [return value] 37: Return Value: return "Task completed with input: " + result.get(); /src/main/java/com/sast/astbenchmark/case_language_maturity/completeness/single_app_tracing/asynchronous_tracing/promise_callback_await/CompletableFuture_003_T.java - AffectedNodeName: + AffectedNodeName: 33: CALL RETURN: CompletableFuture future = CompletableFuture.supplyAsync(() -> { 34: CALL RETURN: // 异步任务开始 35: CALL RETURN: try { @@ -2725,11 +2663,14 @@ Trace: AffectedNodeName: [return value] 43: Return Value: return result.get(); /src/main/java/com/sast/astbenchmark/case_language_maturity/completeness/single_app_tracing/asynchronous_tracing/promise_callback_await/CompletableFuture_003_T.java - AffectedNodeName: + AffectedNodeName: 41: CALL RETURN: }, executorService).thenApply(output -> { 42: CALL RETURN: // 处理结果 43: CALL RETURN: return result.get(); 44: CALL RETURN: }).thenAccept(notCleanedResult -> { + /src/main/java/com/sast/astbenchmark/case_language_maturity/completeness/single_app_tracing/asynchronous_tracing/promise_callback_await/CompletableFuture_003_T.java + AffectedNodeName: Runtime.getRuntime() + 47: Var Pass: Runtime.getRuntime().exec(notCleanedResult); /src/main/java/com/sast/astbenchmark/case_language_maturity/completeness/single_app_tracing/asynchronous_tracing/promise_callback_await/CompletableFuture_003_T.java AffectedNodeName: future 33: Var Pass: CompletableFuture future = CompletableFuture.supplyAsync(() -> { @@ -2751,11 +2692,126 @@ Trace: 49: Var Pass: modelMap.put("status", "error"); 50: Var Pass: } 51: Var Pass: }); + /src/main/java/com/sast/astbenchmark/case_language_maturity/completeness/single_app_tracing/asynchronous_tracing/promise_callback_await/CompletableFuture_003_T.java + AffectedNodeName: [return value] + 37: Return Value: return "Task completed with input: " + result.get(); + /src/main/java/com/sast/astbenchmark/case_language_maturity/completeness/single_app_tracing/asynchronous_tracing/promise_callback_await/CompletableFuture_003_T.java + AffectedNodeName: + 33: CALL RETURN: CompletableFuture future = CompletableFuture.supplyAsync(() -> { + 34: CALL RETURN: // 异步任务开始 + 35: CALL RETURN: try { + 36: CALL RETURN: Thread.sleep(2000); // 模拟长时间任务 + 37: CALL RETURN: return "Task completed with input: " + result.get(); + 38: CALL RETURN: } catch (InterruptedException e) { + 39: CALL RETURN: throw new RuntimeException(e); + 40: CALL RETURN: } + 41: CALL RETURN: }, executorService).thenApply(output -> { + /src/main/java/com/sast/astbenchmark/case_language_maturity/completeness/single_app_tracing/asynchronous_tracing/promise_callback_await/CompletableFuture_003_T.java + AffectedNodeName: [return value] + 43: Return Value: return result.get(); + /src/main/java/com/sast/astbenchmark/case_language_maturity/completeness/single_app_tracing/asynchronous_tracing/promise_callback_await/CompletableFuture_003_T.java + AffectedNodeName: + 41: CALL RETURN: }, executorService).thenApply(output -> { + 42: CALL RETURN: // 处理结果 + 43: CALL RETURN: return result.get(); + 44: CALL RETURN: }).thenAccept(notCleanedResult -> { /src/main/java/com/sast/astbenchmark/case_language_maturity/completeness/single_app_tracing/asynchronous_tracing/promise_callback_await/CompletableFuture_003_T.java AffectedNodeName: Runtime.getRuntime().exec 47: SINK: Runtime.getRuntime().exec(notCleanedResult); -------------- 116: taint_flow_java_input_inner------------- +------------- 124: taint_flow_java_input_inner------------- +Description:Java污点分析checker,不会使用CallGraph边界制作entrypoint,蚂蚁内部使用 +File:/src/main/java/com/sast/astbenchmark/case_language_maturity/completeness/single_app_tracing/asynchronous_tracing/promise_callback_await/CompletableFuture_003_T.java +Line 47: Runtime.getRuntime().exec(notCleanedResult) +SINK RULE:Runtime.getRuntime().exec +SINK Attribute:JavaCommandExec +entrypoint: +{"filePath":"/src/main/java/com/sast/astbenchmark/case_language_maturity/completeness/single_app_tracing/asynchronous_tracing/promise_callback_await/CompletableFuture_003_T.java","functionName":"testcase","attribute":"HTTP","type":"functionCall"} +Trace: + /src/main/java/com/sast/astbenchmark/case_language_maturity/completeness/single_app_tracing/asynchronous_tracing/promise_callback_await/CompletableFuture_003_T.java + AffectedNodeName: cmd + 28: SOURCE: public Map testcase(@RequestParam String cmd) { + /src/main/java/com/sast/astbenchmark/case_language_maturity/completeness/single_app_tracing/asynchronous_tracing/promise_callback_await/CompletableFuture_003_T.java + AffectedNodeName: result + 30: Var Pass: AtomicReference result = new AtomicReference<>(cmd); + /src/main/java/com/sast/astbenchmark/case_language_maturity/completeness/single_app_tracing/asynchronous_tracing/promise_callback_await/CompletableFuture_003_T.java + AffectedNodeName: [return value] + 37: Return Value: return "Task completed with input: " + result.get(); + /src/main/java/com/sast/astbenchmark/case_language_maturity/completeness/single_app_tracing/asynchronous_tracing/promise_callback_await/CompletableFuture_003_T.java + AffectedNodeName: + 33: CALL RETURN: CompletableFuture future = CompletableFuture.supplyAsync(() -> { + 34: CALL RETURN: // 异步任务开始 + 35: CALL RETURN: try { + 36: CALL RETURN: Thread.sleep(2000); // 模拟长时间任务 + 37: CALL RETURN: return "Task completed with input: " + result.get(); + 38: CALL RETURN: } catch (InterruptedException e) { + 39: CALL RETURN: throw new RuntimeException(e); + 40: CALL RETURN: } + 41: CALL RETURN: }, executorService).thenApply(output -> { + /src/main/java/com/sast/astbenchmark/case_language_maturity/completeness/single_app_tracing/asynchronous_tracing/promise_callback_await/CompletableFuture_003_T.java + AffectedNodeName: [return value] + 43: Return Value: return result.get(); + /src/main/java/com/sast/astbenchmark/case_language_maturity/completeness/single_app_tracing/asynchronous_tracing/promise_callback_await/CompletableFuture_003_T.java + AffectedNodeName: + 41: CALL RETURN: }, executorService).thenApply(output -> { + 42: CALL RETURN: // 处理结果 + 43: CALL RETURN: return result.get(); + 44: CALL RETURN: }).thenAccept(notCleanedResult -> { + /src/main/java/com/sast/astbenchmark/case_language_maturity/completeness/single_app_tracing/asynchronous_tracing/promise_callback_await/CompletableFuture_003_T.java + AffectedNodeName: Runtime.getRuntime() + 47: Var Pass: Runtime.getRuntime().exec(notCleanedResult); + /src/main/java/com/sast/astbenchmark/case_language_maturity/completeness/single_app_tracing/asynchronous_tracing/promise_callback_await/CompletableFuture_003_T.java + AffectedNodeName: future + 33: Var Pass: CompletableFuture future = CompletableFuture.supplyAsync(() -> { + 34: Var Pass: // 异步任务开始 + 35: Var Pass: try { + 36: Var Pass: Thread.sleep(2000); // 模拟长时间任务 + 37: Var Pass: return "Task completed with input: " + result.get(); + 38: Var Pass: } catch (InterruptedException e) { + 39: Var Pass: throw new RuntimeException(e); + 40: Var Pass: } + 41: Var Pass: }, executorService).thenApply(output -> { + 42: Var Pass: // 处理结果 + 43: Var Pass: return result.get(); + 44: Var Pass: }).thenAccept(notCleanedResult -> { + 45: Var Pass: // 最终操作 + 46: Var Pass: try { + 47: Var Pass: Runtime.getRuntime().exec(notCleanedResult); + 48: Var Pass: } catch (Exception e) { + 49: Var Pass: modelMap.put("status", "error"); + 50: Var Pass: } + 51: Var Pass: }); + /src/main/java/com/sast/astbenchmark/case_language_maturity/completeness/single_app_tracing/asynchronous_tracing/promise_callback_await/CompletableFuture_003_T.java + AffectedNodeName: [return value] + 37: Return Value: return "Task completed with input: " + result.get(); + /src/main/java/com/sast/astbenchmark/case_language_maturity/completeness/single_app_tracing/asynchronous_tracing/promise_callback_await/CompletableFuture_003_T.java + AffectedNodeName: + 33: CALL RETURN: CompletableFuture future = CompletableFuture.supplyAsync(() -> { + 34: CALL RETURN: // 异步任务开始 + 35: CALL RETURN: try { + 36: CALL RETURN: Thread.sleep(2000); // 模拟长时间任务 + 37: CALL RETURN: return "Task completed with input: " + result.get(); + 38: CALL RETURN: } catch (InterruptedException e) { + 39: CALL RETURN: throw new RuntimeException(e); + 40: CALL RETURN: } + 41: CALL RETURN: }, executorService).thenApply(output -> { + /src/main/java/com/sast/astbenchmark/case_language_maturity/completeness/single_app_tracing/asynchronous_tracing/promise_callback_await/CompletableFuture_003_T.java + AffectedNodeName: [return value] + 43: Return Value: return result.get(); + /src/main/java/com/sast/astbenchmark/case_language_maturity/completeness/single_app_tracing/asynchronous_tracing/promise_callback_await/CompletableFuture_003_T.java + AffectedNodeName: + 41: CALL RETURN: }, executorService).thenApply(output -> { + 42: CALL RETURN: // 处理结果 + 43: CALL RETURN: return result.get(); + 44: CALL RETURN: }).thenAccept(notCleanedResult -> { + /src/main/java/com/sast/astbenchmark/case_language_maturity/completeness/single_app_tracing/asynchronous_tracing/promise_callback_await/CompletableFuture_003_T.java + AffectedNodeName: Runtime.getRuntime() + 47: Var Pass: Runtime.getRuntime().exec(notCleanedResult); + /src/main/java/com/sast/astbenchmark/case_language_maturity/completeness/single_app_tracing/asynchronous_tracing/promise_callback_await/CompletableFuture_003_T.java + AffectedNodeName: Runtime.getRuntime().exec + 47: SINK: Runtime.getRuntime().exec(notCleanedResult); + +------------- 125: taint_flow_java_input_inner------------- Description:Java污点分析checker,不会使用CallGraph边界制作entrypoint,蚂蚁内部使用 File:/src/main/java/com/sast/astbenchmark/common/utils/CmdUtil.java Line 7: Runtime.getRuntime().exec(cmd) @@ -2777,7 +2833,7 @@ Trace: AffectedNodeName: Runtime.getRuntime().exec 7: SINK: Runtime.getRuntime().exec(cmd); -------------- 117: taint_flow_java_input_inner------------- +------------- 126: taint_flow_java_input_inner------------- Description:Java污点分析checker,不会使用CallGraph边界制作entrypoint,蚂蚁内部使用 File:/src/main/java/com/sast/astbenchmark/common/utils/CmdUtil.java Line 7: Runtime.getRuntime().exec(cmd) @@ -2799,7 +2855,7 @@ Trace: AffectedNodeName: Runtime.getRuntime().exec 7: SINK: Runtime.getRuntime().exec(cmd); -------------- 118: taint_flow_java_input_inner------------- +------------- 127: taint_flow_java_input_inner------------- Description:Java污点分析checker,不会使用CallGraph边界制作entrypoint,蚂蚁内部使用 File:/src/main/java/com/sast/astbenchmark/common/utils/CmdUtil.java Line 7: Runtime.getRuntime().exec(cmd) @@ -2821,7 +2877,7 @@ Trace: AffectedNodeName: Runtime.getRuntime().exec 7: SINK: Runtime.getRuntime().exec(cmd); -------------- 119: taint_flow_java_input_inner------------- +------------- 128: taint_flow_java_input_inner------------- Description:Java污点分析checker,不会使用CallGraph边界制作entrypoint,蚂蚁内部使用 File:/src/main/java/com/sast/astbenchmark/common/utils/CmdUtil.java Line 7: Runtime.getRuntime().exec(cmd) @@ -2846,7 +2902,7 @@ Trace: AffectedNodeName: Runtime.getRuntime().exec 7: SINK: Runtime.getRuntime().exec(cmd); -------------- 120: taint_flow_java_input_inner------------- +------------- 129: taint_flow_java_input_inner------------- Description:Java污点分析checker,不会使用CallGraph边界制作entrypoint,蚂蚁内部使用 File:/src/main/java/com/sast/astbenchmark/common/utils/CmdUtil.java Line 7: Runtime.getRuntime().exec(cmd) @@ -2868,7 +2924,7 @@ Trace: AffectedNodeName: Runtime.getRuntime().exec 7: SINK: Runtime.getRuntime().exec(cmd); -------------- 121: taint_flow_java_input_inner------------- +------------- 130: taint_flow_java_input_inner------------- Description:Java污点分析checker,不会使用CallGraph边界制作entrypoint,蚂蚁内部使用 File:/src/main/java/com/sast/astbenchmark/case_language_maturity/completeness/single_app_tracing/control_flow/loop_stmt/Statement_DoStatement_001_T.java Line 33: Runtime.getRuntime().exec(a) @@ -2887,7 +2943,7 @@ Trace: AffectedNodeName: Runtime.getRuntime().exec 33: SINK: Runtime.getRuntime().exec(a); -------------- 122: taint_flow_java_input_inner------------- +------------- 131: taint_flow_java_input_inner------------- Description:Java污点分析checker,不会使用CallGraph边界制作entrypoint,蚂蚁内部使用 File:/src/main/java/com/sast/astbenchmark/case_language_maturity/completeness/single_app_tracing/control_flow/loop_stmt/Statement_ForEachStatement_001_T.java Line 30: Runtime.getRuntime().exec(a) @@ -2909,7 +2965,7 @@ Trace: AffectedNodeName: Runtime.getRuntime().exec 30: SINK: Runtime.getRuntime().exec(a); -------------- 123: taint_flow_java_input_inner------------- +------------- 132: taint_flow_java_input_inner------------- Description:Java污点分析checker,不会使用CallGraph边界制作entrypoint,蚂蚁内部使用 File:/src/main/java/com/sast/astbenchmark/case_language_maturity/completeness/single_app_tracing/control_flow/loop_stmt/Statement_ForStatement_001_T.java Line 29: Runtime.getRuntime().exec(a) @@ -2928,7 +2984,7 @@ Trace: AffectedNodeName: Runtime.getRuntime().exec 29: SINK: Runtime.getRuntime().exec(a); -------------- 124: taint_flow_java_input_inner------------- +------------- 133: taint_flow_java_input_inner------------- Description:Java污点分析checker,不会使用CallGraph边界制作entrypoint,蚂蚁内部使用 File:/src/main/java/com/sast/astbenchmark/case_language_maturity/completeness/single_app_tracing/control_flow/loop_stmt/Statement_WhileStatement_001_T.java Line 31: Runtime.getRuntime().exec(a) @@ -2947,7 +3003,7 @@ Trace: AffectedNodeName: Runtime.getRuntime().exec 31: SINK: Runtime.getRuntime().exec(a); -------------- 125: taint_flow_java_input_inner------------- +------------- 134: taint_flow_java_input_inner------------- Description:Java污点分析checker,不会使用CallGraph边界制作entrypoint,蚂蚁内部使用 File:/src/main/java/com/sast/astbenchmark/case_language_maturity/completeness/single_app_tracing/exception_error/assert_statement/Statement_AssertStatement_001_T.java Line 25: Runtime.getRuntime().exec(cmd) @@ -2963,7 +3019,7 @@ Trace: AffectedNodeName: Runtime.getRuntime().exec 25: SINK: assert cmd == null : Runtime.getRuntime().exec(cmd); -------------- 126: taint_flow_java_input_inner------------- +------------- 135: taint_flow_java_input_inner------------- Description:Java污点分析checker,不会使用CallGraph边界制作entrypoint,蚂蚁内部使用 File:/src/main/java/com/sast/astbenchmark/case_language_maturity/completeness/single_app_tracing/exception_error/assert_statement/Statement_AssertStatement_002_F.java Line 25: Runtime.getRuntime().exec(cmd) @@ -2979,7 +3035,7 @@ Trace: AffectedNodeName: Runtime.getRuntime().exec 25: SINK: assert cmd != null : Runtime.getRuntime().exec(cmd); -------------- 127: taint_flow_java_input_inner------------- +------------- 136: taint_flow_java_input_inner------------- Description:Java污点分析checker,不会使用CallGraph边界制作entrypoint,蚂蚁内部使用 File:/src/main/java/com/sast/astbenchmark/case_language_maturity/completeness/single_app_tracing/exception_error/exception_throw/Statement_FinallyStatement_001_T.java Line 30: Runtime.getRuntime().exec(cmd) @@ -2995,7 +3051,7 @@ Trace: AffectedNodeName: Runtime.getRuntime().exec 30: SINK: Runtime.getRuntime().exec(cmd); -------------- 128: taint_flow_java_input_inner------------- +------------- 137: taint_flow_java_input_inner------------- Description:Java污点分析checker,不会使用CallGraph边界制作entrypoint,蚂蚁内部使用 File:/src/main/java/com/sast/astbenchmark/case_language_maturity/completeness/single_app_tracing/exception_error/exception_throw/Statement_TryBlock_001_T.java Line 25: Runtime.getRuntime().exec(cmd) @@ -3011,7 +3067,7 @@ Trace: AffectedNodeName: Runtime.getRuntime().exec 25: SINK: Runtime.getRuntime().exec(cmd); -------------- 129: taint_flow_java_input_inner------------- +------------- 138: taint_flow_java_input_inner------------- Description:Java污点分析checker,不会使用CallGraph边界制作entrypoint,蚂蚁内部使用 File:/src/main/java/com/sast/astbenchmark/case_language_maturity/completeness/single_app_tracing/exception_error/exception_throw/Statement_TryCatchStatement_001_T.java Line 29: Runtime.getRuntime().exec(cmd) @@ -3027,7 +3083,7 @@ Trace: AffectedNodeName: Runtime.getRuntime().exec 29: SINK: Runtime.getRuntime().exec(cmd); -------------- 130: taint_flow_java_input_inner------------- +------------- 139: taint_flow_java_input_inner------------- Description:Java污点分析checker,不会使用CallGraph边界制作entrypoint,蚂蚁内部使用 File:/src/main/java/com/sast/astbenchmark/case_language_maturity/completeness/single_app_tracing/expression/basic_expression_operation/Expression_AssignmentExpression_001_T.java Line 31: Runtime.getRuntime().exec(b.0) @@ -3039,11 +3095,17 @@ Trace: /src/main/java/com/sast/astbenchmark/case_language_maturity/completeness/single_app_tracing/expression/basic_expression_operation/Expression_AssignmentExpression_001_T.java AffectedNodeName: cmd 22: SOURCE: public Map aTaintCase018(@PathVariable String[] cmd) { + /src/main/java/com/sast/astbenchmark/case_language_maturity/completeness/single_app_tracing/expression/basic_expression_operation/Expression_AssignmentExpression_001_T.java + AffectedNodeName: + 30: Var Pass: System.arraycopy(cmd, 0, b, 0, 2); + /src/main/java/com/sast/astbenchmark/case_language_maturity/completeness/single_app_tracing/expression/basic_expression_operation/Expression_AssignmentExpression_001_T.java + AffectedNodeName: b + 31: Throw Pass: Runtime.getRuntime().exec(b[0]); /src/main/java/com/sast/astbenchmark/case_language_maturity/completeness/single_app_tracing/expression/basic_expression_operation/Expression_AssignmentExpression_001_T.java AffectedNodeName: Runtime.getRuntime().exec 31: SINK: Runtime.getRuntime().exec(b[0]); -------------- 131: taint_flow_java_input_inner------------- +------------- 140: taint_flow_java_input_inner------------- Description:Java污点分析checker,不会使用CallGraph边界制作entrypoint,蚂蚁内部使用 File:/src/main/java/com/sast/astbenchmark/case_language_maturity/completeness/single_app_tracing/expression/basic_expression_operation/Expression_AssignmentExpression_003_T.java Line 27: Runtime.getRuntime().exec(a) @@ -3062,7 +3124,7 @@ Trace: AffectedNodeName: Runtime.getRuntime().exec 27: SINK: Runtime.getRuntime().exec(a); -------------- 132: taint_flow_java_input_inner------------- +------------- 141: taint_flow_java_input_inner------------- Description:Java污点分析checker,不会使用CallGraph边界制作entrypoint,蚂蚁内部使用 File:/src/main/java/com/sast/astbenchmark/case_language_maturity/completeness/single_app_tracing/expression/basic_expression_operation/Expression_BitOperation_001_T.java Line 27: Runtime.getRuntime().exec(String.valueOf(cmd)) @@ -3077,11 +3139,14 @@ Trace: /src/main/java/com/sast/astbenchmark/case_language_maturity/completeness/single_app_tracing/expression/basic_expression_operation/Expression_BitOperation_001_T.java AffectedNodeName: cmd 26: Var Pass: cmd = (char) (cmd << 1); + /src/main/java/com/sast/astbenchmark/case_language_maturity/completeness/single_app_tracing/expression/basic_expression_operation/Expression_BitOperation_001_T.java + AffectedNodeName: String + 27: Var Pass: Runtime.getRuntime().exec(String.valueOf(cmd)); /src/main/java/com/sast/astbenchmark/case_language_maturity/completeness/single_app_tracing/expression/basic_expression_operation/Expression_BitOperation_001_T.java AffectedNodeName: Runtime.getRuntime().exec 27: SINK: Runtime.getRuntime().exec(String.valueOf(cmd)); -------------- 133: taint_flow_java_input_inner------------- +------------- 142: taint_flow_java_input_inner------------- Description:Java污点分析checker,不会使用CallGraph边界制作entrypoint,蚂蚁内部使用 File:/src/main/java/com/sast/astbenchmark/case_language_maturity/completeness/single_app_tracing/expression/basic_expression_operation/Expression_ClassInstance_Infix_001_T.java Line 26: Runtime.getRuntime().exec(new String(cmd+ &)) @@ -3097,7 +3162,7 @@ Trace: AffectedNodeName: Runtime.getRuntime().exec 26: SINK: Runtime.getRuntime().exec(new String(cmd + " &")); -------------- 134: taint_flow_java_input_inner------------- +------------- 143: taint_flow_java_input_inner------------- Description:Java污点分析checker,不会使用CallGraph边界制作entrypoint,蚂蚁内部使用 File:/src/main/java/com/sast/astbenchmark/case_language_maturity/completeness/single_app_tracing/expression/basic_expression_operation/Expression_InfixExpression_001_T.java Line 27: Runtime.getRuntime().exec(a) @@ -3116,7 +3181,7 @@ Trace: AffectedNodeName: Runtime.getRuntime().exec 27: SINK: Runtime.getRuntime().exec(a); -------------- 135: taint_flow_java_input_inner------------- +------------- 144: taint_flow_java_input_inner------------- Description:Java污点分析checker,不会使用CallGraph边界制作entrypoint,蚂蚁内部使用 File:/src/main/java/com/sast/astbenchmark/case_language_maturity/completeness/single_app_tracing/expression/basic_expression_operation/Expression_InstanceofExpression_001_T.java Line 28: Runtime.getRuntime().exec(data) @@ -3135,7 +3200,7 @@ Trace: AffectedNodeName: Runtime.getRuntime().exec 28: SINK: Runtime.getRuntime().exec(data); -------------- 136: taint_flow_java_input_inner------------- +------------- 145: taint_flow_java_input_inner------------- Description:Java污点分析checker,不会使用CallGraph边界制作entrypoint,蚂蚁内部使用 File:/src/main/java/com/sast/astbenchmark/case_language_maturity/completeness/single_app_tracing/expression/basic_expression_operation/Expression_PostfixExpression_001_T.java Line 28: Runtime.getRuntime().exec(String.valueOf(cmd)) @@ -3151,7 +3216,7 @@ Trace: AffectedNodeName: Runtime.getRuntime().exec 28: SINK: Runtime.getRuntime().exec(String.valueOf(cmd)); -------------- 137: taint_flow_java_input_inner------------- +------------- 146: taint_flow_java_input_inner------------- Description:Java污点分析checker,不会使用CallGraph边界制作entrypoint,蚂蚁内部使用 File:/src/main/java/com/sast/astbenchmark/case_language_maturity/completeness/single_app_tracing/expression/basic_expression_operation/Expression_PrefixExpression_001_T.java Line 27: Runtime.getRuntime().exec(String.valueOf(cmd)) @@ -3167,7 +3232,7 @@ Trace: AffectedNodeName: Runtime.getRuntime().exec 27: SINK: Runtime.getRuntime().exec(String.valueOf(cmd)); -------------- 138: taint_flow_java_input_inner------------- +------------- 147: taint_flow_java_input_inner------------- Description:Java污点分析checker,不会使用CallGraph边界制作entrypoint,蚂蚁内部使用 File:/src/main/java/com/sast/astbenchmark/case_language_maturity/completeness/single_app_tracing/expression/basic_expression_operation/Statement_VariableDeclarationStatement_001_T.java Line 28: Runtime.getRuntime().exec(new String(data)) @@ -3186,7 +3251,7 @@ Trace: AffectedNodeName: Runtime.getRuntime().exec 28: SINK: Runtime.getRuntime().exec(new String(data)); -------------- 139: taint_flow_java_input_inner------------- +------------- 148: taint_flow_java_input_inner------------- Description:Java污点分析checker,不会使用CallGraph边界制作entrypoint,蚂蚁内部使用 File:/src/main/java/com/sast/astbenchmark/service/SSRFShowManageImpl.java Line 72: httpclient.execute(httpget) @@ -3220,7 +3285,7 @@ Trace: AffectedNodeName: httpclient.execute 72: SINK: response = httpclient.execute(httpget); -------------- 140: taint_flow_java_input_inner------------- +------------- 149: taint_flow_java_input_inner------------- Description:Java污点分析checker,不会使用CallGraph边界制作entrypoint,蚂蚁内部使用 File:/src/main/java/com/sast/astbenchmark/common/utils/HttpUtil.java Line 44: httpclient.execute(httpGet) @@ -3233,7 +3298,7 @@ Trace: AffectedNodeName: url 25: SOURCE: public Map aTaintCase017(@RequestBody String url) { /src/main/java/com/sast/astbenchmark/case_language_maturity/completeness/single_app_tracing/expression/lambda_expression/Expression_LambdaExpression_001_T.java - AffectedNodeName: + AffectedNodeName: 36: CALL: String result = processUrl.apply(url); /src/main/java/com/sast/astbenchmark/case_language_maturity/completeness/single_app_tracing/expression/lambda_expression/Expression_LambdaExpression_001_T.java AffectedNodeName: u @@ -3270,7 +3335,7 @@ Trace: AffectedNodeName: httpclient.execute 44: SINK: response = httpclient.execute(httpGet); -------------- 141: taint_flow_java_input_inner------------- +------------- 150: taint_flow_java_input_inner------------- Description:Java污点分析checker,不会使用CallGraph边界制作entrypoint,蚂蚁内部使用 File:/src/main/java/com/sast/astbenchmark/service/DefaultSsrfClient.java Line 21: httpclient.execute(httpget) @@ -3301,7 +3366,7 @@ Trace: AffectedNodeName: httpclient.execute 21: SINK: response = httpclient.execute(httpget); -------------- 142: taint_flow_java_input_inner------------- +------------- 151: taint_flow_java_input_inner------------- Description:Java污点分析checker,不会使用CallGraph边界制作entrypoint,蚂蚁内部使用 File:/src/main/java/com/sast/astbenchmark/service/SSRFShowManageImpl.java Line 36: httpclient.execute(httpget) @@ -3369,7 +3434,7 @@ Trace: AffectedNodeName: httpclient.execute 36: SINK: response = (httpclient).execute(httpget); -------------- 143: taint_flow_java_input_inner------------- +------------- 152: taint_flow_java_input_inner------------- Description:Java污点分析checker,不会使用CallGraph边界制作entrypoint,蚂蚁内部使用 File:/src/main/java/com/sast/astbenchmark/service/SSRFShowManageImpl.java Line 72: httpclient.execute(httpget) @@ -3400,7 +3465,7 @@ Trace: AffectedNodeName: httpclient.execute 72: SINK: response = httpclient.execute(httpget); -------------- 144: taint_flow_java_input_inner------------- +------------- 153: taint_flow_java_input_inner------------- Description:Java污点分析checker,不会使用CallGraph边界制作entrypoint,蚂蚁内部使用 File:/src/main/java/com/sast/astbenchmark/case_language_maturity/completeness/single_app_tracing/expression/type_cast/Expression_CastExpression_001_T.java Line 28: Runtime.getRuntime().exec((String)cmdObject) @@ -3419,7 +3484,7 @@ Trace: AffectedNodeName: Runtime.getRuntime().exec 28: SINK: Runtime.getRuntime().exec((String) cmdObject); -------------- 145: taint_flow_java_input_inner------------- +------------- 154: taint_flow_java_input_inner------------- Description:Java污点分析checker,不会使用CallGraph边界制作entrypoint,蚂蚁内部使用 File:/src/main/java/com/sast/astbenchmark/case_language_maturity/completeness/single_app_tracing/expression/type_cast/Expression_CastExpression_003_T.java Line 30: realUrl.openConnection() @@ -3438,7 +3503,7 @@ Trace: AffectedNodeName: realUrl.openConnection 30: SINK: HttpURLConnection connection = (HttpURLConnection) realUrl.openConnection(); -------------- 146: taint_flow_java_input_inner------------- +------------- 155: taint_flow_java_input_inner------------- Description:Java污点分析checker,不会使用CallGraph边界制作entrypoint,蚂蚁内部使用 File:/src/main/java/com/sast/astbenchmark/common/utils/HttpUtil.java Line 44: httpclient.execute(httpGet) @@ -3475,7 +3540,7 @@ Trace: AffectedNodeName: httpclient.execute 44: SINK: response = httpclient.execute(httpGet); -------------- 147: taint_flow_java_input_inner------------- +------------- 156: taint_flow_java_input_inner------------- Description:Java污点分析checker,不会使用CallGraph边界制作entrypoint,蚂蚁内部使用 File:/src/main/java/com/sast/astbenchmark/common/utils/CmdUtil.java Line 7: Runtime.getRuntime().exec(cmd) @@ -3497,7 +3562,7 @@ Trace: AffectedNodeName: Runtime.getRuntime().exec 7: SINK: Runtime.getRuntime().exec(cmd); -------------- 148: taint_flow_java_input_inner------------- +------------- 157: taint_flow_java_input_inner------------- Description:Java污点分析checker,不会使用CallGraph边界制作entrypoint,蚂蚁内部使用 File:/src/main/java/com/sast/astbenchmark/common/utils/CmdUtil.java Line 7: Runtime.getRuntime().exec(cmd) @@ -3519,7 +3584,7 @@ Trace: AffectedNodeName: Runtime.getRuntime().exec 7: SINK: Runtime.getRuntime().exec(cmd); -------------- 149: taint_flow_java_input_inner------------- +------------- 158: taint_flow_java_input_inner------------- Description:Java污点分析checker,不会使用CallGraph边界制作entrypoint,蚂蚁内部使用 File:/src/main/java/com/sast/astbenchmark/case_language_maturity/completeness/single_app_tracing/function_call/chained_call/Expression_MethodInvocation_Argument_002_T.java Line 27: HttpRequest.post(http://localhost:39100/ataint/case00124/2?cmd=+cmd) @@ -3535,7 +3600,7 @@ Trace: AffectedNodeName: HttpRequest.post 27: SINK: HttpRequest.post("http://localhost:39100/ataint/case00124/2?cmd=" + cmd) -------------- 150: taint_flow_java_input_inner------------- +------------- 159: taint_flow_java_input_inner------------- Description:Java污点分析checker,不会使用CallGraph边界制作entrypoint,蚂蚁内部使用 File:/src/main/java/com/sast/astbenchmark/case_language_maturity/completeness/single_app_tracing/function_call/higher_order_function/higher_order_function_001_T.java Line 33: Runtime.getRuntime().exec(o) @@ -3563,7 +3628,7 @@ Trace: AffectedNodeName: Runtime.getRuntime().exec 33: SINK: Runtime.getRuntime().exec(o); -------------- 151: taint_flow_java_input_inner------------- +------------- 160: taint_flow_java_input_inner------------- Description:Java污点分析checker,不会使用CallGraph边界制作entrypoint,蚂蚁内部使用 File:/src/main/java/com/sast/astbenchmark/case_language_maturity/completeness/single_app_tracing/function_call/library_function/CallExpression_NoSourceCode_Native_002_T.java Line 28: Runtime.getRuntime().exec(exec) @@ -3582,7 +3647,7 @@ Trace: AffectedNodeName: Runtime.getRuntime().exec 28: SINK: Runtime.getRuntime().exec(exec); -------------- 152: taint_flow_java_input_inner------------- +------------- 161: taint_flow_java_input_inner------------- Description:Java污点分析checker,不会使用CallGraph边界制作entrypoint,蚂蚁内部使用 File:/src/main/java/com/sast/astbenchmark/case_language_maturity/completeness/single_app_tracing/function_call/library_function/CallExpression_NoSourceCode_Native_004_T.java Line 26: Runtime.getRuntime().exec(new String(cmd)) @@ -3598,7 +3663,7 @@ Trace: AffectedNodeName: Runtime.getRuntime().exec 26: SINK: Runtime.getRuntime().exec(new String(cmd)); -------------- 153: taint_flow_java_input_inner------------- +------------- 162: taint_flow_java_input_inner------------- Description:Java污点分析checker,不会使用CallGraph边界制作entrypoint,蚂蚁内部使用 File:/src/main/java/com/sast/astbenchmark/case_language_maturity/completeness/single_app_tracing/function_call/library_function/CallExpression_NoSourceCode_Native_006_T.java Line 27: Runtime.getRuntime().exec(cmd) @@ -3617,7 +3682,7 @@ Trace: AffectedNodeName: Runtime.getRuntime().exec 27: SINK: Runtime.getRuntime().exec(cmd); -------------- 154: taint_flow_java_input_inner------------- +------------- 163: taint_flow_java_input_inner------------- Description:Java污点分析checker,不会使用CallGraph边界制作entrypoint,蚂蚁内部使用 File:/src/main/java/com/sast/astbenchmark/case_language_maturity/completeness/single_app_tracing/function_call/library_function/Expression_CallExpression_Array_002_T.java Line 27: Runtime.getRuntime().exec(String.valueOf(chars)) @@ -3632,11 +3697,14 @@ Trace: /src/main/java/com/sast/astbenchmark/case_language_maturity/completeness/single_app_tracing/function_call/library_function/Expression_CallExpression_Array_002_T.java AffectedNodeName: chars 26: Var Pass: char[] chars = cmd.toCharArray(); + /src/main/java/com/sast/astbenchmark/case_language_maturity/completeness/single_app_tracing/function_call/library_function/Expression_CallExpression_Array_002_T.java + AffectedNodeName: String + 27: Var Pass: Runtime.getRuntime().exec(String.valueOf(chars)); /src/main/java/com/sast/astbenchmark/case_language_maturity/completeness/single_app_tracing/function_call/library_function/Expression_CallExpression_Array_002_T.java AffectedNodeName: Runtime.getRuntime().exec 27: SINK: Runtime.getRuntime().exec(String.valueOf(chars)); -------------- 155: taint_flow_java_input_inner------------- +------------- 164: taint_flow_java_input_inner------------- Description:Java污点分析checker,不会使用CallGraph边界制作entrypoint,蚂蚁内部使用 File:/src/main/java/com/sast/astbenchmark/case_language_maturity/completeness/single_app_tracing/function_call/library_function/Expression_MethodInvocation_MethodInvocation_002_T.java Line 27: Runtime.getRuntime().exec(builder.toString()) @@ -3655,7 +3723,7 @@ Trace: AffectedNodeName: Runtime.getRuntime().exec 27: SINK: Runtime.getRuntime().exec(builder.toString()); -------------- 156: taint_flow_java_input_inner------------- +------------- 165: taint_flow_java_input_inner------------- Description:Java污点分析checker,不会使用CallGraph边界制作entrypoint,蚂蚁内部使用 File:/src/main/java/com/sast/astbenchmark/case_language_maturity/completeness/single_app_tracing/function_call/override/Expression_Override_001_T.java Line 27: Runtime.getRuntime().exec(ps.getCmd()) @@ -3670,35 +3738,15 @@ Trace: /src/main/java/com/sast/astbenchmark/case_language_maturity/completeness/single_app_tracing/function_call/override/Expression_Override_001_T.java AffectedNodeName: _CTOR_ 26: CALL: PS ps = new PS(cmd, "~"); - /src/main/java/com/sast/astbenchmark/model/custom/PS.java - AffectedNodeName: cmd - 6: ARG PASS: public PS(String cmd, String cmd2) { - /src/main/java/com/sast/astbenchmark/model/custom/PS.java - AffectedNodeName: _CTOR_ - 7: CALL: super(cmd); - /src/main/java/com/sast/astbenchmark/model/custom/P.java - AffectedNodeName: cmd - 8: ARG PASS: public P(String cmd) { - /src/main/java/com/sast/astbenchmark/model/custom/P.java - AffectedNodeName: [this.cmd] - 9: Var Pass: this.cmd = cmd; /src/main/java/com/sast/astbenchmark/case_language_maturity/completeness/single_app_tracing/function_call/override/Expression_Override_001_T.java AffectedNodeName: ps 26: Var Pass: PS ps = new PS(cmd, "~"); - /src/main/java/com/sast/astbenchmark/model/custom/PS.java - AffectedNodeName: getCmd - 12: CALL: return super.getCmd() + this.cmd2; - /src/main/java/com/sast/astbenchmark/model/custom/PS.java - 12: ARG PASS: return super.getCmd() + this.cmd2; - /src/main/java/com/sast/astbenchmark/model/custom/P.java - AffectedNodeName: [return value] - 13: Return Value: return this.cmd; - /src/main/java/com/sast/astbenchmark/model/custom/PS.java + /src/main/java/com/sast/astbenchmark/case_language_maturity/completeness/single_app_tracing/function_call/override/Expression_Override_001_T.java AffectedNodeName: getCmd - 12: CALL RETURN: return super.getCmd() + this.cmd2; - /src/main/java/com/sast/astbenchmark/model/custom/PS.java - AffectedNodeName: [return value] - 12: Return Value: return super.getCmd() + this.cmd2; + 27: CALL: Runtime.getRuntime().exec(ps.getCmd()); + /src/main/java/com/sast/astbenchmark/case_language_maturity/completeness/single_app_tracing/function_call/override/Expression_Override_001_T.java + AffectedNodeName: ps + 27: ARG PASS: Runtime.getRuntime().exec(ps.getCmd()); /src/main/java/com/sast/astbenchmark/case_language_maturity/completeness/single_app_tracing/function_call/override/Expression_Override_001_T.java AffectedNodeName: getCmd 27: CALL RETURN: Runtime.getRuntime().exec(ps.getCmd()); @@ -3706,7 +3754,7 @@ Trace: AffectedNodeName: Runtime.getRuntime().exec 27: SINK: Runtime.getRuntime().exec(ps.getCmd()); -------------- 157: taint_flow_java_input_inner------------- +------------- 166: taint_flow_java_input_inner------------- Description:Java污点分析checker,不会使用CallGraph边界制作entrypoint,蚂蚁内部使用 File:/src/main/java/com/sast/astbenchmark/case_language_maturity/completeness/single_app_tracing/function_call/return_value_passing/function_return_value_passing_001_T.java Line 31: Runtime.getRuntime().exec(o) @@ -3721,15 +3769,6 @@ Trace: /src/main/java/com/sast/astbenchmark/case_language_maturity/completeness/single_app_tracing/function_call/return_value_passing/function_return_value_passing_001_T.java AffectedNodeName: process 20: CALL: String data = process(__taint_src); - /src/main/java/com/sast/astbenchmark/case_language_maturity/completeness/single_app_tracing/function_call/return_value_passing/function_return_value_passing_001_T.java - AffectedNodeName: __taint_src - 24: ARG PASS: private static String process(String __taint_src) { - /src/main/java/com/sast/astbenchmark/case_language_maturity/completeness/single_app_tracing/function_call/return_value_passing/function_return_value_passing_001_T.java - AffectedNodeName: tmp - 25: Var Pass: String tmp = __taint_src; - /src/main/java/com/sast/astbenchmark/case_language_maturity/completeness/single_app_tracing/function_call/return_value_passing/function_return_value_passing_001_T.java - AffectedNodeName: [return value] - 26: Return Value: return tmp; /src/main/java/com/sast/astbenchmark/case_language_maturity/completeness/single_app_tracing/function_call/return_value_passing/function_return_value_passing_001_T.java AffectedNodeName: process 20: CALL RETURN: String data = process(__taint_src); @@ -3746,7 +3785,7 @@ Trace: AffectedNodeName: Runtime.getRuntime().exec 31: SINK: Runtime.getRuntime().exec(o); -------------- 158: taint_flow_java_input_inner------------- +------------- 167: taint_flow_java_input_inner------------- Description:Java污点分析checker,不会使用CallGraph边界制作entrypoint,蚂蚁内部使用 File:/src/main/java/com/sast/astbenchmark/case_language_maturity/completeness/single_app_tracing/function_call/static_method/static_field_001_T.java Line 30: Runtime.getRuntime().exec(MyClass.data) @@ -3759,13 +3798,13 @@ Trace: AffectedNodeName: __taint_src 23: SOURCE: public void static_field_001_T(@RequestParam String __taint_src) { /src/main/java/com/sast/astbenchmark/case_language_maturity/completeness/single_app_tracing/function_call/static_method/static_field_001_T.java - AffectedNodeName: [MyClass.data] + AffectedNodeName: MyClass.data 24: Var Pass: MyClass.data = __taint_src; /src/main/java/com/sast/astbenchmark/case_language_maturity/completeness/single_app_tracing/function_call/static_method/static_field_001_T.java AffectedNodeName: Runtime.getRuntime().exec 30: SINK: Runtime.getRuntime().exec(MyClass.data); -------------- 159: taint_flow_java_input_inner------------- +------------- 168: taint_flow_java_input_inner------------- Description:Java污点分析checker,不会使用CallGraph边界制作entrypoint,蚂蚁内部使用 File:/src/main/java/com/sast/astbenchmark/case_language_maturity/completeness/single_app_tracing/function_call/static_method/static_method_001_T.java Line 20: Runtime.getRuntime().exec(arg) @@ -3793,7 +3832,7 @@ Trace: AffectedNodeName: Runtime.getRuntime().exec 20: SINK: Runtime.getRuntime().exec(arg); -------------- 160: taint_flow_java_input_inner------------- +------------- 169: taint_flow_java_input_inner------------- Description:Java污点分析checker,不会使用CallGraph边界制作entrypoint,蚂蚁内部使用 File:/src/main/java/com/sast/astbenchmark/case_language_maturity/accuracy/object_field_sensitive/field_sensitive_one_collection/numeric_index_state_no_solver/ArrayOutOfBoundOrNot_001_T.java Line 27: Runtime.getRuntime().exec(arr) @@ -3812,26 +3851,7 @@ Trace: AffectedNodeName: Runtime.getRuntime().exec 27: SINK: Runtime.getRuntime().exec(arr); -------------- 161: taint_flow_java_input_inner------------- -Description:Java污点分析checker,不会使用CallGraph边界制作entrypoint,蚂蚁内部使用 -File:/src/main/java/com/sast/astbenchmark/case_language_maturity/accuracy/object_field_sensitive/field_sensitive_one_collection/numeric_index_state_no_solver/ArrayOutOfBoundOrNot_002_F.java -Line 27: Runtime.getRuntime().exec(arr) -SINK RULE:Runtime.getRuntime().exec -SINK Attribute:JavaCommandExec -entrypoint: -{"filePath":"/src/main/java/com/sast/astbenchmark/case_language_maturity/accuracy/object_field_sensitive/field_sensitive_one_collection/numeric_index_state_no_solver/ArrayOutOfBoundOrNot_002_F.java","functionName":"testcase","attribute":"HTTP","type":"functionCall"} -Trace: - /src/main/java/com/sast/astbenchmark/case_language_maturity/accuracy/object_field_sensitive/field_sensitive_one_collection/numeric_index_state_no_solver/ArrayOutOfBoundOrNot_002_F.java - AffectedNodeName: cmd - 22: SOURCE: public Map testcase(@RequestParam String cmd) { - /src/main/java/com/sast/astbenchmark/case_language_maturity/accuracy/object_field_sensitive/field_sensitive_one_collection/numeric_index_state_no_solver/ArrayOutOfBoundOrNot_002_F.java - AffectedNodeName: arr[3] - 26: Var Pass: arr[3] = cmd; // OutOfBound - /src/main/java/com/sast/astbenchmark/case_language_maturity/accuracy/object_field_sensitive/field_sensitive_one_collection/numeric_index_state_no_solver/ArrayOutOfBoundOrNot_002_F.java - AffectedNodeName: Runtime.getRuntime().exec - 27: SINK: Runtime.getRuntime().exec(arr); - -------------- 162: taint_flow_java_input_inner------------- +------------- 170: taint_flow_java_input_inner------------- Description:Java污点分析checker,不会使用CallGraph边界制作entrypoint,蚂蚁内部使用 File:/src/main/java/com/sast/astbenchmark/case_language_maturity/accuracy/object_field_sensitive/field_sensitive_one_collection/numeric_index_state_no_solver/Array_index_001_T.java Line 26: Runtime.getRuntime().exec(arr.0) @@ -3850,7 +3870,7 @@ Trace: AffectedNodeName: Runtime.getRuntime().exec 26: SINK: Runtime.getRuntime().exec(arr[0]); -------------- 163: taint_flow_java_input_inner------------- +------------- 171: taint_flow_java_input_inner------------- Description:Java污点分析checker,不会使用CallGraph边界制作entrypoint,蚂蚁内部使用 File:/src/main/java/com/sast/astbenchmark/case_language_maturity/accuracy/object_field_sensitive/field_sensitive_one_collection/numeric_index_state_no_solver/MapField_001_T.java Line 28: Runtime.getRuntime().exec(map.get(key1)) @@ -3869,7 +3889,7 @@ Trace: AffectedNodeName: Runtime.getRuntime().exec 28: SINK: Runtime.getRuntime().exec(map.get("key1")); -------------- 164: taint_flow_java_input_inner------------- +------------- 172: taint_flow_java_input_inner------------- Description:Java污点分析checker,不会使用CallGraph边界制作entrypoint,蚂蚁内部使用 File:/src/main/java/com/sast/astbenchmark/case_language_maturity/accuracy/object_field_sensitive/field_sensitive_one_collection/numeric_index_state_no_solver/MapField_003_T.java Line 29: SinkUtil.sink(map.values()) @@ -3888,7 +3908,7 @@ Trace: AffectedNodeName: SinkUtil.sink 29: SINK: SinkUtil.sink(map.values()); -------------- 165: taint_flow_java_input_inner------------- +------------- 173: taint_flow_java_input_inner------------- Description:Java污点分析checker,不会使用CallGraph边界制作entrypoint,蚂蚁内部使用 File:/src/main/java/com/sast/astbenchmark/case_language_maturity/accuracy/object_field_sensitive/field_sensitive_one_collection/numeric_index_state_no_solver/MapField_005_T.java Line 29: SinkUtil.sink(map.keySet()) @@ -3907,7 +3927,7 @@ Trace: AffectedNodeName: SinkUtil.sink 29: SINK: SinkUtil.sink(map.keySet()); -------------- 166: taint_flow_java_input_inner------------- +------------- 174: taint_flow_java_input_inner------------- Description:Java污点分析checker,不会使用CallGraph边界制作entrypoint,蚂蚁内部使用 File:/src/main/java/com/sast/astbenchmark/case_language_maturity/accuracy/object_field_sensitive/field_sensitive_one_collection/numeric_index_state_no_solver/MapField_007_T.java Line 29: SinkUtil.sink(map.entrySet()) @@ -3926,7 +3946,7 @@ Trace: AffectedNodeName: SinkUtil.sink 29: SINK: SinkUtil.sink(map.entrySet()); -------------- 167: taint_flow_java_input_inner------------- +------------- 175: taint_flow_java_input_inner------------- Description:Java污点分析checker,不会使用CallGraph边界制作entrypoint,蚂蚁内部使用 File:/src/main/java/com/sast/astbenchmark/common/utils/HttpUtil.java Line 44: httpclient.execute(httpGet) @@ -3966,7 +3986,152 @@ Trace: AffectedNodeName: httpclient.execute 44: SINK: response = httpclient.execute(httpGet); -------------- 168: taint_flow_java_input_inner------------- +------------- 176: taint_flow_java_input_inner------------- +Description:Java污点分析checker,不会使用CallGraph边界制作entrypoint,蚂蚁内部使用 +File:/src/main/java/com/sast/astbenchmark/case_language_maturity/accuracy/object_field_sensitive/field_sensitive_one_collection/numeric_index_state_no_solver/QueueWithLambda_001_T.java +Line 36: Runtime.getRuntime().exec(e) +SINK RULE:Runtime.getRuntime().exec +SINK Attribute:JavaCommandExec +entrypoint: +{"filePath":"/src/main/java/com/sast/astbenchmark/case_language_maturity/accuracy/object_field_sensitive/field_sensitive_one_collection/numeric_index_state_no_solver/QueueWithLambda_001_T.java","functionName":"testcase","attribute":"HTTP","type":"functionCall"} +Trace: + /src/main/java/com/sast/astbenchmark/case_language_maturity/accuracy/object_field_sensitive/field_sensitive_one_collection/numeric_index_state_no_solver/QueueWithLambda_001_T.java + AffectedNodeName: cmd + 26: SOURCE: public Map testcase(@RequestParam String cmd) { + /src/main/java/com/sast/astbenchmark/case_language_maturity/accuracy/object_field_sensitive/field_sensitive_one_collection/numeric_index_state_no_solver/QueueWithLambda_001_T.java + AffectedNodeName: add + 30: CALL: queue.add(cmd); + /src/main/java/com/sast/astbenchmark/case_language_maturity/accuracy/object_field_sensitive/field_sensitive_one_collection/numeric_index_state_no_solver/QueueWithLambda_001_T.java + AffectedNodeName: + 33: CALL: queue.stream().forEach(e -> { + 34: CALL: if (cmd.equals(e)) { + 35: CALL: try { + 36: CALL: Runtime.getRuntime().exec(e); + 37: CALL: } catch (IOException ex) { + 38: CALL: } + 39: CALL: } + 40: CALL: }); + /src/main/java/com/sast/astbenchmark/case_language_maturity/accuracy/object_field_sensitive/field_sensitive_one_collection/numeric_index_state_no_solver/QueueWithLambda_001_T.java + AffectedNodeName: e + 33: ARG PASS: queue.stream().forEach(e -> { + 34: ARG PASS: if (cmd.equals(e)) { + 35: ARG PASS: try { + 36: ARG PASS: Runtime.getRuntime().exec(e); + 37: ARG PASS: } catch (IOException ex) { + 38: ARG PASS: } + 39: ARG PASS: } + 40: ARG PASS: }); + /src/main/java/com/sast/astbenchmark/case_language_maturity/accuracy/object_field_sensitive/field_sensitive_one_collection/numeric_index_state_no_solver/QueueWithLambda_001_T.java + AffectedNodeName: Runtime.getRuntime().exec + 36: SINK: Runtime.getRuntime().exec(e); + +------------- 177: taint_flow_java_input_inner------------- +Description:Java污点分析checker,不会使用CallGraph边界制作entrypoint,蚂蚁内部使用 +File:/src/main/java/com/sast/astbenchmark/case_language_maturity/accuracy/object_field_sensitive/field_sensitive_one_collection/numeric_index_state_no_solver/QueueWithLambda_001_T.java +Line 36: Runtime.getRuntime().exec(e) +SINK RULE:Runtime.getRuntime().exec +SINK Attribute:JavaCommandExec +entrypoint: +{"filePath":"/src/main/java/com/sast/astbenchmark/case_language_maturity/accuracy/object_field_sensitive/field_sensitive_one_collection/numeric_index_state_no_solver/QueueWithLambda_001_T.java","functionName":"testcase","attribute":"HTTP","type":"functionCall"} +Trace: + /src/main/java/com/sast/astbenchmark/case_language_maturity/accuracy/object_field_sensitive/field_sensitive_one_collection/numeric_index_state_no_solver/QueueWithLambda_001_T.java + AffectedNodeName: cmd + 26: SOURCE: public Map testcase(@RequestParam String cmd) { + /src/main/java/com/sast/astbenchmark/case_language_maturity/accuracy/object_field_sensitive/field_sensitive_one_collection/numeric_index_state_no_solver/QueueWithLambda_001_T.java + AffectedNodeName: cmd + 34: Var Pass: if (cmd.equals(e)) { + /src/main/java/com/sast/astbenchmark/case_language_maturity/accuracy/object_field_sensitive/field_sensitive_one_collection/numeric_index_state_no_solver/QueueWithLambda_001_T.java + AffectedNodeName: Runtime.getRuntime().exec + 36: SINK: Runtime.getRuntime().exec(e); + +------------- 178: taint_flow_java_input_inner------------- +Description:Java污点分析checker,不会使用CallGraph边界制作entrypoint,蚂蚁内部使用 +File:/src/main/java/com/sast/astbenchmark/case_language_maturity/accuracy/object_field_sensitive/field_sensitive_one_collection/numeric_index_state_no_solver/QueueWithLambda_001_T.java +Line 36: Runtime.getRuntime().exec(e) +SINK RULE:Runtime.getRuntime().exec +SINK Attribute:JavaCommandExec +entrypoint: +{"filePath":"/src/main/java/com/sast/astbenchmark/case_language_maturity/accuracy/object_field_sensitive/field_sensitive_one_collection/numeric_index_state_no_solver/QueueWithLambda_001_T.java","functionName":"testcase","attribute":"HTTP","type":"functionCall"} +Trace: + /src/main/java/com/sast/astbenchmark/case_language_maturity/accuracy/object_field_sensitive/field_sensitive_one_collection/numeric_index_state_no_solver/QueueWithLambda_001_T.java + AffectedNodeName: cmd + 26: SOURCE: public Map testcase(@RequestParam String cmd) { + /src/main/java/com/sast/astbenchmark/case_language_maturity/accuracy/object_field_sensitive/field_sensitive_one_collection/numeric_index_state_no_solver/QueueWithLambda_001_T.java + AffectedNodeName: add + 30: CALL: queue.add(cmd); + /src/main/java/com/sast/astbenchmark/case_language_maturity/accuracy/object_field_sensitive/field_sensitive_one_collection/numeric_index_state_no_solver/QueueWithLambda_001_T.java + AffectedNodeName: + 33: CALL: queue.stream().forEach(e -> { + 34: CALL: if (cmd.equals(e)) { + 35: CALL: try { + 36: CALL: Runtime.getRuntime().exec(e); + 37: CALL: } catch (IOException ex) { + 38: CALL: } + 39: CALL: } + 40: CALL: }); + /src/main/java/com/sast/astbenchmark/case_language_maturity/accuracy/object_field_sensitive/field_sensitive_one_collection/numeric_index_state_no_solver/QueueWithLambda_001_T.java + AffectedNodeName: e + 33: ARG PASS: queue.stream().forEach(e -> { + 34: ARG PASS: if (cmd.equals(e)) { + 35: ARG PASS: try { + 36: ARG PASS: Runtime.getRuntime().exec(e); + 37: ARG PASS: } catch (IOException ex) { + 38: ARG PASS: } + 39: ARG PASS: } + 40: ARG PASS: }); + /src/main/java/com/sast/astbenchmark/case_language_maturity/accuracy/object_field_sensitive/field_sensitive_one_collection/numeric_index_state_no_solver/QueueWithLambda_001_T.java + AffectedNodeName: cmd + 34: Var Pass: if (cmd.equals(e)) { + /src/main/java/com/sast/astbenchmark/case_language_maturity/accuracy/object_field_sensitive/field_sensitive_one_collection/numeric_index_state_no_solver/QueueWithLambda_001_T.java + AffectedNodeName: Runtime.getRuntime().exec + 36: SINK: Runtime.getRuntime().exec(e); + +------------- 179: taint_flow_java_input_inner------------- +Description:Java污点分析checker,不会使用CallGraph边界制作entrypoint,蚂蚁内部使用 +File:/src/main/java/com/sast/astbenchmark/case_language_maturity/accuracy/object_field_sensitive/field_sensitive_one_collection/numeric_index_state_no_solver/QueueWithLambda_001_T.java +Line 36: Runtime.getRuntime().exec(e) +SINK RULE:Runtime.getRuntime().exec +SINK Attribute:JavaCommandExec +entrypoint: +{"filePath":"/src/main/java/com/sast/astbenchmark/case_language_maturity/accuracy/object_field_sensitive/field_sensitive_one_collection/numeric_index_state_no_solver/QueueWithLambda_001_T.java","functionName":"testcase","attribute":"HTTP","type":"functionCall"} +Trace: + /src/main/java/com/sast/astbenchmark/case_language_maturity/accuracy/object_field_sensitive/field_sensitive_one_collection/numeric_index_state_no_solver/QueueWithLambda_001_T.java + AffectedNodeName: cmd + 26: SOURCE: public Map testcase(@RequestParam String cmd) { + /src/main/java/com/sast/astbenchmark/case_language_maturity/accuracy/object_field_sensitive/field_sensitive_one_collection/numeric_index_state_no_solver/QueueWithLambda_001_T.java + AffectedNodeName: add + 30: CALL: queue.add(cmd); + /src/main/java/com/sast/astbenchmark/case_language_maturity/accuracy/object_field_sensitive/field_sensitive_one_collection/numeric_index_state_no_solver/QueueWithLambda_001_T.java + AffectedNodeName: + 33: CALL: queue.stream().forEach(e -> { + 34: CALL: if (cmd.equals(e)) { + 35: CALL: try { + 36: CALL: Runtime.getRuntime().exec(e); + 37: CALL: } catch (IOException ex) { + 38: CALL: } + 39: CALL: } + 40: CALL: }); + /src/main/java/com/sast/astbenchmark/case_language_maturity/accuracy/object_field_sensitive/field_sensitive_one_collection/numeric_index_state_no_solver/QueueWithLambda_001_T.java + AffectedNodeName: e + 33: ARG PASS: queue.stream().forEach(e -> { + 34: ARG PASS: if (cmd.equals(e)) { + 35: ARG PASS: try { + 36: ARG PASS: Runtime.getRuntime().exec(e); + 37: ARG PASS: } catch (IOException ex) { + 38: ARG PASS: } + 39: ARG PASS: } + 40: ARG PASS: }); + /src/main/java/com/sast/astbenchmark/case_language_maturity/accuracy/object_field_sensitive/field_sensitive_one_collection/numeric_index_state_no_solver/QueueWithLambda_001_T.java + AffectedNodeName: cmd + 34: Var Pass: if (cmd.equals(e)) { + /src/main/java/com/sast/astbenchmark/case_language_maturity/accuracy/object_field_sensitive/field_sensitive_one_collection/numeric_index_state_no_solver/QueueWithLambda_001_T.java + AffectedNodeName: Runtime.getRuntime() + 36: Var Pass: Runtime.getRuntime().exec(e); + /src/main/java/com/sast/astbenchmark/case_language_maturity/accuracy/object_field_sensitive/field_sensitive_one_collection/numeric_index_state_no_solver/QueueWithLambda_001_T.java + AffectedNodeName: Runtime.getRuntime().exec + 36: SINK: Runtime.getRuntime().exec(e); + +------------- 180: taint_flow_java_input_inner------------- Description:Java污点分析checker,不会使用CallGraph边界制作entrypoint,蚂蚁内部使用 File:/src/main/java/com/sast/astbenchmark/case_language_maturity/accuracy/context_sensitive/multi_invoke/multi_invoke_need_solve/DifferentParamsForFunction_need_solve_001_T.java Line 32: Runtime.getRuntime().exec(exec2) @@ -3981,15 +4146,6 @@ Trace: /src/main/java/com/sast/astbenchmark/case_language_maturity/accuracy/context_sensitive/multi_invoke/multi_invoke_need_solve/DifferentParamsForFunction_need_solve_001_T.java AffectedNodeName: getCmdWithContextSensitive 30: CALL: exec2 = CmdUtil.getCmdWithContextSensitive(i, cmd); - /src/main/java/com/sast/astbenchmark/common/utils/CmdUtil.java - AffectedNodeName: cmd - 13: ARG PASS: public static String getCmdWithContextSensitive(int x, String cmd) { - /src/main/java/com/sast/astbenchmark/common/utils/CmdUtil.java - AffectedNodeName: res - 16: Var Pass: res = cmd; - /src/main/java/com/sast/astbenchmark/common/utils/CmdUtil.java - AffectedNodeName: [return value] - 21: Return Value: return res; /src/main/java/com/sast/astbenchmark/case_language_maturity/accuracy/context_sensitive/multi_invoke/multi_invoke_need_solve/DifferentParamsForFunction_need_solve_001_T.java AffectedNodeName: getCmdWithContextSensitive 30: CALL RETURN: exec2 = CmdUtil.getCmdWithContextSensitive(i, cmd); @@ -4000,41 +4156,7 @@ Trace: AffectedNodeName: Runtime.getRuntime().exec 32: SINK: Runtime.getRuntime().exec(exec2); -------------- 169: taint_flow_java_input_inner------------- -Description:Java污点分析checker,不会使用CallGraph边界制作entrypoint,蚂蚁内部使用 -File:/src/main/java/com/sast/astbenchmark/case_language_maturity/accuracy/context_sensitive/multi_invoke/multi_invoke_need_solve/DifferentParamsForFunction_need_solve_002_F.java -Line 33: Runtime.getRuntime().exec(exec2) -SINK RULE:Runtime.getRuntime().exec -SINK Attribute:JavaCommandExec -entrypoint: -{"filePath":"/src/main/java/com/sast/astbenchmark/case_language_maturity/accuracy/context_sensitive/multi_invoke/multi_invoke_need_solve/DifferentParamsForFunction_need_solve_002_F.java","functionName":"testcase","attribute":"HTTP","type":"functionCall"} -Trace: - /src/main/java/com/sast/astbenchmark/case_language_maturity/accuracy/context_sensitive/multi_invoke/multi_invoke_need_solve/DifferentParamsForFunction_need_solve_002_F.java - AffectedNodeName: cmd - 25: SOURCE: public Map testcase(@RequestParam String cmd) { - /src/main/java/com/sast/astbenchmark/case_language_maturity/accuracy/context_sensitive/multi_invoke/multi_invoke_need_solve/DifferentParamsForFunction_need_solve_002_F.java - AffectedNodeName: getCmdWithContextSensitive - 31: CALL: exec2 = CmdUtil.getCmdWithContextSensitive(i, cmd); - /src/main/java/com/sast/astbenchmark/common/utils/CmdUtil.java - AffectedNodeName: cmd - 13: ARG PASS: public static String getCmdWithContextSensitive(int x, String cmd) { - /src/main/java/com/sast/astbenchmark/common/utils/CmdUtil.java - AffectedNodeName: res - 16: Var Pass: res = cmd; - /src/main/java/com/sast/astbenchmark/common/utils/CmdUtil.java - AffectedNodeName: [return value] - 21: Return Value: return res; - /src/main/java/com/sast/astbenchmark/case_language_maturity/accuracy/context_sensitive/multi_invoke/multi_invoke_need_solve/DifferentParamsForFunction_need_solve_002_F.java - AffectedNodeName: getCmdWithContextSensitive - 31: CALL RETURN: exec2 = CmdUtil.getCmdWithContextSensitive(i, cmd); - /src/main/java/com/sast/astbenchmark/case_language_maturity/accuracy/context_sensitive/multi_invoke/multi_invoke_need_solve/DifferentParamsForFunction_need_solve_002_F.java - AffectedNodeName: exec2 - 31: Var Pass: exec2 = CmdUtil.getCmdWithContextSensitive(i, cmd); - /src/main/java/com/sast/astbenchmark/case_language_maturity/accuracy/context_sensitive/multi_invoke/multi_invoke_need_solve/DifferentParamsForFunction_need_solve_002_F.java - AffectedNodeName: Runtime.getRuntime().exec - 33: SINK: Runtime.getRuntime().exec(exec2); - -------------- 170: taint_flow_java_input_inner------------- +------------- 181: taint_flow_java_input_inner------------- Description:Java污点分析checker,不会使用CallGraph边界制作entrypoint,蚂蚁内部使用 File:/src/main/java/com/sast/astbenchmark/case_language_maturity/accuracy/context_sensitive/multi_invoke/multi_invoke_without_solve/DifferentParamsForFunction_001_T.java Line 36: Runtime.getRuntime().exec(rx1.y.f) @@ -4047,20 +4169,11 @@ Trace: AffectedNodeName: cmd 25: SOURCE: public Map testcase(@RequestParam String cmd) { /src/main/java/com/sast/astbenchmark/case_language_maturity/accuracy/context_sensitive/multi_invoke/multi_invoke_without_solve/DifferentParamsForFunction_001_T.java - AffectedNodeName: [y1.f] + AffectedNodeName: y1.f 32: Var Pass: y1.f = cmd; /src/main/java/com/sast/astbenchmark/case_language_maturity/accuracy/context_sensitive/multi_invoke/multi_invoke_without_solve/DifferentParamsForFunction_001_T.java AffectedNodeName: assign 34: CALL: X rx1 = Invoke.assign(x1, y1); - /src/main/java/com/sast/astbenchmark/model/alias/Invoke.java - AffectedNodeName: y - 142: ARG PASS: public static X assign(X x, Y y) { - /src/main/java/com/sast/astbenchmark/model/alias/Invoke.java - AffectedNodeName: [x.y] - 143: Var Pass: x.y = y; - /src/main/java/com/sast/astbenchmark/model/alias/Invoke.java - AffectedNodeName: [return value] - 144: Return Value: return x; /src/main/java/com/sast/astbenchmark/case_language_maturity/accuracy/context_sensitive/multi_invoke/multi_invoke_without_solve/DifferentParamsForFunction_001_T.java AffectedNodeName: assign 34: CALL RETURN: X rx1 = Invoke.assign(x1, y1); @@ -4071,7 +4184,7 @@ Trace: AffectedNodeName: Runtime.getRuntime().exec 36: SINK: Runtime.getRuntime().exec(rx1.y.f); -------------- 171: taint_flow_java_input_inner------------- +------------- 182: taint_flow_java_input_inner------------- Description:Java污点分析checker,不会使用CallGraph边界制作entrypoint,蚂蚁内部使用 File:/src/main/java/com/sast/astbenchmark/case_language_maturity/accuracy/context_sensitive/multi_invoke/multi_invoke_without_solve/DifferentParamsForFunction_003_T.java Line 29: Runtime.getRuntime().exec(c1) @@ -4086,15 +4199,6 @@ Trace: /src/main/java/com/sast/astbenchmark/case_language_maturity/accuracy/context_sensitive/multi_invoke/multi_invoke_without_solve/DifferentParamsForFunction_003_T.java AffectedNodeName: id 27: CALL: String c1 = Invoke.id(cmd); - /src/main/java/com/sast/astbenchmark/model/alias/Invoke.java - AffectedNodeName: data - 87: ARG PASS: public static String id(String data) { - /src/main/java/com/sast/astbenchmark/model/alias/Invoke.java - AffectedNodeName: ret - 88: Var Pass: String ret = data; - /src/main/java/com/sast/astbenchmark/model/alias/Invoke.java - AffectedNodeName: [return value] - 89: Return Value: return ret; /src/main/java/com/sast/astbenchmark/case_language_maturity/accuracy/context_sensitive/multi_invoke/multi_invoke_without_solve/DifferentParamsForFunction_003_T.java AffectedNodeName: id 27: CALL RETURN: String c1 = Invoke.id(cmd); @@ -4105,7 +4209,7 @@ Trace: AffectedNodeName: Runtime.getRuntime().exec 29: SINK: Runtime.getRuntime().exec(c1); -------------- 172: taint_flow_java_input_inner------------- +------------- 183: taint_flow_java_input_inner------------- Description:Java污点分析checker,不会使用CallGraph边界制作entrypoint,蚂蚁内部使用 File:/src/main/java/com/sast/astbenchmark/case_language_maturity/accuracy/context_sensitive/multi_invoke/multi_invoke_without_solve/MultiCallSite_001_T.java Line 28: Runtime.getRuntime().exec(c2) @@ -4120,111 +4224,6 @@ Trace: /src/main/java/com/sast/astbenchmark/case_language_maturity/accuracy/context_sensitive/multi_invoke/multi_invoke_without_solve/MultiCallSite_001_T.java AffectedNodeName: id8 26: CALL: String c1 = Invoke.id8(cmd1); - /src/main/java/com/sast/astbenchmark/model/alias/Invoke.java - AffectedNodeName: data - 120: ARG PASS: public static String id8(String data) { - /src/main/java/com/sast/astbenchmark/model/alias/Invoke.java - AffectedNodeName: id7 - 121: CALL: return id7(data + "bar"); - /src/main/java/com/sast/astbenchmark/model/alias/Invoke.java - AffectedNodeName: data - 116: ARG PASS: public static String id7(String data) { - /src/main/java/com/sast/astbenchmark/model/alias/Invoke.java - AffectedNodeName: id6 - 117: CALL: return id6(data + "bar"); - /src/main/java/com/sast/astbenchmark/model/alias/Invoke.java - AffectedNodeName: data - 112: ARG PASS: public static String id6(String data) { - /src/main/java/com/sast/astbenchmark/model/alias/Invoke.java - AffectedNodeName: id5 - 113: CALL: return id5(data + "bar"); - /src/main/java/com/sast/astbenchmark/model/alias/Invoke.java - AffectedNodeName: data - 108: ARG PASS: public static String id5(String data) { - /src/main/java/com/sast/astbenchmark/model/alias/Invoke.java - AffectedNodeName: id4 - 109: CALL: return id4(data + "bar"); - /src/main/java/com/sast/astbenchmark/model/alias/Invoke.java - AffectedNodeName: data - 104: ARG PASS: public static String id4(String data) { - /src/main/java/com/sast/astbenchmark/model/alias/Invoke.java - AffectedNodeName: id3 - 105: CALL: return id3(data + "bar"); - /src/main/java/com/sast/astbenchmark/model/alias/Invoke.java - AffectedNodeName: data - 100: ARG PASS: public static String id3(String data) { - /src/main/java/com/sast/astbenchmark/model/alias/Invoke.java - AffectedNodeName: id2 - 101: CALL: return id2(data + "bar"); - /src/main/java/com/sast/astbenchmark/model/alias/Invoke.java - AffectedNodeName: data - 96: ARG PASS: public static String id2(String data) { - /src/main/java/com/sast/astbenchmark/model/alias/Invoke.java - AffectedNodeName: id1 - 97: CALL: return id1(data + "bar"); - /src/main/java/com/sast/astbenchmark/model/alias/Invoke.java - AffectedNodeName: data - 92: ARG PASS: public static String id1(String data) { - /src/main/java/com/sast/astbenchmark/model/alias/Invoke.java - AffectedNodeName: id - 93: CALL: return id(data + "bar"); - /src/main/java/com/sast/astbenchmark/model/alias/Invoke.java - AffectedNodeName: data - 87: ARG PASS: public static String id(String data) { - /src/main/java/com/sast/astbenchmark/model/alias/Invoke.java - AffectedNodeName: ret - 88: Var Pass: String ret = data; - /src/main/java/com/sast/astbenchmark/model/alias/Invoke.java - AffectedNodeName: [return value] - 89: Return Value: return ret; - /src/main/java/com/sast/astbenchmark/model/alias/Invoke.java - AffectedNodeName: id - 93: CALL RETURN: return id(data + "bar"); - /src/main/java/com/sast/astbenchmark/model/alias/Invoke.java - AffectedNodeName: [return value] - 93: Return Value: return id(data + "bar"); - /src/main/java/com/sast/astbenchmark/model/alias/Invoke.java - AffectedNodeName: id1 - 97: CALL RETURN: return id1(data + "bar"); - /src/main/java/com/sast/astbenchmark/model/alias/Invoke.java - AffectedNodeName: [return value] - 97: Return Value: return id1(data + "bar"); - /src/main/java/com/sast/astbenchmark/model/alias/Invoke.java - AffectedNodeName: id2 - 101: CALL RETURN: return id2(data + "bar"); - /src/main/java/com/sast/astbenchmark/model/alias/Invoke.java - AffectedNodeName: [return value] - 101: Return Value: return id2(data + "bar"); - /src/main/java/com/sast/astbenchmark/model/alias/Invoke.java - AffectedNodeName: id3 - 105: CALL RETURN: return id3(data + "bar"); - /src/main/java/com/sast/astbenchmark/model/alias/Invoke.java - AffectedNodeName: [return value] - 105: Return Value: return id3(data + "bar"); - /src/main/java/com/sast/astbenchmark/model/alias/Invoke.java - AffectedNodeName: id4 - 109: CALL RETURN: return id4(data + "bar"); - /src/main/java/com/sast/astbenchmark/model/alias/Invoke.java - AffectedNodeName: [return value] - 109: Return Value: return id4(data + "bar"); - /src/main/java/com/sast/astbenchmark/model/alias/Invoke.java - AffectedNodeName: id5 - 113: CALL RETURN: return id5(data + "bar"); - /src/main/java/com/sast/astbenchmark/model/alias/Invoke.java - AffectedNodeName: [return value] - 113: Return Value: return id5(data + "bar"); - /src/main/java/com/sast/astbenchmark/model/alias/Invoke.java - AffectedNodeName: id6 - 117: CALL RETURN: return id6(data + "bar"); - /src/main/java/com/sast/astbenchmark/model/alias/Invoke.java - AffectedNodeName: [return value] - 117: Return Value: return id6(data + "bar"); - /src/main/java/com/sast/astbenchmark/model/alias/Invoke.java - AffectedNodeName: id7 - 121: CALL RETURN: return id7(data + "bar"); - /src/main/java/com/sast/astbenchmark/model/alias/Invoke.java - AffectedNodeName: [return value] - 121: Return Value: return id7(data + "bar"); /src/main/java/com/sast/astbenchmark/case_language_maturity/accuracy/context_sensitive/multi_invoke/multi_invoke_without_solve/MultiCallSite_001_T.java AffectedNodeName: id8 26: CALL RETURN: String c1 = Invoke.id8(cmd1); @@ -4238,7 +4237,7 @@ Trace: AffectedNodeName: Runtime.getRuntime().exec 28: SINK: Runtime.getRuntime().exec(c2); -------------- 173: taint_flow_java_input_inner------------- +------------- 184: taint_flow_java_input_inner------------- Description:Java污点分析checker,不会使用CallGraph边界制作entrypoint,蚂蚁内部使用 File:/src/main/java/com/sast/astbenchmark/case_language_maturity/accuracy/flow_sensitive/loop_stmt/loop_stmt_init/Statement_ForStatement_init_001_T.java Line 28: Runtime.getRuntime().exec(a) @@ -4257,7 +4256,7 @@ Trace: AffectedNodeName: Runtime.getRuntime().exec 28: SINK: Runtime.getRuntime().exec(a); -------------- 174: taint_flow_java_input_inner------------- +------------- 185: taint_flow_java_input_inner------------- Description:Java污点分析checker,不会使用CallGraph边界制作entrypoint,蚂蚁内部使用 File:/src/main/java/com/sast/astbenchmark/case_language_maturity/accuracy/flow_sensitive/loop_stmt/loop_stmt_update/Statement_ForStatement_update_001_T.java Line 26: Runtime.getRuntime().exec(a) @@ -4276,7 +4275,7 @@ Trace: AffectedNodeName: Runtime.getRuntime().exec 26: SINK: for (int i = 0; i < 1; Runtime.getRuntime().exec(a)) { -------------- 175: taint_flow_java_input_inner------------- +------------- 186: taint_flow_java_input_inner------------- Description:Java污点分析checker,不会使用CallGraph边界制作entrypoint,蚂蚁内部使用 File:/src/main/java/com/sast/astbenchmark/case_language_maturity/accuracy/path_sensitive/loop_conditional_stmt/no_solver/ConstantIfGuard_001_T.java Line 27: Runtime.getRuntime().exec(exec) @@ -4291,15 +4290,6 @@ Trace: /src/main/java/com/sast/astbenchmark/case_language_maturity/accuracy/path_sensitive/loop_conditional_stmt/no_solver/ConstantIfGuard_001_T.java AffectedNodeName: getCmdWithPathSensitive 25: CALL: String exec = getCmdWithPathSensitive(cmd); - /src/main/java/com/sast/astbenchmark/case_language_maturity/accuracy/path_sensitive/loop_conditional_stmt/no_solver/ConstantIfGuard_001_T.java - AffectedNodeName: cmd - 35: ARG PASS: private String getCmdWithPathSensitive(String cmd) { - /src/main/java/com/sast/astbenchmark/case_language_maturity/accuracy/path_sensitive/loop_conditional_stmt/no_solver/ConstantIfGuard_001_T.java - AffectedNodeName: [return value] - 38: Return Value: return cmd; - /src/main/java/com/sast/astbenchmark/case_language_maturity/accuracy/path_sensitive/loop_conditional_stmt/no_solver/ConstantIfGuard_001_T.java - AffectedNodeName: [return value] - 40: Return Value: return "ls"; /src/main/java/com/sast/astbenchmark/case_language_maturity/accuracy/path_sensitive/loop_conditional_stmt/no_solver/ConstantIfGuard_001_T.java AffectedNodeName: getCmdWithPathSensitive 25: CALL RETURN: String exec = getCmdWithPathSensitive(cmd); @@ -4310,41 +4300,7 @@ Trace: AffectedNodeName: Runtime.getRuntime().exec 27: SINK: Runtime.getRuntime().exec(exec); -------------- 176: taint_flow_java_input_inner------------- -Description:Java污点分析checker,不会使用CallGraph边界制作entrypoint,蚂蚁内部使用 -File:/src/main/java/com/sast/astbenchmark/case_language_maturity/accuracy/path_sensitive/loop_conditional_stmt/no_solver/ConstantIfGuard_002_F.java -Line 27: Runtime.getRuntime().exec(exec) -SINK RULE:Runtime.getRuntime().exec -SINK Attribute:JavaCommandExec -entrypoint: -{"filePath":"/src/main/java/com/sast/astbenchmark/case_language_maturity/accuracy/path_sensitive/loop_conditional_stmt/no_solver/ConstantIfGuard_002_F.java","functionName":"testcase","attribute":"HTTP","type":"functionCall"} -Trace: - /src/main/java/com/sast/astbenchmark/case_language_maturity/accuracy/path_sensitive/loop_conditional_stmt/no_solver/ConstantIfGuard_002_F.java - AffectedNodeName: cmd - 23: SOURCE: public Map testcase(@RequestParam String cmd) { - /src/main/java/com/sast/astbenchmark/case_language_maturity/accuracy/path_sensitive/loop_conditional_stmt/no_solver/ConstantIfGuard_002_F.java - AffectedNodeName: getCmdWithPathSensitive - 25: CALL: String exec = getCmdWithPathSensitive(cmd); - /src/main/java/com/sast/astbenchmark/case_language_maturity/accuracy/path_sensitive/loop_conditional_stmt/no_solver/ConstantIfGuard_002_F.java - AffectedNodeName: cmd - 35: ARG PASS: private String getCmdWithPathSensitive(String cmd) { - /src/main/java/com/sast/astbenchmark/case_language_maturity/accuracy/path_sensitive/loop_conditional_stmt/no_solver/ConstantIfGuard_002_F.java - AffectedNodeName: [return value] - 38: Return Value: return cmd; - /src/main/java/com/sast/astbenchmark/case_language_maturity/accuracy/path_sensitive/loop_conditional_stmt/no_solver/ConstantIfGuard_002_F.java - AffectedNodeName: [return value] - 40: Return Value: return "ls"; - /src/main/java/com/sast/astbenchmark/case_language_maturity/accuracy/path_sensitive/loop_conditional_stmt/no_solver/ConstantIfGuard_002_F.java - AffectedNodeName: getCmdWithPathSensitive - 25: CALL RETURN: String exec = getCmdWithPathSensitive(cmd); - /src/main/java/com/sast/astbenchmark/case_language_maturity/accuracy/path_sensitive/loop_conditional_stmt/no_solver/ConstantIfGuard_002_F.java - AffectedNodeName: exec - 25: Var Pass: String exec = getCmdWithPathSensitive(cmd); - /src/main/java/com/sast/astbenchmark/case_language_maturity/accuracy/path_sensitive/loop_conditional_stmt/no_solver/ConstantIfGuard_002_F.java - AffectedNodeName: Runtime.getRuntime().exec - 27: SINK: Runtime.getRuntime().exec(exec); - -------------- 177: taint_flow_java_input_inner------------- +------------- 187: taint_flow_java_input_inner------------- Description:Java污点分析checker,不会使用CallGraph边界制作entrypoint,蚂蚁内部使用 File:/src/main/java/com/sast/astbenchmark/case_language_maturity/accuracy/path_sensitive/loop_conditional_stmt/no_solver/Statement_ForStatement_no_solver_001_T.java Line 29: Runtime.getRuntime().exec(a) @@ -4363,7 +4319,7 @@ Trace: AffectedNodeName: Runtime.getRuntime().exec 29: SINK: Runtime.getRuntime().exec(a); -------------- 178: taint_flow_java_input_inner------------- +------------- 188: taint_flow_java_input_inner------------- Description:Java污点分析checker,不会使用CallGraph边界制作entrypoint,蚂蚁内部使用 File:/src/main/java/com/sast/astbenchmark/case_language_maturity/accuracy/path_sensitive/loop_conditional_stmt/solver/DifferentIfBranch_ArrayLength_001_T.java Line 29: Runtime.getRuntime().exec(arr) @@ -4382,26 +4338,7 @@ Trace: AffectedNodeName: Runtime.getRuntime().exec 29: SINK: Runtime.getRuntime().exec(arr); -------------- 179: taint_flow_java_input_inner------------- -Description:Java污点分析checker,不会使用CallGraph边界制作entrypoint,蚂蚁内部使用 -File:/src/main/java/com/sast/astbenchmark/case_language_maturity/accuracy/path_sensitive/loop_conditional_stmt/solver/DifferentIfBranch_ArrayLength_002_F.java -Line 29: Runtime.getRuntime().exec(arr) -SINK RULE:Runtime.getRuntime().exec -SINK Attribute:JavaCommandExec -entrypoint: -{"filePath":"/src/main/java/com/sast/astbenchmark/case_language_maturity/accuracy/path_sensitive/loop_conditional_stmt/solver/DifferentIfBranch_ArrayLength_002_F.java","functionName":"testcase","attribute":"HTTP","type":"functionCall"} -Trace: - /src/main/java/com/sast/astbenchmark/case_language_maturity/accuracy/path_sensitive/loop_conditional_stmt/solver/DifferentIfBranch_ArrayLength_002_F.java - AffectedNodeName: cmd - 22: SOURCE: public Map testcase(@RequestParam String cmd) { - /src/main/java/com/sast/astbenchmark/case_language_maturity/accuracy/path_sensitive/loop_conditional_stmt/solver/DifferentIfBranch_ArrayLength_002_F.java - AffectedNodeName: arr[1] - 27: Var Pass: arr[1] = cmd; // UnReachable - /src/main/java/com/sast/astbenchmark/case_language_maturity/accuracy/path_sensitive/loop_conditional_stmt/solver/DifferentIfBranch_ArrayLength_002_F.java - AffectedNodeName: Runtime.getRuntime().exec - 29: SINK: Runtime.getRuntime().exec(arr); - -------------- 180: taint_flow_java_input_inner------------- +------------- 189: taint_flow_java_input_inner------------- Description:Java污点分析checker,不会使用CallGraph边界制作entrypoint,蚂蚁内部使用 File:/src/main/java/com/sast/astbenchmark/case_language_maturity/accuracy/path_sensitive/loop_conditional_stmt/solver/DifferentIfBranch_ArrayLength_003_T.java Line 30: Runtime.getRuntime().exec(arr2) @@ -4420,7 +4357,7 @@ Trace: AffectedNodeName: Runtime.getRuntime().exec 30: SINK: Runtime.getRuntime().exec(arr2); -------------- 181: taint_flow_java_input_inner------------- +------------- 190: taint_flow_java_input_inner------------- Description:Java污点分析checker,不会使用CallGraph边界制作entrypoint,蚂蚁内部使用 File:/src/main/java/com/sast/astbenchmark/case_language_maturity/accuracy/path_sensitive/loop_conditional_stmt/solver/Expression_InstanceofExpression_solver_001_T.java Line 26: Runtime.getRuntime().exec(cmd) @@ -4436,23 +4373,7 @@ Trace: AffectedNodeName: Runtime.getRuntime().exec 26: SINK: Runtime.getRuntime().exec(cmd); -------------- 182: taint_flow_java_input_inner------------- -Description:Java污点分析checker,不会使用CallGraph边界制作entrypoint,蚂蚁内部使用 -File:/src/main/java/com/sast/astbenchmark/case_language_maturity/accuracy/path_sensitive/loop_conditional_stmt/solver/Expression_InstanceofExpression_solver_002_F.java -Line 28: Runtime.getRuntime().exec(cmd) -SINK RULE:Runtime.getRuntime().exec -SINK Attribute:JavaCommandExec -entrypoint: -{"filePath":"/src/main/java/com/sast/astbenchmark/case_language_maturity/accuracy/path_sensitive/loop_conditional_stmt/solver/Expression_InstanceofExpression_solver_002_F.java","functionName":"testcase","attribute":"HTTP","type":"functionCall"} -Trace: - /src/main/java/com/sast/astbenchmark/case_language_maturity/accuracy/path_sensitive/loop_conditional_stmt/solver/Expression_InstanceofExpression_solver_002_F.java - AffectedNodeName: cmd - 22: SOURCE: public Map testcase(@PathVariable String cmd) { - /src/main/java/com/sast/astbenchmark/case_language_maturity/accuracy/path_sensitive/loop_conditional_stmt/solver/Expression_InstanceofExpression_solver_002_F.java - AffectedNodeName: Runtime.getRuntime().exec - 28: SINK: Runtime.getRuntime().exec(cmd); - -------------- 183: taint_flow_java_input_inner------------- +------------- 191: taint_flow_java_input_inner------------- Description:Java污点分析checker,不会使用CallGraph边界制作entrypoint,蚂蚁内部使用 File:/src/main/java/com/sast/astbenchmark/case_language_maturity/accuracy/path_sensitive/loop_conditional_stmt/solver/Expression_InstanceofExpression_solver_003_T.java Line 28: Runtime.getRuntime().exec(cmd) @@ -4468,23 +4389,7 @@ Trace: AffectedNodeName: Runtime.getRuntime().exec 28: SINK: Runtime.getRuntime().exec(cmd); -------------- 184: taint_flow_java_input_inner------------- -Description:Java污点分析checker,不会使用CallGraph边界制作entrypoint,蚂蚁内部使用 -File:/src/main/java/com/sast/astbenchmark/case_language_maturity/accuracy/path_sensitive/loop_conditional_stmt/solver/Expression_InstanceofExpression_solver_004_F.java -Line 26: Runtime.getRuntime().exec(cmd) -SINK RULE:Runtime.getRuntime().exec -SINK Attribute:JavaCommandExec -entrypoint: -{"filePath":"/src/main/java/com/sast/astbenchmark/case_language_maturity/accuracy/path_sensitive/loop_conditional_stmt/solver/Expression_InstanceofExpression_solver_004_F.java","functionName":"testcase","attribute":"HTTP","type":"functionCall"} -Trace: - /src/main/java/com/sast/astbenchmark/case_language_maturity/accuracy/path_sensitive/loop_conditional_stmt/solver/Expression_InstanceofExpression_solver_004_F.java - AffectedNodeName: cmd - 22: SOURCE: public Map testcase(@PathVariable String cmd) { - /src/main/java/com/sast/astbenchmark/case_language_maturity/accuracy/path_sensitive/loop_conditional_stmt/solver/Expression_InstanceofExpression_solver_004_F.java - AffectedNodeName: Runtime.getRuntime().exec - 26: SINK: Runtime.getRuntime().exec(cmd); - -------------- 185: taint_flow_java_input_inner------------- +------------- 192: taint_flow_java_input_inner------------- Description:Java污点分析checker,不会使用CallGraph边界制作entrypoint,蚂蚁内部使用 File:/src/main/java/com/sast/astbenchmark/case_language_maturity/accuracy/path_sensitive/loop_conditional_stmt/solver/Statement_AssertStatement_solver_001_T.java Line 26: Runtime.getRuntime().exec(cmd) @@ -4500,7 +4405,7 @@ Trace: AffectedNodeName: Runtime.getRuntime().exec 26: SINK: assert a > 0 : Runtime.getRuntime().exec(cmd); -------------- 186: taint_flow_java_input_inner------------- +------------- 193: taint_flow_java_input_inner------------- Description:Java污点分析checker,不会使用CallGraph边界制作entrypoint,蚂蚁内部使用 File:/src/main/java/com/sast/astbenchmark/case_language_maturity/accuracy/path_sensitive/loop_conditional_stmt/solver/Statement_AssertStatement_solver_003_T.java Line 26: Runtime.getRuntime().exec(cmd) @@ -4516,7 +4421,7 @@ Trace: AffectedNodeName: Runtime.getRuntime().exec 26: SINK: assert a > 0 : Runtime.getRuntime().exec(cmd); -------------- 187: taint_flow_java_input_inner------------- +------------- 194: taint_flow_java_input_inner------------- Description:Java污点分析checker,不会使用CallGraph边界制作entrypoint,蚂蚁内部使用 File:/src/main/java/com/sast/astbenchmark/case_language_maturity/accuracy/path_sensitive/loop_conditional_stmt/solver/Statement_WhileStatement_solver_001_T.java Line 29: Runtime.getRuntime().exec(a) @@ -4535,7 +4440,7 @@ Trace: AffectedNodeName: Runtime.getRuntime().exec 29: SINK: Runtime.getRuntime().exec(a); -------------- 188: taint_flow_java_input_inner------------- +------------- 195: taint_flow_java_input_inner------------- Description:Java污点分析checker,不会使用CallGraph边界制作entrypoint,蚂蚁内部使用 File:/src/main/java/com/sast/astbenchmark/case_language_maturity/accuracy/path_sensitive/loop_conditional_stmt/solver/Statement_WhileStatement_solver_002_F.java Line 31: Runtime.getRuntime().exec(a) @@ -4554,7 +4459,7 @@ Trace: AffectedNodeName: Runtime.getRuntime().exec 31: SINK: Runtime.getRuntime().exec(a); -------------- 189: taint_flow_java_input_inner------------- +------------- 196: taint_flow_java_input_inner------------- Description:Java污点分析checker,不会使用CallGraph边界制作entrypoint,蚂蚁内部使用 File:/src/main/java/com/sast/astbenchmark/case_language_maturity/completeness/single_app_tracing/cross_file_package_namespace/cross_file/cross_file_001_T/cross_file_001_T_b.java Line 23: Runtime.getRuntime().exec(cmd) @@ -4576,7 +4481,7 @@ Trace: AffectedNodeName: Runtime.getRuntime().exec 23: SINK: Runtime.getRuntime().exec(cmd); -------------- 190: taint_flow_java_input_inner------------- +------------- 197: taint_flow_java_input_inner------------- Description:Java污点分析checker,不会使用CallGraph边界制作entrypoint,蚂蚁内部使用 File:/src/main/java/com/sast/astbenchmark/case_language_maturity/completeness/single_app_tracing/cross_file_package_namespace/cross_directory/cross_directory_001_T/B/cross_directory_001_T_b.java Line 23: Runtime.getRuntime().exec(cmd) @@ -4598,5 +4503,5 @@ Trace: AffectedNodeName: Runtime.getRuntime().exec 23: SINK: Runtime.getRuntime().exec(cmd); ========================================================== - #Total-findings:190 + #Total-findings:197 ========================================================== \ No newline at end of file diff --git a/test/java/rule_config_xast_java.json b/test/java/rule_config_xast_java.json index e205fb4a..741f8b3c 100644 --- a/test/java/rule_config_xast_java.json +++ b/test/java/rule_config_xast_java.json @@ -70,10 +70,11 @@ "attribute": "JavaSSRF", "calleeType": "java.sql.Statement", "fsig": "executeQuery" - } - ], - "ObjectTaintFuncCallSink": [ + }, { + "args": [ + "-1" + ], "attribute": "JavaSSRF", "calleeType": "java.net.URL", "fsig": "openConnection" diff --git a/test/java/test-java-benchmark.ts b/test/java/test-java-benchmark.ts index ff15565a..ccba8f5b 100644 --- a/test/java/test-java-benchmark.ts +++ b/test/java/test-java-benchmark.ts @@ -1,5 +1,5 @@ import * as path from 'path' -import { describe, it } from 'mocha' +import { describe, it, before } from 'mocha' const { execute } = require('../../src/interface/starter') const { ErrorCode } = require('../../src/util/error-code') const { recordFindingStr, readExpectRes, resolveFindingResult } = require('../test-utils') @@ -8,20 +8,55 @@ import * as fs from 'fs' const logger = require('../../src/util/logger')(__filename) const { handleException } = require('../../src/engine/analyzer/common/exception-handler') -async function runJavaBenchmark(dir: string): Promise { +function runJavaBenchmark(dir: string): void { const description = `YASA test Java benchmark` - describe(description, async function () { - let result = await getRunJavaBenchmarkResult(dir) - const { expectedRes, actualRes, expectedResMap, actualResMap } = result - this.timeout(10000) + const ruleConfigFile = path.join(path.resolve(dir), '../../rule_config_xast_java.json') + const repoName = path.basename(dir) + const expectPath = path.join(dir, '..', '..', 'expect', `${repoName}-expect.result`) + + // 先同步读取期望结果,用于注册测试用例 + let expectedResForRegistration: any = null + let expectedResMapForRegistration: Map = new Map() + if (fs.existsSync(expectPath)) { + expectedResForRegistration = readExpectRes(expectPath) + expectedResMapForRegistration = resolveFindingResult(expectedResForRegistration) + } + + describe(description, function () { + this.timeout(0) + let result: any + let expectedRes: any + let actualRes: any + let expectedResMap: Map + let actualResMap: Map + let benchmarkReady = false + + before(async function () { + result = await getRunJavaBenchmarkResult(dir) + expectedRes = result.expectedRes + actualRes = result.actualRes + expectedResMap = result.expectedResMap + actualResMap = result.actualResMap + benchmarkReady = true + }) it(`check result data directly`, function () { + if (!benchmarkReady) { + this.skip() + return + } logger.info(actualRes) assert.strictEqual(actualRes, expectedRes, '当前靶场扫描结果与历史预期不一致,请逐个核对链路') }) + + // 使用预先读取的期望结果注册测试用例 let i = 1 - expectedResMap.forEach((value, key) => { + expectedResMapForRegistration.forEach((value, key) => { it(`${i++}-entryPointName:${key}`, function () { + if (!benchmarkReady) { + this.skip() + return + } logger.info('expected:\n' + value) logger.info('actual:\n' + actualResMap.get(key)) if (actualResMap.has(key)) { @@ -32,17 +67,22 @@ async function runJavaBenchmark(dir: string): Promise { }) }) - const actualChains = Array.from(actualResMap.keys()) - let addChains = actualChains.filter((key) => !expectedResMap.has(key)) - if (Array.isArray(addChains) && addChains.length > 0) { - for (const addChain of addChains) { - it(`new chain:${addChain}`, function () { + // 动态检查新增的链(在 before 执行后) + it(`check for new chains`, function () { + if (!benchmarkReady) { + this.skip() + return + } + const actualChains = Array.from(actualResMap.keys()) + let addChains = actualChains.filter((key) => !expectedResMap.has(key)) + if (Array.isArray(addChains) && addChains.length > 0) { + for (const addChain of addChains) { logger.info(`新增检出${addChain},请核对新增检出内容是否符合预期`) logger.info(actualResMap.get(addChain)) - assert.fail(`new chain:${addChain}`) - }) + } + assert.fail(`new chain:${addChains.length}`) } - } + }) }) } diff --git a/test/java/test-java-real-project.ts b/test/java/test-java-real-project.ts new file mode 100644 index 00000000..868b289d --- /dev/null +++ b/test/java/test-java-real-project.ts @@ -0,0 +1,189 @@ +import path from 'path' +import fs from 'fs' +import { before, describe, it } from 'mocha' +import assert from 'assert' +const { execute } = require('../../src/interface/starter') +const { handleException } = require('../../src/engine/analyzer/common/exception-handler') +const { ErrorCode } = require('../../src/util/error-code') +const { recordFindingStr, readExpectRes, resolveFindingResult } = require('../test-utils') +const logger = require('../../src/util/logger')(__filename) + +function runSingleProject(dir: string, ruleConfigFile: string, expectPath: string) { + const description = `YASA test ${dir}` + const repoName = path.basename(dir) + + let expectedResForRegistration: any = null + let expectedResMapForRegistration: Map = new Map() + if (fs.existsSync(expectPath)) { + expectedResForRegistration = readExpectRes(expectPath) + expectedResMapForRegistration = resolveFindingResult(expectedResForRegistration) + } + + describe(description, function () { + this.timeout(0) + let result: any + let expectedRes: any + let actualRes: any + let expectedResMap: Map + let actualResMap: Map + let benchmarkReady = false + + before(async function () { + result = await getRunJavaBenchmarkResult(dir, ruleConfigFile, expectPath) + expectedRes = result.expectedRes + actualRes = result.actualRes + expectedResMap = result.expectedResMap + actualResMap = result.actualResMap + benchmarkReady = true + }) + + it(`check result data directly`, function () { + if (!benchmarkReady) { + this.skip() + return + } + logger.info(actualRes) + assert.strictEqual(actualRes, expectedRes, '当前靶场扫描结果与历史预期不一致,请逐个核对链路') + }) + + // 使用预先读取的期望结果注册测试用例 + let i = 1 + expectedResMapForRegistration.forEach((value, key) => { + it(`${i++}-entryPointName:${key}`, function () { + if (!benchmarkReady) { + this.skip() + return + } + logger.info('expected:\n' + value) + logger.info('actual:\n' + actualResMap.get(key)) + if (actualResMap.has(key)) { + assert.strictEqual(actualResMap.get(key), value, `链路${key}实际trace或内容与预期不一致,请核对该链路`) + } else { + assert.fail(`链路或key${key}不存在!!!`) + } + }) + }) + + // 动态检查新增的链(在 before 执行后) + it(`check for new chains`, function () { + if (!benchmarkReady) { + this.skip() + return + } + const actualChains = Array.from(actualResMap.keys()) + let addChains = actualChains.filter((key) => !expectedResMap.has(key)) + if (Array.isArray(addChains) && addChains.length > 0) { + for (const addChain of addChains) { + logger.info(`新增检出${addChain},请核对新增检出内容是否符合预期`) + logger.info(actualResMap.get(addChain)) + } + assert.fail(`new chain:${addChains.length}`) + } + }) + }) +} + +function runMultiProject(dir: string) { + const direntNames = fs + .readdirSync(dir, { withFileTypes: true }) + .filter((element) => element.isDirectory()) + .map((element) => element.name) + for (const direntName of direntNames) { + const projectDir = path.join(dir, direntName) + runSingleProject(projectDir, projectDir + '.json', projectDir + '.result') + } +} + +async function getRunJavaBenchmarkResult( + dir: string, + ruleConfigFile: string, + expectPath: string +): Promise<{ + expectedRes: any + actualRes: any + expectedResMap: Map + actualResMap: Map +}> { + const repoName = path.basename(dir) + + let expectedRes: any, actualRes: any, expectedResMap: Map, actualResMap: Map + let recorder = recordFindingStr() + recorder.clearResult() + + let args = [ + dir, + '--ruleConfigFile', + ruleConfigFile, + '--language', + 'java', + '--checkerPackIds', + 'taint-flow-java-inner', + '--entrypointMode', + 'ONLY_CUSTOM', + ] + await (async () => { + try { + await execute(null, args, recorder.printAndAppend) + } catch (e) { + handleException( + e, + `[test-java-benchmark] 运行Java基准测试时发生错误.ERROR: ${e}`, + `[test-java-benchmark] 运行Java基准测试时发生错误.ERROR: ${e}` + ) + recorder.clearResult() + process.exitCode = ErrorCode.unknown_error + } + })() + + expectedRes = readExpectRes(expectPath) + actualRes = recorder.getFormatResult() + expectedResMap = resolveFindingResult(expectedRes) + actualResMap = resolveFindingResult(actualRes) + + return { + expectedRes, + actualRes, + expectedResMap, + actualResMap, + } +} + +async function updateExpect(dir: string, ruleConfigFile: string, expectPath: string): Promise { + const repoName = path.basename(dir) + let actualRes: any + let recorder = recordFindingStr() + recorder.clearResult() + let args = [ + dir, + '--ruleConfigFile', + ruleConfigFile, + '--language', + 'java', + '--checkerPackIds', + 'taint-flow-java-inner', + '--entrypointMode', + 'ONLY_CUSTOM', + ] + try { + await execute(null, args, recorder.printAndAppend) + } catch (e) { + handleException( + e, + `[test-java-benchmark] 更新预期结果时发生错误.ERROR: ${e}`, + `[test-java-benchmark] 更新预期结果时发生错误.ERROR: ${e}` + ) + recorder.clearResult() + process.exitCode = ErrorCode.unknown_error + } + actualRes = recorder.getFormatResult() + fs.writeFileSync(expectPath, actualRes, { + encoding: 'utf8', + }) +} + +// const dir = '' +// runMultiProject(dir) + +// const dir = '' +// runSingleProject(dir, dir + '.json', dir + '.result') +// updateExpect(dir, dir + '.json', dir + '.result') diff --git a/test/javascript/expect/jsbenchmark-expect.json b/test/javascript/expect/jsbenchmark-expect.json index cf113153..1df30acb 100644 --- a/test/javascript/expect/jsbenchmark-expect.json +++ b/test/javascript/expect/jsbenchmark-expect.json @@ -1 +1 @@ -{"/jsbenchmark/accuracy/context_sensitive/argument_return_value_passing/argument_passing_value_001_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/jsbenchmark/accuracy/context_sensitive/argument_return_value_passing/argument_passing_value_001_T\nLine 14: __taint_sink(arg)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/jsbenchmark/accuracy/context_sensitive/argument_return_value_passing/argument_passing_value_001_T\",\"functionName\":\"argument_passing_value_001_T\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /jsbenchmark/accuracy/context_sensitive/argument_return_value_passing/argument_passing_value_001_T\n AffectedNodeName: __taint_src\n 10: SOURCE: function argument_passing_value_001_T(__taint_src) {\n /jsbenchmark/accuracy/context_sensitive/argument_return_value_passing/argument_passing_value_001_T\n AffectedNodeName: process\n 11: CALL: process(__taint_src);\n /jsbenchmark/accuracy/context_sensitive/argument_return_value_passing/argument_passing_value_001_T\n AffectedNodeName: arg\n 13: ARG PASS: function process(arg) {\n /jsbenchmark/accuracy/context_sensitive/argument_return_value_passing/argument_passing_value_001_T\n AffectedNodeName: __taint_sink\n 14: SINK: __taint_sink(arg);\n==========================================================\n #Total-findings:1\n==========================================================","/jsbenchmark/accuracy/context_sensitive/argument_return_value_passing/argument_passing_value_002_F":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/accuracy/context_sensitive/argument_return_value_passing/argument_passing_value_003_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/jsbenchmark/accuracy/context_sensitive/argument_return_value_passing/argument_passing_value_003_T\nLine 15: __taint_sink(arg1)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/jsbenchmark/accuracy/context_sensitive/argument_return_value_passing/argument_passing_value_003_T\",\"functionName\":\"argument_passing_value_003_T\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /jsbenchmark/accuracy/context_sensitive/argument_return_value_passing/argument_passing_value_003_T\n AffectedNodeName: __taint_src\n 11: SOURCE: function argument_passing_value_003_T(__taint_src) {\n /jsbenchmark/accuracy/context_sensitive/argument_return_value_passing/argument_passing_value_003_T\n AffectedNodeName: process\n 12: CALL: process(__taint_src, \"_\");\n /jsbenchmark/accuracy/context_sensitive/argument_return_value_passing/argument_passing_value_003_T\n AffectedNodeName: arg1\n 14: ARG PASS: function process(arg1, arg2) {\n /jsbenchmark/accuracy/context_sensitive/argument_return_value_passing/argument_passing_value_003_T\n AffectedNodeName: __taint_sink\n 15: SINK: __taint_sink(arg1);\n==========================================================\n #Total-findings:1\n==========================================================","/jsbenchmark/accuracy/context_sensitive/argument_return_value_passing/argument_passing_value_004_F":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/accuracy/context_sensitive/argument_return_value_passing/return_value_passing_001_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/jsbenchmark/accuracy/context_sensitive/argument_return_value_passing/return_value_passing_001_T\nLine 12: __taint_sink(data)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/jsbenchmark/accuracy/context_sensitive/argument_return_value_passing/return_value_passing_001_T\",\"functionName\":\"return_value_passing_001_T\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /jsbenchmark/accuracy/context_sensitive/argument_return_value_passing/return_value_passing_001_T\n AffectedNodeName: __taint_src\n 10: SOURCE: function return_value_passing_001_T(__taint_src) {\n /jsbenchmark/accuracy/context_sensitive/argument_return_value_passing/return_value_passing_001_T\n AffectedNodeName: [return value]\n 15: Return Value: return __taint_src;\n /jsbenchmark/accuracy/context_sensitive/argument_return_value_passing/return_value_passing_001_T\n AffectedNodeName: process\n 11: CALL RETURN: let data = process();\n /jsbenchmark/accuracy/context_sensitive/argument_return_value_passing/return_value_passing_001_T\n AffectedNodeName: data\n 11: Var Pass: let data = process();\n /jsbenchmark/accuracy/context_sensitive/argument_return_value_passing/return_value_passing_001_T\n AffectedNodeName: __taint_sink\n 12: SINK: __taint_sink(data);\n==========================================================\n #Total-findings:1\n==========================================================","/jsbenchmark/accuracy/context_sensitive/argument_return_value_passing/return_value_passing_002_F":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/accuracy/context_sensitive/multi_invoke/multi_invoke_001_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/jsbenchmark/accuracy/context_sensitive/multi_invoke/multi_invoke_001_T\nLine 13: __taint_sink(a)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/jsbenchmark/accuracy/context_sensitive/multi_invoke/multi_invoke_001_T\",\"functionName\":\"multi_invoke_001_T\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /jsbenchmark/accuracy/context_sensitive/multi_invoke/multi_invoke_001_T\n AffectedNodeName: __taint_src\n 10: SOURCE: function multi_invoke_001_T(__taint_src) {\n /jsbenchmark/accuracy/context_sensitive/multi_invoke/multi_invoke_001_T\n AffectedNodeName: process\n 11: CALL: let a = process(__taint_src);\n /jsbenchmark/accuracy/context_sensitive/multi_invoke/multi_invoke_001_T\n AffectedNodeName: arg\n 15: ARG PASS: function process(arg) {\n /jsbenchmark/accuracy/context_sensitive/multi_invoke/multi_invoke_001_T\n AffectedNodeName: [return value]\n 16: Return Value: return arg;\n /jsbenchmark/accuracy/context_sensitive/multi_invoke/multi_invoke_001_T\n AffectedNodeName: process\n 11: CALL RETURN: let a = process(__taint_src);\n /jsbenchmark/accuracy/context_sensitive/multi_invoke/multi_invoke_001_T\n AffectedNodeName: a\n 11: Var Pass: let a = process(__taint_src);\n /jsbenchmark/accuracy/context_sensitive/multi_invoke/multi_invoke_001_T\n AffectedNodeName: __taint_sink\n 13: SINK: __taint_sink(a);\n==========================================================\n #Total-findings:1\n==========================================================","/jsbenchmark/accuracy/context_sensitive/multi_invoke/multi_invoke_002_F":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/accuracy/context_sensitive/polymorphism/no_solver/polymorphism_no_solver_001_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/jsbenchmark/accuracy/context_sensitive/polymorphism/no_solver/polymorphism_no_solver_001_T\nLine 26: __taint_sink(sub.call())\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/jsbenchmark/accuracy/context_sensitive/polymorphism/no_solver/polymorphism_no_solver_001_T\",\"functionName\":\"polymorphism_no_solver_001_T\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /jsbenchmark/accuracy/context_sensitive/polymorphism/no_solver/polymorphism_no_solver_001_T\n AffectedNodeName: __taint_src\n 10: SOURCE: function polymorphism_no_solver_001_T(__taint_src) {\n /jsbenchmark/accuracy/context_sensitive/polymorphism/no_solver/polymorphism_no_solver_001_T\n AffectedNodeName: [return value]\n 15: Return Value: return __taint_src;\n /jsbenchmark/accuracy/context_sensitive/polymorphism/no_solver/polymorphism_no_solver_001_T\n AffectedNodeName: call\n 26: CALL RETURN: __taint_sink(sub.call());\n /jsbenchmark/accuracy/context_sensitive/polymorphism/no_solver/polymorphism_no_solver_001_T\n AffectedNodeName: __taint_sink\n 26: SINK: __taint_sink(sub.call());\n==========================================================\n #Total-findings:1\n==========================================================","/jsbenchmark/accuracy/context_sensitive/polymorphism/no_solver/polymorphism_no_solver_002_F":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/accuracy/context_sensitive/polymorphism/solver/polymorphism_001_T":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/accuracy/context_sensitive/polymorphism/solver/polymorphism_002_F":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/accuracy/field_sensitive/class/constructor_field_001_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/jsbenchmark/accuracy/field_sensitive/class/constructor_field_001_T\nLine 20: __taint_sink(obj.data)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/jsbenchmark/accuracy/field_sensitive/class/constructor_field_001_T\",\"functionName\":\"constructor_field_001_T\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /jsbenchmark/accuracy/field_sensitive/class/constructor_field_001_T\n AffectedNodeName: __taint_src\n 11: SOURCE: function constructor_field_001_T(__taint_src) {\n /jsbenchmark/accuracy/field_sensitive/class/constructor_field_001_T\n AffectedNodeName: [this.data]\n 14: Var Pass: this.data = __taint_src;\n /jsbenchmark/accuracy/field_sensitive/class/constructor_field_001_T\n AffectedNodeName: obj\n 19: Var Pass: let obj = new A();\n /jsbenchmark/accuracy/field_sensitive/class/constructor_field_001_T\n AffectedNodeName: __taint_sink\n 20: SINK: __taint_sink(obj.data);\n==========================================================\n #Total-findings:1\n==========================================================","/jsbenchmark/accuracy/field_sensitive/class/constructor_field_002_F":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/accuracy/field_sensitive/class/constructor_field_003_F":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/accuracy/field_sensitive/class/constructor_field_004_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/jsbenchmark/accuracy/field_sensitive/class/constructor_field_004_T\nLine 20: __taint_sink(obj.data)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/jsbenchmark/accuracy/field_sensitive/class/constructor_field_004_T\",\"functionName\":\"constructor_field_004_T\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /jsbenchmark/accuracy/field_sensitive/class/constructor_field_004_T\n AffectedNodeName: __taint_src\n 11: SOURCE: function constructor_field_004_T(__taint_src) {\n /jsbenchmark/accuracy/field_sensitive/class/constructor_field_004_T\n AffectedNodeName: constructor\n 19: CALL: let obj = new A(__taint_src);\n /jsbenchmark/accuracy/field_sensitive/class/constructor_field_004_T\n AffectedNodeName: param\n 13: ARG PASS: constructor(param) {\n /jsbenchmark/accuracy/field_sensitive/class/constructor_field_004_T\n AffectedNodeName: [this.data]\n 14: Var Pass: this.data = param;\n /jsbenchmark/accuracy/field_sensitive/class/constructor_field_004_T\n AffectedNodeName: obj\n 19: Var Pass: let obj = new A(__taint_src);\n /jsbenchmark/accuracy/field_sensitive/class/constructor_field_004_T\n AffectedNodeName: __taint_sink\n 20: SINK: __taint_sink(obj.data);\n==========================================================\n #Total-findings:1\n==========================================================","/jsbenchmark/accuracy/field_sensitive/class/field_len_001_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/jsbenchmark/accuracy/field_sensitive/class/field_len_001_T\nLine 32: __taint_sink(a.b.c.data)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/jsbenchmark/accuracy/field_sensitive/class/field_len_001_T\",\"functionName\":\"field_len_001_T\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /jsbenchmark/accuracy/field_sensitive/class/field_len_001_T\n AffectedNodeName: __taint_src\n 11: SOURCE: function field_len_001_T(__taint_src) {\n /jsbenchmark/accuracy/field_sensitive/class/field_len_001_T\n AffectedNodeName: [this.data]\n 26: Var Pass: this.data = __taint_src;\n /jsbenchmark/accuracy/field_sensitive/class/field_len_001_T\n AffectedNodeName: [this.c]\n 20: Var Pass: this.c = new C();\n /jsbenchmark/accuracy/field_sensitive/class/field_len_001_T\n AffectedNodeName: [this.b]\n 14: Var Pass: this.b = new B();\n /jsbenchmark/accuracy/field_sensitive/class/field_len_001_T\n AffectedNodeName: a\n 31: Var Pass: const a = new A();\n /jsbenchmark/accuracy/field_sensitive/class/field_len_001_T\n AffectedNodeName: __taint_sink\n 32: SINK: __taint_sink(a.b.c.data);\n==========================================================\n #Total-findings:1\n==========================================================","/jsbenchmark/accuracy/field_sensitive/class/field_len_002_F":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/accuracy/field_sensitive/class/field_len_003_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/jsbenchmark/accuracy/field_sensitive/class/field_len_003_T\nLine 52: __taint_sink(s1)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/jsbenchmark/accuracy/field_sensitive/class/field_len_003_T\",\"functionName\":\"field_len_003_T\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /jsbenchmark/accuracy/field_sensitive/class/field_len_003_T\n AffectedNodeName: __taint_src\n 11: SOURCE: function field_len_003_T(__taint_src) {\n /jsbenchmark/accuracy/field_sensitive/class/field_len_003_T\n AffectedNodeName: [this.data]\n 44: Var Pass: this.data = __taint_src;\n /jsbenchmark/accuracy/field_sensitive/class/field_len_003_T\n AffectedNodeName: [this.f]\n 38: Var Pass: this.f = new F();\n /jsbenchmark/accuracy/field_sensitive/class/field_len_003_T\n AffectedNodeName: [this.e]\n 32: Var Pass: this.e = new E();\n /jsbenchmark/accuracy/field_sensitive/class/field_len_003_T\n AffectedNodeName: [this.d]\n 26: Var Pass: this.d = new D();\n /jsbenchmark/accuracy/field_sensitive/class/field_len_003_T\n AffectedNodeName: [this.c]\n 20: Var Pass: this.c = new C();\n /jsbenchmark/accuracy/field_sensitive/class/field_len_003_T\n AffectedNodeName: [this.b]\n 14: Var Pass: this.b = new B();\n /jsbenchmark/accuracy/field_sensitive/class/field_len_003_T\n AffectedNodeName: a\n 49: Var Pass: const a = new A();\n /jsbenchmark/accuracy/field_sensitive/class/field_len_003_T\n AffectedNodeName: s\n 50: Var Pass: const s = a.b.c;\n /jsbenchmark/accuracy/field_sensitive/class/field_len_003_T\n AffectedNodeName: s1\n 51: Var Pass: const s1 = s.d.e.f.data;\n /jsbenchmark/accuracy/field_sensitive/class/field_len_003_T\n AffectedNodeName: __taint_sink\n 52: SINK: __taint_sink(s1);\n==========================================================\n #Total-findings:1\n==========================================================","/jsbenchmark/accuracy/field_sensitive/class/field_len_004_F":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/accuracy/field_sensitive/class/field_len_005_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/jsbenchmark/accuracy/field_sensitive/class/field_len_005_T\nLine 86: __taint_sink(a.b.c.d.e.f.g.h.i.j.k.l.data)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/jsbenchmark/accuracy/field_sensitive/class/field_len_005_T\",\"functionName\":\"field_len_005_T\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /jsbenchmark/accuracy/field_sensitive/class/field_len_005_T\n AffectedNodeName: __taint_src\n 11: SOURCE: function field_len_005_T(__taint_src) {\n /jsbenchmark/accuracy/field_sensitive/class/field_len_005_T\n AffectedNodeName: [this.data]\n 80: Var Pass: this.data = __taint_src;\n /jsbenchmark/accuracy/field_sensitive/class/field_len_005_T\n AffectedNodeName: [this.l]\n 74: Var Pass: this.l = new L();\n /jsbenchmark/accuracy/field_sensitive/class/field_len_005_T\n AffectedNodeName: [this.k]\n 68: Var Pass: this.k = new K();\n /jsbenchmark/accuracy/field_sensitive/class/field_len_005_T\n AffectedNodeName: [this.j]\n 62: Var Pass: this.j = new J();\n /jsbenchmark/accuracy/field_sensitive/class/field_len_005_T\n AffectedNodeName: [this.i]\n 56: Var Pass: this.i = new I();\n /jsbenchmark/accuracy/field_sensitive/class/field_len_005_T\n AffectedNodeName: [this.h]\n 50: Var Pass: this.h = new H();\n /jsbenchmark/accuracy/field_sensitive/class/field_len_005_T\n AffectedNodeName: [this.g]\n 44: Var Pass: this.g = new G();\n /jsbenchmark/accuracy/field_sensitive/class/field_len_005_T\n AffectedNodeName: [this.f]\n 38: Var Pass: this.f = new F();\n /jsbenchmark/accuracy/field_sensitive/class/field_len_005_T\n AffectedNodeName: [this.e]\n 32: Var Pass: this.e = new E();\n /jsbenchmark/accuracy/field_sensitive/class/field_len_005_T\n AffectedNodeName: [this.d]\n 26: Var Pass: this.d = new D();\n /jsbenchmark/accuracy/field_sensitive/class/field_len_005_T\n AffectedNodeName: [this.c]\n 20: Var Pass: this.c = new C();\n /jsbenchmark/accuracy/field_sensitive/class/field_len_005_T\n AffectedNodeName: [this.b]\n 14: Var Pass: this.b = new B();\n /jsbenchmark/accuracy/field_sensitive/class/field_len_005_T\n AffectedNodeName: a\n 85: Var Pass: const a = new A();\n /jsbenchmark/accuracy/field_sensitive/class/field_len_005_T\n AffectedNodeName: __taint_sink\n 86: SINK: __taint_sink(a.b.c.d.e.f.g.h.i.j.k.l.data);\n==========================================================\n #Total-findings:1\n==========================================================","/jsbenchmark/accuracy/field_sensitive/class/field_len_006_F":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/accuracy/field_sensitive/multidimensional_collection/array_multidimensional_collection_001_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/jsbenchmark/accuracy/field_sensitive/multidimensional_collection/array_multidimensional_collection_001_T\nLine 13: __taint_sink(s.0.0)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/jsbenchmark/accuracy/field_sensitive/multidimensional_collection/array_multidimensional_collection_001_T\",\"functionName\":\"array_multidimensional_collection_001_T\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /jsbenchmark/accuracy/field_sensitive/multidimensional_collection/array_multidimensional_collection_001_T\n AffectedNodeName: __taint_src\n 11: SOURCE: function array_multidimensional_collection_001_T(__taint_src) {\n /jsbenchmark/accuracy/field_sensitive/multidimensional_collection/array_multidimensional_collection_001_T\n AffectedNodeName: s\n 12: Var Pass: let s = [[__taint_src], [\"b\"], \"c\"];\n /jsbenchmark/accuracy/field_sensitive/multidimensional_collection/array_multidimensional_collection_001_T\n AffectedNodeName: __taint_sink\n 13: SINK: __taint_sink(s[0][0]);\n==========================================================\n #Total-findings:1\n==========================================================","/jsbenchmark/accuracy/field_sensitive/multidimensional_collection/array_multidimensional_collection_002_F":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/accuracy/field_sensitive/one_dimensional_collection/numeric_index_state_no_solver/array_no_solver_001_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/jsbenchmark/accuracy/field_sensitive/one_dimensional_collection/numeric_index_state_no_solver/array_no_solver_001_T\nLine 13: __taint_sink(s.0)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/jsbenchmark/accuracy/field_sensitive/one_dimensional_collection/numeric_index_state_no_solver/array_no_solver_001_T\",\"functionName\":\"array_no_solver_001_T\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /jsbenchmark/accuracy/field_sensitive/one_dimensional_collection/numeric_index_state_no_solver/array_no_solver_001_T\n AffectedNodeName: __taint_src\n 11: SOURCE: function array_no_solver_001_T(__taint_src) {\n /jsbenchmark/accuracy/field_sensitive/one_dimensional_collection/numeric_index_state_no_solver/array_no_solver_001_T\n AffectedNodeName: s\n 12: Var Pass: let s = [__taint_src, \"b\", \"c\"];\n /jsbenchmark/accuracy/field_sensitive/one_dimensional_collection/numeric_index_state_no_solver/array_no_solver_001_T\n AffectedNodeName: __taint_sink\n 13: SINK: __taint_sink(s[0]);\n==========================================================\n #Total-findings:1\n==========================================================","/jsbenchmark/accuracy/field_sensitive/one_dimensional_collection/numeric_index_state_no_solver/array_no_solver_002_F":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/accuracy/field_sensitive/one_dimensional_collection/numeric_index_state_no_solver/array_no_solver_003_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/jsbenchmark/accuracy/field_sensitive/one_dimensional_collection/numeric_index_state_no_solver/array_no_solver_003_T\nLine 14: __taint_sink(s)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/jsbenchmark/accuracy/field_sensitive/one_dimensional_collection/numeric_index_state_no_solver/array_no_solver_003_T\",\"functionName\":\"array_no_solver_003_T\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /jsbenchmark/accuracy/field_sensitive/one_dimensional_collection/numeric_index_state_no_solver/array_no_solver_003_T\n AffectedNodeName: __taint_src\n 11: SOURCE: function array_no_solver_003_T(__taint_src) {\n /jsbenchmark/accuracy/field_sensitive/one_dimensional_collection/numeric_index_state_no_solver/array_no_solver_003_T\n AffectedNodeName: s\n 12: Var Pass: let s = [__taint_src, \"b\", \"c\"];\n /jsbenchmark/accuracy/field_sensitive/one_dimensional_collection/numeric_index_state_no_solver/array_no_solver_003_T\n AffectedNodeName: __taint_sink\n 14: SINK: __taint_sink(s);\n==========================================================\n #Total-findings:1\n==========================================================","/jsbenchmark/accuracy/field_sensitive/one_dimensional_collection/numeric_index_state_no_solver/array_no_solver_004_F":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/accuracy/field_sensitive/one_dimensional_collection/numeric_index_state_no_solver/map_field_sensitive_001_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/jsbenchmark/accuracy/field_sensitive/one_dimensional_collection/numeric_index_state_no_solver/map_field_sensitive_001_T\nLine 15: __taint_sink(map.get(key1))\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/jsbenchmark/accuracy/field_sensitive/one_dimensional_collection/numeric_index_state_no_solver/map_field_sensitive_001_T\",\"functionName\":\"map_field_sensitive_001_T\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /jsbenchmark/accuracy/field_sensitive/one_dimensional_collection/numeric_index_state_no_solver/map_field_sensitive_001_T\n AffectedNodeName: __taint_src\n 11: SOURCE: function map_field_sensitive_001_T(__taint_src) {\n /jsbenchmark/accuracy/field_sensitive/one_dimensional_collection/numeric_index_state_no_solver/map_field_sensitive_001_T\n AffectedNodeName: set\n 13: CALL: map.set(\"key1\", __taint_src);\n /jsbenchmark/accuracy/field_sensitive/one_dimensional_collection/numeric_index_state_no_solver/map_field_sensitive_001_T\n AffectedNodeName: __taint_sink\n 15: SINK: __taint_sink(map.get(\"key1\"));\n==========================================================\n #Total-findings:1\n==========================================================","/jsbenchmark/accuracy/field_sensitive/one_dimensional_collection/numeric_index_state_no_solver/map_field_sensitive_002_F":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/accuracy/field_sensitive/one_dimensional_collection/numeric_index_state_no_solver/map_field_sensitive_003_F":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/accuracy/field_sensitive/one_dimensional_collection/numeric_index_state_no_solver/map_field_sensitive_004_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/jsbenchmark/accuracy/field_sensitive/one_dimensional_collection/numeric_index_state_no_solver/map_field_sensitive_004_T\nLine 17: __taint_sink(map.get(key2))\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/jsbenchmark/accuracy/field_sensitive/one_dimensional_collection/numeric_index_state_no_solver/map_field_sensitive_004_T\",\"functionName\":\"map_field_sensitive_004_T\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /jsbenchmark/accuracy/field_sensitive/one_dimensional_collection/numeric_index_state_no_solver/map_field_sensitive_004_T\n AffectedNodeName: __taint_src\n 11: SOURCE: function map_field_sensitive_004_T(__taint_src) {\n /jsbenchmark/accuracy/field_sensitive/one_dimensional_collection/numeric_index_state_no_solver/map_field_sensitive_004_T\n AffectedNodeName: set\n 15: CALL: map.set(\"key2\", __taint_src);\n /jsbenchmark/accuracy/field_sensitive/one_dimensional_collection/numeric_index_state_no_solver/map_field_sensitive_004_T\n AffectedNodeName: __taint_sink\n 17: SINK: __taint_sink(map.get(\"key2\"));\n==========================================================\n #Total-findings:1\n==========================================================","/jsbenchmark/accuracy/field_sensitive/one_dimensional_collection/numeric_index_state_no_solver/map_field_sensitive_005_F":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/accuracy/field_sensitive/one_dimensional_collection/numeric_index_state_no_solver/map_field_sensitive_006_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/jsbenchmark/accuracy/field_sensitive/one_dimensional_collection/numeric_index_state_no_solver/map_field_sensitive_006_T\nLine 15: __taint_sink(map.values())\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/jsbenchmark/accuracy/field_sensitive/one_dimensional_collection/numeric_index_state_no_solver/map_field_sensitive_006_T\",\"functionName\":\"map_field_sensitive_006_T\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /jsbenchmark/accuracy/field_sensitive/one_dimensional_collection/numeric_index_state_no_solver/map_field_sensitive_006_T\n AffectedNodeName: __taint_src\n 11: SOURCE: function map_field_sensitive_006_T(__taint_src) {\n /jsbenchmark/accuracy/field_sensitive/one_dimensional_collection/numeric_index_state_no_solver/map_field_sensitive_006_T\n AffectedNodeName: set\n 13: CALL: map.set(\"key1\", __taint_src);\n /jsbenchmark/accuracy/field_sensitive/one_dimensional_collection/numeric_index_state_no_solver/map_field_sensitive_006_T\n AffectedNodeName: __taint_sink\n 15: SINK: __taint_sink(map.values());\n==========================================================\n #Total-findings:1\n==========================================================","/jsbenchmark/accuracy/field_sensitive/one_dimensional_collection/numeric_index_state_no_solver/map_field_sensitive_007_F":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/accuracy/field_sensitive/one_dimensional_collection/numeric_index_state_no_solver/map_field_sensitive_008_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/jsbenchmark/accuracy/field_sensitive/one_dimensional_collection/numeric_index_state_no_solver/map_field_sensitive_008_T\nLine 15: __taint_sink(map.keys())\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/jsbenchmark/accuracy/field_sensitive/one_dimensional_collection/numeric_index_state_no_solver/map_field_sensitive_008_T\",\"functionName\":\"map_field_sensitive_008_T\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /jsbenchmark/accuracy/field_sensitive/one_dimensional_collection/numeric_index_state_no_solver/map_field_sensitive_008_T\n AffectedNodeName: __taint_src\n 11: SOURCE: function map_field_sensitive_008_T(__taint_src) {\n /jsbenchmark/accuracy/field_sensitive/one_dimensional_collection/numeric_index_state_no_solver/map_field_sensitive_008_T\n AffectedNodeName: set\n 13: CALL: map.set(__taint_src, \"value1\");\n /jsbenchmark/accuracy/field_sensitive/one_dimensional_collection/numeric_index_state_no_solver/map_field_sensitive_008_T\n AffectedNodeName: __taint_sink\n 15: SINK: __taint_sink(map.keys());\n==========================================================\n #Total-findings:1\n==========================================================","/jsbenchmark/accuracy/field_sensitive/one_dimensional_collection/numeric_index_state_no_solver/map_field_sensitive_009_F":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/accuracy/field_sensitive/one_dimensional_collection/numeric_index_state_no_solver/rest_parameter_no_solver_001_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/jsbenchmark/accuracy/field_sensitive/one_dimensional_collection/numeric_index_state_no_solver/rest_parameter_no_solver_001_T\nLine 16: __taint_sink(args.1)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/jsbenchmark/accuracy/field_sensitive/one_dimensional_collection/numeric_index_state_no_solver/rest_parameter_no_solver_001_T\",\"functionName\":\"rest_parameter_no_solver_001_T\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /jsbenchmark/accuracy/field_sensitive/one_dimensional_collection/numeric_index_state_no_solver/rest_parameter_no_solver_001_T\n AffectedNodeName: __taint_src\n 11: SOURCE: function rest_parameter_no_solver_001_T(__taint_src) {\n /jsbenchmark/accuracy/field_sensitive/one_dimensional_collection/numeric_index_state_no_solver/rest_parameter_no_solver_001_T\n AffectedNodeName: collectArgs\n 12: CALL: collectArgs(\"prefix\", __taint_src, \"suffix\");\n /jsbenchmark/accuracy/field_sensitive/one_dimensional_collection/numeric_index_state_no_solver/rest_parameter_no_solver_001_T\n AffectedNodeName: __tmp1__\n 15: ARG PASS: function collectArgs(...args) {\n /jsbenchmark/accuracy/field_sensitive/one_dimensional_collection/numeric_index_state_no_solver/rest_parameter_no_solver_001_T\n AffectedNodeName: args\n 15: Var Pass: function collectArgs(...args) {\n 16: Var Pass: __taint_sink(args[1]);\n 17: Var Pass: }\n /jsbenchmark/accuracy/field_sensitive/one_dimensional_collection/numeric_index_state_no_solver/rest_parameter_no_solver_001_T\n AffectedNodeName: __taint_sink\n 16: SINK: __taint_sink(args[1]);\n==========================================================\n #Total-findings:1\n==========================================================","/jsbenchmark/accuracy/field_sensitive/one_dimensional_collection/numeric_index_state_no_solver/rest_parameter_no_solver_002_F":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/accuracy/field_sensitive/one_dimensional_collection/numeric_index_state_no_solver/spread_operator_no_solver_001_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/jsbenchmark/accuracy/field_sensitive/one_dimensional_collection/numeric_index_state_no_solver/spread_operator_no_solver_001_T\nLine 15: __taint_sink(rest.0)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/jsbenchmark/accuracy/field_sensitive/one_dimensional_collection/numeric_index_state_no_solver/spread_operator_no_solver_001_T\",\"functionName\":\"spread_operator_no_solver_001_T\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /jsbenchmark/accuracy/field_sensitive/one_dimensional_collection/numeric_index_state_no_solver/spread_operator_no_solver_001_T\n AffectedNodeName: __taint_src\n 11: SOURCE: function spread_operator_no_solver_001_T(__taint_src) {\n /jsbenchmark/accuracy/field_sensitive/one_dimensional_collection/numeric_index_state_no_solver/spread_operator_no_solver_001_T\n AffectedNodeName: foo\n 12: Var Pass: const foo = __taint_src;\n /jsbenchmark/accuracy/field_sensitive/one_dimensional_collection/numeric_index_state_no_solver/spread_operator_no_solver_001_T\n AffectedNodeName: __tmp1__\n 14: Var Pass: const [r1, r2, ...rest] = [123, 456, foo, bar];\n /jsbenchmark/accuracy/field_sensitive/one_dimensional_collection/numeric_index_state_no_solver/spread_operator_no_solver_001_T\n AffectedNodeName: rest\n 14: Var Pass: const [r1, r2, ...rest] = [123, 456, foo, bar];\n /jsbenchmark/accuracy/field_sensitive/one_dimensional_collection/numeric_index_state_no_solver/spread_operator_no_solver_001_T\n AffectedNodeName: __taint_sink\n 15: SINK: __taint_sink(rest[0]);\n==========================================================\n #Total-findings:1\n==========================================================","/jsbenchmark/accuracy/field_sensitive/one_dimensional_collection/numeric_index_state_no_solver/spread_operator_no_solver_002_F":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/accuracy/field_sensitive/one_dimensional_collection/numeric_index_state_no_solver/spread_operator_no_solver_003_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/jsbenchmark/accuracy/field_sensitive/one_dimensional_collection/numeric_index_state_no_solver/spread_operator_no_solver_003_T\nLine 14: __taint_sink(array.3)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/jsbenchmark/accuracy/field_sensitive/one_dimensional_collection/numeric_index_state_no_solver/spread_operator_no_solver_003_T\",\"functionName\":\"spread_operator_no_solver_003_T\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /jsbenchmark/accuracy/field_sensitive/one_dimensional_collection/numeric_index_state_no_solver/spread_operator_no_solver_003_T\n AffectedNodeName: __taint_src\n 11: SOURCE: function spread_operator_no_solver_003_T(__taint_src) {\n /jsbenchmark/accuracy/field_sensitive/one_dimensional_collection/numeric_index_state_no_solver/spread_operator_no_solver_003_T\n AffectedNodeName: array1\n 12: Var Pass: let array1 = [\"a\", \"b\", __taint_src];\n /jsbenchmark/accuracy/field_sensitive/one_dimensional_collection/numeric_index_state_no_solver/spread_operator_no_solver_003_T\n AffectedNodeName: array\n 13: Var Pass: let array = [\"c\", ...array1];\n /jsbenchmark/accuracy/field_sensitive/one_dimensional_collection/numeric_index_state_no_solver/spread_operator_no_solver_003_T\n AffectedNodeName: __taint_sink\n 14: SINK: __taint_sink(array[3]);\n==========================================================\n #Total-findings:1\n==========================================================","/jsbenchmark/accuracy/field_sensitive/one_dimensional_collection/numeric_index_state_no_solver/spread_operator_no_solver_004_F":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/accuracy/field_sensitive/one_dimensional_collection/numeric_index_state_solver/array_solver_001_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/jsbenchmark/accuracy/field_sensitive/one_dimensional_collection/numeric_index_state_solver/array_solver_001_T\nLine 13: __taint_sink(s.1+1)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/jsbenchmark/accuracy/field_sensitive/one_dimensional_collection/numeric_index_state_solver/array_solver_001_T\",\"functionName\":\"array_solver_001_T\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /jsbenchmark/accuracy/field_sensitive/one_dimensional_collection/numeric_index_state_solver/array_solver_001_T\n AffectedNodeName: __taint_src\n 11: SOURCE: function array_solver_001_T(__taint_src) {\n /jsbenchmark/accuracy/field_sensitive/one_dimensional_collection/numeric_index_state_solver/array_solver_001_T\n AffectedNodeName: s\n 12: Var Pass: let s = [\"a\", \"b\", __taint_src, \"c\", \"d\"];\n /jsbenchmark/accuracy/field_sensitive/one_dimensional_collection/numeric_index_state_solver/array_solver_001_T\n AffectedNodeName: __taint_sink\n 13: SINK: __taint_sink(s[1 + 1]);\n==========================================================\n #Total-findings:1\n==========================================================","/jsbenchmark/accuracy/field_sensitive/one_dimensional_collection/numeric_index_state_solver/array_solver_002_F":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/jsbenchmark/accuracy/field_sensitive/one_dimensional_collection/numeric_index_state_solver/array_solver_002_F\nLine 13: __taint_sink(s.1+2)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/jsbenchmark/accuracy/field_sensitive/one_dimensional_collection/numeric_index_state_solver/array_solver_002_F\",\"functionName\":\"array_solver_002_F\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /jsbenchmark/accuracy/field_sensitive/one_dimensional_collection/numeric_index_state_solver/array_solver_002_F\n AffectedNodeName: __taint_src\n 11: SOURCE: function array_solver_002_F(__taint_src) {\n /jsbenchmark/accuracy/field_sensitive/one_dimensional_collection/numeric_index_state_solver/array_solver_002_F\n AffectedNodeName: s\n 12: Var Pass: let s = [\"a\", \"b\", __taint_src, \"c\", \"d\"];\n /jsbenchmark/accuracy/field_sensitive/one_dimensional_collection/numeric_index_state_solver/array_solver_002_F\n AffectedNodeName: __taint_sink\n 13: SINK: __taint_sink(s[1 + 2]);\n==========================================================\n #Total-findings:1\n==========================================================","/jsbenchmark/accuracy/flow_sensitive/asynchronous/asynchronous_await_001_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/jsbenchmark/accuracy/flow_sensitive/asynchronous/asynchronous_await_001_T\nLine 14: __taint_sink(data)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/jsbenchmark/accuracy/flow_sensitive/asynchronous/asynchronous_await_001_T\",\"functionName\":\"asynchronous_await_001_T\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /jsbenchmark/accuracy/flow_sensitive/asynchronous/asynchronous_await_001_T\n AffectedNodeName: __taint_src\n 11: SOURCE: async function asynchronous_await_001_T(__taint_src) {\n /jsbenchmark/accuracy/flow_sensitive/asynchronous/asynchronous_await_001_T\n AffectedNodeName: resolve\n 19: CALL: resolve(__taint_src);\n /jsbenchmark/accuracy/flow_sensitive/asynchronous/asynchronous_await_001_T\n AffectedNodeName: __taint_sink\n 14: SINK: __taint_sink(data);\n==========================================================\n #Total-findings:1\n==========================================================","/jsbenchmark/accuracy/flow_sensitive/asynchronous/asynchronous_await_002_F":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/accuracy/flow_sensitive/loop_stmt/dowhile_body_loop_stmt_001_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/jsbenchmark/accuracy/flow_sensitive/loop_stmt/dowhile_body_loop_stmt_001_T\nLine 15: __taint_sink(res)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/jsbenchmark/accuracy/flow_sensitive/loop_stmt/dowhile_body_loop_stmt_001_T\",\"functionName\":\"dowhile_body_loop_stmt_001_T\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /jsbenchmark/accuracy/flow_sensitive/loop_stmt/dowhile_body_loop_stmt_001_T\n AffectedNodeName: __taint_src\n 11: SOURCE: function dowhile_body_loop_stmt_001_T(__taint_src) {\n /jsbenchmark/accuracy/flow_sensitive/loop_stmt/dowhile_body_loop_stmt_001_T\n AffectedNodeName: res\n 14: Var Pass: res = __taint_src;\n /jsbenchmark/accuracy/flow_sensitive/loop_stmt/dowhile_body_loop_stmt_001_T\n AffectedNodeName: __taint_sink\n 15: SINK: __taint_sink(res);\n==========================================================\n #Total-findings:1\n==========================================================","/jsbenchmark/accuracy/flow_sensitive/loop_stmt/dowhile_body_loop_stmt_002_F":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/jsbenchmark/accuracy/flow_sensitive/loop_stmt/dowhile_body_loop_stmt_002_F\nLine 14: __taint_sink(res)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/jsbenchmark/accuracy/flow_sensitive/loop_stmt/dowhile_body_loop_stmt_002_F\",\"functionName\":\"dowhile_body_loop_stmt_002_F\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /jsbenchmark/accuracy/flow_sensitive/loop_stmt/dowhile_body_loop_stmt_002_F\n AffectedNodeName: __taint_src\n 11: SOURCE: function dowhile_body_loop_stmt_002_F(__taint_src) {\n /jsbenchmark/accuracy/flow_sensitive/loop_stmt/dowhile_body_loop_stmt_002_F\n AffectedNodeName: res\n 15: Var Pass: res = __taint_src;\n /jsbenchmark/accuracy/flow_sensitive/loop_stmt/dowhile_body_loop_stmt_002_F\n AffectedNodeName: __taint_sink\n 14: SINK: __taint_sink(res);\n==========================================================\n #Total-findings:1\n==========================================================","/jsbenchmark/accuracy/flow_sensitive/loop_stmt/for_001_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/jsbenchmark/accuracy/flow_sensitive/loop_stmt/for_001_T\nLine 16: __taint_sink(res)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/jsbenchmark/accuracy/flow_sensitive/loop_stmt/for_001_T\",\"functionName\":\"for_001_T\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /jsbenchmark/accuracy/flow_sensitive/loop_stmt/for_001_T\n AffectedNodeName: __taint_src\n 11: SOURCE: function for_001_T(__taint_src) {\n /jsbenchmark/accuracy/flow_sensitive/loop_stmt/for_001_T\n AffectedNodeName: res\n 15: Var Pass: res = __taint_src;\n /jsbenchmark/accuracy/flow_sensitive/loop_stmt/for_001_T\n AffectedNodeName: __taint_sink\n 16: SINK: __taint_sink(res);\n==========================================================\n #Total-findings:1\n==========================================================","/jsbenchmark/accuracy/flow_sensitive/loop_stmt/for_002_F":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/jsbenchmark/accuracy/flow_sensitive/loop_stmt/for_002_F\nLine 15: __taint_sink(res)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/jsbenchmark/accuracy/flow_sensitive/loop_stmt/for_002_F\",\"functionName\":\"for_002_F\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /jsbenchmark/accuracy/flow_sensitive/loop_stmt/for_002_F\n AffectedNodeName: __taint_src\n 11: SOURCE: function for_002_F(__taint_src) {\n /jsbenchmark/accuracy/flow_sensitive/loop_stmt/for_002_F\n AffectedNodeName: res\n 16: Var Pass: res = __taint_src;\n /jsbenchmark/accuracy/flow_sensitive/loop_stmt/for_002_F\n AffectedNodeName: __taint_sink\n 15: SINK: __taint_sink(res);\n==========================================================\n #Total-findings:1\n==========================================================","/jsbenchmark/accuracy/flow_sensitive/loop_stmt/for_003_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/jsbenchmark/accuracy/flow_sensitive/loop_stmt/for_003_T\nLine 15: __taint_sink(res)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/jsbenchmark/accuracy/flow_sensitive/loop_stmt/for_003_T\",\"functionName\":\"for_003_T\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /jsbenchmark/accuracy/flow_sensitive/loop_stmt/for_003_T\n AffectedNodeName: __taint_src\n 11: SOURCE: function for_003_T(__taint_src) {\n /jsbenchmark/accuracy/flow_sensitive/loop_stmt/for_003_T\n AffectedNodeName: res\n 14: Var Pass: for (res = __taint_src; i < 1; i++) {\n /jsbenchmark/accuracy/flow_sensitive/loop_stmt/for_003_T\n AffectedNodeName: __taint_sink\n 15: SINK: __taint_sink(res);\n==========================================================\n #Total-findings:1\n==========================================================","/jsbenchmark/accuracy/flow_sensitive/loop_stmt/for_004_F":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/accuracy/flow_sensitive/normal_stmt/assign_expression_stmt_001_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/jsbenchmark/accuracy/flow_sensitive/normal_stmt/assign_expression_stmt_001_T\nLine 13: __taint_sink(result)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/jsbenchmark/accuracy/flow_sensitive/normal_stmt/assign_expression_stmt_001_T\",\"functionName\":\"assign_expression_stmt_001_T\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /jsbenchmark/accuracy/flow_sensitive/normal_stmt/assign_expression_stmt_001_T\n AffectedNodeName: __taint_src\n 11: SOURCE: function assign_expression_stmt_001_T(__taint_src) {\n /jsbenchmark/accuracy/flow_sensitive/normal_stmt/assign_expression_stmt_001_T\n AffectedNodeName: result\n 12: Var Pass: let result = __taint_src;\n /jsbenchmark/accuracy/flow_sensitive/normal_stmt/assign_expression_stmt_001_T\n AffectedNodeName: __taint_sink\n 13: SINK: __taint_sink(result);\n==========================================================\n #Total-findings:1\n==========================================================","/jsbenchmark/accuracy/flow_sensitive/normal_stmt/assign_expression_stmt_002_F":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/accuracy/object_sensitive/class/constructor_obj_001_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/jsbenchmark/accuracy/object_sensitive/class/constructor_obj_001_T\nLine 20: __taint_sink(obj)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/jsbenchmark/accuracy/object_sensitive/class/constructor_obj_001_T\",\"functionName\":\"constructor_obj_001_T\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /jsbenchmark/accuracy/object_sensitive/class/constructor_obj_001_T\n AffectedNodeName: __taint_src\n 11: SOURCE: function constructor_obj_001_T(__taint_src) {\n /jsbenchmark/accuracy/object_sensitive/class/constructor_obj_001_T\n AffectedNodeName: constructor\n 18: CALL: let obj = new A(__taint_src);\n /jsbenchmark/accuracy/object_sensitive/class/constructor_obj_001_T\n AffectedNodeName: data\n 13: ARG PASS: constructor(data) {\n /jsbenchmark/accuracy/object_sensitive/class/constructor_obj_001_T\n AffectedNodeName: [this.data]\n 14: Var Pass: this.data = data;\n /jsbenchmark/accuracy/object_sensitive/class/constructor_obj_001_T\n AffectedNodeName: obj\n 18: Var Pass: let obj = new A(__taint_src);\n /jsbenchmark/accuracy/object_sensitive/class/constructor_obj_001_T\n AffectedNodeName: __taint_sink\n 20: SINK: __taint_sink(obj);\n==========================================================\n #Total-findings:1\n==========================================================","/jsbenchmark/accuracy/object_sensitive/class/constructor_obj_002_F":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/accuracy/object_sensitive/collection/array_object_sensitive_001_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/jsbenchmark/accuracy/object_sensitive/collection/array_object_sensitive_001_T\nLine 14: __taint_sink(s)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/jsbenchmark/accuracy/object_sensitive/collection/array_object_sensitive_001_T\",\"functionName\":\"array_object_sensitive_001_T\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /jsbenchmark/accuracy/object_sensitive/collection/array_object_sensitive_001_T\n AffectedNodeName: __taint_src\n 11: SOURCE: function array_object_sensitive_001_T(__taint_src) {\n /jsbenchmark/accuracy/object_sensitive/collection/array_object_sensitive_001_T\n AffectedNodeName: s\n 12: Var Pass: let s = [__taint_src, \"b\", \"c\"];\n /jsbenchmark/accuracy/object_sensitive/collection/array_object_sensitive_001_T\n AffectedNodeName: __taint_sink\n 14: SINK: __taint_sink(s);\n==========================================================\n #Total-findings:1\n==========================================================","/jsbenchmark/accuracy/object_sensitive/collection/array_object_sensitive_002_F":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/accuracy/object_sensitive/collection/array_object_sensitive_003_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/jsbenchmark/accuracy/object_sensitive/collection/array_object_sensitive_003_T\nLine 14: __taint_sink(s)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/jsbenchmark/accuracy/object_sensitive/collection/array_object_sensitive_003_T\",\"functionName\":\"array_object_sensitive_003_T\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /jsbenchmark/accuracy/object_sensitive/collection/array_object_sensitive_003_T\n AffectedNodeName: __taint_src\n 11: SOURCE: function array_object_sensitive_003_T(__taint_src) {\n /jsbenchmark/accuracy/object_sensitive/collection/array_object_sensitive_003_T\n AffectedNodeName: s\n 12: Var Pass: let s = [[__taint_src], [\"b\"], \"c\"];\n /jsbenchmark/accuracy/object_sensitive/collection/array_object_sensitive_003_T\n AffectedNodeName: __taint_sink\n 14: SINK: __taint_sink(s);\n==========================================================\n #Total-findings:1\n==========================================================","/jsbenchmark/accuracy/object_sensitive/collection/array_object_sensitive_004_F":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/accuracy/object_sensitive/collection/array_object_sensitive_005_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/jsbenchmark/accuracy/object_sensitive/collection/array_object_sensitive_005_T\nLine 16: __taint_sink(s)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/jsbenchmark/accuracy/object_sensitive/collection/array_object_sensitive_005_T\",\"functionName\":\"array_object_sensitive_005_T\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /jsbenchmark/accuracy/object_sensitive/collection/array_object_sensitive_005_T\n AffectedNodeName: __taint_src\n 11: SOURCE: function array_object_sensitive_005_T(__taint_src) {\n /jsbenchmark/accuracy/object_sensitive/collection/array_object_sensitive_005_T\n AffectedNodeName: push\n 13: CALL: s.push(__taint_src);\n /jsbenchmark/accuracy/object_sensitive/collection/array_object_sensitive_005_T\n AffectedNodeName: __taint_sink\n 16: SINK: __taint_sink(s);\n==========================================================\n #Total-findings:1\n==========================================================","/jsbenchmark/accuracy/object_sensitive/collection/array_object_sensitive_006_F":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/accuracy/object_sensitive/collection/map_object_sensitive_001_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/jsbenchmark/accuracy/object_sensitive/collection/map_object_sensitive_001_T\nLine 16: __taint_sink(map)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/jsbenchmark/accuracy/object_sensitive/collection/map_object_sensitive_001_T\",\"functionName\":\"map_object_sensitive_001_T\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /jsbenchmark/accuracy/object_sensitive/collection/map_object_sensitive_001_T\n AffectedNodeName: __taint_src\n 11: SOURCE: function map_object_sensitive_001_T(__taint_src) {\n /jsbenchmark/accuracy/object_sensitive/collection/map_object_sensitive_001_T\n AffectedNodeName: set\n 13: CALL: map.set(\"key1\", __taint_src);\n /jsbenchmark/accuracy/object_sensitive/collection/map_object_sensitive_001_T\n AffectedNodeName: __taint_sink\n 16: SINK: __taint_sink(map);\n==========================================================\n #Total-findings:1\n==========================================================","/jsbenchmark/accuracy/object_sensitive/collection/map_object_sensitive_002_F":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/accuracy/object_sensitive/collection/map_object_sensitive_003_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/jsbenchmark/accuracy/object_sensitive/collection/map_object_sensitive_003_T\nLine 16: __taint_sink(map)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/jsbenchmark/accuracy/object_sensitive/collection/map_object_sensitive_003_T\",\"functionName\":\"map_object_sensitive_003_T\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /jsbenchmark/accuracy/object_sensitive/collection/map_object_sensitive_003_T\n AffectedNodeName: __taint_src\n 11: SOURCE: function map_object_sensitive_003_T(__taint_src) {\n /jsbenchmark/accuracy/object_sensitive/collection/map_object_sensitive_003_T\n AffectedNodeName: set\n 13: CALL: map.set(__taint_src, \"value\");\n /jsbenchmark/accuracy/object_sensitive/collection/map_object_sensitive_003_T\n AffectedNodeName: __taint_sink\n 16: SINK: __taint_sink(map);\n==========================================================\n #Total-findings:1\n==========================================================","/jsbenchmark/accuracy/object_sensitive/collection/map_object_sensitive_004_F":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/accuracy/object_sensitive/collection/map_object_sensitive_005_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/jsbenchmark/accuracy/object_sensitive/collection/map_object_sensitive_005_T\nLine 16: __taint_sink(map)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/jsbenchmark/accuracy/object_sensitive/collection/map_object_sensitive_005_T\",\"functionName\":\"map_object_sensitive_005_T\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /jsbenchmark/accuracy/object_sensitive/collection/map_object_sensitive_005_T\n AffectedNodeName: __taint_src\n 11: SOURCE: function map_object_sensitive_005_T(__taint_src) {\n /jsbenchmark/accuracy/object_sensitive/collection/map_object_sensitive_005_T\n AffectedNodeName: __taint_sink\n 16: SINK: __taint_sink(map);\n==========================================================\n #Total-findings:1\n==========================================================","/jsbenchmark/accuracy/object_sensitive/collection/map_object_sensitive_006_F":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/accuracy/object_sensitive/collection/set_object_sensitive_001_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/jsbenchmark/accuracy/object_sensitive/collection/set_object_sensitive_001_T\nLine 14: __taint_sink(set)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/jsbenchmark/accuracy/object_sensitive/collection/set_object_sensitive_001_T\",\"functionName\":\"set_object_sensitive_001_T\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /jsbenchmark/accuracy/object_sensitive/collection/set_object_sensitive_001_T\n AffectedNodeName: __taint_src\n 11: SOURCE: function set_object_sensitive_001_T(__taint_src) {\n /jsbenchmark/accuracy/object_sensitive/collection/set_object_sensitive_001_T\n AffectedNodeName: set\n 12: Var Pass: let set = new Set(__taint_src);\n /jsbenchmark/accuracy/object_sensitive/collection/set_object_sensitive_001_T\n AffectedNodeName: __taint_sink\n 14: SINK: __taint_sink(set);\n==========================================================\n #Total-findings:1\n==========================================================","/jsbenchmark/accuracy/object_sensitive/collection/set_object_sensitive_002_F":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/accuracy/object_sensitive/collection/set_object_sensitive_003_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/jsbenchmark/accuracy/object_sensitive/collection/set_object_sensitive_003_T\nLine 15: __taint_sink(set)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/jsbenchmark/accuracy/object_sensitive/collection/set_object_sensitive_003_T\",\"functionName\":\"set_object_sensitive_003_T\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /jsbenchmark/accuracy/object_sensitive/collection/set_object_sensitive_003_T\n AffectedNodeName: __taint_src\n 11: SOURCE: function set_object_sensitive_003_T(__taint_src) {\n /jsbenchmark/accuracy/object_sensitive/collection/set_object_sensitive_003_T\n AffectedNodeName: add\n 13: CALL: set.add(__taint_src);\n /jsbenchmark/accuracy/object_sensitive/collection/set_object_sensitive_003_T\n AffectedNodeName: __taint_sink\n 15: SINK: __taint_sink(set);\n==========================================================\n #Total-findings:1\n==========================================================","/jsbenchmark/accuracy/object_sensitive/collection/set_object_sensitive_004_F":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/accuracy/path_sensitive/exception_throw/exception_throw_001_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/jsbenchmark/accuracy/path_sensitive/exception_throw/exception_throw_001_T\nLine 13: __taint_sink(__taint_src)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/jsbenchmark/accuracy/path_sensitive/exception_throw/exception_throw_001_T\",\"functionName\":\"exception_throw_001_T\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /jsbenchmark/accuracy/path_sensitive/exception_throw/exception_throw_001_T\n AffectedNodeName: __taint_src\n 11: SOURCE: function exception_throw_001_T(__taint_src) {\n /jsbenchmark/accuracy/path_sensitive/exception_throw/exception_throw_001_T\n AffectedNodeName: __taint_sink\n 13: SINK: __taint_sink(__taint_src);\n==========================================================\n #Total-findings:1\n==========================================================","/jsbenchmark/accuracy/path_sensitive/exception_throw/exception_throw_002_F":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/jsbenchmark/accuracy/path_sensitive/exception_throw/exception_throw_002_F\nLine 14: __taint_sink(__taint_src)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/jsbenchmark/accuracy/path_sensitive/exception_throw/exception_throw_002_F\",\"functionName\":\"exception_throw_002_F\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /jsbenchmark/accuracy/path_sensitive/exception_throw/exception_throw_002_F\n AffectedNodeName: __taint_src\n 11: SOURCE: function exception_throw_002_F(__taint_src) {\n /jsbenchmark/accuracy/path_sensitive/exception_throw/exception_throw_002_F\n AffectedNodeName: __taint_sink\n 14: SINK: __taint_sink(__taint_src);\n==========================================================\n #Total-findings:1\n==========================================================","/jsbenchmark/accuracy/path_sensitive/exception_throw/exception_throw_003_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/jsbenchmark/accuracy/path_sensitive/exception_throw/exception_throw_003_T\nLine 15: __taint_sink(e)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/jsbenchmark/accuracy/path_sensitive/exception_throw/exception_throw_003_T\",\"functionName\":\"exception_throw_003_T\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /jsbenchmark/accuracy/path_sensitive/exception_throw/exception_throw_003_T\n AffectedNodeName: __taint_src\n 11: SOURCE: function exception_throw_003_T(__taint_src) {\n /jsbenchmark/accuracy/path_sensitive/exception_throw/exception_throw_003_T\n AffectedNodeName: __taint_src\n 13: Throw Pass: throw __taint_src;\n /jsbenchmark/accuracy/path_sensitive/exception_throw/exception_throw_003_T\n AffectedNodeName: e\n 14: Var Pass: } catch (e) {\n /jsbenchmark/accuracy/path_sensitive/exception_throw/exception_throw_003_T\n AffectedNodeName: __taint_sink\n 15: SINK: __taint_sink(e);\n==========================================================\n #Total-findings:1\n==========================================================","/jsbenchmark/accuracy/path_sensitive/explicit_jump_control/break_001_F":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/jsbenchmark/accuracy/path_sensitive/explicit_jump_control/break_001_F\nLine 18: __taint_sink(res)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/jsbenchmark/accuracy/path_sensitive/explicit_jump_control/break_001_F\",\"functionName\":\"break_001_F\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /jsbenchmark/accuracy/path_sensitive/explicit_jump_control/break_001_F\n AffectedNodeName: __taint_src\n 11: SOURCE: function break_001_F(__taint_src) {\n /jsbenchmark/accuracy/path_sensitive/explicit_jump_control/break_001_F\n AffectedNodeName: res\n 15: Var Pass: res = __taint_src;\n /jsbenchmark/accuracy/path_sensitive/explicit_jump_control/break_001_F\n AffectedNodeName: __taint_sink\n 18: SINK: __taint_sink(res);\n==========================================================\n #Total-findings:1\n==========================================================","/jsbenchmark/accuracy/path_sensitive/explicit_jump_control/break_002_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/jsbenchmark/accuracy/path_sensitive/explicit_jump_control/break_002_T\nLine 17: __taint_sink(res)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/jsbenchmark/accuracy/path_sensitive/explicit_jump_control/break_002_T\",\"functionName\":\"break_002_T\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /jsbenchmark/accuracy/path_sensitive/explicit_jump_control/break_002_T\n AffectedNodeName: __taint_src\n 11: SOURCE: function break_002_T(__taint_src) {\n /jsbenchmark/accuracy/path_sensitive/explicit_jump_control/break_002_T\n AffectedNodeName: res\n 15: Var Pass: res = __taint_src;\n /jsbenchmark/accuracy/path_sensitive/explicit_jump_control/break_002_T\n AffectedNodeName: __taint_sink\n 17: SINK: __taint_sink(res);\n==========================================================\n #Total-findings:1\n==========================================================","/jsbenchmark/accuracy/path_sensitive/explicit_jump_control/break_label_001_F":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/accuracy/path_sensitive/explicit_jump_control/break_label_002_T":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/accuracy/path_sensitive/explicit_jump_control/continue_001_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/jsbenchmark/accuracy/path_sensitive/explicit_jump_control/continue_001_T\nLine 18: __taint_sink(res)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/jsbenchmark/accuracy/path_sensitive/explicit_jump_control/continue_001_T\",\"functionName\":\"continue_001_T\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /jsbenchmark/accuracy/path_sensitive/explicit_jump_control/continue_001_T\n AffectedNodeName: __taint_src\n 11: SOURCE: function continue_001_T(__taint_src) {\n /jsbenchmark/accuracy/path_sensitive/explicit_jump_control/continue_001_T\n AffectedNodeName: res\n 15: Var Pass: res = __taint_src;\n /jsbenchmark/accuracy/path_sensitive/explicit_jump_control/continue_001_T\n AffectedNodeName: __taint_sink\n 18: SINK: __taint_sink(res);\n==========================================================\n #Total-findings:1\n==========================================================","/jsbenchmark/accuracy/path_sensitive/explicit_jump_control/continue_002_F":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/jsbenchmark/accuracy/path_sensitive/explicit_jump_control/continue_002_F\nLine 15: __taint_sink(res)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/jsbenchmark/accuracy/path_sensitive/explicit_jump_control/continue_002_F\",\"functionName\":\"continue_002_F\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /jsbenchmark/accuracy/path_sensitive/explicit_jump_control/continue_002_F\n AffectedNodeName: __taint_src\n 11: SOURCE: function continue_002_F(__taint_src) {\n /jsbenchmark/accuracy/path_sensitive/explicit_jump_control/continue_002_F\n AffectedNodeName: res\n 16: Var Pass: res = __taint_src;\n /jsbenchmark/accuracy/path_sensitive/explicit_jump_control/continue_002_F\n AffectedNodeName: __taint_sink\n 15: SINK: __taint_sink(res);\n==========================================================\n #Total-findings:1\n==========================================================","/jsbenchmark/accuracy/path_sensitive/explicit_jump_control/return_001_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/jsbenchmark/accuracy/path_sensitive/explicit_jump_control/return_001_T\nLine 16: __taint_sink(arg1)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/jsbenchmark/accuracy/path_sensitive/explicit_jump_control/return_001_T\",\"functionName\":\"return_001_T\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /jsbenchmark/accuracy/path_sensitive/explicit_jump_control/return_001_T\n AffectedNodeName: __taint_src\n 11: SOURCE: function return_001_T(__taint_src) {\n /jsbenchmark/accuracy/path_sensitive/explicit_jump_control/return_001_T\n AffectedNodeName: process\n 12: CALL: process(__taint_src, \"some_condition\");\n /jsbenchmark/accuracy/path_sensitive/explicit_jump_control/return_001_T\n AffectedNodeName: arg1\n 14: ARG PASS: function process(arg1, arg2) {\n /jsbenchmark/accuracy/path_sensitive/explicit_jump_control/return_001_T\n AffectedNodeName: __taint_sink\n 16: SINK: __taint_sink(arg1);\n==========================================================\n #Total-findings:1\n==========================================================","/jsbenchmark/accuracy/path_sensitive/explicit_jump_control/return_002_F":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/accuracy/path_sensitive/loop_conditional_stmt/no_solver/conditional_if_no_solver_001_F":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/jsbenchmark/accuracy/path_sensitive/loop_conditional_stmt/no_solver/conditional_if_no_solver_001_F\nLine 16: __taint_sink(res)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/jsbenchmark/accuracy/path_sensitive/loop_conditional_stmt/no_solver/conditional_if_no_solver_001_F\",\"functionName\":\"conditional_if_no_solver_001_F\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /jsbenchmark/accuracy/path_sensitive/loop_conditional_stmt/no_solver/conditional_if_no_solver_001_F\n AffectedNodeName: __taint_src\n 11: SOURCE: function conditional_if_no_solver_001_F(__taint_src) {\n /jsbenchmark/accuracy/path_sensitive/loop_conditional_stmt/no_solver/conditional_if_no_solver_001_F\n AffectedNodeName: res\n 14: Var Pass: res = __taint_src;\n /jsbenchmark/accuracy/path_sensitive/loop_conditional_stmt/no_solver/conditional_if_no_solver_001_F\n AffectedNodeName: __taint_sink\n 16: SINK: __taint_sink(res);\n==========================================================\n #Total-findings:1\n==========================================================","/jsbenchmark/accuracy/path_sensitive/loop_conditional_stmt/no_solver/conditional_if_no_solver_002_F":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/accuracy/path_sensitive/loop_conditional_stmt/no_solver/conditional_if_no_solver_003_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/jsbenchmark/accuracy/path_sensitive/loop_conditional_stmt/no_solver/conditional_if_no_solver_003_T\nLine 18: __taint_sink(res)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/jsbenchmark/accuracy/path_sensitive/loop_conditional_stmt/no_solver/conditional_if_no_solver_003_T\",\"functionName\":\"conditional_if_no_solver_003_T\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /jsbenchmark/accuracy/path_sensitive/loop_conditional_stmt/no_solver/conditional_if_no_solver_003_T\n AffectedNodeName: __taint_src\n 11: SOURCE: function conditional_if_no_solver_003_T(__taint_src) {\n /jsbenchmark/accuracy/path_sensitive/loop_conditional_stmt/no_solver/conditional_if_no_solver_003_T\n AffectedNodeName: res\n 16: Var Pass: res = __taint_src;\n /jsbenchmark/accuracy/path_sensitive/loop_conditional_stmt/no_solver/conditional_if_no_solver_003_T\n AffectedNodeName: __taint_sink\n 18: SINK: __taint_sink(res);\n==========================================================\n #Total-findings:1\n==========================================================","/jsbenchmark/accuracy/path_sensitive/loop_conditional_stmt/no_solver/conditional_if_no_solver_004_F":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/jsbenchmark/accuracy/path_sensitive/loop_conditional_stmt/no_solver/conditional_if_no_solver_004_F\nLine 18: __taint_sink(res)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/jsbenchmark/accuracy/path_sensitive/loop_conditional_stmt/no_solver/conditional_if_no_solver_004_F\",\"functionName\":\"conditional_if_no_solver_004_F\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /jsbenchmark/accuracy/path_sensitive/loop_conditional_stmt/no_solver/conditional_if_no_solver_004_F\n AffectedNodeName: __taint_src\n 11: SOURCE: function conditional_if_no_solver_004_F(__taint_src) {\n /jsbenchmark/accuracy/path_sensitive/loop_conditional_stmt/no_solver/conditional_if_no_solver_004_F\n AffectedNodeName: res\n 16: Var Pass: res = __taint_src;\n /jsbenchmark/accuracy/path_sensitive/loop_conditional_stmt/no_solver/conditional_if_no_solver_004_F\n AffectedNodeName: __taint_sink\n 18: SINK: __taint_sink(res);\n==========================================================\n #Total-findings:1\n==========================================================","/jsbenchmark/accuracy/path_sensitive/loop_conditional_stmt/no_solver/conditional_switch_no_solver_001_F":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/accuracy/path_sensitive/loop_conditional_stmt/no_solver/conditional_switch_no_solver_002_F":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/accuracy/path_sensitive/loop_conditional_stmt/no_solver/conditional_switch_no_solver_003_F":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/accuracy/path_sensitive/loop_conditional_stmt/no_solver/conditional_switch_no_solver_004_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/jsbenchmark/accuracy/path_sensitive/loop_conditional_stmt/no_solver/conditional_switch_no_solver_004_T\nLine 18: __taint_sink(data)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/jsbenchmark/accuracy/path_sensitive/loop_conditional_stmt/no_solver/conditional_switch_no_solver_004_T\",\"functionName\":\"conditional_switch_no_solver_004_T\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /jsbenchmark/accuracy/path_sensitive/loop_conditional_stmt/no_solver/conditional_switch_no_solver_004_T\n AffectedNodeName: __taint_src\n 11: SOURCE: function conditional_switch_no_solver_004_T(__taint_src) {\n /jsbenchmark/accuracy/path_sensitive/loop_conditional_stmt/no_solver/conditional_switch_no_solver_004_T\n AffectedNodeName: data\n 15: Var Pass: data = __taint_src;\n /jsbenchmark/accuracy/path_sensitive/loop_conditional_stmt/no_solver/conditional_switch_no_solver_004_T\n AffectedNodeName: __taint_sink\n 18: SINK: __taint_sink(data);\n==========================================================\n #Total-findings:1\n==========================================================","/jsbenchmark/accuracy/path_sensitive/loop_conditional_stmt/solver/conditional_if_solver_001_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/jsbenchmark/accuracy/path_sensitive/loop_conditional_stmt/solver/conditional_if_solver_001_T\nLine 18: __taint_sink(res)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/jsbenchmark/accuracy/path_sensitive/loop_conditional_stmt/solver/conditional_if_solver_001_T\",\"functionName\":\"conditional_if_solver_001_T\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /jsbenchmark/accuracy/path_sensitive/loop_conditional_stmt/solver/conditional_if_solver_001_T\n AffectedNodeName: __taint_src\n 11: SOURCE: function conditional_if_solver_001_T(__taint_src) {\n /jsbenchmark/accuracy/path_sensitive/loop_conditional_stmt/solver/conditional_if_solver_001_T\n AffectedNodeName: res\n 14: Var Pass: res = __taint_src;\n /jsbenchmark/accuracy/path_sensitive/loop_conditional_stmt/solver/conditional_if_solver_001_T\n AffectedNodeName: __taint_sink\n 18: SINK: __taint_sink(res);\n==========================================================\n #Total-findings:1\n==========================================================","/jsbenchmark/accuracy/path_sensitive/loop_conditional_stmt/solver/conditional_if_solver_002_F":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/jsbenchmark/accuracy/path_sensitive/loop_conditional_stmt/solver/conditional_if_solver_002_F\nLine 18: __taint_sink(res)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/jsbenchmark/accuracy/path_sensitive/loop_conditional_stmt/solver/conditional_if_solver_002_F\",\"functionName\":\"conditional_if_solver_002_F\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /jsbenchmark/accuracy/path_sensitive/loop_conditional_stmt/solver/conditional_if_solver_002_F\n AffectedNodeName: __taint_src\n 11: SOURCE: function conditional_if_solver_002_F(__taint_src) {\n /jsbenchmark/accuracy/path_sensitive/loop_conditional_stmt/solver/conditional_if_solver_002_F\n AffectedNodeName: res\n 14: Var Pass: res = __taint_src;\n /jsbenchmark/accuracy/path_sensitive/loop_conditional_stmt/solver/conditional_if_solver_002_F\n AffectedNodeName: __taint_sink\n 18: SINK: __taint_sink(res);\n==========================================================\n #Total-findings:1\n==========================================================","/jsbenchmark/accuracy/path_sensitive/loop_conditional_stmt/solver/conditional_switch_solver_001_F":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/jsbenchmark/accuracy/path_sensitive/loop_conditional_stmt/solver/conditional_switch_solver_001_F\nLine 18: __taint_sink(data)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/jsbenchmark/accuracy/path_sensitive/loop_conditional_stmt/solver/conditional_switch_solver_001_F\",\"functionName\":\"conditional_switch_solver_001_F\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /jsbenchmark/accuracy/path_sensitive/loop_conditional_stmt/solver/conditional_switch_solver_001_F\n AffectedNodeName: __taint_src\n 11: SOURCE: function conditional_switch_solver_001_F(__taint_src) {\n /jsbenchmark/accuracy/path_sensitive/loop_conditional_stmt/solver/conditional_switch_solver_001_F\n AffectedNodeName: data\n 15: Var Pass: data = __taint_src;\n /jsbenchmark/accuracy/path_sensitive/loop_conditional_stmt/solver/conditional_switch_solver_001_F\n AffectedNodeName: __taint_sink\n 18: SINK: __taint_sink(data);\n==========================================================\n #Total-findings:1\n==========================================================","/jsbenchmark/accuracy/path_sensitive/loop_conditional_stmt/solver/conditional_switch_solver_002_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/jsbenchmark/accuracy/path_sensitive/loop_conditional_stmt/solver/conditional_switch_solver_002_T\nLine 18: __taint_sink(data)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/jsbenchmark/accuracy/path_sensitive/loop_conditional_stmt/solver/conditional_switch_solver_002_T\",\"functionName\":\"conditional_switch_solver_002_T\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /jsbenchmark/accuracy/path_sensitive/loop_conditional_stmt/solver/conditional_switch_solver_002_T\n AffectedNodeName: __taint_src\n 11: SOURCE: function conditional_switch_solver_002_T(__taint_src) {\n /jsbenchmark/accuracy/path_sensitive/loop_conditional_stmt/solver/conditional_switch_solver_002_T\n AffectedNodeName: data\n 15: Var Pass: data = __taint_src;\n /jsbenchmark/accuracy/path_sensitive/loop_conditional_stmt/solver/conditional_switch_solver_002_T\n AffectedNodeName: __taint_sink\n 18: SINK: __taint_sink(data);\n==========================================================\n #Total-findings:1\n==========================================================","/jsbenchmark/accuracy/path_sensitive/loop_conditional_stmt/solver/for_body_solver_001_T":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/accuracy/path_sensitive/loop_conditional_stmt/solver/for_body_solver_002_F":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/jsbenchmark/accuracy/path_sensitive/loop_conditional_stmt/solver/for_body_solver_002_F\nLine 16: __taint_sink(res)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/jsbenchmark/accuracy/path_sensitive/loop_conditional_stmt/solver/for_body_solver_002_F\",\"functionName\":\"for_body_solver_002_F\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /jsbenchmark/accuracy/path_sensitive/loop_conditional_stmt/solver/for_body_solver_002_F\n AffectedNodeName: __taint_src\n 11: SOURCE: function for_body_solver_002_F(__taint_src) {\n /jsbenchmark/accuracy/path_sensitive/loop_conditional_stmt/solver/for_body_solver_002_F\n AffectedNodeName: res\n 14: Var Pass: res = __taint_src;\n /jsbenchmark/accuracy/path_sensitive/loop_conditional_stmt/solver/for_body_solver_002_F\n AffectedNodeName: __taint_sink\n 16: SINK: __taint_sink(res);\n==========================================================\n #Total-findings:1\n==========================================================","/jsbenchmark/accuracy/path_sensitive/loop_conditional_stmt/solver/while_body_solver_001_F":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/jsbenchmark/accuracy/path_sensitive/loop_conditional_stmt/solver/while_body_solver_001_F\nLine 18: __taint_sink(res)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/jsbenchmark/accuracy/path_sensitive/loop_conditional_stmt/solver/while_body_solver_001_F\",\"functionName\":\"while_body_solver_001_F\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /jsbenchmark/accuracy/path_sensitive/loop_conditional_stmt/solver/while_body_solver_001_F\n AffectedNodeName: __taint_src\n 11: SOURCE: function while_body_solver_001_F(__taint_src) {\n /jsbenchmark/accuracy/path_sensitive/loop_conditional_stmt/solver/while_body_solver_001_F\n AffectedNodeName: res\n 15: Var Pass: res = __taint_src;\n /jsbenchmark/accuracy/path_sensitive/loop_conditional_stmt/solver/while_body_solver_001_F\n AffectedNodeName: __taint_sink\n 18: SINK: __taint_sink(res);\n==========================================================\n #Total-findings:1\n==========================================================","/jsbenchmark/accuracy/path_sensitive/loop_conditional_stmt/solver/while_body_solver_002_T":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/completeness/dynamic_tracing/dynamic_call/dynamic_call_reflect_001_F":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/completeness/dynamic_tracing/dynamic_call/dynamic_call_reflect_002_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/jsbenchmark/completeness/dynamic_tracing/dynamic_call/dynamic_call_reflect_002_T\nLine 16: __taint_sink(Reflect.get(obj, name))\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/jsbenchmark/completeness/dynamic_tracing/dynamic_call/dynamic_call_reflect_002_T\",\"functionName\":\"dynamic_call_reflect_002_T\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /jsbenchmark/completeness/dynamic_tracing/dynamic_call/dynamic_call_reflect_002_T\n AffectedNodeName: __taint_src\n 11: SOURCE: function dynamic_call_reflect_002_T(__taint_src) {\n /jsbenchmark/completeness/dynamic_tracing/dynamic_call/dynamic_call_reflect_002_T\n AffectedNodeName: obj\n 12: Var Pass: let obj = {\n 13: Var Pass: name: __taint_src,\n 14: Var Pass: };\n /jsbenchmark/completeness/dynamic_tracing/dynamic_call/dynamic_call_reflect_002_T\n AffectedNodeName: get\n 16: CALL: __taint_sink(Reflect.get(obj, \"name\"));\n /jsbenchmark/completeness/dynamic_tracing/dynamic_call/dynamic_call_reflect_002_T\n AffectedNodeName: __taint_sink\n 16: SINK: __taint_sink(Reflect.get(obj, \"name\"));\n==========================================================\n #Total-findings:1\n==========================================================","/jsbenchmark/completeness/dynamic_tracing/dynamic_call/dynamic_call_reflect_003_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/jsbenchmark/completeness/dynamic_tracing/dynamic_call/dynamic_call_reflect_003_T\nLine 17: __taint_sink(obj.foo)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/jsbenchmark/completeness/dynamic_tracing/dynamic_call/dynamic_call_reflect_003_T\",\"functionName\":\"dynamic_call_reflect_003_T\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /jsbenchmark/completeness/dynamic_tracing/dynamic_call/dynamic_call_reflect_003_T\n AffectedNodeName: __taint_src\n 11: SOURCE: function dynamic_call_reflect_003_T(__taint_src) {\n /jsbenchmark/completeness/dynamic_tracing/dynamic_call/dynamic_call_reflect_003_T\n AffectedNodeName: set\n 16: CALL: Reflect.set(obj, \"foo\", __taint_src);\n /jsbenchmark/completeness/dynamic_tracing/dynamic_call/dynamic_call_reflect_003_T\n AffectedNodeName: obj\n 16: Reflect.set Pass: Reflect.set(obj, \"foo\", __taint_src);\n /jsbenchmark/completeness/dynamic_tracing/dynamic_call/dynamic_call_reflect_003_T\n AffectedNodeName: __taint_sink\n 17: SINK: __taint_sink(obj.foo);\n==========================================================\n #Total-findings:1\n==========================================================","/jsbenchmark/completeness/dynamic_tracing/dynamic_call/dynamic_call_reflect_004_F":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/completeness/dynamic_tracing/dynamic_call/dynamic_call_reflect_005_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/jsbenchmark/completeness/dynamic_tracing/dynamic_call/dynamic_call_reflect_005_T\nLine 18: __taint_sink(obj.data)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/jsbenchmark/completeness/dynamic_tracing/dynamic_call/dynamic_call_reflect_005_T\",\"functionName\":\"dynamic_call_reflect_005_T\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /jsbenchmark/completeness/dynamic_tracing/dynamic_call/dynamic_call_reflect_005_T\n AffectedNodeName: __taint_src\n 11: SOURCE: function dynamic_call_reflect_005_T(__taint_src) {\n /jsbenchmark/completeness/dynamic_tracing/dynamic_call/dynamic_call_reflect_005_T\n AffectedNodeName: obj\n 12: Var Pass: let obj = {\n 13: Var Pass: data: __taint_src,\n 14: Var Pass: data1: \"aaa\",\n 15: Var Pass: };\n /jsbenchmark/completeness/dynamic_tracing/dynamic_call/dynamic_call_reflect_005_T\n AffectedNodeName: deleteProperty\n 17: CALL: Reflect.deleteProperty(obj, \"data1\");\n /jsbenchmark/completeness/dynamic_tracing/dynamic_call/dynamic_call_reflect_005_T\n AffectedNodeName: __taint_sink\n 18: SINK: __taint_sink(obj.data);\n==========================================================\n #Total-findings:1\n==========================================================","/jsbenchmark/completeness/dynamic_tracing/dynamic_call/dynamic_call_reflect_006_F":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/completeness/single_app_tracing/alias/alias_001_F":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/completeness/single_app_tracing/alias/alias_002_F":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/completeness/single_app_tracing/alias/alias_003_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/jsbenchmark/completeness/single_app_tracing/alias/alias_003_T\nLine 15: __taint_sink(a.value)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/jsbenchmark/completeness/single_app_tracing/alias/alias_003_T\",\"functionName\":\"alias_003_T\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /jsbenchmark/completeness/single_app_tracing/alias/alias_003_T\n AffectedNodeName: __taint_src\n 11: SOURCE: function alias_003_T(__taint_src) {\n /jsbenchmark/completeness/single_app_tracing/alias/alias_003_T\n AffectedNodeName: [b.value]\n 14: Var Pass: b.value = __taint_src;\n /jsbenchmark/completeness/single_app_tracing/alias/alias_003_T\n AffectedNodeName: __taint_sink\n 15: SINK: __taint_sink(a.value);\n==========================================================\n #Total-findings:1\n==========================================================","/jsbenchmark/completeness/single_app_tracing/asynchronous_tracing/promise_callback_await/async_await_001_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/jsbenchmark/completeness/single_app_tracing/asynchronous_tracing/promise_callback_await/async_await_001_T\nLine 13: __taint_sink(data)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/jsbenchmark/completeness/single_app_tracing/asynchronous_tracing/promise_callback_await/async_await_001_T\",\"functionName\":\"async_await_001_T\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /jsbenchmark/completeness/single_app_tracing/asynchronous_tracing/promise_callback_await/async_await_001_T\n AffectedNodeName: __taint_src\n 11: SOURCE: async function async_await_001_T(__taint_src) {\n /jsbenchmark/completeness/single_app_tracing/asynchronous_tracing/promise_callback_await/async_await_001_T\n AffectedNodeName: resolve\n 18: CALL: resolve(__taint_src);\n /jsbenchmark/completeness/single_app_tracing/asynchronous_tracing/promise_callback_await/async_await_001_T\n AffectedNodeName: __taint_sink\n 13: SINK: __taint_sink(data);\n==========================================================\n #Total-findings:1\n==========================================================","/jsbenchmark/completeness/single_app_tracing/asynchronous_tracing/promise_callback_await/async_await_002_F":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/completeness/single_app_tracing/asynchronous_tracing/promise_callback_await/asynchronous_promise_001_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/jsbenchmark/completeness/single_app_tracing/asynchronous_tracing/promise_callback_await/asynchronous_promise_001_T\nLine 18: __taint_sink(result)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/jsbenchmark/completeness/single_app_tracing/asynchronous_tracing/promise_callback_await/asynchronous_promise_001_T\",\"functionName\":\"asynchronous_promise_001_T\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /jsbenchmark/completeness/single_app_tracing/asynchronous_tracing/promise_callback_await/asynchronous_promise_001_T\n AffectedNodeName: __taint_src\n 11: SOURCE: function asynchronous_promise_001_T(__taint_src) {\n /jsbenchmark/completeness/single_app_tracing/asynchronous_tracing/promise_callback_await/asynchronous_promise_001_T\n AffectedNodeName: resolve\n 13: CALL: resolve(__taint_src);\n /jsbenchmark/completeness/single_app_tracing/asynchronous_tracing/promise_callback_await/asynchronous_promise_001_T\n AffectedNodeName: \n 16: CALL: promise\n 17: CALL: .then((result) => {\n 18: CALL: __taint_sink(result);\n 19: CALL: })\n /jsbenchmark/completeness/single_app_tracing/asynchronous_tracing/promise_callback_await/asynchronous_promise_001_T\n AffectedNodeName: result\n 17: ARG PASS: .then((result) => {\n /jsbenchmark/completeness/single_app_tracing/asynchronous_tracing/promise_callback_await/asynchronous_promise_001_T\n AffectedNodeName: __taint_sink\n 18: SINK: __taint_sink(result);\n==========================================================\n #Total-findings:1\n==========================================================","/jsbenchmark/completeness/single_app_tracing/asynchronous_tracing/promise_callback_await/asynchronous_promise_002_F":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/completeness/single_app_tracing/asynchronous_tracing/promise_callback_await/asynchronous_promise_003_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/jsbenchmark/completeness/single_app_tracing/asynchronous_tracing/promise_callback_await/asynchronous_promise_003_T\nLine 18: __taint_sink(value)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/jsbenchmark/completeness/single_app_tracing/asynchronous_tracing/promise_callback_await/asynchronous_promise_003_T\",\"functionName\":\"asynchronous_promise_003_T\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /jsbenchmark/completeness/single_app_tracing/asynchronous_tracing/promise_callback_await/asynchronous_promise_003_T\n AffectedNodeName: __taint_src\n 11: SOURCE: function asynchronous_promise_003_T(__taint_src) {\n /jsbenchmark/completeness/single_app_tracing/asynchronous_tracing/promise_callback_await/asynchronous_promise_003_T\n AffectedNodeName: asyncFunc\n 18: CALL: asyncFunc(__taint_src).then((value) => __taint_sink(value));\n /jsbenchmark/completeness/single_app_tracing/asynchronous_tracing/promise_callback_await/asynchronous_promise_003_T\n AffectedNodeName: value\n 12: ARG PASS: function asyncFunc(value) {\n /jsbenchmark/completeness/single_app_tracing/asynchronous_tracing/promise_callback_await/asynchronous_promise_003_T\n AffectedNodeName: resolve\n 14: CALL: setTimeout(() => resolve(value), 10);\n /jsbenchmark/completeness/single_app_tracing/asynchronous_tracing/promise_callback_await/asynchronous_promise_003_T\n AffectedNodeName: \n 18: CALL: asyncFunc(__taint_src).then((value) => __taint_sink(value));\n /jsbenchmark/completeness/single_app_tracing/asynchronous_tracing/promise_callback_await/asynchronous_promise_003_T\n AffectedNodeName: value\n 18: ARG PASS: asyncFunc(__taint_src).then((value) => __taint_sink(value));\n /jsbenchmark/completeness/single_app_tracing/asynchronous_tracing/promise_callback_await/asynchronous_promise_003_T\n AffectedNodeName: __taint_sink\n 18: SINK: asyncFunc(__taint_src).then((value) => __taint_sink(value));\n==========================================================\n #Total-findings:1\n==========================================================","/jsbenchmark/completeness/single_app_tracing/asynchronous_tracing/promise_callback_await/asynchronous_promise_004_F":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/completeness/single_app_tracing/asynchronous_tracing/promise_callback_await/asynchronous_promise_005_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/jsbenchmark/completeness/single_app_tracing/asynchronous_tracing/promise_callback_await/asynchronous_promise_005_T\nLine 18: __taint_sink(result)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/jsbenchmark/completeness/single_app_tracing/asynchronous_tracing/promise_callback_await/asynchronous_promise_005_T\",\"functionName\":\"asynchronous_promise_005_T\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /jsbenchmark/completeness/single_app_tracing/asynchronous_tracing/promise_callback_await/asynchronous_promise_005_T\n AffectedNodeName: __taint_src\n 11: SOURCE: function asynchronous_promise_005_T(__taint_src) {\n /jsbenchmark/completeness/single_app_tracing/asynchronous_tracing/promise_callback_await/asynchronous_promise_005_T\n AffectedNodeName: resolve\n 13: CALL: resolve(__taint_src);\n /jsbenchmark/completeness/single_app_tracing/asynchronous_tracing/promise_callback_await/asynchronous_promise_005_T\n AffectedNodeName: \n 16: CALL: promise\n 17: CALL: .then((result) => {\n 18: CALL: __taint_sink(result);\n 19: CALL: })\n /jsbenchmark/completeness/single_app_tracing/asynchronous_tracing/promise_callback_await/asynchronous_promise_005_T\n AffectedNodeName: result\n 17: ARG PASS: .then((result) => {\n /jsbenchmark/completeness/single_app_tracing/asynchronous_tracing/promise_callback_await/asynchronous_promise_005_T\n AffectedNodeName: __taint_sink\n 18: SINK: __taint_sink(result);\n==========================================================\n #Total-findings:1\n==========================================================","/jsbenchmark/completeness/single_app_tracing/asynchronous_tracing/promise_callback_await/asynchronous_promise_006_F":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/completeness/single_app_tracing/asynchronous_tracing/promise_callback_await/asynchronous_promise_007_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/jsbenchmark/completeness/single_app_tracing/asynchronous_tracing/promise_callback_await/asynchronous_promise_007_T\nLine 24: __taint_sink(final)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/jsbenchmark/completeness/single_app_tracing/asynchronous_tracing/promise_callback_await/asynchronous_promise_007_T\",\"functionName\":\"asynchronous_promise_007_T\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /jsbenchmark/completeness/single_app_tracing/asynchronous_tracing/promise_callback_await/asynchronous_promise_007_T\n AffectedNodeName: __taint_src\n 11: SOURCE: function asynchronous_promise_007_T(__taint_src) {\n /jsbenchmark/completeness/single_app_tracing/asynchronous_tracing/promise_callback_await/asynchronous_promise_007_T\n AffectedNodeName: resolve\n 13: CALL: resolve(__taint_src);\n /jsbenchmark/completeness/single_app_tracing/asynchronous_tracing/promise_callback_await/asynchronous_promise_007_T\n AffectedNodeName: \n 16: CALL: promise\n 17: CALL: .then((result) => {\n 18: CALL: final = result;\n 19: CALL: })\n /jsbenchmark/completeness/single_app_tracing/asynchronous_tracing/promise_callback_await/asynchronous_promise_007_T\n AffectedNodeName: result\n 17: ARG PASS: .then((result) => {\n /jsbenchmark/completeness/single_app_tracing/asynchronous_tracing/promise_callback_await/asynchronous_promise_007_T\n AffectedNodeName: final\n 18: Var Pass: final = result;\n /jsbenchmark/completeness/single_app_tracing/asynchronous_tracing/promise_callback_await/asynchronous_promise_007_T\n AffectedNodeName: __taint_sink\n 24: SINK: __taint_sink(final);\n==========================================================\n #Total-findings:1\n==========================================================","/jsbenchmark/completeness/single_app_tracing/asynchronous_tracing/promise_callback_await/asynchronous_promise_008_F":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/completeness/single_app_tracing/asynchronous_tracing/promise_callback_await/asynchronous_promise_009_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/jsbenchmark/completeness/single_app_tracing/asynchronous_tracing/promise_callback_await/asynchronous_promise_009_T\nLine 20: __taint_sink(result)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/jsbenchmark/completeness/single_app_tracing/asynchronous_tracing/promise_callback_await/asynchronous_promise_009_T\",\"functionName\":\"asynchronous_promise_009_T\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /jsbenchmark/completeness/single_app_tracing/asynchronous_tracing/promise_callback_await/asynchronous_promise_009_T\n AffectedNodeName: __taint_src\n 11: SOURCE: function asynchronous_promise_009_T(__taint_src) {\n /jsbenchmark/completeness/single_app_tracing/asynchronous_tracing/promise_callback_await/asynchronous_promise_009_T\n AffectedNodeName: resolve\n 13: CALL: resolve(__taint_src);\n /jsbenchmark/completeness/single_app_tracing/asynchronous_tracing/promise_callback_await/asynchronous_promise_009_T\n AffectedNodeName: \n 16: CALL: promise\n 17: CALL: .then((result) => result + \"_1\")\n /jsbenchmark/completeness/single_app_tracing/asynchronous_tracing/promise_callback_await/asynchronous_promise_009_T\n AffectedNodeName: result\n 17: ARG PASS: .then((result) => result + \"_1\")\n /jsbenchmark/completeness/single_app_tracing/asynchronous_tracing/promise_callback_await/asynchronous_promise_009_T\n AffectedNodeName: [return value]\n 17: Return Value: .then((result) => result + \"_1\")\n /jsbenchmark/completeness/single_app_tracing/asynchronous_tracing/promise_callback_await/asynchronous_promise_009_T\n AffectedNodeName: \n 16: CALL RETURN: promise\n 17: CALL RETURN: .then((result) => result + \"_1\")\n /jsbenchmark/completeness/single_app_tracing/asynchronous_tracing/promise_callback_await/asynchronous_promise_009_T\n AffectedNodeName: \n 16: CALL: promise\n 17: CALL: .then((result) => result + \"_1\")\n 18: CALL: .then((result) => result + \"_2\")\n /jsbenchmark/completeness/single_app_tracing/asynchronous_tracing/promise_callback_await/asynchronous_promise_009_T\n AffectedNodeName: result\n 18: ARG PASS: .then((result) => result + \"_2\")\n /jsbenchmark/completeness/single_app_tracing/asynchronous_tracing/promise_callback_await/asynchronous_promise_009_T\n AffectedNodeName: [return value]\n 18: Return Value: .then((result) => result + \"_2\")\n /jsbenchmark/completeness/single_app_tracing/asynchronous_tracing/promise_callback_await/asynchronous_promise_009_T\n AffectedNodeName: \n 16: CALL RETURN: promise\n 17: CALL RETURN: .then((result) => result + \"_1\")\n 18: CALL RETURN: .then((result) => result + \"_2\")\n /jsbenchmark/completeness/single_app_tracing/asynchronous_tracing/promise_callback_await/asynchronous_promise_009_T\n AffectedNodeName: \n 16: CALL: promise\n 17: CALL: .then((result) => result + \"_1\")\n 18: CALL: .then((result) => result + \"_2\")\n 19: CALL: .then((result) => {\n 20: CALL: __taint_sink(result);\n 21: CALL: });\n /jsbenchmark/completeness/single_app_tracing/asynchronous_tracing/promise_callback_await/asynchronous_promise_009_T\n AffectedNodeName: result\n 19: ARG PASS: .then((result) => {\n /jsbenchmark/completeness/single_app_tracing/asynchronous_tracing/promise_callback_await/asynchronous_promise_009_T\n AffectedNodeName: __taint_sink\n 20: SINK: __taint_sink(result);\n==========================================================\n #Total-findings:1\n==========================================================","/jsbenchmark/completeness/single_app_tracing/asynchronous_tracing/promise_callback_await/asynchronous_promise_010_F":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/completeness/single_app_tracing/asynchronous_tracing/promise_callback_await/asynchronous_promise_011_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/jsbenchmark/completeness/single_app_tracing/asynchronous_tracing/promise_callback_await/asynchronous_promise_011_T\nLine 19: __taint_sink(error)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/jsbenchmark/completeness/single_app_tracing/asynchronous_tracing/promise_callback_await/asynchronous_promise_011_T\",\"functionName\":\"asynchronous_promise_011_T\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /jsbenchmark/completeness/single_app_tracing/asynchronous_tracing/promise_callback_await/asynchronous_promise_011_T\n AffectedNodeName: __taint_src\n 11: SOURCE: function asynchronous_promise_011_T(__taint_src) {\n /jsbenchmark/completeness/single_app_tracing/asynchronous_tracing/promise_callback_await/asynchronous_promise_011_T\n AffectedNodeName: reject\n 13: CALL: reject(__taint_src);\n /jsbenchmark/completeness/single_app_tracing/asynchronous_tracing/promise_callback_await/asynchronous_promise_011_T\n AffectedNodeName: \n 16: CALL: promise\n 17: CALL: .then((result) => {})\n 18: CALL: .catch((error) => {\n 19: CALL: __taint_sink(error);\n 20: CALL: });\n /jsbenchmark/completeness/single_app_tracing/asynchronous_tracing/promise_callback_await/asynchronous_promise_011_T\n AffectedNodeName: error\n 18: ARG PASS: .catch((error) => {\n /jsbenchmark/completeness/single_app_tracing/asynchronous_tracing/promise_callback_await/asynchronous_promise_011_T\n AffectedNodeName: __taint_sink\n 19: SINK: __taint_sink(error);\n==========================================================\n #Total-findings:1\n==========================================================","/jsbenchmark/completeness/single_app_tracing/asynchronous_tracing/promise_callback_await/asynchronous_promise_012_F":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/completeness/single_app_tracing/asynchronous_tracing/promise_callback_await/asynchronous_promisify_001_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/jsbenchmark/completeness/single_app_tracing/asynchronous_tracing/promise_callback_await/asynchronous_promisify_001_T\nLine 26: __taint_sink(data)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/jsbenchmark/completeness/single_app_tracing/asynchronous_tracing/promise_callback_await/asynchronous_promisify_001_T\",\"functionName\":\"asynchronous_promisify_001_T\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /jsbenchmark/completeness/single_app_tracing/asynchronous_tracing/promise_callback_await/asynchronous_promisify_001_T\n AffectedNodeName: __taint_src\n 22: SOURCE: async function asynchronous_promisify_001_T(__taint_src) {\n /jsbenchmark/completeness/single_app_tracing/asynchronous_tracing/promise_callback_await/asynchronous_promisify_001_T\n AffectedNodeName: data\n 25: Var Pass: let data = await readFileAsync(__taint_src);\n /jsbenchmark/completeness/single_app_tracing/asynchronous_tracing/promise_callback_await/asynchronous_promisify_001_T\n AffectedNodeName: __taint_sink\n 26: SINK: __taint_sink(data);\n==========================================================\n #Total-findings:1\n==========================================================","/jsbenchmark/completeness/single_app_tracing/asynchronous_tracing/promise_callback_await/asynchronous_promisify_002_F":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/completeness/single_app_tracing/class/complex_object/cross_class_001_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/jsbenchmark/completeness/single_app_tracing/class/complex_object/cross_class_001_T\nLine 29: __taint_sink(obj)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/jsbenchmark/completeness/single_app_tracing/class/complex_object/cross_class_001_T\",\"functionName\":\"cross_class_001_T\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /jsbenchmark/completeness/single_app_tracing/class/complex_object/cross_class_001_T\n AffectedNodeName: __taint_src\n 11: SOURCE: function cross_class_001_T(__taint_src) {\n /jsbenchmark/completeness/single_app_tracing/class/complex_object/cross_class_001_T\n AffectedNodeName: [this.data]\n 14: Var Pass: this.data = __taint_src;\n /jsbenchmark/completeness/single_app_tracing/class/complex_object/cross_class_001_T\n AffectedNodeName: getData\n 24: CALL: this.data = new A().getData();\n /jsbenchmark/completeness/single_app_tracing/class/complex_object/cross_class_001_T\n 24: ARG PASS: this.data = new A().getData();\n /jsbenchmark/completeness/single_app_tracing/class/complex_object/cross_class_001_T\n AffectedNodeName: [return value]\n 18: Return Value: return this.data;\n /jsbenchmark/completeness/single_app_tracing/class/complex_object/cross_class_001_T\n AffectedNodeName: getData\n 24: CALL RETURN: this.data = new A().getData();\n /jsbenchmark/completeness/single_app_tracing/class/complex_object/cross_class_001_T\n AffectedNodeName: [this.data]\n 24: Var Pass: this.data = new A().getData();\n /jsbenchmark/completeness/single_app_tracing/class/complex_object/cross_class_001_T\n AffectedNodeName: obj\n 28: Var Pass: let obj = new B();\n /jsbenchmark/completeness/single_app_tracing/class/complex_object/cross_class_001_T\n AffectedNodeName: __taint_sink\n 29: SINK: __taint_sink(obj);\n==========================================================\n #Total-findings:1\n==========================================================","/jsbenchmark/completeness/single_app_tracing/class/complex_object/cross_class_002_F":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/completeness/single_app_tracing/class/complex_object/cross_class_003_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/jsbenchmark/completeness/single_app_tracing/class/complex_object/cross_class_003_T\nLine 36: __taint_sink(a)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/jsbenchmark/completeness/single_app_tracing/class/complex_object/cross_class_003_T\",\"functionName\":\"cross_class_003_T\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /jsbenchmark/completeness/single_app_tracing/class/complex_object/cross_class_003_T\n AffectedNodeName: __taint_src\n 11: SOURCE: function cross_class_003_T(__taint_src) {\n /jsbenchmark/completeness/single_app_tracing/class/complex_object/cross_class_003_T\n AffectedNodeName: setData\n 35: CALL: b.setData(__taint_src);\n /jsbenchmark/completeness/single_app_tracing/class/complex_object/cross_class_003_T\n AffectedNodeName: data\n 28: ARG PASS: setData(data) {\n /jsbenchmark/completeness/single_app_tracing/class/complex_object/cross_class_003_T\n AffectedNodeName: [this.data]\n 29: Var Pass: this.data = data;\n /jsbenchmark/completeness/single_app_tracing/class/complex_object/cross_class_003_T\n AffectedNodeName: __taint_sink\n 36: SINK: __taint_sink(a);\n==========================================================\n #Total-findings:1\n==========================================================","/jsbenchmark/completeness/single_app_tracing/class/complex_object/cross_class_004_F":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/completeness/single_app_tracing/class/simple_object/simple_object_001_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/jsbenchmark/completeness/single_app_tracing/class/simple_object/simple_object_001_T\nLine 19: __taint_sink(obj)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/jsbenchmark/completeness/single_app_tracing/class/simple_object/simple_object_001_T\",\"functionName\":\"simple_object_001_T\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /jsbenchmark/completeness/single_app_tracing/class/simple_object/simple_object_001_T\n AffectedNodeName: __taint_src\n 11: SOURCE: function simple_object_001_T(__taint_src) {\n /jsbenchmark/completeness/single_app_tracing/class/simple_object/simple_object_001_T\n AffectedNodeName: constructor\n 18: CALL: let obj = new A(__taint_src);\n /jsbenchmark/completeness/single_app_tracing/class/simple_object/simple_object_001_T\n AffectedNodeName: data\n 13: ARG PASS: constructor(data) {\n /jsbenchmark/completeness/single_app_tracing/class/simple_object/simple_object_001_T\n AffectedNodeName: [this.data]\n 14: Var Pass: this.data = data;\n /jsbenchmark/completeness/single_app_tracing/class/simple_object/simple_object_001_T\n AffectedNodeName: obj\n 18: Var Pass: let obj = new A(__taint_src);\n /jsbenchmark/completeness/single_app_tracing/class/simple_object/simple_object_001_T\n AffectedNodeName: __taint_sink\n 19: SINK: __taint_sink(obj);\n==========================================================\n #Total-findings:1\n==========================================================","/jsbenchmark/completeness/single_app_tracing/class/simple_object/simple_object_002_F":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/completeness/single_app_tracing/class/simple_object/simple_object_prototype_001_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/jsbenchmark/completeness/single_app_tracing/class/simple_object/simple_object_prototype_001_T\nLine 18: __taint_sink(person.name)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/jsbenchmark/completeness/single_app_tracing/class/simple_object/simple_object_prototype_001_T\",\"functionName\":\"simple_object_prototype_001_T\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /jsbenchmark/completeness/single_app_tracing/class/simple_object/simple_object_prototype_001_T\n AffectedNodeName: __taint_src\n 11: SOURCE: function simple_object_prototype_001_T(__taint_src) {\n /jsbenchmark/completeness/single_app_tracing/class/simple_object/simple_object_prototype_001_T\n AffectedNodeName: [[Person.prototype].name]\n 14: Var Pass: Person.prototype.name = __taint_src;\n /jsbenchmark/completeness/single_app_tracing/class/simple_object/simple_object_prototype_001_T\n AffectedNodeName: person\n 16: Var Pass: let person = new Person();\n /jsbenchmark/completeness/single_app_tracing/class/simple_object/simple_object_prototype_001_T\n AffectedNodeName: __taint_sink\n 18: SINK: __taint_sink(person.name);\n==========================================================\n #Total-findings:1\n==========================================================","/jsbenchmark/completeness/single_app_tracing/class/simple_object/simple_object_prototype_002_F":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/completeness/single_app_tracing/class/simple_object/simple_object_prototype_003_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/jsbenchmark/completeness/single_app_tracing/class/simple_object/simple_object_prototype_003_T\nLine 18: __taint_sink(person.__proto__.name)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/jsbenchmark/completeness/single_app_tracing/class/simple_object/simple_object_prototype_003_T\",\"functionName\":\"simple_object_prototype_003_T\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /jsbenchmark/completeness/single_app_tracing/class/simple_object/simple_object_prototype_003_T\n AffectedNodeName: __taint_src\n 11: SOURCE: function simple_object_prototype_003_T(__taint_src) {\n /jsbenchmark/completeness/single_app_tracing/class/simple_object/simple_object_prototype_003_T\n AffectedNodeName: [[Person.prototype].name]\n 14: Var Pass: Person.prototype.name = __taint_src;\n /jsbenchmark/completeness/single_app_tracing/class/simple_object/simple_object_prototype_003_T\n AffectedNodeName: person\n 16: Var Pass: let person = new Person();\n /jsbenchmark/completeness/single_app_tracing/class/simple_object/simple_object_prototype_003_T\n AffectedNodeName: __taint_sink\n 18: SINK: __taint_sink(person.__proto__.name);\n==========================================================\n #Total-findings:1\n==========================================================","/jsbenchmark/completeness/single_app_tracing/class/simple_object/simple_object_prototype_004_F":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/completeness/single_app_tracing/control_flow/conditional_stmt/conditional_if_001_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/jsbenchmark/completeness/single_app_tracing/control_flow/conditional_stmt/conditional_if_001_T\nLine 13: __taint_sink(__taint_src)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/jsbenchmark/completeness/single_app_tracing/control_flow/conditional_stmt/conditional_if_001_T\",\"functionName\":\"conditional_if_001_T\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /jsbenchmark/completeness/single_app_tracing/control_flow/conditional_stmt/conditional_if_001_T\n AffectedNodeName: __taint_src\n 11: SOURCE: function conditional_if_001_T(__taint_src) {\n /jsbenchmark/completeness/single_app_tracing/control_flow/conditional_stmt/conditional_if_001_T\n AffectedNodeName: __taint_sink\n 13: SINK: __taint_sink(__taint_src);\n==========================================================\n #Total-findings:1\n==========================================================","/jsbenchmark/completeness/single_app_tracing/control_flow/conditional_stmt/conditional_if_002_F":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/completeness/single_app_tracing/control_flow/conditional_stmt/conditional_if_003_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/jsbenchmark/completeness/single_app_tracing/control_flow/conditional_stmt/conditional_if_003_T\nLine 14: __taint_sink(__taint_src)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/jsbenchmark/completeness/single_app_tracing/control_flow/conditional_stmt/conditional_if_003_T\",\"functionName\":\"conditional_if_003_T\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /jsbenchmark/completeness/single_app_tracing/control_flow/conditional_stmt/conditional_if_003_T\n AffectedNodeName: __taint_src\n 11: SOURCE: function conditional_if_003_T(__taint_src) {\n /jsbenchmark/completeness/single_app_tracing/control_flow/conditional_stmt/conditional_if_003_T\n AffectedNodeName: __taint_sink\n 14: SINK: __taint_sink(__taint_src);\n==========================================================\n #Total-findings:1\n==========================================================","/jsbenchmark/completeness/single_app_tracing/control_flow/conditional_stmt/conditional_if_004_F":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/completeness/single_app_tracing/control_flow/conditional_stmt/conditional_if_005_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/jsbenchmark/completeness/single_app_tracing/control_flow/conditional_stmt/conditional_if_005_T\nLine 14: __taint_sink(__taint_src)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/jsbenchmark/completeness/single_app_tracing/control_flow/conditional_stmt/conditional_if_005_T\",\"functionName\":\"conditional_if_005_T\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /jsbenchmark/completeness/single_app_tracing/control_flow/conditional_stmt/conditional_if_005_T\n AffectedNodeName: __taint_src\n 11: SOURCE: function conditional_if_005_T(__taint_src) {\n /jsbenchmark/completeness/single_app_tracing/control_flow/conditional_stmt/conditional_if_005_T\n AffectedNodeName: __taint_sink\n 14: SINK: __taint_sink(__taint_src);\n==========================================================\n #Total-findings:1\n==========================================================","/jsbenchmark/completeness/single_app_tracing/control_flow/conditional_stmt/conditional_if_006_F":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/completeness/single_app_tracing/control_flow/conditional_stmt/conditional_switch_001_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/jsbenchmark/completeness/single_app_tracing/control_flow/conditional_stmt/conditional_switch_001_T\nLine 14: __taint_sink(__taint_src)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/jsbenchmark/completeness/single_app_tracing/control_flow/conditional_stmt/conditional_switch_001_T\",\"functionName\":\"conditional_switch_001_T\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /jsbenchmark/completeness/single_app_tracing/control_flow/conditional_stmt/conditional_switch_001_T\n AffectedNodeName: __taint_src\n 11: SOURCE: function conditional_switch_001_T(__taint_src) {\n /jsbenchmark/completeness/single_app_tracing/control_flow/conditional_stmt/conditional_switch_001_T\n AffectedNodeName: __taint_sink\n 14: SINK: __taint_sink(__taint_src);\n==========================================================\n #Total-findings:1\n==========================================================","/jsbenchmark/completeness/single_app_tracing/control_flow/conditional_stmt/conditional_switch_002_F":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/completeness/single_app_tracing/control_flow/loop_stmt/dowhile_body_001_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/jsbenchmark/completeness/single_app_tracing/control_flow/loop_stmt/dowhile_body_001_T\nLine 15: __taint_sink(res)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/jsbenchmark/completeness/single_app_tracing/control_flow/loop_stmt/dowhile_body_001_T\",\"functionName\":\"dowhile_body_001_T\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /jsbenchmark/completeness/single_app_tracing/control_flow/loop_stmt/dowhile_body_001_T\n AffectedNodeName: __taint_src\n 11: SOURCE: function dowhile_body_001_T(__taint_src) {\n /jsbenchmark/completeness/single_app_tracing/control_flow/loop_stmt/dowhile_body_001_T\n AffectedNodeName: res\n 14: Var Pass: res = res + __taint_src;\n /jsbenchmark/completeness/single_app_tracing/control_flow/loop_stmt/dowhile_body_001_T\n AffectedNodeName: __taint_sink\n 15: SINK: } while (__taint_sink(res));\n==========================================================\n #Total-findings:1\n==========================================================","/jsbenchmark/completeness/single_app_tracing/control_flow/loop_stmt/dowhile_body_002_F":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/completeness/single_app_tracing/control_flow/loop_stmt/every_001_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/jsbenchmark/completeness/single_app_tracing/control_flow/loop_stmt/every_001_T\nLine 14: __taint_sink(item)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/jsbenchmark/completeness/single_app_tracing/control_flow/loop_stmt/every_001_T\",\"functionName\":\"every_001_T\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /jsbenchmark/completeness/single_app_tracing/control_flow/loop_stmt/every_001_T\n AffectedNodeName: __taint_src\n 11: SOURCE: function every_001_T(__taint_src) {\n /jsbenchmark/completeness/single_app_tracing/control_flow/loop_stmt/every_001_T\n AffectedNodeName: arr\n 12: Var Pass: let arr = [\"a\", \"b\", __taint_src];\n /jsbenchmark/completeness/single_app_tracing/control_flow/loop_stmt/every_001_T\n AffectedNodeName: \n 13: CALL: arr.every(function (item) {\n 14: CALL: __taint_sink(item);\n 15: CALL: });\n /jsbenchmark/completeness/single_app_tracing/control_flow/loop_stmt/every_001_T\n AffectedNodeName: item\n 13: ARG PASS: arr.every(function (item) {\n /jsbenchmark/completeness/single_app_tracing/control_flow/loop_stmt/every_001_T\n AffectedNodeName: __taint_sink\n 14: SINK: __taint_sink(item);\n==========================================================\n #Total-findings:1\n==========================================================","/jsbenchmark/completeness/single_app_tracing/control_flow/loop_stmt/every_002_F":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/completeness/single_app_tracing/control_flow/loop_stmt/for_body_001_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/jsbenchmark/completeness/single_app_tracing/control_flow/loop_stmt/for_body_001_T\nLine 17: __taint_sink(res)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/jsbenchmark/completeness/single_app_tracing/control_flow/loop_stmt/for_body_001_T\",\"functionName\":\"for_body_001_T\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /jsbenchmark/completeness/single_app_tracing/control_flow/loop_stmt/for_body_001_T\n AffectedNodeName: __taint_src\n 11: SOURCE: function for_body_001_T(__taint_src) {\n /jsbenchmark/completeness/single_app_tracing/control_flow/loop_stmt/for_body_001_T\n AffectedNodeName: res\n 15: Var Pass: res = __taint_src;\n /jsbenchmark/completeness/single_app_tracing/control_flow/loop_stmt/for_body_001_T\n AffectedNodeName: __taint_sink\n 17: SINK: __taint_sink(res);\n==========================================================\n #Total-findings:1\n==========================================================","/jsbenchmark/completeness/single_app_tracing/control_flow/loop_stmt/for_body_002_F":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/completeness/single_app_tracing/control_flow/loop_stmt/for_init_001_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/jsbenchmark/completeness/single_app_tracing/control_flow/loop_stmt/for_init_001_T\nLine 18: __taint_sink(res)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/jsbenchmark/completeness/single_app_tracing/control_flow/loop_stmt/for_init_001_T\",\"functionName\":\"for_init_001_T\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /jsbenchmark/completeness/single_app_tracing/control_flow/loop_stmt/for_init_001_T\n AffectedNodeName: __taint_src\n 11: SOURCE: function for_init_001_T(__taint_src) {\n /jsbenchmark/completeness/single_app_tracing/control_flow/loop_stmt/for_init_001_T\n AffectedNodeName: ini\n 15: Var Pass: for (ini = __taint_src; j < 10; j++) {\n /jsbenchmark/completeness/single_app_tracing/control_flow/loop_stmt/for_init_001_T\n AffectedNodeName: res\n 16: Var Pass: res = res + ini;\n /jsbenchmark/completeness/single_app_tracing/control_flow/loop_stmt/for_init_001_T\n AffectedNodeName: __taint_sink\n 18: SINK: __taint_sink(res);\n==========================================================\n #Total-findings:1\n==========================================================","/jsbenchmark/completeness/single_app_tracing/control_flow/loop_stmt/for_init_002_F":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/completeness/single_app_tracing/control_flow/loop_stmt/for_update_001_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/jsbenchmark/completeness/single_app_tracing/control_flow/loop_stmt/for_update_001_T\nLine 19: __taint_sink(res)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/jsbenchmark/completeness/single_app_tracing/control_flow/loop_stmt/for_update_001_T\",\"functionName\":\"for_update_001_T\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /jsbenchmark/completeness/single_app_tracing/control_flow/loop_stmt/for_update_001_T\n AffectedNodeName: __taint_src\n 11: SOURCE: function for_update_001_T(__taint_src) {\n /jsbenchmark/completeness/single_app_tracing/control_flow/loop_stmt/for_update_001_T\n AffectedNodeName: j\n 15: Var Pass: for (; ini < 2; j = __taint_src) {\n /jsbenchmark/completeness/single_app_tracing/control_flow/loop_stmt/for_update_001_T\n AffectedNodeName: res\n 16: Var Pass: res = j;\n /jsbenchmark/completeness/single_app_tracing/control_flow/loop_stmt/for_update_001_T\n AffectedNodeName: __taint_sink\n 19: SINK: __taint_sink(res);\n==========================================================\n #Total-findings:1\n==========================================================","/jsbenchmark/completeness/single_app_tracing/control_flow/loop_stmt/for_update_002_F":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/completeness/single_app_tracing/control_flow/loop_stmt/foreach_001_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/jsbenchmark/completeness/single_app_tracing/control_flow/loop_stmt/foreach_001_T\nLine 15: __taint_sink(item)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/jsbenchmark/completeness/single_app_tracing/control_flow/loop_stmt/foreach_001_T\",\"functionName\":\"foreach_001_T\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /jsbenchmark/completeness/single_app_tracing/control_flow/loop_stmt/foreach_001_T\n AffectedNodeName: __taint_src\n 11: SOURCE: function foreach_001_T(__taint_src) {\n /jsbenchmark/completeness/single_app_tracing/control_flow/loop_stmt/foreach_001_T\n AffectedNodeName: arr\n 12: Var Pass: let arr = [\"a\", \"b\", __taint_src];\n /jsbenchmark/completeness/single_app_tracing/control_flow/loop_stmt/foreach_001_T\n AffectedNodeName: \n 14: CALL: arr.forEach(function (item) {\n 15: CALL: __taint_sink(item);\n 16: CALL: });\n /jsbenchmark/completeness/single_app_tracing/control_flow/loop_stmt/foreach_001_T\n AffectedNodeName: item\n 14: ARG PASS: arr.forEach(function (item) {\n /jsbenchmark/completeness/single_app_tracing/control_flow/loop_stmt/foreach_001_T\n AffectedNodeName: __taint_sink\n 15: SINK: __taint_sink(item);\n==========================================================\n #Total-findings:1\n==========================================================","/jsbenchmark/completeness/single_app_tracing/control_flow/loop_stmt/foreach_002_F":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/completeness/single_app_tracing/control_flow/loop_stmt/forin_body_001_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/jsbenchmark/completeness/single_app_tracing/control_flow/loop_stmt/forin_body_001_T\nLine 19: __taint_sink(res)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/jsbenchmark/completeness/single_app_tracing/control_flow/loop_stmt/forin_body_001_T\",\"functionName\":\"forin_body_001_T\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /jsbenchmark/completeness/single_app_tracing/control_flow/loop_stmt/forin_body_001_T\n AffectedNodeName: __taint_src\n 11: SOURCE: function forin_body_001_T(__taint_src) {\n /jsbenchmark/completeness/single_app_tracing/control_flow/loop_stmt/forin_body_001_T\n AffectedNodeName: obj\n 12: Var Pass: let obj = { key1: \"value1\", key2: __taint_src };\n /jsbenchmark/completeness/single_app_tracing/control_flow/loop_stmt/forin_body_001_T\n AffectedNodeName: __taint_sink\n 19: SINK: __taint_sink(res);\n==========================================================\n #Total-findings:1\n==========================================================","/jsbenchmark/completeness/single_app_tracing/control_flow/loop_stmt/forin_body_002_F":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/completeness/single_app_tracing/control_flow/loop_stmt/forof_body_001_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/jsbenchmark/completeness/single_app_tracing/control_flow/loop_stmt/forof_body_001_T\nLine 17: __taint_sink(res)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/jsbenchmark/completeness/single_app_tracing/control_flow/loop_stmt/forof_body_001_T\",\"functionName\":\"forof_body_001_T\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /jsbenchmark/completeness/single_app_tracing/control_flow/loop_stmt/forof_body_001_T\n AffectedNodeName: __taint_src\n 11: SOURCE: function forof_body_001_T(__taint_src) {\n /jsbenchmark/completeness/single_app_tracing/control_flow/loop_stmt/forof_body_001_T\n AffectedNodeName: arr\n 12: Var Pass: let arr = [\"a\", \"b\", __taint_src];\n /jsbenchmark/completeness/single_app_tracing/control_flow/loop_stmt/forof_body_001_T\n AffectedNodeName: value\n 14: Var Pass: for (let value of arr) {\n 15: Var Pass: res = value;\n 16: Var Pass: }\n /jsbenchmark/completeness/single_app_tracing/control_flow/loop_stmt/forof_body_001_T\n AffectedNodeName: res\n 15: Var Pass: res = value;\n /jsbenchmark/completeness/single_app_tracing/control_flow/loop_stmt/forof_body_001_T\n AffectedNodeName: __taint_sink\n 17: SINK: __taint_sink(res);\n==========================================================\n #Total-findings:1\n==========================================================","/jsbenchmark/completeness/single_app_tracing/control_flow/loop_stmt/forof_body_002_F":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/completeness/single_app_tracing/control_flow/loop_stmt/some_001_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/jsbenchmark/completeness/single_app_tracing/control_flow/loop_stmt/some_001_T\nLine 14: __taint_sink(item)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/jsbenchmark/completeness/single_app_tracing/control_flow/loop_stmt/some_001_T\",\"functionName\":\"some_001_T\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /jsbenchmark/completeness/single_app_tracing/control_flow/loop_stmt/some_001_T\n AffectedNodeName: __taint_src\n 11: SOURCE: function some_001_T(__taint_src) {\n /jsbenchmark/completeness/single_app_tracing/control_flow/loop_stmt/some_001_T\n AffectedNodeName: arr\n 12: Var Pass: let arr = [\"a\", \"b\", __taint_src];\n /jsbenchmark/completeness/single_app_tracing/control_flow/loop_stmt/some_001_T\n AffectedNodeName: \n 13: CALL: arr.some(function (item) {\n 14: CALL: __taint_sink(item);\n 15: CALL: });\n /jsbenchmark/completeness/single_app_tracing/control_flow/loop_stmt/some_001_T\n AffectedNodeName: item\n 13: ARG PASS: arr.some(function (item) {\n /jsbenchmark/completeness/single_app_tracing/control_flow/loop_stmt/some_001_T\n AffectedNodeName: __taint_sink\n 14: SINK: __taint_sink(item);\n==========================================================\n #Total-findings:1\n==========================================================","/jsbenchmark/completeness/single_app_tracing/control_flow/loop_stmt/some_002_F":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/completeness/single_app_tracing/control_flow/loop_stmt/while_body_001_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/jsbenchmark/completeness/single_app_tracing/control_flow/loop_stmt/while_body_001_T\nLine 18: __taint_sink(res)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/jsbenchmark/completeness/single_app_tracing/control_flow/loop_stmt/while_body_001_T\",\"functionName\":\"while_body_001_T\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /jsbenchmark/completeness/single_app_tracing/control_flow/loop_stmt/while_body_001_T\n AffectedNodeName: __taint_src\n 11: SOURCE: function while_body_001_T(__taint_src) {\n /jsbenchmark/completeness/single_app_tracing/control_flow/loop_stmt/while_body_001_T\n AffectedNodeName: res\n 15: Var Pass: res = res + __taint_src;\n /jsbenchmark/completeness/single_app_tracing/control_flow/loop_stmt/while_body_001_T\n AffectedNodeName: __taint_sink\n 18: SINK: __taint_sink(res);\n==========================================================\n #Total-findings:1\n==========================================================","/jsbenchmark/completeness/single_app_tracing/control_flow/loop_stmt/while_body_002_F":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/completeness/single_app_tracing/cross_file_package_namespace/cross_module/cross_module_001_T/A/cross_module_001_T_a":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/completeness/single_app_tracing/cross_file_package_namespace/cross_module/cross_module_001_T/B/cross_module_001_T_b":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/completeness/single_app_tracing/cross_file_package_namespace/cross_module/cross_module_002_F/A/cross_module_002_F_a":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/completeness/single_app_tracing/cross_file_package_namespace/cross_module/cross_module_002_F/B/cross_module_002_F_b":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/completeness/single_app_tracing/cross_file_package_namespace/cross_module/cross_module_003_T/A/cross_module_003_T_a":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/completeness/single_app_tracing/cross_file_package_namespace/cross_module/cross_module_003_T/B/cross_module_003_T_b":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/completeness/single_app_tracing/cross_file_package_namespace/cross_module/cross_module_004_F/A/cross_module_004_F_a":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/completeness/single_app_tracing/cross_file_package_namespace/cross_module/cross_module_004_F/B/cross_module_004_F_b":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/completeness/single_app_tracing/cross_file_package_namespace/cross_module/cross_module_005_T/A/cross_module_005_T_a":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/completeness/single_app_tracing/cross_file_package_namespace/cross_module/cross_module_005_T/B/cross_module_005_T_b":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/completeness/single_app_tracing/cross_file_package_namespace/cross_module/cross_module_006_F/A/cross_module_006_F_a":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/completeness/single_app_tracing/cross_file_package_namespace/cross_module/cross_module_006_F/B/cross_module_006_F_b":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/completeness/single_app_tracing/cross_file_package_namespace/cross_module/cross_module_007_T/A/cross_module_007_T_a":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/completeness/single_app_tracing/cross_file_package_namespace/cross_module/cross_module_007_T/B/cross_module_007_T_b":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/completeness/single_app_tracing/cross_file_package_namespace/cross_module/cross_module_008_F/A/cross_module_008_F_a":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/completeness/single_app_tracing/cross_file_package_namespace/cross_module/cross_module_008_F/B/cross_module_008_F_b":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/completeness/single_app_tracing/cross_file_package_namespace/cross_module/cross_module_009_T/A/cross_module_009_T_a":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/completeness/single_app_tracing/cross_file_package_namespace/cross_module/cross_module_009_T/B/cross_module_009_T_b":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/completeness/single_app_tracing/cross_file_package_namespace/cross_module/cross_module_010_F/A/cross_module_010_F_a":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/completeness/single_app_tracing/cross_file_package_namespace/cross_module/cross_module_010_F/B/cross_module_010_F_b":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/completeness/single_app_tracing/cross_file_package_namespace/cross_module/cross_module_011_T/A/cross_module_011_T_a":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/completeness/single_app_tracing/cross_file_package_namespace/cross_module/cross_module_011_T/B/cross_module_011_T_b":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/completeness/single_app_tracing/cross_file_package_namespace/cross_module/cross_module_012_F/A/cross_module_012_F_a":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/completeness/single_app_tracing/cross_file_package_namespace/cross_module/cross_module_012_F/B/cross_module_012_F_b":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/completeness/single_app_tracing/datatype/array/array_001_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/jsbenchmark/completeness/single_app_tracing/datatype/array/array_001_T\nLine 13: __taint_sink(s)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/jsbenchmark/completeness/single_app_tracing/datatype/array/array_001_T\",\"functionName\":\"array_001_T\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /jsbenchmark/completeness/single_app_tracing/datatype/array/array_001_T\n AffectedNodeName: __taint_src\n 11: SOURCE: function array_001_T(__taint_src) {\n /jsbenchmark/completeness/single_app_tracing/datatype/array/array_001_T\n AffectedNodeName: s\n 12: Var Pass: let s = [__taint_src, \"b\", \"c\"];\n /jsbenchmark/completeness/single_app_tracing/datatype/array/array_001_T\n AffectedNodeName: __taint_sink\n 13: SINK: __taint_sink(s);\n==========================================================\n #Total-findings:1\n==========================================================","/jsbenchmark/completeness/single_app_tracing/datatype/array/array_002_F":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/completeness/single_app_tracing/datatype/array/array_003_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/jsbenchmark/completeness/single_app_tracing/datatype/array/array_003_T\nLine 13: __taint_sink(s)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/jsbenchmark/completeness/single_app_tracing/datatype/array/array_003_T\",\"functionName\":\"array_003_T\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /jsbenchmark/completeness/single_app_tracing/datatype/array/array_003_T\n AffectedNodeName: __taint_src\n 11: SOURCE: function array_003_T(__taint_src) {\n /jsbenchmark/completeness/single_app_tracing/datatype/array/array_003_T\n AffectedNodeName: s\n 12: Var Pass: let s = [[__taint_src], [\"b\"], \"c\"];\n /jsbenchmark/completeness/single_app_tracing/datatype/array/array_003_T\n AffectedNodeName: __taint_sink\n 13: SINK: __taint_sink(s);\n==========================================================\n #Total-findings:1\n==========================================================","/jsbenchmark/completeness/single_app_tracing/datatype/array/array_004_F":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/completeness/single_app_tracing/datatype/array/array_005_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/jsbenchmark/completeness/single_app_tracing/datatype/array/array_005_T\nLine 14: __taint_sink(s)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/jsbenchmark/completeness/single_app_tracing/datatype/array/array_005_T\",\"functionName\":\"array_005_T\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /jsbenchmark/completeness/single_app_tracing/datatype/array/array_005_T\n AffectedNodeName: __taint_src\n 11: SOURCE: function array_005_T(__taint_src) {\n /jsbenchmark/completeness/single_app_tracing/datatype/array/array_005_T\n AffectedNodeName: push\n 13: CALL: s.push(__taint_src);\n /jsbenchmark/completeness/single_app_tracing/datatype/array/array_005_T\n AffectedNodeName: __taint_sink\n 14: SINK: __taint_sink(s);\n==========================================================\n #Total-findings:1\n==========================================================","/jsbenchmark/completeness/single_app_tracing/datatype/array/array_006_F":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/completeness/single_app_tracing/datatype/collections/set_001_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/jsbenchmark/completeness/single_app_tracing/datatype/collections/set_001_T\nLine 13: __taint_sink(set)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/jsbenchmark/completeness/single_app_tracing/datatype/collections/set_001_T\",\"functionName\":\"set_001_T\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /jsbenchmark/completeness/single_app_tracing/datatype/collections/set_001_T\n AffectedNodeName: __taint_src\n 11: SOURCE: function set_001_T(__taint_src) {\n /jsbenchmark/completeness/single_app_tracing/datatype/collections/set_001_T\n AffectedNodeName: set\n 12: Var Pass: let set = new Set(__taint_src);\n /jsbenchmark/completeness/single_app_tracing/datatype/collections/set_001_T\n AffectedNodeName: __taint_sink\n 13: SINK: __taint_sink(set);\n==========================================================\n #Total-findings:1\n==========================================================","/jsbenchmark/completeness/single_app_tracing/datatype/collections/set_002_F":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/completeness/single_app_tracing/datatype/map/map_001_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/jsbenchmark/completeness/single_app_tracing/datatype/map/map_001_T\nLine 14: __taint_sink(map)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/jsbenchmark/completeness/single_app_tracing/datatype/map/map_001_T\",\"functionName\":\"map_001_T\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /jsbenchmark/completeness/single_app_tracing/datatype/map/map_001_T\n AffectedNodeName: __taint_src\n 11: SOURCE: function map_001_T(__taint_src) {\n /jsbenchmark/completeness/single_app_tracing/datatype/map/map_001_T\n AffectedNodeName: set\n 13: CALL: map.set(\"key1\", __taint_src);\n /jsbenchmark/completeness/single_app_tracing/datatype/map/map_001_T\n AffectedNodeName: __taint_sink\n 14: SINK: __taint_sink(map);\n==========================================================\n #Total-findings:1\n==========================================================","/jsbenchmark/completeness/single_app_tracing/datatype/map/map_002_F":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/completeness/single_app_tracing/exception_error/exception_throw/exception_catch_001_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/jsbenchmark/completeness/single_app_tracing/exception_error/exception_throw/exception_catch_001_T\nLine 15: __taint_sink(e)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/jsbenchmark/completeness/single_app_tracing/exception_error/exception_throw/exception_catch_001_T\",\"functionName\":\"exception_catch_001_T\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /jsbenchmark/completeness/single_app_tracing/exception_error/exception_throw/exception_catch_001_T\n AffectedNodeName: __taint_src\n 11: SOURCE: function exception_catch_001_T(__taint_src) {\n /jsbenchmark/completeness/single_app_tracing/exception_error/exception_throw/exception_catch_001_T\n AffectedNodeName: __taint_src\n 13: Throw Pass: throw __taint_src;\n /jsbenchmark/completeness/single_app_tracing/exception_error/exception_throw/exception_catch_001_T\n AffectedNodeName: e\n 14: Var Pass: } catch (e) {\n /jsbenchmark/completeness/single_app_tracing/exception_error/exception_throw/exception_catch_001_T\n AffectedNodeName: __taint_sink\n 15: SINK: __taint_sink(e);\n==========================================================\n #Total-findings:1\n==========================================================","/jsbenchmark/completeness/single_app_tracing/exception_error/exception_throw/exception_catch_002_F":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/completeness/single_app_tracing/exception_error/exception_throw/exception_catch_003_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/jsbenchmark/completeness/single_app_tracing/exception_error/exception_throw/exception_catch_003_T\nLine 15: __taint_sink(e.message)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/jsbenchmark/completeness/single_app_tracing/exception_error/exception_throw/exception_catch_003_T\",\"functionName\":\"exception_catch_003_T\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /jsbenchmark/completeness/single_app_tracing/exception_error/exception_throw/exception_catch_003_T\n AffectedNodeName: __taint_src\n 11: SOURCE: function exception_catch_003_T(__taint_src) {\n /jsbenchmark/completeness/single_app_tracing/exception_error/exception_throw/exception_catch_003_T\n 13: Throw Pass: throw { message: __taint_src, code: 123 };\n /jsbenchmark/completeness/single_app_tracing/exception_error/exception_throw/exception_catch_003_T\n AffectedNodeName: e\n 14: Var Pass: } catch (e) {\n /jsbenchmark/completeness/single_app_tracing/exception_error/exception_throw/exception_catch_003_T\n AffectedNodeName: __taint_sink\n 15: SINK: __taint_sink(e.message);\n==========================================================\n #Total-findings:1\n==========================================================","/jsbenchmark/completeness/single_app_tracing/exception_error/exception_throw/exception_catch_004_F":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/completeness/single_app_tracing/exception_error/exception_throw/exception_finally_001_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/jsbenchmark/completeness/single_app_tracing/exception_error/exception_throw/exception_finally_001_T\nLine 18: __taint_sink(res)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/jsbenchmark/completeness/single_app_tracing/exception_error/exception_throw/exception_finally_001_T\",\"functionName\":\"exception_finally_001_T\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /jsbenchmark/completeness/single_app_tracing/exception_error/exception_throw/exception_finally_001_T\n AffectedNodeName: __taint_src\n 11: SOURCE: function exception_finally_001_T(__taint_src) {\n /jsbenchmark/completeness/single_app_tracing/exception_error/exception_throw/exception_finally_001_T\n AffectedNodeName: __taint_src\n 14: Throw Pass: throw __taint_src;\n /jsbenchmark/completeness/single_app_tracing/exception_error/exception_throw/exception_finally_001_T\n AffectedNodeName: e\n 15: Var Pass: } catch (e) {\n /jsbenchmark/completeness/single_app_tracing/exception_error/exception_throw/exception_finally_001_T\n AffectedNodeName: res\n 16: Var Pass: res = e;\n /jsbenchmark/completeness/single_app_tracing/exception_error/exception_throw/exception_finally_001_T\n AffectedNodeName: __taint_sink\n 18: SINK: __taint_sink(res);\n==========================================================\n #Total-findings:1\n==========================================================","/jsbenchmark/completeness/single_app_tracing/exception_error/exception_throw/exception_finally_002_F":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/completeness/single_app_tracing/exception_error/exception_throw/exception_try_001_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/jsbenchmark/completeness/single_app_tracing/exception_error/exception_throw/exception_try_001_T\nLine 13: __taint_sink(__taint_src)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/jsbenchmark/completeness/single_app_tracing/exception_error/exception_throw/exception_try_001_T\",\"functionName\":\"exception_try_001_T\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /jsbenchmark/completeness/single_app_tracing/exception_error/exception_throw/exception_try_001_T\n AffectedNodeName: __taint_src\n 11: SOURCE: function exception_try_001_T(__taint_src) {\n /jsbenchmark/completeness/single_app_tracing/exception_error/exception_throw/exception_try_001_T\n AffectedNodeName: __taint_sink\n 13: SINK: __taint_sink(__taint_src);\n==========================================================\n #Total-findings:1\n==========================================================","/jsbenchmark/completeness/single_app_tracing/exception_error/exception_throw/exception_try_002_F":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/completeness/single_app_tracing/expression/basic_expression_operation/assign_expression_001_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/jsbenchmark/completeness/single_app_tracing/expression/basic_expression_operation/assign_expression_001_T\nLine 14: __taint_sink(result)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/jsbenchmark/completeness/single_app_tracing/expression/basic_expression_operation/assign_expression_001_T\",\"functionName\":\"assign_expression_001_T\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /jsbenchmark/completeness/single_app_tracing/expression/basic_expression_operation/assign_expression_001_T\n AffectedNodeName: __taint_src\n 11: SOURCE: function assign_expression_001_T(__taint_src) {\n /jsbenchmark/completeness/single_app_tracing/expression/basic_expression_operation/assign_expression_001_T\n AffectedNodeName: result\n 13: Var Pass: result = __taint_src;\n /jsbenchmark/completeness/single_app_tracing/expression/basic_expression_operation/assign_expression_001_T\n AffectedNodeName: __taint_sink\n 14: SINK: __taint_sink(result);\n==========================================================\n #Total-findings:1\n==========================================================","/jsbenchmark/completeness/single_app_tracing/expression/basic_expression_operation/assign_expression_002_F":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/completeness/single_app_tracing/expression/basic_expression_operation/binary_expression_add_001_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/jsbenchmark/completeness/single_app_tracing/expression/basic_expression_operation/binary_expression_add_001_T\nLine 13: __taint_sink(result)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/jsbenchmark/completeness/single_app_tracing/expression/basic_expression_operation/binary_expression_add_001_T\",\"functionName\":\"binary_expression_add_001_T\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /jsbenchmark/completeness/single_app_tracing/expression/basic_expression_operation/binary_expression_add_001_T\n AffectedNodeName: __taint_src\n 11: SOURCE: function binary_expression_add_001_T(__taint_src) {\n /jsbenchmark/completeness/single_app_tracing/expression/basic_expression_operation/binary_expression_add_001_T\n AffectedNodeName: result\n 12: Var Pass: let result = __taint_src + \"_\";\n /jsbenchmark/completeness/single_app_tracing/expression/basic_expression_operation/binary_expression_add_001_T\n AffectedNodeName: __taint_sink\n 13: SINK: __taint_sink(result);\n==========================================================\n #Total-findings:1\n==========================================================","/jsbenchmark/completeness/single_app_tracing/expression/basic_expression_operation/binary_expression_add_002_F":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/completeness/single_app_tracing/expression/basic_expression_operation/binary_expression_add_assignment_001_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/jsbenchmark/completeness/single_app_tracing/expression/basic_expression_operation/binary_expression_add_assignment_001_T\nLine 14: __taint_sink(result)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/jsbenchmark/completeness/single_app_tracing/expression/basic_expression_operation/binary_expression_add_assignment_001_T\",\"functionName\":\"binary_expression_add_assignment_001_T\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /jsbenchmark/completeness/single_app_tracing/expression/basic_expression_operation/binary_expression_add_assignment_001_T\n AffectedNodeName: __taint_src\n 11: SOURCE: function binary_expression_add_assignment_001_T(__taint_src) {\n /jsbenchmark/completeness/single_app_tracing/expression/basic_expression_operation/binary_expression_add_assignment_001_T\n AffectedNodeName: __taint_sink\n 14: SINK: __taint_sink(result);\n==========================================================\n #Total-findings:1\n==========================================================","/jsbenchmark/completeness/single_app_tracing/expression/basic_expression_operation/binary_expression_add_assignment_002_F":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/completeness/single_app_tracing/expression/basic_expression_operation/bitwise_expression_and_001_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/jsbenchmark/completeness/single_app_tracing/expression/basic_expression_operation/bitwise_expression_and_001_T\nLine 13: __taint_sink(result)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/jsbenchmark/completeness/single_app_tracing/expression/basic_expression_operation/bitwise_expression_and_001_T\",\"functionName\":\"bitwise_expression_and_001_T\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /jsbenchmark/completeness/single_app_tracing/expression/basic_expression_operation/bitwise_expression_and_001_T\n AffectedNodeName: __taint_src\n 11: SOURCE: function bitwise_expression_and_001_T(__taint_src) {\n /jsbenchmark/completeness/single_app_tracing/expression/basic_expression_operation/bitwise_expression_and_001_T\n AffectedNodeName: result\n 12: Var Pass: let result = __taint_src & 1;\n /jsbenchmark/completeness/single_app_tracing/expression/basic_expression_operation/bitwise_expression_and_001_T\n AffectedNodeName: __taint_sink\n 13: SINK: __taint_sink(result);\n==========================================================\n #Total-findings:1\n==========================================================","/jsbenchmark/completeness/single_app_tracing/expression/basic_expression_operation/bitwise_expression_and_002_F":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/completeness/single_app_tracing/expression/basic_expression_operation/bitwise_expression_lsh_001_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/jsbenchmark/completeness/single_app_tracing/expression/basic_expression_operation/bitwise_expression_lsh_001_T\nLine 13: __taint_sink(result)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/jsbenchmark/completeness/single_app_tracing/expression/basic_expression_operation/bitwise_expression_lsh_001_T\",\"functionName\":\"bitwise_expression_lsh_001_T\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /jsbenchmark/completeness/single_app_tracing/expression/basic_expression_operation/bitwise_expression_lsh_001_T\n AffectedNodeName: __taint_src\n 11: SOURCE: function bitwise_expression_lsh_001_T(__taint_src) {\n /jsbenchmark/completeness/single_app_tracing/expression/basic_expression_operation/bitwise_expression_lsh_001_T\n AffectedNodeName: result\n 12: Var Pass: let result = __taint_src << 1;\n /jsbenchmark/completeness/single_app_tracing/expression/basic_expression_operation/bitwise_expression_lsh_001_T\n AffectedNodeName: __taint_sink\n 13: SINK: __taint_sink(result);\n==========================================================\n #Total-findings:1\n==========================================================","/jsbenchmark/completeness/single_app_tracing/expression/basic_expression_operation/bitwise_expression_lsh_002_F":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/completeness/single_app_tracing/expression/basic_expression_operation/bitwise_expression_not_001_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/jsbenchmark/completeness/single_app_tracing/expression/basic_expression_operation/bitwise_expression_not_001_T\nLine 13: __taint_sink(result)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/jsbenchmark/completeness/single_app_tracing/expression/basic_expression_operation/bitwise_expression_not_001_T\",\"functionName\":\"bitwise_expression_not_001_T\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /jsbenchmark/completeness/single_app_tracing/expression/basic_expression_operation/bitwise_expression_not_001_T\n AffectedNodeName: __taint_src\n 11: SOURCE: function bitwise_expression_not_001_T(__taint_src) {\n /jsbenchmark/completeness/single_app_tracing/expression/basic_expression_operation/bitwise_expression_not_001_T\n AffectedNodeName: __taint_sink\n 13: SINK: __taint_sink(result);\n==========================================================\n #Total-findings:1\n==========================================================","/jsbenchmark/completeness/single_app_tracing/expression/basic_expression_operation/bitwise_expression_not_002_F":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/completeness/single_app_tracing/expression/basic_expression_operation/bitwise_expression_or_001_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/jsbenchmark/completeness/single_app_tracing/expression/basic_expression_operation/bitwise_expression_or_001_T\nLine 13: __taint_sink(result)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/jsbenchmark/completeness/single_app_tracing/expression/basic_expression_operation/bitwise_expression_or_001_T\",\"functionName\":\"bitwise_expression_or_001_T\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /jsbenchmark/completeness/single_app_tracing/expression/basic_expression_operation/bitwise_expression_or_001_T\n AffectedNodeName: __taint_src\n 11: SOURCE: function bitwise_expression_or_001_T(__taint_src) {\n /jsbenchmark/completeness/single_app_tracing/expression/basic_expression_operation/bitwise_expression_or_001_T\n AffectedNodeName: result\n 12: Var Pass: let result = __taint_src | 1;\n /jsbenchmark/completeness/single_app_tracing/expression/basic_expression_operation/bitwise_expression_or_001_T\n AffectedNodeName: __taint_sink\n 13: SINK: __taint_sink(result);\n==========================================================\n #Total-findings:1\n==========================================================","/jsbenchmark/completeness/single_app_tracing/expression/basic_expression_operation/bitwise_expression_or_002_F":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/completeness/single_app_tracing/expression/basic_expression_operation/bitwise_expression_rsh_001_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/jsbenchmark/completeness/single_app_tracing/expression/basic_expression_operation/bitwise_expression_rsh_001_T\nLine 13: __taint_sink(result)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/jsbenchmark/completeness/single_app_tracing/expression/basic_expression_operation/bitwise_expression_rsh_001_T\",\"functionName\":\"bitwise_expression_rsh_001_T\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /jsbenchmark/completeness/single_app_tracing/expression/basic_expression_operation/bitwise_expression_rsh_001_T\n AffectedNodeName: __taint_src\n 11: SOURCE: function bitwise_expression_rsh_001_T(__taint_src) {\n /jsbenchmark/completeness/single_app_tracing/expression/basic_expression_operation/bitwise_expression_rsh_001_T\n AffectedNodeName: result\n 12: Var Pass: let result = __taint_src >> 1;\n /jsbenchmark/completeness/single_app_tracing/expression/basic_expression_operation/bitwise_expression_rsh_001_T\n AffectedNodeName: __taint_sink\n 13: SINK: __taint_sink(result);\n==========================================================\n #Total-findings:1\n==========================================================","/jsbenchmark/completeness/single_app_tracing/expression/basic_expression_operation/bitwise_expression_rsh_002_F":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/completeness/single_app_tracing/expression/basic_expression_operation/bitwise_expression_xor_001_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/jsbenchmark/completeness/single_app_tracing/expression/basic_expression_operation/bitwise_expression_xor_001_T\nLine 13: __taint_sink(result)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/jsbenchmark/completeness/single_app_tracing/expression/basic_expression_operation/bitwise_expression_xor_001_T\",\"functionName\":\"bitwise_expression_xor_001_T\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /jsbenchmark/completeness/single_app_tracing/expression/basic_expression_operation/bitwise_expression_xor_001_T\n AffectedNodeName: __taint_src\n 11: SOURCE: function bitwise_expression_xor_001_T(__taint_src) {\n /jsbenchmark/completeness/single_app_tracing/expression/basic_expression_operation/bitwise_expression_xor_001_T\n AffectedNodeName: result\n 12: Var Pass: let result = __taint_src ^ 1;\n /jsbenchmark/completeness/single_app_tracing/expression/basic_expression_operation/bitwise_expression_xor_001_T\n AffectedNodeName: __taint_sink\n 13: SINK: __taint_sink(result);\n==========================================================\n #Total-findings:1\n==========================================================","/jsbenchmark/completeness/single_app_tracing/expression/basic_expression_operation/bitwise_expression_xor_002_F":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/completeness/single_app_tracing/expression/basic_expression_operation/logic_expression_and_001_F":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/completeness/single_app_tracing/expression/basic_expression_operation/logic_expression_and_002_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/jsbenchmark/completeness/single_app_tracing/expression/basic_expression_operation/logic_expression_and_002_T\nLine 13: __taint_sink(result)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/jsbenchmark/completeness/single_app_tracing/expression/basic_expression_operation/logic_expression_and_002_T\",\"functionName\":\"logic_expression_and_002_T\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /jsbenchmark/completeness/single_app_tracing/expression/basic_expression_operation/logic_expression_and_002_T\n AffectedNodeName: __taint_src\n 11: SOURCE: function logic_expression_and_002_T(__taint_src) {\n /jsbenchmark/completeness/single_app_tracing/expression/basic_expression_operation/logic_expression_and_002_T\n AffectedNodeName: result\n 12: Var Pass: let result = \"_\" && __taint_src;\n /jsbenchmark/completeness/single_app_tracing/expression/basic_expression_operation/logic_expression_and_002_T\n AffectedNodeName: __taint_sink\n 13: SINK: __taint_sink(result);\n==========================================================\n #Total-findings:1\n==========================================================","/jsbenchmark/completeness/single_app_tracing/expression/basic_expression_operation/logic_expression_or_001_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/jsbenchmark/completeness/single_app_tracing/expression/basic_expression_operation/logic_expression_or_001_T\nLine 13: __taint_sink(result)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/jsbenchmark/completeness/single_app_tracing/expression/basic_expression_operation/logic_expression_or_001_T\",\"functionName\":\"logic_expression_or_001_T\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /jsbenchmark/completeness/single_app_tracing/expression/basic_expression_operation/logic_expression_or_001_T\n AffectedNodeName: __taint_src\n 11: SOURCE: function logic_expression_or_001_T(__taint_src) {\n /jsbenchmark/completeness/single_app_tracing/expression/basic_expression_operation/logic_expression_or_001_T\n AffectedNodeName: result\n 12: Var Pass: let result = __taint_src || \"_\";\n /jsbenchmark/completeness/single_app_tracing/expression/basic_expression_operation/logic_expression_or_001_T\n AffectedNodeName: __taint_sink\n 13: SINK: __taint_sink(result);\n==========================================================\n #Total-findings:1\n==========================================================","/jsbenchmark/completeness/single_app_tracing/expression/basic_expression_operation/logic_expression_or_002_F":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/completeness/single_app_tracing/expression/basic_expression_operation/prefix_expression_001_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/jsbenchmark/completeness/single_app_tracing/expression/basic_expression_operation/prefix_expression_001_T\nLine 13: __taint_sink(result)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/jsbenchmark/completeness/single_app_tracing/expression/basic_expression_operation/prefix_expression_001_T\",\"functionName\":\"prefix_expression_001_T\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /jsbenchmark/completeness/single_app_tracing/expression/basic_expression_operation/prefix_expression_001_T\n AffectedNodeName: __taint_src\n 11: SOURCE: function prefix_expression_001_T(__taint_src) {\n /jsbenchmark/completeness/single_app_tracing/expression/basic_expression_operation/prefix_expression_001_T\n AffectedNodeName: __taint_sink\n 13: SINK: __taint_sink(result);\n==========================================================\n #Total-findings:1\n==========================================================","/jsbenchmark/completeness/single_app_tracing/expression/basic_expression_operation/prefix_expression_002_F":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/completeness/single_app_tracing/expression/basic_expression_operation/relation_expression_equal_001_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/jsbenchmark/completeness/single_app_tracing/expression/basic_expression_operation/relation_expression_equal_001_T\nLine 13: __taint_sink(result)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/jsbenchmark/completeness/single_app_tracing/expression/basic_expression_operation/relation_expression_equal_001_T\",\"functionName\":\"relation_expression_equal_001_T\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /jsbenchmark/completeness/single_app_tracing/expression/basic_expression_operation/relation_expression_equal_001_T\n AffectedNodeName: __taint_src\n 11: SOURCE: function relation_expression_equal_001_T(__taint_src) {\n /jsbenchmark/completeness/single_app_tracing/expression/basic_expression_operation/relation_expression_equal_001_T\n AffectedNodeName: result\n 12: Var Pass: let result = __taint_src === \"taint_src_value\";\n /jsbenchmark/completeness/single_app_tracing/expression/basic_expression_operation/relation_expression_equal_001_T\n AffectedNodeName: __taint_sink\n 13: SINK: __taint_sink(result);\n==========================================================\n #Total-findings:1\n==========================================================","/jsbenchmark/completeness/single_app_tracing/expression/basic_expression_operation/relation_expression_equal_002_F":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/jsbenchmark/completeness/single_app_tracing/expression/basic_expression_operation/relation_expression_equal_002_F\nLine 13: __taint_sink(result)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/jsbenchmark/completeness/single_app_tracing/expression/basic_expression_operation/relation_expression_equal_002_F\",\"functionName\":\"relation_expression_equal_002_F\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /jsbenchmark/completeness/single_app_tracing/expression/basic_expression_operation/relation_expression_equal_002_F\n AffectedNodeName: __taint_src\n 11: SOURCE: function relation_expression_equal_002_F(__taint_src) {\n /jsbenchmark/completeness/single_app_tracing/expression/basic_expression_operation/relation_expression_equal_002_F\n AffectedNodeName: result\n 12: Var Pass: let result = __taint_src === \"__taint_src\";\n /jsbenchmark/completeness/single_app_tracing/expression/basic_expression_operation/relation_expression_equal_002_F\n AffectedNodeName: __taint_sink\n 13: SINK: __taint_sink(result);\n==========================================================\n #Total-findings:1\n==========================================================","/jsbenchmark/completeness/single_app_tracing/expression/basic_expression_operation/relation_expression_greater_001_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/jsbenchmark/completeness/single_app_tracing/expression/basic_expression_operation/relation_expression_greater_001_T\nLine 13: __taint_sink(result)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/jsbenchmark/completeness/single_app_tracing/expression/basic_expression_operation/relation_expression_greater_001_T\",\"functionName\":\"relation_expression_greater_001_T\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /jsbenchmark/completeness/single_app_tracing/expression/basic_expression_operation/relation_expression_greater_001_T\n AffectedNodeName: __taint_src\n 11: SOURCE: function relation_expression_greater_001_T(__taint_src) {\n /jsbenchmark/completeness/single_app_tracing/expression/basic_expression_operation/relation_expression_greater_001_T\n AffectedNodeName: result\n 12: Var Pass: let result = __taint_src > \"__taint_src\";\n /jsbenchmark/completeness/single_app_tracing/expression/basic_expression_operation/relation_expression_greater_001_T\n AffectedNodeName: __taint_sink\n 13: SINK: __taint_sink(result);\n==========================================================\n #Total-findings:1\n==========================================================","/jsbenchmark/completeness/single_app_tracing/expression/basic_expression_operation/relation_expression_greater_002_F":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/jsbenchmark/completeness/single_app_tracing/expression/basic_expression_operation/relation_expression_greater_002_F\nLine 13: __taint_sink(result)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/jsbenchmark/completeness/single_app_tracing/expression/basic_expression_operation/relation_expression_greater_002_F\",\"functionName\":\"relation_expression_greater_002_F\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /jsbenchmark/completeness/single_app_tracing/expression/basic_expression_operation/relation_expression_greater_002_F\n AffectedNodeName: __taint_src\n 11: SOURCE: function relation_expression_greater_002_F(__taint_src) {\n /jsbenchmark/completeness/single_app_tracing/expression/basic_expression_operation/relation_expression_greater_002_F\n AffectedNodeName: result\n 12: Var Pass: let result = __taint_src > \"taint_src_value\";\n /jsbenchmark/completeness/single_app_tracing/expression/basic_expression_operation/relation_expression_greater_002_F\n AffectedNodeName: __taint_sink\n 13: SINK: __taint_sink(result);\n==========================================================\n #Total-findings:1\n==========================================================","/jsbenchmark/completeness/single_app_tracing/expression/basic_expression_operation/relation_expression_less_001_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/jsbenchmark/completeness/single_app_tracing/expression/basic_expression_operation/relation_expression_less_001_T\nLine 13: __taint_sink(result)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/jsbenchmark/completeness/single_app_tracing/expression/basic_expression_operation/relation_expression_less_001_T\",\"functionName\":\"relation_expression_less_001_T\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /jsbenchmark/completeness/single_app_tracing/expression/basic_expression_operation/relation_expression_less_001_T\n AffectedNodeName: __taint_src\n 11: SOURCE: function relation_expression_less_001_T(__taint_src) {\n /jsbenchmark/completeness/single_app_tracing/expression/basic_expression_operation/relation_expression_less_001_T\n AffectedNodeName: result\n 12: Var Pass: let result = __taint_src < \"__taint_src\";\n /jsbenchmark/completeness/single_app_tracing/expression/basic_expression_operation/relation_expression_less_001_T\n AffectedNodeName: __taint_sink\n 13: SINK: __taint_sink(result);\n==========================================================\n #Total-findings:1\n==========================================================","/jsbenchmark/completeness/single_app_tracing/expression/basic_expression_operation/relation_expression_less_002_F":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/jsbenchmark/completeness/single_app_tracing/expression/basic_expression_operation/relation_expression_less_002_F\nLine 13: __taint_sink(result)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/jsbenchmark/completeness/single_app_tracing/expression/basic_expression_operation/relation_expression_less_002_F\",\"functionName\":\"relation_expression_less_002_F\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /jsbenchmark/completeness/single_app_tracing/expression/basic_expression_operation/relation_expression_less_002_F\n AffectedNodeName: __taint_src\n 11: SOURCE: function relation_expression_less_002_F(__taint_src) {\n /jsbenchmark/completeness/single_app_tracing/expression/basic_expression_operation/relation_expression_less_002_F\n AffectedNodeName: result\n 12: Var Pass: let result = __taint_src < \"taint_src_valueaa\";\n /jsbenchmark/completeness/single_app_tracing/expression/basic_expression_operation/relation_expression_less_002_F\n AffectedNodeName: __taint_sink\n 13: SINK: __taint_sink(result);\n==========================================================\n #Total-findings:1\n==========================================================","/jsbenchmark/completeness/single_app_tracing/expression/basic_expression_operation/suffix_expression_001_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/jsbenchmark/completeness/single_app_tracing/expression/basic_expression_operation/suffix_expression_001_T\nLine 13: __taint_sink(result)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/jsbenchmark/completeness/single_app_tracing/expression/basic_expression_operation/suffix_expression_001_T\",\"functionName\":\"suffix_expression_001_T\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /jsbenchmark/completeness/single_app_tracing/expression/basic_expression_operation/suffix_expression_001_T\n AffectedNodeName: __taint_src\n 11: SOURCE: function suffix_expression_001_T(__taint_src) {\n /jsbenchmark/completeness/single_app_tracing/expression/basic_expression_operation/suffix_expression_001_T\n AffectedNodeName: __taint_sink\n 13: SINK: __taint_sink(result);\n==========================================================\n #Total-findings:1\n==========================================================","/jsbenchmark/completeness/single_app_tracing/expression/basic_expression_operation/suffix_expression_002_F":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/completeness/single_app_tracing/expression/conditional_expression/conditional_expression_001_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/jsbenchmark/completeness/single_app_tracing/expression/conditional_expression/conditional_expression_001_T\nLine 14: __taint_sink(result)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/jsbenchmark/completeness/single_app_tracing/expression/conditional_expression/conditional_expression_001_T\",\"functionName\":\"conditional_expression_001_T\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /jsbenchmark/completeness/single_app_tracing/expression/conditional_expression/conditional_expression_001_T\n AffectedNodeName: __taint_src\n 11: SOURCE: function conditional_expression_001_T(__taint_src) {\n /jsbenchmark/completeness/single_app_tracing/expression/conditional_expression/conditional_expression_001_T\n AffectedNodeName: result\n 13: Var Pass: result = true ? __taint_src : \"aa\";\n /jsbenchmark/completeness/single_app_tracing/expression/conditional_expression/conditional_expression_001_T\n AffectedNodeName: __taint_sink\n 14: SINK: __taint_sink(result);\n==========================================================\n #Total-findings:1\n==========================================================","/jsbenchmark/completeness/single_app_tracing/expression/conditional_expression/conditional_expression_002_F":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/completeness/single_app_tracing/expression/lambda_expression/lambda_expression_001_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/jsbenchmark/completeness/single_app_tracing/expression/lambda_expression/lambda_expression_001_T\nLine 15: __taint_sink(result)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/jsbenchmark/completeness/single_app_tracing/expression/lambda_expression/lambda_expression_001_T\",\"functionName\":\"lambda_expression_001_T\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /jsbenchmark/completeness/single_app_tracing/expression/lambda_expression/lambda_expression_001_T\n AffectedNodeName: __taint_src\n 11: SOURCE: function lambda_expression_001_T(__taint_src) {\n /jsbenchmark/completeness/single_app_tracing/expression/lambda_expression/lambda_expression_001_T\n AffectedNodeName: \n 14: CALL: result = lambda(__taint_src);\n /jsbenchmark/completeness/single_app_tracing/expression/lambda_expression/lambda_expression_001_T\n AffectedNodeName: a\n 13: ARG PASS: const lambda = (a) => a;\n /jsbenchmark/completeness/single_app_tracing/expression/lambda_expression/lambda_expression_001_T\n AffectedNodeName: [return value]\n 13: Return Value: const lambda = (a) => a;\n /jsbenchmark/completeness/single_app_tracing/expression/lambda_expression/lambda_expression_001_T\n AffectedNodeName: \n 14: CALL RETURN: result = lambda(__taint_src);\n /jsbenchmark/completeness/single_app_tracing/expression/lambda_expression/lambda_expression_001_T\n AffectedNodeName: result\n 14: Var Pass: result = lambda(__taint_src);\n /jsbenchmark/completeness/single_app_tracing/expression/lambda_expression/lambda_expression_001_T\n AffectedNodeName: __taint_sink\n 15: SINK: __taint_sink(result);\n==========================================================\n #Total-findings:1\n==========================================================","/jsbenchmark/completeness/single_app_tracing/expression/lambda_expression/lambda_expression_002_F":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/completeness/single_app_tracing/expression/special_expression/delete_expression_001_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/jsbenchmark/completeness/single_app_tracing/expression/special_expression/delete_expression_001_T\nLine 17: __taint_sink(Employee.lastname)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/jsbenchmark/completeness/single_app_tracing/expression/special_expression/delete_expression_001_T\",\"functionName\":\"delete_expression_001_T\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /jsbenchmark/completeness/single_app_tracing/expression/special_expression/delete_expression_001_T\n AffectedNodeName: __taint_src\n 10: SOURCE: function delete_expression_001_T(__taint_src) {\n /jsbenchmark/completeness/single_app_tracing/expression/special_expression/delete_expression_001_T\n AffectedNodeName: Employee\n 11: Var Pass: const Employee = {\n 12: Var Pass: firstname: \"Bob\",\n 13: Var Pass: lastname: __taint_src,\n 14: Var Pass: };\n /jsbenchmark/completeness/single_app_tracing/expression/special_expression/delete_expression_001_T\n AffectedNodeName: __taint_sink\n 17: SINK: __taint_sink(Employee.lastname);\n==========================================================\n #Total-findings:1\n==========================================================","/jsbenchmark/completeness/single_app_tracing/expression/special_expression/delete_expression_002_F":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/completeness/single_app_tracing/expression/special_expression/delete_expression_003_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/jsbenchmark/completeness/single_app_tracing/expression/special_expression/delete_expression_003_T\nLine 13: __taint_sink(array)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/jsbenchmark/completeness/single_app_tracing/expression/special_expression/delete_expression_003_T\",\"functionName\":\"delete_expression_003_T\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /jsbenchmark/completeness/single_app_tracing/expression/special_expression/delete_expression_003_T\n AffectedNodeName: __taint_src\n 10: SOURCE: function delete_expression_003_T(__taint_src) {\n /jsbenchmark/completeness/single_app_tracing/expression/special_expression/delete_expression_003_T\n AffectedNodeName: array\n 11: Var Pass: const array = [__taint_src, \"b\", \"c\", \"d\"];\n /jsbenchmark/completeness/single_app_tracing/expression/special_expression/delete_expression_003_T\n AffectedNodeName: __taint_sink\n 13: SINK: __taint_sink(array);\n==========================================================\n #Total-findings:1\n==========================================================","/jsbenchmark/completeness/single_app_tracing/expression/special_expression/delete_expression_004_F":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/completeness/single_app_tracing/expression/special_expression/destructuring_assignment_001_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/jsbenchmark/completeness/single_app_tracing/expression/special_expression/destructuring_assignment_001_T\nLine 14: __taint_sink(result)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/jsbenchmark/completeness/single_app_tracing/expression/special_expression/destructuring_assignment_001_T\",\"functionName\":\"destructuring_assignment_001_T\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /jsbenchmark/completeness/single_app_tracing/expression/special_expression/destructuring_assignment_001_T\n AffectedNodeName: __taint_src\n 11: SOURCE: function destructuring_assignment_001_T(__taint_src) {\n /jsbenchmark/completeness/single_app_tracing/expression/special_expression/destructuring_assignment_001_T\n AffectedNodeName: arr\n 12: Var Pass: let arr = [\"_\", \"_\", __taint_src];\n /jsbenchmark/completeness/single_app_tracing/expression/special_expression/destructuring_assignment_001_T\n AffectedNodeName: result\n 13: Var Pass: let [a, b, result] = arr;\n /jsbenchmark/completeness/single_app_tracing/expression/special_expression/destructuring_assignment_001_T\n AffectedNodeName: __taint_sink\n 14: SINK: __taint_sink(result);\n==========================================================\n #Total-findings:1\n==========================================================","/jsbenchmark/completeness/single_app_tracing/expression/special_expression/destructuring_assignment_002_F":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/completeness/single_app_tracing/expression/special_expression/destructuring_assignment_003_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/jsbenchmark/completeness/single_app_tracing/expression/special_expression/destructuring_assignment_003_T\nLine 14: __taint_sink(c)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/jsbenchmark/completeness/single_app_tracing/expression/special_expression/destructuring_assignment_003_T\",\"functionName\":\"destructuring_assignment_003_T\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /jsbenchmark/completeness/single_app_tracing/expression/special_expression/destructuring_assignment_003_T\n AffectedNodeName: __taint_src\n 11: SOURCE: function destructuring_assignment_003_T(__taint_src) {\n /jsbenchmark/completeness/single_app_tracing/expression/special_expression/destructuring_assignment_003_T\n AffectedNodeName: arr\n 12: Var Pass: let arr = { a: \"_\", b: \"_\", c: __taint_src };\n /jsbenchmark/completeness/single_app_tracing/expression/special_expression/destructuring_assignment_003_T\n AffectedNodeName: c\n 13: Var Pass: let { a, b, c } = arr;\n /jsbenchmark/completeness/single_app_tracing/expression/special_expression/destructuring_assignment_003_T\n AffectedNodeName: __taint_sink\n 14: SINK: __taint_sink(c);\n==========================================================\n #Total-findings:1\n==========================================================","/jsbenchmark/completeness/single_app_tracing/expression/special_expression/destructuring_assignment_004_F":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/completeness/single_app_tracing/expression/special_expression/destructuring_assignment_005_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/jsbenchmark/completeness/single_app_tracing/expression/special_expression/destructuring_assignment_005_T\nLine 14: __taint_sink(c)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/jsbenchmark/completeness/single_app_tracing/expression/special_expression/destructuring_assignment_005_T\",\"functionName\":\"destructuring_assignment_005_T\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /jsbenchmark/completeness/single_app_tracing/expression/special_expression/destructuring_assignment_005_T\n AffectedNodeName: __taint_src\n 11: SOURCE: function destructuring_assignment_005_T(__taint_src) {\n /jsbenchmark/completeness/single_app_tracing/expression/special_expression/destructuring_assignment_005_T\n AffectedNodeName: arr\n 12: Var Pass: let arr = [\"_\", \"_\", [__taint_src, \"_\"]];\n /jsbenchmark/completeness/single_app_tracing/expression/special_expression/destructuring_assignment_005_T\n AffectedNodeName: c\n 13: Var Pass: let [a, b, [c, d]] = arr;\n /jsbenchmark/completeness/single_app_tracing/expression/special_expression/destructuring_assignment_005_T\n AffectedNodeName: __taint_sink\n 14: SINK: __taint_sink(c);\n==========================================================\n #Total-findings:1\n==========================================================","/jsbenchmark/completeness/single_app_tracing/expression/special_expression/destructuring_assignment_006_F":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/completeness/single_app_tracing/expression/special_expression/destructuring_assignment_007_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/jsbenchmark/completeness/single_app_tracing/expression/special_expression/destructuring_assignment_007_T\nLine 14: __taint_sink(c)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/jsbenchmark/completeness/single_app_tracing/expression/special_expression/destructuring_assignment_007_T\",\"functionName\":\"destructuring_assignment_007_T\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /jsbenchmark/completeness/single_app_tracing/expression/special_expression/destructuring_assignment_007_T\n AffectedNodeName: __taint_src\n 11: SOURCE: function destructuring_assignment_007_T(__taint_src) {\n /jsbenchmark/completeness/single_app_tracing/expression/special_expression/destructuring_assignment_007_T\n AffectedNodeName: arr\n 12: Var Pass: let arr = { a: \"_\", b: \"_\", c: { __taint_src, d: \"a\" } };\n /jsbenchmark/completeness/single_app_tracing/expression/special_expression/destructuring_assignment_007_T\n AffectedNodeName: c\n 13: Var Pass: let { a, b, c } = arr;\n /jsbenchmark/completeness/single_app_tracing/expression/special_expression/destructuring_assignment_007_T\n AffectedNodeName: __taint_sink\n 14: SINK: __taint_sink(c);\n==========================================================\n #Total-findings:1\n==========================================================","/jsbenchmark/completeness/single_app_tracing/expression/special_expression/destructuring_assignment_008_F":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/completeness/single_app_tracing/expression/special_expression/exponentiation_operator_001_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/jsbenchmark/completeness/single_app_tracing/expression/special_expression/exponentiation_operator_001_T\nLine 13: __taint_sink(result)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/jsbenchmark/completeness/single_app_tracing/expression/special_expression/exponentiation_operator_001_T\",\"functionName\":\"exponentiation_operator_001_T\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /jsbenchmark/completeness/single_app_tracing/expression/special_expression/exponentiation_operator_001_T\n AffectedNodeName: __taint_src\n 11: SOURCE: function exponentiation_operator_001_T(__taint_src) {\n /jsbenchmark/completeness/single_app_tracing/expression/special_expression/exponentiation_operator_001_T\n AffectedNodeName: result\n 12: Var Pass: let result = __taint_src ** 2;\n /jsbenchmark/completeness/single_app_tracing/expression/special_expression/exponentiation_operator_001_T\n AffectedNodeName: __taint_sink\n 13: SINK: __taint_sink(result);\n==========================================================\n #Total-findings:1\n==========================================================","/jsbenchmark/completeness/single_app_tracing/expression/special_expression/exponentiation_operator_002_F":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/completeness/single_app_tracing/expression/special_expression/nullish_coalescing_operator_001_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/jsbenchmark/completeness/single_app_tracing/expression/special_expression/nullish_coalescing_operator_001_T\nLine 13: __taint_sink(result)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/jsbenchmark/completeness/single_app_tracing/expression/special_expression/nullish_coalescing_operator_001_T\",\"functionName\":\"nullish_coalescing_operator_001_T\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /jsbenchmark/completeness/single_app_tracing/expression/special_expression/nullish_coalescing_operator_001_T\n AffectedNodeName: __taint_src\n 11: SOURCE: function nullish_coalescing_operator_001_T(__taint_src) {\n /jsbenchmark/completeness/single_app_tracing/expression/special_expression/nullish_coalescing_operator_001_T\n AffectedNodeName: result\n 12: Var Pass: let result = null ?? __taint_src;\n /jsbenchmark/completeness/single_app_tracing/expression/special_expression/nullish_coalescing_operator_001_T\n AffectedNodeName: __taint_sink\n 13: SINK: __taint_sink(result);\n==========================================================\n #Total-findings:1\n==========================================================","/jsbenchmark/completeness/single_app_tracing/expression/special_expression/nullish_coalescing_operator_002_F":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/completeness/single_app_tracing/expression/special_expression/optional_chaining_operator_001_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/jsbenchmark/completeness/single_app_tracing/expression/special_expression/optional_chaining_operator_001_T\nLine 17: __taint_sink(result)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/jsbenchmark/completeness/single_app_tracing/expression/special_expression/optional_chaining_operator_001_T\",\"functionName\":\"optional_chaining_operator_001_T\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /jsbenchmark/completeness/single_app_tracing/expression/special_expression/optional_chaining_operator_001_T\n AffectedNodeName: __taint_src\n 11: SOURCE: function optional_chaining_operator_001_T(__taint_src) {\n /jsbenchmark/completeness/single_app_tracing/expression/special_expression/optional_chaining_operator_001_T\n AffectedNodeName: obj\n 12: Var Pass: let obj = {\n 13: Var Pass: taintKey: __taint_src,\n 14: Var Pass: };\n /jsbenchmark/completeness/single_app_tracing/expression/special_expression/optional_chaining_operator_001_T\n AffectedNodeName: result\n 16: Var Pass: let result = obj?.taintKey;\n /jsbenchmark/completeness/single_app_tracing/expression/special_expression/optional_chaining_operator_001_T\n AffectedNodeName: __taint_sink\n 17: SINK: __taint_sink(result);\n==========================================================\n #Total-findings:1\n==========================================================","/jsbenchmark/completeness/single_app_tracing/expression/special_expression/optional_chaining_operator_002_F":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/completeness/single_app_tracing/expression/special_expression/rest_parameter_001_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/jsbenchmark/completeness/single_app_tracing/expression/special_expression/rest_parameter_001_T\nLine 16: __taint_sink(args)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/jsbenchmark/completeness/single_app_tracing/expression/special_expression/rest_parameter_001_T\",\"functionName\":\"rest_parameter_001_T\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /jsbenchmark/completeness/single_app_tracing/expression/special_expression/rest_parameter_001_T\n AffectedNodeName: __taint_src\n 11: SOURCE: function rest_parameter_001_T(__taint_src) {\n /jsbenchmark/completeness/single_app_tracing/expression/special_expression/rest_parameter_001_T\n AffectedNodeName: collectArgs\n 12: CALL: collectArgs(\"prefix\", __taint_src, \"suffix\");\n /jsbenchmark/completeness/single_app_tracing/expression/special_expression/rest_parameter_001_T\n AffectedNodeName: __tmp1__\n 15: ARG PASS: function collectArgs(...args) {\n /jsbenchmark/completeness/single_app_tracing/expression/special_expression/rest_parameter_001_T\n AffectedNodeName: args\n 15: Var Pass: function collectArgs(...args) {\n 16: Var Pass: __taint_sink(args);\n 17: Var Pass: }\n /jsbenchmark/completeness/single_app_tracing/expression/special_expression/rest_parameter_001_T\n AffectedNodeName: __taint_sink\n 16: SINK: __taint_sink(args);\n==========================================================\n #Total-findings:1\n==========================================================","/jsbenchmark/completeness/single_app_tracing/expression/special_expression/rest_parameter_002_F":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/completeness/single_app_tracing/expression/special_expression/rest_parameter_003_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/jsbenchmark/completeness/single_app_tracing/expression/special_expression/rest_parameter_003_T\nLine 17: __taint_sink({with(params)})\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/jsbenchmark/completeness/single_app_tracing/expression/special_expression/rest_parameter_003_T\",\"functionName\":\"rest_parameter_003_T\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /jsbenchmark/completeness/single_app_tracing/expression/special_expression/rest_parameter_003_T\n AffectedNodeName: __taint_src\n 11: SOURCE: function rest_parameter_003_T(__taint_src) {\n /jsbenchmark/completeness/single_app_tracing/expression/special_expression/rest_parameter_003_T\n AffectedNodeName: params\n 12: Var Pass: const params = {\n 13: Var Pass: name: \"Tony\",\n 14: Var Pass: age: \"12\",\n 15: Var Pass: id: __taint_src,\n 16: Var Pass: };\n /jsbenchmark/completeness/single_app_tracing/expression/special_expression/rest_parameter_003_T\n AffectedNodeName: __taint_sink\n 17: SINK: __taint_sink({ ...params });\n==========================================================\n #Total-findings:1\n==========================================================","/jsbenchmark/completeness/single_app_tracing/expression/special_expression/rest_parameter_004_F":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/completeness/single_app_tracing/expression/special_expression/rest_parameter_005_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/jsbenchmark/completeness/single_app_tracing/expression/special_expression/rest_parameter_005_T\nLine 16: __taint_sink(args)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/jsbenchmark/completeness/single_app_tracing/expression/special_expression/rest_parameter_005_T\",\"functionName\":\"rest_parameter_005_T\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /jsbenchmark/completeness/single_app_tracing/expression/special_expression/rest_parameter_005_T\n AffectedNodeName: __taint_src\n 11: SOURCE: function rest_parameter_005_T(__taint_src) {\n /jsbenchmark/completeness/single_app_tracing/expression/special_expression/rest_parameter_005_T\n AffectedNodeName: collectArgs\n 12: CALL: collectArgs([\"prefix\", __taint_src, \"suffix\"]);\n /jsbenchmark/completeness/single_app_tracing/expression/special_expression/rest_parameter_005_T\n AffectedNodeName: __tmp1__\n 15: ARG PASS: function collectArgs(...args) {\n /jsbenchmark/completeness/single_app_tracing/expression/special_expression/rest_parameter_005_T\n AffectedNodeName: args\n 15: Var Pass: function collectArgs(...args) {\n 16: Var Pass: __taint_sink(args);\n 17: Var Pass: }\n /jsbenchmark/completeness/single_app_tracing/expression/special_expression/rest_parameter_005_T\n AffectedNodeName: __taint_sink\n 16: SINK: __taint_sink(args);\n==========================================================\n #Total-findings:1\n==========================================================","/jsbenchmark/completeness/single_app_tracing/expression/special_expression/rest_parameter_006_F":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/completeness/single_app_tracing/expression/special_expression/spread_operator_001_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/jsbenchmark/completeness/single_app_tracing/expression/special_expression/spread_operator_001_T\nLine 14: __taint_sink(array)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/jsbenchmark/completeness/single_app_tracing/expression/special_expression/spread_operator_001_T\",\"functionName\":\"spread_operator_001_T\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /jsbenchmark/completeness/single_app_tracing/expression/special_expression/spread_operator_001_T\n AffectedNodeName: __taint_src\n 11: SOURCE: function spread_operator_001_T(__taint_src) {\n /jsbenchmark/completeness/single_app_tracing/expression/special_expression/spread_operator_001_T\n AffectedNodeName: array1\n 12: Var Pass: let array1 = [\"a\", \"b\", __taint_src];\n /jsbenchmark/completeness/single_app_tracing/expression/special_expression/spread_operator_001_T\n AffectedNodeName: array\n 13: Var Pass: let array = [\"c\", ...array1];\n /jsbenchmark/completeness/single_app_tracing/expression/special_expression/spread_operator_001_T\n AffectedNodeName: __taint_sink\n 14: SINK: __taint_sink(array);\n==========================================================\n #Total-findings:1\n==========================================================","/jsbenchmark/completeness/single_app_tracing/expression/special_expression/spread_operator_002_F":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/completeness/single_app_tracing/expression/special_expression/spread_operator_003_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/jsbenchmark/completeness/single_app_tracing/expression/special_expression/spread_operator_003_T\nLine 21: __taint_sink(newParams)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/jsbenchmark/completeness/single_app_tracing/expression/special_expression/spread_operator_003_T\",\"functionName\":\"spread_operator_003_T\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /jsbenchmark/completeness/single_app_tracing/expression/special_expression/spread_operator_003_T\n AffectedNodeName: __taint_src\n 11: SOURCE: function spread_operator_003_T(__taint_src) {\n /jsbenchmark/completeness/single_app_tracing/expression/special_expression/spread_operator_003_T\n AffectedNodeName: params\n 12: Var Pass: const params = {\n 13: Var Pass: name: \"Tony\",\n 14: Var Pass: age: \"12\",\n 15: Var Pass: id: __taint_src,\n 16: Var Pass: };\n /jsbenchmark/completeness/single_app_tracing/expression/special_expression/spread_operator_003_T\n AffectedNodeName: newParams\n 17: Var Pass: const newParams = {\n 18: Var Pass: score: 100,\n 19: Var Pass: ...params,\n 20: Var Pass: };\n /jsbenchmark/completeness/single_app_tracing/expression/special_expression/spread_operator_003_T\n AffectedNodeName: __taint_sink\n 21: SINK: __taint_sink(newParams);\n==========================================================\n #Total-findings:1\n==========================================================","/jsbenchmark/completeness/single_app_tracing/expression/special_expression/spread_operator_004_F":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/completeness/single_app_tracing/expression/special_expression/spread_operator_005_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/jsbenchmark/completeness/single_app_tracing/expression/special_expression/spread_operator_005_T\nLine 15: __taint_sink(rest)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/jsbenchmark/completeness/single_app_tracing/expression/special_expression/spread_operator_005_T\",\"functionName\":\"spread_operator_005_T\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /jsbenchmark/completeness/single_app_tracing/expression/special_expression/spread_operator_005_T\n AffectedNodeName: __taint_src\n 11: SOURCE: function spread_operator_005_T(__taint_src) {\n /jsbenchmark/completeness/single_app_tracing/expression/special_expression/spread_operator_005_T\n AffectedNodeName: foo\n 12: Var Pass: const foo = __taint_src;\n /jsbenchmark/completeness/single_app_tracing/expression/special_expression/spread_operator_005_T\n AffectedNodeName: __tmp1__\n 14: Var Pass: const [r1, r2, ...rest] = [123, 456, foo, bar];\n /jsbenchmark/completeness/single_app_tracing/expression/special_expression/spread_operator_005_T\n AffectedNodeName: rest\n 14: Var Pass: const [r1, r2, ...rest] = [123, 456, foo, bar];\n /jsbenchmark/completeness/single_app_tracing/expression/special_expression/spread_operator_005_T\n AffectedNodeName: __taint_sink\n 15: SINK: __taint_sink(rest);\n==========================================================\n #Total-findings:1\n==========================================================","/jsbenchmark/completeness/single_app_tracing/expression/special_expression/spread_operator_006_F":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/completeness/single_app_tracing/expression/special_expression/template_literal_001_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/jsbenchmark/completeness/single_app_tracing/expression/special_expression/template_literal_001_T\nLine 13: __taint_sink(result)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/jsbenchmark/completeness/single_app_tracing/expression/special_expression/template_literal_001_T\",\"functionName\":\"template_literal_001_T\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /jsbenchmark/completeness/single_app_tracing/expression/special_expression/template_literal_001_T\n AffectedNodeName: __taint_src\n 11: SOURCE: function template_literal_001_T(__taint_src) {\n /jsbenchmark/completeness/single_app_tracing/expression/special_expression/template_literal_001_T\n AffectedNodeName: result\n 12: Var Pass: let result = `_${__taint_src}`;\n /jsbenchmark/completeness/single_app_tracing/expression/special_expression/template_literal_001_T\n AffectedNodeName: __taint_sink\n 13: SINK: __taint_sink(result);\n==========================================================\n #Total-findings:1\n==========================================================","/jsbenchmark/completeness/single_app_tracing/expression/special_expression/template_literal_002_F":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/completeness/single_app_tracing/expression/special_expression/template_literal_003_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/jsbenchmark/completeness/single_app_tracing/expression/special_expression/template_literal_003_T\nLine 13: __taint_sink(result)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/jsbenchmark/completeness/single_app_tracing/expression/special_expression/template_literal_003_T\",\"functionName\":\"template_literal_003_T\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /jsbenchmark/completeness/single_app_tracing/expression/special_expression/template_literal_003_T\n AffectedNodeName: __taint_src\n 11: SOURCE: function template_literal_003_T(__taint_src) {\n /jsbenchmark/completeness/single_app_tracing/expression/special_expression/template_literal_003_T\n AffectedNodeName: result\n 12: Var Pass: let result = `${__taint_src}_`;\n /jsbenchmark/completeness/single_app_tracing/expression/special_expression/template_literal_003_T\n AffectedNodeName: __taint_sink\n 13: SINK: __taint_sink(result);\n==========================================================\n #Total-findings:1\n==========================================================","/jsbenchmark/completeness/single_app_tracing/expression/special_expression/template_literal_004_F":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/completeness/single_app_tracing/expression/special_expression/template_literal_005_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/jsbenchmark/completeness/single_app_tracing/expression/special_expression/template_literal_005_T\nLine 13: __taint_sink(result)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/jsbenchmark/completeness/single_app_tracing/expression/special_expression/template_literal_005_T\",\"functionName\":\"template_literal_005_T\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /jsbenchmark/completeness/single_app_tracing/expression/special_expression/template_literal_005_T\n AffectedNodeName: __taint_src\n 11: SOURCE: function template_literal_005_T(__taint_src) {\n /jsbenchmark/completeness/single_app_tracing/expression/special_expression/template_literal_005_T\n AffectedNodeName: result\n 12: Var Pass: let result = `_${__taint_src}_`;\n /jsbenchmark/completeness/single_app_tracing/expression/special_expression/template_literal_005_T\n AffectedNodeName: __taint_sink\n 13: SINK: __taint_sink(result);\n==========================================================\n #Total-findings:1\n==========================================================","/jsbenchmark/completeness/single_app_tracing/expression/special_expression/template_literal_006_F":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/completeness/single_app_tracing/expression/this_expression/this_expression_001_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/jsbenchmark/completeness/single_app_tracing/expression/this_expression/this_expression_001_T\nLine 20: __taint_sink(result)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/jsbenchmark/completeness/single_app_tracing/expression/this_expression/this_expression_001_T\",\"functionName\":\"this_expression_001_T\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /jsbenchmark/completeness/single_app_tracing/expression/this_expression/this_expression_001_T\n AffectedNodeName: __taint_src\n 11: SOURCE: function this_expression_001_T(__taint_src) {\n /jsbenchmark/completeness/single_app_tracing/expression/this_expression/this_expression_001_T\n AffectedNodeName: obj\n 12: Var Pass: let obj = {\n 13: Var Pass: value: __taint_src,\n 14: Var Pass: getValue: function () {\n 15: Var Pass: return this.value;\n 16: Var Pass: },\n 17: Var Pass: };\n /jsbenchmark/completeness/single_app_tracing/expression/this_expression/this_expression_001_T\n AffectedNodeName: \n 19: CALL: let result = obj.getValue();\n /jsbenchmark/completeness/single_app_tracing/expression/this_expression/this_expression_001_T\n AffectedNodeName: obj\n 19: ARG PASS: let result = obj.getValue();\n /jsbenchmark/completeness/single_app_tracing/expression/this_expression/this_expression_001_T\n AffectedNodeName: [return value]\n 15: Return Value: return this.value;\n /jsbenchmark/completeness/single_app_tracing/expression/this_expression/this_expression_001_T\n AffectedNodeName: \n 19: CALL RETURN: let result = obj.getValue();\n /jsbenchmark/completeness/single_app_tracing/expression/this_expression/this_expression_001_T\n AffectedNodeName: result\n 19: Var Pass: let result = obj.getValue();\n /jsbenchmark/completeness/single_app_tracing/expression/this_expression/this_expression_001_T\n AffectedNodeName: __taint_sink\n 20: SINK: __taint_sink(result);\n==========================================================\n #Total-findings:1\n==========================================================","/jsbenchmark/completeness/single_app_tracing/expression/this_expression/this_expression_002_F":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/completeness/single_app_tracing/expression/this_expression/this_expression_003_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/jsbenchmark/completeness/single_app_tracing/expression/this_expression/this_expression_003_T\nLine 15: __taint_sink(this.result)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/jsbenchmark/completeness/single_app_tracing/expression/this_expression/this_expression_003_T\",\"functionName\":\"this_expression_003_T\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /jsbenchmark/completeness/single_app_tracing/expression/this_expression/this_expression_003_T\n AffectedNodeName: __taint_src\n 13: SOURCE: function this_expression_003_T(__taint_src) {\n /jsbenchmark/completeness/single_app_tracing/expression/this_expression/this_expression_003_T\n AffectedNodeName: [this.result]\n 14: Var Pass: this.result = __taint_src;\n /jsbenchmark/completeness/single_app_tracing/expression/this_expression/this_expression_003_T\n AffectedNodeName: __taint_sink\n 15: SINK: __taint_sink(this.result);\n==========================================================\n #Total-findings:1\n==========================================================","/jsbenchmark/completeness/single_app_tracing/expression/this_expression/this_expression_004_F":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/completeness/single_app_tracing/expression/type_cast/type_cast_001_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/jsbenchmark/completeness/single_app_tracing/expression/type_cast/type_cast_001_T\nLine 13: __taint_sink(result)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/jsbenchmark/completeness/single_app_tracing/expression/type_cast/type_cast_001_T\",\"functionName\":\"type_cast_001_T\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /jsbenchmark/completeness/single_app_tracing/expression/type_cast/type_cast_001_T\n AffectedNodeName: __taint_src\n 11: SOURCE: function type_cast_001_T(__taint_src) {\n /jsbenchmark/completeness/single_app_tracing/expression/type_cast/type_cast_001_T\n AffectedNodeName: result\n 12: Var Pass: let result = Number(__taint_src);\n /jsbenchmark/completeness/single_app_tracing/expression/type_cast/type_cast_001_T\n AffectedNodeName: __taint_sink\n 13: SINK: __taint_sink(result);\n==========================================================\n #Total-findings:1\n==========================================================","/jsbenchmark/completeness/single_app_tracing/expression/type_cast/type_cast_002_F":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/completeness/single_app_tracing/expression/type_cast/type_cast_003_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/jsbenchmark/completeness/single_app_tracing/expression/type_cast/type_cast_003_T\nLine 13: __taint_sink(result)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/jsbenchmark/completeness/single_app_tracing/expression/type_cast/type_cast_003_T\",\"functionName\":\"type_cast_003_T\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /jsbenchmark/completeness/single_app_tracing/expression/type_cast/type_cast_003_T\n AffectedNodeName: __taint_src\n 11: SOURCE: function type_cast_003_T(__taint_src) {\n /jsbenchmark/completeness/single_app_tracing/expression/type_cast/type_cast_003_T\n AffectedNodeName: result\n 12: Var Pass: let result = __taint_src == 5;\n /jsbenchmark/completeness/single_app_tracing/expression/type_cast/type_cast_003_T\n AffectedNodeName: __taint_sink\n 13: SINK: __taint_sink(result);\n==========================================================\n #Total-findings:1\n==========================================================","/jsbenchmark/completeness/single_app_tracing/expression/type_cast/type_cast_004_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/jsbenchmark/completeness/single_app_tracing/expression/type_cast/type_cast_004_T\nLine 13: __taint_sink(result)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/jsbenchmark/completeness/single_app_tracing/expression/type_cast/type_cast_004_T\",\"functionName\":\"type_cast_004_T\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /jsbenchmark/completeness/single_app_tracing/expression/type_cast/type_cast_004_T\n AffectedNodeName: __taint_src\n 11: SOURCE: function type_cast_004_T(__taint_src) {\n /jsbenchmark/completeness/single_app_tracing/expression/type_cast/type_cast_004_T\n AffectedNodeName: result\n 12: Var Pass: let result = __taint_src == \"5\";\n /jsbenchmark/completeness/single_app_tracing/expression/type_cast/type_cast_004_T\n AffectedNodeName: __taint_sink\n 13: SINK: __taint_sink(result);\n==========================================================\n #Total-findings:1\n==========================================================","/jsbenchmark/completeness/single_app_tracing/function_call/anonymous_function_closure/anonymous_function_001_F":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/completeness/single_app_tracing/function_call/anonymous_function_closure/anonymous_function_002_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/jsbenchmark/completeness/single_app_tracing/function_call/anonymous_function_closure/anonymous_function_002_T\nLine 14: __taint_sink(process(__taint_src, foo))\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/jsbenchmark/completeness/single_app_tracing/function_call/anonymous_function_closure/anonymous_function_002_T\",\"functionName\":\"anonymous_function_002_T\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /jsbenchmark/completeness/single_app_tracing/function_call/anonymous_function_closure/anonymous_function_002_T\n AffectedNodeName: __taint_src\n 10: SOURCE: function anonymous_function_002_T(__taint_src) {\n /jsbenchmark/completeness/single_app_tracing/function_call/anonymous_function_closure/anonymous_function_002_T\n AffectedNodeName: \n 14: CALL: __taint_sink(process(__taint_src, \"foo\"));\n /jsbenchmark/completeness/single_app_tracing/function_call/anonymous_function_closure/anonymous_function_002_T\n AffectedNodeName: a\n 11: ARG PASS: const process = function (a, b) {\n /jsbenchmark/completeness/single_app_tracing/function_call/anonymous_function_closure/anonymous_function_002_T\n AffectedNodeName: [return value]\n 12: Return Value: return a + b;\n /jsbenchmark/completeness/single_app_tracing/function_call/anonymous_function_closure/anonymous_function_002_T\n AffectedNodeName: \n 14: CALL RETURN: __taint_sink(process(__taint_src, \"foo\"));\n /jsbenchmark/completeness/single_app_tracing/function_call/anonymous_function_closure/anonymous_function_002_T\n AffectedNodeName: __taint_sink\n 14: SINK: __taint_sink(process(__taint_src, \"foo\"));\n==========================================================\n #Total-findings:1\n==========================================================","/jsbenchmark/completeness/single_app_tracing/function_call/anonymous_function_closure/anonymous_function_003_F":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/completeness/single_app_tracing/function_call/anonymous_function_closure/anonymous_function_004_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/jsbenchmark/completeness/single_app_tracing/function_call/anonymous_function_closure/anonymous_function_004_T\nLine 12: __taint_sink(input)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/jsbenchmark/completeness/single_app_tracing/function_call/anonymous_function_closure/anonymous_function_004_T\",\"functionName\":\"anonymous_function_004_T\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /jsbenchmark/completeness/single_app_tracing/function_call/anonymous_function_closure/anonymous_function_004_T\n AffectedNodeName: __taint_src\n 10: SOURCE: function anonymous_function_004_T(__taint_src) {\n /jsbenchmark/completeness/single_app_tracing/function_call/anonymous_function_closure/anonymous_function_004_T\n AffectedNodeName: \n 15: CALL: process(__taint_src);\n /jsbenchmark/completeness/single_app_tracing/function_call/anonymous_function_closure/anonymous_function_004_T\n AffectedNodeName: input\n 11: ARG PASS: let process = function (input) {\n /jsbenchmark/completeness/single_app_tracing/function_call/anonymous_function_closure/anonymous_function_004_T\n AffectedNodeName: __taint_sink\n 12: SINK: __taint_sink(input);\n==========================================================\n #Total-findings:1\n==========================================================","/jsbenchmark/completeness/single_app_tracing/function_call/anonymous_function_closure/anonymous_function_005_F":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/completeness/single_app_tracing/function_call/anonymous_function_closure/anonymous_function_006_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/jsbenchmark/completeness/single_app_tracing/function_call/anonymous_function_closure/anonymous_function_006_T\nLine 12: __taint_sink(__taint_src)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/jsbenchmark/completeness/single_app_tracing/function_call/anonymous_function_closure/anonymous_function_006_T\",\"functionName\":\"anonymous_function_006_T\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /jsbenchmark/completeness/single_app_tracing/function_call/anonymous_function_closure/anonymous_function_006_T\n AffectedNodeName: __taint_src\n 10: SOURCE: function anonymous_function_006_T(__taint_src) {\n /jsbenchmark/completeness/single_app_tracing/function_call/anonymous_function_closure/anonymous_function_006_T\n AffectedNodeName: __taint_sink\n 12: SINK: __taint_sink(__taint_src);\n==========================================================\n #Total-findings:1\n==========================================================","/jsbenchmark/completeness/single_app_tracing/function_call/anonymous_function_closure/closure_function_001_F":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/completeness/single_app_tracing/function_call/anonymous_function_closure/closure_function_002_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/jsbenchmark/completeness/single_app_tracing/function_call/anonymous_function_closure/closure_function_002_T\nLine 12: __taint_sink(__taint_src)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/jsbenchmark/completeness/single_app_tracing/function_call/anonymous_function_closure/closure_function_002_T\",\"functionName\":\"closure_function_002_T\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /jsbenchmark/completeness/single_app_tracing/function_call/anonymous_function_closure/closure_function_002_T\n AffectedNodeName: __taint_src\n 10: SOURCE: function closure_function_002_T(__taint_src) {\n /jsbenchmark/completeness/single_app_tracing/function_call/anonymous_function_closure/closure_function_002_T\n AffectedNodeName: __taint_sink\n 12: SINK: __taint_sink(__taint_src);\n==========================================================\n #Total-findings:1\n==========================================================","/jsbenchmark/completeness/single_app_tracing/function_call/anonymous_function_closure/closure_function_003_F":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/completeness/single_app_tracing/function_call/anonymous_function_closure/closure_function_004_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/jsbenchmark/completeness/single_app_tracing/function_call/anonymous_function_closure/closure_function_004_T\nLine 13: __taint_sink(__taint_src)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/jsbenchmark/completeness/single_app_tracing/function_call/anonymous_function_closure/closure_function_004_T\",\"functionName\":\"closure_function_004_T\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /jsbenchmark/completeness/single_app_tracing/function_call/anonymous_function_closure/closure_function_004_T\n AffectedNodeName: __taint_src\n 10: SOURCE: function closure_function_004_T(__taint_src) {\n /jsbenchmark/completeness/single_app_tracing/function_call/anonymous_function_closure/closure_function_004_T\n AffectedNodeName: __taint_sink\n 13: SINK: __taint_sink(__taint_src);\n==========================================================\n #Total-findings:1\n==========================================================","/jsbenchmark/completeness/single_app_tracing/function_call/anonymous_function_closure/closure_function_005_F":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/completeness/single_app_tracing/function_call/anonymous_function_closure/closure_function_006_F":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/completeness/single_app_tracing/function_call/anonymous_function_closure/closure_function_007_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/jsbenchmark/completeness/single_app_tracing/function_call/anonymous_function_closure/closure_function_007_T\nLine 25: __taint_sink(a.update())\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/jsbenchmark/completeness/single_app_tracing/function_call/anonymous_function_closure/closure_function_007_T\",\"functionName\":\"closure_function_007_T\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /jsbenchmark/completeness/single_app_tracing/function_call/anonymous_function_closure/closure_function_007_T\n AffectedNodeName: __taint_src\n 10: SOURCE: function closure_function_007_T(__taint_src) {\n /jsbenchmark/completeness/single_app_tracing/function_call/anonymous_function_closure/closure_function_007_T\n AffectedNodeName: source\n 15: Var Pass: source = __taint_src;\n /jsbenchmark/completeness/single_app_tracing/function_call/anonymous_function_closure/closure_function_007_T\n AffectedNodeName: [return value]\n 16: Return Value: return source;\n /jsbenchmark/completeness/single_app_tracing/function_call/anonymous_function_closure/closure_function_007_T\n AffectedNodeName: \n 25: CALL RETURN: __taint_sink(a.update());\n /jsbenchmark/completeness/single_app_tracing/function_call/anonymous_function_closure/closure_function_007_T\n AffectedNodeName: __taint_sink\n 25: SINK: __taint_sink(a.update());\n==========================================================\n #Total-findings:1\n==========================================================","/jsbenchmark/completeness/single_app_tracing/function_call/anonymous_function_closure/closure_function_008_F":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/completeness/single_app_tracing/function_call/anonymous_function_closure/closure_function_009_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/jsbenchmark/completeness/single_app_tracing/function_call/anonymous_function_closure/closure_function_009_T\nLine 18: __taint_sink(middleVar)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/jsbenchmark/completeness/single_app_tracing/function_call/anonymous_function_closure/closure_function_009_T\",\"functionName\":\"closure_function_009_T\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /jsbenchmark/completeness/single_app_tracing/function_call/anonymous_function_closure/closure_function_009_T\n AffectedNodeName: __taint_src\n 10: SOURCE: function closure_function_009_T(__taint_src) {\n /jsbenchmark/completeness/single_app_tracing/function_call/anonymous_function_closure/closure_function_009_T\n AffectedNodeName: outerVar\n 12: Var Pass: let outerVar = __taint_src;\n /jsbenchmark/completeness/single_app_tracing/function_call/anonymous_function_closure/closure_function_009_T\n AffectedNodeName: middleVar\n 15: Var Pass: let middleVar = outerVar;\n /jsbenchmark/completeness/single_app_tracing/function_call/anonymous_function_closure/closure_function_009_T\n AffectedNodeName: __taint_sink\n 18: SINK: __taint_sink(middleVar);\n==========================================================\n #Total-findings:1\n==========================================================","/jsbenchmark/completeness/single_app_tracing/function_call/anonymous_function_closure/closure_function_010_F":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/completeness/single_app_tracing/function_call/anonymous_function_closure/closure_function_011_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/jsbenchmark/completeness/single_app_tracing/function_call/anonymous_function_closure/closure_function_011_T\nLine 16: __taint_sink(outerVar)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/jsbenchmark/completeness/single_app_tracing/function_call/anonymous_function_closure/closure_function_011_T\",\"functionName\":\"closure_function_011_T\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /jsbenchmark/completeness/single_app_tracing/function_call/anonymous_function_closure/closure_function_011_T\n AffectedNodeName: __taint_src\n 10: SOURCE: function closure_function_011_T(__taint_src) {\n /jsbenchmark/completeness/single_app_tracing/function_call/anonymous_function_closure/closure_function_011_T\n AffectedNodeName: outerVar\n 12: Var Pass: let outerVar = __taint_src;\n /jsbenchmark/completeness/single_app_tracing/function_call/anonymous_function_closure/closure_function_011_T\n AffectedNodeName: __taint_sink\n 16: SINK: __taint_sink(outerVar);\n==========================================================\n #Total-findings:1\n==========================================================","/jsbenchmark/completeness/single_app_tracing/function_call/anonymous_function_closure/closure_function_012_F":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/completeness/single_app_tracing/function_call/anonymous_function_closure/closure_function_013_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/jsbenchmark/completeness/single_app_tracing/function_call/anonymous_function_closure/closure_function_013_T\nLine 14: __taint_sink(this.name)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/jsbenchmark/completeness/single_app_tracing/function_call/anonymous_function_closure/closure_function_013_T\",\"functionName\":\"closure_function_013_T\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /jsbenchmark/completeness/single_app_tracing/function_call/anonymous_function_closure/closure_function_013_T\n AffectedNodeName: __taint_src\n 10: SOURCE: function closure_function_013_T(__taint_src) {\n /jsbenchmark/completeness/single_app_tracing/function_call/anonymous_function_closure/closure_function_013_T\n AffectedNodeName: data\n 11: Var Pass: var data = {\n 12: Var Pass: name: __taint_src,\n 13: Var Pass: show: function () {\n 14: Var Pass: __taint_sink(this.name);\n 15: Var Pass: },\n 16: Var Pass: };\n /jsbenchmark/completeness/single_app_tracing/function_call/anonymous_function_closure/closure_function_013_T\n AffectedNodeName: \n 17: CALL: data.show();\n /jsbenchmark/completeness/single_app_tracing/function_call/anonymous_function_closure/closure_function_013_T\n AffectedNodeName: data\n 17: ARG PASS: data.show();\n /jsbenchmark/completeness/single_app_tracing/function_call/anonymous_function_closure/closure_function_013_T\n AffectedNodeName: __taint_sink\n 14: SINK: __taint_sink(this.name);\n==========================================================\n #Total-findings:1\n==========================================================","/jsbenchmark/completeness/single_app_tracing/function_call/anonymous_function_closure/closure_function_014_F":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/completeness/single_app_tracing/function_call/anonymous_function_closure/closure_function_015_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/jsbenchmark/completeness/single_app_tracing/function_call/anonymous_function_closure/closure_function_015_T\nLine 15: __taint_sink(this.name)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/jsbenchmark/completeness/single_app_tracing/function_call/anonymous_function_closure/closure_function_015_T\",\"functionName\":\"closure_function_015_T\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /jsbenchmark/completeness/single_app_tracing/function_call/anonymous_function_closure/closure_function_015_T\n AffectedNodeName: __taint_src\n 10: SOURCE: function closure_function_015_T(__taint_src) {\n /jsbenchmark/completeness/single_app_tracing/function_call/anonymous_function_closure/closure_function_015_T\n AffectedNodeName: data\n 11: Var Pass: var data = {\n 12: Var Pass: name: __taint_src,\n 13: Var Pass: show: function () {\n 14: Var Pass: return function () {\n 15: Var Pass: __taint_sink(this.name);\n 16: Var Pass: };\n 17: Var Pass: },\n 18: Var Pass: };\n /jsbenchmark/completeness/single_app_tracing/function_call/anonymous_function_closure/closure_function_015_T\n AffectedNodeName: \n 19: CALL: data.show().call(data);\n /jsbenchmark/completeness/single_app_tracing/function_call/anonymous_function_closure/closure_function_015_T\n AffectedNodeName: data\n 19: ARG PASS: data.show().call(data);\n /jsbenchmark/completeness/single_app_tracing/function_call/anonymous_function_closure/closure_function_015_T\n AffectedNodeName: __taint_sink\n 15: SINK: __taint_sink(this.name);\n==========================================================\n #Total-findings:1\n==========================================================","/jsbenchmark/completeness/single_app_tracing/function_call/anonymous_function_closure/closure_function_016_F":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/completeness/single_app_tracing/function_call/anonymous_function_closure/closure_function_017_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/jsbenchmark/completeness/single_app_tracing/function_call/anonymous_function_closure/closure_function_017_T\nLine 14: __taint_sink(this.data)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/jsbenchmark/completeness/single_app_tracing/function_call/anonymous_function_closure/closure_function_017_T\",\"functionName\":\"closure_function_017_T\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /jsbenchmark/completeness/single_app_tracing/function_call/anonymous_function_closure/closure_function_017_T\n AffectedNodeName: __taint_src\n 10: SOURCE: function closure_function_017_T(__taint_src) {\n /jsbenchmark/completeness/single_app_tracing/function_call/anonymous_function_closure/closure_function_017_T\n AffectedNodeName: Process\n 18: CALL: const p = new Process(__taint_src);\n /jsbenchmark/completeness/single_app_tracing/function_call/anonymous_function_closure/closure_function_017_T\n AffectedNodeName: data\n 11: ARG PASS: function Process(data) {\n /jsbenchmark/completeness/single_app_tracing/function_call/anonymous_function_closure/closure_function_017_T\n AffectedNodeName: [this.data]\n 12: Var Pass: this.data = data;\n /jsbenchmark/completeness/single_app_tracing/function_call/anonymous_function_closure/closure_function_017_T\n AffectedNodeName: p\n 18: Var Pass: const p = new Process(__taint_src);\n /jsbenchmark/completeness/single_app_tracing/function_call/anonymous_function_closure/closure_function_017_T\n AffectedNodeName: \n 19: CALL: p.show();\n /jsbenchmark/completeness/single_app_tracing/function_call/anonymous_function_closure/closure_function_017_T\n AffectedNodeName: p\n 19: ARG PASS: p.show();\n /jsbenchmark/completeness/single_app_tracing/function_call/anonymous_function_closure/closure_function_017_T\n AffectedNodeName: __taint_sink\n 14: SINK: __taint_sink(this.data);\n==========================================================\n #Total-findings:1\n==========================================================","/jsbenchmark/completeness/single_app_tracing/function_call/argument_passing/argument_passing_default_value_001_F":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/completeness/single_app_tracing/function_call/argument_passing/argument_passing_default_value_002_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/jsbenchmark/completeness/single_app_tracing/function_call/argument_passing/argument_passing_default_value_002_T\nLine 15: __taint_sink(input)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/jsbenchmark/completeness/single_app_tracing/function_call/argument_passing/argument_passing_default_value_002_T\",\"functionName\":\"argument_passing_default_value_002_T\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /jsbenchmark/completeness/single_app_tracing/function_call/argument_passing/argument_passing_default_value_002_T\n AffectedNodeName: __taint_src\n 11: SOURCE: function argument_passing_default_value_002_T(__taint_src) {\n /jsbenchmark/completeness/single_app_tracing/function_call/argument_passing/argument_passing_default_value_002_T\n AffectedNodeName: process\n 12: CALL: process(__taint_src);\n /jsbenchmark/completeness/single_app_tracing/function_call/argument_passing/argument_passing_default_value_002_T\n AffectedNodeName: __tmp1__\n 14: ARG PASS: function process(input = \"default_value\") {\n /jsbenchmark/completeness/single_app_tracing/function_call/argument_passing/argument_passing_default_value_002_T\n AffectedNodeName: input\n 14: Var Pass: function process(input = \"default_value\") {\n 15: Var Pass: __taint_sink(input);\n 16: Var Pass: }\n /jsbenchmark/completeness/single_app_tracing/function_call/argument_passing/argument_passing_default_value_002_T\n AffectedNodeName: __taint_sink\n 15: SINK: __taint_sink(input);\n==========================================================\n #Total-findings:1\n==========================================================","/jsbenchmark/completeness/single_app_tracing/function_call/argument_passing/argument_passing_normal_value_001_F":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/completeness/single_app_tracing/function_call/argument_passing/argument_passing_normal_value_002_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/jsbenchmark/completeness/single_app_tracing/function_call/argument_passing/argument_passing_normal_value_002_T\nLine 15: __taint_sink(arg)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/jsbenchmark/completeness/single_app_tracing/function_call/argument_passing/argument_passing_normal_value_002_T\",\"functionName\":\"argument_passing_normal_value_002_T\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /jsbenchmark/completeness/single_app_tracing/function_call/argument_passing/argument_passing_normal_value_002_T\n AffectedNodeName: __taint_src\n 11: SOURCE: function argument_passing_normal_value_002_T(__taint_src) {\n /jsbenchmark/completeness/single_app_tracing/function_call/argument_passing/argument_passing_normal_value_002_T\n AffectedNodeName: process\n 12: CALL: process(__taint_src);\n /jsbenchmark/completeness/single_app_tracing/function_call/argument_passing/argument_passing_normal_value_002_T\n AffectedNodeName: arg\n 14: ARG PASS: function process(arg) {\n /jsbenchmark/completeness/single_app_tracing/function_call/argument_passing/argument_passing_normal_value_002_T\n AffectedNodeName: __taint_sink\n 15: SINK: __taint_sink(arg);\n==========================================================\n #Total-findings:1\n==========================================================","/jsbenchmark/completeness/single_app_tracing/function_call/argument_passing/argument_passing_normal_value_003_F":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/completeness/single_app_tracing/function_call/argument_passing/argument_passing_normal_value_004_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/jsbenchmark/completeness/single_app_tracing/function_call/argument_passing/argument_passing_normal_value_004_T\nLine 15: __taint_sink(arg1)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/jsbenchmark/completeness/single_app_tracing/function_call/argument_passing/argument_passing_normal_value_004_T\",\"functionName\":\"argument_passing_normal_value_004_T\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /jsbenchmark/completeness/single_app_tracing/function_call/argument_passing/argument_passing_normal_value_004_T\n AffectedNodeName: __taint_src\n 11: SOURCE: function argument_passing_normal_value_004_T(__taint_src) {\n /jsbenchmark/completeness/single_app_tracing/function_call/argument_passing/argument_passing_normal_value_004_T\n AffectedNodeName: process\n 12: CALL: process(__taint_src, \"_\");\n /jsbenchmark/completeness/single_app_tracing/function_call/argument_passing/argument_passing_normal_value_004_T\n AffectedNodeName: arg1\n 14: ARG PASS: function process(arg1, arg2) {\n /jsbenchmark/completeness/single_app_tracing/function_call/argument_passing/argument_passing_normal_value_004_T\n AffectedNodeName: __taint_sink\n 15: SINK: __taint_sink(arg1);\n==========================================================\n #Total-findings:1\n==========================================================","/jsbenchmark/completeness/single_app_tracing/function_call/argument_passing/argument_passing_normal_value_005_F":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/completeness/single_app_tracing/function_call/argument_passing/argument_passing_normal_value_006_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/jsbenchmark/completeness/single_app_tracing/function_call/argument_passing/argument_passing_normal_value_006_T\nLine 13: __taint_sink(innerInput)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/jsbenchmark/completeness/single_app_tracing/function_call/argument_passing/argument_passing_normal_value_006_T\",\"functionName\":\"argument_passing_normal_value_006_T\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /jsbenchmark/completeness/single_app_tracing/function_call/argument_passing/argument_passing_normal_value_006_T\n AffectedNodeName: __taint_src\n 10: SOURCE: function argument_passing_normal_value_006_T(__taint_src) {\n /jsbenchmark/completeness/single_app_tracing/function_call/argument_passing/argument_passing_normal_value_006_T\n AffectedNodeName: outer\n 19: CALL: outer(__taint_src);\n /jsbenchmark/completeness/single_app_tracing/function_call/argument_passing/argument_passing_normal_value_006_T\n AffectedNodeName: input\n 11: ARG PASS: function outer(input) {\n /jsbenchmark/completeness/single_app_tracing/function_call/argument_passing/argument_passing_normal_value_006_T\n AffectedNodeName: inner\n 16: CALL: inner(input);\n /jsbenchmark/completeness/single_app_tracing/function_call/argument_passing/argument_passing_normal_value_006_T\n AffectedNodeName: innerInput\n 12: ARG PASS: function inner(innerInput) {\n /jsbenchmark/completeness/single_app_tracing/function_call/argument_passing/argument_passing_normal_value_006_T\n AffectedNodeName: __taint_sink\n 13: SINK: __taint_sink(innerInput);\n==========================================================\n #Total-findings:1\n==========================================================","/jsbenchmark/completeness/single_app_tracing/function_call/argument_passing/argument_passing_reference_001_F":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/completeness/single_app_tracing/function_call/argument_passing/argument_passing_reference_002_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/jsbenchmark/completeness/single_app_tracing/function_call/argument_passing/argument_passing_reference_002_T\nLine 14: __taint_sink(obj.data)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/jsbenchmark/completeness/single_app_tracing/function_call/argument_passing/argument_passing_reference_002_T\",\"functionName\":\"argument_passing_reference_002_T\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /jsbenchmark/completeness/single_app_tracing/function_call/argument_passing/argument_passing_reference_002_T\n AffectedNodeName: __taint_src\n 11: SOURCE: function argument_passing_reference_002_T(__taint_src) {\n /jsbenchmark/completeness/single_app_tracing/function_call/argument_passing/argument_passing_reference_002_T\n AffectedNodeName: [obj.data]\n 17: Var Pass: obj.data = __taint_src;\n /jsbenchmark/completeness/single_app_tracing/function_call/argument_passing/argument_passing_reference_002_T\n AffectedNodeName: __taint_sink\n 14: SINK: __taint_sink(obj.data);\n==========================================================\n #Total-findings:1\n==========================================================","/jsbenchmark/completeness/single_app_tracing/function_call/argument_passing/argument_passing_reference_003_F":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/completeness/single_app_tracing/function_call/argument_passing/argument_passing_reference_004_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/jsbenchmark/completeness/single_app_tracing/function_call/argument_passing/argument_passing_reference_004_T\nLine 14: __taint_sink(arr)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/jsbenchmark/completeness/single_app_tracing/function_call/argument_passing/argument_passing_reference_004_T\",\"functionName\":\"argument_passing_reference_004_T\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /jsbenchmark/completeness/single_app_tracing/function_call/argument_passing/argument_passing_reference_004_T\n AffectedNodeName: __taint_src\n 11: SOURCE: function argument_passing_reference_004_T(__taint_src) {\n /jsbenchmark/completeness/single_app_tracing/function_call/argument_passing/argument_passing_reference_004_T\n AffectedNodeName: inputArr[0]\n 17: Var Pass: inputArr[0] = __taint_src;\n /jsbenchmark/completeness/single_app_tracing/function_call/argument_passing/argument_passing_reference_004_T\n AffectedNodeName: __taint_sink\n 14: SINK: __taint_sink(arr);\n==========================================================\n #Total-findings:1\n==========================================================","/jsbenchmark/completeness/single_app_tracing/function_call/argument_passing/argument_passing_reference_005_F":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/completeness/single_app_tracing/function_call/argument_passing/argument_passing_reference_006_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/jsbenchmark/completeness/single_app_tracing/function_call/argument_passing/argument_passing_reference_006_T\nLine 16: __taint_sink(objB.name)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/jsbenchmark/completeness/single_app_tracing/function_call/argument_passing/argument_passing_reference_006_T\",\"functionName\":\"argument_passing_reference_006_T\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /jsbenchmark/completeness/single_app_tracing/function_call/argument_passing/argument_passing_reference_006_T\n AffectedNodeName: __taint_src\n 11: SOURCE: function argument_passing_reference_006_T(__taint_src) {\n /jsbenchmark/completeness/single_app_tracing/function_call/argument_passing/argument_passing_reference_006_T\n AffectedNodeName: objA\n 12: Var Pass: const objA = { name: __taint_src };\n /jsbenchmark/completeness/single_app_tracing/function_call/argument_passing/argument_passing_reference_006_T\n AffectedNodeName: swap\n 15: CALL: swap(objA, objB);\n /jsbenchmark/completeness/single_app_tracing/function_call/argument_passing/argument_passing_reference_006_T\n AffectedNodeName: obj1\n 18: ARG PASS: function swap(obj1, obj2) {\n /jsbenchmark/completeness/single_app_tracing/function_call/argument_passing/argument_passing_reference_006_T\n AffectedNodeName: temp\n 19: Var Pass: const temp = obj1.name;\n /jsbenchmark/completeness/single_app_tracing/function_call/argument_passing/argument_passing_reference_006_T\n AffectedNodeName: [obj2.name]\n 21: Var Pass: obj2.name = temp;\n /jsbenchmark/completeness/single_app_tracing/function_call/argument_passing/argument_passing_reference_006_T\n AffectedNodeName: __taint_sink\n 16: SINK: __taint_sink(objB.name);\n==========================================================\n #Total-findings:1\n==========================================================","/jsbenchmark/completeness/single_app_tracing/function_call/arrow_function/arrow_function_001_F":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/completeness/single_app_tracing/function_call/arrow_function/arrow_function_002_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/jsbenchmark/completeness/single_app_tracing/function_call/arrow_function/arrow_function_002_T\nLine 12: __taint_sink(__taint_src)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/jsbenchmark/completeness/single_app_tracing/function_call/arrow_function/arrow_function_002_T\",\"functionName\":\"arrow_function_002_T\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /jsbenchmark/completeness/single_app_tracing/function_call/arrow_function/arrow_function_002_T\n AffectedNodeName: __taint_src\n 11: SOURCE: function arrow_function_002_T(__taint_src) {\n /jsbenchmark/completeness/single_app_tracing/function_call/arrow_function/arrow_function_002_T\n AffectedNodeName: __taint_sink\n 12: SINK: let arrowFunction = () => __taint_sink(__taint_src);\n==========================================================\n #Total-findings:1\n==========================================================","/jsbenchmark/completeness/single_app_tracing/function_call/arrow_function/arrow_function_003_F":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/completeness/single_app_tracing/function_call/arrow_function/arrow_function_004_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/jsbenchmark/completeness/single_app_tracing/function_call/arrow_function/arrow_function_004_T\nLine 14: __taint_sink(__taint_src)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/jsbenchmark/completeness/single_app_tracing/function_call/arrow_function/arrow_function_004_T\",\"functionName\":\"arrow_function_004_T\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /jsbenchmark/completeness/single_app_tracing/function_call/arrow_function/arrow_function_004_T\n AffectedNodeName: __taint_src\n 11: SOURCE: function arrow_function_004_T(__taint_src) {\n /jsbenchmark/completeness/single_app_tracing/function_call/arrow_function/arrow_function_004_T\n AffectedNodeName: __taint_sink\n 14: SINK: __taint_sink(__taint_src);\n==========================================================\n #Total-findings:1\n==========================================================","/jsbenchmark/completeness/single_app_tracing/function_call/arrow_function/arrow_function_005_F":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/completeness/single_app_tracing/function_call/arrow_function/arrow_function_006_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/jsbenchmark/completeness/single_app_tracing/function_call/arrow_function/arrow_function_006_T\nLine 15: __taint_sink(self.name)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/jsbenchmark/completeness/single_app_tracing/function_call/arrow_function/arrow_function_006_T\",\"functionName\":\"arrow_function_006_T\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /jsbenchmark/completeness/single_app_tracing/function_call/arrow_function/arrow_function_006_T\n AffectedNodeName: __taint_src\n 11: SOURCE: function arrow_function_006_T(__taint_src) {\n /jsbenchmark/completeness/single_app_tracing/function_call/arrow_function/arrow_function_006_T\n AffectedNodeName: [this.name]\n 12: Var Pass: this.name = __taint_src;\n /jsbenchmark/completeness/single_app_tracing/function_call/arrow_function/arrow_function_006_T\n AffectedNodeName: __taint_sink\n 15: SINK: show: () => __taint_sink(self.name),\n==========================================================\n #Total-findings:1\n==========================================================","/jsbenchmark/completeness/single_app_tracing/function_call/arrow_function/arrow_function_007_F":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/completeness/single_app_tracing/function_call/arrow_function/arrow_function_008_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/jsbenchmark/completeness/single_app_tracing/function_call/arrow_function/arrow_function_008_T\nLine 16: __taint_sink(self.name)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/jsbenchmark/completeness/single_app_tracing/function_call/arrow_function/arrow_function_008_T\",\"functionName\":\"arrow_function_008_T\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /jsbenchmark/completeness/single_app_tracing/function_call/arrow_function/arrow_function_008_T\n AffectedNodeName: __taint_src\n 11: SOURCE: function arrow_function_008_T(__taint_src) {\n /jsbenchmark/completeness/single_app_tracing/function_call/arrow_function/arrow_function_008_T\n AffectedNodeName: [this.name]\n 12: Var Pass: this.name = __taint_src;\n /jsbenchmark/completeness/single_app_tracing/function_call/arrow_function/arrow_function_008_T\n AffectedNodeName: __taint_sink\n 16: SINK: return () => __taint_sink(self.name);\n==========================================================\n #Total-findings:1\n==========================================================","/jsbenchmark/completeness/single_app_tracing/function_call/arrow_function/arrow_function_009_F":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/completeness/single_app_tracing/function_call/arrow_function/arrow_function_010_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/jsbenchmark/completeness/single_app_tracing/function_call/arrow_function/arrow_function_010_T\nLine 14: __taint_sink(this.data)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/jsbenchmark/completeness/single_app_tracing/function_call/arrow_function/arrow_function_010_T\",\"functionName\":\"arrow_function_010_T\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /jsbenchmark/completeness/single_app_tracing/function_call/arrow_function/arrow_function_010_T\n AffectedNodeName: __taint_src\n 11: SOURCE: function arrow_function_010_T(__taint_src) {\n /jsbenchmark/completeness/single_app_tracing/function_call/arrow_function/arrow_function_010_T\n AffectedNodeName: Process\n 17: CALL: const p = new Process(__taint_src);\n /jsbenchmark/completeness/single_app_tracing/function_call/arrow_function/arrow_function_010_T\n AffectedNodeName: data\n 12: ARG PASS: function Process(data) {\n /jsbenchmark/completeness/single_app_tracing/function_call/arrow_function/arrow_function_010_T\n AffectedNodeName: [this.data]\n 13: Var Pass: this.data = data;\n /jsbenchmark/completeness/single_app_tracing/function_call/arrow_function/arrow_function_010_T\n AffectedNodeName: p\n 17: Var Pass: const p = new Process(__taint_src);\n /jsbenchmark/completeness/single_app_tracing/function_call/arrow_function/arrow_function_010_T\n AffectedNodeName: \n 18: CALL: p.show();\n /jsbenchmark/completeness/single_app_tracing/function_call/arrow_function/arrow_function_010_T\n AffectedNodeName: p\n 18: ARG PASS: p.show();\n /jsbenchmark/completeness/single_app_tracing/function_call/arrow_function/arrow_function_010_T\n AffectedNodeName: __taint_sink\n 14: SINK: this.show = () => __taint_sink(this.data);\n==========================================================\n #Total-findings:1\n==========================================================","/jsbenchmark/completeness/single_app_tracing/function_call/chained_call/chained_call_001_F":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/completeness/single_app_tracing/function_call/chained_call/chained_call_002_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/jsbenchmark/completeness/single_app_tracing/function_call/chained_call/chained_call_002_T\nLine 28: __taint_sink(this.name)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/jsbenchmark/completeness/single_app_tracing/function_call/chained_call/chained_call_002_T\",\"functionName\":\"chained_call_002_T\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /jsbenchmark/completeness/single_app_tracing/function_call/chained_call/chained_call_002_T\n AffectedNodeName: __taint_src\n 11: SOURCE: function chained_call_002_T(__taint_src) {\n /jsbenchmark/completeness/single_app_tracing/function_call/chained_call/chained_call_002_T\n AffectedNodeName: setName\n 32: CALL: new A().setName(\"_\").clearName().setName(__taint_src).process();\n /jsbenchmark/completeness/single_app_tracing/function_call/chained_call/chained_call_002_T\n AffectedNodeName: name\n 17: ARG PASS: setName(name) {\n /jsbenchmark/completeness/single_app_tracing/function_call/chained_call/chained_call_002_T\n AffectedNodeName: [this.name]\n 18: Var Pass: this.name = name;\n /jsbenchmark/completeness/single_app_tracing/function_call/chained_call/chained_call_002_T\n AffectedNodeName: [return value]\n 19: Return Value: return this;\n /jsbenchmark/completeness/single_app_tracing/function_call/chained_call/chained_call_002_T\n AffectedNodeName: setName\n 32: CALL RETURN: new A().setName(\"_\").clearName().setName(__taint_src).process();\n /jsbenchmark/completeness/single_app_tracing/function_call/chained_call/chained_call_002_T\n 32: ARG PASS: new A().setName(\"_\").clearName().setName(__taint_src).process();\n /jsbenchmark/completeness/single_app_tracing/function_call/chained_call/chained_call_002_T\n AffectedNodeName: __taint_sink\n 28: SINK: __taint_sink(this.name);\n==========================================================\n #Total-findings:1\n==========================================================","/jsbenchmark/completeness/single_app_tracing/function_call/decorator_function/class_decorator_001_F":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/completeness/single_app_tracing/function_call/decorator_function/class_decorator_002_T":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/completeness/single_app_tracing/function_call/decorator_function/class_decorator_003_F":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/completeness/single_app_tracing/function_call/decorator_function/class_decorator_004_T":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/completeness/single_app_tracing/function_call/decorator_function/class_member_decorator_001_F":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/completeness/single_app_tracing/function_call/decorator_function/class_member_decorator_002_T":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/completeness/single_app_tracing/function_call/decorator_function/function_decorator_001_F":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/completeness/single_app_tracing/function_call/decorator_function/function_decorator_002_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/jsbenchmark/completeness/single_app_tracing/function_call/decorator_function/function_decorator_002_T\nLine 14: __taint_sink(args)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/jsbenchmark/completeness/single_app_tracing/function_call/decorator_function/function_decorator_002_T\",\"functionName\":\"function_decorator_002_T\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /jsbenchmark/completeness/single_app_tracing/function_call/decorator_function/function_decorator_002_T\n AffectedNodeName: __taint_src\n 11: SOURCE: function function_decorator_002_T(__taint_src) {\n /jsbenchmark/completeness/single_app_tracing/function_call/decorator_function/function_decorator_002_T\n AffectedNodeName: \n 20: CALL: decoratedFunction(__taint_src);\n /jsbenchmark/completeness/single_app_tracing/function_call/decorator_function/function_decorator_002_T\n AffectedNodeName: __tmp1__\n 13: ARG PASS: return function (...args) {\n /jsbenchmark/completeness/single_app_tracing/function_call/decorator_function/function_decorator_002_T\n AffectedNodeName: args\n 13: Var Pass: return function (...args) {\n 14: Var Pass: __taint_sink(args);\n 15: Var Pass: return targetFunction.apply(this, args);\n 16: Var Pass: };\n /jsbenchmark/completeness/single_app_tracing/function_call/decorator_function/function_decorator_002_T\n AffectedNodeName: __taint_sink\n 14: SINK: __taint_sink(args);\n==========================================================\n #Total-findings:1\n==========================================================","/jsbenchmark/completeness/single_app_tracing/function_call/decorator_function/function_decorator_003_F":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/completeness/single_app_tracing/function_call/decorator_function/function_decorator_004_T":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/completeness/single_app_tracing/function_call/generator_function/generator_function_001_F":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/completeness/single_app_tracing/function_call/generator_function/generator_function_002_T":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/completeness/single_app_tracing/function_call/generator_function/generator_function_003_F":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/completeness/single_app_tracing/function_call/generator_function/generator_function_004_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/jsbenchmark/completeness/single_app_tracing/function_call/generator_function/generator_function_004_T\nLine 21: __taint_sink(g.next(__taint_src).value)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/jsbenchmark/completeness/single_app_tracing/function_call/generator_function/generator_function_004_T\",\"functionName\":\"generator_function_004_T\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /jsbenchmark/completeness/single_app_tracing/function_call/generator_function/generator_function_004_T\n AffectedNodeName: __taint_src\n 11: SOURCE: function generator_function_004_T(__taint_src) {\n /jsbenchmark/completeness/single_app_tracing/function_call/generator_function/generator_function_004_T\n AffectedNodeName: __taint_sink\n 21: SINK: __taint_sink(g.next(__taint_src).value);\n==========================================================\n #Total-findings:1\n==========================================================","/jsbenchmark/completeness/single_app_tracing/function_call/higher_order_function/higher_order_function_001_F":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/completeness/single_app_tracing/function_call/higher_order_function/higher_order_function_002_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/jsbenchmark/completeness/single_app_tracing/function_call/higher_order_function/higher_order_function_002_T\nLine 19: __taint_sink(f(__taint_src, _)())\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/jsbenchmark/completeness/single_app_tracing/function_call/higher_order_function/higher_order_function_002_T\",\"functionName\":\"higher_order_function_002_T\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /jsbenchmark/completeness/single_app_tracing/function_call/higher_order_function/higher_order_function_002_T\n AffectedNodeName: __taint_src\n 11: SOURCE: function higher_order_function_002_T(__taint_src) {\n /jsbenchmark/completeness/single_app_tracing/function_call/higher_order_function/higher_order_function_002_T\n AffectedNodeName: f\n 19: CALL: __taint_sink(f(__taint_src, \"_\")());\n /jsbenchmark/completeness/single_app_tracing/function_call/higher_order_function/higher_order_function_002_T\n AffectedNodeName: a\n 12: ARG PASS: function f(a, b) {\n /jsbenchmark/completeness/single_app_tracing/function_call/higher_order_function/higher_order_function_002_T\n AffectedNodeName: [return value]\n 15: Return Value: return a + b + c;\n /jsbenchmark/completeness/single_app_tracing/function_call/higher_order_function/higher_order_function_002_T\n AffectedNodeName: \n 19: CALL RETURN: __taint_sink(f(__taint_src, \"_\")());\n /jsbenchmark/completeness/single_app_tracing/function_call/higher_order_function/higher_order_function_002_T\n AffectedNodeName: __taint_sink\n 19: SINK: __taint_sink(f(__taint_src, \"_\")());\n==========================================================\n #Total-findings:1\n==========================================================","/jsbenchmark/completeness/single_app_tracing/function_call/higher_order_function/higher_order_function_003_F":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/completeness/single_app_tracing/function_call/higher_order_function/higher_order_function_004_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/jsbenchmark/completeness/single_app_tracing/function_call/higher_order_function/higher_order_function_004_T\nLine 23: __taint_sink(f(g, __taint_src, _)())\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/jsbenchmark/completeness/single_app_tracing/function_call/higher_order_function/higher_order_function_004_T\",\"functionName\":\"higher_order_function_004_T\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /jsbenchmark/completeness/single_app_tracing/function_call/higher_order_function/higher_order_function_004_T\n AffectedNodeName: __taint_src\n 11: SOURCE: function higher_order_function_004_T(__taint_src) {\n /jsbenchmark/completeness/single_app_tracing/function_call/higher_order_function/higher_order_function_004_T\n AffectedNodeName: f\n 23: CALL: __taint_sink(f(g, __taint_src, \"_\")());\n /jsbenchmark/completeness/single_app_tracing/function_call/higher_order_function/higher_order_function_004_T\n AffectedNodeName: a\n 12: ARG PASS: function f(g, a, b) {\n /jsbenchmark/completeness/single_app_tracing/function_call/higher_order_function/higher_order_function_004_T\n AffectedNodeName: g\n 13: CALL: return g(a, b);\n /jsbenchmark/completeness/single_app_tracing/function_call/higher_order_function/higher_order_function_004_T\n AffectedNodeName: a\n 16: ARG PASS: function g(a, b) {\n /jsbenchmark/completeness/single_app_tracing/function_call/higher_order_function/higher_order_function_004_T\n AffectedNodeName: [return value]\n 19: Return Value: return a + b + c;\n /jsbenchmark/completeness/single_app_tracing/function_call/higher_order_function/higher_order_function_004_T\n AffectedNodeName: \n 23: CALL RETURN: __taint_sink(f(g, __taint_src, \"_\")());\n /jsbenchmark/completeness/single_app_tracing/function_call/higher_order_function/higher_order_function_004_T\n AffectedNodeName: __taint_sink\n 23: SINK: __taint_sink(f(g, __taint_src, \"_\")());\n==========================================================\n #Total-findings:1\n==========================================================","/jsbenchmark/completeness/single_app_tracing/function_call/higher_order_function/higher_order_function_005_F":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/completeness/single_app_tracing/function_call/higher_order_function/higher_order_function_006_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/jsbenchmark/completeness/single_app_tracing/function_call/higher_order_function/higher_order_function_006_T\nLine 27: __taint_sink(f(g, u, __taint_src, _)())\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/jsbenchmark/completeness/single_app_tracing/function_call/higher_order_function/higher_order_function_006_T\",\"functionName\":\"higher_order_function_006_T\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /jsbenchmark/completeness/single_app_tracing/function_call/higher_order_function/higher_order_function_006_T\n AffectedNodeName: __taint_src\n 11: SOURCE: function higher_order_function_006_T(__taint_src) {\n /jsbenchmark/completeness/single_app_tracing/function_call/higher_order_function/higher_order_function_006_T\n AffectedNodeName: f\n 27: CALL: __taint_sink(f(g, u, __taint_src, \"_\")());\n /jsbenchmark/completeness/single_app_tracing/function_call/higher_order_function/higher_order_function_006_T\n AffectedNodeName: a\n 12: ARG PASS: function f(g, u, a, b) {\n /jsbenchmark/completeness/single_app_tracing/function_call/higher_order_function/higher_order_function_006_T\n AffectedNodeName: g\n 13: CALL: return g(u, a, b);\n /jsbenchmark/completeness/single_app_tracing/function_call/higher_order_function/higher_order_function_006_T\n AffectedNodeName: a\n 16: ARG PASS: function g(u, a, b) {\n /jsbenchmark/completeness/single_app_tracing/function_call/higher_order_function/higher_order_function_006_T\n AffectedNodeName: u\n 18: CALL: return u(a, b, c);\n /jsbenchmark/completeness/single_app_tracing/function_call/higher_order_function/higher_order_function_006_T\n AffectedNodeName: a\n 21: ARG PASS: function u(a, b, c) {\n /jsbenchmark/completeness/single_app_tracing/function_call/higher_order_function/higher_order_function_006_T\n AffectedNodeName: [return value]\n 23: Return Value: return a + b + c;\n /jsbenchmark/completeness/single_app_tracing/function_call/higher_order_function/higher_order_function_006_T\n AffectedNodeName: \n 27: CALL RETURN: __taint_sink(f(g, u, __taint_src, \"_\")());\n /jsbenchmark/completeness/single_app_tracing/function_call/higher_order_function/higher_order_function_006_T\n AffectedNodeName: __taint_sink\n 27: SINK: __taint_sink(f(g, u, __taint_src, \"_\")());\n==========================================================\n #Total-findings:1\n==========================================================","/jsbenchmark/completeness/single_app_tracing/function_call/higher_order_function/higher_order_function_007_F":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/completeness/single_app_tracing/function_call/higher_order_function/higher_order_function_008_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/jsbenchmark/completeness/single_app_tracing/function_call/higher_order_function/higher_order_function_008_T\nLine 17: __taint_sink(result)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/jsbenchmark/completeness/single_app_tracing/function_call/higher_order_function/higher_order_function_008_T\",\"functionName\":\"higher_order_function_008_T\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /jsbenchmark/completeness/single_app_tracing/function_call/higher_order_function/higher_order_function_008_T\n AffectedNodeName: __taint_src\n 11: SOURCE: function higher_order_function_008_T(__taint_src) {\n /jsbenchmark/completeness/single_app_tracing/function_call/higher_order_function/higher_order_function_008_T\n AffectedNodeName: \n 13: CALL: return callback(__taint_src, \"_\");\n /jsbenchmark/completeness/single_app_tracing/function_call/higher_order_function/higher_order_function_008_T\n AffectedNodeName: a\n 16: ARG PASS: const result = higherOrderFunction((a, b) => a + b);\n /jsbenchmark/completeness/single_app_tracing/function_call/higher_order_function/higher_order_function_008_T\n AffectedNodeName: [return value]\n 16: Return Value: const result = higherOrderFunction((a, b) => a + b);\n /jsbenchmark/completeness/single_app_tracing/function_call/higher_order_function/higher_order_function_008_T\n AffectedNodeName: \n 13: CALL RETURN: return callback(__taint_src, \"_\");\n /jsbenchmark/completeness/single_app_tracing/function_call/higher_order_function/higher_order_function_008_T\n AffectedNodeName: [return value]\n 13: Return Value: return callback(__taint_src, \"_\");\n /jsbenchmark/completeness/single_app_tracing/function_call/higher_order_function/higher_order_function_008_T\n AffectedNodeName: higherOrderFunction\n 16: CALL RETURN: const result = higherOrderFunction((a, b) => a + b);\n /jsbenchmark/completeness/single_app_tracing/function_call/higher_order_function/higher_order_function_008_T\n AffectedNodeName: result\n 16: Var Pass: const result = higherOrderFunction((a, b) => a + b);\n /jsbenchmark/completeness/single_app_tracing/function_call/higher_order_function/higher_order_function_008_T\n AffectedNodeName: __taint_sink\n 17: SINK: __taint_sink(result);\n==========================================================\n #Total-findings:1\n==========================================================","/jsbenchmark/completeness/single_app_tracing/function_call/higher_order_function/higher_order_function_009_F":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/completeness/single_app_tracing/function_call/higher_order_function/higher_order_function_010_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/jsbenchmark/completeness/single_app_tracing/function_call/higher_order_function/higher_order_function_010_T\nLine 19: __taint_sink(result)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/jsbenchmark/completeness/single_app_tracing/function_call/higher_order_function/higher_order_function_010_T\",\"functionName\":\"higher_order_function_010_T\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /jsbenchmark/completeness/single_app_tracing/function_call/higher_order_function/higher_order_function_010_T\n AffectedNodeName: __taint_src\n 11: SOURCE: function higher_order_function_010_T(__taint_src) {\n /jsbenchmark/completeness/single_app_tracing/function_call/higher_order_function/higher_order_function_010_T\n AffectedNodeName: \n 13: CALL: return callback(__taint_src, \"_\");\n /jsbenchmark/completeness/single_app_tracing/function_call/higher_order_function/higher_order_function_010_T\n AffectedNodeName: a\n 16: ARG PASS: const result = higherOrderFunction(function (a, b) {\n /jsbenchmark/completeness/single_app_tracing/function_call/higher_order_function/higher_order_function_010_T\n AffectedNodeName: [return value]\n 17: Return Value: return a + b;\n /jsbenchmark/completeness/single_app_tracing/function_call/higher_order_function/higher_order_function_010_T\n AffectedNodeName: \n 13: CALL RETURN: return callback(__taint_src, \"_\");\n /jsbenchmark/completeness/single_app_tracing/function_call/higher_order_function/higher_order_function_010_T\n AffectedNodeName: [return value]\n 13: Return Value: return callback(__taint_src, \"_\");\n /jsbenchmark/completeness/single_app_tracing/function_call/higher_order_function/higher_order_function_010_T\n AffectedNodeName: higherOrderFunction\n 16: CALL RETURN: const result = higherOrderFunction(function (a, b) {\n 17: CALL RETURN: return a + b;\n 18: CALL RETURN: });\n /jsbenchmark/completeness/single_app_tracing/function_call/higher_order_function/higher_order_function_010_T\n AffectedNodeName: result\n 16: Var Pass: const result = higherOrderFunction(function (a, b) {\n 17: Var Pass: return a + b;\n 18: Var Pass: });\n /jsbenchmark/completeness/single_app_tracing/function_call/higher_order_function/higher_order_function_010_T\n AffectedNodeName: __taint_sink\n 19: SINK: __taint_sink(result);\n==========================================================\n #Total-findings:1\n==========================================================","/jsbenchmark/completeness/single_app_tracing/function_call/library_function/json_001_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/jsbenchmark/completeness/single_app_tracing/function_call/library_function/json_001_T\nLine 15: __taint_sink(obj)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/jsbenchmark/completeness/single_app_tracing/function_call/library_function/json_001_T\",\"functionName\":\"json_001_T\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /jsbenchmark/completeness/single_app_tracing/function_call/library_function/json_001_T\n AffectedNodeName: __taint_src\n 10: SOURCE: function json_001_T(__taint_src) {\n /jsbenchmark/completeness/single_app_tracing/function_call/library_function/json_001_T\n AffectedNodeName: process\n 11: CALL: process(JSON.stringify(__taint_src));\n /jsbenchmark/completeness/single_app_tracing/function_call/library_function/json_001_T\n AffectedNodeName: arg\n 13: ARG PASS: function process(arg) {\n /jsbenchmark/completeness/single_app_tracing/function_call/library_function/json_001_T\n AffectedNodeName: obj\n 14: Var Pass: let obj = JSON.parse(arg);\n /jsbenchmark/completeness/single_app_tracing/function_call/library_function/json_001_T\n AffectedNodeName: __taint_sink\n 15: SINK: __taint_sink(obj);\n==========================================================\n #Total-findings:1\n==========================================================","/jsbenchmark/completeness/single_app_tracing/function_call/library_function/json_002_F":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/completeness/single_app_tracing/function_call/library_function/string_001_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/jsbenchmark/completeness/single_app_tracing/function_call/library_function/string_001_T\nLine 15: __taint_sink(result)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/jsbenchmark/completeness/single_app_tracing/function_call/library_function/string_001_T\",\"functionName\":\"string_001_T\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /jsbenchmark/completeness/single_app_tracing/function_call/library_function/string_001_T\n AffectedNodeName: __taint_src\n 10: SOURCE: function string_001_T(__taint_src) {\n /jsbenchmark/completeness/single_app_tracing/function_call/library_function/string_001_T\n AffectedNodeName: process\n 11: CALL: process(__taint_src);\n /jsbenchmark/completeness/single_app_tracing/function_call/library_function/string_001_T\n AffectedNodeName: arg\n 13: ARG PASS: function process(arg) {\n /jsbenchmark/completeness/single_app_tracing/function_call/library_function/string_001_T\n AffectedNodeName: result\n 14: Var Pass: let result = arg.trim();\n /jsbenchmark/completeness/single_app_tracing/function_call/library_function/string_001_T\n AffectedNodeName: __taint_sink\n 15: SINK: __taint_sink(result);\n==========================================================\n #Total-findings:1\n==========================================================","/jsbenchmark/completeness/single_app_tracing/function_call/library_function/string_002_F":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/completeness/single_app_tracing/function_call/override/constructor_extends_001_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/jsbenchmark/completeness/single_app_tracing/function_call/override/constructor_extends_001_T\nLine 31: __taint_sink(this.getData())\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/jsbenchmark/completeness/single_app_tracing/function_call/override/constructor_extends_001_T\",\"functionName\":\"constructor_extends_001_T\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /jsbenchmark/completeness/single_app_tracing/function_call/override/constructor_extends_001_T\n AffectedNodeName: __taint_src\n 10: SOURCE: function constructor_extends_001_T(__taint_src) {\n /jsbenchmark/completeness/single_app_tracing/function_call/override/constructor_extends_001_T\n AffectedNodeName: constructor\n 35: CALL: const derived = new DerivedClass(__taint_src);\n /jsbenchmark/completeness/single_app_tracing/function_call/override/constructor_extends_001_T\n AffectedNodeName: data\n 26: ARG PASS: constructor(data) {\n /jsbenchmark/completeness/single_app_tracing/function_call/override/constructor_extends_001_T\n AffectedNodeName: constructor\n 27: CALL: super(data);\n /jsbenchmark/completeness/single_app_tracing/function_call/override/constructor_extends_001_T\n AffectedNodeName: data\n 14: ARG PASS: constructor(data) {\n /jsbenchmark/completeness/single_app_tracing/function_call/override/constructor_extends_001_T\n AffectedNodeName: [this.data]\n 15: Var Pass: this.data = data;\n /jsbenchmark/completeness/single_app_tracing/function_call/override/constructor_extends_001_T\n AffectedNodeName: derived\n 35: Var Pass: const derived = new DerivedClass(__taint_src);\n /jsbenchmark/completeness/single_app_tracing/function_call/override/constructor_extends_001_T\n AffectedNodeName: process\n 36: CALL: derived.process();\n /jsbenchmark/completeness/single_app_tracing/function_call/override/constructor_extends_001_T\n AffectedNodeName: derived\n 36: ARG PASS: derived.process();\n /jsbenchmark/completeness/single_app_tracing/function_call/override/constructor_extends_001_T\n AffectedNodeName: getData\n 31: CALL: __taint_sink(this.getData());\n /jsbenchmark/completeness/single_app_tracing/function_call/override/constructor_extends_001_T\n 31: ARG PASS: __taint_sink(this.getData());\n /jsbenchmark/completeness/single_app_tracing/function_call/override/constructor_extends_001_T\n AffectedNodeName: [return value]\n 19: Return Value: return this.data;\n /jsbenchmark/completeness/single_app_tracing/function_call/override/constructor_extends_001_T\n AffectedNodeName: getData\n 31: CALL RETURN: __taint_sink(this.getData());\n /jsbenchmark/completeness/single_app_tracing/function_call/override/constructor_extends_001_T\n AffectedNodeName: __taint_sink\n 31: SINK: __taint_sink(this.getData());\n==========================================================\n #Total-findings:1\n==========================================================","/jsbenchmark/completeness/single_app_tracing/function_call/override/constructor_extends_002_F":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/completeness/single_app_tracing/function_call/override/constructor_extends_003_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/jsbenchmark/completeness/single_app_tracing/function_call/override/constructor_extends_003_T\nLine 29: __taint_sink(this.getData())\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/jsbenchmark/completeness/single_app_tracing/function_call/override/constructor_extends_003_T\",\"functionName\":\"constructor_extends_003_T\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /jsbenchmark/completeness/single_app_tracing/function_call/override/constructor_extends_003_T\n AffectedNodeName: __taint_src\n 10: SOURCE: function constructor_extends_003_T(__taint_src) {\n /jsbenchmark/completeness/single_app_tracing/function_call/override/constructor_extends_003_T\n AffectedNodeName: [this.data]\n 13: Var Pass: this.data = __taint_src;\n /jsbenchmark/completeness/single_app_tracing/function_call/override/constructor_extends_003_T\n AffectedNodeName: derived\n 33: Var Pass: const derived = new DerivedClass();\n /jsbenchmark/completeness/single_app_tracing/function_call/override/constructor_extends_003_T\n AffectedNodeName: process\n 34: CALL: derived.process();\n /jsbenchmark/completeness/single_app_tracing/function_call/override/constructor_extends_003_T\n AffectedNodeName: derived\n 34: ARG PASS: derived.process();\n /jsbenchmark/completeness/single_app_tracing/function_call/override/constructor_extends_003_T\n AffectedNodeName: getData\n 29: CALL: __taint_sink(this.getData());\n /jsbenchmark/completeness/single_app_tracing/function_call/override/constructor_extends_003_T\n 29: ARG PASS: __taint_sink(this.getData());\n /jsbenchmark/completeness/single_app_tracing/function_call/override/constructor_extends_003_T\n AffectedNodeName: [return value]\n 17: Return Value: return this.data;\n /jsbenchmark/completeness/single_app_tracing/function_call/override/constructor_extends_003_T\n AffectedNodeName: getData\n 29: CALL RETURN: __taint_sink(this.getData());\n /jsbenchmark/completeness/single_app_tracing/function_call/override/constructor_extends_003_T\n AffectedNodeName: __taint_sink\n 29: SINK: __taint_sink(this.getData());\n==========================================================\n #Total-findings:1\n==========================================================","/jsbenchmark/completeness/single_app_tracing/function_call/override/constructor_extends_004_F":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/completeness/single_app_tracing/function_call/override/polymorphism_override_001_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/jsbenchmark/completeness/single_app_tracing/function_call/override/polymorphism_override_001_T\nLine 26: __taint_sink(sub.call())\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/jsbenchmark/completeness/single_app_tracing/function_call/override/polymorphism_override_001_T\",\"functionName\":\"polymorphism_override_001_T\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /jsbenchmark/completeness/single_app_tracing/function_call/override/polymorphism_override_001_T\n AffectedNodeName: __taint_src\n 10: SOURCE: function polymorphism_override_001_T(__taint_src) {\n /jsbenchmark/completeness/single_app_tracing/function_call/override/polymorphism_override_001_T\n AffectedNodeName: [return value]\n 15: Return Value: return __taint_src;\n /jsbenchmark/completeness/single_app_tracing/function_call/override/polymorphism_override_001_T\n AffectedNodeName: call\n 26: CALL RETURN: __taint_sink(sub.call());\n /jsbenchmark/completeness/single_app_tracing/function_call/override/polymorphism_override_001_T\n AffectedNodeName: __taint_sink\n 26: SINK: __taint_sink(sub.call());\n==========================================================\n #Total-findings:1\n==========================================================","/jsbenchmark/completeness/single_app_tracing/function_call/override/polymorphism_override_002_F":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/completeness/single_app_tracing/function_call/override/prototype_extends_001_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/jsbenchmark/completeness/single_app_tracing/function_call/override/prototype_extends_001_T\nLine 27: __taint_sink(instance.getChValue())\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/jsbenchmark/completeness/single_app_tracing/function_call/override/prototype_extends_001_T\",\"functionName\":\"prototype_extends_001_T\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /jsbenchmark/completeness/single_app_tracing/function_call/override/prototype_extends_001_T\n AffectedNodeName: __taint_src\n 10: SOURCE: function prototype_extends_001_T(__taint_src) {\n /jsbenchmark/completeness/single_app_tracing/function_call/override/prototype_extends_001_T\n AffectedNodeName: [this.chProperty]\n 18: Var Pass: this.chProperty = __taint_src;\n /jsbenchmark/completeness/single_app_tracing/function_call/override/prototype_extends_001_T\n AffectedNodeName: instance\n 26: Var Pass: let instance = new Child();\n /jsbenchmark/completeness/single_app_tracing/function_call/override/prototype_extends_001_T\n AffectedNodeName: \n 27: CALL: __taint_sink(instance.getChValue());\n /jsbenchmark/completeness/single_app_tracing/function_call/override/prototype_extends_001_T\n AffectedNodeName: instance\n 27: ARG PASS: __taint_sink(instance.getChValue());\n /jsbenchmark/completeness/single_app_tracing/function_call/override/prototype_extends_001_T\n AffectedNodeName: [return value]\n 23: Return Value: return this.chProperty;\n /jsbenchmark/completeness/single_app_tracing/function_call/override/prototype_extends_001_T\n AffectedNodeName: \n 27: CALL RETURN: __taint_sink(instance.getChValue());\n /jsbenchmark/completeness/single_app_tracing/function_call/override/prototype_extends_001_T\n AffectedNodeName: __taint_sink\n 27: SINK: __taint_sink(instance.getChValue());\n==========================================================\n #Total-findings:1\n==========================================================","/jsbenchmark/completeness/single_app_tracing/function_call/override/prototype_extends_002_F":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/completeness/single_app_tracing/function_call/return_value_passing/return_normal_value_passing_001_F":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/completeness/single_app_tracing/function_call/return_value_passing/return_normal_value_passing_002_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/jsbenchmark/completeness/single_app_tracing/function_call/return_value_passing/return_normal_value_passing_002_T\nLine 13: __taint_sink(data)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/jsbenchmark/completeness/single_app_tracing/function_call/return_value_passing/return_normal_value_passing_002_T\",\"functionName\":\"return_normal_value_passing_002_T\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /jsbenchmark/completeness/single_app_tracing/function_call/return_value_passing/return_normal_value_passing_002_T\n AffectedNodeName: __taint_src\n 11: SOURCE: function return_normal_value_passing_002_T(__taint_src) {\n /jsbenchmark/completeness/single_app_tracing/function_call/return_value_passing/return_normal_value_passing_002_T\n AffectedNodeName: [return value]\n 16: Return Value: return __taint_src;\n /jsbenchmark/completeness/single_app_tracing/function_call/return_value_passing/return_normal_value_passing_002_T\n AffectedNodeName: process\n 12: CALL RETURN: let data = process();\n /jsbenchmark/completeness/single_app_tracing/function_call/return_value_passing/return_normal_value_passing_002_T\n AffectedNodeName: data\n 12: Var Pass: let data = process();\n /jsbenchmark/completeness/single_app_tracing/function_call/return_value_passing/return_normal_value_passing_002_T\n AffectedNodeName: __taint_sink\n 13: SINK: __taint_sink(data);\n==========================================================\n #Total-findings:1\n==========================================================","/jsbenchmark/completeness/single_app_tracing/function_call/static_method/static_method_001_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/jsbenchmark/completeness/single_app_tracing/function_call/static_method/static_method_001_T\nLine 13: __taint_sink(arg)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/jsbenchmark/completeness/single_app_tracing/function_call/static_method/static_method_001_T\",\"functionName\":\"static_method_001_T\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /jsbenchmark/completeness/single_app_tracing/function_call/static_method/static_method_001_T\n AffectedNodeName: __taint_src\n 17: SOURCE: function static_method_001_T(__taint_src) {\n /jsbenchmark/completeness/single_app_tracing/function_call/static_method/static_method_001_T\n AffectedNodeName: process\n 18: CALL: MyClass.process(__taint_src);\n /jsbenchmark/completeness/single_app_tracing/function_call/static_method/static_method_001_T\n AffectedNodeName: arg\n 12: ARG PASS: static process(arg) {\n /jsbenchmark/completeness/single_app_tracing/function_call/static_method/static_method_001_T\n AffectedNodeName: __taint_sink\n 13: SINK: __taint_sink(arg);\n==========================================================\n #Total-findings:1\n==========================================================","/jsbenchmark/completeness/single_app_tracing/function_call/static_method/static_method_002_F":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/completeness/single_app_tracing/function_call/tagged_template_literals/tagged_template_literal_001_F":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/completeness/single_app_tracing/function_call/tagged_template_literals/tagged_template_literal_002_T":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/completeness/single_app_tracing/variable_scope/private_scope/private_variable_001_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/jsbenchmark/completeness/single_app_tracing/variable_scope/private_scope/private_variable_001_T\nLine 22: __taint_sink(o.GetData())\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/jsbenchmark/completeness/single_app_tracing/variable_scope/private_scope/private_variable_001_T\",\"functionName\":\"private_variable_001_T\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /jsbenchmark/completeness/single_app_tracing/variable_scope/private_scope/private_variable_001_T\n AffectedNodeName: __taint_src\n 11: SOURCE: function private_variable_001_T(__taint_src) {\n /jsbenchmark/completeness/single_app_tracing/variable_scope/private_scope/private_variable_001_T\n AffectedNodeName: data\n 13: Var Pass: #data = __taint_src;\n /jsbenchmark/completeness/single_app_tracing/variable_scope/private_scope/private_variable_001_T\n AffectedNodeName: o\n 21: Var Pass: let o = new A();\n /jsbenchmark/completeness/single_app_tracing/variable_scope/private_scope/private_variable_001_T\n AffectedNodeName: GetData\n 22: CALL: __taint_sink(o.GetData());\n /jsbenchmark/completeness/single_app_tracing/variable_scope/private_scope/private_variable_001_T\n AffectedNodeName: o\n 22: ARG PASS: __taint_sink(o.GetData());\n /jsbenchmark/completeness/single_app_tracing/variable_scope/private_scope/private_variable_001_T\n AffectedNodeName: [return value]\n 15: Return Value: return this.#data;\n /jsbenchmark/completeness/single_app_tracing/variable_scope/private_scope/private_variable_001_T\n AffectedNodeName: GetData\n 22: CALL RETURN: __taint_sink(o.GetData());\n /jsbenchmark/completeness/single_app_tracing/variable_scope/private_scope/private_variable_001_T\n AffectedNodeName: __taint_sink\n 22: SINK: __taint_sink(o.GetData());\n==========================================================\n #Total-findings:1\n==========================================================","/jsbenchmark/completeness/single_app_tracing/variable_scope/private_scope/private_variable_002_F":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/completeness/single_app_tracing/variable_scope/static_variable/static_variable_001_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/jsbenchmark/completeness/single_app_tracing/variable_scope/static_variable/static_variable_001_T\nLine 16: __taint_sink(A.data)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/jsbenchmark/completeness/single_app_tracing/variable_scope/static_variable/static_variable_001_T\",\"functionName\":\"static_variable_001_T\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /jsbenchmark/completeness/single_app_tracing/variable_scope/static_variable/static_variable_001_T\n AffectedNodeName: __taint_src\n 11: SOURCE: function static_variable_001_T(__taint_src) {\n /jsbenchmark/completeness/single_app_tracing/variable_scope/static_variable/static_variable_001_T\n AffectedNodeName: data\n 13: Var Pass: static data = __taint_src;\n /jsbenchmark/completeness/single_app_tracing/variable_scope/static_variable/static_variable_001_T\n AffectedNodeName: __taint_sink\n 16: SINK: __taint_sink(A.data);\n==========================================================\n #Total-findings:1\n==========================================================","/jsbenchmark/completeness/single_app_tracing/variable_scope/static_variable/static_variable_002_F":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/completeness/single_app_tracing/variable_scope/static_variable/static_variable_003_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/jsbenchmark/completeness/single_app_tracing/variable_scope/static_variable/static_variable_003_T\nLine 27: __taint_sink(data)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/jsbenchmark/completeness/single_app_tracing/variable_scope/static_variable/static_variable_003_T\",\"functionName\":\"static_variable_003_T\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /jsbenchmark/completeness/single_app_tracing/variable_scope/static_variable/static_variable_003_T\n AffectedNodeName: __taint_src\n 11: SOURCE: function static_variable_003_T(__taint_src) {\n /jsbenchmark/completeness/single_app_tracing/variable_scope/static_variable/static_variable_003_T\n AffectedNodeName: data\n 13: Var Pass: static data = __taint_src;\n /jsbenchmark/completeness/single_app_tracing/variable_scope/static_variable/static_variable_003_T\n AffectedNodeName: data\n 26: Var Pass: const data = A.data;\n /jsbenchmark/completeness/single_app_tracing/variable_scope/static_variable/static_variable_003_T\n AffectedNodeName: __taint_sink\n 27: SINK: __taint_sink(data);\n==========================================================\n #Total-findings:1\n==========================================================","/jsbenchmark/completeness/single_app_tracing/variable_scope/static_variable/static_variable_004_F":"======================== Findings ========================\nNo findings!\n=========================================================="} \ No newline at end of file +{"/jsbenchmark/accuracy/context_sensitive/argument_return_value_passing/argument_passing_value_001_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/jsbenchmark/accuracy/context_sensitive/argument_return_value_passing/argument_passing_value_001_T\nLine 14: __taint_sink(arg)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/jsbenchmark/accuracy/context_sensitive/argument_return_value_passing/argument_passing_value_001_T\",\"functionName\":\"argument_passing_value_001_T\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /jsbenchmark/accuracy/context_sensitive/argument_return_value_passing/argument_passing_value_001_T\n AffectedNodeName: __taint_src\n 10: SOURCE: function argument_passing_value_001_T(__taint_src) {\n /jsbenchmark/accuracy/context_sensitive/argument_return_value_passing/argument_passing_value_001_T\n AffectedNodeName: process\n 11: CALL: process(__taint_src);\n /jsbenchmark/accuracy/context_sensitive/argument_return_value_passing/argument_passing_value_001_T\n AffectedNodeName: arg\n 13: ARG PASS: function process(arg) {\n /jsbenchmark/accuracy/context_sensitive/argument_return_value_passing/argument_passing_value_001_T\n AffectedNodeName: __taint_sink\n 14: SINK: __taint_sink(arg);\n==========================================================\n #Total-findings:1\n==========================================================","/jsbenchmark/accuracy/context_sensitive/argument_return_value_passing/argument_passing_value_002_F":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/accuracy/context_sensitive/argument_return_value_passing/argument_passing_value_003_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/jsbenchmark/accuracy/context_sensitive/argument_return_value_passing/argument_passing_value_003_T\nLine 15: __taint_sink(arg1)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/jsbenchmark/accuracy/context_sensitive/argument_return_value_passing/argument_passing_value_003_T\",\"functionName\":\"argument_passing_value_003_T\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /jsbenchmark/accuracy/context_sensitive/argument_return_value_passing/argument_passing_value_003_T\n AffectedNodeName: __taint_src\n 11: SOURCE: function argument_passing_value_003_T(__taint_src) {\n /jsbenchmark/accuracy/context_sensitive/argument_return_value_passing/argument_passing_value_003_T\n AffectedNodeName: process\n 12: CALL: process(__taint_src, \"_\");\n /jsbenchmark/accuracy/context_sensitive/argument_return_value_passing/argument_passing_value_003_T\n AffectedNodeName: arg1\n 14: ARG PASS: function process(arg1, arg2) {\n /jsbenchmark/accuracy/context_sensitive/argument_return_value_passing/argument_passing_value_003_T\n AffectedNodeName: __taint_sink\n 15: SINK: __taint_sink(arg1);\n==========================================================\n #Total-findings:1\n==========================================================","/jsbenchmark/accuracy/context_sensitive/argument_return_value_passing/argument_passing_value_004_F":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/accuracy/context_sensitive/argument_return_value_passing/return_value_passing_001_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/jsbenchmark/accuracy/context_sensitive/argument_return_value_passing/return_value_passing_001_T\nLine 12: __taint_sink(data)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/jsbenchmark/accuracy/context_sensitive/argument_return_value_passing/return_value_passing_001_T\",\"functionName\":\"return_value_passing_001_T\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /jsbenchmark/accuracy/context_sensitive/argument_return_value_passing/return_value_passing_001_T\n AffectedNodeName: __taint_src\n 10: SOURCE: function return_value_passing_001_T(__taint_src) {\n /jsbenchmark/accuracy/context_sensitive/argument_return_value_passing/return_value_passing_001_T\n AffectedNodeName: [return value]\n 15: Return Value: return __taint_src;\n /jsbenchmark/accuracy/context_sensitive/argument_return_value_passing/return_value_passing_001_T\n AffectedNodeName: process\n 11: CALL RETURN: let data = process();\n /jsbenchmark/accuracy/context_sensitive/argument_return_value_passing/return_value_passing_001_T\n AffectedNodeName: data\n 11: Var Pass: let data = process();\n /jsbenchmark/accuracy/context_sensitive/argument_return_value_passing/return_value_passing_001_T\n AffectedNodeName: __taint_sink\n 12: SINK: __taint_sink(data);\n==========================================================\n #Total-findings:1\n==========================================================","/jsbenchmark/accuracy/context_sensitive/argument_return_value_passing/return_value_passing_002_F":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/accuracy/context_sensitive/multi_invoke/multi_invoke_001_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/jsbenchmark/accuracy/context_sensitive/multi_invoke/multi_invoke_001_T\nLine 13: __taint_sink(a)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/jsbenchmark/accuracy/context_sensitive/multi_invoke/multi_invoke_001_T\",\"functionName\":\"multi_invoke_001_T\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /jsbenchmark/accuracy/context_sensitive/multi_invoke/multi_invoke_001_T\n AffectedNodeName: __taint_src\n 10: SOURCE: function multi_invoke_001_T(__taint_src) {\n /jsbenchmark/accuracy/context_sensitive/multi_invoke/multi_invoke_001_T\n AffectedNodeName: process\n 11: CALL: let a = process(__taint_src);\n /jsbenchmark/accuracy/context_sensitive/multi_invoke/multi_invoke_001_T\n AffectedNodeName: arg\n 15: ARG PASS: function process(arg) {\n /jsbenchmark/accuracy/context_sensitive/multi_invoke/multi_invoke_001_T\n AffectedNodeName: [return value]\n 16: Return Value: return arg;\n /jsbenchmark/accuracy/context_sensitive/multi_invoke/multi_invoke_001_T\n AffectedNodeName: process\n 11: CALL RETURN: let a = process(__taint_src);\n /jsbenchmark/accuracy/context_sensitive/multi_invoke/multi_invoke_001_T\n AffectedNodeName: a\n 11: Var Pass: let a = process(__taint_src);\n /jsbenchmark/accuracy/context_sensitive/multi_invoke/multi_invoke_001_T\n AffectedNodeName: __taint_sink\n 13: SINK: __taint_sink(a);\n==========================================================\n #Total-findings:1\n==========================================================","/jsbenchmark/accuracy/context_sensitive/multi_invoke/multi_invoke_002_F":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/accuracy/context_sensitive/polymorphism/no_solver/polymorphism_no_solver_001_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/jsbenchmark/accuracy/context_sensitive/polymorphism/no_solver/polymorphism_no_solver_001_T\nLine 26: __taint_sink(sub.call())\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/jsbenchmark/accuracy/context_sensitive/polymorphism/no_solver/polymorphism_no_solver_001_T\",\"functionName\":\"polymorphism_no_solver_001_T\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /jsbenchmark/accuracy/context_sensitive/polymorphism/no_solver/polymorphism_no_solver_001_T\n AffectedNodeName: __taint_src\n 10: SOURCE: function polymorphism_no_solver_001_T(__taint_src) {\n /jsbenchmark/accuracy/context_sensitive/polymorphism/no_solver/polymorphism_no_solver_001_T\n AffectedNodeName: [return value]\n 15: Return Value: return __taint_src;\n /jsbenchmark/accuracy/context_sensitive/polymorphism/no_solver/polymorphism_no_solver_001_T\n AffectedNodeName: call\n 26: CALL RETURN: __taint_sink(sub.call());\n /jsbenchmark/accuracy/context_sensitive/polymorphism/no_solver/polymorphism_no_solver_001_T\n AffectedNodeName: __taint_sink\n 26: SINK: __taint_sink(sub.call());\n==========================================================\n #Total-findings:1\n==========================================================","/jsbenchmark/accuracy/context_sensitive/polymorphism/no_solver/polymorphism_no_solver_002_F":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/accuracy/context_sensitive/polymorphism/solver/polymorphism_001_T":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/accuracy/context_sensitive/polymorphism/solver/polymorphism_002_F":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/accuracy/field_sensitive/class/constructor_field_001_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/jsbenchmark/accuracy/field_sensitive/class/constructor_field_001_T\nLine 20: __taint_sink(obj.data)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/jsbenchmark/accuracy/field_sensitive/class/constructor_field_001_T\",\"functionName\":\"constructor_field_001_T\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /jsbenchmark/accuracy/field_sensitive/class/constructor_field_001_T\n AffectedNodeName: __taint_src\n 11: SOURCE: function constructor_field_001_T(__taint_src) {\n /jsbenchmark/accuracy/field_sensitive/class/constructor_field_001_T\n AffectedNodeName: this.data\n 14: Var Pass: this.data = __taint_src;\n /jsbenchmark/accuracy/field_sensitive/class/constructor_field_001_T\n AffectedNodeName: obj\n 19: Var Pass: let obj = new A();\n /jsbenchmark/accuracy/field_sensitive/class/constructor_field_001_T\n AffectedNodeName: __taint_sink\n 20: SINK: __taint_sink(obj.data);\n==========================================================\n #Total-findings:1\n==========================================================","/jsbenchmark/accuracy/field_sensitive/class/constructor_field_002_F":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/accuracy/field_sensitive/class/constructor_field_003_F":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/accuracy/field_sensitive/class/constructor_field_004_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/jsbenchmark/accuracy/field_sensitive/class/constructor_field_004_T\nLine 20: __taint_sink(obj.data)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/jsbenchmark/accuracy/field_sensitive/class/constructor_field_004_T\",\"functionName\":\"constructor_field_004_T\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /jsbenchmark/accuracy/field_sensitive/class/constructor_field_004_T\n AffectedNodeName: __taint_src\n 11: SOURCE: function constructor_field_004_T(__taint_src) {\n /jsbenchmark/accuracy/field_sensitive/class/constructor_field_004_T\n AffectedNodeName: constructor\n 19: CALL: let obj = new A(__taint_src);\n /jsbenchmark/accuracy/field_sensitive/class/constructor_field_004_T\n AffectedNodeName: param\n 13: ARG PASS: constructor(param) {\n /jsbenchmark/accuracy/field_sensitive/class/constructor_field_004_T\n AffectedNodeName: this.data\n 14: Var Pass: this.data = param;\n /jsbenchmark/accuracy/field_sensitive/class/constructor_field_004_T\n AffectedNodeName: obj\n 19: Var Pass: let obj = new A(__taint_src);\n /jsbenchmark/accuracy/field_sensitive/class/constructor_field_004_T\n AffectedNodeName: __taint_sink\n 20: SINK: __taint_sink(obj.data);\n==========================================================\n #Total-findings:1\n==========================================================","/jsbenchmark/accuracy/field_sensitive/class/field_len_001_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/jsbenchmark/accuracy/field_sensitive/class/field_len_001_T\nLine 32: __taint_sink(a.b.c.data)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/jsbenchmark/accuracy/field_sensitive/class/field_len_001_T\",\"functionName\":\"field_len_001_T\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /jsbenchmark/accuracy/field_sensitive/class/field_len_001_T\n AffectedNodeName: __taint_src\n 11: SOURCE: function field_len_001_T(__taint_src) {\n /jsbenchmark/accuracy/field_sensitive/class/field_len_001_T\n AffectedNodeName: this.data\n 26: Var Pass: this.data = __taint_src;\n /jsbenchmark/accuracy/field_sensitive/class/field_len_001_T\n AffectedNodeName: this.c\n 20: Var Pass: this.c = new C();\n /jsbenchmark/accuracy/field_sensitive/class/field_len_001_T\n AffectedNodeName: this.b\n 14: Var Pass: this.b = new B();\n /jsbenchmark/accuracy/field_sensitive/class/field_len_001_T\n AffectedNodeName: a\n 31: Var Pass: const a = new A();\n /jsbenchmark/accuracy/field_sensitive/class/field_len_001_T\n AffectedNodeName: __taint_sink\n 32: SINK: __taint_sink(a.b.c.data);\n==========================================================\n #Total-findings:1\n==========================================================","/jsbenchmark/accuracy/field_sensitive/class/field_len_002_F":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/accuracy/field_sensitive/class/field_len_003_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/jsbenchmark/accuracy/field_sensitive/class/field_len_003_T\nLine 52: __taint_sink(s1)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/jsbenchmark/accuracy/field_sensitive/class/field_len_003_T\",\"functionName\":\"field_len_003_T\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /jsbenchmark/accuracy/field_sensitive/class/field_len_003_T\n AffectedNodeName: __taint_src\n 11: SOURCE: function field_len_003_T(__taint_src) {\n /jsbenchmark/accuracy/field_sensitive/class/field_len_003_T\n AffectedNodeName: this.data\n 44: Var Pass: this.data = __taint_src;\n /jsbenchmark/accuracy/field_sensitive/class/field_len_003_T\n AffectedNodeName: this.f\n 38: Var Pass: this.f = new F();\n /jsbenchmark/accuracy/field_sensitive/class/field_len_003_T\n AffectedNodeName: this.e\n 32: Var Pass: this.e = new E();\n /jsbenchmark/accuracy/field_sensitive/class/field_len_003_T\n AffectedNodeName: this.d\n 26: Var Pass: this.d = new D();\n /jsbenchmark/accuracy/field_sensitive/class/field_len_003_T\n AffectedNodeName: this.c\n 20: Var Pass: this.c = new C();\n /jsbenchmark/accuracy/field_sensitive/class/field_len_003_T\n AffectedNodeName: this.b\n 14: Var Pass: this.b = new B();\n /jsbenchmark/accuracy/field_sensitive/class/field_len_003_T\n AffectedNodeName: a\n 49: Var Pass: const a = new A();\n /jsbenchmark/accuracy/field_sensitive/class/field_len_003_T\n AffectedNodeName: s\n 50: Var Pass: const s = a.b.c;\n /jsbenchmark/accuracy/field_sensitive/class/field_len_003_T\n AffectedNodeName: s1\n 51: Var Pass: const s1 = s.d.e.f.data;\n /jsbenchmark/accuracy/field_sensitive/class/field_len_003_T\n AffectedNodeName: __taint_sink\n 52: SINK: __taint_sink(s1);\n==========================================================\n #Total-findings:1\n==========================================================","/jsbenchmark/accuracy/field_sensitive/class/field_len_004_F":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/accuracy/field_sensitive/class/field_len_005_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/jsbenchmark/accuracy/field_sensitive/class/field_len_005_T\nLine 86: __taint_sink(a.b.c.d.e.f.g.h.i.j.k.l.data)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/jsbenchmark/accuracy/field_sensitive/class/field_len_005_T\",\"functionName\":\"field_len_005_T\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /jsbenchmark/accuracy/field_sensitive/class/field_len_005_T\n AffectedNodeName: __taint_src\n 11: SOURCE: function field_len_005_T(__taint_src) {\n /jsbenchmark/accuracy/field_sensitive/class/field_len_005_T\n AffectedNodeName: this.data\n 80: Var Pass: this.data = __taint_src;\n /jsbenchmark/accuracy/field_sensitive/class/field_len_005_T\n AffectedNodeName: this.l\n 74: Var Pass: this.l = new L();\n /jsbenchmark/accuracy/field_sensitive/class/field_len_005_T\n AffectedNodeName: this.k\n 68: Var Pass: this.k = new K();\n /jsbenchmark/accuracy/field_sensitive/class/field_len_005_T\n AffectedNodeName: this.j\n 62: Var Pass: this.j = new J();\n /jsbenchmark/accuracy/field_sensitive/class/field_len_005_T\n AffectedNodeName: this.i\n 56: Var Pass: this.i = new I();\n /jsbenchmark/accuracy/field_sensitive/class/field_len_005_T\n AffectedNodeName: this.h\n 50: Var Pass: this.h = new H();\n /jsbenchmark/accuracy/field_sensitive/class/field_len_005_T\n AffectedNodeName: this.g\n 44: Var Pass: this.g = new G();\n /jsbenchmark/accuracy/field_sensitive/class/field_len_005_T\n AffectedNodeName: this.f\n 38: Var Pass: this.f = new F();\n /jsbenchmark/accuracy/field_sensitive/class/field_len_005_T\n AffectedNodeName: this.e\n 32: Var Pass: this.e = new E();\n /jsbenchmark/accuracy/field_sensitive/class/field_len_005_T\n AffectedNodeName: this.d\n 26: Var Pass: this.d = new D();\n /jsbenchmark/accuracy/field_sensitive/class/field_len_005_T\n AffectedNodeName: this.c\n 20: Var Pass: this.c = new C();\n /jsbenchmark/accuracy/field_sensitive/class/field_len_005_T\n AffectedNodeName: this.b\n 14: Var Pass: this.b = new B();\n /jsbenchmark/accuracy/field_sensitive/class/field_len_005_T\n AffectedNodeName: a\n 85: Var Pass: const a = new A();\n /jsbenchmark/accuracy/field_sensitive/class/field_len_005_T\n AffectedNodeName: __taint_sink\n 86: SINK: __taint_sink(a.b.c.d.e.f.g.h.i.j.k.l.data);\n==========================================================\n #Total-findings:1\n==========================================================","/jsbenchmark/accuracy/field_sensitive/class/field_len_006_F":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/accuracy/field_sensitive/multidimensional_collection/array_multidimensional_collection_001_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/jsbenchmark/accuracy/field_sensitive/multidimensional_collection/array_multidimensional_collection_001_T\nLine 13: __taint_sink(s.0.0)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/jsbenchmark/accuracy/field_sensitive/multidimensional_collection/array_multidimensional_collection_001_T\",\"functionName\":\"array_multidimensional_collection_001_T\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /jsbenchmark/accuracy/field_sensitive/multidimensional_collection/array_multidimensional_collection_001_T\n AffectedNodeName: __taint_src\n 11: SOURCE: function array_multidimensional_collection_001_T(__taint_src) {\n /jsbenchmark/accuracy/field_sensitive/multidimensional_collection/array_multidimensional_collection_001_T\n AffectedNodeName: s\n 12: Var Pass: let s = [[__taint_src], [\"b\"], \"c\"];\n /jsbenchmark/accuracy/field_sensitive/multidimensional_collection/array_multidimensional_collection_001_T\n AffectedNodeName: __taint_sink\n 13: SINK: __taint_sink(s[0][0]);\n==========================================================\n #Total-findings:1\n==========================================================","/jsbenchmark/accuracy/field_sensitive/multidimensional_collection/array_multidimensional_collection_002_F":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/accuracy/field_sensitive/one_dimensional_collection/numeric_index_state_no_solver/array_no_solver_001_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/jsbenchmark/accuracy/field_sensitive/one_dimensional_collection/numeric_index_state_no_solver/array_no_solver_001_T\nLine 13: __taint_sink(s.0)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/jsbenchmark/accuracy/field_sensitive/one_dimensional_collection/numeric_index_state_no_solver/array_no_solver_001_T\",\"functionName\":\"array_no_solver_001_T\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /jsbenchmark/accuracy/field_sensitive/one_dimensional_collection/numeric_index_state_no_solver/array_no_solver_001_T\n AffectedNodeName: __taint_src\n 11: SOURCE: function array_no_solver_001_T(__taint_src) {\n /jsbenchmark/accuracy/field_sensitive/one_dimensional_collection/numeric_index_state_no_solver/array_no_solver_001_T\n AffectedNodeName: s\n 12: Var Pass: let s = [__taint_src, \"b\", \"c\"];\n /jsbenchmark/accuracy/field_sensitive/one_dimensional_collection/numeric_index_state_no_solver/array_no_solver_001_T\n AffectedNodeName: __taint_sink\n 13: SINK: __taint_sink(s[0]);\n==========================================================\n #Total-findings:1\n==========================================================","/jsbenchmark/accuracy/field_sensitive/one_dimensional_collection/numeric_index_state_no_solver/array_no_solver_002_F":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/accuracy/field_sensitive/one_dimensional_collection/numeric_index_state_no_solver/array_no_solver_003_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/jsbenchmark/accuracy/field_sensitive/one_dimensional_collection/numeric_index_state_no_solver/array_no_solver_003_T\nLine 14: __taint_sink(s)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/jsbenchmark/accuracy/field_sensitive/one_dimensional_collection/numeric_index_state_no_solver/array_no_solver_003_T\",\"functionName\":\"array_no_solver_003_T\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /jsbenchmark/accuracy/field_sensitive/one_dimensional_collection/numeric_index_state_no_solver/array_no_solver_003_T\n AffectedNodeName: __taint_src\n 11: SOURCE: function array_no_solver_003_T(__taint_src) {\n /jsbenchmark/accuracy/field_sensitive/one_dimensional_collection/numeric_index_state_no_solver/array_no_solver_003_T\n AffectedNodeName: s\n 12: Var Pass: let s = [__taint_src, \"b\", \"c\"];\n /jsbenchmark/accuracy/field_sensitive/one_dimensional_collection/numeric_index_state_no_solver/array_no_solver_003_T\n AffectedNodeName: __taint_sink\n 14: SINK: __taint_sink(s);\n==========================================================\n #Total-findings:1\n==========================================================","/jsbenchmark/accuracy/field_sensitive/one_dimensional_collection/numeric_index_state_no_solver/array_no_solver_004_F":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/accuracy/field_sensitive/one_dimensional_collection/numeric_index_state_no_solver/map_field_sensitive_001_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/jsbenchmark/accuracy/field_sensitive/one_dimensional_collection/numeric_index_state_no_solver/map_field_sensitive_001_T\nLine 15: __taint_sink(map.get(key1))\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/jsbenchmark/accuracy/field_sensitive/one_dimensional_collection/numeric_index_state_no_solver/map_field_sensitive_001_T\",\"functionName\":\"map_field_sensitive_001_T\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /jsbenchmark/accuracy/field_sensitive/one_dimensional_collection/numeric_index_state_no_solver/map_field_sensitive_001_T\n AffectedNodeName: __taint_src\n 11: SOURCE: function map_field_sensitive_001_T(__taint_src) {\n /jsbenchmark/accuracy/field_sensitive/one_dimensional_collection/numeric_index_state_no_solver/map_field_sensitive_001_T\n AffectedNodeName: set\n 13: CALL: map.set(\"key1\", __taint_src);\n /jsbenchmark/accuracy/field_sensitive/one_dimensional_collection/numeric_index_state_no_solver/map_field_sensitive_001_T\n AffectedNodeName: __taint_sink\n 15: SINK: __taint_sink(map.get(\"key1\"));\n==========================================================\n #Total-findings:1\n==========================================================","/jsbenchmark/accuracy/field_sensitive/one_dimensional_collection/numeric_index_state_no_solver/map_field_sensitive_002_F":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/accuracy/field_sensitive/one_dimensional_collection/numeric_index_state_no_solver/map_field_sensitive_003_F":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/accuracy/field_sensitive/one_dimensional_collection/numeric_index_state_no_solver/map_field_sensitive_004_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/jsbenchmark/accuracy/field_sensitive/one_dimensional_collection/numeric_index_state_no_solver/map_field_sensitive_004_T\nLine 17: __taint_sink(map.get(key2))\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/jsbenchmark/accuracy/field_sensitive/one_dimensional_collection/numeric_index_state_no_solver/map_field_sensitive_004_T\",\"functionName\":\"map_field_sensitive_004_T\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /jsbenchmark/accuracy/field_sensitive/one_dimensional_collection/numeric_index_state_no_solver/map_field_sensitive_004_T\n AffectedNodeName: __taint_src\n 11: SOURCE: function map_field_sensitive_004_T(__taint_src) {\n /jsbenchmark/accuracy/field_sensitive/one_dimensional_collection/numeric_index_state_no_solver/map_field_sensitive_004_T\n AffectedNodeName: set\n 15: CALL: map.set(\"key2\", __taint_src);\n /jsbenchmark/accuracy/field_sensitive/one_dimensional_collection/numeric_index_state_no_solver/map_field_sensitive_004_T\n AffectedNodeName: __taint_sink\n 17: SINK: __taint_sink(map.get(\"key2\"));\n==========================================================\n #Total-findings:1\n==========================================================","/jsbenchmark/accuracy/field_sensitive/one_dimensional_collection/numeric_index_state_no_solver/map_field_sensitive_005_F":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/accuracy/field_sensitive/one_dimensional_collection/numeric_index_state_no_solver/map_field_sensitive_006_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/jsbenchmark/accuracy/field_sensitive/one_dimensional_collection/numeric_index_state_no_solver/map_field_sensitive_006_T\nLine 15: __taint_sink(map.values())\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/jsbenchmark/accuracy/field_sensitive/one_dimensional_collection/numeric_index_state_no_solver/map_field_sensitive_006_T\",\"functionName\":\"map_field_sensitive_006_T\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /jsbenchmark/accuracy/field_sensitive/one_dimensional_collection/numeric_index_state_no_solver/map_field_sensitive_006_T\n AffectedNodeName: __taint_src\n 11: SOURCE: function map_field_sensitive_006_T(__taint_src) {\n /jsbenchmark/accuracy/field_sensitive/one_dimensional_collection/numeric_index_state_no_solver/map_field_sensitive_006_T\n AffectedNodeName: set\n 13: CALL: map.set(\"key1\", __taint_src);\n /jsbenchmark/accuracy/field_sensitive/one_dimensional_collection/numeric_index_state_no_solver/map_field_sensitive_006_T\n AffectedNodeName: __taint_sink\n 15: SINK: __taint_sink(map.values());\n==========================================================\n #Total-findings:1\n==========================================================","/jsbenchmark/accuracy/field_sensitive/one_dimensional_collection/numeric_index_state_no_solver/map_field_sensitive_007_F":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/accuracy/field_sensitive/one_dimensional_collection/numeric_index_state_no_solver/map_field_sensitive_008_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/jsbenchmark/accuracy/field_sensitive/one_dimensional_collection/numeric_index_state_no_solver/map_field_sensitive_008_T\nLine 15: __taint_sink(map.keys())\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/jsbenchmark/accuracy/field_sensitive/one_dimensional_collection/numeric_index_state_no_solver/map_field_sensitive_008_T\",\"functionName\":\"map_field_sensitive_008_T\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /jsbenchmark/accuracy/field_sensitive/one_dimensional_collection/numeric_index_state_no_solver/map_field_sensitive_008_T\n AffectedNodeName: __taint_src\n 11: SOURCE: function map_field_sensitive_008_T(__taint_src) {\n /jsbenchmark/accuracy/field_sensitive/one_dimensional_collection/numeric_index_state_no_solver/map_field_sensitive_008_T\n AffectedNodeName: set\n 13: CALL: map.set(__taint_src, \"value1\");\n /jsbenchmark/accuracy/field_sensitive/one_dimensional_collection/numeric_index_state_no_solver/map_field_sensitive_008_T\n AffectedNodeName: __taint_sink\n 15: SINK: __taint_sink(map.keys());\n==========================================================\n #Total-findings:1\n==========================================================","/jsbenchmark/accuracy/field_sensitive/one_dimensional_collection/numeric_index_state_no_solver/map_field_sensitive_009_F":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/accuracy/field_sensitive/one_dimensional_collection/numeric_index_state_no_solver/rest_parameter_no_solver_001_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/jsbenchmark/accuracy/field_sensitive/one_dimensional_collection/numeric_index_state_no_solver/rest_parameter_no_solver_001_T\nLine 16: __taint_sink(args.1)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/jsbenchmark/accuracy/field_sensitive/one_dimensional_collection/numeric_index_state_no_solver/rest_parameter_no_solver_001_T\",\"functionName\":\"rest_parameter_no_solver_001_T\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /jsbenchmark/accuracy/field_sensitive/one_dimensional_collection/numeric_index_state_no_solver/rest_parameter_no_solver_001_T\n AffectedNodeName: __taint_src\n 11: SOURCE: function rest_parameter_no_solver_001_T(__taint_src) {\n /jsbenchmark/accuracy/field_sensitive/one_dimensional_collection/numeric_index_state_no_solver/rest_parameter_no_solver_001_T\n AffectedNodeName: collectArgs\n 12: CALL: collectArgs(\"prefix\", __taint_src, \"suffix\");\n /jsbenchmark/accuracy/field_sensitive/one_dimensional_collection/numeric_index_state_no_solver/rest_parameter_no_solver_001_T\n AffectedNodeName: __tmp1__\n 15: ARG PASS: function collectArgs(...args) {\n /jsbenchmark/accuracy/field_sensitive/one_dimensional_collection/numeric_index_state_no_solver/rest_parameter_no_solver_001_T\n AffectedNodeName: args\n 15: Var Pass: function collectArgs(...args) {\n 16: Var Pass: __taint_sink(args[1]);\n 17: Var Pass: }\n /jsbenchmark/accuracy/field_sensitive/one_dimensional_collection/numeric_index_state_no_solver/rest_parameter_no_solver_001_T\n AffectedNodeName: __taint_sink\n 16: SINK: __taint_sink(args[1]);\n==========================================================\n #Total-findings:1\n==========================================================","/jsbenchmark/accuracy/field_sensitive/one_dimensional_collection/numeric_index_state_no_solver/rest_parameter_no_solver_002_F":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/accuracy/field_sensitive/one_dimensional_collection/numeric_index_state_no_solver/spread_operator_no_solver_001_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/jsbenchmark/accuracy/field_sensitive/one_dimensional_collection/numeric_index_state_no_solver/spread_operator_no_solver_001_T\nLine 15: __taint_sink(rest.0)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/jsbenchmark/accuracy/field_sensitive/one_dimensional_collection/numeric_index_state_no_solver/spread_operator_no_solver_001_T\",\"functionName\":\"spread_operator_no_solver_001_T\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /jsbenchmark/accuracy/field_sensitive/one_dimensional_collection/numeric_index_state_no_solver/spread_operator_no_solver_001_T\n AffectedNodeName: __taint_src\n 11: SOURCE: function spread_operator_no_solver_001_T(__taint_src) {\n /jsbenchmark/accuracy/field_sensitive/one_dimensional_collection/numeric_index_state_no_solver/spread_operator_no_solver_001_T\n AffectedNodeName: foo\n 12: Var Pass: const foo = __taint_src;\n /jsbenchmark/accuracy/field_sensitive/one_dimensional_collection/numeric_index_state_no_solver/spread_operator_no_solver_001_T\n AffectedNodeName: __tmp2__\n 14: Var Pass: const [r1, r2, ...rest] = [123, 456, foo, bar];\n /jsbenchmark/accuracy/field_sensitive/one_dimensional_collection/numeric_index_state_no_solver/spread_operator_no_solver_001_T\n AffectedNodeName: rest\n 14: Var Pass: const [r1, r2, ...rest] = [123, 456, foo, bar];\n /jsbenchmark/accuracy/field_sensitive/one_dimensional_collection/numeric_index_state_no_solver/spread_operator_no_solver_001_T\n AffectedNodeName: __taint_sink\n 15: SINK: __taint_sink(rest[0]);\n==========================================================\n #Total-findings:1\n==========================================================","/jsbenchmark/accuracy/field_sensitive/one_dimensional_collection/numeric_index_state_no_solver/spread_operator_no_solver_002_F":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/accuracy/field_sensitive/one_dimensional_collection/numeric_index_state_no_solver/spread_operator_no_solver_003_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/jsbenchmark/accuracy/field_sensitive/one_dimensional_collection/numeric_index_state_no_solver/spread_operator_no_solver_003_T\nLine 14: __taint_sink(array.3)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/jsbenchmark/accuracy/field_sensitive/one_dimensional_collection/numeric_index_state_no_solver/spread_operator_no_solver_003_T\",\"functionName\":\"spread_operator_no_solver_003_T\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /jsbenchmark/accuracy/field_sensitive/one_dimensional_collection/numeric_index_state_no_solver/spread_operator_no_solver_003_T\n AffectedNodeName: __taint_src\n 11: SOURCE: function spread_operator_no_solver_003_T(__taint_src) {\n /jsbenchmark/accuracy/field_sensitive/one_dimensional_collection/numeric_index_state_no_solver/spread_operator_no_solver_003_T\n AffectedNodeName: array1\n 12: Var Pass: let array1 = [\"a\", \"b\", __taint_src];\n /jsbenchmark/accuracy/field_sensitive/one_dimensional_collection/numeric_index_state_no_solver/spread_operator_no_solver_003_T\n AffectedNodeName: array\n 13: Var Pass: let array = [\"c\", ...array1];\n /jsbenchmark/accuracy/field_sensitive/one_dimensional_collection/numeric_index_state_no_solver/spread_operator_no_solver_003_T\n AffectedNodeName: __taint_sink\n 14: SINK: __taint_sink(array[3]);\n==========================================================\n #Total-findings:1\n==========================================================","/jsbenchmark/accuracy/field_sensitive/one_dimensional_collection/numeric_index_state_no_solver/spread_operator_no_solver_004_F":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/accuracy/field_sensitive/one_dimensional_collection/numeric_index_state_solver/array_solver_001_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/jsbenchmark/accuracy/field_sensitive/one_dimensional_collection/numeric_index_state_solver/array_solver_001_T\nLine 13: __taint_sink(s.1+1)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/jsbenchmark/accuracy/field_sensitive/one_dimensional_collection/numeric_index_state_solver/array_solver_001_T\",\"functionName\":\"array_solver_001_T\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /jsbenchmark/accuracy/field_sensitive/one_dimensional_collection/numeric_index_state_solver/array_solver_001_T\n AffectedNodeName: __taint_src\n 11: SOURCE: function array_solver_001_T(__taint_src) {\n /jsbenchmark/accuracy/field_sensitive/one_dimensional_collection/numeric_index_state_solver/array_solver_001_T\n AffectedNodeName: s\n 12: Var Pass: let s = [\"a\", \"b\", __taint_src, \"c\", \"d\"];\n /jsbenchmark/accuracy/field_sensitive/one_dimensional_collection/numeric_index_state_solver/array_solver_001_T\n AffectedNodeName: __taint_sink\n 13: SINK: __taint_sink(s[1 + 1]);\n==========================================================\n #Total-findings:1\n==========================================================","/jsbenchmark/accuracy/field_sensitive/one_dimensional_collection/numeric_index_state_solver/array_solver_002_F":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/jsbenchmark/accuracy/field_sensitive/one_dimensional_collection/numeric_index_state_solver/array_solver_002_F\nLine 13: __taint_sink(s.1+2)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/jsbenchmark/accuracy/field_sensitive/one_dimensional_collection/numeric_index_state_solver/array_solver_002_F\",\"functionName\":\"array_solver_002_F\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /jsbenchmark/accuracy/field_sensitive/one_dimensional_collection/numeric_index_state_solver/array_solver_002_F\n AffectedNodeName: __taint_src\n 11: SOURCE: function array_solver_002_F(__taint_src) {\n /jsbenchmark/accuracy/field_sensitive/one_dimensional_collection/numeric_index_state_solver/array_solver_002_F\n AffectedNodeName: s\n 12: Var Pass: let s = [\"a\", \"b\", __taint_src, \"c\", \"d\"];\n /jsbenchmark/accuracy/field_sensitive/one_dimensional_collection/numeric_index_state_solver/array_solver_002_F\n AffectedNodeName: __taint_sink\n 13: SINK: __taint_sink(s[1 + 2]);\n==========================================================\n #Total-findings:1\n==========================================================","/jsbenchmark/accuracy/flow_sensitive/asynchronous/asynchronous_await_001_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/jsbenchmark/accuracy/flow_sensitive/asynchronous/asynchronous_await_001_T\nLine 14: __taint_sink(data)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/jsbenchmark/accuracy/flow_sensitive/asynchronous/asynchronous_await_001_T\",\"functionName\":\"asynchronous_await_001_T\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /jsbenchmark/accuracy/flow_sensitive/asynchronous/asynchronous_await_001_T\n AffectedNodeName: __taint_src\n 11: SOURCE: async function asynchronous_await_001_T(__taint_src) {\n /jsbenchmark/accuracy/flow_sensitive/asynchronous/asynchronous_await_001_T\n AffectedNodeName: resolve\n 19: CALL: resolve(__taint_src);\n /jsbenchmark/accuracy/flow_sensitive/asynchronous/asynchronous_await_001_T\n AffectedNodeName: __taint_sink\n 14: SINK: __taint_sink(data);\n==========================================================\n #Total-findings:1\n==========================================================","/jsbenchmark/accuracy/flow_sensitive/asynchronous/asynchronous_await_002_F":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/accuracy/flow_sensitive/loop_stmt/dowhile_body_loop_stmt_001_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/jsbenchmark/accuracy/flow_sensitive/loop_stmt/dowhile_body_loop_stmt_001_T\nLine 15: __taint_sink(res)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/jsbenchmark/accuracy/flow_sensitive/loop_stmt/dowhile_body_loop_stmt_001_T\",\"functionName\":\"dowhile_body_loop_stmt_001_T\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /jsbenchmark/accuracy/flow_sensitive/loop_stmt/dowhile_body_loop_stmt_001_T\n AffectedNodeName: __taint_src\n 11: SOURCE: function dowhile_body_loop_stmt_001_T(__taint_src) {\n /jsbenchmark/accuracy/flow_sensitive/loop_stmt/dowhile_body_loop_stmt_001_T\n AffectedNodeName: res\n 14: Var Pass: res = __taint_src;\n /jsbenchmark/accuracy/flow_sensitive/loop_stmt/dowhile_body_loop_stmt_001_T\n AffectedNodeName: __taint_sink\n 15: SINK: __taint_sink(res);\n==========================================================\n #Total-findings:1\n==========================================================","/jsbenchmark/accuracy/flow_sensitive/loop_stmt/dowhile_body_loop_stmt_002_F":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/jsbenchmark/accuracy/flow_sensitive/loop_stmt/dowhile_body_loop_stmt_002_F\nLine 14: __taint_sink(res)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/jsbenchmark/accuracy/flow_sensitive/loop_stmt/dowhile_body_loop_stmt_002_F\",\"functionName\":\"dowhile_body_loop_stmt_002_F\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /jsbenchmark/accuracy/flow_sensitive/loop_stmt/dowhile_body_loop_stmt_002_F\n AffectedNodeName: __taint_src\n 11: SOURCE: function dowhile_body_loop_stmt_002_F(__taint_src) {\n /jsbenchmark/accuracy/flow_sensitive/loop_stmt/dowhile_body_loop_stmt_002_F\n AffectedNodeName: res\n 15: Var Pass: res = __taint_src;\n /jsbenchmark/accuracy/flow_sensitive/loop_stmt/dowhile_body_loop_stmt_002_F\n AffectedNodeName: __taint_sink\n 14: SINK: __taint_sink(res);\n==========================================================\n #Total-findings:1\n==========================================================","/jsbenchmark/accuracy/flow_sensitive/loop_stmt/for_001_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/jsbenchmark/accuracy/flow_sensitive/loop_stmt/for_001_T\nLine 16: __taint_sink(res)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/jsbenchmark/accuracy/flow_sensitive/loop_stmt/for_001_T\",\"functionName\":\"for_001_T\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /jsbenchmark/accuracy/flow_sensitive/loop_stmt/for_001_T\n AffectedNodeName: __taint_src\n 11: SOURCE: function for_001_T(__taint_src) {\n /jsbenchmark/accuracy/flow_sensitive/loop_stmt/for_001_T\n AffectedNodeName: res\n 15: Var Pass: res = __taint_src;\n /jsbenchmark/accuracy/flow_sensitive/loop_stmt/for_001_T\n AffectedNodeName: __taint_sink\n 16: SINK: __taint_sink(res);\n==========================================================\n #Total-findings:1\n==========================================================","/jsbenchmark/accuracy/flow_sensitive/loop_stmt/for_002_F":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/jsbenchmark/accuracy/flow_sensitive/loop_stmt/for_002_F\nLine 15: __taint_sink(res)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/jsbenchmark/accuracy/flow_sensitive/loop_stmt/for_002_F\",\"functionName\":\"for_002_F\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /jsbenchmark/accuracy/flow_sensitive/loop_stmt/for_002_F\n AffectedNodeName: __taint_src\n 11: SOURCE: function for_002_F(__taint_src) {\n /jsbenchmark/accuracy/flow_sensitive/loop_stmt/for_002_F\n AffectedNodeName: res\n 16: Var Pass: res = __taint_src;\n /jsbenchmark/accuracy/flow_sensitive/loop_stmt/for_002_F\n AffectedNodeName: __taint_sink\n 15: SINK: __taint_sink(res);\n==========================================================\n #Total-findings:1\n==========================================================","/jsbenchmark/accuracy/flow_sensitive/loop_stmt/for_003_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/jsbenchmark/accuracy/flow_sensitive/loop_stmt/for_003_T\nLine 15: __taint_sink(res)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/jsbenchmark/accuracy/flow_sensitive/loop_stmt/for_003_T\",\"functionName\":\"for_003_T\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /jsbenchmark/accuracy/flow_sensitive/loop_stmt/for_003_T\n AffectedNodeName: __taint_src\n 11: SOURCE: function for_003_T(__taint_src) {\n /jsbenchmark/accuracy/flow_sensitive/loop_stmt/for_003_T\n AffectedNodeName: res\n 14: Var Pass: for (res = __taint_src; i < 1; i++) {\n /jsbenchmark/accuracy/flow_sensitive/loop_stmt/for_003_T\n AffectedNodeName: __taint_sink\n 15: SINK: __taint_sink(res);\n==========================================================\n #Total-findings:1\n==========================================================","/jsbenchmark/accuracy/flow_sensitive/loop_stmt/for_004_F":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/accuracy/flow_sensitive/normal_stmt/assign_expression_stmt_001_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/jsbenchmark/accuracy/flow_sensitive/normal_stmt/assign_expression_stmt_001_T\nLine 13: __taint_sink(result)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/jsbenchmark/accuracy/flow_sensitive/normal_stmt/assign_expression_stmt_001_T\",\"functionName\":\"assign_expression_stmt_001_T\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /jsbenchmark/accuracy/flow_sensitive/normal_stmt/assign_expression_stmt_001_T\n AffectedNodeName: __taint_src\n 11: SOURCE: function assign_expression_stmt_001_T(__taint_src) {\n /jsbenchmark/accuracy/flow_sensitive/normal_stmt/assign_expression_stmt_001_T\n AffectedNodeName: result\n 12: Var Pass: let result = __taint_src;\n /jsbenchmark/accuracy/flow_sensitive/normal_stmt/assign_expression_stmt_001_T\n AffectedNodeName: __taint_sink\n 13: SINK: __taint_sink(result);\n==========================================================\n #Total-findings:1\n==========================================================","/jsbenchmark/accuracy/flow_sensitive/normal_stmt/assign_expression_stmt_002_F":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/accuracy/object_sensitive/class/constructor_obj_001_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/jsbenchmark/accuracy/object_sensitive/class/constructor_obj_001_T\nLine 20: __taint_sink(obj)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/jsbenchmark/accuracy/object_sensitive/class/constructor_obj_001_T\",\"functionName\":\"constructor_obj_001_T\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /jsbenchmark/accuracy/object_sensitive/class/constructor_obj_001_T\n AffectedNodeName: __taint_src\n 11: SOURCE: function constructor_obj_001_T(__taint_src) {\n /jsbenchmark/accuracy/object_sensitive/class/constructor_obj_001_T\n AffectedNodeName: constructor\n 18: CALL: let obj = new A(__taint_src);\n /jsbenchmark/accuracy/object_sensitive/class/constructor_obj_001_T\n AffectedNodeName: data\n 13: ARG PASS: constructor(data) {\n /jsbenchmark/accuracy/object_sensitive/class/constructor_obj_001_T\n AffectedNodeName: this.data\n 14: Var Pass: this.data = data;\n /jsbenchmark/accuracy/object_sensitive/class/constructor_obj_001_T\n AffectedNodeName: obj\n 18: Var Pass: let obj = new A(__taint_src);\n /jsbenchmark/accuracy/object_sensitive/class/constructor_obj_001_T\n AffectedNodeName: __taint_sink\n 20: SINK: __taint_sink(obj);\n==========================================================\n #Total-findings:1\n==========================================================","/jsbenchmark/accuracy/object_sensitive/class/constructor_obj_002_F":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/accuracy/object_sensitive/collection/array_object_sensitive_001_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/jsbenchmark/accuracy/object_sensitive/collection/array_object_sensitive_001_T\nLine 14: __taint_sink(s)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/jsbenchmark/accuracy/object_sensitive/collection/array_object_sensitive_001_T\",\"functionName\":\"array_object_sensitive_001_T\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /jsbenchmark/accuracy/object_sensitive/collection/array_object_sensitive_001_T\n AffectedNodeName: __taint_src\n 11: SOURCE: function array_object_sensitive_001_T(__taint_src) {\n /jsbenchmark/accuracy/object_sensitive/collection/array_object_sensitive_001_T\n AffectedNodeName: s\n 12: Var Pass: let s = [__taint_src, \"b\", \"c\"];\n /jsbenchmark/accuracy/object_sensitive/collection/array_object_sensitive_001_T\n AffectedNodeName: __taint_sink\n 14: SINK: __taint_sink(s);\n==========================================================\n #Total-findings:1\n==========================================================","/jsbenchmark/accuracy/object_sensitive/collection/array_object_sensitive_002_F":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/accuracy/object_sensitive/collection/array_object_sensitive_003_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/jsbenchmark/accuracy/object_sensitive/collection/array_object_sensitive_003_T\nLine 14: __taint_sink(s)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/jsbenchmark/accuracy/object_sensitive/collection/array_object_sensitive_003_T\",\"functionName\":\"array_object_sensitive_003_T\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /jsbenchmark/accuracy/object_sensitive/collection/array_object_sensitive_003_T\n AffectedNodeName: __taint_src\n 11: SOURCE: function array_object_sensitive_003_T(__taint_src) {\n /jsbenchmark/accuracy/object_sensitive/collection/array_object_sensitive_003_T\n AffectedNodeName: s\n 12: Var Pass: let s = [[__taint_src], [\"b\"], \"c\"];\n /jsbenchmark/accuracy/object_sensitive/collection/array_object_sensitive_003_T\n AffectedNodeName: __taint_sink\n 14: SINK: __taint_sink(s);\n==========================================================\n #Total-findings:1\n==========================================================","/jsbenchmark/accuracy/object_sensitive/collection/array_object_sensitive_004_F":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/accuracy/object_sensitive/collection/array_object_sensitive_005_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/jsbenchmark/accuracy/object_sensitive/collection/array_object_sensitive_005_T\nLine 16: __taint_sink(s)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/jsbenchmark/accuracy/object_sensitive/collection/array_object_sensitive_005_T\",\"functionName\":\"array_object_sensitive_005_T\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /jsbenchmark/accuracy/object_sensitive/collection/array_object_sensitive_005_T\n AffectedNodeName: __taint_src\n 11: SOURCE: function array_object_sensitive_005_T(__taint_src) {\n /jsbenchmark/accuracy/object_sensitive/collection/array_object_sensitive_005_T\n AffectedNodeName: push\n 13: CALL: s.push(__taint_src);\n /jsbenchmark/accuracy/object_sensitive/collection/array_object_sensitive_005_T\n AffectedNodeName: __taint_sink\n 16: SINK: __taint_sink(s);\n==========================================================\n #Total-findings:1\n==========================================================","/jsbenchmark/accuracy/object_sensitive/collection/array_object_sensitive_006_F":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/accuracy/object_sensitive/collection/map_object_sensitive_001_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/jsbenchmark/accuracy/object_sensitive/collection/map_object_sensitive_001_T\nLine 16: __taint_sink(map)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/jsbenchmark/accuracy/object_sensitive/collection/map_object_sensitive_001_T\",\"functionName\":\"map_object_sensitive_001_T\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /jsbenchmark/accuracy/object_sensitive/collection/map_object_sensitive_001_T\n AffectedNodeName: __taint_src\n 11: SOURCE: function map_object_sensitive_001_T(__taint_src) {\n /jsbenchmark/accuracy/object_sensitive/collection/map_object_sensitive_001_T\n AffectedNodeName: set\n 13: CALL: map.set(\"key1\", __taint_src);\n /jsbenchmark/accuracy/object_sensitive/collection/map_object_sensitive_001_T\n AffectedNodeName: __taint_sink\n 16: SINK: __taint_sink(map);\n==========================================================\n #Total-findings:1\n==========================================================","/jsbenchmark/accuracy/object_sensitive/collection/map_object_sensitive_002_F":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/accuracy/object_sensitive/collection/map_object_sensitive_003_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/jsbenchmark/accuracy/object_sensitive/collection/map_object_sensitive_003_T\nLine 16: __taint_sink(map)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/jsbenchmark/accuracy/object_sensitive/collection/map_object_sensitive_003_T\",\"functionName\":\"map_object_sensitive_003_T\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /jsbenchmark/accuracy/object_sensitive/collection/map_object_sensitive_003_T\n AffectedNodeName: __taint_src\n 11: SOURCE: function map_object_sensitive_003_T(__taint_src) {\n /jsbenchmark/accuracy/object_sensitive/collection/map_object_sensitive_003_T\n AffectedNodeName: set\n 13: CALL: map.set(__taint_src, \"value\");\n /jsbenchmark/accuracy/object_sensitive/collection/map_object_sensitive_003_T\n AffectedNodeName: __taint_sink\n 16: SINK: __taint_sink(map);\n==========================================================\n #Total-findings:1\n==========================================================","/jsbenchmark/accuracy/object_sensitive/collection/map_object_sensitive_004_F":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/accuracy/object_sensitive/collection/map_object_sensitive_005_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/jsbenchmark/accuracy/object_sensitive/collection/map_object_sensitive_005_T\nLine 16: __taint_sink(map)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/jsbenchmark/accuracy/object_sensitive/collection/map_object_sensitive_005_T\",\"functionName\":\"map_object_sensitive_005_T\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /jsbenchmark/accuracy/object_sensitive/collection/map_object_sensitive_005_T\n AffectedNodeName: __taint_src\n 11: SOURCE: function map_object_sensitive_005_T(__taint_src) {\n /jsbenchmark/accuracy/object_sensitive/collection/map_object_sensitive_005_T\n AffectedNodeName: __taint_sink\n 16: SINK: __taint_sink(map);\n==========================================================\n #Total-findings:1\n==========================================================","/jsbenchmark/accuracy/object_sensitive/collection/map_object_sensitive_006_F":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/accuracy/object_sensitive/collection/set_object_sensitive_001_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/jsbenchmark/accuracy/object_sensitive/collection/set_object_sensitive_001_T\nLine 14: __taint_sink(set)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/jsbenchmark/accuracy/object_sensitive/collection/set_object_sensitive_001_T\",\"functionName\":\"set_object_sensitive_001_T\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /jsbenchmark/accuracy/object_sensitive/collection/set_object_sensitive_001_T\n AffectedNodeName: __taint_src\n 11: SOURCE: function set_object_sensitive_001_T(__taint_src) {\n /jsbenchmark/accuracy/object_sensitive/collection/set_object_sensitive_001_T\n AffectedNodeName: set\n 12: Var Pass: let set = new Set(__taint_src);\n /jsbenchmark/accuracy/object_sensitive/collection/set_object_sensitive_001_T\n AffectedNodeName: __taint_sink\n 14: SINK: __taint_sink(set);\n==========================================================\n #Total-findings:1\n==========================================================","/jsbenchmark/accuracy/object_sensitive/collection/set_object_sensitive_002_F":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/accuracy/object_sensitive/collection/set_object_sensitive_003_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/jsbenchmark/accuracy/object_sensitive/collection/set_object_sensitive_003_T\nLine 15: __taint_sink(set)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/jsbenchmark/accuracy/object_sensitive/collection/set_object_sensitive_003_T\",\"functionName\":\"set_object_sensitive_003_T\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /jsbenchmark/accuracy/object_sensitive/collection/set_object_sensitive_003_T\n AffectedNodeName: __taint_src\n 11: SOURCE: function set_object_sensitive_003_T(__taint_src) {\n /jsbenchmark/accuracy/object_sensitive/collection/set_object_sensitive_003_T\n AffectedNodeName: add\n 13: CALL: set.add(__taint_src);\n /jsbenchmark/accuracy/object_sensitive/collection/set_object_sensitive_003_T\n AffectedNodeName: __taint_sink\n 15: SINK: __taint_sink(set);\n==========================================================\n #Total-findings:1\n==========================================================","/jsbenchmark/accuracy/object_sensitive/collection/set_object_sensitive_004_F":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/accuracy/path_sensitive/exception_throw/exception_throw_001_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/jsbenchmark/accuracy/path_sensitive/exception_throw/exception_throw_001_T\nLine 13: __taint_sink(__taint_src)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/jsbenchmark/accuracy/path_sensitive/exception_throw/exception_throw_001_T\",\"functionName\":\"exception_throw_001_T\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /jsbenchmark/accuracy/path_sensitive/exception_throw/exception_throw_001_T\n AffectedNodeName: __taint_src\n 11: SOURCE: function exception_throw_001_T(__taint_src) {\n /jsbenchmark/accuracy/path_sensitive/exception_throw/exception_throw_001_T\n AffectedNodeName: __taint_sink\n 13: SINK: __taint_sink(__taint_src);\n==========================================================\n #Total-findings:1\n==========================================================","/jsbenchmark/accuracy/path_sensitive/exception_throw/exception_throw_002_F":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/jsbenchmark/accuracy/path_sensitive/exception_throw/exception_throw_002_F\nLine 14: __taint_sink(__taint_src)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/jsbenchmark/accuracy/path_sensitive/exception_throw/exception_throw_002_F\",\"functionName\":\"exception_throw_002_F\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /jsbenchmark/accuracy/path_sensitive/exception_throw/exception_throw_002_F\n AffectedNodeName: __taint_src\n 11: SOURCE: function exception_throw_002_F(__taint_src) {\n /jsbenchmark/accuracy/path_sensitive/exception_throw/exception_throw_002_F\n AffectedNodeName: __taint_sink\n 14: SINK: __taint_sink(__taint_src);\n==========================================================\n #Total-findings:1\n==========================================================","/jsbenchmark/accuracy/path_sensitive/exception_throw/exception_throw_003_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/jsbenchmark/accuracy/path_sensitive/exception_throw/exception_throw_003_T\nLine 15: __taint_sink(e)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/jsbenchmark/accuracy/path_sensitive/exception_throw/exception_throw_003_T\",\"functionName\":\"exception_throw_003_T\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /jsbenchmark/accuracy/path_sensitive/exception_throw/exception_throw_003_T\n AffectedNodeName: __taint_src\n 11: SOURCE: function exception_throw_003_T(__taint_src) {\n /jsbenchmark/accuracy/path_sensitive/exception_throw/exception_throw_003_T\n AffectedNodeName: __taint_src\n 13: Throw Pass: throw __taint_src;\n /jsbenchmark/accuracy/path_sensitive/exception_throw/exception_throw_003_T\n AffectedNodeName: e\n 14: Var Pass: } catch (e) {\n /jsbenchmark/accuracy/path_sensitive/exception_throw/exception_throw_003_T\n AffectedNodeName: __taint_sink\n 15: SINK: __taint_sink(e);\n==========================================================\n #Total-findings:1\n==========================================================","/jsbenchmark/accuracy/path_sensitive/explicit_jump_control/break_001_F":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/jsbenchmark/accuracy/path_sensitive/explicit_jump_control/break_001_F\nLine 18: __taint_sink(res)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/jsbenchmark/accuracy/path_sensitive/explicit_jump_control/break_001_F\",\"functionName\":\"break_001_F\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /jsbenchmark/accuracy/path_sensitive/explicit_jump_control/break_001_F\n AffectedNodeName: __taint_src\n 11: SOURCE: function break_001_F(__taint_src) {\n /jsbenchmark/accuracy/path_sensitive/explicit_jump_control/break_001_F\n AffectedNodeName: res\n 15: Var Pass: res = __taint_src;\n /jsbenchmark/accuracy/path_sensitive/explicit_jump_control/break_001_F\n AffectedNodeName: __taint_sink\n 18: SINK: __taint_sink(res);\n\n------------- 2: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/jsbenchmark/accuracy/path_sensitive/explicit_jump_control/break_001_F\nLine 18: __taint_sink(res)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/jsbenchmark/accuracy/path_sensitive/explicit_jump_control/break_001_F\",\"functionName\":\"break_001_F\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /jsbenchmark/accuracy/path_sensitive/explicit_jump_control/break_001_F\n AffectedNodeName: __taint_src\n 11: SOURCE: function break_001_F(__taint_src) {\n /jsbenchmark/accuracy/path_sensitive/explicit_jump_control/break_001_F\n AffectedNodeName: res\n 15: Var Pass: res = __taint_src;\n /jsbenchmark/accuracy/path_sensitive/explicit_jump_control/break_001_F\n AffectedNodeName: __taint_sink\n 18: CALL: __taint_sink(res);\n /jsbenchmark/accuracy/path_sensitive/explicit_jump_control/break_001_F\n AffectedNodeName: __taint_sink\n 18: SINK: __taint_sink(res);\n==========================================================\n #Total-findings:2\n==========================================================","/jsbenchmark/accuracy/path_sensitive/explicit_jump_control/break_002_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/jsbenchmark/accuracy/path_sensitive/explicit_jump_control/break_002_T\nLine 17: __taint_sink(res)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/jsbenchmark/accuracy/path_sensitive/explicit_jump_control/break_002_T\",\"functionName\":\"break_002_T\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /jsbenchmark/accuracy/path_sensitive/explicit_jump_control/break_002_T\n AffectedNodeName: __taint_src\n 11: SOURCE: function break_002_T(__taint_src) {\n /jsbenchmark/accuracy/path_sensitive/explicit_jump_control/break_002_T\n AffectedNodeName: res\n 15: Var Pass: res = __taint_src;\n /jsbenchmark/accuracy/path_sensitive/explicit_jump_control/break_002_T\n AffectedNodeName: __taint_sink\n 17: SINK: __taint_sink(res);\n\n------------- 2: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/jsbenchmark/accuracy/path_sensitive/explicit_jump_control/break_002_T\nLine 17: __taint_sink(res)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/jsbenchmark/accuracy/path_sensitive/explicit_jump_control/break_002_T\",\"functionName\":\"break_002_T\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /jsbenchmark/accuracy/path_sensitive/explicit_jump_control/break_002_T\n AffectedNodeName: __taint_src\n 11: SOURCE: function break_002_T(__taint_src) {\n /jsbenchmark/accuracy/path_sensitive/explicit_jump_control/break_002_T\n AffectedNodeName: res\n 15: Var Pass: res = __taint_src;\n /jsbenchmark/accuracy/path_sensitive/explicit_jump_control/break_002_T\n AffectedNodeName: __taint_sink\n 17: CALL: __taint_sink(res);\n /jsbenchmark/accuracy/path_sensitive/explicit_jump_control/break_002_T\n AffectedNodeName: __taint_sink\n 17: SINK: __taint_sink(res);\n==========================================================\n #Total-findings:2\n==========================================================","/jsbenchmark/accuracy/path_sensitive/explicit_jump_control/break_label_001_F":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/accuracy/path_sensitive/explicit_jump_control/break_label_002_T":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/accuracy/path_sensitive/explicit_jump_control/continue_001_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/jsbenchmark/accuracy/path_sensitive/explicit_jump_control/continue_001_T\nLine 18: __taint_sink(res)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/jsbenchmark/accuracy/path_sensitive/explicit_jump_control/continue_001_T\",\"functionName\":\"continue_001_T\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /jsbenchmark/accuracy/path_sensitive/explicit_jump_control/continue_001_T\n AffectedNodeName: __taint_src\n 11: SOURCE: function continue_001_T(__taint_src) {\n /jsbenchmark/accuracy/path_sensitive/explicit_jump_control/continue_001_T\n AffectedNodeName: res\n 15: Var Pass: res = __taint_src;\n /jsbenchmark/accuracy/path_sensitive/explicit_jump_control/continue_001_T\n AffectedNodeName: __taint_sink\n 18: SINK: __taint_sink(res);\n\n------------- 2: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/jsbenchmark/accuracy/path_sensitive/explicit_jump_control/continue_001_T\nLine 18: __taint_sink(res)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/jsbenchmark/accuracy/path_sensitive/explicit_jump_control/continue_001_T\",\"functionName\":\"continue_001_T\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /jsbenchmark/accuracy/path_sensitive/explicit_jump_control/continue_001_T\n AffectedNodeName: __taint_src\n 11: SOURCE: function continue_001_T(__taint_src) {\n /jsbenchmark/accuracy/path_sensitive/explicit_jump_control/continue_001_T\n AffectedNodeName: res\n 15: Var Pass: res = __taint_src;\n /jsbenchmark/accuracy/path_sensitive/explicit_jump_control/continue_001_T\n AffectedNodeName: __taint_sink\n 18: CALL: __taint_sink(res);\n /jsbenchmark/accuracy/path_sensitive/explicit_jump_control/continue_001_T\n AffectedNodeName: __taint_sink\n 18: SINK: __taint_sink(res);\n==========================================================\n #Total-findings:2\n==========================================================","/jsbenchmark/accuracy/path_sensitive/explicit_jump_control/continue_002_F":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/jsbenchmark/accuracy/path_sensitive/explicit_jump_control/continue_002_F\nLine 15: __taint_sink(res)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/jsbenchmark/accuracy/path_sensitive/explicit_jump_control/continue_002_F\",\"functionName\":\"continue_002_F\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /jsbenchmark/accuracy/path_sensitive/explicit_jump_control/continue_002_F\n AffectedNodeName: __taint_src\n 11: SOURCE: function continue_002_F(__taint_src) {\n /jsbenchmark/accuracy/path_sensitive/explicit_jump_control/continue_002_F\n AffectedNodeName: res\n 16: Var Pass: res = __taint_src;\n /jsbenchmark/accuracy/path_sensitive/explicit_jump_control/continue_002_F\n AffectedNodeName: __taint_sink\n 15: SINK: __taint_sink(res);\n==========================================================\n #Total-findings:1\n==========================================================","/jsbenchmark/accuracy/path_sensitive/explicit_jump_control/return_001_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/jsbenchmark/accuracy/path_sensitive/explicit_jump_control/return_001_T\nLine 16: __taint_sink(arg1)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/jsbenchmark/accuracy/path_sensitive/explicit_jump_control/return_001_T\",\"functionName\":\"return_001_T\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /jsbenchmark/accuracy/path_sensitive/explicit_jump_control/return_001_T\n AffectedNodeName: __taint_src\n 11: SOURCE: function return_001_T(__taint_src) {\n /jsbenchmark/accuracy/path_sensitive/explicit_jump_control/return_001_T\n AffectedNodeName: process\n 12: CALL: process(__taint_src, \"some_condition\");\n /jsbenchmark/accuracy/path_sensitive/explicit_jump_control/return_001_T\n AffectedNodeName: arg1\n 14: ARG PASS: function process(arg1, arg2) {\n /jsbenchmark/accuracy/path_sensitive/explicit_jump_control/return_001_T\n AffectedNodeName: __taint_sink\n 16: SINK: __taint_sink(arg1);\n==========================================================\n #Total-findings:1\n==========================================================","/jsbenchmark/accuracy/path_sensitive/explicit_jump_control/return_002_F":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/accuracy/path_sensitive/loop_conditional_stmt/no_solver/conditional_if_no_solver_001_F":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/accuracy/path_sensitive/loop_conditional_stmt/no_solver/conditional_if_no_solver_002_F":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/accuracy/path_sensitive/loop_conditional_stmt/no_solver/conditional_if_no_solver_003_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/jsbenchmark/accuracy/path_sensitive/loop_conditional_stmt/no_solver/conditional_if_no_solver_003_T\nLine 18: __taint_sink(res)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/jsbenchmark/accuracy/path_sensitive/loop_conditional_stmt/no_solver/conditional_if_no_solver_003_T\",\"functionName\":\"conditional_if_no_solver_003_T\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /jsbenchmark/accuracy/path_sensitive/loop_conditional_stmt/no_solver/conditional_if_no_solver_003_T\n AffectedNodeName: __taint_src\n 11: SOURCE: function conditional_if_no_solver_003_T(__taint_src) {\n /jsbenchmark/accuracy/path_sensitive/loop_conditional_stmt/no_solver/conditional_if_no_solver_003_T\n AffectedNodeName: res\n 16: Var Pass: res = __taint_src;\n /jsbenchmark/accuracy/path_sensitive/loop_conditional_stmt/no_solver/conditional_if_no_solver_003_T\n AffectedNodeName: __taint_sink\n 18: SINK: __taint_sink(res);\n==========================================================\n #Total-findings:1\n==========================================================","/jsbenchmark/accuracy/path_sensitive/loop_conditional_stmt/no_solver/conditional_if_no_solver_004_F":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/accuracy/path_sensitive/loop_conditional_stmt/no_solver/conditional_switch_no_solver_001_F":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/accuracy/path_sensitive/loop_conditional_stmt/no_solver/conditional_switch_no_solver_002_F":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/accuracy/path_sensitive/loop_conditional_stmt/no_solver/conditional_switch_no_solver_003_F":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/accuracy/path_sensitive/loop_conditional_stmt/no_solver/conditional_switch_no_solver_004_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/jsbenchmark/accuracy/path_sensitive/loop_conditional_stmt/no_solver/conditional_switch_no_solver_004_T\nLine 18: __taint_sink(data)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/jsbenchmark/accuracy/path_sensitive/loop_conditional_stmt/no_solver/conditional_switch_no_solver_004_T\",\"functionName\":\"conditional_switch_no_solver_004_T\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /jsbenchmark/accuracy/path_sensitive/loop_conditional_stmt/no_solver/conditional_switch_no_solver_004_T\n AffectedNodeName: __taint_src\n 11: SOURCE: function conditional_switch_no_solver_004_T(__taint_src) {\n /jsbenchmark/accuracy/path_sensitive/loop_conditional_stmt/no_solver/conditional_switch_no_solver_004_T\n AffectedNodeName: data\n 15: Var Pass: data = __taint_src;\n /jsbenchmark/accuracy/path_sensitive/loop_conditional_stmt/no_solver/conditional_switch_no_solver_004_T\n AffectedNodeName: __taint_sink\n 18: SINK: __taint_sink(data);\n==========================================================\n #Total-findings:1\n==========================================================","/jsbenchmark/accuracy/path_sensitive/loop_conditional_stmt/solver/conditional_if_solver_001_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/jsbenchmark/accuracy/path_sensitive/loop_conditional_stmt/solver/conditional_if_solver_001_T\nLine 18: __taint_sink(res)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/jsbenchmark/accuracy/path_sensitive/loop_conditional_stmt/solver/conditional_if_solver_001_T\",\"functionName\":\"conditional_if_solver_001_T\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /jsbenchmark/accuracy/path_sensitive/loop_conditional_stmt/solver/conditional_if_solver_001_T\n AffectedNodeName: __taint_src\n 11: SOURCE: function conditional_if_solver_001_T(__taint_src) {\n /jsbenchmark/accuracy/path_sensitive/loop_conditional_stmt/solver/conditional_if_solver_001_T\n AffectedNodeName: res\n 14: Var Pass: res = __taint_src;\n /jsbenchmark/accuracy/path_sensitive/loop_conditional_stmt/solver/conditional_if_solver_001_T\n AffectedNodeName: __taint_sink\n 18: SINK: __taint_sink(res);\n==========================================================\n #Total-findings:1\n==========================================================","/jsbenchmark/accuracy/path_sensitive/loop_conditional_stmt/solver/conditional_if_solver_002_F":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/jsbenchmark/accuracy/path_sensitive/loop_conditional_stmt/solver/conditional_if_solver_002_F\nLine 18: __taint_sink(res)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/jsbenchmark/accuracy/path_sensitive/loop_conditional_stmt/solver/conditional_if_solver_002_F\",\"functionName\":\"conditional_if_solver_002_F\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /jsbenchmark/accuracy/path_sensitive/loop_conditional_stmt/solver/conditional_if_solver_002_F\n AffectedNodeName: __taint_src\n 11: SOURCE: function conditional_if_solver_002_F(__taint_src) {\n /jsbenchmark/accuracy/path_sensitive/loop_conditional_stmt/solver/conditional_if_solver_002_F\n AffectedNodeName: res\n 14: Var Pass: res = __taint_src;\n /jsbenchmark/accuracy/path_sensitive/loop_conditional_stmt/solver/conditional_if_solver_002_F\n AffectedNodeName: __taint_sink\n 18: SINK: __taint_sink(res);\n==========================================================\n #Total-findings:1\n==========================================================","/jsbenchmark/accuracy/path_sensitive/loop_conditional_stmt/solver/conditional_switch_solver_001_F":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/jsbenchmark/accuracy/path_sensitive/loop_conditional_stmt/solver/conditional_switch_solver_001_F\nLine 18: __taint_sink(data)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/jsbenchmark/accuracy/path_sensitive/loop_conditional_stmt/solver/conditional_switch_solver_001_F\",\"functionName\":\"conditional_switch_solver_001_F\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /jsbenchmark/accuracy/path_sensitive/loop_conditional_stmt/solver/conditional_switch_solver_001_F\n AffectedNodeName: __taint_src\n 11: SOURCE: function conditional_switch_solver_001_F(__taint_src) {\n /jsbenchmark/accuracy/path_sensitive/loop_conditional_stmt/solver/conditional_switch_solver_001_F\n AffectedNodeName: data\n 15: Var Pass: data = __taint_src;\n /jsbenchmark/accuracy/path_sensitive/loop_conditional_stmt/solver/conditional_switch_solver_001_F\n AffectedNodeName: __taint_sink\n 18: SINK: __taint_sink(data);\n==========================================================\n #Total-findings:1\n==========================================================","/jsbenchmark/accuracy/path_sensitive/loop_conditional_stmt/solver/conditional_switch_solver_002_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/jsbenchmark/accuracy/path_sensitive/loop_conditional_stmt/solver/conditional_switch_solver_002_T\nLine 18: __taint_sink(data)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/jsbenchmark/accuracy/path_sensitive/loop_conditional_stmt/solver/conditional_switch_solver_002_T\",\"functionName\":\"conditional_switch_solver_002_T\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /jsbenchmark/accuracy/path_sensitive/loop_conditional_stmt/solver/conditional_switch_solver_002_T\n AffectedNodeName: __taint_src\n 11: SOURCE: function conditional_switch_solver_002_T(__taint_src) {\n /jsbenchmark/accuracy/path_sensitive/loop_conditional_stmt/solver/conditional_switch_solver_002_T\n AffectedNodeName: data\n 15: Var Pass: data = __taint_src;\n /jsbenchmark/accuracy/path_sensitive/loop_conditional_stmt/solver/conditional_switch_solver_002_T\n AffectedNodeName: __taint_sink\n 18: SINK: __taint_sink(data);\n==========================================================\n #Total-findings:1\n==========================================================","/jsbenchmark/accuracy/path_sensitive/loop_conditional_stmt/solver/for_body_solver_001_T":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/accuracy/path_sensitive/loop_conditional_stmt/solver/for_body_solver_002_F":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/jsbenchmark/accuracy/path_sensitive/loop_conditional_stmt/solver/for_body_solver_002_F\nLine 16: __taint_sink(res)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/jsbenchmark/accuracy/path_sensitive/loop_conditional_stmt/solver/for_body_solver_002_F\",\"functionName\":\"for_body_solver_002_F\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /jsbenchmark/accuracy/path_sensitive/loop_conditional_stmt/solver/for_body_solver_002_F\n AffectedNodeName: __taint_src\n 11: SOURCE: function for_body_solver_002_F(__taint_src) {\n /jsbenchmark/accuracy/path_sensitive/loop_conditional_stmt/solver/for_body_solver_002_F\n AffectedNodeName: res\n 14: Var Pass: res = __taint_src;\n /jsbenchmark/accuracy/path_sensitive/loop_conditional_stmt/solver/for_body_solver_002_F\n AffectedNodeName: __taint_sink\n 16: SINK: __taint_sink(res);\n==========================================================\n #Total-findings:1\n==========================================================","/jsbenchmark/accuracy/path_sensitive/loop_conditional_stmt/solver/while_body_solver_001_F":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/jsbenchmark/accuracy/path_sensitive/loop_conditional_stmt/solver/while_body_solver_001_F\nLine 18: __taint_sink(res)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/jsbenchmark/accuracy/path_sensitive/loop_conditional_stmt/solver/while_body_solver_001_F\",\"functionName\":\"while_body_solver_001_F\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /jsbenchmark/accuracy/path_sensitive/loop_conditional_stmt/solver/while_body_solver_001_F\n AffectedNodeName: __taint_src\n 11: SOURCE: function while_body_solver_001_F(__taint_src) {\n /jsbenchmark/accuracy/path_sensitive/loop_conditional_stmt/solver/while_body_solver_001_F\n AffectedNodeName: res\n 15: Var Pass: res = __taint_src;\n /jsbenchmark/accuracy/path_sensitive/loop_conditional_stmt/solver/while_body_solver_001_F\n AffectedNodeName: __taint_sink\n 18: SINK: __taint_sink(res);\n==========================================================\n #Total-findings:1\n==========================================================","/jsbenchmark/accuracy/path_sensitive/loop_conditional_stmt/solver/while_body_solver_002_T":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/completeness/dynamic_tracing/dynamic_call/dynamic_call_reflect_001_F":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/completeness/dynamic_tracing/dynamic_call/dynamic_call_reflect_002_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/jsbenchmark/completeness/dynamic_tracing/dynamic_call/dynamic_call_reflect_002_T\nLine 16: __taint_sink(Reflect.get(obj, name))\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/jsbenchmark/completeness/dynamic_tracing/dynamic_call/dynamic_call_reflect_002_T\",\"functionName\":\"dynamic_call_reflect_002_T\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /jsbenchmark/completeness/dynamic_tracing/dynamic_call/dynamic_call_reflect_002_T\n AffectedNodeName: __taint_src\n 11: SOURCE: function dynamic_call_reflect_002_T(__taint_src) {\n /jsbenchmark/completeness/dynamic_tracing/dynamic_call/dynamic_call_reflect_002_T\n AffectedNodeName: obj\n 12: Var Pass: let obj = {\n 13: Var Pass: name: __taint_src,\n 14: Var Pass: };\n /jsbenchmark/completeness/dynamic_tracing/dynamic_call/dynamic_call_reflect_002_T\n AffectedNodeName: get\n 16: CALL: __taint_sink(Reflect.get(obj, \"name\"));\n /jsbenchmark/completeness/dynamic_tracing/dynamic_call/dynamic_call_reflect_002_T\n AffectedNodeName: __taint_sink\n 16: SINK: __taint_sink(Reflect.get(obj, \"name\"));\n==========================================================\n #Total-findings:1\n==========================================================","/jsbenchmark/completeness/dynamic_tracing/dynamic_call/dynamic_call_reflect_003_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/jsbenchmark/completeness/dynamic_tracing/dynamic_call/dynamic_call_reflect_003_T\nLine 17: __taint_sink(obj.foo)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/jsbenchmark/completeness/dynamic_tracing/dynamic_call/dynamic_call_reflect_003_T\",\"functionName\":\"dynamic_call_reflect_003_T\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /jsbenchmark/completeness/dynamic_tracing/dynamic_call/dynamic_call_reflect_003_T\n AffectedNodeName: __taint_src\n 11: SOURCE: function dynamic_call_reflect_003_T(__taint_src) {\n /jsbenchmark/completeness/dynamic_tracing/dynamic_call/dynamic_call_reflect_003_T\n AffectedNodeName: set\n 16: CALL: Reflect.set(obj, \"foo\", __taint_src);\n /jsbenchmark/completeness/dynamic_tracing/dynamic_call/dynamic_call_reflect_003_T\n AffectedNodeName: \n 16: Reflect.set Pass: Reflect.set(obj, \"foo\", __taint_src);\n /jsbenchmark/completeness/dynamic_tracing/dynamic_call/dynamic_call_reflect_003_T\n AffectedNodeName: __taint_sink\n 17: SINK: __taint_sink(obj.foo);\n==========================================================\n #Total-findings:1\n==========================================================","/jsbenchmark/completeness/dynamic_tracing/dynamic_call/dynamic_call_reflect_004_F":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/completeness/dynamic_tracing/dynamic_call/dynamic_call_reflect_005_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/jsbenchmark/completeness/dynamic_tracing/dynamic_call/dynamic_call_reflect_005_T\nLine 18: __taint_sink(obj.data)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/jsbenchmark/completeness/dynamic_tracing/dynamic_call/dynamic_call_reflect_005_T\",\"functionName\":\"dynamic_call_reflect_005_T\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /jsbenchmark/completeness/dynamic_tracing/dynamic_call/dynamic_call_reflect_005_T\n AffectedNodeName: __taint_src\n 11: SOURCE: function dynamic_call_reflect_005_T(__taint_src) {\n /jsbenchmark/completeness/dynamic_tracing/dynamic_call/dynamic_call_reflect_005_T\n AffectedNodeName: obj\n 12: Var Pass: let obj = {\n 13: Var Pass: data: __taint_src,\n 14: Var Pass: data1: \"aaa\",\n 15: Var Pass: };\n /jsbenchmark/completeness/dynamic_tracing/dynamic_call/dynamic_call_reflect_005_T\n AffectedNodeName: deleteProperty\n 17: CALL: Reflect.deleteProperty(obj, \"data1\");\n /jsbenchmark/completeness/dynamic_tracing/dynamic_call/dynamic_call_reflect_005_T\n AffectedNodeName: __taint_sink\n 18: SINK: __taint_sink(obj.data);\n==========================================================\n #Total-findings:1\n==========================================================","/jsbenchmark/completeness/dynamic_tracing/dynamic_call/dynamic_call_reflect_006_F":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/completeness/single_app_tracing/alias/alias_001_F":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/completeness/single_app_tracing/alias/alias_002_F":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/completeness/single_app_tracing/alias/alias_003_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/jsbenchmark/completeness/single_app_tracing/alias/alias_003_T\nLine 15: __taint_sink(a.value)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/jsbenchmark/completeness/single_app_tracing/alias/alias_003_T\",\"functionName\":\"alias_003_T\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /jsbenchmark/completeness/single_app_tracing/alias/alias_003_T\n AffectedNodeName: __taint_src\n 11: SOURCE: function alias_003_T(__taint_src) {\n /jsbenchmark/completeness/single_app_tracing/alias/alias_003_T\n AffectedNodeName: b.value\n 14: Var Pass: b.value = __taint_src;\n /jsbenchmark/completeness/single_app_tracing/alias/alias_003_T\n AffectedNodeName: __taint_sink\n 15: SINK: __taint_sink(a.value);\n==========================================================\n #Total-findings:1\n==========================================================","/jsbenchmark/completeness/single_app_tracing/asynchronous_tracing/promise_callback_await/async_await_001_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/jsbenchmark/completeness/single_app_tracing/asynchronous_tracing/promise_callback_await/async_await_001_T\nLine 13: __taint_sink(data)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/jsbenchmark/completeness/single_app_tracing/asynchronous_tracing/promise_callback_await/async_await_001_T\",\"functionName\":\"async_await_001_T\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /jsbenchmark/completeness/single_app_tracing/asynchronous_tracing/promise_callback_await/async_await_001_T\n AffectedNodeName: __taint_src\n 11: SOURCE: async function async_await_001_T(__taint_src) {\n /jsbenchmark/completeness/single_app_tracing/asynchronous_tracing/promise_callback_await/async_await_001_T\n AffectedNodeName: resolve\n 18: CALL: resolve(__taint_src);\n /jsbenchmark/completeness/single_app_tracing/asynchronous_tracing/promise_callback_await/async_await_001_T\n AffectedNodeName: __taint_sink\n 13: SINK: __taint_sink(data);\n==========================================================\n #Total-findings:1\n==========================================================","/jsbenchmark/completeness/single_app_tracing/asynchronous_tracing/promise_callback_await/async_await_002_F":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/completeness/single_app_tracing/asynchronous_tracing/promise_callback_await/asynchronous_promise_001_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/jsbenchmark/completeness/single_app_tracing/asynchronous_tracing/promise_callback_await/asynchronous_promise_001_T\nLine 18: __taint_sink(result)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/jsbenchmark/completeness/single_app_tracing/asynchronous_tracing/promise_callback_await/asynchronous_promise_001_T\",\"functionName\":\"asynchronous_promise_001_T\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /jsbenchmark/completeness/single_app_tracing/asynchronous_tracing/promise_callback_await/asynchronous_promise_001_T\n AffectedNodeName: __taint_src\n 11: SOURCE: function asynchronous_promise_001_T(__taint_src) {\n /jsbenchmark/completeness/single_app_tracing/asynchronous_tracing/promise_callback_await/asynchronous_promise_001_T\n AffectedNodeName: resolve\n 13: CALL: resolve(__taint_src);\n /jsbenchmark/completeness/single_app_tracing/asynchronous_tracing/promise_callback_await/asynchronous_promise_001_T\n AffectedNodeName: \n 16: CALL: promise\n 17: CALL: .then((result) => {\n 18: CALL: __taint_sink(result);\n 19: CALL: })\n /jsbenchmark/completeness/single_app_tracing/asynchronous_tracing/promise_callback_await/asynchronous_promise_001_T\n AffectedNodeName: result\n 17: ARG PASS: .then((result) => {\n /jsbenchmark/completeness/single_app_tracing/asynchronous_tracing/promise_callback_await/asynchronous_promise_001_T\n AffectedNodeName: __taint_sink\n 18: SINK: __taint_sink(result);\n==========================================================\n #Total-findings:1\n==========================================================","/jsbenchmark/completeness/single_app_tracing/asynchronous_tracing/promise_callback_await/asynchronous_promise_002_F":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/completeness/single_app_tracing/asynchronous_tracing/promise_callback_await/asynchronous_promise_003_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/jsbenchmark/completeness/single_app_tracing/asynchronous_tracing/promise_callback_await/asynchronous_promise_003_T\nLine 18: __taint_sink(value)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/jsbenchmark/completeness/single_app_tracing/asynchronous_tracing/promise_callback_await/asynchronous_promise_003_T\",\"functionName\":\"asynchronous_promise_003_T\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /jsbenchmark/completeness/single_app_tracing/asynchronous_tracing/promise_callback_await/asynchronous_promise_003_T\n AffectedNodeName: __taint_src\n 11: SOURCE: function asynchronous_promise_003_T(__taint_src) {\n /jsbenchmark/completeness/single_app_tracing/asynchronous_tracing/promise_callback_await/asynchronous_promise_003_T\n AffectedNodeName: asyncFunc\n 18: CALL: asyncFunc(__taint_src).then((value) => __taint_sink(value));\n /jsbenchmark/completeness/single_app_tracing/asynchronous_tracing/promise_callback_await/asynchronous_promise_003_T\n AffectedNodeName: value\n 12: ARG PASS: function asyncFunc(value) {\n /jsbenchmark/completeness/single_app_tracing/asynchronous_tracing/promise_callback_await/asynchronous_promise_003_T\n AffectedNodeName: resolve\n 14: CALL: setTimeout(() => resolve(value), 10);\n /jsbenchmark/completeness/single_app_tracing/asynchronous_tracing/promise_callback_await/asynchronous_promise_003_T\n AffectedNodeName: \n 18: CALL: asyncFunc(__taint_src).then((value) => __taint_sink(value));\n /jsbenchmark/completeness/single_app_tracing/asynchronous_tracing/promise_callback_await/asynchronous_promise_003_T\n AffectedNodeName: value\n 18: ARG PASS: asyncFunc(__taint_src).then((value) => __taint_sink(value));\n /jsbenchmark/completeness/single_app_tracing/asynchronous_tracing/promise_callback_await/asynchronous_promise_003_T\n AffectedNodeName: __taint_sink\n 18: SINK: asyncFunc(__taint_src).then((value) => __taint_sink(value));\n==========================================================\n #Total-findings:1\n==========================================================","/jsbenchmark/completeness/single_app_tracing/asynchronous_tracing/promise_callback_await/asynchronous_promise_004_F":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/completeness/single_app_tracing/asynchronous_tracing/promise_callback_await/asynchronous_promise_005_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/jsbenchmark/completeness/single_app_tracing/asynchronous_tracing/promise_callback_await/asynchronous_promise_005_T\nLine 18: __taint_sink(result)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/jsbenchmark/completeness/single_app_tracing/asynchronous_tracing/promise_callback_await/asynchronous_promise_005_T\",\"functionName\":\"asynchronous_promise_005_T\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /jsbenchmark/completeness/single_app_tracing/asynchronous_tracing/promise_callback_await/asynchronous_promise_005_T\n AffectedNodeName: __taint_src\n 11: SOURCE: function asynchronous_promise_005_T(__taint_src) {\n /jsbenchmark/completeness/single_app_tracing/asynchronous_tracing/promise_callback_await/asynchronous_promise_005_T\n AffectedNodeName: resolve\n 13: CALL: resolve(__taint_src);\n /jsbenchmark/completeness/single_app_tracing/asynchronous_tracing/promise_callback_await/asynchronous_promise_005_T\n AffectedNodeName: \n 16: CALL: promise\n 17: CALL: .then((result) => {\n 18: CALL: __taint_sink(result);\n 19: CALL: })\n /jsbenchmark/completeness/single_app_tracing/asynchronous_tracing/promise_callback_await/asynchronous_promise_005_T\n AffectedNodeName: result\n 17: ARG PASS: .then((result) => {\n /jsbenchmark/completeness/single_app_tracing/asynchronous_tracing/promise_callback_await/asynchronous_promise_005_T\n AffectedNodeName: __taint_sink\n 18: SINK: __taint_sink(result);\n==========================================================\n #Total-findings:1\n==========================================================","/jsbenchmark/completeness/single_app_tracing/asynchronous_tracing/promise_callback_await/asynchronous_promise_006_F":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/completeness/single_app_tracing/asynchronous_tracing/promise_callback_await/asynchronous_promise_007_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/jsbenchmark/completeness/single_app_tracing/asynchronous_tracing/promise_callback_await/asynchronous_promise_007_T\nLine 24: __taint_sink(final)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/jsbenchmark/completeness/single_app_tracing/asynchronous_tracing/promise_callback_await/asynchronous_promise_007_T\",\"functionName\":\"asynchronous_promise_007_T\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /jsbenchmark/completeness/single_app_tracing/asynchronous_tracing/promise_callback_await/asynchronous_promise_007_T\n AffectedNodeName: __taint_src\n 11: SOURCE: function asynchronous_promise_007_T(__taint_src) {\n /jsbenchmark/completeness/single_app_tracing/asynchronous_tracing/promise_callback_await/asynchronous_promise_007_T\n AffectedNodeName: resolve\n 13: CALL: resolve(__taint_src);\n /jsbenchmark/completeness/single_app_tracing/asynchronous_tracing/promise_callback_await/asynchronous_promise_007_T\n AffectedNodeName: \n 16: CALL: promise\n 17: CALL: .then((result) => {\n 18: CALL: final = result;\n 19: CALL: })\n /jsbenchmark/completeness/single_app_tracing/asynchronous_tracing/promise_callback_await/asynchronous_promise_007_T\n AffectedNodeName: result\n 17: ARG PASS: .then((result) => {\n /jsbenchmark/completeness/single_app_tracing/asynchronous_tracing/promise_callback_await/asynchronous_promise_007_T\n AffectedNodeName: final\n 18: Var Pass: final = result;\n /jsbenchmark/completeness/single_app_tracing/asynchronous_tracing/promise_callback_await/asynchronous_promise_007_T\n AffectedNodeName: __taint_sink\n 24: SINK: __taint_sink(final);\n==========================================================\n #Total-findings:1\n==========================================================","/jsbenchmark/completeness/single_app_tracing/asynchronous_tracing/promise_callback_await/asynchronous_promise_008_F":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/completeness/single_app_tracing/asynchronous_tracing/promise_callback_await/asynchronous_promise_009_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/jsbenchmark/completeness/single_app_tracing/asynchronous_tracing/promise_callback_await/asynchronous_promise_009_T\nLine 20: __taint_sink(result)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/jsbenchmark/completeness/single_app_tracing/asynchronous_tracing/promise_callback_await/asynchronous_promise_009_T\",\"functionName\":\"asynchronous_promise_009_T\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /jsbenchmark/completeness/single_app_tracing/asynchronous_tracing/promise_callback_await/asynchronous_promise_009_T\n AffectedNodeName: __taint_src\n 11: SOURCE: function asynchronous_promise_009_T(__taint_src) {\n /jsbenchmark/completeness/single_app_tracing/asynchronous_tracing/promise_callback_await/asynchronous_promise_009_T\n AffectedNodeName: resolve\n 13: CALL: resolve(__taint_src);\n /jsbenchmark/completeness/single_app_tracing/asynchronous_tracing/promise_callback_await/asynchronous_promise_009_T\n AffectedNodeName: \n 16: CALL: promise\n 17: CALL: .then((result) => result + \"_1\")\n /jsbenchmark/completeness/single_app_tracing/asynchronous_tracing/promise_callback_await/asynchronous_promise_009_T\n AffectedNodeName: result\n 17: ARG PASS: .then((result) => result + \"_1\")\n /jsbenchmark/completeness/single_app_tracing/asynchronous_tracing/promise_callback_await/asynchronous_promise_009_T\n AffectedNodeName: [return value]\n 17: Return Value: .then((result) => result + \"_1\")\n /jsbenchmark/completeness/single_app_tracing/asynchronous_tracing/promise_callback_await/asynchronous_promise_009_T\n AffectedNodeName: \n 16: CALL RETURN: promise\n 17: CALL RETURN: .then((result) => result + \"_1\")\n /jsbenchmark/completeness/single_app_tracing/asynchronous_tracing/promise_callback_await/asynchronous_promise_009_T\n AffectedNodeName: \n 16: CALL: promise\n 17: CALL: .then((result) => result + \"_1\")\n 18: CALL: .then((result) => result + \"_2\")\n /jsbenchmark/completeness/single_app_tracing/asynchronous_tracing/promise_callback_await/asynchronous_promise_009_T\n AffectedNodeName: result\n 18: ARG PASS: .then((result) => result + \"_2\")\n /jsbenchmark/completeness/single_app_tracing/asynchronous_tracing/promise_callback_await/asynchronous_promise_009_T\n AffectedNodeName: [return value]\n 18: Return Value: .then((result) => result + \"_2\")\n /jsbenchmark/completeness/single_app_tracing/asynchronous_tracing/promise_callback_await/asynchronous_promise_009_T\n AffectedNodeName: \n 16: CALL RETURN: promise\n 17: CALL RETURN: .then((result) => result + \"_1\")\n 18: CALL RETURN: .then((result) => result + \"_2\")\n /jsbenchmark/completeness/single_app_tracing/asynchronous_tracing/promise_callback_await/asynchronous_promise_009_T\n AffectedNodeName: \n 16: CALL: promise\n 17: CALL: .then((result) => result + \"_1\")\n 18: CALL: .then((result) => result + \"_2\")\n 19: CALL: .then((result) => {\n 20: CALL: __taint_sink(result);\n 21: CALL: });\n /jsbenchmark/completeness/single_app_tracing/asynchronous_tracing/promise_callback_await/asynchronous_promise_009_T\n AffectedNodeName: result\n 19: ARG PASS: .then((result) => {\n /jsbenchmark/completeness/single_app_tracing/asynchronous_tracing/promise_callback_await/asynchronous_promise_009_T\n AffectedNodeName: __taint_sink\n 20: SINK: __taint_sink(result);\n==========================================================\n #Total-findings:1\n==========================================================","/jsbenchmark/completeness/single_app_tracing/asynchronous_tracing/promise_callback_await/asynchronous_promise_010_F":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/completeness/single_app_tracing/asynchronous_tracing/promise_callback_await/asynchronous_promise_011_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/jsbenchmark/completeness/single_app_tracing/asynchronous_tracing/promise_callback_await/asynchronous_promise_011_T\nLine 19: __taint_sink(error)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/jsbenchmark/completeness/single_app_tracing/asynchronous_tracing/promise_callback_await/asynchronous_promise_011_T\",\"functionName\":\"asynchronous_promise_011_T\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /jsbenchmark/completeness/single_app_tracing/asynchronous_tracing/promise_callback_await/asynchronous_promise_011_T\n AffectedNodeName: __taint_src\n 11: SOURCE: function asynchronous_promise_011_T(__taint_src) {\n /jsbenchmark/completeness/single_app_tracing/asynchronous_tracing/promise_callback_await/asynchronous_promise_011_T\n AffectedNodeName: reject\n 13: CALL: reject(__taint_src);\n /jsbenchmark/completeness/single_app_tracing/asynchronous_tracing/promise_callback_await/asynchronous_promise_011_T\n AffectedNodeName: \n 16: CALL: promise\n 17: CALL: .then((result) => {})\n 18: CALL: .catch((error) => {\n 19: CALL: __taint_sink(error);\n 20: CALL: });\n /jsbenchmark/completeness/single_app_tracing/asynchronous_tracing/promise_callback_await/asynchronous_promise_011_T\n AffectedNodeName: error\n 18: ARG PASS: .catch((error) => {\n /jsbenchmark/completeness/single_app_tracing/asynchronous_tracing/promise_callback_await/asynchronous_promise_011_T\n AffectedNodeName: __taint_sink\n 19: SINK: __taint_sink(error);\n==========================================================\n #Total-findings:1\n==========================================================","/jsbenchmark/completeness/single_app_tracing/asynchronous_tracing/promise_callback_await/asynchronous_promise_012_F":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/completeness/single_app_tracing/asynchronous_tracing/promise_callback_await/asynchronous_promisify_001_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/jsbenchmark/completeness/single_app_tracing/asynchronous_tracing/promise_callback_await/asynchronous_promisify_001_T\nLine 26: __taint_sink(data)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/jsbenchmark/completeness/single_app_tracing/asynchronous_tracing/promise_callback_await/asynchronous_promisify_001_T\",\"functionName\":\"asynchronous_promisify_001_T\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /jsbenchmark/completeness/single_app_tracing/asynchronous_tracing/promise_callback_await/asynchronous_promisify_001_T\n AffectedNodeName: __taint_src\n 22: SOURCE: async function asynchronous_promisify_001_T(__taint_src) {\n /jsbenchmark/completeness/single_app_tracing/asynchronous_tracing/promise_callback_await/asynchronous_promisify_001_T\n AffectedNodeName: data\n 25: Var Pass: let data = await readFileAsync(__taint_src);\n /jsbenchmark/completeness/single_app_tracing/asynchronous_tracing/promise_callback_await/asynchronous_promisify_001_T\n AffectedNodeName: __taint_sink\n 26: SINK: __taint_sink(data);\n==========================================================\n #Total-findings:1\n==========================================================","/jsbenchmark/completeness/single_app_tracing/asynchronous_tracing/promise_callback_await/asynchronous_promisify_002_F":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/completeness/single_app_tracing/class/complex_object/cross_class_001_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/jsbenchmark/completeness/single_app_tracing/class/complex_object/cross_class_001_T\nLine 29: __taint_sink(obj)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/jsbenchmark/completeness/single_app_tracing/class/complex_object/cross_class_001_T\",\"functionName\":\"cross_class_001_T\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /jsbenchmark/completeness/single_app_tracing/class/complex_object/cross_class_001_T\n AffectedNodeName: __taint_src\n 11: SOURCE: function cross_class_001_T(__taint_src) {\n /jsbenchmark/completeness/single_app_tracing/class/complex_object/cross_class_001_T\n AffectedNodeName: this.data\n 14: Var Pass: this.data = __taint_src;\n /jsbenchmark/completeness/single_app_tracing/class/complex_object/cross_class_001_T\n AffectedNodeName: getData\n 24: CALL: this.data = new A().getData();\n /jsbenchmark/completeness/single_app_tracing/class/complex_object/cross_class_001_T\n AffectedNodeName: new A()\n 24: ARG PASS: this.data = new A().getData();\n /jsbenchmark/completeness/single_app_tracing/class/complex_object/cross_class_001_T\n AffectedNodeName: [return value]\n 18: Return Value: return this.data;\n /jsbenchmark/completeness/single_app_tracing/class/complex_object/cross_class_001_T\n AffectedNodeName: getData\n 24: CALL RETURN: this.data = new A().getData();\n /jsbenchmark/completeness/single_app_tracing/class/complex_object/cross_class_001_T\n AffectedNodeName: this.data\n 24: Var Pass: this.data = new A().getData();\n /jsbenchmark/completeness/single_app_tracing/class/complex_object/cross_class_001_T\n AffectedNodeName: obj\n 28: Var Pass: let obj = new B();\n /jsbenchmark/completeness/single_app_tracing/class/complex_object/cross_class_001_T\n AffectedNodeName: __taint_sink\n 29: SINK: __taint_sink(obj);\n==========================================================\n #Total-findings:1\n==========================================================","/jsbenchmark/completeness/single_app_tracing/class/complex_object/cross_class_002_F":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/completeness/single_app_tracing/class/complex_object/cross_class_003_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/jsbenchmark/completeness/single_app_tracing/class/complex_object/cross_class_003_T\nLine 36: __taint_sink(a)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/jsbenchmark/completeness/single_app_tracing/class/complex_object/cross_class_003_T\",\"functionName\":\"cross_class_003_T\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /jsbenchmark/completeness/single_app_tracing/class/complex_object/cross_class_003_T\n AffectedNodeName: __taint_src\n 11: SOURCE: function cross_class_003_T(__taint_src) {\n /jsbenchmark/completeness/single_app_tracing/class/complex_object/cross_class_003_T\n AffectedNodeName: setData\n 35: CALL: b.setData(__taint_src);\n /jsbenchmark/completeness/single_app_tracing/class/complex_object/cross_class_003_T\n AffectedNodeName: data\n 28: ARG PASS: setData(data) {\n /jsbenchmark/completeness/single_app_tracing/class/complex_object/cross_class_003_T\n AffectedNodeName: this.data\n 29: Var Pass: this.data = data;\n /jsbenchmark/completeness/single_app_tracing/class/complex_object/cross_class_003_T\n AffectedNodeName: __taint_sink\n 36: SINK: __taint_sink(a);\n==========================================================\n #Total-findings:1\n==========================================================","/jsbenchmark/completeness/single_app_tracing/class/complex_object/cross_class_004_F":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/completeness/single_app_tracing/class/simple_object/simple_object_001_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/jsbenchmark/completeness/single_app_tracing/class/simple_object/simple_object_001_T\nLine 19: __taint_sink(obj)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/jsbenchmark/completeness/single_app_tracing/class/simple_object/simple_object_001_T\",\"functionName\":\"simple_object_001_T\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /jsbenchmark/completeness/single_app_tracing/class/simple_object/simple_object_001_T\n AffectedNodeName: __taint_src\n 11: SOURCE: function simple_object_001_T(__taint_src) {\n /jsbenchmark/completeness/single_app_tracing/class/simple_object/simple_object_001_T\n AffectedNodeName: constructor\n 18: CALL: let obj = new A(__taint_src);\n /jsbenchmark/completeness/single_app_tracing/class/simple_object/simple_object_001_T\n AffectedNodeName: data\n 13: ARG PASS: constructor(data) {\n /jsbenchmark/completeness/single_app_tracing/class/simple_object/simple_object_001_T\n AffectedNodeName: this.data\n 14: Var Pass: this.data = data;\n /jsbenchmark/completeness/single_app_tracing/class/simple_object/simple_object_001_T\n AffectedNodeName: obj\n 18: Var Pass: let obj = new A(__taint_src);\n /jsbenchmark/completeness/single_app_tracing/class/simple_object/simple_object_001_T\n AffectedNodeName: __taint_sink\n 19: SINK: __taint_sink(obj);\n==========================================================\n #Total-findings:1\n==========================================================","/jsbenchmark/completeness/single_app_tracing/class/simple_object/simple_object_002_F":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/completeness/single_app_tracing/class/simple_object/simple_object_prototype_001_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/jsbenchmark/completeness/single_app_tracing/class/simple_object/simple_object_prototype_001_T\nLine 18: __taint_sink(person.name)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/jsbenchmark/completeness/single_app_tracing/class/simple_object/simple_object_prototype_001_T\",\"functionName\":\"simple_object_prototype_001_T\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /jsbenchmark/completeness/single_app_tracing/class/simple_object/simple_object_prototype_001_T\n AffectedNodeName: __taint_src\n 11: SOURCE: function simple_object_prototype_001_T(__taint_src) {\n /jsbenchmark/completeness/single_app_tracing/class/simple_object/simple_object_prototype_001_T\n AffectedNodeName: Person.prototype.name\n 14: Var Pass: Person.prototype.name = __taint_src;\n /jsbenchmark/completeness/single_app_tracing/class/simple_object/simple_object_prototype_001_T\n AffectedNodeName: person\n 16: Var Pass: let person = new Person();\n /jsbenchmark/completeness/single_app_tracing/class/simple_object/simple_object_prototype_001_T\n AffectedNodeName: __taint_sink\n 18: SINK: __taint_sink(person.name);\n==========================================================\n #Total-findings:1\n==========================================================","/jsbenchmark/completeness/single_app_tracing/class/simple_object/simple_object_prototype_002_F":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/completeness/single_app_tracing/class/simple_object/simple_object_prototype_003_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/jsbenchmark/completeness/single_app_tracing/class/simple_object/simple_object_prototype_003_T\nLine 18: __taint_sink(person.__proto__.name)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/jsbenchmark/completeness/single_app_tracing/class/simple_object/simple_object_prototype_003_T\",\"functionName\":\"simple_object_prototype_003_T\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /jsbenchmark/completeness/single_app_tracing/class/simple_object/simple_object_prototype_003_T\n AffectedNodeName: __taint_src\n 11: SOURCE: function simple_object_prototype_003_T(__taint_src) {\n /jsbenchmark/completeness/single_app_tracing/class/simple_object/simple_object_prototype_003_T\n AffectedNodeName: Person.prototype.name\n 14: Var Pass: Person.prototype.name = __taint_src;\n /jsbenchmark/completeness/single_app_tracing/class/simple_object/simple_object_prototype_003_T\n AffectedNodeName: person\n 16: Var Pass: let person = new Person();\n /jsbenchmark/completeness/single_app_tracing/class/simple_object/simple_object_prototype_003_T\n AffectedNodeName: __taint_sink\n 18: SINK: __taint_sink(person.__proto__.name);\n==========================================================\n #Total-findings:1\n==========================================================","/jsbenchmark/completeness/single_app_tracing/class/simple_object/simple_object_prototype_004_F":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/completeness/single_app_tracing/control_flow/conditional_stmt/conditional_if_001_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/jsbenchmark/completeness/single_app_tracing/control_flow/conditional_stmt/conditional_if_001_T\nLine 13: __taint_sink(__taint_src)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/jsbenchmark/completeness/single_app_tracing/control_flow/conditional_stmt/conditional_if_001_T\",\"functionName\":\"conditional_if_001_T\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /jsbenchmark/completeness/single_app_tracing/control_flow/conditional_stmt/conditional_if_001_T\n AffectedNodeName: __taint_src\n 11: SOURCE: function conditional_if_001_T(__taint_src) {\n /jsbenchmark/completeness/single_app_tracing/control_flow/conditional_stmt/conditional_if_001_T\n AffectedNodeName: __taint_sink\n 13: SINK: __taint_sink(__taint_src);\n==========================================================\n #Total-findings:1\n==========================================================","/jsbenchmark/completeness/single_app_tracing/control_flow/conditional_stmt/conditional_if_002_F":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/completeness/single_app_tracing/control_flow/conditional_stmt/conditional_if_003_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/jsbenchmark/completeness/single_app_tracing/control_flow/conditional_stmt/conditional_if_003_T\nLine 14: __taint_sink(__taint_src)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/jsbenchmark/completeness/single_app_tracing/control_flow/conditional_stmt/conditional_if_003_T\",\"functionName\":\"conditional_if_003_T\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /jsbenchmark/completeness/single_app_tracing/control_flow/conditional_stmt/conditional_if_003_T\n AffectedNodeName: __taint_src\n 11: SOURCE: function conditional_if_003_T(__taint_src) {\n /jsbenchmark/completeness/single_app_tracing/control_flow/conditional_stmt/conditional_if_003_T\n AffectedNodeName: __taint_sink\n 14: SINK: __taint_sink(__taint_src);\n==========================================================\n #Total-findings:1\n==========================================================","/jsbenchmark/completeness/single_app_tracing/control_flow/conditional_stmt/conditional_if_004_F":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/completeness/single_app_tracing/control_flow/conditional_stmt/conditional_if_005_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/jsbenchmark/completeness/single_app_tracing/control_flow/conditional_stmt/conditional_if_005_T\nLine 14: __taint_sink(__taint_src)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/jsbenchmark/completeness/single_app_tracing/control_flow/conditional_stmt/conditional_if_005_T\",\"functionName\":\"conditional_if_005_T\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /jsbenchmark/completeness/single_app_tracing/control_flow/conditional_stmt/conditional_if_005_T\n AffectedNodeName: __taint_src\n 11: SOURCE: function conditional_if_005_T(__taint_src) {\n /jsbenchmark/completeness/single_app_tracing/control_flow/conditional_stmt/conditional_if_005_T\n AffectedNodeName: __taint_sink\n 14: SINK: __taint_sink(__taint_src);\n==========================================================\n #Total-findings:1\n==========================================================","/jsbenchmark/completeness/single_app_tracing/control_flow/conditional_stmt/conditional_if_006_F":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/completeness/single_app_tracing/control_flow/conditional_stmt/conditional_switch_001_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/jsbenchmark/completeness/single_app_tracing/control_flow/conditional_stmt/conditional_switch_001_T\nLine 14: __taint_sink(__taint_src)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/jsbenchmark/completeness/single_app_tracing/control_flow/conditional_stmt/conditional_switch_001_T\",\"functionName\":\"conditional_switch_001_T\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /jsbenchmark/completeness/single_app_tracing/control_flow/conditional_stmt/conditional_switch_001_T\n AffectedNodeName: __taint_src\n 11: SOURCE: function conditional_switch_001_T(__taint_src) {\n /jsbenchmark/completeness/single_app_tracing/control_flow/conditional_stmt/conditional_switch_001_T\n AffectedNodeName: __taint_sink\n 14: SINK: __taint_sink(__taint_src);\n==========================================================\n #Total-findings:1\n==========================================================","/jsbenchmark/completeness/single_app_tracing/control_flow/conditional_stmt/conditional_switch_002_F":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/completeness/single_app_tracing/control_flow/loop_stmt/dowhile_body_001_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/jsbenchmark/completeness/single_app_tracing/control_flow/loop_stmt/dowhile_body_001_T\nLine 15: __taint_sink(res)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/jsbenchmark/completeness/single_app_tracing/control_flow/loop_stmt/dowhile_body_001_T\",\"functionName\":\"dowhile_body_001_T\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /jsbenchmark/completeness/single_app_tracing/control_flow/loop_stmt/dowhile_body_001_T\n AffectedNodeName: __taint_src\n 11: SOURCE: function dowhile_body_001_T(__taint_src) {\n /jsbenchmark/completeness/single_app_tracing/control_flow/loop_stmt/dowhile_body_001_T\n AffectedNodeName: res\n 14: Var Pass: res = res + __taint_src;\n /jsbenchmark/completeness/single_app_tracing/control_flow/loop_stmt/dowhile_body_001_T\n AffectedNodeName: __taint_sink\n 15: SINK: } while (__taint_sink(res));\n==========================================================\n #Total-findings:1\n==========================================================","/jsbenchmark/completeness/single_app_tracing/control_flow/loop_stmt/dowhile_body_002_F":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/completeness/single_app_tracing/control_flow/loop_stmt/every_001_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/jsbenchmark/completeness/single_app_tracing/control_flow/loop_stmt/every_001_T\nLine 14: __taint_sink(item)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/jsbenchmark/completeness/single_app_tracing/control_flow/loop_stmt/every_001_T\",\"functionName\":\"every_001_T\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /jsbenchmark/completeness/single_app_tracing/control_flow/loop_stmt/every_001_T\n AffectedNodeName: __taint_src\n 11: SOURCE: function every_001_T(__taint_src) {\n /jsbenchmark/completeness/single_app_tracing/control_flow/loop_stmt/every_001_T\n AffectedNodeName: arr\n 12: Var Pass: let arr = [\"a\", \"b\", __taint_src];\n /jsbenchmark/completeness/single_app_tracing/control_flow/loop_stmt/every_001_T\n AffectedNodeName: \n 13: CALL: arr.every(function (item) {\n 14: CALL: __taint_sink(item);\n 15: CALL: });\n /jsbenchmark/completeness/single_app_tracing/control_flow/loop_stmt/every_001_T\n AffectedNodeName: item\n 13: ARG PASS: arr.every(function (item) {\n /jsbenchmark/completeness/single_app_tracing/control_flow/loop_stmt/every_001_T\n AffectedNodeName: __taint_sink\n 14: SINK: __taint_sink(item);\n==========================================================\n #Total-findings:1\n==========================================================","/jsbenchmark/completeness/single_app_tracing/control_flow/loop_stmt/every_002_F":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/completeness/single_app_tracing/control_flow/loop_stmt/for_body_001_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/jsbenchmark/completeness/single_app_tracing/control_flow/loop_stmt/for_body_001_T\nLine 17: __taint_sink(res)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/jsbenchmark/completeness/single_app_tracing/control_flow/loop_stmt/for_body_001_T\",\"functionName\":\"for_body_001_T\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /jsbenchmark/completeness/single_app_tracing/control_flow/loop_stmt/for_body_001_T\n AffectedNodeName: __taint_src\n 11: SOURCE: function for_body_001_T(__taint_src) {\n /jsbenchmark/completeness/single_app_tracing/control_flow/loop_stmt/for_body_001_T\n AffectedNodeName: res\n 15: Var Pass: res = __taint_src;\n /jsbenchmark/completeness/single_app_tracing/control_flow/loop_stmt/for_body_001_T\n AffectedNodeName: __taint_sink\n 17: SINK: __taint_sink(res);\n==========================================================\n #Total-findings:1\n==========================================================","/jsbenchmark/completeness/single_app_tracing/control_flow/loop_stmt/for_body_002_F":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/completeness/single_app_tracing/control_flow/loop_stmt/for_init_001_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/jsbenchmark/completeness/single_app_tracing/control_flow/loop_stmt/for_init_001_T\nLine 18: __taint_sink(res)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/jsbenchmark/completeness/single_app_tracing/control_flow/loop_stmt/for_init_001_T\",\"functionName\":\"for_init_001_T\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /jsbenchmark/completeness/single_app_tracing/control_flow/loop_stmt/for_init_001_T\n AffectedNodeName: __taint_src\n 11: SOURCE: function for_init_001_T(__taint_src) {\n /jsbenchmark/completeness/single_app_tracing/control_flow/loop_stmt/for_init_001_T\n AffectedNodeName: ini\n 15: Var Pass: for (ini = __taint_src; j < 10; j++) {\n /jsbenchmark/completeness/single_app_tracing/control_flow/loop_stmt/for_init_001_T\n AffectedNodeName: res\n 16: Var Pass: res = res + ini;\n /jsbenchmark/completeness/single_app_tracing/control_flow/loop_stmt/for_init_001_T\n AffectedNodeName: __taint_sink\n 18: SINK: __taint_sink(res);\n==========================================================\n #Total-findings:1\n==========================================================","/jsbenchmark/completeness/single_app_tracing/control_flow/loop_stmt/for_init_002_F":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/completeness/single_app_tracing/control_flow/loop_stmt/for_update_001_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/jsbenchmark/completeness/single_app_tracing/control_flow/loop_stmt/for_update_001_T\nLine 19: __taint_sink(res)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/jsbenchmark/completeness/single_app_tracing/control_flow/loop_stmt/for_update_001_T\",\"functionName\":\"for_update_001_T\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /jsbenchmark/completeness/single_app_tracing/control_flow/loop_stmt/for_update_001_T\n AffectedNodeName: __taint_src\n 11: SOURCE: function for_update_001_T(__taint_src) {\n /jsbenchmark/completeness/single_app_tracing/control_flow/loop_stmt/for_update_001_T\n AffectedNodeName: j\n 15: Var Pass: for (; ini < 2; j = __taint_src) {\n /jsbenchmark/completeness/single_app_tracing/control_flow/loop_stmt/for_update_001_T\n AffectedNodeName: res\n 16: Var Pass: res = j;\n /jsbenchmark/completeness/single_app_tracing/control_flow/loop_stmt/for_update_001_T\n AffectedNodeName: __taint_sink\n 19: SINK: __taint_sink(res);\n==========================================================\n #Total-findings:1\n==========================================================","/jsbenchmark/completeness/single_app_tracing/control_flow/loop_stmt/for_update_002_F":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/completeness/single_app_tracing/control_flow/loop_stmt/foreach_001_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/jsbenchmark/completeness/single_app_tracing/control_flow/loop_stmt/foreach_001_T\nLine 15: __taint_sink(item)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/jsbenchmark/completeness/single_app_tracing/control_flow/loop_stmt/foreach_001_T\",\"functionName\":\"foreach_001_T\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /jsbenchmark/completeness/single_app_tracing/control_flow/loop_stmt/foreach_001_T\n AffectedNodeName: __taint_src\n 11: SOURCE: function foreach_001_T(__taint_src) {\n /jsbenchmark/completeness/single_app_tracing/control_flow/loop_stmt/foreach_001_T\n AffectedNodeName: arr\n 12: Var Pass: let arr = [\"a\", \"b\", __taint_src];\n /jsbenchmark/completeness/single_app_tracing/control_flow/loop_stmt/foreach_001_T\n AffectedNodeName: \n 14: CALL: arr.forEach(function (item) {\n 15: CALL: __taint_sink(item);\n 16: CALL: });\n /jsbenchmark/completeness/single_app_tracing/control_flow/loop_stmt/foreach_001_T\n AffectedNodeName: item\n 14: ARG PASS: arr.forEach(function (item) {\n /jsbenchmark/completeness/single_app_tracing/control_flow/loop_stmt/foreach_001_T\n AffectedNodeName: __taint_sink\n 15: SINK: __taint_sink(item);\n==========================================================\n #Total-findings:1\n==========================================================","/jsbenchmark/completeness/single_app_tracing/control_flow/loop_stmt/foreach_002_F":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/completeness/single_app_tracing/control_flow/loop_stmt/forin_body_001_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/jsbenchmark/completeness/single_app_tracing/control_flow/loop_stmt/forin_body_001_T\nLine 19: __taint_sink(res)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/jsbenchmark/completeness/single_app_tracing/control_flow/loop_stmt/forin_body_001_T\",\"functionName\":\"forin_body_001_T\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /jsbenchmark/completeness/single_app_tracing/control_flow/loop_stmt/forin_body_001_T\n AffectedNodeName: __taint_src\n 11: SOURCE: function forin_body_001_T(__taint_src) {\n /jsbenchmark/completeness/single_app_tracing/control_flow/loop_stmt/forin_body_001_T\n AffectedNodeName: obj\n 12: Var Pass: let obj = { key1: \"value1\", key2: __taint_src };\n /jsbenchmark/completeness/single_app_tracing/control_flow/loop_stmt/forin_body_001_T\n AffectedNodeName: __taint_sink\n 19: SINK: __taint_sink(res);\n==========================================================\n #Total-findings:1\n==========================================================","/jsbenchmark/completeness/single_app_tracing/control_flow/loop_stmt/forin_body_002_F":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/completeness/single_app_tracing/control_flow/loop_stmt/forof_body_001_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/jsbenchmark/completeness/single_app_tracing/control_flow/loop_stmt/forof_body_001_T\nLine 17: __taint_sink(res)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/jsbenchmark/completeness/single_app_tracing/control_flow/loop_stmt/forof_body_001_T\",\"functionName\":\"forof_body_001_T\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /jsbenchmark/completeness/single_app_tracing/control_flow/loop_stmt/forof_body_001_T\n AffectedNodeName: __taint_src\n 11: SOURCE: function forof_body_001_T(__taint_src) {\n /jsbenchmark/completeness/single_app_tracing/control_flow/loop_stmt/forof_body_001_T\n AffectedNodeName: arr\n 12: Var Pass: let arr = [\"a\", \"b\", __taint_src];\n /jsbenchmark/completeness/single_app_tracing/control_flow/loop_stmt/forof_body_001_T\n AffectedNodeName: value\n 14: Var Pass: for (let value of arr) {\n 15: Var Pass: res = value;\n 16: Var Pass: }\n /jsbenchmark/completeness/single_app_tracing/control_flow/loop_stmt/forof_body_001_T\n AffectedNodeName: res\n 15: Var Pass: res = value;\n /jsbenchmark/completeness/single_app_tracing/control_flow/loop_stmt/forof_body_001_T\n AffectedNodeName: __taint_sink\n 17: SINK: __taint_sink(res);\n==========================================================\n #Total-findings:1\n==========================================================","/jsbenchmark/completeness/single_app_tracing/control_flow/loop_stmt/forof_body_002_F":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/completeness/single_app_tracing/control_flow/loop_stmt/some_001_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/jsbenchmark/completeness/single_app_tracing/control_flow/loop_stmt/some_001_T\nLine 14: __taint_sink(item)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/jsbenchmark/completeness/single_app_tracing/control_flow/loop_stmt/some_001_T\",\"functionName\":\"some_001_T\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /jsbenchmark/completeness/single_app_tracing/control_flow/loop_stmt/some_001_T\n AffectedNodeName: __taint_src\n 11: SOURCE: function some_001_T(__taint_src) {\n /jsbenchmark/completeness/single_app_tracing/control_flow/loop_stmt/some_001_T\n AffectedNodeName: arr\n 12: Var Pass: let arr = [\"a\", \"b\", __taint_src];\n /jsbenchmark/completeness/single_app_tracing/control_flow/loop_stmt/some_001_T\n AffectedNodeName: \n 13: CALL: arr.some(function (item) {\n 14: CALL: __taint_sink(item);\n 15: CALL: });\n /jsbenchmark/completeness/single_app_tracing/control_flow/loop_stmt/some_001_T\n AffectedNodeName: item\n 13: ARG PASS: arr.some(function (item) {\n /jsbenchmark/completeness/single_app_tracing/control_flow/loop_stmt/some_001_T\n AffectedNodeName: __taint_sink\n 14: SINK: __taint_sink(item);\n==========================================================\n #Total-findings:1\n==========================================================","/jsbenchmark/completeness/single_app_tracing/control_flow/loop_stmt/some_002_F":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/completeness/single_app_tracing/control_flow/loop_stmt/while_body_001_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/jsbenchmark/completeness/single_app_tracing/control_flow/loop_stmt/while_body_001_T\nLine 18: __taint_sink(res)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/jsbenchmark/completeness/single_app_tracing/control_flow/loop_stmt/while_body_001_T\",\"functionName\":\"while_body_001_T\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /jsbenchmark/completeness/single_app_tracing/control_flow/loop_stmt/while_body_001_T\n AffectedNodeName: __taint_src\n 11: SOURCE: function while_body_001_T(__taint_src) {\n /jsbenchmark/completeness/single_app_tracing/control_flow/loop_stmt/while_body_001_T\n AffectedNodeName: res\n 15: Var Pass: res = res + __taint_src;\n /jsbenchmark/completeness/single_app_tracing/control_flow/loop_stmt/while_body_001_T\n AffectedNodeName: __taint_sink\n 18: SINK: __taint_sink(res);\n==========================================================\n #Total-findings:1\n==========================================================","/jsbenchmark/completeness/single_app_tracing/control_flow/loop_stmt/while_body_002_F":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/completeness/single_app_tracing/cross_file_package_namespace/cross_module/cross_module_001_T/A/cross_module_001_T_a":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/completeness/single_app_tracing/cross_file_package_namespace/cross_module/cross_module_001_T/B/cross_module_001_T_b":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/completeness/single_app_tracing/cross_file_package_namespace/cross_module/cross_module_002_F/A/cross_module_002_F_a":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/completeness/single_app_tracing/cross_file_package_namespace/cross_module/cross_module_002_F/B/cross_module_002_F_b":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/completeness/single_app_tracing/cross_file_package_namespace/cross_module/cross_module_003_T/A/cross_module_003_T_a":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/completeness/single_app_tracing/cross_file_package_namespace/cross_module/cross_module_003_T/B/cross_module_003_T_b":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/completeness/single_app_tracing/cross_file_package_namespace/cross_module/cross_module_004_F/A/cross_module_004_F_a":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/completeness/single_app_tracing/cross_file_package_namespace/cross_module/cross_module_004_F/B/cross_module_004_F_b":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/completeness/single_app_tracing/cross_file_package_namespace/cross_module/cross_module_005_T/A/cross_module_005_T_a":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/completeness/single_app_tracing/cross_file_package_namespace/cross_module/cross_module_005_T/B/cross_module_005_T_b":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/completeness/single_app_tracing/cross_file_package_namespace/cross_module/cross_module_006_F/A/cross_module_006_F_a":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/completeness/single_app_tracing/cross_file_package_namespace/cross_module/cross_module_006_F/B/cross_module_006_F_b":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/completeness/single_app_tracing/cross_file_package_namespace/cross_module/cross_module_007_T/A/cross_module_007_T_a":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/completeness/single_app_tracing/cross_file_package_namespace/cross_module/cross_module_007_T/B/cross_module_007_T_b":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/completeness/single_app_tracing/cross_file_package_namespace/cross_module/cross_module_008_F/A/cross_module_008_F_a":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/completeness/single_app_tracing/cross_file_package_namespace/cross_module/cross_module_008_F/B/cross_module_008_F_b":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/completeness/single_app_tracing/cross_file_package_namespace/cross_module/cross_module_009_T/A/cross_module_009_T_a":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/completeness/single_app_tracing/cross_file_package_namespace/cross_module/cross_module_009_T/B/cross_module_009_T_b":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/completeness/single_app_tracing/cross_file_package_namespace/cross_module/cross_module_010_F/A/cross_module_010_F_a":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/completeness/single_app_tracing/cross_file_package_namespace/cross_module/cross_module_010_F/B/cross_module_010_F_b":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/completeness/single_app_tracing/cross_file_package_namespace/cross_module/cross_module_011_T/A/cross_module_011_T_a":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/completeness/single_app_tracing/cross_file_package_namespace/cross_module/cross_module_011_T/B/cross_module_011_T_b":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/completeness/single_app_tracing/cross_file_package_namespace/cross_module/cross_module_012_F/A/cross_module_012_F_a":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/completeness/single_app_tracing/cross_file_package_namespace/cross_module/cross_module_012_F/B/cross_module_012_F_b":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/completeness/single_app_tracing/datatype/array/array_001_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/jsbenchmark/completeness/single_app_tracing/datatype/array/array_001_T\nLine 13: __taint_sink(s)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/jsbenchmark/completeness/single_app_tracing/datatype/array/array_001_T\",\"functionName\":\"array_001_T\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /jsbenchmark/completeness/single_app_tracing/datatype/array/array_001_T\n AffectedNodeName: __taint_src\n 11: SOURCE: function array_001_T(__taint_src) {\n /jsbenchmark/completeness/single_app_tracing/datatype/array/array_001_T\n AffectedNodeName: s\n 12: Var Pass: let s = [__taint_src, \"b\", \"c\"];\n /jsbenchmark/completeness/single_app_tracing/datatype/array/array_001_T\n AffectedNodeName: __taint_sink\n 13: SINK: __taint_sink(s);\n==========================================================\n #Total-findings:1\n==========================================================","/jsbenchmark/completeness/single_app_tracing/datatype/array/array_002_F":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/completeness/single_app_tracing/datatype/array/array_003_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/jsbenchmark/completeness/single_app_tracing/datatype/array/array_003_T\nLine 13: __taint_sink(s)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/jsbenchmark/completeness/single_app_tracing/datatype/array/array_003_T\",\"functionName\":\"array_003_T\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /jsbenchmark/completeness/single_app_tracing/datatype/array/array_003_T\n AffectedNodeName: __taint_src\n 11: SOURCE: function array_003_T(__taint_src) {\n /jsbenchmark/completeness/single_app_tracing/datatype/array/array_003_T\n AffectedNodeName: s\n 12: Var Pass: let s = [[__taint_src], [\"b\"], \"c\"];\n /jsbenchmark/completeness/single_app_tracing/datatype/array/array_003_T\n AffectedNodeName: __taint_sink\n 13: SINK: __taint_sink(s);\n==========================================================\n #Total-findings:1\n==========================================================","/jsbenchmark/completeness/single_app_tracing/datatype/array/array_004_F":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/completeness/single_app_tracing/datatype/array/array_005_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/jsbenchmark/completeness/single_app_tracing/datatype/array/array_005_T\nLine 14: __taint_sink(s)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/jsbenchmark/completeness/single_app_tracing/datatype/array/array_005_T\",\"functionName\":\"array_005_T\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /jsbenchmark/completeness/single_app_tracing/datatype/array/array_005_T\n AffectedNodeName: __taint_src\n 11: SOURCE: function array_005_T(__taint_src) {\n /jsbenchmark/completeness/single_app_tracing/datatype/array/array_005_T\n AffectedNodeName: push\n 13: CALL: s.push(__taint_src);\n /jsbenchmark/completeness/single_app_tracing/datatype/array/array_005_T\n AffectedNodeName: __taint_sink\n 14: SINK: __taint_sink(s);\n==========================================================\n #Total-findings:1\n==========================================================","/jsbenchmark/completeness/single_app_tracing/datatype/array/array_006_F":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/completeness/single_app_tracing/datatype/collections/set_001_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/jsbenchmark/completeness/single_app_tracing/datatype/collections/set_001_T\nLine 13: __taint_sink(set)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/jsbenchmark/completeness/single_app_tracing/datatype/collections/set_001_T\",\"functionName\":\"set_001_T\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /jsbenchmark/completeness/single_app_tracing/datatype/collections/set_001_T\n AffectedNodeName: __taint_src\n 11: SOURCE: function set_001_T(__taint_src) {\n /jsbenchmark/completeness/single_app_tracing/datatype/collections/set_001_T\n AffectedNodeName: set\n 12: Var Pass: let set = new Set(__taint_src);\n /jsbenchmark/completeness/single_app_tracing/datatype/collections/set_001_T\n AffectedNodeName: __taint_sink\n 13: SINK: __taint_sink(set);\n==========================================================\n #Total-findings:1\n==========================================================","/jsbenchmark/completeness/single_app_tracing/datatype/collections/set_002_F":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/completeness/single_app_tracing/datatype/map/map_001_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/jsbenchmark/completeness/single_app_tracing/datatype/map/map_001_T\nLine 14: __taint_sink(map)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/jsbenchmark/completeness/single_app_tracing/datatype/map/map_001_T\",\"functionName\":\"map_001_T\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /jsbenchmark/completeness/single_app_tracing/datatype/map/map_001_T\n AffectedNodeName: __taint_src\n 11: SOURCE: function map_001_T(__taint_src) {\n /jsbenchmark/completeness/single_app_tracing/datatype/map/map_001_T\n AffectedNodeName: set\n 13: CALL: map.set(\"key1\", __taint_src);\n /jsbenchmark/completeness/single_app_tracing/datatype/map/map_001_T\n AffectedNodeName: __taint_sink\n 14: SINK: __taint_sink(map);\n==========================================================\n #Total-findings:1\n==========================================================","/jsbenchmark/completeness/single_app_tracing/datatype/map/map_002_F":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/completeness/single_app_tracing/exception_error/exception_throw/exception_catch_001_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/jsbenchmark/completeness/single_app_tracing/exception_error/exception_throw/exception_catch_001_T\nLine 15: __taint_sink(e)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/jsbenchmark/completeness/single_app_tracing/exception_error/exception_throw/exception_catch_001_T\",\"functionName\":\"exception_catch_001_T\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /jsbenchmark/completeness/single_app_tracing/exception_error/exception_throw/exception_catch_001_T\n AffectedNodeName: __taint_src\n 11: SOURCE: function exception_catch_001_T(__taint_src) {\n /jsbenchmark/completeness/single_app_tracing/exception_error/exception_throw/exception_catch_001_T\n AffectedNodeName: __taint_src\n 13: Throw Pass: throw __taint_src;\n /jsbenchmark/completeness/single_app_tracing/exception_error/exception_throw/exception_catch_001_T\n AffectedNodeName: e\n 14: Var Pass: } catch (e) {\n /jsbenchmark/completeness/single_app_tracing/exception_error/exception_throw/exception_catch_001_T\n AffectedNodeName: __taint_sink\n 15: SINK: __taint_sink(e);\n==========================================================\n #Total-findings:1\n==========================================================","/jsbenchmark/completeness/single_app_tracing/exception_error/exception_throw/exception_catch_002_F":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/completeness/single_app_tracing/exception_error/exception_throw/exception_catch_003_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/jsbenchmark/completeness/single_app_tracing/exception_error/exception_throw/exception_catch_003_T\nLine 15: __taint_sink(e.message)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/jsbenchmark/completeness/single_app_tracing/exception_error/exception_throw/exception_catch_003_T\",\"functionName\":\"exception_catch_003_T\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /jsbenchmark/completeness/single_app_tracing/exception_error/exception_throw/exception_catch_003_T\n AffectedNodeName: __taint_src\n 11: SOURCE: function exception_catch_003_T(__taint_src) {\n /jsbenchmark/completeness/single_app_tracing/exception_error/exception_throw/exception_catch_003_T\n AffectedNodeName: {message:__taint_src, code:123}\n 13: Throw Pass: throw { message: __taint_src, code: 123 };\n /jsbenchmark/completeness/single_app_tracing/exception_error/exception_throw/exception_catch_003_T\n AffectedNodeName: e\n 14: Var Pass: } catch (e) {\n /jsbenchmark/completeness/single_app_tracing/exception_error/exception_throw/exception_catch_003_T\n AffectedNodeName: __taint_sink\n 15: SINK: __taint_sink(e.message);\n==========================================================\n #Total-findings:1\n==========================================================","/jsbenchmark/completeness/single_app_tracing/exception_error/exception_throw/exception_catch_004_F":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/completeness/single_app_tracing/exception_error/exception_throw/exception_finally_001_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/jsbenchmark/completeness/single_app_tracing/exception_error/exception_throw/exception_finally_001_T\nLine 18: __taint_sink(res)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/jsbenchmark/completeness/single_app_tracing/exception_error/exception_throw/exception_finally_001_T\",\"functionName\":\"exception_finally_001_T\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /jsbenchmark/completeness/single_app_tracing/exception_error/exception_throw/exception_finally_001_T\n AffectedNodeName: __taint_src\n 11: SOURCE: function exception_finally_001_T(__taint_src) {\n /jsbenchmark/completeness/single_app_tracing/exception_error/exception_throw/exception_finally_001_T\n AffectedNodeName: __taint_src\n 14: Throw Pass: throw __taint_src;\n /jsbenchmark/completeness/single_app_tracing/exception_error/exception_throw/exception_finally_001_T\n AffectedNodeName: e\n 15: Var Pass: } catch (e) {\n /jsbenchmark/completeness/single_app_tracing/exception_error/exception_throw/exception_finally_001_T\n AffectedNodeName: res\n 16: Var Pass: res = e;\n /jsbenchmark/completeness/single_app_tracing/exception_error/exception_throw/exception_finally_001_T\n AffectedNodeName: __taint_sink\n 18: SINK: __taint_sink(res);\n==========================================================\n #Total-findings:1\n==========================================================","/jsbenchmark/completeness/single_app_tracing/exception_error/exception_throw/exception_finally_002_F":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/completeness/single_app_tracing/exception_error/exception_throw/exception_try_001_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/jsbenchmark/completeness/single_app_tracing/exception_error/exception_throw/exception_try_001_T\nLine 13: __taint_sink(__taint_src)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/jsbenchmark/completeness/single_app_tracing/exception_error/exception_throw/exception_try_001_T\",\"functionName\":\"exception_try_001_T\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /jsbenchmark/completeness/single_app_tracing/exception_error/exception_throw/exception_try_001_T\n AffectedNodeName: __taint_src\n 11: SOURCE: function exception_try_001_T(__taint_src) {\n /jsbenchmark/completeness/single_app_tracing/exception_error/exception_throw/exception_try_001_T\n AffectedNodeName: __taint_sink\n 13: SINK: __taint_sink(__taint_src);\n==========================================================\n #Total-findings:1\n==========================================================","/jsbenchmark/completeness/single_app_tracing/exception_error/exception_throw/exception_try_002_F":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/completeness/single_app_tracing/expression/basic_expression_operation/assign_expression_001_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/jsbenchmark/completeness/single_app_tracing/expression/basic_expression_operation/assign_expression_001_T\nLine 14: __taint_sink(result)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/jsbenchmark/completeness/single_app_tracing/expression/basic_expression_operation/assign_expression_001_T\",\"functionName\":\"assign_expression_001_T\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /jsbenchmark/completeness/single_app_tracing/expression/basic_expression_operation/assign_expression_001_T\n AffectedNodeName: __taint_src\n 11: SOURCE: function assign_expression_001_T(__taint_src) {\n /jsbenchmark/completeness/single_app_tracing/expression/basic_expression_operation/assign_expression_001_T\n AffectedNodeName: result\n 13: Var Pass: result = __taint_src;\n /jsbenchmark/completeness/single_app_tracing/expression/basic_expression_operation/assign_expression_001_T\n AffectedNodeName: __taint_sink\n 14: SINK: __taint_sink(result);\n==========================================================\n #Total-findings:1\n==========================================================","/jsbenchmark/completeness/single_app_tracing/expression/basic_expression_operation/assign_expression_002_F":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/completeness/single_app_tracing/expression/basic_expression_operation/binary_expression_add_001_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/jsbenchmark/completeness/single_app_tracing/expression/basic_expression_operation/binary_expression_add_001_T\nLine 13: __taint_sink(result)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/jsbenchmark/completeness/single_app_tracing/expression/basic_expression_operation/binary_expression_add_001_T\",\"functionName\":\"binary_expression_add_001_T\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /jsbenchmark/completeness/single_app_tracing/expression/basic_expression_operation/binary_expression_add_001_T\n AffectedNodeName: __taint_src\n 11: SOURCE: function binary_expression_add_001_T(__taint_src) {\n /jsbenchmark/completeness/single_app_tracing/expression/basic_expression_operation/binary_expression_add_001_T\n AffectedNodeName: result\n 12: Var Pass: let result = __taint_src + \"_\";\n /jsbenchmark/completeness/single_app_tracing/expression/basic_expression_operation/binary_expression_add_001_T\n AffectedNodeName: __taint_sink\n 13: SINK: __taint_sink(result);\n==========================================================\n #Total-findings:1\n==========================================================","/jsbenchmark/completeness/single_app_tracing/expression/basic_expression_operation/binary_expression_add_002_F":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/completeness/single_app_tracing/expression/basic_expression_operation/binary_expression_add_assignment_001_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/jsbenchmark/completeness/single_app_tracing/expression/basic_expression_operation/binary_expression_add_assignment_001_T\nLine 14: __taint_sink(result)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/jsbenchmark/completeness/single_app_tracing/expression/basic_expression_operation/binary_expression_add_assignment_001_T\",\"functionName\":\"binary_expression_add_assignment_001_T\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /jsbenchmark/completeness/single_app_tracing/expression/basic_expression_operation/binary_expression_add_assignment_001_T\n AffectedNodeName: __taint_src\n 11: SOURCE: function binary_expression_add_assignment_001_T(__taint_src) {\n /jsbenchmark/completeness/single_app_tracing/expression/basic_expression_operation/binary_expression_add_assignment_001_T\n AffectedNodeName: __taint_sink\n 14: SINK: __taint_sink(result);\n==========================================================\n #Total-findings:1\n==========================================================","/jsbenchmark/completeness/single_app_tracing/expression/basic_expression_operation/binary_expression_add_assignment_002_F":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/completeness/single_app_tracing/expression/basic_expression_operation/bitwise_expression_and_001_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/jsbenchmark/completeness/single_app_tracing/expression/basic_expression_operation/bitwise_expression_and_001_T\nLine 13: __taint_sink(result)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/jsbenchmark/completeness/single_app_tracing/expression/basic_expression_operation/bitwise_expression_and_001_T\",\"functionName\":\"bitwise_expression_and_001_T\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /jsbenchmark/completeness/single_app_tracing/expression/basic_expression_operation/bitwise_expression_and_001_T\n AffectedNodeName: __taint_src\n 11: SOURCE: function bitwise_expression_and_001_T(__taint_src) {\n /jsbenchmark/completeness/single_app_tracing/expression/basic_expression_operation/bitwise_expression_and_001_T\n AffectedNodeName: result\n 12: Var Pass: let result = __taint_src & 1;\n /jsbenchmark/completeness/single_app_tracing/expression/basic_expression_operation/bitwise_expression_and_001_T\n AffectedNodeName: __taint_sink\n 13: SINK: __taint_sink(result);\n==========================================================\n #Total-findings:1\n==========================================================","/jsbenchmark/completeness/single_app_tracing/expression/basic_expression_operation/bitwise_expression_and_002_F":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/completeness/single_app_tracing/expression/basic_expression_operation/bitwise_expression_lsh_001_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/jsbenchmark/completeness/single_app_tracing/expression/basic_expression_operation/bitwise_expression_lsh_001_T\nLine 13: __taint_sink(result)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/jsbenchmark/completeness/single_app_tracing/expression/basic_expression_operation/bitwise_expression_lsh_001_T\",\"functionName\":\"bitwise_expression_lsh_001_T\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /jsbenchmark/completeness/single_app_tracing/expression/basic_expression_operation/bitwise_expression_lsh_001_T\n AffectedNodeName: __taint_src\n 11: SOURCE: function bitwise_expression_lsh_001_T(__taint_src) {\n /jsbenchmark/completeness/single_app_tracing/expression/basic_expression_operation/bitwise_expression_lsh_001_T\n AffectedNodeName: result\n 12: Var Pass: let result = __taint_src << 1;\n /jsbenchmark/completeness/single_app_tracing/expression/basic_expression_operation/bitwise_expression_lsh_001_T\n AffectedNodeName: __taint_sink\n 13: SINK: __taint_sink(result);\n==========================================================\n #Total-findings:1\n==========================================================","/jsbenchmark/completeness/single_app_tracing/expression/basic_expression_operation/bitwise_expression_lsh_002_F":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/completeness/single_app_tracing/expression/basic_expression_operation/bitwise_expression_not_001_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/jsbenchmark/completeness/single_app_tracing/expression/basic_expression_operation/bitwise_expression_not_001_T\nLine 13: __taint_sink(result)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/jsbenchmark/completeness/single_app_tracing/expression/basic_expression_operation/bitwise_expression_not_001_T\",\"functionName\":\"bitwise_expression_not_001_T\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /jsbenchmark/completeness/single_app_tracing/expression/basic_expression_operation/bitwise_expression_not_001_T\n AffectedNodeName: __taint_src\n 11: SOURCE: function bitwise_expression_not_001_T(__taint_src) {\n /jsbenchmark/completeness/single_app_tracing/expression/basic_expression_operation/bitwise_expression_not_001_T\n AffectedNodeName: __taint_sink\n 13: SINK: __taint_sink(result);\n==========================================================\n #Total-findings:1\n==========================================================","/jsbenchmark/completeness/single_app_tracing/expression/basic_expression_operation/bitwise_expression_not_002_F":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/completeness/single_app_tracing/expression/basic_expression_operation/bitwise_expression_or_001_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/jsbenchmark/completeness/single_app_tracing/expression/basic_expression_operation/bitwise_expression_or_001_T\nLine 13: __taint_sink(result)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/jsbenchmark/completeness/single_app_tracing/expression/basic_expression_operation/bitwise_expression_or_001_T\",\"functionName\":\"bitwise_expression_or_001_T\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /jsbenchmark/completeness/single_app_tracing/expression/basic_expression_operation/bitwise_expression_or_001_T\n AffectedNodeName: __taint_src\n 11: SOURCE: function bitwise_expression_or_001_T(__taint_src) {\n /jsbenchmark/completeness/single_app_tracing/expression/basic_expression_operation/bitwise_expression_or_001_T\n AffectedNodeName: result\n 12: Var Pass: let result = __taint_src | 1;\n /jsbenchmark/completeness/single_app_tracing/expression/basic_expression_operation/bitwise_expression_or_001_T\n AffectedNodeName: __taint_sink\n 13: SINK: __taint_sink(result);\n==========================================================\n #Total-findings:1\n==========================================================","/jsbenchmark/completeness/single_app_tracing/expression/basic_expression_operation/bitwise_expression_or_002_F":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/completeness/single_app_tracing/expression/basic_expression_operation/bitwise_expression_rsh_001_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/jsbenchmark/completeness/single_app_tracing/expression/basic_expression_operation/bitwise_expression_rsh_001_T\nLine 13: __taint_sink(result)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/jsbenchmark/completeness/single_app_tracing/expression/basic_expression_operation/bitwise_expression_rsh_001_T\",\"functionName\":\"bitwise_expression_rsh_001_T\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /jsbenchmark/completeness/single_app_tracing/expression/basic_expression_operation/bitwise_expression_rsh_001_T\n AffectedNodeName: __taint_src\n 11: SOURCE: function bitwise_expression_rsh_001_T(__taint_src) {\n /jsbenchmark/completeness/single_app_tracing/expression/basic_expression_operation/bitwise_expression_rsh_001_T\n AffectedNodeName: result\n 12: Var Pass: let result = __taint_src >> 1;\n /jsbenchmark/completeness/single_app_tracing/expression/basic_expression_operation/bitwise_expression_rsh_001_T\n AffectedNodeName: __taint_sink\n 13: SINK: __taint_sink(result);\n==========================================================\n #Total-findings:1\n==========================================================","/jsbenchmark/completeness/single_app_tracing/expression/basic_expression_operation/bitwise_expression_rsh_002_F":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/completeness/single_app_tracing/expression/basic_expression_operation/bitwise_expression_xor_001_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/jsbenchmark/completeness/single_app_tracing/expression/basic_expression_operation/bitwise_expression_xor_001_T\nLine 13: __taint_sink(result)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/jsbenchmark/completeness/single_app_tracing/expression/basic_expression_operation/bitwise_expression_xor_001_T\",\"functionName\":\"bitwise_expression_xor_001_T\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /jsbenchmark/completeness/single_app_tracing/expression/basic_expression_operation/bitwise_expression_xor_001_T\n AffectedNodeName: __taint_src\n 11: SOURCE: function bitwise_expression_xor_001_T(__taint_src) {\n /jsbenchmark/completeness/single_app_tracing/expression/basic_expression_operation/bitwise_expression_xor_001_T\n AffectedNodeName: result\n 12: Var Pass: let result = __taint_src ^ 1;\n /jsbenchmark/completeness/single_app_tracing/expression/basic_expression_operation/bitwise_expression_xor_001_T\n AffectedNodeName: __taint_sink\n 13: SINK: __taint_sink(result);\n==========================================================\n #Total-findings:1\n==========================================================","/jsbenchmark/completeness/single_app_tracing/expression/basic_expression_operation/bitwise_expression_xor_002_F":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/completeness/single_app_tracing/expression/basic_expression_operation/logic_expression_and_001_F":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/completeness/single_app_tracing/expression/basic_expression_operation/logic_expression_and_002_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/jsbenchmark/completeness/single_app_tracing/expression/basic_expression_operation/logic_expression_and_002_T\nLine 13: __taint_sink(result)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/jsbenchmark/completeness/single_app_tracing/expression/basic_expression_operation/logic_expression_and_002_T\",\"functionName\":\"logic_expression_and_002_T\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /jsbenchmark/completeness/single_app_tracing/expression/basic_expression_operation/logic_expression_and_002_T\n AffectedNodeName: __taint_src\n 11: SOURCE: function logic_expression_and_002_T(__taint_src) {\n /jsbenchmark/completeness/single_app_tracing/expression/basic_expression_operation/logic_expression_and_002_T\n AffectedNodeName: result\n 12: Var Pass: let result = \"_\" && __taint_src;\n /jsbenchmark/completeness/single_app_tracing/expression/basic_expression_operation/logic_expression_and_002_T\n AffectedNodeName: __taint_sink\n 13: SINK: __taint_sink(result);\n==========================================================\n #Total-findings:1\n==========================================================","/jsbenchmark/completeness/single_app_tracing/expression/basic_expression_operation/logic_expression_or_001_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/jsbenchmark/completeness/single_app_tracing/expression/basic_expression_operation/logic_expression_or_001_T\nLine 13: __taint_sink(result)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/jsbenchmark/completeness/single_app_tracing/expression/basic_expression_operation/logic_expression_or_001_T\",\"functionName\":\"logic_expression_or_001_T\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /jsbenchmark/completeness/single_app_tracing/expression/basic_expression_operation/logic_expression_or_001_T\n AffectedNodeName: __taint_src\n 11: SOURCE: function logic_expression_or_001_T(__taint_src) {\n /jsbenchmark/completeness/single_app_tracing/expression/basic_expression_operation/logic_expression_or_001_T\n AffectedNodeName: result\n 12: Var Pass: let result = __taint_src || \"_\";\n /jsbenchmark/completeness/single_app_tracing/expression/basic_expression_operation/logic_expression_or_001_T\n AffectedNodeName: __taint_sink\n 13: SINK: __taint_sink(result);\n==========================================================\n #Total-findings:1\n==========================================================","/jsbenchmark/completeness/single_app_tracing/expression/basic_expression_operation/logic_expression_or_002_F":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/completeness/single_app_tracing/expression/basic_expression_operation/prefix_expression_001_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/jsbenchmark/completeness/single_app_tracing/expression/basic_expression_operation/prefix_expression_001_T\nLine 13: __taint_sink(result)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/jsbenchmark/completeness/single_app_tracing/expression/basic_expression_operation/prefix_expression_001_T\",\"functionName\":\"prefix_expression_001_T\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /jsbenchmark/completeness/single_app_tracing/expression/basic_expression_operation/prefix_expression_001_T\n AffectedNodeName: __taint_src\n 11: SOURCE: function prefix_expression_001_T(__taint_src) {\n /jsbenchmark/completeness/single_app_tracing/expression/basic_expression_operation/prefix_expression_001_T\n AffectedNodeName: __taint_sink\n 13: SINK: __taint_sink(result);\n==========================================================\n #Total-findings:1\n==========================================================","/jsbenchmark/completeness/single_app_tracing/expression/basic_expression_operation/prefix_expression_002_F":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/completeness/single_app_tracing/expression/basic_expression_operation/relation_expression_equal_001_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/jsbenchmark/completeness/single_app_tracing/expression/basic_expression_operation/relation_expression_equal_001_T\nLine 13: __taint_sink(result)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/jsbenchmark/completeness/single_app_tracing/expression/basic_expression_operation/relation_expression_equal_001_T\",\"functionName\":\"relation_expression_equal_001_T\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /jsbenchmark/completeness/single_app_tracing/expression/basic_expression_operation/relation_expression_equal_001_T\n AffectedNodeName: __taint_src\n 11: SOURCE: function relation_expression_equal_001_T(__taint_src) {\n /jsbenchmark/completeness/single_app_tracing/expression/basic_expression_operation/relation_expression_equal_001_T\n AffectedNodeName: result\n 12: Var Pass: let result = __taint_src === \"taint_src_value\";\n /jsbenchmark/completeness/single_app_tracing/expression/basic_expression_operation/relation_expression_equal_001_T\n AffectedNodeName: __taint_sink\n 13: SINK: __taint_sink(result);\n==========================================================\n #Total-findings:1\n==========================================================","/jsbenchmark/completeness/single_app_tracing/expression/basic_expression_operation/relation_expression_equal_002_F":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/jsbenchmark/completeness/single_app_tracing/expression/basic_expression_operation/relation_expression_equal_002_F\nLine 13: __taint_sink(result)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/jsbenchmark/completeness/single_app_tracing/expression/basic_expression_operation/relation_expression_equal_002_F\",\"functionName\":\"relation_expression_equal_002_F\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /jsbenchmark/completeness/single_app_tracing/expression/basic_expression_operation/relation_expression_equal_002_F\n AffectedNodeName: __taint_src\n 11: SOURCE: function relation_expression_equal_002_F(__taint_src) {\n /jsbenchmark/completeness/single_app_tracing/expression/basic_expression_operation/relation_expression_equal_002_F\n AffectedNodeName: result\n 12: Var Pass: let result = __taint_src === \"__taint_src\";\n /jsbenchmark/completeness/single_app_tracing/expression/basic_expression_operation/relation_expression_equal_002_F\n AffectedNodeName: __taint_sink\n 13: SINK: __taint_sink(result);\n==========================================================\n #Total-findings:1\n==========================================================","/jsbenchmark/completeness/single_app_tracing/expression/basic_expression_operation/relation_expression_greater_001_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/jsbenchmark/completeness/single_app_tracing/expression/basic_expression_operation/relation_expression_greater_001_T\nLine 13: __taint_sink(result)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/jsbenchmark/completeness/single_app_tracing/expression/basic_expression_operation/relation_expression_greater_001_T\",\"functionName\":\"relation_expression_greater_001_T\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /jsbenchmark/completeness/single_app_tracing/expression/basic_expression_operation/relation_expression_greater_001_T\n AffectedNodeName: __taint_src\n 11: SOURCE: function relation_expression_greater_001_T(__taint_src) {\n /jsbenchmark/completeness/single_app_tracing/expression/basic_expression_operation/relation_expression_greater_001_T\n AffectedNodeName: result\n 12: Var Pass: let result = __taint_src > \"__taint_src\";\n /jsbenchmark/completeness/single_app_tracing/expression/basic_expression_operation/relation_expression_greater_001_T\n AffectedNodeName: __taint_sink\n 13: SINK: __taint_sink(result);\n==========================================================\n #Total-findings:1\n==========================================================","/jsbenchmark/completeness/single_app_tracing/expression/basic_expression_operation/relation_expression_greater_002_F":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/jsbenchmark/completeness/single_app_tracing/expression/basic_expression_operation/relation_expression_greater_002_F\nLine 13: __taint_sink(result)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/jsbenchmark/completeness/single_app_tracing/expression/basic_expression_operation/relation_expression_greater_002_F\",\"functionName\":\"relation_expression_greater_002_F\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /jsbenchmark/completeness/single_app_tracing/expression/basic_expression_operation/relation_expression_greater_002_F\n AffectedNodeName: __taint_src\n 11: SOURCE: function relation_expression_greater_002_F(__taint_src) {\n /jsbenchmark/completeness/single_app_tracing/expression/basic_expression_operation/relation_expression_greater_002_F\n AffectedNodeName: result\n 12: Var Pass: let result = __taint_src > \"taint_src_value\";\n /jsbenchmark/completeness/single_app_tracing/expression/basic_expression_operation/relation_expression_greater_002_F\n AffectedNodeName: __taint_sink\n 13: SINK: __taint_sink(result);\n==========================================================\n #Total-findings:1\n==========================================================","/jsbenchmark/completeness/single_app_tracing/expression/basic_expression_operation/relation_expression_less_001_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/jsbenchmark/completeness/single_app_tracing/expression/basic_expression_operation/relation_expression_less_001_T\nLine 13: __taint_sink(result)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/jsbenchmark/completeness/single_app_tracing/expression/basic_expression_operation/relation_expression_less_001_T\",\"functionName\":\"relation_expression_less_001_T\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /jsbenchmark/completeness/single_app_tracing/expression/basic_expression_operation/relation_expression_less_001_T\n AffectedNodeName: __taint_src\n 11: SOURCE: function relation_expression_less_001_T(__taint_src) {\n /jsbenchmark/completeness/single_app_tracing/expression/basic_expression_operation/relation_expression_less_001_T\n AffectedNodeName: result\n 12: Var Pass: let result = __taint_src < \"__taint_src\";\n /jsbenchmark/completeness/single_app_tracing/expression/basic_expression_operation/relation_expression_less_001_T\n AffectedNodeName: __taint_sink\n 13: SINK: __taint_sink(result);\n==========================================================\n #Total-findings:1\n==========================================================","/jsbenchmark/completeness/single_app_tracing/expression/basic_expression_operation/relation_expression_less_002_F":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/jsbenchmark/completeness/single_app_tracing/expression/basic_expression_operation/relation_expression_less_002_F\nLine 13: __taint_sink(result)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/jsbenchmark/completeness/single_app_tracing/expression/basic_expression_operation/relation_expression_less_002_F\",\"functionName\":\"relation_expression_less_002_F\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /jsbenchmark/completeness/single_app_tracing/expression/basic_expression_operation/relation_expression_less_002_F\n AffectedNodeName: __taint_src\n 11: SOURCE: function relation_expression_less_002_F(__taint_src) {\n /jsbenchmark/completeness/single_app_tracing/expression/basic_expression_operation/relation_expression_less_002_F\n AffectedNodeName: result\n 12: Var Pass: let result = __taint_src < \"taint_src_valueaa\";\n /jsbenchmark/completeness/single_app_tracing/expression/basic_expression_operation/relation_expression_less_002_F\n AffectedNodeName: __taint_sink\n 13: SINK: __taint_sink(result);\n==========================================================\n #Total-findings:1\n==========================================================","/jsbenchmark/completeness/single_app_tracing/expression/basic_expression_operation/suffix_expression_001_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/jsbenchmark/completeness/single_app_tracing/expression/basic_expression_operation/suffix_expression_001_T\nLine 13: __taint_sink(result)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/jsbenchmark/completeness/single_app_tracing/expression/basic_expression_operation/suffix_expression_001_T\",\"functionName\":\"suffix_expression_001_T\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /jsbenchmark/completeness/single_app_tracing/expression/basic_expression_operation/suffix_expression_001_T\n AffectedNodeName: __taint_src\n 11: SOURCE: function suffix_expression_001_T(__taint_src) {\n /jsbenchmark/completeness/single_app_tracing/expression/basic_expression_operation/suffix_expression_001_T\n AffectedNodeName: __taint_sink\n 13: SINK: __taint_sink(result);\n==========================================================\n #Total-findings:1\n==========================================================","/jsbenchmark/completeness/single_app_tracing/expression/basic_expression_operation/suffix_expression_002_F":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/completeness/single_app_tracing/expression/conditional_expression/conditional_expression_001_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/jsbenchmark/completeness/single_app_tracing/expression/conditional_expression/conditional_expression_001_T\nLine 14: __taint_sink(result)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/jsbenchmark/completeness/single_app_tracing/expression/conditional_expression/conditional_expression_001_T\",\"functionName\":\"conditional_expression_001_T\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /jsbenchmark/completeness/single_app_tracing/expression/conditional_expression/conditional_expression_001_T\n AffectedNodeName: __taint_src\n 11: SOURCE: function conditional_expression_001_T(__taint_src) {\n /jsbenchmark/completeness/single_app_tracing/expression/conditional_expression/conditional_expression_001_T\n AffectedNodeName: result\n 13: Var Pass: result = true ? __taint_src : \"aa\";\n /jsbenchmark/completeness/single_app_tracing/expression/conditional_expression/conditional_expression_001_T\n AffectedNodeName: __taint_sink\n 14: SINK: __taint_sink(result);\n==========================================================\n #Total-findings:1\n==========================================================","/jsbenchmark/completeness/single_app_tracing/expression/conditional_expression/conditional_expression_002_F":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/completeness/single_app_tracing/expression/lambda_expression/lambda_expression_001_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/jsbenchmark/completeness/single_app_tracing/expression/lambda_expression/lambda_expression_001_T\nLine 15: __taint_sink(result)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/jsbenchmark/completeness/single_app_tracing/expression/lambda_expression/lambda_expression_001_T\",\"functionName\":\"lambda_expression_001_T\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /jsbenchmark/completeness/single_app_tracing/expression/lambda_expression/lambda_expression_001_T\n AffectedNodeName: __taint_src\n 11: SOURCE: function lambda_expression_001_T(__taint_src) {\n /jsbenchmark/completeness/single_app_tracing/expression/lambda_expression/lambda_expression_001_T\n AffectedNodeName: \n 14: CALL: result = lambda(__taint_src);\n /jsbenchmark/completeness/single_app_tracing/expression/lambda_expression/lambda_expression_001_T\n AffectedNodeName: a\n 13: ARG PASS: const lambda = (a) => a;\n /jsbenchmark/completeness/single_app_tracing/expression/lambda_expression/lambda_expression_001_T\n AffectedNodeName: [return value]\n 13: Return Value: const lambda = (a) => a;\n /jsbenchmark/completeness/single_app_tracing/expression/lambda_expression/lambda_expression_001_T\n AffectedNodeName: \n 14: CALL RETURN: result = lambda(__taint_src);\n /jsbenchmark/completeness/single_app_tracing/expression/lambda_expression/lambda_expression_001_T\n AffectedNodeName: result\n 14: Var Pass: result = lambda(__taint_src);\n /jsbenchmark/completeness/single_app_tracing/expression/lambda_expression/lambda_expression_001_T\n AffectedNodeName: __taint_sink\n 15: SINK: __taint_sink(result);\n==========================================================\n #Total-findings:1\n==========================================================","/jsbenchmark/completeness/single_app_tracing/expression/lambda_expression/lambda_expression_002_F":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/completeness/single_app_tracing/expression/special_expression/delete_expression_001_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/jsbenchmark/completeness/single_app_tracing/expression/special_expression/delete_expression_001_T\nLine 17: __taint_sink(Employee.lastname)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/jsbenchmark/completeness/single_app_tracing/expression/special_expression/delete_expression_001_T\",\"functionName\":\"delete_expression_001_T\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /jsbenchmark/completeness/single_app_tracing/expression/special_expression/delete_expression_001_T\n AffectedNodeName: __taint_src\n 10: SOURCE: function delete_expression_001_T(__taint_src) {\n /jsbenchmark/completeness/single_app_tracing/expression/special_expression/delete_expression_001_T\n AffectedNodeName: Employee\n 11: Var Pass: const Employee = {\n 12: Var Pass: firstname: \"Bob\",\n 13: Var Pass: lastname: __taint_src,\n 14: Var Pass: };\n /jsbenchmark/completeness/single_app_tracing/expression/special_expression/delete_expression_001_T\n AffectedNodeName: __taint_sink\n 17: SINK: __taint_sink(Employee.lastname);\n==========================================================\n #Total-findings:1\n==========================================================","/jsbenchmark/completeness/single_app_tracing/expression/special_expression/delete_expression_002_F":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/completeness/single_app_tracing/expression/special_expression/delete_expression_003_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/jsbenchmark/completeness/single_app_tracing/expression/special_expression/delete_expression_003_T\nLine 13: __taint_sink(array)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/jsbenchmark/completeness/single_app_tracing/expression/special_expression/delete_expression_003_T\",\"functionName\":\"delete_expression_003_T\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /jsbenchmark/completeness/single_app_tracing/expression/special_expression/delete_expression_003_T\n AffectedNodeName: __taint_src\n 10: SOURCE: function delete_expression_003_T(__taint_src) {\n /jsbenchmark/completeness/single_app_tracing/expression/special_expression/delete_expression_003_T\n AffectedNodeName: array\n 11: Var Pass: const array = [__taint_src, \"b\", \"c\", \"d\"];\n /jsbenchmark/completeness/single_app_tracing/expression/special_expression/delete_expression_003_T\n AffectedNodeName: __taint_sink\n 13: SINK: __taint_sink(array);\n==========================================================\n #Total-findings:1\n==========================================================","/jsbenchmark/completeness/single_app_tracing/expression/special_expression/delete_expression_004_F":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/completeness/single_app_tracing/expression/special_expression/destructuring_assignment_001_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/jsbenchmark/completeness/single_app_tracing/expression/special_expression/destructuring_assignment_001_T\nLine 14: __taint_sink(result)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/jsbenchmark/completeness/single_app_tracing/expression/special_expression/destructuring_assignment_001_T\",\"functionName\":\"destructuring_assignment_001_T\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /jsbenchmark/completeness/single_app_tracing/expression/special_expression/destructuring_assignment_001_T\n AffectedNodeName: __taint_src\n 11: SOURCE: function destructuring_assignment_001_T(__taint_src) {\n /jsbenchmark/completeness/single_app_tracing/expression/special_expression/destructuring_assignment_001_T\n AffectedNodeName: arr\n 12: Var Pass: let arr = [\"_\", \"_\", __taint_src];\n /jsbenchmark/completeness/single_app_tracing/expression/special_expression/destructuring_assignment_001_T\n AffectedNodeName: result\n 13: Var Pass: let [a, b, result] = arr;\n /jsbenchmark/completeness/single_app_tracing/expression/special_expression/destructuring_assignment_001_T\n AffectedNodeName: __taint_sink\n 14: SINK: __taint_sink(result);\n==========================================================\n #Total-findings:1\n==========================================================","/jsbenchmark/completeness/single_app_tracing/expression/special_expression/destructuring_assignment_002_F":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/completeness/single_app_tracing/expression/special_expression/destructuring_assignment_003_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/jsbenchmark/completeness/single_app_tracing/expression/special_expression/destructuring_assignment_003_T\nLine 14: __taint_sink(c)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/jsbenchmark/completeness/single_app_tracing/expression/special_expression/destructuring_assignment_003_T\",\"functionName\":\"destructuring_assignment_003_T\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /jsbenchmark/completeness/single_app_tracing/expression/special_expression/destructuring_assignment_003_T\n AffectedNodeName: __taint_src\n 11: SOURCE: function destructuring_assignment_003_T(__taint_src) {\n /jsbenchmark/completeness/single_app_tracing/expression/special_expression/destructuring_assignment_003_T\n AffectedNodeName: arr\n 12: Var Pass: let arr = { a: \"_\", b: \"_\", c: __taint_src };\n /jsbenchmark/completeness/single_app_tracing/expression/special_expression/destructuring_assignment_003_T\n AffectedNodeName: c\n 13: Var Pass: let { a, b, c } = arr;\n /jsbenchmark/completeness/single_app_tracing/expression/special_expression/destructuring_assignment_003_T\n AffectedNodeName: __taint_sink\n 14: SINK: __taint_sink(c);\n==========================================================\n #Total-findings:1\n==========================================================","/jsbenchmark/completeness/single_app_tracing/expression/special_expression/destructuring_assignment_004_F":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/completeness/single_app_tracing/expression/special_expression/destructuring_assignment_005_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/jsbenchmark/completeness/single_app_tracing/expression/special_expression/destructuring_assignment_005_T\nLine 14: __taint_sink(c)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/jsbenchmark/completeness/single_app_tracing/expression/special_expression/destructuring_assignment_005_T\",\"functionName\":\"destructuring_assignment_005_T\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /jsbenchmark/completeness/single_app_tracing/expression/special_expression/destructuring_assignment_005_T\n AffectedNodeName: __taint_src\n 11: SOURCE: function destructuring_assignment_005_T(__taint_src) {\n /jsbenchmark/completeness/single_app_tracing/expression/special_expression/destructuring_assignment_005_T\n AffectedNodeName: arr\n 12: Var Pass: let arr = [\"_\", \"_\", [__taint_src, \"_\"]];\n /jsbenchmark/completeness/single_app_tracing/expression/special_expression/destructuring_assignment_005_T\n AffectedNodeName: c\n 13: Var Pass: let [a, b, [c, d]] = arr;\n /jsbenchmark/completeness/single_app_tracing/expression/special_expression/destructuring_assignment_005_T\n AffectedNodeName: __taint_sink\n 14: SINK: __taint_sink(c);\n==========================================================\n #Total-findings:1\n==========================================================","/jsbenchmark/completeness/single_app_tracing/expression/special_expression/destructuring_assignment_006_F":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/completeness/single_app_tracing/expression/special_expression/destructuring_assignment_007_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/jsbenchmark/completeness/single_app_tracing/expression/special_expression/destructuring_assignment_007_T\nLine 14: __taint_sink(c)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/jsbenchmark/completeness/single_app_tracing/expression/special_expression/destructuring_assignment_007_T\",\"functionName\":\"destructuring_assignment_007_T\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /jsbenchmark/completeness/single_app_tracing/expression/special_expression/destructuring_assignment_007_T\n AffectedNodeName: __taint_src\n 11: SOURCE: function destructuring_assignment_007_T(__taint_src) {\n /jsbenchmark/completeness/single_app_tracing/expression/special_expression/destructuring_assignment_007_T\n AffectedNodeName: arr\n 12: Var Pass: let arr = { a: \"_\", b: \"_\", c: { __taint_src, d: \"a\" } };\n /jsbenchmark/completeness/single_app_tracing/expression/special_expression/destructuring_assignment_007_T\n AffectedNodeName: c\n 13: Var Pass: let { a, b, c } = arr;\n /jsbenchmark/completeness/single_app_tracing/expression/special_expression/destructuring_assignment_007_T\n AffectedNodeName: __taint_sink\n 14: SINK: __taint_sink(c);\n==========================================================\n #Total-findings:1\n==========================================================","/jsbenchmark/completeness/single_app_tracing/expression/special_expression/destructuring_assignment_008_F":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/completeness/single_app_tracing/expression/special_expression/exponentiation_operator_001_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/jsbenchmark/completeness/single_app_tracing/expression/special_expression/exponentiation_operator_001_T\nLine 13: __taint_sink(result)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/jsbenchmark/completeness/single_app_tracing/expression/special_expression/exponentiation_operator_001_T\",\"functionName\":\"exponentiation_operator_001_T\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /jsbenchmark/completeness/single_app_tracing/expression/special_expression/exponentiation_operator_001_T\n AffectedNodeName: __taint_src\n 11: SOURCE: function exponentiation_operator_001_T(__taint_src) {\n /jsbenchmark/completeness/single_app_tracing/expression/special_expression/exponentiation_operator_001_T\n AffectedNodeName: result\n 12: Var Pass: let result = __taint_src ** 2;\n /jsbenchmark/completeness/single_app_tracing/expression/special_expression/exponentiation_operator_001_T\n AffectedNodeName: __taint_sink\n 13: SINK: __taint_sink(result);\n==========================================================\n #Total-findings:1\n==========================================================","/jsbenchmark/completeness/single_app_tracing/expression/special_expression/exponentiation_operator_002_F":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/completeness/single_app_tracing/expression/special_expression/nullish_coalescing_operator_001_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/jsbenchmark/completeness/single_app_tracing/expression/special_expression/nullish_coalescing_operator_001_T\nLine 13: __taint_sink(result)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/jsbenchmark/completeness/single_app_tracing/expression/special_expression/nullish_coalescing_operator_001_T\",\"functionName\":\"nullish_coalescing_operator_001_T\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /jsbenchmark/completeness/single_app_tracing/expression/special_expression/nullish_coalescing_operator_001_T\n AffectedNodeName: __taint_src\n 11: SOURCE: function nullish_coalescing_operator_001_T(__taint_src) {\n /jsbenchmark/completeness/single_app_tracing/expression/special_expression/nullish_coalescing_operator_001_T\n AffectedNodeName: result\n 12: Var Pass: let result = null ?? __taint_src;\n /jsbenchmark/completeness/single_app_tracing/expression/special_expression/nullish_coalescing_operator_001_T\n AffectedNodeName: __taint_sink\n 13: SINK: __taint_sink(result);\n==========================================================\n #Total-findings:1\n==========================================================","/jsbenchmark/completeness/single_app_tracing/expression/special_expression/nullish_coalescing_operator_002_F":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/completeness/single_app_tracing/expression/special_expression/optional_chaining_operator_001_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/jsbenchmark/completeness/single_app_tracing/expression/special_expression/optional_chaining_operator_001_T\nLine 17: __taint_sink(result)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/jsbenchmark/completeness/single_app_tracing/expression/special_expression/optional_chaining_operator_001_T\",\"functionName\":\"optional_chaining_operator_001_T\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /jsbenchmark/completeness/single_app_tracing/expression/special_expression/optional_chaining_operator_001_T\n AffectedNodeName: __taint_src\n 11: SOURCE: function optional_chaining_operator_001_T(__taint_src) {\n /jsbenchmark/completeness/single_app_tracing/expression/special_expression/optional_chaining_operator_001_T\n AffectedNodeName: obj\n 12: Var Pass: let obj = {\n 13: Var Pass: taintKey: __taint_src,\n 14: Var Pass: };\n /jsbenchmark/completeness/single_app_tracing/expression/special_expression/optional_chaining_operator_001_T\n AffectedNodeName: result\n 16: Var Pass: let result = obj?.taintKey;\n /jsbenchmark/completeness/single_app_tracing/expression/special_expression/optional_chaining_operator_001_T\n AffectedNodeName: __taint_sink\n 17: SINK: __taint_sink(result);\n==========================================================\n #Total-findings:1\n==========================================================","/jsbenchmark/completeness/single_app_tracing/expression/special_expression/optional_chaining_operator_002_F":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/completeness/single_app_tracing/expression/special_expression/rest_parameter_001_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/jsbenchmark/completeness/single_app_tracing/expression/special_expression/rest_parameter_001_T\nLine 16: __taint_sink(args)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/jsbenchmark/completeness/single_app_tracing/expression/special_expression/rest_parameter_001_T\",\"functionName\":\"rest_parameter_001_T\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /jsbenchmark/completeness/single_app_tracing/expression/special_expression/rest_parameter_001_T\n AffectedNodeName: __taint_src\n 11: SOURCE: function rest_parameter_001_T(__taint_src) {\n /jsbenchmark/completeness/single_app_tracing/expression/special_expression/rest_parameter_001_T\n AffectedNodeName: collectArgs\n 12: CALL: collectArgs(\"prefix\", __taint_src, \"suffix\");\n /jsbenchmark/completeness/single_app_tracing/expression/special_expression/rest_parameter_001_T\n AffectedNodeName: __tmp1__\n 15: ARG PASS: function collectArgs(...args) {\n /jsbenchmark/completeness/single_app_tracing/expression/special_expression/rest_parameter_001_T\n AffectedNodeName: args\n 15: Var Pass: function collectArgs(...args) {\n 16: Var Pass: __taint_sink(args);\n 17: Var Pass: }\n /jsbenchmark/completeness/single_app_tracing/expression/special_expression/rest_parameter_001_T\n AffectedNodeName: __taint_sink\n 16: SINK: __taint_sink(args);\n==========================================================\n #Total-findings:1\n==========================================================","/jsbenchmark/completeness/single_app_tracing/expression/special_expression/rest_parameter_002_F":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/completeness/single_app_tracing/expression/special_expression/rest_parameter_003_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/jsbenchmark/completeness/single_app_tracing/expression/special_expression/rest_parameter_003_T\nLine 17: __taint_sink({with(params)})\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/jsbenchmark/completeness/single_app_tracing/expression/special_expression/rest_parameter_003_T\",\"functionName\":\"rest_parameter_003_T\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /jsbenchmark/completeness/single_app_tracing/expression/special_expression/rest_parameter_003_T\n AffectedNodeName: __taint_src\n 11: SOURCE: function rest_parameter_003_T(__taint_src) {\n /jsbenchmark/completeness/single_app_tracing/expression/special_expression/rest_parameter_003_T\n AffectedNodeName: params\n 12: Var Pass: const params = {\n 13: Var Pass: name: \"Tony\",\n 14: Var Pass: age: \"12\",\n 15: Var Pass: id: __taint_src,\n 16: Var Pass: };\n /jsbenchmark/completeness/single_app_tracing/expression/special_expression/rest_parameter_003_T\n AffectedNodeName: __taint_sink\n 17: SINK: __taint_sink({ ...params });\n==========================================================\n #Total-findings:1\n==========================================================","/jsbenchmark/completeness/single_app_tracing/expression/special_expression/rest_parameter_004_F":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/completeness/single_app_tracing/expression/special_expression/rest_parameter_005_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/jsbenchmark/completeness/single_app_tracing/expression/special_expression/rest_parameter_005_T\nLine 16: __taint_sink(args)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/jsbenchmark/completeness/single_app_tracing/expression/special_expression/rest_parameter_005_T\",\"functionName\":\"rest_parameter_005_T\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /jsbenchmark/completeness/single_app_tracing/expression/special_expression/rest_parameter_005_T\n AffectedNodeName: __taint_src\n 11: SOURCE: function rest_parameter_005_T(__taint_src) {\n /jsbenchmark/completeness/single_app_tracing/expression/special_expression/rest_parameter_005_T\n AffectedNodeName: collectArgs\n 12: CALL: collectArgs([\"prefix\", __taint_src, \"suffix\"]);\n /jsbenchmark/completeness/single_app_tracing/expression/special_expression/rest_parameter_005_T\n AffectedNodeName: __tmp1__\n 15: ARG PASS: function collectArgs(...args) {\n /jsbenchmark/completeness/single_app_tracing/expression/special_expression/rest_parameter_005_T\n AffectedNodeName: args\n 15: Var Pass: function collectArgs(...args) {\n 16: Var Pass: __taint_sink(args);\n 17: Var Pass: }\n /jsbenchmark/completeness/single_app_tracing/expression/special_expression/rest_parameter_005_T\n AffectedNodeName: __taint_sink\n 16: SINK: __taint_sink(args);\n==========================================================\n #Total-findings:1\n==========================================================","/jsbenchmark/completeness/single_app_tracing/expression/special_expression/rest_parameter_006_F":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/completeness/single_app_tracing/expression/special_expression/spread_operator_001_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/jsbenchmark/completeness/single_app_tracing/expression/special_expression/spread_operator_001_T\nLine 14: __taint_sink(array)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/jsbenchmark/completeness/single_app_tracing/expression/special_expression/spread_operator_001_T\",\"functionName\":\"spread_operator_001_T\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /jsbenchmark/completeness/single_app_tracing/expression/special_expression/spread_operator_001_T\n AffectedNodeName: __taint_src\n 11: SOURCE: function spread_operator_001_T(__taint_src) {\n /jsbenchmark/completeness/single_app_tracing/expression/special_expression/spread_operator_001_T\n AffectedNodeName: array1\n 12: Var Pass: let array1 = [\"a\", \"b\", __taint_src];\n /jsbenchmark/completeness/single_app_tracing/expression/special_expression/spread_operator_001_T\n AffectedNodeName: array\n 13: Var Pass: let array = [\"c\", ...array1];\n /jsbenchmark/completeness/single_app_tracing/expression/special_expression/spread_operator_001_T\n AffectedNodeName: __taint_sink\n 14: SINK: __taint_sink(array);\n==========================================================\n #Total-findings:1\n==========================================================","/jsbenchmark/completeness/single_app_tracing/expression/special_expression/spread_operator_002_F":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/completeness/single_app_tracing/expression/special_expression/spread_operator_003_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/jsbenchmark/completeness/single_app_tracing/expression/special_expression/spread_operator_003_T\nLine 21: __taint_sink(newParams)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/jsbenchmark/completeness/single_app_tracing/expression/special_expression/spread_operator_003_T\",\"functionName\":\"spread_operator_003_T\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /jsbenchmark/completeness/single_app_tracing/expression/special_expression/spread_operator_003_T\n AffectedNodeName: __taint_src\n 11: SOURCE: function spread_operator_003_T(__taint_src) {\n /jsbenchmark/completeness/single_app_tracing/expression/special_expression/spread_operator_003_T\n AffectedNodeName: params\n 12: Var Pass: const params = {\n 13: Var Pass: name: \"Tony\",\n 14: Var Pass: age: \"12\",\n 15: Var Pass: id: __taint_src,\n 16: Var Pass: };\n /jsbenchmark/completeness/single_app_tracing/expression/special_expression/spread_operator_003_T\n AffectedNodeName: newParams\n 17: Var Pass: const newParams = {\n 18: Var Pass: score: 100,\n 19: Var Pass: ...params,\n 20: Var Pass: };\n /jsbenchmark/completeness/single_app_tracing/expression/special_expression/spread_operator_003_T\n AffectedNodeName: __taint_sink\n 21: SINK: __taint_sink(newParams);\n==========================================================\n #Total-findings:1\n==========================================================","/jsbenchmark/completeness/single_app_tracing/expression/special_expression/spread_operator_004_F":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/completeness/single_app_tracing/expression/special_expression/spread_operator_005_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/jsbenchmark/completeness/single_app_tracing/expression/special_expression/spread_operator_005_T\nLine 15: __taint_sink(rest)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/jsbenchmark/completeness/single_app_tracing/expression/special_expression/spread_operator_005_T\",\"functionName\":\"spread_operator_005_T\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /jsbenchmark/completeness/single_app_tracing/expression/special_expression/spread_operator_005_T\n AffectedNodeName: __taint_src\n 11: SOURCE: function spread_operator_005_T(__taint_src) {\n /jsbenchmark/completeness/single_app_tracing/expression/special_expression/spread_operator_005_T\n AffectedNodeName: foo\n 12: Var Pass: const foo = __taint_src;\n /jsbenchmark/completeness/single_app_tracing/expression/special_expression/spread_operator_005_T\n AffectedNodeName: __tmp2__\n 14: Var Pass: const [r1, r2, ...rest] = [123, 456, foo, bar];\n /jsbenchmark/completeness/single_app_tracing/expression/special_expression/spread_operator_005_T\n AffectedNodeName: rest\n 14: Var Pass: const [r1, r2, ...rest] = [123, 456, foo, bar];\n /jsbenchmark/completeness/single_app_tracing/expression/special_expression/spread_operator_005_T\n AffectedNodeName: __taint_sink\n 15: SINK: __taint_sink(rest);\n==========================================================\n #Total-findings:1\n==========================================================","/jsbenchmark/completeness/single_app_tracing/expression/special_expression/spread_operator_006_F":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/completeness/single_app_tracing/expression/special_expression/template_literal_001_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/jsbenchmark/completeness/single_app_tracing/expression/special_expression/template_literal_001_T\nLine 13: __taint_sink(result)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/jsbenchmark/completeness/single_app_tracing/expression/special_expression/template_literal_001_T\",\"functionName\":\"template_literal_001_T\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /jsbenchmark/completeness/single_app_tracing/expression/special_expression/template_literal_001_T\n AffectedNodeName: __taint_src\n 11: SOURCE: function template_literal_001_T(__taint_src) {\n /jsbenchmark/completeness/single_app_tracing/expression/special_expression/template_literal_001_T\n AffectedNodeName: result\n 12: Var Pass: let result = `_${__taint_src}`;\n /jsbenchmark/completeness/single_app_tracing/expression/special_expression/template_literal_001_T\n AffectedNodeName: __taint_sink\n 13: SINK: __taint_sink(result);\n==========================================================\n #Total-findings:1\n==========================================================","/jsbenchmark/completeness/single_app_tracing/expression/special_expression/template_literal_002_F":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/completeness/single_app_tracing/expression/special_expression/template_literal_003_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/jsbenchmark/completeness/single_app_tracing/expression/special_expression/template_literal_003_T\nLine 13: __taint_sink(result)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/jsbenchmark/completeness/single_app_tracing/expression/special_expression/template_literal_003_T\",\"functionName\":\"template_literal_003_T\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /jsbenchmark/completeness/single_app_tracing/expression/special_expression/template_literal_003_T\n AffectedNodeName: __taint_src\n 11: SOURCE: function template_literal_003_T(__taint_src) {\n /jsbenchmark/completeness/single_app_tracing/expression/special_expression/template_literal_003_T\n AffectedNodeName: result\n 12: Var Pass: let result = `${__taint_src}_`;\n /jsbenchmark/completeness/single_app_tracing/expression/special_expression/template_literal_003_T\n AffectedNodeName: __taint_sink\n 13: SINK: __taint_sink(result);\n==========================================================\n #Total-findings:1\n==========================================================","/jsbenchmark/completeness/single_app_tracing/expression/special_expression/template_literal_004_F":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/completeness/single_app_tracing/expression/special_expression/template_literal_005_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/jsbenchmark/completeness/single_app_tracing/expression/special_expression/template_literal_005_T\nLine 13: __taint_sink(result)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/jsbenchmark/completeness/single_app_tracing/expression/special_expression/template_literal_005_T\",\"functionName\":\"template_literal_005_T\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /jsbenchmark/completeness/single_app_tracing/expression/special_expression/template_literal_005_T\n AffectedNodeName: __taint_src\n 11: SOURCE: function template_literal_005_T(__taint_src) {\n /jsbenchmark/completeness/single_app_tracing/expression/special_expression/template_literal_005_T\n AffectedNodeName: result\n 12: Var Pass: let result = `_${__taint_src}_`;\n /jsbenchmark/completeness/single_app_tracing/expression/special_expression/template_literal_005_T\n AffectedNodeName: __taint_sink\n 13: SINK: __taint_sink(result);\n==========================================================\n #Total-findings:1\n==========================================================","/jsbenchmark/completeness/single_app_tracing/expression/special_expression/template_literal_006_F":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/completeness/single_app_tracing/expression/this_expression/this_expression_001_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/jsbenchmark/completeness/single_app_tracing/expression/this_expression/this_expression_001_T\nLine 20: __taint_sink(result)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/jsbenchmark/completeness/single_app_tracing/expression/this_expression/this_expression_001_T\",\"functionName\":\"this_expression_001_T\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /jsbenchmark/completeness/single_app_tracing/expression/this_expression/this_expression_001_T\n AffectedNodeName: __taint_src\n 11: SOURCE: function this_expression_001_T(__taint_src) {\n /jsbenchmark/completeness/single_app_tracing/expression/this_expression/this_expression_001_T\n AffectedNodeName: obj\n 12: Var Pass: let obj = {\n 13: Var Pass: value: __taint_src,\n 14: Var Pass: getValue: function () {\n 15: Var Pass: return this.value;\n 16: Var Pass: },\n 17: Var Pass: };\n /jsbenchmark/completeness/single_app_tracing/expression/this_expression/this_expression_001_T\n AffectedNodeName: \n 19: CALL: let result = obj.getValue();\n /jsbenchmark/completeness/single_app_tracing/expression/this_expression/this_expression_001_T\n AffectedNodeName: obj\n 19: ARG PASS: let result = obj.getValue();\n /jsbenchmark/completeness/single_app_tracing/expression/this_expression/this_expression_001_T\n AffectedNodeName: [return value]\n 15: Return Value: return this.value;\n /jsbenchmark/completeness/single_app_tracing/expression/this_expression/this_expression_001_T\n AffectedNodeName: \n 19: CALL RETURN: let result = obj.getValue();\n /jsbenchmark/completeness/single_app_tracing/expression/this_expression/this_expression_001_T\n AffectedNodeName: result\n 19: Var Pass: let result = obj.getValue();\n /jsbenchmark/completeness/single_app_tracing/expression/this_expression/this_expression_001_T\n AffectedNodeName: __taint_sink\n 20: SINK: __taint_sink(result);\n==========================================================\n #Total-findings:1\n==========================================================","/jsbenchmark/completeness/single_app_tracing/expression/this_expression/this_expression_002_F":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/completeness/single_app_tracing/expression/this_expression/this_expression_003_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/jsbenchmark/completeness/single_app_tracing/expression/this_expression/this_expression_003_T\nLine 15: __taint_sink(this.result)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/jsbenchmark/completeness/single_app_tracing/expression/this_expression/this_expression_003_T\",\"functionName\":\"this_expression_003_T\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /jsbenchmark/completeness/single_app_tracing/expression/this_expression/this_expression_003_T\n AffectedNodeName: __taint_src\n 13: SOURCE: function this_expression_003_T(__taint_src) {\n /jsbenchmark/completeness/single_app_tracing/expression/this_expression/this_expression_003_T\n AffectedNodeName: this.result\n 14: Var Pass: this.result = __taint_src;\n /jsbenchmark/completeness/single_app_tracing/expression/this_expression/this_expression_003_T\n AffectedNodeName: __taint_sink\n 15: SINK: __taint_sink(this.result);\n==========================================================\n #Total-findings:1\n==========================================================","/jsbenchmark/completeness/single_app_tracing/expression/this_expression/this_expression_004_F":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/completeness/single_app_tracing/expression/type_cast/type_cast_001_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/jsbenchmark/completeness/single_app_tracing/expression/type_cast/type_cast_001_T\nLine 13: __taint_sink(result)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/jsbenchmark/completeness/single_app_tracing/expression/type_cast/type_cast_001_T\",\"functionName\":\"type_cast_001_T\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /jsbenchmark/completeness/single_app_tracing/expression/type_cast/type_cast_001_T\n AffectedNodeName: __taint_src\n 11: SOURCE: function type_cast_001_T(__taint_src) {\n /jsbenchmark/completeness/single_app_tracing/expression/type_cast/type_cast_001_T\n AffectedNodeName: result\n 12: Var Pass: let result = Number(__taint_src);\n /jsbenchmark/completeness/single_app_tracing/expression/type_cast/type_cast_001_T\n AffectedNodeName: __taint_sink\n 13: SINK: __taint_sink(result);\n==========================================================\n #Total-findings:1\n==========================================================","/jsbenchmark/completeness/single_app_tracing/expression/type_cast/type_cast_002_F":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/completeness/single_app_tracing/expression/type_cast/type_cast_003_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/jsbenchmark/completeness/single_app_tracing/expression/type_cast/type_cast_003_T\nLine 13: __taint_sink(result)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/jsbenchmark/completeness/single_app_tracing/expression/type_cast/type_cast_003_T\",\"functionName\":\"type_cast_003_T\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /jsbenchmark/completeness/single_app_tracing/expression/type_cast/type_cast_003_T\n AffectedNodeName: __taint_src\n 11: SOURCE: function type_cast_003_T(__taint_src) {\n /jsbenchmark/completeness/single_app_tracing/expression/type_cast/type_cast_003_T\n AffectedNodeName: result\n 12: Var Pass: let result = __taint_src == 5;\n /jsbenchmark/completeness/single_app_tracing/expression/type_cast/type_cast_003_T\n AffectedNodeName: __taint_sink\n 13: SINK: __taint_sink(result);\n==========================================================\n #Total-findings:1\n==========================================================","/jsbenchmark/completeness/single_app_tracing/expression/type_cast/type_cast_004_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/jsbenchmark/completeness/single_app_tracing/expression/type_cast/type_cast_004_T\nLine 13: __taint_sink(result)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/jsbenchmark/completeness/single_app_tracing/expression/type_cast/type_cast_004_T\",\"functionName\":\"type_cast_004_T\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /jsbenchmark/completeness/single_app_tracing/expression/type_cast/type_cast_004_T\n AffectedNodeName: __taint_src\n 11: SOURCE: function type_cast_004_T(__taint_src) {\n /jsbenchmark/completeness/single_app_tracing/expression/type_cast/type_cast_004_T\n AffectedNodeName: result\n 12: Var Pass: let result = __taint_src == \"5\";\n /jsbenchmark/completeness/single_app_tracing/expression/type_cast/type_cast_004_T\n AffectedNodeName: __taint_sink\n 13: SINK: __taint_sink(result);\n==========================================================\n #Total-findings:1\n==========================================================","/jsbenchmark/completeness/single_app_tracing/function_call/anonymous_function_closure/anonymous_function_001_F":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/completeness/single_app_tracing/function_call/anonymous_function_closure/anonymous_function_002_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/jsbenchmark/completeness/single_app_tracing/function_call/anonymous_function_closure/anonymous_function_002_T\nLine 14: __taint_sink(process(__taint_src, foo))\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/jsbenchmark/completeness/single_app_tracing/function_call/anonymous_function_closure/anonymous_function_002_T\",\"functionName\":\"anonymous_function_002_T\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /jsbenchmark/completeness/single_app_tracing/function_call/anonymous_function_closure/anonymous_function_002_T\n AffectedNodeName: __taint_src\n 10: SOURCE: function anonymous_function_002_T(__taint_src) {\n /jsbenchmark/completeness/single_app_tracing/function_call/anonymous_function_closure/anonymous_function_002_T\n AffectedNodeName: \n 14: CALL: __taint_sink(process(__taint_src, \"foo\"));\n /jsbenchmark/completeness/single_app_tracing/function_call/anonymous_function_closure/anonymous_function_002_T\n AffectedNodeName: a\n 11: ARG PASS: const process = function (a, b) {\n /jsbenchmark/completeness/single_app_tracing/function_call/anonymous_function_closure/anonymous_function_002_T\n AffectedNodeName: [return value]\n 12: Return Value: return a + b;\n /jsbenchmark/completeness/single_app_tracing/function_call/anonymous_function_closure/anonymous_function_002_T\n AffectedNodeName: \n 14: CALL RETURN: __taint_sink(process(__taint_src, \"foo\"));\n /jsbenchmark/completeness/single_app_tracing/function_call/anonymous_function_closure/anonymous_function_002_T\n AffectedNodeName: __taint_sink\n 14: SINK: __taint_sink(process(__taint_src, \"foo\"));\n==========================================================\n #Total-findings:1\n==========================================================","/jsbenchmark/completeness/single_app_tracing/function_call/anonymous_function_closure/anonymous_function_003_F":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/completeness/single_app_tracing/function_call/anonymous_function_closure/anonymous_function_004_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/jsbenchmark/completeness/single_app_tracing/function_call/anonymous_function_closure/anonymous_function_004_T\nLine 12: __taint_sink(input)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/jsbenchmark/completeness/single_app_tracing/function_call/anonymous_function_closure/anonymous_function_004_T\",\"functionName\":\"anonymous_function_004_T\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /jsbenchmark/completeness/single_app_tracing/function_call/anonymous_function_closure/anonymous_function_004_T\n AffectedNodeName: __taint_src\n 10: SOURCE: function anonymous_function_004_T(__taint_src) {\n /jsbenchmark/completeness/single_app_tracing/function_call/anonymous_function_closure/anonymous_function_004_T\n AffectedNodeName: \n 15: CALL: process(__taint_src);\n /jsbenchmark/completeness/single_app_tracing/function_call/anonymous_function_closure/anonymous_function_004_T\n AffectedNodeName: input\n 11: ARG PASS: let process = function (input) {\n /jsbenchmark/completeness/single_app_tracing/function_call/anonymous_function_closure/anonymous_function_004_T\n AffectedNodeName: __taint_sink\n 12: SINK: __taint_sink(input);\n==========================================================\n #Total-findings:1\n==========================================================","/jsbenchmark/completeness/single_app_tracing/function_call/anonymous_function_closure/anonymous_function_005_F":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/completeness/single_app_tracing/function_call/anonymous_function_closure/anonymous_function_006_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/jsbenchmark/completeness/single_app_tracing/function_call/anonymous_function_closure/anonymous_function_006_T\nLine 12: __taint_sink(__taint_src)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/jsbenchmark/completeness/single_app_tracing/function_call/anonymous_function_closure/anonymous_function_006_T\",\"functionName\":\"anonymous_function_006_T\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /jsbenchmark/completeness/single_app_tracing/function_call/anonymous_function_closure/anonymous_function_006_T\n AffectedNodeName: __taint_src\n 10: SOURCE: function anonymous_function_006_T(__taint_src) {\n /jsbenchmark/completeness/single_app_tracing/function_call/anonymous_function_closure/anonymous_function_006_T\n AffectedNodeName: __taint_sink\n 12: SINK: __taint_sink(__taint_src);\n==========================================================\n #Total-findings:1\n==========================================================","/jsbenchmark/completeness/single_app_tracing/function_call/anonymous_function_closure/closure_function_001_F":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/completeness/single_app_tracing/function_call/anonymous_function_closure/closure_function_002_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/jsbenchmark/completeness/single_app_tracing/function_call/anonymous_function_closure/closure_function_002_T\nLine 12: __taint_sink(__taint_src)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/jsbenchmark/completeness/single_app_tracing/function_call/anonymous_function_closure/closure_function_002_T\",\"functionName\":\"closure_function_002_T\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /jsbenchmark/completeness/single_app_tracing/function_call/anonymous_function_closure/closure_function_002_T\n AffectedNodeName: __taint_src\n 10: SOURCE: function closure_function_002_T(__taint_src) {\n /jsbenchmark/completeness/single_app_tracing/function_call/anonymous_function_closure/closure_function_002_T\n AffectedNodeName: __taint_sink\n 12: SINK: __taint_sink(__taint_src);\n==========================================================\n #Total-findings:1\n==========================================================","/jsbenchmark/completeness/single_app_tracing/function_call/anonymous_function_closure/closure_function_003_F":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/completeness/single_app_tracing/function_call/anonymous_function_closure/closure_function_004_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/jsbenchmark/completeness/single_app_tracing/function_call/anonymous_function_closure/closure_function_004_T\nLine 13: __taint_sink(__taint_src)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/jsbenchmark/completeness/single_app_tracing/function_call/anonymous_function_closure/closure_function_004_T\",\"functionName\":\"closure_function_004_T\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /jsbenchmark/completeness/single_app_tracing/function_call/anonymous_function_closure/closure_function_004_T\n AffectedNodeName: __taint_src\n 10: SOURCE: function closure_function_004_T(__taint_src) {\n /jsbenchmark/completeness/single_app_tracing/function_call/anonymous_function_closure/closure_function_004_T\n AffectedNodeName: __taint_sink\n 13: SINK: __taint_sink(__taint_src);\n==========================================================\n #Total-findings:1\n==========================================================","/jsbenchmark/completeness/single_app_tracing/function_call/anonymous_function_closure/closure_function_005_F":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/completeness/single_app_tracing/function_call/anonymous_function_closure/closure_function_006_F":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/completeness/single_app_tracing/function_call/anonymous_function_closure/closure_function_007_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/jsbenchmark/completeness/single_app_tracing/function_call/anonymous_function_closure/closure_function_007_T\nLine 25: __taint_sink(a.update())\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/jsbenchmark/completeness/single_app_tracing/function_call/anonymous_function_closure/closure_function_007_T\",\"functionName\":\"closure_function_007_T\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /jsbenchmark/completeness/single_app_tracing/function_call/anonymous_function_closure/closure_function_007_T\n AffectedNodeName: __taint_src\n 10: SOURCE: function closure_function_007_T(__taint_src) {\n /jsbenchmark/completeness/single_app_tracing/function_call/anonymous_function_closure/closure_function_007_T\n AffectedNodeName: source\n 15: Var Pass: source = __taint_src;\n /jsbenchmark/completeness/single_app_tracing/function_call/anonymous_function_closure/closure_function_007_T\n AffectedNodeName: [return value]\n 16: Return Value: return source;\n /jsbenchmark/completeness/single_app_tracing/function_call/anonymous_function_closure/closure_function_007_T\n AffectedNodeName: \n 25: CALL RETURN: __taint_sink(a.update());\n /jsbenchmark/completeness/single_app_tracing/function_call/anonymous_function_closure/closure_function_007_T\n AffectedNodeName: __taint_sink\n 25: SINK: __taint_sink(a.update());\n==========================================================\n #Total-findings:1\n==========================================================","/jsbenchmark/completeness/single_app_tracing/function_call/anonymous_function_closure/closure_function_008_F":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/completeness/single_app_tracing/function_call/anonymous_function_closure/closure_function_009_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/jsbenchmark/completeness/single_app_tracing/function_call/anonymous_function_closure/closure_function_009_T\nLine 18: __taint_sink(middleVar)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/jsbenchmark/completeness/single_app_tracing/function_call/anonymous_function_closure/closure_function_009_T\",\"functionName\":\"closure_function_009_T\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /jsbenchmark/completeness/single_app_tracing/function_call/anonymous_function_closure/closure_function_009_T\n AffectedNodeName: __taint_src\n 10: SOURCE: function closure_function_009_T(__taint_src) {\n /jsbenchmark/completeness/single_app_tracing/function_call/anonymous_function_closure/closure_function_009_T\n AffectedNodeName: outerVar\n 12: Var Pass: let outerVar = __taint_src;\n /jsbenchmark/completeness/single_app_tracing/function_call/anonymous_function_closure/closure_function_009_T\n AffectedNodeName: middleVar\n 15: Var Pass: let middleVar = outerVar;\n /jsbenchmark/completeness/single_app_tracing/function_call/anonymous_function_closure/closure_function_009_T\n AffectedNodeName: __taint_sink\n 18: SINK: __taint_sink(middleVar);\n==========================================================\n #Total-findings:1\n==========================================================","/jsbenchmark/completeness/single_app_tracing/function_call/anonymous_function_closure/closure_function_010_F":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/completeness/single_app_tracing/function_call/anonymous_function_closure/closure_function_011_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/jsbenchmark/completeness/single_app_tracing/function_call/anonymous_function_closure/closure_function_011_T\nLine 16: __taint_sink(outerVar)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/jsbenchmark/completeness/single_app_tracing/function_call/anonymous_function_closure/closure_function_011_T\",\"functionName\":\"closure_function_011_T\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /jsbenchmark/completeness/single_app_tracing/function_call/anonymous_function_closure/closure_function_011_T\n AffectedNodeName: __taint_src\n 10: SOURCE: function closure_function_011_T(__taint_src) {\n /jsbenchmark/completeness/single_app_tracing/function_call/anonymous_function_closure/closure_function_011_T\n AffectedNodeName: outerVar\n 12: Var Pass: let outerVar = __taint_src;\n /jsbenchmark/completeness/single_app_tracing/function_call/anonymous_function_closure/closure_function_011_T\n AffectedNodeName: __taint_sink\n 16: SINK: __taint_sink(outerVar);\n==========================================================\n #Total-findings:1\n==========================================================","/jsbenchmark/completeness/single_app_tracing/function_call/anonymous_function_closure/closure_function_012_F":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/completeness/single_app_tracing/function_call/anonymous_function_closure/closure_function_013_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/jsbenchmark/completeness/single_app_tracing/function_call/anonymous_function_closure/closure_function_013_T\nLine 14: __taint_sink(this.name)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/jsbenchmark/completeness/single_app_tracing/function_call/anonymous_function_closure/closure_function_013_T\",\"functionName\":\"closure_function_013_T\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /jsbenchmark/completeness/single_app_tracing/function_call/anonymous_function_closure/closure_function_013_T\n AffectedNodeName: __taint_src\n 10: SOURCE: function closure_function_013_T(__taint_src) {\n /jsbenchmark/completeness/single_app_tracing/function_call/anonymous_function_closure/closure_function_013_T\n AffectedNodeName: data\n 11: Var Pass: var data = {\n 12: Var Pass: name: __taint_src,\n 13: Var Pass: show: function () {\n 14: Var Pass: __taint_sink(this.name);\n 15: Var Pass: },\n 16: Var Pass: };\n /jsbenchmark/completeness/single_app_tracing/function_call/anonymous_function_closure/closure_function_013_T\n AffectedNodeName: \n 17: CALL: data.show();\n /jsbenchmark/completeness/single_app_tracing/function_call/anonymous_function_closure/closure_function_013_T\n AffectedNodeName: data\n 17: ARG PASS: data.show();\n /jsbenchmark/completeness/single_app_tracing/function_call/anonymous_function_closure/closure_function_013_T\n AffectedNodeName: __taint_sink\n 14: SINK: __taint_sink(this.name);\n==========================================================\n #Total-findings:1\n==========================================================","/jsbenchmark/completeness/single_app_tracing/function_call/anonymous_function_closure/closure_function_014_F":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/completeness/single_app_tracing/function_call/anonymous_function_closure/closure_function_015_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/jsbenchmark/completeness/single_app_tracing/function_call/anonymous_function_closure/closure_function_015_T\nLine 15: __taint_sink(this.name)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/jsbenchmark/completeness/single_app_tracing/function_call/anonymous_function_closure/closure_function_015_T\",\"functionName\":\"closure_function_015_T\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /jsbenchmark/completeness/single_app_tracing/function_call/anonymous_function_closure/closure_function_015_T\n AffectedNodeName: __taint_src\n 10: SOURCE: function closure_function_015_T(__taint_src) {\n /jsbenchmark/completeness/single_app_tracing/function_call/anonymous_function_closure/closure_function_015_T\n AffectedNodeName: data\n 11: Var Pass: var data = {\n 12: Var Pass: name: __taint_src,\n 13: Var Pass: show: function () {\n 14: Var Pass: return function () {\n 15: Var Pass: __taint_sink(this.name);\n 16: Var Pass: };\n 17: Var Pass: },\n 18: Var Pass: };\n /jsbenchmark/completeness/single_app_tracing/function_call/anonymous_function_closure/closure_function_015_T\n AffectedNodeName: \n 19: CALL: data.show().call(data);\n /jsbenchmark/completeness/single_app_tracing/function_call/anonymous_function_closure/closure_function_015_T\n AffectedNodeName: data\n 19: ARG PASS: data.show().call(data);\n /jsbenchmark/completeness/single_app_tracing/function_call/anonymous_function_closure/closure_function_015_T\n AffectedNodeName: \n 19: CALL: data.show().call(data);\n /jsbenchmark/completeness/single_app_tracing/function_call/anonymous_function_closure/closure_function_015_T\n AffectedNodeName: data.show()\n 19: ARG PASS: data.show().call(data);\n /jsbenchmark/completeness/single_app_tracing/function_call/anonymous_function_closure/closure_function_015_T\n AffectedNodeName: __taint_sink\n 15: SINK: __taint_sink(this.name);\n==========================================================\n #Total-findings:1\n==========================================================","/jsbenchmark/completeness/single_app_tracing/function_call/anonymous_function_closure/closure_function_016_F":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/completeness/single_app_tracing/function_call/anonymous_function_closure/closure_function_017_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/jsbenchmark/completeness/single_app_tracing/function_call/anonymous_function_closure/closure_function_017_T\nLine 14: __taint_sink(this.data)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/jsbenchmark/completeness/single_app_tracing/function_call/anonymous_function_closure/closure_function_017_T\",\"functionName\":\"closure_function_017_T\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /jsbenchmark/completeness/single_app_tracing/function_call/anonymous_function_closure/closure_function_017_T\n AffectedNodeName: __taint_src\n 10: SOURCE: function closure_function_017_T(__taint_src) {\n /jsbenchmark/completeness/single_app_tracing/function_call/anonymous_function_closure/closure_function_017_T\n AffectedNodeName: Process\n 18: CALL: const p = new Process(__taint_src);\n /jsbenchmark/completeness/single_app_tracing/function_call/anonymous_function_closure/closure_function_017_T\n AffectedNodeName: data\n 11: ARG PASS: function Process(data) {\n /jsbenchmark/completeness/single_app_tracing/function_call/anonymous_function_closure/closure_function_017_T\n AffectedNodeName: this.data\n 12: Var Pass: this.data = data;\n /jsbenchmark/completeness/single_app_tracing/function_call/anonymous_function_closure/closure_function_017_T\n AffectedNodeName: p\n 18: Var Pass: const p = new Process(__taint_src);\n /jsbenchmark/completeness/single_app_tracing/function_call/anonymous_function_closure/closure_function_017_T\n AffectedNodeName: \n 19: CALL: p.show();\n /jsbenchmark/completeness/single_app_tracing/function_call/anonymous_function_closure/closure_function_017_T\n AffectedNodeName: p\n 19: ARG PASS: p.show();\n /jsbenchmark/completeness/single_app_tracing/function_call/anonymous_function_closure/closure_function_017_T\n AffectedNodeName: __taint_sink\n 14: SINK: __taint_sink(this.data);\n==========================================================\n #Total-findings:1\n==========================================================","/jsbenchmark/completeness/single_app_tracing/function_call/argument_passing/argument_passing_default_value_001_F":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/completeness/single_app_tracing/function_call/argument_passing/argument_passing_default_value_002_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/jsbenchmark/completeness/single_app_tracing/function_call/argument_passing/argument_passing_default_value_002_T\nLine 15: __taint_sink(input)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/jsbenchmark/completeness/single_app_tracing/function_call/argument_passing/argument_passing_default_value_002_T\",\"functionName\":\"argument_passing_default_value_002_T\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /jsbenchmark/completeness/single_app_tracing/function_call/argument_passing/argument_passing_default_value_002_T\n AffectedNodeName: __taint_src\n 11: SOURCE: function argument_passing_default_value_002_T(__taint_src) {\n /jsbenchmark/completeness/single_app_tracing/function_call/argument_passing/argument_passing_default_value_002_T\n AffectedNodeName: process\n 12: CALL: process(__taint_src);\n /jsbenchmark/completeness/single_app_tracing/function_call/argument_passing/argument_passing_default_value_002_T\n AffectedNodeName: __tmp1__\n 14: ARG PASS: function process(input = \"default_value\") {\n /jsbenchmark/completeness/single_app_tracing/function_call/argument_passing/argument_passing_default_value_002_T\n AffectedNodeName: input\n 14: Var Pass: function process(input = \"default_value\") {\n 15: Var Pass: __taint_sink(input);\n 16: Var Pass: }\n /jsbenchmark/completeness/single_app_tracing/function_call/argument_passing/argument_passing_default_value_002_T\n AffectedNodeName: __taint_sink\n 15: SINK: __taint_sink(input);\n==========================================================\n #Total-findings:1\n==========================================================","/jsbenchmark/completeness/single_app_tracing/function_call/argument_passing/argument_passing_normal_value_001_F":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/completeness/single_app_tracing/function_call/argument_passing/argument_passing_normal_value_002_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/jsbenchmark/completeness/single_app_tracing/function_call/argument_passing/argument_passing_normal_value_002_T\nLine 15: __taint_sink(arg)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/jsbenchmark/completeness/single_app_tracing/function_call/argument_passing/argument_passing_normal_value_002_T\",\"functionName\":\"argument_passing_normal_value_002_T\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /jsbenchmark/completeness/single_app_tracing/function_call/argument_passing/argument_passing_normal_value_002_T\n AffectedNodeName: __taint_src\n 11: SOURCE: function argument_passing_normal_value_002_T(__taint_src) {\n /jsbenchmark/completeness/single_app_tracing/function_call/argument_passing/argument_passing_normal_value_002_T\n AffectedNodeName: process\n 12: CALL: process(__taint_src);\n /jsbenchmark/completeness/single_app_tracing/function_call/argument_passing/argument_passing_normal_value_002_T\n AffectedNodeName: arg\n 14: ARG PASS: function process(arg) {\n /jsbenchmark/completeness/single_app_tracing/function_call/argument_passing/argument_passing_normal_value_002_T\n AffectedNodeName: __taint_sink\n 15: SINK: __taint_sink(arg);\n==========================================================\n #Total-findings:1\n==========================================================","/jsbenchmark/completeness/single_app_tracing/function_call/argument_passing/argument_passing_normal_value_003_F":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/completeness/single_app_tracing/function_call/argument_passing/argument_passing_normal_value_004_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/jsbenchmark/completeness/single_app_tracing/function_call/argument_passing/argument_passing_normal_value_004_T\nLine 15: __taint_sink(arg1)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/jsbenchmark/completeness/single_app_tracing/function_call/argument_passing/argument_passing_normal_value_004_T\",\"functionName\":\"argument_passing_normal_value_004_T\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /jsbenchmark/completeness/single_app_tracing/function_call/argument_passing/argument_passing_normal_value_004_T\n AffectedNodeName: __taint_src\n 11: SOURCE: function argument_passing_normal_value_004_T(__taint_src) {\n /jsbenchmark/completeness/single_app_tracing/function_call/argument_passing/argument_passing_normal_value_004_T\n AffectedNodeName: process\n 12: CALL: process(__taint_src, \"_\");\n /jsbenchmark/completeness/single_app_tracing/function_call/argument_passing/argument_passing_normal_value_004_T\n AffectedNodeName: arg1\n 14: ARG PASS: function process(arg1, arg2) {\n /jsbenchmark/completeness/single_app_tracing/function_call/argument_passing/argument_passing_normal_value_004_T\n AffectedNodeName: __taint_sink\n 15: SINK: __taint_sink(arg1);\n==========================================================\n #Total-findings:1\n==========================================================","/jsbenchmark/completeness/single_app_tracing/function_call/argument_passing/argument_passing_normal_value_005_F":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/completeness/single_app_tracing/function_call/argument_passing/argument_passing_normal_value_006_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/jsbenchmark/completeness/single_app_tracing/function_call/argument_passing/argument_passing_normal_value_006_T\nLine 13: __taint_sink(innerInput)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/jsbenchmark/completeness/single_app_tracing/function_call/argument_passing/argument_passing_normal_value_006_T\",\"functionName\":\"argument_passing_normal_value_006_T\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /jsbenchmark/completeness/single_app_tracing/function_call/argument_passing/argument_passing_normal_value_006_T\n AffectedNodeName: __taint_src\n 10: SOURCE: function argument_passing_normal_value_006_T(__taint_src) {\n /jsbenchmark/completeness/single_app_tracing/function_call/argument_passing/argument_passing_normal_value_006_T\n AffectedNodeName: outer\n 19: CALL: outer(__taint_src);\n /jsbenchmark/completeness/single_app_tracing/function_call/argument_passing/argument_passing_normal_value_006_T\n AffectedNodeName: input\n 11: ARG PASS: function outer(input) {\n /jsbenchmark/completeness/single_app_tracing/function_call/argument_passing/argument_passing_normal_value_006_T\n AffectedNodeName: inner\n 16: CALL: inner(input);\n /jsbenchmark/completeness/single_app_tracing/function_call/argument_passing/argument_passing_normal_value_006_T\n AffectedNodeName: innerInput\n 12: ARG PASS: function inner(innerInput) {\n /jsbenchmark/completeness/single_app_tracing/function_call/argument_passing/argument_passing_normal_value_006_T\n AffectedNodeName: __taint_sink\n 13: SINK: __taint_sink(innerInput);\n==========================================================\n #Total-findings:1\n==========================================================","/jsbenchmark/completeness/single_app_tracing/function_call/argument_passing/argument_passing_reference_001_F":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/completeness/single_app_tracing/function_call/argument_passing/argument_passing_reference_002_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/jsbenchmark/completeness/single_app_tracing/function_call/argument_passing/argument_passing_reference_002_T\nLine 14: __taint_sink(obj.data)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/jsbenchmark/completeness/single_app_tracing/function_call/argument_passing/argument_passing_reference_002_T\",\"functionName\":\"argument_passing_reference_002_T\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /jsbenchmark/completeness/single_app_tracing/function_call/argument_passing/argument_passing_reference_002_T\n AffectedNodeName: __taint_src\n 11: SOURCE: function argument_passing_reference_002_T(__taint_src) {\n /jsbenchmark/completeness/single_app_tracing/function_call/argument_passing/argument_passing_reference_002_T\n AffectedNodeName: obj.data\n 17: Var Pass: obj.data = __taint_src;\n /jsbenchmark/completeness/single_app_tracing/function_call/argument_passing/argument_passing_reference_002_T\n AffectedNodeName: __taint_sink\n 14: SINK: __taint_sink(obj.data);\n==========================================================\n #Total-findings:1\n==========================================================","/jsbenchmark/completeness/single_app_tracing/function_call/argument_passing/argument_passing_reference_003_F":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/completeness/single_app_tracing/function_call/argument_passing/argument_passing_reference_004_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/jsbenchmark/completeness/single_app_tracing/function_call/argument_passing/argument_passing_reference_004_T\nLine 14: __taint_sink(arr)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/jsbenchmark/completeness/single_app_tracing/function_call/argument_passing/argument_passing_reference_004_T\",\"functionName\":\"argument_passing_reference_004_T\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /jsbenchmark/completeness/single_app_tracing/function_call/argument_passing/argument_passing_reference_004_T\n AffectedNodeName: __taint_src\n 11: SOURCE: function argument_passing_reference_004_T(__taint_src) {\n /jsbenchmark/completeness/single_app_tracing/function_call/argument_passing/argument_passing_reference_004_T\n AffectedNodeName: inputArr[0]\n 17: Var Pass: inputArr[0] = __taint_src;\n /jsbenchmark/completeness/single_app_tracing/function_call/argument_passing/argument_passing_reference_004_T\n AffectedNodeName: __taint_sink\n 14: SINK: __taint_sink(arr);\n==========================================================\n #Total-findings:1\n==========================================================","/jsbenchmark/completeness/single_app_tracing/function_call/argument_passing/argument_passing_reference_005_F":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/completeness/single_app_tracing/function_call/argument_passing/argument_passing_reference_006_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/jsbenchmark/completeness/single_app_tracing/function_call/argument_passing/argument_passing_reference_006_T\nLine 16: __taint_sink(objB.name)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/jsbenchmark/completeness/single_app_tracing/function_call/argument_passing/argument_passing_reference_006_T\",\"functionName\":\"argument_passing_reference_006_T\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /jsbenchmark/completeness/single_app_tracing/function_call/argument_passing/argument_passing_reference_006_T\n AffectedNodeName: __taint_src\n 11: SOURCE: function argument_passing_reference_006_T(__taint_src) {\n /jsbenchmark/completeness/single_app_tracing/function_call/argument_passing/argument_passing_reference_006_T\n AffectedNodeName: objA\n 12: Var Pass: const objA = { name: __taint_src };\n /jsbenchmark/completeness/single_app_tracing/function_call/argument_passing/argument_passing_reference_006_T\n AffectedNodeName: swap\n 15: CALL: swap(objA, objB);\n /jsbenchmark/completeness/single_app_tracing/function_call/argument_passing/argument_passing_reference_006_T\n AffectedNodeName: obj1\n 18: ARG PASS: function swap(obj1, obj2) {\n /jsbenchmark/completeness/single_app_tracing/function_call/argument_passing/argument_passing_reference_006_T\n AffectedNodeName: temp\n 19: Var Pass: const temp = obj1.name;\n /jsbenchmark/completeness/single_app_tracing/function_call/argument_passing/argument_passing_reference_006_T\n AffectedNodeName: obj2.name\n 21: Var Pass: obj2.name = temp;\n /jsbenchmark/completeness/single_app_tracing/function_call/argument_passing/argument_passing_reference_006_T\n AffectedNodeName: __taint_sink\n 16: SINK: __taint_sink(objB.name);\n==========================================================\n #Total-findings:1\n==========================================================","/jsbenchmark/completeness/single_app_tracing/function_call/arrow_function/arrow_function_001_F":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/completeness/single_app_tracing/function_call/arrow_function/arrow_function_002_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/jsbenchmark/completeness/single_app_tracing/function_call/arrow_function/arrow_function_002_T\nLine 12: __taint_sink(__taint_src)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/jsbenchmark/completeness/single_app_tracing/function_call/arrow_function/arrow_function_002_T\",\"functionName\":\"arrow_function_002_T\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /jsbenchmark/completeness/single_app_tracing/function_call/arrow_function/arrow_function_002_T\n AffectedNodeName: __taint_src\n 11: SOURCE: function arrow_function_002_T(__taint_src) {\n /jsbenchmark/completeness/single_app_tracing/function_call/arrow_function/arrow_function_002_T\n AffectedNodeName: __taint_sink\n 12: SINK: let arrowFunction = () => __taint_sink(__taint_src);\n==========================================================\n #Total-findings:1\n==========================================================","/jsbenchmark/completeness/single_app_tracing/function_call/arrow_function/arrow_function_003_F":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/completeness/single_app_tracing/function_call/arrow_function/arrow_function_004_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/jsbenchmark/completeness/single_app_tracing/function_call/arrow_function/arrow_function_004_T\nLine 14: __taint_sink(__taint_src)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/jsbenchmark/completeness/single_app_tracing/function_call/arrow_function/arrow_function_004_T\",\"functionName\":\"arrow_function_004_T\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /jsbenchmark/completeness/single_app_tracing/function_call/arrow_function/arrow_function_004_T\n AffectedNodeName: __taint_src\n 11: SOURCE: function arrow_function_004_T(__taint_src) {\n /jsbenchmark/completeness/single_app_tracing/function_call/arrow_function/arrow_function_004_T\n AffectedNodeName: __taint_sink\n 14: SINK: __taint_sink(__taint_src);\n==========================================================\n #Total-findings:1\n==========================================================","/jsbenchmark/completeness/single_app_tracing/function_call/arrow_function/arrow_function_005_F":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/completeness/single_app_tracing/function_call/arrow_function/arrow_function_006_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/jsbenchmark/completeness/single_app_tracing/function_call/arrow_function/arrow_function_006_T\nLine 15: __taint_sink(self.name)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/jsbenchmark/completeness/single_app_tracing/function_call/arrow_function/arrow_function_006_T\",\"functionName\":\"arrow_function_006_T\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /jsbenchmark/completeness/single_app_tracing/function_call/arrow_function/arrow_function_006_T\n AffectedNodeName: __taint_src\n 11: SOURCE: function arrow_function_006_T(__taint_src) {\n /jsbenchmark/completeness/single_app_tracing/function_call/arrow_function/arrow_function_006_T\n AffectedNodeName: this.name\n 12: Var Pass: this.name = __taint_src;\n /jsbenchmark/completeness/single_app_tracing/function_call/arrow_function/arrow_function_006_T\n AffectedNodeName: __taint_sink\n 15: SINK: show: () => __taint_sink(self.name),\n==========================================================\n #Total-findings:1\n==========================================================","/jsbenchmark/completeness/single_app_tracing/function_call/arrow_function/arrow_function_007_F":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/completeness/single_app_tracing/function_call/arrow_function/arrow_function_008_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/jsbenchmark/completeness/single_app_tracing/function_call/arrow_function/arrow_function_008_T\nLine 16: __taint_sink(self.name)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/jsbenchmark/completeness/single_app_tracing/function_call/arrow_function/arrow_function_008_T\",\"functionName\":\"arrow_function_008_T\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /jsbenchmark/completeness/single_app_tracing/function_call/arrow_function/arrow_function_008_T\n AffectedNodeName: __taint_src\n 11: SOURCE: function arrow_function_008_T(__taint_src) {\n /jsbenchmark/completeness/single_app_tracing/function_call/arrow_function/arrow_function_008_T\n AffectedNodeName: this.name\n 12: Var Pass: this.name = __taint_src;\n /jsbenchmark/completeness/single_app_tracing/function_call/arrow_function/arrow_function_008_T\n AffectedNodeName: __taint_sink\n 16: SINK: return () => __taint_sink(self.name);\n==========================================================\n #Total-findings:1\n==========================================================","/jsbenchmark/completeness/single_app_tracing/function_call/arrow_function/arrow_function_009_F":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/completeness/single_app_tracing/function_call/arrow_function/arrow_function_010_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/jsbenchmark/completeness/single_app_tracing/function_call/arrow_function/arrow_function_010_T\nLine 14: __taint_sink(this.data)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/jsbenchmark/completeness/single_app_tracing/function_call/arrow_function/arrow_function_010_T\",\"functionName\":\"arrow_function_010_T\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /jsbenchmark/completeness/single_app_tracing/function_call/arrow_function/arrow_function_010_T\n AffectedNodeName: __taint_src\n 11: SOURCE: function arrow_function_010_T(__taint_src) {\n /jsbenchmark/completeness/single_app_tracing/function_call/arrow_function/arrow_function_010_T\n AffectedNodeName: Process\n 17: CALL: const p = new Process(__taint_src);\n /jsbenchmark/completeness/single_app_tracing/function_call/arrow_function/arrow_function_010_T\n AffectedNodeName: data\n 12: ARG PASS: function Process(data) {\n /jsbenchmark/completeness/single_app_tracing/function_call/arrow_function/arrow_function_010_T\n AffectedNodeName: this.data\n 13: Var Pass: this.data = data;\n /jsbenchmark/completeness/single_app_tracing/function_call/arrow_function/arrow_function_010_T\n AffectedNodeName: p\n 17: Var Pass: const p = new Process(__taint_src);\n /jsbenchmark/completeness/single_app_tracing/function_call/arrow_function/arrow_function_010_T\n AffectedNodeName: \n 18: CALL: p.show();\n /jsbenchmark/completeness/single_app_tracing/function_call/arrow_function/arrow_function_010_T\n AffectedNodeName: p\n 18: ARG PASS: p.show();\n /jsbenchmark/completeness/single_app_tracing/function_call/arrow_function/arrow_function_010_T\n AffectedNodeName: __taint_sink\n 14: SINK: this.show = () => __taint_sink(this.data);\n==========================================================\n #Total-findings:1\n==========================================================","/jsbenchmark/completeness/single_app_tracing/function_call/chained_call/chained_call_001_F":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/completeness/single_app_tracing/function_call/chained_call/chained_call_002_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/jsbenchmark/completeness/single_app_tracing/function_call/chained_call/chained_call_002_T\nLine 28: __taint_sink(this.name)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/jsbenchmark/completeness/single_app_tracing/function_call/chained_call/chained_call_002_T\",\"functionName\":\"chained_call_002_T\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /jsbenchmark/completeness/single_app_tracing/function_call/chained_call/chained_call_002_T\n AffectedNodeName: __taint_src\n 11: SOURCE: function chained_call_002_T(__taint_src) {\n /jsbenchmark/completeness/single_app_tracing/function_call/chained_call/chained_call_002_T\n AffectedNodeName: setName\n 32: CALL: new A().setName(\"_\").clearName().setName(__taint_src).process();\n /jsbenchmark/completeness/single_app_tracing/function_call/chained_call/chained_call_002_T\n AffectedNodeName: name\n 17: ARG PASS: setName(name) {\n /jsbenchmark/completeness/single_app_tracing/function_call/chained_call/chained_call_002_T\n AffectedNodeName: this.name\n 18: Var Pass: this.name = name;\n /jsbenchmark/completeness/single_app_tracing/function_call/chained_call/chained_call_002_T\n AffectedNodeName: [return value]\n 19: Return Value: return this;\n /jsbenchmark/completeness/single_app_tracing/function_call/chained_call/chained_call_002_T\n AffectedNodeName: setName\n 32: CALL RETURN: new A().setName(\"_\").clearName().setName(__taint_src).process();\n /jsbenchmark/completeness/single_app_tracing/function_call/chained_call/chained_call_002_T\n AffectedNodeName: process\n 32: CALL: new A().setName(\"_\").clearName().setName(__taint_src).process();\n /jsbenchmark/completeness/single_app_tracing/function_call/chained_call/chained_call_002_T\n AffectedNodeName: new A().setName(_).clearName().setName(__taint_src\n 32: ARG PASS: new A().setName(\"_\").clearName().setName(__taint_src).process();\n /jsbenchmark/completeness/single_app_tracing/function_call/chained_call/chained_call_002_T\n AffectedNodeName: __taint_sink\n 28: SINK: __taint_sink(this.name);\n==========================================================\n #Total-findings:1\n==========================================================","/jsbenchmark/completeness/single_app_tracing/function_call/decorator_function/class_decorator_001_F":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/completeness/single_app_tracing/function_call/decorator_function/class_decorator_002_T":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/completeness/single_app_tracing/function_call/decorator_function/class_decorator_003_F":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/completeness/single_app_tracing/function_call/decorator_function/class_decorator_004_T":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/completeness/single_app_tracing/function_call/decorator_function/class_member_decorator_001_F":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/completeness/single_app_tracing/function_call/decorator_function/class_member_decorator_002_T":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/completeness/single_app_tracing/function_call/decorator_function/function_decorator_001_F":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/completeness/single_app_tracing/function_call/decorator_function/function_decorator_002_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/jsbenchmark/completeness/single_app_tracing/function_call/decorator_function/function_decorator_002_T\nLine 14: __taint_sink(args)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/jsbenchmark/completeness/single_app_tracing/function_call/decorator_function/function_decorator_002_T\",\"functionName\":\"function_decorator_002_T\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /jsbenchmark/completeness/single_app_tracing/function_call/decorator_function/function_decorator_002_T\n AffectedNodeName: __taint_src\n 11: SOURCE: function function_decorator_002_T(__taint_src) {\n /jsbenchmark/completeness/single_app_tracing/function_call/decorator_function/function_decorator_002_T\n AffectedNodeName: \n 20: CALL: decoratedFunction(__taint_src);\n /jsbenchmark/completeness/single_app_tracing/function_call/decorator_function/function_decorator_002_T\n AffectedNodeName: __tmp1__\n 13: ARG PASS: return function (...args) {\n /jsbenchmark/completeness/single_app_tracing/function_call/decorator_function/function_decorator_002_T\n AffectedNodeName: args\n 13: Var Pass: return function (...args) {\n 14: Var Pass: __taint_sink(args);\n 15: Var Pass: return targetFunction.apply(this, args);\n 16: Var Pass: };\n /jsbenchmark/completeness/single_app_tracing/function_call/decorator_function/function_decorator_002_T\n AffectedNodeName: __taint_sink\n 14: SINK: __taint_sink(args);\n==========================================================\n #Total-findings:1\n==========================================================","/jsbenchmark/completeness/single_app_tracing/function_call/decorator_function/function_decorator_003_F":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/completeness/single_app_tracing/function_call/decorator_function/function_decorator_004_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/jsbenchmark/completeness/single_app_tracing/function_call/decorator_function/function_decorator_004_T\nLine 19: __taint_sink(input)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/jsbenchmark/completeness/single_app_tracing/function_call/decorator_function/function_decorator_004_T\",\"functionName\":\"function_decorator_004_T\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /jsbenchmark/completeness/single_app_tracing/function_call/decorator_function/function_decorator_004_T\n AffectedNodeName: __taint_src\n 11: SOURCE: function function_decorator_004_T(__taint_src) {\n /jsbenchmark/completeness/single_app_tracing/function_call/decorator_function/function_decorator_004_T\n AffectedNodeName: \n 21: CALL: decoratedFunction(__taint_src);\n /jsbenchmark/completeness/single_app_tracing/function_call/decorator_function/function_decorator_004_T\n AffectedNodeName: __tmp1__\n 13: ARG PASS: return function (...args) {\n /jsbenchmark/completeness/single_app_tracing/function_call/decorator_function/function_decorator_004_T\n AffectedNodeName: args\n 13: Var Pass: return function (...args) {\n 14: Var Pass: return targetFunction.apply(this, args);\n 15: Var Pass: };\n /jsbenchmark/completeness/single_app_tracing/function_call/decorator_function/function_decorator_004_T\n AffectedNodeName: \n 14: CALL: return targetFunction.apply(this, args);\n /jsbenchmark/completeness/single_app_tracing/function_call/decorator_function/function_decorator_004_T\n AffectedNodeName: input\n 18: ARG PASS: const decoratedFunction = taintDecorator(function (input) {\n /jsbenchmark/completeness/single_app_tracing/function_call/decorator_function/function_decorator_004_T\n AffectedNodeName: __taint_sink\n 19: SINK: __taint_sink(input);\n==========================================================\n #Total-findings:1\n==========================================================","/jsbenchmark/completeness/single_app_tracing/function_call/generator_function/generator_function_001_F":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/completeness/single_app_tracing/function_call/generator_function/generator_function_002_T":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/completeness/single_app_tracing/function_call/generator_function/generator_function_003_F":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/completeness/single_app_tracing/function_call/generator_function/generator_function_004_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/jsbenchmark/completeness/single_app_tracing/function_call/generator_function/generator_function_004_T\nLine 21: __taint_sink(g.next(__taint_src).value)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/jsbenchmark/completeness/single_app_tracing/function_call/generator_function/generator_function_004_T\",\"functionName\":\"generator_function_004_T\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /jsbenchmark/completeness/single_app_tracing/function_call/generator_function/generator_function_004_T\n AffectedNodeName: __taint_src\n 11: SOURCE: function generator_function_004_T(__taint_src) {\n /jsbenchmark/completeness/single_app_tracing/function_call/generator_function/generator_function_004_T\n AffectedNodeName: __taint_sink\n 21: SINK: __taint_sink(g.next(__taint_src).value);\n==========================================================\n #Total-findings:1\n==========================================================","/jsbenchmark/completeness/single_app_tracing/function_call/higher_order_function/higher_order_function_001_F":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/completeness/single_app_tracing/function_call/higher_order_function/higher_order_function_002_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/jsbenchmark/completeness/single_app_tracing/function_call/higher_order_function/higher_order_function_002_T\nLine 19: __taint_sink(f(__taint_src, _)())\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/jsbenchmark/completeness/single_app_tracing/function_call/higher_order_function/higher_order_function_002_T\",\"functionName\":\"higher_order_function_002_T\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /jsbenchmark/completeness/single_app_tracing/function_call/higher_order_function/higher_order_function_002_T\n AffectedNodeName: __taint_src\n 11: SOURCE: function higher_order_function_002_T(__taint_src) {\n /jsbenchmark/completeness/single_app_tracing/function_call/higher_order_function/higher_order_function_002_T\n AffectedNodeName: f\n 19: CALL: __taint_sink(f(__taint_src, \"_\")());\n /jsbenchmark/completeness/single_app_tracing/function_call/higher_order_function/higher_order_function_002_T\n AffectedNodeName: a\n 12: ARG PASS: function f(a, b) {\n /jsbenchmark/completeness/single_app_tracing/function_call/higher_order_function/higher_order_function_002_T\n AffectedNodeName: [return value]\n 15: Return Value: return a + b + c;\n /jsbenchmark/completeness/single_app_tracing/function_call/higher_order_function/higher_order_function_002_T\n AffectedNodeName: \n 19: CALL RETURN: __taint_sink(f(__taint_src, \"_\")());\n /jsbenchmark/completeness/single_app_tracing/function_call/higher_order_function/higher_order_function_002_T\n AffectedNodeName: __taint_sink\n 19: SINK: __taint_sink(f(__taint_src, \"_\")());\n==========================================================\n #Total-findings:1\n==========================================================","/jsbenchmark/completeness/single_app_tracing/function_call/higher_order_function/higher_order_function_003_F":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/completeness/single_app_tracing/function_call/higher_order_function/higher_order_function_004_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/jsbenchmark/completeness/single_app_tracing/function_call/higher_order_function/higher_order_function_004_T\nLine 23: __taint_sink(f(g, __taint_src, _)())\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/jsbenchmark/completeness/single_app_tracing/function_call/higher_order_function/higher_order_function_004_T\",\"functionName\":\"higher_order_function_004_T\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /jsbenchmark/completeness/single_app_tracing/function_call/higher_order_function/higher_order_function_004_T\n AffectedNodeName: __taint_src\n 11: SOURCE: function higher_order_function_004_T(__taint_src) {\n /jsbenchmark/completeness/single_app_tracing/function_call/higher_order_function/higher_order_function_004_T\n AffectedNodeName: f\n 23: CALL: __taint_sink(f(g, __taint_src, \"_\")());\n /jsbenchmark/completeness/single_app_tracing/function_call/higher_order_function/higher_order_function_004_T\n AffectedNodeName: a\n 12: ARG PASS: function f(g, a, b) {\n /jsbenchmark/completeness/single_app_tracing/function_call/higher_order_function/higher_order_function_004_T\n AffectedNodeName: g\n 13: CALL: return g(a, b);\n /jsbenchmark/completeness/single_app_tracing/function_call/higher_order_function/higher_order_function_004_T\n AffectedNodeName: a\n 16: ARG PASS: function g(a, b) {\n /jsbenchmark/completeness/single_app_tracing/function_call/higher_order_function/higher_order_function_004_T\n AffectedNodeName: [return value]\n 19: Return Value: return a + b + c;\n /jsbenchmark/completeness/single_app_tracing/function_call/higher_order_function/higher_order_function_004_T\n AffectedNodeName: \n 23: CALL RETURN: __taint_sink(f(g, __taint_src, \"_\")());\n /jsbenchmark/completeness/single_app_tracing/function_call/higher_order_function/higher_order_function_004_T\n AffectedNodeName: __taint_sink\n 23: SINK: __taint_sink(f(g, __taint_src, \"_\")());\n==========================================================\n #Total-findings:1\n==========================================================","/jsbenchmark/completeness/single_app_tracing/function_call/higher_order_function/higher_order_function_005_F":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/completeness/single_app_tracing/function_call/higher_order_function/higher_order_function_006_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/jsbenchmark/completeness/single_app_tracing/function_call/higher_order_function/higher_order_function_006_T\nLine 27: __taint_sink(f(g, u, __taint_src, _)())\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/jsbenchmark/completeness/single_app_tracing/function_call/higher_order_function/higher_order_function_006_T\",\"functionName\":\"higher_order_function_006_T\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /jsbenchmark/completeness/single_app_tracing/function_call/higher_order_function/higher_order_function_006_T\n AffectedNodeName: __taint_src\n 11: SOURCE: function higher_order_function_006_T(__taint_src) {\n /jsbenchmark/completeness/single_app_tracing/function_call/higher_order_function/higher_order_function_006_T\n AffectedNodeName: f\n 27: CALL: __taint_sink(f(g, u, __taint_src, \"_\")());\n /jsbenchmark/completeness/single_app_tracing/function_call/higher_order_function/higher_order_function_006_T\n AffectedNodeName: a\n 12: ARG PASS: function f(g, u, a, b) {\n /jsbenchmark/completeness/single_app_tracing/function_call/higher_order_function/higher_order_function_006_T\n AffectedNodeName: g\n 13: CALL: return g(u, a, b);\n /jsbenchmark/completeness/single_app_tracing/function_call/higher_order_function/higher_order_function_006_T\n AffectedNodeName: a\n 16: ARG PASS: function g(u, a, b) {\n /jsbenchmark/completeness/single_app_tracing/function_call/higher_order_function/higher_order_function_006_T\n AffectedNodeName: u\n 18: CALL: return u(a, b, c);\n /jsbenchmark/completeness/single_app_tracing/function_call/higher_order_function/higher_order_function_006_T\n AffectedNodeName: a\n 21: ARG PASS: function u(a, b, c) {\n /jsbenchmark/completeness/single_app_tracing/function_call/higher_order_function/higher_order_function_006_T\n AffectedNodeName: [return value]\n 23: Return Value: return a + b + c;\n /jsbenchmark/completeness/single_app_tracing/function_call/higher_order_function/higher_order_function_006_T\n AffectedNodeName: \n 27: CALL RETURN: __taint_sink(f(g, u, __taint_src, \"_\")());\n /jsbenchmark/completeness/single_app_tracing/function_call/higher_order_function/higher_order_function_006_T\n AffectedNodeName: __taint_sink\n 27: SINK: __taint_sink(f(g, u, __taint_src, \"_\")());\n==========================================================\n #Total-findings:1\n==========================================================","/jsbenchmark/completeness/single_app_tracing/function_call/higher_order_function/higher_order_function_007_F":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/completeness/single_app_tracing/function_call/higher_order_function/higher_order_function_008_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/jsbenchmark/completeness/single_app_tracing/function_call/higher_order_function/higher_order_function_008_T\nLine 17: __taint_sink(result)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/jsbenchmark/completeness/single_app_tracing/function_call/higher_order_function/higher_order_function_008_T\",\"functionName\":\"higher_order_function_008_T\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /jsbenchmark/completeness/single_app_tracing/function_call/higher_order_function/higher_order_function_008_T\n AffectedNodeName: __taint_src\n 11: SOURCE: function higher_order_function_008_T(__taint_src) {\n /jsbenchmark/completeness/single_app_tracing/function_call/higher_order_function/higher_order_function_008_T\n AffectedNodeName: \n 13: CALL: return callback(__taint_src, \"_\");\n /jsbenchmark/completeness/single_app_tracing/function_call/higher_order_function/higher_order_function_008_T\n AffectedNodeName: a\n 16: ARG PASS: const result = higherOrderFunction((a, b) => a + b);\n /jsbenchmark/completeness/single_app_tracing/function_call/higher_order_function/higher_order_function_008_T\n AffectedNodeName: [return value]\n 16: Return Value: const result = higherOrderFunction((a, b) => a + b);\n /jsbenchmark/completeness/single_app_tracing/function_call/higher_order_function/higher_order_function_008_T\n AffectedNodeName: \n 13: CALL RETURN: return callback(__taint_src, \"_\");\n /jsbenchmark/completeness/single_app_tracing/function_call/higher_order_function/higher_order_function_008_T\n AffectedNodeName: [return value]\n 13: Return Value: return callback(__taint_src, \"_\");\n /jsbenchmark/completeness/single_app_tracing/function_call/higher_order_function/higher_order_function_008_T\n AffectedNodeName: higherOrderFunction\n 16: CALL RETURN: const result = higherOrderFunction((a, b) => a + b);\n /jsbenchmark/completeness/single_app_tracing/function_call/higher_order_function/higher_order_function_008_T\n AffectedNodeName: result\n 16: Var Pass: const result = higherOrderFunction((a, b) => a + b);\n /jsbenchmark/completeness/single_app_tracing/function_call/higher_order_function/higher_order_function_008_T\n AffectedNodeName: __taint_sink\n 17: SINK: __taint_sink(result);\n==========================================================\n #Total-findings:1\n==========================================================","/jsbenchmark/completeness/single_app_tracing/function_call/higher_order_function/higher_order_function_009_F":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/completeness/single_app_tracing/function_call/higher_order_function/higher_order_function_010_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/jsbenchmark/completeness/single_app_tracing/function_call/higher_order_function/higher_order_function_010_T\nLine 19: __taint_sink(result)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/jsbenchmark/completeness/single_app_tracing/function_call/higher_order_function/higher_order_function_010_T\",\"functionName\":\"higher_order_function_010_T\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /jsbenchmark/completeness/single_app_tracing/function_call/higher_order_function/higher_order_function_010_T\n AffectedNodeName: __taint_src\n 11: SOURCE: function higher_order_function_010_T(__taint_src) {\n /jsbenchmark/completeness/single_app_tracing/function_call/higher_order_function/higher_order_function_010_T\n AffectedNodeName: \n 13: CALL: return callback(__taint_src, \"_\");\n /jsbenchmark/completeness/single_app_tracing/function_call/higher_order_function/higher_order_function_010_T\n AffectedNodeName: a\n 16: ARG PASS: const result = higherOrderFunction(function (a, b) {\n /jsbenchmark/completeness/single_app_tracing/function_call/higher_order_function/higher_order_function_010_T\n AffectedNodeName: [return value]\n 17: Return Value: return a + b;\n /jsbenchmark/completeness/single_app_tracing/function_call/higher_order_function/higher_order_function_010_T\n AffectedNodeName: \n 13: CALL RETURN: return callback(__taint_src, \"_\");\n /jsbenchmark/completeness/single_app_tracing/function_call/higher_order_function/higher_order_function_010_T\n AffectedNodeName: [return value]\n 13: Return Value: return callback(__taint_src, \"_\");\n /jsbenchmark/completeness/single_app_tracing/function_call/higher_order_function/higher_order_function_010_T\n AffectedNodeName: higherOrderFunction\n 16: CALL RETURN: const result = higherOrderFunction(function (a, b) {\n 17: CALL RETURN: return a + b;\n 18: CALL RETURN: });\n /jsbenchmark/completeness/single_app_tracing/function_call/higher_order_function/higher_order_function_010_T\n AffectedNodeName: result\n 16: Var Pass: const result = higherOrderFunction(function (a, b) {\n 17: Var Pass: return a + b;\n 18: Var Pass: });\n /jsbenchmark/completeness/single_app_tracing/function_call/higher_order_function/higher_order_function_010_T\n AffectedNodeName: __taint_sink\n 19: SINK: __taint_sink(result);\n==========================================================\n #Total-findings:1\n==========================================================","/jsbenchmark/completeness/single_app_tracing/function_call/library_function/json_001_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/jsbenchmark/completeness/single_app_tracing/function_call/library_function/json_001_T\nLine 15: __taint_sink(obj)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/jsbenchmark/completeness/single_app_tracing/function_call/library_function/json_001_T\",\"functionName\":\"json_001_T\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /jsbenchmark/completeness/single_app_tracing/function_call/library_function/json_001_T\n AffectedNodeName: __taint_src\n 10: SOURCE: function json_001_T(__taint_src) {\n /jsbenchmark/completeness/single_app_tracing/function_call/library_function/json_001_T\n AffectedNodeName: process\n 11: CALL: process(JSON.stringify(__taint_src));\n /jsbenchmark/completeness/single_app_tracing/function_call/library_function/json_001_T\n AffectedNodeName: arg\n 13: ARG PASS: function process(arg) {\n /jsbenchmark/completeness/single_app_tracing/function_call/library_function/json_001_T\n AffectedNodeName: obj\n 14: Var Pass: let obj = JSON.parse(arg);\n /jsbenchmark/completeness/single_app_tracing/function_call/library_function/json_001_T\n AffectedNodeName: __taint_sink\n 15: SINK: __taint_sink(obj);\n==========================================================\n #Total-findings:1\n==========================================================","/jsbenchmark/completeness/single_app_tracing/function_call/library_function/json_002_F":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/completeness/single_app_tracing/function_call/library_function/string_001_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/jsbenchmark/completeness/single_app_tracing/function_call/library_function/string_001_T\nLine 15: __taint_sink(result)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/jsbenchmark/completeness/single_app_tracing/function_call/library_function/string_001_T\",\"functionName\":\"string_001_T\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /jsbenchmark/completeness/single_app_tracing/function_call/library_function/string_001_T\n AffectedNodeName: __taint_src\n 10: SOURCE: function string_001_T(__taint_src) {\n /jsbenchmark/completeness/single_app_tracing/function_call/library_function/string_001_T\n AffectedNodeName: process\n 11: CALL: process(__taint_src);\n /jsbenchmark/completeness/single_app_tracing/function_call/library_function/string_001_T\n AffectedNodeName: arg\n 13: ARG PASS: function process(arg) {\n /jsbenchmark/completeness/single_app_tracing/function_call/library_function/string_001_T\n AffectedNodeName: result\n 14: Var Pass: let result = arg.trim();\n /jsbenchmark/completeness/single_app_tracing/function_call/library_function/string_001_T\n AffectedNodeName: __taint_sink\n 15: SINK: __taint_sink(result);\n==========================================================\n #Total-findings:1\n==========================================================","/jsbenchmark/completeness/single_app_tracing/function_call/library_function/string_002_F":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/completeness/single_app_tracing/function_call/override/constructor_extends_001_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/jsbenchmark/completeness/single_app_tracing/function_call/override/constructor_extends_001_T\nLine 31: __taint_sink(this.getData())\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/jsbenchmark/completeness/single_app_tracing/function_call/override/constructor_extends_001_T\",\"functionName\":\"constructor_extends_001_T\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /jsbenchmark/completeness/single_app_tracing/function_call/override/constructor_extends_001_T\n AffectedNodeName: __taint_src\n 10: SOURCE: function constructor_extends_001_T(__taint_src) {\n /jsbenchmark/completeness/single_app_tracing/function_call/override/constructor_extends_001_T\n AffectedNodeName: constructor\n 35: CALL: const derived = new DerivedClass(__taint_src);\n /jsbenchmark/completeness/single_app_tracing/function_call/override/constructor_extends_001_T\n AffectedNodeName: data\n 26: ARG PASS: constructor(data) {\n /jsbenchmark/completeness/single_app_tracing/function_call/override/constructor_extends_001_T\n AffectedNodeName: constructor\n 27: CALL: super(data);\n /jsbenchmark/completeness/single_app_tracing/function_call/override/constructor_extends_001_T\n AffectedNodeName: data\n 14: ARG PASS: constructor(data) {\n /jsbenchmark/completeness/single_app_tracing/function_call/override/constructor_extends_001_T\n AffectedNodeName: this.data\n 15: Var Pass: this.data = data;\n /jsbenchmark/completeness/single_app_tracing/function_call/override/constructor_extends_001_T\n AffectedNodeName: derived\n 35: Var Pass: const derived = new DerivedClass(__taint_src);\n /jsbenchmark/completeness/single_app_tracing/function_call/override/constructor_extends_001_T\n AffectedNodeName: process\n 36: CALL: derived.process();\n /jsbenchmark/completeness/single_app_tracing/function_call/override/constructor_extends_001_T\n AffectedNodeName: derived\n 36: ARG PASS: derived.process();\n /jsbenchmark/completeness/single_app_tracing/function_call/override/constructor_extends_001_T\n AffectedNodeName: getData\n 31: CALL: __taint_sink(this.getData());\n /jsbenchmark/completeness/single_app_tracing/function_call/override/constructor_extends_001_T\n AffectedNodeName: this\n 31: ARG PASS: __taint_sink(this.getData());\n /jsbenchmark/completeness/single_app_tracing/function_call/override/constructor_extends_001_T\n AffectedNodeName: [return value]\n 19: Return Value: return this.data;\n /jsbenchmark/completeness/single_app_tracing/function_call/override/constructor_extends_001_T\n AffectedNodeName: getData\n 31: CALL RETURN: __taint_sink(this.getData());\n /jsbenchmark/completeness/single_app_tracing/function_call/override/constructor_extends_001_T\n AffectedNodeName: __taint_sink\n 31: SINK: __taint_sink(this.getData());\n==========================================================\n #Total-findings:1\n==========================================================","/jsbenchmark/completeness/single_app_tracing/function_call/override/constructor_extends_002_F":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/completeness/single_app_tracing/function_call/override/constructor_extends_003_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/jsbenchmark/completeness/single_app_tracing/function_call/override/constructor_extends_003_T\nLine 29: __taint_sink(this.getData())\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/jsbenchmark/completeness/single_app_tracing/function_call/override/constructor_extends_003_T\",\"functionName\":\"constructor_extends_003_T\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /jsbenchmark/completeness/single_app_tracing/function_call/override/constructor_extends_003_T\n AffectedNodeName: __taint_src\n 10: SOURCE: function constructor_extends_003_T(__taint_src) {\n /jsbenchmark/completeness/single_app_tracing/function_call/override/constructor_extends_003_T\n AffectedNodeName: this.data\n 13: Var Pass: this.data = __taint_src;\n /jsbenchmark/completeness/single_app_tracing/function_call/override/constructor_extends_003_T\n AffectedNodeName: derived\n 33: Var Pass: const derived = new DerivedClass();\n /jsbenchmark/completeness/single_app_tracing/function_call/override/constructor_extends_003_T\n AffectedNodeName: process\n 34: CALL: derived.process();\n /jsbenchmark/completeness/single_app_tracing/function_call/override/constructor_extends_003_T\n AffectedNodeName: derived\n 34: ARG PASS: derived.process();\n /jsbenchmark/completeness/single_app_tracing/function_call/override/constructor_extends_003_T\n AffectedNodeName: getData\n 29: CALL: __taint_sink(this.getData());\n /jsbenchmark/completeness/single_app_tracing/function_call/override/constructor_extends_003_T\n AffectedNodeName: this\n 29: ARG PASS: __taint_sink(this.getData());\n /jsbenchmark/completeness/single_app_tracing/function_call/override/constructor_extends_003_T\n AffectedNodeName: [return value]\n 17: Return Value: return this.data;\n /jsbenchmark/completeness/single_app_tracing/function_call/override/constructor_extends_003_T\n AffectedNodeName: getData\n 29: CALL RETURN: __taint_sink(this.getData());\n /jsbenchmark/completeness/single_app_tracing/function_call/override/constructor_extends_003_T\n AffectedNodeName: __taint_sink\n 29: SINK: __taint_sink(this.getData());\n==========================================================\n #Total-findings:1\n==========================================================","/jsbenchmark/completeness/single_app_tracing/function_call/override/constructor_extends_004_F":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/completeness/single_app_tracing/function_call/override/polymorphism_override_001_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/jsbenchmark/completeness/single_app_tracing/function_call/override/polymorphism_override_001_T\nLine 26: __taint_sink(sub.call())\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/jsbenchmark/completeness/single_app_tracing/function_call/override/polymorphism_override_001_T\",\"functionName\":\"polymorphism_override_001_T\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /jsbenchmark/completeness/single_app_tracing/function_call/override/polymorphism_override_001_T\n AffectedNodeName: __taint_src\n 10: SOURCE: function polymorphism_override_001_T(__taint_src) {\n /jsbenchmark/completeness/single_app_tracing/function_call/override/polymorphism_override_001_T\n AffectedNodeName: [return value]\n 15: Return Value: return __taint_src;\n /jsbenchmark/completeness/single_app_tracing/function_call/override/polymorphism_override_001_T\n AffectedNodeName: call\n 26: CALL RETURN: __taint_sink(sub.call());\n /jsbenchmark/completeness/single_app_tracing/function_call/override/polymorphism_override_001_T\n AffectedNodeName: __taint_sink\n 26: SINK: __taint_sink(sub.call());\n==========================================================\n #Total-findings:1\n==========================================================","/jsbenchmark/completeness/single_app_tracing/function_call/override/polymorphism_override_002_F":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/completeness/single_app_tracing/function_call/override/prototype_extends_001_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/jsbenchmark/completeness/single_app_tracing/function_call/override/prototype_extends_001_T\nLine 27: __taint_sink(instance.getChValue())\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/jsbenchmark/completeness/single_app_tracing/function_call/override/prototype_extends_001_T\",\"functionName\":\"prototype_extends_001_T\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /jsbenchmark/completeness/single_app_tracing/function_call/override/prototype_extends_001_T\n AffectedNodeName: __taint_src\n 10: SOURCE: function prototype_extends_001_T(__taint_src) {\n /jsbenchmark/completeness/single_app_tracing/function_call/override/prototype_extends_001_T\n AffectedNodeName: this.chProperty\n 18: Var Pass: this.chProperty = __taint_src;\n /jsbenchmark/completeness/single_app_tracing/function_call/override/prototype_extends_001_T\n AffectedNodeName: instance\n 26: Var Pass: let instance = new Child();\n /jsbenchmark/completeness/single_app_tracing/function_call/override/prototype_extends_001_T\n AffectedNodeName: \n 27: CALL: __taint_sink(instance.getChValue());\n /jsbenchmark/completeness/single_app_tracing/function_call/override/prototype_extends_001_T\n AffectedNodeName: instance\n 27: ARG PASS: __taint_sink(instance.getChValue());\n /jsbenchmark/completeness/single_app_tracing/function_call/override/prototype_extends_001_T\n AffectedNodeName: [return value]\n 23: Return Value: return this.chProperty;\n /jsbenchmark/completeness/single_app_tracing/function_call/override/prototype_extends_001_T\n AffectedNodeName: \n 27: CALL RETURN: __taint_sink(instance.getChValue());\n /jsbenchmark/completeness/single_app_tracing/function_call/override/prototype_extends_001_T\n AffectedNodeName: __taint_sink\n 27: SINK: __taint_sink(instance.getChValue());\n==========================================================\n #Total-findings:1\n==========================================================","/jsbenchmark/completeness/single_app_tracing/function_call/override/prototype_extends_002_F":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/completeness/single_app_tracing/function_call/return_value_passing/return_normal_value_passing_001_F":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/completeness/single_app_tracing/function_call/return_value_passing/return_normal_value_passing_002_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/jsbenchmark/completeness/single_app_tracing/function_call/return_value_passing/return_normal_value_passing_002_T\nLine 13: __taint_sink(data)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/jsbenchmark/completeness/single_app_tracing/function_call/return_value_passing/return_normal_value_passing_002_T\",\"functionName\":\"return_normal_value_passing_002_T\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /jsbenchmark/completeness/single_app_tracing/function_call/return_value_passing/return_normal_value_passing_002_T\n AffectedNodeName: __taint_src\n 11: SOURCE: function return_normal_value_passing_002_T(__taint_src) {\n /jsbenchmark/completeness/single_app_tracing/function_call/return_value_passing/return_normal_value_passing_002_T\n AffectedNodeName: [return value]\n 16: Return Value: return __taint_src;\n /jsbenchmark/completeness/single_app_tracing/function_call/return_value_passing/return_normal_value_passing_002_T\n AffectedNodeName: process\n 12: CALL RETURN: let data = process();\n /jsbenchmark/completeness/single_app_tracing/function_call/return_value_passing/return_normal_value_passing_002_T\n AffectedNodeName: data\n 12: Var Pass: let data = process();\n /jsbenchmark/completeness/single_app_tracing/function_call/return_value_passing/return_normal_value_passing_002_T\n AffectedNodeName: __taint_sink\n 13: SINK: __taint_sink(data);\n==========================================================\n #Total-findings:1\n==========================================================","/jsbenchmark/completeness/single_app_tracing/function_call/static_method/static_method_001_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/jsbenchmark/completeness/single_app_tracing/function_call/static_method/static_method_001_T\nLine 13: __taint_sink(arg)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/jsbenchmark/completeness/single_app_tracing/function_call/static_method/static_method_001_T\",\"functionName\":\"static_method_001_T\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /jsbenchmark/completeness/single_app_tracing/function_call/static_method/static_method_001_T\n AffectedNodeName: __taint_src\n 17: SOURCE: function static_method_001_T(__taint_src) {\n /jsbenchmark/completeness/single_app_tracing/function_call/static_method/static_method_001_T\n AffectedNodeName: process\n 18: CALL: MyClass.process(__taint_src);\n /jsbenchmark/completeness/single_app_tracing/function_call/static_method/static_method_001_T\n AffectedNodeName: arg\n 12: ARG PASS: static process(arg) {\n /jsbenchmark/completeness/single_app_tracing/function_call/static_method/static_method_001_T\n AffectedNodeName: __taint_sink\n 13: SINK: __taint_sink(arg);\n==========================================================\n #Total-findings:1\n==========================================================","/jsbenchmark/completeness/single_app_tracing/function_call/static_method/static_method_002_F":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/completeness/single_app_tracing/function_call/tagged_template_literals/tagged_template_literal_001_F":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/completeness/single_app_tracing/function_call/tagged_template_literals/tagged_template_literal_002_T":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/completeness/single_app_tracing/variable_scope/private_scope/private_variable_001_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/jsbenchmark/completeness/single_app_tracing/variable_scope/private_scope/private_variable_001_T\nLine 22: __taint_sink(o.GetData())\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/jsbenchmark/completeness/single_app_tracing/variable_scope/private_scope/private_variable_001_T\",\"functionName\":\"private_variable_001_T\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /jsbenchmark/completeness/single_app_tracing/variable_scope/private_scope/private_variable_001_T\n AffectedNodeName: __taint_src\n 11: SOURCE: function private_variable_001_T(__taint_src) {\n /jsbenchmark/completeness/single_app_tracing/variable_scope/private_scope/private_variable_001_T\n AffectedNodeName: data\n 13: Var Pass: #data = __taint_src;\n /jsbenchmark/completeness/single_app_tracing/variable_scope/private_scope/private_variable_001_T\n AffectedNodeName: o\n 21: Var Pass: let o = new A();\n /jsbenchmark/completeness/single_app_tracing/variable_scope/private_scope/private_variable_001_T\n AffectedNodeName: GetData\n 22: CALL: __taint_sink(o.GetData());\n /jsbenchmark/completeness/single_app_tracing/variable_scope/private_scope/private_variable_001_T\n AffectedNodeName: o\n 22: ARG PASS: __taint_sink(o.GetData());\n /jsbenchmark/completeness/single_app_tracing/variable_scope/private_scope/private_variable_001_T\n AffectedNodeName: [return value]\n 15: Return Value: return this.#data;\n /jsbenchmark/completeness/single_app_tracing/variable_scope/private_scope/private_variable_001_T\n AffectedNodeName: GetData\n 22: CALL RETURN: __taint_sink(o.GetData());\n /jsbenchmark/completeness/single_app_tracing/variable_scope/private_scope/private_variable_001_T\n AffectedNodeName: __taint_sink\n 22: SINK: __taint_sink(o.GetData());\n==========================================================\n #Total-findings:1\n==========================================================","/jsbenchmark/completeness/single_app_tracing/variable_scope/private_scope/private_variable_002_F":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/completeness/single_app_tracing/variable_scope/static_variable/static_variable_001_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/jsbenchmark/completeness/single_app_tracing/variable_scope/static_variable/static_variable_001_T\nLine 16: __taint_sink(A.data)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/jsbenchmark/completeness/single_app_tracing/variable_scope/static_variable/static_variable_001_T\",\"functionName\":\"static_variable_001_T\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /jsbenchmark/completeness/single_app_tracing/variable_scope/static_variable/static_variable_001_T\n AffectedNodeName: __taint_src\n 11: SOURCE: function static_variable_001_T(__taint_src) {\n /jsbenchmark/completeness/single_app_tracing/variable_scope/static_variable/static_variable_001_T\n AffectedNodeName: data\n 13: Var Pass: static data = __taint_src;\n /jsbenchmark/completeness/single_app_tracing/variable_scope/static_variable/static_variable_001_T\n AffectedNodeName: __taint_sink\n 16: SINK: __taint_sink(A.data);\n==========================================================\n #Total-findings:1\n==========================================================","/jsbenchmark/completeness/single_app_tracing/variable_scope/static_variable/static_variable_002_F":"======================== Findings ========================\nNo findings!\n==========================================================","/jsbenchmark/completeness/single_app_tracing/variable_scope/static_variable/static_variable_003_T":"======================== Findings ========================\n\n------------- 1: taint_flow_test-------------\nDescription:taint_flow_test,回归测试使用,不推荐外部使用\nFile:/jsbenchmark/completeness/single_app_tracing/variable_scope/static_variable/static_variable_003_T\nLine 27: __taint_sink(data)\nSINK RULE:__taint_sink\nentrypoint:\n{\"filePath\":\"/jsbenchmark/completeness/single_app_tracing/variable_scope/static_variable/static_variable_003_T\",\"functionName\":\"static_variable_003_T\",\"attribute\":\"fullCallGraphMade\",\"type\":\"functionCall\",\"funcReceiverType\":\"\"}\nTrace:\n /jsbenchmark/completeness/single_app_tracing/variable_scope/static_variable/static_variable_003_T\n AffectedNodeName: __taint_src\n 11: SOURCE: function static_variable_003_T(__taint_src) {\n /jsbenchmark/completeness/single_app_tracing/variable_scope/static_variable/static_variable_003_T\n AffectedNodeName: data\n 13: Var Pass: static data = __taint_src;\n /jsbenchmark/completeness/single_app_tracing/variable_scope/static_variable/static_variable_003_T\n AffectedNodeName: data\n 26: Var Pass: const data = A.data;\n /jsbenchmark/completeness/single_app_tracing/variable_scope/static_variable/static_variable_003_T\n AffectedNodeName: __taint_sink\n 27: SINK: __taint_sink(data);\n==========================================================\n #Total-findings:1\n==========================================================","/jsbenchmark/completeness/single_app_tracing/variable_scope/static_variable/static_variable_004_F":"======================== Findings ========================\nNo findings!\n=========================================================="} \ No newline at end of file diff --git a/test/javascript/prepare-js-benchmark.ts b/test/javascript/prepare-js-benchmark.ts index 5e879e59..5f187575 100644 --- a/test/javascript/prepare-js-benchmark.ts +++ b/test/javascript/prepare-js-benchmark.ts @@ -130,8 +130,7 @@ function moveSrcDirectoryForJs(directory: string): void { const childAaaPath = path.join(directory, 'sast-js') const srcPath = path.join(childAaaPath, 'case') if (fs.existsSync(srcPath)) { - // fs.moveSync(srcPath, directory, { overwrite: true }) - fs.copySync(srcPath, directory) + fs.moveSync(srcPath, directory) } fs.removeSync(childAaaPath) } diff --git a/test/javascript/test-js-benchmark.ts b/test/javascript/test-js-benchmark.ts index adfee61c..c774d544 100644 --- a/test/javascript/test-js-benchmark.ts +++ b/test/javascript/test-js-benchmark.ts @@ -1,7 +1,7 @@ import * as _ from 'lodash' import * as fs from 'fs' import * as path from 'path' -import { describe, it } from 'mocha' +import { describe, it, before } from 'mocha' import * as assert from 'assert' const config = require('../../src/config') const logger = require('../../src/util/logger')(__filename) @@ -15,12 +15,65 @@ const taint_flow_name = ['taint_flow_test'] function regressionXastJsBenchmark(): void { const jsBenchmarkPath = path.resolve(__dirname, BENCHMARKS_DIR, XAST_JS_BENCHMARK) - if (fs.existsSync(jsBenchmarkPath)) { - const result = runXastJsBenchmark(jsBenchmarkPath) - checkXastJsBenchmarkResult(result) + const expectResultPath = path.join(path.resolve(jsBenchmarkPath), '..', '..', 'expect', 'jsbenchmark-expect.json') + let expectedResult: Record = {} + if (fs.existsSync(expectResultPath)) { + const expectedData = fs.readFileSync(expectResultPath).toString() + expectedResult = JSON.parse(expectedData) } else { - logger.warn(`XAST JS benchmark directory not found: ${jsBenchmarkPath}`) + logger.warn(`JS benchmark expectation file not found: ${expectResultPath}`) } + + describe('YASA test Xast Js Benchmark', function () { + this.timeout(0) + let actualRes: Record = {} + let actualResMap = new Map() + let benchmarkReady = false + + before(async function () { + if (!fs.existsSync(jsBenchmarkPath)) { + this.skip() + return + } + const result = await runXastJsBenchmark(jsBenchmarkPath) + actualRes = result.actualRes + actualResMap = result.actualResMap + benchmarkReady = true + }) + + it(`check result data directly`, function () { + if (!benchmarkReady) { + this.skip() + return + } + const testReport = statisticImpactArea(actualResMap, './test/javascript/test-report') + logger.info(testReport) + writeLog(testReport, './test/javascript/test-report') + }) + + let i = 1 + if (expectedResult) { + for (const caseKey of Object.keys(expectedResult)) { + it(`${i++}-case:${caseKey}`, function () { + if (!benchmarkReady) { + this.skip() + return + } + logger.info('expected:\n' + expectedResult[caseKey]) + logger.info('actual:\n' + actualRes[caseKey]) + if (_.has(actualRes, caseKey)) { + assert.strictEqual( + actualRes[caseKey], + expectedResult[caseKey], + `链路${caseKey}实际trace或内容与预期不一致,请核对该链路` + ) + } else { + assert.fail(`链路:${caseKey}不存在!!!需要排查原因`) + } + }) + } + } + }) } function getAllTestCase(filename: string): string[] { @@ -56,7 +109,20 @@ function getAllTestCase(filename: string): string[] { } function recordFinding(finding: any, filename: string, findingResMap: Map): void { - const keyname = filename.substring(filename.lastIndexOf('/benchmarks')) + // 规范化路径分隔符为 /,兼容不同操作系统(Windows 使用 \) + const normalizedFilename = filename.replace(/\\/g, '/') + // 兼容 /benchmarks 和 /jsbenchmark 两种路径格式 + let keyname: string + const benchmarksIndex = normalizedFilename.lastIndexOf('/benchmarks') + const jsbenchmarkIndex = normalizedFilename.lastIndexOf('/jsbenchmark') + if (benchmarksIndex !== -1) { + keyname = normalizedFilename.substring(benchmarksIndex) + } else if (jsbenchmarkIndex !== -1) { + keyname = normalizedFilename.substring(jsbenchmarkIndex) + } else { + // 如果都找不到,使用整个路径 + keyname = normalizedFilename + } for (const ruleName of taint_flow_name) { if (!finding || Object.keys(finding).length === 0) { findingResMap.set(keyname, { [ruleName]: 0 }) @@ -194,7 +260,11 @@ function getTFPN(findingResMap: Map): { return { TP, TN, FP, FN, tpChainNum, tnChainNum, unknown } } -function runSingleTest(casePath: string, actualResMap: Map, outputStrategyAutoRegister: any): any { +async function runSingleTest( + casePath: string, + actualResMap: Map, + outputStrategyAutoRegister: any +): Promise { config.ruleConfigFile = './test/javascript/rule_config.json' config.checkerIds = ['taint_flow_test'] config.language = 'javascript' @@ -203,7 +273,13 @@ function runSingleTest(casePath: string, actualResMap: Map, outputS const code = fs.readFileSync(casePath).toString() const recorder = recordFindingStr() - const filename = casePath.substring(casePath.lastIndexOf('/jsbenchmark')).replace(/\.js/g, '') + // 规范化路径分隔符为 /,兼容不同操作系统(Windows 使用 \),保持原有提取逻辑 + const normalizedCasePath = casePath.replace(/\\/g, '/') + let filename = normalizedCasePath.substring(normalizedCasePath.lastIndexOf('/jsbenchmark')).replace(/\.js/g, '') + // 兼容期望结果格式:去掉 /sast-js/case 或 /case 目录(期望结果文件中不包含这些目录) + // 这样既兼容原有逻辑,又能匹配期望的 key 格式 + filename = filename.replace(/^\/jsbenchmark\/sast-js\/case\//, '/jsbenchmark/') + filename = filename.replace(/^\/jsbenchmark\/case\//, '/jsbenchmark/') const analyzer = new Analyzer({ ...config, language: 'javascript', @@ -215,7 +291,7 @@ function runSingleTest(casePath: string, actualResMap: Map, outputS ruleConfigFile: ruleConfigFile, }) - const findingRes = analyzer.analyzeSingleFile(code, filename) + const findingRes = await analyzer.analyzeSingleFile(code, filename) if (findingRes) { const { resultManager } = analyzer.getCheckerManager() const allFindings = resultManager.getFindings() @@ -235,82 +311,44 @@ function runSingleTest(casePath: string, actualResMap: Map, outputS } } -function runXastJsBenchmark(dir: string): { - actualRes: any +async function runXastJsBenchmark(dir: string): Promise<{ + actualRes: Record actualResMap: Map - expectedResult: any -} { - let allCases = getAllTestCase(dir) - let actualRes: any = {} - let actualResMap = new Map() +}> { + const allCases = getAllTestCase(dir) + const actualRes: Record = {} + const actualResMap = new Map() const outputStrategyAutoRegister = new OutputStrategyAutoRegister() outputStrategyAutoRegister.autoRegisterAllStrategies() for (const casePath of allCases) { - const singleRes = runSingleTest(casePath, actualResMap, outputStrategyAutoRegister) + const singleRes = await runSingleTest(casePath, actualResMap, outputStrategyAutoRegister) if (singleRes) { for (const [key, value] of Object.entries(singleRes)) { - actualRes[key] = value + actualRes[key as string] = value } } } - const expectResultPath = path.join(path.resolve(dir), '..', '..', 'expect', 'jsbenchmark-expect.json') - const expectedData = fs.readFileSync(expectResultPath).toString() - const expectedResult = JSON.parse(expectedData) return { actualRes, actualResMap, - expectedResult, } } -function checkXastJsBenchmarkResult(result: { - actualRes: any - actualResMap: Map - expectedResult: any -}): void { - const { actualRes, actualResMap, expectedResult } = result - describe('YASA test Xast Js Benchmark', function () { - it(`check result data directly`, function () { - let testReport = statisticImpactArea(actualResMap, './test/javascript/test-report') - logger.info(testReport) - writeLog(testReport, './test/javascript/test-report') - }) - let i = 1 - if (expectedResult) { - for (let caseKey of Object.keys(expectedResult)) { - it(`${i++}-case:${caseKey}`, function () { - logger.info('expected:\n' + expectedResult[caseKey]) - logger.info('actual:\n' + actualRes[caseKey]) - if (_.has(actualRes, caseKey)) { - assert.strictEqual( - actualRes[caseKey], - expectedResult[caseKey], - `链路${caseKey}实际trace或内容与预期不一致,请核对该链路` - ) - } else { - assert.fail(`链路:${caseKey}不存在!!!需要排查原因`) - } - }) - } - } - }) -} - regressionXastJsBenchmark() // const JSBENCHMARK_PATH = fileUtil.getAbsolutePath('./test/javascript/benchmarks/jsbenchmark/') // updateJsBenchmarkBackupfile(JSBENCHMARK_PATH) -function updateJsBenchmarkBackupfile(dir: string): void { - let allCases = getAllTestCase(dir) - let actualRes: any = {} - let actualResMap = new Map() +async function updateJsBenchmarkBackupfile(dir: string): Promise { + const allCases = getAllTestCase(dir) + const actualRes: Record = {} + const actualResMap = new Map() const outputStrategyAutoRegister = new OutputStrategyAutoRegister() outputStrategyAutoRegister.autoRegisterAllStrategies() for (const casePath of allCases) { - const singleRes = runSingleTest(casePath, actualResMap, outputStrategyAutoRegister) + const singleRes = await runSingleTest(casePath, actualResMap, outputStrategyAutoRegister) if (singleRes) { for (const [key, value] of Object.entries(singleRes)) { - actualRes[key] = value + actualRes[key as string] = value } } } diff --git a/test/python/expect/pythonbenchmark-expect.result b/test/python/expect/pythonbenchmark-expect.result index 4c939568..72a6479f 100644 --- a/test/python/expect/pythonbenchmark-expect.result +++ b/test/python/expect/pythonbenchmark-expect.result @@ -2,39 +2,6 @@ ------------- 1: taint_flow_test------------- Description:taint_flow_test,回归测试使用,不推荐外部使用 -File:/case/completeness/other/ellipsis/ellipsis_003_T.py -Line 23: os.system(str(o)) -SINK RULE:os.system -entrypoint: -{"filePath":"/case/completeness/other/ellipsis/ellipsis_003_T.py","attribute":"fullfileManagerMade","type":"fileBegin","funcReceiverType":""} -Trace: - /case/completeness/other/ellipsis/ellipsis_003_T.py - AffectedNodeName: taint_src - 29: SOURCE: ellipsis_003_T(taint_src) - /case/completeness/other/ellipsis/ellipsis_003_T.py - AffectedNodeName: ellipsis_003_T - 29: CALL: ellipsis_003_T(taint_src) - /case/completeness/other/ellipsis/ellipsis_003_T.py - AffectedNodeName: taint_src - 14: ARG PASS: def ellipsis_003_T(taint_src): - /case/completeness/other/ellipsis/ellipsis_003_T.py - AffectedNodeName: arr - 15: Var Pass: arr = np.random.randint(taint_src, 10, (3, 3, 3)) # 创建一个 3x3x3 的随机数组 - /case/completeness/other/ellipsis/ellipsis_003_T.py - AffectedNodeName: sliced - 18: Var Pass: sliced = arr[..., 0] # 等价于 arr[:, :, 0] - /case/completeness/other/ellipsis/ellipsis_003_T.py - AffectedNodeName: taint_sink - 19: CALL: taint_sink(sliced) - /case/completeness/other/ellipsis/ellipsis_003_T.py - AffectedNodeName: o - 22: ARG PASS: def taint_sink(o): - /case/completeness/other/ellipsis/ellipsis_003_T.py - AffectedNodeName: os.system - 23: SINK: os.system(str(o)) - -------------- 2: taint_flow_test------------- -Description:taint_flow_test,回归测试使用,不推荐外部使用 File:/case/completeness/single_app_tracing/datatype/new_type/type_annotation_new_type_001_T.py Line 27: os.system(o) SINK RULE:os.system @@ -75,34 +42,7 @@ Trace: AffectedNodeName: os.system 27: SINK: os.system(o) -------------- 3: taint_flow_test------------- -Description:taint_flow_test,回归测试使用,不推荐外部使用 -File:/case/completeness/single_app_tracing/datatype/primitives/bool_002_F.py -Line 15: os.system(str(o)) -SINK RULE:os.system -entrypoint: -{"filePath":"/case/completeness/single_app_tracing/datatype/primitives/bool_002_F.py","attribute":"fullfileManagerMade","type":"fileBegin","funcReceiverType":""} -Trace: - /case/completeness/single_app_tracing/datatype/primitives/bool_002_F.py - AffectedNodeName: taint_src - 19: SOURCE: bool_002_F(taint_src) - /case/completeness/single_app_tracing/datatype/primitives/bool_002_F.py - AffectedNodeName: bool_002_F - 19: CALL: bool_002_F(taint_src) - /case/completeness/single_app_tracing/datatype/primitives/bool_002_F.py - AffectedNodeName: taint_src - 11: ARG PASS: def bool_002_F(taint_src): - /case/completeness/single_app_tracing/datatype/primitives/bool_002_F.py - AffectedNodeName: taint_sink - 12: CALL: taint_sink(taint_src) - /case/completeness/single_app_tracing/datatype/primitives/bool_002_F.py - AffectedNodeName: o - 14: ARG PASS: def taint_sink(o): - /case/completeness/single_app_tracing/datatype/primitives/bool_002_F.py - AffectedNodeName: os.system - 15: SINK: os.system(str(o)) - -------------- 4: taint_flow_test------------- +------------- 2: taint_flow_test------------- Description:taint_flow_test,回归测试使用,不推荐外部使用 File:/case/completeness/single_app_tracing/datatype/primitives/type_annotation_complex_001_T.py Line 20: os.system(str(o)) @@ -135,28 +75,7 @@ Trace: AffectedNodeName: os.system 20: SINK: os.system(str(o)) -------------- 5: taint_flow_test------------- -Description:taint_flow_test,回归测试使用,不推荐外部使用 -File:/case/completeness/single_app_tracing/expression/basic_expression_operation/unary_expression_not_001_T.py -Line 19: os.system(str(o)) -SINK RULE:os.system -entrypoint: -{"filePath":"/case/completeness/single_app_tracing/expression/basic_expression_operation/unary_expression_not_001_T.py","attribute":"fullfileManagerMade","type":"fileBegin","funcReceiverType":""} -Trace: - /case/completeness/single_app_tracing/expression/basic_expression_operation/unary_expression_not_001_T.py - AffectedNodeName: taint_src - 24: SOURCE: unary_expression_not_001_T(taint_src) - /case/completeness/single_app_tracing/expression/basic_expression_operation/unary_expression_not_001_T.py - AffectedNodeName: unary_expression_not_001_T - 24: CALL: unary_expression_not_001_T(taint_src) - /case/completeness/single_app_tracing/expression/basic_expression_operation/unary_expression_not_001_T.py - AffectedNodeName: taint_src - 13: ARG PASS: def unary_expression_not_001_T(taint_src): - /case/completeness/single_app_tracing/expression/basic_expression_operation/unary_expression_not_001_T.py - AffectedNodeName: os.system - 19: SINK: os.system(str(o)) - -------------- 6: taint_flow_test------------- +------------- 3: taint_flow_test------------- Description:taint_flow_test,回归测试使用,不推荐外部使用 File:/case/accuracy/context_sensitive/argument_return_value_passing/argument_passing_value_001_T.py Line 18: os.system(o) @@ -183,7 +102,7 @@ Trace: AffectedNodeName: os.system 18: SINK: os.system(o) -------------- 7: taint_flow_test------------- +------------- 4: taint_flow_test------------- Description:taint_flow_test,回归测试使用,不推荐外部使用 File:/case/accuracy/context_sensitive/argument_return_value_passing/argument_passing_value_003_T.py Line 18: os.system(o) @@ -210,7 +129,7 @@ Trace: AffectedNodeName: os.system 18: SINK: os.system(o) -------------- 8: taint_flow_test------------- +------------- 5: taint_flow_test------------- Description:taint_flow_test,回归测试使用,不推荐外部使用 File:/case/accuracy/context_sensitive/argument_return_value_passing/argument_passing_value_005_T.py Line 18: os.system(o) @@ -237,7 +156,7 @@ Trace: AffectedNodeName: os.system 18: SINK: os.system(o) -------------- 9: taint_flow_test------------- +------------- 6: taint_flow_test------------- Description:taint_flow_test,回归测试使用,不推荐外部使用 File:/case/accuracy/context_sensitive/argument_return_value_passing/argument_passing_value_007_T.py Line 18: os.system(o) @@ -267,7 +186,7 @@ Trace: AffectedNodeName: os.system 18: SINK: os.system(o) -------------- 10: taint_flow_test------------- +------------- 7: taint_flow_test------------- Description:taint_flow_test,回归测试使用,不推荐外部使用 File:/case/accuracy/context_sensitive/argument_return_value_passing/argument_passing_value_009_T.py Line 18: os.system(o) @@ -294,7 +213,7 @@ Trace: AffectedNodeName: os.system 18: SINK: os.system(o) -------------- 11: taint_flow_test------------- +------------- 8: taint_flow_test------------- Description:taint_flow_test,回归测试使用,不推荐外部使用 File:/case/accuracy/context_sensitive/argument_return_value_passing/return_value_passing_001_T.py Line 22: os.system(o) @@ -324,7 +243,7 @@ Trace: AffectedNodeName: os.system 22: SINK: os.system(o) -------------- 12: taint_flow_test------------- +------------- 9: taint_flow_test------------- Description:taint_flow_test,回归测试使用,不推荐外部使用 File:/case/accuracy/context_sensitive/argument_return_value_passing/return_value_passing_003_T.py Line 22: os.system(o) @@ -360,7 +279,7 @@ Trace: AffectedNodeName: os.system 22: SINK: os.system(o) -------------- 13: taint_flow_test------------- +------------- 10: taint_flow_test------------- Description:taint_flow_test,回归测试使用,不推荐外部使用 File:/case/accuracy/context_sensitive/multi_invoke/multi_invoke_001_T.py Line 20: os.system(o) @@ -396,7 +315,7 @@ Trace: AffectedNodeName: os.system 20: SINK: os.system(o) -------------- 14: taint_flow_test------------- +------------- 11: taint_flow_test------------- Description:taint_flow_test,回归测试使用,不推荐外部使用 File:/case/accuracy/context_sensitive/multi_invoke/multi_invoke_003_T.py Line 23: os.system(o) @@ -444,7 +363,7 @@ Trace: AffectedNodeName: os.system 23: SINK: os.system(o) -------------- 15: taint_flow_test------------- +------------- 12: taint_flow_test------------- Description:taint_flow_test,回归测试使用,不推荐外部使用 File:/case/accuracy/context_sensitive/polymorphism/polymorphism_001_T.py Line 29: os.system(o) @@ -471,7 +390,7 @@ Trace: AffectedNodeName: os.system 29: SINK: os.system(o) -------------- 16: taint_flow_test------------- +------------- 13: taint_flow_test------------- Description:taint_flow_test,回归测试使用,不推荐外部使用 File:/case/accuracy/context_sensitive/polymorphism/polymorphism_003_T.py Line 29: os.system(o) @@ -498,7 +417,7 @@ Trace: AffectedNodeName: os.system 29: SINK: os.system(o) -------------- 17: taint_flow_test------------- +------------- 14: taint_flow_test------------- Description:taint_flow_test,回归测试使用,不推荐外部使用 File:/case/accuracy/field_sensitive/class/constructor_field_001_T.py Line 22: os.system(o) @@ -510,7 +429,7 @@ Trace: AffectedNodeName: taint_src 11: SOURCE: def constructor_field_001_T(taint_src): /case/accuracy/field_sensitive/class/constructor_field_001_T.py - AffectedNodeName: [self.data] + AffectedNodeName: self.data 14: Var Pass: self.data = taint_src /case/accuracy/field_sensitive/class/constructor_field_001_T.py AffectedNodeName: obj @@ -525,7 +444,7 @@ Trace: AffectedNodeName: os.system 22: SINK: os.system(o) -------------- 18: taint_flow_test------------- +------------- 15: taint_flow_test------------- Description:taint_flow_test,回归测试使用,不推荐外部使用 File:/case/accuracy/field_sensitive/class/constructor_field_003_T.py Line 22: os.system(o) @@ -543,7 +462,7 @@ Trace: AffectedNodeName: param 13: ARG PASS: def __init__(self, param): /case/accuracy/field_sensitive/class/constructor_field_003_T.py - AffectedNodeName: [self.data] + AffectedNodeName: self.data 14: Var Pass: self.data = param /case/accuracy/field_sensitive/class/constructor_field_003_T.py AffectedNodeName: obj @@ -558,7 +477,7 @@ Trace: AffectedNodeName: os.system 22: SINK: os.system(o) -------------- 19: taint_flow_test------------- +------------- 16: taint_flow_test------------- Description:taint_flow_test,回归测试使用,不推荐外部使用 File:/case/accuracy/field_sensitive/class/constructor_field_005_T.py Line 30: os.system(o) @@ -572,12 +491,6 @@ Trace: /case/accuracy/field_sensitive/class/constructor_field_005_T.py AffectedNodeName: __init__ 12: CALL: a = ClassA(taint_src) - /case/accuracy/field_sensitive/class/constructor_field_005_T.py - AffectedNodeName: taint_src - 18: ARG PASS: def __init__(self, taint_src): - /case/accuracy/field_sensitive/class/constructor_field_005_T.py - AffectedNodeName: [self.field] - 19: Var Pass: self.field = taint_src /case/accuracy/field_sensitive/class/constructor_field_005_T.py AffectedNodeName: a 12: Var Pass: a = ClassA(taint_src) @@ -597,7 +510,7 @@ Trace: AffectedNodeName: os.system 30: SINK: os.system(o) -------------- 20: taint_flow_test------------- +------------- 17: taint_flow_test------------- Description:taint_flow_test,回归测试使用,不推荐外部使用 File:/case/accuracy/field_sensitive/class/field_len_001_T.py Line 31: os.system(o) @@ -627,13 +540,13 @@ Trace: AffectedNodeName: taint_src 21: ARG PASS: def __init__(self, taint_src): /case/accuracy/field_sensitive/class/field_len_001_T.py - AffectedNodeName: [self.data] + AffectedNodeName: self.data 22: Var Pass: self.data = taint_src # 使用参数赋值给 data /case/accuracy/field_sensitive/class/field_len_001_T.py - AffectedNodeName: [self.c] + AffectedNodeName: self.c 18: Var Pass: self.c = C(taint_src) # 继续传递参数到 C /case/accuracy/field_sensitive/class/field_len_001_T.py - AffectedNodeName: [self.b] + AffectedNodeName: self.b 14: Var Pass: self.b = B(taint_src) # 将参数传递给下一层类 /case/accuracy/field_sensitive/class/field_len_001_T.py AffectedNodeName: a @@ -648,7 +561,7 @@ Trace: AffectedNodeName: os.system 31: SINK: os.system(o) -------------- 21: taint_flow_test------------- +------------- 18: taint_flow_test------------- Description:taint_flow_test,回归测试使用,不推荐外部使用 File:/case/accuracy/field_sensitive/class/field_len_003_T.py Line 45: os.system(o) @@ -696,22 +609,22 @@ Trace: AffectedNodeName: taint_src 33: ARG PASS: def __init__(self, taint_src): /case/accuracy/field_sensitive/class/field_len_003_T.py - AffectedNodeName: [self.data] + AffectedNodeName: self.data 34: Var Pass: self.data = taint_src # 污染数据 /case/accuracy/field_sensitive/class/field_len_003_T.py - AffectedNodeName: [self.f] + AffectedNodeName: self.f 30: Var Pass: self.f = F(taint_src) # 传递参数到 F /case/accuracy/field_sensitive/class/field_len_003_T.py - AffectedNodeName: [self.e] + AffectedNodeName: self.e 26: Var Pass: self.e = E(taint_src) # 传递参数到 E /case/accuracy/field_sensitive/class/field_len_003_T.py - AffectedNodeName: [self.d] + AffectedNodeName: self.d 22: Var Pass: self.d = D(taint_src) # 传递参数到 D /case/accuracy/field_sensitive/class/field_len_003_T.py - AffectedNodeName: [self.c] + AffectedNodeName: self.c 18: Var Pass: self.c = C(taint_src) # 传递参数到 C /case/accuracy/field_sensitive/class/field_len_003_T.py - AffectedNodeName: [self.b] + AffectedNodeName: self.b 14: Var Pass: self.b = B(taint_src) # 传递参数到 B /case/accuracy/field_sensitive/class/field_len_003_T.py AffectedNodeName: a @@ -732,7 +645,7 @@ Trace: AffectedNodeName: os.system 45: SINK: os.system(o) -------------- 22: taint_flow_test------------- +------------- 19: taint_flow_test------------- Description:taint_flow_test,回归测试使用,不推荐外部使用 File:/case/accuracy/field_sensitive/class/field_len_005_T.py Line 68: os.system(o) @@ -816,40 +729,40 @@ Trace: AffectedNodeName: taint_src 57: ARG PASS: def __init__(self, taint_src): /case/accuracy/field_sensitive/class/field_len_005_T.py - AffectedNodeName: [self.data] + AffectedNodeName: self.data 58: Var Pass: self.data = taint_src # 污染数据 /case/accuracy/field_sensitive/class/field_len_005_T.py - AffectedNodeName: [self.l] + AffectedNodeName: self.l 54: Var Pass: self.l = L(taint_src) # 传递参数到 L /case/accuracy/field_sensitive/class/field_len_005_T.py - AffectedNodeName: [self.k] + AffectedNodeName: self.k 50: Var Pass: self.k = K(taint_src) # 传递参数到 K /case/accuracy/field_sensitive/class/field_len_005_T.py - AffectedNodeName: [self.j] + AffectedNodeName: self.j 46: Var Pass: self.j = J(taint_src) # 传递参数到 J /case/accuracy/field_sensitive/class/field_len_005_T.py - AffectedNodeName: [self.i] + AffectedNodeName: self.i 42: Var Pass: self.i = I(taint_src) # 传递参数到 I /case/accuracy/field_sensitive/class/field_len_005_T.py - AffectedNodeName: [self.h] + AffectedNodeName: self.h 38: Var Pass: self.h = H(taint_src) # 传递参数到 H /case/accuracy/field_sensitive/class/field_len_005_T.py - AffectedNodeName: [self.g] + AffectedNodeName: self.g 34: Var Pass: self.g = G(taint_src) # 传递参数到 G /case/accuracy/field_sensitive/class/field_len_005_T.py - AffectedNodeName: [self.f] + AffectedNodeName: self.f 30: Var Pass: self.f = F(taint_src) # 传递参数到 F /case/accuracy/field_sensitive/class/field_len_005_T.py - AffectedNodeName: [self.e] + AffectedNodeName: self.e 26: Var Pass: self.e = E(taint_src) # 传递参数到 E /case/accuracy/field_sensitive/class/field_len_005_T.py - AffectedNodeName: [self.d] + AffectedNodeName: self.d 22: Var Pass: self.d = D(taint_src) # 传递参数到 D /case/accuracy/field_sensitive/class/field_len_005_T.py - AffectedNodeName: [self.c] + AffectedNodeName: self.c 18: Var Pass: self.c = C(taint_src) # 传递参数到 C /case/accuracy/field_sensitive/class/field_len_005_T.py - AffectedNodeName: [self.b] + AffectedNodeName: self.b 14: Var Pass: self.b = B(taint_src) # 传递参数到 B /case/accuracy/field_sensitive/class/field_len_005_T.py AffectedNodeName: a @@ -864,7 +777,7 @@ Trace: AffectedNodeName: os.system 68: SINK: os.system(o) -------------- 23: taint_flow_test------------- +------------- 20: taint_flow_test------------- Description:taint_flow_test,回归测试使用,不推荐外部使用 File:/case/accuracy/field_sensitive/class/inheritance_001_T.py Line 28: os.system(o) @@ -878,12 +791,6 @@ Trace: /case/accuracy/field_sensitive/class/inheritance_001_T.py AffectedNodeName: __init__ 12: CALL: parent_obj = Parent(taint_src) - /case/accuracy/field_sensitive/class/inheritance_001_T.py - AffectedNodeName: taint_src - 18: ARG PASS: def __init__(self, taint_src): - /case/accuracy/field_sensitive/class/inheritance_001_T.py - AffectedNodeName: [self.field] - 19: Var Pass: self.field = taint_src # 父类字段携带污点 /case/accuracy/field_sensitive/class/inheritance_001_T.py AffectedNodeName: parent_obj 12: Var Pass: parent_obj = Parent(taint_src) @@ -897,7 +804,7 @@ Trace: AffectedNodeName: os.system 28: SINK: os.system(o) -------------- 24: taint_flow_test------------- +------------- 21: taint_flow_test------------- Description:taint_flow_test,回归测试使用,不推荐外部使用 File:/case/accuracy/field_sensitive/multidimensional_collection/list_mc_001_T.py Line 23: os.system(o) @@ -921,7 +828,7 @@ Trace: AffectedNodeName: os.system 23: SINK: os.system(o) -------------- 25: taint_flow_test------------- +------------- 22: taint_flow_test------------- Description:taint_flow_test,回归测试使用,不推荐外部使用 File:/case/accuracy/field_sensitive/multidimensional_collection/list_mc_003_T.py Line 19: os.system(o) @@ -945,7 +852,7 @@ Trace: AffectedNodeName: os.system 19: SINK: os.system(o) -------------- 26: taint_flow_test------------- +------------- 23: taint_flow_test------------- Description:taint_flow_test,回归测试使用,不推荐外部使用 File:/case/accuracy/field_sensitive/multidimensional_collection/list_mc_005_T.py Line 19: os.system(o) @@ -966,7 +873,7 @@ Trace: AffectedNodeName: os.system 19: SINK: os.system(o) -------------- 27: taint_flow_test------------- +------------- 24: taint_flow_test------------- Description:taint_flow_test,回归测试使用,不推荐外部使用 File:/case/accuracy/field_sensitive/multidimensional_collection/list_mc_006_F.py Line 20: os.system(o) @@ -987,7 +894,7 @@ Trace: AffectedNodeName: os.system 20: SINK: os.system(o) -------------- 28: taint_flow_test------------- +------------- 25: taint_flow_test------------- Description:taint_flow_test,回归测试使用,不推荐外部使用 File:/case/accuracy/field_sensitive/multidimensional_collection/map_mc_001_T.py Line 19: os.system(o) @@ -1011,7 +918,7 @@ Trace: AffectedNodeName: os.system 19: SINK: os.system(o) -------------- 29: taint_flow_test------------- +------------- 26: taint_flow_test------------- Description:taint_flow_test,回归测试使用,不推荐外部使用 File:/case/accuracy/field_sensitive/multidimensional_collection/map_mc_003_T.py Line 21: os.system(o) @@ -1029,7 +936,7 @@ Trace: AffectedNodeName: d2 15: Var Pass: d2 = {"b": d1} /case/accuracy/field_sensitive/multidimensional_collection/map_mc_003_T.py - AffectedNodeName: [d1.c] + AffectedNodeName: d1.c 16: Var Pass: d1["c"] = d2 /case/accuracy/field_sensitive/multidimensional_collection/map_mc_003_T.py AffectedNodeName: taint_sink @@ -1041,7 +948,7 @@ Trace: AffectedNodeName: os.system 21: SINK: os.system(o) -------------- 30: taint_flow_test------------- +------------- 27: taint_flow_test------------- Description:taint_flow_test,回归测试使用,不推荐外部使用 File:/case/accuracy/flow_sensitive/asynchronous/asynchronous_chain_001_T.py Line 28: os.system(o) @@ -1061,12 +968,6 @@ Trace: /case/accuracy/flow_sensitive/asynchronous/asynchronous_chain_001_T.py AffectedNodeName: async_chain_step1 13: CALL: data1 = await async_chain_step1(taint_src) - /case/accuracy/flow_sensitive/asynchronous/asynchronous_chain_001_T.py - AffectedNodeName: taint_src - 19: ARG PASS: async def async_chain_step1(taint_src): - /case/accuracy/flow_sensitive/asynchronous/asynchronous_chain_001_T.py - AffectedNodeName: [return value] - 21: Return Value: return taint_src /case/accuracy/flow_sensitive/asynchronous/asynchronous_chain_001_T.py AffectedNodeName: async_chain_step1 13: CALL RETURN: data1 = await async_chain_step1(taint_src) @@ -1076,12 +977,6 @@ Trace: /case/accuracy/flow_sensitive/asynchronous/asynchronous_chain_001_T.py AffectedNodeName: async_chain_step2 14: CALL: data2 = await async_chain_step2(data1) - /case/accuracy/flow_sensitive/asynchronous/asynchronous_chain_001_T.py - AffectedNodeName: data - 23: ARG PASS: async def async_chain_step2(data): - /case/accuracy/flow_sensitive/asynchronous/asynchronous_chain_001_T.py - AffectedNodeName: [return value] - 25: Return Value: return data /case/accuracy/flow_sensitive/asynchronous/asynchronous_chain_001_T.py AffectedNodeName: async_chain_step2 14: CALL RETURN: data2 = await async_chain_step2(data1) @@ -1098,7 +993,7 @@ Trace: AffectedNodeName: os.system 28: SINK: os.system(o) -------------- 31: taint_flow_test------------- +------------- 28: taint_flow_test------------- Description:taint_flow_test,回归测试使用,不推荐外部使用 File:/case/accuracy/flow_sensitive/asynchronous/asyncio_await_001_T.py Line 22: os.system(o) @@ -1134,7 +1029,7 @@ Trace: AffectedNodeName: os.system 22: SINK: os.system(o) -------------- 32: taint_flow_test------------- +------------- 29: taint_flow_test------------- Description:taint_flow_test,回归测试使用,不推荐外部使用 File:/case/accuracy/flow_sensitive/loop_stmt/for_enumerate_001_T.py Line 17: os.system(o) @@ -1155,7 +1050,7 @@ Trace: AffectedNodeName: os.system 17: SINK: os.system(o) -------------- 33: taint_flow_test------------- +------------- 30: taint_flow_test------------- Description:taint_flow_test,回归测试使用,不推荐外部使用 File:/case/accuracy/flow_sensitive/loop_stmt/for_zip_001_T.py Line 17: os.system(o) @@ -1176,7 +1071,7 @@ Trace: AffectedNodeName: os.system 17: SINK: os.system(o) -------------- 34: taint_flow_test------------- +------------- 31: taint_flow_test------------- Description:taint_flow_test,回归测试使用,不推荐外部使用 File:/case/accuracy/flow_sensitive/normal_stmt/assign_expression_stmt_001_T.py Line 18: os.system(o) @@ -1200,7 +1095,7 @@ Trace: AffectedNodeName: os.system 18: SINK: os.system(o) -------------- 35: taint_flow_test------------- +------------- 32: taint_flow_test------------- Description:taint_flow_test,回归测试使用,不推荐外部使用 File:/case/accuracy/object_sensitive/class/constructor_object_sensitive_001_T.py Line 23: os.system(o.data) @@ -1218,7 +1113,7 @@ Trace: AffectedNodeName: data 14: ARG PASS: def __init__(self, data): /case/accuracy/object_sensitive/class/constructor_object_sensitive_001_T.py - AffectedNodeName: [self.data] + AffectedNodeName: self.data 15: Var Pass: self.data = data # 污染源或干净值赋值给实例的 data 属性 /case/accuracy/object_sensitive/class/constructor_object_sensitive_001_T.py AffectedNodeName: obj @@ -1233,7 +1128,7 @@ Trace: AffectedNodeName: os.system 23: SINK: os.system(o.data) -------------- 36: taint_flow_test------------- +------------- 33: taint_flow_test------------- Description:taint_flow_test,回归测试使用,不推荐外部使用 File:/case/accuracy/object_sensitive/class/constructor_object_sensitive_003_T.py Line 29: os.system(o.data) @@ -1251,7 +1146,7 @@ Trace: AffectedNodeName: data 14: ARG PASS: def __init__(self, data): /case/accuracy/object_sensitive/class/constructor_object_sensitive_003_T.py - AffectedNodeName: [self.data] + AffectedNodeName: self.data 15: Var Pass: self.data = data /case/accuracy/object_sensitive/class/constructor_object_sensitive_003_T.py AffectedNodeName: parent_tainted @@ -1266,7 +1161,7 @@ Trace: AffectedNodeName: os.system 29: SINK: os.system(o.data) -------------- 37: taint_flow_test------------- +------------- 34: taint_flow_test------------- Description:taint_flow_test,回归测试使用,不推荐外部使用 File:/case/accuracy/object_sensitive/collection/array_object_sensitive_001_T.py Line 21: os.system(.join(o)) @@ -1293,7 +1188,7 @@ Trace: AffectedNodeName: os.system 21: SINK: os.system(''.join(o)) -------------- 38: taint_flow_test------------- +------------- 35: taint_flow_test------------- Description:taint_flow_test,回归测试使用,不推荐外部使用 File:/case/accuracy/object_sensitive/collection/list_object_sensitive_001_T.py Line 20: os.system(str(o)) @@ -1317,7 +1212,7 @@ Trace: AffectedNodeName: os.system 20: SINK: os.system(str(o)) -------------- 39: taint_flow_test------------- +------------- 36: taint_flow_test------------- Description:taint_flow_test,回归测试使用,不推荐外部使用 File:/case/accuracy/object_sensitive/collection/list_object_sensitive_003_T.py Line 21: os.system(str(o)) @@ -1341,7 +1236,7 @@ Trace: AffectedNodeName: os.system 21: SINK: os.system(str(o)) -------------- 40: taint_flow_test------------- +------------- 37: taint_flow_test------------- Description:taint_flow_test,回归测试使用,不推荐外部使用 File:/case/accuracy/object_sensitive/collection/list_object_sensitive_005_T.py Line 22: os.system(str(o)) @@ -1362,7 +1257,31 @@ Trace: AffectedNodeName: os.system 22: SINK: os.system(str(o)) -------------- 41: taint_flow_test------------- +------------- 38: taint_flow_test------------- +Description:taint_flow_test,回归测试使用,不推荐外部使用 +File:/case/accuracy/object_sensitive/collection/list_object_sensitive_007_T.py +Line 20: os.system(str(o)) +SINK RULE:os.system +entrypoint: +{"filePath":"/case/accuracy/object_sensitive/collection/list_object_sensitive_007_T.py","functionName":"list_object_sensitive_007_T","attribute":"fullCallGraphMade","type":"functionCall","funcReceiverType":""} +Trace: + /case/accuracy/object_sensitive/collection/list_object_sensitive_007_T.py + AffectedNodeName: taint_src + 11: SOURCE: def list_object_sensitive_007_T(taint_src): + /case/accuracy/object_sensitive/collection/list_object_sensitive_007_T.py + AffectedNodeName: s + 14: Var Pass: s.extend([taint_src, "d"]) + /case/accuracy/object_sensitive/collection/list_object_sensitive_007_T.py + AffectedNodeName: taint_sink + 16: CALL: taint_sink(s) # 传递污染后的列表 + /case/accuracy/object_sensitive/collection/list_object_sensitive_007_T.py + AffectedNodeName: o + 19: ARG PASS: def taint_sink(o): + /case/accuracy/object_sensitive/collection/list_object_sensitive_007_T.py + AffectedNodeName: os.system + 20: SINK: os.system(str(o)) + +------------- 39: taint_flow_test------------- Description:taint_flow_test,回归测试使用,不推荐外部使用 File:/case/accuracy/object_sensitive/collection/list_object_sensitive_008_F.py Line 22: os.system(str(o)) @@ -1386,7 +1305,7 @@ Trace: AffectedNodeName: os.system 22: SINK: os.system(str(o)) -------------- 42: taint_flow_test------------- +------------- 40: taint_flow_test------------- Description:taint_flow_test,回归测试使用,不推荐外部使用 File:/case/accuracy/object_sensitive/collection/map_object_sensitive_001_T.py Line 22: os.system(str(o)) @@ -1398,7 +1317,7 @@ Trace: AffectedNodeName: taint_src 11: SOURCE: def map_object_sensitive_001_T(taint_src): /case/accuracy/object_sensitive/collection/map_object_sensitive_001_T.py - AffectedNodeName: [map.key1] + AffectedNodeName: map.key1 13: Var Pass: map["key1"] = taint_src /case/accuracy/object_sensitive/collection/map_object_sensitive_001_T.py AffectedNodeName: taint_sink @@ -1410,7 +1329,7 @@ Trace: AffectedNodeName: os.system 22: SINK: os.system(str(o)) -------------- 43: taint_flow_test------------- +------------- 41: taint_flow_test------------- Description:taint_flow_test,回归测试使用,不推荐外部使用 File:/case/accuracy/object_sensitive/collection/set_object_sensitive_001_T.py Line 21: os.system(str(o)) @@ -1434,6 +1353,57 @@ Trace: AffectedNodeName: os.system 21: SINK: os.system(str(o)) +------------- 42: taint_flow_test------------- +Description:taint_flow_test,回归测试使用,不推荐外部使用 +File:/case/accuracy/object_sensitive/collection/set_object_sensitive_003_T.py +Line 22: os.system(str(o)) +SINK RULE:os.system +entrypoint: +{"filePath":"/case/accuracy/object_sensitive/collection/set_object_sensitive_003_T.py","functionName":"set_object_sensitive_003_T","attribute":"fullCallGraphMade","type":"functionCall","funcReceiverType":""} +Trace: + /case/accuracy/object_sensitive/collection/set_object_sensitive_003_T.py + AffectedNodeName: taint_src + 12: SOURCE: def set_object_sensitive_003_T(taint_src): + /case/accuracy/object_sensitive/collection/set_object_sensitive_003_T.py + AffectedNodeName: polluted_set + 14: Var Pass: polluted_set.add(taint_src) + /case/accuracy/object_sensitive/collection/set_object_sensitive_003_T.py + AffectedNodeName: taint_sink + 18: CALL: taint_sink(polluted_set) + /case/accuracy/object_sensitive/collection/set_object_sensitive_003_T.py + AffectedNodeName: o + 21: ARG PASS: def taint_sink(o): + /case/accuracy/object_sensitive/collection/set_object_sensitive_003_T.py + AffectedNodeName: os.system + 22: SINK: os.system(str(o)) + +------------- 43: taint_flow_test------------- +Description:taint_flow_test,回归测试使用,不推荐外部使用 +File:/case/accuracy/object_sensitive/collection/set_object_sensitive_004_F.py +Line 20: os.system(str(o)) +SINK RULE:os.system +entrypoint: +{"filePath":"/case/accuracy/object_sensitive/collection/set_object_sensitive_004_F.py","functionName":"set_object_sensitive_004_F","attribute":"fullCallGraphMade","type":"functionCall","funcReceiverType":""} +Trace: + /case/accuracy/object_sensitive/collection/set_object_sensitive_004_F.py + AffectedNodeName: taint_src + 11: SOURCE: def set_object_sensitive_004_F(taint_src): + /case/accuracy/object_sensitive/collection/set_object_sensitive_004_F.py + AffectedNodeName: polluted_set + 14: Var Pass: polluted_set.add(taint_src) + /case/accuracy/object_sensitive/collection/set_object_sensitive_004_F.py + AffectedNodeName: polluted_set + 15: Var Pass: polluted_set.discard(taint_src) + /case/accuracy/object_sensitive/collection/set_object_sensitive_004_F.py + AffectedNodeName: taint_sink + 17: CALL: taint_sink(polluted_set) + /case/accuracy/object_sensitive/collection/set_object_sensitive_004_F.py + AffectedNodeName: o + 19: ARG PASS: def taint_sink(o): + /case/accuracy/object_sensitive/collection/set_object_sensitive_004_F.py + AffectedNodeName: os.system + 20: SINK: os.system(str(o)) + ------------- 44: taint_flow_test------------- Description:taint_flow_test,回归测试使用,不推荐外部使用 File:/case/accuracy/path_sensitive/exception_throw/exception_throw_001_T.py @@ -1668,7 +1638,7 @@ Trace: AffectedNodeName: name 14: ARG PASS: def __init__(self, name): /case/completeness/dynamic_tracing/dynamic_call/dynamic_call_reflect_002_T.py - AffectedNodeName: [self.name] + AffectedNodeName: self.name 15: Var Pass: self.name = name /case/completeness/dynamic_tracing/dynamic_call/dynamic_call_reflect_002_T.py AffectedNodeName: obj @@ -1701,7 +1671,7 @@ Trace: AffectedNodeName: data 14: ARG PASS: def __init__(self, data): /case/completeness/dynamic_tracing/dynamic_call/dynamic_call_reflect_004_F.py - AffectedNodeName: [self.data] + AffectedNodeName: self.data 15: Var Pass: self.data = data /case/completeness/dynamic_tracing/dynamic_call/dynamic_call_reflect_004_F.py AffectedNodeName: obj @@ -1734,7 +1704,7 @@ Trace: AffectedNodeName: value 14: ARG PASS: def __init__(self,value): /case/completeness/dynamic_tracing/dynamic_call/dynamic_call_reflect_006_F.py - AffectedNodeName: [self.data] + AffectedNodeName: self.data 15: Var Pass: self.data = value /case/completeness/dynamic_tracing/dynamic_call/dynamic_call_reflect_006_F.py AffectedNodeName: obj @@ -1830,7 +1800,7 @@ Trace: AffectedNodeName: taint_src 12: SOURCE: def alias_001_T(taint_src): /case/completeness/single_app_tracing/alias/alias_001_T.py - AffectedNodeName: [b.value] + AffectedNodeName: b.value 15: Var Pass: b['value'] = taint_src /case/completeness/single_app_tracing/alias/alias_001_T.py AffectedNodeName: taint_sink @@ -1854,7 +1824,7 @@ Trace: AffectedNodeName: taint_src 12: SOURCE: def alias_003_T(taint_src): /case/completeness/single_app_tracing/alias/alias_003_T.py - AffectedNodeName: [c.value] + AffectedNodeName: c.value 16: Var Pass: c['value'] = taint_src # 修改末级别名 /case/completeness/single_app_tracing/alias/alias_003_T.py AffectedNodeName: taint_sink @@ -1878,7 +1848,7 @@ Trace: AffectedNodeName: taint_src 12: SOURCE: def alias_005_T(taint_src): /case/completeness/single_app_tracing/alias/alias_005_T.py - AffectedNodeName: [b.0] + AffectedNodeName: b.0 15: Var Pass: b[0] = taint_src # 修改列表元素 /case/completeness/single_app_tracing/alias/alias_005_T.py AffectedNodeName: taint_sink @@ -1902,7 +1872,7 @@ Trace: AffectedNodeName: taint_src 12: SOURCE: def alias_007_T(taint_src): /case/completeness/single_app_tracing/alias/alias_007_T.py - AffectedNodeName: [obj.value] + AffectedNodeName: obj.value 14: Var Pass: obj['value'] = taint_src # 通过参数修改 /case/completeness/single_app_tracing/alias/alias_007_T.py AffectedNodeName: taint_sink @@ -1926,7 +1896,7 @@ Trace: AffectedNodeName: taint_src 12: SOURCE: def alias_009_T(taint_src): /case/completeness/single_app_tracing/alias/alias_009_T.py - AffectedNodeName: [b.data] + AffectedNodeName: b.data 19: Var Pass: b.data = taint_src /case/completeness/single_app_tracing/alias/alias_009_T.py AffectedNodeName: taint_sink @@ -1976,12 +1946,6 @@ Trace: /case/completeness/single_app_tracing/alias/type_alias_003_T.py AffectedNodeName: __init__ 21: CALL: points: Points = [Point(taint_src, "SAFE"), Point("2.0", "3.0")] - /case/completeness/single_app_tracing/alias/type_alias_003_T.py - AffectedNodeName: x - 13: ARG PASS: def __init__(self, x: str, y: str): - /case/completeness/single_app_tracing/alias/type_alias_003_T.py - AffectedNodeName: [self.x] - 14: Var Pass: self.x = x /case/completeness/single_app_tracing/alias/type_alias_003_T.py AffectedNodeName: points 21: Var Pass: points: Points = [Point(taint_src, "SAFE"), Point("2.0", "3.0")] @@ -2064,7 +2028,7 @@ Trace: AffectedNodeName: char_array 16: Var Pass: char_array = array.array('u', taint_src) # 每个字符作为独立元素 /case/accuracy/field_sensitive/one_dimensional_collection/numeric_index_state_no_solver/array_no_solver_003_T.py - AffectedNodeName: [arr.0] + AffectedNodeName: arr.0 17: Var Pass: arr[0] = char_array[0] # 动态修改索引0 /case/accuracy/field_sensitive/one_dimensional_collection/numeric_index_state_no_solver/array_no_solver_003_T.py AffectedNodeName: taint_sink @@ -2091,7 +2055,7 @@ Trace: AffectedNodeName: char_array 16: Var Pass: char_array = array.array('u', taint_src) # 每个字符作为独立元素 /case/accuracy/field_sensitive/one_dimensional_collection/numeric_index_state_no_solver/array_no_solver_004_F.py - AffectedNodeName: [arr.0] + AffectedNodeName: arr.0 17: Var Pass: arr[0] = char_array[0] # 动态修改索引0 /case/accuracy/field_sensitive/one_dimensional_collection/numeric_index_state_no_solver/array_no_solver_004_F.py AffectedNodeName: taint_sink @@ -2163,7 +2127,7 @@ Trace: AffectedNodeName: taint_src 12: SOURCE: def map_field_sensitive_001_T(taint_src): /case/accuracy/field_sensitive/one_dimensional_collection/numeric_index_state_no_solver/map_field_sensitive_001_T.py - AffectedNodeName: [my_map.key1] + AffectedNodeName: my_map.key1 14: Var Pass: my_map['key1'] = taint_src # 设置键值对,污染源绑定到 'key1' /case/accuracy/field_sensitive/one_dimensional_collection/numeric_index_state_no_solver/map_field_sensitive_001_T.py AffectedNodeName: taint_sink @@ -2187,7 +2151,7 @@ Trace: AffectedNodeName: taint_src 12: SOURCE: def map_field_sensitive_002_F(taint_src): /case/accuracy/field_sensitive/one_dimensional_collection/numeric_index_state_no_solver/map_field_sensitive_002_F.py - AffectedNodeName: [my_map.key1] + AffectedNodeName: my_map.key1 14: Var Pass: my_map['key1'] = taint_src # 设置键值对,污染源绑定到 'key1' /case/accuracy/field_sensitive/one_dimensional_collection/numeric_index_state_no_solver/map_field_sensitive_002_F.py AffectedNodeName: taint_sink @@ -2232,7 +2196,7 @@ Trace: AffectedNodeName: taint_src 12: SOURCE: def map_field_sensitive_004_T(taint_src): /case/accuracy/field_sensitive/one_dimensional_collection/numeric_index_state_no_solver/map_field_sensitive_004_T.py - AffectedNodeName: [my_map.key1] + AffectedNodeName: my_map.key1 14: Var Pass: my_map['key1'] = taint_src # 污染源绑定到 'key1' /case/accuracy/field_sensitive/one_dimensional_collection/numeric_index_state_no_solver/map_field_sensitive_004_T.py AffectedNodeName: taint_sink @@ -2256,7 +2220,7 @@ Trace: AffectedNodeName: taint_src 12: SOURCE: def map_field_sensitive_005_F(taint_src): /case/accuracy/field_sensitive/one_dimensional_collection/numeric_index_state_no_solver/map_field_sensitive_005_F.py - AffectedNodeName: [my_map.key1] + AffectedNodeName: my_map.key1 14: Var Pass: my_map['key1'] = taint_src # 污染源绑定到 'key1' /case/accuracy/field_sensitive/one_dimensional_collection/numeric_index_state_no_solver/map_field_sensitive_005_F.py AffectedNodeName: taint_sink @@ -2280,7 +2244,7 @@ Trace: AffectedNodeName: taint_src 11: SOURCE: def map_field_sensitive_006_T(taint_src): /case/accuracy/field_sensitive/one_dimensional_collection/numeric_index_state_no_solver/map_field_sensitive_006_T.py - AffectedNodeName: [my_map.key1] + AffectedNodeName: my_map.key1 13: Var Pass: my_map['key1'] = taint_src # 污染源绑定到 'key1' /case/accuracy/field_sensitive/one_dimensional_collection/numeric_index_state_no_solver/map_field_sensitive_006_T.py AffectedNodeName: taint_sink @@ -2304,7 +2268,7 @@ Trace: AffectedNodeName: taint_src 11: SOURCE: def map_field_sensitive_009_F(taint_src): /case/accuracy/field_sensitive/one_dimensional_collection/numeric_index_state_no_solver/map_field_sensitive_009_F.py - AffectedNodeName: [my_map.key1] + AffectedNodeName: my_map.key1 13: Var Pass: my_map['key1'] = taint_src # 键 'key1' 是干净的,但值被污染 /case/accuracy/field_sensitive/one_dimensional_collection/numeric_index_state_no_solver/map_field_sensitive_009_F.py AffectedNodeName: taint_sink @@ -2877,30 +2841,6 @@ Trace: ------------- 99: taint_flow_test------------- Description:taint_flow_test,回归测试使用,不推荐外部使用 -File:/case/accuracy/path_sensitive/loop_conditional_stmt/no_solver/conditional_if_no_solver_004_F.py -Line 24: os.system(o) -SINK RULE:os.system -entrypoint: -{"filePath":"/case/accuracy/path_sensitive/loop_conditional_stmt/no_solver/conditional_if_no_solver_004_F.py","functionName":"conditional_if_no_solver_004_F","attribute":"fullCallGraphMade","type":"functionCall","funcReceiverType":""} -Trace: - /case/accuracy/path_sensitive/loop_conditional_stmt/no_solver/conditional_if_no_solver_004_F.py - AffectedNodeName: taint_src - 12: SOURCE: def conditional_if_no_solver_004_F(taint_src): - /case/accuracy/path_sensitive/loop_conditional_stmt/no_solver/conditional_if_no_solver_004_F.py - AffectedNodeName: res - 17: Var Pass: res = taint_src - /case/accuracy/path_sensitive/loop_conditional_stmt/no_solver/conditional_if_no_solver_004_F.py - AffectedNodeName: taint_sink - 19: CALL: taint_sink(res) - /case/accuracy/path_sensitive/loop_conditional_stmt/no_solver/conditional_if_no_solver_004_F.py - AffectedNodeName: o - 23: ARG PASS: def taint_sink(o): - /case/accuracy/path_sensitive/loop_conditional_stmt/no_solver/conditional_if_no_solver_004_F.py - AffectedNodeName: os.system - 24: SINK: os.system(o) - -------------- 100: taint_flow_test------------- -Description:taint_flow_test,回归测试使用,不推荐外部使用 File:/case/accuracy/path_sensitive/loop_conditional_stmt/no_solver/conditional_match_no_solver_004_T.py Line 23: os.system(o) SINK RULE:os.system @@ -2923,7 +2863,7 @@ Trace: AffectedNodeName: os.system 23: SINK: os.system(o) -------------- 101: taint_flow_test------------- +------------- 100: taint_flow_test------------- Description:taint_flow_test,回归测试使用,不推荐外部使用 File:/case/accuracy/path_sensitive/loop_conditional_stmt/solver/conditional_if_solver_001_T.py Line 24: os.system(o) @@ -2947,7 +2887,7 @@ Trace: AffectedNodeName: os.system 24: SINK: os.system(o) -------------- 102: taint_flow_test------------- +------------- 101: taint_flow_test------------- Description:taint_flow_test,回归测试使用,不推荐外部使用 File:/case/accuracy/path_sensitive/loop_conditional_stmt/solver/conditional_if_solver_002_F.py Line 24: os.system(o) @@ -2971,7 +2911,7 @@ Trace: AffectedNodeName: os.system 24: SINK: os.system(o) -------------- 103: taint_flow_test------------- +------------- 102: taint_flow_test------------- Description:taint_flow_test,回归测试使用,不推荐外部使用 File:/case/accuracy/path_sensitive/loop_conditional_stmt/solver/conditional_match_solver_001_F.py Line 23: os.system(o) @@ -2995,7 +2935,7 @@ Trace: AffectedNodeName: os.system 23: SINK: os.system(o) -------------- 104: taint_flow_test------------- +------------- 103: taint_flow_test------------- Description:taint_flow_test,回归测试使用,不推荐外部使用 File:/case/accuracy/path_sensitive/loop_conditional_stmt/solver/conditional_match_solver_002_T.py Line 22: os.system(o) @@ -3019,7 +2959,7 @@ Trace: AffectedNodeName: os.system 22: SINK: os.system(o) -------------- 105: taint_flow_test------------- +------------- 104: taint_flow_test------------- Description:taint_flow_test,回归测试使用,不推荐外部使用 File:/case/accuracy/path_sensitive/loop_conditional_stmt/solver/for_body_solver_001_T.py Line 20: os.system(o) @@ -3043,7 +2983,7 @@ Trace: AffectedNodeName: os.system 20: SINK: os.system(o) -------------- 106: taint_flow_test------------- +------------- 105: taint_flow_test------------- Description:taint_flow_test,回归测试使用,不推荐外部使用 File:/case/accuracy/path_sensitive/loop_conditional_stmt/solver/for_body_solver_002_F.py Line 21: os.system(str(o)) @@ -3067,7 +3007,7 @@ Trace: AffectedNodeName: os.system 21: SINK: os.system(str(o)) -------------- 107: taint_flow_test------------- +------------- 106: taint_flow_test------------- Description:taint_flow_test,回归测试使用,不推荐外部使用 File:/case/completeness/single_app_tracing/asynchronous_tracing/async_for/async_for_001_T.py Line 27: os.system(str(o)) @@ -3097,7 +3037,7 @@ Trace: AffectedNodeName: os.system 27: SINK: os.system(str(o)) -------------- 108: taint_flow_test------------- +------------- 107: taint_flow_test------------- Description:taint_flow_test,回归测试使用,不推荐外部使用 File:/case/completeness/single_app_tracing/asynchronous_tracing/promise_callback_await/asynchronous_await_001_T.py Line 25: os.system(o) @@ -3111,12 +3051,6 @@ Trace: /case/completeness/single_app_tracing/asynchronous_tracing/promise_callback_await/asynchronous_await_001_T.py AffectedNodeName: process 15: CALL: data = await process(taint_src) - /case/completeness/single_app_tracing/asynchronous_tracing/promise_callback_await/asynchronous_await_001_T.py - AffectedNodeName: taint_src - 19: ARG PASS: async def process(taint_src): - /case/completeness/single_app_tracing/asynchronous_tracing/promise_callback_await/asynchronous_await_001_T.py - AffectedNodeName: [return value] - 21: Return Value: return taint_src /case/completeness/single_app_tracing/asynchronous_tracing/promise_callback_await/asynchronous_await_001_T.py AffectedNodeName: process 15: CALL RETURN: data = await process(taint_src) @@ -3133,7 +3067,7 @@ Trace: AffectedNodeName: os.system 25: SINK: os.system(o) -------------- 109: taint_flow_test------------- +------------- 108: taint_flow_test------------- Description:taint_flow_test,回归测试使用,不推荐外部使用 File:/case/completeness/single_app_tracing/asynchronous_tracing/promise_callback_await/asynchronous_await_005_T.py Line 28: os.system(o) @@ -3160,7 +3094,7 @@ Trace: AffectedNodeName: os.system 28: SINK: os.system(o) -------------- 110: taint_flow_test------------- +------------- 109: taint_flow_test------------- Description:taint_flow_test,回归测试使用,不推荐外部使用 File:/case/completeness/single_app_tracing/asynchronous_tracing/promise_callback_await/asynchronous_await_009_T.py Line 28: os.system(o) @@ -3199,7 +3133,7 @@ Trace: AffectedNodeName: os.system 28: SINK: os.system(o) -------------- 111: taint_flow_test------------- +------------- 110: taint_flow_test------------- Description:taint_flow_test,回归测试使用,不推荐外部使用 File:/case/completeness/single_app_tracing/class/complex_object/cross_class_001_T.py Line 30: os.system(o) @@ -3223,7 +3157,7 @@ Trace: AffectedNodeName: taint_src 14: ARG PASS: def __init__(self, taint_src): /case/completeness/single_app_tracing/class/complex_object/cross_class_001_T.py - AffectedNodeName: [self.data] + AffectedNodeName: self.data 15: Var Pass: self.data = taint_src /case/completeness/single_app_tracing/class/complex_object/cross_class_001_T.py AffectedNodeName: a_instance @@ -3241,7 +3175,7 @@ Trace: AffectedNodeName: get_data 23: CALL RETURN: self.data = a_instance.get_data() /case/completeness/single_app_tracing/class/complex_object/cross_class_001_T.py - AffectedNodeName: [self.data] + AffectedNodeName: self.data 23: Var Pass: self.data = a_instance.get_data() /case/completeness/single_app_tracing/class/complex_object/cross_class_001_T.py AffectedNodeName: obj @@ -3256,7 +3190,7 @@ Trace: AffectedNodeName: os.system 30: SINK: os.system(o) -------------- 112: taint_flow_test------------- +------------- 111: taint_flow_test------------- Description:taint_flow_test,回归测试使用,不推荐外部使用 File:/case/completeness/single_app_tracing/class/complex_object/cross_class_003_T.py Line 35: os.system(o) @@ -3274,7 +3208,7 @@ Trace: AffectedNodeName: data 25: ARG PASS: def set_data(self, data): /case/completeness/single_app_tracing/class/complex_object/cross_class_003_T.py - AffectedNodeName: [self.data] + AffectedNodeName: self.data 26: Var Pass: self.data = data /case/completeness/single_app_tracing/class/complex_object/cross_class_003_T.py AffectedNodeName: taint_sink @@ -3286,7 +3220,7 @@ Trace: AffectedNodeName: os.system 35: SINK: os.system(o) -------------- 113: taint_flow_test------------- +------------- 112: taint_flow_test------------- Description:taint_flow_test,回归测试使用,不推荐外部使用 File:/case/completeness/single_app_tracing/class/complex_object/inheritance_class_001_T.py Line 31: os.system(o) @@ -3310,7 +3244,7 @@ Trace: AffectedNodeName: data 14: ARG PASS: def __init__(self, data): /case/completeness/single_app_tracing/class/complex_object/inheritance_class_001_T.py - AffectedNodeName: [self.data] + AffectedNodeName: self.data 15: Var Pass: self.data = data /case/completeness/single_app_tracing/class/complex_object/inheritance_class_001_T.py AffectedNodeName: obj @@ -3337,7 +3271,7 @@ Trace: AffectedNodeName: os.system 31: SINK: os.system(o) -------------- 114: taint_flow_test------------- +------------- 113: taint_flow_test------------- Description:taint_flow_test,回归测试使用,不推荐外部使用 File:/case/completeness/single_app_tracing/class/complex_object/inject_data_new_001_T.py Line 24: os.system(o) @@ -3361,7 +3295,7 @@ Trace: AffectedNodeName: os.system 24: SINK: os.system(o) -------------- 115: taint_flow_test------------- +------------- 114: taint_flow_test------------- Description:taint_flow_test,回归测试使用,不推荐外部使用 File:/case/completeness/single_app_tracing/class/complex_object/inject_data_new_003_T.py Line 42: os.system(o) @@ -3388,7 +3322,7 @@ Trace: AffectedNodeName: os.system 42: SINK: os.system(o) -------------- 116: taint_flow_test------------- +------------- 115: taint_flow_test------------- Description:taint_flow_test,回归测试使用,不推荐外部使用 File:/case/completeness/single_app_tracing/class/simple_object/simple_object_001_T.py Line 22: os.system(o) @@ -3406,7 +3340,7 @@ Trace: AffectedNodeName: data 14: ARG PASS: def __init__(self, data): /case/completeness/single_app_tracing/class/simple_object/simple_object_001_T.py - AffectedNodeName: [self.data] + AffectedNodeName: self.data 15: Var Pass: self.data = data /case/completeness/single_app_tracing/class/simple_object/simple_object_001_T.py AffectedNodeName: obj @@ -3421,7 +3355,7 @@ Trace: AffectedNodeName: os.system 22: SINK: os.system(o) -------------- 117: taint_flow_test------------- +------------- 116: taint_flow_test------------- Description:taint_flow_test,回归测试使用,不推荐外部使用 File:/case/completeness/single_app_tracing/class/simple_object/simple_object_003_T.py Line 25: os.system(o) @@ -3433,7 +3367,7 @@ Trace: AffectedNodeName: taint_src 12: SOURCE: def simple_object_003_T(taint_src): /case/completeness/single_app_tracing/class/simple_object/simple_object_003_T.py - AffectedNodeName: [Person.name] + AffectedNodeName: Person.name 16: Var Pass: Person.name = taint_src /case/completeness/single_app_tracing/class/simple_object/simple_object_003_T.py AffectedNodeName: person @@ -3448,7 +3382,7 @@ Trace: AffectedNodeName: os.system 25: SINK: os.system(o) -------------- 118: taint_flow_test------------- +------------- 117: taint_flow_test------------- Description:taint_flow_test,回归测试使用,不推荐外部使用 File:/case/completeness/single_app_tracing/class/simple_object/simple_object_005_T.py Line 30: os.system(o) @@ -3462,12 +3396,6 @@ Trace: /case/completeness/single_app_tracing/class/simple_object/simple_object_005_T.py AffectedNodeName: __init__ 25: CALL: int_box = Box(taint_src) - /case/completeness/single_app_tracing/class/simple_object/simple_object_005_T.py - AffectedNodeName: content - 16: ARG PASS: def __init__(self, content: T): - /case/completeness/single_app_tracing/class/simple_object/simple_object_005_T.py - AffectedNodeName: [self.content] - 17: Var Pass: self.content = content /case/completeness/single_app_tracing/class/simple_object/simple_object_005_T.py AffectedNodeName: int_box 25: Var Pass: int_box = Box(taint_src) @@ -3477,9 +3405,6 @@ Trace: /case/completeness/single_app_tracing/class/simple_object/simple_object_005_T.py AffectedNodeName: int_box 26: ARG PASS: taint_sink(int_box.get_content()) - /case/completeness/single_app_tracing/class/simple_object/simple_object_005_T.py - AffectedNodeName: [return value] - 20: Return Value: return self.content /case/completeness/single_app_tracing/class/simple_object/simple_object_005_T.py AffectedNodeName: get_content 26: CALL RETURN: taint_sink(int_box.get_content()) @@ -3493,7 +3418,7 @@ Trace: AffectedNodeName: os.system 30: SINK: os.system(o) -------------- 119: taint_flow_test------------- +------------- 118: taint_flow_test------------- Description:taint_flow_test,回归测试使用,不推荐外部使用 File:/case/completeness/single_app_tracing/control_flow/assert/assert_001_T.py Line 26: os.system(o) @@ -3517,7 +3442,7 @@ Trace: AffectedNodeName: os.system 26: SINK: os.system(o) -------------- 120: taint_flow_test------------- +------------- 119: taint_flow_test------------- Description:taint_flow_test,回归测试使用,不推荐外部使用 File:/case/completeness/single_app_tracing/control_flow/assert/assert_002_F.py Line 27: os.system(o) @@ -3541,7 +3466,7 @@ Trace: AffectedNodeName: os.system 27: SINK: os.system(o) -------------- 121: taint_flow_test------------- +------------- 120: taint_flow_test------------- Description:taint_flow_test,回归测试使用,不推荐外部使用 File:/case/completeness/single_app_tracing/control_flow/conditional_stmt/conditional_if_001_T.py Line 18: os.system(o) @@ -3562,7 +3487,7 @@ Trace: AffectedNodeName: os.system 18: SINK: os.system(o) -------------- 122: taint_flow_test------------- +------------- 121: taint_flow_test------------- Description:taint_flow_test,回归测试使用,不推荐外部使用 File:/case/completeness/single_app_tracing/control_flow/conditional_stmt/conditional_if_003_T.py Line 22: os.system(o) @@ -3583,7 +3508,7 @@ Trace: AffectedNodeName: os.system 22: SINK: os.system(o) -------------- 123: taint_flow_test------------- +------------- 122: taint_flow_test------------- Description:taint_flow_test,回归测试使用,不推荐外部使用 File:/case/completeness/single_app_tracing/control_flow/conditional_stmt/conditional_match_001_T.py Line 20: os.system(o) @@ -3607,7 +3532,7 @@ Trace: AffectedNodeName: os.system 20: SINK: os.system(o) -------------- 124: taint_flow_test------------- +------------- 123: taint_flow_test------------- Description:taint_flow_test,回归测试使用,不推荐外部使用 File:/case/completeness/single_app_tracing/control_flow/conditional_stmt/conditional_ternary_001_T.py Line 17: os.system(o) @@ -3631,7 +3556,7 @@ Trace: AffectedNodeName: os.system 17: SINK: os.system(o) -------------- 125: taint_flow_test------------- +------------- 124: taint_flow_test------------- Description:taint_flow_test,回归测试使用,不推荐外部使用 File:/case/completeness/single_app_tracing/control_flow/conditional_stmt/conditional_ternary_002_F.py Line 17: os.system(o) @@ -3655,7 +3580,7 @@ Trace: AffectedNodeName: os.system 17: SINK: os.system(o) -------------- 126: taint_flow_test------------- +------------- 125: taint_flow_test------------- Description:taint_flow_test,回归测试使用,不推荐外部使用 File:/case/completeness/single_app_tracing/control_flow/loop_stmt/all_001_T.py Line 16: os.system(o) @@ -3679,7 +3604,7 @@ Trace: AffectedNodeName: os.system 16: SINK: os.system(o) -------------- 127: taint_flow_test------------- +------------- 126: taint_flow_test------------- Description:taint_flow_test,回归测试使用,不推荐外部使用 File:/case/completeness/single_app_tracing/control_flow/loop_stmt/any_001_T.py Line 16: os.system(o) @@ -3703,7 +3628,7 @@ Trace: AffectedNodeName: os.system 16: SINK: os.system(o) -------------- 128: taint_flow_test------------- +------------- 127: taint_flow_test------------- Description:taint_flow_test,回归测试使用,不推荐外部使用 File:/case/completeness/single_app_tracing/control_flow/loop_stmt/for_body_001_T.py Line 20: os.system(o) @@ -3727,7 +3652,7 @@ Trace: AffectedNodeName: os.system 20: SINK: os.system(o) -------------- 129: taint_flow_test------------- +------------- 128: taint_flow_test------------- Description:taint_flow_test,回归测试使用,不推荐外部使用 File:/case/completeness/single_app_tracing/control_flow/loop_stmt/forin_body_001_T.py Line 23: os.system(o) @@ -3754,7 +3679,7 @@ Trace: AffectedNodeName: os.system 23: SINK: os.system(o) -------------- 130: taint_flow_test------------- +------------- 129: taint_flow_test------------- Description:taint_flow_test,回归测试使用,不推荐外部使用 File:/case/completeness/single_app_tracing/control_flow/loop_stmt/nested_loop_001_T.py Line 20: os.system(o) @@ -3778,7 +3703,7 @@ Trace: AffectedNodeName: os.system 20: SINK: os.system(o) -------------- 131: taint_flow_test------------- +------------- 130: taint_flow_test------------- Description:taint_flow_test,回归测试使用,不推荐外部使用 File:/case/completeness/single_app_tracing/control_flow/loop_stmt/nested_loop_002_F.py Line 22: os.system(o) @@ -3802,7 +3727,7 @@ Trace: AffectedNodeName: os.system 22: SINK: os.system(o) -------------- 132: taint_flow_test------------- +------------- 131: taint_flow_test------------- Description:taint_flow_test,回归测试使用,不推荐外部使用 File:/case/completeness/single_app_tracing/control_flow/loop_stmt/while_body_001_T.py Line 23: os.system(o) @@ -3826,7 +3751,7 @@ Trace: AffectedNodeName: os.system 23: SINK: os.system(o) -------------- 133: taint_flow_test------------- +------------- 132: taint_flow_test------------- Description:taint_flow_test,回归测试使用,不推荐外部使用 File:/case/completeness/single_app_tracing/control_flow/loop_stmt/while_break_001_T.py Line 21: os.system(o) @@ -3850,7 +3775,7 @@ Trace: AffectedNodeName: os.system 21: SINK: os.system(o) -------------- 134: taint_flow_test------------- +------------- 133: taint_flow_test------------- Description:taint_flow_test,回归测试使用,不推荐外部使用 File:/case/completeness/single_app_tracing/control_flow/loop_stmt/while_else_001_T.py Line 25: os.system(o) @@ -3874,7 +3799,7 @@ Trace: AffectedNodeName: os.system 25: SINK: os.system(o) -------------- 135: taint_flow_test------------- +------------- 134: taint_flow_test------------- Description:taint_flow_test,回归测试使用,不推荐外部使用 File:/case/completeness/single_app_tracing/control_flow/loop_stmt/while_else_002_F.py Line 25: os.system(o) @@ -3898,7 +3823,7 @@ Trace: AffectedNodeName: os.system 25: SINK: os.system(o) -------------- 136: taint_flow_test------------- +------------- 135: taint_flow_test------------- Description:taint_flow_test,回归测试使用,不推荐外部使用 File:/case/completeness/single_app_tracing/datatype/any/type_annotation_any_001_T.py Line 24: os.system(o) @@ -3925,7 +3850,7 @@ Trace: AffectedNodeName: os.system 24: SINK: os.system(o) -------------- 137: taint_flow_test------------- +------------- 136: taint_flow_test------------- Description:taint_flow_test,回归测试使用,不推荐外部使用 File:/case/completeness/single_app_tracing/datatype/array/array_001_T.py Line 20: os.system(.join(o)) @@ -3952,7 +3877,7 @@ Trace: AffectedNodeName: os.system 20: SINK: os.system(''.join(o)) -------------- 138: taint_flow_test------------- +------------- 137: taint_flow_test------------- Description:taint_flow_test,回归测试使用,不推荐外部使用 File:/case/completeness/single_app_tracing/datatype/array/extslice_001_T.py Line 24: os.system(o) @@ -3976,7 +3901,7 @@ Trace: AffectedNodeName: os.system 24: SINK: os.system(o) -------------- 139: taint_flow_test------------- +------------- 138: taint_flow_test------------- Description:taint_flow_test,回归测试使用,不推荐外部使用 File:/case/completeness/single_app_tracing/datatype/array/extslice_002_F.py Line 24: os.system(o) @@ -4000,7 +3925,7 @@ Trace: AffectedNodeName: os.system 24: SINK: os.system(o) -------------- 140: taint_flow_test------------- +------------- 139: taint_flow_test------------- Description:taint_flow_test,回归测试使用,不推荐外部使用 File:/case/completeness/single_app_tracing/datatype/array/numpy_array_001_T.py Line 21: os.system(.join(o)) @@ -4024,7 +3949,7 @@ Trace: AffectedNodeName: os.system 21: SINK: os.system(''.join(o)) -------------- 141: taint_flow_test------------- +------------- 140: taint_flow_test------------- Description:taint_flow_test,回归测试使用,不推荐外部使用 File:/case/completeness/single_app_tracing/datatype/bytearray/bytearray_001_T.py Line 21: os.system(bytes(o)) @@ -4048,7 +3973,7 @@ Trace: AffectedNodeName: os.system 21: SINK: os.system(bytes(o)) -------------- 142: taint_flow_test------------- +------------- 141: taint_flow_test------------- Description:taint_flow_test,回归测试使用,不推荐外部使用 File:/case/completeness/single_app_tracing/datatype/bytes/bytes_003_T.py Line 21: os.system(o) @@ -4072,7 +3997,7 @@ Trace: AffectedNodeName: os.system 21: SINK: os.system(o) -------------- 143: taint_flow_test------------- +------------- 142: taint_flow_test------------- Description:taint_flow_test,回归测试使用,不推荐外部使用 File:/case/completeness/single_app_tracing/datatype/bytes/bytes_005_T.py Line 22: os.system(str(o)) @@ -4099,7 +4024,7 @@ Trace: AffectedNodeName: os.system 22: SINK: os.system(str(o)) -------------- 144: taint_flow_test------------- +------------- 143: taint_flow_test------------- Description:taint_flow_test,回归测试使用,不推荐外部使用 File:/case/completeness/single_app_tracing/datatype/bytes/bytes_007_T.py Line 22: os.system(o) @@ -4126,7 +4051,7 @@ Trace: AffectedNodeName: os.system 22: SINK: os.system(o) -------------- 145: taint_flow_test------------- +------------- 144: taint_flow_test------------- Description:taint_flow_test,回归测试使用,不推荐外部使用 File:/case/completeness/single_app_tracing/datatype/bytes/bytes_009_T.py Line 23: os.system(o) @@ -4153,7 +4078,7 @@ Trace: AffectedNodeName: os.system 23: SINK: os.system(o) -------------- 146: taint_flow_test------------- +------------- 145: taint_flow_test------------- Description:taint_flow_test,回归测试使用,不推荐外部使用 File:/case/completeness/single_app_tracing/datatype/bytes/bytes_011_T.py Line 22: os.system(o) @@ -4180,7 +4105,7 @@ Trace: AffectedNodeName: os.system 22: SINK: os.system(o) -------------- 147: taint_flow_test------------- +------------- 146: taint_flow_test------------- Description:taint_flow_test,回归测试使用,不推荐外部使用 File:/case/completeness/single_app_tracing/datatype/bytes/bytes_013_T.py Line 22: os.system(str(o)) @@ -4207,7 +4132,7 @@ Trace: AffectedNodeName: os.system 22: SINK: os.system(str(o)) -------------- 148: taint_flow_test------------- +------------- 147: taint_flow_test------------- Description:taint_flow_test,回归测试使用,不推荐外部使用 File:/case/completeness/single_app_tracing/datatype/collections/set_001_T.py Line 19: os.system(str(o)) @@ -4231,6 +4156,30 @@ Trace: AffectedNodeName: os.system 19: SINK: os.system(str(o)) +------------- 148: taint_flow_test------------- +Description:taint_flow_test,回归测试使用,不推荐外部使用 +File:/case/completeness/single_app_tracing/datatype/collections/set_003_T.py +Line 17: os.system(str(o)) +SINK RULE:os.system +entrypoint: +{"filePath":"/case/completeness/single_app_tracing/datatype/collections/set_003_T.py","functionName":"set_003_T","attribute":"fullCallGraphMade","type":"functionCall","funcReceiverType":""} +Trace: + /case/completeness/single_app_tracing/datatype/collections/set_003_T.py + AffectedNodeName: taint_src + 11: SOURCE: def set_003_T(taint_src): + /case/completeness/single_app_tracing/datatype/collections/set_003_T.py + AffectedNodeName: s + 13: Var Pass: s.add(taint_src) # 添加污点元素 + /case/completeness/single_app_tracing/datatype/collections/set_003_T.py + AffectedNodeName: taint_sink + 14: CALL: taint_sink(s) + /case/completeness/single_app_tracing/datatype/collections/set_003_T.py + AffectedNodeName: o + 16: ARG PASS: def taint_sink(o): + /case/completeness/single_app_tracing/datatype/collections/set_003_T.py + AffectedNodeName: os.system + 17: SINK: os.system(str(o)) + ------------- 149: taint_flow_test------------- Description:taint_flow_test,回归测试使用,不推荐外部使用 File:/case/completeness/single_app_tracing/datatype/collections/set_005_T.py @@ -4353,12 +4302,6 @@ Trace: /case/completeness/single_app_tracing/datatype/customize/type_annotation_customize_001_T.py AffectedNodeName: __init__ 18: CALL: a: MyClass = MyClass(taint_src) # 使用自定义类型注解,a的值必须是MyClass类的实例 - /case/completeness/single_app_tracing/datatype/customize/type_annotation_customize_001_T.py - AffectedNodeName: value - 14: ARG PASS: def __init__(self, value): - /case/completeness/single_app_tracing/datatype/customize/type_annotation_customize_001_T.py - AffectedNodeName: [self.value] - 15: Var Pass: self.value = value /case/completeness/single_app_tracing/datatype/customize/type_annotation_customize_001_T.py AffectedNodeName: a 18: Var Pass: a: MyClass = MyClass(taint_src) # 使用自定义类型注解,a的值必须是MyClass类的实例 @@ -4507,7 +4450,7 @@ Trace: AffectedNodeName: taint_src 12: SOURCE: def map_001_T(taint_src): /case/completeness/single_app_tracing/datatype/map/map_001_T.py - AffectedNodeName: [m.key1] + AffectedNodeName: m.key1 14: Var Pass: m['key1'] = taint_src /case/completeness/single_app_tracing/datatype/map/map_001_T.py AffectedNodeName: taint_sink @@ -4521,6 +4464,30 @@ Trace: ------------- 160: taint_flow_test------------- Description:taint_flow_test,回归测试使用,不推荐外部使用 +File:/case/completeness/single_app_tracing/datatype/map/map_005_T.py +Line 22: os.system(str(o)) +SINK RULE:os.system +entrypoint: +{"filePath":"/case/completeness/single_app_tracing/datatype/map/map_005_T.py","functionName":"map_005_T","attribute":"fullCallGraphMade","type":"functionCall","funcReceiverType":""} +Trace: + /case/completeness/single_app_tracing/datatype/map/map_005_T.py + AffectedNodeName: taint_src + 12: SOURCE: def map_005_T(taint_src): + /case/completeness/single_app_tracing/datatype/map/map_005_T.py + AffectedNodeName: m + 16: Var Pass: m.update({"key": taint_src}) + /case/completeness/single_app_tracing/datatype/map/map_005_T.py + AffectedNodeName: taint_sink + 18: CALL: taint_sink(m) # 传递更新后的污染字典 + /case/completeness/single_app_tracing/datatype/map/map_005_T.py + AffectedNodeName: o + 21: ARG PASS: def taint_sink(o): + /case/completeness/single_app_tracing/datatype/map/map_005_T.py + AffectedNodeName: os.system + 22: SINK: os.system(str(o)) + +------------- 161: taint_flow_test------------- +Description:taint_flow_test,回归测试使用,不推荐外部使用 File:/case/completeness/single_app_tracing/datatype/map/map_006_F.py Line 22: os.system(str(o)) SINK RULE:os.system @@ -4543,7 +4510,7 @@ Trace: AffectedNodeName: os.system 22: SINK: os.system(str(o)) -------------- 161: taint_flow_test------------- +------------- 162: taint_flow_test------------- Description:taint_flow_test,回归测试使用,不推荐外部使用 File:/case/completeness/single_app_tracing/datatype/map/map_007_T.py Line 22: os.system(str(o)) @@ -4567,7 +4534,7 @@ Trace: AffectedNodeName: os.system 22: SINK: os.system(str(o)) -------------- 162: taint_flow_test------------- +------------- 163: taint_flow_test------------- Description:taint_flow_test,回归测试使用,不推荐外部使用 File:/case/completeness/single_app_tracing/datatype/map/map_008_F.py Line 22: os.system(str(o)) @@ -4591,7 +4558,7 @@ Trace: AffectedNodeName: os.system 22: SINK: os.system(str(o)) -------------- 163: taint_flow_test------------- +------------- 164: taint_flow_test------------- Description:taint_flow_test,回归测试使用,不推荐外部使用 File:/case/completeness/single_app_tracing/datatype/map/map_009_T.py Line 22: os.system(str(o)) @@ -4621,7 +4588,7 @@ Trace: AffectedNodeName: os.system 22: SINK: os.system(str(o)) -------------- 164: taint_flow_test------------- +------------- 165: taint_flow_test------------- Description:taint_flow_test,回归测试使用,不推荐外部使用 File:/case/completeness/single_app_tracing/datatype/new_type/type_annotation_new_type_001_T.py Line 27: os.system(o) @@ -4657,7 +4624,7 @@ Trace: AffectedNodeName: os.system 27: SINK: os.system(o) -------------- 165: taint_flow_test------------- +------------- 166: taint_flow_test------------- Description:taint_flow_test,回归测试使用,不推荐外部使用 File:/case/completeness/single_app_tracing/datatype/primitives/bool_001_T.py Line 15: os.system(str(o)) @@ -4678,7 +4645,7 @@ Trace: AffectedNodeName: os.system 15: SINK: os.system(str(o)) -------------- 166: taint_flow_test------------- +------------- 167: taint_flow_test------------- Description:taint_flow_test,回归测试使用,不推荐外部使用 File:/case/completeness/single_app_tracing/datatype/primitives/bool_002_F.py Line 15: os.system(str(o)) @@ -4699,7 +4666,7 @@ Trace: AffectedNodeName: os.system 15: SINK: os.system(str(o)) -------------- 167: taint_flow_test------------- +------------- 168: taint_flow_test------------- Description:taint_flow_test,回归测试使用,不推荐外部使用 File:/case/completeness/single_app_tracing/datatype/primitives/complex_001_T.py Line 16: os.system(str(o)) @@ -4723,7 +4690,7 @@ Trace: AffectedNodeName: os.system 16: SINK: os.system(str(o)) -------------- 168: taint_flow_test------------- +------------- 169: taint_flow_test------------- Description:taint_flow_test,回归测试使用,不推荐外部使用 File:/case/completeness/single_app_tracing/datatype/primitives/complex_003_T.py Line 17: os.system(str(o)) @@ -4750,7 +4717,7 @@ Trace: AffectedNodeName: os.system 17: SINK: os.system(str(o)) -------------- 169: taint_flow_test------------- +------------- 170: taint_flow_test------------- Description:taint_flow_test,回归测试使用,不推荐外部使用 File:/case/completeness/single_app_tracing/datatype/primitives/complex_004_F.py Line 17: os.system(str(o)) @@ -4777,7 +4744,7 @@ Trace: AffectedNodeName: os.system 17: SINK: os.system(str(o)) -------------- 170: taint_flow_test------------- +------------- 171: taint_flow_test------------- Description:taint_flow_test,回归测试使用,不推荐外部使用 File:/case/completeness/single_app_tracing/datatype/primitives/float_001_T.py Line 16: os.system(str(o)) @@ -4801,7 +4768,7 @@ Trace: AffectedNodeName: os.system 16: SINK: os.system(str(o)) -------------- 171: taint_flow_test------------- +------------- 172: taint_flow_test------------- Description:taint_flow_test,回归测试使用,不推荐外部使用 File:/case/completeness/single_app_tracing/datatype/primitives/int_001_T.py Line 16: os.system(str(o)) @@ -4825,7 +4792,7 @@ Trace: AffectedNodeName: os.system 16: SINK: os.system(str(o)) -------------- 172: taint_flow_test------------- +------------- 173: taint_flow_test------------- Description:taint_flow_test,回归测试使用,不推荐外部使用 File:/case/completeness/single_app_tracing/datatype/primitives/none_001_T.py Line 16: os.system(str(o)) @@ -4849,7 +4816,7 @@ Trace: AffectedNodeName: os.system 16: SINK: os.system(str(o)) -------------- 173: taint_flow_test------------- +------------- 174: taint_flow_test------------- Description:taint_flow_test,回归测试使用,不推荐外部使用 File:/case/completeness/single_app_tracing/datatype/primitives/str_001_T.py Line 16: os.system(o) @@ -4873,7 +4840,7 @@ Trace: AffectedNodeName: os.system 16: SINK: os.system(o) -------------- 174: taint_flow_test------------- +------------- 175: taint_flow_test------------- Description:taint_flow_test,回归测试使用,不推荐外部使用 File:/case/completeness/single_app_tracing/datatype/primitives/type_annotation_bool_001_T.py Line 17: os.system(str(o)) @@ -4897,7 +4864,7 @@ Trace: AffectedNodeName: os.system 17: SINK: os.system(str(o)) -------------- 175: taint_flow_test------------- +------------- 176: taint_flow_test------------- Description:taint_flow_test,回归测试使用,不推荐外部使用 File:/case/completeness/single_app_tracing/datatype/primitives/type_annotation_complex_001_T.py Line 20: os.system(str(o)) @@ -4924,7 +4891,7 @@ Trace: AffectedNodeName: os.system 20: SINK: os.system(str(o)) -------------- 176: taint_flow_test------------- +------------- 177: taint_flow_test------------- Description:taint_flow_test,回归测试使用,不推荐外部使用 File:/case/completeness/single_app_tracing/datatype/primitives/type_annotation_float_001_T.py Line 17: os.system(str(o)) @@ -4948,7 +4915,7 @@ Trace: AffectedNodeName: os.system 17: SINK: os.system(str(o)) -------------- 177: taint_flow_test------------- +------------- 178: taint_flow_test------------- Description:taint_flow_test,回归测试使用,不推荐外部使用 File:/case/completeness/single_app_tracing/datatype/primitives/type_annotation_int_001_T.py Line 18: os.system(str(o)) @@ -4972,7 +4939,7 @@ Trace: AffectedNodeName: os.system 18: SINK: os.system(str(o)) -------------- 178: taint_flow_test------------- +------------- 179: taint_flow_test------------- Description:taint_flow_test,回归测试使用,不推荐外部使用 File:/case/completeness/single_app_tracing/datatype/primitives/type_annotation_none_001_T.py Line 21: os.system(o) @@ -4993,7 +4960,7 @@ Trace: AffectedNodeName: os.system 21: SINK: os.system(o) -------------- 179: taint_flow_test------------- +------------- 180: taint_flow_test------------- Description:taint_flow_test,回归测试使用,不推荐外部使用 File:/case/completeness/single_app_tracing/datatype/primitives/type_annotation_str_001_T.py Line 18: os.system(o) @@ -5017,7 +4984,7 @@ Trace: AffectedNodeName: os.system 18: SINK: os.system(o) -------------- 180: taint_flow_test------------- +------------- 181: taint_flow_test------------- Description:taint_flow_test,回归测试使用,不推荐外部使用 File:/case/completeness/single_app_tracing/datatype/tuple/tuple_001_T.py Line 18: os.system(str(o)) @@ -5041,7 +5008,7 @@ Trace: AffectedNodeName: os.system 18: SINK: os.system(str(o)) -------------- 181: taint_flow_test------------- +------------- 182: taint_flow_test------------- Description:taint_flow_test,回归测试使用,不推荐外部使用 File:/case/completeness/single_app_tracing/datatype/tuple/tuple_003_T.py Line 19: os.system(str(o)) @@ -5068,7 +5035,7 @@ Trace: AffectedNodeName: os.system 19: SINK: os.system(str(o)) -------------- 182: taint_flow_test------------- +------------- 183: taint_flow_test------------- Description:taint_flow_test,回归测试使用,不推荐外部使用 File:/case/completeness/single_app_tracing/exception_error/exception_throw/exception_try_001_T.py Line 21: os.system(o) @@ -5089,7 +5056,7 @@ Trace: AffectedNodeName: os.system 21: SINK: os.system(o) -------------- 183: taint_flow_test------------- +------------- 184: taint_flow_test------------- Description:taint_flow_test,回归测试使用,不推荐外部使用 File:/case/completeness/single_app_tracing/expression/basic_expression_operation/assign_expression_001_T.py Line 18: os.system(o) @@ -5113,7 +5080,7 @@ Trace: AffectedNodeName: os.system 18: SINK: os.system(o) -------------- 184: taint_flow_test------------- +------------- 185: taint_flow_test------------- Description:taint_flow_test,回归测试使用,不推荐外部使用 File:/case/completeness/single_app_tracing/expression/basic_expression_operation/binary_expression_add_001_T.py Line 18: os.system(o) @@ -5137,7 +5104,7 @@ Trace: AffectedNodeName: os.system 18: SINK: os.system(o) -------------- 185: taint_flow_test------------- +------------- 186: taint_flow_test------------- Description:taint_flow_test,回归测试使用,不推荐外部使用 File:/case/completeness/single_app_tracing/expression/basic_expression_operation/binary_expression_add_assignment_001_T.py Line 19: os.system(o) @@ -5161,7 +5128,7 @@ Trace: AffectedNodeName: os.system 19: SINK: os.system(o) -------------- 186: taint_flow_test------------- +------------- 187: taint_flow_test------------- Description:taint_flow_test,回归测试使用,不推荐外部使用 File:/case/completeness/single_app_tracing/expression/basic_expression_operation/binary_expression_bitwise_and_001_T.py Line 19: os.system(str(o)) @@ -5185,7 +5152,7 @@ Trace: AffectedNodeName: os.system 19: SINK: os.system(str(o)) -------------- 187: taint_flow_test------------- +------------- 188: taint_flow_test------------- Description:taint_flow_test,回归测试使用,不推荐外部使用 File:/case/completeness/single_app_tracing/expression/basic_expression_operation/binary_expression_bitwise_or_001_T.py Line 19: os.system(str(o)) @@ -5209,7 +5176,7 @@ Trace: AffectedNodeName: os.system 19: SINK: os.system(str(o)) -------------- 188: taint_flow_test------------- +------------- 189: taint_flow_test------------- Description:taint_flow_test,回归测试使用,不推荐外部使用 File:/case/completeness/single_app_tracing/expression/basic_expression_operation/binary_expression_bitwise_xor_001_T.py Line 19: os.system(str(o)) @@ -5233,7 +5200,7 @@ Trace: AffectedNodeName: os.system 19: SINK: os.system(str(o)) -------------- 189: taint_flow_test------------- +------------- 190: taint_flow_test------------- Description:taint_flow_test,回归测试使用,不推荐外部使用 File:/case/completeness/single_app_tracing/expression/basic_expression_operation/binary_expression_divide_assignment_001_T.py Line 20: os.system(str(o)) @@ -5257,7 +5224,7 @@ Trace: AffectedNodeName: os.system 20: SINK: os.system(str(o)) -------------- 190: taint_flow_test------------- +------------- 191: taint_flow_test------------- Description:taint_flow_test,回归测试使用,不推荐外部使用 File:/case/completeness/single_app_tracing/expression/basic_expression_operation/binary_expression_division_001_T.py Line 21: os.system(str(o)) @@ -5281,7 +5248,7 @@ Trace: AffectedNodeName: os.system 21: SINK: os.system(str(o)) -------------- 191: taint_flow_test------------- +------------- 192: taint_flow_test------------- Description:taint_flow_test,回归测试使用,不推荐外部使用 File:/case/completeness/single_app_tracing/expression/basic_expression_operation/binary_expression_floor_div_case_001_T.py Line 17: os.system(str(o)) @@ -5302,7 +5269,7 @@ Trace: AffectedNodeName: os.system 17: SINK: os.system(str(o)) -------------- 192: taint_flow_test------------- +------------- 193: taint_flow_test------------- Description:taint_flow_test,回归测试使用,不推荐外部使用 File:/case/completeness/single_app_tracing/expression/basic_expression_operation/binary_expression_floor_division_001_T.py Line 19: os.system(str(o)) @@ -5326,7 +5293,7 @@ Trace: AffectedNodeName: os.system 19: SINK: os.system(str(o)) -------------- 193: taint_flow_test------------- +------------- 194: taint_flow_test------------- Description:taint_flow_test,回归测试使用,不推荐外部使用 File:/case/completeness/single_app_tracing/expression/basic_expression_operation/binary_expression_left_shift_001_T.py Line 19: os.system(str(o)) @@ -5350,7 +5317,7 @@ Trace: AffectedNodeName: os.system 19: SINK: os.system(str(o)) -------------- 194: taint_flow_test------------- +------------- 195: taint_flow_test------------- Description:taint_flow_test,回归测试使用,不推荐外部使用 File:/case/completeness/single_app_tracing/expression/basic_expression_operation/binary_expression_matrix_multiplication_001_T.py Line 27: os.system(str(o)) @@ -5377,7 +5344,7 @@ Trace: AffectedNodeName: os.system 27: SINK: os.system(str(o)) -------------- 195: taint_flow_test------------- +------------- 196: taint_flow_test------------- Description:taint_flow_test,回归测试使用,不推荐外部使用 File:/case/completeness/single_app_tracing/expression/basic_expression_operation/binary_expression_mod_001_T.py Line 17: os.system(str(o)) @@ -5401,7 +5368,7 @@ Trace: AffectedNodeName: os.system 17: SINK: os.system(str(o)) -------------- 196: taint_flow_test------------- +------------- 197: taint_flow_test------------- Description:taint_flow_test,回归测试使用,不推荐外部使用 File:/case/completeness/single_app_tracing/expression/basic_expression_operation/binary_expression_modulo_assignment_001_T.py Line 19: os.system(str(o)) @@ -5425,7 +5392,7 @@ Trace: AffectedNodeName: os.system 19: SINK: os.system(str(o)) -------------- 197: taint_flow_test------------- +------------- 198: taint_flow_test------------- Description:taint_flow_test,回归测试使用,不推荐外部使用 File:/case/completeness/single_app_tracing/expression/basic_expression_operation/binary_expression_mult_001_T.py Line 20: os.system(str(o)) @@ -5449,7 +5416,7 @@ Trace: AffectedNodeName: os.system 20: SINK: os.system(str(o)) -------------- 198: taint_flow_test------------- +------------- 199: taint_flow_test------------- Description:taint_flow_test,回归测试使用,不推荐外部使用 File:/case/completeness/single_app_tracing/expression/basic_expression_operation/binary_expression_multiply_assignment_001_T.py Line 20: os.system(str(o)) @@ -5473,7 +5440,7 @@ Trace: AffectedNodeName: os.system 20: SINK: os.system(str(o)) -------------- 199: taint_flow_test------------- +------------- 200: taint_flow_test------------- Description:taint_flow_test,回归测试使用,不推荐外部使用 File:/case/completeness/single_app_tracing/expression/basic_expression_operation/binary_expression_power_assignment_001_T.py Line 19: os.system(str(o)) @@ -5497,7 +5464,7 @@ Trace: AffectedNodeName: os.system 19: SINK: os.system(str(o)) -------------- 200: taint_flow_test------------- +------------- 201: taint_flow_test------------- Description:taint_flow_test,回归测试使用,不推荐外部使用 File:/case/completeness/single_app_tracing/expression/basic_expression_operation/binary_expression_right_shift_001_T.py Line 19: os.system(str(o)) @@ -5521,7 +5488,7 @@ Trace: AffectedNodeName: os.system 19: SINK: os.system(str(o)) -------------- 201: taint_flow_test------------- +------------- 202: taint_flow_test------------- Description:taint_flow_test,回归测试使用,不推荐外部使用 File:/case/completeness/single_app_tracing/expression/basic_expression_operation/binary_expression_sub_001_T.py Line 20: os.system(str(o)) @@ -5545,7 +5512,7 @@ Trace: AffectedNodeName: os.system 20: SINK: os.system(str(o)) -------------- 202: taint_flow_test------------- +------------- 203: taint_flow_test------------- Description:taint_flow_test,回归测试使用,不推荐外部使用 File:/case/completeness/single_app_tracing/expression/basic_expression_operation/binary_expression_subtract_assignment_001_T.py Line 20: os.system(str(o)) @@ -5569,7 +5536,7 @@ Trace: AffectedNodeName: os.system 20: SINK: os.system(str(o)) -------------- 203: taint_flow_test------------- +------------- 204: taint_flow_test------------- Description:taint_flow_test,回归测试使用,不推荐外部使用 File:/case/completeness/single_app_tracing/expression/basic_expression_operation/bitwise_expression_and_001_T.py Line 18: os.system(str(o)) @@ -5593,7 +5560,7 @@ Trace: AffectedNodeName: os.system 18: SINK: os.system(str(o)) -------------- 204: taint_flow_test------------- +------------- 205: taint_flow_test------------- Description:taint_flow_test,回归测试使用,不推荐外部使用 File:/case/completeness/single_app_tracing/expression/basic_expression_operation/bitwise_expression_lsh_001_T.py Line 18: os.system(str(o)) @@ -5617,7 +5584,7 @@ Trace: AffectedNodeName: os.system 18: SINK: os.system(str(o)) -------------- 205: taint_flow_test------------- +------------- 206: taint_flow_test------------- Description:taint_flow_test,回归测试使用,不推荐外部使用 File:/case/completeness/single_app_tracing/expression/basic_expression_operation/bitwise_expression_not_001_T.py Line 18: os.system(str(o)) @@ -5632,7 +5599,7 @@ Trace: AffectedNodeName: os.system 18: SINK: os.system(str(o)) -------------- 206: taint_flow_test------------- +------------- 207: taint_flow_test------------- Description:taint_flow_test,回归测试使用,不推荐外部使用 File:/case/completeness/single_app_tracing/expression/basic_expression_operation/bitwise_expression_or_001_T.py Line 18: os.system(str(o)) @@ -5656,7 +5623,7 @@ Trace: AffectedNodeName: os.system 18: SINK: os.system(str(o)) -------------- 207: taint_flow_test------------- +------------- 208: taint_flow_test------------- Description:taint_flow_test,回归测试使用,不推荐外部使用 File:/case/completeness/single_app_tracing/expression/basic_expression_operation/bitwise_expression_rsh_001_T.py Line 18: os.system(str(o)) @@ -5680,7 +5647,7 @@ Trace: AffectedNodeName: os.system 18: SINK: os.system(str(o)) -------------- 208: taint_flow_test------------- +------------- 209: taint_flow_test------------- Description:taint_flow_test,回归测试使用,不推荐外部使用 File:/case/completeness/single_app_tracing/expression/basic_expression_operation/bitwise_expression_xor_001_T.py Line 18: os.system(str(o)) @@ -5704,7 +5671,7 @@ Trace: AffectedNodeName: os.system 18: SINK: os.system(str(o)) -------------- 209: taint_flow_test------------- +------------- 210: taint_flow_test------------- Description:taint_flow_test,回归测试使用,不推荐外部使用 File:/case/completeness/single_app_tracing/expression/basic_expression_operation/greater_than_equal_001_T.py Line 19: os.system(str(o)) @@ -5728,7 +5695,7 @@ Trace: AffectedNodeName: os.system 19: SINK: os.system(str(o)) -------------- 210: taint_flow_test------------- +------------- 211: taint_flow_test------------- Description:taint_flow_test,回归测试使用,不推荐外部使用 File:/case/completeness/single_app_tracing/expression/basic_expression_operation/less_than_equal_001_T.py Line 19: os.system(str(o)) @@ -5752,7 +5719,7 @@ Trace: AffectedNodeName: os.system 19: SINK: os.system(str(o)) -------------- 211: taint_flow_test------------- +------------- 212: taint_flow_test------------- Description:taint_flow_test,回归测试使用,不推荐外部使用 File:/case/completeness/single_app_tracing/expression/basic_expression_operation/logic_expression_and_001_F.py Line 18: os.system(str(o)) @@ -5776,7 +5743,7 @@ Trace: AffectedNodeName: os.system 18: SINK: os.system(str(o)) -------------- 212: taint_flow_test------------- +------------- 213: taint_flow_test------------- Description:taint_flow_test,回归测试使用,不推荐外部使用 File:/case/completeness/single_app_tracing/expression/basic_expression_operation/logic_expression_and_002_T.py Line 18: os.system(o) @@ -5800,7 +5767,7 @@ Trace: AffectedNodeName: os.system 18: SINK: os.system(o) -------------- 213: taint_flow_test------------- +------------- 214: taint_flow_test------------- Description:taint_flow_test,回归测试使用,不推荐外部使用 File:/case/completeness/single_app_tracing/expression/basic_expression_operation/logic_expression_or_001_T.py Line 18: os.system(o) @@ -5824,7 +5791,7 @@ Trace: AffectedNodeName: os.system 18: SINK: os.system(o) -------------- 214: taint_flow_test------------- +------------- 215: taint_flow_test------------- Description:taint_flow_test,回归测试使用,不推荐外部使用 File:/case/completeness/single_app_tracing/expression/basic_expression_operation/logic_expression_or_002_F.py Line 18: os.system(o) @@ -5848,7 +5815,7 @@ Trace: AffectedNodeName: os.system 18: SINK: os.system(o) -------------- 215: taint_flow_test------------- +------------- 216: taint_flow_test------------- Description:taint_flow_test,回归测试使用,不推荐外部使用 File:/case/completeness/single_app_tracing/expression/basic_expression_operation/relation_expression_equal_001_T.py Line 18: os.system(str(o)) @@ -5872,7 +5839,7 @@ Trace: AffectedNodeName: os.system 18: SINK: os.system(str(o)) -------------- 216: taint_flow_test------------- +------------- 217: taint_flow_test------------- Description:taint_flow_test,回归测试使用,不推荐外部使用 File:/case/completeness/single_app_tracing/expression/basic_expression_operation/relation_expression_equal_002_F.py Line 18: os.system(str(o)) @@ -5896,7 +5863,7 @@ Trace: AffectedNodeName: os.system 18: SINK: os.system(str(o)) -------------- 217: taint_flow_test------------- +------------- 218: taint_flow_test------------- Description:taint_flow_test,回归测试使用,不推荐外部使用 File:/case/completeness/single_app_tracing/expression/basic_expression_operation/relation_expression_greater_001_T.py Line 18: os.system(str(o)) @@ -5920,7 +5887,7 @@ Trace: AffectedNodeName: os.system 18: SINK: os.system(str(o)) -------------- 218: taint_flow_test------------- +------------- 219: taint_flow_test------------- Description:taint_flow_test,回归测试使用,不推荐外部使用 File:/case/completeness/single_app_tracing/expression/basic_expression_operation/relation_expression_greater_002_F.py Line 18: os.system(str(o)) @@ -5944,7 +5911,7 @@ Trace: AffectedNodeName: os.system 18: SINK: os.system(str(o)) -------------- 219: taint_flow_test------------- +------------- 220: taint_flow_test------------- Description:taint_flow_test,回归测试使用,不推荐外部使用 File:/case/completeness/single_app_tracing/expression/basic_expression_operation/relation_expression_in_001_T.py Line 20: os.system(str(o)) @@ -5968,7 +5935,7 @@ Trace: AffectedNodeName: os.system 20: SINK: os.system(str(o)) -------------- 220: taint_flow_test------------- +------------- 221: taint_flow_test------------- Description:taint_flow_test,回归测试使用,不推荐外部使用 File:/case/completeness/single_app_tracing/expression/basic_expression_operation/relation_expression_in_002_F.py Line 20: os.system(str(o)) @@ -5992,7 +5959,7 @@ Trace: AffectedNodeName: os.system 20: SINK: os.system(str(o)) -------------- 221: taint_flow_test------------- +------------- 222: taint_flow_test------------- Description:taint_flow_test,回归测试使用,不推荐外部使用 File:/case/completeness/single_app_tracing/expression/basic_expression_operation/relation_expression_is_001_T.py Line 20: os.system(str(o)) @@ -6016,7 +5983,7 @@ Trace: AffectedNodeName: os.system 20: SINK: os.system(str(o)) -------------- 222: taint_flow_test------------- +------------- 223: taint_flow_test------------- Description:taint_flow_test,回归测试使用,不推荐外部使用 File:/case/completeness/single_app_tracing/expression/basic_expression_operation/relation_expression_is_002_F.py Line 20: os.system(str(o)) @@ -6040,7 +6007,7 @@ Trace: AffectedNodeName: os.system 20: SINK: os.system(str(o)) -------------- 223: taint_flow_test------------- +------------- 224: taint_flow_test------------- Description:taint_flow_test,回归测试使用,不推荐外部使用 File:/case/completeness/single_app_tracing/expression/basic_expression_operation/relation_expression_is_not_001_T.py Line 20: os.system(str(o)) @@ -6064,7 +6031,7 @@ Trace: AffectedNodeName: os.system 20: SINK: os.system(str(o)) -------------- 224: taint_flow_test------------- +------------- 225: taint_flow_test------------- Description:taint_flow_test,回归测试使用,不推荐外部使用 File:/case/completeness/single_app_tracing/expression/basic_expression_operation/relation_expression_is_not_002_F.py Line 20: os.system(str(o)) @@ -6088,7 +6055,7 @@ Trace: AffectedNodeName: os.system 20: SINK: os.system(str(o)) -------------- 225: taint_flow_test------------- +------------- 226: taint_flow_test------------- Description:taint_flow_test,回归测试使用,不推荐外部使用 File:/case/completeness/single_app_tracing/expression/basic_expression_operation/relation_expression_less_001_T.py Line 18: os.system(str(o)) @@ -6112,7 +6079,7 @@ Trace: AffectedNodeName: os.system 18: SINK: os.system(str(o)) -------------- 226: taint_flow_test------------- +------------- 227: taint_flow_test------------- Description:taint_flow_test,回归测试使用,不推荐外部使用 File:/case/completeness/single_app_tracing/expression/basic_expression_operation/relation_expression_less_002_F.py Line 18: os.system(str(o)) @@ -6136,7 +6103,7 @@ Trace: AffectedNodeName: os.system 18: SINK: os.system(str(o)) -------------- 227: taint_flow_test------------- +------------- 228: taint_flow_test------------- Description:taint_flow_test,回归测试使用,不推荐外部使用 File:/case/completeness/single_app_tracing/expression/basic_expression_operation/relation_expression_not_equal_001_T.py Line 20: os.system(str(o)) @@ -6160,7 +6127,7 @@ Trace: AffectedNodeName: os.system 20: SINK: os.system(str(o)) -------------- 228: taint_flow_test------------- +------------- 229: taint_flow_test------------- Description:taint_flow_test,回归测试使用,不推荐外部使用 File:/case/completeness/single_app_tracing/expression/basic_expression_operation/relation_expression_not_equal_002_F.py Line 20: os.system(str(o)) @@ -6184,7 +6151,7 @@ Trace: AffectedNodeName: os.system 20: SINK: os.system(str(o)) -------------- 229: taint_flow_test------------- +------------- 230: taint_flow_test------------- Description:taint_flow_test,回归测试使用,不推荐外部使用 File:/case/completeness/single_app_tracing/expression/basic_expression_operation/relation_expression_not_in_001_T.py Line 20: os.system(str(o)) @@ -6208,7 +6175,7 @@ Trace: AffectedNodeName: os.system 20: SINK: os.system(str(o)) -------------- 230: taint_flow_test------------- +------------- 231: taint_flow_test------------- Description:taint_flow_test,回归测试使用,不推荐外部使用 File:/case/completeness/single_app_tracing/expression/basic_expression_operation/relation_expression_not_in_002_F.py Line 20: os.system(str(o)) @@ -6232,7 +6199,7 @@ Trace: AffectedNodeName: os.system 20: SINK: os.system(str(o)) -------------- 231: taint_flow_test------------- +------------- 232: taint_flow_test------------- Description:taint_flow_test,回归测试使用,不推荐外部使用 File:/case/completeness/single_app_tracing/expression/basic_expression_operation/unary_expression_not_001_T.py Line 19: os.system(str(o)) @@ -6247,7 +6214,7 @@ Trace: AffectedNodeName: os.system 19: SINK: os.system(str(o)) -------------- 232: taint_flow_test------------- +------------- 233: taint_flow_test------------- Description:taint_flow_test,回归测试使用,不推荐外部使用 File:/case/completeness/single_app_tracing/expression/basic_expression_operation/unary_expression_not_002_F.py Line 19: os.system(str(o)) @@ -6262,7 +6229,7 @@ Trace: AffectedNodeName: os.system 19: SINK: os.system(str(o)) -------------- 233: taint_flow_test------------- +------------- 234: taint_flow_test------------- Description:taint_flow_test,回归测试使用,不推荐外部使用 File:/case/completeness/single_app_tracing/expression/basic_expression_operation/unary_expression_uadd_001_T.py Line 19: os.system(str(o)) @@ -6277,7 +6244,7 @@ Trace: AffectedNodeName: os.system 19: SINK: os.system(str(o)) -------------- 234: taint_flow_test------------- +------------- 235: taint_flow_test------------- Description:taint_flow_test,回归测试使用,不推荐外部使用 File:/case/completeness/single_app_tracing/expression/basic_expression_operation/unary_expression_usub_001_T.py Line 19: os.system(str(o)) @@ -6292,7 +6259,7 @@ Trace: AffectedNodeName: os.system 19: SINK: os.system(str(o)) -------------- 235: taint_flow_test------------- +------------- 236: taint_flow_test------------- Description:taint_flow_test,回归测试使用,不推荐外部使用 File:/case/completeness/single_app_tracing/expression/conditional_expression/conditional_expression_001_T.py Line 19: os.system(o) @@ -6316,7 +6283,7 @@ Trace: AffectedNodeName: os.system 19: SINK: os.system(o) -------------- 236: taint_flow_test------------- +------------- 237: taint_flow_test------------- Description:taint_flow_test,回归测试使用,不推荐外部使用 File:/case/completeness/single_app_tracing/expression/conditional_expression/logical_and_001_T.py Line 17: os.system(o) @@ -6340,7 +6307,7 @@ Trace: AffectedNodeName: os.system 17: SINK: os.system(o) -------------- 237: taint_flow_test------------- +------------- 238: taint_flow_test------------- Description:taint_flow_test,回归测试使用,不推荐外部使用 File:/case/completeness/single_app_tracing/expression/conditional_expression/logical_and_002_F.py Line 17: os.system(o) @@ -6364,7 +6331,7 @@ Trace: AffectedNodeName: os.system 17: SINK: os.system(o) -------------- 238: taint_flow_test------------- +------------- 239: taint_flow_test------------- Description:taint_flow_test,回归测试使用,不推荐外部使用 File:/case/completeness/single_app_tracing/expression/conditional_expression/logical_or_001_T.py Line 17: os.system(o) @@ -6388,7 +6355,7 @@ Trace: AffectedNodeName: os.system 17: SINK: os.system(o) -------------- 239: taint_flow_test------------- +------------- 240: taint_flow_test------------- Description:taint_flow_test,回归测试使用,不推荐外部使用 File:/case/completeness/single_app_tracing/expression/conditional_expression/logical_or_002_F.py Line 17: os.system(o) @@ -6412,7 +6379,7 @@ Trace: AffectedNodeName: os.system 17: SINK: os.system(o) -------------- 240: taint_flow_test------------- +------------- 241: taint_flow_test------------- Description:taint_flow_test,回归测试使用,不推荐外部使用 File:/case/completeness/single_app_tracing/expression/lambda_expression/lambda_expression_001_T.py Line 26: os.system(o) @@ -6424,7 +6391,7 @@ Trace: AffectedNodeName: taint_src 12: SOURCE: def lambda_expression_001_T(taint_src): /case/completeness/single_app_tracing/expression/lambda_expression/lambda_expression_001_T.py - AffectedNodeName: + AffectedNodeName: 20: CALL: result = lambda_func(taint_src) /case/completeness/single_app_tracing/expression/lambda_expression/lambda_expression_001_T.py AffectedNodeName: a @@ -6433,7 +6400,7 @@ Trace: AffectedNodeName: [return value] 17: Return Value: lambda_func = lambda a: a /case/completeness/single_app_tracing/expression/lambda_expression/lambda_expression_001_T.py - AffectedNodeName: + AffectedNodeName: 20: CALL RETURN: result = lambda_func(taint_src) /case/completeness/single_app_tracing/expression/lambda_expression/lambda_expression_001_T.py AffectedNodeName: result @@ -6448,7 +6415,7 @@ Trace: AffectedNodeName: os.system 26: SINK: os.system(o) -------------- 241: taint_flow_test------------- +------------- 242: taint_flow_test------------- Description:taint_flow_test,回归测试使用,不推荐外部使用 File:/case/completeness/single_app_tracing/expression/special_expression/del_expression_001_T.py Line 25: os.system(o) @@ -6469,8 +6436,11 @@ Trace: AffectedNodeName: lastname 14: ARG PASS: def __init__(self, firstname, lastname): /case/completeness/single_app_tracing/expression/special_expression/del_expression_001_T.py - AffectedNodeName: [self.lastname] + AffectedNodeName: self.lastname 16: Var Pass: self.lastname = lastname + /case/completeness/single_app_tracing/expression/special_expression/del_expression_001_T.py + AffectedNodeName: Employee + 18: Var Pass: Employee = EmployeeClass(firstname='Bob', lastname=taint_src) /case/completeness/single_app_tracing/expression/special_expression/del_expression_001_T.py AffectedNodeName: taint_sink 21: CALL: taint_sink(Employee.lastname) @@ -6481,7 +6451,7 @@ Trace: AffectedNodeName: os.system 25: SINK: os.system(o) -------------- 242: taint_flow_test------------- +------------- 243: taint_flow_test------------- Description:taint_flow_test,回归测试使用,不推荐外部使用 File:/case/completeness/single_app_tracing/expression/special_expression/del_expression_002_F.py Line 23: os.system(str(o)) @@ -6508,7 +6478,7 @@ Trace: AffectedNodeName: os.system 23: SINK: os.system(str(o)) -------------- 243: taint_flow_test------------- +------------- 244: taint_flow_test------------- Description:taint_flow_test,回归测试使用,不推荐外部使用 File:/case/completeness/single_app_tracing/expression/special_expression/del_expression_003_T.py Line 19: os.system(str(o)) @@ -6532,7 +6502,7 @@ Trace: AffectedNodeName: os.system 19: SINK: os.system(str(o)) -------------- 244: taint_flow_test------------- +------------- 245: taint_flow_test------------- Description:taint_flow_test,回归测试使用,不推荐外部使用 File:/case/completeness/single_app_tracing/expression/special_expression/del_expression_004_F.py Line 19: os.system(str(o)) @@ -6556,7 +6526,7 @@ Trace: AffectedNodeName: os.system 19: SINK: os.system(str(o)) -------------- 245: taint_flow_test------------- +------------- 246: taint_flow_test------------- Description:taint_flow_test,回归测试使用,不推荐外部使用 File:/case/completeness/single_app_tracing/expression/special_expression/del_expression_005_T.py Line 20: os.system(str(o)) @@ -6580,7 +6550,7 @@ Trace: AffectedNodeName: os.system 20: SINK: os.system(str(o)) -------------- 246: taint_flow_test------------- +------------- 247: taint_flow_test------------- Description:taint_flow_test,回归测试使用,不推荐外部使用 File:/case/completeness/single_app_tracing/expression/special_expression/del_expression_006_F.py Line 20: os.system(str(o)) @@ -6604,7 +6574,7 @@ Trace: AffectedNodeName: os.system 20: SINK: os.system(str(o)) -------------- 247: taint_flow_test------------- +------------- 248: taint_flow_test------------- Description:taint_flow_test,回归测试使用,不推荐外部使用 File:/case/completeness/single_app_tracing/expression/special_expression/del_expression_007_T.py Line 20: os.system(str(o)) @@ -6628,7 +6598,7 @@ Trace: AffectedNodeName: os.system 20: SINK: os.system(str(o)) -------------- 248: taint_flow_test------------- +------------- 249: taint_flow_test------------- Description:taint_flow_test,回归测试使用,不推荐外部使用 File:/case/completeness/single_app_tracing/expression/special_expression/del_expression_008_F.py Line 20: os.system(str(o)) @@ -6652,7 +6622,7 @@ Trace: AffectedNodeName: os.system 20: SINK: os.system(str(o)) -------------- 249: taint_flow_test------------- +------------- 250: taint_flow_test------------- Description:taint_flow_test,回归测试使用,不推荐外部使用 File:/case/completeness/single_app_tracing/expression/special_expression/destructuring_assignment_001_T.py Line 19: os.system(o) @@ -6679,7 +6649,7 @@ Trace: AffectedNodeName: os.system 19: SINK: os.system(o) -------------- 250: taint_flow_test------------- +------------- 251: taint_flow_test------------- Description:taint_flow_test,回归测试使用,不推荐外部使用 File:/case/completeness/single_app_tracing/expression/special_expression/destructuring_assignment_003_T.py Line 21: os.system(o) @@ -6706,7 +6676,7 @@ Trace: AffectedNodeName: os.system 21: SINK: os.system(o) -------------- 251: taint_flow_test------------- +------------- 252: taint_flow_test------------- Description:taint_flow_test,回归测试使用,不推荐外部使用 File:/case/completeness/single_app_tracing/expression/special_expression/destructuring_assignment_004_F.py Line 21: os.system(o) @@ -6733,7 +6703,7 @@ Trace: AffectedNodeName: os.system 21: SINK: os.system(o) -------------- 252: taint_flow_test------------- +------------- 253: taint_flow_test------------- Description:taint_flow_test,回归测试使用,不推荐外部使用 File:/case/completeness/single_app_tracing/expression/special_expression/destructuring_assignment_005_T.py Line 19: os.system(o) @@ -6760,7 +6730,7 @@ Trace: AffectedNodeName: os.system 19: SINK: os.system(o) -------------- 253: taint_flow_test------------- +------------- 254: taint_flow_test------------- Description:taint_flow_test,回归测试使用,不推荐外部使用 File:/case/completeness/single_app_tracing/expression/special_expression/destructuring_assignment_006_F.py Line 19: os.system(o) @@ -6787,7 +6757,7 @@ Trace: AffectedNodeName: os.system 19: SINK: os.system(o) -------------- 254: taint_flow_test------------- +------------- 255: taint_flow_test------------- Description:taint_flow_test,回归测试使用,不推荐外部使用 File:/case/completeness/single_app_tracing/expression/special_expression/enum_001_T.py Line 27: os.system(str(o)) @@ -6814,7 +6784,7 @@ Trace: AffectedNodeName: os.system 27: SINK: os.system(str(o)) -------------- 255: taint_flow_test------------- +------------- 256: taint_flow_test------------- Description:taint_flow_test,回归测试使用,不推荐外部使用 File:/case/completeness/single_app_tracing/expression/special_expression/exponentiation_operator_001_T.py Line 17: os.system(str(o)) @@ -6838,7 +6808,7 @@ Trace: AffectedNodeName: os.system 17: SINK: os.system(str(o)) -------------- 256: taint_flow_test------------- +------------- 257: taint_flow_test------------- Description:taint_flow_test,回归测试使用,不推荐外部使用 File:/case/completeness/single_app_tracing/expression/special_expression/list_comprehension_001_T.py Line 18: os.system(o) @@ -6862,7 +6832,7 @@ Trace: AffectedNodeName: os.system 18: SINK: os.system(o) -------------- 257: taint_flow_test------------- +------------- 258: taint_flow_test------------- Description:taint_flow_test,回归测试使用,不推荐外部使用 File:/case/completeness/single_app_tracing/expression/special_expression/list_comprehension_002_F.py Line 18: os.system(o) @@ -6886,7 +6856,7 @@ Trace: AffectedNodeName: os.system 18: SINK: os.system(o) -------------- 258: taint_flow_test------------- +------------- 259: taint_flow_test------------- Description:taint_flow_test,回归测试使用,不推荐外部使用 File:/case/completeness/single_app_tracing/expression/special_expression/map_comprehension_001_T.py Line 21: os.system(o) @@ -6910,7 +6880,7 @@ Trace: AffectedNodeName: os.system 21: SINK: os.system(o) -------------- 259: taint_flow_test------------- +------------- 260: taint_flow_test------------- Description:taint_flow_test,回归测试使用,不推荐外部使用 File:/case/completeness/single_app_tracing/expression/special_expression/multi_target_assignment_001_T.py Line 22: os.system(o) @@ -6934,7 +6904,7 @@ Trace: AffectedNodeName: os.system 22: SINK: os.system(o) -------------- 260: taint_flow_test------------- +------------- 261: taint_flow_test------------- Description:taint_flow_test,回归测试使用,不推荐外部使用 File:/case/completeness/single_app_tracing/expression/special_expression/rest_parameter_001_T.py Line 20: os.system(str(o)) @@ -6961,7 +6931,7 @@ Trace: AffectedNodeName: os.system 20: SINK: os.system(str(o)) -------------- 261: taint_flow_test------------- +------------- 262: taint_flow_test------------- Description:taint_flow_test,回归测试使用,不推荐外部使用 File:/case/completeness/single_app_tracing/expression/special_expression/spread_operator_001_T.py Line 19: os.system(str(o)) @@ -6988,7 +6958,7 @@ Trace: AffectedNodeName: os.system 19: SINK: os.system(str(o)) -------------- 262: taint_flow_test------------- +------------- 263: taint_flow_test------------- Description:taint_flow_test,回归测试使用,不推荐外部使用 File:/case/completeness/single_app_tracing/expression/special_expression/spread_operator_003_T.py Line 26: os.system(str(o)) @@ -7022,7 +6992,7 @@ Trace: AffectedNodeName: os.system 26: SINK: os.system(str(o)) -------------- 263: taint_flow_test------------- +------------- 264: taint_flow_test------------- Description:taint_flow_test,回归测试使用,不推荐外部使用 File:/case/completeness/single_app_tracing/expression/special_expression/spread_operator_005_T.py Line 21: os.system(str(o)) @@ -7049,7 +7019,7 @@ Trace: AffectedNodeName: os.system 21: SINK: os.system(str(o)) -------------- 264: taint_flow_test------------- +------------- 265: taint_flow_test------------- Description:taint_flow_test,回归测试使用,不推荐外部使用 File:/case/completeness/single_app_tracing/expression/special_expression/spread_operator_007_T.py Line 21: os.system(str(o)) @@ -7076,7 +7046,7 @@ Trace: AffectedNodeName: os.system 21: SINK: os.system(str(o)) -------------- 265: taint_flow_test------------- +------------- 266: taint_flow_test------------- Description:taint_flow_test,回归测试使用,不推荐外部使用 File:/case/completeness/single_app_tracing/expression/special_expression/template_literal_001_T.py Line 18: os.system(o) @@ -7100,7 +7070,7 @@ Trace: AffectedNodeName: os.system 18: SINK: os.system(o) -------------- 266: taint_flow_test------------- +------------- 267: taint_flow_test------------- Description:taint_flow_test,回归测试使用,不推荐外部使用 File:/case/completeness/single_app_tracing/expression/special_expression/template_literal_003_T.py Line 18: os.system(o) @@ -7124,7 +7094,7 @@ Trace: AffectedNodeName: os.system 18: SINK: os.system(o) -------------- 267: taint_flow_test------------- +------------- 268: taint_flow_test------------- Description:taint_flow_test,回归测试使用,不推荐外部使用 File:/case/completeness/single_app_tracing/expression/special_expression/template_literal_005_T.py Line 18: os.system(o) @@ -7148,7 +7118,7 @@ Trace: AffectedNodeName: os.system 18: SINK: os.system(o) -------------- 268: taint_flow_test------------- +------------- 269: taint_flow_test------------- Description:taint_flow_test,回归测试使用,不推荐外部使用 File:/case/completeness/single_app_tracing/expression/type_cast/bool_conversion_001_T.py Line 18: os.system(str(o)) @@ -7172,7 +7142,7 @@ Trace: AffectedNodeName: os.system 18: SINK: os.system(str(o)) -------------- 269: taint_flow_test------------- +------------- 270: taint_flow_test------------- Description:taint_flow_test,回归测试使用,不推荐外部使用 File:/case/completeness/single_app_tracing/expression/type_cast/float_truncate_001_T.py Line 18: os.system(str(o)) @@ -7196,7 +7166,7 @@ Trace: AffectedNodeName: os.system 18: SINK: os.system(str(o)) -------------- 270: taint_flow_test------------- +------------- 271: taint_flow_test------------- Description:taint_flow_test,回归测试使用,不推荐外部使用 File:/case/completeness/single_app_tracing/expression/type_cast/int_truncate_001_T.py Line 17: os.system(str(o)) @@ -7220,7 +7190,7 @@ Trace: AffectedNodeName: os.system 17: SINK: os.system(str(o)) -------------- 271: taint_flow_test------------- +------------- 272: taint_flow_test------------- Description:taint_flow_test,回归测试使用,不推荐外部使用 File:/case/completeness/single_app_tracing/expression/type_cast/str_conversion_001_T.py Line 16: os.system(o) @@ -7244,7 +7214,7 @@ Trace: AffectedNodeName: os.system 16: SINK: os.system(o) -------------- 272: taint_flow_test------------- +------------- 273: taint_flow_test------------- Description:taint_flow_test,回归测试使用,不推荐外部使用 File:/case/completeness/single_app_tracing/expression/type_cast/type_cast_001_T.py Line 18: os.system(str(o)) @@ -7268,7 +7238,7 @@ Trace: AffectedNodeName: os.system 18: SINK: os.system(str(o)) -------------- 273: taint_flow_test------------- +------------- 274: taint_flow_test------------- Description:taint_flow_test,回归测试使用,不推荐外部使用 File:/case/completeness/single_app_tracing/expression/type_cast/type_cast_002_F.py Line 18: os.system(str(o)) @@ -7292,7 +7262,7 @@ Trace: AffectedNodeName: os.system 18: SINK: os.system(str(o)) -------------- 274: taint_flow_test------------- +------------- 275: taint_flow_test------------- Description:taint_flow_test,回归测试使用,不推荐外部使用 File:/case/completeness/single_app_tracing/function_call/anonymous_function_closure/anonymous_function_002_T.py Line 17: os.system(o) @@ -7304,7 +7274,7 @@ Trace: AffectedNodeName: taint_src 12: SOURCE: def anonymous_function_002_T(taint_src): /case/completeness/single_app_tracing/function_call/anonymous_function_closure/anonymous_function_002_T.py - AffectedNodeName: + AffectedNodeName: 14: CALL: process(taint_src) /case/completeness/single_app_tracing/function_call/anonymous_function_closure/anonymous_function_002_T.py AffectedNodeName: input @@ -7319,7 +7289,7 @@ Trace: AffectedNodeName: os.system 17: SINK: os.system(o) -------------- 275: taint_flow_test------------- +------------- 276: taint_flow_test------------- Description:taint_flow_test,回归测试使用,不推荐外部使用 File:/case/completeness/single_app_tracing/function_call/anonymous_function_closure/anonymous_function_004_T.py Line 17: os.system(o) @@ -7340,7 +7310,7 @@ Trace: AffectedNodeName: os.system 17: SINK: os.system(o) -------------- 276: taint_flow_test------------- +------------- 277: taint_flow_test------------- Description:taint_flow_test,回归测试使用,不推荐外部使用 File:/case/completeness/single_app_tracing/function_call/anonymous_function_closure/anonymous_function_006_T.py Line 18: os.system(o) @@ -7361,7 +7331,7 @@ Trace: AffectedNodeName: os.system 18: SINK: os.system(o) -------------- 277: taint_flow_test------------- +------------- 278: taint_flow_test------------- Description:taint_flow_test,回归测试使用,不推荐外部使用 File:/case/completeness/single_app_tracing/function_call/anonymous_function_closure/anonymous_function_008_T.py Line 20: os.system(o) @@ -7373,7 +7343,7 @@ Trace: AffectedNodeName: taint_src 12: SOURCE: def anonymous_function_008_T(taint_src): /case/completeness/single_app_tracing/function_call/anonymous_function_closure/anonymous_function_008_T.py - AffectedNodeName: + AffectedNodeName: 17: CALL: make_adder(taint_src)("abc") /case/completeness/single_app_tracing/function_call/anonymous_function_closure/anonymous_function_008_T.py AffectedNodeName: n @@ -7388,7 +7358,37 @@ Trace: AffectedNodeName: os.system 20: SINK: os.system(o) -------------- 278: taint_flow_test------------- +------------- 279: taint_flow_test------------- +Description:taint_flow_test,回归测试使用,不推荐外部使用 +File:/case/completeness/single_app_tracing/function_call/argument_passing/argument_passing_keyword_taint_001_T.py +Line 19: os.system(o) +SINK RULE:os.system +entrypoint: +{"filePath":"/case/completeness/single_app_tracing/function_call/argument_passing/argument_passing_keyword_taint_001_T.py","functionName":"argument_passing_keyword_taint_001_T","attribute":"fullCallGraphMade","type":"functionCall","funcReceiverType":""} +Trace: + /case/completeness/single_app_tracing/function_call/argument_passing/argument_passing_keyword_taint_001_T.py + AffectedNodeName: taint_src + 12: SOURCE: def argument_passing_keyword_taint_001_T(taint_src): + /case/completeness/single_app_tracing/function_call/argument_passing/argument_passing_keyword_taint_001_T.py + AffectedNodeName: data + 16: Var Pass: process(data=taint_src) # 显式传递污点 + /case/completeness/single_app_tracing/function_call/argument_passing/argument_passing_keyword_taint_001_T.py + AffectedNodeName: process + 16: CALL: process(data=taint_src) # 显式传递污点 + /case/completeness/single_app_tracing/function_call/argument_passing/argument_passing_keyword_taint_001_T.py + AffectedNodeName: kwargs + 13: ARG PASS: def process(**kwargs): + /case/completeness/single_app_tracing/function_call/argument_passing/argument_passing_keyword_taint_001_T.py + AffectedNodeName: taint_sink + 14: CALL: taint_sink(kwargs['data']) # 关键字参数捕获污点 + /case/completeness/single_app_tracing/function_call/argument_passing/argument_passing_keyword_taint_001_T.py + AffectedNodeName: o + 18: ARG PASS: def taint_sink(o): + /case/completeness/single_app_tracing/function_call/argument_passing/argument_passing_keyword_taint_001_T.py + AffectedNodeName: os.system + 19: SINK: os.system(o) + +------------- 280: taint_flow_test------------- Description:taint_flow_test,回归测试使用,不推荐外部使用 File:/case/completeness/single_app_tracing/function_call/argument_passing/argument_passing_normal_value_002_T.py Line 23: os.system(o) @@ -7421,7 +7421,7 @@ Trace: AffectedNodeName: os.system 23: SINK: os.system(o) -------------- 279: taint_flow_test------------- +------------- 281: taint_flow_test------------- Description:taint_flow_test,回归测试使用,不推荐外部使用 File:/case/completeness/single_app_tracing/function_call/argument_passing/argument_passing_normal_value_003_T.py Line 20: os.system(o) @@ -7448,7 +7448,7 @@ Trace: AffectedNodeName: os.system 20: SINK: os.system(o) -------------- 280: taint_flow_test------------- +------------- 282: taint_flow_test------------- Description:taint_flow_test,回归测试使用,不推荐外部使用 File:/case/completeness/single_app_tracing/function_call/argument_passing/argument_passing_reference_002_T.py Line 23: os.system(o) @@ -7462,12 +7462,6 @@ Trace: /case/completeness/single_app_tracing/function_call/argument_passing/argument_passing_reference_002_T.py AffectedNodeName: process 14: CALL: process(obj, taint_src) # 将__taint_src作为参数传递给process函数 - /case/completeness/single_app_tracing/function_call/argument_passing/argument_passing_reference_002_T.py - AffectedNodeName: taint_src - 18: ARG PASS: def process(obj, taint_src): # 增加参数__taint_src - /case/completeness/single_app_tracing/function_call/argument_passing/argument_passing_reference_002_T.py - AffectedNodeName: [obj.data] - 19: Var Pass: obj['data'] = taint_src /case/completeness/single_app_tracing/function_call/argument_passing/argument_passing_reference_002_T.py AffectedNodeName: taint_sink 15: CALL: taint_sink(obj['data']) @@ -7478,7 +7472,7 @@ Trace: AffectedNodeName: os.system 23: SINK: os.system(o) -------------- 281: taint_flow_test------------- +------------- 283: taint_flow_test------------- Description:taint_flow_test,回归测试使用,不推荐外部使用 File:/case/completeness/single_app_tracing/function_call/argument_passing/argument_passing_reference_004_T.py Line 22: os.system(str(o)) @@ -7490,7 +7484,7 @@ Trace: AffectedNodeName: taint_src 12: SOURCE: def argument_passing_reference_004_T(taint_src): /case/completeness/single_app_tracing/function_call/argument_passing/argument_passing_reference_004_T.py - AffectedNodeName: [input_arr.0] + AffectedNodeName: input_arr.0 14: Var Pass: input_arr[0] = taint_src /case/completeness/single_app_tracing/function_call/argument_passing/argument_passing_reference_004_T.py AffectedNodeName: taint_sink @@ -7502,7 +7496,7 @@ Trace: AffectedNodeName: os.system 22: SINK: os.system(str(o)) -------------- 282: taint_flow_test------------- +------------- 284: taint_flow_test------------- Description:taint_flow_test,回归测试使用,不推荐外部使用 File:/case/completeness/single_app_tracing/function_call/argument_passing/argument_passing_reference_006_T.py Line 27: os.system(o) @@ -7519,15 +7513,6 @@ Trace: /case/completeness/single_app_tracing/function_call/argument_passing/argument_passing_reference_006_T.py AffectedNodeName: swap 16: CALL: swap(objA, objB) - /case/completeness/single_app_tracing/function_call/argument_passing/argument_passing_reference_006_T.py - AffectedNodeName: obj1 - 20: ARG PASS: def swap(obj1, obj2): - /case/completeness/single_app_tracing/function_call/argument_passing/argument_passing_reference_006_T.py - AffectedNodeName: temp - 21: Var Pass: temp = obj1['name'] - /case/completeness/single_app_tracing/function_call/argument_passing/argument_passing_reference_006_T.py - AffectedNodeName: [obj2.name] - 23: Var Pass: obj2['name'] = temp /case/completeness/single_app_tracing/function_call/argument_passing/argument_passing_reference_006_T.py AffectedNodeName: taint_sink 17: CALL: taint_sink(objB['name']) @@ -7538,7 +7523,7 @@ Trace: AffectedNodeName: os.system 27: SINK: os.system(o) -------------- 283: taint_flow_test------------- +------------- 285: taint_flow_test------------- Description:taint_flow_test,回归测试使用,不推荐外部使用 File:/case/completeness/single_app_tracing/function_call/argument_passing/argument_passing_various_types_001_T.py Line 22: os.system(o) @@ -7565,7 +7550,7 @@ Trace: AffectedNodeName: os.system 22: SINK: os.system(o) -------------- 284: taint_flow_test------------- +------------- 286: taint_flow_test------------- Description:taint_flow_test,回归测试使用,不推荐外部使用 File:/case/completeness/single_app_tracing/function_call/argument_passing/argument_passing_various_types_003_T.py Line 22: os.system(o) @@ -7595,61 +7580,64 @@ Trace: AffectedNodeName: os.system 22: SINK: os.system(o) -------------- 285: taint_flow_test------------- +------------- 287: taint_flow_test------------- Description:taint_flow_test,回归测试使用,不推荐外部使用 -File:/case/completeness/single_app_tracing/function_call/argument_passing/argument_passing_various_types_007_T.py +File:/case/completeness/single_app_tracing/function_call/argument_passing/argument_passing_various_types_005_T.py Line 22: os.system(o) SINK RULE:os.system entrypoint: -{"filePath":"/case/completeness/single_app_tracing/function_call/argument_passing/argument_passing_various_types_007_T.py","functionName":"argument_passing_various_types_007_T","attribute":"fullCallGraphMade","type":"functionCall","funcReceiverType":""} +{"filePath":"/case/completeness/single_app_tracing/function_call/argument_passing/argument_passing_various_types_005_T.py","functionName":"argument_passing_various_types_005_T","attribute":"fullCallGraphMade","type":"functionCall","funcReceiverType":""} Trace: - /case/completeness/single_app_tracing/function_call/argument_passing/argument_passing_various_types_007_T.py + /case/completeness/single_app_tracing/function_call/argument_passing/argument_passing_various_types_005_T.py AffectedNodeName: taint_src - 13: SOURCE: def argument_passing_various_types_007_T(taint_src): - /case/completeness/single_app_tracing/function_call/argument_passing/argument_passing_various_types_007_T.py + 13: SOURCE: def argument_passing_various_types_005_T(taint_src): + /case/completeness/single_app_tracing/function_call/argument_passing/argument_passing_various_types_005_T.py + AffectedNodeName: data + 18: Var Pass: process(1, taint_src, 4, c="critical", data=taint_src) + /case/completeness/single_app_tracing/function_call/argument_passing/argument_passing_various_types_005_T.py AffectedNodeName: process - 18: CALL: process(1, taint_src, c="critical", data=taint_src, *(taint_src,"nono")) - /case/completeness/single_app_tracing/function_call/argument_passing/argument_passing_various_types_007_T.py - AffectedNodeName: args + 18: CALL: process(1, taint_src, 4, c="critical", data=taint_src) + /case/completeness/single_app_tracing/function_call/argument_passing/argument_passing_various_types_005_T.py + AffectedNodeName: kwargs 14: ARG PASS: def process(a, b=2, *args, **kwargs): - /case/completeness/single_app_tracing/function_call/argument_passing/argument_passing_various_types_007_T.py + /case/completeness/single_app_tracing/function_call/argument_passing/argument_passing_various_types_005_T.py AffectedNodeName: taint_sink - 15: CALL: taint_sink(args[0]) - /case/completeness/single_app_tracing/function_call/argument_passing/argument_passing_various_types_007_T.py + 15: CALL: taint_sink(kwargs['data']) + /case/completeness/single_app_tracing/function_call/argument_passing/argument_passing_various_types_005_T.py AffectedNodeName: o 21: ARG PASS: def taint_sink(o): - /case/completeness/single_app_tracing/function_call/argument_passing/argument_passing_various_types_007_T.py + /case/completeness/single_app_tracing/function_call/argument_passing/argument_passing_various_types_005_T.py AffectedNodeName: os.system 22: SINK: os.system(o) -------------- 286: taint_flow_test------------- +------------- 288: taint_flow_test------------- Description:taint_flow_test,回归测试使用,不推荐外部使用 -File:/case/completeness/single_app_tracing/function_call/argument_passing/argument_passing_various_types_008_F.py +File:/case/completeness/single_app_tracing/function_call/argument_passing/argument_passing_various_types_007_T.py Line 22: os.system(o) SINK RULE:os.system entrypoint: -{"filePath":"/case/completeness/single_app_tracing/function_call/argument_passing/argument_passing_various_types_008_F.py","functionName":"argument_passing_various_types_008_F","attribute":"fullCallGraphMade","type":"functionCall","funcReceiverType":""} +{"filePath":"/case/completeness/single_app_tracing/function_call/argument_passing/argument_passing_various_types_007_T.py","functionName":"argument_passing_various_types_007_T","attribute":"fullCallGraphMade","type":"functionCall","funcReceiverType":""} Trace: - /case/completeness/single_app_tracing/function_call/argument_passing/argument_passing_various_types_008_F.py + /case/completeness/single_app_tracing/function_call/argument_passing/argument_passing_various_types_007_T.py AffectedNodeName: taint_src - 13: SOURCE: def argument_passing_various_types_008_F(taint_src): - /case/completeness/single_app_tracing/function_call/argument_passing/argument_passing_various_types_008_F.py + 13: SOURCE: def argument_passing_various_types_007_T(taint_src): + /case/completeness/single_app_tracing/function_call/argument_passing/argument_passing_various_types_007_T.py AffectedNodeName: process - 18: CALL: process(1, taint_src, c="critical", data=taint_src, *(taint_src,"nono")) - /case/completeness/single_app_tracing/function_call/argument_passing/argument_passing_various_types_008_F.py + 18: CALL: process(1, taint_src, c="critical", data=taint_src, *(taint_src,"nono")) + /case/completeness/single_app_tracing/function_call/argument_passing/argument_passing_various_types_007_T.py AffectedNodeName: args 14: ARG PASS: def process(a, b=2, *args, **kwargs): - /case/completeness/single_app_tracing/function_call/argument_passing/argument_passing_various_types_008_F.py + /case/completeness/single_app_tracing/function_call/argument_passing/argument_passing_various_types_007_T.py AffectedNodeName: taint_sink - 15: CALL: taint_sink(args[1]) - /case/completeness/single_app_tracing/function_call/argument_passing/argument_passing_various_types_008_F.py + 15: CALL: taint_sink(args[0]) + /case/completeness/single_app_tracing/function_call/argument_passing/argument_passing_various_types_007_T.py AffectedNodeName: o 21: ARG PASS: def taint_sink(o): - /case/completeness/single_app_tracing/function_call/argument_passing/argument_passing_various_types_008_F.py + /case/completeness/single_app_tracing/function_call/argument_passing/argument_passing_various_types_007_T.py AffectedNodeName: os.system 22: SINK: os.system(o) -------------- 287: taint_flow_test------------- +------------- 289: taint_flow_test------------- Description:taint_flow_test,回归测试使用,不推荐外部使用 File:/case/completeness/single_app_tracing/function_call/chained_call/chained_call_002_T.py Line 17: os.system(o) @@ -7663,16 +7651,14 @@ Trace: /case/completeness/single_app_tracing/function_call/chained_call/chained_call_002_T.py AffectedNodeName: set_name 13: CALL: A(taint_sink).set_name("_").clear_name().set_name(taint_src).process() - /case/completeness/single_app_tracing/function_call/chained_call/chained_call_002_T.py - AffectedNodeName: name - 25: ARG PASS: def set_name(self, name): - /case/completeness/single_app_tracing/function_call/chained_call/chained_call_002_T.py - AffectedNodeName: [self.name] - 26: Var Pass: self.name = name /case/completeness/single_app_tracing/function_call/chained_call/chained_call_002_T.py AffectedNodeName: set_name 13: CALL RETURN: A(taint_sink).set_name("_").clear_name().set_name(taint_src).process() /case/completeness/single_app_tracing/function_call/chained_call/chained_call_002_T.py + AffectedNodeName: process + 13: CALL: A(taint_sink).set_name("_").clear_name().set_name(taint_src).process() + /case/completeness/single_app_tracing/function_call/chained_call/chained_call_002_T.py + AffectedNodeName: A(taint_sink).set_name(_).clear_name().set_name(ta 13: ARG PASS: A(taint_sink).set_name("_").clear_name().set_name(taint_src).process() /case/completeness/single_app_tracing/function_call/chained_call/chained_call_002_T.py AffectedNodeName: taint_sink @@ -7684,7 +7670,7 @@ Trace: AffectedNodeName: os.system 17: SINK: os.system(o) -------------- 288: taint_flow_test------------- +------------- 290: taint_flow_test------------- Description:taint_flow_test,回归测试使用,不推荐外部使用 File:/case/completeness/single_app_tracing/function_call/chained_call/chained_call_003_T.py Line 32: os.system(o) @@ -7705,7 +7691,28 @@ Trace: AffectedNodeName: os.system 32: SINK: os.system(o) -------------- 289: taint_flow_test------------- +------------- 291: taint_flow_test------------- +Description:taint_flow_test,回归测试使用,不推荐外部使用 +File:/case/completeness/single_app_tracing/function_call/chained_call/chained_call_003_T.py +Line 32: os.system(o) +SINK RULE:os.system +entrypoint: +{"filePath":"/case/completeness/single_app_tracing/function_call/chained_call/chained_call_003_T.py","functionName":"process","attribute":"fullCallGraphMade","type":"functionCall","funcReceiverType":""} +Trace: + /case/completeness/single_app_tracing/function_call/chained_call/chained_call_003_T.py + AffectedNodeName: taint_src + 25: SOURCE: taint_sink(taint_src) + /case/completeness/single_app_tracing/function_call/chained_call/chained_call_003_T.py + AffectedNodeName: taint_sink + 25: CALL: taint_sink(taint_src) + /case/completeness/single_app_tracing/function_call/chained_call/chained_call_003_T.py + AffectedNodeName: o + 31: ARG PASS: def taint_sink(o): + /case/completeness/single_app_tracing/function_call/chained_call/chained_call_003_T.py + AffectedNodeName: os.system + 32: SINK: os.system(o) + +------------- 292: taint_flow_test------------- Description:taint_flow_test,回归测试使用,不推荐外部使用 File:/case/completeness/single_app_tracing/function_call/decorator_function/abstractmethod_decorator_001_T.py Line 34: os.system(o) @@ -7729,7 +7736,31 @@ Trace: AffectedNodeName: os.system 34: SINK: os.system(o) -------------- 290: taint_flow_test------------- +------------- 293: taint_flow_test------------- +Description:taint_flow_test,回归测试使用,不推荐外部使用 +File:/case/completeness/single_app_tracing/function_call/decorator_function/classmethod_decorator_001_T.py +Line 28: os.system(o) +SINK RULE:os.system +entrypoint: +{"filePath":"/case/completeness/single_app_tracing/function_call/decorator_function/classmethod_decorator_001_T.py","functionName":"classmethod_decorator_001_T","attribute":"fullCallGraphMade","type":"functionCall","funcReceiverType":""} +Trace: + /case/completeness/single_app_tracing/function_call/decorator_function/classmethod_decorator_001_T.py + AffectedNodeName: taint_src + 20: SOURCE: def classmethod_decorator_001_T(taint_src): + /case/completeness/single_app_tracing/function_call/decorator_function/classmethod_decorator_001_T.py + AffectedNodeName: result + 23: Var Pass: result = Validator.validate(taint_src) + /case/completeness/single_app_tracing/function_call/decorator_function/classmethod_decorator_001_T.py + AffectedNodeName: taint_sink + 24: CALL: taint_sink(result) + /case/completeness/single_app_tracing/function_call/decorator_function/classmethod_decorator_001_T.py + AffectedNodeName: o + 27: ARG PASS: def taint_sink(o): + /case/completeness/single_app_tracing/function_call/decorator_function/classmethod_decorator_001_T.py + AffectedNodeName: os.system + 28: SINK: os.system(o) + +------------- 294: taint_flow_test------------- Description:taint_flow_test,回归测试使用,不推荐外部使用 File:/case/completeness/single_app_tracing/function_call/decorator_function/dataclass_decorator_001_T.py Line 28: os.system(o) @@ -7741,7 +7772,7 @@ Trace: AffectedNodeName: taint_src 20: SOURCE: def dataclass_decorator_001_T(taint_src): /case/completeness/single_app_tracing/function_call/decorator_function/dataclass_decorator_001_T.py - AffectedNodeName: name + AffectedNodeName: product 22: Var Pass: product = Product(name=taint_src, price=9.99) /case/completeness/single_app_tracing/function_call/decorator_function/dataclass_decorator_001_T.py AffectedNodeName: taint_sink @@ -7753,7 +7784,7 @@ Trace: AffectedNodeName: os.system 28: SINK: os.system(o) -------------- 291: taint_flow_test------------- +------------- 295: taint_flow_test------------- Description:taint_flow_test,回归测试使用,不推荐外部使用 File:/case/completeness/single_app_tracing/function_call/decorator_function/dataclass_decorator_002_F.py Line 28: os.system(str(o)) @@ -7765,7 +7796,7 @@ Trace: AffectedNodeName: taint_src 20: SOURCE: def dataclass_decorator_002_F(taint_src): /case/completeness/single_app_tracing/function_call/decorator_function/dataclass_decorator_002_F.py - AffectedNodeName: name + AffectedNodeName: product 22: Var Pass: product = Product(name=taint_src, price=9.99) /case/completeness/single_app_tracing/function_call/decorator_function/dataclass_decorator_002_F.py AffectedNodeName: taint_sink @@ -7777,7 +7808,7 @@ Trace: AffectedNodeName: os.system 28: SINK: os.system(str(o)) -------------- 292: taint_flow_test------------- +------------- 296: taint_flow_test------------- Description:taint_flow_test,回归测试使用,不推荐外部使用 File:/case/completeness/single_app_tracing/function_call/decorator_function/property_decorator_001_T.py Line 47: os.system(o) @@ -7789,7 +7820,7 @@ Trace: AffectedNodeName: taint_src 34: SOURCE: def property_decorator_001_T(taint_src): /case/completeness/single_app_tracing/function_call/decorator_function/property_decorator_001_T.py - AffectedNodeName: [obj.value] + AffectedNodeName: obj.value 40: Var Pass: obj.value = taint_src /case/completeness/single_app_tracing/function_call/decorator_function/property_decorator_001_T.py AffectedNodeName: taint_sink @@ -7801,7 +7832,7 @@ Trace: AffectedNodeName: os.system 47: SINK: os.system(o) -------------- 293: taint_flow_test------------- +------------- 297: taint_flow_test------------- Description:taint_flow_test,回归测试使用,不推荐外部使用 File:/case/completeness/single_app_tracing/function_call/decorator_function/staticmethod_decorator_001_T.py Line 26: os.system(o) @@ -7812,13 +7843,6 @@ Trace: /case/completeness/single_app_tracing/function_call/decorator_function/staticmethod_decorator_001_T.py AffectedNodeName: taint_src 19: SOURCE: def staticmethod_decorator_001_T(taint_src): - /case/completeness/single_app_tracing/function_call/decorator_function/staticmethod_decorator_001_T.py - AffectedNodeName: [return value] - 16: Return Value: return data - /case/completeness/single_app_tracing/function_call/decorator_function/staticmethod_decorator_001_T.py - AffectedNodeName: process - 15: CALL RETURN: def process(data): - 16: CALL RETURN: return data /case/completeness/single_app_tracing/function_call/decorator_function/staticmethod_decorator_001_T.py AffectedNodeName: result 21: Var Pass: result = Processor.process(taint_src) @@ -7832,7 +7856,7 @@ Trace: AffectedNodeName: os.system 26: SINK: os.system(o) -------------- 294: taint_flow_test------------- +------------- 298: taint_flow_test------------- Description:taint_flow_test,回归测试使用,不推荐外部使用 File:/case/completeness/single_app_tracing/function_call/generator_function/generator_function_002_T.py Line 25: os.system(o) @@ -7871,7 +7895,7 @@ Trace: AffectedNodeName: os.system 25: SINK: os.system(o) -------------- 295: taint_flow_test------------- +------------- 299: taint_flow_test------------- Description:taint_flow_test,回归测试使用,不推荐外部使用 File:/case/completeness/single_app_tracing/function_call/generator_function/generator_function_004_T.py Line 30: os.system(o) @@ -7913,7 +7937,7 @@ Trace: AffectedNodeName: os.system 30: SINK: os.system(o) -------------- 296: taint_flow_test------------- +------------- 300: taint_flow_test------------- Description:taint_flow_test,回归测试使用,不推荐外部使用 File:/case/completeness/single_app_tracing/function_call/generator_function/generator_function_005_T.py Line 27: os.system(o) @@ -7970,7 +7994,7 @@ Trace: AffectedNodeName: os.system 27: SINK: os.system(o) -------------- 297: taint_flow_test------------- +------------- 301: taint_flow_test------------- Description:taint_flow_test,回归测试使用,不推荐外部使用 File:/case/completeness/single_app_tracing/function_call/generator_function/generator_function_007_T.py Line 17: os.system(o) @@ -7994,7 +8018,7 @@ Trace: AffectedNodeName: os.system 17: SINK: os.system(o) -------------- 298: taint_flow_test------------- +------------- 302: taint_flow_test------------- Description:taint_flow_test,回归测试使用,不推荐外部使用 File:/case/completeness/single_app_tracing/function_call/generator_function/yieldFrom_001_T.py Line 19: os.system(o) @@ -8024,7 +8048,7 @@ Trace: AffectedNodeName: os.system 19: SINK: os.system(o) -------------- 299: taint_flow_test------------- +------------- 303: taint_flow_test------------- Description:taint_flow_test,回归测试使用,不推荐外部使用 File:/case/completeness/single_app_tracing/function_call/generator_function/yieldFrom_003_T.py Line 19: os.system(o) @@ -8054,7 +8078,7 @@ Trace: AffectedNodeName: os.system 19: SINK: os.system(o) -------------- 300: taint_flow_test------------- +------------- 304: taint_flow_test------------- Description:taint_flow_test,回归测试使用,不推荐外部使用 File:/case/completeness/single_app_tracing/function_call/higher_order_function/higher_order_function_002_T.py Line 25: os.system(o) @@ -8077,6 +8101,9 @@ Trace: /case/completeness/single_app_tracing/function_call/higher_order_function/higher_order_function_002_T.py AffectedNodeName: inner 21: CALL RETURN: taint_sink(f(taint_src, '_')()) + /case/completeness/single_app_tracing/function_call/higher_order_function/higher_order_function_002_T.py + AffectedNodeName: taint_sink + 21: CALL: taint_sink(f(taint_src, '_')()) /case/completeness/single_app_tracing/function_call/higher_order_function/higher_order_function_002_T.py AffectedNodeName: o 24: ARG PASS: def taint_sink(o): @@ -8084,7 +8111,7 @@ Trace: AffectedNodeName: os.system 25: SINK: os.system(o) -------------- 301: taint_flow_test------------- +------------- 305: taint_flow_test------------- Description:taint_flow_test,回归测试使用,不推荐外部使用 File:/case/completeness/single_app_tracing/function_call/higher_order_function/higher_order_function_004_T.py Line 24: os.system(o) @@ -8111,8 +8138,11 @@ Trace: AffectedNodeName: [return value] 18: Return Value: return lambda: a + b + c /case/completeness/single_app_tracing/function_call/higher_order_function/higher_order_function_004_T.py - AffectedNodeName: + AffectedNodeName: 20: CALL RETURN: taint_sink(f(g, taint_src, '_')()) + /case/completeness/single_app_tracing/function_call/higher_order_function/higher_order_function_004_T.py + AffectedNodeName: taint_sink + 20: CALL: taint_sink(f(g, taint_src, '_')()) /case/completeness/single_app_tracing/function_call/higher_order_function/higher_order_function_004_T.py AffectedNodeName: o 23: ARG PASS: def taint_sink(o): @@ -8120,7 +8150,7 @@ Trace: AffectedNodeName: os.system 24: SINK: os.system(o) -------------- 302: taint_flow_test------------- +------------- 306: taint_flow_test------------- Description:taint_flow_test,回归测试使用,不推荐外部使用 File:/case/completeness/single_app_tracing/function_call/higher_order_function/higher_order_function_006_T.py Line 30: os.system(o) @@ -8155,6 +8185,9 @@ Trace: /case/completeness/single_app_tracing/function_call/higher_order_function/higher_order_function_006_T.py AffectedNodeName: inner 26: CALL RETURN: taint_sink(f(g, u, taint_src, '_')()) + /case/completeness/single_app_tracing/function_call/higher_order_function/higher_order_function_006_T.py + AffectedNodeName: taint_sink + 26: CALL: taint_sink(f(g, u, taint_src, '_')()) /case/completeness/single_app_tracing/function_call/higher_order_function/higher_order_function_006_T.py AffectedNodeName: o 29: ARG PASS: def taint_sink(o): @@ -8162,7 +8195,7 @@ Trace: AffectedNodeName: os.system 30: SINK: os.system(o) -------------- 303: taint_flow_test------------- +------------- 307: taint_flow_test------------- Description:taint_flow_test,回归测试使用,不推荐外部使用 File:/case/completeness/single_app_tracing/function_call/higher_order_function/higher_order_function_008_T.py Line 21: os.system(o) @@ -8174,7 +8207,7 @@ Trace: AffectedNodeName: taint_src 12: SOURCE: def higher_order_function_008_T(taint_src): /case/completeness/single_app_tracing/function_call/higher_order_function/higher_order_function_008_T.py - AffectedNodeName: + AffectedNodeName: 14: CALL: return callback(taint_src, '_') /case/completeness/single_app_tracing/function_call/higher_order_function/higher_order_function_008_T.py AffectedNodeName: a @@ -8183,7 +8216,7 @@ Trace: AffectedNodeName: [return value] 16: Return Value: result = higher_order_function(lambda a, b: a + b) /case/completeness/single_app_tracing/function_call/higher_order_function/higher_order_function_008_T.py - AffectedNodeName: + AffectedNodeName: 14: CALL RETURN: return callback(taint_src, '_') /case/completeness/single_app_tracing/function_call/higher_order_function/higher_order_function_008_T.py AffectedNodeName: [return value] @@ -8204,7 +8237,7 @@ Trace: AffectedNodeName: os.system 21: SINK: os.system(o) -------------- 304: taint_flow_test------------- +------------- 308: taint_flow_test------------- Description:taint_flow_test,回归测试使用,不推荐外部使用 File:/case/completeness/single_app_tracing/function_call/higher_order_function/higher_order_function_010_T.py Line 28: os.system(o) @@ -8216,7 +8249,7 @@ Trace: AffectedNodeName: taint_src 12: SOURCE: def higher_order_function_010_T(taint_src): /case/completeness/single_app_tracing/function_call/higher_order_function/higher_order_function_010_T.py - AffectedNodeName: + AffectedNodeName: 23: CALL: combined = process_sequence(add_prefix, add_suffix)(taint_src) /case/completeness/single_app_tracing/function_call/higher_order_function/higher_order_function_010_T.py AffectedNodeName: s @@ -8233,17 +8266,23 @@ Trace: /case/completeness/single_app_tracing/function_call/higher_order_function/higher_order_function_010_T.py AffectedNodeName: add_prefix 15: CALL RETURN: return lambda s: func2(func1(s)) + /case/completeness/single_app_tracing/function_call/higher_order_function/higher_order_function_010_T.py + AffectedNodeName: add_suffix + 15: CALL: return lambda s: func2(func1(s)) /case/completeness/single_app_tracing/function_call/higher_order_function/higher_order_function_010_T.py AffectedNodeName: s 20: ARG PASS: def add_suffix(s): /case/completeness/single_app_tracing/function_call/higher_order_function/higher_order_function_010_T.py AffectedNodeName: [return value] 21: Return Value: return f"{s}_post" + /case/completeness/single_app_tracing/function_call/higher_order_function/higher_order_function_010_T.py + AffectedNodeName: add_suffix + 15: CALL RETURN: return lambda s: func2(func1(s)) /case/completeness/single_app_tracing/function_call/higher_order_function/higher_order_function_010_T.py AffectedNodeName: [return value] 15: Return Value: return lambda s: func2(func1(s)) /case/completeness/single_app_tracing/function_call/higher_order_function/higher_order_function_010_T.py - AffectedNodeName: + AffectedNodeName: 23: CALL RETURN: combined = process_sequence(add_prefix, add_suffix)(taint_src) /case/completeness/single_app_tracing/function_call/higher_order_function/higher_order_function_010_T.py AffectedNodeName: combined @@ -8258,7 +8297,7 @@ Trace: AffectedNodeName: os.system 28: SINK: os.system(o) -------------- 305: taint_flow_test------------- +------------- 309: taint_flow_test------------- Description:taint_flow_test,回归测试使用,不推荐外部使用 File:/case/completeness/single_app_tracing/function_call/higher_order_function/higher_order_function_012_T.py Line 32: os.system(o) @@ -8306,7 +8345,7 @@ Trace: AffectedNodeName: os.system 32: SINK: os.system(o) -------------- 306: taint_flow_test------------- +------------- 310: taint_flow_test------------- Description:taint_flow_test,回归测试使用,不推荐外部使用 File:/case/completeness/single_app_tracing/function_call/library_function/datetime_001_T.py Line 22: os.system(str(o)) @@ -8336,7 +8375,31 @@ Trace: AffectedNodeName: os.system 22: SINK: os.system(str(o)) -------------- 307: taint_flow_test------------- +------------- 311: taint_flow_test------------- +Description:taint_flow_test,回归测试使用,不推荐外部使用 +File:/case/completeness/single_app_tracing/function_call/library_function/datetime_002_F.py +Line 21: os.system(str(o)) +SINK RULE:os.system +entrypoint: +{"filePath":"/case/completeness/single_app_tracing/function_call/library_function/datetime_002_F.py","functionName":"datetime_002_F","attribute":"fullCallGraphMade","type":"functionCall","funcReceiverType":""} +Trace: + /case/completeness/single_app_tracing/function_call/library_function/datetime_001_T.py + AffectedNodeName: taint_src + 14: SOURCE: def datetime_001_T(taint_src): + /case/completeness/single_app_tracing/function_call/library_function/datetime_002_F.py + AffectedNodeName: dt + 15: Var Pass: dt = datetime.strptime(time_str, "%Y-%m-%d") + /case/completeness/single_app_tracing/function_call/library_function/datetime_002_F.py + AffectedNodeName: taint_sink + 16: CALL: taint_sink(dt) + /case/completeness/single_app_tracing/function_call/library_function/datetime_002_F.py + AffectedNodeName: o + 20: ARG PASS: def taint_sink(o): + /case/completeness/single_app_tracing/function_call/library_function/datetime_002_F.py + AffectedNodeName: os.system + 21: SINK: os.system(str(o)) + +------------- 312: taint_flow_test------------- Description:taint_flow_test,回归测试使用,不推荐外部使用 File:/case/completeness/single_app_tracing/function_call/library_function/json_001_T.py Line 21: os.system(o) @@ -8366,7 +8429,7 @@ Trace: AffectedNodeName: os.system 21: SINK: os.system(o) -------------- 308: taint_flow_test------------- +------------- 313: taint_flow_test------------- Description:taint_flow_test,回归测试使用,不推荐外部使用 File:/case/completeness/single_app_tracing/function_call/library_function/math_001_T.py Line 23: os.system(str(o)) @@ -8396,7 +8459,7 @@ Trace: AffectedNodeName: os.system 23: SINK: os.system(str(o)) -------------- 309: taint_flow_test------------- +------------- 314: taint_flow_test------------- Description:taint_flow_test,回归测试使用,不推荐外部使用 File:/case/completeness/single_app_tracing/function_call/library_function/os_001_T.py Line 17: os.system(o) @@ -8420,7 +8483,7 @@ Trace: AffectedNodeName: os.system 17: SINK: os.system(o) -------------- 310: taint_flow_test------------- +------------- 315: taint_flow_test------------- Description:taint_flow_test,回归测试使用,不推荐外部使用 File:/case/completeness/single_app_tracing/function_call/library_function/re_001_T.py Line 19: os.system(str(o)) @@ -8444,7 +8507,7 @@ Trace: AffectedNodeName: os.system 19: SINK: os.system(str(o)) -------------- 311: taint_flow_test------------- +------------- 316: taint_flow_test------------- Description:taint_flow_test,回归测试使用,不推荐外部使用 File:/case/completeness/single_app_tracing/function_call/library_function/string_001_T.py Line 22: os.system(o) @@ -8474,7 +8537,7 @@ Trace: AffectedNodeName: os.system 22: SINK: os.system(o) -------------- 312: taint_flow_test------------- +------------- 317: taint_flow_test------------- Description:taint_flow_test,回归测试使用,不推荐外部使用 File:/case/completeness/single_app_tracing/function_call/override/constructor_extends_001_T.py Line 35: os.system(o) @@ -8488,18 +8551,6 @@ Trace: /case/completeness/single_app_tracing/function_call/override/constructor_extends_001_T.py AffectedNodeName: __init__ 12: CALL: derived = DerivedClass(taint_src) - /case/completeness/single_app_tracing/function_call/override/constructor_extends_001_T.py - AffectedNodeName: data - 27: ARG PASS: def __init__(self, data): - /case/completeness/single_app_tracing/function_call/override/constructor_extends_001_T.py - AffectedNodeName: __init__ - 28: CALL: super().__init__(data) - /case/completeness/single_app_tracing/function_call/override/constructor_extends_001_T.py - AffectedNodeName: data - 16: ARG PASS: def __init__(self, data): - /case/completeness/single_app_tracing/function_call/override/constructor_extends_001_T.py - AffectedNodeName: [self.data] - 17: Var Pass: self.data = data /case/completeness/single_app_tracing/function_call/override/constructor_extends_001_T.py AffectedNodeName: derived 12: Var Pass: derived = DerivedClass(taint_src) @@ -8515,9 +8566,6 @@ Trace: /case/completeness/single_app_tracing/function_call/override/constructor_extends_001_T.py AffectedNodeName: self 31: ARG PASS: taint_sink(self.get_data()) - /case/completeness/single_app_tracing/function_call/override/constructor_extends_001_T.py - AffectedNodeName: [return value] - 20: Return Value: return self.data /case/completeness/single_app_tracing/function_call/override/constructor_extends_001_T.py AffectedNodeName: get_data 31: CALL RETURN: taint_sink(self.get_data()) @@ -8531,7 +8579,7 @@ Trace: AffectedNodeName: os.system 35: SINK: os.system(o) -------------- 313: taint_flow_test------------- +------------- 318: taint_flow_test------------- Description:taint_flow_test,回归测试使用,不推荐外部使用 File:/case/completeness/single_app_tracing/function_call/override/constructor_extends_003_T.py Line 37: os.system(data) @@ -8543,7 +8591,7 @@ Trace: AffectedNodeName: taint_src 12: SOURCE: def constructor_extends_003_T(taint_src): /case/completeness/single_app_tracing/function_call/override/constructor_extends_003_T.py - AffectedNodeName: [self.data] + AffectedNodeName: self.data 15: Var Pass: self.data = taint_src /case/completeness/single_app_tracing/function_call/override/constructor_extends_003_T.py AffectedNodeName: derived @@ -8576,7 +8624,7 @@ Trace: AffectedNodeName: os.system 37: SINK: os.system(data) -------------- 314: taint_flow_test------------- +------------- 319: taint_flow_test------------- Description:taint_flow_test,回归测试使用,不推荐外部使用 File:/case/completeness/single_app_tracing/function_call/override/static_method_override_001_T.py Line 29: os.system(o) @@ -8604,7 +8652,7 @@ Trace: AffectedNodeName: os.system 29: SINK: os.system(o) -------------- 315: taint_flow_test------------- +------------- 320: taint_flow_test------------- Description:taint_flow_test,回归测试使用,不推荐外部使用 File:/case/completeness/single_app_tracing/function_call/return_value_passing/return_normal_value_passing_002_T.py Line 22: os.system(o) @@ -8618,12 +8666,6 @@ Trace: /case/completeness/single_app_tracing/function_call/return_value_passing/return_normal_value_passing_002_T.py AffectedNodeName: process 13: CALL: data = process(taint_src) - /case/completeness/single_app_tracing/function_call/return_value_passing/return_normal_value_passing_002_T.py - AffectedNodeName: src - 17: ARG PASS: def process(src): - /case/completeness/single_app_tracing/function_call/return_value_passing/return_normal_value_passing_002_T.py - AffectedNodeName: [return value] - 18: Return Value: return src /case/completeness/single_app_tracing/function_call/return_value_passing/return_normal_value_passing_002_T.py AffectedNodeName: process 13: CALL RETURN: data = process(taint_src) @@ -8640,7 +8682,7 @@ Trace: AffectedNodeName: os.system 22: SINK: os.system(o) -------------- 316: taint_flow_test------------- +------------- 321: taint_flow_test------------- Description:taint_flow_test,回归测试使用,不推荐外部使用 File:/case/completeness/single_app_tracing/function_call/return_value_passing/return_normal_value_passing_004_T.py Line 22: os.system(o) @@ -8688,7 +8730,7 @@ Trace: AffectedNodeName: os.system 22: SINK: os.system(o) -------------- 317: taint_flow_test------------- +------------- 322: taint_flow_test------------- Description:taint_flow_test,回归测试使用,不推荐外部使用 File:/case/completeness/single_app_tracing/function_call/return_value_passing/return_normal_value_passing_005_T.py Line 22: os.system(o) @@ -8724,7 +8766,7 @@ Trace: AffectedNodeName: os.system 22: SINK: os.system(o) -------------- 318: taint_flow_test------------- +------------- 323: taint_flow_test------------- Description:taint_flow_test,回归测试使用,不推荐外部使用 File:/case/completeness/single_app_tracing/function_call/static_method/higher_order_001_T.py Line 28: os.system(o) @@ -8738,19 +8780,6 @@ Trace: /case/completeness/single_app_tracing/function_call/static_method/higher_order_001_T.py AffectedNodeName: execute_operation 23: CALL: result = execute_operation(Calculator.add_taint, taint_src, "_") - /case/completeness/single_app_tracing/function_call/static_method/higher_order_001_T.py - AffectedNodeName: a - 18: ARG PASS: def execute_operation(op_func, a, b): - /case/completeness/single_app_tracing/function_call/static_method/higher_order_001_T.py - AffectedNodeName: [return value] - 15: Return Value: return f"{a}_{b}" # 污点扩展 - /case/completeness/single_app_tracing/function_call/static_method/higher_order_001_T.py - AffectedNodeName: add_taint - 14: CALL RETURN: def add_taint(a, b): - 15: CALL RETURN: return f"{a}_{b}" # 污点扩展 - /case/completeness/single_app_tracing/function_call/static_method/higher_order_001_T.py - AffectedNodeName: [return value] - 19: Return Value: return op_func(a, b) # 调用传入的静态方法 /case/completeness/single_app_tracing/function_call/static_method/higher_order_001_T.py AffectedNodeName: execute_operation 23: CALL RETURN: result = execute_operation(Calculator.add_taint, taint_src, "_") @@ -8767,7 +8796,7 @@ Trace: AffectedNodeName: os.system 28: SINK: os.system(o) -------------- 319: taint_flow_test------------- +------------- 324: taint_flow_test------------- Description:taint_flow_test,回归测试使用,不推荐外部使用 File:/case/completeness/single_app_tracing/function_call/static_method/static_access_001_T.py Line 29: os.system(o) @@ -8779,7 +8808,7 @@ Trace: AffectedNodeName: taint_src 12: SOURCE: def static_access_001_T(taint_src): /case/completeness/single_app_tracing/function_call/static_method/static_access_001_T.py - AffectedNodeName: [DataProcessor.__taint_storage] + AffectedNodeName: DataProcessor.__taint_storage 18: Var Pass: DataProcessor.__taint_storage = src /case/completeness/single_app_tracing/function_call/static_method/static_access_001_T.py AffectedNodeName: [return value] @@ -8798,7 +8827,7 @@ Trace: AffectedNodeName: os.system 29: SINK: os.system(o) -------------- 320: taint_flow_test------------- +------------- 325: taint_flow_test------------- Description:taint_flow_test,回归测试使用,不推荐外部使用 File:/case/completeness/single_app_tracing/variable_scope/global/global_001_T.py Line 19: os.system(o) @@ -8822,7 +8851,7 @@ Trace: AffectedNodeName: os.system 19: SINK: os.system(o) -------------- 321: taint_flow_test------------- +------------- 326: taint_flow_test------------- Description:taint_flow_test,回归测试使用,不推荐外部使用 File:/case/completeness/single_app_tracing/variable_scope/global/global_003_T.py Line 20: os.system(o) @@ -8846,7 +8875,7 @@ Trace: AffectedNodeName: os.system 20: SINK: os.system(o) -------------- 322: taint_flow_test------------- +------------- 327: taint_flow_test------------- Description:taint_flow_test,回归测试使用,不推荐外部使用 File:/case/completeness/single_app_tracing/variable_scope/nonlocal/nonlocal_001_T.py Line 26: os.system(o) @@ -8870,7 +8899,7 @@ Trace: AffectedNodeName: os.system 26: SINK: os.system(o) -------------- 323: taint_flow_test------------- +------------- 328: taint_flow_test------------- Description:taint_flow_test,回归测试使用,不推荐外部使用 File:/case/completeness/single_app_tracing/variable_scope/private_variable/private_variable_001_T.py Line 28: os.system(o) @@ -8891,8 +8920,11 @@ Trace: AffectedNodeName: data 14: ARG PASS: def __init__(self, data): /case/completeness/single_app_tracing/variable_scope/private_variable/private_variable_001_T.py - AffectedNodeName: [self.__data] + AffectedNodeName: self.__data 15: Var Pass: self.__data = data + /case/completeness/single_app_tracing/variable_scope/private_variable/private_variable_001_T.py + AffectedNodeName: o + 23: Var Pass: o = A(data=taint_src) # 显式传递 taint_src /case/completeness/single_app_tracing/variable_scope/private_variable/private_variable_001_T.py AffectedNodeName: get_data 24: CALL: taint_sink(o.get_data()) @@ -8915,7 +8947,7 @@ Trace: AffectedNodeName: os.system 28: SINK: os.system(o) -------------- 324: taint_flow_test------------- +------------- 329: taint_flow_test------------- Description:taint_flow_test,回归测试使用,不推荐外部使用 File:/case/completeness/single_app_tracing/variable_scope/static_variable/static_variable_003_T.py Line 22: os.system(o) @@ -8939,5 +8971,5 @@ Trace: AffectedNodeName: os.system 22: SINK: os.system(o) ========================================================== - #Total-findings:324 + #Total-findings:329 ========================================================== \ No newline at end of file diff --git a/test/python/test-python-benchmark.ts b/test/python/test-python-benchmark.ts index 4929d8b5..92ab5284 100644 --- a/test/python/test-python-benchmark.ts +++ b/test/python/test-python-benchmark.ts @@ -93,7 +93,7 @@ async function update(dir: string): Promise { '--checkerIds', 'taint_flow_test', '--uastSDKPath', - path.join(__dirname, '../../deps/uast4py/uast4py'), + path.join(__dirname, '../../deps'), ] try { await execute(null, args, recorder.printAndAppend) @@ -140,7 +140,7 @@ async function getRunPythonBenchmarkResult( '--checkerIds', 'taint_flow_test', '--uastSDKPath', - path.join(__dirname, '../../deps/uast4py/uast4py'), + path.join(__dirname, '../../deps'), ] try { diff --git a/tsconfig.json b/tsconfig.json index 9ab46deb..4e3e91e2 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,6 +1,7 @@ { "compilerOptions": { "target": "ES2020", + "lib": ["ES2020", "ES2021.String", "ES2021.WeakRef"], "module": "CommonJS", "rootDir": "./src", "outDir": "./dist", @@ -9,6 +10,7 @@ "allowJs": true, "checkJs": false, "strict": true, + "noImplicitOverride": true, "esModuleInterop": true, "skipLibCheck": true, "forceConsistentCasingInFileNames": true,