summaryrefslogtreecommitdiffstats
path: root/src/corelib
diff options
context:
space:
mode:
authorPeter Kümmel <syntheticpp@gmx.net>2012-10-10 16:17:08 +0200
committerThe Qt Project <gerrit-noreply@qt-project.org>2012-10-11 02:47:40 +0200
commita47f21edd61ce033475743a35d6dad35f2e68c48 (patch)
treeaa96b4aefc2d651e2ea331d29a51d59bb2fa7a7f /src/corelib
parent191c0e300b8d625fa93939ecbff777469b816a44 (diff)
Make QVarLengthArray exception safe in case of OOM
After a exception is thrown in resize(), QVarLengthArray has an invalid state with ptr == 0. On the next resize call when malloc returns a valid pointer, oldPtr is 0 and it could crash in memcpy because the pointer to the source is 0. The patch ensures the valid pointer isn't overwritten with NULL. When exceptions are disabled the user must ensure that malloc will not fail. Change-Id: Id12a5e3e1eacc551e4d1b64cba8e8414cfebd6e1 Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
Diffstat (limited to 'src/corelib')
-rw-r--r--src/corelib/tools/qvarlengtharray.h48
1 files changed, 22 insertions, 26 deletions
diff --git a/src/corelib/tools/qvarlengtharray.h b/src/corelib/tools/qvarlengtharray.h
index a6c95e0cb7..90b10a3ed1 100644
--- a/src/corelib/tools/qvarlengtharray.h
+++ b/src/corelib/tools/qvarlengtharray.h
@@ -252,35 +252,31 @@ Q_OUTOFLINE_TEMPLATE void QVarLengthArray<T, Prealloc>::realloc(int asize, int a
const int copySize = qMin(asize, osize);
if (aalloc != a) {
- ptr = reinterpret_cast<T *>(malloc(aalloc * sizeof(T)));
- Q_CHECK_PTR(ptr);
- if (ptr) {
- s = 0;
- a = aalloc;
-
- if (QTypeInfo<T>::isStatic) {
- QT_TRY {
- // copy all the old elements
- while (s < copySize) {
- new (ptr+s) T(*(oldPtr+s));
- (oldPtr+s)->~T();
- s++;
- }
- } QT_CATCH(...) {
- // clean up all the old objects and then free the old ptr
- int sClean = s;
- while (sClean < osize)
- (oldPtr+(sClean++))->~T();
- if (oldPtr != reinterpret_cast<T *>(array) && oldPtr != ptr)
- free(oldPtr);
- QT_RETHROW;
+ T* newPtr = reinterpret_cast<T *>(malloc(aalloc * sizeof(T)));
+ Q_CHECK_PTR(newPtr); // could throw
+ // by design: in case of QT_NO_EXCEPTIONS malloc must not fail or it crashes here
+ ptr = newPtr;
+ s = 0;
+ a = aalloc;
+ if (QTypeInfo<T>::isStatic) {
+ QT_TRY {
+ // copy all the old elements
+ while (s < copySize) {
+ new (ptr+s) T(*(oldPtr+s));
+ (oldPtr+s)->~T();
+ s++;
}
- } else {
- memcpy(ptr, oldPtr, copySize * sizeof(T));
+ } QT_CATCH(...) {
+ // clean up all the old objects and then free the old ptr
+ int sClean = s;
+ while (sClean < osize)
+ (oldPtr+(sClean++))->~T();
+ if (oldPtr != reinterpret_cast<T *>(array) && oldPtr != ptr)
+ free(oldPtr);
+ QT_RETHROW;
}
} else {
- ptr = oldPtr;
- return;
+ memcpy(ptr, oldPtr, copySize * sizeof(T));
}
}
s = copySize;