From ce1ca376f14b1e2d173405e659ede970cdc946f0 Mon Sep 17 00:00:00 2001 From: tetektoza Date: Sun, 19 Oct 2025 21:12:56 +0200 Subject: [PATCH] Gui: Fix stack-use-after-return in DlgSettingsLightSources lambdas Randomly discovered during some other bug hunt, only with AddressSanitizer on. Basically, ASAN detected stack-use-after-return when playing with spinboxes in the Light Sources preferences when Qt signal handlers tried to invoke lambda callbacks that referenced deallocated stack memory. The main problem is that those lambda functions in the constructor were captruing by reference. When they were connected to Qt signals and invoked after constructor completed, they accessed stack vars that have gone out of scope. So fixed that by changing lambda captures from `[&]` to explicit captures: - [this] for lambdas needing only class member access - [this, updateLight] for lambdas that need both class members and the `updateLight` lambda. --- .../DlgSettingsLightSources.cpp | 52 +++++++++---------- 1 file changed, 26 insertions(+), 26 deletions(-) diff --git a/src/Gui/PreferencePages/DlgSettingsLightSources.cpp b/src/Gui/PreferencePages/DlgSettingsLightSources.cpp index ac096778a8..0f22b577de 100644 --- a/src/Gui/PreferencePages/DlgSettingsLightSources.cpp +++ b/src/Gui/PreferencePages/DlgSettingsLightSources.cpp @@ -54,12 +54,12 @@ DlgSettingsLightSources::DlgSettingsLightSources(QWidget* parent) configureViewer(); - const auto connectLightEvents = [&](QuantitySpinBox* horizontalAngleSpinBox, - QuantitySpinBox* verticalAngleSpinBox, - QSpinBox* intensitySpinBox, - ColorButton* colorButton, - QCheckBox* enabledCheckbox, - auto updateLightFunction) { + const auto connectLightEvents = [this](QuantitySpinBox* horizontalAngleSpinBox, + QuantitySpinBox* verticalAngleSpinBox, + QSpinBox* intensitySpinBox, + ColorButton* colorButton, + QCheckBox* enabledCheckbox, + auto updateLightFunction) { connect(horizontalAngleSpinBox, qOverload(&QuantitySpinBox::valueChanged), this, @@ -80,13 +80,13 @@ DlgSettingsLightSources::DlgSettingsLightSources(QWidget* parent) #endif }; - const auto updateLight = [&](SoDirectionalLight* light, - QuantitySpinBox* horizontalAngleSpinBox, - QuantitySpinBox* verticalAngleSpinBox, - QSpinBox* intensitySpinBox, - ColorButton* colorButton, - QCheckBox* enabledCheckbox, - std::function setLightEnabled) { + const auto updateLight = [this](SoDirectionalLight* light, + QuantitySpinBox* horizontalAngleSpinBox, + QuantitySpinBox* verticalAngleSpinBox, + QSpinBox* intensitySpinBox, + ColorButton* colorButton, + QCheckBox* enabledCheckbox, + std::function setLightEnabled) { light->color = Base::convertTo(colorButton->color()); light->intensity = Base::fromPercent(intensitySpinBox->value()); light->direction = @@ -95,38 +95,38 @@ DlgSettingsLightSources::DlgSettingsLightSources(QWidget* parent) setLightEnabled(enabledCheckbox->isChecked()); }; - const auto updateHeadLight = [&] { + const auto updateHeadLight = [this, updateLight] { updateLight(view->getHeadlight(), ui->mainLightHorizontalAngle, ui->mainLightVerticalAngle, ui->mainLightIntensitySpinBox, ui->mainLightColor, ui->mainLightEnable, - [&](bool enabled) { + [this](bool enabled) { view->setHeadlightEnabled(enabled); }); }; - const auto updateFillLight = [&] { + const auto updateFillLight = [this, updateLight] { updateLight(view->getFillLight(), ui->fillLightHorizontalAngle, ui->fillLightVerticalAngle, ui->fillLightIntensitySpinBox, ui->fillLightColor, ui->fillLightEnable, - [&](bool enabled) { + [this](bool enabled) { view->setFillLightEnabled(enabled); }); }; - const auto updateBackLight = [&] { + const auto updateBackLight = [this, updateLight] { updateLight(view->getBacklight(), ui->backLightHorizontalAngle, ui->backLightVerticalAngle, ui->backLightIntensitySpinBox, ui->backLightColor, ui->backLightEnable, - [&](bool enabled) { + [this](bool enabled) { view->setBacklightEnabled(enabled); }); }; @@ -150,7 +150,7 @@ DlgSettingsLightSources::DlgSettingsLightSources(QWidget* parent) ui->fillLightEnable, updateFillLight); - const auto updateAmbientLight = [&] { + const auto updateAmbientLight = [this] { view->getEnvironment()->ambientColor = Base::convertTo(ui->ambientLightColor->color()); view->getEnvironment()->ambientIntensity = @@ -269,9 +269,9 @@ void DlgSettingsLightSources::saveSettings() } } - const auto saveAngles = [&](QuantitySpinBox* horizontalAngleSpinBox, - QuantitySpinBox* verticalAngleSpinBox, - const char* parameter) { + const auto saveAngles = [this](QuantitySpinBox* horizontalAngleSpinBox, + QuantitySpinBox* verticalAngleSpinBox, + const char* parameter) { try { const auto direction = azimuthElevationToDirection(horizontalAngleSpinBox->rawValue(), verticalAngleSpinBox->rawValue()); @@ -296,9 +296,9 @@ void DlgSettingsLightSources::loadSettings() } } - const auto loadAngles = [&](QuantitySpinBox* horizontalAngleSpinBox, - QuantitySpinBox* verticalAngleSpinBox, - const char* parameter) { + const auto loadAngles = [this](QuantitySpinBox* horizontalAngleSpinBox, + QuantitySpinBox* verticalAngleSpinBox, + const char* parameter) { try { const auto direction = Base::stringToVector(hGrp->GetASCII(parameter)); const auto [azimuth, elevation] =