Coverage Report

Created: 2025-11-16 07:45

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/qtbase/src/xml/dom/qdomhelpers.cpp
Line
Count
Source
1
/****************************************************************************
2
**
3
** Copyright (C) 2019 The Qt Company Ltd.
4
** Contact: https://www.qt.io/licensing/
5
**
6
** This file is part of the QtXml module of the Qt Toolkit.
7
**
8
** $QT_BEGIN_LICENSE:LGPL$
9
** Commercial License Usage
10
** Licensees holding valid commercial Qt licenses may use this file in
11
** accordance with the commercial license agreement provided with the
12
** Software or, alternatively, in accordance with the terms contained in
13
** a written agreement between you and The Qt Company. For licensing terms
14
** and conditions see https://www.qt.io/terms-conditions. For further
15
** information use the contact form at https://www.qt.io/contact-us.
16
**
17
** GNU Lesser General Public License Usage
18
** Alternatively, this file may be used under the terms of the GNU Lesser
19
** General Public License version 3 as published by the Free Software
20
** Foundation and appearing in the file LICENSE.LGPL3 included in the
21
** packaging of this file. Please review the following information to
22
** ensure the GNU Lesser General Public License version 3 requirements
23
** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
24
**
25
** GNU General Public License Usage
26
** Alternatively, this file may be used under the terms of the GNU
27
** General Public License version 2.0 or (at your option) the GNU General
28
** Public license version 3 or any later version approved by the KDE Free
29
** Qt Foundation. The licenses are as published by the Free Software
30
** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
31
** included in the packaging of this file. Please review the following
32
** information to ensure the GNU General Public License requirements will
33
** be met: https://www.gnu.org/licenses/gpl-2.0.html and
34
** https://www.gnu.org/licenses/gpl-3.0.html.
35
**
36
** $QT_END_LICENSE$
37
**
38
****************************************************************************/
39
40
#include <QtXml/qtxmlglobal.h>
41
42
#ifndef QT_NO_DOM
43
44
#include "qdomhelpers_p.h"
45
#include "qdom_p.h"
46
#include "qxmlstream.h"
47
#include "private/qxml_p.h"
48
49
QT_BEGIN_NAMESPACE
50
51
#if QT_DEPRECATED_SINCE(5, 15)
52
53
/**************************************************************
54
 *
55
 * QDomHandler
56
 *
57
 **************************************************************/
58
QT_WARNING_PUSH
59
QT_WARNING_DISABLE_DEPRECATED
60
QDomHandler::QDomHandler(QDomDocumentPrivate *adoc, QXmlSimpleReader *areader,
61
                         bool namespaceProcessing)
62
0
    : cdata(false), reader(areader), domBuilder(adoc, &locator, namespaceProcessing)
63
0
{
64
0
}
65
66
0
QDomHandler::~QDomHandler() {}
67
68
bool QDomHandler::endDocument()
69
0
{
70
0
    return domBuilder.endDocument();
71
0
}
72
73
bool QDomHandler::startDTD(const QString &name, const QString &publicId, const QString &systemId)
74
0
{
75
0
    return domBuilder.startDTD(name, publicId, systemId);
76
0
}
77
78
bool QDomHandler::startElement(const QString &nsURI, const QString &, const QString &qName,
79
                               const QXmlAttributes &atts)
80
0
{
81
0
    return domBuilder.startElement(nsURI, qName, atts);
82
0
}
83
84
bool QDomHandler::endElement(const QString &, const QString &, const QString &)
85
0
{
86
0
    return domBuilder.endElement();
87
0
}
88
89
bool QDomHandler::characters(const QString &ch)
90
0
{
91
0
    return domBuilder.characters(ch, cdata);
92
0
}
93
94
bool QDomHandler::processingInstruction(const QString &target, const QString &data)
95
0
{
96
0
    return domBuilder.processingInstruction(target, data);
97
0
}
98
99
bool QDomHandler::skippedEntity(const QString &name)
100
0
{
101
    // we can only handle inserting entity references into content
102
0
    if (reader && !reader->d_ptr->skipped_entity_in_content)
103
0
        return true;
104
105
0
    return domBuilder.skippedEntity(name);
106
0
}
107
108
bool QDomHandler::fatalError(const QXmlParseException &exception)
109
0
{
110
0
    domBuilder.errorMsg = exception.message();
111
0
    domBuilder.errorLine = exception.lineNumber();
112
0
    domBuilder.errorColumn = exception.columnNumber();
113
0
    return QXmlDefaultHandler::fatalError(exception);
114
0
}
115
116
bool QDomHandler::startCDATA()
117
0
{
118
0
    cdata = true;
119
0
    return true;
120
0
}
121
122
bool QDomHandler::endCDATA()
123
0
{
124
0
    cdata = false;
125
0
    return true;
126
0
}
127
128
bool QDomHandler::startEntity(const QString &name)
129
0
{
130
0
    return domBuilder.startEntity(name);
131
0
}
132
133
bool QDomHandler::endEntity(const QString &)
134
0
{
135
0
    return domBuilder.endEntity();
136
0
}
137
138
bool QDomHandler::comment(const QString &ch)
139
0
{
140
0
    return domBuilder.comment(ch);
141
0
}
142
143
bool QDomHandler::unparsedEntityDecl(const QString &name, const QString &publicId,
144
                                     const QString &systemId, const QString &notationName)
