Repository: osbuild/osbuild
Pull request #1927 (2024-11-12 18:15:33)

util/osrelease.py:  improve quote stripping
- Enhanced the value stripping logic in osrelease parsing to handle leading and trailing spaces, newlines, tabs, and both single and double quotes.
- This ensures cleaner and more accurate key-value assignments.

ravanelli: @mvo5 , @supakeen can we get another review on it?

Patch:
diff --git a/osbuild/util/osrelease.py b/osbuild/util/osrelease.py
index b8d56e73..c7031a8a 100644
--- a/osbuild/util/osrelease.py
+++ b/osbuild/util/osrelease.py
@@ -5,6 +5,7 @@ related documentation can be found in `os-release(5)`.
 """
 
 import os
+import shlex
 
 # The default paths where os-release is located, as per os-release(5)
 DEFAULT_PATHS = [
@@ -33,7 +34,12 @@ def parse_files(*paths):
                 if line[0] == "#":
                     continue
                 key, value = line.split("=", 1)
-                osrelease[key] = value.strip('"')
+                split_value = shlex.split(value)
+                if not split_value:
+                    raise ValueError(f"Key '{key}' has an empty value")
+                if len(split_value) > 1:
+                    raise ValueError(f"Key '{key}' has more than one token: {value}")
+                osrelease[key] = split_value[0]
 
     return osrelease
 


Test patch:
diff --git a/test/data/os-release/fedora40 b/test/data/os-release/fedora40
new file mode 100644
index 00000000..7214dee8
--- /dev/null
+++ b/test/data/os-release/fedora40
@@ -0,0 +1,22 @@
+NAME="Fedora Linux"
+VERSION="40.20241106.dev.0 (CoreOS)"
+ID=fedora
+VERSION_ID=40
+VERSION_CODENAME=""
+PLATFORM_ID="platform:f40"
+PRETTY_NAME="Fedora CoreOS 40.20241106.dev.0"
+ANSI_COLOR="0;38;2;60;110;180"
+LOGO=fedora-logo-icon
+CPE_NAME="cpe:/o:fedoraproject:fedora:40"
+HOME_URL="https://getfedora.org/coreos/"
+DOCUMENTATION_URL="https://docs.fedoraproject.org/en-US/fedora-coreos/"
+SUPPORT_URL="https://github.com/coreos/fedora-coreos-tracker/"
+BUG_REPORT_URL="https://github.com/coreos/fedora-coreos-tracker/"
+REDHAT_BUGZILLA_PRODUCT="Fedora"
+REDHAT_BUGZILLA_PRODUCT_VERSION=40
+REDHAT_SUPPORT_PRODUCT="Fedora"
+REDHAT_SUPPORT_PRODUCT_VERSION=40
+SUPPORT_END=2025-05-13
+VARIANT="CoreOS"
+VARIANT_ID=coreos
+OSTREE_VERSION='40.20241106.dev.0'
diff --git a/test/mod/test_util_osrelease.py b/test/mod/test_util_osrelease.py
index 0b250ebc..d46549ce 100644
--- a/test/mod/test_util_osrelease.py
+++ b/test/mod/test_util_osrelease.py
@@ -5,6 +5,8 @@
 import os
 import unittest
 
+import pytest
+
 from osbuild.util import osrelease
 
 from .. import test
@@ -28,3 +30,23 @@ class TestUtilOSRelease(test.TestBase):
         for entry in os.scandir(os.path.join(self.locate_test_data(), "os-release")):
             with self.subTest(entry.name):
                 self.assertEqual(osrelease.describe_os(entry.path), entry.name)
+
+
+def test_osreleae_f40_really_coreos_happy():
+    here = os.path.dirname(__file__)
+    res = osrelease.parse_files(os.path.join(here, "../data/os-release/fedora40"))
+    assert res["NAME"] == 'Fedora Linux'
+    assert res["ID"] == 'fedora'
+    assert res["OSTREE_VERSION"] == '40.20241106.dev.0'
+
+
+@pytest.mark.parametrize("content,expected_err", [
+    ("OSTREE=", "Key 'OSTREE' has an empty value"),
+    ("OSTREE='foo' 'bar'", "Key 'OSTREE' has more than one token: 'foo' 'bar'"),
+])
+def test_osrelease_bad_split_empty(tmp_path, content, expected_err):
+    bad_os_release_path = tmp_path / "os-release"
+    bad_os_release_path.write_text(content + "\n")
+    with pytest.raises(ValueError) as exc:
+        osrelease.parse_files(bad_os_release_path)
+    assert str(exc.value) == expected_err