commit:     4007f00c7833aae6e455ee1b50d50a7c1d10799f
Author:     Arthur Zamarin <arthurzam <AT> gentoo <DOT> org>
AuthorDate: Sat Jan 13 09:46:54 2024 +0000
Commit:     Arthur Zamarin <arthurzam <AT> gentoo <DOT> org>
CommitDate: Sun Jan 14 18:14:37 2024 +0000
URL:        
https://gitweb.gentoo.org/proj/pkgcore/pkgcheck.git/commit/?id=4007f00c

SandboxCallCheck: new check for invalid sandbox calls

Catches multiple arguments passed to function, and colon separated path.

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

 src/pkgcheck/checks/codingstyle.py                 | 33 ++++++++++++++++++++++
 .../InvalidSandboxCall/expected.json               |  2 ++
 .../SandboxCallCheck/InvalidSandboxCall/fix.patch  | 17 +++++++++++
 .../InvalidSandboxCall/InvalidSandboxCall-0.ebuild | 12 ++++++++
 4 files changed, 64 insertions(+)

diff --git a/src/pkgcheck/checks/codingstyle.py 
b/src/pkgcheck/checks/codingstyle.py
index 90cb03b2..67dbe6c1 100644
--- a/src/pkgcheck/checks/codingstyle.py
+++ b/src/pkgcheck/checks/codingstyle.py
@@ -1539,3 +1539,36 @@ class DeclarationShadowedCheck(Check):
             if len(nodes) > 1:
                 lines = sorted(node.start_point[0] + 1 for node in nodes)
                 yield DuplicateFunctionDefinition(func_name, lines=lines, 
pkg=pkg)
+
+
+class InvalidSandboxCall(results.LineResult, results.Error):
+    """Invalid call to a sandbox function.
+
+    According to PMS and the Devmanual [#]_, only a single item is allowed as
+    argument for ``addread``, ``addwrite``, ``adddeny``, and ``addpredict``.
+    Multiple path items should not be passed as a colon-separated list.
+
+    .. [#] https://devmanual.gentoo.org/function-reference/sandbox-functions/
+    """
+
+    @property
+    def desc(self):
+        return f"line {self.lineno}: invalid call to sandbox function: 
{self.line}"
+
+
+class SandboxCallCheck(Check):
+    """Scan ebuilds for correct sandbox funcitons usage."""
+
+    _source = sources.EbuildParseRepoSource
+    known_results = frozenset({InvalidSandboxCall})
+
+    functions = frozenset({"addread", "addwrite", "adddeny", "addpredict"})
+
+    def feed(self, pkg: bash.ParseTree):
+        for node, _ in bash.cmd_query.captures(pkg.tree.root_node):
+            name = pkg.node_str(node.child_by_field_name("name"))
+            if name in self.functions:
+                args = node.children_by_field_name("argument")
+                if len(args) != 1 or ":" in pkg.node_str(args[0]):
+                    lineno, _ = node.start_point
+                    yield InvalidSandboxCall(line=pkg.node_str(node), 
lineno=lineno + 1, pkg=pkg)

diff --git 
a/testdata/data/repos/standalone/SandboxCallCheck/InvalidSandboxCall/expected.json
 
b/testdata/data/repos/standalone/SandboxCallCheck/InvalidSandboxCall/expected.json
new file mode 100644
index 00000000..bb9a6894
--- /dev/null
+++ 
b/testdata/data/repos/standalone/SandboxCallCheck/InvalidSandboxCall/expected.json
@@ -0,0 +1,2 @@
+{"__class__": "InvalidSandboxCall", "category": "SandboxCallCheck", "package": 
"InvalidSandboxCall", "version": "0", "line": "addpredict /etc/dfs:/dev/zfs", 
"lineno": 7}
+{"__class__": "InvalidSandboxCall", "category": "SandboxCallCheck", "package": 
"InvalidSandboxCall", "version": "0", "line": "addwrite /dev /etc", "lineno": 
11}

diff --git 
a/testdata/data/repos/standalone/SandboxCallCheck/InvalidSandboxCall/fix.patch 
b/testdata/data/repos/standalone/SandboxCallCheck/InvalidSandboxCall/fix.patch
new file mode 100644
index 00000000..7f28be1a
--- /dev/null
+++ 
b/testdata/data/repos/standalone/SandboxCallCheck/InvalidSandboxCall/fix.patch
@@ -0,0 +1,17 @@
+diff -Naur 
standalone/SandboxCallCheck/InvalidSandboxCall/InvalidSandboxCall-0.ebuild 
fixed/SandboxCallCheck/InvalidSandboxCall/InvalidSandboxCall-0.ebuild
+--- standalone/SandboxCallCheck/InvalidSandboxCall/InvalidSandboxCall-0.ebuild
++++ fixed/SandboxCallCheck/InvalidSandboxCall/InvalidSandboxCall-0.ebuild
+@@ -4,9 +4,11 @@ SLOT="0"
+ LICENSE="BSD"
+
+ src_compile() {
+-      addpredict /etc/dfs:/dev/zfs
++      addpredict /etc/dfs
++      addpredict /dev/zfs
+ }
+
+ src_test() {
+-      addwrite /dev /etc
++      addwrite /dev
++      addwrite /etc
+ }

diff --git 
a/testdata/repos/standalone/SandboxCallCheck/InvalidSandboxCall/InvalidSandboxCall-0.ebuild
 
b/testdata/repos/standalone/SandboxCallCheck/InvalidSandboxCall/InvalidSandboxCall-0.ebuild
new file mode 100644
index 00000000..97062656
--- /dev/null
+++ 
b/testdata/repos/standalone/SandboxCallCheck/InvalidSandboxCall/InvalidSandboxCall-0.ebuild
@@ -0,0 +1,12 @@
+DESCRIPTION="Ebuild with invalid sandbox calls"
+HOMEPAGE="https://github.com/pkgcore/pkgcheck";
+SLOT="0"
+LICENSE="BSD"
+
+src_compile() {
+       addpredict /etc/dfs:/dev/zfs
+}
+
+src_test() {
+       addwrite /dev /etc
+}

Reply via email to