changeset 18059:d560ef366011 draft

(svn r22874) -Fix [FS#4747]: Check size of various buffers before allocation. (monoid)
author michi_cc <michi_cc@openttd.org>
date Fri, 02 Sep 2011 20:16:41 +0000
parents 1d79b9eb4b64
children 26f943948e28
files src/fontcache.cpp src/openttd.cpp src/script/squirrel_helper.hpp src/sound.cpp src/sound/win32_s.cpp
diffstat 5 files changed, 15 insertions(+), 5 deletions(-) [+]
line wrap: on
line diff
--- a/src/fontcache.cpp
+++ b/src/fontcache.cpp
@@ -1034,6 +1034,9 @@
 	width  = max(1, slot->bitmap.width + (size == FS_NORMAL));
 	height = max(1, slot->bitmap.rows  + (size == FS_NORMAL));
 
+	/* Limit glyph size to prevent overflows later on. */
+	if (width > 256 || height > 256) usererror("Font glyph is too large");
+
 	/* FreeType has rendered the glyph, now we allocate a sprite and copy the image into it */
 	sprite.AllocateData(width * height);
 	sprite.width = width;
--- a/src/openttd.cpp
+++ b/src/openttd.cpp
@@ -596,11 +596,12 @@
 
 	/*
 	 * The width and height must be at least 1 pixel and width times
-	 * height must still fit within a 32 bits integer, this way all
-	 * internal drawing routines work correctly.
+	 * height times bytes per pixel must still fit within a 32 bits
+	 * integer, even for 32 bpp video modes. This way all internal
+	 * drawing routines work correctly.
 	 */
-	_cur_resolution.width  = ClampU(_cur_resolution.width,  1, UINT16_MAX);
-	_cur_resolution.height = ClampU(_cur_resolution.height, 1, UINT16_MAX);
+	_cur_resolution.width  = ClampU(_cur_resolution.width,  1, UINT16_MAX / 2);
+	_cur_resolution.height = ClampU(_cur_resolution.height, 1, UINT16_MAX / 2);
 
 	/* enumerate language files */
 	InitializeLanguagePacks();
--- a/src/script/squirrel_helper.hpp
+++ b/src/script/squirrel_helper.hpp
@@ -118,6 +118,9 @@
 
 	template <> inline Array      *GetParam(ForceType<Array *>,      HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr)
 	{
+		/* Sanity check of the size. */
+		if (sq_getsize(vm, index) > UINT16_MAX) throw sq_throwerror(vm, _SC("an array used as parameter to a function is too large"));
+
 		SQObject obj;
 		sq_getstackobj(vm, index, &obj);
 		sq_pushobject(vm, obj);
--- a/src/sound.cpp
+++ b/src/sound.cpp
@@ -110,7 +110,8 @@
 {
 	assert(sound != NULL);
 
-	if (sound->file_size == 0) return false;
+	/* Check for valid sound size. */
+	if (sound->file_size == 0 || sound->file_size > ((size_t)-1) - 2) return false;
 
 	int8 *mem = MallocT<int8>(sound->file_size + 2);
 	/* Add two extra bytes so rate conversion can read these
--- a/src/sound/win32_s.cpp
+++ b/src/sound/win32_s.cpp
@@ -63,7 +63,9 @@
 	wfex.nBlockAlign = (wfex.nChannels * wfex.wBitsPerSample) / 8;
 	wfex.nAvgBytesPerSec = wfex.nSamplesPerSec * wfex.nBlockAlign;
 
+	/* Limit buffer size to prevent overflows. */
 	_bufsize = GetDriverParamInt(parm, "bufsize", (GB(GetVersion(), 0, 8) > 5) ? 8192 : 4096);
+	_bufsize = min(_bufsize, UINT16_MAX);
 
 	try {
 		if (NULL == (_event = CreateEvent(NULL, FALSE, FALSE, NULL))) throw "Failed to create event";