rapidjson: gcc14 compat, backport cursorstreamwrapper

This commit is contained in:
John 2025-04-19 21:59:04 +02:00 committed by John Zimmermann
parent 2750815305
commit 32770fbd0c
8 changed files with 449 additions and 5 deletions

View file

@ -0,0 +1,130 @@
From b16ff281f854564e2669b2c3f4871793ddc51fc3 Mon Sep 17 00:00:00 2001
From: KaitoHH <hh.kaito@gmail.com>
Date: Tue, 26 Sep 2017 15:39:06 +0800
Subject: [PATCH] Add feature of locating line and column number of error
---
include/rapidjson/document.h | 11 ++++++++-
include/rapidjson/error/error.h | 8 +++++++
include/rapidjson/stream.h | 42 +++++++++++++++++++++++++++++++++
3 files changed, 60 insertions(+), 1 deletion(-)
diff --git a/include/rapidjson/document.h b/include/rapidjson/document.h
index 93b091f64..de6574090 100644
--- document.h 2025-04-19 22:31:29.000000000 +0200
+++ document.h 2025-04-19 22:31:29.000000000 +0200
@@ -2152,14 +2150,17 @@
\return The document itself for fluent API.
*/
template <unsigned parseFlags, typename SourceEncoding, typename InputStream>
- GenericDocument& ParseStream(InputStream& is) {
+ GenericDocument& ParseStream(InputStream& is_) {
GenericReader<SourceEncoding, Encoding, StackAllocator> reader(
stack_.HasAllocator() ? &stack_.GetAllocator() : 0);
ClearStackOnExit scope(*this);
+ GenericStreamWrapper<InputStream, SourceEncoding> is(is_);
parseResult_ = reader.template Parse<parseFlags>(is, *this);
if (parseResult_) {
RAPIDJSON_ASSERT(stack_.GetSize() == sizeof(ValueType)); // Got one and only one root object
ValueType::operator=(*stack_.template Pop<ValueType>(1));// Move value from stack to document
+ } else {
+ parseResult_.SetPos(is.line_, is.col_);
}
return *this;
}
@@ -2288,6 +2289,12 @@
//! Get the position of last parsing error in input, 0 otherwise.
size_t GetErrorOffset() const { return parseResult_.Offset(); }
+
+ //! Get the position of last parsing error in input, 0 otherwise.
+ size_t GetErrorLine() const { return parseResult_.Line(); }
+
+ //! Get the position of last parsing error in input, 0 otherwise.
+ size_t GetErrorColumn() const { return parseResult_.Col(); }
//! Implicit conversion to get the last parse result
#ifndef __clang // -Wdocumentation
diff --git a/include/rapidjson/error/error.h b/include/rapidjson/error/error.h
index 9311d2f03..be8057911 100644
--- a/include/rapidjson/error/error.h
+++ b/include/rapidjson/error/error.h
@@ -114,6 +114,10 @@
ParseErrorCode Code() const { return code_; }
//! Get the error offset, if \ref IsError(), 0 otherwise.
size_t Offset() const { return offset_; }
+ //! Get the position of line number if error exists.
+ size_t Line() const { return line_; }
+ //! Get the position of column number if error exists.
+ size_t Col() const { return col_; }
//! Conversion to \c bool, returns \c true, iff !\ref IsError().
operator bool() const { return !IsError(); }
@@ -128,10 +132,14 @@
void Clear() { Set(kParseErrorNone); }
//! Update error code and offset.
void Set(ParseErrorCode code, size_t offset = 0) { code_ = code; offset_ = offset; }
+ //! Update line number and column number of the error position
+ void SetPos(size_t line, size_t col) { line_ = line; col_ = col; }
private:
ParseErrorCode code_;
size_t offset_;
+ size_t line_;
+ size_t col_;
};
//! Function pointer type of GetParseError().
diff --git a/include/rapidjson/stream.h b/include/rapidjson/stream.h
index fef82c252..4e4ba80a4 100644
--- a/include/rapidjson/stream.h
+++ b/include/rapidjson/stream.h
@@ -100,6 +100,48 @@ inline void PutN(Stream& stream, Ch c, size_t n) {
PutUnsafe(stream, c);
}
+///////////////////////////////////////////////////////////////////////////////
+// GenericStreamWrapper
+
+//! A Stream Wrapper
+/*! \tThis string stream is designed for counting line and column number
+ \tof the error (if exists) position, while just forwarding any received
+ \tmessage to the origin stream.
+ \note implements Stream concept
+*/
+template <typename InputStream, typename Encoding>
+class GenericStreamWrapper {
+public:
+ typedef typename Encoding::Ch Ch;
+ size_t line_;
+ size_t col_;
+ GenericStreamWrapper(InputStream& is): is_(is), line_(1), col_(0) {}
+
+ Ch Peek() const { return is_.Peek(); }
+
+ // counting line and column number
+ Ch Take() {
+ Ch ch = is_.Take();
+ if(ch == '\n') {
+ line_ ++;
+ col_ = 0;
+ } else {
+ col_ ++;
+ }
+ return ch;
+ }
+ size_t Tell() { return is_.Tell(); }
+
+ Ch* PutBegin() { return is_.PutBegin(); }
+ void Put(Ch ch) { return is_.Put(ch); }
+ void Flush() { return is_.Flush(); }
+ size_t PutEnd(Ch* ch) { is_.PutEnd(ch); }
+
+ const Ch* Peek4() const { is_.Peek4(); }
+private:
+ InputStream& is_;
+};
+
///////////////////////////////////////////////////////////////////////////////
// StringStream

