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
This commit is contained in:
Hermet Park 2022-01-20 12:04:19 +09:00 committed by Hermet Park
parent a00b68ba40
commit 0f87685c85

View file

@ -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<SvgNodeIdPair>* 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 <defs> element at the end of the file