manualpathconcat: parenthesized "/" separator and compound-assign RHS escape detection (paren_unwrap_gap)
メンテナーはふだん 1 日以内に返信
まだ誰も着手していません。
- #72566 @github-actions による — マージされずにクローズ
評価
- 難易度
- 2/5
- 見積もり時間
- 1〜3時間
- 初心者へのやさしさ
- 77/100
- issue の種類
- バグ
- 明瞭さ
- 明確に書かれている
- 活発さ
- 活発
- 技術スタック
- go
- 領域
- testing-qa
調査の方向性
pkg/linters/manualpathconcat/manualpathconcat.goから始め、isSlashLiteral、embeddedSlashLiteral、analyzeAssignStmtを読んで、括弧で囲まれた式がどのように検査されるかを追ってください。次にtestdata/src/manualpathconcatを調べ、dir + ("/") + fileとpath += ("/" + file)のテストを追加してください。両方のケースで期待される診断が出力され、go test ./pkg/linters/manualpathconcat/...が成功すれば完了です。
索引モデルが issue の本文から書いたものです。
説明
Summary
manualpathconcat (pkg/linters/manualpathconcat/manualpathconcat.go) has never been individually day-one audited by Sergo despite being registered since 2026-08 and iterated on twice since (#54986, #57056). A fresh audit against the standing paren_unwrap_gap check found two concrete, code-verified gaps.
Gap 1: isSlashLiteral never unwraps parens (line 171-178)
func isSlashLiteral(expr ast.Expr) bool {
lit, ok := expr.(*ast.BasicLit)
...
This is called on inner.Y in matchSlashSeparator (line 148) to detect the "/" separator in X + "/" + Y. A parenthesized separator, e.g. dir + ("/") + file, makes inner.Y an *ast.ParenExpr, which fails the bare *ast.BasicLit assertion and silently escapes detection. The file does not import astutil.UnwrapParenExpr anywhere.
Gap 2: embeddedSlashLiteral has the same bare assertion (line 185-195), and analyzeAssignStmt never unwraps the whole RHS (line 92-112)
analyzeAssignStmt type-switches directly on assign.Rhs[0] (line 99: switch rhs := assign.Rhs[0].(type) { case *ast.BinaryExpr: ... default: ... embeddedSlashLiteral(assign.Rhs[0])). A parenthesized compound-assign RHS, e.g. path += ("/" + file) or path += ("/subpath"), makes assign.Rhs[0] an *ast.ParenExpr. The BinaryExpr case fails, falling to default, and embeddedSlashLiteral also fails its own bare BasicLit assertion on the ParenExpr - the whole compound-assign form escapes detection with no diagnostic at all.
Why this matters
This is the same recurring paren_unwrap_gap shape found in 15+ other linters across the registry (nilctxpassed, errstringmatch, closeerrorunchecked, typeassertionnil, wgdonenotdeferred, etc.) - gofmt does not strip redundant parens around literals or binary expressions, so these shapes can persist in hand-written or mechanically-refactored code.
Evidence
- No existing testdata coverage for either parenthesized shape (testdata/src/manualpathconcat has no ParenExpr cases).
- manualpathconcat is absent from .github/workflows/cgo.yml LINTER_FLAGS (native and wasm both) - not yet CI-enforced, so this is a latent correctness gap rather than a live false-negative, same filing bar as several prior latent paren_unwrap_gap findings.
Recommendation
- In isSlashLiteral and embeddedSlashLiteral, call astutil.UnwrapParenExpr(expr) before the
*ast.BasicLittype assertion. - In analyzeAssignStmt, call astutil.UnwrapParenExpr(assign.Rhs[0]) once up front before the type switch.
- Add testdata cases for
dir + ("/") + fileandpath += ("/" + file).
Validation
- Unwrap added at both isSlashLiteral and embeddedSlashLiteral call sites
- Unwrap added before the analyzeAssignStmt type switch
- New testdata cases added and pass
- go test ./pkg/linters/manualpathconcat/... green
Effort: small (single-file fix, no shared-helper blast radius).
Generated by 🤖 Sergo - Serena Go Expert · claude · agent · ~267 AIC · ⌖ ~1 AIC · ⊞ 4.1K · ◷
- expires on Nov 2, 2026, 8:06 PM UTC-08:00
- 主要言語
- Go
- スター
- 5.5k
- フォーク
- 606
- 平均マージ
- 4時間 44分
- マージ済み PR(30日)
- 799
環境構築
このプロジェクトの開発コンテナを、あなたの GitHub アカウントでブラウザ上に起動します。
- Dockerfile または Docker Compose ファイルあり
- プルリクエストのテンプレートなし
- コントリビューションガイドを読む
はじめの一歩
- issue を最後まで読み、次にプロジェクトのコントリビューションガイドを読みます。
- 着手することを issue にコメントします — 二人が同じ作業をするのを防げます。
- リポジトリをフォークし、ブランチを切って変更します。
- issue 番号を参照したプルリクエストを送ります。
github/gh-aw のほかの issue
-
難易度 2/5 1〜3時間 初心者へのやさしさ 72/100
メンテナーはふだん 1 日以内に返信
-
automated-analysis code-quality cookie refactoring
難易度 2/5 1〜3時間 初心者へのやさしさ 72/100
メンテナーはふだん 1 日以内に返信
-
cookie maintenance step-naming
難易度 2/5 1〜3時間 初心者へのやさしさ 64/100
メンテナーはふだん 1 日以内に返信
-
automation doc-healer documentation
難易度 2/5 1〜3時間 初心者へのやさしさ 65/100
メンテナーはふだん 1 日以内に返信
-
agentic-workflows automation aw-essential cookie
難易度 2/5 1〜3時間 初心者へのやさしさ 75/100
メンテナーはふだん 1 日以内に返信
似ている issue
-
難易度 2/5 1〜3時間 初心者へのやさしさ 84/100
hyperledger/fabric-x-orderer#1409 ·
メンテナーはふだん 3 日以内に返信
-
難易度 2/5 1〜3時間 初心者へのやさしさ 78/100
メンテナーはふだん 1 日以内に返信
-
needs-area
難易度 2/5 1〜3時間 初心者へのやさしさ 68/100
Azure/typespec-azure#5936 ·
メンテナーはふだん 1 日以内に返信
-
難易度 1/5 1時間未満 初心者へのやさしさ 70/100
-
Fix mode unpins a reusable workflow call when the same repository is also used as a step actionオープン
難易度 2/5 1〜3時間 初心者へのやさしさ 72/100
github/gh-actions-lock#261 ·
メンテナーはふだん 1 日以内に返信