https://issues.dlang.org/show_bug.cgi?id=20482
Issue ID: 20482
Summary: formatValue overlap detection does not account for
nested anonymous unions
Product: D
Version: D2
Hardware: All
OS: All
Status: NEW
Keywords: safe
Severity: normal
Priority: P1
Component: phobos
Assignee: [email protected]
Reporter: [email protected]
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
--