shithub: cstory

Download patch

ref: 220f48a98bf44365b8d45cdfb5d48e0080fe92d6
parent: ffa4b16376bf1f2f0c0c5479337b46c093ece6ca
author: Clownacy <Clownacy@users.noreply.github.com>
date: Mon Jul 6 11:10:01 EDT 2020

Backport some undefined-behaviour fixes

--- a/src/Bullet.cpp
+++ b/src/Bullet.cpp
@@ -1641,7 +1641,12 @@
 				bul->damage = 1;
 
 			if (bul->ani_no > 4)
+			{
 				bul->cond = 0;
+			#ifdef FIX_BUGS
+				return;	// The code below will use 'ani_no' to access 'rcLeft' and 'rcRight', even though it's now too high
+			#endif
+			}
 
 			break;
 	}
@@ -1661,8 +1666,6 @@
 		{72, 88, 96, 112},
 		{96, 88, 120, 112},
 	};
-
-	// Note that 'bul->ani_no' can exceed the size of 'rcLeft' and 'rcRight'
 
 	if (bul->direct == 0)
 		bul->rect = rcLeft[bul->ani_no];
--- a/src/Caret.cpp
+++ b/src/Caret.cpp
@@ -71,12 +71,16 @@
 	if (++crt->ani_wait > 5)
 	{
 		crt->ani_wait = 0;
+
 		if (++crt->ani_no > 3)
+		{
 			crt->cond = 0;
+		#ifdef FIX_BUGS
+			return;	// The code below will use 'ani_no' to access 'rcLeft' and 'rcRight', even though it's now too high
+		#endif
+		}
 	}
 
-	// Note that 'crt->ani_no' can exceed the size of 'rcLeft' and 'rcRight'
-
 	if (crt->direct == 0)
 		crt->rect = rcLeft[crt->ani_no];
 	else
@@ -118,10 +122,13 @@
 			}
 
 			if (crt->ani_no > 3)
+			{
 				crt->cond = 0;
+			#ifdef FIX_BUGS
+				return;	// The code below will use 'ani_no' to access 'rect_left', even though it's now too high
+			#endif
+			}
 
-			// Note that 'crt->ani_no' can exceed the size of 'rect_left'
-
 			crt->rect = rect_left[crt->ani_no];
 			break;
 
@@ -133,10 +140,13 @@
 			}
 
 			if (crt->ani_no > 3)
+			{
 				crt->cond = 0;
+			#ifdef FIX_BUGS
+				return;	// The code below will use 'ani_no' to access 'rect_right', even though it's now too high
+			#endif
+			}
 
-			// Note that 'crt->ani_no' can exceed the size of 'rect_right'
-
 			crt->rect = rect_right[crt->ani_no];
 			break;
 
@@ -162,12 +172,16 @@
 	if (++crt->ani_wait > 2)
 	{
 		crt->ani_wait = 0;
+
 		if (++crt->ani_no > 3)
+		{
 			crt->cond = 0;
+		#ifdef FIX_BUGS
+			return;	// The code below will use 'ani_no' to access 'rect', even though it's now too high
+		#endif
+		}
 	}
 
-	// Note that 'crt->ani_no' can exceed the size of 'rect'
-
 	crt->rect = rect[crt->ani_no];
 }
 
@@ -177,9 +191,11 @@
 		{64, 32, 80, 48},
 		{80, 32, 96, 48},
 		{96, 32, 112, 48},
+
 		{64, 48, 80, 64},
 		{80, 48, 96, 64},
 		{96, 48, 112, 64},
+
 		{64, 64, 80, 80},
 		{80, 64, 96, 80},
 		{96, 64, 112, 80},
@@ -190,7 +206,12 @@
 		crt->ani_wait = 0;
 
 		if (++crt->ani_no > 2)
+		{
 			crt->cond = 0;
+		#ifdef FIX_BUGS
+			return;	// The code below will use 'ani_no' to access 'rect', even though it's now too high
+		#endif
+		}
 	}
 
 	crt->rect = rect[(crt->direct * 3) + crt->ani_no];
