1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package io.netty.handler.codec.http3;
17
18 import io.netty.buffer.ByteBuf;
19 import io.netty.util.AsciiString;
20 import io.netty.util.internal.ConstantTimeUtils;
21 import io.netty.util.internal.PlatformDependent;
22
23 import static io.netty.util.internal.ObjectUtil.checkInRange;
24 import static java.lang.Math.floorDiv;
25
26 final class QpackUtil {
27 private static final QpackException PREFIXED_INTEGER_TOO_LONG =
28 QpackException.newStatic(QpackDecoder.class, "toIntOrThrow(...)",
29 "QPACK - invalid prefixed integer");
30
31
32
33
34
35 static void encodePrefixedInteger(ByteBuf out, byte mask, int prefixLength, long toEncode) {
36 checkInRange(toEncode, 0, MAX_UNSIGNED_INT, "toEncode");
37 int nbits = (1 << prefixLength) - 1;
38 if (toEncode < nbits) {
39 out.writeByte((byte) (mask | toEncode));
40 } else {
41 out.writeByte((byte) (mask | nbits));
42 long remainder = toEncode - nbits;
43 while (remainder > 128) {
44 byte next = (byte) ((remainder % 128) | 0x80);
45 out.writeByte(next);
46 remainder = remainder / 128;
47 }
48 out.writeByte((byte) remainder);
49 }
50 }
51
52
53
54
55
56
57
58
59
60 static int decodePrefixedIntegerAsInt(ByteBuf in, int prefixLength) throws QpackException {
61 return toIntOrThrow(decodePrefixedInteger(in, prefixLength));
62 }
63
64
65
66
67
68
69
70
71 static int toIntOrThrow(long aLong) throws QpackException {
72 if ((int) aLong != aLong) {
73 throw PREFIXED_INTEGER_TOO_LONG;
74 }
75 return (int) aLong;
76 }
77
78
79
80
81
82
83
84
85
86 static long decodePrefixedInteger(ByteBuf in, int prefixLength) {
87 int readerIndex = in.readerIndex();
88 int writerIndex = in.writerIndex();
89 if (readerIndex == writerIndex) {
90 return -1;
91 }
92
93 int nbits = (1 << prefixLength) - 1;
94 int first = in.readByte() & nbits;
95 if (first < nbits) {
96 return first;
97 }
98
99 int idx = readerIndex + 1;
100 long i = first;
101 int factor = 0;
102 byte next;
103 do {
104 if (idx == writerIndex) {
105 in.readerIndex(readerIndex);
106 return -1;
107 }
108 next = in.getByte(idx++);
109 i += (next & 0x7fL) << factor;
110 factor += 7;
111 } while ((next & 0x80) == 0x80);
112 in.readerIndex(idx);
113 return i;
114 }
115
116 static boolean firstByteEquals(ByteBuf in, byte mask) {
117 return (in.getByte(in.readerIndex()) & mask) == mask;
118 }
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135 static int equalsConstantTime(CharSequence s1, CharSequence s2) {
136 if (s1 instanceof AsciiString && s2 instanceof AsciiString) {
137 if (s1.length() != s2.length()) {
138 return 0;
139 }
140 AsciiString s1Ascii = (AsciiString) s1;
141 AsciiString s2Ascii = (AsciiString) s2;
142 return PlatformDependent.equalsConstantTime(s1Ascii.array(), s1Ascii.arrayOffset(),
143 s2Ascii.array(), s2Ascii.arrayOffset(), s1.length());
144 }
145
146 return ConstantTimeUtils.equalsConstantTime(s1, s2);
147 }
148
149
150
151
152
153
154
155 static boolean equalsVariableTime(CharSequence s1, CharSequence s2) {
156 return AsciiString.contentEquals(s1, s2);
157 }
158
159
160
161
162
163
164
165
166 static long maxEntries(long maxTableCapacity) {
167
168 return floorDiv(maxTableCapacity, 32);
169 }
170
171
172 enum IndexType {
173 INCREMENTAL,
174 NONE,
175 NEVER
176 }
177
178
179
180 static final int[] HUFFMAN_CODES = {
181 0x1ff8,
182 0x7fffd8,
183 0xfffffe2,
184 0xfffffe3,
185 0xfffffe4,
186 0xfffffe5,
187 0xfffffe6,
188 0xfffffe7,
189 0xfffffe8,
190 0xffffea,
191 0x3ffffffc,
192 0xfffffe9,
193 0xfffffea,
194 0x3ffffffd,
195 0xfffffeb,
196 0xfffffec,
197 0xfffffed,
198 0xfffffee,
199 0xfffffef,
200 0xffffff0,
201 0xffffff1,
202 0xffffff2,
203 0x3ffffffe,
204 0xffffff3,
205 0xffffff4,
206 0xffffff5,
207 0xffffff6,
208 0xffffff7,
209 0xffffff8,
210 0xffffff9,
211 0xffffffa,
212 0xffffffb,
213 0x14,
214 0x3f8,
215 0x3f9,
216 0xffa,
217 0x1ff9,
218 0x15,
219 0xf8,
220 0x7fa,
221 0x3fa,
222 0x3fb,
223 0xf9,
224 0x7fb,
225 0xfa,
226 0x16,
227 0x17,
228 0x18,
229 0x0,
230 0x1,
231 0x2,
232 0x19,
233 0x1a,
234 0x1b,
235 0x1c,
236 0x1d,
237 0x1e,
238 0x1f,
239 0x5c,
240 0xfb,
241 0x7ffc,
242 0x20,
243 0xffb,
244 0x3fc,
245 0x1ffa,
246 0x21,
247 0x5d,
248 0x5e,
249 0x5f,
250 0x60,
251 0x61,
252 0x62,
253 0x63,
254 0x64,
255 0x65,
256 0x66,
257 0x67,
258 0x68,
259 0x69,
260 0x6a,
261 0x6b,
262 0x6c,
263 0x6d,
264 0x6e,
265 0x6f,
266 0x70,
267 0x71,
268 0x72,
269 0xfc,
270 0x73,
271 0xfd,
272 0x1ffb,
273 0x7fff0,
274 0x1ffc,
275 0x3ffc,
276 0x22,
277 0x7ffd,
278 0x3,
279 0x23,
280 0x4,
281 0x24,
282 0x5,
283 0x25,
284 0x26,
285 0x27,
286 0x6,
287 0x74,
288 0x75,
289 0x28,
290 0x29,
291 0x2a,
292 0x7,
293 0x2b,
294 0x76,
295 0x2c,
296 0x8,
297 0x9,
298 0x2d,
299 0x77,
300 0x78,
301 0x79,
302 0x7a,
303 0x7b,
304 0x7ffe,
305 0x7fc,
306 0x3ffd,
307 0x1ffd,
308 0xffffffc,
309 0xfffe6,
310 0x3fffd2,
311 0xfffe7,
312 0xfffe8,
313 0x3fffd3,
314 0x3fffd4,
315 0x3fffd5,
316 0x7fffd9,
317 0x3fffd6,
318 0x7fffda,
319 0x7fffdb,
320 0x7fffdc,
321 0x7fffdd,
322 0x7fffde,
323 0xffffeb,
324 0x7fffdf,
325 0xffffec,
326 0xffffed,
327 0x3fffd7,
328 0x7fffe0,
329 0xffffee,
330 0x7fffe1,
331 0x7fffe2,
332 0x7fffe3,
333 0x7fffe4,
334 0x1fffdc,
335 0x3fffd8,
336 0x7fffe5,
337 0x3fffd9,
338 0x7fffe6,
339 0x7fffe7,
340 0xffffef,
341 0x3fffda,
342 0x1fffdd,
343 0xfffe9,
344 0x3fffdb,
345 0x3fffdc,
346 0x7fffe8,
347 0x7fffe9,
348 0x1fffde,
349 0x7fffea,
350 0x3fffdd,
351 0x3fffde,
352 0xfffff0,
353 0x1fffdf,
354 0x3fffdf,
355 0x7fffeb,
356 0x7fffec,
357 0x1fffe0,
358 0x1fffe1,
359 0x3fffe0,
360 0x1fffe2,
361 0x7fffed,
362 0x3fffe1,
363 0x7fffee,
364 0x7fffef,
365 0xfffea,
366 0x3fffe2,
367 0x3fffe3,
368 0x3fffe4,
369 0x7ffff0,
370 0x3fffe5,
371 0x3fffe6,
372 0x7ffff1,
373 0x3ffffe0,
374 0x3ffffe1,
375 0xfffeb,
376 0x7fff1,
377 0x3fffe7,
378 0x7ffff2,
379 0x3fffe8,
380 0x1ffffec,
381 0x3ffffe2,
382 0x3ffffe3,
383 0x3ffffe4,
384 0x7ffffde,
385 0x7ffffdf,
386 0x3ffffe5,
387 0xfffff1,
388 0x1ffffed,
389 0x7fff2,
390 0x1fffe3,
391 0x3ffffe6,
392 0x7ffffe0,
393 0x7ffffe1,
394 0x3ffffe7,
395 0x7ffffe2,
396 0xfffff2,
397 0x1fffe4,
398 0x1fffe5,
399 0x3ffffe8,
400 0x3ffffe9,
401 0xffffffd,
402 0x7ffffe3,
403 0x7ffffe4,
404 0x7ffffe5,
405 0xfffec,
406 0xfffff3,
407 0xfffed,
408 0x1fffe6,
409 0x3fffe9,
410 0x1fffe7,
411 0x1fffe8,
412 0x7ffff3,
413 0x3fffea,
414 0x3fffeb,
415 0x1ffffee,
416 0x1ffffef,
417 0xfffff4,
418 0xfffff5,
419 0x3ffffea,
420 0x7ffff4,
421 0x3ffffeb,
422 0x7ffffe6,
423 0x3ffffec,
424 0x3ffffed,
425 0x7ffffe7,
426 0x7ffffe8,
427 0x7ffffe9,
428 0x7ffffea,
429 0x7ffffeb,
430 0xffffffe,
431 0x7ffffec,
432 0x7ffffed,
433 0x7ffffee,
434 0x7ffffef,
435 0x7fffff0,
436 0x3ffffee,
437 0x3fffffff
438 };
439
440 static final byte[] HUFFMAN_CODE_LENGTHS = {
441 13, 23, 28, 28, 28, 28, 28, 28, 28, 24, 30, 28, 28, 30, 28, 28,
442 28, 28, 28, 28, 28, 28, 30, 28, 28, 28, 28, 28, 28, 28, 28, 28,
443 6, 10, 10, 12, 13, 6, 8, 11, 10, 10, 8, 11, 8, 6, 6, 6,
444 5, 5, 5, 6, 6, 6, 6, 6, 6, 6, 7, 8, 15, 6, 12, 10,
445 13, 6, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
446 7, 7, 7, 7, 7, 7, 7, 7, 8, 7, 8, 13, 19, 13, 14, 6,
447 15, 5, 6, 5, 6, 5, 6, 6, 6, 5, 7, 7, 6, 6, 6, 5,
448 6, 7, 6, 5, 5, 6, 7, 7, 7, 7, 7, 15, 11, 14, 13, 28,
449 20, 22, 20, 20, 22, 22, 22, 23, 22, 23, 23, 23, 23, 23, 24, 23,
450 24, 24, 22, 23, 24, 23, 23, 23, 23, 21, 22, 23, 22, 23, 23, 24,
451 22, 21, 20, 22, 22, 23, 23, 21, 23, 22, 22, 24, 21, 22, 23, 23,
452 21, 21, 22, 21, 23, 22, 23, 23, 20, 22, 22, 22, 23, 22, 22, 23,
453 26, 26, 20, 19, 22, 23, 22, 25, 26, 26, 26, 27, 27, 26, 24, 25,
454 19, 21, 26, 27, 27, 26, 27, 24, 21, 21, 26, 26, 28, 27, 27, 27,
455 20, 24, 20, 21, 22, 21, 21, 23, 22, 22, 25, 25, 24, 24, 26, 23,
456 26, 27, 26, 26, 27, 27, 27, 27, 27, 28, 27, 27, 27, 27, 27, 26,
457 30
458 };
459
460 static final int HUFFMAN_EOS = 256;
461
462 static final long MIN_HEADER_TABLE_SIZE = 0;
463 static final long MAX_UNSIGNED_INT = 0xffffffffL;
464 static final long MAX_HEADER_TABLE_SIZE = MAX_UNSIGNED_INT;
465
466 private QpackUtil() {
467 }
468 }