@@ -19,6 +19,14 @@ public static partial class LogPathHelper
1919 [ GeneratedRegex ( @"(?<=[\\/][Uu]sers[\\/])[^\\/:*?""'<>|\r\n]+" ) ]
2020 private static partial Regex UserProfileSegmentRegex ( ) ;
2121
22+ // Email address token; "%40" also matches the URL-encoded "@" in remote-URL userinfo
23+ [ GeneratedRegex ( @"[A-Za-z0-9._+\-]+(?:@|%40)[A-Za-z0-9.\-]+\.[A-Za-z]{2,}" ) ]
24+ private static partial Regex EmailRegex ( ) ;
25+
26+ // Authority of a "scheme://" URL (userinfo, host, port), up to the path/query/fragment
27+ [ GeneratedRegex ( @"(?<=://)[^/?#\s""'<>|\\,;)\]]+" ) ]
28+ private static partial Regex UrlAuthorityRegex ( ) ;
29+
2230 [ GeneratedRegex ( @"[^\\/]+" ) ]
2331 private static partial Regex PathSegmentRegex ( ) ;
2432
@@ -59,6 +67,10 @@ public static string SanitizeMessage(string? message)
5967 var lines = message . Split ( '\n ' ) ;
6068 for ( int i = 0 ; i < lines . Length ; i ++ )
6169 {
70+ // Scrubbed on every line, stack trace frames included
71+ lines [ i ] = EmailRegex ( ) . Replace ( lines [ i ] , "%Email%" ) ;
72+ lines [ i ] = UrlAuthorityRegex ( ) . Replace ( lines [ i ] , "%Host%" ) ;
73+
6274 // Stack trace frames (" at Method() in <file>:line n") carry build-machine source
6375 // paths that are needed to read the trace; only the user name is scrubbed there
6476 if ( ! lines [ i ] . TrimStart ( ) . StartsWith ( "at " , StringComparison . Ordinal ) )
0 commit comments