svg_loader: If there is already set color url, it will be deleted. 55/289755/1
authorJunsuChoi <jsuya.choi@samsung.com>
Mon, 29 Aug 2022 04:32:06 +0000 (13:32 +0900)
committerMichal Szczecinski <mihashco89@gmail.com>
Tue, 14 Mar 2023 06:43:33 +0000 (07:43 +0100)
When setting the url for color, if there is an already set url,
it will be overwritten after deletion. This prevents memory leaks.

asan result)

Direct leak of 2 byte(s) in 1 object(s) allocated from:
    #0 0x7ff1d547bc68 in __interceptor_malloc (/usr/lib/x86_64-linux-gnu/libasan.so.5+0x10bc68)
    #1 0x7ff1d4e435b4 in _idFromUrl ../src/loaders/svg/tvgSvgLoader.cpp:327
    #2 0x7ff1d4e44a8e in _toColor ../src/loaders/svg/tvgSvgLoader.cpp:558
    #3 0x7ff1d4e42ee9 in _parseStyleAttr ../src/loaders/svg/tvgSvgLoader.cpp:1033
    #4 0x7ff1d4e7f092 in simpleXmlParseAttributes(char const*, unsigned int, bool (*)(void*, char const*, char const*), void const*) ../src/loaders/svg/tvgXmlParser.cpp:361
    #5 0x7ff1d4e597d3 in _createPathNode ../src/loaders/svg/tvgSvgLoader.cpp:1363
    #6 0x7ff1d4e61359 in _svgLoaderParserXmlOpen ../src/loaders/svg/tvgSvgLoader.cpp:2723
    #7 0x7ff1d4e61c49 in _svgLoaderParser ../src/loaders/svg/tvgSvgLoader.cpp:2801
    #8 0x7ff1d4e7f3f6 in simpleXmlParse(char const*, unsigned int, bool, bool (*)(void*, SimpleXMLType, char const*, unsigned int), void const*) ../src/loaders/svg/tvgXmlParser.cpp:429
    #9 0x7ff1d4e639a1 in SvgLoader::run(unsigned int) ../src/loaders/svg/tvgSvgLoader.cpp:3121
    #10 0x7ff1d4dc8b75 in tvg::Task::operator()(unsigned int) ../src/lib/tvgTaskScheduler.h:68
    #11 0x7ff1d4dc8b75 in tvg::TaskSchedulerImpl::run(unsigned int) ../src/lib/tvgTaskScheduler.cpp:138
    #12 0x7ff1d4dc98f7 in tvg::TaskSchedulerImpl::TaskSchedulerImpl(unsigned int)::{lambda()#1}::operator()() const ../src/lib/tvgTaskScheduler.cpp:113
    #13 0x7ff1d4dc98f7 in void std::__invoke_impl<void, tvg::TaskSchedulerImpl::TaskSchedulerImpl(unsigned int)::{lambda()#1}>(std::__invoke_other, tvg::TaskSchedulerImpl::TaskSchedulerImpl(unsigned int)::{lambda()#1}&&) /usr/include/c++/9/bits/invoke.h:60
    #14 0x7ff1d4dc98f7 in std::__invoke_result<tvg::TaskSchedulerImpl::TaskSchedulerImpl(unsigned int)::{lambda()#1}>::type std::__invoke<tvg::TaskSchedulerImpl::TaskSchedulerImpl(unsigned int)::{lambda()#1}>(std::__invoke_result&&, (tvg::TaskSchedulerImpl::TaskSchedulerImpl(unsigned int)::{lambda()#1}&&)...) /usr/include/c++/9/bits/invoke.h:95
    #15 0x7ff1d4dc98f7 in void std::thread::_Invoker<std::tuple<tvg::TaskSchedulerImpl::TaskSchedulerImpl(unsigned int)::{lambda()#1}> >::_M_invoke<0ul>(std::_Index_tuple<0ul>) /usr/include/c++/9/thread:244
    #16 0x7ff1d4dc98f7 in std::thread::_Invoker<std::tuple<tvg::TaskSchedulerImpl::TaskSchedulerImpl(unsigned int)::{lambda()#1}> >::operator()() /usr/include/c++/9/thread:251
    #17 0x7ff1d4dc98f7 in std::thread::_State_impl<std::thread::_Invoker<std::tuple<tvg::TaskSchedulerImpl::TaskSchedulerImpl(unsigned int)::{lambda()#1}> > >::_M_run() /usr/include/c++/9/thread:195
    #18 0x7ff1d3a344bf  (/usr/lib/x86_64-linux-gnu/libstdc++.so.6+0xd44bf)

example)
<svg height="400" width="600" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns="http://www.w3.org/2000/svg">
   <defs>
      <radialGradient r="12" fy="10" fx="10" cy="10" cx="10" id="i" xlink:href="#d"/>
      <clipPath id="g" clipPathUnits="userSpaceOnUse">
         <path d="M0 10 10z" style="marker:none" fill="#fff" stroke-width="2"/>
      </clipPath>
   </defs>
         <path d="M0 10 Z" fill="url(#g)" style="fill:url(#i);fill-opacity:1"/>
</svg>

Change-Id: I14c605e7555dbda19113b9f9027954654e423f4b

src/loaders/svg/tvgSvgCssStyle.cpp
src/loaders/svg/tvgSvgLoader.cpp

