Skip to content

Commit

Permalink
Guard against min/max being macros in reader.h
Browse files Browse the repository at this point in the history
Sometimes, particularly when Microsoft's windows.h is included, min/max
are defined as macros, interfering with use of
std::numeric_limits::min() and the like.

To guard against this, the function name is wrapped in an extra set of
parenthesis, which inhibits function-style macro expansion.

This is a similar commit to 6e38649, but fixes uses of
std::numeric_limits added after that commit, like those introduced in
2ea4343.
  • Loading branch information
chwarr committed Jul 10, 2018
1 parent 129d19b commit 960b9cf
Show file tree
Hide file tree
Showing 3 changed files with 31 additions and 31 deletions.
46 changes: 23 additions & 23 deletions include/rapidjson/reader.h
Expand Up @@ -606,7 +606,7 @@ class GenericReader {
parseResult_.Clear();
state_ = IterativeParsingStartState;
}

//! Parse one token from JSON text
/*! \tparam InputStream Type of input stream, implementing Stream concept
\tparam Handler Type of handler, implementing Handler concept.
Expand All @@ -618,23 +618,23 @@ class GenericReader {
bool IterativeParseNext(InputStream& is, Handler& handler) {
while (RAPIDJSON_LIKELY(is.Peek() != '\0')) {
SkipWhitespaceAndComments<parseFlags>(is);

Token t = Tokenize(is.Peek());
IterativeParsingState n = Predict(state_, t);
IterativeParsingState d = Transit<parseFlags>(state_, t, n, is, handler);

// If we've finished or hit an error...
if (RAPIDJSON_UNLIKELY(IsIterativeParsingCompleteState(d))) {
// Report errors.
if (d == IterativeParsingErrorState) {
HandleError(state_, is);
return false;
}

// Transition to the finish state.
RAPIDJSON_ASSERT(d == IterativeParsingFinishState);
state_ = d;

// If StopWhenDone is not set...
if (!(parseFlags & kParseStopWhenDoneFlag)) {
// ... and extra non-whitespace data is found...
Expand All @@ -645,30 +645,30 @@ class GenericReader {
return false;
}
}

// Success! We are done!
return true;
}

// Transition to the new state.
state_ = d;

// If we parsed anything other than a delimiter, we invoked the handler, so we can return true now.
if (!IsIterativeParsingDelimiterState(n))
return true;
}

// We reached the end of file.
stack_.Clear();

if (state_ != IterativeParsingFinishState) {
HandleError(state_, is);
return false;
}

return true;
}

//! Check if token-by-token parsing JSON text is complete
/*! \return Whether the JSON has been fully decoded.
*/
Expand Down Expand Up @@ -1523,7 +1523,7 @@ class GenericReader {
}
}
}

