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)
```
    <defs id="def">
        <linearGradient x1="1" y1="2" x2="3" y2="4" id="l"/>
        </linearGradient>
        <rect x="10" y="10" width="10" height="10"  fill="blue" id="r2"/>
    </defs>
```

related issue: https://github.com/thorvg/thorvg/issues/2518
This commit is contained in:
JunsuChoi 2024-07-04 19:24:35 +09:00 committed by Hermet Park
parent d6cdae6237
commit c922eb9d2d

View file

@ -3254,19 +3254,34 @@ static void _clonePostponedNodes(Array<SvgNodeIdPair>* 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: