Skip to content

Commit a995e20

Browse files
committed
Add padding failsafe for DDS textures
1 parent 695bb25 commit a995e20

File tree

1 file changed

+34
-11
lines changed

1 file changed

+34
-11
lines changed

UndertaleModLib/Util/GMImage.cs

Lines changed: 34 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -409,7 +409,7 @@ public static GMImage FromBinaryReader(IBinaryReader reader, long maxEndOfStream
409409
int h = (int)height;
410410

411411
// Starting at 1 because the mipmap count includes the main texture
412-
for (var i = 1; i < mipMapCount; i++)
412+
for (int i = 1; i < mipMapCount; i++)
413413
{
414414
w /= 2;
415415
h /= 2;
@@ -419,20 +419,43 @@ public static GMImage FromBinaryReader(IBinaryReader reader, long maxEndOfStream
419419
}
420420
}
421421

422-
// Read entire data
423-
reader.Position = startAddress;
424-
byte[] bytes = reader.ReadBytes(size);
425-
426-
int byteAmountLeft = (int)(maxEndOfStreamPosition - reader.Position);
422+
// Before reading data, check if our padding is correct (since we don't support the full DDS format...)
423+
long paddingStartAddress = startAddress + size;
424+
long paddingSize = maxEndOfStreamPosition - paddingStartAddress;
425+
bool paddingError = false;
426+
const int maxPaddingSize = 127;
427+
if (paddingSize > maxPaddingSize)
428+
{
429+
// Padding is over 127 bytes in length, which is impossible (it should align to 128-byte boundaries)
430+
paddingError = true;
431+
}
432+
else if (paddingSize > 0)
433+
{
434+
// Ensure padding is all 0 bytes
435+
Span<byte> paddingData = stackalloc byte[maxPaddingSize];
436+
reader.Position = paddingStartAddress;
437+
reader.Stream.ReadExactly(paddingData[..(int)paddingSize]);
438+
for (int i = 0; i < paddingSize; i++)
439+
{
440+
if (paddingData[i] != 0)
441+
{
442+
paddingError = true;
443+
break;
444+
}
445+
}
446+
}
427447

428-
// Check if rest of bytes are 0x00 padded
429-
byte[] paddingBytes = reader.ReadBytes(byteAmountLeft);
430-
for (int i = 0; i < paddingBytes.Length; i++)
448+
// If a padding error was detected, just include it as part of the image data as a failsafe.
449+
// This means that extra padding may be added if textures somehow misalign, but generally this shouldn't be a concern...
450+
if (paddingError)
431451
{
432-
if (paddingBytes[i] != 0)
433-
throw new IOException("Non-zero bytes in padding");
452+
size += (int)paddingSize;
434453
}
435454

455+
// Read entire data
456+
reader.Position = startAddress;
457+
byte[] bytes = reader.ReadBytes(size);
458+
436459
return FromDds(bytes);
437460
}
438461

0 commit comments

Comments
 (0)