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

strconv: float memory leak fix (#11980)

This commit is contained in:
penguindark 2021-09-26 06:33:35 +02:00 committed by GitHub
parent d329e1decd
commit f3757a7cd1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -35,6 +35,7 @@ pub fn format_str_sb(s string, p BF_param, mut sb strings.Builder) {
} }
const ( const (
max_size_f64_char = 32 // the f64 max representation is -36,028,797,018,963,968e1023, 21 chars, 32 is faster for the memory manger
// digit pairs in reverse order // digit pairs in reverse order
digit_pairs = '00102030405060708090011121314151617181910212223242526272829203132333435363738393041424344454647484940515253545556575859506162636465666768696071727374757677787970818283848586878889809192939495969798999' digit_pairs = '00102030405060708090011121314151617181910212223242526272829203132333435363738393041424344454647484940515253545556575859506162636465666768696071727374757677787970818283848586878889809192939495969798999'
) )
@ -297,18 +298,13 @@ pub fn f64_to_str_lnd1(f f64, dec_digit int) string {
} }
// strings.Builder version of format_fl // strings.Builder version of format_fl
[manualfree] [direct_array_access; manualfree]
pub fn format_fl(f f64, p BF_param) string { pub fn format_fl(f f64, p BF_param) string {
unsafe { unsafe {
mut s := ''
// mut fs := "1.2343"
mut fs := f64_to_str_lnd1(if f >= 0.0 { f } else { -f }, p.len1) mut fs := f64_to_str_lnd1(if f >= 0.0 { f } else { -f }, p.len1)
// println("Dario")
// println(fs)
// error!! // error!!
if fs[0] == `[` { if fs[0] == `[` {
s.free()
return fs return fs
} }
@ -317,121 +313,134 @@ pub fn format_fl(f f64, p BF_param) string {
fs = remove_tail_zeros(fs) fs = remove_tail_zeros(fs)
tmp.free() tmp.free()
} }
mut res := strings.new_builder(if p.len0 > fs.len { p.len0 } else { fs.len })
mut buf := [strconv.max_size_f64_char]u8{} // write temp float buffer in stack
mut out := [strconv.max_size_f64_char]u8{} // out buffer
mut buf_i := 0 // index temporary string
mut out_i := 0 // index output string
mut sign_len_diff := 0 mut sign_len_diff := 0
if p.pad_ch == `0` { if p.pad_ch == `0` {
if p.positive { if p.positive {
if p.sign_flag { if p.sign_flag {
res.write_b(`+`) out[out_i] = `+`
out_i++
sign_len_diff = -1 sign_len_diff = -1
} }
} else { } else {
res.write_b(`-`) out[out_i] = `-`
out_i++
sign_len_diff = -1 sign_len_diff = -1
} }
tmp := s
s = fs.clone()
tmp.free()
} else { } else {
if p.positive { if p.positive {
if p.sign_flag { if p.sign_flag {
tmp := s buf[buf_i] = `+`
s = '+' + fs buf_i++
tmp.free()
} else {
tmp := s
s = fs.clone()
tmp.free()
} }
} else { } else {
tmp := s buf[buf_i] = `-`
s = '-' + fs buf_i++
tmp.free()
} }
} }
dif := p.len0 - s.len + sign_len_diff // copy the float
vmemcpy(&buf[buf_i], fs.str, fs.len)
buf_i += fs.len
// make the padding if needed
dif := p.len0 - buf_i + sign_len_diff
if p.allign == .right { if p.allign == .right {
for i1 := 0; i1 < dif; i1++ { for i1 := 0; i1 < dif; i1++ {
res.write_b(p.pad_ch) out[out_i] = p.pad_ch
out_i++
} }
} }
res.write_string(s) vmemcpy(&out[out_i], &buf[0], buf_i)
out_i += buf_i
if p.allign == .left { if p.allign == .left {
for i1 := 0; i1 < dif; i1++ { for i1 := 0; i1 < dif; i1++ {
res.write_b(p.pad_ch) out[out_i] = p.pad_ch
out_i++
}
}
out[out_i] = 0
// return and free
tmp := fs
fs = tos_clone(&out[0])
tmp.free()
return fs
} }
} }
s.free() [direct_array_access; manualfree]
fs.free()
tmp_res := res.str()
res.free()
return tmp_res
}
}
[manualfree]
pub fn format_es(f f64, p BF_param) string { pub fn format_es(f f64, p BF_param) string {
unsafe { unsafe {
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(fs) fs = remove_tail_zeros(fs)
tmp.free()
} }
mut res := strings.new_builder(if p.len0 > fs.len { p.len0 } else { fs.len })
mut buf := [strconv.max_size_f64_char]u8{} // write temp float buffer in stack
mut out := [strconv.max_size_f64_char]u8{} // out buffer
mut buf_i := 0 // index temporary string
mut out_i := 0 // index output string
mut sign_len_diff := 0 mut sign_len_diff := 0
if p.pad_ch == `0` { if p.pad_ch == `0` {
if p.positive { if p.positive {
if p.sign_flag { if p.sign_flag {
res.write_b(`+`) out[out_i] = `+`
out_i++
sign_len_diff = -1 sign_len_diff = -1
} }
} else { } else {
res.write_b(`-`) out[out_i] = `-`
out_i++
sign_len_diff = -1 sign_len_diff = -1
} }
tmp := s
s = fs.clone()
tmp.free()
} else { } else {
if p.positive { if p.positive {
if p.sign_flag { if p.sign_flag {
tmp := s buf[buf_i] = `+`
s = '+' + fs buf_i++
tmp.free()
} else {
tmp := s
s = fs.clone()
tmp.free()
} }
} else { } else {
tmp := s buf[buf_i] = `-`
s = '-' + fs buf_i++
tmp.free()
} }
} }
dif := p.len0 - s.len + sign_len_diff // copy the float
vmemcpy(&buf[buf_i], fs.str, fs.len)
buf_i += fs.len
// make the padding if needed
dif := p.len0 - buf_i + sign_len_diff
if p.allign == .right { if p.allign == .right {
for i1 := 0; i1 < dif; i1++ { for i1 := 0; i1 < dif; i1++ {
res.write_b(p.pad_ch) out[out_i] = p.pad_ch
out_i++
} }
} }
res.write_string(s) vmemcpy(&out[out_i], &buf[0], buf_i)
out_i += buf_i
if p.allign == .left { if p.allign == .left {
for i1 := 0; i1 < dif; i1++ { for i1 := 0; i1 < dif; i1++ {
res.write_b(p.pad_ch) out[out_i] = p.pad_ch
out_i++
} }
} }
s.free() out[out_i] = 0
fs.free()
tmp_res := res.str() // return and free
res.free() tmp := fs
return tmp_res fs = tos_clone(&out[0])
tmp.free()
return fs
} }
} }