@@ -48,13 +48,47 @@ fn has_css_extension(s: &str) -> bool {
4848 s. ends_with ( ".css" ) || s. contains ( ".css?" )
4949}
5050
51+ fn starts_with_url_scheme ( s : & str ) -> bool {
52+ let Some ( ( scheme, _) ) = s. split_once ( ':' ) else {
53+ return false ;
54+ } ;
55+ let mut chars = scheme. chars ( ) ;
56+ matches ! ( chars. next( ) , Some ( c) if c. is_ascii_alphabetic( ) )
57+ && chars. all ( |c| c. is_ascii_alphanumeric ( ) || matches ! ( c, '+' | '-' | '.' ) )
58+ }
59+
60+ fn starts_with_windows_drive_letter ( s : & str ) -> bool {
61+ let bytes = s. as_bytes ( ) ;
62+ bytes. len ( ) >= 2
63+ && bytes[ 0 ] . is_ascii_alphabetic ( )
64+ && matches ! ( bytes[ 1 ] , b':' | b'|' )
65+ && ( bytes. len ( ) == 2 || matches ! ( bytes[ 2 ] , b'/' | b'\\' | b'?' | b'#' ) )
66+ }
67+
5168fn is_relative_source_name ( s : & str ) -> bool {
52- // `module_filename_helpers::resolve_relative_resource_path` emits URL-style
53- // relative paths for `[relative-resource-path]`. In real projects, generated
54- // assets and source files are typically in different directories, so these
55- // names normally start with `../`. Keep the detection narrow to avoid treating
56- // custom bare source names, such as `module`, as file resources.
57- s. starts_with ( "../" )
69+ // Source map `sources` entries are URL references. Per ECMA-426
70+ // "9 Source map format", each source is a potentially relative URL; per
71+ // "9.3 Resolving sources", non-absolute sources are resolved against the
72+ // source map URL.
73+ //
74+ // WHATWG URL "4.3 URL writing" gives the useful forms here:
75+ // - absolute URLs: `webpack://...`, `file://...`, `data:...`
76+ // - scheme-relative URLs: `//host/path`
77+ // - path-absolute URLs: `/path`
78+ // - path-relative, scheme-less URLs: `index.js`, `./index.js`, `../index.js`
79+ //
80+ // Only path-relative, scheme-less URLs depend on the source map location, so
81+ // only they need to be canonicalized before names are deduplicated across
82+ // assets.
83+ //
84+ // WHATWG URL "4.2 URL miscellaneous" defines "Windows drive letter",
85+ // "normalized Windows drive letter", and "starts with a Windows drive
86+ // letter"; keep those Windows absolute paths (`C:/...`, `C:\...`, `C|/...`)
87+ // and backslash-rooted Windows paths (`\\server\share`) verbatim.
88+ !s. is_empty ( )
89+ && !s. starts_with ( [ '/' , '\\' ] )
90+ && !starts_with_url_scheme ( s)
91+ && !starts_with_windows_drive_letter ( s)
5892}
5993
6094fn normalize_relative_source_name_url (
0 commit comments