From 871d46e50c00b5a3030aa694538a51d5c1707fd6 Mon Sep 17 00:00:00 2001 From: biwa <6475593+biwa@users.noreply.github.com> Date: Thu, 15 Apr 2021 22:06:49 +0200 Subject: [PATCH] Added some sanity checks for maximum number of entries in the VERTEXES/SIDEDEFS/LINEDEFS/THINGS lumps for the binary map formats --- Source/Core/IO/DoomMapSetIO.cs | 39 ++++++++++++++++++++++++++++++++- Source/Core/IO/HexenMapSetIO.cs | 39 ++++++++++++++++++++++++++++++++- 2 files changed, 76 insertions(+), 2 deletions(-) diff --git a/Source/Core/IO/DoomMapSetIO.cs b/Source/Core/IO/DoomMapSetIO.cs index c592cf118..6aee0b66e 100755 --- a/Source/Core/IO/DoomMapSetIO.cs +++ b/Source/Core/IO/DoomMapSetIO.cs @@ -124,7 +124,14 @@ namespace CodeImp.DoomBuilder.IO MemoryStream mem = new MemoryStream(lump.Stream.ReadAllBytes()); int num = (int)lump.Stream.Length / 10; BinaryReader reader = new BinaryReader(mem); - + + // Sanity check against the defined maximum + if (num > General.Map.FormatInterface.MaxThings) + { + General.ErrorLogger.Add(ErrorType.Warning, "There are " + num + " thing entries in the THINGS lump, exceeding the limit of " + General.Map.FormatInterface.MaxThings + " entries. Things after this limit will be ignored"); + num = General.Map.FormatInterface.MaxThings; + } + // Read items from the lump map.SetCapacity(0, 0, 0, 0, map.Things.Count + num); for(int i = 0; i < num; i++) @@ -166,6 +173,16 @@ namespace CodeImp.DoomBuilder.IO int num = (int)lump.Stream.Length / 4; BinaryReader reader = new BinaryReader(mem); + // There are some maps that have more than 65536 vertices, for example MAP32 of https://www.doomworld.com/forum/topic/106186-frog_and_toadwad-12-maps/ + // Vertices after this limit should not be read, as they can't be referenced by linedefs anyway, and cause massive slowdowns while loading (likely due to + // CreateVertex not creating vertices past the limit and trying to play a warning sound) + // Also see https://github.com/jewalky/UltimateDoomBuilder/issues/552 + if (num > General.Map.FormatInterface.MaxVertices) + { + General.ErrorLogger.Add(ErrorType.Warning, "There are " + num + " vertex entries in the VERTEXES lump, exceeding the limit of " + General.Map.FormatInterface.MaxVertices + " entries. Vertices after this limit will be ignored"); + num = General.Map.FormatInterface.MaxVertices; + } + // Create lookup table Dictionary<int, Vertex> link = new Dictionary<int, Vertex>(num); @@ -204,6 +221,13 @@ namespace CodeImp.DoomBuilder.IO int num = (int)lump.Stream.Length / 26; BinaryReader reader = new BinaryReader(mem); + // Sanity check against the defined maximum + if (num > General.Map.FormatInterface.MaxSectors) + { + General.ErrorLogger.Add(ErrorType.Warning, "There are " + num + " sector entries in the SECTORS lump, exceeding the limit of " + General.Map.FormatInterface.MaxSectors + " entries. Sectors after this limit will be ignored"); + num = General.Map.FormatInterface.MaxSectors; + } + // Create lookup table Dictionary<int, Sector> link = new Dictionary<int, Sector>(num); @@ -255,6 +279,19 @@ namespace CodeImp.DoomBuilder.IO BinaryReader readline = new BinaryReader(linedefsmem); BinaryReader readside = new BinaryReader(sidedefsmem); + // Sanity check against the defined maximum + if (num > General.Map.FormatInterface.MaxLinedefs) + { + General.ErrorLogger.Add(ErrorType.Warning, "There are " + num + " linedef entries in the LINEDEFS lump, exceeding the limit of " + General.Map.FormatInterface.MaxLinedefs + " entries. Linedefs after this limit will be ignored"); + num = General.Map.FormatInterface.MaxLinedefs; + } + + if (numsides > General.Map.FormatInterface.MaxSidedefs) + { + General.ErrorLogger.Add(ErrorType.Warning, "There are " + numsides + " sidedef entries in the SIDEDEFS lump, exceeding the limit of " + General.Map.FormatInterface.MaxSidedefs + " entries. Sidedefs after this limit will be ignored"); + numsides = General.Map.FormatInterface.MaxSidedefs; + } + // Read items from the lump map.SetCapacity(0, map.Linedefs.Count + num, map.Sidedefs.Count + numsides, 0, 0); for(int i = 0; i < num; i++) diff --git a/Source/Core/IO/HexenMapSetIO.cs b/Source/Core/IO/HexenMapSetIO.cs index e4ca3d433..5bbff6798 100755 --- a/Source/Core/IO/HexenMapSetIO.cs +++ b/Source/Core/IO/HexenMapSetIO.cs @@ -124,7 +124,14 @@ namespace CodeImp.DoomBuilder.IO MemoryStream mem = new MemoryStream(lump.Stream.ReadAllBytes()); int num = (int)lump.Stream.Length / 20; BinaryReader reader = new BinaryReader(mem); - + + // Sanity check against the defined maximum + if (num > General.Map.FormatInterface.MaxThings) + { + General.ErrorLogger.Add(ErrorType.Warning, "There are " + num + " thing entries in the THINGS lump, exceeding the limit of " + General.Map.FormatInterface.MaxThings + " entries. Things after this limit will be ignored"); + num = General.Map.FormatInterface.MaxThings; + } + // Read items from the lump map.SetCapacity(0, 0, 0, 0, map.Things.Count + num); for(int i = 0; i < num; i++) @@ -174,6 +181,16 @@ namespace CodeImp.DoomBuilder.IO int num = (int)lump.Stream.Length / 4; BinaryReader reader = new BinaryReader(mem); + // There are some maps that have more than 65536 vertices, for example MAP32 of https://www.doomworld.com/forum/topic/106186-frog_and_toadwad-12-maps/ + // Vertices after this limit should not be read, as they can't be referenced by linedefs anyway, and cause massive slowdowns while loading (likely due to + // CreateVertex not creating vertices past the limit and trying to play a warning sound) + // Also see https://github.com/jewalky/UltimateDoomBuilder/issues/552 + if (num > General.Map.FormatInterface.MaxVertices) + { + General.ErrorLogger.Add(ErrorType.Warning, "There are " + num + " vertex entries in the VERTEXES lump, exceeding the limit of " + General.Map.FormatInterface.MaxVertices + " entries. Vertices after this limit will be ignored"); + num = General.Map.FormatInterface.MaxVertices; + } + // Create lookup table Dictionary<int, Vertex> link = new Dictionary<int, Vertex>(num); @@ -212,6 +229,13 @@ namespace CodeImp.DoomBuilder.IO int num = (int)lump.Stream.Length / 26; BinaryReader reader = new BinaryReader(mem); + // Sanity check against the defined maximum + if (num > General.Map.FormatInterface.MaxSectors) + { + General.ErrorLogger.Add(ErrorType.Warning, "There are " + num + " sector entries in the SECTORS lump, exceeding the limit of " + General.Map.FormatInterface.MaxSectors + " entries. Sectors after this limit will be ignored"); + num = General.Map.FormatInterface.MaxSectors; + } + // Create lookup table Dictionary<int, Sector> link = new Dictionary<int, Sector>(num); @@ -265,6 +289,19 @@ namespace CodeImp.DoomBuilder.IO BinaryReader readline = new BinaryReader(linedefsmem); BinaryReader readside = new BinaryReader(sidedefsmem); + // Sanity check against the defined maximum + if (num > General.Map.FormatInterface.MaxLinedefs) + { + General.ErrorLogger.Add(ErrorType.Warning, "There are " + num + " linedef entries in the LINEDEFS lump, exceeding the limit of " + General.Map.FormatInterface.MaxLinedefs + " entries. Linedefs after this limit will be ignored"); + num = General.Map.FormatInterface.MaxLinedefs; + } + + if (numsides > General.Map.FormatInterface.MaxSidedefs) + { + General.ErrorLogger.Add(ErrorType.Warning, "There are " + numsides + " sidedef entries in the SIDEDEFS lump, exceeding the limit of " + General.Map.FormatInterface.MaxSidedefs + " entries. Sidedefs after this limit will be ignored"); + numsides = General.Map.FormatInterface.MaxSidedefs; + } + // Read items from the lump map.SetCapacity(0, map.Linedefs.Count + num, map.Sidedefs.Count + numsides, 0, 0); for(int i = 0; i < num; i++) -- GitLab