145
0
{
146
0
    return domBuilder.unparsedEntityDecl(name, publicId, systemId, notationName);
147
0
}
148
149
bool QDomHandler::externalEntityDecl(const QString &name, const QString &publicId,
150
                                     const QString &systemId)
151
0
{
152
0
    return unparsedEntityDecl(name, publicId, systemId, QString());
153
0
}
154
155
bool QDomHandler::notationDecl(const QString &name, const QString &publicId,
156
                               const QString &systemId)
157
0
{
158
0
    return domBuilder.notationDecl(name, publicId, systemId);
159
0
}
160
161
void QDomHandler::setDocumentLocator(QXmlLocator *locator)
162
0
{
163
0
    this->locator.setLocator(locator);
164
0
}
165
166
QDomBuilder::ErrorInfo QDomHandler::errorInfo() const
167
0
{
168
0
    return domBuilder.error();
169
0
}
170
QT_WARNING_POP
171
172
#endif // QT_DEPRECATED_SINCE(5, 15)
173
174
/**************************************************************
175
 *
176
 * QXmlDocumentLocators
177
 *
178
 **************************************************************/
179
180
int QDomDocumentLocator::column() const
181
0
{
182
0
    Q_ASSERT(reader);
183
0
    return static_cast<int>(reader->columnNumber());
184
0
}
185
186
int QDomDocumentLocator::line() const
187
0
{
188
0
    Q_ASSERT(reader);
189
0
    return static_cast<int>(reader->lineNumber());
190
0
}
191
192
#if QT_DEPRECATED_SINCE(5, 15)
193
194
QT_WARNING_PUSH
195
QT_WARNING_DISABLE_DEPRECATED
196
197
void QSAXDocumentLocator::setLocator(QXmlLocator *l)
198
0
{
199
0
    locator = l;
200
0
}
201
202
int QSAXDocumentLocator::column() const
203
0
{
204
0
    if (!locator)
205
0
        return 0;
206
207
0
    return static_cast<int>(locator->columnNumber());
208
0
}
209
210
int QSAXDocumentLocator::line() const
211
0
{
212
0
    if (!locator)
213
0
        return 0;
214
215
0
    return static_cast<int>(locator->lineNumber());
216
0
}
217
218
QT_WARNING_POP
219
220
#endif // QT_DEPRECATED_SINCE(5, 15)
221
222
/**************************************************************
223
 *
224
 * QDomBuilder
225
 *
226
 **************************************************************/
227
228
QDomBuilder::QDomBuilder(QDomDocumentPrivate *d, QXmlDocumentLocator *l, bool namespaceProcessing)
229
0
    : errorLine(0),
230
0
      errorColumn(0),
231
0
      doc(d),
232
0
      node(d),
233
0
      locator(l),
234
0
      nsProcessing(namespaceProcessing)
235
0
{
236
0
}
237
238
0
QDomBuilder::~QDomBuilder() {}
239
240
bool QDomBuilder::endDocument()
241
0
{
242
    // ### is this really necessary? (rms)
243
0
    if (node != doc)
244
0
        return false;
245
0
    return true;
246
0
}
247
248
bool QDomBuilder::startDTD(const QString &name, const QString &publicId, const QString &systemId)
249
0
{
250
0
    doc->doctype()->name = name;
251
0
    doc->doctype()->publicId = publicId;
252
0
    doc->doctype()->systemId = systemId;
253
0
    return true;
254
0
}
255
256
#if QT_DEPRECATED_SINCE(5, 15)
257
258
QT_WARNING_PUSH
259
QT_WARNING_DISABLE_DEPRECATED
260
bool QDomBuilder::startElement(const QString &nsURI, const QString &qName,
261
                               const QXmlAttributes &atts)
