From bcc36b87fb0e8608b153dbf24f03403fe759ffb0 Mon Sep 17 00:00:00 2001 From: Michael Pyne Date: Mon, 28 Dec 2015 17:08:15 -0500 Subject: [PATCH] Avoid undefined behavior in nearestPowerOfTwo. The way nearestPowerOfTwo is currently defined allows for the possibility of left-shifting an int by 32 bits or more, which is undefined behavior on platforms where int is 32 bits, and is something that can happen here if `s` is equal to 31 by the end of the loop. Noted by Coverity as CID 1291191. This patch takes an algorithm to perform the same operation from Hank Warren Jr.'s book "Hacker's Delight", which should avoid UB. REVIEW:126540 --- libkwineffects/kwinglutils.cpp | 25 ++++++++++++++----------- libkwineffects/kwinglutils.h | 1 + 2 files changed, 15 insertions(+), 11 deletions(-) diff --git a/libkwineffects/kwinglutils.cpp b/libkwineffects/kwinglutils.cpp index 438b785610..950ba3d2b0 100644 --- a/libkwineffects/kwinglutils.cpp +++ b/libkwineffects/kwinglutils.cpp @@ -205,19 +205,22 @@ bool checkGLError(const char* txt) return hasError; } +// TODO: Drop for Plasma 6, no longer needed after OpenGL 2.0 int nearestPowerOfTwo(int x) { - // This method had been copied from Qt's nearest_gl_texture_size() - int n = 0, last = 0; - for (int s = 0; s < 32; ++s) { - if (((x >> s) & 1) == 1) { - ++n; - last = s; - } - } - if (n > 1) - return 1 << (last + 1); - return 1 << last; + unsigned y = static_cast(x); + + // From Hank Warren's "Hacker's Delight", clp2() method. + // Works for up to 32-bit integers. + + y = y - 1; + y = y | (y >> 1); + y = y | (y >> 2); + y = y | (y >> 4); + y = y | (y >> 8); + y = y | (y >> 16); + + return static_cast(y + 1); } //**************************************** diff --git a/libkwineffects/kwinglutils.h b/libkwineffects/kwinglutils.h index 701397a5fe..1124fd48d5 100644 --- a/libkwineffects/kwinglutils.h +++ b/libkwineffects/kwinglutils.h @@ -81,6 +81,7 @@ inline bool KWINGLUTILS_EXPORT isPowerOfTwo(int x) * @return power of two integer _greater or equal to_ x. * E.g. nearestPowerOfTwo(513) = nearestPowerOfTwo(800) = 1024 **/ +// TODO: Drop for Plasma 6, no longer needed after OpenGL 2.0 int KWINGLUTILS_EXPORT nearestPowerOfTwo(int x); class KWINGLUTILS_EXPORT GLShader