if (RAPIDJSON_UNLIKELY(!useNanOrInf)) {
RAPIDJSON_PARSE_ERROR(kParseErrorValueInvalid, s.Tell());
}
Expand Down Expand Up @@ -1701,7 +1701,7 @@ class GenericReader {
d = internal::StrtodNormalPrecision(d, p);

// Use > max, instead of == inf, to fix bogus warning -Wfloat-equal
if (d > std::numeric_limits<double>::max()) {
if (d > (std::numeric_limits<double>::max)()) {
// Overflow
// TODO: internal::StrtodX should report overflow (or underflow)
RAPIDJSON_PARSE_ERROR(kParseErrorNumberTooBig, startOffset);
Expand Down Expand Up @@ -1769,12 +1769,12 @@ class GenericReader {

// Single value state
IterativeParsingValueState,

// Delimiter states (at bottom)
IterativeParsingElementDelimiterState,
IterativeParsingMemberDelimiterState,
IterativeParsingKeyValueDelimiterState,

cIterativeParsingStateCount
};

Expand Down Expand Up @@ -2167,43 +2167,43 @@ class GenericReader {
RAPIDJSON_FORCEINLINE bool IsIterativeParsingDelimiterState(IterativeParsingState s) const {
return s >= IterativeParsingElementDelimiterState;
}

RAPIDJSON_FORCEINLINE bool IsIterativeParsingCompleteState(IterativeParsingState s) const {
return s <= IterativeParsingErrorState;
}

template <unsigned parseFlags, typename InputStream, typename Handler>
ParseResult IterativeParse(InputStream& is, Handler& handler) {
parseResult_.Clear();
ClearStackOnExit scope(*this);
IterativeParsingState state = IterativeParsingStartState;

SkipWhitespaceAndComments<parseFlags>(is);
RAPIDJSON_PARSE_ERROR_EARLY_RETURN(parseResult_);
while (is.Peek() != '\0') {
Token t = Tokenize(is.Peek());
IterativeParsingState n = Predict(state, t);
IterativeParsingState d = Transit<parseFlags>(state, t, n, is, handler);

if (d == IterativeParsingErrorState) {
HandleError(state, is);
break;
}

state = d;

// Do not further consume streams if a root JSON has been parsed.
if ((parseFlags & kParseStopWhenDoneFlag) && state == IterativeParsingFinishState)
break;

SkipWhitespaceAndComments<parseFlags>(is);
RAPIDJSON_PARSE_ERROR_EARLY_RETURN(parseResult_);
}

// Handle the end of file.
if (state != IterativeParsingFinishState)
HandleError(state, is);

return parseResult_;
}

Expand Down
14 changes: 7 additions & 7 deletions test/unittest/itoatest.cpp
@@ -1,15 +1,15 @@
// Tencent is pleased to support the open source community by making RapidJSON available.
//
//
// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved.
//
// Licensed under the MIT License (the "License"); you may not use this file except
// in compliance with the License. You may obtain a copy of the License at
//
// http://opensource.org/licenses/MIT
//
// Unless required by applicable law or agreed to in writing, software distributed
// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
// CONDITIONS OF ANY KIND, either express or implied. See the License for the
// Unless required by applicable law or agreed to in writing, software distributed
// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
// CONDITIONS OF ANY KIND, either express or implied. See the License for the
// specific language governing permissions and limitations under the License.

#include "unittest.h"
Expand Down Expand Up @@ -61,7 +61,7 @@ static void VerifyValue(T value, void(*f)(T, char*), char* (*g)(T, char*)) {

f(value, buffer1);
*g(value, buffer2) = '\0';


EXPECT_STREQ(buffer1, buffer2);
}
Expand All @@ -79,12 +79,12 @@ static void Verify(void(*f)(T, char*), char* (*g)(T, char*)) {
do {
VerifyValue<T>(i - 1, f, g);
VerifyValue<T>(i, f, g);
if (std::numeric_limits<T>::min() < 0) {
if ((std::numeric_limits<T>::min)() < 0) {
VerifyValue<T>(Traits<T>::Negate(i), f, g);
VerifyValue<T>(Traits<T>::Negate(i + 1), f, g);
}
last = i;
if (i > static_cast<T>(std::numeric_limits<T>::max() / static_cast<T>(power)))
if (i > static_cast<T>((std::numeric_limits<T>::max)() / static_cast<T>(power)))
break;
i *= static_cast<T>(power);
} while (last < i);
Expand Down
2 changes: 1 addition & 1 deletion test/unittest/readertest.cpp
Expand Up @@ -422,7 +422,7 @@ static void TestParseDouble() {
"67546703537516986049910576551282076245490090389328944075868508455133942"
"30458323690322294816580855933212334827479782620414472316873817718091929"
"9881250404026184124858368",
std::numeric_limits<double>::max());
(std::numeric_limits<double>::max)());

TEST_DOUBLE(fullPrecision,
"243546080556034731077856379609316893158278902575447060151047"
Expand Down

0 comments on commit 960b9cf

Please sign in to comment.