[Scummvm-git-logs] scummvm master -> 3ca9da6a1c36ed1450ec5c5f08d48a225c7699df

sdelamarre noreply at scummvm.org
Tue Nov 4 22:02:13 UTC 2025


This automated email contains information about 1 new commit which have been
pushed to the 'scummvm' repo located at https://api.github.com/repos/scummvm/scummvm .

Summary:
3ca9da6a1c GOB: Allow to read past announced Resource size() when unpacking sprites


Commit: 3ca9da6a1c36ed1450ec5c5f08d48a225c7699df
    https://github.com/scummvm/scummvm/commit/3ca9da6a1c36ed1450ec5c5f08d48a225c7699df
Author: Simon Delamarre (simon.delamarre14 at gmail.com)
Date: 2025-11-04T23:01:54+01:00

Commit Message:
GOB: Allow to read past announced Resource size() when unpacking sprites

Resource size() is not always reliable, and is actually not required to
bound the read, as the chunks to unpack it contains are prefixed with
their length.

Fix a corrupted sprites issue in the character creation step in Adi4.

Changed paths:
    engines/gob/cmpfile.cpp
    engines/gob/draw_fascin.cpp
    engines/gob/draw_playtoons.cpp
    engines/gob/draw_v1.cpp
    engines/gob/draw_v2.cpp
    engines/gob/init.cpp
    engines/gob/inter_v1.cpp
    engines/gob/inter_v6.cpp
    engines/gob/inter_v7.cpp
    engines/gob/video.cpp
    engines/gob/video.h
    engines/gob/video_v1.cpp
    engines/gob/video_v2.cpp
    engines/gob/video_v6.cpp


diff --git a/engines/gob/cmpfile.cpp b/engines/gob/cmpfile.cpp
index 8ef50ebd0c9..183d48ed438 100644
--- a/engines/gob/cmpfile.cpp
+++ b/engines/gob/cmpfile.cpp
@@ -146,7 +146,7 @@ void CMPFile::loadCMP(Common::SeekableReadStream &cmp) {
 		return;
 	}
 
-	_vm->_video->drawPackedSprite(data, size, _surface->getWidth(), _surface->getHeight(), 0, 0, 0, *_surface);
+	_vm->_video->drawPackedSprite(data, _surface->getWidth(), _surface->getHeight(), 0, 0, 0, *_surface);
 
 	delete[] data;
 }
diff --git a/engines/gob/draw_fascin.cpp b/engines/gob/draw_fascin.cpp
index 8ad199646e5..5748aba589f 100644
--- a/engines/gob/draw_fascin.cpp
+++ b/engines/gob/draw_fascin.cpp
@@ -196,7 +196,7 @@ void Draw_Fascination::spriteOperation(int16 operation, bool ttsAddHotspotText)
 		if (!resource)
 			break;
 
