Skip to content

fix: don't conflate ZLIB_NG_* with ZLIB_* in symbol-version policy check#694

Open
Fedr wants to merge 1 commit intopypa:mainfrom
Fedr:fix/zlib-ng-version-tag-matching
Open

fix: don't conflate ZLIB_NG_* with ZLIB_* in symbol-version policy check#694
Fedr wants to merge 1 commit intopypa:mainfrom
Fedr:fix/zlib-ng-version-tag-matching

Conversation

@Fedr
Copy link
Copy Markdown

@Fedr Fedr commented Apr 29, 2026

Fixes #613.

Why

versioned_symbols_policy buckets every version tag by splitting on the first underscore:

sym_name, _, _ = symbol.partition("_")
required_vers.setdefault(sym_name, set()).add(symbol)

For zlib-ng's ZLIB_NG_2.0.0 / ZLIB_NG_2.1.0 tags this produces namespace ZLIB, landing them in the same bucket as stock zlib's ZLIB_1.2.0. Policies whose ZLIB allowlist does not contain ZLIB_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:

it's not intended, needs a fix to exclude ZLIB_NG_*.

The same class of bug also bites CXXABI_LDBL_*.* (long-double-specific libstdc++ symbols), which currently get bucketed into CXXABI and collide with CXXABI_*.*.

What

Match the namespace with a regex that requires a trailing numeric version (\d+(?:[._]\d+)*):

_SYMBOL_VERSION_TAG_RE = re.compile(r"^([A-Za-z][A-Za-z0-9_]*?)_(\d+(?:[._]\d+)*)$")

Now ZLIB_NG_2.0.0 resolves to namespace ZLIB_NG instead of ZLIB, and CXXABI_LDBL_1.3 resolves to CXXABI_LDBL instead of CXXABI. 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 and CXXABI_LDBL don't appear in any policy's symbol_versions map, the existing set(required_vers) & set(policy_sym_vers) intersection in policy_is_satisfied then 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_zlib covering:

  • A wheel with only ZLIB_NG_* tags is accepted (was rejected before).
  • A wheel mixing ZLIB_1.2.0 and ZLIB_NG_2.0.0 doesn't poison the ZLIB bucket — the ZLIB_1.2.0 check still has to pass on its own.

The new test plus all existing test_policy.py tests pass:

============================= 19 passed in 0.15s ==============================

(The remaining unit-test failures on Windows are pre-existing environmental issues — symlink privilege, Linux-only ctypes for test_libc.py, Unix permission modes in test_tools.py — and are unrelated to this change.)

`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.
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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” the ZLIB bucket 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
Copy link
Copy Markdown

codecov Bot commented Apr 29, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 95.35%. Comparing base (e21df8b) to head (3ee74c6).

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.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@auvipy auvipy requested a review from mayeut April 29, 2026 17:54
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Unable to repair wheel that uses zlib-ng

2 participants