1use alloc::string::String;
2use alloc::vec::Vec;
3
4use crate::error::{ParseError, ParseErrorKind};
5use crate::value::JsonValue;
6
7const MAX_DEPTH: usize = 128;
8
9struct Parser<'a> {
10 input: &'a [u8],
11 position: usize,
12 depth: usize,
13}
14
15pub fn parse(input: &[u8]) -> Result<JsonValue, ParseError> {
17 let mut parser = Parser {
18 input,
19 position: 0,
20 depth: 0,
21 };
22 let value = parser.parse_value()?;
23 parser.skip_whitespace();
24 if parser.position < parser.input.len() {
25 return Err(parser.error(ParseErrorKind::TrailingContent));
26 }
27 Ok(value)
28}
29
30impl<'a> Parser<'a> {
31 fn error(&self, kind: ParseErrorKind) -> ParseError {
32 ParseError {
33 kind,
34 position: self.position,
35 }
36 }
37
38 fn error_at(&self, position: usize, kind: ParseErrorKind) -> ParseError {
39 ParseError { kind, position }
40 }
41
42 fn peek(&self) -> Option<u8> {
43 self.input.get(self.position).copied()
44 }
45
46 fn advance(&mut self) -> Option<u8> {
47 let byte = self.input.get(self.position).copied();
48 if byte.is_some() {
49 self.position += 1;
50 }
51 byte
52 }
53
54 fn expect(&mut self, expected: u8) -> Result<(), ParseError> {
55 match self.advance() {
56 Some(b) if b == expected => Ok(()),
57 Some(b) => {
58 Err(self.error_at(self.position - 1, ParseErrorKind::UnexpectedCharacter(b)))
59 }
60 None => Err(self.error(ParseErrorKind::UnexpectedEnd)),
61 }
62 }
63
64 fn skip_whitespace(&mut self) {
65 while let Some(b) = self.peek() {
66 match b {
67 b' ' | b'\t' | b'\n' | b'\r' => {
68 self.position += 1;
69 }
70 _ => break,
71 }
72 }
73 }
74
75 fn parse_value(&mut self) -> Result<JsonValue, ParseError> {
76 self.skip_whitespace();
77 match self.peek() {
78 Some(b'n') => self.parse_null(),
79 Some(b't') => self.parse_true(),
80 Some(b'f') => self.parse_false(),
81 Some(b'"') => self.parse_string().map(JsonValue::String),
82 Some(b'[') => self.parse_array(),
83 Some(b'{') => self.parse_object(),
84 Some(b'-') | Some(b'0'..=b'9') => self.parse_number(),
85 Some(b) => Err(self.error(ParseErrorKind::UnexpectedCharacter(b))),
86 None => Err(self.error(ParseErrorKind::UnexpectedEnd)),
87 }
88 }
89
90 fn parse_null(&mut self) -> Result<JsonValue, ParseError> {
91 self.expect_literal(b"null")?;
92 Ok(JsonValue::Null)
93 }
94
95 fn parse_true(&mut self) -> Result<JsonValue, ParseError> {
96 self.expect_literal(b"true")?;
97 Ok(JsonValue::Bool(true))
98 }
99
100 fn parse_false(&mut self) -> Result<JsonValue, ParseError> {
101 self.expect_literal(b"false")?;
102 Ok(JsonValue::Bool(false))
103 }
104
105 fn expect_literal(&mut self, literal: &[u8]) -> Result<(), ParseError> {
106 for &expected in literal {
107 match self.advance() {
108 Some(b) if b == expected => {}
109 Some(b) => {
110 return Err(
111 self.error_at(self.position - 1, ParseErrorKind::UnexpectedCharacter(b))
112 )
113 }
114 None => return Err(self.error(ParseErrorKind::UnexpectedEnd)),
115 }
116 }
117 Ok(())
118 }
119
120 fn parse_number(&mut self) -> Result<JsonValue, ParseError> {
121 let start = self.position;
122
123 if self.peek() == Some(b'-') {
125 self.position += 1;
126 }
127
128 match self.peek() {
130 Some(b'0') => {
131 self.position += 1;
132 }
135 Some(b'1'..=b'9') => {
136 self.position += 1;
137 while let Some(b'0'..=b'9') = self.peek() {
138 self.position += 1;
139 }
140 }
141 _ => return Err(self.error(ParseErrorKind::InvalidNumber)),
142 }
143
144 if self.peek() == Some(b'.') {
146 self.position += 1;
147 let frac_start = self.position;
148 while let Some(b'0'..=b'9') = self.peek() {
149 self.position += 1;
150 }
151 if self.position == frac_start {
152 return Err(self.error(ParseErrorKind::InvalidNumber));
153 }
154 }
155
156 if matches!(self.peek(), Some(b'e') | Some(b'E')) {
158 self.position += 1;
159 if matches!(self.peek(), Some(b'+') | Some(b'-')) {
160 self.position += 1;
161 }
162 let exp_start = self.position;
163 while let Some(b'0'..=b'9') = self.peek() {
164 self.position += 1;
165 }
166 if self.position == exp_start {
167 return Err(self.error(ParseErrorKind::InvalidNumber));
168 }
169 }
170
171 let slice = &self.input[start..self.position];
172 let s = core::str::from_utf8(slice).map_err(|_| self.error(ParseErrorKind::InvalidUtf8))?;
174 let value: f64 = s
175 .parse()
176 .map_err(|_| self.error(ParseErrorKind::InvalidNumber))?;
177 Ok(JsonValue::Number(value))
178 }
179
180 fn parse_string(&mut self) -> Result<String, ParseError> {
181 self.expect(b'"')?;
182 let mut buf = String::new();
183 loop {
184 match self.advance() {
185 Some(b'"') => return Ok(buf),
186 Some(b'\\') => {
187 let ch = self.parse_escape()?;
188 buf.push(ch);
189 }
190 Some(b) if b < 0x20 => {
191 return Err(
192 self.error_at(self.position - 1, ParseErrorKind::UnexpectedCharacter(b))
193 );
194 }
195 Some(b) => {
196 let width = utf8_char_width(b);
197 if width == 0 {
198 return Err(self.error(ParseErrorKind::InvalidUtf8));
199 }
200 if width == 1 {
201 buf.push(b as char);
202 } else {
203 let start = self.position - 1;
204 let mut bytes = [0_u8; 4];
205 bytes[0] = b;
206
207 for slot in bytes.iter_mut().take(width).skip(1) {
208 *slot = match self.advance() {
209 Some(cont) => cont,
210 None => return Err(self.error(ParseErrorKind::InvalidUtf8)),
211 };
212 }
213
214 if !is_valid_utf8_sequence(&bytes[..width]) {
215 return Err(self.error(ParseErrorKind::InvalidUtf8));
216 }
217
218 let s = core::str::from_utf8(&self.input[start..self.position])
219 .map_err(|_| self.error(ParseErrorKind::InvalidUtf8))?;
220 buf.push_str(s);
221 }
222 }
223 None => return Err(self.error(ParseErrorKind::UnexpectedEnd)),
224 }
225 }
226 }
227
228 fn parse_escape(&mut self) -> Result<char, ParseError> {
229 match self.advance() {
230 Some(b'"') => Ok('"'),
231 Some(b'\\') => Ok('\\'),
232 Some(b'/') => Ok('/'),
233 Some(b'b') => Ok('\u{0008}'),
234 Some(b'f') => Ok('\u{000C}'),
235 Some(b'n') => Ok('\n'),
236 Some(b'r') => Ok('\r'),
237 Some(b't') => Ok('\t'),
238 Some(b'u') => self.parse_unicode_escape(),
239 Some(_) => Err(self.error_at(self.position - 1, ParseErrorKind::InvalidEscape)),
240 None => Err(self.error(ParseErrorKind::UnexpectedEnd)),
241 }
242 }
243
244 fn parse_unicode_escape(&mut self) -> Result<char, ParseError> {
245 let cp = self.parse_hex4()?;
246
247 if (0xD800..=0xDBFF).contains(&cp) {
249 self.expect(b'\\')
251 .map_err(|_| self.error(ParseErrorKind::InvalidUnicodeEscape))?;
252 self.expect(b'u')
253 .map_err(|_| self.error(ParseErrorKind::InvalidUnicodeEscape))?;
254 let low = self.parse_hex4()?;
255 if !(0xDC00..=0xDFFF).contains(&low) {
256 return Err(self.error(ParseErrorKind::InvalidUnicodeEscape));
257 }
258 let combined = (cp - 0xD800) * 0x400 + (low - 0xDC00) + 0x10000;
259 char::from_u32(combined).ok_or_else(|| self.error(ParseErrorKind::InvalidUnicodeEscape))
260 } else if (0xDC00..=0xDFFF).contains(&cp) {
261 Err(self.error(ParseErrorKind::InvalidUnicodeEscape))
263 } else {
264 char::from_u32(cp).ok_or_else(|| self.error(ParseErrorKind::InvalidUnicodeEscape))
265 }
266 }
267
268 fn parse_hex4(&mut self) -> Result<u32, ParseError> {
269 let mut value: u32 = 0;
270 for _ in 0..4 {
271 let digit = match self.advance() {
272 Some(b @ b'0'..=b'9') => (b - b'0') as u32,
273 Some(b @ b'a'..=b'f') => (b - b'a' + 10) as u32,
274 Some(b @ b'A'..=b'F') => (b - b'A' + 10) as u32,
275 Some(_) => {
276 return Err(
277 self.error_at(self.position - 1, ParseErrorKind::InvalidUnicodeEscape)
278 )
279 }
280 None => return Err(self.error(ParseErrorKind::InvalidUnicodeEscape)),
281 };
282 value = value * 16 + digit;
283 }
284 Ok(value)
285 }
286
287 fn parse_array(&mut self) -> Result<JsonValue, ParseError> {
288 self.expect(b'[')?;
289 self.depth += 1;
290 if self.depth > MAX_DEPTH {
291 return Err(self.error(ParseErrorKind::NestingTooDeep));
292 }
293
294 self.skip_whitespace();
295 if self.peek() == Some(b']') {
296 self.position += 1;
297 self.depth -= 1;
298 return Ok(JsonValue::Array(Vec::new()));
299 }
300
301 let mut items = Vec::new();
302 loop {
303 let value = self.parse_value()?;
304 items.push(value);
305 self.skip_whitespace();
306 match self.peek() {
307 Some(b',') => {
308 self.position += 1;
309 }
310 Some(b']') => {
311 self.position += 1;
312 self.depth -= 1;
313 return Ok(JsonValue::Array(items));
314 }
315 Some(b) => return Err(self.error(ParseErrorKind::UnexpectedCharacter(b))),
316 None => return Err(self.error(ParseErrorKind::UnexpectedEnd)),
317 }
318 }
319 }
320
321 fn parse_object(&mut self) -> Result<JsonValue, ParseError> {
322 self.expect(b'{')?;
323 self.depth += 1;
324 if self.depth > MAX_DEPTH {
325 return Err(self.error(ParseErrorKind::NestingTooDeep));
326 }
327
328 self.skip_whitespace();
329 if self.peek() == Some(b'}') {
330 self.position += 1;
331 self.depth -= 1;
332 return Ok(JsonValue::Object(Vec::new()));
333 }
334
335 let mut fields = Vec::new();
336 loop {
337 self.skip_whitespace();
338 if self.peek() != Some(b'"') {
339 return Err(match self.peek() {
340 Some(b) => self.error(ParseErrorKind::UnexpectedCharacter(b)),
341 None => self.error(ParseErrorKind::UnexpectedEnd),
342 });
343 }
344 let key = self.parse_string()?;
345 self.skip_whitespace();
346 self.expect(b':')?;
347 let value = self.parse_value()?;
348 fields.push((key, value));
349 self.skip_whitespace();
350 match self.peek() {
351 Some(b',') => {
352 self.position += 1;
353 }
354 Some(b'}') => {
355 self.position += 1;
356 self.depth -= 1;
357 return Ok(JsonValue::Object(fields));
358 }
359 Some(b) => return Err(self.error(ParseErrorKind::UnexpectedCharacter(b))),
360 None => return Err(self.error(ParseErrorKind::UnexpectedEnd)),
361 }
362 }
363 }
364}
365
366fn utf8_char_width(b: u8) -> usize {
368 if b < 0x80 {
369 1
370 } else if (0xC2..=0xDF).contains(&b) {
371 2
372 } else if (0xE0..=0xEF).contains(&b) {
373 3
374 } else if (0xF0..=0xF4).contains(&b) {
375 4
376 } else {
377 0
378 }
379}
380
381fn is_valid_utf8_sequence(bytes: &[u8]) -> bool {
382 match bytes {
383 [first, second] => (0xC2..=0xDF).contains(first) && is_continuation_byte(*second),
384 [first, second, third] => {
385 (match *first {
386 0xE0 => (0xA0..=0xBF).contains(second),
387 0xE1..=0xEC | 0xEE..=0xEF => is_continuation_byte(*second),
388 0xED => (0x80..=0x9F).contains(second),
389 _ => false,
390 }) && is_continuation_byte(*third)
391 }
392 [first, second, third, fourth] => {
393 (match *first {
394 0xF0 => (0x90..=0xBF).contains(second),
395 0xF1..=0xF3 => is_continuation_byte(*second),
396 0xF4 => (0x80..=0x8F).contains(second),
397 _ => false,
398 }) && is_continuation_byte(*third)
399 && is_continuation_byte(*fourth)
400 }
401 _ => false,
402 }
403}
404
405fn is_continuation_byte(b: u8) -> bool {
406 (0x80..=0xBF).contains(&b)
407}
408
409#[cfg(test)]
410mod tests {
411 use alloc::string::String;
412 use alloc::vec;
413
414 use super::parse;
415 use crate::{JsonValue, ParseErrorKind};
416
417 #[test]
418 fn parses_basic_types() {
419 assert_eq!(parse(b"null"), Ok(JsonValue::Null));
420 assert_eq!(parse(b"true"), Ok(JsonValue::Bool(true)));
421 assert_eq!(parse(b"false"), Ok(JsonValue::Bool(false)));
422 assert_eq!(parse(b"0"), Ok(JsonValue::Number(0.0)));
423 assert_eq!(parse(b"-12"), Ok(JsonValue::Number(-12.0)));
424 assert_eq!(parse(b"3.5"), Ok(JsonValue::Number(3.5)));
425 assert_eq!(parse(b"1.25e2"), Ok(JsonValue::Number(125.0)));
426 assert_eq!(
427 parse(br#""hello""#),
428 Ok(JsonValue::String(String::from("hello")))
429 );
430 }
431
432 #[test]
433 fn parses_string_escapes() {
434 assert_eq!(
435 parse(br#""\"\\\/\b\f\n\r\t""#),
436 Ok(JsonValue::String(String::from(
437 "\"\\/\u{0008}\u{000C}\n\r\t"
438 )))
439 );
440 }
441
442 #[test]
443 fn parses_unicode_escapes_and_surrogate_pairs() {
444 assert_eq!(
445 parse(br#""\u0041""#),
446 Ok(JsonValue::String(String::from("A")))
447 );
448 assert_eq!(
449 parse(br#""\u3042""#),
450 Ok(JsonValue::String(String::from("あ")))
451 );
452 assert_eq!(
453 parse(br#""\uD83D\uDE00""#),
454 Ok(JsonValue::String(String::from("😀")))
455 );
456 }
457
458 #[test]
459 fn parses_nested_values() {
460 assert_eq!(
461 parse(br#"{"items":[{"flag":true},[null,{"n":2}]],"name":"ok"}"#),
462 Ok(JsonValue::Object(vec![
463 (
464 String::from("items"),
465 JsonValue::Array(vec![
466 JsonValue::Object(vec![(String::from("flag"), JsonValue::Bool(true))]),
467 JsonValue::Array(vec![
468 JsonValue::Null,
469 JsonValue::Object(vec![(String::from("n"), JsonValue::Number(2.0))]),
470 ]),
471 ]),
472 ),
473 (String::from("name"), JsonValue::String(String::from("ok"))),
474 ]))
475 );
476 }
477
478 #[test]
479 fn parses_deep_nesting_at_limit() {
480 let mut input = vec![b'['; 128];
481 input.extend(vec![b']'; 128]);
482 assert!(parse(&input).is_ok());
484 }
485
486 #[test]
487 fn skips_whitespace() {
488 assert_eq!(
489 parse(b" \n\t\r {\"a\" : [ true , null ] } \n"),
490 Ok(JsonValue::Object(vec![(
491 String::from("a"),
492 JsonValue::Array(vec![JsonValue::Bool(true), JsonValue::Null]),
493 )]))
494 );
495 }
496
497 #[test]
498 fn reports_trailing_content() {
499 let error = parse(b"true false").unwrap_err();
500 assert_eq!(error.kind, ParseErrorKind::TrailingContent);
501 }
502
503 #[test]
504 fn reports_lone_surrogates() {
505 assert_eq!(
506 parse(br#""\uD83D""#).unwrap_err().kind,
507 ParseErrorKind::InvalidUnicodeEscape
508 );
509 assert_eq!(
510 parse(br#""\uDE00""#).unwrap_err().kind,
511 ParseErrorKind::InvalidUnicodeEscape
512 );
513 }
514
515 #[test]
516 fn reports_leading_zero_numbers() {
517 assert_eq!(
519 parse(b"01").unwrap_err().kind,
520 ParseErrorKind::TrailingContent
521 );
522 assert_eq!(
523 parse(b"-01").unwrap_err().kind,
524 ParseErrorKind::TrailingContent
525 );
526 }
527
528 #[test]
529 fn parses_all_supported_number_forms() {
530 assert_eq!(parse(b"0"), Ok(JsonValue::Number(0.0)));
531 assert_eq!(parse(b"-0"), Ok(JsonValue::Number(-0.0)));
532 assert_eq!(parse(b"0.5"), Ok(JsonValue::Number(0.5)));
533 assert_eq!(parse(b"-0.5"), Ok(JsonValue::Number(-0.5)));
534 assert_eq!(parse(b"1e10"), Ok(JsonValue::Number(1e10)));
535 assert_eq!(parse(b"1E+10"), Ok(JsonValue::Number(1e10)));
536 assert_eq!(parse(b"1e-10"), Ok(JsonValue::Number(1e-10)));
537 assert_eq!(parse(b"1.5e2"), Ok(JsonValue::Number(150.0)));
538 assert_eq!(parse(b"-1.5E-3"), Ok(JsonValue::Number(-1.5e-3)));
539 }
540
541 #[test]
542 fn rejects_additional_leading_zero_forms() {
543 assert_eq!(
544 parse(b"00").unwrap_err().kind,
545 ParseErrorKind::TrailingContent
546 );
547 assert_eq!(
548 parse(b"-00").unwrap_err().kind,
549 ParseErrorKind::TrailingContent
550 );
551 assert_eq!(parse(b"-0"), Ok(JsonValue::Number(-0.0)));
552 }
553
554 #[test]
555 fn parses_solidus_escape_explicitly() {
556 assert_eq!(parse(br#""\/""#), Ok(JsonValue::String(String::from("/"))));
557 }
558
559 #[test]
560 fn accepts_all_json_whitespace_around_values() {
561 assert_eq!(parse(b"\t\r\n 42 \r\n\t"), Ok(JsonValue::Number(42.0)));
562 assert_eq!(
563 parse(b"\r\n[\t1,\n2,\r3 \t]\n"),
564 Ok(JsonValue::Array(vec![
565 JsonValue::Number(1.0),
566 JsonValue::Number(2.0),
567 JsonValue::Number(3.0),
568 ]))
569 );
570 assert_eq!(
571 parse(b"\t{\n\"a\"\r:\ttrue \n}\r"),
572 Ok(JsonValue::Object(vec![(
573 String::from("a"),
574 JsonValue::Bool(true)
575 )]))
576 );
577 }
578
579 #[test]
580 fn parses_empty_object_array_and_empty_string_key() {
581 assert_eq!(parse(b"{}"), Ok(JsonValue::Object(vec![])));
582 assert_eq!(parse(b"[]"), Ok(JsonValue::Array(vec![])));
583 assert_eq!(
584 parse(br#"{"":1}"#),
585 Ok(JsonValue::Object(vec![(
586 String::from(""),
587 JsonValue::Number(1.0)
588 )]))
589 );
590 }
591
592 #[test]
593 fn parses_unicode_escape_boundary_values() {
594 assert_eq!(
595 parse(br#""\u0000""#),
596 Ok(JsonValue::String(String::from("\u{0000}")))
597 );
598 assert_eq!(
599 parse(br#""\uFFFF""#),
600 Ok(JsonValue::String(String::from("\u{FFFF}")))
601 );
602 }
603
604 #[test]
605 fn rejects_utf8_bom_prefix() {
606 assert_eq!(
607 parse(b"\xEF\xBB\xBFnull").unwrap_err().kind,
608 ParseErrorKind::UnexpectedCharacter(0xEF)
609 );
610 }
611
612 #[test]
613 fn rejects_invalid_single_token_and_trailing_comma_inputs() {
614 for input in [b"]".as_slice(), b"}", b",", b":"] {
615 assert!(matches!(
616 parse(input).unwrap_err().kind,
617 ParseErrorKind::UnexpectedCharacter(_)
618 ));
619 }
620
621 assert_eq!(
622 parse(b"[,]").unwrap_err().kind,
623 ParseErrorKind::UnexpectedCharacter(b',')
624 );
625 assert_eq!(
626 parse(b"{,}").unwrap_err().kind,
627 ParseErrorKind::UnexpectedCharacter(b',')
628 );
629 assert_eq!(
630 parse(br#"{"key"}"#).unwrap_err().kind,
631 ParseErrorKind::UnexpectedCharacter(b'}')
632 );
633 assert_eq!(
634 parse(b"[1,]").unwrap_err().kind,
635 ParseErrorKind::UnexpectedCharacter(b']')
636 );
637 }
638
639 #[test]
640 fn reports_max_depth_exceeded() {
641 let mut input = vec![b'['; 129];
642 input.extend(vec![b']'; 129]);
643 assert_eq!(
644 parse(&input).unwrap_err().kind,
645 ParseErrorKind::NestingTooDeep
646 );
647 }
648
649 #[test]
650 fn reports_invalid_escape_sequences() {
651 assert_eq!(
652 parse(br#""\x""#).unwrap_err().kind,
653 ParseErrorKind::InvalidEscape
654 );
655 }
656
657 #[test]
658 fn reports_exact_error_positions_for_post_advance_failures() {
659 let invalid_escape = parse(br#""\x""#).unwrap_err();
660 assert_eq!(invalid_escape.kind, ParseErrorKind::InvalidEscape);
661 assert_eq!(invalid_escape.position, 2);
662
663 let invalid_literal = parse(b"tXue").unwrap_err();
664 assert_eq!(
665 invalid_literal.kind,
666 ParseErrorKind::UnexpectedCharacter(b'X')
667 );
668 assert_eq!(invalid_literal.position, 1);
669
670 let control = parse(b"\"hello\nworld\"").unwrap_err();
671 assert_eq!(control.kind, ParseErrorKind::UnexpectedCharacter(b'\n'));
672 assert_eq!(control.position, 6);
673
674 let invalid_unicode = parse(br#""\u12G4""#).unwrap_err();
675 assert_eq!(invalid_unicode.kind, ParseErrorKind::InvalidUnicodeEscape);
676 assert_eq!(invalid_unicode.position, 5);
677 }
678
679 #[test]
680 fn reports_empty_input() {
681 assert_eq!(parse(b"").unwrap_err().kind, ParseErrorKind::UnexpectedEnd);
682 }
683
684 #[test]
685 fn parses_empty_array_and_object() {
686 assert_eq!(parse(b"[]"), Ok(JsonValue::Array(vec![])));
687 assert_eq!(parse(b"{}"), Ok(JsonValue::Object(vec![])));
688 }
689
690 #[test]
691 fn parses_negative_exponent() {
692 assert_eq!(parse(b"1e-2"), Ok(JsonValue::Number(0.01)));
693 assert_eq!(parse(b"5E+3"), Ok(JsonValue::Number(5000.0)));
694 }
695
696 #[test]
697 fn parses_multibyte_utf8_in_string() {
698 assert_eq!(
700 parse("\"日本語\"".as_bytes()),
701 Ok(JsonValue::String(String::from("日本語")))
702 );
703 }
704
705 #[test]
706 fn reports_control_character_in_string() {
707 assert!(parse(b"\"hello\nworld\"").is_err());
709 }
710
711 #[test]
712 fn reports_invalid_utf8_sequences_in_string() {
713 assert_eq!(
714 parse(b"\"\x80\"").unwrap_err().kind,
715 ParseErrorKind::InvalidUtf8
716 );
717 assert_eq!(
718 parse(b"\"\xC0\xAF\"").unwrap_err().kind,
719 ParseErrorKind::InvalidUtf8
720 );
721 assert_eq!(
722 parse(b"\"\xE3\x81\"").unwrap_err().kind,
723 ParseErrorKind::InvalidUtf8
724 );
725 }
726}