From 66af48797802d44d898d6bbb0fe66d5bf2d60b8d Mon Sep 17 00:00:00 2001 From: Zhengchao An Date: Thu, 13 Aug 2026 03:41:09 +0800 Subject: [PATCH] docs(policy): pin the deliberate slash-only path.Clean duplication (#6013) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The policy crate's Go path.Clean port and rustfs-utils' Windows-aware clean look like duplicates but are not interchangeable: S3 ARN/resource matching must treat backslashes as object-name data, never as separators, so adopting the utils version would change policy evaluation semantics on Windows — a security-adjacent behavior change. Record that judgment as bidirectional do-not-merge notes on both implementations, per the issue's adversarial ruling. Comment-only change. Ref rustfs/backlog#1833 (PR7). --- crates/policy/src/policy/utils/path.rs | 9 +++++++++ crates/utils/src/path.rs | 6 ++++++ 2 files changed, 15 insertions(+) diff --git a/crates/policy/src/policy/utils/path.rs b/crates/policy/src/policy/utils/path.rs index 21cc296ec..f26634fb7 100644 --- a/crates/policy/src/policy/utils/path.rs +++ b/crates/policy/src/policy/utils/path.rs @@ -53,6 +53,15 @@ impl<'a> LazyBuf<'a> { } /// copy from golang(path.Clean) +/// +/// DELIBERATE DUPLICATION — do not replace with `rustfs_utils::path::clean`. +/// This is a faithful port of Go's slash-only `path.Clean`, which is what S3 +/// ARN/resource matching requires: policy resource paths are opaque S3 keys, +/// and a backslash in a key is object-name data, never a separator. The utils +/// version is Windows-aware (`filepath.Clean` semantics: converts backslashes +/// to forward slashes), so swapping it in would change policy evaluation on +/// Windows — a security-adjacent behavior change. Mirror note sits on the +/// utils implementation (backlog#1833). pub fn clean(path: &str) -> String { if path.is_empty() { return ".".into(); diff --git a/crates/utils/src/path.rs b/crates/utils/src/path.rs index d672302d4..c383dc822 100644 --- a/crates/utils/src/path.rs +++ b/crates/utils/src/path.rs @@ -444,6 +444,12 @@ impl LazyBuf { /// The returned path ends in a slash only if it represents a root directory, such as `/` on Unix or `C:/` on Windows. /// /// If the result of this process is an empty string, `clean` returns the string `.`. +/// +/// Note: `crates/policy/src/policy/utils/path.rs` deliberately keeps its own +/// slash-only Go `path.Clean` port instead of using this function — S3 +/// ARN/resource matching must not treat backslashes as separators, and this +/// Windows-aware version would change policy evaluation semantics on Windows. +/// Do not consolidate the two (backlog#1833). pub fn clean(path: &str) -> String { if path.is_empty() { return ".".to_string();