Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

SVG loader crash when loading specific icon from the AssetLibrary #97078

Closed
SaracenOne opened this issue Sep 16, 2024 · 7 comments · Fixed by #97079
Closed

SVG loader crash when loading specific icon from the AssetLibrary #97078

SaracenOne opened this issue Sep 16, 2024 · 7 comments · Fixed by #97079

Comments

@SaracenOne
Copy link
Member

SaracenOne commented Sep 16, 2024

Tested versions

6681f25

System information

Windows 11

Issue description

The editor will hard crash when browsing the AssetLibrary. It appears to be caused by a ThorVG parsing error with the icon for Gnumaru's Scene Tree View Buttons (https://godotengine.org/asset-library/asset/3063) addon where it will encounter a nullptr. It's unclear at the moment if this is a bug we have to fix or something that need to pass onto the ThorVG developers (or perhaps we just need to update the library), but I don't see anything currently in our implementation of the addon which looks obviously incorrect.

Steps to reproduce

  • Open the editor.
  • Search for Gnumaru's Scene Tree View Buttons or a shortened version.
  • The editor should crash when the icon for this addon is fetched

Minimal reproduction project (MRP)

N/A

@akien-mga
Copy link
Member

I confirm the crash in latest master, including with #97079. Backtrace with thorvg 0.14.10 from that PR:

