Skip to content

Commit

Permalink
Allow escaped apostrophe in values (#1639)
Browse files Browse the repository at this point in the history
* Allow escaped apostrophe in values

* Allow escaped apostrophe in values

* Canonical flag name

* Add translation for escaped apostrophe

Co-authored-by: Milo Yip <miloyip@gmail.com>
  • Loading branch information
xpahos and miloyip authored Feb 13, 2020
1 parent 418331e commit a895ce1
Show file tree
Hide file tree
Showing 4 changed files with 32 additions and 1 deletion.
1 change: 1 addition & 0 deletions doc/dom.md
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,7 @@ Parse flags | Meaning
`kParseNumbersAsStringsFlag` | Parse numerical type values as strings.
`kParseTrailingCommasFlag` | Allow trailing commas at the end of objects and arrays (relaxed JSON syntax).
`kParseNanAndInfFlag` | Allow parsing `NaN`, `Inf`, `Infinity`, `-Inf` and `-Infinity` as `double` values (relaxed JSON syntax).
`kParseEscapedApostropheFlag` | Allow escaped apostrophe `\'` in strings (relaxed JSON syntax).
By using a non-type template parameter, instead of a function parameter, C++ compiler can generate code which is optimized for specified combinations, improving speed, and reducing code size (if only using a single specialization). The downside is the flags needed to be determined in compile-time.
Expand Down
1 change: 1 addition & 0 deletions doc/dom.zh-cn.md
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,7 @@ GenericDocument& GenericDocument::Parse(const Ch* str);
`kParseNumbersAsStringsFlag` | 把数字类型解析成字符串。
`kParseTrailingCommasFlag` | 容许在对象和数组结束前含有逗号(放宽的 JSON 语法)。
`kParseNanAndInfFlag` | 容许 `NaN`、`Inf`、`Infinity`、`-Inf` 及 `-Infinity` 作为 `double` 值(放宽的 JSON 语法)。
`kParseEscapedApostropheFlag` | 容许字符串中转义单引号 `\'` (放宽的 JSON 语法)。
由于使用了非类型模板参数,而不是函数参数,C++ 编译器能为个别组合生成代码,以改善性能及减少代码尺寸(当只用单种特化)。缺点是需要在编译期决定标志。
Expand Down
7 changes: 6 additions & 1 deletion include/rapidjson/reader.h
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,7 @@ enum ParseFlag {
kParseNumbersAsStringsFlag = 64, //!< Parse all numbers (ints/doubles) as strings.
kParseTrailingCommasFlag = 128, //!< Allow trailing commas at the end of objects and arrays.
kParseNanAndInfFlag = 256, //!< Allow parsing NaN, Inf, Infinity, -Inf and -Infinity as doubles.
kParseEscapedApostropheFlag = 512, //!< Allow escaped apostrophe in strings.
kParseDefaultFlags = RAPIDJSON_PARSE_DEFAULT_FLAGS //!< Default parse flags. Can be customized by defining RAPIDJSON_PARSE_DEFAULT_FLAGS
};

Expand Down Expand Up @@ -991,7 +992,7 @@ class GenericReader {
//!@cond RAPIDJSON_HIDDEN_FROM_DOXYGEN
#define Z16 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
static const char escape[256] = {
Z16, Z16, 0, 0,'\"', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,'/',
Z16, Z16, 0, 0,'\"', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, '/',
Z16, Z16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,'\\', 0, 0, 0,
0, 0,'\b', 0, 0, 0,'\f', 0, 0, 0, 0, 0, 0, 0,'\n', 0,
0, 0,'\r', 0,'\t', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
Expand All @@ -1014,6 +1015,10 @@ class GenericReader {
is.Take();
os.Put(static_cast<typename TEncoding::Ch>(escape[static_cast<unsigned char>(e)]));
}
else if ((parseFlags & kParseEscapedApostropheFlag) && RAPIDJSON_LIKELY(e == '\'')) { // Allow escaped apostrophe
is.Take();
os.Put('\'');
}
else if (RAPIDJSON_LIKELY(e == 'u')) { // Unicode
is.Take();
unsigned codepoint = ParseHex4(is, escapeOffset);
Expand Down
24 changes: 24 additions & 0 deletions test/unittest/readertest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2198,4 +2198,28 @@ TEST(Reader, ParseNanAndInfinity) {
#undef TEST_NAN_INF
}

TEST(Reader, EscapedApostrophe) {
const char json[] = " { \"foo\": \"bar\\'buzz\" } ";

BaseReaderHandler<> h;

{
StringStream s(json);
Reader reader;
ParseResult r = reader.Parse<kParseNoFlags>(s, h);
EXPECT_TRUE(reader.HasParseError());
EXPECT_EQ(kParseErrorStringEscapeInvalid, r.Code());
EXPECT_EQ(14u, r.Offset());
}

{
StringStream s(json);
Reader reader;
ParseResult r = reader.Parse<kParseEscapedApostropheFlag>(s, h);
EXPECT_FALSE(reader.HasParseError());
EXPECT_EQ(kParseErrorNone, r.Code());
EXPECT_EQ(0u, r.Offset());
}
}

RAPIDJSON_DIAG_POP

0 comments on commit a895ce1

Please sign in to comment.