Skip to content

Commit

Permalink
Merge af9e958 into 9906eb5
Browse files Browse the repository at this point in the history
  • Loading branch information
cpjulia committed Sep 6, 2022
2 parents 9906eb5 + af9e958 commit a12a682
Show file tree
Hide file tree
Showing 3 changed files with 46 additions and 16 deletions.
5 changes: 4 additions & 1 deletion include/velocypack/Options.h
Original file line number Diff line number Diff line change
Expand Up @@ -113,9 +113,12 @@ struct Options {
bool checkAttributeUniqueness = false;

// escape forward slashes when serializing VPack values into
// JSON with a Dumper
// JSON with a Dumper (requires escapeControl = true)
bool escapeForwardSlashes = false;

// with a Dumper (creates \uxxxx sequences or displays '\n', '\r' or \'t')
bool escapeControl = true;

// escape multi-byte Unicode characters when dumping them to JSON
// with a Dumper (creates \uxxxx sequences)
bool escapeUnicode = false;
Expand Down
37 changes: 22 additions & 15 deletions src/Dumper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -308,21 +308,28 @@ void Dumper::dumpString(char const* src, ValueLength len) {
char esc = EscapeTable[c];

if (esc) {
if (c != '/' || options->escapeForwardSlashes) {
// escape forward slashes only when requested
_sink->push_back('\\');
}
_sink->push_back(static_cast<char>(esc));

if (esc == 'u') {
uint16_t i1 = (((uint16_t)c) & 0xf0U) >> 4;
uint16_t i2 = (((uint16_t)c) & 0x0fU);

_sink->append("00", 2);
_sink->push_back(
static_cast<char>((i1 < 10) ? ('0' + i1) : ('A' + i1 - 10)));
_sink->push_back(
static_cast<char>((i2 < 10) ? ('0' + i2) : ('A' + i2 - 10)));
if (options->escapeControl) {
if (c != '/' || options->escapeForwardSlashes) {
// escape forward slashes only when requested
_sink->push_back('\\');
}
_sink->push_back(static_cast<char>(esc));
if (esc == 'u') {
uint16_t i1 = (((uint16_t)c) & 0xf0U) >> 4;
uint16_t i2 = (((uint16_t)c) & 0x0fU);

_sink->append("00", 2);
_sink->push_back(
static_cast<char>((i1 < 10) ? ('0' + i1) : ('A' + i1 - 10)));
_sink->push_back(
static_cast<char>((i2 < 10) ? ('0' + i2) : ('A' + i2 - 10)));
}
} else {
if (esc == '"' || esc == '/' || esc == '\\') {
_sink->push_back(static_cast<char>(esc));
} else {
_sink->push_back(' ');
}
}
} else {
_sink->push_back(static_cast<char>(c));
Expand Down
20 changes: 20 additions & 0 deletions tests/testsDumper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -476,6 +476,26 @@ TEST(StringDumperTest, StringControlChars) {
Dumper::toString(slice));
}

TEST(StringDumperTest, SuppressControlChars) {
Builder b;
b.add(Value("Before\nAfter\r\t\v\x01\x02/"));

Options options;
options.escapeControl = false;
ASSERT_EQ(std::string("\"Before After /\""),
Dumper::toString(b.slice(), &options));
}

TEST(StringDumperTest, EscapeControlChars) {
Builder b;
b.add(Value("Before\nAfter\r\t\v\x01\x02"));

Options options;
options.escapeControl = true;
ASSERT_EQ(std::string("\"Before\\nAfter\\r\\t\\u000B\\u0001\\u0002\""),
Dumper::toString(b.slice(), &options));
}

TEST(StringDumperTest, StringUTF8) {
Builder b;
b.add(Value("mötör"));
Expand Down

0 comments on commit a12a682

Please sign in to comment.