commit:     e37b148ae13dc7f28e47f78c5a4ec724895d4d5f
Author:     Zac Medico <zmedico <AT> gentoo <DOT> org>
AuthorDate: Sat Nov 22 23:06:19 2025 +0000
Commit:     Zac Medico <zmedico <AT> gentoo <DOT> org>
CommitDate: Mon Nov 24 21:41:19 2025 +0000
URL:        https://gitweb.gentoo.org/proj/portage.git/commit/?id=e37b148a

_parse_build_id: use _pkg_split for accuracy

Use _pkgsplit to ensure that a version is not confused with a build_id.

Bug: https://bugs.gentoo.org/966349
Signed-off-by: Zac Medico <zmedico <AT> gentoo.org>

 lib/portage/dbapi/bintree.py                     | 16 +++++++++++++---
 lib/portage/tests/dbapi/meson.build              |  1 +
 lib/portage/tests/dbapi/test_bintree_build_id.py | 23 +++++++++++++++++++++++
 3 files changed, 37 insertions(+), 3 deletions(-)

diff --git a/lib/portage/dbapi/bintree.py b/lib/portage/dbapi/bintree.py
index c1d55499a6..8f5499eafe 100644
--- a/lib/portage/dbapi/bintree.py
+++ b/lib/portage/dbapi/bintree.py
@@ -64,7 +64,6 @@ import codecs
 import errno
 import io
 import json
-import re
 import shlex
 import stat
 import subprocess
@@ -2519,6 +2518,8 @@ class binarytree:
 
     @staticmethod
     def _parse_build_id(filename):
+        from portage.versions import _pkgsplit
+
         build_id = -1
         if filename.endswith(SUPPORTED_XPAK_EXTENSIONS):
             suffixlen = len(".xpak")
@@ -2528,8 +2529,17 @@ class binarytree:
             raise InvalidBinaryPackageFormat(filename)
 
         filename = filename[:-suffixlen]
-        if re.match(r".*-[\w.]*\d+[\w.]*-\d+$", filename):
-            build_id = int(filename.split("-")[-1])
+        filename = os.path.basename(filename)
+        filename_split = filename.rsplit("-", 1)
+        if len(filename_split) == 2:
+            pf, build_id_str = filename_split
+            # Use _pkgsplit to ensure that a version is not confused with a 
build_id.
+            pf_split = _pkgsplit(pf)
+            if pf_split is not None:
+                try:
+                    build_id = int(build_id_str)
+                except ValueError:
+                    pass
 
         return build_id
 

diff --git a/lib/portage/tests/dbapi/meson.build 
b/lib/portage/tests/dbapi/meson.build
index bbfb7f97ae..f7a360e1c8 100644
--- a/lib/portage/tests/dbapi/meson.build
+++ b/lib/portage/tests/dbapi/meson.build
@@ -2,6 +2,7 @@ py.install_sources(
     [
         'test_auxdb.py',
         'test_bintree.py',
+        'test_bintree_build_id.py',
         'test_fakedbapi.py',
         'test_portdb_cache.py',
         '__init__.py',

diff --git a/lib/portage/tests/dbapi/test_bintree_build_id.py 
b/lib/portage/tests/dbapi/test_bintree_build_id.py
new file mode 100644
index 0000000000..60b8706152
--- /dev/null
+++ b/lib/portage/tests/dbapi/test_bintree_build_id.py
@@ -0,0 +1,23 @@
+# Copyright 2025 Gentoo Authors
+# Distributed under the terms of the GNU General Public License v2
+
+from portage.tests import TestCase
+
+from portage.dbapi.bintree import binarytree
+
+
+class BinarytreeBuildIdTestCase(TestCase):
+    def testBinarytreeBuildId(self):
+        cases = {
+            "sec-keys/openpgp-keys-bzip2-20220406.gpkg.tar": -1,
+            
"sec-keys/openpgp-keys-bzip2/openpgp-keys-bzip2-20220406-1.gpkg.tar": 1,
+            "sec-keys/openpgp-keys-bzip2-20220406.xpak": -1,
+            "sec-keys/openpgp-keys-bzip2/openpgp-keys-bzip2-20220406-1.xpak": 
1,
+        }
+        for filename, expected_build_id in cases.items():
+            build_id = binarytree._parse_build_id(filename)
+            self.assertEqual(
+                build_id,
+                expected_build_id,
+                msg=f"Failed to parse build ID from '{filename}'",
+            )

Reply via email to