diff --git a/include/rapidjson/internal/dtoa.h b/include/rapidjson/internal/dtoa.h index c888402..bf686b0 100644 --- a/include/rapidjson/internal/dtoa.h +++ b/include/rapidjson/internal/dtoa.h @@ -21,6 +21,7 @@ #include "itoa.h" // GetDigitsLut() #include "diyfp.h" +#include "ieee754.h" RAPIDJSON_NAMESPACE_BEGIN namespace internal { @@ -193,6 +194,9 @@ inline char* Prettify(char* buffer, int length, int k) { inline char* dtoa(double value, char* buffer) { if (value == 0) { + Double d(value); + if (d.Sign()) + *buffer++ = '-'; // -0.0, Issue #289 buffer[0] = '0'; buffer[1] = '.'; buffer[2] = '0'; diff --git a/include/rapidjson/reader.h b/include/rapidjson/reader.h index a59f26e..0ee2523 100644 --- a/include/rapidjson/reader.h +++ b/include/rapidjson/reader.h @@ -689,11 +689,13 @@ private: } else if (e == 'u') { // Unicode unsigned codepoint = ParseHex4(is); + RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID; if (codepoint >= 0xD800 && codepoint <= 0xDBFF) { // Handle UTF-16 surrogate pair if (is.Take() != '\\' || is.Take() != 'u') RAPIDJSON_PARSE_ERROR(kParseErrorStringUnicodeSurrogateInvalid, is.Tell() - 2); unsigned codepoint2 = ParseHex4(is); + RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID; if (codepoint2 < 0xDC00 || codepoint2 > 0xDFFF) RAPIDJSON_PARSE_ERROR(kParseErrorStringUnicodeSurrogateInvalid, is.Tell() - 2); codepoint = (((codepoint - 0xD800) << 10) | (codepoint2 - 0xDC00)) + 0x10000; diff --git a/test/unittest/readertest.cpp b/test/unittest/readertest.cpp index 64904b0..318f188 100644 --- a/test/unittest/readertest.cpp +++ b/test/unittest/readertest.cpp @@ -187,6 +187,8 @@ static void TestParseDouble() { Reader reader; \ ASSERT_EQ(kParseErrorNone, reader.Parse(s, h).Code()); \ EXPECT_EQ(1u, h.step_); \ + internal::Double e(x), a(h.actual_); \ + EXPECT_EQ(e.Sign(), a.Sign()); \ if (fullPrecision) { \ EXPECT_EQ(x, h.actual_); \ if (x != h.actual_) \ @@ -197,6 +199,7 @@ static void TestParseDouble() { } TEST_DOUBLE(fullPrecision, "0.0", 0.0); + TEST_DOUBLE(fullPrecision, "-0.0", -0.0); // For checking issue #289 TEST_DOUBLE(fullPrecision, "1.0", 1.0); TEST_DOUBLE(fullPrecision, "-1.0", -1.0); TEST_DOUBLE(fullPrecision, "1.5", 1.5); @@ -517,6 +520,10 @@ TEST(Reader, ParseString_Error) { // Incorrect hex digit after \\u escape in string. TEST_STRING_ERROR(kParseErrorStringUnicodeEscapeInvalidHex, "[\"\\uABCG\"]"); + // Quotation in \\u escape in string (Issue #288) + TEST_STRING_ERROR(kParseErrorStringUnicodeEscapeInvalidHex, "[\"\\uaaa\"]"); + TEST_STRING_ERROR(kParseErrorStringUnicodeEscapeInvalidHex, "[\"\\uD800\\uFFF\"]"); + // The surrogate pair in string is invalid. TEST_STRING_ERROR(kParseErrorStringUnicodeSurrogateInvalid, "[\"\\uD800X\"]"); TEST_STRING_ERROR(kParseErrorStringUnicodeSurrogateInvalid, "[\"\\uD800\\uFFFF\"]"); diff --git a/test/unittest/writertest.cpp b/test/unittest/writertest.cpp index 0ef1423..642161a 100644 --- a/test/unittest/writertest.cpp +++ b/test/unittest/writertest.cpp @@ -93,7 +93,7 @@ TEST(Writer, String) { TEST(Writer, Double) { TEST_ROUNDTRIP("[1.2345,1.2345678,0.123456789012,1234567.8]"); - + TEST_ROUNDTRIP("[-0.0]"); // Issue #289 } TEST(Writer, Transcode) {