262
0
{
263
    // tag name
264
0
    QDomNodePrivate *n;
265
0
    if (nsProcessing) {
266
0
        n = doc->createElementNS(nsURI, qName);
267
0
    } else {
268
0
        n = doc->createElement(qName);
269
0
    }
270
271
0
    if (!n)
272
0
        return false;
273
274
0
    n->setLocation(locator->line(), locator->column());
275
276
0
    node->appendChild(n);
277
0
    node = n;
278
279
    // attributes
280
0
    for (int i = 0; i < atts.length(); i++) {
281
0
        auto domElement = static_cast<QDomElementPrivate *>(node);
282
0
        if (nsProcessing)
283
0
            domElement->setAttributeNS(atts.uri(i), atts.qName(i), atts.value(i));
284
0
        else
285
0
            domElement->setAttribute(atts.qName(i), atts.value(i));
286
0
    }
287
288
0
    return true;
289
0
}
290
QT_WARNING_POP
291
292
#endif // QT_DEPRECATED_SINCE(5, 15)
293
294
inline QString stringRefToString(const QStringRef &stringRef)
295
0
{
296
    // Calling QStringRef::toString() on a NULL QStringRef in some cases returns
297
    // an empty string (i.e. QString("")) instead of a NULL string (i.e. QString()).
298
    // QDom implementation differentiates between NULL and empty strings, so
299
    // we need this as workaround to keep the current behavior unchanged.
300
0
    return stringRef.isNull() ? QString() : stringRef.toString();
301
0
}
302
303
QString QDomBuilder::dtdInternalSubset(const QString &dtd)
304
0
{
305
    // https://www.w3.org/TR/xml/#NT-intSubset
306
    // doctypedecl: '<!DOCTYPE' S Name (S ExternalID)? S? ('[' intSubset ']' S?)? '>'
307
0
    const QString &name = doc->doctype()->name;
308
0
    QStringView tmp = QStringView(dtd).mid(dtd.indexOf(name) + name.size());
309
310
0
    const QString &publicId = doc->doctype()->publicId;
311
0
    if (!publicId.isEmpty())
312
0
        tmp = tmp.mid(tmp.indexOf(publicId) + publicId.size());
313
314
0
    const QString &systemId = doc->doctype()->systemId;
315
0
    if (!systemId.isEmpty())
316
0
        tmp = tmp.mid(tmp.indexOf(systemId) + systemId.size());
317
318
0
    const qsizetype obra = tmp.indexOf(u'[');
319
0
    const qsizetype cbra = tmp.lastIndexOf(u']');
320
0
    if (obra >= 0 && cbra >= 0)
321
0
        return tmp.left(cbra).mid(obra + 1).toString();
322
323
0
    return QString();
324
0
}
325
326
bool QDomBuilder::parseDTD(const QString &dtd)
327
0
{
328
0
    doc->doctype()->internalSubset = dtdInternalSubset(dtd);
329
0
    return true;
330
0
}
331
332
bool QDomBuilder::startElement(const QString &nsURI, const QString &qName,
333
                               const QXmlStreamAttributes &atts)
