From 6b6eac8f93e3673b763a4f141036604272b6ed5c Mon Sep 17 00:00:00 2001 From: JunsuChoi Date: Thu, 4 Jul 2024 19:24:35 +0900 Subject: [PATCH] svg_loader: Fix incorrect stack.pop() call in loader loader->stack.pop() at line 3271 is called to remove the defs node added to the stack due to nested graphics elements. However, it is called in an inappropriate situation and the loader's node tree is damaged. Fixes an error where the close tag is recognized as a `line` of the graphics tag when it is `linearGradient`. ex) ``` ``` related issue: https://github.com/thorvg/thorvg/issues/2518 --- src/loaders/svg/tvgSvgLoader.cpp | 23 +++++++++++++++++++---- 1 file changed, 19 insertions(+), 4 deletions(-) diff --git a/src/loaders/svg/tvgSvgLoader.cpp b/src/loaders/svg/tvgSvgLoader.cpp index 4b0143e0..b610feb3 100644 --- a/src/loaders/svg/tvgSvgLoader.cpp +++ b/src/loaders/svg/tvgSvgLoader.cpp @@ -3254,19 +3254,34 @@ static void _clonePostponedNodes(Array* cloneNodes, SvgNode* doc) } -static void _svgLoaderParserXmlClose(SvgLoaderData* loader, const char* content) +static void _svgLoaderParserXmlClose(SvgLoaderData* loader, const char* content, unsigned int length) { + const char* itr = nullptr; + int sz = length; + char tagName[20] = ""; + content = _skipSpace(content, nullptr); + itr = content; + while ((itr != nullptr) && *itr != '>') itr++; + + if (itr) { + sz = itr - content; + while ((sz > 0) && (isspace(content[sz - 1]))) sz--; + if ((unsigned int)sz >= sizeof(tagName)) sz = sizeof(tagName) - 1; + strncpy(tagName, content, sz); + tagName[sz] = '\0'; + } + else return; for (unsigned int i = 0; i < sizeof(groupTags) / sizeof(groupTags[0]); i++) { - if (!strncmp(content, groupTags[i].tag, groupTags[i].sz - 1)) { + if (!strncmp(tagName, groupTags[i].tag, sz)) { loader->stack.pop(); break; } } for (unsigned int i = 0; i < sizeof(graphicsTags) / sizeof(graphicsTags[0]); i++) { - if (!strncmp(content, graphicsTags[i].tag, graphicsTags[i].sz - 1)) { + if (!strncmp(tagName, graphicsTags[i].tag, sz)) { loader->currentGraphicsNode = nullptr; loader->stack.pop(); break; @@ -3437,7 +3452,7 @@ static bool _svgLoaderParser(void* data, SimpleXMLType type, const char* content break; } case SimpleXMLType::Close: { - _svgLoaderParserXmlClose(loader, content); + _svgLoaderParserXmlClose(loader, content, length); break; } case SimpleXMLType::Data: