@@ -12,7 +12,9 @@ const seeds = []
1212for ( let i = 1 ; i <= 128 ; i ++ ) seeds . push ( fixedPRG . randomBytes ( 23 * i ) )
1313const rand = ( ) => fixedPRG . randomBytes ( 1 ) [ 0 ] / 256 // or Math.random()
1414
15- function streamTest ( t , label , testFatal ) {
15+ const isConsistenFatalEncoding = ( label ) => legacySingleByte . includes ( label ) || label === 'utf-8' // see explanation below
16+
17+ function streamChecks ( t , label , testFatal ) {
1618 for ( const u8i of seeds ) {
1719 const u8 = Uint8Array . from ( u8i )
1820 const loose = new TextDecoder ( label )
@@ -41,12 +43,16 @@ function streamTest(t, label, testFatal) {
4143 // Can differ on multi-byte as the previous chunk might have caused a second error in next one
4244 // In fatal mode the queue from the previous invalid chunk is ignored, while in replacement it causes another error
4345 // It can also go the other way around: previous state causing next input to be valid for replacement but not for fatal
44- // Continiuing streaming after fatal error can also completely switch the behavior for e.g. utf-32
45- if ( legacySingleByte . includes ( label ) || ( label === 'utf-8' && previousValidBytes >= 3 ) ) {
46- if ( ok ) {
47- t . assert . strictEqual ( b , a )
48- } else {
49- t . assert . ok ( a . includes ( '\uFFFD' ) )
46+ // Continuing streaming after fatal error can also completely switch the behavior for e.g. utf-16
47+ // See e.g. https://github.com/whatwg/encoding/issues/358#issuecomment-3678655834
48+ if ( isConsistenFatalEncoding ( label ) ) {
49+ if ( ok ) t . assert . ok ( a . includes ( b ) )
50+ if ( legacySingleByte . includes ( label ) || ( label === 'utf-8' && previousValidBytes >= 3 ) ) {
51+ if ( ok ) {
52+ t . assert . strictEqual ( b , a )
53+ } else {
54+ t . assert . ok ( a . includes ( '\uFFFD' ) )
55+ }
5056 }
5157 }
5258 }
@@ -62,11 +68,14 @@ function streamTest(t, label, testFatal) {
6268 okf = true
6369 } catch { }
6470
65- if ( legacySingleByte . includes ( label ) || ( label === 'utf-8' && continiousValidBytes >= 3 ) ) {
66- if ( okf ) {
67- t . assert . strictEqual ( bf , af )
68- } else {
69- t . assert . ok ( af . includes ( '\uFFFD' ) )
71+ if ( isConsistenFatalEncoding ( label ) ) {
72+ if ( okf ) t . assert . ok ( af . includes ( bf ) )
73+ if ( legacySingleByte . includes ( label ) || ( label === 'utf-8' && continiousValidBytes >= 3 ) ) {
74+ if ( okf ) {
75+ t . assert . strictEqual ( bf , af )
76+ } else {
77+ t . assert . ok ( af . includes ( '\uFFFD' ) )
78+ }
7079 }
7180 }
7281 }
@@ -78,31 +87,32 @@ function streamTest(t, label, testFatal) {
7887 }
7988}
8089
90+ function streamTest ( label , fatal ) {
91+ const skip = fatal && ! isConsistenFatalEncoding ( label ) // see explanation in fatal path above
92+ test ( label , { skip } , ( t ) => streamChecks ( t , label , fatal ) )
93+ }
94+
8195describe ( 'stream=true in small chunks' , ( ) => {
8296 describe ( 'Unicode' , ( ) => {
8397 for ( const fatal of [ false , true ] ) {
8498 describe ( fatal ? 'fatal' : 'loose' , ( ) => {
85- for ( const label of unicode ) {
86- if ( label !== 'utf-8' && fatal ) continue // see comment above, utf-16 is hard to test here
87- test ( label , ( t ) => streamTest ( t , label , fatal ) )
88- }
99+ for ( const label of unicode ) streamTest ( label , fatal )
89100 } )
90101 }
91102 } )
92103
93104 describe ( '1-byte encodings' , ( ) => {
94105 for ( const fatal of [ false , true ] ) {
95106 describe ( fatal ? 'fatal' : 'loose' , ( ) => {
96- for ( const label of legacySingleByte ) test ( label , ( t ) => streamTest ( t , label , fatal ) )
107+ for ( const label of legacySingleByte ) streamTest ( label , fatal )
97108 } )
98109 }
99110 } )
100111
101112 describe ( 'legacy multi-byte encodings' , ( ) => {
102- // See comment above, fatal streaming is hard to test blindly for these
103- for ( const fatal of [ false ] ) {
113+ for ( const fatal of [ false , true ] ) {
104114 describe ( fatal ? 'fatal' : 'loose' , ( ) => {
105- for ( const label of legacyMultiByte ) test ( label , ( t ) => streamTest ( t , label , fatal ) )
115+ for ( const label of legacyMultiByte ) streamTest ( label , fatal )
106116 } )
107117 }
108118 } )
0 commit comments