From 3971094377b431c0dc000d2aea06785b38d20e7e 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 76bb9581..6371bd97 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: