From f731d793cf762af1ac3bc644e70cd3be81e528c2 Mon Sep 17 00:00:00 2001 From: "Iskander (Alex) Sharipov" Date: Sat, 22 Aug 2020 21:44:05 +0300 Subject: [PATCH] ruleguard: unquote the pattern string properly (#73) Instead of just dropping the both quotes, do the actual unquoting that may involve some string interpretation in case of the "-literals. strconv.Unquote() is the right way to do it. Refs #72 Signed-off-by: Iskander Sharipov --- analyzer/testdata/src/regression/issue72.go | 10 ++++++++++ analyzer/testdata/src/regression/rules.go | 9 +++++++++ ruleguard/parser.go | 6 +++++- ruleguard/utils.go | 4 ---- 4 files changed, 24 insertions(+), 5 deletions(-) create mode 100644 analyzer/testdata/src/regression/issue72.go diff --git a/analyzer/testdata/src/regression/issue72.go b/analyzer/testdata/src/regression/issue72.go new file mode 100644 index 00000000..b63b8f0a --- /dev/null +++ b/analyzer/testdata/src/regression/issue72.go @@ -0,0 +1,10 @@ +package regression + +import "fmt" + +func testIssue72() { + _ = fmt.Sprintf("%s<%s>", "name", "email@domain.example") // want `\Quse net/mail Address.String() instead of fmt.Sprintf()` + _ = fmt.Sprintf("\"%s\" <%s>", "name", "email@domain.example") // want `\Quse net/mail Address.String() instead of fmt.Sprintf()` + _ = fmt.Sprintf(`"%s" <%s>`, "name", "email@domain.example") // want `\Quse net/mail Address.String() instead of fmt.Sprintf()` + _ = fmt.Sprintf(`"%s"<%s>`, "name", "email@domain.example") // want `\Quse net/mail Address.String() instead of fmt.Sprintf()` +} diff --git a/analyzer/testdata/src/regression/rules.go b/analyzer/testdata/src/regression/rules.go index 0afd1978..d866124f 100644 --- a/analyzer/testdata/src/regression/rules.go +++ b/analyzer/testdata/src/regression/rules.go @@ -10,3 +10,12 @@ func issue68(m fluent.Matcher) { m.Match(`func $_($_ *testing.T) { $p; $*_ }`).Where(m["p"].Text != "t.Parallel()").Report(`Not a parallel test`) m.Match(`func $_($_ *testing.T) { $p; $*_ }`).Where(m["p"].Text == "t.Parallel()").Report(`Parallel test`) } + +func issue72(m fluent.Matcher) { + m.Match("fmt.Sprintf(`\"%s\" <%s>`, $name, $email)", + "fmt.Sprintf(`\"%s\"<%s>`, $name, $email)", + `fmt.Sprintf("\"%s\" <%s>", $name, $email)`, + `fmt.Sprintf("\"%s\"<%s>", $name, $email)`, + `fmt.Sprintf("%s<%s>", $name, $email)`). + Report("use net/mail Address.String() instead of fmt.Sprintf()") +} diff --git a/ruleguard/parser.go b/ruleguard/parser.go index 98fcd20d..c85994b9 100644 --- a/ruleguard/parser.go +++ b/ruleguard/parser.go @@ -603,7 +603,11 @@ func (p *rulesParser) toStringValue(x ast.Node) (string, bool) { if x.Kind != token.STRING { return "", false } - return unquoteNode(x), true + s, err := strconv.Unquote(x.Value) + if err != nil { + return "", false + } + return s, true case ast.Expr: typ, ok := p.types.Types[x] if !ok || typ.Type.String() != "string" { diff --git a/ruleguard/utils.go b/ruleguard/utils.go index c17dc243..71a6cc0e 100644 --- a/ruleguard/utils.go +++ b/ruleguard/utils.go @@ -10,10 +10,6 @@ import ( "strings" ) -func unquoteNode(lit *ast.BasicLit) string { - return lit.Value[1 : len(lit.Value)-1] -} - func sprintNode(fset *token.FileSet, n ast.Node) string { if fset == nil { fset = token.NewFileSet()