From 5a13be1f7b0d98fd0a575258177c202f199c2ed3 Mon Sep 17 00:00:00 2001 From: terminx Date: Tue, 11 Feb 2020 09:21:28 +0000 Subject: [PATCH] Avoid overflow in clipmove() git-svn-id: https://svn.eduke32.com/eduke32@8633 1a8010ca-5511-0410-912e-c29ae57300e0 --- source/build/src/clip.cpp | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/source/build/src/clip.cpp b/source/build/src/clip.cpp index 6a6887473..1a78fe3c2 100644 --- a/source/build/src/clip.cpp +++ b/source/build/src/clip.cpp @@ -1433,17 +1433,21 @@ int32_t clipmove(vec3_t * const pos, int16_t * const sectnum, int32_t xvect, int } vec2_t vec = goal; - + if ((hitwall = cliptrace(pos->vec2, &vec)) >= 0) { vec2_t const clipr = { clipit[hitwall].x2 - clipit[hitwall].x1, clipit[hitwall].y2 - clipit[hitwall].y1 }; - int64_t const templl = compat_maybe_truncate_to_int32((int64_t)clipr.x * clipr.x + (int64_t)clipr.y * clipr.y); + // clamp to the max value we can utilize without reworking the scaling below + // this works around the overflow issue that affects dukedc2.map + int32_t const templl = (int32_t)clamp(compat_maybe_truncate_to_int32((int64_t)clipr.x * clipr.x + (int64_t)clipr.y * clipr.y), INT32_MIN, INT32_MAX); if (templl > 0 && templl <= INT32_MAX) // without the upper bounds check this code misbehaves and occasionally makes the player move backwards. // This hints at another overflow problem elsewhere... { - int64_t const templl2 = compat_maybe_truncate_to_int32((int64_t)(goal.x-vec.x)*clipr.x + (int64_t)(goal.y-vec.y)*clipr.y); - int32_t const i = (enginecompatibility_mode == ENGINECOMPATIBILITY_19950829 || (llabs(templl2)>>11) < templl) ? + // I don't know if this one actually overflows or not, but I highly doubt it hurts to check + int32_t const templl2 + = (int32_t)clamp(compat_maybe_truncate_to_int32((int64_t)(goal.x - vec.x) * clipr.x + (int64_t)(goal.y - vec.y) * clipr.y), INT32_MIN, INT32_MAX); + int32_t const i = (enginecompatibility_mode == ENGINECOMPATIBILITY_19950829 || (klabs(templl2)>>11) < templl) ? divscale64(templl2, templl, 20) : 0; goal = { mulscale20(clipr.x, i)+vec.x, mulscale20(clipr.y, i)+vec.y };