File tree Expand file tree Collapse file tree
Expand file tree Collapse file tree Original file line number Diff line number Diff line change @@ -60,15 +60,24 @@ describe('instrument', () => {
6060 assert . ok ( isLatin1Safe ( ua ) ) ;
6161 } ) ;
6262
63- it ( 'should return a Latin-1 safe user agent when process.title contains non-ASCII characters' , ( ) => {
64- const notLatin1SafeTitle = '管理者'
63+ it ( 'should return a Latin-1 safe user agent when process.title contains non-Latin-1 characters' , ( ) => {
64+ const notLatin1SafeTitle = '管理者: Windows PowerShell '
6565 assert . strictEqual ( isLatin1Safe ( notLatin1SafeTitle ) , false ) ;
6666
6767 mockProcessTitle ( notLatin1SafeTitle ) ;
6868 const { getUserAgent } = freshImport ( ) ;
6969 const ua = getUserAgent ( ) ;
7070 assert . ok ( isLatin1Safe ( ua ) , `User-Agent contains non-Latin-1 characters: ${ ua } ` ) ;
7171 assert . ok ( ! ua . includes ( notLatin1SafeTitle ) , 'User-Agent should not contain raw non-ASCII characters' ) ;
72+ assert . ok ( ua . includes ( '%E7%AE%A1%E7%90%86%E8%80%85: Windows PowerShell' ) , 'User-Agent should percent-encode only non-Latin-1 characters' ) ;
73+ } ) ;
74+
75+ it ( 'should preserve Latin-1 characters in process.title' , ( ) => {
76+ mockProcessTitle ( 'café' ) ;
77+ const { getUserAgent } = freshImport ( ) ;
78+ const ua = getUserAgent ( ) ;
79+ assert . ok ( ua . includes ( 'café/' ) , `User-Agent should preserve Latin-1 characters: ${ ua } ` ) ;
80+ assert . ok ( isLatin1Safe ( ua ) ) ;
7281 } ) ;
7382 } ) ;
7483} ) ;
Original file line number Diff line number Diff line change @@ -10,6 +10,20 @@ function replaceSlashes(s: string): string {
1010 return s . replace ( '/' , ':' ) ;
1111}
1212
13+ const MAX_LATIN1_CODE = 0xFF ;
14+
15+ /**
16+ * Ensures a string is safe for use in HTTP headers by URI-encoding characters outside the Latin-1 (ISO-8859-1) range.
17+ * Latin-1 characters (code points 0x00–0xFF) are preserved as-is; all others are percent-encoded via encodeURIComponent.
18+ */
19+ function toLatin1Safe ( s : string ) : string {
20+ let result = '' ;
21+ for ( const char of s ) {
22+ result += char . charCodeAt ( 0 ) <= MAX_LATIN1_CODE ? char : encodeURIComponent ( char ) ;
23+ }
24+ return result ;
25+ }
26+
1327// TODO: for the deno build (see the `npm run build:deno` npm run script), we could replace the `os-browserify` npm
1428// module shim with our own shim leveraging the deno beta compatibility layer for node's `os` module (for more info
1529// see https://deno.land/std@0.116.0/node/os.ts). At the time of writing this TODO (2021/11/25), this required deno
@@ -18,7 +32,7 @@ function replaceSlashes(s: string): string {
1832// based code will report "browser/undefined" from a deno runtime.
1933const baseUserAgent =
2034 `${ replaceSlashes ( packageJson . name ) } /${ packageJson . version } ` +
21- `${ encodeURI ( basename ( process . title ) ) } /${ process . version . replace ( 'v' , '' ) } ` +
35+ `${ toLatin1Safe ( basename ( process . title ) ) } /${ process . version . replace ( 'v' , '' ) } ` +
2236 `${ os . platform ( ) } /${ os . release ( ) } ` ;
2337
2438const appMetadata : { [ key : string ] : string } = { } ;
You can’t perform that action at this time.
0 commit comments