Revision control
++ -- Copyright (C) 2020 The Qt Company Ltd.
++ -- SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
++ -- Qt-Security score:critical reason:data-parser
++
++ %parser QXmlStreamGrammar
++ %impl qxmlstreamparser_p.h
++
++ %expect 4
++
++ %token NOTOKEN
++ %token SPACE " "
++ %token LANGLE "<"
++ %token RANGLE ">"
++ %token AMPERSAND "&"
++ %token HASH "#"
++ %token QUOTE "\'"
++ %token DBLQUOTE "\""
++ %token LBRACK "["
++ %token RBRACK "]"
++ %token LPAREN "("
++ %token RPAREN ")"
++ %token PIPE "|"
++ %token EQ "="
++ %token PERCENT "%"
++ %token SLASH "/"
++ %token COLON ":"
++ %token SEMICOLON ";"
++ %token COMMA ","
++ %token DASH "-"
++ %token PLUS "+"
++ %token STAR "*"
++ %token DOT "."
++ %token QUESTIONMARK "?"
++ %token BANG "!"
++ %token LETTER "[a-zA-Z]"
++ %token DIGIT "[0-9]"
++
++ -- after langle_bang
++ %token CDATA_START "[CDATA["
++ %token DOCTYPE "DOCTYPE"
++ %token ELEMENT "ELEMENT"
++ %token ATTLIST "ATTLIST"
++ %token ENTITY "ENTITY"
++ %token NOTATION "NOTATION"
++
++ -- entity decl
++ %token SYSTEM "SYSTEM"
++ %token PUBLIC "PUBLIC"
++ %token NDATA "NDATA"
++
++ -- default decl
++ %token REQUIRED "REQUIRED"
++ %token IMPLIED "IMPLIED"
++ %token FIXED "FIXED"
++
++ -- content spec
++ %token EMPTY "EMPTY"
++ %token ANY "ANY"
++ %token PCDATA "PCDATA"
++
++ -- error
++ %token XML_ERROR
++
++ -- entities
++ %token PARSE_ENTITY
++ %token ENTITY_DONE
++ %token UNRESOLVED_ENTITY
++
++ -- att type
++ %token CDATA "CDATA"
++ %token ID "ID"
++ %token IDREF "IDREF"
++ %token IDREFS "IDREFS"
++ %token ENTITY "ENTITY"
++ %token ENTITIES "ENTITIES"
++ %token NMTOKEN "NMTOKEN"
++ %token NMTOKENS "NMTOKENS"
++
++ -- xml declaration
++ %token XML "<?xml"
++ %token VERSION "version"
++
++ %nonassoc SHIFT_THERE
++ %nonassoc AMPERSAND
++ BANG
++ COLON
++ COMMA
++ DASH
++ DBLQUOTE
++ DIGIT
++ DOT
++ ENTITY_DONE
++ EQ
++ HASH
++ LBRACK
++ LETTER
++ LPAREN
++ PERCENT
++ PIPE
++ PLUS
++ QUESTIONMARK
++ QUOTE
++ RANGLE
++ RBRACK
++ RPAREN
++ SEMICOLON
++ SLASH
++ SPACE
++ STAR
++
++ %start document
++
++ /.// Copyright (C) 2020 The Qt Company Ltd.
++ // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
++ // Qt-Security score:critical reason:data-parser
++
++
++ //
++ // W A R N I N G
++ // -------------
++ //
++ // This file is not part of the Qt API. It exists purely as an
++ // implementation detail. This header file may change from version to
++ // version without notice, or even be removed.
++ //
++ // We mean it.
++ //
++
++ //
++ // W A R N I N G
++ // -------------
++ //
++ // This file is automatically generated from qxmlstream.g.
++ // Changes should be made to that file, not here. Any change to this file will
++ // be lost!
++ //
++ // To regenerate this file, run:
++ // qlalr --no-debug --no-lines --qt qxmlstream.g
++ //
++
++ #include <QtCore/private/qglobal_p.h>
++ #include <qxmlstream.h>
++ #include "qxmlstream_p.h"
++ #include "qxmlutils_p.h"
++ #include <qstringconverter.h>
++
++ #include <memory>
++
++ #ifndef QXMLSTREAMPARSER_P_H
++ #define QXMLSTREAMPARSER_P_H
++
++ QT_BEGIN_NAMESPACE
++
++ #if QT_CONFIG(xmlstreamreader)
++
++ bool QXmlStreamReaderPrivate::parse()
++ {
++ // cleanup currently reported token
++
++ using namespace Qt::StringLiterals;
++
++ switch (type) {
++ case QXmlStreamReader::StartElement:
++ name.clear();
++ prefix.clear();
++ qualifiedName.clear();
++ namespaceUri.clear();
++ publicNamespaceDeclarations.clear();
++ attributes.clear();
++ if (isEmptyElement) {
++ setType(QXmlStreamReader::EndElement);
++ Tag tag = tagStack_pop();
++ namespaceUri = tag.namespaceDeclaration.namespaceUri;
++ prefix = tag.namespaceDeclaration.prefix;
++ name = tag.name;
++ qualifiedName = tag.qualifiedName;
++ isEmptyElement = false;
++ return true;
++ }
++ clearTextBuffer();
++ break;
++ case QXmlStreamReader::EndElement:
++ name.clear();
++ prefix.clear();
++ qualifiedName.clear();
++ namespaceUri.clear();
++ clearTextBuffer();
++ break;
++ case QXmlStreamReader::DTD:
++ publicNotationDeclarations.clear();
++ publicEntityDeclarations.clear();
++ dtdName.clear();
++ dtdPublicId.clear();
++ dtdSystemId.clear();
++ Q_FALLTHROUGH();
++ case QXmlStreamReader::Comment:
++ case QXmlStreamReader::Characters:
++ isCDATA = false;
++ isWhitespace = true;
++ text.clear();
++ clearTextBuffer();
++ break;
++ case QXmlStreamReader::EntityReference:
++ text.clear();
++ name.clear();
++ clearTextBuffer();
++ break;
++ case QXmlStreamReader::ProcessingInstruction:
++ processingInstructionTarget.clear();
++ processingInstructionData.clear();
++ clearTextBuffer();
++ break;
++ case QXmlStreamReader::NoToken:
++ case QXmlStreamReader::Invalid:
++ break;
++ case QXmlStreamReader::StartDocument:
++ lockEncoding = true;
++ documentVersion.clear();
++ documentEncoding.clear();
++ if (decoder.isValid() && decoder.hasError()) {
++ raiseWellFormedError(QXmlStream::tr("Encountered incorrectly encoded content."));
++ readBuffer.clear();
++ return false;
++ }
++ Q_FALLTHROUGH();
++ case QXmlStreamReader::EndDocument:
++ clearTextBuffer();
++ }
++
++ setType(QXmlStreamReader::NoToken);
++
++
++ // the main parse loop
++ int act, r;
++
++ if (resumeReduction) {
++ act = state_stack[tos-1];
++ r = resumeReduction;
++ resumeReduction = 0;
++ goto ResumeReduction;
++ }
++
++ act = state_stack[tos];
++
++ while (true) {
++ if (token == -1 && - TERMINAL_COUNT != action_index[act]) {
++ uint cu = getChar();
++ token = NOTOKEN;
++ token_char = cu == ~0U ? cu : ushort(cu);
++ if ((cu != ~0U) && (cu & 0xff0000)) {
++ token = cu >> 16;
++ } else switch (token_char) {
++ case 0xfffe:
++ case 0xffff:
++ token = XML_ERROR;
++ break;
++ case '\r':
++ token = SPACE;
++ if (cu == '\r') {
++ if ((token_char = filterCarriageReturn())) {
++ ++lineNumber;
++ lastLineStart = characterOffset + readBufferPos;
++ break;
++ }
++ } else {
++ break;
++ }
++ Q_FALLTHROUGH();
++ case ~0U: {
++ token = EOF_SYMBOL;
++ if (!tagsDone && !inParseEntity) {
++ int a = t_action(act, token);
++ if (a < 0) {
++ raiseError(QXmlStreamReader::PrematureEndOfDocumentError);
++ return false;
++ }
++ }
++
++ } break;
++ case '\n':
++ ++lineNumber;
++ lastLineStart = characterOffset + readBufferPos;
++ Q_FALLTHROUGH();
++ case ' ':
++ case '\t':
++ token = SPACE;
++ break;
++ case '&':
++ token = AMPERSAND;
++ break;
++ case '#':
++ token = HASH;
++ break;
++ case '\'':
++ token = QUOTE;
++ break;
++ case '\"':
++ token = DBLQUOTE;
++ break;
++ case '<':
++ token = LANGLE;
++ break;
++ case '>':
++ token = RANGLE;
++ break;
++ case '[':
++ token = LBRACK;
++ break;
++ case ']':
++ token = RBRACK;
++ break;
++ case '(':
++ token = LPAREN;
++ break;
++ case ')':
++ token = RPAREN;
++ break;
++ case '|':
++ token = PIPE;
++ break;
++ case '=':
++ token = EQ;
++ break;
++ case '%':
++ token = PERCENT;
++ break;
++ case '/':
++ token = SLASH;
++ break;
++ case ':':
++ token = COLON;
++ break;
++ case ';':
++ token = SEMICOLON;
++ break;
++ case ',':
++ token = COMMA;
++ break;
++ case '-':
++ token = DASH;
++ break;
++ case '+':
++ token = PLUS;
++ break;
++ case '*':
++ token = STAR;
++ break;
++ case '.':
++ token = DOT;
++ break;
++ case '?':
++ token = QUESTIONMARK;
++ break;
++ case '!':
++ token = BANG;
++ break;
++ case '0':
++ case '1':
++ case '2':
++ case '3':
++ case '4':
++ case '5':
++ case '6':
++ case '7':
++ case '8':
++ case '9':
++ token = DIGIT;
++ break;
++ default:
++ if (cu < 0x20)
++ token = NOTOKEN;
++ else
++ token = LETTER;
++ break;
++ }
++ }
++
++ act = t_action (act, token);
++ if (act == ACCEPT_STATE) {
++ // reset the parser in case someone resumes (process instructions can follow a valid document)
++ tos = 0;
++ state_stack[tos++] = 0;
++ state_stack[tos] = 0;
++ return true;
++ } else if (act > 0) {
++ if (tos + 1 >= stack_size - 1)
++ reallocateStack();
++ ++tos;
++
++ Value &val = sym_stack[tos];
++ val.c = token_char;
++ val.pos = textBuffer.size();
++ val.prefix = 0;
++ val.len = 1;
++ if (token_char)
++ textBuffer += QChar(token_char);
++
++ state_stack[tos] = act;
++ token = -1;
++
++
++ } else if (act < 0) {
++ r = - act - 1;
++
++ #if defined (QLALR_DEBUG)
++ int ridx = rule_index[r];
++ printf ("%3d) %s ::=", r + 1, spell[rule_info[ridx]]);
++ ++ridx;
++ for (int i = ridx; i < ridx + rhs[r]; ++i) {
++ int symbol = rule_info[i];
++ if (const char *name = spell[symbol])
++ printf (" %s", name);
++ else
++ printf (" #%d", symbol);
++ }
++ printf ("\n");
++ #endif
++
++ tos -= rhs[r];
++ act = state_stack[tos++];
++ ResumeReduction:
++ switch (r) {
++ ./
++
++ document ::= PARSE_ENTITY content;
++ /.
++ case $rule_number:
++ setType(QXmlStreamReader::EndDocument);
++ break;
++ ./
++
++ document ::= prolog;
++ /.
++ case $rule_number:
++ if (type != QXmlStreamReader::Invalid) {
++ if (hasSeenTag || inParseEntity) {
++ setType(QXmlStreamReader::EndDocument);
++ } else {
++ raiseError(QXmlStreamReader::NotWellFormedError, QXmlStream::tr("Start tag expected."));
++ // reset the parser
++ tos = 0;
++ state_stack[tos++] = 0;
++ state_stack[tos] = 0;
++ return false;
++ }
++ }
++ break;
++ ./
++
++
++ prolog ::= prolog stag content etag;
++ prolog ::= prolog empty_element_tag;
++ prolog ::= prolog comment;
++ prolog ::= prolog xml_decl;
++ prolog ::= prolog processing_instruction;
++ prolog ::= prolog doctype_decl;
++ prolog ::= prolog SPACE;
++ prolog ::=;
++
++ entity_done ::= ENTITY_DONE;
++ /.
++ case $rule_number: {
++ auto reference = entityReferenceStack.pop();
++ auto it = reference.hash->find(reference.name);
++ Q_ASSERT(it != reference.hash->end());
++ it->isCurrentlyReferenced = false;
++ if (entityReferenceStack.isEmpty())
++ entityLength = 0;
++ clearSym();
++ } break;
++ ./
++
++
++ xml_decl_start ::= XML;
++ /.
++ case $rule_number:
++ if (!scanString(spell[VERSION], VERSION, false) && atEnd) {
++ resume($rule_number);
++ return false;
++ }
++ break;
++ ./
++
++ xml_decl ::= xml_decl_start VERSION space_opt EQ space_opt literal attribute_list_opt QUESTIONMARK RANGLE;
++ /.
++ case $rule_number:
++ setType(QXmlStreamReader::StartDocument);
++ documentVersion = symString(6);
++ startDocument();
++ break;
++ ./
++
++ external_id ::= SYSTEM literal;
++ /.
++ case $rule_number:
++ hasExternalDtdSubset = true;
++ dtdSystemId = symString(2);
++ break;
++ ./
++ external_id ::= PUBLIC public_literal space literal;
++ /.
++ case $rule_number:
++ checkPublicLiteral(symString(2));
++ dtdPublicId = symString(2);
++ dtdSystemId = symString(4);
++ hasExternalDtdSubset = true;
++ break;
++ ./
++ external_id ::=;
++
++ doctype_decl_start ::= langle_bang DOCTYPE qname space;
++ /.
++ case $rule_number:
++ if (!scanPublicOrSystem() && atEnd) {
++ resume($rule_number);
++ return false;
++ }
++ dtdName = symString(3);
++ break;
++ ./
++
++ doctype_decl ::= langle_bang DOCTYPE qname RANGLE;
++ /.
++ case $rule_number:./
++ doctype_decl ::= langle_bang DOCTYPE qname markup space_opt RANGLE;
++ /.
++ case $rule_number:
++ dtdName = symString(3);
++ Q_FALLTHROUGH();
++ ./
++ doctype_decl ::= doctype_decl_start external_id space_opt markup space_opt RANGLE;
++ /.
++ case $rule_number:./
++ doctype_decl ::= doctype_decl_start external_id space_opt RANGLE;
++ /.
++ case $rule_number:
++ setType(QXmlStreamReader::DTD);
++ text = &textBuffer;
++ break;
++ ./
++
++ markup_start ::= LBRACK;
++ /.
++ case $rule_number:
++ scanDtd = true;
++ break;
++ ./
++
++ markup ::= markup_start markup_list RBRACK;
++ /.
++ case $rule_number:
++ scanDtd = false;
++ break;
++ ./
++
++
++ markup_list ::= markup_decl | space | pereference;
++ markup_list ::= markup_list markup_decl | markup_list space | markup_list pereference;
++ markup_list ::=;
++
++ markup_decl ::= element_decl | attlist_decl | entity_decl | entity_done | notation_decl | processing_instruction | comment;
++
++
++ element_decl_start ::= langle_bang ELEMENT qname space;
++ /.
++ case $rule_number:
++ if (!scanString(spell[EMPTY], EMPTY, false)
++ && !scanString(spell[ANY], ANY, false)
++ && atEnd) {
++ resume($rule_number);
++ return false;
++ }
++ break;
++ ./
++
++ element_decl ::= element_decl_start content_spec space_opt RANGLE;
++
++
++ content_spec ::= EMPTY | ANY | mixed | children;
++
++ pcdata_start ::= HASH;
++ /.
++ case $rule_number:
++ if (!scanString(spell[PCDATA], PCDATA, false) && atEnd) {
++ resume($rule_number);
++ return false;
++ }
++ break;
++ ./
++
++ pcdata ::= pcdata_start PCDATA;
++
++ questionmark_or_star_or_plus_opt ::= QUESTIONMARK | STAR | PLUS;
++ questionmark_or_star_or_plus_opt ::=;
++
++ cp ::= qname questionmark_or_star_or_plus_opt | choice_or_seq questionmark_or_star_or_plus_opt;
++
++ cp_pipe_or_comma_list ::= cp space_opt;
++ cp_pipe_or_comma_list ::= cp space_opt PIPE space_opt cp_pipe_list space_opt;
++ cp_pipe_or_comma_list ::= cp space_opt COMMA space_opt cp_comma_list space_opt;
++ cp_pipe_list ::= cp | cp_pipe_list space_opt PIPE space_opt cp;
++ cp_comma_list ::= cp | cp_comma_list space_opt COMMA space_opt cp;
++
++
++ name_pipe_list ::= PIPE space_opt qname;
++ name_pipe_list ::= name_pipe_list space_opt PIPE space_opt qname;
++
++ star_opt ::= | STAR;
++
++ mixed ::= LPAREN space_opt pcdata space_opt RPAREN star_opt;
++ mixed ::= LPAREN space_opt pcdata space_opt name_pipe_list space_opt RPAREN STAR;
++
++ choice_or_seq ::= LPAREN space_opt cp_pipe_or_comma_list RPAREN;
++
++ children ::= choice_or_seq questionmark_or_star_or_plus_opt;
++
++
++ nmtoken_pipe_list ::= nmtoken;
++ nmtoken_pipe_list ::= nmtoken_pipe_list space_opt PIPE space_opt nmtoken;
++
++
++ att_type ::= CDATA;
++ /.
++ case $rule_number: {
++ lastAttributeIsCData = true;
++ } break;
++ ./
++ att_type ::= ID | IDREF | IDREFS | ENTITY | ENTITIES | NMTOKEN | NMTOKENS;
++ att_type ::= LPAREN space_opt nmtoken_pipe_list space_opt RPAREN space;
++ att_type ::= NOTATION LPAREN space_opt nmtoken_pipe_list space_opt RPAREN space;
++
++
++ default_declhash ::= HASH;
++ /.
++ case $rule_number:
++ if (!scanAfterDefaultDecl() && atEnd) {
++ resume($rule_number);
++ return false;
++ }
++ break;
++ ./
++
++ default_decl ::= default_declhash REQUIRED;
++ default_decl ::= default_declhash IMPLIED;
++ default_decl ::= attribute_value;
++ default_decl ::= default_declhash FIXED space attribute_value;
++ attdef_start ::= space qname space;
++ /.
++ case $rule_number:
++ sym(1) = sym(2);
++ lastAttributeValue.clear();
++ lastAttributeIsCData = false;
++ if (!scanAttType() && atEnd) {
++ resume($rule_number);
++ return false;
++ }
++ break;
++ ./
++
++ attdef ::= attdef_start att_type default_decl;
++ /.
++ case $rule_number: {
++ DtdAttribute &dtdAttribute = dtdAttributes.push();
++ dtdAttribute.tagName.clear();
++ dtdAttribute.isCDATA = lastAttributeIsCData;
++ auto symbol = symQName(1);
++ symbol.resetBackingStorage(addToStringStorage(symbol.all()));
++ dtdAttribute.attributePrefix = symbol.prefix();
++ dtdAttribute.attributeName = symbol.localPart();
++ dtdAttribute.attributeQualifiedName = symbol.qname();
++ dtdAttribute.isNamespaceAttribute = (dtdAttribute.attributePrefix == "xmlns"_L1
++ || (dtdAttribute.attributePrefix.isEmpty()
++ && dtdAttribute.attributeName == "xmlns"_L1));
++ if (lastAttributeValue.isNull()) {
++ dtdAttribute.defaultValue.clear();
++ } else {
++ if (dtdAttribute.isCDATA)
++ dtdAttribute.defaultValue = addToStringStorage(lastAttributeValue);
++ else
++ dtdAttribute.defaultValue = addToStringStorage(lastAttributeValue.toString().simplified());
++
++ }
++ } break;
++ ./
++
++ attdef_list ::= attdef;
++ attdef_list ::= attdef_list attdef;
++
++ attlist_decl ::= langle_bang ATTLIST qname space_opt RANGLE;
++ attlist_decl ::= langle_bang ATTLIST qname attdef_list space_opt RANGLE;
++ /.
++ case $rule_number: {
++ if (referenceToUnparsedEntityDetected && !standalone)
++ break;
++ qsizetype n = dtdAttributes.size();
++ XmlStringRef tagName = addToStringStorage(symName(3));
++ while (n--) {
++ DtdAttribute &dtdAttribute = dtdAttributes[n];
++ if (!dtdAttribute.tagName.isNull())
++ break;
++ dtdAttribute.tagName = tagName;
++ for (qsizetype i = 0; i < n; ++i) {
++ if ((dtdAttributes[i].tagName.isNull() || dtdAttributes[i].tagName == tagName)
++ && dtdAttributes[i].attributeQualifiedName == dtdAttribute.attributeQualifiedName) {
++ dtdAttribute.attributeQualifiedName.clear(); // redefined, delete it
++ break;
++ }
++ }
++ }
++ } break;
++ ./
++
++ entity_decl_start ::= langle_bang ENTITY name space;
++ /.
++ case $rule_number: {
++ if (!scanPublicOrSystem() && atEnd) {
++ resume($rule_number);
++ return false;
++ }
++ EntityDeclaration &entityDeclaration = entityDeclarations.push();
++ entityDeclaration.clear();
++ entityDeclaration.name = symString(3);
++ } break;
++ ./
++
++ entity_decl_start ::= langle_bang ENTITY PERCENT space name space;
++ /.
++ case $rule_number: {
++ if (!scanPublicOrSystem() && atEnd) {
++ resume($rule_number);
++ return false;
++ }
++ EntityDeclaration &entityDeclaration = entityDeclarations.push();
++ entityDeclaration.clear();
++ entityDeclaration.name = symString(5);
++ entityDeclaration.parameter = true;
++ } break;
++ ./
++
++ entity_decl_external ::= entity_decl_start SYSTEM literal;
++ /.
++ case $rule_number: {
++ if (!scanNData() && atEnd) {
++ resume($rule_number);
++ return false;
++ }
++ EntityDeclaration &entityDeclaration = entityDeclarations.top();
++ entityDeclaration.systemId = symString(3);
++ entityDeclaration.external = true;
++ } break;
++ ./
++
++ entity_decl_external ::= entity_decl_start PUBLIC public_literal space literal;
++ /.
++ case $rule_number: {
++ if (!scanNData() && atEnd) {
++ resume($rule_number);
++ return false;
++ }
++ EntityDeclaration &entityDeclaration = entityDeclarations.top();
++ checkPublicLiteral((entityDeclaration.publicId = symString(3)));
++ entityDeclaration.systemId = symString(5);
++ entityDeclaration.external = true;
++ } break;
++ ./
++
++ entity_decl ::= entity_decl_external NDATA name space_opt RANGLE;
++ /.
++ case $rule_number: {
++ EntityDeclaration &entityDeclaration = entityDeclarations.top();
++ entityDeclaration.notationName = symString(3);
++ if (entityDeclaration.parameter)
++ raiseWellFormedError(QXmlStream::tr("NDATA in parameter entity declaration."));
++ }
++ Q_FALLTHROUGH();
++ ./
++
++ entity_decl ::= entity_decl_external space_opt RANGLE;
++ /.
++ case $rule_number:./
++
++ entity_decl ::= entity_decl_start entity_value space_opt RANGLE;
++ /.
++ case $rule_number: {
++ if (referenceToUnparsedEntityDetected && !standalone) {
++ entityDeclarations.pop();
++ break;
++ }
++ EntityDeclaration &entityDeclaration = entityDeclarations.top();
++ if (!entityDeclaration.external)
++ entityDeclaration.value = symString(2);
++ auto &hash = entityDeclaration.parameter ? parameterEntityHash : entityHash;
++ if (!hash.contains(entityDeclaration.name)) {
++ Entity entity(entityDeclaration.name.toString(),
++ entityDeclaration.value.toString());
++ entity.unparsed = (!entityDeclaration.notationName.isNull());
++ entity.external = entityDeclaration.external;
++ hash.insert(qToStringViewIgnoringNull(entity.name), entity);
++ }
++ } break;
++ ./
++
++
++ processing_instruction ::= LANGLE QUESTIONMARK name space;
++ /.
++ case $rule_number: {
++ setType(QXmlStreamReader::ProcessingInstruction);
++ const qsizetype pos = sym(4).pos + sym(4).len;
++ processingInstructionTarget = symString(3);
++ if (scanUntil("?>")) {
++ processingInstructionData = XmlStringRef(&textBuffer, pos, textBuffer.size() - pos - 2);
++ if (!processingInstructionTarget.view().compare("xml"_L1, Qt::CaseInsensitive)) {
++ raiseWellFormedError(QXmlStream::tr("XML declaration not at start of document."));
++ }
++ else if (!QXmlUtils::isNCName(processingInstructionTarget))
++ raiseWellFormedError(QXmlStream::tr("%1 is an invalid processing instruction name.")
++ .arg(processingInstructionTarget));
++ } else if (type != QXmlStreamReader::Invalid){
++ resume($rule_number);
++ return false;
++ }
++ } break;
++ ./
++
++ processing_instruction ::= LANGLE QUESTIONMARK name QUESTIONMARK RANGLE;
++ /.
++ case $rule_number:
++ setType(QXmlStreamReader::ProcessingInstruction);
++ processingInstructionTarget = symString(3);
++ if (!processingInstructionTarget.view().compare("xml"_L1, Qt::CaseInsensitive))
++ raiseWellFormedError(QXmlStream::tr("Invalid processing instruction name."));
++ break;
++ ./
++
++
++ langle_bang ::= LANGLE BANG;
++ /.
++ case $rule_number:
++ if (!scanAfterLangleBang() && atEnd) {
++ resume($rule_number);
++ return false;
++ }
++ break;
++ ./
++
++ comment_start ::= langle_bang DASH DASH;
++ /.
++ case $rule_number:
++ if (!scanUntil("--")) {
++ resume($rule_number);
++ return false;
++ }
++ break;
++ ./
++
++ comment ::= comment_start RANGLE;
++ /.
++ case $rule_number: {
++ setType(QXmlStreamReader::Comment);
++ const qsizetype pos = sym(1).pos + 4;
++ text = XmlStringRef(&textBuffer, pos, textBuffer.size() - pos - 3);
++ } break;
++ ./
++
++
++ cdata ::= langle_bang CDATA_START;
++ /.
++ case $rule_number: {
++ setType(QXmlStreamReader::Characters);
++ isCDATA = true;
++ isWhitespace = false;
++ const qsizetype pos = sym(2).pos;
++ if (scanUntil("]]>", -1)) {
++ text = XmlStringRef(&textBuffer, pos, textBuffer.size() - pos - 3);
++ } else {
++ resume($rule_number);
++ return false;
++ }
++ } break;
++ ./
++
++ notation_decl_start ::= langle_bang NOTATION name space;
++ /.
++ case $rule_number: {
++ if (!scanPublicOrSystem() && atEnd) {
++ resume($rule_number);
++ return false;
++ }
++ NotationDeclaration ¬ationDeclaration = notationDeclarations.push();
++ notationDeclaration.name = symString(3);
++ } break;
++ ./
++
++ notation_decl ::= notation_decl_start SYSTEM literal space_opt RANGLE;
++ /.
++ case $rule_number: {
++ NotationDeclaration ¬ationDeclaration = notationDeclarations.top();
++ notationDeclaration.systemId = symString(3);
++ notationDeclaration.publicId.clear();
++ } break;
++ ./
++
++ notation_decl ::= notation_decl_start PUBLIC public_literal space_opt RANGLE;
++ /.
++ case $rule_number: {
++ NotationDeclaration ¬ationDeclaration = notationDeclarations.top();
++ notationDeclaration.systemId.clear();
++ checkPublicLiteral((notationDeclaration.publicId = symString(3)));
++ } break;
++ ./
++
++ notation_decl ::= notation_decl_start PUBLIC public_literal space literal space_opt RANGLE;
++ /.
++ case $rule_number: {
++ NotationDeclaration ¬ationDeclaration = notationDeclarations.top();
++ checkPublicLiteral((notationDeclaration.publicId = symString(3)));
++ notationDeclaration.systemId = symString(5);
++ } break;
++ ./
++
++
++
++ content_char ::= RANGLE | HASH | LBRACK | RBRACK | LPAREN | RPAREN | PIPE | EQ | PERCENT | SLASH | COLON | SEMICOLON | COMMA | DASH | PLUS | STAR | DOT | QUESTIONMARK | BANG | QUOTE | DBLQUOTE | LETTER | DIGIT;
++
++ scan_content_char ::= content_char;
++ /.
++ case $rule_number:
++ isWhitespace = false;
++ Q_FALLTHROUGH();
++ ./
++
++ scan_content_char ::= SPACE;
++ /.
++ case $rule_number:
++ sym(1).len += fastScanContentCharList();
++ if (atEnd && !inParseEntity) {
++ resume($rule_number);
++ return false;
++ }
++ break;
++ ./
++
++ content_char_list ::= content_char_list char_ref;
++ content_char_list ::= content_char_list entity_ref;
++ content_char_list ::= content_char_list entity_done;
++ content_char_list ::= content_char_list scan_content_char;
++ content_char_list ::= char_ref;
++ content_char_list ::= entity_ref;
++ content_char_list ::= entity_done;
++ content_char_list ::= scan_content_char;
++
++
++ character_content ::= content_char_list %prec SHIFT_THERE;
++ /.
++ case $rule_number:
++ if (!textBuffer.isEmpty()) {
++ setType(QXmlStreamReader::Characters);
++ text = &textBuffer;
++ }
++ break;
++ ./
++
++ literal ::= QUOTE QUOTE;
++ /.
++ case $rule_number:./
++ literal ::= DBLQUOTE DBLQUOTE;
++ /.
++ case $rule_number:
++ clearSym();
++ break;
++ ./
++ literal ::= QUOTE literal_content_with_dblquote QUOTE;
++ /.
++ case $rule_number:./
++ literal ::= DBLQUOTE literal_content_with_quote DBLQUOTE;
++ /.
++ case $rule_number:
++ sym(1) = sym(2);
++ break;
++ ./
++
++ literal_content_with_dblquote ::= literal_content_with_dblquote literal_content;
++ /.
++ case $rule_number:./
++ literal_content_with_quote ::= literal_content_with_quote literal_content;
++ /.
++ case $rule_number:./
++ literal_content_with_dblquote ::= literal_content_with_dblquote DBLQUOTE;
++ /.
++ case $rule_number:./
++ literal_content_with_quote ::= literal_content_with_quote QUOTE;
++ /.
++ case $rule_number:
++ sym(1).len += sym(2).len;
++ break;
++ ./
++ literal_content_with_dblquote ::= literal_content;
++ literal_content_with_quote ::= literal_content;
++ literal_content_with_dblquote ::= DBLQUOTE;
++ literal_content_with_quote ::= QUOTE;
++
++ literal_content_start ::= LETTER | DIGIT | RANGLE | HASH | LBRACK | RBRACK | LPAREN | RPAREN | PIPE | EQ | PERCENT | SLASH | COLON | SEMICOLON | COMMA | DASH | PLUS | STAR | DOT | QUESTIONMARK | BANG;
++
++ literal_content_start ::= SPACE;
++ /.
++ case $rule_number:
++ if (normalizeLiterals)
++ textBuffer.data()[textBuffer.size()-1] = u' ';
++ break;
++ ./
++
++ literal_content ::= literal_content_start;
++ /.
++ case $rule_number:
++ sym(1).len += fastScanLiteralContent();
++ if (atEnd) {
++ resume($rule_number);
++ return false;
++ }
++ break;
++ ./
++
++
++ public_literal ::= literal;
++ /.
++ case $rule_number: {
++ if (!QXmlUtils::isPublicID(symString(1))) {
++ raiseWellFormedError(QXmlStream::tr("%1 is an invalid PUBLIC identifier.").arg(symString(1)));
++ resume($rule_number);
++ return false;
++ }
++ } break;
++ ./
++
++ entity_value ::= QUOTE QUOTE;
++ /.
++ case $rule_number:./
++ entity_value ::= DBLQUOTE DBLQUOTE;
++ /.
++ case $rule_number:
++ clearSym();
++ break;
++ ./
++
++ entity_value ::= QUOTE entity_value_content_with_dblquote QUOTE;
++ /.
++ case $rule_number:./
++ entity_value ::= DBLQUOTE entity_value_content_with_quote DBLQUOTE;
++ /.
++ case $rule_number:
++ sym(1) = sym(2);
++ break;
++ ./
++
++ entity_value_content_with_dblquote ::= entity_value_content_with_dblquote entity_value_content;
++ /.
++ case $rule_number:./
++ entity_value_content_with_quote ::= entity_value_content_with_quote entity_value_content;
++ /.
++ case $rule_number:./
++ entity_value_content_with_dblquote ::= entity_value_content_with_dblquote DBLQUOTE;
++ /.
++ case $rule_number:./
++ entity_value_content_with_quote ::= entity_value_content_with_quote QUOTE;
++ /.
++ case $rule_number:
++ sym(1).len += sym(2).len;
++ break;
++ ./
++ entity_value_content_with_dblquote ::= entity_value_content;
++ entity_value_content_with_quote ::= entity_value_content;
++ entity_value_content_with_dblquote ::= DBLQUOTE;
++ entity_value_content_with_quote ::= QUOTE;
++
++ entity_value_content ::= LETTER | DIGIT | LANGLE | RANGLE | HASH | LBRACK | RBRACK | LPAREN | RPAREN | PIPE | EQ | SLASH | COLON | SEMICOLON | COMMA | SPACE | DASH | PLUS | STAR | DOT | QUESTIONMARK | BANG;
++ entity_value_content ::= char_ref | entity_ref_in_entity_value | entity_done;
++
++
++ attribute_value ::= QUOTE QUOTE;
++ /.
++ case $rule_number:./
++ attribute_value ::= DBLQUOTE DBLQUOTE;
++ /.
++ case $rule_number:
++ clearSym();
++ break;
++ ./
++ attribute_value ::= QUOTE attribute_value_content_with_dblquote QUOTE;
++ /.
++ case $rule_number:./
++ attribute_value ::= DBLQUOTE attribute_value_content_with_quote DBLQUOTE;
++ /.
++ case $rule_number:
++ sym(1) = sym(2);
++ lastAttributeValue = symString(1);
++ break;
++ ./
++
++ attribute_value_content_with_dblquote ::= attribute_value_content_with_dblquote attribute_value_content;
++ /.
++ case $rule_number:./
++ attribute_value_content_with_quote ::= attribute_value_content_with_quote attribute_value_content;
++ /.
++ case $rule_number:./
++ attribute_value_content_with_dblquote ::= attribute_value_content_with_dblquote DBLQUOTE;
++ /.
++ case $rule_number:./
++ attribute_value_content_with_quote ::= attribute_value_content_with_quote QUOTE;
++ /.
++ case $rule_number:
++ sym(1).len += sym(2).len;
++ break;
++ ./
++ attribute_value_content_with_dblquote ::= attribute_value_content | DBLQUOTE;
++ attribute_value_content_with_quote ::= attribute_value_content | QUOTE;
++
++ attribute_value_content ::= literal_content | char_ref | entity_ref_in_attribute_value | entity_done;
++
++ attribute ::= qname space_opt EQ space_opt attribute_value;
++ /.
++ case $rule_number: {
++ const XmlStringRef prfx = symPrefix(1);
++ if (prfx.isEmpty() && symString(1) == "xmlns"_L1 && namespaceProcessing) {
++ NamespaceDeclaration &namespaceDeclaration = namespaceDeclarations.push();
++ namespaceDeclaration.prefix.clear();
++
++ const XmlStringRef ns(symString(5));
++ if (ns.view() == "http://www.w3.org/2000/xmlns/"_L1 ||
++ ns.view() == "http://www.w3.org/XML/1998/namespace"_L1)
++ raiseWellFormedError(QXmlStream::tr("Illegal namespace declaration."));
++ else
++ namespaceDeclaration.namespaceUri = addToStringStorage(ns);
++ } else {
++ Attribute &attribute = attributeStack.push();
++ attribute.key = sym(1);
++ attribute.value = sym(5);
++
++ XmlStringRef attributeQualifiedName = symName(1);
++ bool normalize = false;
++ for (const DtdAttribute &dtdAttribute : std::as_const(dtdAttributes)) {
++ if (!dtdAttribute.isCDATA
++ && dtdAttribute.tagName == qualifiedName
++ && dtdAttribute.attributeQualifiedName == attributeQualifiedName
++ ) {
++ normalize = true;
++ break;
++ }
++ }
++ if (normalize) {
++ // normalize attribute value (simplify and trim)
++ const qsizetype pos = textBuffer.size();
++ qsizetype n = 0;
++ bool wasSpace = true;
++ for (qsizetype i = 0; i < attribute.value.len; ++i) {
++ QChar c = textBuffer.at(attribute.value.pos + i);
++ if (c.unicode() == ' ') {
++ if (wasSpace)
++ continue;
++ wasSpace = true;
++ } else {
++ wasSpace = false;
++ }
++ textBuffer += textBuffer.at(attribute.value.pos + i);
++ ++n;
++ }
++ if (wasSpace)
++ while (n && textBuffer.at(pos + n - 1).unicode() == ' ')
++ --n;
++ attribute.value.pos = pos;
++ attribute.value.len = n;
++ }
++ if (prfx == "xmlns"_L1 && namespaceProcessing) {
++ NamespaceDeclaration &namespaceDeclaration = namespaceDeclarations.push();
++ XmlStringRef namespacePrefix = symString(attribute.key);
++ XmlStringRef namespaceUri = symString(attribute.value);
++ attributeStack.pop();
++ if (((namespacePrefix == "xml"_L1)
++ ^ (namespaceUri == "http://www.w3.org/XML/1998/namespace"_L1))
++ || namespaceUri == "http://www.w3.org/2000/xmlns/"_L1
++ || namespaceUri.isEmpty()
++ || namespacePrefix == "xmlns"_L1)
++ raiseWellFormedError(QXmlStream::tr("Illegal namespace declaration."));
++
++ namespaceDeclaration.prefix = addToStringStorage(namespacePrefix);
++ namespaceDeclaration.namespaceUri = addToStringStorage(namespaceUri);
++ }
++ }
++ } break;
++ ./
++
++
++
++ attribute_list_opt ::= | space | space attribute_list space_opt;
++ attribute_list ::= attribute | attribute_list space attribute;
++
++ stag_start ::= LANGLE qname;
++ /.
++ case $rule_number: {
++ normalizeLiterals = true;
++ Tag &tag = tagStack_push();
++ auto symbol = symQName(2);
++ symbol.resetBackingStorage(addToStringStorage(symbol.all()));
++ prefix = tag.namespaceDeclaration.prefix = symbol.prefix();
++ name = tag.name = symbol.localPart();
++ qualifiedName = tag.qualifiedName = symbol.qname();
++ if ((!prefix.isEmpty() && !QXmlUtils::isNCName(prefix)) || !QXmlUtils::isNCName(name))
++ raiseWellFormedError(QXmlStream::tr("Invalid XML name."));
++ } break;
++ ./
++
++
++ empty_element_tag ::= stag_start attribute_list_opt SLASH RANGLE;
++ /.
++ case $rule_number:
++ isEmptyElement = true;
++ Q_FALLTHROUGH();
++ ./
++
++
++ stag ::= stag_start attribute_list_opt RANGLE;
++ /.
++ case $rule_number:
++ setType(QXmlStreamReader::StartElement);
++ resolveTag();
++ if (tagStack.size() == 1 && hasSeenTag && !inParseEntity)
++ raiseWellFormedError(QXmlStream::tr("Extra content at end of document."));
++ hasSeenTag = true;
++ break;
++ ./
++
++
++ etag ::= LANGLE SLASH qname space_opt RANGLE;
++ /.
++ case $rule_number: {
++ setType(QXmlStreamReader::EndElement);
++ Tag tag = tagStack_pop();
++
++ namespaceUri = tag.namespaceDeclaration.namespaceUri;
++ prefix = tag.namespaceDeclaration.prefix;
++ name = tag.name;
++ qualifiedName = tag.qualifiedName;
++ if (qualifiedName != symName(3))
++ raiseWellFormedError(QXmlStream::tr("Opening and ending tag mismatch."));
++ } break;
++ ./
++
++
++ unresolved_entity ::= UNRESOLVED_ENTITY;
++ /.
++ case $rule_number:
++ if (entitiesMustBeDeclared()) {
++ raiseWellFormedError(QXmlStream::tr("Entity '%1' not declared.").arg(unresolvedEntity));
++ break;
++ }
++ setType(QXmlStreamReader::EntityReference);
++ name = &unresolvedEntity;
++ break;
++ ./
++
++ entity_ref ::= AMPERSAND name SEMICOLON;
++ /.
++ case $rule_number: {
++ sym(1).len += sym(2).len + 1;
++ QStringView reference = symView(2);
++ if (const auto it = entityHash.find(reference); it != entityHash.end()) {
++ Entity &entity = *it;
++ if (entity.unparsed) {
++ raiseWellFormedError(QXmlStream::tr("Reference to unparsed entity '%1'.").arg(reference));
++ } else {
++ if (!entity.hasBeenParsed) {
++ parseEntity(entity.value);
++ entity.hasBeenParsed = true;
++ }
++ if (entity.literal)
++ putStringLiteral(entity.value);
++ else if (referenceEntity(&entityHash, entity))
++ putReplacement(entity.value);
++ textBuffer.chop(2 + sym(2).len);
++ clearSym();
++ }
++ break;
++ }
++
++ if (entityResolver) {
++ QString replacementText = resolveUndeclaredEntity(reference.toString());
++ if (!replacementText.isNull()) {
++ putReplacement(replacementText);
++ textBuffer.chop(2 + sym(2).len);
++ clearSym();
++ break;
++ }
++ }
++
++ injectToken(UNRESOLVED_ENTITY);
++ unresolvedEntity = symString(2).toString();
++ textBuffer.chop(2 + sym(2).len);
++ clearSym();
++
++ } break;
++ ./
++
++ pereference ::= PERCENT name SEMICOLON;
++ /.
++ case $rule_number: {
++ sym(1).len += sym(2).len + 1;
++ QStringView reference = symView(2);
++ if (const auto it = parameterEntityHash.find(reference); it != parameterEntityHash.end()) {
++ referenceToParameterEntityDetected = true;
++ Entity &entity = *it;
++ if (entity.unparsed || entity.external) {
++ referenceToUnparsedEntityDetected = true;
++ } else {
++ if (referenceEntity(¶meterEntityHash, entity))
++ putString(entity.value);
++ textBuffer.chop(2 + sym(2).len);
++ clearSym();
++ }
++ } else if (entitiesMustBeDeclared()) {
++ raiseWellFormedError(QXmlStream::tr("Entity '%1' not declared.").arg(symString(2)));
++ }
++ } break;
++ ./
++
++
++
++ entity_ref_in_entity_value ::= AMPERSAND name SEMICOLON;
++ /.
++ case $rule_number:
++ sym(1).len += sym(2).len + 1;
++ break;
++ ./
++
++ entity_ref_in_attribute_value ::= AMPERSAND name SEMICOLON;
++ /.
++ case $rule_number: {
++ sym(1).len += sym(2).len + 1;
++ QStringView reference = symView(2);
++ if (const auto it = entityHash.find(reference); it != entityHash.end()) {
++ Entity &entity = *it;
++ if (entity.unparsed || entity.value.isNull()) {
++ raiseWellFormedError(QXmlStream::tr("Reference to external entity '%1' in attribute value.").arg(reference));
++ break;
++ }
++ if (!entity.hasBeenParsed) {
++ parseEntity(entity.value);
++ entity.hasBeenParsed = true;
++ }
++ if (entity.literal)
++ putStringLiteral(entity.value);
++ else if (referenceEntity(&entityHash, entity))
++ putReplacementInAttributeValue(entity.value);
++ textBuffer.chop(2 + sym(2).len);
++ clearSym();
++ break;
++ }
++
++ if (entityResolver) {
++ QString replacementText = resolveUndeclaredEntity(reference.toString());
++ if (!replacementText.isNull()) {
++ putReplacement(replacementText);
++ textBuffer.chop(2 + sym(2).len);
++ clearSym();
++ break;
++ }
++ }
++ if (entitiesMustBeDeclared()) {
++ raiseWellFormedError(QXmlStream::tr("Entity '%1' not declared.").arg(reference));
++ }
++ } break;
++ ./
++
++ char_ref ::= AMPERSAND HASH char_ref_value SEMICOLON;
++ /.
++ case $rule_number: {
++ if (char32_t s = resolveCharRef(3)) {
++ putStringLiteral(QChar::fromUcs4(s));
++ textBuffer.chop(3 + sym(3).len);
++ clearSym();
++ } else {
++ raiseWellFormedError(QXmlStream::tr("Invalid character reference."));
++ }
++ } break;
++ ./
++
++
++ char_ref_value ::= LETTER | DIGIT;
++ char_ref_value ::= char_ref_value LETTER;
++ /.
++ case $rule_number:./
++ char_ref_value ::= char_ref_value DIGIT;
++ /.
++ case $rule_number:
++ sym(1).len += sym(2).len;
++ break;
++ ./
++
++
++ content ::= content character_content;
++ content ::= content stag content etag;
++ content ::= content empty_element_tag;
++ content ::= content comment;
++ content ::= content cdata;
++ content ::= content xml_decl;
++ content ::= content processing_instruction;
++ content ::= content doctype_decl;
++ content ::= content unresolved_entity;
++ content ::= ;
++
++
++ space ::= SPACE;
++ /.
++ case $rule_number:
++ sym(1).len += fastScanSpace();
++ if (atEnd) {
++ resume($rule_number);
++ return false;
++ }
++ break;
++ ./
++
++
++ space_opt ::=;
++ space_opt ::= space;
++
++ qname ::= LETTER;
++ /.
++ case $rule_number: {
++ Value &val = sym(1);
++ if (auto res = fastScanName(&val))
++ val.len += *res;
++ else
++ return false;
++
++ if (atEnd) {
++ resume($rule_number);
++ return false;
++ }
++ } break;
++ ./
++
++ name ::= LETTER;
++ /.
++ case $rule_number:
++ if (auto res = fastScanName())
++ sym(1).len += *res;
++ else
++ return false;
++
++ if (atEnd) {
++ resume($rule_number);
++ return false;
++ }
++ break;
++ ./
++
++ nmtoken ::= LETTER;
++ /.
++ case $rule_number:./
++ nmtoken ::= DIGIT;
++ /.
++ case $rule_number:./
++ nmtoken ::= DOT;
++ /.
++ case $rule_number:./
++ nmtoken ::= DASH;
++ /.
++ case $rule_number:./
++ nmtoken ::= COLON;
++ /.
++ case $rule_number:
++ sym(1).len += fastScanNMTOKEN();
++ if (atEnd) {
++ resume($rule_number);
++ return false;
++ }
++
++ break;
++ ./
++
++
++ /.
++ default:
++ ;
++ } // switch
++ act = state_stack[tos] = nt_action (act, lhs[r] - TERMINAL_COUNT);
++ if (type != QXmlStreamReader::NoToken)
++ return true;
++ } else {
++ parseError();
++ break;
++ }
++ }
++ return false;
++ }
++
++ #endif // feature xmlstreamreader
++
++ QT_END_NAMESPACE
++
++ #endif
++
++ ./