Details
-
Bug
-
Resolution: Unresolved
-
P1: Critical
-
None
-
6.5.7, 6.10.0
-
None
Description
In case of a qml item with a shader attached to it (MultiEffect for ex.), and his width or height are computed as NaN (and there is multiple cases with different behaviour). The app will freeze when attempting to display it.
The minimal repro is attached, here are the cases:
// Crash with error: Invalid property assignment: number expected implicitWidth: "SomeString" // SQG debug assert and infinite loop freeze implicitWidth: { return "SomeString"; } // No error other than broken display width: { return "SomeString"; } // runtime error: Unable to assign [undefined] to double implicitWidth: testMenu.nonExistentProperty // Compile error: Unable to assign [undefined] to double implicitWidth: { return testMenu.nonExistentProperty; } // No error other than broken display width: { return testMenu.nonExistentProperty; } // SQG debug assert and infinite loop freeze implicitWidth: testMenu.nonExistentProperty + 5 // SQG debug assert and infinite loop freeze implicitWidth: { return testMenu.nonExistentProperty + 5; } // No error other than broken display width: { return testMenu.nonExistentProperty + 5; } // SQG debug assert and infinite loop freeze implicitWidth: NaN // SQG debug assert and infinite loop freeze implicitWidth: { return NaN; } // No error other than broken display width: { return NaN; } // SQG debug assert and infinite loop freeze + loop in the main thread in polish implicitWidth: 1 / 0 // SQG debug assert and infinite loop freeze + loop in the main thread in polish implicitWidth: { return 1 / 0; } // SQG debug assert and infinite loop freeze + loop in the main thread in polish width: { return 1 / 0; }
In debug, we also trigger "Q_ASSERT(!textureSize.isEmpty());" in qquickshadereffectsource.cpp. Due to NaN based math before that set the width to 0.
Soon after, the QSGRenderThread will get stuck on:
while (textureSize.width() < minTextureSize.width())
textureSize.rwidth() *= 2;
There are multiple point that would be nice to have changed:
1. if we hit the assert, instead of getting stuck in an infinite loop, would be better to just throw an error log and skip the effect / item.
2. In qquickitem.cpp, setWidth has a
if (qt_is_nan(w)) return;
But not setImplicitWidth. Would be good to have the behavior similar in that matter. Especially that setImplicitWidth also set the width. So we and up in a NaN there too. Same for height, setSize, x, y, position etc.
3. If possible, would be best to throw a runtime error when a NaN for a geometry is returned in all previously mentioned cases.
4. the 1/0 cases seems like an uncatched exception that do some strange things to the main event loop.