Bug 8580 – VariantN.peek works wrongly for types with size bigger than maxDataSize template argument

Status
RESOLVED
Resolution
FIXED
Severity
normal
Priority
P2
Component
phobos
Product
D
Version
D2
Platform
All
OS
All
Creation time
2012-08-23T16:31:00Z
Last change time
2014-02-17T01:11:16Z
Keywords
pull
Assigned to
nobody
Creator
cybevnm

Comments

Comment #0 by cybevnm — 2012-08-23T16:31:48Z
Consider the code: import std.stdio; import std.variant; struct S(size_t BuffLen) { ubyte[BuffLen] arr; } void fill(T)(ref T val) { foreach(ref item; val.arr) { item = 0xff; } } void printFewBytes(T)(T val) { foreach(i; 0..10) { writef("%02X ", val.arr[ i ]); } writeln(); } // for 64 bit linux maxDataSize is 32 bytes void main() { // case when user type fits directly in Variant's storage { S!(32) s; // structure with specified size fill(s); // fill structure with some recognizable pattern (0xFF in our case) auto v = Variant(s); printFewBytes(*v.peek!(S!(32))()); } // case when user type bigger than Variant's storage { S!(33) s; fill(s); auto v = Variant(s); printFewBytes(*v.peek!(S!(33))()); } } Output: FF FF FF FF FF FF FF FF FF FF 80 FF 02 33 4E 7F 00 00 00 00 For structure with size smaller than Variant's storage we have expected output, in second case we seeing some random bytes, which actually are address of dynamically allocated by Variant's implementation object. Some fragments of variant implementation: // part of Variant.opAssign, where pointer saved to storage ... auto p = new T; *p = rhs; memcpy(&store, &p, p.sizeof); ... // part of Variant.peek where storage erroneously interpreted as type's instance bytes ... return type == typeid(T) ? cast(T*) &store : null; ...
Comment #1 by opantm2+dbugs — 2014-02-13T21:16:57Z
Comment #2 by github-bugzilla — 2014-02-17T01:06:10Z
Commits pushed to master at https://github.com/D-Programming-Language/phobos https://github.com/D-Programming-Language/phobos/commit/0c82698b6f50df89e946be797e2754153f1a0e29 Fix issue 8580 - Peek returns an invalid pointer for structs larger than Variant.size. Style: Add space between if and condition. https://github.com/D-Programming-Language/phobos/commit/91c85101e8a8273fc6abe425b8eaac1d4808ece4 Merge pull request #1934 from Kapps/fix8580 Fix issue 8580 - Peek returns an invalid pointer for structs larger than Variant.size.