Skip to content
Permalink
Browse files Browse the repository at this point in the history
force fraction to a limited resolution to finally solve those pesky n…
…umerical edge cases
  • Loading branch information
farindk committed Aug 2, 2019
1 parent 444b24c commit 2710c93
Show file tree
Hide file tree
Showing 2 changed files with 9 additions and 43 deletions.
50 changes: 8 additions & 42 deletions libheif/box.cc
Expand Up @@ -40,54 +40,20 @@ heif::Error heif::Error::Ok(heif_error_Ok);



static int32_t gcd(int a, int b)
{
if (a == 0 && b == 0) {
return 1;
}

if (a == 0) return b;
if (b == 0) return a;

int32_t h;

do {
h = a % b;
a = b;
b = h;
} while (b != 0);

return a;
}


Fraction::Fraction(int32_t num,int32_t den)
{
int32_t g = gcd(num, den);

// these strange tests are for catching the case that we divide -2147483648 by -1,
// which would exceed the maximum positive value by one.

if (num == std::numeric_limits<int32_t>::min() && g == -1) {
num++;
}

if (den == std::numeric_limits<int32_t>::min() && g == -1) {
den++;
}


numerator = num / g;
denominator = den / g;


// Reduce resolution of fraction until we are in a safe range.
// We need this as adding fractions may lead to very large denominators
// (e.g. 0x10000 * 0x10000 > 0x100000000 -> overflow, leading to integer 0)

while (denominator > MAX_FRACTION_DENOMINATOR) {
numerator >>= 1;
denominator >>= 1;
while (denominator > MAX_FRACTION_VALUE || denominator < -MAX_FRACTION_VALUE) {
numerator /= 2;
denominator /= 2;
}

while (numerator > MAX_FRACTION_VALUE || numerator < -MAX_FRACTION_VALUE) {
numerator /= 2;
denominator /= 2;
}
}

Expand Down
2 changes: 1 addition & 1 deletion libheif/heif_limits.h
Expand Up @@ -47,6 +47,6 @@ static const int MAX_BOX_NESTING_LEVEL = 20;
static const int MAX_BOX_SIZE = 0x7FFFFFFF; // 2 GB
static const int64_t MAX_LARGE_BOX_SIZE = 0x0FFFFFFFFFFFFFFF;
static const int64_t MAX_FILE_POS = 0x007FFFFFFFFFFFFFLL; // maximum file position
static const int MAX_FRACTION_DENOMINATOR = 0x10000;
static const int MAX_FRACTION_VALUE = 0x10000;

#endif // LIBHEIF_HEIF_LIMITS_H

0 comments on commit 2710c93

Please sign in to comment.