commit:     5fc63263f3f08b2c1bbd9ec02314c28947023501
Author:     Arthur Zamarin <arthurzam <AT> gentoo <DOT> org>
AuthorDate: Mon Oct 21 17:17:21 2024 +0000
Commit:     Arthur Zamarin <arthurzam <AT> gentoo <DOT> org>
CommitDate: Fri Feb  7 19:13:31 2025 +0000
URL:        
https://gitweb.gentoo.org/proj/pkgcore/pkgcheck.git/commit/?id=5fc63263

NonConsistentTarUsage: check tar without -f

The ``tar`` command defaults to reading from stdin, unless this default is
changed at compile time or the ``TAPE`` environment variable is set.

To ensure consistent behavior, the ``-f`` or ``--file`` option should
always be given to ensure the input device is chosen explicitly.

Resolves: https://github.com/pkgcore/pkgcheck/issues/704
Signed-off-by: Arthur Zamarin <arthurzam <AT> gentoo.org>

 src/pkgcheck/checks/codingstyle.py                 | 29 +++++++++++++++++++++-
 .../NonConsistentTarUsage/expected.json            |  2 ++
 .../NonPosixCheck/NonConsistentTarUsage/fix.patch  | 13 ++++++++++
 .../NonConsistentTarUsage-0.ebuild                 | 16 ++++++++++++
 4 files changed, 59 insertions(+), 1 deletion(-)

diff --git a/src/pkgcheck/checks/codingstyle.py 
b/src/pkgcheck/checks/codingstyle.py
index 257fb9db..b49ffced 100644
--- a/src/pkgcheck/checks/codingstyle.py
+++ b/src/pkgcheck/checks/codingstyle.py
@@ -1426,11 +1426,26 @@ class NonPosixHeadTailUsage(results.LineResult, 
results.Warning):
         return f"line {self.lineno}: non-posix usage of {self.command!r}: 
{self.line!r}"
 
 
+class NonConsistentTarUsage(results.LineResult, results.Warning):
+    """Using of non-consistent compliant ``tar``.
+
+    The ``tar`` command defaults to reading from stdin, unless this default is
+    changed at compile time or the ``TAPE`` environment variable is set.
+
+    To ensure consistent behavior, the ``-f`` or ``--file`` option should
+    always be given to ensure the input device is chosen explicitly.
+    """
+
+    @property
+    def desc(self):
+        return f"line {self.lineno}: non-consistent usage of tar without '-f' 
or '--file': {self.line!r}"
+
+
 class NonPosixCheck(Check):
     """Scan ebuild for non-posix usage, code which might be not portable."""
 
     _source = sources.EbuildParseRepoSource
-    known_results = frozenset([NonPosixHeadTailUsage])
+    known_results = frozenset({NonPosixHeadTailUsage, NonConsistentTarUsage})
 
     def __init__(self, options, **kwargs):
         super().__init__(options, **kwargs)
@@ -1449,11 +1464,23 @@ class NonPosixCheck(Check):
                 break
             prev_arg = arg
 
+    def check_tar(self, pkg, call_node):
+        for idx, arg in enumerate(map(pkg.node_str, call_node.children[1:])):
+            if idx == 0 or (arg[:1] == "-" and arg[1:2] != "-"):
+                if "f" in arg:
+                    return
+            elif arg == "--file" or arg.startswith("--file="):
+                return
+        lineno, _ = call_node.start_point
+        yield NonConsistentTarUsage(lineno=lineno + 1, 
line=pkg.node_str(call_node), pkg=pkg)
+
     def feed(self, pkg):
         for call_node in 
bash.cmd_query.captures(pkg.tree.root_node).get("call", ()):
             call_name = pkg.node_str(call_node.child_by_field_name("name"))
             if call_name in ("head", "tail"):
                 yield from self.check_head_tail(pkg, call_node, call_name)
+            elif call_name == "tar":
+                yield from self.check_tar(pkg, call_node)
 
 
 class GlobDistdir(results.LineResult, results.Warning):

diff --git 
a/testdata/data/repos/standalone/NonPosixCheck/NonConsistentTarUsage/expected.json
 
b/testdata/data/repos/standalone/NonPosixCheck/NonConsistentTarUsage/expected.json
new file mode 100644
index 00000000..cdccb5ad
--- /dev/null
+++ 
b/testdata/data/repos/standalone/NonPosixCheck/NonConsistentTarUsage/expected.json
@@ -0,0 +1,2 @@
+{"__class__": "NonConsistentTarUsage", "category": "NonPosixCheck", "package": 
"NonConsistentTarUsage", "version": "0", "line": "tar -zx \"${A}\"", "lineno": 
7}
+{"__class__": "NonConsistentTarUsage", "category": "NonPosixCheck", "package": 
"NonConsistentTarUsage", "version": "0", "line": "tar c \\\n\t\t--owner=0 
\\\n\t\t--group=0 \\\n\t\t--numeric-owner \\\n\t\t-C \"${S}\" .", "lineno": 8}

diff --git 
a/testdata/data/repos/standalone/NonPosixCheck/NonConsistentTarUsage/fix.patch 
b/testdata/data/repos/standalone/NonPosixCheck/NonConsistentTarUsage/fix.patch
new file mode 100644
index 00000000..831101b2
--- /dev/null
+++ 
b/testdata/data/repos/standalone/NonPosixCheck/NonConsistentTarUsage/fix.patch
@@ -0,0 +1,13 @@
+--- 
standalone/NonPosixCheck/NonConsistentTarUsage/NonConsistentTarUsage-0.ebuild
++++ fixed/NonPosixCheck/NonConsistentTarUsage/NonConsistentTarUsage-0.ebuild
+@@ -4,8 +4,8 @@ LICENSE="BSD"
+ SLOT="0"
+
+ src_prepare() {
+-      tar -zx "${A}"
+-      tar c \
++      tar -zx -f - "${A}"
++      tar cf - \
+               --owner=0 \
+               --group=0 \
+               --numeric-owner \

diff --git 
a/testdata/repos/standalone/NonPosixCheck/NonConsistentTarUsage/NonConsistentTarUsage-0.ebuild
 
b/testdata/repos/standalone/NonPosixCheck/NonConsistentTarUsage/NonConsistentTarUsage-0.ebuild
new file mode 100644
index 00000000..934a2076
--- /dev/null
+++ 
b/testdata/repos/standalone/NonPosixCheck/NonConsistentTarUsage/NonConsistentTarUsage-0.ebuild
@@ -0,0 +1,16 @@
+DESCRIPTION="Ebuild with non posix tar usage"
+HOMEPAGE="https://github.com/pkgcore/pkgcheck";
+LICENSE="BSD"
+SLOT="0"
+
+src_prepare() {
+       tar -zx "${A}"
+       tar c \
+               --owner=0 \
+               --group=0 \
+               --numeric-owner \
+               -C "${S}" . | something
+       tar -c -f - -C "${S}" . | something
+       tar -c --file - -C "${S}" . | something
+       tar -c --file=- -C "${S}" . | something
+}

Reply via email to