diff options
author | Qt Forward Merge Bot <qt_forward_merge_bot@qt-project.org> | 2020-04-14 12:27:02 +0200 |
---|---|---|
committer | Qt Forward Merge Bot <qt_forward_merge_bot@qt-project.org> | 2020-04-14 12:27:02 +0200 |
commit | 6bd24577658c1e2fde21b14147b4ba964890afe1 (patch) | |
tree | 2002796555a0fda4069f44b1a0b33282e4be4a94 /src/corelib/serialization | |
parent | 2161414cdf2790d39eeb25fc35e26c966708d4b8 (diff) | |
parent | 08d6cb7673aa51bc0532d71db4134f4912e14769 (diff) |
Merge remote-tracking branch 'origin/5.12.8' into 5.12
Change-Id: I3c060326bf24f31dda0fd6dd9ebf278da4c2fe46
Diffstat (limited to 'src/corelib/serialization')
-rw-r--r-- | src/corelib/serialization/qxmlstream.g | 14 | ||||
-rw-r--r-- | src/corelib/serialization/qxmlstream_p.h | 14 |
2 files changed, 26 insertions, 2 deletions
diff --git a/src/corelib/serialization/qxmlstream.g b/src/corelib/serialization/qxmlstream.g index 10bfcd491c..5726bafb26 100644 --- a/src/corelib/serialization/qxmlstream.g +++ b/src/corelib/serialization/qxmlstream.g @@ -277,9 +277,19 @@ public: QHash<QStringView, Entity> entityHash; QHash<QStringView, Entity> parameterEntityHash; QXmlStreamSimpleStack<Entity *>entityReferenceStack; + int entityExpansionLimit = 4096; + int entityLength = 0; inline bool referenceEntity(Entity &entity) { if (entity.isCurrentlyReferenced) { - raiseWellFormedError(QXmlStream::tr("Recursive entity detected.")); + raiseWellFormedError(QXmlStream::tr("Self-referencing entity detected.")); + return false; + } + // entityLength represents the amount of additional characters the + // entity expands into (can be negative for e.g. &). It's used to + // avoid DoS attacks through recursive entity expansions + entityLength += entity.value.size() - entity.name.size() - 2; + if (entityLength > entityExpansionLimit) { + raiseWellFormedError(QXmlStream::tr("Entity expands to more characters than the entity expansion limit.")); return false; } entity.isCurrentlyReferenced = true; @@ -830,6 +840,8 @@ entity_done ::= ENTITY_DONE; /. case $rule_number: entityReferenceStack.pop()->isCurrentlyReferenced = false; + if (entityReferenceStack.isEmpty()) + entityLength = 0; clearSym(); break; ./ diff --git a/src/corelib/serialization/qxmlstream_p.h b/src/corelib/serialization/qxmlstream_p.h index 61f501f81b..31053f8e0b 100644 --- a/src/corelib/serialization/qxmlstream_p.h +++ b/src/corelib/serialization/qxmlstream_p.h @@ -774,9 +774,19 @@ public: QHash<QStringView, Entity> entityHash; QHash<QStringView, Entity> parameterEntityHash; QXmlStreamSimpleStack<Entity *>entityReferenceStack; + int entityExpansionLimit = 4096; + int entityLength = 0; inline bool referenceEntity(Entity &entity) { if (entity.isCurrentlyReferenced) { - raiseWellFormedError(QXmlStream::tr("Recursive entity detected.")); + raiseWellFormedError(QXmlStream::tr("Self-referencing entity detected.")); + return false; + } + // entityLength represents the amount of additional characters the + // entity expands into (can be negative for e.g. &). It's used to + // avoid DoS attacks through recursive entity expansions + entityLength += entity.value.size() - entity.name.size() - 2; + if (entityLength > entityExpansionLimit) { + raiseWellFormedError(QXmlStream::tr("Entity expands to more characters than the entity expansion limit.")); return false; } entity.isCurrentlyReferenced = true; @@ -1308,6 +1318,8 @@ bool QXmlStreamReaderPrivate::parse() case 10: entityReferenceStack.pop()->isCurrentlyReferenced = false; + if (entityReferenceStack.isEmpty()) + entityLength = 0; clearSym(); break; |