Skip to content

Commit 9dad198

Browse files
committed
Merge pull request open-source-parsers#320 from shields/negation-overflow
Fix cases where the most negative signed integer was negated, causing undefined behavior.
2 parents d84702c + 7f06e9d commit 9dad198

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
@@ -555,7 +555,7 @@ bool Reader::decodeNumber(Token& token, Value& decoded) {
555555
++current;
556556
// TODO: Help the compiler do the div and mod at compile time or get rid of them.
557557
Value::LargestUInt maxIntegerValue =
558-
isNegative ? Value::LargestUInt(-Value::minLargestInt)
558+
isNegative ? Value::LargestUInt(Value::maxLargestInt) + 1
559559
: Value::maxLargestUInt;
560560
Value::LargestUInt threshold = maxIntegerValue / 10;
561561
Value::LargestUInt value = 0;
@@ -576,7 +576,9 @@ bool Reader::decodeNumber(Token& token, Value& decoded) {
576576
}
577577
value = value * 10 + digit;
578578
}
579-
if (isNegative)
579+
if (isNegative && value == maxIntegerValue)
580+
decoded = Value::minLargestInt;
581+
else if (isNegative)
580582
decoded = -Value::LargestInt(value);
581583
else if (value <= Value::LargestUInt(Value::maxInt))
582584
decoded = Value::LargestInt(value);

src/lib_json/json_writer.cpp

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -75,12 +75,15 @@ static bool containsControlCharacter0(const char* str, unsigned len) {
7575
std::string valueToString(LargestInt value) {
7676
UIntToStringBuffer buffer;
7777
char* current = buffer + sizeof(buffer);
78-
bool isNegative = value < 0;
79-
if (isNegative)
80-
value = -value;
81-
uintToString(LargestUInt(value), current);
82-
if (isNegative)
78+
if (value == Value::minLargestInt) {
79+
uintToString(LargestUInt(Value::maxLargestInt) + 1, current);
8380
*--current = '-';
81+
} else if (value < 0) {
82+
uintToString(LargestUInt(-value), current);
83+
*--current = '-';
84+
} else {
85+
uintToString(LargestUInt(value), current);
86+
}
8487
assert(current >= buffer);
8588
return current;
8689
}

0 commit comments

Comments
 (0)