Skip to main content

sark_core/http/
huffman.rs

1use core::convert::Infallible;
2
3#[repr(transparent)]
4#[derive(Copy, Clone, Debug, PartialEq, Eq)]
5/// Bytes before HPACK/QPACK Huffman encoding.
6pub struct HpackHuffmanSource<'a>(&'a [u8]);
7
8#[repr(transparent)]
9#[derive(Copy, Clone, Debug, PartialEq, Eq)]
10/// Bytes carrying an HPACK/QPACK Huffman bit stream.
11pub struct HpackHuffmanEncoded<'a>(&'a [u8]);
12
13#[derive(Copy, Clone, Debug, PartialEq, Eq)]
14/// An invalid Huffman code, EOS symbol, or padding suffix.
15pub struct HpackHuffmanError;
16
17#[derive(Copy, Clone, Debug, PartialEq, Eq)]
18/// Separates malformed input from a failure in the decoded-byte sink.
19pub enum HpackHuffmanDecodeError<E> {
20    InvalidEncoding(HpackHuffmanError),
21    Sink(E),
22}
23
24#[derive(Clone, Copy, Debug, PartialEq, Eq)]
25/// Incremental HPACK/QPACK Huffman decoder state.
26pub struct HpackHuffmanDecoder {
27    state: u8,
28    maybe_eos: bool,
29}
30
31/// RFC 7541 Appendix B canonical codes, including EOS at index 256.
32pub const CODES: [(u32, u8); 257] = [
33    (0x1ff8, 13),
34    (0x7fffd8, 23),
35    (0xfffffe2, 28),
36    (0xfffffe3, 28),
37    (0xfffffe4, 28),
38    (0xfffffe5, 28),
39    (0xfffffe6, 28),
40    (0xfffffe7, 28),
41    (0xfffffe8, 28),
42    (0xffffea, 24),
43    (0x3ffffffc, 30),
44    (0xfffffe9, 28),
45    (0xfffffea, 28),
46    (0x3ffffffd, 30),
47    (0xfffffeb, 28),
48    (0xfffffec, 28),
49    (0xfffffed, 28),
50    (0xfffffee, 28),
51    (0xfffffef, 28),
52    (0xffffff0, 28),
53    (0xffffff1, 28),
54    (0xffffff2, 28),
55    (0x3ffffffe, 30),
56    (0xffffff3, 28),
57    (0xffffff4, 28),
58    (0xffffff5, 28),
59    (0xffffff6, 28),
60    (0xffffff7, 28),
61    (0xffffff8, 28),
62    (0xffffff9, 28),
63    (0xffffffa, 28),
64    (0xffffffb, 28),
65    (0x14, 6),
66    (0x3f8, 10),
67    (0x3f9, 10),
68    (0xffa, 12),
69    (0x1ff9, 13),
70    (0x15, 6),
71    (0xf8, 8),
72    (0x7fa, 11),
73    (0x3fa, 10),
74    (0x3fb, 10),
75    (0xf9, 8),
76    (0x7fb, 11),
77    (0xfa, 8),
78    (0x16, 6),
79    (0x17, 6),
80    (0x18, 6),
81    (0x0, 5),
82    (0x1, 5),
83    (0x2, 5),
84    (0x19, 6),
85    (0x1a, 6),
86    (0x1b, 6),
87    (0x1c, 6),
88    (0x1d, 6),
89    (0x1e, 6),
90    (0x1f, 6),
91    (0x5c, 7),
92    (0xfb, 8),
93    (0x7ffc, 15),
94    (0x20, 6),
95    (0xffb, 12),
96    (0x3fc, 10),
97    (0x1ffa, 13),
98    (0x21, 6),
99    (0x5d, 7),
100    (0x5e, 7),
101    (0x5f, 7),
102    (0x60, 7),
103    (0x61, 7),
104    (0x62, 7),
105    (0x63, 7),
106    (0x64, 7),
107    (0x65, 7),
108    (0x66, 7),
109    (0x67, 7),
110    (0x68, 7),
111    (0x69, 7),
112    (0x6a, 7),
113    (0x6b, 7),
114    (0x6c, 7),
115    (0x6d, 7),
116    (0x6e, 7),
117    (0x6f, 7),
118    (0x70, 7),
119    (0x71, 7),
120    (0x72, 7),
121    (0xfc, 8),
122    (0x73, 7),
123    (0xfd, 8),
124    (0x1ffb, 13),
125    (0x7fff0, 19),
126    (0x1ffc, 13),
127    (0x3ffc, 14),
128    (0x22, 6),
129    (0x7ffd, 15),
130    (0x3, 5),
131    (0x23, 6),
132    (0x4, 5),
133    (0x24, 6),
134    (0x5, 5),
135    (0x25, 6),
136    (0x26, 6),
137    (0x27, 6),
138    (0x6, 5),
139    (0x74, 7),
140    (0x75, 7),
141    (0x28, 6),
142    (0x29, 6),
143    (0x2a, 6),
144    (0x7, 5),
145    (0x2b, 6),
146    (0x76, 7),
147    (0x2c, 6),
148    (0x8, 5),
149    (0x9, 5),
150    (0x2d, 6),
151    (0x77, 7),
152    (0x78, 7),
153    (0x79, 7),
154    (0x7a, 7),
155    (0x7b, 7),
156    (0x7ffe, 15),
157    (0x7fc, 11),
158    (0x3ffd, 14),
159    (0x1ffd, 13),
160    (0xffffffc, 28),
161    (0xfffe6, 20),
162    (0x3fffd2, 22),
163    (0xfffe7, 20),
164    (0xfffe8, 20),
165    (0x3fffd3, 22),
166    (0x3fffd4, 22),
167    (0x3fffd5, 22),
168    (0x7fffd9, 23),
169    (0x3fffd6, 22),
170    (0x7fffda, 23),
171    (0x7fffdb, 23),
172    (0x7fffdc, 23),
173    (0x7fffdd, 23),
174    (0x7fffde, 23),
175    (0xffffeb, 24),
176    (0x7fffdf, 23),
177    (0xffffec, 24),
178    (0xffffed, 24),
179    (0x3fffd7, 22),
180    (0x7fffe0, 23),
181    (0xffffee, 24),
182    (0x7fffe1, 23),
183    (0x7fffe2, 23),
184    (0x7fffe3, 23),
185    (0x7fffe4, 23),
186    (0x1fffdc, 21),
187    (0x3fffd8, 22),
188    (0x7fffe5, 23),
189    (0x3fffd9, 22),
190    (0x7fffe6, 23),
191    (0x7fffe7, 23),
192    (0xffffef, 24),
193    (0x3fffda, 22),
194    (0x1fffdd, 21),
195    (0xfffe9, 20),
196    (0x3fffdb, 22),
197    (0x3fffdc, 22),
198    (0x7fffe8, 23),
199    (0x7fffe9, 23),
200    (0x1fffde, 21),
201    (0x7fffea, 23),
202    (0x3fffdd, 22),
203    (0x3fffde, 22),
204    (0xfffff0, 24),
205    (0x1fffdf, 21),
206    (0x3fffdf, 22),
207    (0x7fffeb, 23),
208    (0x7fffec, 23),
209    (0x1fffe0, 21),
210    (0x1fffe1, 21),
211    (0x3fffe0, 22),
212    (0x1fffe2, 21),
213    (0x7fffed, 23),
214    (0x3fffe1, 22),
215    (0x7fffee, 23),
216    (0x7fffef, 23),
217    (0xfffea, 20),
218    (0x3fffe2, 22),
219    (0x3fffe3, 22),
220    (0x3fffe4, 22),
221    (0x7ffff0, 23),
222    (0x3fffe5, 22),
223    (0x3fffe6, 22),
224    (0x7ffff1, 23),
225    (0x3ffffe0, 26),
226    (0x3ffffe1, 26),
227    (0xfffeb, 20),
228    (0x7fff1, 19),
229    (0x3fffe7, 22),
230    (0x7ffff2, 23),
231    (0x3fffe8, 22),
232    (0x1ffffec, 25),
233    (0x3ffffe2, 26),
234    (0x3ffffe3, 26),
235    (0x3ffffe4, 26),
236    (0x7ffffde, 27),
237    (0x7ffffdf, 27),
238    (0x3ffffe5, 26),
239    (0xfffff1, 24),
240    (0x1ffffed, 25),
241    (0x7fff2, 19),
242    (0x1fffe3, 21),
243    (0x3ffffe6, 26),
244    (0x7ffffe0, 27),
245    (0x7ffffe1, 27),
246    (0x3ffffe7, 26),
247    (0x7ffffe2, 27),
248    (0xfffff2, 24),
249    (0x1fffe4, 21),
250    (0x1fffe5, 21),
251    (0x3ffffe8, 26),
252    (0x3ffffe9, 26),
253    (0xffffffd, 28),
254    (0x7ffffe3, 27),
255    (0x7ffffe4, 27),
256    (0x7ffffe5, 27),
257    (0xfffec, 20),
258    (0xfffff3, 24),
259    (0xfffed, 20),
260    (0x1fffe6, 21),
261    (0x3fffe9, 22),
262    (0x1fffe7, 21),
263    (0x1fffe8, 21),
264    (0x7ffff3, 23),
265    (0x3fffea, 22),
266    (0x3fffeb, 22),
267    (0x1ffffee, 25),
268    (0x1ffffef, 25),
269    (0xfffff4, 24),
270    (0xfffff5, 24),
271    (0x3ffffea, 26),
272    (0x7ffff4, 23),
273    (0x3ffffeb, 26),
274    (0x7ffffe6, 27),
275    (0x3ffffec, 26),
276    (0x3ffffed, 26),
277    (0x7ffffe7, 27),
278    (0x7ffffe8, 27),
279    (0x7ffffe9, 27),
280    (0x7ffffea, 27),
281    (0x7ffffeb, 27),
282    (0xffffffe, 28),
283    (0x7ffffec, 27),
284    (0x7ffffed, 27),
285    (0x7ffffee, 27),
286    (0x7ffffef, 27),
287    (0x7fffff0, 27),
288    (0x3ffffee, 26),
289    (0x3fffffff, 30),
290];
291
292const DECODED: u8 = 1;
293const ERROR: u8 = 2;
294const MAYBE_EOS: u8 = 4;
295const NO_NODE: u16 = u16::MAX;
296const NO_SYMBOL: u16 = u16::MAX;
297const NODE_COUNT: usize = CODES.len() * 2 - 1;
298const STATE_COUNT: usize = CODES.len() - 1;
299
300#[repr(C)]
301#[derive(Copy, Clone)]
302struct DecodeEntry {
303    next_state: u8,
304    byte: u8,
305    flags: u8,
306}
307
308impl DecodeEntry {
309    const EMPTY: Self = Self {
310        next_state: 0,
311        byte: 0,
312        flags: 0,
313    };
314}
315
316#[derive(Copy, Clone)]
317struct TreeNode {
318    children: [u16; 2],
319    symbol: u16,
320}
321
322impl TreeNode {
323    const EMPTY: Self = Self {
324        children: [NO_NODE; 2],
325        symbol: NO_SYMBOL,
326    };
327}
328
329const DECODE_TABLE: [[DecodeEntry; 16]; STATE_COUNT] = build_decode_table();
330
331const fn build_decode_table() -> [[DecodeEntry; 16]; STATE_COUNT] {
332    let mut nodes = [TreeNode::EMPTY; NODE_COUNT];
333    let mut node_count = 1usize;
334    let mut symbol = 0usize;
335    while symbol < CODES.len() {
336        let (code, code_len) = CODES[symbol];
337        let mut node = 0usize;
338        let mut bit = code_len as usize;
339        while bit != 0 {
340            bit -= 1;
341            let direction = ((code >> bit) & 1) as usize;
342            let child = nodes[node].children[direction];
343            if child == NO_NODE {
344                nodes[node].children[direction] = node_count as u16;
345                node = node_count;
346                node_count += 1;
347            } else {
348                node = child as usize;
349            }
350        }
351        nodes[node].symbol = symbol as u16;
352        symbol += 1;
353    }
354
355    let mut node_by_state = [0u16; STATE_COUNT];
356    let mut state_by_node = [0u8; NODE_COUNT];
357    let mut state_count = 0usize;
358    let mut node = 0usize;
359    while node < node_count {
360        if nodes[node].symbol == NO_SYMBOL {
361            node_by_state[state_count] = node as u16;
362            state_by_node[node] = state_count as u8;
363            state_count += 1;
364        }
365        node += 1;
366    }
367
368    let mut eos_prefix = [false; NODE_COUNT];
369    eos_prefix[0] = true;
370    node = 0;
371    let mut eos_bits = 0;
372    while eos_bits < 7 {
373        node = nodes[node].children[1] as usize;
374        eos_prefix[node] = true;
375        eos_bits += 1;
376    }
377
378    let mut table = [[DecodeEntry::EMPTY; 16]; STATE_COUNT];
379    let mut state = 0usize;
380    while state < state_count {
381        let mut nibble = 0usize;
382        while nibble < 16 {
383            node = node_by_state[state] as usize;
384            let mut byte = 0;
385            let mut flags = 0;
386            let mut remaining = 4usize;
387            while remaining != 0 {
388                remaining -= 1;
389                let direction = (nibble >> remaining) & 1;
390                node = nodes[node].children[direction] as usize;
391                let decoded = nodes[node].symbol;
392                if decoded != NO_SYMBOL {
393                    if decoded == 256 {
394                        flags |= ERROR;
395                        node = 0;
396                        break;
397                    }
398                    flags |= DECODED;
399                    byte = decoded as u8;
400                    node = 0;
401                }
402            }
403            if eos_prefix[node] {
404                flags |= MAYBE_EOS;
405            }
406            table[state][nibble] = DecodeEntry {
407                next_state: state_by_node[node],
408                byte,
409                flags,
410            };
411            nibble += 1;
412        }
413        state += 1;
414    }
415    table
416}
417
418impl<'a> HpackHuffmanSource<'a> {
419    pub const fn new(input: &'a [u8]) -> Self {
420        Self(input)
421    }
422
423    pub fn encoded_len(self) -> usize {
424        let mut bits: u64 = 0;
425        for &b in self.0 {
426            bits += CODES[b as usize].1 as u64;
427        }
428        bits.div_ceil(8) as usize
429    }
430
431    pub fn encode(self, out: &mut Vec<u8>) {
432        let mut buffer: u64 = 0;
433        let mut bits_in: u32 = 0;
434        for &b in self.0 {
435            let (code, len) = CODES[b as usize];
436            let len = len as u32;
437            buffer = (buffer << len) | (code as u64);
438            bits_in += len;
439            while bits_in >= 8 {
440                bits_in -= 8;
441                out.push((buffer >> bits_in) as u8);
442            }
443        }
444        if bits_in > 0 {
445            let pad_bits = 8 - bits_in;
446            buffer = (buffer << pad_bits) | ((1u64 << pad_bits) - 1);
447            out.push(buffer as u8);
448        }
449    }
450}
451
452impl<'a> HpackHuffmanEncoded<'a> {
453    pub const fn new(input: &'a [u8]) -> Self {
454        Self(input)
455    }
456
457    pub fn decode(self, out: &mut Vec<u8>) -> Result<(), HpackHuffmanError> {
458        match self.decode_with(|byte| {
459            out.push(byte);
460            Ok::<_, Infallible>(())
461        }) {
462            Ok(()) => Ok(()),
463            Err(HpackHuffmanDecodeError::InvalidEncoding(error)) => Err(error),
464            Err(HpackHuffmanDecodeError::Sink(never)) => match never {},
465        }
466    }
467
468    pub fn decode_with<E>(
469        self,
470        emit: impl FnMut(u8) -> Result<(), E>,
471    ) -> Result<(), HpackHuffmanDecodeError<E>> {
472        let mut decoder = HpackHuffmanDecoder::new();
473        decoder.feed(self.0, emit)?;
474        decoder
475            .finish()
476            .map_err(HpackHuffmanDecodeError::InvalidEncoding)
477    }
478}
479
480impl HpackHuffmanDecoder {
481    pub const fn new() -> Self {
482        Self {
483            state: 0,
484            maybe_eos: true,
485        }
486    }
487
488    pub fn feed<E>(
489        &mut self,
490        input: &[u8],
491        mut emit: impl FnMut(u8) -> Result<(), E>,
492    ) -> Result<(), HpackHuffmanDecodeError<E>> {
493        let mut state = self.state as usize;
494        let mut maybe_eos = self.maybe_eos;
495        for &byte in input {
496            let high = DECODE_TABLE[state][(byte >> 4) as usize];
497            if high.flags & ERROR != 0 {
498                return Err(HpackHuffmanDecodeError::InvalidEncoding(HpackHuffmanError));
499            }
500            if high.flags & DECODED != 0 {
501                emit(high.byte).map_err(HpackHuffmanDecodeError::Sink)?;
502            }
503            state = high.next_state as usize;
504
505            let low = DECODE_TABLE[state][(byte & 0x0f) as usize];
506            if low.flags & ERROR != 0 {
507                return Err(HpackHuffmanDecodeError::InvalidEncoding(HpackHuffmanError));
508            }
509            if low.flags & DECODED != 0 {
510                emit(low.byte).map_err(HpackHuffmanDecodeError::Sink)?;
511            }
512            state = low.next_state as usize;
513            maybe_eos = low.flags & MAYBE_EOS != 0;
514        }
515        self.state = state as u8;
516        self.maybe_eos = maybe_eos;
517        Ok(())
518    }
519
520    pub fn finish(self) -> Result<(), HpackHuffmanError> {
521        if self.state == 0 || self.maybe_eos {
522            Ok(())
523        } else {
524            Err(HpackHuffmanError)
525        }
526    }
527}
528
529impl Default for HpackHuffmanDecoder {
530    fn default() -> Self {
531        Self::new()
532    }
533}