Skip to content

Commit

Permalink
Merge pull request #1885 from UnderminersTeam/add-negative-length-checks
Browse files Browse the repository at this point in the history
Add negative length checks during deserialization
  • Loading branch information
Miepee authored Aug 23, 2024
2 parents 4e3f420 + 28d7c87 commit 3dd882b
Show file tree
Hide file tree
Showing 5 changed files with 39 additions and 6 deletions.
4 changes: 2 additions & 2 deletions UndertaleModLib/Models/UndertaleSprite.cs
Original file line number Diff line number Diff line change
Expand Up @@ -764,13 +764,13 @@ public static uint UnserializeChildObjectCount(UndertaleReader reader)
switch (spineVersion)
{
case 1:
reader.Position += 8 + jsonLength + atlasLength + textures;
reader.Position += 8 + (uint)jsonLength + (uint)atlasLength + (uint)textures;
break;

case 2:
case 3:
{
reader.Position += jsonLength + atlasLength;
reader.Position += (uint)jsonLength + (uint)atlasLength;

// TODO: make this return count instead if spine sprite
// couldn't have sequence or nine slices data.
Expand Down
2 changes: 1 addition & 1 deletion UndertaleModLib/UndertaleChunks.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1167,7 +1167,7 @@ private void CheckForTileCompression(UndertaleReader reader)

reader.Position += 32;
int effectCount = reader.ReadInt32();
reader.Position += effectCount * 12 + 4;
reader.Position += (uint)effectCount * 12 + 4;

int tileMapWidth = reader.ReadInt32();
int tileMapHeight = reader.ReadInt32();
Expand Down
4 changes: 2 additions & 2 deletions UndertaleModLib/Util/AdaptiveBinaryReader.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
using System;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
Expand Down Expand Up @@ -86,7 +86,7 @@ public long AbsPosition
{
if (isUsingBufferReader)
{
if (value > Length)
if (value < 0 || value > Length)
throw new IOException("Reading out of bounds.");
bufferBinaryReader.Position = value - bufferBinaryReader.ChunkStartPosition + 8;
}
Expand Down
21 changes: 21 additions & 0 deletions UndertaleModLib/Util/BufferBinaryReader.cs
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,11 @@ public ChunkBuffer(int capacity)

public int Read(byte[] buffer, int count)
{
if (count < 0)
{
throw new ArgumentOutOfRangeException(nameof(count));
}

int n = _length - _position;
if (n > count)
n = count;
Expand Down Expand Up @@ -75,6 +80,9 @@ public byte ReadByte()

public void Write(byte[] buffer, int count)
{
if (count < 0)
throw new ArgumentOutOfRangeException(nameof(count));

int i = _position + count;
if (i < 0)
throw new IOException("Writing out of the chunk buffer bounds.");
Expand Down Expand Up @@ -174,6 +182,10 @@ public virtual bool ReadBoolean()

public string ReadChars(int count)
{
if (count < 0)
{
throw new ArgumentOutOfRangeException(nameof(count));
}
if (chunkBuffer.Position + count > _length)
{
throw new IOException("Reading out of chunk bounds");
Expand All @@ -198,6 +210,10 @@ public string ReadChars(int count)

public byte[] ReadBytes(int count)
{
if (count < 0)
{
throw new ArgumentOutOfRangeException(nameof(count));
}
if (chunkBuffer.Position + count > _length)
{
throw new IOException("Reading out of chunk bounds");
Expand Down Expand Up @@ -268,6 +284,8 @@ public string ReadGMString()

int length = BinaryPrimitives.ReadInt32LittleEndian(ReadToBuffer(4));

if (length < 0)
throw new IOException("Invalid string length");
if (chunkBuffer.Position + length + 1 >= _length)
throw new IOException("Reading out of chunk bounds");

Expand All @@ -293,9 +311,12 @@ public string ReadGMString()

return res;
}

public void SkipGMString()
{
int length = BinaryPrimitives.ReadInt32LittleEndian(ReadToBuffer(4));
if (length < 0)
throw new IOException("Invalid string length");
Position += (uint)length + 1;
}

Expand Down
14 changes: 13 additions & 1 deletion UndertaleModLib/Util/FileBinaryReader.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
using System;
using System;
using System.Buffers.Binary;
using System.IO;
using System.Text;
Expand Down Expand Up @@ -62,6 +62,10 @@ public virtual bool ReadBoolean()

public string ReadChars(int count)
{
if (count < 0)
{
throw new ArgumentOutOfRangeException(nameof(count));
}
if (Stream.Position + count > _length)
{
throw new IOException("Reading out of bounds");
Expand All @@ -85,6 +89,10 @@ public string ReadChars(int count)

public byte[] ReadBytes(int count)
{
if (count < 0)
{
throw new ArgumentOutOfRangeException(nameof(count));
}
if (Stream.Position + count > _length)
{
throw new IOException("Reading out of bounds");
Expand Down Expand Up @@ -204,6 +212,8 @@ public string ReadGMString()

int length = BinaryPrimitives.ReadInt32LittleEndian(ReadToBuffer(4));

if (length < 0)
throw new IOException("Invalid string length");
if (Stream.Position + length + 1 >= _length)
throw new IOException("Reading out of bounds");

Expand Down Expand Up @@ -232,6 +242,8 @@ public string ReadGMString()
public void SkipGMString()
{
int length = BinaryPrimitives.ReadInt32LittleEndian(ReadToBuffer(4));
if (length < 0)
throw new IOException("Invalid string length");
Position += (uint)length + 1;
}

Expand Down

0 comments on commit 3dd882b

Please sign in to comment.