-		_vm->_video->drawPackedSprite(resource->getData(), resource->getSize(),
+		_vm->_video->drawPackedSprite(resource->getData(),
 				_spriteRight, _spriteBottom, _destSpriteX, _destSpriteY,
 				_transparency, *_spritesArray[_destSurface]);
 
@@ -430,7 +430,7 @@ void Draw_Fascination::drawWin(int16 fct) {
 			break;
 		}
 
-		_vm->_video->drawPackedSprite(resource->getData(), resource->getSize(),
+		_vm->_video->drawPackedSprite(resource->getData(),
 				_spriteRight, _spriteBottom, _destSpriteX, _destSpriteY,
 				_transparency, *_spritesArray[_destSurface]);
 
@@ -747,7 +747,7 @@ void Draw_Fascination::decompWin(int16 x, int16 y, SurfacePtr destPtr) {
 	if (!resource)
 		return;
 
-	_vm->_video->drawPackedSprite(resource->getData(), resource->getSize(),
+	_vm->_video->drawPackedSprite(resource->getData(),
 			_spriteRight, _spriteBottom, x, y, _transparency, *destPtr);
 
 	delete resource;
diff --git a/engines/gob/draw_playtoons.cpp b/engines/gob/draw_playtoons.cpp
index f9a82af9bf6..97fd66ba7fc 100644
--- a/engines/gob/draw_playtoons.cpp
+++ b/engines/gob/draw_playtoons.cpp
@@ -865,7 +865,7 @@ void Draw_Playtoons::spriteOperation(int16 operation, bool ttsAddHotspotText) {
 		if (!resource)
 			break;
 
-		_vm->_video->drawPackedSprite(resource->getData(), resource->getSize(),
+		_vm->_video->drawPackedSprite(resource->getData(),
 				_spriteRight, _spriteBottom, _destSpriteX, _destSpriteY,
 				_transparency, *_spritesArray[_destSurface]);
 
diff --git a/engines/gob/draw_v1.cpp b/engines/gob/draw_v1.cpp
index 7ea2a36df24..e63210a6eec 100644
--- a/engines/gob/draw_v1.cpp
+++ b/engines/gob/draw_v1.cpp
@@ -414,7 +414,7 @@ void Draw_v1::spriteOperation(int16 operation, bool ttsAddHotspotText) {
 		if (!resource)
 			break;
 
-		_vm->_video->drawPackedSprite(resource->getData(), resource->getSize(),
+		_vm->_video->drawPackedSprite(resource->getData(),
 				_spriteRight, _spriteBottom, _destSpriteX, _destSpriteY,
 				_transparency, *_spritesArray[_destSurface]);
 
diff --git a/engines/gob/draw_v2.cpp b/engines/gob/draw_v2.cpp
index 43bc16e5187..261c4fe59e8 100644
--- a/engines/gob/draw_v2.cpp
+++ b/engines/gob/draw_v2.cpp
@@ -814,7 +814,7 @@ void Draw_v2::spriteOperation(int16 operation, bool ttsAddHotspotText) {
 		if (_vm->_draw->_needAdjust == 3 || _vm->_draw->_needAdjust == 4)
 			adjustCoords(0, &_spriteRight, &_spriteBottom);
 
-		_vm->_video->drawPackedSprite(resource->getData(), resource->getSize(),
+		_vm->_video->drawPackedSprite(resource->getData(),
 				_spriteRight, _spriteBottom, _destSpriteX, _destSpriteY,
 				_transparency, *_spritesArray[_destSurface]);
 
diff --git a/engines/gob/init.cpp b/engines/gob/init.cpp
index 885c8460221..cf31c4ed937 100644
--- a/engines/gob/init.cpp
+++ b/engines/gob/init.cpp
@@ -194,7 +194,7 @@ void Init::initGame() {
 				int32 size;
 				byte *sprite = _vm->_dataIO->getFile("coktel.ims", size);
 				if (sprite) {
-					_vm->_video->drawPackedSprite(sprite, size, 320, 200, 0, 0, 0,
+					_vm->_video->drawPackedSprite(sprite, 320, 200, 0, 0, 0,
 							*_vm->_draw->_frontSurface);
 					_vm->_palAnim->fade(_palDesc, 0, 0);
 					_vm->_util->delay(500);
diff --git a/engines/gob/inter_v1.cpp b/engines/gob/inter_v1.cpp
index 683be2a8aad..b3c316992b4 100644
--- a/engines/gob/inter_v1.cpp
+++ b/engines/gob/inter_v1.cpp
@@ -772,7 +772,7 @@ void Inter_v1::o1_loadCursor(OpFuncParams &params) {
 	int16 height = resource->getHeight();
 	_vm->_draw->adjustCoords(0, &width, &height);
 
-	_vm->_video->drawPackedSprite(resource->getData(), resource->getSize(),
+	_vm->_video->drawPackedSprite(resource->getData(),
 			width, height,
 			index * _vm->_draw->_cursorWidth, 0, 0, *_vm->_draw->_cursorSprites);
 	_vm->_draw->_cursorAnimLow[index] = 0;
diff --git a/engines/gob/inter_v6.cpp b/engines/gob/inter_v6.cpp
index 971e6fc2417..72fc08f4a0c 100644
--- a/engines/gob/inter_v6.cpp
+++ b/engines/gob/inter_v6.cpp
@@ -253,7 +253,7 @@ void Inter_v6::o6_loadCursor(OpFuncParams &params) {
 			index * _vm->_draw->_cursorWidth + _vm->_draw->_cursorWidth - 1,
 			_vm->_draw->_cursorHeight - 1, 0);
 
-	_vm->_video->drawPackedSprite(resource->getData(), resource->getSize(),
+	_vm->_video->drawPackedSprite(resource->getData(),
 			resource->getWidth(), resource->getHeight(),
 			index * _vm->_draw->_cursorWidth, 0, 0, *_vm->_draw->_cursorSprites);
 	_vm->_draw->_cursorAnimLow[index] = 0;
diff --git a/engines/gob/inter_v7.cpp b/engines/gob/inter_v7.cpp
index 6cacabc077e..38c3d9b7166 100644
--- a/engines/gob/inter_v7.cpp
+++ b/engines/gob/inter_v7.cpp
@@ -241,7 +241,7 @@ void Inter_v7::o7_loadCursor(OpFuncParams &params) {
 										 index * _vm->_draw->_cursorWidth + _vm->_draw->_cursorWidth - 1,
 										 _vm->_draw->_cursorHeight - 1, 0);
 
-	_vm->_video->drawPackedSprite(resource->getData(), resource->getSize(),
+	_vm->_video->drawPackedSprite(resource->getData(),
 								  resource->getWidth(), resource->getHeight(),
 								  index * _vm->_draw->_cursorWidth, 0, 0, *_vm->_draw->_cursorSprites);
 	_vm->_draw->_cursorAnimLow[index] = 0;
diff --git a/engines/gob/video.cpp b/engines/gob/video.cpp
index c711da51994..1fca42ea216 100644
--- a/engines/gob/video.cpp
+++ b/engines/gob/video.cpp
@@ -325,7 +325,7 @@ void Video::sparseRetrace(int max) {
 	_lastSparse = timeKey;
 }
 
-void Video::drawPacked(byte *sprBuf, int32 size, int16 width, int16 height,
+void Video::drawPacked(byte *sprBuf, int16 width, int16 height,
 		int16 x, int16 y, byte transp, Surface &dest) {
 
 	int destRight = x + width;
@@ -371,7 +371,7 @@ void Video::drawPacked(byte *sprBuf, int32 size, int16 width, int16 height,
 	}
 }
 
-void Video::drawPackedSprite(byte *sprBuf, int32 size, int16 width, int16 height,
+void Video::drawPackedSprite(byte *sprBuf, int16 width, int16 height,
 		int16 x, int16 y, int16 transp, Surface &dest) {
 
 	if (y + height > dest.getHeight()) {
@@ -379,10 +379,10 @@ void Video::drawPackedSprite(byte *sprBuf, int32 size, int16 width, int16 height
 		return;
 	}
 
-	if (spriteUncompressor(sprBuf, size, width, height, x, y, transp, dest))
+	if (spriteUncompressor(sprBuf, width, height, x, y, transp, dest))
 		return;
 
-	drawPacked(sprBuf,size,  width, height, x, y, transp, dest);
+	drawPacked(sprBuf, width, height, x, y, transp, dest);
 }
 
 void Video::drawPackedSprite(const char *path, Surface &dest, int width) {
@@ -393,7 +393,7 @@ void Video::drawPackedSprite(const char *path, Surface &dest, int width) {
 		return;
 	}
 
-	drawPackedSprite(data, size, width, dest.getHeight(), 0, 0, 0, dest);
+	drawPackedSprite(data, width, dest.getHeight(), 0, 0, 0, dest);
 	delete[] data;
 }
 
diff --git a/engines/gob/video.h b/engines/gob/video.h
index de2987b648a..1aca3d94ed4 100644
--- a/engines/gob/video.h
+++ b/engines/gob/video.h
@@ -129,7 +129,7 @@ public:
 	void waitRetrace(bool mouse = true);
 	void sparseRetrace(int max);
 
-	void drawPackedSprite(byte *sprBuf, int32 size, int16 width, int16 height,
+	void drawPackedSprite(byte *sprBuf, int16 width, int16 height,
 			int16 x, int16 y, int16 transp, Surface &dest);
 	void drawPackedSprite(const char *path, Surface &dest, int width = 320);
 
@@ -152,7 +152,7 @@ public:
 	void dirtyRectsAdd(int16 left, int16 top, int16 right, int16 bottom);
 	void dirtyRectsApply(int left, int top, int width, int height, int x, int y);
 
-	virtual char spriteUncompressor(byte *sprBuf, int32 size, int16 srcWidth,
+	virtual char spriteUncompressor(byte *sprBuf, int16 srcWidth,
 			int16 srcHeight, int16 x, int16 y, int16 transp,
 			Surface &destDesc) = 0;
 
@@ -168,12 +168,12 @@ protected:
 
 	GobEngine *_vm;
 
-	void drawPacked(byte *sprBuf, int32 size, int16 width, int16 height, int16 x, int16 y, byte transp, Surface &dest);
+	void drawPacked(byte *sprBuf, int16 width, int16 height, int16 x, int16 y, byte transp, Surface &dest);
 };
 
 class Video_v1 : public Video {
 public:
-	char spriteUncompressor(byte *sprBuf, int32 size, int16 srcWidth, int16 srcHeight,
+	char spriteUncompressor(byte *sprBuf, int16 srcWidth, int16 srcHeight,
 			int16 x, int16 y, int16 transp, Surface &destDesc) override;
 
 	Video_v1(GobEngine *vm);
@@ -182,7 +182,7 @@ public:
 
 class Video_v2 : public Video_v1 {
 public:
-	char spriteUncompressor(byte *sprBuf, int32 size, int16 srcWidth, int16 srcHeight,
+	char spriteUncompressor(byte *sprBuf, int16 srcWidth, int16 srcHeight,
 			int16 x, int16 y, int16 transp, Surface &destDesc) override;
 
 	Video_v2(GobEngine *vm);
@@ -191,7 +191,7 @@ public:
 
 class Video_v6 : public Video_v2 {
 public:
-	char spriteUncompressor(byte *sprBuf, int32 size, int16 srcWidth, int16 srcHeight,
+	char spriteUncompressor(byte *sprBuf, int16 srcWidth, int16 srcHeight,
 			int16 x, int16 y, int16 transp, Surface &destDesc) override;
 
 	Video_v6(GobEngine *vm);
@@ -200,7 +200,7 @@ public:
 private:
 	Graphics::PixelFormat _highColorPackedSpriteFormat;
 
-	void drawPacked(const byte *sprBuf, int32 size, int16 x, int16 y, Surface &surfDesc);
+	void drawPacked(const byte *sprBuf, int16 x, int16 y, Surface &surfDesc);
 	void drawYUVData(const byte *srcData, Surface &destDesc,
 			int16 width, int16 height, int16 x, int16 y);
 	void drawYUV(Surface &destDesc, int16 x, int16 y,
diff --git a/engines/gob/video_v1.cpp b/engines/gob/video_v1.cpp
index cfef8a4d31c..8d40d4c04bd 100644
--- a/engines/gob/video_v1.cpp
+++ b/engines/gob/video_v1.cpp
@@ -35,7 +35,7 @@ namespace Gob {
 Video_v1::Video_v1(GobEngine *vm) : Video(vm) {
 }
 
-char Video_v1::spriteUncompressor(byte *sprBuf, int32 size, int16 srcWidth, int16 srcHeight,
+char Video_v1::spriteUncompressor(byte *sprBuf, int16 srcWidth, int16 srcHeight,
 	    int16 x, int16 y, int16 transp, Surface &destDesc) {
 	byte *memBuffer;
 	byte *srcPtr;
diff --git a/engines/gob/video_v2.cpp b/engines/gob/video_v2.cpp
index 05cdf0a3e9c..783ac4d5c8e 100644
--- a/engines/gob/video_v2.cpp
+++ b/engines/gob/video_v2.cpp
@@ -37,7 +37,7 @@ namespace Gob {
 Video_v2::Video_v2(GobEngine *vm) : Video_v1(vm) {
 }
 
-char Video_v2::spriteUncompressor(byte *sprBuf, int32 size, int16 srcWidth, int16 srcHeight,
+char Video_v2::spriteUncompressor(byte *sprBuf, int16 srcWidth, int16 srcHeight,
 	    int16 x, int16 y, int16 transp, Surface &destDesc) {
 	byte *memBuffer;
 	byte *srcPtr;
diff --git a/engines/gob/video_v6.cpp b/engines/gob/video_v6.cpp
index 6c476e3a1ab..aad18a26a00 100644
--- a/engines/gob/video_v6.cpp
+++ b/engines/gob/video_v6.cpp
@@ -41,11 +41,11 @@ Video_v6::Video_v6(GobEngine *vm) : Video_v2(vm), _highColorPackedSpriteFormat(2
 {
 }
 
-char Video_v6::spriteUncompressor(byte *sprBuf, int32 size, int16 srcWidth, int16 srcHeight,
+char Video_v6::spriteUncompressor(byte *sprBuf, int16 srcWidth, int16 srcHeight,
 	    int16 x, int16 y, int16 transp, Surface &destDesc) {
 
 	if ((sprBuf[0] == 1) && (sprBuf[1] == 3)) {
-		drawPacked(sprBuf, size, x, y, destDesc);
+		drawPacked(sprBuf, x, y, destDesc);
 		return 1;
 	}
 
@@ -55,10 +55,10 @@ char Video_v6::spriteUncompressor(byte *sprBuf, int32 size, int16 srcWidth, int1
 	}
 
 	if ((sprBuf[0] == 1) && (sprBuf[1] == 2)) {
-		if (Video_v2::spriteUncompressor(sprBuf, size, srcWidth, srcHeight, x, y, transp, destDesc))
+		if (Video_v2::spriteUncompressor(sprBuf, srcWidth, srcHeight, x, y, transp, destDesc))
 			return 1;
 
-		Video::drawPacked(sprBuf, size, srcWidth, srcHeight, x, y, transp, destDesc);
+		Video::drawPacked(sprBuf, srcWidth, srcHeight, x, y, transp, destDesc);
 		return 1;
 	}
 
@@ -67,7 +67,11 @@ char Video_v6::spriteUncompressor(byte *sprBuf, int32 size, int16 srcWidth, int1
 	return 1;
 }
 
-void Video_v6::drawPacked(const byte *sprBuf, int32 size, int16 x, int16 y, Surface &surfDesc) {
+#ifndef INT32_MAX
+#define INT32_MAX              (2147483647)
+#endif
+
+void Video_v6::drawPacked(const byte *sprBuf, int16 x, int16 y, Surface &surfDesc) {
 	const byte *data = sprBuf + 2;
 
 	int16 width = READ_LE_UINT16(data);
@@ -84,13 +88,13 @@ void Video_v6::drawPacked(const byte *sprBuf, int32 size, int16 x, int16 y, Surf
 		// Compressed YUV data
 		warning("drawPacked: untested case, compressed YUV data");
 		int32 uncompresedSize = 0;
-		byte *uncompressedData = DataIO::unpack(srcData, size, uncompresedSize, 1);
+		byte *uncompressedData = DataIO::unpack(srcData, INT32_MAX, uncompresedSize, 1);
 		drawYUVData(uncompressedData, surfDesc, width, height, x, y);
 		delete uncompressedData;
 	} else if (dataType == 3) {
 		// Compressed high-color RGB data
 		int32 uncompresesSize = 0;
-		byte *uncompressedData = DataIO::unpack(srcData, size, uncompresesSize, 1);
+		byte *uncompressedData = DataIO::unpack(srcData, INT32_MAX, uncompresesSize, 1);
 		Graphics::PixelFormat &format = _highColorPackedSpriteFormat;
 
 		if (_vm->getPixelFormat().aBits() > 0) {
@@ -105,12 +109,12 @@ void Video_v6::drawPacked(const byte *sprBuf, int32 size, int16 x, int16 y, Surf
 												  surfDesc.getWidth() * surfDesc.getBPP(), width * format.bytesPerPixel,
 												  width, height,
 												  _vm->getPixelFormat(), format, 0);
-		}
-		else
+		} else {
 			conversionOk = Graphics::crossBlit(surfDesc.getData(x, y), uncompressedData,
 											   surfDesc.getWidth() * surfDesc.getBPP(), width * format.bytesPerPixel,
 											   width, height,
 											   _vm->getPixelFormat(), format);
+		}
 
 		if (!conversionOk)
 			warning("drawPacked: error when cross-blitting from compressed RGB high-color data");




More information about the Scummvm-git-logs mailing list