From 7f06e9dc28413224edf9974e2990e4af03418986 Mon Sep 17 00:00:00 2001 From: Michael Shields Date: Mon, 27 Jul 2015 16:35:19 -0700 Subject: [PATCH] Fix cases where the most negative signed integer was negated, causing undefined behavior. --- src/lib_json/json_reader.cpp | 6 ++++-- src/lib_json/json_writer.cpp | 13 ++++++++----- 2 files changed, 12 insertions(+), 7 deletions(-) diff --git a/src/lib_json/json_reader.cpp b/src/lib_json/json_reader.cpp index ceff66c..8d09273 100644 --- a/src/lib_json/json_reader.cpp +++ b/src/lib_json/json_reader.cpp @@ -555,7 +555,7 @@ bool Reader::decodeNumber(Token& token, Value& decoded) { ++current; // TODO: Help the compiler do the div and mod at compile time or get rid of them. Value::LargestUInt maxIntegerValue = - isNegative ? Value::LargestUInt(-Value::minLargestInt) + isNegative ? Value::LargestUInt(Value::maxLargestInt) + 1 : Value::maxLargestUInt; Value::LargestUInt threshold = maxIntegerValue / 10; Value::LargestUInt value = 0; @@ -576,7 +576,9 @@ bool Reader::decodeNumber(Token& token, Value& decoded) { } value = value * 10 + digit; } - if (isNegative) + if (isNegative && value == maxIntegerValue) + decoded = Value::minLargestInt; + else if (isNegative) decoded = -Value::LargestInt(value); else if (value <= Value::LargestUInt(Value::maxInt)) decoded = Value::LargestInt(value); diff --git a/src/lib_json/json_writer.cpp b/src/lib_json/json_writer.cpp index 2f940c8..89cd651 100644 --- a/src/lib_json/json_writer.cpp +++ b/src/lib_json/json_writer.cpp @@ -75,12 +75,15 @@ static bool containsControlCharacter0(const char* str, unsigned len) { std::string valueToString(LargestInt value) { UIntToStringBuffer buffer; char* current = buffer + sizeof(buffer); - bool isNegative = value < 0; - if (isNegative) - value = -value; - uintToString(LargestUInt(value), current); - if (isNegative) + if (value == Value::minLargestInt) { + uintToString(LargestUInt(Value::maxLargestInt) + 1, current); *--current = '-'; + } else if (value < 0) { + uintToString(LargestUInt(-value), current); + *--current = '-'; + } else { + uintToString(LargestUInt(value), current); + } assert(current >= buffer); return current; }