Skip to content

Commit

Permalink
fix: Query string percent-encoded in import map (denoland#11976)
Browse files Browse the repository at this point in the history
This commit fixes a problem in import map when resolving
specifiers containing "?" or "#". 

Due to special handling of Windows specifiers required because 
of how "url" crate works, a regression was introduced that percent-encoded
all parts of URL that were not considered "path segments".

Co-authored-by: Andreu Botella <abb@randomunok.com>
  • Loading branch information
bartlomieju and Andreu Botella committed Sep 11, 2021
1 parent fa96390 commit bd4ca72
Showing 1 changed file with 61 additions and 2 deletions.
63 changes: 61 additions & 2 deletions cli/import_map.rs
Expand Up @@ -197,13 +197,29 @@ impl ImportMap {
// the url since it contains what looks to be a uri scheme. To work around
// this, we append the specifier to the path segments of the base url when
// the specifier is not relative or absolute.
let mut maybe_query_string_and_fragment = None;
if !is_relative_or_absolute_specifier && base.path_segments_mut().is_ok() {
{
let mut segments = base.path_segments_mut().unwrap();
segments.pop_if_empty();
segments.extend(specifier.split('/'));

// Handle query-string and fragment first, otherwise they would be percent-encoded
// by `extend()`
let prefix = match specifier.find(&['?', '#'][..]) {
Some(idx) => {
maybe_query_string_and_fragment = Some(&specifier[idx..]);
&specifier[..idx]
}
None => specifier,
};
segments.extend(prefix.split('/'));
}

if let Some(query_string_and_fragment) = maybe_query_string_and_fragment {
Ok(base.join(query_string_and_fragment)?)
} else {
Ok(base)
}
Ok(base)
} else {
Ok(base.join(specifier)?)
}
Expand Down Expand Up @@ -805,4 +821,47 @@ mod tests {
"http://localhost/C:/folder/file.ts"
);
}

#[test]
fn querystring() {
let json_map = r#"{
"imports": {
"npm/": "https://esm.sh/"
}
}"#;
let import_map =
ImportMap::from_json("https://deno.land", json_map).unwrap();

let resolved = import_map
.resolve("npm/postcss-modules@4.2.2?no-check", "https://deno.land")
.unwrap();
assert_eq!(
resolved.as_str(),
"https://esm.sh/postcss-modules@4.2.2?no-check"
);

let resolved = import_map
.resolve("npm/key/a?b?c", "https://deno.land")
.unwrap();
assert_eq!(resolved.as_str(), "https://esm.sh/key/a?b?c");

let resolved = import_map
.resolve(
"npm/postcss-modules@4.2.2?no-check#fragment",
"https://deno.land",
)
.unwrap();
assert_eq!(
resolved.as_str(),
"https://esm.sh/postcss-modules@4.2.2?no-check#fragment"
);

let resolved = import_map
.resolve("npm/postcss-modules@4.2.2#fragment", "https://deno.land")
.unwrap();
assert_eq!(
resolved.as_str(),
"https://esm.sh/postcss-modules@4.2.2#fragment"
);
}
}

0 comments on commit bd4ca72

Please sign in to comment.