Fix: TextfileWindow called virtual methods before constructor completed. (#11889)
SetStringParameters() was called during widget tree init in the constructor.
Calls within a constructor cannot call the derived classes methods. This would result in invalid data being passed to the string system, which could then crash.
(cherry picked from commit fef0bfcfd3)
This commit is contained in:
committed by
Jonathan G Rennison
parent
a7c2f489f6
commit
4bf9c123d3
@@ -59,6 +59,8 @@ static std::optional<std::string> FindGameManualFilePath(std::string_view filena
|
||||
struct GameManualTextfileWindow : public TextfileWindow {
|
||||
GameManualTextfileWindow(std::string_view filename) : TextfileWindow(TFT_GAME_MANUAL)
|
||||
{
|
||||
this->ConstructWindow();
|
||||
|
||||
/* Mark the content of these files as trusted. */
|
||||
this->trusted = true;
|
||||
|
||||
|
||||
@@ -44,6 +44,8 @@ struct ContentTextfileWindow : public TextfileWindow {
|
||||
|
||||
ContentTextfileWindow(TextfileType file_type, const ContentInfo *ci) : TextfileWindow(file_type), ci(ci)
|
||||
{
|
||||
this->ConstructWindow();
|
||||
|
||||
const char *textfile = this->ci->GetTextfile(file_type);
|
||||
this->LoadTextfile(textfile, GetContentInfoSubDir(this->ci->type));
|
||||
}
|
||||
|
||||
@@ -2571,6 +2571,8 @@ struct SurveyResultTextfileWindow : public TextfileWindow {
|
||||
|
||||
SurveyResultTextfileWindow(TextfileType file_type) : TextfileWindow(file_type)
|
||||
{
|
||||
this->ConstructWindow();
|
||||
|
||||
auto result = _survey.CreatePayload(NetworkSurveyHandler::Reason::PREVIEW, true);
|
||||
this->LoadText(result);
|
||||
this->InvalidateData();
|
||||
|
||||
@@ -573,6 +573,8 @@ struct NewGRFTextfileWindow : public TextfileWindow {
|
||||
|
||||
NewGRFTextfileWindow(TextfileType file_type, const GRFConfig *c) : TextfileWindow(file_type), grf_config(c)
|
||||
{
|
||||
this->ConstructWindow();
|
||||
|
||||
const char *textfile = this->grf_config->GetTextfile(file_type);
|
||||
this->LoadTextfile(textfile, NEWGRF_DIR);
|
||||
}
|
||||
|
||||
@@ -649,6 +649,7 @@ struct ScriptTextfileWindow : public TextfileWindow {
|
||||
|
||||
ScriptTextfileWindow(TextfileType file_type, CompanyID slot) : TextfileWindow(file_type), slot(slot)
|
||||
{
|
||||
this->ConstructWindow();
|
||||
this->OnInvalidateData();
|
||||
}
|
||||
|
||||
|
||||
@@ -105,6 +105,8 @@ struct BaseSetTextfileWindow : public TextfileWindow {
|
||||
|
||||
BaseSetTextfileWindow(TextfileType file_type, const TBaseSet *baseset, StringID content_type) : TextfileWindow(file_type), baseset(baseset), content_type(content_type)
|
||||
{
|
||||
this->ConstructWindow();
|
||||
|
||||
const char *textfile = this->baseset->GetTextfile(file_type);
|
||||
this->LoadTextfile(textfile, BASESET_DIR);
|
||||
}
|
||||
|
||||
@@ -84,13 +84,19 @@ static WindowDesc _textfile_desc(__FILE__, __LINE__,
|
||||
);
|
||||
|
||||
TextfileWindow::TextfileWindow(TextfileType file_type) : Window(&_textfile_desc), file_type(file_type)
|
||||
{
|
||||
/* Init of nested tree is deferred.
|
||||
* TextfileWindow::ConstructWindow must be called by the inheriting window. */
|
||||
}
|
||||
|
||||
void TextfileWindow::ConstructWindow()
|
||||
{
|
||||
this->CreateNestedTree();
|
||||
this->vscroll = this->GetScrollbar(WID_TF_VSCROLLBAR);
|
||||
this->hscroll = this->GetScrollbar(WID_TF_HSCROLLBAR);
|
||||
this->GetWidget<NWidgetCore>(WID_TF_CAPTION)->SetDataTip(STR_TEXTFILE_README_CAPTION + file_type, STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS);
|
||||
this->GetWidget<NWidgetCore>(WID_TF_CAPTION)->SetDataTip(STR_TEXTFILE_README_CAPTION + this->file_type, STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS);
|
||||
this->GetWidget<NWidgetStacked>(WID_TF_SEL_JUMPLIST)->SetDisplayedPlane(SZSP_HORIZONTAL);
|
||||
this->FinishInitNested(file_type);
|
||||
this->FinishInitNested(this->file_type);
|
||||
|
||||
this->DisableWidget(WID_TF_NAVBACK);
|
||||
this->DisableWidget(WID_TF_NAVFORWARD);
|
||||
|
||||
@@ -30,8 +30,6 @@ struct TextfileWindow : public Window, MissingGlyphSearcher {
|
||||
Scrollbar *vscroll; ///< Vertical scrollbar.
|
||||
Scrollbar *hscroll; ///< Horizontal scrollbar.
|
||||
|
||||
TextfileWindow(TextfileType file_type);
|
||||
|
||||
void UpdateWidgetSize(WidgetID widget, Dimension *size, [[maybe_unused]] const Dimension &padding, [[maybe_unused]] Dimension *fill, [[maybe_unused]] Dimension *resize) override;
|
||||
void OnClick([[maybe_unused]] Point pt, WidgetID widget, [[maybe_unused]] int click_count) override;
|
||||
void DrawWidget(const Rect &r, WidgetID widget) const override;
|
||||
@@ -54,6 +52,9 @@ struct TextfileWindow : public Window, MissingGlyphSearcher {
|
||||
}
|
||||
|
||||
protected:
|
||||
TextfileWindow(TextfileType file_type);
|
||||
void ConstructWindow();
|
||||
|
||||
struct Line {
|
||||
int top{0}; ///< Top scroll position in visual lines.
|
||||
int bottom{0}; ///< Bottom scroll position in visual lines.
|
||||
|
||||
Reference in New Issue
Block a user