View file

@ -0,0 +1,64 @@
From 79d9c71f98b0f1cfea5fae2fe33595efcbf79028 Mon Sep 17 00:00:00 2001
From: KaitoHH <hh.kaito@gmail.com>
Date: Tue, 26 Sep 2017 16:03:09 +0800
Subject: [PATCH] fix stream wrapper initializer
fix initialization warning
add special wrapper for AutoUTFInputStream
---
include/rapidjson/error/error.h | 4 ++--
include/rapidjson/stream.h | 16 +++++++++++-----
2 files changed, 13 insertions(+), 7 deletions(-)
diff --git a/include/rapidjson/error/error.h b/include/rapidjson/error/error.h
index be8057911..618a6cf69 100644
--- a/include/rapidjson/error/error.h
+++ b/include/rapidjson/error/error.h
@@ -106,9 +106,9 @@
struct ParseResult {
public:
//! Default constructor, no error.
- ParseResult() : code_(kParseErrorNone), offset_(0) {}
+ ParseResult() : code_(kParseErrorNone), offset_(0), line_(0), col_(0) {}
//! Constructor to set an error.
- ParseResult(ParseErrorCode code, size_t offset) : code_(code), offset_(offset) {}
+ ParseResult(ParseErrorCode code, size_t offset) : code_(code), offset_(offset), line_(0), col_(0) {}
//! Get the error code.
ParseErrorCode Code() const { return code_; }
diff --git a/include/rapidjson/stream.h b/include/rapidjson/stream.h
index 4e4ba80a4..a315d3f0a 100644
--- a/include/rapidjson/stream.h
+++ b/include/rapidjson/stream.h
@@ -115,7 +115,7 @@ class GenericStreamWrapper {
typedef typename Encoding::Ch Ch;
size_t line_;
size_t col_;
- GenericStreamWrapper(InputStream& is): is_(is), line_(1), col_(0) {}
+ GenericStreamWrapper(InputStream& is): line_(1), col_(0), is_(is) {}
Ch Peek() const { return is_.Peek(); }
@@ -133,11 +133,17 @@ class GenericStreamWrapper {
size_t Tell() { return is_.Tell(); }
Ch* PutBegin() { return is_.PutBegin(); }
- void Put(Ch ch) { return is_.Put(ch); }
- void Flush() { return is_.Flush(); }
- size_t PutEnd(Ch* ch) { is_.PutEnd(ch); }
+ void Put(Ch ch) { is_.Put(ch); }
+ void Flush() { is_.Flush(); }
+ size_t PutEnd(Ch* ch) { return is_.PutEnd(ch); }
- const Ch* Peek4() const { is_.Peek4(); }
+ // wrapper for MemoryStream
+ const Ch* Peek4() const { return is_.Peek4(); }
+
+ // wrapper for AutoUTFInputStream
+ UTFType GetType() const { return is_.GetType(); }
+ bool HasBOM() const { return is_.HasBOM(); }
+
private:
InputStream& is_;
};

View file

@ -0,0 +1,118 @@
From 799fdea9fc05aa74c2ebfb49340943195ac2e1dc Mon Sep 17 00:00:00 2001
From: KaitoHH <hh.kaito@gmail.com>
Date: Thu, 28 Sep 2017 16:57:52 +0800
Subject: [PATCH] add cursor wrapper
---
include/rapidjson/cursorstreamwrapper.h | 59 +++++++++++++++++++++++++
include/rapidjson/stream.h | 37 +++++-----------
4 files changed, 72 insertions(+), 47 deletions(-)
create mode 100644 include/rapidjson/cursorstreamwrapper.h
diff --git a/include/rapidjson/cursorstreamwrapper.h b/include/rapidjson/cursorstreamwrapper.h
new file mode 100644
index 000000000..5c752af41
--- /dev/null
+++ b/include/rapidjson/cursorstreamwrapper.h
@@ -0,0 +1,59 @@
+// 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
+// specific language governing permissions and limitations under the License.
+
+#ifndef RAPIDJSON_CURSORSTREAMWRAPPER_H_
+#define RAPIDJSON_CURSORSTREAMWRAPPER_H_
+
+#include "stream.h"
+
+RAPIDJSON_NAMESPACE_BEGIN
+
+
+//! Cursor stream wrapper for counting line and column number if error exists.
+/*!
+ \tparam InputStream Any stream that implements Stream Concept
+*/
+template <typename InputStream, typename Encoding = UTF8<> >
+class CursorStreamWrapper : public GenericStreamWrapper<InputStream, Encoding> {
+public:
+ typedef typename Encoding::Ch Ch;
+
+ CursorStreamWrapper(InputStream& is):
+ GenericStreamWrapper<InputStream, Encoding>(is), line_(1), col_(0) {}
+
+ // counting line and column number
+ Ch Take() {
+ Ch ch = this->is_.Take();
+ if(ch == '\n') {
+ line_ ++;
+ col_ = 0;
+ } else {
+ col_ ++;
+ }
+ return ch;
+ }
+
+ //! Get the error line number, if error exists.
+ size_t GetLine() const { return line_; }
+ //! Get the error column number, if error exists.
+ size_t GetColumn() const { return col_; }
+
+private:
+ size_t line_; //!< Current Line
+ size_t col_; //!< Current Column
+};
+
+RAPIDJSON_NAMESPACE_END
+
+#endif // RAPIDJSON_CURSORSTREAMWRAPPER_H_
--- a/include/rapidjson/stream.h 2025-04-19 22:38:11.560827241 +0200
+++ - 2025-04-19 22:39:40.261791105 +0200
@@ -109,27 +109,17 @@
\tmessage to the origin stream.
\note implements Stream concept
*/
-template <typename InputStream, typename Encoding>
+template <typename InputStream, typename Encoding = UTF8<> >
class GenericStreamWrapper {
public:
typedef typename Encoding::Ch Ch;
size_t line_;
size_t col_;
- GenericStreamWrapper(InputStream& is): line_(1), col_(0), is_(is) {}
+ GenericStreamWrapper(InputStream& is): is_(is) {}
Ch Peek() const { return is_.Peek(); }
- // counting line and column number
- Ch Take() {
- Ch ch = is_.Take();
- if(ch == '\n') {
- line_ ++;
- col_ = 0;
- } else {
- col_ ++;
- }
- return ch;
- }
+ Ch Take() { return is_.Take(); }
size_t Tell() { return is_.Tell(); }
Ch* PutBegin() { return is_.PutBegin(); }
@@ -144,7 +134,7 @@
UTFType GetType() const { return is_.GetType(); }
bool HasBOM() const { return is_.HasBOM(); }
-private:
+protected:
InputStream& is_;
};

View file

@ -0,0 +1,58 @@
From 473553bd5ae255217d4176666bff604faa464826 Mon Sep 17 00:00:00 2001
From: KaitoHH <hh.kaito@gmail.com>
Date: Fri, 29 Sep 2017 19:13:29 +0800
Subject: [PATCH] fix gcc & cl warning
---
include/rapidjson/cursorstreamwrapper.h | 23 +++++++++++++++++++++--
1 file changed, 21 insertions(+), 2 deletions(-)
diff --git a/include/rapidjson/cursorstreamwrapper.h b/include/rapidjson/cursorstreamwrapper.h
index 5c752af41..52c11a7c0 100644
--- a/include/rapidjson/cursorstreamwrapper.h
+++ b/include/rapidjson/cursorstreamwrapper.h
@@ -17,6 +17,17 @@
#include "stream.h"
+#if defined(__GNUC__)
+RAPIDJSON_DIAG_PUSH
+RAPIDJSON_DIAG_OFF(effc++)
+#endif
+
+#if defined(_MSC_VER) && _MSC_VER <= 1800
+RAPIDJSON_DIAG_PUSH
+RAPIDJSON_DIAG_OFF(4702) // unreachable code
+RAPIDJSON_DIAG_OFF(4512) // assignment operator could not be generated
+#endif
+
RAPIDJSON_NAMESPACE_BEGIN
@@ -29,9 +40,9 @@ class CursorStreamWrapper : public GenericStreamWrapper<InputStream, Encoding> {
public:
typedef typename Encoding::Ch Ch;
- CursorStreamWrapper(InputStream& is):
+ CursorStreamWrapper(InputStream& is):
GenericStreamWrapper<InputStream, Encoding>(is), line_(1), col_(0) {}
-
+
// counting line and column number
Ch Take() {
Ch ch = this->is_.Take();
@@ -54,6 +65,14 @@ class CursorStreamWrapper : public GenericStreamWrapper<InputStream, Encoding> {
size_t col_; //!< Current Column
};
+#if defined(_MSC_VER) && _MSC_VER <= 1800
+RAPIDJSON_DIAG_POP
+#endif
+
+#if defined(__GNUC__)
+RAPIDJSON_DIAG_POP
+#endif
+
RAPIDJSON_NAMESPACE_END
#endif // RAPIDJSON_CURSORSTREAMWRAPPER_H_

View file

@ -0,0 +1,22 @@
From 3b2441b87f99ab65f37b141a7b548ebadb607b96 Mon Sep 17 00:00:00 2001
From: Janusz Chorko <janusz.chorko@apdu.pl>
Date: Fri, 26 Aug 2016 21:17:38 +0200
Subject: [PATCH] Removed non-compiling assignment operator. Fixed #718
---
include/rapidjson/document.h | 2 --
1 file changed, 2 deletions(-)
diff --git a/include/rapidjson/document.h b/include/rapidjson/document.h
index e3e20dfbd..b0f1f70be 100644
--- a/include/rapidjson/document.h
+++ b/include/rapidjson/document.h
@@ -316,8 +316,6 @@ struct GenericStringRef {
GenericStringRef(const GenericStringRef& rhs) : s(rhs.s), length(rhs.length) {}
- GenericStringRef& operator=(const GenericStringRef& rhs) { s = rhs.s; length = rhs.length; }
-
//! implicit conversion to plain CharType pointer
operator const Ch *() const { return s; }

View file

@ -2,7 +2,7 @@ See: https://github.com/Tencent/rapidjson/pull/909
--- a/include/rapidjson/prettywriter.h
+++ b/include/rapidjson/prettywriter.h
@@ -47,7 +47,7 @@ enum PrettyFormatOptions {
@@ -42,7 +42,7 @@
template<typename OutputStream, typename SourceEncoding = UTF8<>, typename TargetEncoding = UTF8<>, typename StackAllocator = CrtAllocator, unsigned writeFlags = kWriteDefaultFlags>
class PrettyWriter : public Writer<OutputStream, SourceEncoding, TargetEncoding, StackAllocator, writeFlags> {
public:

View file

@ -0,0 +1,52 @@
From 8269bc2bc289e9d343bae51cdf6d23ef0950e001 Mon Sep 17 00:00:00 2001
From: Florin Malita <fmalita@gmail.com>
Date: Tue, 15 May 2018 22:48:07 -0400
Subject: [PATCH] Prevent int underflow when parsing exponents
When parsing negative exponents, the current implementation takes
precautions for |exp| to not underflow int.
But that is not sufficient: later on [1], |exp + expFrac| is also
stored to an int - so we must ensure that the sum stays within int
representable values.
Update the exp clamping logic to take expFrac into account.
[1] https://github.com/Tencent/rapidjson/blob/master/include/rapidjson/reader.h#L1690
---
include/rapidjson/reader.h | 11 ++++++++++-
test/unittest/readertest.cpp | 1 +
2 files changed, 11 insertions(+), 1 deletion(-)
--- a/test/unittest/readertest.cpp
+++ b/test/unittest/readertest.cpp
@@ -242,6 +242,7 @@ static void TestParseDouble() {
TEST_DOUBLE(fullPrecision, "1e-214748363", 0.0); // Maximum supported negative exponent
TEST_DOUBLE(fullPrecision, "1e-214748364", 0.0);
TEST_DOUBLE(fullPrecision, "1e-21474836311", 0.0);
+ TEST_DOUBLE(fullPrecision, "1.00000000001e-2147483638", 0.0);
TEST_DOUBLE(fullPrecision, "0.017976931348623157e+310", 1.7976931348623157e+308); // Max double in another form
// Since
--- a/include/rapidjson/reader.h
+++ a/include/rapidjson/reader.h
@@ -1302,9 +1302,18 @@
if (RAPIDJSON_LIKELY(s.Peek() >= '0' && s.Peek() <= '9')) {
exp = static_cast<int>(s.Take() - '0');
if (expMinus) {
+ // (exp + expFrac) must not underflow int => we're detecting when -exp gets
+ // dangerously close to INT_MIN (a pessimistic next digit 9 would push it into
+ // underflow territory):
+ //
+ // -(exp * 10 + 9) + expFrac >= INT_MIN
+ // <=> exp <= (expFrac - INT_MIN - 9) / 10
+ RAPIDJSON_ASSERT(expFrac <= 0);
+ int maxExp = (expFrac + 2147483639) / 10;
+
while (RAPIDJSON_LIKELY(s.Peek() >= '0' && s.Peek() <= '9')) {
exp = exp * 10 + static_cast<int>(s.Take() - '0');
- if (exp >= 214748364) { // Issue #313: prevent overflow exponent
+ if (RAPIDJSON_UNLIKELY(exp > maxExp)) {
while (RAPIDJSON_UNLIKELY(s.Peek() >= '0' && s.Peek() <= '9')) // Consume the rest of exponent
s.Take();
}

View file

@ -1,17 +1,17 @@
# Template file for 'rapidjson'
pkgname=rapidjson
version=1.1.0
revision=5
revision=6
build_style=cmake
short_desc="Fast JSON parser/generator for C++ with both SAX/DOM style API"
maintainer="Alexander Egorenkov <egorenar-dev@posteo.net>"
license="BSD-3-Clause, MIT"
homepage="https://github.com/miloyip/rapidjson"
distfiles="https://github.com/miloyip/${pkgname}/archive/v${version}.tar.gz"
homepage="https://github.com/Tencent/rapidjson"
distfiles="https://github.com/Tencent/${pkgname}/archive/v${version}.tar.gz"
checksum=bf7ced29704a1e696fbccf2a2b4ea068e7774fa37f6d7dd4039d0787f8bed98e
# class-memaccess is required by https://github.com/Tencent/rapidjson/issues/1700
CXXFLAGS="-Wno-type-limits -Wno-error=class-memaccess -DNDEBUG"
CXXFLAGS="-Wno-type-limits -Wno-error=class-memaccess -Wno-error=effc++ -DNDEBUG"
post_patch() {
# Remove bin/jsonchecker, which is the JSON licensed files