mirror of
https://github.com/vlang/v.git
synced 2025-09-13 14:32:26 +03:00
x.json2: fix "\\" scanner bug, disallow (ch < 0x20) unescaped control characters (#23954)
This commit is contained in:
parent
b2ff9d5d08
commit
21874f93dc
3 changed files with 26 additions and 8 deletions
|
@ -127,14 +127,18 @@ fn (mut s Scanner) text_scan() Token {
|
|||
break
|
||||
}
|
||||
ch := s.text[s.pos]
|
||||
if (s.pos - 1 >= 0 && s.text[s.pos - 1] != `\\`) && ch == `"` {
|
||||
if ch == `"` {
|
||||
has_closed = true
|
||||
break
|
||||
} else if (s.pos - 1 >= 0 && s.text[s.pos - 1] != `\\`) && ch in important_escapable_chars {
|
||||
return s.error('character must be escaped with a backslash')
|
||||
} else if (s.pos == s.text.len - 1 && ch == `\\`) || ch == u8(0) {
|
||||
return s.error('invalid backslash escape')
|
||||
} else if s.pos + 1 < s.text.len && ch == `\\` {
|
||||
} else if ch in important_escapable_chars {
|
||||
return s.error('character must be escaped with a backslash, replace with: \\${valid_unicode_escapes[important_escapable_chars.index(ch)]}')
|
||||
} else if ch < 0x20 {
|
||||
return s.error('character must be escaped with a unicode escape, replace with: \\u${ch:04x}')
|
||||
} else if ch == `\\` {
|
||||
if s.pos == s.text.len - 1 {
|
||||
return s.error('incomplete backslash escape at end of JSON input')
|
||||
}
|
||||
|
||||
peek := s.text[s.pos + 1]
|
||||
if peek in valid_unicode_escapes {
|
||||
chrs << unicode_transform_escapes[int(peek)]
|
||||
|
|
|
@ -46,7 +46,21 @@ fn test_str_invalid_must_be_escape() {
|
|||
}
|
||||
tok := sc.scan()
|
||||
assert tok.kind == .error
|
||||
assert tok.lit.bytestr() == 'character must be escaped with a backslash'
|
||||
assert tok.lit.bytestr() == 'character must be escaped with a backslash, replace with: \\${valid_unicode_escapes[important_escapable_chars.index(ch)]}'
|
||||
}
|
||||
}
|
||||
|
||||
fn test_str_control_must_be_escape() {
|
||||
for ch := u8(0); ch < 0x20; ch++ {
|
||||
if ch in important_escapable_chars {
|
||||
continue
|
||||
}
|
||||
mut sc := Scanner{
|
||||
text: [u8(`"`), `t`, ch, `"`]
|
||||
}
|
||||
tok := sc.scan()
|
||||
assert tok.kind == .error
|
||||
assert tok.lit.bytestr() == 'character must be escaped with a unicode escape, replace with: \\u${ch:04x}'
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -6,7 +6,7 @@ fn test_raw_decode_string() {
|
|||
}
|
||||
|
||||
fn test_raw_decode_string_escape() {
|
||||
jstr := json.raw_decode('"\u001b"')!
|
||||
jstr := json.raw_decode('"\\u001b"')!
|
||||
str := jstr.str()
|
||||
assert str.len == 1
|
||||
assert str[0] == 27
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue