1use core::fmt;
13
14use bumpalo::Bump;
15use bumpalo::collections::Vec as BumpVec;
16
17use crate::number::NumberValue;
18use crate::value::DataValue;
19
20#[derive(Debug, Clone, PartialEq, Eq)]
21pub struct ParseError {
22 pub kind: ParseErrorKind,
23 pub position: usize,
24}
25
26#[derive(Debug, Clone, PartialEq, Eq)]
27pub enum ParseErrorKind {
28 UnexpectedEof,
29 UnexpectedByte(u8),
30 InvalidEscape,
31 InvalidUnicodeEscape,
32 InvalidNumber,
33 TrailingData,
34 DepthLimitExceeded,
35}
36
37impl fmt::Display for ParseError {
38 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
39 write!(f, "json parse error at byte {}: ", self.position)?;
40 match self.kind {
41 ParseErrorKind::UnexpectedEof => write!(f, "unexpected end of input"),
42 ParseErrorKind::UnexpectedByte(b) => {
43 write!(f, "unexpected byte 0x{:02x} ({:?})", b, b as char)
44 }
45 ParseErrorKind::InvalidEscape => write!(f, "invalid string escape"),
46 ParseErrorKind::InvalidUnicodeEscape => write!(f, "invalid \\u escape"),
47 ParseErrorKind::InvalidNumber => write!(f, "invalid number literal"),
48 ParseErrorKind::TrailingData => write!(f, "unexpected data after JSON value"),
49 ParseErrorKind::DepthLimitExceeded => write!(f, "nesting depth limit exceeded"),
50 }
51 }
52}
53
54impl std::error::Error for ParseError {}
55
56const MAX_DEPTH: u16 = 256;
60
61use crate::simd::special_mask8 as string_terminator_mask;
67
68const SWAR_WINDOWS_BEFORE_WIDE: u32 = 2;
74
75#[inline]
80fn bump_extend(out: &mut BumpVec<u8>, b: &[u8]) {
81 out.reserve(b.len());
82 let len = out.len();
83 unsafe {
87 core::ptr::copy_nonoverlapping(b.as_ptr(), out.as_mut_ptr().add(len), b.len());
88 out.set_len(len + b.len());
89 }
90}
91
92impl<'a> DataValue<'a> {
93 pub fn from_str(input: &'a str, arena: &'a Bump) -> Result<DataValue<'a>, ParseError> {
98 let mut p = Parser {
99 bytes: input.as_bytes(),
100 input,
101 pos: 0,
102 arena,
103 };
104 p.skip_ws();
105 let value = p.parse_value(0)?;
106 p.skip_ws();
107 if p.pos != p.bytes.len() {
108 return Err(p.err(ParseErrorKind::TrailingData));
109 }
110 Ok(value)
111 }
112}
113
114struct Parser<'a> {
115 bytes: &'a [u8],
116 input: &'a str,
117 pos: usize,
118 arena: &'a Bump,
119}
120
121impl<'a> Parser<'a> {
122 #[inline(always)]
123 fn err(&self, kind: ParseErrorKind) -> ParseError {
124 ParseError {
125 kind,
126 position: self.pos,
127 }
128 }
129
130 #[inline(always)]
131 fn peek(&self) -> Result<u8, ParseError> {
132 self.bytes
133 .get(self.pos)
134 .copied()
135 .ok_or_else(|| self.err(ParseErrorKind::UnexpectedEof))
136 }
137
138 #[inline(always)]
139 fn bump(&mut self) -> Result<u8, ParseError> {
140 let b = self.peek()?;
141 self.pos += 1;
142 Ok(b)
143 }
144
145 #[inline(always)]
146 fn skip_ws(&mut self) {
147 while self.pos < self.bytes.len() {
148 match self.bytes[self.pos] {
149 b' ' | b'\t' | b'\n' | b'\r' => self.pos += 1,
150 _ => break,
151 }
152 }
153 }
154
155 fn parse_value(&mut self, depth: u16) -> Result<DataValue<'a>, ParseError> {
156 if depth > MAX_DEPTH {
157 return Err(self.err(ParseErrorKind::DepthLimitExceeded));
158 }
159 self.skip_ws();
160 let b = self.peek()?;
161 match b {
162 b'"' => self.parse_string().map(DataValue::String),
163 b'{' => self.parse_object(depth),
164 b'[' => self.parse_array(depth),
165 b't' | b'f' => self.parse_bool(),
166 b'n' => self.parse_null(),
167 b'-' | b'0'..=b'9' => self.parse_number(),
168 other => Err(self.err(ParseErrorKind::UnexpectedByte(other))),
169 }
170 }
171
172 fn parse_null(&mut self) -> Result<DataValue<'a>, ParseError> {
173 if self.bytes.get(self.pos..self.pos + 4) == Some(b"null") {
174 self.pos += 4;
175 Ok(DataValue::Null)
176 } else {
177 Err(self.err(ParseErrorKind::UnexpectedByte(self.bytes[self.pos])))
178 }
179 }
180
181 fn parse_bool(&mut self) -> Result<DataValue<'a>, ParseError> {
182 if self.bytes.get(self.pos..self.pos + 4) == Some(b"true") {
183 self.pos += 4;
184 Ok(DataValue::Bool(true))
185 } else if self.bytes.get(self.pos..self.pos + 5) == Some(b"false") {
186 self.pos += 5;
187 Ok(DataValue::Bool(false))
188 } else {
189 Err(self.err(ParseErrorKind::UnexpectedByte(self.bytes[self.pos])))
190 }
191 }
192
193 fn parse_number(&mut self) -> Result<DataValue<'a>, ParseError> {
194 let start = self.pos;
195 let mut is_float = false;
196
197 let neg = if self.bytes[self.pos] == b'-' {
202 self.pos += 1;
203 true
204 } else {
205 false
206 };
207 let mut acc: i64 = 0;
208 let mut int_overflowed = false;
209
210 match self.peek()? {
211 b'0' => {
212 self.pos += 1;
213 }
214 c @ b'1'..=b'9' => {
215 acc = -((c - b'0') as i64);
216 self.pos += 1;
217 let mut digits: u32 = 1;
223 while let Some(&d) = self.bytes.get(self.pos) {
224 match d {
225 b'0'..=b'9' => {
226 if digits < 18 {
227 acc = acc * 10 - (d - b'0') as i64;
228 digits += 1;
229 } else if !int_overflowed {
230 match acc
231 .checked_mul(10)
232 .and_then(|v| v.checked_sub((d - b'0') as i64))
233 {
234 Some(v) => acc = v,
235 None => int_overflowed = true,
236 }
237 }
238 self.pos += 1;
239 }
240 _ => break,
241 }
242 }
243 }
244 _ => return Err(self.err(ParseErrorKind::InvalidNumber)),
245 }
246 if let Some(&b'.') = self.bytes.get(self.pos) {
248 is_float = true;
249 self.pos += 1;
250 let frac_start = self.pos;
251 while let Some(&c) = self.bytes.get(self.pos) {
252 if c.is_ascii_digit() {
253 self.pos += 1;
254 } else {
255 break;
256 }
257 }
258 if self.pos == frac_start {
259 return Err(self.err(ParseErrorKind::InvalidNumber));
260 }
261 }
262 if matches!(self.bytes.get(self.pos), Some(b'e' | b'E')) {
264 is_float = true;
265 self.pos += 1;
266 if matches!(self.bytes.get(self.pos), Some(b'+' | b'-')) {
267 self.pos += 1;
268 }
269 let exp_start = self.pos;
270 while let Some(&d) = self.bytes.get(self.pos) {
271 if d.is_ascii_digit() {
272 self.pos += 1;
273 } else {
274 break;
275 }
276 }
277 if self.pos == exp_start {
278 return Err(self.err(ParseErrorKind::InvalidNumber));
279 }
280 }
281
282 if !is_float && !int_overflowed {
283 let result = if neg { Some(acc) } else { acc.checked_neg() };
288 if let Some(i) = result {
289 return Ok(DataValue::Number(NumberValue::Integer(i)));
290 }
291 }
292
293 let slice = &self.bytes[start..self.pos];
298 match fast_float2::parse::<f64, _>(slice) {
299 Ok(f) => Ok(DataValue::Number(NumberValue::Float(f))),
300 Err(_) => Err(ParseError {
301 kind: ParseErrorKind::InvalidNumber,
302 position: start,
303 }),
304 }
305 }
306
307 fn parse_string(&mut self) -> Result<&'a str, ParseError> {
311 debug_assert_eq!(self.bytes[self.pos], b'"');
313 self.pos += 1;
314 let start = self.pos;
315
316 self.scan_to_special();
317 match self.bytes.get(self.pos) {
318 Some(&b'"') => {
319 let s = &self.input[start..self.pos];
320 self.pos += 1;
321 Ok(s)
322 }
323 Some(&b'\\') => {
324 self.parse_string_with_escapes(start)
327 }
328 Some(&b) => Err(self.err(ParseErrorKind::UnexpectedByte(b))),
330 None => Err(self.err(ParseErrorKind::UnexpectedEof)),
331 }
332 }
333
334 #[inline(always)]
343 fn scan_to_special(&mut self) {
344 let mut clean_windows = 0u32;
345 while self.pos + 8 <= self.bytes.len() {
346 let w = u64::from_le_bytes(self.bytes[self.pos..self.pos + 8].try_into().unwrap());
347 let mask = string_terminator_mask(w);
348 if mask != 0 {
349 self.pos += (mask.trailing_zeros() / 8) as usize;
350 return;
351 }
352 self.pos += 8;
353 clean_windows += 1;
354 if clean_windows >= SWAR_WINDOWS_BEFORE_WIDE {
355 match crate::simd::find_string_terminator(&self.bytes[self.pos..]) {
356 Some(off) => self.pos += off,
357 None => self.pos = self.bytes.len(),
358 }
359 return;
360 }
361 }
362 while let Some(&b) = self.bytes.get(self.pos) {
364 if matches!(b, b'"' | b'\\') || b < 0x20 {
365 return;
366 }
367 self.pos += 1;
368 }
369 }
370
371 fn parse_string_with_escapes(&mut self, start: usize) -> Result<&'a str, ParseError> {
372 let mut out: BumpVec<u8> = BumpVec::with_capacity_in(self.pos - start + 16, self.arena);
373 bump_extend(&mut out, &self.bytes[start..self.pos]);
374
375 loop {
376 let chunk_start = self.pos;
380 self.scan_to_special();
381 if self.pos > chunk_start {
382 bump_extend(&mut out, &self.bytes[chunk_start..self.pos]);
383 }
384
385 let b = match self.bytes.get(self.pos) {
386 Some(&b) => b,
387 None => return Err(self.err(ParseErrorKind::UnexpectedEof)),
388 };
389 match b {
390 b'"' => {
391 self.pos += 1;
392 let slice = out.into_bump_slice();
393 return Ok(unsafe { core::str::from_utf8_unchecked(slice) });
397 }
398 b'\\' => {
399 self.pos += 1;
400 let esc = self.bump()?;
401 match esc {
402 b'"' => out.push(b'"'),
403 b'\\' => out.push(b'\\'),
404 b'/' => out.push(b'/'),
405 b'b' => out.push(0x08),
406 b'f' => out.push(0x0C),
407 b'n' => out.push(b'\n'),
408 b'r' => out.push(b'\r'),
409 b't' => out.push(b'\t'),
410 b'u' => {
411 let code = self.parse_hex4()?;
412 let ch = if (0xD800..=0xDBFF).contains(&code) {
414 if self.bytes.get(self.pos) != Some(&b'\\')
415 || self.bytes.get(self.pos + 1) != Some(&b'u')
416 {
417 return Err(self.err(ParseErrorKind::InvalidUnicodeEscape));
418 }
419 self.pos += 2;
420 let low = self.parse_hex4()?;
421 if !(0xDC00..=0xDFFF).contains(&low) {
422 return Err(self.err(ParseErrorKind::InvalidUnicodeEscape));
423 }
424 let scalar = 0x10000
425 + (((code - 0xD800) as u32) << 10)
426 + ((low - 0xDC00) as u32);
427 char::from_u32(scalar)
428 .ok_or_else(|| self.err(ParseErrorKind::InvalidUnicodeEscape))?
429 } else if (0xDC00..=0xDFFF).contains(&code) {
430 return Err(self.err(ParseErrorKind::InvalidUnicodeEscape));
431 } else {
432 char::from_u32(code as u32)
433 .ok_or_else(|| self.err(ParseErrorKind::InvalidUnicodeEscape))?
434 };
435 let mut buf = [0u8; 4];
436 let s = ch.encode_utf8(&mut buf);
437 out.extend_from_slice(s.as_bytes());
438 }
439 _ => return Err(self.err(ParseErrorKind::InvalidEscape)),
440 }
441 }
442 _ => return Err(self.err(ParseErrorKind::UnexpectedByte(b))),
443 }
444 }
445 }
446
447 fn parse_hex4(&mut self) -> Result<u16, ParseError> {
448 if self.pos + 4 > self.bytes.len() {
449 return Err(self.err(ParseErrorKind::InvalidUnicodeEscape));
450 }
451 let mut v: u16 = 0;
452 for _ in 0..4 {
453 let b = self.bytes[self.pos];
454 let d = match b {
455 b'0'..=b'9' => b - b'0',
456 b'a'..=b'f' => b - b'a' + 10,
457 b'A'..=b'F' => b - b'A' + 10,
458 _ => return Err(self.err(ParseErrorKind::InvalidUnicodeEscape)),
459 } as u16;
460 v = (v << 4) | d;
461 self.pos += 1;
462 }
463 Ok(v)
464 }
465
466 fn parse_array(&mut self, depth: u16) -> Result<DataValue<'a>, ParseError> {
467 debug_assert_eq!(self.bytes[self.pos], b'[');
468 self.pos += 1;
469 self.skip_ws();
470 if let Some(&b']') = self.bytes.get(self.pos) {
479 self.pos += 1;
480 return Ok(DataValue::Array(&[]));
481 }
482 let mut items: BumpVec<DataValue<'a>> = BumpVec::with_capacity_in(8, self.arena);
483 loop {
484 let v = self.parse_value(depth + 1)?;
485 items.push(v);
486 match self.bytes.get(self.pos) {
490 Some(&b',') => {
491 self.pos += 1;
492 self.skip_ws();
493 }
494 Some(&b']') => {
495 self.pos += 1;
496 return Ok(DataValue::Array(items.into_bump_slice()));
497 }
498 _ => {
499 self.skip_ws();
500 match self.bump()? {
501 b',' => self.skip_ws(),
502 b']' => return Ok(DataValue::Array(items.into_bump_slice())),
503 other => return Err(self.err(ParseErrorKind::UnexpectedByte(other))),
504 }
505 }
506 }
507 }
508 }
509
510 fn parse_object(&mut self, depth: u16) -> Result<DataValue<'a>, ParseError> {
511 debug_assert_eq!(self.bytes[self.pos], b'{');
512 self.pos += 1;
513 self.skip_ws();
514 if let Some(&b'}') = self.bytes.get(self.pos) {
523 self.pos += 1;
524 return Ok(DataValue::Object(&[]));
525 }
526 let mut pairs: BumpVec<(&'a str, DataValue<'a>)> =
527 BumpVec::with_capacity_in(32, self.arena);
528 loop {
529 if self.peek()? != b'"' {
531 return Err(self.err(ParseErrorKind::UnexpectedByte(self.bytes[self.pos])));
532 }
533 let key = self.parse_string()?;
534
535 match self.bytes.get(self.pos) {
537 Some(&b':') => self.pos += 1,
538 _ => {
539 self.skip_ws();
540 if self.bump()? != b':' {
541 return Err(
542 self.err(ParseErrorKind::UnexpectedByte(self.bytes[self.pos - 1]))
543 );
544 }
545 }
546 }
547
548 let value = self.parse_value(depth + 1)?;
550 pairs.push((key, value));
551
552 match self.bytes.get(self.pos) {
554 Some(&b',') => {
555 self.pos += 1;
556 self.skip_ws();
557 }
558 Some(&b'}') => {
559 self.pos += 1;
560 return Ok(DataValue::Object(pairs.into_bump_slice()));
561 }
562 _ => {
563 self.skip_ws();
564 match self.bump()? {
565 b',' => self.skip_ws(),
566 b'}' => return Ok(DataValue::Object(pairs.into_bump_slice())),
567 other => return Err(self.err(ParseErrorKind::UnexpectedByte(other))),
568 }
569 }
570 }
571 }
572 }
573}
574
575#[cfg(test)]
576mod tests {
577 use super::*;
578
579 fn parse(s: &str) -> DataValue<'_> {
580 let arena = Box::leak(Box::new(Bump::new()));
581 DataValue::from_str(s, arena).expect("parse")
582 }
583
584 #[test]
585 fn primitives() {
586 assert!(parse("null").is_null());
587 assert_eq!(parse("true").as_bool(), Some(true));
588 assert_eq!(parse("false").as_bool(), Some(false));
589 assert_eq!(parse("0").as_i64(), Some(0));
590 assert_eq!(parse("-7").as_i64(), Some(-7));
591 assert_eq!(parse("3.5").as_f64(), Some(3.5));
592 assert_eq!(parse("1e3").as_f64(), Some(1000.0));
593 assert_eq!(parse(r#""hello""#).as_str(), Some("hello"));
594 }
595
596 #[test]
597 fn integer_overflow_falls_to_float() {
598 let v = parse("123456789012345678901234567890");
599 assert!(v.is_f64());
600 }
601
602 #[test]
603 fn malformed_number_literals_reject() {
604 let arena = Bump::new();
608 for input in [
609 "1.",
610 "-1.",
611 "1.e5",
612 "1e",
613 "1e+",
614 "1e-",
615 "1E",
616 "[1.]",
617 "[1e]",
618 "{\"a\":1.}",
619 "1.5e",
620 "0.",
621 "-0.e1",
622 ] {
623 assert!(
624 DataValue::from_str(input, &arena).is_err(),
625 "{input:?} should be rejected"
626 );
627 }
628 }
629
630 #[test]
631 #[allow(clippy::excessive_precision)]
634 fn float_parse_parity() {
635 for (input, expect) in [
638 ("0.5", 0.5),
639 ("-0.5", -0.5),
640 ("3.5", 3.5),
641 ("1e3", 1000.0),
642 ("1E3", 1000.0),
643 ("1e+3", 1000.0),
644 ("2.5e-2", 0.025),
645 ("-65.613616999999977", -65.613616999999977),
646 ("112.58598277699663", 112.58598277699663),
647 ("0e0", 0.0),
648 ("0.0", 0.0),
649 ] {
650 assert_eq!(parse(input).as_f64(), Some(expect), "{input}");
651 }
652 assert_eq!(parse("1e999").as_f64(), Some(f64::INFINITY));
655 assert_eq!(parse("-1e999").as_f64(), Some(f64::NEG_INFINITY));
656 let arena = Bump::new();
658 let v = DataValue::from_str("[1.5,2.5e1,-3]", &arena).unwrap();
659 assert_eq!(v[0].as_f64(), Some(1.5));
660 assert_eq!(v[1].as_f64(), Some(25.0));
661 assert_eq!(v[2].as_i64(), Some(-3));
662 }
663
664 #[test]
665 fn i64_boundaries() {
666 assert_eq!(parse("9223372036854775807").as_i64(), Some(i64::MAX));
667 assert_eq!(parse("-9223372036854775808").as_i64(), Some(i64::MIN));
668 assert_eq!(
671 parse("1234567890123456789").as_i64(),
672 Some(1_234_567_890_123_456_789)
673 );
674 assert!(parse("9223372036854775808").is_f64());
676 assert!(parse("-9223372036854775809").is_f64());
678 }
679
680 #[test]
681 fn empty_collections() {
682 assert_eq!(parse("[]").len(), Some(0));
683 assert_eq!(parse("{}").len(), Some(0));
684 }
685
686 #[test]
687 fn arrays_and_objects() {
688 let v = parse(r#"{"a":[1,2,3],"b":{"c":true}}"#);
689 assert_eq!(v["a"][0].as_i64(), Some(1));
690 assert_eq!(v["a"][2].as_i64(), Some(3));
691 assert_eq!(v["b"]["c"].as_bool(), Some(true));
692 }
693
694 #[test]
695 fn string_escapes() {
696 assert_eq!(parse(r#""a\nb""#).as_str(), Some("a\nb"));
697 assert_eq!(parse(r#""a\\b""#).as_str(), Some("a\\b"));
698 assert_eq!(parse(r#""é""#).as_str(), Some("é"));
699 assert_eq!(parse(r#""😀""#).as_str(), Some("😀"));
701 }
702
703 #[test]
704 fn whitespace_tolerant() {
705 let v = parse(" {\n \"a\" :\t1 ,\n \"b\":2\n} ");
706 assert_eq!(v["a"].as_i64(), Some(1));
707 assert_eq!(v["b"].as_i64(), Some(2));
708 }
709
710 #[test]
711 fn rejects_trailing_data() {
712 let arena = Bump::new();
713 assert!(DataValue::from_str("1 2", &arena).is_err());
714 }
715
716 #[test]
717 fn rejects_bad_escape() {
718 let arena = Bump::new();
719 assert!(DataValue::from_str(r#""\q""#, &arena).is_err());
720 }
721
722 #[test]
723 fn rejects_unescaped_control_bytes_in_string() {
724 let arena = Bump::new();
728 for ctl in 0u8..0x20 {
729 let mut s = Vec::from(b"\"abcdefghijklmnop");
732 s.push(ctl);
733 s.push(b'"');
734 let input = std::str::from_utf8(&s).unwrap();
735 assert!(
736 DataValue::from_str(input, &arena).is_err(),
737 "control byte 0x{ctl:02x} should error",
738 );
739 }
740 }
741
742 #[test]
743 fn long_escape_string_round_trips() {
744 let mut json = String::from("\"");
747 for _ in 0..10 {
748 json.push_str(&"x".repeat(40));
749 json.push_str(r"\n");
750 }
751 json.push('"');
752 let arena = Bump::new();
753 let v = DataValue::from_str(&json, &arena).unwrap();
754 let s = v.as_str().unwrap();
755 assert_eq!(s.matches('\n').count(), 10);
756 assert!(s.starts_with(&"x".repeat(40)));
757 }
758
759 #[test]
760 fn long_string_round_trips() {
761 let s = "x".repeat(200);
764 let json = format!("\"{s}\"");
765 let arena = Bump::new();
766 let v = DataValue::from_str(&json, &arena).unwrap();
767 assert_eq!(v.as_str(), Some(s.as_str()));
768 }
769
770 #[test]
771 fn deep_nesting_under_limit_ok() {
772 let n = 200;
773 let s = "[".repeat(n) + &"]".repeat(n);
774 let arena = Bump::new();
775 assert!(DataValue::from_str(&s, &arena).is_ok());
776 }
777
778 #[test]
779 fn deep_nesting_over_limit_errors() {
780 let n = 1000;
781 let s = "[".repeat(n) + &"]".repeat(n);
782 let arena = Bump::new();
783 assert!(DataValue::from_str(&s, &arena).is_err());
784 }
785}