334
0
{
335
0
    QDomNodePrivate *n =
336
0
            nsProcessing ? doc->createElementNS(nsURI, qName) : doc->createElement(qName);
337
0
    if (!n)
338
0
        return false;
339
340
0
    n->setLocation(locator->line(), locator->column());
341
342
0
    node->appendChild(n);
343
0
    node = n;
344
345
    // attributes
346
0
    for (const auto &attr : atts) {
347
0
        auto domElement = static_cast<QDomElementPrivate *>(node);
348
0
        if (nsProcessing) {
349
0
            domElement->setAttributeNS(stringRefToString(attr.namespaceUri()),
350
0
                                       stringRefToString(attr.qualifiedName()),
351
0
                                       stringRefToString(attr.value()));
352
0
        } else {
353
0
            domElement->setAttribute(stringRefToString(attr.qualifiedName()),
354
0
                                     stringRefToString(attr.value()));
355
0
        }
356
0
    }
357
358
0
    return true;
359
0
}
360
361
bool QDomBuilder::endElement()
362
0
{
363
0
    if (!node || node == doc)
364
0
        return false;
365
0
    node = node->parent();
366
367
0
    return true;
368
0
}
369
370
bool QDomBuilder::characters(const QString &characters, bool cdata)
371
0
{
372
    // No text as child of some document
373
0
    if (node == doc)
374
0
        return false;
375
376
0
    QScopedPointer<QDomNodePrivate> n;
377
0
    if (cdata) {
378
0
        n.reset(doc->createCDATASection(characters));
379
0
    } else if (!entityName.isEmpty()) {
380
0
        QScopedPointer<QDomEntityPrivate> e(
381
0
                new QDomEntityPrivate(doc, nullptr, entityName, QString(), QString(), QString()));
382
0
        e->value = characters;
383
0
        e->ref.deref();
384
0
        doc->doctype()->appendChild(e.data());
385
0
        e.take();
386
0
        n.reset(doc->createEntityReference(entityName));
387
0
    } else {
388
0
        n.reset(doc->createTextNode(characters));
389
0
    }
390
0
    n->setLocation(locator->line(), locator->column());
391
0
    node->appendChild(n.data());
392
0
    n.take();
393
394
0
    return true;
395
0
}
396
397
bool QDomBuilder::processingInstruction(const QString &target, const QString &data)
398
0
{
399
0
    QDomNodePrivate *n;
400
0
    n = doc->createProcessingInstruction(target, data);
401
0
    if (n) {
402
0
        n->setLocation(locator->line(), locator->column());
403
0
        node->appendChild(n);
404
0
        return true;
405
0
    } else
406
0
        return false;
407
0
}
408
409
bool QDomBuilder::skippedEntity(const QString &name)
410
0
{
411
0
    QDomNodePrivate *n = doc->createEntityReference(name);
412
0
    n->setLocation(locator->line(), locator->column());
413
0
    node->appendChild(n);
414
0
    return true;
415
0
}
416
417
void QDomBuilder::fatalError(const QString &message)
418
0
{
419
0
    errorMsg = message;
420
0
    errorLine = static_cast<int>(locator->line());
421
0
    errorColumn = static_cast<int>(locator->column());
422
0
}
423
424
QDomBuilder::ErrorInfo QDomBuilder::error() const
425
0
{
426
0
    return ErrorInfo(errorMsg, errorLine, errorColumn);
427
0
}
428
429
bool QDomBuilder::startEntity(const QString &name)
430
0
{
431
0
    entityName = name;
432
0
    return true;
433
0
}
434
435
bool QDomBuilder::endEntity()
436
0
{
437
0
    entityName.clear();
438
0
    return true;
439
0
}
440
441
bool QDomBuilder::comment(const QString &characters)
442
0
{
443
0
    QDomNodePrivate *n;
444
0
    n = doc->createComment(characters);
445
0
    n->setLocation(locator->line(), locator->column());
446
0
    node->appendChild(n);
447
0
    return true;
448
0
}
449
450
bool QDomBuilder::unparsedEntityDecl(const QString &name, const QString &publicId,
451
                                     const QString &systemId, const QString &notationName)
452
0
{
453
0
    QDomEntityPrivate *e =
454
0
            new QDomEntityPrivate(doc, nullptr, name, publicId, systemId, notationName);
455
    // keep the refcount balanced: appendChild() does a ref anyway.
456
0
    e->ref.deref();
457
0
    doc->doctype()->appendChild(e);
458
0
    return true;
459
0
}
460
461
bool QDomBuilder::externalEntityDecl(const QString &name, const QString &publicId,
462
                                     const QString &systemId)
463
0
{
464
0
    return unparsedEntityDecl(name, publicId, systemId, QString());
465
0
}
466
467
bool QDomBuilder::notationDecl(const QString &name, const QString &publicId,
468
                               const QString &systemId)
469
0
{
470
0
    QDomNotationPrivate *n = new QDomNotationPrivate(doc, nullptr, name, publicId, systemId);
471
    // keep the refcount balanced: appendChild() does a ref anyway.
472
0
    n->ref.deref();
473
0
    doc->doctype()->appendChild(n);
474
0
    return true;
475
0
}
476
477
/**************************************************************
478
 *
479
 * QDomParser
480
 *
481
 **************************************************************/
482
483
QDomParser::QDomParser(QDomDocumentPrivate *d, QXmlStreamReader *r, bool namespaceProcessing)
484
0
    : reader(r), locator(r), domBuilder(d, &locator, namespaceProcessing)
