strconv.v_sprintf: add runtime checks&panics on arrity mismatches

pull/6393/head
Delyan Angelov 2020-09-17 00:24:33 +03:00
parent bb20586a5e
commit 80b150d3ad
1 changed files with 28 additions and 6 deletions

View File

@ -428,7 +428,6 @@ pub fn v_printf(str string, pt ... voidptr) {
}
pub fn v_sprintf(str string, pt ... voidptr) string{
mut res := strings.new_builder(pt.len * 16)
mut i := 0 // main strign index
@ -473,7 +472,8 @@ pub fn v_sprintf(str string, pt ... voidptr) string{
}
// single char, manage it here
if ch == `c` && status == .field_char {
if ch == `c` && status == .field_char {
v_sprintf_panic(p_index, pt.len)
d1 := unsafe {*(&byte(pt[p_index]))}
res.write_b(d1)
status = .reset_params
@ -484,6 +484,7 @@ pub fn v_sprintf(str string, pt ... voidptr) string{
// pointer, manage it here
if ch == `p` && status == .field_char {
v_sprintf_panic(p_index, pt.len)
res.write("0x")
res.write(ptr_str(unsafe {pt[p_index]}))
status = .reset_params
@ -526,8 +527,10 @@ pub fn v_sprintf(str string, pt ... voidptr) string{
}
// manage "%.*s" precision field
else if ch == `.` && fc_ch1 == `*` && fc_ch2 == `s` {
v_sprintf_panic(p_index, pt.len)
len := unsafe {*(&int(pt[p_index]))}
p_index++
v_sprintf_panic(p_index, pt.len)
mut s := unsafe {*(&string(pt[p_index]))}
s = s[..len]
p_index++
@ -630,6 +633,7 @@ pub fn v_sprintf(str string, pt ... voidptr) string{
// hh fot 8 bit int
`h` {
if ch2 == `h` {
v_sprintf_panic(p_index, pt.len)
x := unsafe {*(&i8(pt[p_index]))}
positive = if x >= 0 { true } else { false }
d1 = if positive { u64(x) } else { u64(-x) }
@ -645,28 +649,31 @@ pub fn v_sprintf(str string, pt ... voidptr) string{
// placeholder for future 128bit integer code
/*
if ch2 == `l` {
v_sprintf_panic(p_index, pt.len)
x := *(&i128(pt[p_index]))
positive = if x >= 0 { true } else { false }
d1 = if positive { u128(x) } else { u128(-x) }
} else {
v_sprintf_panic(p_index, pt.len)
x := *(&i64(pt[p_index]))
positive = if x >= 0 { true } else { false }
d1 = if positive { u64(x) } else { u64(-x) }
}
*/
v_sprintf_panic(p_index, pt.len)
x := unsafe {*(&i64(pt[p_index]))}
positive = if x >= 0 { true } else { false }
d1 = if positive { u64(x) } else { u64(-x) }
}
// default int
else {
v_sprintf_panic(p_index, pt.len)
x := unsafe {*(&int(pt[p_index]))}
positive = if x >= 0 { true } else { false }
d1 = if positive { u64(x) } else { u64(-x) }
}
}
res.write(format_dec(d1,{pad_ch: pad_ch, len0: len0, len1: 0, positive: positive, sign_flag: sign, allign: allign}))
status = .reset_params
p_index++
@ -680,7 +687,7 @@ pub fn v_sprintf(str string, pt ... voidptr) string{
else if ch == `u` {
mut d1 := u64(0)
positive := true
v_sprintf_panic(p_index, pt.len)
match ch1 {
// h for 16 bit unsigned int
// hh fot 8 bit unsigned int
@ -704,7 +711,7 @@ pub fn v_sprintf(str string, pt ... voidptr) string{
*/
d1 = u64(unsafe {*(&u64(pt[p_index]))})
}
// defualt int
// default int
else {
d1 = u64(unsafe {*(&u32(pt[p_index]))})
}
@ -719,8 +726,8 @@ pub fn v_sprintf(str string, pt ... voidptr) string{
// hex
else if ch in [`x`, `X`] {
v_sprintf_panic(p_index, pt.len)
mut s := ""
match ch1 {
// h for 16 bit int
// hh fot 8 bit int
@ -768,6 +775,7 @@ pub fn v_sprintf(str string, pt ... voidptr) string{
// float and double
if ch in [`f`, `F`] {
v_sprintf_panic(p_index, pt.len)
x := unsafe {*(&f64(pt[p_index]))}
mut positive := x >= f64(0.0)
len1 = if len1 >= 0 { len1 } else { def_len1 }
@ -779,6 +787,7 @@ pub fn v_sprintf(str string, pt ... voidptr) string{
continue
}
else if ch in [`e`, `E`] {
v_sprintf_panic(p_index, pt.len)
x := unsafe {*(&f64(pt[p_index]))}
mut positive := x >= f64(0.0)
len1 = if len1 >= 0 { len1 } else { def_len1 }
@ -790,6 +799,7 @@ pub fn v_sprintf(str string, pt ... voidptr) string{
continue
}
else if ch in [`g`, `G`] {
v_sprintf_panic(p_index, pt.len)
x := unsafe {*(&f64(pt[p_index]))}
mut positive := x >= f64(0.0)
mut s := ""
@ -811,6 +821,7 @@ pub fn v_sprintf(str string, pt ... voidptr) string{
// string
else if ch == `s` {
v_sprintf_panic(p_index, pt.len)
s1 := unsafe{*(&string(pt[p_index]))}
pad_ch = ` `
res.write(format_str(s1, {pad_ch: pad_ch, len0: len0, len1: 0, positive: true, sign_flag: false, allign: allign}))
@ -826,9 +837,20 @@ pub fn v_sprintf(str string, pt ... voidptr) string{
i++
}
if p_index != pt.len {
panic('${p_index} % conversion specifiers, but given ${pt.len} args')
}
return res.str()
}
[inline]
fn v_sprintf_panic( idx, len int) {
if idx >= len {
panic('${idx+1} % conversion specifiers, but given only ${len} args')
}
}
fn fabs(x f64) f64 {
if x < 0.0 {
return -x