[BUG][code-analyzer] sfge: Database.query() on a string that is empty on any path aborts the entry point ("Query should have fields")
还没有人认领这个 Issue。
评估
- 难度
- 3/5
- 预计耗时
- 1-2 天
- 新手友好度
- 72/100
- Issue 类型
- 缺陷
- 描述清晰度
- 描述清楚
- 活跃度
- 活跃
- 技术栈
- java, typescript
- 领域
- devtools, testing-qa
调研方向
Start with SoqlParserUtil.java, especially extractFields and the existing handling of IllegalStateException; compare what happens when the field-pattern match fails. Run the sfge rule against the QueryEmptyOnOnePath reproducer and check that an empty query path no longer aborts analysis, while a real query path still reports the ApexFlsViolation for Account.Name.
由索引模型根据 Issue 内容生成。
描述
Have you tried to resolve this issue yourself first?
- I confirm I have gone through the above steps and still have an issue to report.
Bug Description
Engine: sfge (Salesforce Graph Engine) · Rule: ApexFlsViolation (DevPreview) · Selector: --rule-selector sfge
sfge parses the string passed to Database.query() with SoqlParserUtil.parseQuery. When the field pattern finds no match, extractFields throws:
// SoqlParserUtil.java:330-334
final Matcher fieldMatcher = FIELD_PATTERN.matcher(query);
if (!fieldMatcher.find()) {
throw new UnexpectedException("Query should have fields: " + query);
}
A common way to build a dynamic query is to start from '' and assign the query in branches. sfge expands every path, including the one where no branch ran, and the string there is still ''. The throw on that one path abandons the whole entry point, so the paths with a real query are never checked for FLS either.
String query = '';
if (mode == 'all') {
query = 'SELECT Id, Name FROM Account';
}
return Database.query(query);
Output / Logs
UnexpectedException: Query should have fields: :
com.salesforce.graph.ops.SoqlParserUtil.extractFields(SoqlParserUtil.java:333);
com.salesforce.graph.ops.SoqlParserUtil.parseFields(SoqlParserUtil.java:356);
com.salesforce.graph.ops.SoqlParserUtil.getSoqlQueryInfo(SoqlParserUtil.java:211);
com.salesforce.graph.ops.SoqlParserUtil.getInnerQueries(SoqlParserUtil.java:194);
com.salesforce.graph.ops.SoqlParserUtil.parseQuery(SoqlParserUtil.java:144);
com.salesforce.graph.symbols.apex.ApexSoqlValue.setObjectProperties(ApexSoqlValue.java:135)
The query after Query should have fields: is empty.
Steps To Reproduce
- Create an empty SFDX project (
sfdx-project.jsonwith a singleforce-apppackage directory). - Add
force-app/main/default/classes/QueryEmptyOnOnePath.clswith the class shown below, plus a standardQueryEmptyOnOnePath.cls-meta.xml(apiVersion 62.0). - Add
code-analyzer.yml:engines: sfge: java_thread_timeout: 900000 java_thread_count: 4 - Run:
sf code-analyzer run --rule-selector sfge --workspace . --config-file code-analyzer.yml - The run reports an
InternalExecutionErrorfor the entry point instead of analysing it. TheREADonAccount.Namegoes unreported, and nothing in the summary indicates coverage was lost.
public with sharing class QueryEmptyOnOnePath {
@AuraEnabled
public static List<Account> run(String mode) {
String query = '';
if (mode == 'all') {
query = 'SELECT Id, Name FROM Account';
}
return Database.query(query);
}
}
Expected Behavior
A query string that does not parse should leave that one path's query unresolved, the way sfge already reports "couldn't resolve the parameter passed to [READ] operation". It should not throw. extractFields already degrades to an empty field list on IllegalStateException, and a failed match could take the same route.
Operating System
macOS 26.7.1
Salesforce CLI Version
@salesforce/cli/2.147.7 darwin-arm64 node-v24.5.0
Code Analyzer Plugin (code-analyzer) Version
code-analyzer 5.15.0
Node Version
v24.5.0
Java Version
openjdk version "11.0.32" 2026-07-21
Python Version
N/A
Additional Context (Screenshots, Files, etc)
Also fails on code-analyzer 5.16.0 (sfge 0.25.0) under OpenJDK 21 on ubuntu-latest, with the same stack. In our codebase it abandons 1 @AuraEnabled entry point.
A control in the same workspace, with a non-empty query on every path (String query = 'SELECT Id, Name FROM Account';, overwritten in the branch), was analysed normally and reports the expected ApexFlsViolation for the READ on Account.Name.
#1224, closed in the 2026-06-30 pre-v5 sweep, failed at the same line with a different input: an inner query in a WHERE clause (Id NOT IN (INNER_QUERY) AND ...), which matches the TODO: Handle contents within brackets in getInnerQueries. We have not re-tested that input. A fix that degrades instead of throwing would cover both.
Workaround
Initialise the query string to a valid query, or return before Database.query() on the path that builds none.
Urgency
Moderate
- 主要语言
- TypeScript
- 星标
- 241
- 派生
- 51
- PR 合并指标
- 30 天内没有已合并 PR
环境准备
- 没有 Dockerfile 或 Docker Compose 文件
- 没有 Pull Request 模板
- 阅读贡献指南
从这里开始
- 先读完整个 Issue,再读项目的贡献指南。
- 在 Issue 下留言说明你要接手 —— 这能避免两个人做同样的事。
- Fork 仓库,在一个分支上完成修改。
- 提交 Pull Request,并在描述里引用这个 Issue 编号。
forcedotcom/code-analyzer 的其他 Issue
-
难度 2/5 1-3 小时 新手友好度 78/100
forcedotcom/code-analyzer#2094 ·
-
难度 1/5 1 小时以内 新手友好度 88/100
forcedotcom/code-analyzer#2093 ·
-
难度 2/5 1-3 小时 新手友好度 82/100
forcedotcom/code-analyzer#2091 ·
-
难度 2/5 1-3 小时 新手友好度 76/100
forcedotcom/code-analyzer#2090 ·
-
难度 3/5 1-2 天 新手友好度 63/100
forcedotcom/code-analyzer#2103 ·
查看 forcedotcom/code-analyzer 的全部 Issue
相似的 Issue
-
clawsweeper:fix-shape-clear clawsweeper:queueable-fix clawsweeper:source-repro impact:other issue-rating: 🦞 diamond lobster no-stale P2
难度 2/5 1-3 小时 新手友好度 72/100
openclaw/openclaw#168089 · 2 条评论 · 1 个 reaction ·
维护者通常 1 天内回复
-
✨ enhancement needs-discussion
难度 1/5 1 小时以内 新手友好度 85/100
-
[Bug]: [MCP/CLI] Bare loopback IP addresses (127.0.0.1:port) and hosts with ports fail to navigate due to erroneous scheme inference可能已有人在做 @alok-108 今天认领。 未关闭
难度 2/5 1-3 小时 新手友好度 78/100
microsoft/playwright#43263 ·
维护者通常 1 天内回复
-
area:studio type:security
难度 2/5 1-3 小时 新手友好度 78/100
维护者通常 1 天内回复
-
enhancement good first issue Stellar Wave trivial
难度 2/5 1-3 小时 新手友好度 85/100
StellarCanary/ProtocolCanary-Action#331 ·
维护者通常 1 天内回复