From 15e3f15b48073f4085f81b9a063b709c7872eab7 Mon Sep 17 00:00:00 2001
From: engineer_apple <engineer_apple@dfc29bdd-3216-0410-991c-e03cc46cb475>
Date: Sun, 1 May 2022 09:50:32 +0000
Subject: [PATCH] SpriteBank: error check on non existing textureNumber

seen in broken Fonts. unified getFrameNr

git-svn-id: svn://svn.code.sf.net/p/irrlicht/code/trunk@6368 dfc29bdd-3216-0410-991c-e03cc46cb475
---
 source/Irrlicht/CGUISpriteBank.cpp | 53 +++++++++++++++++++-----------
 source/Irrlicht/CGUISpriteBank.h   | 14 +-------
 2 files changed, 35 insertions(+), 32 deletions(-)

diff --git a/source/Irrlicht/CGUISpriteBank.cpp b/source/Irrlicht/CGUISpriteBank.cpp
index 8f5fb673..6dd7aa3f 100644
--- a/source/Irrlicht/CGUISpriteBank.cpp
+++ b/source/Irrlicht/CGUISpriteBank.cpp
@@ -31,10 +31,7 @@ CGUISpriteBank::CGUISpriteBank(IGUIEnvironment* env) :
 
 CGUISpriteBank::~CGUISpriteBank()
 {
-	// drop textures
-	for (u32 i=0; i<Textures.size(); ++i)
-		if (Textures[i])
-			Textures[i]->drop();
+	clear();
 
 	// drop video driver
 	if (Driver)
@@ -132,15 +129,38 @@ s32 CGUISpriteBank::addTextureAsSprite(video::ITexture* texture)
 	return Sprites.size() - 1;
 }
 
+// get FrameNr for time. return true on exisiting frame
+inline bool CGUISpriteBank::getFrameNr(u32& frame,u32 index, u32 time, bool loop) const
+{
+	frame = 0;
+	if (index >= Sprites.size())
+		return false;
+
+	const SGUISprite& sprite = Sprites[index];
+	const u32 frameSize = sprite.Frames.size();
+	if (frameSize < 1)
+		return false;
+
+	if (sprite.frameTime)
+	{
+		u32 f = (time / sprite.frameTime);
+		if (loop)
+			frame = f % frameSize;
+		else
+			frame = (f >= frameSize) ? frameSize - 1 : f;
+	}
+	return true;
+}
+
 //! draws a sprite in 2d with scale and color
 void CGUISpriteBank::draw2DSprite(u32 index, const core::position2di& pos,
 		const core::rect<s32>* clip, const video::SColor& color,
 		u32 starttime, u32 currenttime, bool loop, bool center)
 {
-	if (index >= Sprites.size() || Sprites[index].Frames.empty() )
+	u32 frame = 0;
+	if (!getFrameNr(frame, index, currenttime - starttime, loop))
 		return;
 
-	u32 frame = getFrameNr(index, currenttime - starttime, loop);
 	const video::ITexture* tex = getTexture(Sprites[index].Frames[frame].textureNumber);
 	if (!tex)
 		return;
@@ -162,10 +182,10 @@ void CGUISpriteBank::draw2DSprite(u32 index, const core::rect<s32>& destRect,
 		const core::rect<s32>* clip, const video::SColor * const colors,
 		u32 timeTicks, bool loop)
 {
-	if (index >= Sprites.size() || Sprites[index].Frames.empty() )
+	u32 frame = 0;
+	if (!getFrameNr(frame,index, timeTicks, loop))
 		return;
 
-	u32 frame = getFrameNr(index, timeTicks, loop);
 	const video::ITexture* tex = getTexture(Sprites[index].Frames[frame].textureNumber);
 	if (!tex)
 		return;
@@ -200,21 +220,16 @@ void CGUISpriteBank::draw2DSpriteBatch(	const core::array<u32>& indices,
 	{
 		const u32 index = indices[i];
 
-		if (index >= Sprites.size() || Sprites[index].Frames.empty() )
-			continue;
-
 		// work out frame number
 		u32 frame = 0;
-		if (Sprites[index].frameTime)
-		{
-			u32 f = ((currenttime - starttime) / Sprites[index].frameTime);
-			if (loop)
-				frame = f % Sprites[index].Frames.size();
-			else
-				frame = (f >= Sprites[index].Frames.size()) ? Sprites[index].Frames.size()-1 : f;
-		}
+		if (!getFrameNr(frame, index, currenttime - starttime, loop))
+			return;
 
 		const u32 texNum = Sprites[index].Frames[frame].textureNumber;
+		if (texNum >= drawBatches.size())
+		{
+			continue;
+		}
 		SDrawBatch& currentBatch = drawBatches[texNum];
 
 		const u32 rn = Sprites[index].Frames[frame].rectNumber;
diff --git a/source/Irrlicht/CGUISpriteBank.h b/source/Irrlicht/CGUISpriteBank.h
index affd6bfd..5bd115bc 100644
--- a/source/Irrlicht/CGUISpriteBank.h
+++ b/source/Irrlicht/CGUISpriteBank.h
@@ -64,19 +64,7 @@ public:
 
 protected:
 
-	inline u32 getFrameNr(u32 index, u32 time, bool loop) const
-	{
-		u32 frame = 0;
-		if (Sprites[index].frameTime && Sprites[index].Frames.size() )
-		{
-			u32 f = (time / Sprites[index].frameTime);
-			if (loop)
-				frame = f % Sprites[index].Frames.size();
-			else
-				frame = (f >= Sprites[index].Frames.size()) ? Sprites[index].Frames.size()-1 : f;
-		}
-		return frame;
-	}
+	bool getFrameNr(u32& frameNr, u32 index, u32 time, bool loop) const;
 
 	struct SDrawBatch
 	{