[Issue 15645] New: Tuple.slice() causes memory corruption.

via Digitalmars-d-bugs digitalmars-d-bugs at puremagic.com
Thu Feb 4 09:51:47 PST 2016


https://issues.dlang.org/show_bug.cgi?id=15645

          Issue ID: 15645
           Summary: Tuple.slice() causes memory corruption.
           Product: D
           Version: D2
          Hardware: x86_64
               URL: http://forum.dlang.org/thread/ctpsgcekdbwmlsayonqs@for
                    um.dlang.org
                OS: Linux
            Status: NEW
          Severity: major
          Priority: P1
         Component: phobos
          Assignee: nobody at puremagic.com
          Reporter: Marco.Leise at gmx.de

Good thing we have @trusted to mark suspicious memory operations that are
actually safe. When it covers a bug that @safe would have caught though, it
leaves a bad taste...

First let's look at the implementation:

    @property
    ref Tuple!(sliceSpecs!(from, to)) slice(size_t from, size_t to)() @trusted
    if (from <= to && to <= Types.length)
    {
        return *cast(typeof(return)*) &(field[from]);
    }

To return a slice into the tuple, a pointer to the new first is reinterpreted
as the new tuple type. This mirrors the effect of slicing an array, just that
tuples are actually structs and that causes a serious problem. Consider we
slice off the first element of the following tuple and compare the relative
offsets of the 2nd and 3rd field respectively:

    pragma(msg, Tuple!(int, bool, string)._2.offsetof - Tuple!(int, bool,
string)._1.offsetof);
    pragma(msg, Tuple!(     bool, string)._1.offsetof - Tuple!(     bool,
string)._0.offsetof);

This prints:

    4LU
    8LU

So the relative offset of the string part moved which causes memory corruption
when slice() reinterprets pointers. More visually the layout on amd64 is:

                           0   4   8
Tuple!(int, bool, string): int boolstring
                               0   4   8
         Tuple!(bool, string): bool    string

The memory adresses of the boolean field match, but the string moves due to its
alignment constraints.

--


More information about the Digitalmars-d-bugs mailing list