index 8f46b62..cca188e 100644 (file)
@@ -42,7 +42,10 @@ static void _copyStyle(SvgStyleProperty* to, const SvgStyleProperty* from)
         to->fill.paint.color = from->fill.paint.color;
         to->fill.paint.none = from->fill.paint.none;
         to->fill.paint.curColor = from->fill.paint.curColor;
-        if (from->fill.paint.url) to->fill.paint.url = strdup(from->fill.paint.url);
+        if (from->fill.paint.url) {
+            if (to->fill.paint.url) free(to->fill.paint.url);
+            to->fill.paint.url = strdup(from->fill.paint.url);
+        }
         to->fill.flags = (SvgFillFlags)((int)to->fill.flags | (int)SvgFillFlags::Paint);
         to->flags = (SvgStyleFlags)((int)to->flags | (int)SvgStyleFlags::Fill);
     }
@@ -61,7 +64,10 @@ static void _copyStyle(SvgStyleProperty* to, const SvgStyleProperty* from)
         to->stroke.paint.color = from->stroke.paint.color;
         to->stroke.paint.none = from->stroke.paint.none;
         to->stroke.paint.curColor = from->stroke.paint.curColor;
-        if (from->stroke.paint.url) to->stroke.paint.url = strdup(from->stroke.paint.url);
+        if (from->stroke.paint.url) {
+            if (to->stroke.paint.url) free(to->stroke.paint.url);
+            to->stroke.paint.url = strdup(from->stroke.paint.url);
+        }
         to->stroke.flags = (SvgStrokeFlags)((int)to->stroke.flags | (int)SvgStrokeFlags::Paint);
         to->flags = (SvgStyleFlags)((int)to->flags | (int)SvgStyleFlags::Stroke);
     }
index 3b3183d..8b4dc7b 100644 (file)
@@ -554,6 +554,7 @@ static void _toColor(const char* str, uint8_t* r, uint8_t* g, uint8_t* b, char**
             }
         }
     } else if (ref && len >= 3 && !strncmp(str, "url", 3)) {
+        if (*ref) free(*ref);
         *ref = _idFromUrl((const char*)(str + 3));
     } else {
         //Handle named color
@@ -1889,7 +1890,10 @@ static void _styleInherit(SvgStyleProperty* child, const SvgStyleProperty* paren
         child->fill.paint.color = parent->fill.paint.color;
         child->fill.paint.none = parent->fill.paint.none;
         child->fill.paint.curColor = parent->fill.paint.curColor;
-        if (parent->fill.paint.url) child->fill.paint.url = _copyId(parent->fill.paint.url);
+        if (parent->fill.paint.url) {
+            if (child->fill.paint.url) free(child->fill.paint.url);
+            child->fill.paint.url = _copyId(parent->fill.paint.url);
+        }
     }
     if (!((int)child->fill.flags & (int)SvgFillFlags::Opacity)) {
         child->fill.opacity = parent->fill.opacity;
@@ -1902,7 +1906,12 @@ static void _styleInherit(SvgStyleProperty* child, const SvgStyleProperty* paren
         child->stroke.paint.color = parent->stroke.paint.color;
         child->stroke.paint.none = parent->stroke.paint.none;
         child->stroke.paint.curColor = parent->stroke.paint.curColor;
-        child->stroke.paint.url = parent->stroke.paint.url ? _copyId(parent->stroke.paint.url) : nullptr;
+        if (parent->stroke.paint.url) {
+            if (child->stroke.paint.url) free(child->stroke.paint.url);
+            child->stroke.paint.url = _copyId(parent->stroke.paint.url);
+        } else {
+            child->stroke.paint.url = nullptr;
+        }
     }
     if (!((int)child->stroke.flags & (int)SvgStrokeFlags::Opacity)) {
         child->stroke.opacity = parent->stroke.opacity;
@@ -1942,7 +1951,10 @@ static void _styleCopy(SvgStyleProperty* to, const SvgStyleProperty* from)
         to->fill.paint.color = from->fill.paint.color;
         to->fill.paint.none = from->fill.paint.none;
         to->fill.paint.curColor = from->fill.paint.curColor;
-        if (from->fill.paint.url) to->fill.paint.url = _copyId(from->fill.paint.url);
+        if (from->fill.paint.url) {
+            if (to->fill.paint.url) free(to->fill.paint.url);
+            to->fill.paint.url = _copyId(from->fill.paint.url);
+        }
     }
     if (((int)from->fill.flags & (int)SvgFillFlags::Opacity)) {
         to->fill.opacity = from->fill.opacity;
@@ -1956,7 +1968,12 @@ static void _styleCopy(SvgStyleProperty* to, const SvgStyleProperty* from)
         to->stroke.paint.color = from->stroke.paint.color;
         to->stroke.paint.none = from->stroke.paint.none;
         to->stroke.paint.curColor = from->stroke.paint.curColor;
-        to->stroke.paint.url = from->stroke.paint.url ? _copyId(from->stroke.paint.url) : nullptr;
+        if (from->stroke.paint.url) {
+            if (to->stroke.paint.url) free(to->stroke.paint.url);
+            to->stroke.paint.url = _copyId(from->stroke.paint.url);
+        } else {
+            to->stroke.paint.url = nullptr;
+        }
     }
     if (((int)from->stroke.flags & (int)SvgStrokeFlags::Opacity)) {
         to->stroke.opacity = from->stroke.opacity;