diff options
author | Ye ShanShan <yeshanshan@uniontech.com> | 2022-06-10 13:53:40 +0800 |
---|---|---|
committer | Ye ShanShan <yeshanshan@uniontech.com> | 2022-06-23 02:18:39 +0800 |
commit | c3b959733a739e9b2fc00b2af469fa44f3048e29 (patch) | |
tree | 3c16d07bef71219e70801dec7203fc751c194171 /src/xml/dom/qdomhelpers.cpp | |
parent | 5271f5082cd5413c618fc464fbeea6529626838b (diff) |
Add QDom internalSubset implementation
QDom's internalSubset() always returned empty because nothing
actually set the internal data member it returns. When parsing
the DECLTYPE, extract the internal subset and save it to the
doctype()'s member when present.
Pick-to: 5.15 6.2 6.3 6.4
Fixes: QTBUG-53661
Change-Id: I6e41ff8b914381168246073b3289d82205b1c255
Reviewed-by: Sona Kurazyan <sona.kurazyan@qt.io>
Diffstat (limited to 'src/xml/dom/qdomhelpers.cpp')
-rw-r--r-- | src/xml/dom/qdomhelpers.cpp | 31 |
1 files changed, 31 insertions, 0 deletions
diff --git a/src/xml/dom/qdomhelpers.cpp b/src/xml/dom/qdomhelpers.cpp index 39c7dcd360..b58d2f7ae9 100644 --- a/src/xml/dom/qdomhelpers.cpp +++ b/src/xml/dom/qdomhelpers.cpp @@ -52,6 +52,35 @@ bool QDomBuilder::startDTD(const QString &name, const QString &publicId, const Q return true; } +QString QDomBuilder::dtdInternalSubset(const QString &dtd) +{ + // https://www.w3.org/TR/xml/#NT-intSubset + // doctypedecl: '<!DOCTYPE' S Name (S ExternalID)? S? ('[' intSubset ']' S?)? '>' + const QString &name = doc->doctype()->name; + QStringView tmp = QStringView(dtd).sliced(dtd.indexOf(name) + name.size()); + + const QString &publicId = doc->doctype()->publicId; + if (!publicId.isEmpty()) + tmp = tmp.sliced(tmp.indexOf(publicId) + publicId.size()); + + const QString &systemId = doc->doctype()->systemId; + if (!systemId.isEmpty()) + tmp = tmp.sliced(tmp.indexOf(systemId) + systemId.size()); + + const qsizetype obra = tmp.indexOf(u'['); + const qsizetype cbra = tmp.lastIndexOf(u']'); + if (obra >= 0 && cbra >= 0) + return tmp.left(cbra).sliced(obra + 1).toString(); + + return QString(); +} + +bool QDomBuilder::parseDTD(const QString &dtd) +{ + doc->doctype()->internalSubset = dtdInternalSubset(dtd); + return true; +} + bool QDomBuilder::startElement(const QString &nsURI, const QString &qName, const QXmlStreamAttributes &atts) { @@ -272,6 +301,8 @@ bool QDomParser::parseProlog() QDomParser::tr("Error occurred while processing document type declaration")); return false; } + if (!domBuilder.parseDTD(reader->text().toString())) + return false; if (!parseMarkupDecl()) return false; break; |