1 /*
2  * Copyright (c) 2024 Nordic Semiconductor ASA
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 #include <errno.h>
7 #include <string.h>
8 #include <stdint.h>
9 
10 #include <zephyr/logging/log.h>
11 #include <zephyr/sys/byteorder.h>
12 
13 LOG_MODULE_DECLARE(net_http_server, CONFIG_NET_HTTP_SERVER_LOG_LEVEL);
14 
15 struct decode_elem {
16 	uint8_t bitlen;
17 	uint8_t symbol;
18 	uint8_t code[4];
19 };
20 
21 static const struct decode_elem decode_table[] = {
22 	{  5,  48, { 0b00000000, 0b00000000, 0b00000000, 0b00000000 } },
23 	{  5,  49, { 0b00001000, 0b00000000, 0b00000000, 0b00000000 } },
24 	{  5,  50, { 0b00010000, 0b00000000, 0b00000000, 0b00000000 } },
25 	{  5,  97, { 0b00011000, 0b00000000, 0b00000000, 0b00000000 } },
26 	{  5,  99, { 0b00100000, 0b00000000, 0b00000000, 0b00000000 } },
27 	{  5, 101, { 0b00101000, 0b00000000, 0b00000000, 0b00000000 } },
28 	{  5, 105, { 0b00110000, 0b00000000, 0b00000000, 0b00000000 } },
29 	{  5, 111, { 0b00111000, 0b00000000, 0b00000000, 0b00000000 } },
30 	{  5, 115, { 0b01000000, 0b00000000, 0b00000000, 0b00000000 } },
31 	{  5, 116, { 0b01001000, 0b00000000, 0b00000000, 0b00000000 } },
32 	{  6,  32, { 0b01010000, 0b00000000, 0b00000000, 0b00000000 } },
33 	{  6,  37, { 0b01010100, 0b00000000, 0b00000000, 0b00000000 } },
34 	{  6,  45, { 0b01011000, 0b00000000, 0b00000000, 0b00000000 } },
35 	{  6,  46, { 0b01011100, 0b00000000, 0b00000000, 0b00000000 } },
36 	{  6,  47, { 0b01100000, 0b00000000, 0b00000000, 0b00000000 } },
37 	{  6,  51, { 0b01100100, 0b00000000, 0b00000000, 0b00000000 } },
38 	{  6,  52, { 0b01101000, 0b00000000, 0b00000000, 0b00000000 } },
39 	{  6,  53, { 0b01101100, 0b00000000, 0b00000000, 0b00000000 } },
40 	{  6,  54, { 0b01110000, 0b00000000, 0b00000000, 0b00000000 } },
41 	{  6,  55, { 0b01110100, 0b00000000, 0b00000000, 0b00000000 } },
42 	{  6,  56, { 0b01111000, 0b00000000, 0b00000000, 0b00000000 } },
43 	{  6,  57, { 0b01111100, 0b00000000, 0b00000000, 0b00000000 } },
44 	{  6,  61, { 0b10000000, 0b00000000, 0b00000000, 0b00000000 } },
45 	{  6,  65, { 0b10000100, 0b00000000, 0b00000000, 0b00000000 } },
46 	{  6,  95, { 0b10001000, 0b00000000, 0b00000000, 0b00000000 } },
47 	{  6,  98, { 0b10001100, 0b00000000, 0b00000000, 0b00000000 } },
48 	{  6, 100, { 0b10010000, 0b00000000, 0b00000000, 0b00000000 } },
49 	{  6, 102, { 0b10010100, 0b00000000, 0b00000000, 0b00000000 } },
50 	{  6, 103, { 0b10011000, 0b00000000, 0b00000000, 0b00000000 } },
51 	{  6, 104, { 0b10011100, 0b00000000, 0b00000000, 0b00000000 } },
52 	{  6, 108, { 0b10100000, 0b00000000, 0b00000000, 0b00000000 } },
53 	{  6, 109, { 0b10100100, 0b00000000, 0b00000000, 0b00000000 } },
54 	{  6, 110, { 0b10101000, 0b00000000, 0b00000000, 0b00000000 } },
55 	{  6, 112, { 0b10101100, 0b00000000, 0b00000000, 0b00000000 } },
56 	{  6, 114, { 0b10110000, 0b00000000, 0b00000000, 0b00000000 } },
57 	{  6, 117, { 0b10110100, 0b00000000, 0b00000000, 0b00000000 } },
58 	{  7,  58, { 0b10111000, 0b00000000, 0b00000000, 0b00000000 } },
59 	{  7,  66, { 0b10111010, 0b00000000, 0b00000000, 0b00000000 } },
60 	{  7,  67, { 0b10111100, 0b00000000, 0b00000000, 0b00000000 } },
61 	{  7,  68, { 0b10111110, 0b00000000, 0b00000000, 0b00000000 } },
62 	{  7,  69, { 0b11000000, 0b00000000, 0b00000000, 0b00000000 } },
63 	{  7,  70, { 0b11000010, 0b00000000, 0b00000000, 0b00000000 } },
64 	{  7,  71, { 0b11000100, 0b00000000, 0b00000000, 0b00000000 } },
65 	{  7,  72, { 0b11000110, 0b00000000, 0b00000000, 0b00000000 } },
66 	{  7,  73, { 0b11001000, 0b00000000, 0b00000000, 0b00000000 } },
67 	{  7,  74, { 0b11001010, 0b00000000, 0b00000000, 0b00000000 } },
68 	{  7,  75, { 0b11001100, 0b00000000, 0b00000000, 0b00000000 } },
69 	{  7,  76, { 0b11001110, 0b00000000, 0b00000000, 0b00000000 } },
70 	{  7,  77, { 0b11010000, 0b00000000, 0b00000000, 0b00000000 } },
71 	{  7,  78, { 0b11010010, 0b00000000, 0b00000000, 0b00000000 } },
72 	{  7,  79, { 0b11010100, 0b00000000, 0b00000000, 0b00000000 } },
73 	{  7,  80, { 0b11010110, 0b00000000, 0b00000000, 0b00000000 } },
74 	{  7,  81, { 0b11011000, 0b00000000, 0b00000000, 0b00000000 } },
75 	{  7,  82, { 0b11011010, 0b00000000, 0b00000000, 0b00000000 } },
76 	{  7,  83, { 0b11011100, 0b00000000, 0b00000000, 0b00000000 } },
77 	{  7,  84, { 0b11011110, 0b00000000, 0b00000000, 0b00000000 } },
78 	{  7,  85, { 0b11100000, 0b00000000, 0b00000000, 0b00000000 } },
79 	{  7,  86, { 0b11100010, 0b00000000, 0b00000000, 0b00000000 } },
80 	{  7,  87, { 0b11100100, 0b00000000, 0b00000000, 0b00000000 } },
81 	{  7,  89, { 0b11100110, 0b00000000, 0b00000000, 0b00000000 } },
82 	{  7, 106, { 0b11101000, 0b00000000, 0b00000000, 0b00000000 } },
83 	{  7, 107, { 0b11101010, 0b00000000, 0b00000000, 0b00000000 } },
84 	{  7, 113, { 0b11101100, 0b00000000, 0b00000000, 0b00000000 } },
85 	{  7, 118, { 0b11101110, 0b00000000, 0b00000000, 0b00000000 } },
86 	{  7, 119, { 0b11110000, 0b00000000, 0b00000000, 0b00000000 } },
87 	{  7, 120, { 0b11110010, 0b00000000, 0b00000000, 0b00000000 } },
88 	{  7, 121, { 0b11110100, 0b00000000, 0b00000000, 0b00000000 } },
89 	{  7, 122, { 0b11110110, 0b00000000, 0b00000000, 0b00000000 } },
90 	{  8,  38, { 0b11111000, 0b00000000, 0b00000000, 0b00000000 } },
91 	{  8,  42, { 0b11111001, 0b00000000, 0b00000000, 0b00000000 } },
92 	{  8,  44, { 0b11111010, 0b00000000, 0b00000000, 0b00000000 } },
93 	{  8,  59, { 0b11111011, 0b00000000, 0b00000000, 0b00000000 } },
94 	{  8,  88, { 0b11111100, 0b00000000, 0b00000000, 0b00000000 } },
95 	{  8,  90, { 0b11111101, 0b00000000, 0b00000000, 0b00000000 } },
96 	{ 10,  33, { 0b11111110, 0b00000000, 0b00000000, 0b00000000 } },
97 	{ 10,  34, { 0b11111110, 0b01000000, 0b00000000, 0b00000000 } },
98 	{ 10,  40, { 0b11111110, 0b10000000, 0b00000000, 0b00000000 } },
99 	{ 10,  41, { 0b11111110, 0b11000000, 0b00000000, 0b00000000 } },
100 	{ 10,  63, { 0b11111111, 0b00000000, 0b00000000, 0b00000000 } },
101 	{ 11,  39, { 0b11111111, 0b01000000, 0b00000000, 0b00000000 } },
102 	{ 11,  43, { 0b11111111, 0b01100000, 0b00000000, 0b00000000 } },
103 	{ 11, 124, { 0b11111111, 0b10000000, 0b00000000, 0b00000000 } },
104 	{ 12,  35, { 0b11111111, 0b10100000, 0b00000000, 0b00000000 } },
105 	{ 12,  62, { 0b11111111, 0b10110000, 0b00000000, 0b00000000 } },
106 	{ 13,   0, { 0b11111111, 0b11000000, 0b00000000, 0b00000000 } },
107 	{ 13,  36, { 0b11111111, 0b11001000, 0b00000000, 0b00000000 } },
108 	{ 13,  64, { 0b11111111, 0b11010000, 0b00000000, 0b00000000 } },
109 	{ 13,  91, { 0b11111111, 0b11011000, 0b00000000, 0b00000000 } },
110 	{ 13,  93, { 0b11111111, 0b11100000, 0b00000000, 0b00000000 } },
111 	{ 13, 126, { 0b11111111, 0b11101000, 0b00000000, 0b00000000 } },
112 	{ 14,  94, { 0b11111111, 0b11110000, 0b00000000, 0b00000000 } },
113 	{ 14, 125, { 0b11111111, 0b11110100, 0b00000000, 0b00000000 } },
114 	{ 15,  60, { 0b11111111, 0b11111000, 0b00000000, 0b00000000 } },
115 	{ 15,  96, { 0b11111111, 0b11111010, 0b00000000, 0b00000000 } },
116 	{ 15, 123, { 0b11111111, 0b11111100, 0b00000000, 0b00000000 } },
117 	{ 19,  92, { 0b11111111, 0b11111110, 0b00000000, 0b00000000 } },
118 	{ 19, 195, { 0b11111111, 0b11111110, 0b00100000, 0b00000000 } },
119 	{ 19, 208, { 0b11111111, 0b11111110, 0b01000000, 0b00000000 } },
120 	{ 20, 128, { 0b11111111, 0b11111110, 0b01100000, 0b00000000 } },
121 	{ 20, 130, { 0b11111111, 0b11111110, 0b01110000, 0b00000000 } },
122 	{ 20, 131, { 0b11111111, 0b11111110, 0b10000000, 0b00000000 } },
123 	{ 20, 162, { 0b11111111, 0b11111110, 0b10010000, 0b00000000 } },
124 	{ 20, 184, { 0b11111111, 0b11111110, 0b10100000, 0b00000000 } },
125 	{ 20, 194, { 0b11111111, 0b11111110, 0b10110000, 0b00000000 } },
126 	{ 20, 224, { 0b11111111, 0b11111110, 0b11000000, 0b00000000 } },
127 	{ 20, 226, { 0b11111111, 0b11111110, 0b11010000, 0b00000000 } },
128 	{ 21, 153, { 0b11111111, 0b11111110, 0b11100000, 0b00000000 } },
129 	{ 21, 161, { 0b11111111, 0b11111110, 0b11101000, 0b00000000 } },
130 	{ 21, 167, { 0b11111111, 0b11111110, 0b11110000, 0b00000000 } },
131 	{ 21, 172, { 0b11111111, 0b11111110, 0b11111000, 0b00000000 } },
132 	{ 21, 176, { 0b11111111, 0b11111111, 0b00000000, 0b00000000 } },
133 	{ 21, 177, { 0b11111111, 0b11111111, 0b00001000, 0b00000000 } },
134 	{ 21, 179, { 0b11111111, 0b11111111, 0b00010000, 0b00000000 } },
135 	{ 21, 209, { 0b11111111, 0b11111111, 0b00011000, 0b00000000 } },
136 	{ 21, 216, { 0b11111111, 0b11111111, 0b00100000, 0b00000000 } },
137 	{ 21, 217, { 0b11111111, 0b11111111, 0b00101000, 0b00000000 } },
138 	{ 21, 227, { 0b11111111, 0b11111111, 0b00110000, 0b00000000 } },
139 	{ 21, 229, { 0b11111111, 0b11111111, 0b00111000, 0b00000000 } },
140 	{ 21, 230, { 0b11111111, 0b11111111, 0b01000000, 0b00000000 } },
141 	{ 22, 129, { 0b11111111, 0b11111111, 0b01001000, 0b00000000 } },
142 	{ 22, 132, { 0b11111111, 0b11111111, 0b01001100, 0b00000000 } },
143 	{ 22, 133, { 0b11111111, 0b11111111, 0b01010000, 0b00000000 } },
144 	{ 22, 134, { 0b11111111, 0b11111111, 0b01010100, 0b00000000 } },
145 	{ 22, 136, { 0b11111111, 0b11111111, 0b01011000, 0b00000000 } },
146 	{ 22, 146, { 0b11111111, 0b11111111, 0b01011100, 0b00000000 } },
147 	{ 22, 154, { 0b11111111, 0b11111111, 0b01100000, 0b00000000 } },
148 	{ 22, 156, { 0b11111111, 0b11111111, 0b01100100, 0b00000000 } },
149 	{ 22, 160, { 0b11111111, 0b11111111, 0b01101000, 0b00000000 } },
150 	{ 22, 163, { 0b11111111, 0b11111111, 0b01101100, 0b00000000 } },
151 	{ 22, 164, { 0b11111111, 0b11111111, 0b01110000, 0b00000000 } },
152 	{ 22, 169, { 0b11111111, 0b11111111, 0b01110100, 0b00000000 } },
153 	{ 22, 170, { 0b11111111, 0b11111111, 0b01111000, 0b00000000 } },
154 	{ 22, 173, { 0b11111111, 0b11111111, 0b01111100, 0b00000000 } },
155 	{ 22, 178, { 0b11111111, 0b11111111, 0b10000000, 0b00000000 } },
156 	{ 22, 181, { 0b11111111, 0b11111111, 0b10000100, 0b00000000 } },
157 	{ 22, 185, { 0b11111111, 0b11111111, 0b10001000, 0b00000000 } },
158 	{ 22, 186, { 0b11111111, 0b11111111, 0b10001100, 0b00000000 } },
159 	{ 22, 187, { 0b11111111, 0b11111111, 0b10010000, 0b00000000 } },
160 	{ 22, 189, { 0b11111111, 0b11111111, 0b10010100, 0b00000000 } },
161 	{ 22, 190, { 0b11111111, 0b11111111, 0b10011000, 0b00000000 } },
162 	{ 22, 196, { 0b11111111, 0b11111111, 0b10011100, 0b00000000 } },
163 	{ 22, 198, { 0b11111111, 0b11111111, 0b10100000, 0b00000000 } },
164 	{ 22, 228, { 0b11111111, 0b11111111, 0b10100100, 0b00000000 } },
165 	{ 22, 232, { 0b11111111, 0b11111111, 0b10101000, 0b00000000 } },
166 	{ 22, 233, { 0b11111111, 0b11111111, 0b10101100, 0b00000000 } },
167 	{ 23,   1, { 0b11111111, 0b11111111, 0b10110000, 0b00000000 } },
168 	{ 23, 135, { 0b11111111, 0b11111111, 0b10110010, 0b00000000 } },
169 	{ 23, 137, { 0b11111111, 0b11111111, 0b10110100, 0b00000000 } },
170 	{ 23, 138, { 0b11111111, 0b11111111, 0b10110110, 0b00000000 } },
171 	{ 23, 139, { 0b11111111, 0b11111111, 0b10111000, 0b00000000 } },
172 	{ 23, 140, { 0b11111111, 0b11111111, 0b10111010, 0b00000000 } },
173 	{ 23, 141, { 0b11111111, 0b11111111, 0b10111100, 0b00000000 } },
174 	{ 23, 143, { 0b11111111, 0b11111111, 0b10111110, 0b00000000 } },
175 	{ 23, 147, { 0b11111111, 0b11111111, 0b11000000, 0b00000000 } },
176 	{ 23, 149, { 0b11111111, 0b11111111, 0b11000010, 0b00000000 } },
177 	{ 23, 150, { 0b11111111, 0b11111111, 0b11000100, 0b00000000 } },
178 	{ 23, 151, { 0b11111111, 0b11111111, 0b11000110, 0b00000000 } },
179 	{ 23, 152, { 0b11111111, 0b11111111, 0b11001000, 0b00000000 } },
180 	{ 23, 155, { 0b11111111, 0b11111111, 0b11001010, 0b00000000 } },
181 	{ 23, 157, { 0b11111111, 0b11111111, 0b11001100, 0b00000000 } },
182 	{ 23, 158, { 0b11111111, 0b11111111, 0b11001110, 0b00000000 } },
183 	{ 23, 165, { 0b11111111, 0b11111111, 0b11010000, 0b00000000 } },
184 	{ 23, 166, { 0b11111111, 0b11111111, 0b11010010, 0b00000000 } },
185 	{ 23, 168, { 0b11111111, 0b11111111, 0b11010100, 0b00000000 } },
186 	{ 23, 174, { 0b11111111, 0b11111111, 0b11010110, 0b00000000 } },
187 	{ 23, 175, { 0b11111111, 0b11111111, 0b11011000, 0b00000000 } },
188 	{ 23, 180, { 0b11111111, 0b11111111, 0b11011010, 0b00000000 } },
189 	{ 23, 182, { 0b11111111, 0b11111111, 0b11011100, 0b00000000 } },
190 	{ 23, 183, { 0b11111111, 0b11111111, 0b11011110, 0b00000000 } },
191 	{ 23, 188, { 0b11111111, 0b11111111, 0b11100000, 0b00000000 } },
192 	{ 23, 191, { 0b11111111, 0b11111111, 0b11100010, 0b00000000 } },
193 	{ 23, 197, { 0b11111111, 0b11111111, 0b11100100, 0b00000000 } },
194 	{ 23, 231, { 0b11111111, 0b11111111, 0b11100110, 0b00000000 } },
195 	{ 23, 239, { 0b11111111, 0b11111111, 0b11101000, 0b00000000 } },
196 	{ 24,   9, { 0b11111111, 0b11111111, 0b11101010, 0b00000000 } },
197 	{ 24, 142, { 0b11111111, 0b11111111, 0b11101011, 0b00000000 } },
198 	{ 24, 144, { 0b11111111, 0b11111111, 0b11101100, 0b00000000 } },
199 	{ 24, 145, { 0b11111111, 0b11111111, 0b11101101, 0b00000000 } },
200 	{ 24, 148, { 0b11111111, 0b11111111, 0b11101110, 0b00000000 } },
201 	{ 24, 159, { 0b11111111, 0b11111111, 0b11101111, 0b00000000 } },
202 	{ 24, 171, { 0b11111111, 0b11111111, 0b11110000, 0b00000000 } },
203 	{ 24, 206, { 0b11111111, 0b11111111, 0b11110001, 0b00000000 } },
204 	{ 24, 215, { 0b11111111, 0b11111111, 0b11110010, 0b00000000 } },
205 	{ 24, 225, { 0b11111111, 0b11111111, 0b11110011, 0b00000000 } },
206 	{ 24, 236, { 0b11111111, 0b11111111, 0b11110100, 0b00000000 } },
207 	{ 24, 237, { 0b11111111, 0b11111111, 0b11110101, 0b00000000 } },
208 	{ 25, 199, { 0b11111111, 0b11111111, 0b11110110, 0b00000000 } },
209 	{ 25, 207, { 0b11111111, 0b11111111, 0b11110110, 0b10000000 } },
210 	{ 25, 234, { 0b11111111, 0b11111111, 0b11110111, 0b00000000 } },
211 	{ 25, 235, { 0b11111111, 0b11111111, 0b11110111, 0b10000000 } },
212 	{ 26, 192, { 0b11111111, 0b11111111, 0b11111000, 0b00000000 } },
213 	{ 26, 193, { 0b11111111, 0b11111111, 0b11111000, 0b01000000 } },
214 	{ 26, 200, { 0b11111111, 0b11111111, 0b11111000, 0b10000000 } },
215 	{ 26, 201, { 0b11111111, 0b11111111, 0b11111000, 0b11000000 } },
216 	{ 26, 202, { 0b11111111, 0b11111111, 0b11111001, 0b00000000 } },
217 	{ 26, 205, { 0b11111111, 0b11111111, 0b11111001, 0b01000000 } },
218 	{ 26, 210, { 0b11111111, 0b11111111, 0b11111001, 0b10000000 } },
219 	{ 26, 213, { 0b11111111, 0b11111111, 0b11111001, 0b11000000 } },
220 	{ 26, 218, { 0b11111111, 0b11111111, 0b11111010, 0b00000000 } },
221 	{ 26, 219, { 0b11111111, 0b11111111, 0b11111010, 0b01000000 } },
222 	{ 26, 238, { 0b11111111, 0b11111111, 0b11111010, 0b10000000 } },
223 	{ 26, 240, { 0b11111111, 0b11111111, 0b11111010, 0b11000000 } },
224 	{ 26, 242, { 0b11111111, 0b11111111, 0b11111011, 0b00000000 } },
225 	{ 26, 243, { 0b11111111, 0b11111111, 0b11111011, 0b01000000 } },
226 	{ 26, 255, { 0b11111111, 0b11111111, 0b11111011, 0b10000000 } },
227 	{ 27, 203, { 0b11111111, 0b11111111, 0b11111011, 0b11000000 } },
228 	{ 27, 204, { 0b11111111, 0b11111111, 0b11111011, 0b11100000 } },
229 	{ 27, 211, { 0b11111111, 0b11111111, 0b11111100, 0b00000000 } },
230 	{ 27, 212, { 0b11111111, 0b11111111, 0b11111100, 0b00100000 } },
231 	{ 27, 214, { 0b11111111, 0b11111111, 0b11111100, 0b01000000 } },
232 	{ 27, 221, { 0b11111111, 0b11111111, 0b11111100, 0b01100000 } },
233 	{ 27, 222, { 0b11111111, 0b11111111, 0b11111100, 0b10000000 } },
234 	{ 27, 223, { 0b11111111, 0b11111111, 0b11111100, 0b10100000 } },
235 	{ 27, 241, { 0b11111111, 0b11111111, 0b11111100, 0b11000000 } },
236 	{ 27, 244, { 0b11111111, 0b11111111, 0b11111100, 0b11100000 } },
237 	{ 27, 245, { 0b11111111, 0b11111111, 0b11111101, 0b00000000 } },
238 	{ 27, 246, { 0b11111111, 0b11111111, 0b11111101, 0b00100000 } },
239 	{ 27, 247, { 0b11111111, 0b11111111, 0b11111101, 0b01000000 } },
240 	{ 27, 248, { 0b11111111, 0b11111111, 0b11111101, 0b01100000 } },
241 	{ 27, 250, { 0b11111111, 0b11111111, 0b11111101, 0b10000000 } },
242 	{ 27, 251, { 0b11111111, 0b11111111, 0b11111101, 0b10100000 } },
243 	{ 27, 252, { 0b11111111, 0b11111111, 0b11111101, 0b11000000 } },
244 	{ 27, 253, { 0b11111111, 0b11111111, 0b11111101, 0b11100000 } },
245 	{ 27, 254, { 0b11111111, 0b11111111, 0b11111110, 0b00000000 } },
246 	{ 28,   2, { 0b11111111, 0b11111111, 0b11111110, 0b00100000 } },
247 	{ 28,   3, { 0b11111111, 0b11111111, 0b11111110, 0b00110000 } },
248 	{ 28,   4, { 0b11111111, 0b11111111, 0b11111110, 0b01000000 } },
249 	{ 28,   5, { 0b11111111, 0b11111111, 0b11111110, 0b01010000 } },
250 	{ 28,   6, { 0b11111111, 0b11111111, 0b11111110, 0b01100000 } },
251 	{ 28,   7, { 0b11111111, 0b11111111, 0b11111110, 0b01110000 } },
252 	{ 28,   8, { 0b11111111, 0b11111111, 0b11111110, 0b10000000 } },
253 	{ 28,  11, { 0b11111111, 0b11111111, 0b11111110, 0b10010000 } },
254 	{ 28,  12, { 0b11111111, 0b11111111, 0b11111110, 0b10100000 } },
255 	{ 28,  14, { 0b11111111, 0b11111111, 0b11111110, 0b10110000 } },
256 	{ 28,  15, { 0b11111111, 0b11111111, 0b11111110, 0b11000000 } },
257 	{ 28,  16, { 0b11111111, 0b11111111, 0b11111110, 0b11010000 } },
258 	{ 28,  17, { 0b11111111, 0b11111111, 0b11111110, 0b11100000 } },
259 	{ 28,  18, { 0b11111111, 0b11111111, 0b11111110, 0b11110000 } },
260 	{ 28,  19, { 0b11111111, 0b11111111, 0b11111111, 0b00000000 } },
261 	{ 28,  20, { 0b11111111, 0b11111111, 0b11111111, 0b00010000 } },
262 	{ 28,  21, { 0b11111111, 0b11111111, 0b11111111, 0b00100000 } },
263 	{ 28,  23, { 0b11111111, 0b11111111, 0b11111111, 0b00110000 } },
264 	{ 28,  24, { 0b11111111, 0b11111111, 0b11111111, 0b01000000 } },
265 	{ 28,  25, { 0b11111111, 0b11111111, 0b11111111, 0b01010000 } },
266 	{ 28,  26, { 0b11111111, 0b11111111, 0b11111111, 0b01100000 } },
267 	{ 28,  27, { 0b11111111, 0b11111111, 0b11111111, 0b01110000 } },
268 	{ 28,  28, { 0b11111111, 0b11111111, 0b11111111, 0b10000000 } },
269 	{ 28,  29, { 0b11111111, 0b11111111, 0b11111111, 0b10010000 } },
270 	{ 28,  30, { 0b11111111, 0b11111111, 0b11111111, 0b10100000 } },
271 	{ 28,  31, { 0b11111111, 0b11111111, 0b11111111, 0b10110000 } },
272 	{ 28, 127, { 0b11111111, 0b11111111, 0b11111111, 0b11000000 } },
273 	{ 28, 220, { 0b11111111, 0b11111111, 0b11111111, 0b11010000 } },
274 	{ 28, 249, { 0b11111111, 0b11111111, 0b11111111, 0b11100000 } },
275 	{ 30,  10, { 0b11111111, 0b11111111, 0b11111111, 0b11110000 } },
276 	{ 30,  13, { 0b11111111, 0b11111111, 0b11111111, 0b11110100 } },
277 	{ 30,  22, { 0b11111111, 0b11111111, 0b11111111, 0b11111000 } },
278 };
279 
280 static const struct decode_elem eos = {
281 	30,   0, { 0b11111111, 0b11111111, 0b11111111, 0b11111100 }
282 };
283 
284 #define UINT32_BITLEN 32
285 
286 #define MSB_MASK(len) (UINT32_MAX << (UINT32_BITLEN - len))
287 #define LSB_MASK(len) ((1UL << len) - 1UL)
288 
huffman_bits_compare(uint32_t bits,const struct decode_elem * entry)289 static bool huffman_bits_compare(uint32_t bits, const struct decode_elem *entry)
290 {
291 	uint32_t mask = MSB_MASK(entry->bitlen);
292 	uint32_t code = sys_get_be32(entry->code);
293 
294 	if (code == (bits & mask)) {
295 		return true;
296 	}
297 
298 	return false;
299 }
300 
huffman_decode_bits(uint32_t bits)301 static const struct decode_elem *huffman_decode_bits(uint32_t bits)
302 {
303 	for (int i = 0; i < ARRAY_SIZE(decode_table); i++) {
304 		if (huffman_bits_compare(bits, &decode_table[i])) {
305 			return &decode_table[i];
306 		}
307 	}
308 
309 	if (huffman_bits_compare(bits, &eos)) {
310 		return &eos;
311 	}
312 
313 	return NULL;
314 }
315 
huffman_find_entry(uint8_t symbol)316 static const struct decode_elem *huffman_find_entry(uint8_t symbol)
317 {
318 	for (int i = 0; i < ARRAY_SIZE(decode_table); i++) {
319 		if (decode_table[i].symbol == symbol) {
320 			return &decode_table[i];
321 		}
322 	}
323 
324 	return NULL;
325 }
326 
327 #define MAX_PADDING_LEN 7
328 
http_hpack_huffman_decode(const uint8_t * encoded_buf,size_t encoded_len,uint8_t * buf,size_t buflen)329 int http_hpack_huffman_decode(const uint8_t *encoded_buf, size_t encoded_len,
330 			      uint8_t *buf, size_t buflen)
331 {
332 	size_t encoded_bits_len = encoded_len * 8;
333 	uint8_t bits_needed = UINT32_BITLEN;
334 	const struct decode_elem *decoded;
335 	uint8_t bits_in_byte_left = 8;
336 	size_t decoded_len = 0;
337 	uint32_t bits = 0;
338 
339 	if (encoded_buf == NULL || buf == NULL || encoded_len == 0) {
340 		return -EINVAL;
341 	}
342 
343 	while (encoded_bits_len > 0) {
344 		/* Refill the bits variable */
345 		while (bits_needed > 0) {
346 			if (encoded_len > 0) {
347 				if (bits_in_byte_left <= bits_needed) {
348 					/* Consume rest of the byte */
349 					bits <<= bits_in_byte_left;
350 					bits |= *encoded_buf &
351 						    LSB_MASK(bits_in_byte_left);
352 					bits_needed -= bits_in_byte_left;
353 					bits_in_byte_left = 0;
354 				} else {
355 					/* Consume part of the byte */
356 					bits <<= bits_needed;
357 					bits |= (*encoded_buf >>
358 						 (bits_in_byte_left - bits_needed)) &
359 						LSB_MASK(bits_needed);
360 					bits_in_byte_left -= bits_needed;
361 					bits_needed = 0;
362 				}
363 			} else {
364 				/* Pad with ones */
365 				bits <<= bits_needed;
366 				bits |= LSB_MASK(bits_needed);
367 				bits_needed = 0;
368 			}
369 
370 			/* Move to next encoded byte */
371 			if (bits_in_byte_left == 0) {
372 				encoded_buf++;
373 				encoded_len--;
374 				bits_in_byte_left = 8;
375 			}
376 		}
377 
378 		/* Pass to decoder */
379 		decoded = huffman_decode_bits(bits);
380 		if (decoded == NULL) {
381 			LOG_ERR("No symbol found");
382 			return -EBADMSG;
383 		}
384 
385 		if (decoded == &eos) {
386 			if (encoded_bits_len > MAX_PADDING_LEN) {
387 				LOG_ERR("eos reached prematurely");
388 				return -EBADMSG;
389 			}
390 
391 			break;
392 		}
393 
394 		if (encoded_bits_len < decoded->bitlen) {
395 			LOG_ERR("Invalid symbol used for padding");
396 			return -EBADMSG;
397 		}
398 
399 		/* Remove consumed bits from bits variable. */
400 		bits_needed += decoded->bitlen;
401 		encoded_bits_len -= decoded->bitlen;
402 
403 		/* Store decoded symbol */
404 		if (buflen == 0) {
405 			LOG_ERR("Not enough buffer to decode string");
406 			return -ENOBUFS;
407 		}
408 
409 		*buf = decoded->symbol;
410 		buf++;
411 		buflen--;
412 		decoded_len++;
413 	}
414 
415 	return decoded_len;
416 }
417 
http_hpack_huffman_encode(const uint8_t * str,size_t str_len,uint8_t * buf,size_t buflen)418 int http_hpack_huffman_encode(const uint8_t *str, size_t str_len,
419 			      uint8_t *buf, size_t buflen)
420 {
421 	const struct decode_elem *entry;
422 	size_t buflen_bits = buflen * 8;
423 	uint8_t bit_offset = 0;
424 	int len = 0;
425 
426 	if (str == NULL || buf == NULL || str_len == 0) {
427 		return -EINVAL;
428 	}
429 
430 	while (str_len > 0) {
431 		uint32_t code;
432 		uint8_t bitlen;
433 
434 		entry = huffman_find_entry(*str);
435 		if (entry == NULL) {
436 			return -EINVAL;
437 		}
438 
439 		if (entry->bitlen > buflen_bits) {
440 			return -ENOBUFS;
441 		}
442 
443 		bitlen = entry->bitlen;
444 		code = sys_get_be32(entry->code);
445 
446 		while (bitlen > 0) {
447 			uint8_t to_copy = MIN(8 - bit_offset, bitlen);
448 			uint8_t byte = (uint8_t)((code & MSB_MASK(to_copy)) >>
449 						 (24 + bit_offset));
450 
451 			/* This is way suboptimal */
452 			if (bit_offset == 0) {
453 				*buf = byte;
454 			} else {
455 				*buf |= byte;
456 			}
457 
458 			code <<= to_copy;
459 			bitlen -= to_copy;
460 			bit_offset  = (bit_offset + to_copy) % 8;
461 
462 			if (bit_offset == 0) {
463 				buf++;
464 				len++;
465 			}
466 		}
467 
468 		buflen_bits -= entry->bitlen;
469 		str_len--;
470 		str++;
471 	}
472 
473 	/* Pad with ones. */
474 	if (bit_offset > 0) {
475 		*buf |= LSB_MASK((8 - bit_offset));
476 		len++;
477 	}
478 
479 	return len;
480 }
481