changeset 12911:6c10aa6a3232 draft

(svn r17403) -Fix [Squirrel]: guard against squirrel stack overflows; if assert is enabled assert (catch possible overflow bugs in nightlies/RCs), otherwise just increase the stack's size (don't get into invalid reads/writes in releases)
author rubidium <rubidium@openttd.org>
date Thu, 03 Sep 2009 11:48:08 +0000
parents 57cb6eb5b9ab
children 6e3b759a3b58
files src/3rdparty/squirrel/squirrel/squtils.h src/3rdparty/squirrel/squirrel/sqvm.cpp
diffstat 2 files changed, 14 insertions(+), 2 deletions(-) [+]
line wrap: on
line diff
--- a/src/3rdparty/squirrel/squirrel/squtils.h
+++ b/src/3rdparty/squirrel/squirrel/squtils.h
@@ -88,7 +88,7 @@
 	}
 	SQUnsignedInteger capacity() { return _allocated; }
 	inline T &back() const { return _vals[_size - 1]; }
-	inline T& operator[](SQUnsignedInteger pos) const{ return _vals[pos]; }
+	inline T& operator[](SQUnsignedInteger pos) const{ assert(pos < _allocated); return _vals[pos]; }
 	T* _vals;
 private:
 	void _realloc(SQUnsignedInteger newsize)
--- a/src/3rdparty/squirrel/squirrel/sqvm.cpp
+++ b/src/3rdparty/squirrel/squirrel/sqvm.cpp
@@ -1526,7 +1526,19 @@
 	}
 }
 
-void SQVM::Push(const SQObjectPtr &o) { _stack[_top++] = o; }
+void SQVM::Push(const SQObjectPtr &o) {
+	/* Normally the stack shouldn't get this full, sometimes it might. As of now
+	 * all cases have been bugs in "our" (OpenTTD) code. Trigger an assert for
+	 * all debug builds and for the release builds just increase the stack size.
+	 * This way getting a false positive isn't that bad (releases work fine) and
+	 * if there is something fishy it can be caught in RCs/nightlies. */
+#ifdef NDEBUG
+	if (_top >= (int)_stack.capacity()) _stack.resize(2 * _stack.capacity());
+#else
+	assert(_top < (int)_stack.capacity());
+#endif
+	_stack[_top++] = o;
+}
 SQObjectPtr &SQVM::Top() { return _stack[_top-1]; }
 SQObjectPtr &SQVM::PopGet() { return _stack[--_top]; }
 SQObjectPtr &SQVM::GetUp(SQInteger n) { return _stack[_top+n]; }