diff options
author | Simon G <intrigus> | 2020-01-27 19:53:49 +0300 |
---|---|---|
committer | Brecht Van Lommel <brechtvanlommel@gmail.com> | 2020-01-27 20:00:34 +0300 |
commit | c8103efbe3bfa2487a2866a7cf22e3b7681338ef (patch) | |
tree | afc251aa124d5149e2a3e300392101b0032637db /intern/mikktspace | |
parent | 6bf0e9dbb1c68c183cf48ee2c7c0ca10c53f9075 (diff) |
Fix undefined behavior in tangent space computation
Use an improved implementation for circular shift.
Differential Revision: https://developer.blender.org/D6677
Diffstat (limited to 'intern/mikktspace')
-rw-r--r-- | intern/mikktspace/mikktspace.c | 14 |
1 files changed, 13 insertions, 1 deletions
diff --git a/intern/mikktspace/mikktspace.c b/intern/mikktspace/mikktspace.c index 4f120b7d83c..285529298eb 100644 --- a/intern/mikktspace/mikktspace.c +++ b/intern/mikktspace/mikktspace.c @@ -27,6 +27,7 @@ #include <string.h> #include <float.h> #include <stdlib.h> +#include <limits.h> #include "mikktspace.h" @@ -135,6 +136,17 @@ MIKK_INLINE tbool VNotZero(const SVec3 v) } #endif +// Shift operations in C are only defined for shift values which are +// not negative and smaller than sizeof(value) * CHAR_BIT. +// The mask, used with bitwise-and (&), prevents undefined behaviour +// when the shift count is 0 or >= the width of unsigned int. +MIKK_INLINE unsigned int rotl(unsigned int value, unsigned int count) +{ + const unsigned int mask = CHAR_BIT * sizeof(value) - 1; + count &= mask; + return (value << count) | (value >> (-count & mask)); +} + typedef struct { int iNrFaces; int *pTriMembers; @@ -1605,7 +1617,7 @@ static void QuickSortEdges( // Random t = uSeed & 31; - t = (uSeed << t) | (uSeed >> (32 - t)); + t = rotl(uSeed, t); uSeed = uSeed + t + 3; // Random end |