toml: fix memory corruption when returning new date/time types (#12507)

pull/12546/head
Larpon 2021-11-19 19:35:11 +01:00 committed by GitHub
parent a894a6cf36
commit 1bbc73384c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 52 additions and 10 deletions

View File

@ -26,10 +26,10 @@ pub fn (a Any) string() string {
// ... certain call-patterns to this function will cause a memory corruption. // ... certain call-patterns to this function will cause a memory corruption.
// See `tests/toml_memory_corruption_test.v` for a matching regression test. // See `tests/toml_memory_corruption_test.v` for a matching regression test.
string { return (a as string).clone() } string { return (a as string).clone() }
DateTime { return a.str() } DateTime { return a.str().clone() }
Date { return a.str() } Date { return a.str().clone() }
Time { return a.str() } Time { return a.str().clone() }
else { return a.str() } else { return a.str().clone() }
} }
} }
@ -126,7 +126,8 @@ pub fn (a Any) bool() bool {
pub fn (a Any) date() Date { pub fn (a Any) date() Date {
match a { match a {
// string { } // TODO // string { } // TODO
Date { return a } // NOTE `.clone()` is to avoid memory corruption see `pub fn (a Any) string() string`
Date { return Date{a.str().clone()} }
else { return Date{''} } else { return Date{''} }
} }
} }
@ -135,7 +136,8 @@ pub fn (a Any) date() Date {
pub fn (a Any) time() Time { pub fn (a Any) time() Time {
match a { match a {
// string { } // TODO // string { } // TODO
Time { return a } // NOTE `.clone()` is to avoid memory corruption see `pub fn (a Any) string() string`
Time { return Time{a.str().clone()} }
else { return Time{''} } else { return Time{''} }
} }
} }
@ -144,7 +146,8 @@ pub fn (a Any) time() Time {
pub fn (a Any) datetime() DateTime { pub fn (a Any) datetime() DateTime {
match a { match a {
// string { } // TODO // string { } // TODO
DateTime { return a } // NOTE `.clone()` is to avoid memory corruption see `pub fn (a Any) string() string`
DateTime { return DateTime{a.str().clone()} }
else { return DateTime{''} } else { return DateTime{''} }
} }
} }

View File

@ -56,17 +56,17 @@ fn test_dates() {
od_time := toml.Date{'1979-05-27'} od_time := toml.Date{'1979-05-27'}
ld1 := toml_doc.value('ld1') ld1 := toml_doc.value('ld1')
assert ld1.date() == od_time assert ld1.date() == od_time
// assert ld1.string() == '1979-05-27' // TODO memory corruption assert ld1.string() == '1979-05-27'
// lt1 test section // lt1 test section
mut ot_time := toml.Time{'07:32:00'} mut ot_time := toml.Time{'07:32:00'}
lt1 := toml_doc.value('lt1') lt1 := toml_doc.value('lt1')
assert lt1.time() == ot_time assert lt1.time() == ot_time
// assert lt1.string() == '07:32:00' // TODO memory corruption assert lt1.string() == '07:32:00'
// lt2 test section // lt2 test section
ot_time = toml.Time{'00:32:00.999999'} ot_time = toml.Time{'00:32:00.999999'}
lt2 := toml_doc.value('lt2') lt2 := toml_doc.value('lt2')
assert lt2.time() == ot_time assert lt2.time() == ot_time
// assert lt2.string() == '00:32:00.999999' // TODO memory corruption assert lt2.string() == '00:32:00.999999'
} }

View File

@ -22,3 +22,42 @@ fn test_toml_known_memory_corruption() {
assert any_name.string() == 'Tom Preston-Werner' assert any_name.string() == 'Tom Preston-Werner'
assert toml_doc.value('owner.name') as string == 'Tom Preston-Werner' assert toml_doc.value('owner.name') as string == 'Tom Preston-Werner'
} }
fn test_toml_known_memory_corruption_2() {
toml_txt := '
# Local Date-Time
ldt1 = 1979-05-27T07:32:00
ldt2 = 1979-05-27T00:32:00.999999
# Local Date
ld1 = 1979-05-27
# Local Time
lt1 = 07:32:00
lt2 = 00:32:00.999999
'
toml_doc := toml.parse(toml_txt) or { panic(err) }
// ldt1 test section
odt_time := toml.DateTime{'1979-05-27T07:32:00'}
ldt1 := toml_doc.value('ldt1')
assert ldt1.string() == '1979-05-27T07:32:00' // Running this before yielded a double free segfault
assert ldt1.datetime() == odt_time
assert ldt1.string() == '1979-05-27T07:32:00' // Used to yield a memory corruption
// ld1 test section
od_time := toml.Date{'1979-05-27'}
ld1 := toml_doc.value('ld1')
assert ld1.date() == od_time
assert ld1.string() == '1979-05-27' // Used to yield a memory corruption
// lt1 test section
mut ot_time := toml.Time{'07:32:00'}
lt1 := toml_doc.value('lt1')
assert lt1.time() == ot_time
assert lt1.string() == '07:32:00' // Used to yield a memory corruption
// lt2 test section
ot_time = toml.Time{'00:32:00.999999'}
lt2 := toml_doc.value('lt2')
assert lt2.time() == ot_time
assert lt2.string() == '00:32:00.999999' // Used to yield a memory corruption
}