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