From adda399b271a19da834d0b8c4ca7a7c4bf97567b Mon Sep 17 00:00:00 2001 From: Hermet Park Date: Thu, 20 Jan 2022 12:04:19 +0900 Subject: [PATCH] svg_loader: ++robustness Prevent recursive calls by counting just in case. The size is arbitrary value, we can adjust it experimentally. @Issue: https://github.com/Samsung/thorvg/issues/1161 Change-Id: I30571e5de085c65980a240b14c592bc0b47a7860 --- src/loaders/svg/tvgSvgLoader.cpp | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/src/loaders/svg/tvgSvgLoader.cpp b/src/loaders/svg/tvgSvgLoader.cpp index 74e6144..4990c5c 100644 --- a/src/loaders/svg/tvgSvgLoader.cpp +++ b/src/loaders/svg/tvgSvgLoader.cpp @@ -1934,8 +1934,15 @@ static void _copyAttr(SvgNode* to, const SvgNode* from) } -static void _cloneNode(SvgNode* from, SvgNode* parent) +static void _cloneNode(SvgNode* from, SvgNode* parent, int depth) { + /* Exception handling: Prevent invalid SVG data input. + The size is the arbitrary value, we need an experimental size. */ + if (depth == 8192) { + TVGERR("SVG", "Infinite recursive call - stopped after %d calls! Svg file may be incorrectly formatted.", depth); + return; + } + SvgNode* newNode; if (!from || !parent || from == parent) return; @@ -1947,7 +1954,7 @@ static void _cloneNode(SvgNode* from, SvgNode* parent) auto child = from->child.data; for (uint32_t i = 0; i < from->child.count; ++i, ++child) { - _cloneNode(*child, newNode); + _cloneNode(*child, newNode, depth + 1); } } @@ -1965,7 +1972,7 @@ static void _clonePostponedNodes(Array* cloneNodes, SvgNode* doc) auto defs = _getDefsNode(nodeIdPair.node); auto nodeFrom = _findChildById(defs, nodeIdPair.id); if (!nodeFrom) nodeFrom = _findChildById(doc, nodeIdPair.id); - _cloneNode(nodeFrom, nodeIdPair.node); + _cloneNode(nodeFrom, nodeIdPair.node, 0); free(nodeIdPair.id); } } @@ -2006,7 +2013,7 @@ static bool _attrParseUseNode(void* data, const char* key, const char* value) defs = _getDefsNode(node); nodeFrom = _findChildById(defs, id); if (nodeFrom) { - _cloneNode(nodeFrom, node); + _cloneNode(nodeFrom, node, 0); free(id); } else { //some svg export software include element at the end of the file -- 2.7.4