Skip to content

Commit 1b32e3e

Browse files
Michael Shieldscdunn2001
Michael Shields
authored andcommitted
Fix cases where the most negative signed integer was negated, causing
undefined behavior.
1 parent 18e4d04 commit 1b32e3e

File tree

2 files changed

+12
-7
lines changed

2 files changed

+12
-7
lines changed

src/lib_json/json_reader.cpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -517,7 +517,7 @@ bool Reader::decodeNumber(Token& token, Value& decoded) {
517517
++current;
518518
// TODO: Help the compiler do the div and mod at compile time or get rid of them.
519519
Value::LargestUInt maxIntegerValue =
520-
isNegative ? Value::LargestUInt(-Value::minLargestInt)
520+
isNegative ? Value::LargestUInt(Value::maxLargestInt) + 1
521521
: Value::maxLargestUInt;
522522
Value::LargestUInt threshold = maxIntegerValue / 10;
523523
Value::LargestUInt value = 0;
@@ -538,7 +538,9 @@ bool Reader::decodeNumber(Token& token, Value& decoded) {
538538
}
539539
value = value * 10 + digit;
540540
}
541-
if (isNegative)
541+
if (isNegative && value == maxIntegerValue)
542+
decoded = Value::minLargestInt;
543+
else if (isNegative)
542544
decoded = -Value::LargestInt(value);
543545
else if (value <= Value::LargestUInt(Value::maxInt))
544546
decoded = Value::LargestInt(value);

src/lib_json/json_writer.cpp

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -71,12 +71,15 @@ static bool containsControlCharacter0(const char* str, unsigned len) {
7171
std::string valueToString(LargestInt value) {
7272
UIntToStringBuffer buffer;
7373
char* current = buffer + sizeof(buffer);
74-
bool isNegative = value < 0;
75-
if (isNegative)
76-
value = -value;
77-
uintToString(LargestUInt(value), current);
78-
if (isNegative)
74+
if (value == Value::minLargestInt) {
75+
uintToString(LargestUInt(Value::maxLargestInt) + 1, current);
7976
*--current = '-';
77+
} else if (value < 0) {
78+
uintToString(LargestUInt(-value), current);
79+
*--current = '-';
80+
} else {
81+
uintToString(LargestUInt(value), current);
82+
}
8083
assert(current >= buffer);
8184
return current;
8285
}

0 commit comments

Comments
 (0)