fix: don't conflate ZLIB_NG_* with ZLIB_* in symbol-version policy check#694
fix: don't conflate ZLIB_NG_* with ZLIB_* in symbol-version policy check#694Fedr wants to merge 1 commit into
Conversation
`versioned_symbols_policy` was bucketing every version tag by splitting
on the first underscore (`symbol.partition("_")`). For zlib-ng's
`ZLIB_NG_2.0.0` / `ZLIB_NG_2.1.0` tags this produced namespace `ZLIB`,
landing them in the same bucket as stock zlib's `ZLIB_1.2.0`. Policies
whose `ZLIB` allowlist did not contain `ZLIB_NG_*` (none do, since
libz-ng.so.2 is not a manylinux system library) then rejected the
wheel as carrying "too-recent versioned symbols", even though no actual
symbol was too recent.
Match the namespace with a regex that requires a trailing numeric
version (`\d+(?:[._]\d+)*`), so `ZLIB_NG_2.0.0` resolves to namespace
`ZLIB_NG` instead of `ZLIB`. Tags whose suffix is not a numeric version
(e.g. `GLIBC_PRIVATE`, or fully bare tokens with no `_`) fall back to
the original first-underscore split so existing behavior is preserved.
Because `ZLIB_NG` does not appear in any policy's `symbol_versions`
map, `policy_is_satisfied`'s existing `set(required_vers) &
set(policy_sym_vers)` intersection then drops it from the check
entirely -- the same way any other unmodelled namespace already is --
and the wheel passes. The bucketing change also disambiguates
`CXXABI_LDBL_*.*` from `CXXABI_*.*`, which had the same class of bug.
Fixes pypa#613.
There was a problem hiding this comment.
Pull request overview
This PR fixes versioned_symbols_policy so it no longer conflates multi-underscore symbol-version namespaces (e.g., ZLIB_NG_*, CXXABI_LDBL_*) with their shorter prefixes (e.g., ZLIB_*, CXXABI_*), addressing auditwheel issue #613.
Changes:
- Add a regex-based namespace extractor that requires a trailing numeric version component, preserving legacy behavior for non-numeric suffixes (e.g.,
GLIBC_PRIVATE). - Update symbol-version bucketing to use the regex when applicable, preventing namespace collisions.
- Add a regression test ensuring
ZLIB_NG_*does not “poison” theZLIBbucket and is ignored as an unmodeled namespace.
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated no comments.
| File | Description |
|---|---|
| tests/unit/test_policy.py | Adds regression coverage for zlib-ng symbol-version tags not being bucketed under ZLIB. |
| src/auditwheel/policy/init.py | Changes symbol-version tag bucketing logic to correctly handle multi-underscore namespaces with numeric version tails. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #694 +/- ##
=======================================
Coverage 95.34% 95.35%
=======================================
Files 22 22
Lines 1870 1872 +2
Branches 355 355
=======================================
+ Hits 1783 1785 +2
Misses 48 48
Partials 39 39 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
In this case, I think it's not a bug. Thus it feels safer just to add an exception for |
Fixes #613.
Why
versioned_symbols_policybuckets every version tag by splitting on the first underscore:For zlib-ng's
ZLIB_NG_2.0.0/ZLIB_NG_2.1.0tags this produces namespaceZLIB, landing them in the same bucket as stock zlib'sZLIB_1.2.0. Policies whoseZLIBallowlist does not containZLIB_NG_*(none do — libz-ng.so.2 is not a manylinux system library) then reject the wheel as carrying "too-recent versioned symbols", even though no symbol is actually too recent. This is exactly what #613 reports, and matches @mayeut's diagnosis on that issue:The same class of bug also bites
CXXABI_LDBL_*.*(long-double-specific libstdc++ symbols), which currently get bucketed intoCXXABIand collide withCXXABI_*.*.What
Match the namespace with a regex that requires a trailing numeric version (
\d+(?:[._]\d+)*):Now
ZLIB_NG_2.0.0resolves to namespaceZLIB_NGinstead ofZLIB, andCXXABI_LDBL_1.3resolves toCXXABI_LDBLinstead ofCXXABI. Tags whose suffix is not a numeric version (e.g.GLIBC_PRIVATE, or fully bare tokens with no_) fall back to the original first-underscore split so existing behavior is preserved.Because
ZLIB_NGandCXXABI_LDBLdon't appear in any policy'ssymbol_versionsmap, the existingset(required_vers) & set(policy_sym_vers)intersection inpolicy_is_satisfiedthen drops them from the check entirely — the same way any other unmodelled namespace (e.g.OPENSSL,LIBSSL) already is — and the wheel passes.Test
Added
test_policy_does_not_conflate_zlib_ng_with_zlibcovering:ZLIB_NG_*tags is accepted (was rejected before).ZLIB_1.2.0andZLIB_NG_2.0.0doesn't poison theZLIBbucket — theZLIB_1.2.0check still has to pass on its own.The new test plus all existing
test_policy.pytests pass:(The remaining unit-test failures on Windows are pre-existing environmental issues — symlink privilege, Linux-only ctypes for
test_libc.py, Unix permission modes intest_tools.py— and are unrelated to this change.)