1
0
mirror of https://github.com/vlang/v.git synced 2023-08-10 21:13:21 +03:00

compiler: add EOF checks in scanner to prevent panic exits

swap s.text[s.pos + 1] to nextc
This commit is contained in:
Henrixounez 2019-06-27 17:05:02 +02:00 committed by Alexander Medvednikov
parent 56608dfd2b
commit 748c45203d

View File

@ -67,6 +67,9 @@ fn (s mut Scanner) ident_name() string {
start := s.pos start := s.pos
for { for {
s.pos++ s.pos++
if s.pos >= s.text.len {
break
}
c := s.text[s.pos] c := s.text[s.pos]
if !is_name_char(c) && !c.is_digit() { if !is_name_char(c) && !c.is_digit() {
break break
@ -79,18 +82,21 @@ fn (s mut Scanner) ident_name() string {
fn (s mut Scanner) ident_number() string { fn (s mut Scanner) ident_number() string {
start := s.pos start := s.pos
is_hex := s.text[s.pos] == `0` && s.text[s.pos + 1] == `x` is_hex := s.pos + 1 < s.text.len && s.text[s.pos] == `0` && s.text[s.pos + 1] == `x`
is_oct := !is_hex && s.text[s.pos] == `0` is_oct := !is_hex && s.text[s.pos] == `0`
mut is_float := false mut is_float := false
for { for {
s.pos++ s.pos++
if s.pos >= s.text.len {
break
}
c := s.text[s.pos] c := s.text[s.pos]
if c == `.` { if c == `.` {
is_float = true is_float = true
} }
is_good_hex := is_hex && (c == `x` || (c >= `a` && c <= `f`)) is_good_hex := is_hex && (c == `x` || (c >= `a` && c <= `f`))
// 1e+3, 1e-3, 1e3 // 1e+3, 1e-3, 1e3
if !is_hex && c == `e` { if !is_hex && c == `e` && s.pos + 1 < s.text.len {
next := s.text[s.pos + 1] next := s.text[s.pos + 1]
if next == `+` || next == `-` || next.is_digit() { if next == `+` || next == `-` || next.is_digit() {
s.pos++ s.pos++
@ -101,7 +107,7 @@ fn (s mut Scanner) ident_number() string {
break break
} }
// 1..9 // 1..9
if c == `.` && s.text[s.pos + 1] == `.` { if c == `.` && s.pos + 1 < s.text.len && s.text[s.pos + 1] == `.` {
break break
} }
if is_oct && c >= `8` && !is_float { if is_oct && c >= `8` && !is_float {
@ -189,7 +195,9 @@ fn (s mut Scanner) scan() ScanRes {
// name or keyword // name or keyword
if is_name_char(c) { if is_name_char(c) {
name := s.ident_name() name := s.ident_name()
next_char := s.text[s.pos + 1]// tmp hack to detect . in ${} // tmp hack to detect . in ${}
// Check if not EOF to prevent panic
next_char := if s.pos + 1 < s.text.len { s.text[s.pos + 1] } else { `\0` }
// println('!!! got name=$name next_char=$next_char') // println('!!! got name=$name next_char=$next_char')
if is_key(name) { if is_key(name) {
// println('IS KEY') // println('IS KEY')
@ -201,7 +209,7 @@ fn (s mut Scanner) scan() ScanRes {
// at the next ', skip it // at the next ', skip it
if s.inside_string { if s.inside_string {
// println('is_letter inside string! nextc=${nextc.str()}') // println('is_letter inside string! nextc=${nextc.str()}')
if s.text[s.pos + 1] == SINGLE_QUOTE { if next_char == SINGLE_QUOTE {
// println('var is last before QUOTE') // println('var is last before QUOTE')
s.pos++ s.pos++
s.dollar_start = false s.dollar_start = false
@ -316,13 +324,13 @@ fn (s mut Scanner) scan() ScanRes {
s.cao_change('&') s.cao_change('&')
return scan_res(AND_ASSIGN, '') return scan_res(AND_ASSIGN, '')
} }
if s.text[s.pos + 1] == `&` { if nextc == `&` {
s.pos++ s.pos++
return scan_res(AND, '') return scan_res(AND, '')
} }
return scan_res(AMP, '') return scan_res(AMP, '')
case `|`: case `|`:
if s.text[s.pos + 1] == `|` { if nextc == `|` {
s.pos++ s.pos++
return scan_res(OR, '') return scan_res(OR, '')
} }
@ -342,14 +350,14 @@ fn (s mut Scanner) scan() ScanRes {
case `\n`: case `\n`:
return scan_res(NL, '') return scan_res(NL, '')
case `.`: case `.`:
if s.text[s.pos + 1] == `.` { if nextc == `.` {
s.pos++ s.pos++
return scan_res(DOTDOT, '') return scan_res(DOTDOT, '')
} }
return scan_res(DOT, '') return scan_res(DOT, '')
case `#`: case `#`:
start := s.pos + 1 start := s.pos + 1
for s.text[s.pos] != `\n` { for s.pos < s.text.len && s.text[s.pos] != `\n` {
s.pos++ s.pos++
} }
s.line_nr++ s.line_nr++
@ -360,12 +368,12 @@ fn (s mut Scanner) scan() ScanRes {
} }
return scan_res(HASH, hash.trim_space()) return scan_res(HASH, hash.trim_space())
case `>`: case `>`:
if s.text[s.pos + 1] == `=` { if nextc == `=` {
s.pos++ s.pos++
return scan_res(GE, '') return scan_res(GE, '')
} }
else if s.text[s.pos + 1] == `>` { else if nextc == `>` {
if s.text[s.pos + 2] == `=` { if s.pos + 2 < s.text.len && s.text[s.pos + 2] == `=` {
s.pos += 2 s.pos += 2
s.cao_change('>>') s.cao_change('>>')
return scan_res(RIGHT_SHIFT_ASSIGN, '') return scan_res(RIGHT_SHIFT_ASSIGN, '')
@ -377,12 +385,12 @@ fn (s mut Scanner) scan() ScanRes {
return scan_res(GT, '') return scan_res(GT, '')
} }
case `<`: case `<`:
if s.text[s.pos + 1] == `=` { if nextc == `=` {
s.pos++ s.pos++
return scan_res(LE, '') return scan_res(LE, '')
} }
else if s.text[s.pos + 1] == `<` { else if nextc == `<` {
if s.text[s.pos + 2] == `=` { if s.pos + 2 < s.text.len && s.text[s.pos + 2] == `=` {
s.pos += 2 s.pos += 2
s.cao_change('<<') s.cao_change('<<')
return scan_res(LEFT_SHIFT_ASSIGN, '') return scan_res(LEFT_SHIFT_ASSIGN, '')
@ -394,7 +402,7 @@ fn (s mut Scanner) scan() ScanRes {
return scan_res(LT, '') return scan_res(LT, '')
} }
case `=`: case `=`:
if s.text[s.pos + 1] == `=` { if nextc == `=` {
s.pos++ s.pos++
return scan_res(EQ, '') return scan_res(EQ, '')
} }
@ -402,7 +410,7 @@ fn (s mut Scanner) scan() ScanRes {
return scan_res(ASSIGN, '') return scan_res(ASSIGN, '')
} }
case `:`: case `:`:
if s.text[s.pos + 1] == `=` { if nextc == `=` {
s.pos++ s.pos++
return scan_res(DECL_ASSIGN, '') return scan_res(DECL_ASSIGN, '')
} }
@ -412,7 +420,7 @@ fn (s mut Scanner) scan() ScanRes {
case `;`: case `;`:
return scan_res(SEMICOLON, '') return scan_res(SEMICOLON, '')
case `!`: case `!`:
if s.text[s.pos + 1] == `=` { if nextc == `=` {
s.pos++ s.pos++
return scan_res(NE, '') return scan_res(NE, '')
} }
@ -427,10 +435,10 @@ fn (s mut Scanner) scan() ScanRes {
s.cao_change('/') s.cao_change('/')
return scan_res(DIV_ASSIGN, '') return scan_res(DIV_ASSIGN, '')
} }
if s.text[s.pos + 1] == `/` { if nextc == `/` {
// debug("!!!!!!GOT LINE COM") // debug("!!!!!!GOT LINE COM")
start := s.pos + 1 start := s.pos + 1
for s.text[s.pos] != `\n` { for s.pos < s.text.len && s.text[s.pos] != `\n`{
s.pos++ s.pos++
} }
s.line_nr++ s.line_nr++
@ -448,7 +456,7 @@ fn (s mut Scanner) scan() ScanRes {
return scan_res(LINE_COM, s.line_comment) return scan_res(LINE_COM, s.line_comment)
} }
// Multiline comments // Multiline comments
if s.text[s.pos + 1] == `*` { if nextc == `*` {
start := s.pos start := s.pos
// Skip comment // Skip comment
for ! (s.text[s.pos] == `*` && s.text[s.pos + 1] == `/`) { for ! (s.text[s.pos] == `*` && s.text[s.pos + 1] == `/`) {