Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

proposal: cmd/vet: report strings.Trim/TrimLeft/TrimRight with duplicate runes in cutset #46533

Open
CAFxX opened this issue Jun 3, 2021 · 11 comments
Labels
Projects
Milestone

Comments

@CAFxX
Copy link
Contributor

@CAFxX CAFxX commented Jun 3, 2021

go vet should ideally report likely misuses of standard library functions especially when it comes to providing constant(-ish) string arguments, e.g. (note: the following list is absolutely not exhaustive)

  • strings.(Trim|TrimLeft|TrimRight) with a cutset containing duplicated runes
  • net/http.NewRequest with an invalid HTTP method or a non-HTTP url
  • net/http.(Do|Get|Post) with a non-HTTP url
  • regexp.(Must)?Compile with an invalid regexp
  • (text|html)/template.Template.Parse with an invalid template text
  • (and so on, for all functions/structs where it makes sense; not all of them need to be added right away, coverage will likely improve over time)
@jfesler
Copy link

@jfesler jfesler commented Jun 3, 2021

I especially like the regexp.MustCompile example, consider it panics. And I see people using this function in places that may or may not be observed in testing. Code reviews help guard against this; but the reviewers are unfortunately human.

@seankhliao seankhliao changed the title vet: report suspicious constant string arguments proposal: cmd/vet: report suspicious constant string arguments Jun 3, 2021
@gopherbot gopherbot added this to the Proposal milestone Jun 3, 2021
@mvdan
Copy link
Member

@mvdan mvdan commented Jun 3, 2021

Would this qualify for the "frequency" factor of vet checks? How often do these issues occur?

It's also worth noting that @dominikh's staticcheck has had some of these for a while, like https://staticcheck.io/docs/checks#SA1000.

@dominikh
Copy link
Member

@dominikh dominikh commented Jun 3, 2021

net/http.NewRequest with an invalid HTTP method

I believe there's nothing stopping a server from offering non-standard methods, so this could cause false positives.

or a non-HTTP url

With custom transports that could also lead to false positives.

@guodongli-google
Copy link

@guodongli-google guodongli-google commented Jun 6, 2021

One question is whether we should use one checker to check all these cases or one checker for each API.
StaticCheck has some related or similar checks, e.g.

@ianlancetaylor ianlancetaylor added this to Incoming in Proposals Jun 8, 2021
@rsc
Copy link
Contributor

@rsc rsc commented Jun 9, 2021

This proposal has been added to the active column of the proposals project
and will now be reviewed at the weekly proposal review meetings.
— rsc for the proposal review group

@rsc rsc moved this from Incoming to Active in Proposals Jun 9, 2021
@rsc
Copy link
Contributor

@rsc rsc commented Jun 16, 2021

