Project

General

Profile

RE: Segfault on Refresh (F5) » SegfaultApp.cpp

Christian Meyer, 06/04/2025 03:03 PM

 

#include "SegfaultApp.h"

#include <Wt/WContainerWidget.h>
#include <Wt/WPushButton.h>
#include <Wt/WTemplate.h>
#include <Wt/WText.h>

#include <Wt/WDialog.h>

namespace TestCase
{
namespace SegfaultOnF5
{
std::unique_ptr<Application> createApplication(const Wt::WEnvironment& env)
{
return std::make_unique<Application>(env);
}


DefaultWidget::DefaultWidget()
{
createLayout();
setupConnections();
}

void DefaultWidget::setupForFail()
{
tmpl_Layout->setCondition("if_Layer2", true);
tmpl_Layout->setCondition("if_Fault", true);
btn_Fail = tmpl_Layout->bindNew<Wt::WPushButton>("btn_Fail", "This Button should not be seen in the example");
btn_Fail->clicked().connect([this](){

addNew<Wt::WText>("This also should never be seen, but the connection itself is key");
});
btn_Fail->clicked().preventPropagation();
}


void DefaultWidget::handlePathChange(const std::string& path)
{
if(path.rfind("/fault", 0) == 0)
{
faultContainer->setHidden(false);
tmpl_Layout->setHidden(true);
}
}

void DefaultWidget::createLayout()
{
faultContainer = addNew<Wt::WContainerWidget>();
faultContainer->addNew<Wt::WText>("If this Widget is shown on Application Startup and navigated away from the app, Destruction should cause a Segfault.");
faultContainer->addNew<Wt::WBreak>();
faultContainer->addNew<Wt::WText>("On the other hand, if after starting here and this button is pressed to show the other widget, it should not.");
faultContainer->addNew<Wt::WBreak>();
btn_Success = faultContainer->addNew<Wt::WPushButton>("Click to avoid Sefault");

faultContainer->setHidden(true);

tmpl_Layout = addNew<Wt::WTemplate>(
"<div>"
"<p>"
"This is the default Widget to be shown. If you see this before navigating away, a Segfault should not happen"
"</p>"
"${<if_Fault>}"
"<p>This should be seen</p>"
"${<if_Layer2>}"
"${btn_Fail}"
"${</if_Layer2>}"
"${</if_Fault>}"
"</div>"
);
tmpl_Layout->setCondition("if_Fault", false);

}

void DefaultWidget::setupConnections()
{

tmpl_Layout->clicked().connect([this](){
this->btn_Fail->setDisabled(true);
});
btn_Success->clicked().connect([this](){
faultContainer->setHidden(true);
tmpl_Layout->setHidden(false);
Wt::WApplication::instance()->setInternalPath("/");
});
}




Application::Application(const Wt::WEnvironment &env)
: Wt::WApplication(env)
{
createLayout();
setupConnections();

wgt_Default->setupForFail();

wgt_Default->handlePathChange(internalPath());
}

void Application::createLayout()
{
wgt_Default = root()->addNew<DefaultWidget>();
}

void Application::setupConnections()
{
internalPathChanged().connect(wgt_Default, &DefaultWidget::handlePathChange);
}



}
}
(2-2/2)