diff --git a/core/core/src/raw/path.rs b/core/core/src/raw/path.rs index 55733f47cec9..9de980248373 100644 --- a/core/core/src/raw/path.rs +++ b/core/core/src/raw/path.rs @@ -90,14 +90,12 @@ pub fn build_rel_path(root: &str, path: &str) -> String { /// /// # Normalize Rules /// -/// - All whitespace will be trimmed: ` abc/def ` => `abc/def` /// - All leading / will be trimmed: `///abc` => `abc` /// - Internal // will be replaced by /: `abc///def` => `abc/def` /// - Empty path will be `/`: `` => `/` pub fn normalize_path(path: &str) -> String { - // - all whitespace has been trimmed. // - all leading `/` has been trimmed. - let path = path.trim().trim_start_matches('/'); + let path = path.trim_start_matches('/'); // Fast line for empty path. if path.is_empty() { @@ -284,7 +282,16 @@ mod tests { ("abs dir path with extra /", "///abc/def/", "abc/def/"), ("file path contains ///", "abc///def", "abc/def"), ("dir path contains ///", "abc///def///", "abc/def/"), - ("file with whitespace", "abc/def ", "abc/def"), + ( + "file path contains trailing whitespace", + "abc/def ", + "abc/def ", + ), + ( + "file path contains leading whitespace", + " abc/def", + " abc/def", + ), ]; for (name, input, expect) in cases { diff --git a/core/tests/behavior/async_read.rs b/core/tests/behavior/async_read.rs index 89fedf164b91..3cdafd849a0f 100644 --- a/core/tests/behavior/async_read.rs +++ b/core/tests/behavior/async_read.rs @@ -50,6 +50,7 @@ pub fn tests(op: &Operator, tests: &mut Vec) { test_read_with_if_unmodified_since, test_read_with_dir_path, test_read_with_special_chars, + test_read_with_trailing_space, test_read_with_override_cache_control, test_read_with_override_content_disposition, test_read_with_override_content_type, @@ -550,6 +551,22 @@ pub async fn test_read_with_special_chars(op: Operator) -> anyhow::Result<()> { Ok(()) } +/// Read file with trailing space should succeed. +pub async fn test_read_with_trailing_space(op: Operator) -> anyhow::Result<()> { + let path = format!("{} ", uuid::Uuid::new_v4()); + let (path, content, size) = TEST_FIXTURE.new_file_with_path(op.clone(), &path); + + op.write(&path, content.clone()) + .await + .expect("write must succeed"); + + let bs = op.read(&path).await?.to_bytes(); + assert_eq!(size, bs.len(), "read size"); + assert_eq!(sha256_digest(&bs), sha256_digest(&content), "read content"); + + Ok(()) +} + /// Read file with override-cache-control should succeed. pub async fn test_read_with_override_cache_control(op: Operator) -> anyhow::Result<()> { if !(op.info().full_capability().read_with_override_cache_control