mirror of
https://github.com/vlang/v.git
synced 2025-08-03 09:47:15 -04:00
strconv: fix strconv.atof64() inconsistency with the other .ato functions; make it return an error by default, when it detects an extra non number character after a number (#23815)
This commit is contained in:
parent
62cbc8befe
commit
675fe14cbb
@ -636,13 +636,13 @@ pub fn (s string) i64() i64 {
|
||||
// f32 returns the value of the string as f32 `'1.0'.f32() == f32(1)`.
|
||||
@[inline]
|
||||
pub fn (s string) f32() f32 {
|
||||
return f32(strconv.atof64(s) or { 0 })
|
||||
return f32(strconv.atof64(s, allow_extra_chars: true) or { 0 })
|
||||
}
|
||||
|
||||
// f64 returns the value of the string as f64 `'1.0'.f64() == f64(1)`.
|
||||
@[inline]
|
||||
pub fn (s string) f64() f64 {
|
||||
return strconv.atof64(s) or { 0 }
|
||||
return strconv.atof64(s, allow_extra_chars: true) or { 0 }
|
||||
}
|
||||
|
||||
// u8_array returns the value of the hex/bin string as u8 array.
|
||||
|
@ -114,6 +114,7 @@ enum ParserState {
|
||||
pinf // number is higher than +HUGE_VAL
|
||||
minf // number is lower than -HUGE_VAL
|
||||
invalid_number // invalid number, used for '#@%^' for example
|
||||
extra_char // extra char after number
|
||||
}
|
||||
|
||||
// parser tries to parse the given string into a number
|
||||
@ -218,6 +219,9 @@ fn parser(s string) (ParserState, PrepNumber) {
|
||||
if i == 0 && s.len > 0 {
|
||||
return ParserState.invalid_number, pn
|
||||
}
|
||||
if i != s.len {
|
||||
return ParserState.extra_char, pn
|
||||
}
|
||||
return result, pn
|
||||
}
|
||||
|
||||
@ -387,13 +391,19 @@ fn converter(mut pn PrepNumber) u64 {
|
||||
return result
|
||||
}
|
||||
|
||||
@[params]
|
||||
pub struct AtoF64Param {
|
||||
pub:
|
||||
allow_extra_chars bool // allow extra characters after number
|
||||
}
|
||||
|
||||
// atof64 parses the string `s`, and if possible, converts it into a f64 number
|
||||
pub fn atof64(s string) !f64 {
|
||||
pub fn atof64(s string, param AtoF64Param) !f64 {
|
||||
if s.len == 0 {
|
||||
return error('expected a number found an empty string')
|
||||
}
|
||||
mut res := Float64u{}
|
||||
mut res_parsing, mut pn := parser(s)
|
||||
res_parsing, mut pn := parser(s)
|
||||
match res_parsing {
|
||||
.ok {
|
||||
res.u = converter(mut pn)
|
||||
@ -410,6 +420,13 @@ pub fn atof64(s string) !f64 {
|
||||
.minf {
|
||||
res.u = double_minus_infinity
|
||||
}
|
||||
.extra_char {
|
||||
if param.allow_extra_chars {
|
||||
res.u = converter(mut pn)
|
||||
} else {
|
||||
return error('extra char after number')
|
||||
}
|
||||
}
|
||||
.invalid_number {
|
||||
return error('not a number')
|
||||
}
|
||||
|
@ -20,6 +20,9 @@ fn test_atof() {
|
||||
0.0,
|
||||
-0.0,
|
||||
31234567890123,
|
||||
0.01,
|
||||
2000,
|
||||
-300,
|
||||
]
|
||||
|
||||
// strings
|
||||
@ -31,6 +34,9 @@ fn test_atof() {
|
||||
'0.0',
|
||||
'-0.0',
|
||||
'31234567890123',
|
||||
'1e-2',
|
||||
'+2e+3',
|
||||
'-3.0e+2',
|
||||
]
|
||||
|
||||
// check conversion case 1 string <=> string
|
||||
@ -89,4 +95,16 @@ fn test_atof_errors() {
|
||||
} else {
|
||||
assert err.str() == 'not a number'
|
||||
}
|
||||
if x := strconv.atof64('uu577.01') {
|
||||
eprintln('> x: ${x}')
|
||||
assert false // strconv.atof64 should have failed
|
||||
} else {
|
||||
assert err.str() == 'not a number'
|
||||
}
|
||||
if x := strconv.atof64('123.33xyz') {
|
||||
eprintln('> x: ${x}')
|
||||
assert false // strconv.atof64 should have failed
|
||||
} else {
|
||||
assert err.str() == 'extra char after number'
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user