builtin: implement a double free detection for v strings

pull/5588/head
Delyan Angelov 2020-06-30 18:28:28 +03:00
parent f10d2bb75f
commit 2fd960f12c
2 changed files with 19 additions and 6 deletions

View File

@ -46,10 +46,18 @@ pub struct string {
pub:
str byteptr // points to a C style 0 terminated string of bytes.
len int // the length of the .str field, excluding the ending 0 byte. It is always equal to strlen(.str).
is_lit bool
mut:
is_lit int
}
// mut:
// hash_cache int
// mut:
// hash_cache int
//
// NB string.is_lit is an enumeration of the following:
// .is_lit == 0 => a fresh string, should be freed by autofree
// .is_lit == 1 => a literal string from .rodata, should NOT be freed
// .is_lit == -98761234 => already freed string, protects against double frees.
// ^^^^^^^^^ calling free on these is a bug.
// Any other value means that the string has been corrupted.
pub struct ustring {
pub mut:
@ -109,7 +117,7 @@ pub fn tos_lit(s charptr) string {
return string{
str: byteptr(s)
len: C.strlen(s)
is_lit:true
is_lit: 1
}
}
@ -1186,10 +1194,15 @@ pub fn (c byte) is_letter() bool {
}
pub fn (s &string) free() {
if s.is_lit || s.len == 0 {
if s.is_lit == -98761234 {
C.printf('double string.free() detected\n')
return
}
if s.is_lit == 1 || s.len == 0 {
return
}
free(s.str)
s.is_lit = -98761234
}
// all_before('23:34:45.234', '.') == '23:34:45'

View File

@ -108,7 +108,7 @@ string _STR_TMP(const char *fmt, ...) {
//puts(g_str_buf);
#endif
string res = tos(g_str_buf, len);
res.is_lit = true;
res.is_lit = 1;
return res;
} // endof _STR_TMP