diff options
author | rillig <rillig@pkgsrc.org> | 2019-05-06 20:27:17 +0000 |
---|---|---|
committer | rillig <rillig@pkgsrc.org> | 2019-05-06 20:27:17 +0000 |
commit | 916339bb022f0f3e4e1da5f753114ce4b8d69709 (patch) | |
tree | e2358c7c52324fbad66bfd953ea252d6197ffed5 /pkgtools/pkglint/files/shell.go | |
parent | 3e83a6c4d69c38a42d8a7a8b46cba5f3e4ea734d (diff) | |
download | pkgsrc-916339bb022f0f3e4e1da5f753114ce4b8d69709.tar.gz |
pkgtools/pkglint: update to 5.7.9
Changes since 5.7.8:
* Buildlink3.mk files are checked for typos in the identifier that is
used for BUILDLINK_TREE, to detect copy-and-paste mistakes.
* Having a rationale is recommended for some variables, especially those
that make a package fail to build or crash at runtime. This check is
only active when -Wextra is given, since it is still actively debated
whether such a check is actually useful.
* Files called Makefile.php can easily be mistaken to be PHP files.
Therefore the recommended naming convention is to have auxiliary files
called *.mk. There are already many more files called *.mk than those
being called Makefile.*.
* The check for unquoted sed substitution commands has been made more
detailed, but since it is completely disabled, there's nothing to see
for now.
* The definitions for MASTER_SITE_* are loaded directly from the pkgsrc
infrastructure instead of hard-coding them in pkglint.
Diffstat (limited to 'pkgtools/pkglint/files/shell.go')
-rw-r--r-- | pkgtools/pkglint/files/shell.go | 71 |
1 files changed, 58 insertions, 13 deletions
diff --git a/pkgtools/pkglint/files/shell.go b/pkgtools/pkglint/files/shell.go index 98e50c70c36..35e23aea7fd 100644 --- a/pkgtools/pkglint/files/shell.go +++ b/pkgtools/pkglint/files/shell.go @@ -189,10 +189,30 @@ func (ck *ShellLineChecker) checkVaruseToken(atoms *[]*ShAtom, quoting ShQuoting // This is ok as long as these variables don't have embedded [$\\"'`]. case quoting == shqDquot && varuse.IsQ(): - ck.mkline.Warnf("The :Q modifier should not be used inside double quotes.") - ck.mkline.Explain( + ck.Warnf("The :Q modifier should not be used inside double quotes.") + ck.Explain( + "The :Q modifier is intended for embedding a string into a shell program.", + "It escapes all characters that have a special meaning in shell programs.", + "It only works correctly when it appears outside of \"double\" or 'single'", + "quotes or `backticks`.", + "", + "When it is used inside double quotes or backticks, the resulting string may", + "contain more backslashes than intended.", + "", + "When it is used inside single quotes and the string contains a single quote", + "itself, it produces syntax errors in the shell.", + "", "To fix this warning, either remove the :Q or the double quotes.", - "In most cases, it is more appropriate to remove the double quotes.") + "In most cases, it is more appropriate to remove the double quotes.", + "", + "A special case is for empty strings.", + "If the empty string should be preserved as an empty string,", + "the correct form is ${VAR:Q}'' with either leading or trailing single or double quotes.", + "If the empty string should just be skipped,", + "a simple ${VAR:Q} without any surrounding quotes is correct.") + + // TODO: What about single quotes? + // TODO: What about backticks? } if ck.checkVarUse { @@ -623,17 +643,42 @@ func (scc *SimpleCommandChecker) checkRegexReplace() { defer trace.Call0()() } - cmdname := scc.strcmd.Name - isSubst := false - for _, arg := range scc.strcmd.Args { - if G.Testing && isSubst && !matches(arg, `"^[\"\'].*[\"\']$`) { - scc.Warnf("Substitution commands like %q should always be quoted.", arg) - scc.Explain( - "Usually these substitution commands contain characters like '*' or", - "other shell metacharacters that might lead to lookup of matching", - "filenames and then expand to more than one word.") + if !G.Testing { + return + } + + checkArg := func(arg string) { + if matches(arg, `"^[\"\'].*[\"\']$`) { + return } - isSubst = cmdname == "${PAX}" && arg == "-s" || cmdname == "${SED}" && arg == "-e" + + // Substitution commands that consist only of safe characters cannot + // have any side effects, therefore they don't need to be quoted. + if matches(arg, `^([\w,.]|\\[.])+$`) { + return + } + + scc.Warnf("Substitution commands like %q should always be quoted.", arg) + scc.Explain( + "Usually these substitution commands contain characters like '*' or", + "other shell metacharacters that might lead to lookup of matching", + "filenames and then expand to more than one word.") + } + + checkArgAfter := func(opt string) { + args := scc.strcmd.Args + for i, arg := range args { + if i > 0 && args[i-1] == opt { + checkArg(arg) + } + } + } + + switch scc.strcmd.Name { + case "${PAX}", "pax": + checkArgAfter("-s") + case "${SED}", "sed": + checkArgAfter("-e") } } |