Bug 20482 – formatValue overlap detection does not account for nested anonymous unions

Status
NEW
Severity
normal
Priority
P3
Component
phobos
Product
D
Version
D2
Platform
All
OS
All
Creation time
2020-01-05T13:19:42Z
Last change time
2024-12-01T16:36:09Z
Keywords
safe
Assigned to
No Owner
Creator
Dennis
Moved to GitHub: phobos#9786 →

Comments

Comment #0 by dkorpel — 2020-01-05T13:19:42Z
The logic std.format uses for detecting overlap of anonymous unions is incorrect. It looks at the difference in .offsetof for consecutive members in .tupleof, but doesn't account for nested unions. ``` import std; struct S { union { struct { union { string a = "string a"; long overlapsAlength; } string b = "string b"; } string[2] overlapsAandB; } } void main() @safe { S s; s.overlapsAlength = 32; writeln(s); } ``` Prints: S(#{overlap a, overlapsAlength}, "string b", ["string a\0string b\0%s\0/dlang/dmd-", "string b"]) It only detects the overlap of `a` and `overlapsAlength`, while `overlapsAandB` gets printed, resulting in memory corruption. The example calls writeln on s, but writeln is simply a wrapper around formatValue which is at the heart of the issue: ``` auto a = appender!string; auto f = singleSpec("%s"); formatValue(a, s, f); writeln(a.data); ``` The specific logic can be found here: https://github.com/dlang/phobos/blob/cc977c37b8fa7af5fc54bc64a6aad14714e5cf2d/std/format.d#L4411
Comment #1 by bugzilla — 2021-04-21T18:03:17Z
IMHO, there is more about this: members of unions are only printed, if they are members of structs, but not stand alone unions. They are just formatted as their name. I think, either, members of unions should always be printed (and then correctly) or not at all.
Comment #2 by robert.schadek — 2024-12-01T16:36:09Z
THIS ISSUE HAS BEEN MOVED TO GITHUB https://github.com/dlang/phobos/issues/9786 DO NOT COMMENT HERE ANYMORE, NOBODY WILL SEE IT, THIS ISSUE HAS BEEN MOVED TO GITHUB