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