diff options
author | Oleg Oshmyan <chortos@inbox.lv> | 2016-10-30 02:53:00 +0300 |
---|---|---|
committer | Grigori Goronzy <greg@chown.ath.cx> | 2016-11-21 11:05:34 +0100 |
commit | 0b1eaa83fd46c3b56d68592639d358b0557dc427 (patch) | |
tree | 8a6efde7564275faffe6a617ae63a895e413df61 | |
parent | e54c123d5a08b6212533ddcced2cb1a50fa3d2b2 (diff) | |
download | libass-0b1eaa83fd46c3b56d68592639d358b0557dc427.tar.bz2 libass-0b1eaa83fd46c3b56d68592639d358b0557dc427.tar.xz |
ass_strtod: use size_t for substring lengths
This fixes overflow on extremely long input strings.
See libass#244.
-rw-r--r-- | libass/ass_strtod.c | 37 |
1 files changed, 19 insertions, 18 deletions
diff --git a/libass/ass_strtod.c b/libass/ass_strtod.c index 856815c..20c4ec2 100644 --- a/libass/ass_strtod.c +++ b/libass/ass_strtod.c @@ -20,7 +20,7 @@ #include "ass_string.h" static -const int maxExponent = 511; /* Largest possible base 10 exponent. Any +const size_t maxExponent = 511; /* Largest possible base 10 exponent. Any * exponent larger than this will already * produce underflow or overflow, so there's * no need to worry about additional digits. @@ -78,12 +78,12 @@ ass_strtod( * address here. */ ) { - int sign, expSign = 0; + int sign, fracExpSign, expSign = 0; double fraction, dblExp, *d; register const char *p; register int c; - int exp = 0; /* Exponent read from "EX" field. */ - int fracExp = 0; /* Exponent that derives from the fractional + size_t exp = 0; /* Exponent read from "EX" field. */ + size_t fracExp; /* Exponent that derives from the fractional * part. Under normal circumstatnces, it is * the negative of the number of digits in F. * However, if I is very long, the last digits @@ -92,8 +92,8 @@ ass_strtod( * unnecessary overflow on I alone). In this * case, fracExp is incremented one for each * dropped digit. */ - int mantSize; /* Number of digits in mantissa. */ - int decPt; /* Number of mantissa digits BEFORE decimal + size_t mantSize; /* Number of digits in mantissa. */ + size_t decPt; /* Number of mantissa digits BEFORE decimal * point. */ const char *pExp; /* Temporarily holds location of exponent * in string. */ @@ -126,7 +126,7 @@ ass_strtod( { c = *p; if (!ass_isdigit(c)) { - if ((c != '.') || (decPt >= 0)) { + if ((c != '.') || (decPt != (size_t) -1)) { break; } decPt = mantSize; @@ -143,15 +143,19 @@ ass_strtod( pExp = p; p -= mantSize; - if (decPt < 0) { + if (decPt == (size_t) -1) { decPt = mantSize; } else { mantSize -= 1; /* One of the digits was the point. */ } if (mantSize > 18) { - fracExp = decPt - 18; mantSize = 18; + } + if (decPt < mantSize) { + fracExpSign = 1; + fracExp = mantSize - decPt; } else { + fracExpSign = 0; fracExp = decPt - mantSize; } if (mantSize == 0) { @@ -206,10 +210,13 @@ ass_strtod( p += 1; } } - if (expSign) { - exp = fracExp - exp; - } else { + if (expSign == fracExpSign) { exp = fracExp + exp; + } else if (fracExp <= exp) { + exp = exp - fracExp; + } else { + exp = fracExp - exp; + expSign = fracExpSign; } /* @@ -219,12 +226,6 @@ ass_strtod( * fraction. */ - if (exp < 0) { - expSign = 1; - exp = -exp; - } else { - expSign = 0; - } if (exp > maxExponent) { exp = maxExponent; errno = ERANGE; |