aboutsummaryrefslogtreecommitdiffstats
path: root/src/writer.c
diff options
context:
space:
mode:
authorDavid Robillard <d@drobilla.net>2021-02-15 11:43:55 -0500
committerDavid Robillard <d@drobilla.net>2021-02-15 13:13:41 -0500
commit1c1645ed45f40a2d73101c6237b19b28aad2b598 (patch)
treee2668c09d68544bab5130764b3154ea25cac58e2 /src/writer.c
parent4a731906879cd11f51c08764552c04375844f0ba (diff)
downloadserd-1c1645ed45f40a2d73101c6237b19b28aad2b598.tar.gz
serd-1c1645ed45f40a2d73101c6237b19b28aad2b598.tar.bz2
serd-1c1645ed45f40a2d73101c6237b19b28aad2b598.zip
Fix writing long literals with triple quotes
Diffstat (limited to 'src/writer.c')
-rw-r--r--src/writer.c12
1 files changed, 10 insertions, 2 deletions
diff --git a/src/writer.c b/src/writer.c
index 82ac5eeb..af2980c5 100644
--- a/src/writer.c
+++ b/src/writer.c
@@ -332,8 +332,13 @@ write_text(SerdWriter* writer,
const uint8_t* utf8,
size_t n_bytes)
{
- size_t len = 0;
+ size_t len = 0;
+ size_t n_consecutive_quotes = 0;
for (size_t i = 0; i < n_bytes;) {
+ if (utf8[i] != '"') {
+ n_consecutive_quotes = 0;
+ }
+
// Fast bulk write for long strings of printable ASCII
size_t j = i;
for (; j < n_bytes; ++j) {
@@ -350,6 +355,8 @@ write_text(SerdWriter* writer,
const uint8_t in = utf8[i++];
if (ctx == WRITE_LONG_STRING) {
+ n_consecutive_quotes = (in == '\"') ? (n_consecutive_quotes + 1) : 0;
+
switch (in) {
case '\\':
len += sink("\\\\", 2, writer);
@@ -364,7 +371,8 @@ write_text(SerdWriter* writer,
len += sink(&in, 1, writer); // Write character as-is
continue;
case '\"':
- if (i == n_bytes) { // '"' at string end
+ if (n_consecutive_quotes >= 3 || i == n_bytes) {
+ // Two quotes in a row, or quote at string end, escape
len += sink("\\\"", 2, writer);
} else {
len += sink(&in, 1, writer);