[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