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