@@ -46,8 +46,13 @@ public class HPackDecoderTests
46
46
47
47
private const string _headerNameString = "new-header" ;
48
48
49
+ // On purpose longer than 4096 (DefaultStringOctetsSize from HPackDecoder) to trigger https://github.com/dotnet/runtime/issues/78516
50
+ private static readonly string _literalHeaderNameString = string . Concat ( Enumerable . Range ( 0 , 4100 ) . Select ( c => ( char ) ( 'a' + ( c % 26 ) ) ) ) ;
51
+
49
52
private static readonly byte [ ] _headerNameBytes = Encoding . ASCII . GetBytes ( _headerNameString ) ;
50
53
54
+ private static readonly byte [ ] _literalHeaderNameBytes = Encoding . ASCII . GetBytes ( _literalHeaderNameString ) ;
55
+
51
56
// n e w - h e a d e r *
52
57
// 10101000 10111110 00010110 10011100 10100011 10010000 10110110 01111111
53
58
private static readonly byte [ ] _headerNameHuffmanBytes = new byte [ ] { 0xa8 , 0xbe , 0x16 , 0x9c , 0xa3 , 0x90 , 0xb6 , 0x7f } ;
@@ -64,6 +69,12 @@ public class HPackDecoderTests
64
69
. Concat ( _headerNameBytes )
65
70
. ToArray ( ) ;
66
71
72
+ // size = 4096 ==> 0x7f, 0x81, 0x1f (7+) prefixed integer
73
+ // size = 4100 ==> 0x7f, 0x85, 0x1f (7+) prefixed integer
74
+ private static readonly byte [ ] _literalHeaderName = new byte [ ] { 0x7f , 0x85 , 0x1f } // 4100
75
+ . Concat ( _literalHeaderNameBytes )
76
+ . ToArray ( ) ;
77
+
67
78
private static readonly byte [ ] _headerNameHuffman = new byte [ ] { ( byte ) ( 0x80 | _headerNameHuffmanBytes . Length ) }
68
79
. Concat ( _headerNameHuffmanBytes )
69
80
. ToArray ( ) ;
@@ -392,6 +403,101 @@ public void DecodesLiteralHeaderFieldNeverIndexed_IndexedName_OutOfRange_Error()
392
403
Assert . Empty ( _handler . DecodedHeaders ) ;
393
404
}
394
405
406
+ [ Fact ]
407
+ public void DecodesLiteralHeaderFieldNeverIndexed_NewName_SingleBuffer ( )
408
+ {
409
+ byte [ ] encoded = _literalHeaderFieldWithoutIndexingNewName
410
+ . Concat ( _literalHeaderName )
411
+ . Concat ( _headerValue )
412
+ . ToArray ( ) ;
413
+
414
+ _decoder . Decode ( encoded , endHeaders : true , handler : _handler ) ;
415
+
416
+ Assert . Equal ( 1 , _handler . DecodedHeaders . Count ) ;
417
+ Assert . True ( _handler . DecodedHeaders . ContainsKey ( _literalHeaderNameString ) ) ;
418
+ Assert . Equal ( _headerValueString , _handler . DecodedHeaders [ _literalHeaderNameString ] ) ;
419
+ }
420
+
421
+ [ Fact ]
422
+ public void DecodesLiteralHeaderFieldNeverIndexed_NewName_NameLengthBrokenIntoSeparateBuffers ( )
423
+ {
424
+ byte [ ] encoded = _literalHeaderFieldWithoutIndexingNewName
425
+ . Concat ( _literalHeaderName )
426
+ . Concat ( _headerValue )
427
+ . ToArray ( ) ;
428
+
429
+ _decoder . Decode ( encoded [ ..1 ] , endHeaders : false , handler : _handler ) ;
430
+ _decoder . Decode ( encoded [ 1 ..] , endHeaders : true , handler : _handler ) ;
431
+
432
+ Assert . Equal ( 1 , _handler . DecodedHeaders . Count ) ;
433
+ Assert . True ( _handler . DecodedHeaders . ContainsKey ( _literalHeaderNameString ) ) ;
434
+ Assert . Equal ( _headerValueString , _handler . DecodedHeaders [ _literalHeaderNameString ] ) ;
435
+ }
436
+
437
+ [ Fact ]
438
+ public void DecodesLiteralHeaderFieldNeverIndexed_NewName_NameBrokenIntoSeparateBuffers ( )
439
+ {
440
+ byte [ ] encoded = _literalHeaderFieldWithoutIndexingNewName
441
+ . Concat ( _literalHeaderName )
442
+ . Concat ( _headerValue )
443
+ . ToArray ( ) ;
444
+
445
+ _decoder . Decode ( encoded [ ..( _literalHeaderNameString . Length / 2 ) ] , endHeaders : false , handler : _handler ) ;
446
+ _decoder . Decode ( encoded [ ( _literalHeaderNameString . Length / 2 ) ..] , endHeaders : true , handler : _handler ) ;
447
+
448
+ Assert . Equal ( 1 , _handler . DecodedHeaders . Count ) ;
449
+ Assert . True ( _handler . DecodedHeaders . ContainsKey ( _literalHeaderNameString ) ) ;
450
+ Assert . Equal ( _headerValueString , _handler . DecodedHeaders [ _literalHeaderNameString ] ) ;
451
+ }
452
+
453
+ [ Fact ]
454
+ public void DecodesLiteralHeaderFieldNeverIndexed_NewName_NameAndValueBrokenIntoSeparateBuffers ( )
455
+ {
456
+ byte [ ] encoded = _literalHeaderFieldWithoutIndexingNewName
457
+ . Concat ( _literalHeaderName )
458
+ . Concat ( _headerValue )
459
+ . ToArray ( ) ;
460
+
461
+ _decoder . Decode ( encoded [ ..^ _headerValue . Length ] , endHeaders : false , handler : _handler ) ;
462
+ _decoder . Decode ( encoded [ ^ _headerValue . Length ..] , endHeaders : true , handler : _handler ) ;
463
+
464
+ Assert . Equal ( 1 , _handler . DecodedHeaders . Count ) ;
465
+ Assert . True ( _handler . DecodedHeaders . ContainsKey ( _literalHeaderNameString ) ) ;
466
+ Assert . Equal ( _headerValueString , _handler . DecodedHeaders [ _literalHeaderNameString ] ) ;
467
+ }
468
+
469
+ [ Fact ]
470
+ public void DecodesLiteralHeaderFieldNeverIndexed_NewName_ValueLengthBrokenIntoSeparateBuffers ( )
471
+ {
472
+ byte [ ] encoded = _literalHeaderFieldWithoutIndexingNewName
473
+ . Concat ( _literalHeaderName )
474
+ . Concat ( _headerValue )
475
+ . ToArray ( ) ;
476
+
477
+ _decoder . Decode ( encoded [ ..^ ( _headerValue . Length - 1 ) ] , endHeaders : false , handler : _handler ) ;
478
+ _decoder . Decode ( encoded [ ^ ( _headerValue . Length - 1 ) ..] , endHeaders : true , handler : _handler ) ;
479
+
480
+ Assert . Equal ( 1 , _handler . DecodedHeaders . Count ) ;
481
+ Assert . True ( _handler . DecodedHeaders . ContainsKey ( _literalHeaderNameString ) ) ;
482
+ Assert . Equal ( _headerValueString , _handler . DecodedHeaders [ _literalHeaderNameString ] ) ;
483
+ }
484
+
485
+ [ Fact ]
486
+ public void DecodesLiteralHeaderFieldNeverIndexed_NewName_ValueBrokenIntoSeparateBuffers ( )
487
+ {
488
+ byte [ ] encoded = _literalHeaderFieldWithoutIndexingNewName
489
+ . Concat ( _literalHeaderName )
490
+ . Concat ( _headerValue )
491
+ . ToArray ( ) ;
492
+
493
+ _decoder . Decode ( encoded [ ..^ ( _headerValueString . Length / 2 ) ] , endHeaders : false , handler : _handler ) ;
494
+ _decoder . Decode ( encoded [ ^ ( _headerValueString . Length / 2 ) ..] , endHeaders : true , handler : _handler ) ;
495
+
496
+ Assert . Equal ( 1 , _handler . DecodedHeaders . Count ) ;
497
+ Assert . True ( _handler . DecodedHeaders . ContainsKey ( _literalHeaderNameString ) ) ;
498
+ Assert . Equal ( _headerValueString , _handler . DecodedHeaders [ _literalHeaderNameString ] ) ;
499
+ }
500
+
395
501
[ Fact ]
396
502
public void DecodesDynamicTableSizeUpdate ( )
397
503
{
0 commit comments