strconv: fix a double free bug in v_sprintf/remove_tail_zeros_old, reduce leaks
parent
795fe5844c
commit
a3e9409196
|
@ -89,6 +89,7 @@ pub mut:
|
||||||
rm_tail_zero bool // remove the tail zeros from floats
|
rm_tail_zero bool // remove the tail zeros from floats
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[manualfree]
|
||||||
pub fn format_str(s string, p BF_param) string {
|
pub fn format_str(s string, p BF_param) string {
|
||||||
if p.len0 <= 0 {
|
if p.len0 <= 0 {
|
||||||
return s.clone()
|
return s.clone()
|
||||||
|
|
|
@ -108,3 +108,8 @@ fn test_format() {
|
||||||
cnt++
|
cnt++
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn test_sprintf_does_not_double_free_on_g() {
|
||||||
|
x := 3.141516
|
||||||
|
assert strconv.v_sprintf('aaa %G', x) == 'aaa 3.141516'
|
||||||
|
}
|
||||||
|
|
|
@ -26,6 +26,7 @@ pub fn v_printf(str string, pt ...voidptr) {
|
||||||
print(v_sprintf(str, ...pt))
|
print(v_sprintf(str, ...pt))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[manualfree]
|
||||||
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)
|
||||||
defer {
|
defer {
|
||||||
|
@ -269,14 +270,16 @@ pub fn v_sprintf(str string, pt ...voidptr) string {
|
||||||
d1 = if positive { u64(x) } else { u64(-x) }
|
d1 = if positive { u64(x) } else { u64(-x) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
res.write_string(format_dec_old(d1,
|
tmp := format_dec_old(d1,
|
||||||
pad_ch: pad_ch
|
pad_ch: pad_ch
|
||||||
len0: len0
|
len0: len0
|
||||||
len1: 0
|
len1: 0
|
||||||
positive: positive
|
positive: positive
|
||||||
sign_flag: sign
|
sign_flag: sign
|
||||||
allign: allign
|
allign: allign
|
||||||
))
|
)
|
||||||
|
res.write_string(tmp)
|
||||||
|
unsafe { tmp.free() }
|
||||||
status = .reset_params
|
status = .reset_params
|
||||||
p_index++
|
p_index++
|
||||||
i++
|
i++
|
||||||
|
@ -318,14 +321,16 @@ pub fn v_sprintf(str string, pt ...voidptr) string {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
res.write_string(format_dec_old(d1,
|
tmp := format_dec_old(d1,
|
||||||
pad_ch: pad_ch
|
pad_ch: pad_ch
|
||||||
len0: len0
|
len0: len0
|
||||||
len1: 0
|
len1: 0
|
||||||
positive: positive
|
positive: positive
|
||||||
sign_flag: sign
|
sign_flag: sign
|
||||||
allign: allign
|
allign: allign
|
||||||
))
|
)
|
||||||
|
res.write_string(tmp)
|
||||||
|
unsafe { tmp.free() }
|
||||||
status = .reset_params
|
status = .reset_params
|
||||||
p_index++
|
p_index++
|
||||||
i++
|
i++
|
||||||
|
@ -370,17 +375,22 @@ pub fn v_sprintf(str string, pt ...voidptr) string {
|
||||||
}
|
}
|
||||||
|
|
||||||
if ch == `X` {
|
if ch == `X` {
|
||||||
|
tmp := s
|
||||||
s = s.to_upper()
|
s = s.to_upper()
|
||||||
|
unsafe { tmp.free() }
|
||||||
}
|
}
|
||||||
|
|
||||||
res.write_string(format_str(s,
|
tmp := format_str(s,
|
||||||
pad_ch: pad_ch
|
pad_ch: pad_ch
|
||||||
len0: len0
|
len0: len0
|
||||||
len1: 0
|
len1: 0
|
||||||
positive: true
|
positive: true
|
||||||
sign_flag: false
|
sign_flag: false
|
||||||
allign: allign
|
allign: allign
|
||||||
))
|
)
|
||||||
|
res.write_string(tmp)
|
||||||
|
unsafe { tmp.free() }
|
||||||
|
unsafe { s.free() }
|
||||||
status = .reset_params
|
status = .reset_params
|
||||||
p_index++
|
p_index++
|
||||||
i++
|
i++
|
||||||
|
@ -402,7 +412,14 @@ pub fn v_sprintf(str string, pt ...voidptr) string {
|
||||||
sign_flag: sign
|
sign_flag: sign
|
||||||
allign: allign
|
allign: allign
|
||||||
)
|
)
|
||||||
res.write_string(if ch == `F` { s.to_upper() } else { s })
|
if ch == `F` {
|
||||||
|
tmp := s.to_upper()
|
||||||
|
res.write_string(tmp)
|
||||||
|
unsafe { tmp.free() }
|
||||||
|
} else {
|
||||||
|
res.write_string(s)
|
||||||
|
}
|
||||||
|
unsafe { s.free() }
|
||||||
}
|
}
|
||||||
status = .reset_params
|
status = .reset_params
|
||||||
p_index++
|
p_index++
|
||||||
|
@ -422,7 +439,14 @@ pub fn v_sprintf(str string, pt ...voidptr) string {
|
||||||
sign_flag: sign
|
sign_flag: sign
|
||||||
allign: allign
|
allign: allign
|
||||||
)
|
)
|
||||||
res.write_string(if ch == `E` { s.to_upper() } else { s })
|
if ch == `E` {
|
||||||
|
tmp := s.to_upper()
|
||||||
|
res.write_string(tmp)
|
||||||
|
unsafe { tmp.free() }
|
||||||
|
} else {
|
||||||
|
res.write_string(s)
|
||||||
|
}
|
||||||
|
unsafe { s.free() }
|
||||||
}
|
}
|
||||||
status = .reset_params
|
status = .reset_params
|
||||||
p_index++
|
p_index++
|
||||||
|
@ -438,6 +462,7 @@ pub fn v_sprintf(str string, pt ...voidptr) string {
|
||||||
if tx < 999_999.0 && tx >= 0.00001 {
|
if tx < 999_999.0 && tx >= 0.00001 {
|
||||||
// println("Here g format_fl [$tx]")
|
// println("Here g format_fl [$tx]")
|
||||||
len1 = if len1 >= 0 { len1 + 1 } else { def_len1 }
|
len1 = if len1 >= 0 { len1 + 1 } else { def_len1 }
|
||||||
|
tmp := s
|
||||||
s = format_fl_old(x,
|
s = format_fl_old(x,
|
||||||
pad_ch: pad_ch
|
pad_ch: pad_ch
|
||||||
len0: len0
|
len0: len0
|
||||||
|
@ -447,8 +472,10 @@ pub fn v_sprintf(str string, pt ...voidptr) string {
|
||||||
allign: allign
|
allign: allign
|
||||||
rm_tail_zero: true
|
rm_tail_zero: true
|
||||||
)
|
)
|
||||||
|
unsafe { tmp.free() }
|
||||||
} else {
|
} else {
|
||||||
len1 = if len1 >= 0 { len1 + 1 } else { def_len1 }
|
len1 = if len1 >= 0 { len1 + 1 } else { def_len1 }
|
||||||
|
tmp := s
|
||||||
s = format_es_old(x,
|
s = format_es_old(x,
|
||||||
pad_ch: pad_ch
|
pad_ch: pad_ch
|
||||||
len0: len0
|
len0: len0
|
||||||
|
@ -458,8 +485,16 @@ pub fn v_sprintf(str string, pt ...voidptr) string {
|
||||||
allign: allign
|
allign: allign
|
||||||
rm_tail_zero: true
|
rm_tail_zero: true
|
||||||
)
|
)
|
||||||
|
unsafe { tmp.free() }
|
||||||
}
|
}
|
||||||
res.write_string(if ch == `G` { s.to_upper() } else { s })
|
if ch == `G` {
|
||||||
|
tmp := s.to_upper()
|
||||||
|
res.write_string(tmp)
|
||||||
|
unsafe { tmp.free() }
|
||||||
|
} else {
|
||||||
|
res.write_string(s)
|
||||||
|
}
|
||||||
|
unsafe { s.free() }
|
||||||
}
|
}
|
||||||
status = .reset_params
|
status = .reset_params
|
||||||
p_index++
|
p_index++
|
||||||
|
@ -471,14 +506,16 @@ pub fn v_sprintf(str string, pt ...voidptr) string {
|
||||||
v_sprintf_panic(p_index, pt.len)
|
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_string(format_str(s1,
|
tmp := format_str(s1,
|
||||||
pad_ch: pad_ch
|
pad_ch: pad_ch
|
||||||
len0: len0
|
len0: len0
|
||||||
len1: 0
|
len1: 0
|
||||||
positive: true
|
positive: true
|
||||||
sign_flag: false
|
sign_flag: false
|
||||||
allign: allign
|
allign: allign
|
||||||
))
|
)
|
||||||
|
res.write_string(tmp)
|
||||||
|
unsafe { tmp.free() }
|
||||||
status = .reset_params
|
status = .reset_params
|
||||||
p_index++
|
p_index++
|
||||||
i++
|
i++
|
||||||
|
@ -596,11 +633,15 @@ pub fn format_es_old(f f64, p BF_param) string {
|
||||||
mut s := ''
|
mut s := ''
|
||||||
mut fs := f64_to_str_pad(if f > 0 { f } else { -f }, p.len1)
|
mut fs := f64_to_str_pad(if f > 0 { f } else { -f }, p.len1)
|
||||||
if p.rm_tail_zero {
|
if p.rm_tail_zero {
|
||||||
|
tmp := fs
|
||||||
fs = remove_tail_zeros_old(fs)
|
fs = remove_tail_zeros_old(fs)
|
||||||
|
tmp.free()
|
||||||
}
|
}
|
||||||
mut res := strings.new_builder(if p.len0 > fs.len { p.len0 } else { fs.len })
|
mut res := strings.new_builder(if p.len0 > fs.len { p.len0 } else { fs.len })
|
||||||
defer {
|
defer {
|
||||||
res.free()
|
res.free()
|
||||||
|
fs.free()
|
||||||
|
s.free()
|
||||||
}
|
}
|
||||||
|
|
||||||
mut sign_len_diff := 0
|
mut sign_len_diff := 0
|
||||||
|
@ -647,8 +688,6 @@ pub fn format_es_old(f f64, p BF_param) string {
|
||||||
res.write_byte(p.pad_ch)
|
res.write_byte(p.pad_ch)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
s.free()
|
|
||||||
fs.free()
|
|
||||||
return res.str()
|
return res.str()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -685,7 +724,7 @@ pub fn remove_tail_zeros_old(s string) string {
|
||||||
tmp = s[..last_zero_start] + s[i..]
|
tmp = s[..last_zero_start] + s[i..]
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
tmp = s
|
tmp = s.clone()
|
||||||
}
|
}
|
||||||
if unsafe { tmp.str[tmp.len - 1] } == `.` {
|
if unsafe { tmp.str[tmp.len - 1] } == `.` {
|
||||||
return tmp[..tmp.len - 1]
|
return tmp[..tmp.len - 1]
|
||||||
|
@ -694,11 +733,13 @@ pub fn remove_tail_zeros_old(s string) string {
|
||||||
}
|
}
|
||||||
|
|
||||||
// max int64 9223372036854775807
|
// max int64 9223372036854775807
|
||||||
|
[manualfree]
|
||||||
pub fn format_dec_old(d u64, p BF_param) string {
|
pub fn format_dec_old(d u64, p BF_param) string {
|
||||||
mut s := ''
|
mut s := ''
|
||||||
mut res := strings.new_builder(20)
|
mut res := strings.new_builder(20)
|
||||||
defer {
|
defer {
|
||||||
unsafe { res.free() }
|
unsafe { res.free() }
|
||||||
|
unsafe { s.free() }
|
||||||
}
|
}
|
||||||
mut sign_len_diff := 0
|
mut sign_len_diff := 0
|
||||||
if p.pad_ch == `0` {
|
if p.pad_ch == `0` {
|
||||||
|
@ -711,16 +752,24 @@ pub fn format_dec_old(d u64, p BF_param) string {
|
||||||
res.write_byte(`-`)
|
res.write_byte(`-`)
|
||||||
sign_len_diff = -1
|
sign_len_diff = -1
|
||||||
}
|
}
|
||||||
|
tmp := s
|
||||||
s = d.str()
|
s = d.str()
|
||||||
|
unsafe { tmp.free() }
|
||||||
} else {
|
} else {
|
||||||
if p.positive {
|
if p.positive {
|
||||||
if p.sign_flag {
|
if p.sign_flag {
|
||||||
|
tmp := s
|
||||||
s = '+' + d.str()
|
s = '+' + d.str()
|
||||||
|
unsafe { tmp.free() }
|
||||||
} else {
|
} else {
|
||||||
|
tmp := s
|
||||||
s = d.str()
|
s = d.str()
|
||||||
|
unsafe { tmp.free() }
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
tmp := s
|
||||||
s = '-' + d.str()
|
s = '-' + d.str()
|
||||||
|
unsafe { tmp.free() }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
dif := p.len0 - s.len + sign_len_diff
|
dif := p.len0 - s.len + sign_len_diff
|
||||||
|
|
Loading…
Reference in New Issue