QXmlStreamReader: make fastScanName() indicate parsing status to callers
authorDebian Qt/KDE Maintainers <debian-qt-kde@lists.debian.org>
Sat, 17 Feb 2024 12:11:37 +0000 (15:11 +0300)
committerDmitry Shachnev <mitya57@debian.org>
Sat, 17 Feb 2024 12:11:37 +0000 (15:11 +0300)
commit8f1f960a8d8299424d7f175617c5cfa4a4d4ef68
tree4b0283c9dfd1bc95d10133adb965dc8ceeafa5e6
parentb498f1bdf7d483f1a8c05ef02acd365e7f0958da
QXmlStreamReader: make fastScanName() indicate parsing status to callers

Origin: upstream, commits
 https://code.qt.io/cgit/qt/qtbase.git/commit/?id=1a423ce4372d18a7
 https://code.qt.io/cgit/qt/qtbase.git/commit/?id=6326bec46a618c72
 https://code.qt.io/cgit/qt/qtbase.git/commit/?id=bdc8dc51380d2ce4
 https://code.qt.io/cgit/qt/qtbase.git/commit/?id=3bc3b8d69a291aa5
 .
 Based on KDE's backport:
 https://invent.kde.org/qt/qt/qtbase/-/merge_requests/263
Last-Update: 2023-07-15

This fixes a crash while parsing an XML file with garbage data, the file
starts with '<' then garbage data:
- The loop in the parse() keeps iterating until it hits "case 262:",
  which calls fastScanName()
- fastScanName() iterates over the text buffer scanning for the
  attribute name (e.g. "xml:lang"), until it finds ':'
- Consider a Value val, fastScanName() is called on it, it would set
  val.prefix to a number > val.len, then it would hit the 4096 condition
  and return (returned 0, now it returns the equivalent of
  std::null_opt), which means that val.len doesn't get modified, making
  it smaller than val.prefix
- The code would try constructing an XmlStringRef with negative length,
  which would hit an assert in one of QStringView's constructors

Add an assert to the XmlStringRef constructor.

Add unittest based on the file from the bug report.

Credit to OSS-Fuzz.

Gbp-Pq: Name CVE-2023-37369.diff
src/corelib/serialization/qxmlstream.cpp
src/corelib/serialization/qxmlstream.g
src/corelib/serialization/qxmlstream_p.h
tests/auto/corelib/serialization/qxmlstream/tst_qxmlstream.cpp