[FZ Editor] Crash with malformed layout data fix. (#10500)

* check values on json parsing

* comments

* invalidate malformed canvas layouts

* changed error message

* simplify error message

* removed exception message
This commit is contained in:
Seraphima Zykova
2021-03-30 19:42:10 +01:00
committed by GitHub
parent fba4fd91a1
commit 38b9ce3aa2
4 changed files with 83 additions and 68 deletions

View File

@@ -135,15 +135,7 @@ namespace FancyZonesEditor
sb.AppendLine(ParsingErrorDataTag);
sb.AppendLine(parseResult.MalformedData);
string message = parseResult.Message + Environment.NewLine + Environment.NewLine + FancyZonesEditor.Properties.Resources.Error_Parsing_Zones_Settings_User_Choice;
if (MessageBox.Show(message, FancyZonesEditor.Properties.Resources.Error_Parsing_Zones_Settings_Title, MessageBoxButton.YesNo) == MessageBoxResult.No)
{
// TODO: log error
ShowExceptionReportMessageBox(sb.ToString());
Environment.Exit(0);
}
ShowExceptionReportMessageBox(sb.ToString());
MessageBox.Show(parseResult.Message, FancyZonesEditor.Properties.Resources.Error_Parsing_Zones_Settings_Title, MessageBoxButton.OK);
}
MainWindowSettingsModel settings = ((App)Current).MainWindowSettings;

View File

