Fix two bugs found by Clang's undefined behavior sanitizer.

- Return early from drawsprite_classic() if tspr->owner if oob.
  Commonize that check between renderers into bad_tspr().
- Make the BIT() macro a left-shift of the *unsigned* number 1,
  preventing expansion to (1<<31).

git-svn-id: https://svn.eduke32.com/eduke32@3717 1a8010ca-5511-0410-912e-c29ae57300e0
This commit is contained in:
helixhorned 2013-04-29 19:24:19 +00:00
parent bdecbc45db
commit 74aaac70d2
6 changed files with 21 additions and 5 deletions

View file

@ -5586,7 +5586,16 @@ static void drawsprite_classic(int32_t snum)
int32_t tilenum; int32_t tilenum;
int32_t cstat = tspr->cstat; int32_t cstat = tspr->cstat;
if ((unsigned)tspr->picnum >= MAXTILES || sec==NULL) if (sec == NULL)
return;
if (bad_tspr(tspr))
return;
// This happens when using steroids.
// XXX: Should we instead run the code but handle stuff indexed by
// tspr->owner specially?
if ((unsigned)tspr->owner >= MAXSPRITES)
return; return;
DO_TILE_ANIM(tspr->picnum, spritenum+32768); DO_TILE_ANIM(tspr->picnum, spritenum+32768);

View file

@ -93,6 +93,11 @@ void set_globalang(int16_t ang);
if (picanm[Picnum].sf&PICANM_ANIMTYPE_MASK) Picnum += animateoffs(Picnum, Fakevar); \ if (picanm[Picnum].sf&PICANM_ANIMTYPE_MASK) Picnum += animateoffs(Picnum, Fakevar); \
} while (0) } while (0)
static inline int32_t bad_tspr(const spritetype *tspr)
{
return ((unsigned)tspr->owner >= MAXSPRITES || (unsigned)tspr->picnum >= MAXTILES);
}
void dorotspr_handle_bit2(int32_t *sx, int32_t *sy, int32_t *z, int32_t dastat, void dorotspr_handle_bit2(int32_t *sx, int32_t *sy, int32_t *z, int32_t dastat,
int32_t cx1_plus_cx2, int32_t cy1_plus_cy2, int32_t cx1_plus_cx2, int32_t cy1_plus_cy2,
int32_t *ret_ouryxaspect, int32_t *ret_ourxyaspect); int32_t *ret_ouryxaspect, int32_t *ret_ourxyaspect);

View file

@ -1342,7 +1342,8 @@ void polymer_drawsprite(int32_t snum)
tspr = tspriteptr[snum]; tspr = tspriteptr[snum];
if (tspr->owner < 0 || tspr->picnum < 0) return; if (bad_tspr(tspr))
return;
if ((tspr->cstat & 8192) && (depth && !mirrors[depth-1].plane)) if ((tspr->cstat & 8192) && (depth && !mirrors[depth-1].plane))
return; return;

View file

@ -4875,7 +4875,8 @@ void polymost_drawsprite(int32_t snum)
int32_t tsizx, tsizy; int32_t tsizx, tsizy;
tspr = tspriteptr[snum]; tspr = tspriteptr[snum];
if (tspr->owner < 0 || tspr->picnum < 0 || tspr->picnum >= MAXTILES) return; if (bad_tspr(tspr))
return;
spritenum = tspr->owner; spritenum = tspr->owner;

View file

@ -43,7 +43,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
// mask definitions // mask definitions
#define BIT(shift) (1<<(shift)) #define BIT(shift) (1u<<(shift))
#define TEST_SYNC_KEY(bits, sync_num) TEST(bits, BIT(sync_num)) #define TEST_SYNC_KEY(bits, sync_num) TEST(bits, BIT(sync_num))

View file

@ -2492,7 +2492,7 @@ void P_HandleSharedKeys(int32_t snum)
} }
} }
j = sb_snum & ((15<<SK_WEAPON_BITS)|BIT(SK_STEROIDS)|BIT(SK_NIGHTVISION)|BIT(SK_MEDKIT)|BIT(SK_QUICK_KICK)| \ j = sb_snum & ((15u<<SK_WEAPON_BITS)|BIT(SK_STEROIDS)|BIT(SK_NIGHTVISION)|BIT(SK_MEDKIT)|BIT(SK_QUICK_KICK)| \
BIT(SK_HOLSTER)|BIT(SK_INV_LEFT)|BIT(SK_PAUSE)|BIT(SK_HOLODUKE)|BIT(SK_JETPACK)|BIT(SK_INV_RIGHT)| \ BIT(SK_HOLSTER)|BIT(SK_INV_LEFT)|BIT(SK_PAUSE)|BIT(SK_HOLODUKE)|BIT(SK_JETPACK)|BIT(SK_INV_RIGHT)| \
BIT(SK_TURNAROUND)|BIT(SK_OPEN)|BIT(SK_INVENTORY)|BIT(SK_ESCAPE)); BIT(SK_TURNAROUND)|BIT(SK_OPEN)|BIT(SK_INVENTORY)|BIT(SK_ESCAPE));
sb_snum = j & ~p->interface_toggle_flag; sb_snum = j & ~p->interface_toggle_flag;