[Issue 20482] New: formatValue overlap detection does not account for nested anonymous unions

d-bugmail at puremagic.com d-bugmail at puremagic.com
Sun Jan 5 13:19:42 UTC 2020


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: nobody at puremagic.com
          Reporter: dkorpel at live.nl

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

--


More information about the Digitalmars-d-bugs mailing list