From 4ae3c519e23474641f20983379992c54dc087d5e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Mon, 10 Jul 2023 19:26:41 +0200 Subject: [PATCH] Add assorted null checks for safety More probably needed. Should at least hopefully fix the leaderboard crash reported in #17631 Will try to do something more systematic later. --- Common/System/OSD.cpp | 2 +- Common/UI/Context.cpp | 4 ++++ Core/RetroAchievements.cpp | 10 +++++++--- UI/OnScreenDisplay.cpp | 4 ++++ UI/RetroAchievementScreens.cpp | 17 +++++++++++++---- 5 files changed, 29 insertions(+), 8 deletions(-) diff --git a/Common/System/OSD.cpp b/Common/System/OSD.cpp index 8013463e95..02d1e4d2c9 100644 --- a/Common/System/OSD.cpp +++ b/Common/System/OSD.cpp @@ -168,7 +168,7 @@ void OnScreenDisplay::ShowLeaderboardTracker(int leaderboardTrackerID, const cha if (entry.numericID == leaderboardTrackerID && entry.type == OSDType::LEADERBOARD_TRACKER) { if (show) { // Just an update. - entry.text = trackerText; + entry.text = trackerText ? trackerText : ""; } else { // Keep the current text, hide and eventually delete it. entry.endTime = now + (double)FadeoutTime(); diff --git a/Common/UI/Context.cpp b/Common/UI/Context.cpp index 6e4e277f07..87ab52594b 100644 --- a/Common/UI/Context.cpp +++ b/Common/UI/Context.cpp @@ -208,10 +208,12 @@ void UIContext::SetFontStyle(const UI::FontStyle &fontStyle) { } void UIContext::MeasureText(const UI::FontStyle &style, float scaleX, float scaleY, const char *str, float *x, float *y, int align) const { + _dbg_assert_(str != nullptr); MeasureTextCount(style, scaleX, scaleY, str, (int)strlen(str), x, y, align); } void UIContext::MeasureTextCount(const UI::FontStyle &style, float scaleX, float scaleY, const char *str, int count, float *x, float *y, int align) const { + _dbg_assert_(str != nullptr); if (!textDrawer_ || (align & FLAG_DYNAMIC_ASCII)) { float sizeFactor = (float)style.sizePts / 24.0f; Draw()->SetFontScale(scaleX * sizeFactor, scaleY * sizeFactor); @@ -225,6 +227,7 @@ void UIContext::MeasureTextCount(const UI::FontStyle &style, float scaleX, float } void UIContext::MeasureTextRect(const UI::FontStyle &style, float scaleX, float scaleY, const char *str, int count, const Bounds &bounds, float *x, float *y, int align) const { + _dbg_assert_(str != nullptr); if (!textDrawer_ || (align & FLAG_DYNAMIC_ASCII)) { float sizeFactor = (float)style.sizePts / 24.0f; Draw()->SetFontScale(scaleX * sizeFactor, scaleY * sizeFactor); @@ -238,6 +241,7 @@ void UIContext::MeasureTextRect(const UI::FontStyle &style, float scaleX, float } void UIContext::DrawText(const char *str, float x, float y, uint32_t color, int align) { + _dbg_assert_(str != nullptr); if (!textDrawer_ || (align & FLAG_DYNAMIC_ASCII)) { // Use the font texture if this font is in that texture instead. bool useFontTexture = Draw()->GetFontAtlas()->getFont(fontStyle_->atlasFont) != nullptr; diff --git a/Core/RetroAchievements.cpp b/Core/RetroAchievements.cpp index bee733c43f..c7170955b0 100644 --- a/Core/RetroAchievements.cpp +++ b/Core/RetroAchievements.cpp @@ -51,6 +51,10 @@ #include "Core/FileSystems/MetaFileSystem.h" #include "Core/RetroAchievements.h" +static inline const char *DeNull(const char *ptr) { + return ptr ? ptr : ""; +} + void OSDOpenBackgroundProgressDialog(const char *str_id, std::string message, s32 min, s32 max, s32 value) { NOTICE_LOG(ACHIEVEMENTS, "Progress dialog opened: %s %s", str_id, message.c_str()); g_OSD.SetProgressBar(str_id, std::move(message), min, max, value); @@ -271,7 +275,7 @@ static void event_handler_callback(const rc_client_event_t *event, rc_client_t * std::string message = StringFromFormat(ac->T("%d achievements"), summary.num_unlocked_achievements); - g_OSD.Show(OSDType::MESSAGE_INFO, title, message, gameInfo->badge_name, 10.0f); + g_OSD.Show(OSDType::MESSAGE_INFO, title, message, DeNull(gameInfo->badge_name), 10.0f); INFO_LOG(ACHIEVEMENTS, "%s", message.c_str()); break; @@ -279,7 +283,7 @@ static void event_handler_callback(const rc_client_event_t *event, rc_client_t * case RC_CLIENT_EVENT_LEADERBOARD_STARTED: // A leaderboard attempt has started. The handler may show a message with the leaderboard title and /or description indicating the attempt started. INFO_LOG(ACHIEVEMENTS, "Leaderboard attempt started: %s", event->leaderboard->title); - g_OSD.Show(OSDType::MESSAGE_INFO, ReplaceAll(ac->T("%1: Leaderboard attempt started"), "%1", event->leaderboard->title), event->leaderboard->description, 3.0f); + g_OSD.Show(OSDType::MESSAGE_INFO, ReplaceAll(ac->T("%1: Leaderboard attempt started"), "%1", event->leaderboard->title), DeNull(event->leaderboard->description), 3.0f); break; case RC_CLIENT_EVENT_LEADERBOARD_FAILED: NOTICE_LOG(ACHIEVEMENTS, "Leaderboard attempt failed: %s", event->leaderboard->title); @@ -288,7 +292,7 @@ static void event_handler_callback(const rc_client_event_t *event, rc_client_t * break; case RC_CLIENT_EVENT_LEADERBOARD_SUBMITTED: NOTICE_LOG(ACHIEVEMENTS, "Leaderboard result submitted: %s", event->leaderboard->title); - g_OSD.Show(OSDType::MESSAGE_SUCCESS, ReplaceAll(ReplaceAll(ac->T("%1: Submitting leaderboard score: %2!"), "%1", event->leaderboard->title), "%2", event->leaderboard->tracker_value), event->leaderboard->description, 3.0f); + g_OSD.Show(OSDType::MESSAGE_SUCCESS, ReplaceAll(ReplaceAll(ac->T("%1: Submitting leaderboard score: %2!"), "%1", DeNull(event->leaderboard->title)), "%2", DeNull(event->leaderboard->tracker_value)), DeNull(event->leaderboard->description), 3.0f); // A leaderboard attempt was completed.The handler may show a message with the leaderboard title and /or description indicating the final value being submitted to the server. break; case RC_CLIENT_EVENT_ACHIEVEMENT_CHALLENGE_INDICATOR_SHOW: diff --git a/UI/OnScreenDisplay.cpp b/UI/OnScreenDisplay.cpp index 2c1a0b30ee..3617b19ca4 100644 --- a/UI/OnScreenDisplay.cpp +++ b/UI/OnScreenDisplay.cpp @@ -18,6 +18,10 @@ #include "Common/Net/HTTPClient.h" #include "Core/Config.h" +static inline const char *DeNull(const char *ptr) { + return ptr ? ptr : ""; +} + static const float g_atlasIconSize = 36.0f; static const float extraTextScale = 0.7f; diff --git a/UI/RetroAchievementScreens.cpp b/UI/RetroAchievementScreens.cpp index 9474e19086..79e4492fc4 100644 --- a/UI/RetroAchievementScreens.cpp +++ b/UI/RetroAchievementScreens.cpp @@ -10,6 +10,10 @@ #include "Core/Config.h" #include "Core/RetroAchievements.h" +static inline const char *DeNull(const char *ptr) { + return ptr ? ptr : ""; +} + void RetroAchievementsListScreen::CreateTabs() { auto ac = GetI18NCategory(I18NCat::ACHIEVEMENTS); @@ -378,7 +382,7 @@ void RenderAchievement(UIContext &dc, const rc_client_achievement_t *achievement dc.DrawTextRect(achievement->title, bounds.Inset(iconSpace + 12.0f, 2.0f, padding, padding), fgColor, ALIGN_TOPLEFT); dc.SetFontScale(0.66f, 0.66f); - dc.DrawTextRect(achievement->description, bounds.Inset(iconSpace + 12.0f, 39.0f, padding, padding), fgColor, ALIGN_TOPLEFT); + dc.DrawTextRect(DeNull(achievement->description), bounds.Inset(iconSpace + 12.0f, 39.0f, padding, padding), fgColor, ALIGN_TOPLEFT); if (style == AchievementRenderStyle::LISTED && strlen(achievement->measured_progress) > 0) { dc.SetFontScale(1.0f, 1.0f); @@ -482,10 +486,10 @@ void RenderLeaderboardSummary(UIContext &dc, const rc_client_leaderboard_t *lead dc.SetFontStyle(dc.theme->uiFont); dc.SetFontScale(1.0f, 1.0f); - dc.DrawTextRect(leaderboard->title, bounds.Inset(12.0f, 2.0f, 5.0f, 5.0f), fgColor, ALIGN_TOPLEFT); + dc.DrawTextRect(DeNull(leaderboard->title), bounds.Inset(12.0f, 2.0f, 5.0f, 5.0f), fgColor, ALIGN_TOPLEFT); dc.SetFontScale(0.66f, 0.66f); - dc.DrawTextRect(leaderboard->description, bounds.Inset(12.0f, 39.0f, 5.0f, 5.0f), fgColor, ALIGN_TOPLEFT); + dc.DrawTextRect(DeNull(leaderboard->description), bounds.Inset(12.0f, 39.0f, 5.0f, 5.0f), fgColor, ALIGN_TOPLEFT); /* char temp[64]; @@ -514,6 +518,11 @@ void RenderLeaderboardEntry(UIContext &dc, const rc_client_leaderboard_entry_t * float iconLeft = numberSpace + 5.0f; float iconSpace = numberSpace + 5.0f + iconSize; + // Sanity check + if (!entry->user) { + return; + } + dc.Flush(); dc.Begin(); @@ -528,7 +537,7 @@ void RenderLeaderboardEntry(UIContext &dc, const rc_client_leaderboard_entry_t * dc.DrawTextRect(entry->user, bounds.Inset(iconSpace + 5.0f, 2.0f, 5.0f, 5.0f), fgColor, ALIGN_TOPLEFT); dc.SetFontScale(0.66f, 0.66f); - dc.DrawTextRect(entry->display, bounds.Inset(iconSpace + 5.0f, 38.0f, 5.0f, 5.0f), fgColor, ALIGN_TOPLEFT); + dc.DrawTextRect(DeNull(entry->display), bounds.Inset(iconSpace + 5.0f, 38.0f, 5.0f, 5.0f), fgColor, ALIGN_TOPLEFT); dc.SetFontScale(1.0f, 1.0f); dc.Flush();