Skip to content

cp: prevent panic in aligned_ancestors on shallow source paths#13275

Open
AnuthaDev wants to merge 1 commit into
uutils:mainfrom
AnuthaDev:9-cp-panic
Open

cp: prevent panic in aligned_ancestors on shallow source paths#13275
AnuthaDev wants to merge 1 commit into
uutils:mainfrom
AnuthaDev:9-cp-panic

Conversation

@AnuthaDev

@AnuthaDev AnuthaDev commented Jul 4, 2026

Copy link
Copy Markdown
Contributor

Problem

The aligned_ancestors function in src/uu/cp/src/cp.rs panicked when called with an empty source path, which has only 1 ancestor.
The root cause was unsafe slice indexing:

let n = source_ancestors.len();
let source_ancestors = &source_ancestors[1..n - 1]; // panics when n == 1

When n == 1 (empty source ""), the range [1..0] has start > end and panics.

Reproduction

$ mkdir -p /tmp/dest
$ cp --parents "" /tmp/dest

thread 'main' panicked at src/uu/cp/src/cp.rs:2226:45:
slice index starts at 1 but ends at 0
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace

Fix

Rewrote aligned_ancestors to use iterator combinators instead of manual slice indexing.

Also reduced allocations from 3 Vecs (two ancestor collects + result) to 1 (the zip collect).

Tests

Added 3 unit tests in src/uu/cp/src/cp.rs:

  • test_aligned_ancestors_empty_source — empty source path (regression: previously panicked)
  • test_aligned_ancestors_single_component_source — single-component source (boundary: no intermediates)
  • test_aligned_ancestors_two_component_source — two-component source (boundary: 1 intermediate)

Added 1 integration test in tests/by-util/test_cp.rs:

  • test_cp_parents_empty_source_does_not_panic — verifies cp --parents "" dest
    fails gracefully with a "cannot stat" error instead of panicking

@AnuthaDev AnuthaDev changed the title fix(cp): prevent panic in aligned_ancestors on shallow source paths cp: prevent panic in aligned_ancestors on shallow source paths Jul 4, 2026
@github-actions

github-actions Bot commented Jul 4, 2026

Copy link
Copy Markdown

GNU testsuite comparison:

Skip an intermittent issue tests/date/date-locale-hour (fails in this run but passes in the 'main' branch)
Skipping an intermittent issue tests/date/resolution (passes in this run but fails in the 'main' branch)
Skipping an intermittent issue tests/tail/tail-n0f (passes in this run but fails in the 'main' branch)
Note: The gnu test tests/printf/printf-surprise is now being skipped but was previously passing.
Skip an intermittent issue tests/pr/bounded-memory (was skipped on 'main', now failing)

@codspeed-hq

codspeed-hq Bot commented Jul 4, 2026

Copy link
Copy Markdown

Merging this PR will not alter performance

✅ 331 untouched benchmarks
⏩ 46 skipped benchmarks1


Comparing AnuthaDev:9-cp-panic (2e028c7) with main (51529dc)

Open in CodSpeed

Footnotes

  1. 46 benchmarks were skipped, so the baseline results were used instead. If they were deleted from the codebase, click here and archive them to remove them from the performance reports.

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.

1 participant