@@ -47,6 +47,56 @@ defmodule HPAXTest do
47
47
assert dec_table . entries == [ { "b" , "B" } , { "a" , "A" } ]
48
48
end
49
49
50
+ # https://datatracker.ietf.org/doc/html/rfc7541#section-4.2
51
+ property "decode/2 accepts dynamic resizes at the start of a block" do
52
+ enc_table = HPAX . new ( 20_000 )
53
+ # Start with a non-empty decode table
54
+ dec_table = HPAX . new ( 20_000 )
55
+ { encoded , _enc_table } = HPAX . encode ( [ { :store , "bogus" , "BOGUS" } ] , dec_table )
56
+ encoded = IO . iodata_to_binary ( encoded )
57
+ assert { :ok , _decoded , dec_table } = HPAX . decode ( encoded , dec_table )
58
+ assert dec_table . size > 0
59
+
60
+ check all headers_to_encode <- list_of ( header_with_store ( ) , min_length: 1 ) do
61
+ assert { encoded , enc_table } = HPAX . encode ( headers_to_encode , enc_table )
62
+ encoded = IO . iodata_to_binary ( encoded )
63
+ assert { :ok , _decoded , new_dec_table } = HPAX . decode ( encoded , dec_table )
64
+ assert new_dec_table . size > enc_table . size
65
+
66
+ # Now prepend a table zeroing to the beginning and ensure that we are exactly
67
+ # the same size as the encode table
68
+ encoded = << 0b001 :: 3 , 0 :: 5 >> <> encoded
69
+ assert { :ok , _decoded , new_dec_table } = HPAX . decode ( encoded , dec_table )
70
+ assert new_dec_table . size == enc_table . size
71
+ end
72
+ end
73
+
74
+ # https://datatracker.ietf.org/doc/html/rfc7541#section-4.2
75
+ property "decode/2 rejects dynamic resizes anywhere but at the start of a block" do
76
+ enc_table = HPAX . new ( 20_000 )
77
+ dec_table = HPAX . new ( 20_000 )
78
+
79
+ check all headers_to_encode <- list_of ( header_with_store ( ) , min_length: 1 ) do
80
+ assert { encoded , _enc_table } = HPAX . encode ( headers_to_encode , enc_table )
81
+
82
+ encoded = IO . iodata_to_binary ( encoded ) <> << 0b001 :: 3 , 0 :: 5 >>
83
+ assert { :error , :protocol_error } = HPAX . decode ( encoded , dec_table )
84
+ end
85
+ end
86
+
87
+ # https://datatracker.ietf.org/doc/html/rfc7541#section-6.2
88
+ property "decode/2 rejects dynamic resizes larger than the original table size" do
89
+ enc_table = HPAX . new ( 29 )
90
+ dec_table = HPAX . new ( 29 )
91
+
92
+ check all headers_to_encode <- list_of ( header_with_store ( ) , min_length: 1 ) do
93
+ assert { encoded , _enc_table } = HPAX . encode ( headers_to_encode , enc_table )
94
+
95
+ encoded = << 0b001 :: 3 , 0b11110 :: 5 >> <> IO . iodata_to_binary ( encoded )
96
+ assert { :error , :protocol_error } = HPAX . decode ( encoded , dec_table )
97
+ end
98
+ end
99
+
50
100
property "encoding then decoding headers is circular" do
51
101
table = HPAX . new ( 500 )
52
102
@@ -86,6 +136,10 @@ defmodule HPAXTest do
86
136
end
87
137
end
88
138
139
+ defp header_with_store ( ) do
140
+ map ( header ( ) , fn { name , value } -> { :store , name , value } end )
141
+ end
142
+
89
143
# Header generator.
90
144
defp header_with_action ( ) do
91
145
action = member_of ( [ :store , :store_name , :no_store , :never_store ] )
0 commit comments