Skip to content

Commit 53814a2

Browse files
committed
Use String::from_utf8_unchecked for encode_basestring
1 parent 2e3d766 commit 53814a2

File tree

2 files changed

+14
-14
lines changed

2 files changed

+14
-14
lines changed

vm/src/stdlib/json.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -225,10 +225,10 @@ mod _json {
225225
fn encode_string(s: &str, ascii_only: bool) -> String {
226226
let mut buf = Vec::<u8>::with_capacity(s.len() + 2);
227227
super::machinery::write_json_string(s, ascii_only, &mut buf)
228-
// writing to a vec can't fail
228+
// SAFETY: writing to a vec can't fail
229229
.unwrap_or_else(|_| unsafe { std::hint::unreachable_unchecked() });
230-
// TODO: verify that the implementation is correct enough to use `from_utf8_unchecked`
231-
String::from_utf8(buf).expect("invalid utf-8 in json output")
230+
// SAFETY: we only output valid utf8 from write_json_string
231+
unsafe { String::from_utf8_unchecked(buf) }
232232
}
233233

234234
#[pyfunction]

vm/src/stdlib/json/machinery.rs

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -28,11 +28,11 @@
2828

2929
use std::io;
3030

31-
static ESCAPE_CHARS: [&[u8]; 0x20] = [
32-
b"\\u0000", b"\\u0001", b"\\u0002", b"\\u0003", b"\\u0004", b"\\u0005", b"\\u0006", b"\\u0007",
33-
b"\\b", b"\\t", b"\\n", b"\\u000b", b"\\f", b"\\r", b"\\u000e", b"\\u000f", b"\\u0010",
34-
b"\\u0011", b"\\u0012", b"\\u0013", b"\\u0014", b"\\u0015", b"\\u0016", b"\\u0017", b"\\u0018",
35-
b"\\u0019", b"\\u001a", b"\\u001b", b"\\u001c", b"\\u001d", b"\\u001e", b"\\u001f",
31+
static ESCAPE_CHARS: [&str; 0x20] = [
32+
"\\u0000", "\\u0001", "\\u0002", "\\u0003", "\\u0004", "\\u0005", "\\u0006", "\\u0007", "\\b",
33+
"\\t", "\\n", "\\u000", "\\f", "\\r", "\\u000e", "\\u000f", "\\u0010", "\\u0011", "\\u0012",
34+
"\\u0013", "\\u0014", "\\u0015", "\\u0016", "\\u0017", "\\u0018", "\\u0019", "\\u001a",
35+
"\\u001", "\\u001c", "\\u001d", "\\u001e", "\\u001f",
3636
];
3737

3838
// This bitset represents which bytes can be copied as-is to a JSON string (0)
@@ -48,16 +48,16 @@ static NEEDS_ESCAPING_BITSET: [u64; 4] = [
4848
];
4949

5050
#[inline(always)]
51-
fn json_escaped_char(c: u8) -> Option<&'static [u8]> {
51+
fn json_escaped_char(c: u8) -> Option<&'static str> {
5252
let bitset_value = NEEDS_ESCAPING_BITSET[(c / 64) as usize] & (1 << (c % 64));
5353
if bitset_value == 0 {
5454
None
5555
} else {
5656
Some(match c {
5757
x if x < 0x20 => ESCAPE_CHARS[c as usize],
58-
b'\\' => &b"\\\\"[..],
59-
b'\"' => &b"\\\""[..],
60-
0x7F => &b"\\u007f"[..],
58+
b'\\' => "\\\\",
59+
b'\"' => "\\\"",
60+
0x7F => "\\u007f",
6161
_ => unreachable!(),
6262
})
6363
}
@@ -72,7 +72,7 @@ pub fn write_json_string<W: io::Write>(s: &str, ascii_only: bool, w: &mut W) ->
7272
if c.is_ascii() {
7373
if let Some(escaped) = json_escaped_char(c as u8) {
7474
w.write_all(&bytes[write_start_idx..idx])?;
75-
w.write_all(escaped)?;
75+
w.write_all(escaped.as_bytes())?;
7676
write_start_idx = idx + 1;
7777
}
7878
} else {
@@ -88,7 +88,7 @@ pub fn write_json_string<W: io::Write>(s: &str, ascii_only: bool, w: &mut W) ->
8888
for (idx, c) in s.bytes().enumerate() {
8989
if let Some(escaped) = json_escaped_char(c) {
9090
w.write_all(&bytes[write_start_idx..idx])?;
91-
w.write_all(escaped)?;
91+
w.write_all(escaped.as_bytes())?;
9292
write_start_idx = idx + 1;
9393
}
9494
}

0 commit comments

Comments
 (0)