@@ -215,13 +236,16 @@
 	}
 
 	if (crt->ani_no > 6)
+	{
 		crt->cond = 0;
+	#ifdef FIX_BUGS
+		return;	// The code below will use 'ani_no' to access 'rect', even though it's now too high
+	#endif
+	}
 
 	crt->x += 0x80;
 	crt->y -= 0x80;
 
-	// Note that 'crt->ani_no' can exceed the size of 'rect'
-
 	crt->rect = rect[crt->ani_no];
 }
 
@@ -242,11 +266,14 @@
 		crt->ani_wait = 0;
 
 		if (++crt->ani_no > 6)
+		{
 			crt->cond = 0;
+		#ifdef FIX_BUGS
+			return;	// The code below will use 'ani_no' to access 'rcLeft', even though it's now too high
+		#endif
+		}
 	}
 
-	// Note that 'crt->ani_no' can exceed the size of rcLeft
-
 	crt->rect = rcLeft[crt->ani_no];
 
 	switch (crt->direct)
@@ -359,12 +386,16 @@
 	if (++crt->ani_wait > 2)
 	{
 		crt->ani_wait = 0;
+
 		if (++crt->ani_no > 6)
+		{
 			crt->cond = 0;
+		#ifdef FIX_BUGS
+			return;	// The code below will use 'ani_no' to access 'rcRight', even though it's now too high
+		#endif
+		}
 	}
 
-	// Note that 'crt->ani_no' can exceed the size of 'rcRight'
-
 	crt->rect = rcRight[crt->ani_no];
 }
 
@@ -378,12 +409,16 @@
 	if (++crt->ani_wait > 2)
 	{
 		crt->ani_wait = 0;
+
 		if (++crt->ani_no > 1)
+		{
 			crt->cond = 0;
+		#ifdef FIX_BUGS
+			return;	// The code below will use 'ani_no' to access 'rcLeft', even though it's now too high
+		#endif
+		}
 	}
 
-	// Note that 'crt->ani_no' can exceed the size of 'rcLeft'
-
 	crt->rect = rcLeft[crt->ani_no];
 }
 
@@ -446,11 +481,14 @@
 		crt->ani_wait = 0;
 
 		if (++crt->ani_no > 4)
+		{
 			crt->cond = 0;
+		#ifdef FIX_BUGS
+			return;	// The code below will use 'ani_no' to access 'rect', even though it's now too high
+		#endif
+		}
 	}
 
-	// Note that 'crt->ani_no' can exceed the size of 'rect'
-
 	crt->rect = rect[crt->ani_no];
 }
 
@@ -468,10 +506,13 @@
 		crt->ani_wait = 0;
 
 		if (++crt->ani_no > 3)
+		{
 			crt->cond = 0;
+		#ifdef FIX_BUGS
+			return;	// The code below will use 'ani_no' to access 'rcLeft', even though it's now too high
+		#endif
+		}
 	}
-
-	// Note that 'crt->ani_no' can exceed the size of 'rcLeft'
 
 	crt->rect = rcLeft[crt->ani_no];
 }
--- a/src/MycParam.cpp
+++ b/src/MycParam.cpp
@@ -270,8 +270,16 @@
 	RECT rcExpMax = {40, 72, 80, 80};
 	RECT rcExpFlash = {40, 80, 80, 88};
 
-	// Note that this can result in '-1', causing the following array accesses to be out-of-bounds
 	int lv = gArmsData[gSelectedArms].level - 1;
+
+#ifdef FIX_BUGS
+	// When the player has no weapons, the default level is 0, which becomes -1.
+	// Catch it, and set it to 0 instead, so the following array-accesses aren't
+	// out-of-bounds.
+	if (lv < 0)
+		lv = 0;
+#endif
+
 	int arms_code = gArmsData[gSelectedArms].code;
 	int exp_now = gArmsData[gSelectedArms].exp;
 	int exp_next = gArmsLevelTable[arms_code].exp[lv];
