diff options
author | Thiago Macieira <thiago.macieira@nokia.com> | 2010-05-03 11:22:09 (GMT) |
---|---|---|
committer | Thiago Macieira <thiago.macieira@nokia.com> | 2010-05-03 14:04:27 (GMT) |
commit | 3d852917187e29892529ab51d24c1a1177068a88 (patch) | |
tree | 42e68340f6d2de2fcbd652ec10ab06c2f207cbbd /src | |
parent | 56a0c1d1e2868aa1bba421f16e4f917373f574ff (diff) | |
download | Qt-3d852917187e29892529ab51d24c1a1177068a88.zip Qt-3d852917187e29892529ab51d24c1a1177068a88.tar.gz Qt-3d852917187e29892529ab51d24c1a1177068a88.tar.bz2 |
QMap: make sure we never access forward and backward through typed Node structs
See the comment in the file why.
Reviewed-By: Olivier Goffart
Diffstat (limited to 'src')
-rw-r--r-- | src/corelib/tools/qmap.h | 20 |
1 files changed, 20 insertions, 0 deletions
diff --git a/src/corelib/tools/qmap.h b/src/corelib/tools/qmap.h index df0ae46..5696ba6 100644 --- a/src/corelib/tools/qmap.h +++ b/src/corelib/tools/qmap.h @@ -125,6 +125,10 @@ template <class Key, class T> struct QMapNode { Key key; T value; + +private: + // never access these members through this structure. + // see below QMapData::Node *backward; QMapData::Node *forward[1]; }; @@ -134,6 +138,22 @@ struct QMapPayloadNode { Key key; T value; + +private: + // QMap::e is a pointer to QMapData::Node, which matches the member + // below. However, the memory allocation node in QMapData::node_create + // allocates sizeof(QMapPayloNode) and incorrectly calculates the offset + // of 'backward' below. If the alignment of QMapPayloadNode is larger + // than the alignment of a pointer, the 'backward' member is aligned to + // the end of this structure, not to 'value' above, and will occupy the + // tail-padding area. + // + // e.g., on a 32-bit archictecture with Key = int and + // sizeof(T) = alignof(T) = 8 + // 0 4 8 12 16 20 24 byte + // | key | PAD | value |backward| PAD | correct layout + // | key | PAD | value | |backward| how it's actually used + // |<----- value of QMap::payload() = 20 ----->| QMapData::Node *backward; }; |