================================================================
handle_crash: Program crashed with signal 11
Engine version: Godot Engine v4.4.dev.custom_build (3e0ba54a7951894adbd3cc9b430936743f65d8e6)
Dumping the backtrace. Please include this when reporting the bug to the project developer.
[1] /lib64/libc.so.6(+0x40d00) [0x7fa3546ffd00] (??:0)
[2] tvg::Task::done() (/home/akien/Godot/godot/thirdparty/thorvg/src/renderer/tvgTaskScheduler.h:51)
[3] SwTask::bounds() (/home/akien/Godot/godot/thirdparty/thorvg/src/renderer/sw_engine/tvgSwRenderer.cpp:57)
[4] tvg::SwRenderer::region(void*) (/home/akien/Godot/godot/thirdparty/thorvg/src/renderer/sw_engine/tvgSwRenderer.cpp:505)
[5] tvg::Shape::Impl::bounds(tvg::RenderMethod*) (/home/akien/Godot/godot/thirdparty/thorvg/src/renderer/tvgShape.h:121)
[6] tvg::Text::Impl::bounds(tvg::RenderMethod*) (/home/akien/Godot/godot/thirdparty/thorvg/src/renderer/tvgText.h:88)
[7] tvg::Paint::Impl::bounds(tvg::RenderMethod*) const (/home/akien/Godot/godot/thirdparty/thorvg/src/renderer/tvgPaint.cpp:141 (discriminator 5))
[8] tvg::Scene::Impl::bounds(tvg::RenderMethod*) const (/home/akien/Godot/godot/thirdparty/thorvg/src/renderer/tvgScene.h:149)
[9] tvg::Paint::Impl::bounds(tvg::RenderMethod*) const (/home/akien/Godot/godot/thirdparty/thorvg/src/renderer/tvgPaint.cpp:141 (discriminator 3))
[10] tvg::Scene::Impl::bounds(tvg::RenderMethod*) const (/home/akien/Godot/godot/thirdparty/thorvg/src/renderer/tvgScene.h:149)
[11] tvg::Scene::Impl::render(tvg::RenderMethod*) (/home/akien/Godot/godot/thirdparty/thorvg/src/renderer/tvgScene.h:126 (discriminator 1))
[12] tvg::Paint::Impl::render(tvg::RenderMethod*) (/home/akien/Godot/godot/thirdparty/thorvg/src/renderer/tvgPaint.cpp:229 (discriminator 3))
[13] tvg::Scene::Impl::render(tvg::RenderMethod*) (/home/akien/Godot/godot/thirdparty/thorvg/src/renderer/tvgScene.h:131 (discriminator 1))
[14] tvg::Paint::Impl::render(tvg::RenderMethod*) (/home/akien/Godot/godot/thirdparty/thorvg/src/renderer/tvgPaint.cpp:229 (discriminator 3))
[15] tvg::Scene::Impl::render(tvg::RenderMethod*) (/home/akien/Godot/godot/thirdparty/thorvg/src/renderer/tvgScene.h:131 (discriminator 1))
[16] tvg::Paint::Impl::render(tvg::RenderMethod*) (/home/akien/Godot/godot/thirdparty/thorvg/src/renderer/tvgPaint.cpp:229 (discriminator 3))
[17] tvg::Scene::Impl::render(tvg::RenderMethod*) (/home/akien/Godot/godot/thirdparty/thorvg/src/renderer/tvgScene.h:131 (discriminator 1))
[18] tvg::Paint::Impl::render(tvg::RenderMethod*) (/home/akien/Godot/godot/thirdparty/thorvg/src/renderer/tvgPaint.cpp:229 (discriminator 3))
[19] tvg::Scene::Impl::render(tvg::RenderMethod*) (/home/akien/Godot/godot/thirdparty/thorvg/src/renderer/tvgScene.h:131 (discriminator 1))
[20] tvg::Paint::Impl::render(tvg::RenderMethod*) (/home/akien/Godot/godot/thirdparty/thorvg/src/renderer/tvgPaint.cpp:229 (discriminator 3))
[21] tvg::Scene::Impl::render(tvg::RenderMethod*) (/home/akien/Godot/godot/thirdparty/thorvg/src/renderer/tvgScene.h:131 (discriminator 1))
[22] tvg::Paint::Impl::render(tvg::RenderMethod*) (/home/akien/Godot/godot/thirdparty/thorvg/src/renderer/tvgPaint.cpp:229 (discriminator 3))
[23] tvg::Scene::Impl::render(tvg::RenderMethod*) (/home/akien/Godot/godot/thirdparty/thorvg/src/renderer/tvgScene.h:131 (discriminator 1))
[24] tvg::Paint::Impl::render(tvg::RenderMethod*) (/home/akien/Godot/godot/thirdparty/thorvg/src/renderer/tvgPaint.cpp:229 (discriminator 3))
[25] tvg::Picture::Impl::render(tvg::RenderMethod*) (/home/akien/Godot/godot/thirdparty/thorvg/src/renderer/tvgPicture.cpp:85)
[26] tvg::Paint::Impl::render(tvg::RenderMethod*) (/home/akien/Godot/godot/thirdparty/thorvg/src/renderer/tvgPaint.cpp:229 (discriminator 4))
[27] tvg::Canvas::Impl::draw() (/home/akien/Godot/godot/thirdparty/thorvg/src/renderer/tvgCanvas.h:116 (discriminator 1))
[28] tvg::Canvas::draw() (/home/akien/Godot/godot/thirdparty/thorvg/src/renderer/tvgCanvas.cpp:67)
[29] ImageLoaderSVG::create_image_from_utf8_buffer(Ref<Image>, unsigned char const*, int, float, bool) (/home/akien/Godot/godot/modules/svg/image_loader_svg.cpp:122 (discriminator 1))
[30] ImageLoaderSVG::load_mem_svg(unsigned char const*, int, float) (/home/akien/Godot/godot/modules/svg/image_loader_svg.cpp:74 (discriminator 1))
[31] EditorAssetLibrary::_image_update(bool, bool, Vector<unsigned char> const&, int) (/home/akien/Godot/godot/./editor/plugins/asset_library_editor_plugin.cpp:854 (discriminator 1))
[32] EditorAssetLibrary::_request_image(ObjectID, int, String, EditorAssetLibrary::ImageType, int) (/home/akien/Godot/godot/./editor/plugins/asset_library_editor_plugin.cpp:1027 (discriminator 2))
[33] EditorAssetLibrary::_http_request_completed(int, int, Vector<String> const&, Vector<unsigned char> const&) (/home/akien/Godot/godot/./editor/plugins/asset_library_editor_plugin.cpp:1401 (discriminator 8))
[34] void call_with_variant_args_helper<EditorAssetLibrary, int, int, Vector<String> const&, Vector<unsigned char> const&, 0ul, 1ul, 2ul, 3ul>(EditorAssetLibrary*, void (EditorAssetLibrary::*)(int, int, Vector<String> const&, Vector<unsigned char> const&), Variant const**, Callable::CallError&, IndexSequence<0ul, 1ul, 2ul, 3ul>) (/home/akien/Godot/godot/./core/variant/binder_common.h:304 (discriminator 5))
[35] void call_with_variant_args<EditorAssetLibrary, int, int, Vector<String> const&, Vector<unsigned char> const&>(EditorAssetLibrary*, void (EditorAssetLibrary::*)(int, int, Vector<String> const&, Vector<unsigned char> const&), Variant const**, int, Callable::CallError&) (/home/akien/Godot/godot/./core/variant/binder_common.h:419)
[36] CallableCustomMethodPointer<EditorAssetLibrary, int, int, Vector<String> const&, Vector<unsigned char> const&>::call(Variant const**, int, Variant&, Callable::CallError&) const (/home/akien/Godot/godot/./core/object/callable_method_pointer.h:104)
[37] Callable::callp(Variant const**, int, Variant&, Callable::CallError&) const (/home/akien/Godot/godot/./core/variant/callable.cpp:57)
[38] Object::emit_signalp(StringName const&, Variant const**, int) (/home/akien/Godot/godot/./core/object/object.cpp:1201)
[39] Node::emit_signalp(StringName const&, Variant const**, int) (/home/akien/Godot/godot/./scene/main/node.cpp:3927)
[40] Error Object::emit_signal<int, int, Vector<String>, Vector<unsigned char> >(StringName const&, int, int, Vector<String>, Vector<unsigned char>) (/home/akien/Godot/godot/./core/object/object.h:919)
[41] HTTPRequest::_request_done(int, int, Vector<String> const&, Vector<unsigned char> const&) (/home/akien/Godot/godot/./scene/main/http_request.cpp:483 (discriminator 4))
[42] void call_with_variant_args_helper<HTTPRequest, int, int, Vector<String> const&, Vector<unsigned char> const&, 0ul, 1ul, 2ul, 3ul>(HTTPRequest*, void (HTTPRequest::*)(int, int, Vector<String> const&, Vector<unsigned char> const&), Variant const**, Callable::CallError&, IndexSequence<0ul, 1ul, 2ul, 3ul>) (/home/akien/Godot/godot/./core/variant/binder_common.h:304 (discriminator 5))
[43] void call_with_variant_args<HTTPRequest, int, int, Vector<String> const&, Vector<unsigned char> const&>(HTTPRequest*, void (HTTPRequest::*)(int, int, Vector<String> const&, Vector<unsigned char> const&), Variant const**, int, Callable::CallError&) (/home/akien/Godot/godot/./core/variant/binder_common.h:419)
[44] CallableCustomMethodPointer<HTTPRequest, int, int, Vector<String> const&, Vector<unsigned char> const&>::call(Variant const**, int, Variant&, Callable::CallError&) const (/home/akien/Godot/godot/./core/object/callable_method_pointer.h:104)
[45] Callable::callp(Variant const**, int, Variant&, Callable::CallError&) const (/home/akien/Godot/godot/./core/variant/callable.cpp:57)
[46] CallQueue::_call_function(Callable const&, Variant const*, int, bool) (/home/akien/Godot/godot/./core/object/message_queue.cpp:221)
[47] CallQueue::flush() (/home/akien/Godot/godot/./core/object/message_queue.cpp:270)
[48] SceneTree::process(double) (/home/akien/Godot/godot/./scene/main/scene_tree.cpp:578)
[49] Main::iteration() (/home/akien/Godot/godot/main/main.cpp:4350 (discriminator 3))
[50] OS_LinuxBSD::run() (/home/akien/Godot/godot/platform/linuxbsd/os_linuxbsd.cpp:962 (discriminator 1))
[51] /home/akien/Godot/godot/bin/godot.linuxbsd.editor.dev.x86_64(main+0x14b) [0x5df7c71] (/home/akien/Godot/godot/platform/linuxbsd/godot_linuxbsd.cpp:85)
[52] /lib64/libc.so.6(+0x2a088) [0x7fa3546e9088] (??:0)
[53] /lib64/libc.so.6(__libc_start_main+0x8b) [0x7fa3546e914b] (??:0)
[54] /home/akien/Godot/godot/bin/godot.linuxbsd.editor.dev.x86_64(_start+0x25) [0x5df7a65] (??:?)
-- END OF BACKTRACE --
================================================================

