1use std::collections::VecDeque;
4
5use crate::prim::{get_int, get_span, put_int, span_bytes, Short, STATIC_TABLE};
6use crate::{Error, Field};
7
8#[derive(Debug, Clone, PartialEq, Eq)]
10pub enum Decoded {
11 Fields(Vec<Field>),
13 Blocked,
16}
17
18#[derive(Debug)]
20pub struct Decoder {
21 max_cap: u64,
22 max_blocked: u64,
23 max_section: u64,
24 cap: u64,
25 size: u64,
26 entries: VecDeque<Field>,
27 inserted: u64,
28 acked: u64,
30 blocked: Vec<(u64, u64, Vec<u8>)>,
31 enc_buf: Vec<u8>,
32 out: Vec<u8>,
33}
34
35impl Decoder {
36 pub fn new(max_table_capacity: u64, max_blocked_streams: u64, max_field_section_size: u64) -> Self {
40 Decoder {
41 max_cap: max_table_capacity.min(crate::MAX_INT),
42 max_blocked: max_blocked_streams,
43 max_section: max_field_section_size,
44 cap: 0,
45 size: 0,
46 entries: VecDeque::new(),
47 inserted: 0,
48 acked: 0,
49 blocked: Vec::new(),
50 enc_buf: Vec::new(),
51 out: Vec::new(),
52 }
53 }
54
55 pub fn insert_count(&self) -> u64 {
57 self.inserted
58 }
59
60 pub fn table_size(&self) -> u64 {
62 self.size
63 }
64
65 pub fn blocked_streams(&self) -> usize {
67 let mut n = 0;
68 for (i, b) in self.blocked.iter().enumerate() {
69 if !self.blocked[..i].iter().any(|x| x.0 == b.0) {
70 n += 1;
71 }
72 }
73 n
74 }
75
76 pub fn decode(&mut self, stream_id: u64, block: &[u8]) -> Result<Decoded, Error> {
78 if block.len() as u64 > self.max_section.saturating_add(64) {
79 return Err(Error::FieldSectionTooLarge);
80 }
81 match self.decode_block(block) {
82 Ok((fields, ric)) => {
83 self.ack_section(stream_id, ric);
84 Ok(Decoded::Fields(fields))
85 }
86 Err(Error::Blocked) => {
87 if !self.blocked.iter().any(|b| b.0 == stream_id)
88 && self.blocked_streams() as u64 >= self.max_blocked
89 {
90 return Err(Error::DecompressionFailed);
91 }
92 let ric = self.required_insert_count(block)?;
93 self.blocked.push((stream_id, ric, block.to_vec()));
94 Ok(Decoded::Blocked)
95 }
96 Err(e) => Err(e),
97 }
98 }
99
100 fn ack_section(&mut self, stream_id: u64, ric: u64) {
101 if ric > 0 {
102 put_int(&mut self.out, 0x80, 7, stream_id);
103 self.acked = self.acked.max(ric);
104 }
105 }
106
107 #[allow(clippy::type_complexity)]
110 pub fn on_encoder_stream(&mut self, data: &[u8]) -> Result<Vec<(u64, Result<Vec<Field>, Error>)>, Error> {
111 let mut buf = std::mem::take(&mut self.enc_buf);
112 buf.extend_from_slice(data);
113 let mut pos = 0;
114 let r = loop {
115 let start = pos;
116 match self.instruction(&buf, &mut pos) {
117 Ok(()) => {}
118 Err(Short::Incomplete) => {
119 pos = start;
120 break Ok(());
121 }
122 Err(Short::Invalid) => break Err(Error::EncoderStream),
123 }
124 };
125 r?;
126 buf.drain(..pos);
127 if buf.len() as u64 > self.max_cap.saturating_mul(4).saturating_add(64) {
129 return Err(Error::EncoderStream);
130 }
131 self.enc_buf = buf;
132 let mut done = Vec::new();
133 if self.blocked.iter().any(|b| b.1 <= self.inserted) {
134 let blocked = std::mem::take(&mut self.blocked);
135 for (sid, ric, block) in blocked {
136 if ric > self.inserted {
137 self.blocked.push((sid, ric, block));
138 continue;
139 }
140 let r = self.decode_block(&block).map(|(f, ric)| {
141 self.ack_section(sid, ric);
142 f
143 });
144 done.push((sid, r));
145 }
146 }
147 Ok(done)
148 }
149
150 pub fn cancel_stream(&mut self, stream_id: u64) {
154 self.blocked.retain(|b| b.0 != stream_id);
155 if self.max_cap > 0 {
156 put_int(&mut self.out, 0x40, 6, stream_id);
157 }
158 }
159
160 pub fn take_decoder_stream(&mut self, out: &mut Vec<u8>) {
163 out.append(&mut self.out);
164 if self.inserted > self.acked {
165 put_int(out, 0x00, 6, self.inserted - self.acked);
166 self.acked = self.inserted;
167 }
168 }
169
170 fn dropped(&self) -> u64 {
171 self.inserted - self.entries.len() as u64
172 }
173
174 fn entry(&self, abs: u64) -> Option<&Field> {
175 let d = self.dropped();
176 if abs < d || abs >= self.inserted {
177 return None;
178 }
179 self.entries.get((abs - d) as usize)
180 }
181
182 fn insert(&mut self, f: Field) -> Result<(), Short> {
183 let size = f.size();
184 if size > self.cap {
185 return Err(Short::Invalid);
186 }
187 while self.size + size > self.cap {
188 let e = self.entries.pop_front().ok_or(Short::Invalid)?;
189 self.size -= e.size();
190 }
191 self.size += size;
192 self.entries.push_back(f);
193 self.inserted += 1;
194 Ok(())
195 }
196
197 fn instruction(&mut self, buf: &[u8], pos: &mut usize) -> Result<(), Short> {
200 let b = *buf.get(*pos).ok_or(Short::Incomplete)?;
201 let limit = self.max_cap.saturating_mul(4).saturating_add(64);
202 if b & 0x80 != 0 {
203 let idx = get_int(buf, pos, 6)?;
205 let v = get_span(buf, pos, 7)?;
206 if (v.end - v.start) as u64 > limit {
207 return Err(Short::Invalid);
208 }
209 let name = if b & 0x40 != 0 {
210 STATIC_TABLE.get(idx as usize).ok_or(Short::Invalid)?.0.as_bytes().to_vec()
211 } else {
212 let abs = self.inserted.checked_sub(idx + 1).ok_or(Short::Invalid)?;
213 self.entry(abs).ok_or(Short::Invalid)?.name.clone()
214 };
215 let value = span_bytes(buf, v)?;
216 self.insert(Field { name, value })
217 } else if b & 0x40 != 0 {
218 let n = get_span(buf, pos, 5)?;
220 let v = get_span(buf, pos, 7)?;
221 if (v.end - n.start) as u64 > limit {
222 return Err(Short::Invalid);
223 }
224 let name = span_bytes(buf, n)?;
225 let value = span_bytes(buf, v)?;
226 self.insert(Field { name, value })
227 } else if b & 0x20 != 0 {
228 let cap = get_int(buf, pos, 5)?;
230 if cap > self.max_cap {
231 return Err(Short::Invalid);
232 }
233 self.cap = cap;
234 while self.size > self.cap {
235 let e = self.entries.pop_front().ok_or(Short::Invalid)?;
236 self.size -= e.size();
237 }
238 Ok(())
239 } else {
240 let idx = get_int(buf, pos, 5)?;
242 let abs = self.inserted.checked_sub(idx + 1).ok_or(Short::Invalid)?;
243 let f = self.entry(abs).ok_or(Short::Invalid)?.clone();
244 self.insert(f)
245 }
246 }
247
248 fn required_insert_count(&self, block: &[u8]) -> Result<u64, Error> {
250 let mut pos = 0;
251 let enc = get_int(block, &mut pos, 8).map_err(|_| Error::DecompressionFailed)?;
252 if enc == 0 {
253 return Ok(0);
254 }
255 let max_entries = self.max_cap / 32;
256 let full_range = 2 * max_entries;
257 if enc > full_range {
258 return Err(Error::DecompressionFailed);
259 }
260 let max_value = self.inserted + max_entries;
261 let max_wrapped = (max_value / full_range) * full_range;
262 let mut ric = max_wrapped + enc - 1;
263 if ric > max_value {
264 if ric <= full_range {
265 return Err(Error::DecompressionFailed);
266 }
267 ric -= full_range;
268 }
269 if ric == 0 {
270 return Err(Error::DecompressionFailed);
271 }
272 Ok(ric)
273 }
274
275 fn decode_block(&self, block: &[u8]) -> Result<(Vec<Field>, u64), Error> {
277 let ric = self.required_insert_count(block)?;
278 if ric > self.inserted {
279 return Err(Error::Blocked);
280 }
281 let fail = |_| Error::DecompressionFailed;
282 let mut pos = 0;
283 get_int(block, &mut pos, 8).map_err(fail)?;
284 let sign = *block.get(pos).ok_or(Error::DecompressionFailed)? & 0x80 != 0;
285 let delta = get_int(block, &mut pos, 7).map_err(fail)?;
286 let base = if sign {
287 ric.checked_sub(delta + 1).ok_or(Error::DecompressionFailed)?
288 } else {
289 ric.checked_add(delta).ok_or(Error::DecompressionFailed)?
290 };
291 let mut fields = Vec::new();
292 let mut total = 0u64;
293 let mut max_ref: Option<u64> = None;
294 let mut dyn_ref = |abs: Option<u64>| -> Result<&Field, Error> {
296 let abs = abs.filter(|&a| a < ric).ok_or(Error::DecompressionFailed)?;
297 max_ref = Some(max_ref.map_or(abs, |m: u64| m.max(abs)));
298 self.entry(abs).ok_or(Error::DecompressionFailed)
299 };
300 let static_ref = |idx: u64| -> Result<(&'static [u8], &'static [u8]), Error> {
301 let (n, v) = STATIC_TABLE.get(idx as usize).ok_or(Error::DecompressionFailed)?;
302 Ok((n.as_bytes(), v.as_bytes()))
303 };
304 while pos < block.len() {
305 let b = block[pos];
306 let field = if b & 0x80 != 0 {
307 let idx = get_int(block, &mut pos, 6).map_err(fail)?;
309 if b & 0x40 != 0 {
310 let (n, v) = static_ref(idx)?;
311 Field::new(n, v)
312 } else {
313 dyn_ref(base.checked_sub(idx + 1))?.clone()
314 }
315 } else if b & 0x40 != 0 {
316 let idx = get_int(block, &mut pos, 4).map_err(fail)?;
318 let name = if b & 0x10 != 0 {
319 static_ref(idx)?.0.to_vec()
320 } else {
321 dyn_ref(base.checked_sub(idx + 1))?.name.clone()
322 };
323 let v = get_span(block, &mut pos, 7).map_err(fail)?;
324 Field { name, value: span_bytes(block, v).map_err(fail)? }
325 } else if b & 0x20 != 0 {
326 let n = get_span(block, &mut pos, 3).map_err(fail)?;
328 let v = get_span(block, &mut pos, 7).map_err(fail)?;
329 Field { name: span_bytes(block, n).map_err(fail)?, value: span_bytes(block, v).map_err(fail)? }
330 } else if b & 0x10 != 0 {
331 let idx = get_int(block, &mut pos, 4).map_err(fail)?;
333 dyn_ref(base.checked_add(idx))?.clone()
334 } else {
335 let idx = get_int(block, &mut pos, 3).map_err(fail)?;
337 let name = dyn_ref(base.checked_add(idx))?.name.clone();
338 let v = get_span(block, &mut pos, 7).map_err(fail)?;
339 Field { name, value: span_bytes(block, v).map_err(fail)? }
340 };
341 total += field.size();
342 if total > self.max_section {
343 return Err(Error::FieldSectionTooLarge);
344 }
345 fields.push(field);
346 }
347 if ric != max_ref.map_or(0, |m| m + 1) {
349 return Err(Error::DecompressionFailed);
350 }
351 Ok((fields, ric))
352 }
353}