Skip to content

fix(services/upyun): do not panic when creating the service root - #8050

Open
PDGGK wants to merge 1 commit into
apache:mainfrom
PDGGK:fix-upyun-root-create-dir-panic
Open

fix(services/upyun): do not panic when creating the service root#8050
PDGGK wants to merge 1 commit into
apache:mainfrom
PDGGK:fix-upyun-root-create-dir-panic

Conversation

@PDGGK

@PDGGK PDGGK commented Aug 12, 2026

Copy link
Copy Markdown
Contributor

Which issue does this PR close?

None filed — reporting and fixing together.

Rationale of this change

UpyunCore::create_dir dropped the trailing slash by slicing off the last byte:

let path = build_abs_path(&self.root, path);
let path = path[..path.len() - 1].to_string();

build_abs_path returns an empty string when the root is / and the path is /:

pub fn build_abs_path(root: &str, path: &str) -> String {
    let p = root[1..].to_string();   // "/" -> ""
    if path == "/" { p } else { ... }
}

so path.len() - 1 underflows and the call panics with attempt to subtract with overflow instead of returning a Result.

The root is reachable from the public API. Operator::create_dir only rejects a path that does not end with /:

if !validate_path(&path, EntryMode::DIR) { return Err(...) }

and "/" does end with /, so op.create_dir("/").await on a default-rooted upyun operator panics inside the library rather than returning an error.

This was the only remaining len() - 1] slice under core/services. The sibling services already use trim_end_matches('/') for exactly this (azdls/src/core.rs uses it in five places), which is total and produces an identical result for a normalized path, since normalize_path leaves exactly one trailing slash.

Are there any user-facing changes?

A panic becomes ordinary behaviour: the request is built against the bucket root and the service's own response decides the outcome. No change for any non-root path.

Tests

Two unit tests on the extracted folder_path helper. The root case panics against the previous expression:

thread 'core::tests::folder_path_handles_the_service_root' panicked at
  services/upyun/src/core.rs:79:12: attempt to subtract with overflow
test result: FAILED. 3 passed; 1 failed

The trailing-slash case passes both before and after, so it serves as the control showing the first is not trivially red.

With the fix: 4/4 pass. cargo fmt --check exits 0, cargo clippy --all-targets is clean.

create_dir sliced the last byte off the absolute path to drop its
trailing slash:

    let path = build_abs_path(&self.root, path);
    let path = path[..path.len() - 1].to_string();

build_abs_path returns an empty string when the root is / and the path
is /, so path.len() - 1 underflows and the call panics with "attempt to
subtract with overflow" rather than returning a Result.

The root is reachable from the public API: Operator::create_dir only
rejects a path that does not end with /, and / does end with /, so
op.create_dir("/") on a default-rooted upyun operator panics inside the
library.

This was the only `len() - 1]` slice left in core/services; the sibling
services already use trim_end_matches('/') for this, which is total and
identical for a normalized path since normalize_path leaves exactly one
trailing slash.

Two unit tests. The root one panics against the previous expression;
the trailing-slash one passes either way, so it is a control rather
than a second copy of the same assertion.
@PDGGK
PDGGK requested a review from Xuanwo as a code owner August 12, 2026 01:23
@dosubot dosubot Bot added size:M This PR changes 30-99 lines, ignoring generated files. releases-note/fix The PR fixes a bug or has a title that begins with "fix" labels Aug 12, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

releases-note/fix The PR fixes a bug or has a title that begins with "fix" size:M This PR changes 30-99 lines, ignoring generated files.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant