summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorEdward Welbourne <edward.welbourne@qt.io>2019-02-07 17:04:49 +0100
committerEdward Welbourne <edward.welbourne@qt.io>2019-02-08 13:56:25 +0000
commitc066656aff4841f9095e77754fa7533f7bbbb66a (patch)
tree6a77a0c39aa28b81fb901db5296eed145ea66078 /src
parentb611eb81c822ed2bcd3107ba098b56952ae0685c (diff)
Avoid read-outside-array error by QStringRef over-reach
Constructing a QStringRef directly from the string, offset and a length is UB if the offset + length exceeds the string's length. Thanks to Robert Loehning and libFuzzer for finding this. QString::midRef (as correctly used in both changed uses of QStringRef, since 432d3b69629) takes care of that for us. Changed one UB case and a matching but correct case, for consistency. In the process, deduplicate a QStringList look-up. Added tests to exercise the code (but the one that exercises the formerly UB case doesn't crash before the fix, so isn't very useful; the invalid read is only outside the array it's scanning, not outside allocated memory). Change-Id: I7051bbbc0267dd7ec0a8f75eee2034d0b7eb75a2 Reviewed-by: Anton Kudryavtsev <antkudr@mail.ru> Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
Diffstat (limited to 'src')
-rw-r--r--src/corelib/tools/qdatetimeparser.cpp11
1 files changed, 6 insertions, 5 deletions
diff --git a/src/corelib/tools/qdatetimeparser.cpp b/src/corelib/tools/qdatetimeparser.cpp
index e6afd510fd..e8470f6cde 100644
--- a/src/corelib/tools/qdatetimeparser.cpp
+++ b/src/corelib/tools/qdatetimeparser.cpp
@@ -1125,13 +1125,14 @@ QDateTimeParser::scanString(const QDateTime &defaultValue,
for (int index = 0; index < sectionNodesCount; ++index) {
Q_ASSERT(state != Invalid);
- if (QStringRef(input, pos, separators.at(index).size()) != separators.at(index)) {
- QDTPDEBUG << "invalid because" << input->midRef(pos, separators.at(index).size())
- << "!=" << separators.at(index)
+ const QString &separator = separators.at(index);
+ if (input->midRef(pos, separator.size()) != separator) {
+ QDTPDEBUG << "invalid because" << input->midRef(pos, separator.size())
+ << "!=" << separator
<< index << pos << currentSectionIndex;
return StateNode();
}
- pos += separators.at(index).size();
+ pos += separator.size();
sectionNodes[index].pos = pos;
int *current = 0;
const SectionNode sn = sectionNodes.at(index);
@@ -1227,7 +1228,7 @@ QDateTimeParser::scanString(const QDateTime &defaultValue,
isSet |= sn.type;
}
- if (QStringRef(input, pos, input->size() - pos) != separators.last()) {
+ if (input->midRef(pos) != separators.last()) {
QDTPDEBUG << "invalid because" << input->midRef(pos)
<< "!=" << separators.last() << pos;
return StateNode();