@timothyqiu
Copy link
Member

To reproduce the crash, you can also run the script below with godot --headless -s /path/to/script.gd.

MRP Script with the original SVG
extends SceneTree

const SVG = """
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg width="100%" height="100%" viewBox="0 0 1080 1080" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:space="preserve" xmlns:serif="http://www.serif.com/" style="fill-rule:evenodd;clip-rule:evenodd;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:1.5;">
    <g id="Artboard2" transform="matrix(1,0,0,1,-1392,0)">
        <rect x="1392" y="0" width="1080" height="1080" style="fill:none;"/>
        <clipPath id="_clip1">
            <rect x="1392" y="0" width="1080" height="1080"/>
        </clipPath>
        <g clip-path="url(#_clip1)">
            <g transform="matrix(1,0,0,1,1392,-1.06581e-13)">
                <path d="M1080,97.515L1080,982.485C1080,1036.31 1036.31,1080 982.485,1080L97.515,1080C43.695,1080 0,1036.31 0,982.485L0,97.515C0,43.695 43.695,0 97.515,0L982.485,0C1036.31,0 1080,43.695 1080,97.515Z" style="fill:white;"/>
            </g>
            <g transform="matrix(0.90241,0,0,0.90241,1444.7,52.6988)">
                <path d="M1080,97.515L1080,982.485C1080,1036.31 1036.31,1080 982.485,1080L97.515,1080C43.695,1080 0,1036.31 0,982.485L0,97.515C0,43.695 43.695,0 97.515,0L982.485,0C1036.31,0 1080,43.695 1080,97.515Z"/>
            </g>
            <g id="BG" transform="matrix(5.64316,0,0,5.64316,6094.8,-3755.49)">
                <g opacity="0.2">
                    <g transform="matrix(1,0,0,1,-1391.95,-34.4526)">
                        <text x="604.182px" y="875.692px" style="font-family:'MalgunGothic', 'Malgun Gothic', sans-serif;font-size:100px;fill:white;">丸</text>
                    </g>
                    <g transform="matrix(1,0,0,1,-1534.54,-5.26182)">
                        <text x="698.727px" y="764.177px" style="font-family:'MalgunGothic', 'Malgun Gothic', sans-serif;font-size:100px;fill:white;">ギヌ</text>
                    </g>
                </g>
            </g>
            <g id="EditorCommentSceneTreeViewIcon.svg" transform="matrix(28.776,7.71052,-7.71052,28.776,2152.39,788.108)">
                <g transform="matrix(1,0,0,1,-8,-8)">
                    <g transform="matrix(0.875,0,0,0.823529,1,1)">
                        <path d="M8.862,17L2.767,17L2.802,0L12.427,0L16,3.516L16,9.405L9.494,9.405C9.145,9.405 8.862,9.706 8.862,10.077L8.862,17ZM16,10.748L16,10.76L10.127,17L10.126,10.748L16,10.748Z" style="fill:rgb(224,224,224);"/>
                    </g>
                    <path d="M15,2.772L15,4.627L5.763,4.406L6.041,13.623L4.67,15L2.772,15C1.794,15 1,14.206 1,13.228L1,2.772C1,1.794 1.794,1 2.772,1L13.228,1C14.206,1 15,1.794 15,2.772Z" style="fill:rgb(224,224,224);"/>
                </g>
            </g>
            <g id="IncomingConnectionsSceneTreeViewIcon.svg" transform="matrix(32.0331,-8.58324,8.58324,32.0331,1798.54,340.901)">
                <g transform="matrix(1,0,0,1,-8,-8)">
                    <g transform="matrix(1,0,0,1,-0.285222,0.536616)">
                        <path d="M1.976,3.297C4.608,6.074 4.479,8.852 1.976,11.63" style="fill:none;stroke:rgb(224,224,224);stroke-width:2.08px;"/>
                    </g>
                    <g transform="matrix(0.602424,0,0,0.602424,4.41857,3.50388)">
                        <path d="M1.976,3.297C4.608,6.074 4.479,8.852 1.976,11.63" style="fill:none;stroke:rgb(224,224,224);stroke-width:3.46px;"/>
                    </g>
                    <g transform="matrix(1,0,0,1,-0.719565,0)">
                        <path d="M8.742,4.819C9.505,3.557 12.366,1.218 14.582,4.819C16.049,7.203 13.504,10.778 12.688,11.615C11.99,12.331 11.583,14.735 9.689,11.615" style="fill:none;stroke:rgb(224,224,224);stroke-width:2.08px;"/>
                    </g>
                    <g transform="matrix(1,0,0,1,-0.719565,0)">
                        <path d="M10.327,9.229C11.261,8.691 12.356,7.924 10.352,7.36" style="fill:none;stroke:rgb(224,224,224);stroke-width:2.08px;"/>
                    </g>
                </g>
            </g>
        </g>
    </g>
</svg>
"""

