diff options
Diffstat (limited to 'src/corelib/serialization')
-rw-r--r-- | src/corelib/serialization/qcborstream.cpp | 35 | ||||
-rw-r--r-- | src/corelib/serialization/qcborvalue.cpp | 27 |
2 files changed, 45 insertions, 17 deletions
diff --git a/src/corelib/serialization/qcborstream.cpp b/src/corelib/serialization/qcborstream.cpp index c598eee213..22748e49e1 100644 --- a/src/corelib/serialization/qcborstream.cpp +++ b/src/corelib/serialization/qcborstream.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2018 Intel Corporation. +** Copyright (C) 2020 Intel Corporation. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the QtCore module of the Qt Toolkit. @@ -39,6 +39,7 @@ #include "qcborstream.h" +#include <private/qbytearray_p.h> #include <private/qnumeric_p.h> #include <private/qutfcodec_p.h> #include <qbuffer.h> @@ -2282,6 +2283,10 @@ bool QCborStreamReader::next(int maxRecursion) } else if (isString() || isByteArray()) { auto r = _readByteArray_helper(); while (r.status == Ok) { + if (isString() && r.data.size() > MaxStringSize) { + d->handleError(CborErrorDataTooLarge); + break; + } if (isString() && !QUtf8::isValidUtf8(r.data, r.data.size()).isValidUtf8) { d->handleError(CborErrorInvalidUtf8TextString); break; @@ -2564,15 +2569,23 @@ QCborStreamReader::StringResult<QString> QCborStreamReader::_readString_helper() result.status = r.status; if (r.status == Ok) { - QTextCodec::ConverterState cs; - result.data = QUtf8::convertToUnicode(r.data, r.data.size(), &cs); - if (cs.invalidChars == 0 && cs.remainingChars == 0) - return result; + // See QUtf8::convertToUnicode() a detailed explanation of why this + // conversion uses the same number of words or less. + CborError err = CborNoError; + if (r.data.size() > MaxStringSize) { + err = CborErrorDataTooLarge; + } else { + QTextCodec::ConverterState cs; + result.data = QUtf8::convertToUnicode(r.data, r.data.size(), &cs); + if (cs.invalidChars != 0 || cs.remainingChars != 0) + err = CborErrorInvalidUtf8TextString; + } - d->handleError(CborErrorInvalidUtf8TextString); - result.data.clear(); - result.status = Error; - return result; + if (err) { + d->handleError(err); + result.data.clear(); + result.status = Error; + } } return result; } @@ -2600,6 +2613,10 @@ QCborStreamReader::StringResult<QByteArray> QCborStreamReader::_readByteArray_he qsizetype len = _currentStringChunkSize(); if (len < 0) return result; + if (len > MaxByteArraySize) { + d->handleError(CborErrorDataTooLarge); + return result; + } result.data.resize(len); auto r = readStringChunk(result.data.data(), len); diff --git a/src/corelib/serialization/qcborvalue.cpp b/src/corelib/serialization/qcborvalue.cpp index f4ceba3836..65abf8dba8 100644 --- a/src/corelib/serialization/qcborvalue.cpp +++ b/src/corelib/serialization/qcborvalue.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2018 Intel Corporation. +** Copyright (C) 2020 Intel Corporation. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the QtCore module of the Qt Toolkit. @@ -46,6 +46,7 @@ #include <qendian.h> #include <qlocale.h> +#include <private/qbytearray_p.h> #include <private/qnumeric_p.h> #include <private/qsimd_p.h> @@ -1534,6 +1535,8 @@ void QCborContainerPrivate::decodeStringFromCbor(QCborStreamReader &reader) // and calculate the final size if (add_overflow(offset, increment, &newSize)) return -1; + if (newSize > MaxByteArraySize) + return -1; // since usedData <= data.size(), this can't overflow usedData += increment; @@ -1608,13 +1611,6 @@ void QCborContainerPrivate::decodeStringFromCbor(QCborStreamReader &reader) setErrorInReader(reader, { QCborError::DataTooLarge }); } - if (r.status == QCborStreamReader::Error) { - // There can only be errors if there was data to be read. - Q_ASSERT(e.flags & Element::HasByteData); - data.truncate(e.value); - return; - } - // update size if (e.flags & Element::HasByteData) { auto b = new (dataPtr() + e.value) ByteData; @@ -1626,6 +1622,21 @@ void QCborContainerPrivate::decodeStringFromCbor(QCborStreamReader &reader) Q_ASSERT(e.type == QCborValue::String); e.flags |= Element::StringIsAscii; } + + // check that this UTF-8 text string can be loaded onto a QString + if (e.type == QCborValue::String) { + if (Q_UNLIKELY(b->len > MaxStringSize)) { + setErrorInReader(reader, { QCborError::DataTooLarge }); + r.status = QCborStreamReader::Error; + } + } + } + + if (r.status == QCborStreamReader::Error) { + // There can only be errors if there was data to be read. + Q_ASSERT(e.flags & Element::HasByteData); + data.truncate(e.value); + return; } elements.append(e); |