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 8be44e66d2
commit 6b6eac8f93

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: