Fix cases where the most negative signed integer was negated, causing

undefined behavior.
This commit is contained in:
Michael Shields 2015-07-27 16:35:19 -07:00
parent d84702c903
commit 7f06e9dc28
2 changed files with 12 additions and 7 deletions

View File

@ -555,7 +555,7 @@ bool Reader::decodeNumber(Token& token, Value& decoded) {
++current; ++current;
// TODO: Help the compiler do the div and mod at compile time or get rid of them. // TODO: Help the compiler do the div and mod at compile time or get rid of them.
Value::LargestUInt maxIntegerValue = Value::LargestUInt maxIntegerValue =
isNegative ? Value::LargestUInt(-Value::minLargestInt) isNegative ? Value::LargestUInt(Value::maxLargestInt) + 1
: Value::maxLargestUInt; : Value::maxLargestUInt;
Value::LargestUInt threshold = maxIntegerValue / 10; Value::LargestUInt threshold = maxIntegerValue / 10;
Value::LargestUInt value = 0; Value::LargestUInt value = 0;
@ -576,7 +576,9 @@ bool Reader::decodeNumber(Token& token, Value& decoded) {
} }
value = value * 10 + digit; value = value * 10 + digit;
} }
if (isNegative) if (isNegative && value == maxIntegerValue)
decoded = Value::minLargestInt;
else if (isNegative)
decoded = -Value::LargestInt(value); decoded = -Value::LargestInt(value);
else if (value <= Value::LargestUInt(Value::maxInt)) else if (value <= Value::LargestUInt(Value::maxInt))
decoded = Value::LargestInt(value); decoded = Value::LargestInt(value);

View File

@ -75,12 +75,15 @@ static bool containsControlCharacter0(const char* str, unsigned len) {
std::string valueToString(LargestInt value) { std::string valueToString(LargestInt value) {
UIntToStringBuffer buffer; UIntToStringBuffer buffer;
char* current = buffer + sizeof(buffer); char* current = buffer + sizeof(buffer);
bool isNegative = value < 0; if (value == Value::minLargestInt) {
if (isNegative) uintToString(LargestUInt(Value::maxLargestInt) + 1, current);
value = -value;
uintToString(LargestUInt(value), current);
if (isNegative)
*--current = '-'; *--current = '-';
} else if (value < 0) {
uintToString(LargestUInt(-value), current);
*--current = '-';
} else {
uintToString(LargestUInt(value), current);
}
assert(current >= buffer); assert(current >= buffer);
return current; return current;
} }