Skip to content

Commit

Permalink
Fixed crashing on invalid localization bbcode text (#3226)
Browse files Browse the repository at this point in the history
* Fixed crashing on invalid localization bbcode text

also now the rich text labels will catch any exceptions that happen to be safe against this happening again

* Catch formatting exceptions in LocalizedString
  • Loading branch information
hhyyrylainen committed Apr 17, 2022
1 parent d8ecada commit 7e68563
Show file tree
Hide file tree
Showing 3 changed files with 55 additions and 18 deletions.
13 changes: 11 additions & 2 deletions src/engine/LocalizedString.cs
Expand Up @@ -48,8 +48,17 @@ public string ToString(string? format, IFormatProvider? formatProvider)
return format ?? TranslationServer.Translate(translationKey);
}

return string.Format(formatProvider ?? CultureInfo.CurrentCulture,
format ?? TranslationServer.Translate(translationKey), formatStringArgs);
try
{
return string.Format(formatProvider ?? CultureInfo.CurrentCulture,
format ?? TranslationServer.Translate(translationKey), formatStringArgs);
}
catch (FormatException e)
{
GD.PrintErr("Invalid translation format in string ", translationKey, " for current language, exception: ",
e);
return TranslationServer.Translate(translationKey);
}
}

public override bool Equals(object? obj)
Expand Down
56 changes: 43 additions & 13 deletions src/gui_common/CustomRichTextLabel.cs
Expand Up @@ -89,17 +89,13 @@ public override void _Draw()
}

/// <summary>
/// Parses ExtendedBbcode for any custom Thrive tags and applying the final result
/// into this RichTextLabel's bbcode text.
/// The actual method parsing our extended bbcode, <see cref="ParseCustomTags"/>. This is a separate method
/// to be able to easily catch any exceptions this causes.
/// </summary>
private void ParseCustomTags()
/// <param name="extendedBbcode">The extended bbcode string</param>
/// <returns>Parsed bbcode string in standard format</returns>
private static string ParseCustomTagsString(string extendedBbcode)
{
if (extendedBbcode == null)
{
BbcodeText = null;
return;
}

var result = new StringBuilder(extendedBbcode.Length);
var currentTagBlock = new StringBuilder(50);

Expand Down Expand Up @@ -197,12 +193,20 @@ private void ParseCustomTags()
// Is a closing tag
if (bbcodeNamespace.StartsWith("/", StringComparison.InvariantCulture))
{
if (tagStack.Count < 1)
{
// We have a closing tag with no opening tag seen
result.Append($"[{tagBlock}]");
isIteratingTag = false;
continue;
}

var chunks = tagStack.Peek();

var bbcode = chunks[0];

// Closing tag doesn't match opening tag or vice versa, aborting parsing
if (tagStack.Count == 0 || bbcode != splitTagBlock[0])
if (bbcode != splitTagBlock[0])
{
result.Append($"[{tagBlock}]");
isIteratingTag = false;
Expand Down Expand Up @@ -248,8 +252,8 @@ private void ParseCustomTags()
}
}

// Apply the final string into this RichTextLabel's bbcode text
BbcodeText = result.ToString();
// Return the final string which will be used as this RichTextLabel's bbcode text
return result.ToString();
}

/// <summary>
Expand All @@ -258,7 +262,7 @@ private void ParseCustomTags()
/// <param name="input">The string enclosed by the custom tags</param>
/// <param name="bbcode">Custom Thrive bbcode-styled tags</param>
/// <param name="attributes">Attributes specifying additional functionalities to the bbcode.</param>
private string BuildTemplateForTag(string input, ThriveBbCode bbcode, List<string> attributes)
private static string BuildTemplateForTag(string input, ThriveBbCode bbcode, List<string> attributes)
{
// Defaults to input so if something fails output returns unchanged
var output = input;
Expand Down Expand Up @@ -384,6 +388,32 @@ private string BuildTemplateForTag(string input, ThriveBbCode bbcode, List<strin
return output;
}

/// <summary>
/// Parses ExtendedBbcode for any custom Thrive tags and applying the final result
/// into this RichTextLabel's bbcode text.
/// </summary>
private void ParseCustomTags()
{
if (extendedBbcode == null)
{
BbcodeText = null;
return;
}

try
{
// Parse our custom tags into standard tags and display that text
BbcodeText = ParseCustomTagsString(extendedBbcode);
}
catch (Exception e)
{
GD.PrintErr("Failed to parse bbcode string due to exception: ", e);

// Just display the raw markup for now
BbcodeText = extendedBbcode;
}
}

private void OnInputsRemapped(object sender, EventArgs args)
{
ParseCustomTags();
Expand Down
4 changes: 1 addition & 3 deletions src/microbe_stage/editor/PatchMapEditorComponent.cs
Expand Up @@ -384,9 +384,7 @@ private void UpdatePatchDetails(Patch patch)
patch.BiomeTemplate.Name);

// {0}-{1}m below sea level
patchDepth.Text = string.Format(CultureInfo.CurrentCulture,
TranslationServer.Translate("BELOW_SEA_LEVEL"),
patch.Depth[0], patch.Depth[1]);
patchDepth.Text = new LocalizedString("BELOW_SEA_LEVEL", patch.Depth[0], patch.Depth[1]).ToString();
patchPlayerHere.Visible = Editor.CurrentPatch == patch;

var percentageFormat = TranslationServer.Translate("PERCENTAGE_VALUE");
Expand Down

0 comments on commit 7e68563

Please sign in to comment.