Skip to content

Commit a0f515a

Browse files
committed
0.8.0 read escaped surrogate pairs properly, fixes #39
1 parent 7b7ce78 commit a0f515a

File tree

2 files changed

+32
-1
lines changed

2 files changed

+32
-1
lines changed

src/parser.rs

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -254,11 +254,31 @@ impl<'a> Parser<'a> {
254254
}
255255

256256
fn read_codepoint(&mut self) -> JsonResult<()> {
257-
let codepoint = try!(self.read_char_as_hexnumber()) << 12
257+
let mut codepoint = try!(self.read_char_as_hexnumber()) << 12
258258
| try!(self.read_char_as_hexnumber()) << 8
259259
| try!(self.read_char_as_hexnumber()) << 4
260260
| try!(self.read_char_as_hexnumber());
261261

262+
match codepoint {
263+
0xD800 ... 0xDFFF => {
264+
codepoint -= 0xD800;
265+
codepoint <<= 10;
266+
267+
expect!(self, b'\\');
268+
expect!(self, b'u');
269+
270+
let lower = try!(self.read_char_as_hexnumber()) << 12
271+
| try!(self.read_char_as_hexnumber()) << 8
272+
| try!(self.read_char_as_hexnumber()) << 4
273+
| try!(self.read_char_as_hexnumber());
274+
275+
codepoint |= lower - 0xDC00;
276+
277+
codepoint += 0x010000;
278+
},
279+
_ => {}
280+
}
281+
262282
let ch = try!(
263283
char::from_u32(codepoint).ok_or(JsonError::FailedUtf8Parsing)
264284
);

tests/lib.rs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -533,6 +533,17 @@ fn parse_escaped_unicode() {
533533
assert_eq!(data, "❤️");
534534
}
535535

536+
#[test]
537+
fn parse_escaped_unicode_surrogate() {
538+
let data = parse(r#"
539+
540+
"\uD834\uDD1E"
541+
542+
"#).unwrap();
543+
544+
assert_eq!(data, "𝄞");
545+
}
546+
536547
#[test]
537548
fn array_len() {
538549
let data = array![0, 1, 2, 3];

0 commit comments

Comments
 (0)