diff options
author | Lars Knoll <lars.knoll@qt.io> | 2020-06-02 15:51:15 +0200 |
---|---|---|
committer | Lars Knoll <lars.knoll@qt.io> | 2020-06-09 16:51:16 +0200 |
commit | d2833a3ce5af725d66ef9338f2a61b766dd3cb2d (patch) | |
tree | 3b74823b5f2da7cfd179e4faeed1697c4ff14d09 /src/corelib/tools/qarraydata.h | |
parent | fd856532d7472ccc6daf6a95d5c28264d9e6adca (diff) |
Ensure left/right/mid behave in a compatible way
QString and QStringRef did bounds checking for left/right/mid, whereas
QStringView was asserting on out of bounds.
Relax the behavior for QStringView and do bounds checking on pos/n
as well. This removes a source of potentially hidden errors when porting
from QStringRef (or QString) to QStringView.
Unfortunately, one difference remains, where QByteArray::left/right()
behaves differently (and somewhat more sane) than QString and
QStringRef. We're keeping the difference here, as it has been around
for many years.
Mark left/right/mid as obsolete and to be replaced with the new
first/last/slice methods.
Change-Id: I18c203799ba78c928a4610a6038089f27696c22e
Reviewed-by: MÃ¥rten Nordheim <marten.nordheim@qt.io>
Diffstat (limited to 'src/corelib/tools/qarraydata.h')
-rw-r--r-- | src/corelib/tools/qarraydata.h | 32 |
1 files changed, 31 insertions, 1 deletions
diff --git a/src/corelib/tools/qarraydata.h b/src/corelib/tools/qarraydata.h index b6fc05e108..de52713348 100644 --- a/src/corelib/tools/qarraydata.h +++ b/src/corelib/tools/qarraydata.h @@ -306,7 +306,37 @@ namespace QtPrivate { struct Q_CORE_EXPORT QContainerImplHelper { enum CutResult { Null, Empty, Full, Subset }; - static CutResult mid(int originalLength, int *position, int *length); + static constexpr CutResult mid(qsizetype originalLength, qsizetype *_position, qsizetype *_length) + { + qsizetype &position = *_position; + qsizetype &length = *_length; + if (position > originalLength) { + position = 0; + length = 0; + return Null; + } + + if (position < 0) { + if (length < 0 || length + position >= originalLength) { + position = 0; + length = originalLength; + return Full; + } + if (length + position <= 0) { + position = length = 0; + return Null; + } + length += position; + position = 0; + } else if (size_t(length) > size_t(originalLength - position)) { + length = originalLength - position; + } + + if (position == 0 && length == originalLength) + return Full; + + return length > 0 ? Subset : Empty; + } }; } |