@@ -1041,23 +1041,26 @@ pub fn strip_basedirs(preprocessor_output: &[u8], basedirs: &[Vec<u8>]) -> Vec<u
10411041 // Find all potential matches for each basedir using fast substring search
10421042 // Store as (position, length, basedir_idx) sorted by position
10431043 let mut matches: Vec < ( usize , usize , usize ) > = Vec :: new ( ) ;
1044+ // We must return the original preprocessor output on all platforms,
1045+ // so we only normalize a copy for searching.
1046+ let normalized_output = preprocessor_output;
10441047 #[ cfg( target_os = "windows" ) ]
1045- let preprocessor_output = & normalize_win_path ( preprocessor_output) ;
1048+ let normalized_output = & normalize_win_path ( preprocessor_output) ;
10461049
10471050 for ( idx, basedir_bytes) in basedirs. iter ( ) . enumerate ( ) {
10481051 let basedir = basedir_bytes. as_slice ( ) ;
10491052 #[ cfg( target_os = "windows" ) ]
10501053 // Case insensitive
10511054 let basedir = normalize_win_path ( basedir) ;
10521055 // Use memchr's fast substring search
1053- let finder = memchr:: memmem:: find_iter ( preprocessor_output , & basedir) ;
1056+ let finder = memchr:: memmem:: find_iter ( normalized_output , & basedir) ;
10541057
10551058 for pos in finder {
10561059 // Check if this is a valid boundary (start, whitespace, quote, or '<')
10571060 let is_boundary = pos == 0
1058- || preprocessor_output [ pos - 1 ] . is_ascii_whitespace ( )
1059- || preprocessor_output [ pos - 1 ] == b'"'
1060- || preprocessor_output [ pos - 1 ] == b'<' ;
1061+ || normalized_output [ pos - 1 ] . is_ascii_whitespace ( )
1062+ || normalized_output [ pos - 1 ] == b'"'
1063+ || normalized_output [ pos - 1 ] == b'<' ;
10611064
10621065 if is_boundary {
10631066 matches. push ( ( pos, basedir. len ( ) , idx) ) ;
@@ -1095,14 +1098,14 @@ pub fn strip_basedirs(preprocessor_output: &[u8], basedirs: &[Vec<u8>]) -> Vec<u
10951098
10961099 for ( match_pos, match_len) in filtered_matches {
10971100 // Copy everything before the match
1098- result. extend_from_slice ( & preprocessor_output [ current_pos..match_pos] ) ;
1101+ result. extend_from_slice ( & normalized_output [ current_pos..match_pos] ) ;
10991102 // Replace the basedir with "."
11001103 result. push ( b'.' ) ;
11011104 current_pos = match_pos + match_len;
11021105 }
11031106
11041107 // Copy remaining data
1105- result. extend_from_slice ( & preprocessor_output [ current_pos..] ) ;
1108+ result. extend_from_slice ( & normalized_output [ current_pos..] ) ;
11061109
11071110 result
11081111}
@@ -1368,34 +1371,36 @@ mod tests {
13681371 fn test_strip_basedir_windows_backslashes ( ) {
13691372 // Without trailing backslash
13701373 let basedir = b"C:\\ Users\\ test\\ project" . to_vec ( ) ;
1371- let input = b"# 1 \" C:\\ Users\\ test\\ project\\ src \\ main .c\" " ;
1374+ let input = b"# 1 \" C:\\ Users\\ test\\ project\\ Src \\ Main .c\" " ;
13721375 let output = super :: strip_basedirs ( input, std:: slice:: from_ref ( & basedir) ) ;
13731376 // normalized backslash to slash
1374- let expected = b"# 1 \" ./src/main .c\" " ;
1377+ let expected = b"# 1 \" .\\ Src \\ Main .c\" " ;
13751378 assert_eq ! ( output, expected) ;
13761379
1377- // With multiple trailing backslashes
1378- let basedir = b"C:\\ Users\\ test\\ project\\ \\ \\ " . to_vec ( ) ;
1380+ // Trailing slashes aren't ignored, they must be cleaned in config reader
1381+ let basedir = b"C:\\ Users\\ test\\ project\\ " . to_vec ( ) ;
13791382 let input = b"# 1 \" C:\\ Users\\ test\\ project\\ src\\ main.c\" " ;
13801383 let output = super :: strip_basedirs ( input, std:: slice:: from_ref ( & basedir) ) ;
1381- let expected = b"# 1 \" ./ src/ main.c\" " ;
1384+ let expected = b"# 1 \" .\\ src\\ main.c\" " ;
13821385 assert_eq ! ( output, expected) ;
13831386 }
13841387
13851388 #[ cfg( target_os = "windows" ) ]
13861389 #[ test]
13871390 fn test_strip_basedir_windows_mixed_slashes ( ) {
1391+ // The slashes may be mixed in preprocessor output, but the uncut output
1392+ // should remain untouched.
13881393 // Mixed forward and backslashes in input (common from certain build systems)
13891394 let basedir = b"C:\\ Users\\ test\\ project" . to_vec ( ) ;
13901395 let input = b"# 1 \" C:/Users\\ test\\ project\\ src/main.c\" " ;
13911396 let output = super :: strip_basedirs ( input, std:: slice:: from_ref ( & basedir) ) ;
1392- let expected = b"# 1 \" ./ src/main.c\" " ;
1397+ let expected = b"# 1 \" .\\ src/main.c\" " ;
13931398 assert_eq ! ( output, expected, "Failed to strip mixed slash path" ) ;
13941399
13951400 // Also test the reverse case
13961401 let input = b"# 1 \" C:\\ Users/test/project/src\\ main.c\" " ;
13971402 let output = super :: strip_basedirs ( input, std:: slice:: from_ref ( & basedir) ) ;
1398- let expected = b"# 1 \" ./src/ main.c\" " ;
1403+ let expected = b"# 1 \" ./src\\ main.c\" " ;
13991404 assert_eq ! ( output, expected, "Failed to strip reverse mixed slash path" ) ;
14001405 }
14011406}
0 commit comments