--- a/src/NpcAct120.cpp
+++ b/src/NpcAct120.cpp
@@ -585,12 +585,16 @@
 	if (++npc->ani_wait > 0)
 	{
 		npc->ani_wait = 0;
+
 		if (++npc->ani_no > 2)
+		{
 			npc->cond = 0;
+		#ifdef FIX_BUGS
+			return;	// The code below will use 'ani_no' to access 'rcH' and 'rcV', even though it's now too high
+		#endif
+		}
 	}
 
-	// Note that 'npc->ani_no' can exceed the size of 'rcH' and 'rcV'
-
 	if (npc->direct == 0)
 		npc->rect = rcH[npc->ani_no];
 	else
@@ -649,10 +653,13 @@
 	}
 
 	if (++npc->ani_no > 4)
+	{
 		npc->cond = 0;
+	#ifdef FIX_BUGS
+		return;	// The code below will use 'ani_no' to access 'rcLeft' and co., even though it's now too high
+	#endif
+	}
 
-	// Note that 'npc->ani_no' can exceed the bounds of 'rcLeft', 'rcUp', 'rcRight' and 'rcDown'
-
 	switch (npc->direct)
 	{
 		case 0:
@@ -680,18 +687,23 @@
 		{0x80, 0x30, 0x90, 0x40},
 		{0x90, 0x30, 0xA0, 0x40},
 		{0xA0, 0x30, 0xB0, 0x40},
+
 		{0x80, 0x40, 0x90, 0x50},
 		{0x90, 0x40, 0xA0, 0x50},
 		{0xA0, 0x40, 0xB0, 0x50},
+
 		{0x80, 0x50, 0x90, 0x60},
 		{0x90, 0x50, 0xA0, 0x60},
 		{0xA0, 0x50, 0xB0, 0x60},
+
 		{0xB0, 0x30, 0xC0, 0x40},
 		{0xC0, 0x30, 0xD0, 0x40},
 		{0xD0, 0x30, 0xE0, 0x40},
+
 		{0xB0, 0x40, 0xC0, 0x50},
 		{0xC0, 0x40, 0xD0, 0x50},
 		{0xD0, 0x40, 0xE0, 0x50},
+
 		{0xB0, 0x50, 0xC0, 0x60},
 		{0xC0, 0x50, 0xD0, 0x60},
 		{0xD0, 0x50, 0xE0, 0x60},
@@ -702,12 +714,15 @@
 		npc->ani_wait = 0;
 
 		if (++npc->ani_no > 2)
+		{
 			npc->cond = 0;
+		#ifdef FIX_BUGS
+			return;	// The code below will use 'ani_no' to access 'rect', even though it's now too high
+		#endif
+		}
 	}
 
 	npc->y += npc->ym;
-
-	// Note that '(npc->direct * 3) + npc->ani_no' can exceed the size of 'rect'
 
 	npc->rect = rect[(npc->direct * 3) + npc->ani_no];
 }
--- a/src/NpcAct140.cpp
+++ b/src/NpcAct140.cpp
@@ -753,12 +753,14 @@
 			{
 				SetDestroyNpChar(npc->x, npc->y, 0x1000, 8);
 				npc->cond = 0;
+			#ifdef FIX_BUGS
+				return;	// The code below will use 'ani_no' to access 'rect', even though it's now too high
+			#endif
 			}
 
 			break;
 	}
 
-	// Note that 'npc->ani_no' can exceed the size of 'rect'
 	npc->rect = rect[npc->ani_no];
 }
 
--- a/src/NpcAct180.cpp
+++ b/src/NpcAct180.cpp
@@ -1426,11 +1426,15 @@
 	}
 
 	if (npc->ani_no > 4)
+	{
 		npc->cond = 0;
+	#ifdef FIX_BUGS
+		return;	// The code below will use 'ani_no' to access 'rect', even though it's now too high
+	#endif
+	}
 
 	npc->x += npc->xm;
 	npc->y += npc->ym;
 
-	// Note that 'npc->ani_no' can exceed the size of 'rect'
 	npc->rect = rect[npc->ani_no];
 }