@@ -376,11 +376,11 @@ namespace FancyZonesEditor.Properties {
}
/// <summary>
/// Looks up a localized string similar to &apos;zones-settings.json&apos; contains malformed data..
/// Looks up a localized string similar to A layout that contained invalid data has been removed..
/// </summary>
public static string Error_Parsing_Zones_Settings_Malformed_Data {
public static string Error_Parsing_Zones_Settings_Message {
get {
return ResourceManager.GetString("Error_Parsing_Zones_Settings_Malformed_Data", resourceCulture);
return ResourceManager.GetString("Error_Parsing_Zones_Settings_Message", resourceCulture);
}
}
@@ -393,15 +393,6 @@ namespace FancyZonesEditor.Properties {
}
}
/// <summary>
/// Looks up a localized string similar to Would you like to continue? Malformed data will be lost..
/// </summary>
public static string Error_Parsing_Zones_Settings_User_Choice {
get {
return ResourceManager.GetString("Error_Parsing_Zones_Settings_User_Choice", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Error persisting custom layout.
/// </summary>

View File

@@ -303,14 +303,11 @@
<value>Delete zone</value>
<comment>A tooltip on a button that allows the user to delete a zone</comment>
</data>
<data name="Error_Parsing_Zones_Settings_Malformed_Data" xml:space="preserve">
<value>'zones-settings.json' contains malformed data.</value>
</data>
<data name="Error_Parsing_Zones_Settings_Title" xml:space="preserve">
<value>Editor settings parsing error.</value>
</data>
<data name="Error_Parsing_Zones_Settings_User_Choice" xml:space="preserve">
<value>Would you like to continue? Malformed data will be lost.</value>
<data name="Error_Parsing_Zones_Settings_Message" xml:space="preserve">
<value>A layout that contained invalid data has been removed.</value>
</data>
<data name="Apply_Layout" xml:space="preserve">
<value>Apply layout</value>

View File

@@ -549,7 +549,7 @@ namespace FancyZonesEditor.Utils
if (!devicesParsingResult || !customZonesParsingResult)
{
return new ParsingResult(false, Properties.Resources.Error_Parsing_Zones_Settings_Malformed_Data, settingsString);
return new ParsingResult(false, FancyZonesEditor.Properties.Resources.Error_Parsing_Zones_Settings_Message, settingsString);
}
}
catch (Exception ex)
@@ -810,55 +810,25 @@ namespace FancyZonesEditor.Utils
continue;
}
LayoutModel layout;
if (zoneSet.Type == CanvasLayoutModel.ModelTypeID)
LayoutModel layout = null;
try
{
var info = JsonSerializer.Deserialize<CanvasInfoWrapper>(zoneSet.Info.GetRawText(), _options);
var zones = new List<Int32Rect>();
foreach (var zone in info.Zones)
if (zoneSet.Type == CanvasLayoutModel.ModelTypeID)
{
zones.Add(new Int32Rect { X = (int)zone.X, Y = (int)zone.Y, Width = (int)zone.Width, Height = (int)zone.Height });
layout = ParseCanvasInfo(zoneSet);
}
try
else if (zoneSet.Type == GridLayoutModel.ModelTypeID)
{
layout = new CanvasLayoutModel(zoneSet.Uuid, zoneSet.Name, LayoutType.Custom, zones, info.RefWidth, info.RefHeight);
layout = ParseGridInfo(zoneSet);
}
catch (Exception)
{
continue;
}
layout.SensitivityRadius = info.SensitivityRadius;
}
else if (zoneSet.Type == GridLayoutModel.ModelTypeID)
catch (Exception)
{
var info = JsonSerializer.Deserialize<GridInfoWrapper>(zoneSet.Info.GetRawText(), _options);
var cells = new int[info.Rows, info.Columns];
for (int row = 0; row < info.Rows; row++)
{
for (int column = 0; column < info.Columns; column++)
{
cells[row, column] = info.CellChildMap[row][column];
}
}
try
{
layout = new GridLayoutModel(zoneSet.Uuid, zoneSet.Name, LayoutType.Custom, info.Rows, info.Columns, info.RowsPercentage, info.ColumnsPercentage, cells);
}
catch (Exception)
{
continue;
}
layout.SensitivityRadius = info.SensitivityRadius;
(layout as GridLayoutModel).ShowSpacing = info.ShowSpacing;
(layout as GridLayoutModel).Spacing = info.Spacing;
result = false;
continue;
}
else
if (layout == null)
{
result = false;
continue;
@@ -913,6 +883,71 @@ namespace FancyZonesEditor.Utils
return true;
}
private CanvasLayoutModel ParseCanvasInfo(CustomLayoutWrapper wrapper)
{
var info = JsonSerializer.Deserialize<CanvasInfoWrapper>(wrapper.Info.GetRawText(), _options);
var zones = new List<Int32Rect>();
foreach (var zone in info.Zones)
{
if (zone.Width < 0 || zone.Height < 0)
{
// Malformed data
return null;
}
zones.Add(new Int32Rect { X = zone.X, Y = zone.Y, Width = zone.Width, Height = zone.Height });
}
var layout = new CanvasLayoutModel(wrapper.Uuid, wrapper.Name, LayoutType.Custom, zones, Math.Max(info.RefWidth, 0), Math.Max(info.RefHeight, 0));
layout.SensitivityRadius = info.SensitivityRadius;
return layout;
}
private GridLayoutModel ParseGridInfo(CustomLayoutWrapper wrapper)
{
var info = JsonSerializer.Deserialize<GridInfoWrapper>(wrapper.Info.GetRawText(), _options);
// Check if rows and columns are valid
if (info.Rows <= 0 || info.Columns <= 0)
{
return null;
}
// Check if percentage is valid. Otherwise, Editor could crash on layout rendering.
foreach (int percent in info.RowsPercentage)
{
if (percent < 0)
{
return null;
}
}
foreach (int percent in info.ColumnsPercentage)
{
if (percent < 0)
{
return null;
}
}
var cells = new int[info.Rows, info.Columns];
for (int row = 0; row < info.Rows; row++)
{
for (int column = 0; column < info.Columns; column++)
{
cells[row, column] = info.CellChildMap[row][column];
}
}
var layout = new GridLayoutModel(wrapper.Uuid, wrapper.Name, LayoutType.Custom, info.Rows, info.Columns, info.RowsPercentage, info.ColumnsPercentage, cells);
layout.SensitivityRadius = info.SensitivityRadius;
layout.ShowSpacing = info.ShowSpacing;
layout.Spacing = info.Spacing;
return layout;
}
private LayoutType JsonTagToLayoutType(string tag)
{
switch (tag)