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 {
|
struct GameManualTextfileWindow : public TextfileWindow {
|
||||||
GameManualTextfileWindow(std::string_view filename) : TextfileWindow(TFT_GAME_MANUAL)
|
GameManualTextfileWindow(std::string_view filename) : TextfileWindow(TFT_GAME_MANUAL)
|
||||||
{
|
{
|
||||||
|
this->ConstructWindow();
|
||||||
|
|
||||||
/* Mark the content of these files as trusted. */
|
/* Mark the content of these files as trusted. */
|
||||||
this->trusted = true;
|
this->trusted = true;
|
||||||
|
|
||||||
|
|||||||
@@ -44,6 +44,8 @@ struct ContentTextfileWindow : public TextfileWindow {
|
|||||||
|
|
||||||
ContentTextfileWindow(TextfileType file_type, const ContentInfo *ci) : TextfileWindow(file_type), ci(ci)
|
ContentTextfileWindow(TextfileType file_type, const ContentInfo *ci) : TextfileWindow(file_type), ci(ci)
|
||||||
{
|
{
|
||||||
|
this->ConstructWindow();
|
||||||
|
|
||||||
const char *textfile = this->ci->GetTextfile(file_type);
|
const char *textfile = this->ci->GetTextfile(file_type);
|
||||||
this->LoadTextfile(textfile, GetContentInfoSubDir(this->ci->type));
|
this->LoadTextfile(textfile, GetContentInfoSubDir(this->ci->type));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2571,6 +2571,8 @@ struct SurveyResultTextfileWindow : public TextfileWindow {
|
|||||||
|
|
||||||
SurveyResultTextfileWindow(TextfileType file_type) : TextfileWindow(file_type)
|
SurveyResultTextfileWindow(TextfileType file_type) : TextfileWindow(file_type)
|
||||||
{
|
{
|
||||||
|
this->ConstructWindow();
|
||||||
|
|
||||||
auto result = _survey.CreatePayload(NetworkSurveyHandler::Reason::PREVIEW, true);
|
auto result = _survey.CreatePayload(NetworkSurveyHandler::Reason::PREVIEW, true);
|
||||||
this->LoadText(result);
|
this->LoadText(result);
|
||||||
this->InvalidateData();
|
this->InvalidateData();
|
||||||
|
|||||||
@@ -573,6 +573,8 @@ struct NewGRFTextfileWindow : public TextfileWindow {
|
|||||||
|
|
||||||
NewGRFTextfileWindow(TextfileType file_type, const GRFConfig *c) : TextfileWindow(file_type), grf_config(c)
|
NewGRFTextfileWindow(TextfileType file_type, const GRFConfig *c) : TextfileWindow(file_type), grf_config(c)
|
||||||
{
|
{
|
||||||
|
this->ConstructWindow();
|
||||||
|
|
||||||
const char *textfile = this->grf_config->GetTextfile(file_type);
|
const char *textfile = this->grf_config->GetTextfile(file_type);
|
||||||
this->LoadTextfile(textfile, NEWGRF_DIR);
|
this->LoadTextfile(textfile, NEWGRF_DIR);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -649,6 +649,7 @@ struct ScriptTextfileWindow : public TextfileWindow {
|
|||||||
|
|
||||||
ScriptTextfileWindow(TextfileType file_type, CompanyID slot) : TextfileWindow(file_type), slot(slot)
|
ScriptTextfileWindow(TextfileType file_type, CompanyID slot) : TextfileWindow(file_type), slot(slot)
|
||||||
{
|
{
|
||||||
|
this->ConstructWindow();
|
||||||
this->OnInvalidateData();
|
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)
|
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);
|
const char *textfile = this->baseset->GetTextfile(file_type);
|
||||||
this->LoadTextfile(textfile, BASESET_DIR);
|
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)
|
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->CreateNestedTree();
|
||||||
this->vscroll = this->GetScrollbar(WID_TF_VSCROLLBAR);
|
this->vscroll = this->GetScrollbar(WID_TF_VSCROLLBAR);
|
||||||
this->hscroll = this->GetScrollbar(WID_TF_HSCROLLBAR);
|
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->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_NAVBACK);
|
||||||
this->DisableWidget(WID_TF_NAVFORWARD);
|
this->DisableWidget(WID_TF_NAVFORWARD);
|
||||||
|
|||||||
@@ -30,8 +30,6 @@ struct TextfileWindow : public Window, MissingGlyphSearcher {
|
|||||||
Scrollbar *vscroll; ///< Vertical scrollbar.
|
Scrollbar *vscroll; ///< Vertical scrollbar.
|
||||||
Scrollbar *hscroll; ///< Horizontal 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 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 OnClick([[maybe_unused]] Point pt, WidgetID widget, [[maybe_unused]] int click_count) override;
|
||||||
void DrawWidget(const Rect &r, WidgetID widget) const override;
|
void DrawWidget(const Rect &r, WidgetID widget) const override;
|
||||||
@@ -54,6 +52,9 @@ struct TextfileWindow : public Window, MissingGlyphSearcher {
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
TextfileWindow(TextfileType file_type);
|
||||||
|
void ConstructWindow();
|
||||||
|
|
||||||
struct Line {
|
struct Line {
|
||||||
int top{0}; ///< Top scroll position in visual lines.
|
int top{0}; ///< Top scroll position in visual lines.
|
||||||
int bottom{0}; ///< Bottom scroll position in visual lines.
|
int bottom{0}; ///< Bottom scroll position in visual lines.
|
||||||
|
|||||||
Reference in New Issue
Block a user