From 5eec9d29cb35b094a611262333d65b89f834d965 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20Mail=C3=A4nder?= Date: Tue, 30 May 2023 19:38:58 +0200 Subject: [PATCH] Add a lint check for invalid integer expression syntax. --- .../Lint/CheckChromeIntegerExpressions.cs | 54 +++++++++++++++++++ 1 file changed, 54 insertions(+) create mode 100644 OpenRA.Mods.Common/Lint/CheckChromeIntegerExpressions.cs diff --git a/OpenRA.Mods.Common/Lint/CheckChromeIntegerExpressions.cs b/OpenRA.Mods.Common/Lint/CheckChromeIntegerExpressions.cs new file mode 100644 index 0000000000..909f804817 --- /dev/null +++ b/OpenRA.Mods.Common/Lint/CheckChromeIntegerExpressions.cs @@ -0,0 +1,54 @@ +#region Copyright & License Information +/* + * Copyright (c) The OpenRA Developers and Contributors + * This file is part of OpenRA, which is free software. It is made + * available to you under the terms of the GNU General Public License + * as published by the Free Software Foundation, either version 3 of + * the License, or (at your option) any later version. For more + * information, see COPYING. + */ +#endregion + +using System; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using OpenRA.Support; + +namespace OpenRA.Mods.Common.Lint +{ + class CheckChromeIntegerExpressions : ILintPass + { + public void Run(Action emitError, Action emitWarning, ModData modData) + { + foreach (var filename in modData.Manifest.ChromeLayout) + CheckInner(MiniYaml.FromStream(modData.DefaultFileSystem.Open(filename), filename), filename, emitError); + } + + void CheckInner(List nodes, string filename, Action emitError) + { + var substitutions = new Dictionary(); + var readOnlySubstitutions = new ReadOnlyDictionary(substitutions); + + foreach (var node in nodes) + { + if (node.Value == null) + continue; + + if (node.Key == "X" || node.Key == "Y" || node.Key == "Width" || node.Key == "Height") + { + try + { + FieldLoader.GetValue(node.Key, node.Value.Value); + } + catch (YamlException e) + { + emitError($"Failed to parse integer expression in {node}: {e.Message}"); + } + } + + if (node.Value.Nodes != null) + CheckInner(node.Value.Nodes, filename, emitError); + } + } + } +}