SpriteAnimation in SceneRender backend are access an empty vector
Describe the bug
Crash because of std::out_of_range exception on std::vector at. I think this because backend are trying to access an empty vector.
Workshop link
Most of the wallpaper workshop meet this crash
System Information
- Kde: 6.4.4
- Qt:: 3.1
- OS: Fedora
- Installation Source: Git
- Wallpaper Engine version: 2.7 meet this, fallback to 2.6 fixed this
Additional context
LOG:
#7 0x00007f12206091b4 in __gnu_cxx::__verbose_terminate_handler() [clone .cold] () from /lib64/libstdc++.so.6 #8 0x00007f122061eb9c in __cxxabiv1::__terminate(void (*)()) () from /lib64/libstdc++.so.6 #9 0x00007f1220608d3a in std::terminate() () from /lib64/libstdc++.so.6 #10 0x00007f122061ee48 in __cxa_throw () from /lib64/libstdc++.so.6 #11 0x00007f122060c5fd in std::__throw_out_of_range_fmt(char const*, ...) () from /lib64/libstdc++.so.6 #12 0x00007f11d3803f7c in std::vector<wallpaper::SpriteFrame, std::allocator<wallpaper::SpriteFrame> >::_M_range_check (this=0x7f11d89fd618, __n=0) at /usr/include/c++/15/bits/stl_vector.h:1293 #13 std::vector<wallpaper::SpriteFrame, std::allocator<wallpaper::SpriteFrame> >::at (this=0x7f11d89fd618, __n=0) at /usr/include/c++/15/bits/stl_vector.h:1334 #14 wallpaper::SpriteAnimation::GetCurFrame (this=0x7f11d89fd608) at /home/user/wallpaper-engine-kde-plugin/src/backend_scene/src/./SpriteAnimation.hpp:36 #15 (anonymous namespace)::LoadMaterial (vfs=..., wpmat=..., pScene=<optimized out>, pMaterial=pMaterial@entry=0x7f11d89fdb10, pSvData=pSvData@entry=0x7f11d89fda20, pWPShaderInfo=<optimized out>, pWPShaderInfo@entry=0x7f11d89fdbb0, pNode=0x7f11b80ecd50) at /home/user/wallpaper-engine-kde-plugin/src/backend_scene/src/WPSceneParser.cpp:374 #16 0x00007f11d383ad7f in (anonymous namespace)::ParseParticleObj (context=..., wppartobj=..., child_ptr=...) at /home/user/wallpaper-engine-kde-plugin/src/backend_scene/src/WPSceneParser.cpp:988 #17 0x00007f11d3843f5c in operator() (__closure=<optimized out>, obj=...) at /home/user/wallpaper-engine-kde-plugin/src/backend_scene/src/WPSceneParser.cpp:1160
Recommend solution
The problem seem to be in backend SpriteAnimation at method GetAnimateFrame (https://github.com/catsout/wallpaper-scene-renderer/blob/beda015d4720e9a91e2d8869590256826590291e/src/SpriteAnimation.hpp#L25C1-L40C1).
I have this assumption is because most crashed wallpaper is the thing with Sprite like this Ahri wallpaper workshop/content/431960/2184359275/scene.json+scene while wallpaper with only video render don't meet this crash. Dive in the code at method GetAnimateFrame all access m_frame code are run at without any try catch out of range.
const auto& frame = m_frames.at((usize)m_curFrame);
Hence if the out_of_range meet the KDE will crash.
Temporary solution recommend: : Use try catch out_of_range exception at all m_frames.at((usize)m_curFrame);
Solid solution recommend: : Check the way WE 2.7 are returning the Sprite Animation. Maybe from WE 2.6 to 2.7 they changed something with the way Sprite is output.
Hope this will help.
For anyone are need a hot fixed. Fall back to Wallpaper engine 2.6 seem to fix most of the issue as this comment https://github.com/catsout/wallpaper-engine-kde-plugin/issues/534#issuecomment-3259330881
UPDATE:
I found out where the error is. It is at WPImageEffiect::FromJson
https://github.com/catsout/wallpaper-scene-renderer/blob/beda015d4720e9a91e2d8869590256826590291e/src/wpscene/WPImageObject.cpp#L49C1-L78C2
The thing is json format changed in newer version of WE. Two key are missing in the new version are angles and scale. Here you can see 2 json from a new WE that cause crash and a old one that work OK.
"new_ng_json": { "alpha": 0, "castshadow": false, "clampuvs": true, "disablepropagation": false, "id": 34, "image": "models/util/solidlayer.json", "name": "Solid", "origin": "1920.00000 1080.00000 0.00000", "size": "100.00000 100.00000", "visible": { "script": "'use strict';\n\nexport var scriptProperties = createScriptProperties()\n\t.addCheckbox({\n\t\tname: 'activationSound',\n\t\tlabel: 'Sound Play trigger',\n\t\tvalue: false\n\t})\n\t.finish();\n\n// Condition of Checkbox when checked = play, else stop\nexport function update() {\n if (scriptProperties.activationSound === false) {\n thisScene.getLayer('Moonlit Solitude (Instrumental).mp3').play();\n }\n}\n\n\nlet soundLayerName = 'Moonlit Solitude (Instrumental).mp3'; //change this to the name of the sound layer\n\nexport function cursorClick(event)\n\n{\n\nif (thisScene.getLayer(soundLayerName).isPlaying())\n\n{\n\n thisScene.getLayer(soundLayerName).stop(); //if you want track to pause change \".stop()\" to \".pause()\"\n\n}\n\nelse thisScene.getLayer(soundLayerName).stop();\n\n}", "scriptproperties": { "activationSound": { "user": "stoporplaymusic", "value": true } }, "value": true } }
"old_ok_json": { "alignment": "center", "alpha": 1, "angles": "0.000 0.000 0.000", "color": "1.000 1.000 1.000", "colorBlendMode": 0, "copybackground": true, "effects": [ { "file": "effects/waterwaves/effect.json", "id": 546, "name": "", "passes": [ { "constantshadervalues": { "direction": 2.5535900500422257, "scale": 21.06, "speed": 3.17, "strength": 0.04 }, "textures": [ null, "masks/waterwaves_mask_58d65906b6fa5c1cd6b42cf08d1b7a41605f9cbb" ] } ], "visible": true }, { "file": "effects/waterwaves/effect.json", "id": 561, "name": "", "passes": [ { "constantshadervalues": { "direction": 1.4254863161591944, "strength": 0.04 }, "textures": [ null, "masks/waterwaves_mask_e864acbbac5cc83035e8ec642695dce8e1cf1b6a" ] } ], "visible": true }, { "file": "effects/waterwaves/effect.json", "id": 573, "name": "", "passes": [ { "constantshadervalues": { "direction": 2.2858880260737204, "scale": 52.64, "speed": 3.17, "strength": 0.05 }, "textures": [ null, "masks/waterwaves_mask_8031e77678ff36970c82b0b66ebea75bb6a1bd36" ] } ], "visible": true }, { "file": "effects/waterwaves/effect.json", "id": 590, "name": "", "passes": [ { "constantshadervalues": { "direction": -2.263438170004201, "scale": 15.8, "speed": 3.43, "strength": 0.04 }, "textures": [ null, "masks/waterwaves_mask_9af5eedee80ebfec519539942f5b9e9908dbf12b" ] } ], "visible": true }, { "file": "effects/waterwaves/effect.json", "id": 603, "name": "", "passes": [ { "constantshadervalues": { "direction": 2.3086113869153615, "scale": 47.38, "speed": 2.64, "strength": 0.05 }, "textures": [ null, "masks/waterwaves_mask_a01080c4f6adfbdbacc03b1d0414c9a4daefc352" ] } ], "visible": true }, { "file": "effects/waterwaves/effect.json", "id": 630, "name": "", "passes": [ { "constantshadervalues": { "direction": 1.9631364710104124, "scale": 10.54, "speed": 1.85, "strength": 0.05 }, "textures": [ null, "masks/waterwaves_mask_b7ba210caf7ea60f6c1bc53d7ff128af44fd3967" ] } ], "visible": true }, { "file": "effects/waterwaves/effect.json", "id": 643, "name": "", "passes": [ { "constantshadervalues": { "direction": 0.982793723247329, "scale": 42.11, "speed": 2.64, "strength": 0.04 }, "textures": [ null, "masks/waterwaves_mask_a244f3c0ad93253480c74aa401fa7a025f84233d" ] } ], "visible": true }, { "file": "effects/waterripple/effect.json", "id": 687, "name": "", "passes": [ { "constantshadervalues": { "animationspeed": 0, "ripplestrength": 0.04, "scale": 1.11, "scrolldirection": 0.03844259002118799, "scrollspeed": 0.23 }, "textures": [ null, "masks/waterripple_mask_547bff636de002983ef78f7e95aaeca251671850", "effects/waterripplenormal" ] } ], "visible": true }, { "file": "effects/pulse/effect.json", "id": 747, "name": "", "passes": [ { "combos": { "BLENDMODE": 0 }, "constantshadervalues": { "amount": 0.24, "speed": 5.22, "tinthigh": "0 1 1" }, "textures": [ null, "util/noise", "masks/pulse_mask_ae31195cde802cf25acf6f7f84d0ad9bfecd635c" ] } ], "visible": true }, { "file": "effects/shake/effect.json", "id": 424, "name": "", "passes": [ { "constantshadervalues": { "speed": 2.39, "strength": 0.07 }, "textures": [ null, "masks/shake_mask_ac9cbb27e5fc9f715120b89ddd704a94bd6cc8ff", "util/white" ] } ], "visible": true }, { "file": "effects/shake/effect.json", "id": 761, "name": "", "passes": [ { "constantshadervalues": { "speed": 3.44, "strength": 0.08 }, "textures": [ null, "masks/shake_mask_6d2950ab8c9449a30c55f3091dc40df550e12dfc", "util/white" ] } ], "visible": true } ], "id": 13, "image": "models/1.json", "ledsource": false, "locktransforms": true, "name": "1", "origin": "1920.000 1080.000 0.000", "parallaxDepth": "1.000 1.000", "perspective": false, "scale": "1.000 1.000 1.000", "size": "3840.000 2160.000", "solid": true, "visible": true }
I am working on a fix for this method. I think maybe angles and scalestill somewhere in this new json, it is just that they changed the format