func _process(delta: float) -> bool:
    var image := Image.new()
    print(image.load_svg_from_string(SVG))

    return true

It seems that it's these elements in the SVG that's causing the crash.

<g opacity="0.2">
    <g transform="matrix(1,0,0,1,-1391.95,-34.4526)">
        <text x="604.182px" y="875.692px" style="font-family:'MalgunGothic', 'Malgun Gothic', sans-serif;font-size:100px;fill:white;">丸</text>
    </g>
    <g transform="matrix(1,0,0,1,-1534.54,-5.26182)">
        <text x="698.727px" y="764.177px" style="font-family:'MalgunGothic', 'Malgun Gothic', sans-serif;font-size:100px;fill:white;">ギヌ</text>
    </g>
</g>

The image loads successfully after removing these lines. The opacity is necessary to reproduce the crash.

MRP Script with Minimal SVG
extends SceneTree

const SVG = """
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg width="100%" height="100%" viewBox="0 0 1080 1080" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:space="preserve" xmlns:serif="http://www.serif.com/" style="fill-rule:evenodd;clip-rule:evenodd;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:1.5;">
    <g opacity="0.2">
        <g transform="matrix(1,0,0,1,-1391.95,-34.4526)">
            <text x="604.182px" y="875.692px" style="font-family:'MalgunGothic', 'Malgun Gothic', sans-serif;font-size:100px;fill:white;">丸</text>
        </g>
        <g transform="matrix(1,0,0,1,-1534.54,-5.26182)">
            <text x="698.727px" y="764.177px" style="font-family:'MalgunGothic', 'Malgun Gothic', sans-serif;font-size:100px;fill:white;">ギヌ</text>
        </g>
    </g>
</svg>
"""

