Skip to content

Commit

Permalink
[fix] double-quoted emitter should escape carriage return to ensure r…
Browse files Browse the repository at this point in the history
…oundtrip equivalence

re #253
  • Loading branch information
biojppm committed May 2, 2022
1 parent 8a350c4 commit ff54931
Show file tree
Hide file tree
Showing 3 changed files with 54 additions and 0 deletions.
12 changes: 12 additions & 0 deletions changelog/current.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,3 +19,15 @@
=VAL :foo
=VAL :bar
```
- Fix [#253](https://github.com/biojppm/rapidyaml/issues/253): double-quoted emitter should encode carriage-return `\r` to preserve roundtrip equivalence:
```yaml
Tree tree;
NodeRef root = tree.rootref();
root |= MAP;
root["s"] = "t\rt";
root["s"] |= _WIP_VAL_DQUO;
std::string s = emitrs<std::string>(tree);
EXPECT_EQ(s, "s: \"t\\rt\"\n");
Tree tree2 = parse_in_arena(to_csubstr(s));
EXPECT_EQ(tree2["s"].val(), tree["s"].val());
```
7 changes: 7 additions & 0 deletions src/c4/yml/emit.def.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -767,6 +767,13 @@ void Emitter<Writer>::_write_scalar_dquo(csubstr s, size_t ilevel)
pos = i;
}
}
else if(C4_UNLIKELY(curr == '\r'))
{
csubstr sub = s.range(pos, i);
this->Writer::_do_write(sub); // write everything up to (excluding) this char
this->Writer::_do_write("\\r"); // write the escaped char
pos = i+1;
}
}
// write missing characters at the end of the string
if(pos < s.len)
Expand Down
35 changes: 35 additions & 0 deletions test/test_double_quoted.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -399,6 +399,41 @@ TEST(double_quoted, error_on_bad_utf_codepoints)
verify_error_is_reported("bad value \\U" , R"(foo: "\Ukokokoko")");
}

TEST(double_quoted, github253)
{
{
Tree tree;
NodeRef root = tree.rootref();
root |= MAP;
root["t"] = "t't\\nt";
root["t"] |= _WIP_VAL_DQUO;
std::string s = emitrs<std::string>(tree);
Tree tree2 = parse_in_arena(to_csubstr(s));
EXPECT_EQ(tree2["t"].val(), tree["t"].val());
}
{
Tree tree;
NodeRef root = tree.rootref();
root |= MAP;
root["t"] = "t't\\nt";
root["t"] |= _WIP_VAL_SQUO;
std::string s = emitrs<std::string>(tree);
Tree tree2 = parse_in_arena(to_csubstr(s));
EXPECT_EQ(tree2["t"].val(), tree["t"].val());
}
{
Tree tree;
NodeRef root = tree.rootref();
root |= MAP;
root["s"] = "t\rt";
root["s"] |= _WIP_VAL_DQUO;
std::string s = emitrs<std::string>(tree);
EXPECT_EQ(s, "s: \"t\\rt\"\n");
Tree tree2 = parse_in_arena(to_csubstr(s));
EXPECT_EQ(tree2["s"].val(), tree["s"].val());
}
}


//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
Expand Down

0 comments on commit ff54931

Please sign in to comment.