Chromium Code Reviews| Index: core/fxcrt/fx_basic_util.cpp |
| diff --git a/core/fxcrt/fx_basic_util.cpp b/core/fxcrt/fx_basic_util.cpp |
| index abd84a864fe73a7e2e1e2051b4f8c9f983c2e87e..5a97509d525991ef5a849b5a2c77498cb546ec91 100644 |
| --- a/core/fxcrt/fx_basic_util.cpp |
| +++ b/core/fxcrt/fx_basic_util.cpp |
| @@ -16,8 +16,15 @@ |
| #include <algorithm> |
| #include <cctype> |
| +#include <limits> |
| #include <memory> |
| +namespace { |
| + |
| +const int kDefaultIntValue = 0; |
| + |
| +} // namespace |
| + |
| bool FX_atonum(const CFX_ByteStringC& strc, void* pData) { |
| if (strc.Find('.') != -1) { |
| FX_FLOAT* pFloat = static_cast<FX_FLOAT*>(pData); |
| @@ -25,26 +32,46 @@ bool FX_atonum(const CFX_ByteStringC& strc, void* pData) { |
| return false; |
| } |
| - int cc = 0; |
| - pdfium::base::CheckedNumeric<int> integer = 0; |
| + // Note, numbers in PDF are typically of the form 123, -123, etc. But, |
| + // for things like the Permissions on the encryption hash the number is |
| + // actually a unsigned value. We treat use uint32_t so we can deal with the |
|
Lei Zhang
2016/07/21 20:39:31
"We treat use uint32_t" does not parse English bad
dsinclair
2016/07/25 13:47:59
Done.
|
| + // unsigned and then check for overflow if the user actually signed the value. |
| + // Permissions flag is listed in Table 3.20 PDF 1.7 spec. |
| + pdfium::base::CheckedNumeric<uint32_t> integer = 0; |
| bool bNegative = false; |
| + bool bSigned = false; |
| + int cc = 0; |
| if (strc[0] == '+') { |
| cc++; |
| + bSigned = true; |
| } else if (strc[0] == '-') { |
| bNegative = true; |
| + bSigned = true; |
| cc++; |
| } |
| + |
| while (cc < strc.GetLength() && std::isdigit(strc[cc])) { |
| integer = integer * 10 + FXSYS_toDecimalDigit(strc.CharAt(cc)); |
| if (!integer.IsValid()) |
| break; |
| cc++; |
| } |
| + |
| + // We have a sign, and the value was greater then a regular integer |
| + // we've overflowed, reset to the default value. |
| + if (bSigned && |
| + integer.ValueOrDefault(kDefaultIntValue) >= |
| + static_cast<uint32_t>(std::numeric_limits<int>::max())) { |
| + integer = kDefaultIntValue; |
| + } |
| + |
| + // Switch back to the int space so we can flip to a negative if we need. |
| + int value = integer.ValueOrDefault(kDefaultIntValue); |
| if (bNegative) |
| - integer = -integer; |
| + value = -value; |
|
Lei Zhang
2016/07/21 20:39:31
Do we need to worry about the value = INT_MIN case
dsinclair
2016/07/25 13:47:59
Fixed up some issues around boundary conversions.
|
| int* pInt = static_cast<int*>(pData); |
| - *pInt = integer.ValueOrDefault(0); |
| + *pInt = value; |
| return true; |
| } |