manualpathconcat: parenthesized "/" separator and compound-assign RHS escape detection (paren_unwrap_gap)

Abierto Apto para principiantes
#72,308 0 comentarios 0 reacciones 0 asignados Ver en GitHub

Los mantenedores suelen responder en 1 día

Nadie ha tomado este issue todavía.

  • #72566 de @github-actions — cerrado sin fusionar

Evaluación

Dificultad
2/5
Tiempo estimado
1-3 horas
Aptitud para principiantes
77/100
Tipo de issue
Error
Claridad
Bien especificado
Estado de actividad
Activo
Stack tecnológico
go
Área
testing-qa

Línea de trabajo

Empieza en pkg/linters/manualpathconcat/manualpathconcat.go y lee isSlashLiteral, embeddedSlashLiteral y analyzeAssignStmt para seguir cómo se comprueban las expresiones entre paréntesis. Después, inspecciona testdata/src/manualpathconcat y añade cobertura para dir + ("/") + file y path += ("/" + file). La tarea estará terminada cuando ambos casos produzcan el diagnóstico esperado y go test ./pkg/linters/manualpathconcat/... pase.

Escrito por el modelo de indexación a partir del texto del issue.

Descripción

cookie sergo

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.BasicLit type assertion.
  • In analyzeAssignStmt, call astutil.UnwrapParenExpr(assign.Rhs[0]) once up front before the type switch.
  • Add testdata cases for dir + ("/") + file and path += ("/" + 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
Lenguaje dominante
Go
Estrellas
5.5k
Forks
606
Merge medio
4 h 47 min
PR fusionados (30 d)
797

Preparar el entorno

Abrir en Codespaces

Inicia el contenedor de desarrollo del proyecto en tu navegador, con tu propia cuenta de GitHub.

Primeros pasos

  1. Lee el issue completo y luego la guía de contribución del proyecto.
  2. Comenta en el issue que vas a ocuparte — evita que dos personas hagan lo mismo.
  3. Haz un fork del repositorio y trabaja en una rama.
  4. Abre un pull request que haga referencia al número del issue.

Más de github/gh-aw

Todos los issues de github/gh-aw

Issues similares

Más issues de Go

Recibe los nuevos issues en tu correo

Un resumen breve de issues de GitHub para principiantes.