Vet mostly stays away from the standard library. It does check Printf (in fact that's what vet was created for).
But Printf is far more core to the use of Go than, say, templates, or even regular expressions.
It also seems weird to put more of these library-specific checks in that are not really available to third-party libraries.
(Again, Printf is an exception, but we may not want to add more.)

@CAFxX
Copy link
Contributor Author

@CAFxX CAFxX commented Jun 20, 2021

If this is the direction of the vet tool, then sure.

In this case though, just a few notes:

  • The vet tool description should really be clarified. As it is right now, it makes it sound like vet is the correct place for this kind of checks, because it uses an example to describe what the tool does, and that example is precisely validating arguments to standard library functions: "Vet examines Go source code and reports suspicious constructs, such as Printf calls whose arguments do not align with the format string." and "Vet is a tool that checks correctness of Go programs. It runs a suite of tests, each tailored to check for a particular class of errors. Examples include incorrect Printf format verbs and malformed build tags."
  • The vet README contains helpful criteria for inclusions, but they do not mention those you mentioned (not really supposed to cover the standard library, checks should be available to third-party libraries). Maybe the criteria would benefit from an update?
  • Specifically about the checks not being available to third-party libraries... isn't this an implementation detail? (in that it would seem to be enough to have the analysis live in https://pkg.go.dev/golang.org/x/tools/go/analysis, where again it sounds like it would belong). (Or am I misunderstanding what you meant there?)
  • As a personal opinion though, let me share that I do not really follow the rationale for not considering vet the correct place for checks involving (mis)uses of the standard library. It is definitely not intuitive why that would be the case, given that the standard library can not be really considered "not being part of go" (from the point of view of the spec, maybe, but I would argue that the fraction of Go programs and developers that rely exclusively on the spec and not on the standard library is rather small).
    Indeed, this criterion is somewhat undermined by the impression that a significant number of the existing vet checks (almost half?) are actually about various types of standard library misuse (atomic, copylocks, httpresponse, lostcancel, printf, stdmethods, structtag, tests, unmarshal, unsafeptr). While it's undoubtedly true that the kind of each one of these tests may differ, AFAICT they share in their nature of being about some semantic aspect of the standard library.
@timothy-king
Copy link
Contributor

@timothy-king timothy-king commented Jun 25, 2021

Indeed, this criterion is somewhat undermined by the impression that a significant number of the existing vet checks (almost half?) are actually about various types of standard library misuse (atomic, copylocks, httpresponse, lostcancel, printf, stdmethods, structtag, tests, unmarshal, unsafeptr).

You can also included atomicalign, deepequalerrors , errorsas, and sortslice .

Vet mostly stays away from the standard library.

I am not following this claim either given the precedent for including checks against the standard library within vet.

But Printf is far more core to the use of Go than, say, templates, or even regular expressions.

Does "core"-ness come down to just the "frequency" requirement of vet?

Anyhow my preference would be to have 4 discussions: duplicates in string cutsets, regexg.MustCompile, non-http urls, and invalid template text. I think combining these 4 cases is distracting. Each case will have a different frequency concern. @dominikh brought up false positives for one of the cases that does not apply to the others. I also not sure if constant-ish is interesting for all of these cases (or what constant-ish means). For example, it is not clear whether we should check regexp.MustCompile for invalid constant prefixes with variable suffices. (That seems complicated for not much gain compared to an inferred constant value.) There might be enough underlying similarities that grouping them would help justify creating a new checker? Say in aggregate they are frequent enough, but not individually?

@rsc
Copy link
Contributor

@rsc rsc commented Jul 14, 2021

It's hard to tell exactly where the line is, but http.Do/Get/Post, regexp.Compile, text/template.Parse all return errors that users are expected to check. It doesn't seem like vet needs to repeat these, and it really doesn't seem like vet should link in the template parser.

The http.NewRequest example is an incorrect check, since non-HTTP methods are permitted (and it returns an error anyway).

The strings.Trim examples may be worth adding. They are clear errors, and it comes up more often than we'd like because people confuse Trim/TrimLeft for TrimPrefix and TrimRight for TrimSuffix. The check wouldn't catch all such cases, but it could catch some. If someone has any data on how often that happens, we could narrow the issue to that check.

@rsc rsc changed the title proposal: cmd/vet: report suspicious constant string arguments proposal: cmd/vet: report strings.Trim/TrimLeft/TrimRight with duplicate runes in cutset Jul 28, 2021
@rsc
Copy link
Contributor

@rsc rsc commented Jul 28, 2021

Based on the discussion, retitled to be only about strings.Trim/TrimLeft/TrimRight, detecting something like strings.TrimLeft(s, "http://") that really wants strings.TrimPrefix.

@timothy-king
Copy link
Contributor

@timothy-king timothy-king commented Jul 28, 2021

In case @rsc's example is not obvious enough, strings.TrimLeft(s, "http://") has a cutset with duplicate runes {"t", "/"}. So a duplicate rune detector would catch this. I find this example fairly persuasive.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
Linked pull requests

Successfully merging a pull request may close this issue.

None yet
8 participants