485
0
{
486
0
}
487
488
bool QDomParser::parse()
489
0
{
490
0
    return parseProlog() && parseBody();
491
0
}
492
493
QDomBuilder::ErrorInfo QDomParser::errorInfo() const
494
0
{
495
0
    return domBuilder.error();
496
0
}
497
498
bool QDomParser::parseProlog()
499
0
{
500
0
    Q_ASSERT(reader);
501
502
0
    bool foundDtd = false;
503
504
0
    while (!reader->atEnd()) {
505
0
        reader->readNext();
506
507
0
        if (reader->hasError()) {
508
0
            domBuilder.fatalError(reader->errorString());
509
0
            return false;
510
0
        }
511
512
0
        switch (reader->tokenType()) {
513
0
        case QXmlStreamReader::StartDocument:
514
0
            if (!reader->documentVersion().isEmpty()) {
515
0
                QString value(QLatin1String("version='"));
516
0
                value += reader->documentVersion();
517
0
                value += QLatin1Char('\'');
518
0
                if (!reader->documentEncoding().isEmpty()) {
519
0
                    value += QLatin1String(" encoding='");
520
0
                    value += reader->documentEncoding();
521
0
                    value += QLatin1Char('\'');
522
0
                }
523
0
                if (reader->isStandaloneDocument()) {
524
0
                    value += QLatin1String(" standalone='yes'");
525
0
                } else {
526
                    // TODO: Add standalone='no', if 'standalone' is specified. With the current
527
                    // QXmlStreamReader there is no way to figure out if it was specified or not.
528
                    // QXmlStreamReader needs to be modified for handling that case correctly.
529
0
                }
530
531
0
                if (!domBuilder.processingInstruction(QLatin1String("xml"), value)) {
532
0
                    domBuilder.fatalError(
533
0
                            QDomParser::tr("Error occurred while processing XML declaration"));
534
0
                    return false;
535
0
                }
536
0
            }
537
0
            break;
538
0
        case QXmlStreamReader::DTD:
539
0
            if (foundDtd) {
540
0
                domBuilder.fatalError(QDomParser::tr("Multiple DTD sections are not allowed"));
541
0
                return false;
542
0
            }
543
0
            foundDtd = true;
544
545
0
            if (!domBuilder.startDTD(stringRefToString(reader->dtdName()),
546
0
                                     stringRefToString(reader->dtdPublicId()),
547
0
                                     stringRefToString(reader->dtdSystemId()))) {
548
0
                domBuilder.fatalError(
549
0
                        QDomParser::tr("Error occurred while processing document type declaration"));
550
0
                return false;
551
0
            }
552
0
            if (!domBuilder.parseDTD(reader->text().toString()))
553
0
                return false;
554
0
            if (!parseMarkupDecl())
555
0
                return false;
556
0
            break;
557
0
        case QXmlStreamReader::Comment:
558
0
            if (!domBuilder.comment(reader->text().toString())) {
559
0
                domBuilder.fatalError(QDomParser::tr("Error occurred while processing comment"));
560
0
                return false;
561
0
            }
562
0
            break;
563
0
        case QXmlStreamReader::ProcessingInstruction:
564
0
            if (!domBuilder.processingInstruction(reader->processingInstructionTarget().toString(),
565
0
                                                  reader->processingInstructionData().toString())) {
566
0
                domBuilder.fatalError(
567
0
                        QDomParser::tr("Error occurred while processing a processing instruction"));
568
0
                return false;
569
0
            }
570
0
            break;
571
0
        default:
572
            // If the token is none of the above, prolog processing is done.
573
0
            return true;
574
0
        }
575
0
    }
576
577
0
    return true;
578
0
}
579
580
bool QDomParser::parseBody()
581
0
{
582
0
    Q_ASSERT(reader);
583
584
0
    std::stack<QStringRef> tagStack;
585
0
    while (!reader->atEnd() && !reader->hasError()) {
586
0
        switch (reader->tokenType()) {
587
0
        case QXmlStreamReader::StartElement:
588
0
            tagStack.push(reader->qualifiedName());
589
0
            if (!domBuilder.startElement(stringRefToString(reader->namespaceUri()),
590
0
                                         stringRefToString(reader->qualifiedName()),
591
0
                                         reader->attributes())) {
592
0
                domBuilder.fatalError(
593
0
                        QDomParser::tr("Error occurred while processing a start element"));
594
0
                return false;
595
0
            }
596
0
            break;
597
0
        case QXmlStreamReader::EndElement:
598
0
            if (tagStack.empty() || reader->qualifiedName() != tagStack.top()) {
599
0
                domBuilder.fatalError(
600
0
                        QDomParser::tr("Unexpected end element '%1'").arg(reader->name()));
601
0
                return false;
602
0
            }
603
0
            tagStack.pop();
604
0
            if (!domBuilder.endElement()) {
605
0
                domBuilder.fatalError(
606
0
                        QDomParser::tr("Error occurred while processing an end element"));
607
0
                return false;
608
0
            }
609
0
            break;
610
0
        case QXmlStreamReader::Characters:
611
0
            if (!reader->isWhitespace()) { // Skip the content consisting of only whitespaces
612
0
                if (!reader->text().toString().trimmed().isEmpty()) {
613
0
                    if (!domBuilder.characters(reader->text().toString(), reader->isCDATA())) {
614
0
                        domBuilder.fatalError(QDomParser::tr(
615
0
                                "Error occurred while processing the element content"));
616
0
                        return false;
617
0
                    }
618
0
                }
619
0
            }
620
0
            break;
621
0
        case QXmlStreamReader::Comment:
622
0
            if (!domBuilder.comment(reader->text().toString())) {
623
0
                domBuilder.fatalError(QDomParser::tr("Error occurred while processing comments"));
624
0
                return false;
625
0
            }
626
0
            break;
627
0
        case QXmlStreamReader::ProcessingInstruction:
628
0
            if (!domBuilder.processingInstruction(reader->processingInstructionTarget().toString(),
629
0
                                                  reader->processingInstructionData().toString())) {
630
0
                domBuilder.fatalError(
631
0
                        QDomParser::tr("Error occurred while processing a processing instruction"));
632
0
                return false;
633
0
            }
634
0
            break;
635
0
        case QXmlStreamReader::EntityReference:
636
0
            if (!domBuilder.skippedEntity(reader->name().toString())) {
637
0
                domBuilder.fatalError(
638
0
                        QDomParser::tr("Error occurred while processing an entity reference"));
639
0
                return false;
640
0
            }
641
0
            break;
642
0
        default:
643
0
            domBuilder.fatalError(QDomParser::tr("Unexpected token"));
644
0
            return false;
645
0
        }
646
647
0
        reader->readNext();
648
0
    }
649
650
0
    if (reader->hasError()) {
651
0
        domBuilder.fatalError(reader->errorString());
652
0
        reader->readNext();
653
0
        return false;
654
0
    }
655
656
0
    if (!tagStack.empty()) {
657
0
        domBuilder.fatalError(QDomParser::tr("Tag mismatch"));
658
0
        return false;
659
0
    }
660
661
0
    return true;
662
0
}
663
664
bool QDomParser::parseMarkupDecl()
665
0
{
666
0
    Q_ASSERT(reader);
667
668
0
    const auto entities = reader->entityDeclarations();
669
0
    for (const auto &entityDecl : entities) {
670
        // Entity declarations are created only for Extrenal Entities. Internal Entities
671
        // are parsed, and QXmlStreamReader handles the parsing itself and returns the
672
        // parsed result. So we don't need to do anything for the Internal Entities.
673
0
        if (!entityDecl.publicId().isEmpty() || !entityDecl.systemId().isEmpty()) {
674
            // External Entity
675
0
            if (!domBuilder.unparsedEntityDecl(stringRefToString(entityDecl.name()),
676
0
                                               stringRefToString(entityDecl.publicId()),
677
0
                                               stringRefToString(entityDecl.systemId()),
678
0
                                               stringRefToString(entityDecl.notationName()))) {
679
0
                domBuilder.fatalError(
680
0
                        QDomParser::tr("Error occurred while processing entity declaration"));
681
0
                return false;
682
0
            }
683
0
        }
684
0
    }
685
686
0
    const auto notations = reader->notationDeclarations();
687
0
    for (const auto &notationDecl : notations) {
688
0
        if (!domBuilder.notationDecl(stringRefToString(notationDecl.name()),
689
0
                                     stringRefToString(notationDecl.publicId()),
690
0
                                     stringRefToString(notationDecl.systemId()))) {
691
0
            domBuilder.fatalError(
692
0
                    QDomParser::tr("Error occurred while processing notation declaration"));
693
0
            return false;
694
0
        }
695
0
    }
696
697
0
    return true;
698
0
}
699
700
QT_END_NAMESPACE
701
702
#endif // QT_NO_DOM