func _process(delta: float) -> bool:
    var image := Image.new()
    print(image.load_svg_from_string(SVG))

    return true

@akien-mga
Copy link
Member

CC @capnm

@akien-mga
Copy link
Member

I tested earlier thorvg versions (in Godot), the regression starts with 0.14.7.

@akien-mga
Copy link
Member

I tested earlier thorvg versions (in Godot), the regression starts with 0.14.7.

Bisected the regression to thorvg/thorvg@f533701 (cc @hermet). I'll file an upstream bug report tomorrow.

@akien-mga akien-mga moved this to Immediate Blocker in 4.x Release Blockers Sep 16, 2024
hermet added a commit to thorvg/thorvg that referenced this issue Sep 17, 2024
prevent a nullptr memory access
regression by f533701

issue: godotengine/godot#97078
@hermet
Copy link

hermet commented Sep 17, 2024

@akien-mga Hello, the fix will be in the next release. Thanks!

hermet added a commit to thorvg/thorvg that referenced this issue Sep 17, 2024
prevent a nullptr memory access
regression by f533701

issue: godotengine/godot#97078
@akien-mga
Copy link
Member

Awesome, thanks!

akien-mga added a commit to akien-mga/godot that referenced this issue Sep 17, 2024
More fixes to rendering of SVG files with broken text tags.

Also backports upstream patch to fix godotengine#97078.

(cherry picked from commit 0c0336f)
hermet added a commit to thorvg/thorvg that referenced this issue Sep 30, 2024
prevent a nullptr memory access
regression by f533701

issue: godotengine/godot#97078
hermet added a commit to thorvg/thorvg that referenced this issue Sep 30, 2024
prevent a nullptr memory access
regression by f533701

issue: godotengine/godot#97078
RadiantUwU pushed a commit to RadiantUwU/godot that referenced this issue Sep 30, 2024
More fixes to rendering of SVG files with broken text tags.

Also backports upstream patch to fix godotengine#97078.

(cherry picked from commit 0c0336f)
laurentmackay pushed a commit to metapfhor/godot that referenced this issue Oct 30, 2024
More fixes to rendering of SVG files with broken text tags.

Also backports upstream patch to fix godotengine#97078.
ChrisBase pushed a commit to ChrisBase/godot that referenced this issue Nov 15, 2024
More fixes to rendering of SVG files with broken text tags.

Also backports upstream patch to fix godotengine#97078.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
Status: Immediate Blocker
Development

Successfully merging a pull request may close this issue.

4 participants