Raise MAX_POINTS_PER_POLY to 64

Past releases had a debug-only assertion that 25 was sufficient, but
then dynamically allocated enough storage for larger models as needed.
Commit 22a34809ee ("Move interpreter g3s_lrgb onto stack") added a
hard limit of 25, but did not detect attempts to exceed this.  Custom
models that exceeded 25 would cause a stack buffer overwrite and likely
crash.  Raise the limit to 64 and add sanity checking to refuse to
render models that exceed MAX_POINTS_PER_POLY.

Fixes: 22a34809ee ("Move interpreter g3s_lrgb onto stack")
This commit is contained in:
Kp 2017-06-07 02:44:55 +00:00
parent d077b32201
commit 79e4e0a628
3 changed files with 13 additions and 27 deletions

View file

@ -198,7 +198,7 @@ static inline void g3_draw_poly(grs_canvas &canvas, const uint_fast32_t nv, cons
_g3_draw_poly(canvas, nv, &pointlist[0], color);
}
constexpr std::size_t MAX_POINTS_PER_POLY = 25;
constexpr std::size_t MAX_POINTS_PER_POLY = 64;
//draw a texture-mapped face.
//returns 1 if off screen, 0 if drew
@ -212,6 +212,8 @@ static inline void g3_draw_tmap(grs_canvas &canvas, unsigned nv, const array<cg3
if (DXX_CONSTANT_TRUE(nv > N))
DXX_ALWAYS_ERROR_FUNCTION(dxx_trap_tmap_overread, "reading beyond array");
#endif
if (nv > N)
return;
_g3_draw_tmap(canvas, nv, &pointlist[0], &uvl_list[0], &light_rgb[0], bm);
}

View file

@ -132,6 +132,8 @@ static inline void g3_draw_tmap_2(grs_canvas &canvas, const unsigned nv, const a
if (DXX_CONSTANT_TRUE(nv > N))
DXX_ALWAYS_ERROR_FUNCTION(dxx_trap_tmap_overread, "reading beyond array");
#endif
if (nv > N)
return;
_g3_draw_tmap_2(canvas, nv, &pointlist[0], &uvl_list[0], &light_rgb[0], bmbot, bm, orient);
}

View file

@ -164,8 +164,8 @@ public:
}
void op_flatpoly(const uint8_t *const p, const uint_fast32_t nv)
{
(void)nv; // only used for Assert
Assert( nv < MAX_POINTS_PER_POLY );
if (nv > MAX_POINTS_PER_POLY)
return;
if (g3_check_normal_facing(*vp(p+4),*vp(p+16)) > 0) {
#if defined(DXX_BUILD_DESCENT_I)
color = (w(p+28));
@ -287,7 +287,8 @@ public:
}
void op_flatpoly(const uint8_t *const p, const uint_fast32_t nv)
{
Assert( nv < MAX_POINTS_PER_POLY );
if (nv > MAX_POINTS_PER_POLY)
return;
if (g3_check_normal_facing(*vp(p+4),*vp(p+16)) > 0)
{
#if defined(DXX_BUILD_DESCENT_II)
@ -313,7 +314,8 @@ public:
}
void op_tmappoly(const uint8_t *const p, const uint_fast32_t nv)
{
Assert( nv < MAX_POINTS_PER_POLY );
if (nv > MAX_POINTS_PER_POLY)
return;
if (!(g3_check_normal_facing(*vp(p+4),*vp(p+16)) > 0))
return;
//calculate light from surface normal
@ -387,28 +389,8 @@ public:
}
void op_tmappoly(const uint8_t *const p, const uint_fast32_t nv)
{
/* NOTE: Kept for historical reasons.
int ntris;
//calculate light from surface normal
//now poke light into l values
array<g3s_uvl, 3> uvl_list;
array<g3s_lrgb, 3> lrgb_list;
lrgb_list.fill(get_noglow_light(p));
for (unsigned i = 0; i < 3; ++i)
uvl_list[i] = (reinterpret_cast<const g3s_uvl *>(p+30+((nv&~1)+1)*2))[i];
array<cg3s_point *, 3> point_list;
unsigned i;
for (i = 0; i < 2; ++i)
{
point_list[i] = &Interp_point_list[wp(p+30)[i]];
}
for (ntris=nv-2;ntris;ntris--) {
point_list[2] = &Interp_point_list[wp(p+30)[i]];
i++;
g3_check_and_draw_tmap(point_list,uvl_list,lrgb_list,*model_bitmaps[w(p+28)]);
point_list[1] = point_list[2];
}
*/
if (nv > MAX_POINTS_PER_POLY)
return;
array<g3s_uvl, MAX_POINTS_PER_POLY> uvl_list;
array<g3s_lrgb, MAX_POINTS_PER_POLY> lrgb_list;
lrgb_list.fill(get_noglow_light(p));