Skip to main content

cbor_core/
parse.rs

1//! CBOR diagnostic notation parser (Section 2.3.6 of draft-rundgren-cbor-core-25).
2//!
3//! Parses diagnostic-notation strings into [`Value`]. Exposed through the
4//! standard [`FromStr`] trait: `"42".parse::<Value>()`.
5
6use std::{borrow::Cow, collections::BTreeMap, str::FromStr};
7
8use crate::{
9    Error, Float, SimpleValue, Strictness, Value,
10    error::WithEof,
11    float::Inner,
12    io::{MyReader, SliceReader},
13    limits, tag,
14    util::{trim_leading_zeros, u8_from_base64_digit, u8_from_hex_digit, u64_from_slice},
15};
16
17impl<'a> FromStr for Value<'a> {
18    type Err = Error;
19
20    fn from_str(s: &str) -> Result<Self, Error> {
21        let mut parser = Parser::new(SliceReader(s.as_bytes()), limits::RECURSION_LIMIT, Strictness::STRICT);
22        parser.parse_complete()
23    }
24}
25
26// The underlying reader is forward-only, but the parser needs arbitrary
27// lookahead. Bytes pulled for peeking are held in `buf` until consumed,
28// so the stream is never read past the last byte the parser actually
29// inspects on a successful match.
30pub(crate) struct Parser<R> {
31    reader: R,
32    buf: [u8; 16],
33    buf_len: usize,
34    depth: u16,
35    strictness: Strictness,
36}
37
38impl<'r, R: MyReader<'r>> Parser<R> {
39    pub(crate) fn new(inner: R, recursion_limit: u16, strictness: Strictness) -> Self {
40        Self {
41            reader: inner,
42            buf: [0; _],
43            buf_len: 0,
44            depth: recursion_limit,
45            strictness,
46        }
47    }
48
49    /// Parse a single value and require that the input is then fully
50    /// consumed (trailing whitespace and comments are accepted, nothing
51    /// else). Used by in-memory decode paths.
52    pub(crate) fn parse_complete<'a>(&mut self) -> Result<Value<'a>, R::Error> {
53        self.skip_whitespace()?;
54        let value = self.parse_value()?;
55        self.skip_whitespace()?;
56        if !self.at_end()? {
57            Err(Error::InvalidFormat.into())
58        } else {
59            Ok(value)
60        }
61    }
62
63    /// Parse a single value from a stream. After the value, trailing
64    /// whitespace and comments are consumed up to either EOF or a
65    /// top-level separator comma (the comma is consumed). Anything
66    /// else is rejected. Used by [`DecodeOptions::read_from`] so the
67    /// caller can pull successive elements of a CBOR sequence by
68    /// calling `read_from` repeatedly.
69    pub(crate) fn parse_stream_item<'a>(&mut self) -> Result<Value<'a>, R::Error> {
70        self.skip_whitespace()?;
71        let value = self.parse_value()?;
72        self.consume_trailing_separator()?;
73        Ok(value)
74    }
75
76    /// Pull the next value of a sequence. Returns `Ok(None)` at a clean
77    /// end of input (including a trailing comma). After returning a
78    /// value, any trailing top-level comma is consumed, ready for the
79    /// next call.
80    pub(crate) fn parse_seq_item<'a>(&mut self) -> Result<Option<Value<'a>>, R::Error> {
81        self.skip_whitespace()?;
82        if self.at_end()? {
83            Ok(None)
84        } else {
85            let value = self.parse_value()?;
86            self.consume_trailing_separator()?;
87            Ok(Some(value))
88        }
89    }
90
91    /// After a value has been parsed, consume whitespace and comments
92    /// up to either EOF or a top-level comma (which is also consumed).
93    /// Anything else is a syntax error.
94    fn consume_trailing_separator(&mut self) -> Result<(), R::Error> {
95        self.skip_whitespace()?;
96        if self.at_end()? || self.eat(b',')? {
97            Ok(())
98        } else {
99            Err(Error::InvalidFormat.into())
100        }
101    }
102
103    fn enter(&mut self) -> Result<(), R::Error> {
104        self.depth = self.depth.checked_sub(1).ok_or(Error::NestingTooDeep)?;
105        Ok(())
106    }
107
108    fn leave(&mut self) {
109        self.depth += 1;
110    }
111
112    fn ensure(&mut self, n: usize) -> Result<(), R::Error> {
113        while self.buf_len < n {
114            let [b] = self.reader.read_bytes::<1>()?;
115            self.buf[self.buf_len] = b;
116            self.buf_len += 1;
117        }
118        Ok(())
119    }
120
121    fn peek(&mut self) -> Result<Option<u8>, R::Error> {
122        self.peek_at(0)
123    }
124
125    fn peek_at(&mut self, offset: usize) -> Result<Option<u8>, R::Error> {
126        match self.ensure(offset + 1) {
127            Ok(()) => Ok(Some(self.buf[offset])),
128            Err(e) if e.is_eof() => Ok(None),
129            Err(e) => Err(e),
130        }
131    }
132
133    fn advance(&mut self) -> Result<u8, R::Error> {
134        self.ensure(1)?;
135        let byte = self.buf[0];
136        self.buf.copy_within(1..self.buf_len, 0);
137        self.buf_len -= 1;
138        Ok(byte)
139    }
140
141    fn skip(&mut self, len: usize) -> Result<(), R::Error> {
142        debug_assert!(len <= self.buf_len);
143        self.buf.copy_within(len..self.buf_len, 0);
144        self.buf_len -= len;
145        Ok(())
146    }
147
148    fn eat(&mut self, byte: u8) -> Result<bool, R::Error> {
149        if self.peek()? == Some(byte) {
150            self.skip(1)?;
151            Ok(true)
152        } else {
153            Ok(false)
154        }
155    }
156
157    fn expect(&mut self, byte: u8) -> Result<(), R::Error> {
158        if self.eat(byte)? {
159            Ok(())
160        } else {
161            Err(Error::InvalidFormat.into())
162        }
163    }
164
165    // Tentatively match `prefix` byte-by-byte.
166    fn consume(&mut self, prefix: &[u8]) -> Result<bool, R::Error> {
167        for (i, &b) in prefix.iter().enumerate() {
168            if self.peek_at(i)? != Some(b) {
169                return Ok(false);
170            }
171        }
172        self.skip(prefix.len())?;
173        Ok(true)
174    }
175
176    fn skip_whitespace(&mut self) -> Result<(), R::Error> {
177        loop {
178            while matches!(self.peek()?, Some(b' ' | b'\t' | b'\r' | b'\n')) {
179                self.skip(1)?;
180            }
181
182            if self.eat(b'#')? {
183                while let Some(b) = self.peek()?
184                    && b != b'\n'
185                {
186                    self.skip(1)?;
187                }
188            } else if self.eat(b'/')? {
189                while self.advance()? != b'/' {}
190            } else {
191                return Ok(());
192            }
193        }
194    }
195
196    fn at_end(&mut self) -> Result<bool, R::Error> {
197        Ok(self.peek()?.is_none())
198    }
199
200    fn parse_value<'a>(&mut self) -> Result<Value<'a>, R::Error> {
201        self.skip_whitespace()?;
202        let byte = self.peek()?.ok_or(Error::UnexpectedEof)?;
203        match byte {
204            b'[' => self.parse_array(),
205            b'{' => self.parse_map(),
206            b'(' => self.parse_chunked_string(),
207            b'"' => self.parse_text_string(),
208            b'\'' => self.parse_single_quoted_bstr(),
209            b'<' => self.parse_embedded_bstr(),
210            b'-' => {
211                if self.consume(b"-Infinity")? {
212                    Ok(Value::float(f64::NEG_INFINITY))
213                } else {
214                    self.parse_number_or_tag()
215                }
216            }
217            b'0'..=b'9' => self.parse_number_or_tag(),
218            b'N' if self.consume(b"NaN")? => Ok(Value::Float(Float(Inner::F16(0x7e00)))),
219            b'I' if self.consume(b"Infinity")? => Ok(Value::float(f64::INFINITY)),
220            b't' if self.consume(b"true")? => Ok(Value::from(true)),
221            b'f' if self.consume(b"false")? => Ok(Value::from(false)),
222            b'n' if self.consume(b"null")? => Ok(Value::null()),
223            b's' if self.consume(b"simple(")? => self.parse_simple_tail(),
224            b'h' if self.consume(b"h\'")? => self.parse_hex_bstr_tail(),
225            b'b' if self.consume(b"b64'")? => self.parse_b64_bstr_tail(),
226            b'f' if self.consume(b"float'")? => self.parse_float_hex_tail(),
227            _ => Err(Error::InvalidFormat.into()),
228        }
229    }
230
231    fn parse_array<'a>(&mut self) -> Result<Value<'a>, R::Error> {
232        self.expect(b'[')?;
233        self.skip_whitespace()?;
234        self.consume_indefinite_marker()?;
235        let mut items = Vec::new();
236        if self.eat(b']')? {
237            Ok(Value::Array(items))
238        } else {
239            self.enter()?;
240            let result = loop {
241                items.push(self.parse_value()?);
242                self.skip_whitespace()?;
243                if self.eat(b',')? {
244                    continue;
245                } else if self.eat(b']')? {
246                    break Ok(Value::Array(items));
247                } else {
248                    break Err(Error::InvalidFormat.into());
249                }
250            };
251            self.leave();
252            result
253        }
254    }
255
256    fn parse_map<'a>(&mut self) -> Result<Value<'a>, R::Error> {
257        self.expect(b'{')?;
258        self.skip_whitespace()?;
259        self.consume_indefinite_marker()?;
260        let mut map: BTreeMap<Value, Value> = BTreeMap::new();
261        if self.eat(b'}')? {
262            Ok(Value::Map(map))
263        } else {
264            self.enter()?;
265            let forbid_duplicate = !self.strictness.allow_duplicate_map_keys;
266            let result = loop {
267                let key = self.parse_value()?;
268                self.skip_whitespace()?;
269                if let Err(error) = self.expect(b':') {
270                    break Err(error);
271                }
272                let value = self.parse_value()?;
273                if map.insert(key, value).is_some() && forbid_duplicate {
274                    break Err(Error::NonDeterministic.into());
275                }
276                self.skip_whitespace()?;
277                if self.eat(b',')? {
278                    continue;
279                } else if self.eat(b'}')? {
280                    break Ok(Value::Map(map));
281                } else {
282                    break Err(Error::InvalidFormat.into());
283                }
284            };
285            self.leave();
286            result
287        }
288    }
289
290    /// If the next non-whitespace byte is `_`, consume it as the
291    /// indefinite-length marker (RFC 8949 §8). Reject in strict mode.
292    /// Used by [`parse_array`](Self::parse_array) and
293    /// [`parse_map`](Self::parse_map); the resulting [`Value`] is the
294    /// same canonical form a definite-length container would produce.
295    fn consume_indefinite_marker(&mut self) -> Result<(), R::Error> {
296        if self.eat(b'_')? {
297            if !self.strictness.allow_indefinite_length {
298                return Err(Error::NonDeterministic.into());
299            }
300            self.skip_whitespace()?;
301        }
302        Ok(())
303    }
304
305    /// Parse `(_ chunk, chunk, ...)` -- an indefinite-length byte or
306    /// text string written as a sequence of definite-length chunks.
307    /// The chunk type (bytes or text) is taken from the first chunk
308    /// and all later chunks must match.
309    fn parse_chunked_string<'a>(&mut self) -> Result<Value<'a>, R::Error> {
310        self.expect(b'(')?;
311        self.skip_whitespace()?;
312        self.expect(b'_')?;
313        if !self.strictness.allow_indefinite_length {
314            return Err(Error::NonDeterministic.into());
315        }
316
317        self.enter()?;
318        let result = self.parse_chunked_string_body();
319        self.leave();
320        result
321    }
322
323    fn parse_chunked_string_body<'a>(&mut self) -> Result<Value<'a>, R::Error> {
324        // The empty form `(_ )` is ambiguous between byte and text
325        // strings, so it is rejected. CBOR encodes the two as different
326        // major types; diagnostic notation has no separate marker.
327        self.skip_whitespace()?;
328        if self.eat(b')')? {
329            return Err(Error::InvalidFormat.into());
330        }
331
332        enum Acc {
333            Bytes(Vec<u8>),
334            Text(String),
335        }
336        let mut acc = match self.parse_chunk()? {
337            Value::ByteString(c) => Acc::Bytes(c.into_owned()),
338            Value::TextString(c) => Acc::Text(c.into_owned()),
339            _ => return Err(Error::InvalidFormat.into()),
340        };
341
342        loop {
343            self.skip_whitespace()?;
344            if self.eat(b')')? {
345                return Ok(match acc {
346                    Acc::Bytes(b) => Value::ByteString(b.into()),
347                    Acc::Text(t) => Value::TextString(t.into()),
348                });
349            }
350            self.expect(b',')?;
351            match (&mut acc, self.parse_chunk()?) {
352                (Acc::Bytes(buf), Value::ByteString(c)) => buf.extend_from_slice(&c),
353                (Acc::Text(buf), Value::TextString(c)) => buf.push_str(&c),
354                _ => return Err(Error::InvalidFormat.into()),
355            }
356        }
357    }
358
359    /// Parse a single chunk of an indefinite-length string.
360    ///
361    /// Per RFC 8949 §3.2.2, the chunks of an indefinite-length string
362    /// must themselves be definite-length strings. A nested
363    /// indefinite-length form (`(_ ...)`) is therefore rejected as
364    /// invalid even in lenient mode.
365    fn parse_chunk<'a>(&mut self) -> Result<Value<'a>, R::Error> {
366        self.skip_whitespace()?;
367        if self.peek()? == Some(b'(') {
368            return Err(Error::InvalidFormat.into());
369        }
370        self.parse_value()
371    }
372
373    fn parse_number_or_tag<'a>(&mut self) -> Result<Value<'a>, R::Error> {
374        let negative = self.eat(b'-')?;
375
376        let value = if self.peek()? == Some(b'0') {
377            match self.peek_at(1)? {
378                Some(b'b' | b'B') => {
379                    self.skip(2)?;
380                    self.parse_integer_base(negative, 2)?
381                }
382                Some(b'o' | b'O') => {
383                    self.skip(2)?;
384                    self.parse_integer_base(negative, 8)?
385                }
386                Some(b'x' | b'X') => {
387                    self.skip(2)?;
388                    self.parse_integer_base(negative, 16)?
389                }
390                _ => self.parse_decimal(negative)?,
391            }
392        } else {
393            self.parse_decimal(negative)?
394        };
395
396        self.skip_whitespace()?;
397
398        if self.eat(b'(')? {
399            let Value::Unsigned(tag_number) = value else {
400                return Err(Error::InvalidFormat.into());
401            };
402            self.enter()?;
403            let inner = self.parse_value();
404            self.leave();
405            let inner = inner?;
406            self.skip_whitespace()?;
407            self.expect(b')')?;
408            Ok(Value::tag(tag_number, inner))
409        } else {
410            Ok(value)
411        }
412    }
413
414    fn parse_decimal<'a>(&mut self, negative: bool) -> Result<Value<'a>, R::Error> {
415        let mut int_digits: Vec<u8> = Vec::new();
416        while let Some(b) = self.peek()?
417            && b.is_ascii_digit()
418        {
419            int_digits.push(b);
420            self.skip(1)?;
421        }
422        if int_digits.is_empty() {
423            return Err(Error::InvalidFormat.into());
424        }
425        if self.peek()? == Some(b'.') {
426            let mut text: Vec<u8> = int_digits;
427            text.push(self.advance()?);
428            let frac_start = text.len();
429            while let Some(b) = self.peek()?
430                && b.is_ascii_digit()
431            {
432                text.push(b);
433                self.skip(1)?;
434            }
435            if text.len() == frac_start {
436                return Err(Error::InvalidFormat.into());
437            }
438            if matches!(self.peek()?, Some(b'e' | b'E')) {
439                text.push(self.advance()?);
440                if matches!(self.peek()?, Some(b'+' | b'-')) {
441                    text.push(self.advance()?);
442                }
443                let exp_start = text.len();
444                while let Some(b) = self.peek()?
445                    && b.is_ascii_digit()
446                {
447                    text.push(b);
448                    self.skip(1)?;
449                }
450                if text.len() == exp_start {
451                    return Err(Error::InvalidFormat.into());
452                }
453            }
454            let text = std::str::from_utf8(&text).unwrap();
455            let mut parsed: f64 = text.parse().map_err(|_| Error::InvalidFormat)?;
456            if negative {
457                parsed = -parsed;
458            }
459            return Ok(Value::float(parsed));
460        }
461
462        let bytes = digits_to_be_bytes(&int_digits, 10)?;
463        Ok(be_bytes_to_value(&bytes, negative)?)
464    }
465
466    fn parse_integer_base<'a>(&mut self, negative: bool, base: u32) -> Result<Value<'a>, R::Error> {
467        let mut digits: Vec<u8> = Vec::new();
468        let mut last_was_digit = false;
469        while let Some(b) = self.peek()? {
470            if b == b'_' {
471                if !last_was_digit {
472                    return Err(Error::InvalidFormat.into());
473                } else {
474                    self.skip(1)?;
475                    last_was_digit = false;
476                    continue;
477                }
478            } else {
479                let is_valid = match base {
480                    2 => matches!(b, b'0' | b'1'),
481                    8 => matches!(b, b'0'..=b'7'),
482                    16 => b.is_ascii_hexdigit(),
483                    _ => unreachable!(),
484                };
485                if !is_valid {
486                    break;
487                }
488                digits.push(b);
489                last_was_digit = true;
490                self.skip(1)?;
491            }
492        }
493        if digits.is_empty() || !last_was_digit {
494            Err(Error::InvalidFormat.into())
495        } else {
496            let bytes = digits_to_be_bytes(&digits, base)?;
497            Ok(be_bytes_to_value(&bytes, negative)?)
498        }
499    }
500
501    fn parse_simple_tail<'a>(&mut self) -> Result<Value<'a>, R::Error> {
502        self.skip_whitespace()?;
503        let mut digits: Vec<u8> = Vec::new();
504        while let Some(b) = self.peek()?
505            && b.is_ascii_digit()
506        {
507            digits.push(b);
508            self.skip(1)?;
509        }
510        if digits.is_empty() {
511            Err(Error::InvalidFormat.into())
512        } else {
513            let text = std::str::from_utf8(&digits).unwrap();
514            let number: u8 = text.parse().map_err(|_| Error::InvalidFormat)?;
515            self.skip_whitespace()?;
516            self.expect(b')')?;
517            Ok(Value::from(SimpleValue::try_from(number)?))
518        }
519    }
520
521    fn parse_float_hex_tail<'a>(&mut self) -> Result<Value<'a>, R::Error> {
522        let mut hex: Vec<u8> = Vec::new();
523        while let Some(b) = self.peek()?
524            && b != b'\''
525        {
526            hex.push(b);
527            self.skip(1)?;
528        }
529        self.expect(b'\'')?;
530        let mut bits: u64 = 0;
531        for &byte in &hex {
532            let digit = u8_from_hex_digit(byte)? as u64;
533            bits = (bits << 4) | digit;
534        }
535        let float = match hex.len() {
536            4 => Float::from_bits_u16(bits as u16),
537            8 => Float::from_bits_u32(bits as u32),
538            16 => Float::from_bits_u64(bits),
539            _ => return Err(Error::InvalidFormat.into()),
540        };
541        if float.is_deterministic() {
542            Ok(Value::Float(float))
543        } else if self.strictness.allow_non_shortest_floats {
544            Ok(Value::Float(float.shortest()))
545        } else {
546            Err(Error::NonDeterministic.into())
547        }
548    }
549
550    fn parse_hex_bstr_tail<'a>(&mut self) -> Result<Value<'a>, R::Error> {
551        let mut bytes = Vec::new();
552        let mut half: Option<u8> = None;
553        loop {
554            match self.advance()? {
555                b'\'' => {
556                    if half.is_some() {
557                        return Err(Error::InvalidFormat.into());
558                    } else {
559                        return Ok(Value::ByteString(bytes.into()));
560                    }
561                }
562                b' ' | b'\t' | b'\r' | b'\n' => continue,
563                byte => {
564                    let digit = u8_from_hex_digit(byte)?;
565                    match half.take() {
566                        None => half = Some(digit),
567                        Some(high) => bytes.push((high << 4) | digit),
568                    }
569                }
570            }
571        }
572    }
573
574    fn parse_b64_bstr_tail<'a>(&mut self) -> Result<Value<'a>, R::Error> {
575        let mut data: Vec<u8> = Vec::new();
576        loop {
577            match self.advance()? {
578                b'\'' => return Ok(Value::ByteString(decode_base64(&data)?.into())),
579                b' ' | b'\t' | b'\r' | b'\n' => continue,
580                byte => data.push(byte),
581            }
582        }
583    }
584
585    fn parse_text_string<'a>(&mut self) -> Result<Value<'a>, R::Error> {
586        self.expect(b'"')?;
587        let mut buf: Vec<u8> = Vec::new();
588        loop {
589            match self.advance()? {
590                b'"' => {
591                    let text = String::try_from(buf).map_err(|_| Error::InvalidUtf8)?;
592                    return Ok(Value::from(text));
593                }
594                b'\r' => {
595                    self.eat(b'\n')?;
596                    buf.push(b'\n');
597                }
598                b'\\' => {
599                    self.read_escape_into_string(&mut buf)?;
600                }
601                byte => {
602                    buf.push(byte);
603                }
604            }
605        }
606    }
607
608    fn parse_single_quoted_bstr<'a>(&mut self) -> Result<Value<'a>, R::Error> {
609        self.expect(b'\'')?;
610        let mut bytes: Vec<u8> = Vec::new();
611        loop {
612            match self.advance()? {
613                b'\'' => {
614                    return Ok(Value::ByteString(bytes.into()));
615                }
616                b'\r' => {
617                    self.eat(b'\n')?;
618                    bytes.push(b'\n');
619                }
620                b'\\' => {
621                    self.read_escape_into_string(&mut bytes)?;
622                }
623                byte => {
624                    bytes.push(byte);
625                }
626            }
627        }
628    }
629
630    /// Consume an escape sequence (after the leading backslash) and append
631    /// its decoded value to `out`. Returns `false` if the escape was a
632    /// line continuation that produces no output.
633    fn read_escape_into_string(&mut self, out: &mut Vec<u8>) -> Result<bool, R::Error> {
634        let byte = self.advance()?;
635        let ch = match byte {
636            b'\'' => '\'',
637            b'"' => '"',
638            b'\\' => '\\',
639            b'b' => '\u{08}',
640            b'f' => '\u{0C}',
641            b'n' => '\n',
642            b'r' => '\r',
643            b't' => '\t',
644            b'u' => self.read_u_escape()?,
645            b'\n' => return Ok(false),
646            b'\r' => {
647                self.eat(b'\n')?;
648                return Ok(false);
649            }
650            _ => return Err(Error::InvalidFormat.into()),
651        };
652        let mut buf = [0; 4];
653        let s = ch.encode_utf8(&mut buf);
654        out.extend_from_slice(s.as_bytes());
655
656        // out.push(ch);
657        Ok(true)
658    }
659
660    fn read_u_escape(&mut self) -> Result<char, R::Error> {
661        let high = self.read_4_hex()?;
662        if (0xD800..=0xDBFF).contains(&high) {
663            if !self.consume(b"\\u")? {
664                return Err(Error::InvalidFormat.into());
665            }
666            let low = self.read_4_hex()?;
667            if !(0xDC00..=0xDFFF).contains(&low) {
668                return Err(Error::InvalidFormat.into());
669            }
670            let code = 0x10000 + ((high - 0xD800) << 10) + (low - 0xDC00);
671            char::from_u32(code).ok_or_else(|| Error::InvalidFormat.into())
672        } else if (0xDC00..=0xDFFF).contains(&high) {
673            Err(Error::InvalidFormat.into())
674        } else {
675            char::from_u32(high).ok_or_else(|| Error::InvalidFormat.into())
676        }
677    }
678
679    fn read_4_hex(&mut self) -> Result<u32, R::Error> {
680        let mut code: u32 = 0;
681        for _ in 0..4 {
682            let byte = self.advance()?;
683            let digit = u8_from_hex_digit(byte)? as u32;
684            code = (code << 4) | digit;
685        }
686        Ok(code)
687    }
688
689    fn parse_embedded_bstr<'a>(&mut self) -> Result<Value<'a>, R::Error> {
690        self.expect(b'<')?;
691        self.expect(b'<')?;
692        let mut buf = Vec::new();
693        self.skip_whitespace()?;
694        if self.consume(b">>")? {
695            Ok(Value::ByteString(Cow::Borrowed(&[])))
696        } else {
697            self.enter()?;
698            let result = loop {
699                let value = self.parse_value()?;
700                buf.extend(value.encode());
701                self.skip_whitespace()?;
702                if self.eat(b',')? {
703                    continue;
704                } else if self.consume(b">>")? {
705                    break Ok(Value::ByteString(buf.into()));
706                } else {
707                    break Err(Error::InvalidFormat.into());
708                }
709            };
710            self.leave();
711            result
712        }
713    }
714}
715
716fn decode_base64(input: &[u8]) -> Result<Vec<u8>, Error> {
717    let mut data = input;
718    while let Some(stripped) = data.strip_suffix(b"=") {
719        data = stripped;
720    }
721
722    if data.len() % 4 == 1 {
723        return Err(Error::InvalidFormat);
724    }
725
726    let mut out = Vec::with_capacity(data.len() * 3 / 4);
727    let mut buf: u32 = 0;
728    let mut bits: u32 = 0;
729
730    for &byte in data {
731        let value = u8_from_base64_digit(byte)? as u32;
732        buf = (buf << 6) | value;
733        bits += 6;
734        if bits >= 8 {
735            bits -= 8;
736            out.push((buf >> bits) as u8);
737            buf &= (1 << bits) - 1;
738        }
739    }
740
741    if buf == 0 { Ok(out) } else { Err(Error::InvalidFormat) }
742}
743
744/// Convert ASCII digits in the given base to a big-endian byte representation
745/// of the magnitude.
746fn digits_to_be_bytes(digits: &[u8], base: u32) -> Result<Vec<u8>, Error> {
747    let mut result = vec![0u8];
748
749    for &digit in digits {
750        let value = match digit {
751            b'0'..=b'9' => (digit - b'0') as u32,
752            b'a'..=b'f' => (digit - b'a' + 10) as u32,
753            b'A'..=b'F' => (digit - b'A' + 10) as u32,
754            _ => return Err(Error::InvalidFormat),
755        };
756
757        if value >= base {
758            return Err(Error::InvalidFormat);
759        }
760
761        let mut carry = value;
762
763        for byte in result.iter_mut().rev() {
764            let product = (*byte as u32) * base + carry;
765            *byte = product as u8;
766            carry = product >> 8;
767        }
768
769        while carry > 0 {
770            result.insert(0, carry as u8);
771            carry >>= 8;
772        }
773    }
774
775    Ok(result)
776}
777
778/// Construct a CBOR integer value from a big-endian magnitude and a sign.
779fn be_bytes_to_value<'a>(bytes: &[u8], negative: bool) -> Result<Value<'a>, Error> {
780    let bytes = trim_leading_zeros(bytes);
781
782    if bytes.is_empty() {
783        Ok(Value::Unsigned(0))
784    } else if !negative {
785        if bytes.len() <= 8 {
786            Ok(Value::Unsigned(u64_from_slice(bytes)?))
787        } else {
788            Ok(Value::tag(tag::POS_BIG_INT, bytes.to_vec()))
789        }
790    } else {
791        let mut sub = bytes.to_vec();
792        let mut idx = sub.len();
793        loop {
794            idx -= 1;
795            if sub[idx] > 0 {
796                sub[idx] -= 1;
797                break;
798            } else {
799                sub[idx] = 0xff;
800            }
801        }
802        let sub = trim_leading_zeros(&sub);
803        if sub.len() <= 8 {
804            Ok(Value::Negative(u64_from_slice(sub)?))
805        } else {
806            Ok(Value::tag(tag::NEG_BIG_INT, sub.to_vec()))
807        }
808    }
809}