From 00212bcb0988df74de509b953c9fca348391f7e0 Mon Sep 17 00:00:00 2001 From: Paul Grandperrin Date: Tue, 26 Apr 2016 01:14:50 +0200 Subject: [PATCH 01/10] Correctly escape control characters in strings --- json/src/ser.rs | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/json/src/ser.rs b/json/src/ser.rs index e2d4479e2..85de2dd52 100644 --- a/json/src/ser.rs +++ b/json/src/ser.rs @@ -504,6 +504,17 @@ pub fn escape_bytes(wr: &mut W, bytes: &[u8]) -> Result<()> b'\n' => b"\\n", b'\r' => b"\\r", b'\t' => b"\\t", + c @ b'\x00' ... b'\x1F' => { + if start < i { + try!(wr.write_all(&bytes[start..i])); + } + + try!(write!(wr,"\\u{:04X}", c)); + + start = i + 1; + + continue; + }, _ => { continue; } }; From dd47b9dafabfc1386224602384b9fdf5ed1fa01a Mon Sep 17 00:00:00 2001 From: Paul Grandperrin Date: Tue, 26 Apr 2016 01:13:30 +0200 Subject: [PATCH 02/10] Add more string serialization tests --- json_tests/tests/test_json.rs | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/json_tests/tests/test_json.rs b/json_tests/tests/test_json.rs index fa765fd98..eb897d708 100644 --- a/json_tests/tests/test_json.rs +++ b/json_tests/tests/test_json.rs @@ -139,6 +139,17 @@ fn test_write_str() { let tests = &[ ("", "\"\""), ("foo", "\"foo\""), + ("\u{0}", "\"\\u0000\""), + ("\u{1F}", "\"\\u001F\""), + ("\"", "\"\\\"\""), + ("\\", "\"\\\\\""), + ("\u{8}", "\"\\b\""), + ("\u{C}", "\"\\f\""), + ("\n", "\"\\n\""), + ("\r", "\"\\r\""), + ("\t", "\"\\t\""), + ("\u{FFFF}", "\"\u{FFFF}\""), + ("\u{10FFFF}", "\"\u{10FFFF}\""), ]; test_encode_ok(tests); test_pretty_encode_ok(tests); From 8013546a5bdf1cf07dd5fc87edea7b1dad0e20c8 Mon Sep 17 00:00:00 2001 From: Paul Grandperrin Date: Tue, 26 Apr 2016 01:14:30 +0200 Subject: [PATCH 03/10] Add more string deserialization tests --- json_tests/tests/test_json.rs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/json_tests/tests/test_json.rs b/json_tests/tests/test_json.rs index eb897d708..ba49d8daf 100644 --- a/json_tests/tests/test_json.rs +++ b/json_tests/tests/test_json.rs @@ -819,12 +819,17 @@ fn test_parse_string() { ("\"foo\"", "foo".to_string()), (" \"foo\" ", "foo".to_string()), ("\"\\\"\"", "\"".to_string()), + ("\"\\/\"", "/".to_string()), ("\"\\b\"", "\x08".to_string()), + ("\"\\f\"", "\x0C".to_string()), ("\"\\n\"", "\n".to_string()), ("\"\\r\"", "\r".to_string()), ("\"\\t\"", "\t".to_string()), ("\"\\u12ab\"", "\u{12ab}".to_string()), ("\"\\uAB12\"", "\u{AB12}".to_string()), + ("\"\\uDBFF\\uDFFF\"", "\u{10FFFF}".to_string()), + ("\"\u{FFFF}\"", "\u{FFFF}".to_string()), + ("\"\u{10FFFF}\"", "\u{10FFFF}".to_string()), ]); } From 659e99d5eaa4000f4573948885356934f7ec3fb5 Mon Sep 17 00:00:00 2001 From: Paul Grandperrin Date: Tue, 26 Apr 2016 14:24:45 +0200 Subject: [PATCH 04/10] Escape ASCII DEL control character in strings --- json/src/ser.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/json/src/ser.rs b/json/src/ser.rs index 85de2dd52..5d90ccc38 100644 --- a/json/src/ser.rs +++ b/json/src/ser.rs @@ -504,12 +504,12 @@ pub fn escape_bytes(wr: &mut W, bytes: &[u8]) -> Result<()> b'\n' => b"\\n", b'\r' => b"\\r", b'\t' => b"\\t", - c @ b'\x00' ... b'\x1F' => { + b'\x00' ... b'\x1F' | b'\x7F' => { if start < i { try!(wr.write_all(&bytes[start..i])); } - try!(write!(wr,"\\u{:04X}", c)); + try!(write!(wr,"\\u{:04X}", *byte)); start = i + 1; From 83a87759ccce71e3e869758c0d9f766a42b7ba5a Mon Sep 17 00:00:00 2001 From: Paul Grandperrin Date: Tue, 26 Apr 2016 14:26:26 +0200 Subject: [PATCH 05/10] Escape Unicode C1 control characters in strings --- json/src/ser.rs | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/json/src/ser.rs b/json/src/ser.rs index 5d90ccc38..8c59fa560 100644 --- a/json/src/ser.rs +++ b/json/src/ser.rs @@ -494,6 +494,7 @@ pub fn escape_bytes(wr: &mut W, bytes: &[u8]) -> Result<()> try!(wr.write_all(b"\"")); let mut start = 0; + let mut last_byte_was_c2 = false; for (i, byte) in bytes.iter().enumerate() { let escaped = match *byte { @@ -515,6 +516,21 @@ pub fn escape_bytes(wr: &mut W, bytes: &[u8]) -> Result<()> continue; }, + b'\x80' ... b'\x9F' if last_byte_was_c2 => { + if start < (i - 1) { + try!(wr.write_all(&bytes[start..(i - 1)])); + } + + try!(write!(wr,"\\u{:04X}", *byte)); + + start = i + 1; + + continue; + }, + b'\xC2' => { + last_byte_was_c2 = true; + continue; + }, _ => { continue; } }; From 026f49b061e83e6e12b9eca228964089d4683e91 Mon Sep 17 00:00:00 2001 From: Paul Grandperrin Date: Tue, 26 Apr 2016 14:27:39 +0200 Subject: [PATCH 06/10] Add more tests on string control character escaping Verify the escaping of: - DEL: Ox7F - C1 list: 0x80-0x9F --- json_tests/tests/test_json.rs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/json_tests/tests/test_json.rs b/json_tests/tests/test_json.rs index ba49d8daf..0ea032e37 100644 --- a/json_tests/tests/test_json.rs +++ b/json_tests/tests/test_json.rs @@ -141,6 +141,9 @@ fn test_write_str() { ("foo", "\"foo\""), ("\u{0}", "\"\\u0000\""), ("\u{1F}", "\"\\u001F\""), + ("\u{7F}", "\"\\u007F\""), + ("\u{80}", "\"\\u0080\""), + ("\u{9F}", "\"\\u009F\""), ("\"", "\"\\\"\""), ("\\", "\"\\\\\""), ("\u{8}", "\"\\b\""), From f523b4136c2d3dc317cf0d7bf120ca6530e60f94 Mon Sep 17 00:00:00 2001 From: Paul Grandperrin Date: Tue, 26 Apr 2016 21:34:43 +0200 Subject: [PATCH 07/10] Fix Unicode C1 control character escaping --- json/src/ser.rs | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/json/src/ser.rs b/json/src/ser.rs index 8c59fa560..691835d72 100644 --- a/json/src/ser.rs +++ b/json/src/ser.rs @@ -494,9 +494,12 @@ pub fn escape_bytes(wr: &mut W, bytes: &[u8]) -> Result<()> try!(wr.write_all(b"\"")); let mut start = 0; - let mut last_byte_was_c2 = false; + let mut last_byte = 0u8; for (i, byte) in bytes.iter().enumerate() { + let last_byte_was_c2 = last_byte == b'\xC2'; + last_byte = *byte; + let escaped = match *byte { b'"' => b"\\\"", b'\\' => b"\\\\", @@ -527,10 +530,6 @@ pub fn escape_bytes(wr: &mut W, bytes: &[u8]) -> Result<()> continue; }, - b'\xC2' => { - last_byte_was_c2 = true; - continue; - }, _ => { continue; } }; From 64132013ff0d23c5382c28bf4dfbf7bd328f49fe Mon Sep 17 00:00:00 2001 From: Paul Grandperrin Date: Sat, 30 Apr 2016 22:07:47 +0200 Subject: [PATCH 08/10] Reimplement ser::escape_str() and escape control characters This new implementation does escape Unicode C0, DEL and C1 control characters. It also use its own logic and does not rely on ser::escape_bytes(). Escaping C0 control characters is mandated by ECMA-404. Escaping DEL and C1 control characters is a useful convenience often done by other JSON implementations. --- json/src/ser.rs | 42 +++++++++++++++++++++++++++++++++++++++++- 1 file changed, 41 insertions(+), 1 deletion(-) diff --git a/json/src/ser.rs b/json/src/ser.rs index 691835d72..7563edcb6 100644 --- a/json/src/ser.rs +++ b/json/src/ser.rs @@ -555,7 +555,47 @@ pub fn escape_bytes(wr: &mut W, bytes: &[u8]) -> Result<()> pub fn escape_str(wr: &mut W, value: &str) -> Result<()> where W: io::Write { - escape_bytes(wr, value.as_bytes()) + let mut start = 0; + + try!(wr.write_all(b"\"")); + + for (i, char) in value.char_indices() { + let escaped = match char { + '"' => b"\\\"", + '\\' => b"\\\\", + '\u{08}' => b"\\b", + '\u{0c}' => b"\\f", + '\n' => b"\\n", + '\r' => b"\\r", + '\t' => b"\\t", + '\u{00}' ... '\u{1F}' | '\u{7F}' | '\u{80}' ... '\u{9F}' => { + // only Unicode C0 control characters ('\u{00}' ... '\u{1F}') are mandated to be escaped by ECMA-404. + // DEL ('\u{7F}') and C1 ('\u{80}' ... '\u{9F}') control characters are also escaped for convenience. + + debug_assert_eq!(char.len_utf16(), 1); // C0, DEL and C1 control characters fit on one utf16 code unit by specification. + try!(write!(wr, "{}\\u{:04X}", &value[start..i], char as u32)); + + start = i + char.len_utf8(); + continue; + }, + _ => { continue; } + }; + + if start < i { + try!(wr.write_all(&value[start..i].as_bytes())); + } + try!(wr.write_all(escaped)); + + debug_assert_eq!(char.len_utf8(), 1); + start = i + 1; + } + + if start != value.len() { + try!(wr.write_all(&value[start..].as_bytes())); + } + + try!(wr.write_all(b"\"")); + Ok(()) } #[inline] From 32eb21ef57f6c34c5054e6c20d557498d28738c3 Mon Sep 17 00:00:00 2001 From: Paul Grandperrin Date: Sun, 1 May 2016 14:19:51 +0200 Subject: [PATCH 09/10] Add tons of new tests in test_write_str() --- json_tests/tests/test_json.rs | 424 ++++++++++++++++++++++++++++++++++ 1 file changed, 424 insertions(+) diff --git a/json_tests/tests/test_json.rs b/json_tests/tests/test_json.rs index 0ea032e37..944015255 100644 --- a/json_tests/tests/test_json.rs +++ b/json_tests/tests/test_json.rs @@ -139,6 +139,8 @@ fn test_write_str() { let tests = &[ ("", "\"\""), ("foo", "\"foo\""), + + // special characters ("\u{0}", "\"\\u0000\""), ("\u{1F}", "\"\\u001F\""), ("\u{7F}", "\"\\u007F\""), @@ -153,6 +155,428 @@ fn test_write_str() { ("\t", "\"\\t\""), ("\u{FFFF}", "\"\u{FFFF}\""), ("\u{10FFFF}", "\"\u{10FFFF}\""), + + // special characters twice + ("\u{0}\u{0}", "\"\\u0000\\u0000\""), + ("\u{1F}\u{1F}", "\"\\u001F\\u001F\""), + ("\u{7F}\u{7F}", "\"\\u007F\\u007F\""), + ("\u{80}\u{80}", "\"\\u0080\\u0080\""), + ("\u{9F}\u{9F}", "\"\\u009F\\u009F\""), + ("\"\"", "\"\\\"\\\"\""), + ("\\\\", "\"\\\\\\\\\""), + ("\u{8}\u{8}", "\"\\b\\b\""), + ("\u{C}\u{C}", "\"\\f\\f\""), + ("\n\n", "\"\\n\\n\""), + ("\r\r", "\"\\r\\r\""), + ("\t\t", "\"\\t\\t\""), + ("\u{FFFF}\u{FFFF}", "\"\u{FFFF}\u{FFFF}\""), + ("\u{10FFFF}\u{10FFFF}", "\"\u{10FFFF}\u{10FFFF}\""), + + // patterns of special characters interleaved with a one unit code utf-8 character + ("a\u{0}a\u{0}\u{0}a", "\"a\\u0000a\\u0000\\u0000a\""), + ("\u{0}a\u{0}\u{0}a", "\"\\u0000a\\u0000\\u0000a\""), + ("a\u{0}a\u{0}\u{0}", "\"a\\u0000a\\u0000\\u0000\""), + ("\u{0}a\u{0}\u{0}", "\"\\u0000a\\u0000\\u0000\""), + ("a\u{1F}a\u{1F}\u{1F}a", "\"a\\u001Fa\\u001F\\u001Fa\""), + ("\u{1F}a\u{1F}\u{1F}a", "\"\\u001Fa\\u001F\\u001Fa\""), + ("a\u{1F}a\u{1F}\u{1F}", "\"a\\u001Fa\\u001F\\u001F\""), + ("\u{1F}a\u{1F}\u{1F}", "\"\\u001Fa\\u001F\\u001F\""), + ("a\u{7F}a\u{7F}\u{7F}a", "\"a\\u007Fa\\u007F\\u007Fa\""), + ("\u{7F}a\u{7F}\u{7F}a", "\"\\u007Fa\\u007F\\u007Fa\""), + ("a\u{7F}a\u{7F}\u{7F}", "\"a\\u007Fa\\u007F\\u007F\""), + ("\u{7F}a\u{7F}\u{7F}", "\"\\u007Fa\\u007F\\u007F\""), + ("a\u{80}a\u{80}\u{80}a", "\"a\\u0080a\\u0080\\u0080a\""), + ("\u{80}a\u{80}\u{80}a", "\"\\u0080a\\u0080\\u0080a\""), + ("a\u{80}a\u{80}\u{80}", "\"a\\u0080a\\u0080\\u0080\""), + ("\u{80}a\u{80}\u{80}", "\"\\u0080a\\u0080\\u0080\""), + ("a\u{9F}a\u{9F}\u{9F}a", "\"a\\u009Fa\\u009F\\u009Fa\""), + ("\u{9F}a\u{9F}\u{9F}a", "\"\\u009Fa\\u009F\\u009Fa\""), + ("a\u{9F}a\u{9F}\u{9F}", "\"a\\u009Fa\\u009F\\u009F\""), + ("\u{9F}a\u{9F}\u{9F}", "\"\\u009Fa\\u009F\\u009F\""), + ("a\"a\"\"a", "\"a\\\"a\\\"\\\"a\""), + ("\"a\"\"a", "\"\\\"a\\\"\\\"a\""), + ("a\"a\"\"", "\"a\\\"a\\\"\\\"\""), + ("\"a\"\"", "\"\\\"a\\\"\\\"\""), + ("a\\a\\\\a", "\"a\\\\a\\\\\\\\a\""), + ("\\a\\\\a", "\"\\\\a\\\\\\\\a\""), + ("a\\a\\\\", "\"a\\\\a\\\\\\\\\""), + ("\\a\\\\", "\"\\\\a\\\\\\\\\""), + ("a\u{8}a\u{8}\u{8}a", "\"a\\ba\\b\\ba\""), + ("\u{8}a\u{8}\u{8}a", "\"\\ba\\b\\ba\""), + ("a\u{8}a\u{8}\u{8}", "\"a\\ba\\b\\b\""), + ("\u{8}a\u{8}\u{8}", "\"\\ba\\b\\b\""), + ("a\u{C}a\u{C}\u{C}a", "\"a\\fa\\f\\fa\""), + ("\u{C}a\u{C}\u{C}a", "\"\\fa\\f\\fa\""), + ("a\u{C}a\u{C}\u{C}", "\"a\\fa\\f\\f\""), + ("\u{C}a\u{C}\u{C}", "\"\\fa\\f\\f\""), + ("a\na\n\na", "\"a\\na\\n\\na\""), + ("\na\n\na", "\"\\na\\n\\na\""), + ("a\na\n\n", "\"a\\na\\n\\n\""), + ("\na\n\n", "\"\\na\\n\\n\""), + ("a\ra\r\ra", "\"a\\ra\\r\\ra\""), + ("\ra\r\ra", "\"\\ra\\r\\ra\""), + ("a\ra\r\r", "\"a\\ra\\r\\r\""), + ("\ra\r\r", "\"\\ra\\r\\r\""), + ("a\ta\t\ta", "\"a\\ta\\t\\ta\""), + ("\ta\t\ta", "\"\\ta\\t\\ta\""), + ("a\ta\t\t", "\"a\\ta\\t\\t\""), + ("\ta\t\t", "\"\\ta\\t\\t\""), + ("a\u{FFFF}a\u{FFFF}\u{FFFF}a", "\"a\u{FFFF}a\u{FFFF}\u{FFFF}a\""), + ("\u{FFFF}a\u{FFFF}\u{FFFF}a", "\"\u{FFFF}a\u{FFFF}\u{FFFF}a\""), + ("a\u{FFFF}a\u{FFFF}\u{FFFF}", "\"a\u{FFFF}a\u{FFFF}\u{FFFF}\""), + ("\u{FFFF}a\u{FFFF}\u{FFFF}", "\"\u{FFFF}a\u{FFFF}\u{FFFF}\""), + ("a\u{10FFFF}a\u{10FFFF}\u{10FFFF}a", "\"a\u{10FFFF}a\u{10FFFF}\u{10FFFF}a\""), + ("\u{10FFFF}a\u{10FFFF}\u{10FFFF}a", "\"\u{10FFFF}a\u{10FFFF}\u{10FFFF}a\""), + ("a\u{10FFFF}a\u{10FFFF}\u{10FFFF}", "\"a\u{10FFFF}a\u{10FFFF}\u{10FFFF}\""), + ("\u{10FFFF}a\u{10FFFF}\u{10FFFF}", "\"\u{10FFFF}a\u{10FFFF}\u{10FFFF}\""), + + // patterns of special characters interleaved with multiple one unit code utf-8 character + ("foo\u{0}foo\u{0}\u{0}foo", "\"foo\\u0000foo\\u0000\\u0000foo\""), + ("\u{0}foo\u{0}\u{0}foo", "\"\\u0000foo\\u0000\\u0000foo\""), + ("foo\u{0}foo\u{0}\u{0}", "\"foo\\u0000foo\\u0000\\u0000\""), + ("\u{0}foo\u{0}\u{0}", "\"\\u0000foo\\u0000\\u0000\""), + ("foo\u{1F}foo\u{1F}\u{1F}foo", "\"foo\\u001Ffoo\\u001F\\u001Ffoo\""), + ("\u{1F}foo\u{1F}\u{1F}foo", "\"\\u001Ffoo\\u001F\\u001Ffoo\""), + ("foo\u{1F}foo\u{1F}\u{1F}", "\"foo\\u001Ffoo\\u001F\\u001F\""), + ("\u{1F}foo\u{1F}\u{1F}", "\"\\u001Ffoo\\u001F\\u001F\""), + ("foo\u{7F}foo\u{7F}\u{7F}foo", "\"foo\\u007Ffoo\\u007F\\u007Ffoo\""), + ("\u{7F}foo\u{7F}\u{7F}foo", "\"\\u007Ffoo\\u007F\\u007Ffoo\""), + ("foo\u{7F}foo\u{7F}\u{7F}", "\"foo\\u007Ffoo\\u007F\\u007F\""), + ("\u{7F}foo\u{7F}\u{7F}", "\"\\u007Ffoo\\u007F\\u007F\""), + ("foo\u{80}foo\u{80}\u{80}foo", "\"foo\\u0080foo\\u0080\\u0080foo\""), + ("\u{80}foo\u{80}\u{80}foo", "\"\\u0080foo\\u0080\\u0080foo\""), + ("foo\u{80}foo\u{80}\u{80}", "\"foo\\u0080foo\\u0080\\u0080\""), + ("\u{80}foo\u{80}\u{80}", "\"\\u0080foo\\u0080\\u0080\""), + ("foo\u{9F}foo\u{9F}\u{9F}foo", "\"foo\\u009Ffoo\\u009F\\u009Ffoo\""), + ("\u{9F}foo\u{9F}\u{9F}foo", "\"\\u009Ffoo\\u009F\\u009Ffoo\""), + ("foo\u{9F}foo\u{9F}\u{9F}", "\"foo\\u009Ffoo\\u009F\\u009F\""), + ("\u{9F}foo\u{9F}\u{9F}", "\"\\u009Ffoo\\u009F\\u009F\""), + ("foo\"foo\"\"foo", "\"foo\\\"foo\\\"\\\"foo\""), + ("\"foo\"\"foo", "\"\\\"foo\\\"\\\"foo\""), + ("foo\"foo\"\"", "\"foo\\\"foo\\\"\\\"\""), + ("\"foo\"\"", "\"\\\"foo\\\"\\\"\""), + ("foo\\foo\\\\foo", "\"foo\\\\foo\\\\\\\\foo\""), + ("\\foo\\\\foo", "\"\\\\foo\\\\\\\\foo\""), + ("foo\\foo\\\\", "\"foo\\\\foo\\\\\\\\\""), + ("\\foo\\\\", "\"\\\\foo\\\\\\\\\""), + ("foo\u{8}foo\u{8}\u{8}foo", "\"foo\\bfoo\\b\\bfoo\""), + ("\u{8}foo\u{8}\u{8}foo", "\"\\bfoo\\b\\bfoo\""), + ("foo\u{8}foo\u{8}\u{8}", "\"foo\\bfoo\\b\\b\""), + ("\u{8}foo\u{8}\u{8}", "\"\\bfoo\\b\\b\""), + ("foo\u{C}foo\u{C}\u{C}foo", "\"foo\\ffoo\\f\\ffoo\""), + ("\u{C}foo\u{C}\u{C}foo", "\"\\ffoo\\f\\ffoo\""), + ("foo\u{C}foo\u{C}\u{C}", "\"foo\\ffoo\\f\\f\""), + ("\u{C}foo\u{C}\u{C}", "\"\\ffoo\\f\\f\""), + ("foo\nfoo\n\nfoo", "\"foo\\nfoo\\n\\nfoo\""), + ("\nfoo\n\nfoo", "\"\\nfoo\\n\\nfoo\""), + ("foo\nfoo\n\n", "\"foo\\nfoo\\n\\n\""), + ("\nfoo\n\n", "\"\\nfoo\\n\\n\""), + ("foo\rfoo\r\rfoo", "\"foo\\rfoo\\r\\rfoo\""), + ("\rfoo\r\rfoo", "\"\\rfoo\\r\\rfoo\""), + ("foo\rfoo\r\r", "\"foo\\rfoo\\r\\r\""), + ("\rfoo\r\r", "\"\\rfoo\\r\\r\""), + ("foo\tfoo\t\tfoo", "\"foo\\tfoo\\t\\tfoo\""), + ("\tfoo\t\tfoo", "\"\\tfoo\\t\\tfoo\""), + ("foo\tfoo\t\t", "\"foo\\tfoo\\t\\t\""), + ("\tfoo\t\t", "\"\\tfoo\\t\\t\""), + ("foo\u{FFFF}foo\u{FFFF}\u{FFFF}foo", "\"foo\u{FFFF}foo\u{FFFF}\u{FFFF}foo\""), + ("\u{FFFF}foo\u{FFFF}\u{FFFF}foo", "\"\u{FFFF}foo\u{FFFF}\u{FFFF}foo\""), + ("foo\u{FFFF}foo\u{FFFF}\u{FFFF}", "\"foo\u{FFFF}foo\u{FFFF}\u{FFFF}\""), + ("\u{FFFF}foo\u{FFFF}\u{FFFF}", "\"\u{FFFF}foo\u{FFFF}\u{FFFF}\""), + ("foo\u{10FFFF}foo\u{10FFFF}\u{10FFFF}foo", "\"foo\u{10FFFF}foo\u{10FFFF}\u{10FFFF}foo\""), + ("\u{10FFFF}foo\u{10FFFF}\u{10FFFF}foo", "\"\u{10FFFF}foo\u{10FFFF}\u{10FFFF}foo\""), + ("foo\u{10FFFF}foo\u{10FFFF}\u{10FFFF}", "\"foo\u{10FFFF}foo\u{10FFFF}\u{10FFFF}\""), + ("\u{10FFFF}foo\u{10FFFF}\u{10FFFF}", "\"\u{10FFFF}foo\u{10FFFF}\u{10FFFF}\""), + + // patterns of special characters interleaved with a control character having a specific character replacement + ("\u{8}\u{0}\u{8}\u{0}\u{0}\u{8}", "\"\\b\\u0000\\b\\u0000\\u0000\\b\""), + ("\u{0}\u{8}\u{0}\u{0}\u{8}", "\"\\u0000\\b\\u0000\\u0000\\b\""), + ("\u{8}\u{0}\u{8}\u{0}\u{0}", "\"\\b\\u0000\\b\\u0000\\u0000\""), + ("\u{0}\u{8}\u{0}\u{0}", "\"\\u0000\\b\\u0000\\u0000\""), + ("\u{8}\u{1F}\u{8}\u{1F}\u{1F}\u{8}", "\"\\b\\u001F\\b\\u001F\\u001F\\b\""), + ("\u{1F}\u{8}\u{1F}\u{1F}\u{8}", "\"\\u001F\\b\\u001F\\u001F\\b\""), + ("\u{8}\u{1F}\u{8}\u{1F}\u{1F}", "\"\\b\\u001F\\b\\u001F\\u001F\""), + ("\u{1F}\u{8}\u{1F}\u{1F}", "\"\\u001F\\b\\u001F\\u001F\""), + ("\u{8}\u{7F}\u{8}\u{7F}\u{7F}\u{8}", "\"\\b\\u007F\\b\\u007F\\u007F\\b\""), + ("\u{7F}\u{8}\u{7F}\u{7F}\u{8}", "\"\\u007F\\b\\u007F\\u007F\\b\""), + ("\u{8}\u{7F}\u{8}\u{7F}\u{7F}", "\"\\b\\u007F\\b\\u007F\\u007F\""), + ("\u{7F}\u{8}\u{7F}\u{7F}", "\"\\u007F\\b\\u007F\\u007F\""), + ("\u{8}\u{80}\u{8}\u{80}\u{80}\u{8}", "\"\\b\\u0080\\b\\u0080\\u0080\\b\""), + ("\u{80}\u{8}\u{80}\u{80}\u{8}", "\"\\u0080\\b\\u0080\\u0080\\b\""), + ("\u{8}\u{80}\u{8}\u{80}\u{80}", "\"\\b\\u0080\\b\\u0080\\u0080\""), + ("\u{80}\u{8}\u{80}\u{80}", "\"\\u0080\\b\\u0080\\u0080\""), + ("\u{8}\u{9F}\u{8}\u{9F}\u{9F}\u{8}", "\"\\b\\u009F\\b\\u009F\\u009F\\b\""), + ("\u{9F}\u{8}\u{9F}\u{9F}\u{8}", "\"\\u009F\\b\\u009F\\u009F\\b\""), + ("\u{8}\u{9F}\u{8}\u{9F}\u{9F}", "\"\\b\\u009F\\b\\u009F\\u009F\""), + ("\u{9F}\u{8}\u{9F}\u{9F}", "\"\\u009F\\b\\u009F\\u009F\""), + ("\u{8}\"\u{8}\"\"\u{8}", "\"\\b\\\"\\b\\\"\\\"\\b\""), + ("\"\u{8}\"\"\u{8}", "\"\\\"\\b\\\"\\\"\\b\""), + ("\u{8}\"\u{8}\"\"", "\"\\b\\\"\\b\\\"\\\"\""), + ("\"\u{8}\"\"", "\"\\\"\\b\\\"\\\"\""), + ("\u{8}\\\u{8}\\\\\u{8}", "\"\\b\\\\\\b\\\\\\\\\\b\""), + ("\\\u{8}\\\\\u{8}", "\"\\\\\\b\\\\\\\\\\b\""), + ("\u{8}\\\u{8}\\\\", "\"\\b\\\\\\b\\\\\\\\\""), + ("\\\u{8}\\\\", "\"\\\\\\b\\\\\\\\\""), + ("\u{8}\u{8}\u{8}\u{8}\u{8}\u{8}", "\"\\b\\b\\b\\b\\b\\b\""), + ("\u{8}\u{8}\u{8}\u{8}\u{8}", "\"\\b\\b\\b\\b\\b\""), + ("\u{8}\u{8}\u{8}\u{8}\u{8}", "\"\\b\\b\\b\\b\\b\""), + ("\u{8}\u{8}\u{8}\u{8}", "\"\\b\\b\\b\\b\""), + ("\u{8}\u{C}\u{8}\u{C}\u{C}\u{8}", "\"\\b\\f\\b\\f\\f\\b\""), + ("\u{C}\u{8}\u{C}\u{C}\u{8}", "\"\\f\\b\\f\\f\\b\""), + ("\u{8}\u{C}\u{8}\u{C}\u{C}", "\"\\b\\f\\b\\f\\f\""), + ("\u{C}\u{8}\u{C}\u{C}", "\"\\f\\b\\f\\f\""), + ("\u{8}\n\u{8}\n\n\u{8}", "\"\\b\\n\\b\\n\\n\\b\""), + ("\n\u{8}\n\n\u{8}", "\"\\n\\b\\n\\n\\b\""), + ("\u{8}\n\u{8}\n\n", "\"\\b\\n\\b\\n\\n\""), + ("\n\u{8}\n\n", "\"\\n\\b\\n\\n\""), + ("\u{8}\r\u{8}\r\r\u{8}", "\"\\b\\r\\b\\r\\r\\b\""), + ("\r\u{8}\r\r\u{8}", "\"\\r\\b\\r\\r\\b\""), + ("\u{8}\r\u{8}\r\r", "\"\\b\\r\\b\\r\\r\""), + ("\r\u{8}\r\r", "\"\\r\\b\\r\\r\""), + ("\u{8}\t\u{8}\t\t\u{8}", "\"\\b\\t\\b\\t\\t\\b\""), + ("\t\u{8}\t\t\u{8}", "\"\\t\\b\\t\\t\\b\""), + ("\u{8}\t\u{8}\t\t", "\"\\b\\t\\b\\t\\t\""), + ("\t\u{8}\t\t", "\"\\t\\b\\t\\t\""), + ("\u{8}\u{FFFF}\u{8}\u{FFFF}\u{FFFF}\u{8}", "\"\\b\u{FFFF}\\b\u{FFFF}\u{FFFF}\\b\""), + ("\u{FFFF}\u{8}\u{FFFF}\u{FFFF}\u{8}", "\"\u{FFFF}\\b\u{FFFF}\u{FFFF}\\b\""), + ("\u{8}\u{FFFF}\u{8}\u{FFFF}\u{FFFF}", "\"\\b\u{FFFF}\\b\u{FFFF}\u{FFFF}\""), + ("\u{FFFF}\u{8}\u{FFFF}\u{FFFF}", "\"\u{FFFF}\\b\u{FFFF}\u{FFFF}\""), + ("\u{8}\u{10FFFF}\u{8}\u{10FFFF}\u{10FFFF}\u{8}", "\"\\b\u{10FFFF}\\b\u{10FFFF}\u{10FFFF}\\b\""), + ("\u{10FFFF}\u{8}\u{10FFFF}\u{10FFFF}\u{8}", "\"\u{10FFFF}\\b\u{10FFFF}\u{10FFFF}\\b\""), + ("\u{8}\u{10FFFF}\u{8}\u{10FFFF}\u{10FFFF}", "\"\\b\u{10FFFF}\\b\u{10FFFF}\u{10FFFF}\""), + ("\u{10FFFF}\u{8}\u{10FFFF}\u{10FFFF}", "\"\u{10FFFF}\\b\u{10FFFF}\u{10FFFF}\""), + + // patterns of special characters interleaved with a one unit code utf-8 control character + ("\u{7F}\u{0}\u{7F}\u{0}\u{0}\u{7F}", "\"\\u007F\\u0000\\u007F\\u0000\\u0000\\u007F\""), + ("\u{0}\u{7F}\u{0}\u{0}\u{7F}", "\"\\u0000\\u007F\\u0000\\u0000\\u007F\""), + ("\u{7F}\u{0}\u{7F}\u{0}\u{0}", "\"\\u007F\\u0000\\u007F\\u0000\\u0000\""), + ("\u{0}\u{7F}\u{0}\u{0}", "\"\\u0000\\u007F\\u0000\\u0000\""), + ("\u{7F}\u{1F}\u{7F}\u{1F}\u{1F}\u{7F}", "\"\\u007F\\u001F\\u007F\\u001F\\u001F\\u007F\""), + ("\u{1F}\u{7F}\u{1F}\u{1F}\u{7F}", "\"\\u001F\\u007F\\u001F\\u001F\\u007F\""), + ("\u{7F}\u{1F}\u{7F}\u{1F}\u{1F}", "\"\\u007F\\u001F\\u007F\\u001F\\u001F\""), + ("\u{1F}\u{7F}\u{1F}\u{1F}", "\"\\u001F\\u007F\\u001F\\u001F\""), + ("\u{7F}\u{7F}\u{7F}\u{7F}\u{7F}\u{7F}", "\"\\u007F\\u007F\\u007F\\u007F\\u007F\\u007F\""), + ("\u{7F}\u{7F}\u{7F}\u{7F}\u{7F}", "\"\\u007F\\u007F\\u007F\\u007F\\u007F\""), + ("\u{7F}\u{7F}\u{7F}\u{7F}\u{7F}", "\"\\u007F\\u007F\\u007F\\u007F\\u007F\""), + ("\u{7F}\u{7F}\u{7F}\u{7F}", "\"\\u007F\\u007F\\u007F\\u007F\""), + ("\u{7F}\u{80}\u{7F}\u{80}\u{80}\u{7F}", "\"\\u007F\\u0080\\u007F\\u0080\\u0080\\u007F\""), + ("\u{80}\u{7F}\u{80}\u{80}\u{7F}", "\"\\u0080\\u007F\\u0080\\u0080\\u007F\""), + ("\u{7F}\u{80}\u{7F}\u{80}\u{80}", "\"\\u007F\\u0080\\u007F\\u0080\\u0080\""), + ("\u{80}\u{7F}\u{80}\u{80}", "\"\\u0080\\u007F\\u0080\\u0080\""), + ("\u{7F}\u{9F}\u{7F}\u{9F}\u{9F}\u{7F}", "\"\\u007F\\u009F\\u007F\\u009F\\u009F\\u007F\""), + ("\u{9F}\u{7F}\u{9F}\u{9F}\u{7F}", "\"\\u009F\\u007F\\u009F\\u009F\\u007F\""), + ("\u{7F}\u{9F}\u{7F}\u{9F}\u{9F}", "\"\\u007F\\u009F\\u007F\\u009F\\u009F\""), + ("\u{9F}\u{7F}\u{9F}\u{9F}", "\"\\u009F\\u007F\\u009F\\u009F\""), + ("\u{7F}\"\u{7F}\"\"\u{7F}", "\"\\u007F\\\"\\u007F\\\"\\\"\\u007F\""), + ("\"\u{7F}\"\"\u{7F}", "\"\\\"\\u007F\\\"\\\"\\u007F\""), + ("\u{7F}\"\u{7F}\"\"", "\"\\u007F\\\"\\u007F\\\"\\\"\""), + ("\"\u{7F}\"\"", "\"\\\"\\u007F\\\"\\\"\""), + ("\u{7F}\\\u{7F}\\\\\u{7F}", "\"\\u007F\\\\\\u007F\\\\\\\\\\u007F\""), + ("\\\u{7F}\\\\\u{7F}", "\"\\\\\\u007F\\\\\\\\\\u007F\""), + ("\u{7F}\\\u{7F}\\\\", "\"\\u007F\\\\\\u007F\\\\\\\\\""), + ("\\\u{7F}\\\\", "\"\\\\\\u007F\\\\\\\\\""), + ("\u{7F}\u{8}\u{7F}\u{8}\u{8}\u{7F}", "\"\\u007F\\b\\u007F\\b\\b\\u007F\""), + ("\u{8}\u{7F}\u{8}\u{8}\u{7F}", "\"\\b\\u007F\\b\\b\\u007F\""), + ("\u{7F}\u{8}\u{7F}\u{8}\u{8}", "\"\\u007F\\b\\u007F\\b\\b\""), + ("\u{8}\u{7F}\u{8}\u{8}", "\"\\b\\u007F\\b\\b\""), + ("\u{7F}\u{C}\u{7F}\u{C}\u{C}\u{7F}", "\"\\u007F\\f\\u007F\\f\\f\\u007F\""), + ("\u{C}\u{7F}\u{C}\u{C}\u{7F}", "\"\\f\\u007F\\f\\f\\u007F\""), + ("\u{7F}\u{C}\u{7F}\u{C}\u{C}", "\"\\u007F\\f\\u007F\\f\\f\""), + ("\u{C}\u{7F}\u{C}\u{C}", "\"\\f\\u007F\\f\\f\""), + ("\u{7F}\n\u{7F}\n\n\u{7F}", "\"\\u007F\\n\\u007F\\n\\n\\u007F\""), + ("\n\u{7F}\n\n\u{7F}", "\"\\n\\u007F\\n\\n\\u007F\""), + ("\u{7F}\n\u{7F}\n\n", "\"\\u007F\\n\\u007F\\n\\n\""), + ("\n\u{7F}\n\n", "\"\\n\\u007F\\n\\n\""), + ("\u{7F}\r\u{7F}\r\r\u{7F}", "\"\\u007F\\r\\u007F\\r\\r\\u007F\""), + ("\r\u{7F}\r\r\u{7F}", "\"\\r\\u007F\\r\\r\\u007F\""), + ("\u{7F}\r\u{7F}\r\r", "\"\\u007F\\r\\u007F\\r\\r\""), + ("\r\u{7F}\r\r", "\"\\r\\u007F\\r\\r\""), + ("\u{7F}\t\u{7F}\t\t\u{7F}", "\"\\u007F\\t\\u007F\\t\\t\\u007F\""), + ("\t\u{7F}\t\t\u{7F}", "\"\\t\\u007F\\t\\t\\u007F\""), + ("\u{7F}\t\u{7F}\t\t", "\"\\u007F\\t\\u007F\\t\\t\""), + ("\t\u{7F}\t\t", "\"\\t\\u007F\\t\\t\""), + ("\u{7F}\u{FFFF}\u{7F}\u{FFFF}\u{FFFF}\u{7F}", "\"\\u007F\u{FFFF}\\u007F\u{FFFF}\u{FFFF}\\u007F\""), + ("\u{FFFF}\u{7F}\u{FFFF}\u{FFFF}\u{7F}", "\"\u{FFFF}\\u007F\u{FFFF}\u{FFFF}\\u007F\""), + ("\u{7F}\u{FFFF}\u{7F}\u{FFFF}\u{FFFF}", "\"\\u007F\u{FFFF}\\u007F\u{FFFF}\u{FFFF}\""), + ("\u{FFFF}\u{7F}\u{FFFF}\u{FFFF}", "\"\u{FFFF}\\u007F\u{FFFF}\u{FFFF}\""), + ("\u{7F}\u{10FFFF}\u{7F}\u{10FFFF}\u{10FFFF}\u{7F}", "\"\\u007F\u{10FFFF}\\u007F\u{10FFFF}\u{10FFFF}\\u007F\""), + ("\u{10FFFF}\u{7F}\u{10FFFF}\u{10FFFF}\u{7F}", "\"\u{10FFFF}\\u007F\u{10FFFF}\u{10FFFF}\\u007F\""), + ("\u{7F}\u{10FFFF}\u{7F}\u{10FFFF}\u{10FFFF}", "\"\\u007F\u{10FFFF}\\u007F\u{10FFFF}\u{10FFFF}\""), + ("\u{10FFFF}\u{7F}\u{10FFFF}\u{10FFFF}", "\"\u{10FFFF}\\u007F\u{10FFFF}\u{10FFFF}\""), + + // patterns of special characters interleaved with a two unit code utf-8 control character + ("\u{9F}\u{0}\u{9F}\u{0}\u{0}\u{9F}", "\"\\u009F\\u0000\\u009F\\u0000\\u0000\\u009F\""), + ("\u{0}\u{9F}\u{0}\u{0}\u{9F}", "\"\\u0000\\u009F\\u0000\\u0000\\u009F\""), + ("\u{9F}\u{0}\u{9F}\u{0}\u{0}", "\"\\u009F\\u0000\\u009F\\u0000\\u0000\""), + ("\u{0}\u{9F}\u{0}\u{0}", "\"\\u0000\\u009F\\u0000\\u0000\""), + ("\u{9F}\u{1F}\u{9F}\u{1F}\u{1F}\u{9F}", "\"\\u009F\\u001F\\u009F\\u001F\\u001F\\u009F\""), + ("\u{1F}\u{9F}\u{1F}\u{1F}\u{9F}", "\"\\u001F\\u009F\\u001F\\u001F\\u009F\""), + ("\u{9F}\u{1F}\u{9F}\u{1F}\u{1F}", "\"\\u009F\\u001F\\u009F\\u001F\\u001F\""), + ("\u{1F}\u{9F}\u{1F}\u{1F}", "\"\\u001F\\u009F\\u001F\\u001F\""), + ("\u{9F}\u{7F}\u{9F}\u{7F}\u{7F}\u{9F}", "\"\\u009F\\u007F\\u009F\\u007F\\u007F\\u009F\""), + ("\u{7F}\u{9F}\u{7F}\u{7F}\u{9F}", "\"\\u007F\\u009F\\u007F\\u007F\\u009F\""), + ("\u{9F}\u{7F}\u{9F}\u{7F}\u{7F}", "\"\\u009F\\u007F\\u009F\\u007F\\u007F\""), + ("\u{7F}\u{9F}\u{7F}\u{7F}", "\"\\u007F\\u009F\\u007F\\u007F\""), + ("\u{9F}\u{80}\u{9F}\u{80}\u{80}\u{9F}", "\"\\u009F\\u0080\\u009F\\u0080\\u0080\\u009F\""), + ("\u{80}\u{9F}\u{80}\u{80}\u{9F}", "\"\\u0080\\u009F\\u0080\\u0080\\u009F\""), + ("\u{9F}\u{80}\u{9F}\u{80}\u{80}", "\"\\u009F\\u0080\\u009F\\u0080\\u0080\""), + ("\u{80}\u{9F}\u{80}\u{80}", "\"\\u0080\\u009F\\u0080\\u0080\""), + ("\u{9F}\u{9F}\u{9F}\u{9F}\u{9F}\u{9F}", "\"\\u009F\\u009F\\u009F\\u009F\\u009F\\u009F\""), + ("\u{9F}\u{9F}\u{9F}\u{9F}\u{9F}", "\"\\u009F\\u009F\\u009F\\u009F\\u009F\""), + ("\u{9F}\u{9F}\u{9F}\u{9F}\u{9F}", "\"\\u009F\\u009F\\u009F\\u009F\\u009F\""), + ("\u{9F}\u{9F}\u{9F}\u{9F}", "\"\\u009F\\u009F\\u009F\\u009F\""), + ("\u{9F}\"\u{9F}\"\"\u{9F}", "\"\\u009F\\\"\\u009F\\\"\\\"\\u009F\""), + ("\"\u{9F}\"\"\u{9F}", "\"\\\"\\u009F\\\"\\\"\\u009F\""), + ("\u{9F}\"\u{9F}\"\"", "\"\\u009F\\\"\\u009F\\\"\\\"\""), + ("\"\u{9F}\"\"", "\"\\\"\\u009F\\\"\\\"\""), + ("\u{9F}\\\u{9F}\\\\\u{9F}", "\"\\u009F\\\\\\u009F\\\\\\\\\\u009F\""), + ("\\\u{9F}\\\\\u{9F}", "\"\\\\\\u009F\\\\\\\\\\u009F\""), + ("\u{9F}\\\u{9F}\\\\", "\"\\u009F\\\\\\u009F\\\\\\\\\""), + ("\\\u{9F}\\\\", "\"\\\\\\u009F\\\\\\\\\""), + ("\u{9F}\u{8}\u{9F}\u{8}\u{8}\u{9F}", "\"\\u009F\\b\\u009F\\b\\b\\u009F\""), + ("\u{8}\u{9F}\u{8}\u{8}\u{9F}", "\"\\b\\u009F\\b\\b\\u009F\""), + ("\u{9F}\u{8}\u{9F}\u{8}\u{8}", "\"\\u009F\\b\\u009F\\b\\b\""), + ("\u{8}\u{9F}\u{8}\u{8}", "\"\\b\\u009F\\b\\b\""), + ("\u{9F}\u{C}\u{9F}\u{C}\u{C}\u{9F}", "\"\\u009F\\f\\u009F\\f\\f\\u009F\""), + ("\u{C}\u{9F}\u{C}\u{C}\u{9F}", "\"\\f\\u009F\\f\\f\\u009F\""), + ("\u{9F}\u{C}\u{9F}\u{C}\u{C}", "\"\\u009F\\f\\u009F\\f\\f\""), + ("\u{C}\u{9F}\u{C}\u{C}", "\"\\f\\u009F\\f\\f\""), + ("\u{9F}\n\u{9F}\n\n\u{9F}", "\"\\u009F\\n\\u009F\\n\\n\\u009F\""), + ("\n\u{9F}\n\n\u{9F}", "\"\\n\\u009F\\n\\n\\u009F\""), + ("\u{9F}\n\u{9F}\n\n", "\"\\u009F\\n\\u009F\\n\\n\""), + ("\n\u{9F}\n\n", "\"\\n\\u009F\\n\\n\""), + ("\u{9F}\r\u{9F}\r\r\u{9F}", "\"\\u009F\\r\\u009F\\r\\r\\u009F\""), + ("\r\u{9F}\r\r\u{9F}", "\"\\r\\u009F\\r\\r\\u009F\""), + ("\u{9F}\r\u{9F}\r\r", "\"\\u009F\\r\\u009F\\r\\r\""), + ("\r\u{9F}\r\r", "\"\\r\\u009F\\r\\r\""), + ("\u{9F}\t\u{9F}\t\t\u{9F}", "\"\\u009F\\t\\u009F\\t\\t\\u009F\""), + ("\t\u{9F}\t\t\u{9F}", "\"\\t\\u009F\\t\\t\\u009F\""), + ("\u{9F}\t\u{9F}\t\t", "\"\\u009F\\t\\u009F\\t\\t\""), + ("\t\u{9F}\t\t", "\"\\t\\u009F\\t\\t\""), + ("\u{9F}\u{FFFF}\u{9F}\u{FFFF}\u{FFFF}\u{9F}", "\"\\u009F\u{FFFF}\\u009F\u{FFFF}\u{FFFF}\\u009F\""), + ("\u{FFFF}\u{9F}\u{FFFF}\u{FFFF}\u{9F}", "\"\u{FFFF}\\u009F\u{FFFF}\u{FFFF}\\u009F\""), + ("\u{9F}\u{FFFF}\u{9F}\u{FFFF}\u{FFFF}", "\"\\u009F\u{FFFF}\\u009F\u{FFFF}\u{FFFF}\""), + ("\u{FFFF}\u{9F}\u{FFFF}\u{FFFF}", "\"\u{FFFF}\\u009F\u{FFFF}\u{FFFF}\""), + ("\u{9F}\u{10FFFF}\u{9F}\u{10FFFF}\u{10FFFF}\u{9F}", "\"\\u009F\u{10FFFF}\\u009F\u{10FFFF}\u{10FFFF}\\u009F\""), + ("\u{10FFFF}\u{9F}\u{10FFFF}\u{10FFFF}\u{9F}", "\"\u{10FFFF}\\u009F\u{10FFFF}\u{10FFFF}\\u009F\""), + ("\u{9F}\u{10FFFF}\u{9F}\u{10FFFF}\u{10FFFF}", "\"\\u009F\u{10FFFF}\\u009F\u{10FFFF}\u{10FFFF}\""), + ("\u{10FFFF}\u{9F}\u{10FFFF}\u{10FFFF}", "\"\u{10FFFF}\\u009F\u{10FFFF}\u{10FFFF}\""), + + // patterns of special characters interleaved with the last BMP character + ("\u{FFFF}\u{0}\u{FFFF}\u{0}\u{0}\u{FFFF}", "\"\u{FFFF}\\u0000\u{FFFF}\\u0000\\u0000\u{FFFF}\""), + ("\u{0}\u{FFFF}\u{0}\u{0}\u{FFFF}", "\"\\u0000\u{FFFF}\\u0000\\u0000\u{FFFF}\""), + ("\u{FFFF}\u{0}\u{FFFF}\u{0}\u{0}", "\"\u{FFFF}\\u0000\u{FFFF}\\u0000\\u0000\""), + ("\u{0}\u{FFFF}\u{0}\u{0}", "\"\\u0000\u{FFFF}\\u0000\\u0000\""), + ("\u{FFFF}\u{1F}\u{FFFF}\u{1F}\u{1F}\u{FFFF}", "\"\u{FFFF}\\u001F\u{FFFF}\\u001F\\u001F\u{FFFF}\""), + ("\u{1F}\u{FFFF}\u{1F}\u{1F}\u{FFFF}", "\"\\u001F\u{FFFF}\\u001F\\u001F\u{FFFF}\""), + ("\u{FFFF}\u{1F}\u{FFFF}\u{1F}\u{1F}", "\"\u{FFFF}\\u001F\u{FFFF}\\u001F\\u001F\""), + ("\u{1F}\u{FFFF}\u{1F}\u{1F}", "\"\\u001F\u{FFFF}\\u001F\\u001F\""), + ("\u{FFFF}\u{7F}\u{FFFF}\u{7F}\u{7F}\u{FFFF}", "\"\u{FFFF}\\u007F\u{FFFF}\\u007F\\u007F\u{FFFF}\""), + ("\u{7F}\u{FFFF}\u{7F}\u{7F}\u{FFFF}", "\"\\u007F\u{FFFF}\\u007F\\u007F\u{FFFF}\""), + ("\u{FFFF}\u{7F}\u{FFFF}\u{7F}\u{7F}", "\"\u{FFFF}\\u007F\u{FFFF}\\u007F\\u007F\""), + ("\u{7F}\u{FFFF}\u{7F}\u{7F}", "\"\\u007F\u{FFFF}\\u007F\\u007F\""), + ("\u{FFFF}\u{80}\u{FFFF}\u{80}\u{80}\u{FFFF}", "\"\u{FFFF}\\u0080\u{FFFF}\\u0080\\u0080\u{FFFF}\""), + ("\u{80}\u{FFFF}\u{80}\u{80}\u{FFFF}", "\"\\u0080\u{FFFF}\\u0080\\u0080\u{FFFF}\""), + ("\u{FFFF}\u{80}\u{FFFF}\u{80}\u{80}", "\"\u{FFFF}\\u0080\u{FFFF}\\u0080\\u0080\""), + ("\u{80}\u{FFFF}\u{80}\u{80}", "\"\\u0080\u{FFFF}\\u0080\\u0080\""), + ("\u{FFFF}\u{9F}\u{FFFF}\u{9F}\u{9F}\u{FFFF}", "\"\u{FFFF}\\u009F\u{FFFF}\\u009F\\u009F\u{FFFF}\""), + ("\u{9F}\u{FFFF}\u{9F}\u{9F}\u{FFFF}", "\"\\u009F\u{FFFF}\\u009F\\u009F\u{FFFF}\""), + ("\u{FFFF}\u{9F}\u{FFFF}\u{9F}\u{9F}", "\"\u{FFFF}\\u009F\u{FFFF}\\u009F\\u009F\""), + ("\u{9F}\u{FFFF}\u{9F}\u{9F}", "\"\\u009F\u{FFFF}\\u009F\\u009F\""), + ("\u{FFFF}\"\u{FFFF}\"\"\u{FFFF}", "\"\u{FFFF}\\\"\u{FFFF}\\\"\\\"\u{FFFF}\""), + ("\"\u{FFFF}\"\"\u{FFFF}", "\"\\\"\u{FFFF}\\\"\\\"\u{FFFF}\""), + ("\u{FFFF}\"\u{FFFF}\"\"", "\"\u{FFFF}\\\"\u{FFFF}\\\"\\\"\""), + ("\"\u{FFFF}\"\"", "\"\\\"\u{FFFF}\\\"\\\"\""), + ("\u{FFFF}\\\u{FFFF}\\\\\u{FFFF}", "\"\u{FFFF}\\\\\u{FFFF}\\\\\\\\\u{FFFF}\""), + ("\\\u{FFFF}\\\\\u{FFFF}", "\"\\\\\u{FFFF}\\\\\\\\\u{FFFF}\""), + ("\u{FFFF}\\\u{FFFF}\\\\", "\"\u{FFFF}\\\\\u{FFFF}\\\\\\\\\""), + ("\\\u{FFFF}\\\\", "\"\\\\\u{FFFF}\\\\\\\\\""), + ("\u{FFFF}\u{8}\u{FFFF}\u{8}\u{8}\u{FFFF}", "\"\u{FFFF}\\b\u{FFFF}\\b\\b\u{FFFF}\""), + ("\u{8}\u{FFFF}\u{8}\u{8}\u{FFFF}", "\"\\b\u{FFFF}\\b\\b\u{FFFF}\""), + ("\u{FFFF}\u{8}\u{FFFF}\u{8}\u{8}", "\"\u{FFFF}\\b\u{FFFF}\\b\\b\""), + ("\u{8}\u{FFFF}\u{8}\u{8}", "\"\\b\u{FFFF}\\b\\b\""), + ("\u{FFFF}\u{C}\u{FFFF}\u{C}\u{C}\u{FFFF}", "\"\u{FFFF}\\f\u{FFFF}\\f\\f\u{FFFF}\""), + ("\u{C}\u{FFFF}\u{C}\u{C}\u{FFFF}", "\"\\f\u{FFFF}\\f\\f\u{FFFF}\""), + ("\u{FFFF}\u{C}\u{FFFF}\u{C}\u{C}", "\"\u{FFFF}\\f\u{FFFF}\\f\\f\""), + ("\u{C}\u{FFFF}\u{C}\u{C}", "\"\\f\u{FFFF}\\f\\f\""), + ("\u{FFFF}\n\u{FFFF}\n\n\u{FFFF}", "\"\u{FFFF}\\n\u{FFFF}\\n\\n\u{FFFF}\""), + ("\n\u{FFFF}\n\n\u{FFFF}", "\"\\n\u{FFFF}\\n\\n\u{FFFF}\""), + ("\u{FFFF}\n\u{FFFF}\n\n", "\"\u{FFFF}\\n\u{FFFF}\\n\\n\""), + ("\n\u{FFFF}\n\n", "\"\\n\u{FFFF}\\n\\n\""), + ("\u{FFFF}\r\u{FFFF}\r\r\u{FFFF}", "\"\u{FFFF}\\r\u{FFFF}\\r\\r\u{FFFF}\""), + ("\r\u{FFFF}\r\r\u{FFFF}", "\"\\r\u{FFFF}\\r\\r\u{FFFF}\""), + ("\u{FFFF}\r\u{FFFF}\r\r", "\"\u{FFFF}\\r\u{FFFF}\\r\\r\""), + ("\r\u{FFFF}\r\r", "\"\\r\u{FFFF}\\r\\r\""), + ("\u{FFFF}\t\u{FFFF}\t\t\u{FFFF}", "\"\u{FFFF}\\t\u{FFFF}\\t\\t\u{FFFF}\""), + ("\t\u{FFFF}\t\t\u{FFFF}", "\"\\t\u{FFFF}\\t\\t\u{FFFF}\""), + ("\u{FFFF}\t\u{FFFF}\t\t", "\"\u{FFFF}\\t\u{FFFF}\\t\\t\""), + ("\t\u{FFFF}\t\t", "\"\\t\u{FFFF}\\t\\t\""), + ("\u{FFFF}\u{FFFF}\u{FFFF}\u{FFFF}\u{FFFF}\u{FFFF}", "\"\u{FFFF}\u{FFFF}\u{FFFF}\u{FFFF}\u{FFFF}\u{FFFF}\""), + ("\u{FFFF}\u{FFFF}\u{FFFF}\u{FFFF}\u{FFFF}", "\"\u{FFFF}\u{FFFF}\u{FFFF}\u{FFFF}\u{FFFF}\""), + ("\u{FFFF}\u{FFFF}\u{FFFF}\u{FFFF}\u{FFFF}", "\"\u{FFFF}\u{FFFF}\u{FFFF}\u{FFFF}\u{FFFF}\""), + ("\u{FFFF}\u{FFFF}\u{FFFF}\u{FFFF}", "\"\u{FFFF}\u{FFFF}\u{FFFF}\u{FFFF}\""), + ("\u{FFFF}\u{10FFFF}\u{FFFF}\u{10FFFF}\u{10FFFF}\u{FFFF}", "\"\u{FFFF}\u{10FFFF}\u{FFFF}\u{10FFFF}\u{10FFFF}\u{FFFF}\""), + ("\u{10FFFF}\u{FFFF}\u{10FFFF}\u{10FFFF}\u{FFFF}", "\"\u{10FFFF}\u{FFFF}\u{10FFFF}\u{10FFFF}\u{FFFF}\""), + ("\u{FFFF}\u{10FFFF}\u{FFFF}\u{10FFFF}\u{10FFFF}", "\"\u{FFFF}\u{10FFFF}\u{FFFF}\u{10FFFF}\u{10FFFF}\""), + ("\u{10FFFF}\u{FFFF}\u{10FFFF}\u{10FFFF}", "\"\u{10FFFF}\u{FFFF}\u{10FFFF}\u{10FFFF}\""), + + // patterns of special characters interleaved with the last Unicode character (non-BMP) + ("\u{10FFFF}\u{0}\u{10FFFF}\u{0}\u{0}\u{10FFFF}", "\"\u{10FFFF}\\u0000\u{10FFFF}\\u0000\\u0000\u{10FFFF}\""), + ("\u{0}\u{10FFFF}\u{0}\u{0}\u{10FFFF}", "\"\\u0000\u{10FFFF}\\u0000\\u0000\u{10FFFF}\""), + ("\u{10FFFF}\u{0}\u{10FFFF}\u{0}\u{0}", "\"\u{10FFFF}\\u0000\u{10FFFF}\\u0000\\u0000\""), + ("\u{0}\u{10FFFF}\u{0}\u{0}", "\"\\u0000\u{10FFFF}\\u0000\\u0000\""), + ("\u{10FFFF}\u{1F}\u{10FFFF}\u{1F}\u{1F}\u{10FFFF}", "\"\u{10FFFF}\\u001F\u{10FFFF}\\u001F\\u001F\u{10FFFF}\""), + ("\u{1F}\u{10FFFF}\u{1F}\u{1F}\u{10FFFF}", "\"\\u001F\u{10FFFF}\\u001F\\u001F\u{10FFFF}\""), + ("\u{10FFFF}\u{1F}\u{10FFFF}\u{1F}\u{1F}", "\"\u{10FFFF}\\u001F\u{10FFFF}\\u001F\\u001F\""), + ("\u{1F}\u{10FFFF}\u{1F}\u{1F}", "\"\\u001F\u{10FFFF}\\u001F\\u001F\""), + ("\u{10FFFF}\u{7F}\u{10FFFF}\u{7F}\u{7F}\u{10FFFF}", "\"\u{10FFFF}\\u007F\u{10FFFF}\\u007F\\u007F\u{10FFFF}\""), + ("\u{7F}\u{10FFFF}\u{7F}\u{7F}\u{10FFFF}", "\"\\u007F\u{10FFFF}\\u007F\\u007F\u{10FFFF}\""), + ("\u{10FFFF}\u{7F}\u{10FFFF}\u{7F}\u{7F}", "\"\u{10FFFF}\\u007F\u{10FFFF}\\u007F\\u007F\""), + ("\u{7F}\u{10FFFF}\u{7F}\u{7F}", "\"\\u007F\u{10FFFF}\\u007F\\u007F\""), + ("\u{10FFFF}\u{80}\u{10FFFF}\u{80}\u{80}\u{10FFFF}", "\"\u{10FFFF}\\u0080\u{10FFFF}\\u0080\\u0080\u{10FFFF}\""), + ("\u{80}\u{10FFFF}\u{80}\u{80}\u{10FFFF}", "\"\\u0080\u{10FFFF}\\u0080\\u0080\u{10FFFF}\""), + ("\u{10FFFF}\u{80}\u{10FFFF}\u{80}\u{80}", "\"\u{10FFFF}\\u0080\u{10FFFF}\\u0080\\u0080\""), + ("\u{80}\u{10FFFF}\u{80}\u{80}", "\"\\u0080\u{10FFFF}\\u0080\\u0080\""), + ("\u{10FFFF}\u{9F}\u{10FFFF}\u{9F}\u{9F}\u{10FFFF}", "\"\u{10FFFF}\\u009F\u{10FFFF}\\u009F\\u009F\u{10FFFF}\""), + ("\u{9F}\u{10FFFF}\u{9F}\u{9F}\u{10FFFF}", "\"\\u009F\u{10FFFF}\\u009F\\u009F\u{10FFFF}\""), + ("\u{10FFFF}\u{9F}\u{10FFFF}\u{9F}\u{9F}", "\"\u{10FFFF}\\u009F\u{10FFFF}\\u009F\\u009F\""), + ("\u{9F}\u{10FFFF}\u{9F}\u{9F}", "\"\\u009F\u{10FFFF}\\u009F\\u009F\""), + ("\u{10FFFF}\"\u{10FFFF}\"\"\u{10FFFF}", "\"\u{10FFFF}\\\"\u{10FFFF}\\\"\\\"\u{10FFFF}\""), + ("\"\u{10FFFF}\"\"\u{10FFFF}", "\"\\\"\u{10FFFF}\\\"\\\"\u{10FFFF}\""), + ("\u{10FFFF}\"\u{10FFFF}\"\"", "\"\u{10FFFF}\\\"\u{10FFFF}\\\"\\\"\""), + ("\"\u{10FFFF}\"\"", "\"\\\"\u{10FFFF}\\\"\\\"\""), + ("\u{10FFFF}\\\u{10FFFF}\\\\\u{10FFFF}", "\"\u{10FFFF}\\\\\u{10FFFF}\\\\\\\\\u{10FFFF}\""), + ("\\\u{10FFFF}\\\\\u{10FFFF}", "\"\\\\\u{10FFFF}\\\\\\\\\u{10FFFF}\""), + ("\u{10FFFF}\\\u{10FFFF}\\\\", "\"\u{10FFFF}\\\\\u{10FFFF}\\\\\\\\\""), + ("\\\u{10FFFF}\\\\", "\"\\\\\u{10FFFF}\\\\\\\\\""), + ("\u{10FFFF}\u{8}\u{10FFFF}\u{8}\u{8}\u{10FFFF}", "\"\u{10FFFF}\\b\u{10FFFF}\\b\\b\u{10FFFF}\""), + ("\u{8}\u{10FFFF}\u{8}\u{8}\u{10FFFF}", "\"\\b\u{10FFFF}\\b\\b\u{10FFFF}\""), + ("\u{10FFFF}\u{8}\u{10FFFF}\u{8}\u{8}", "\"\u{10FFFF}\\b\u{10FFFF}\\b\\b\""), + ("\u{8}\u{10FFFF}\u{8}\u{8}", "\"\\b\u{10FFFF}\\b\\b\""), + ("\u{10FFFF}\u{C}\u{10FFFF}\u{C}\u{C}\u{10FFFF}", "\"\u{10FFFF}\\f\u{10FFFF}\\f\\f\u{10FFFF}\""), + ("\u{C}\u{10FFFF}\u{C}\u{C}\u{10FFFF}", "\"\\f\u{10FFFF}\\f\\f\u{10FFFF}\""), + ("\u{10FFFF}\u{C}\u{10FFFF}\u{C}\u{C}", "\"\u{10FFFF}\\f\u{10FFFF}\\f\\f\""), + ("\u{C}\u{10FFFF}\u{C}\u{C}", "\"\\f\u{10FFFF}\\f\\f\""), + ("\u{10FFFF}\n\u{10FFFF}\n\n\u{10FFFF}", "\"\u{10FFFF}\\n\u{10FFFF}\\n\\n\u{10FFFF}\""), + ("\n\u{10FFFF}\n\n\u{10FFFF}", "\"\\n\u{10FFFF}\\n\\n\u{10FFFF}\""), + ("\u{10FFFF}\n\u{10FFFF}\n\n", "\"\u{10FFFF}\\n\u{10FFFF}\\n\\n\""), + ("\n\u{10FFFF}\n\n", "\"\\n\u{10FFFF}\\n\\n\""), + ("\u{10FFFF}\r\u{10FFFF}\r\r\u{10FFFF}", "\"\u{10FFFF}\\r\u{10FFFF}\\r\\r\u{10FFFF}\""), + ("\r\u{10FFFF}\r\r\u{10FFFF}", "\"\\r\u{10FFFF}\\r\\r\u{10FFFF}\""), + ("\u{10FFFF}\r\u{10FFFF}\r\r", "\"\u{10FFFF}\\r\u{10FFFF}\\r\\r\""), + ("\r\u{10FFFF}\r\r", "\"\\r\u{10FFFF}\\r\\r\""), + ("\u{10FFFF}\t\u{10FFFF}\t\t\u{10FFFF}", "\"\u{10FFFF}\\t\u{10FFFF}\\t\\t\u{10FFFF}\""), + ("\t\u{10FFFF}\t\t\u{10FFFF}", "\"\\t\u{10FFFF}\\t\\t\u{10FFFF}\""), + ("\u{10FFFF}\t\u{10FFFF}\t\t", "\"\u{10FFFF}\\t\u{10FFFF}\\t\\t\""), + ("\t\u{10FFFF}\t\t", "\"\\t\u{10FFFF}\\t\\t\""), + ("\u{10FFFF}\u{FFFF}\u{10FFFF}\u{FFFF}\u{FFFF}\u{10FFFF}", "\"\u{10FFFF}\u{FFFF}\u{10FFFF}\u{FFFF}\u{FFFF}\u{10FFFF}\""), + ("\u{FFFF}\u{10FFFF}\u{FFFF}\u{FFFF}\u{10FFFF}", "\"\u{FFFF}\u{10FFFF}\u{FFFF}\u{FFFF}\u{10FFFF}\""), + ("\u{10FFFF}\u{FFFF}\u{10FFFF}\u{FFFF}\u{FFFF}", "\"\u{10FFFF}\u{FFFF}\u{10FFFF}\u{FFFF}\u{FFFF}\""), + ("\u{FFFF}\u{10FFFF}\u{FFFF}\u{FFFF}", "\"\u{FFFF}\u{10FFFF}\u{FFFF}\u{FFFF}\""), + ("\u{10FFFF}\u{10FFFF}\u{10FFFF}\u{10FFFF}\u{10FFFF}\u{10FFFF}", "\"\u{10FFFF}\u{10FFFF}\u{10FFFF}\u{10FFFF}\u{10FFFF}\u{10FFFF}\""), + ("\u{10FFFF}\u{10FFFF}\u{10FFFF}\u{10FFFF}\u{10FFFF}", "\"\u{10FFFF}\u{10FFFF}\u{10FFFF}\u{10FFFF}\u{10FFFF}\""), + ("\u{10FFFF}\u{10FFFF}\u{10FFFF}\u{10FFFF}\u{10FFFF}", "\"\u{10FFFF}\u{10FFFF}\u{10FFFF}\u{10FFFF}\u{10FFFF}\""), + ("\u{10FFFF}\u{10FFFF}\u{10FFFF}\u{10FFFF}", "\"\u{10FFFF}\u{10FFFF}\u{10FFFF}\u{10FFFF}\""), ]; test_encode_ok(tests); test_pretty_encode_ok(tests); From 632a55599eb59be10b47d24939311551120007d4 Mon Sep 17 00:00:00 2001 From: Paul Grandperrin Date: Sun, 1 May 2016 14:49:17 +0200 Subject: [PATCH 10/10] Minor coding style fix in ser::escape_str() --- json/src/ser.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/json/src/ser.rs b/json/src/ser.rs index 7563edcb6..54b1d746d 100644 --- a/json/src/ser.rs +++ b/json/src/ser.rs @@ -578,7 +578,7 @@ pub fn escape_str(wr: &mut W, value: &str) -> Result<()> start = i + char.len_utf8(); continue; }, - _ => { continue; } + _ => continue }; if start < i {