diff options
author | David Robillard <d@drobilla.net> | 2021-02-15 11:43:55 -0500 |
---|---|---|
committer | David Robillard <d@drobilla.net> | 2021-02-15 13:13:41 -0500 |
commit | 1c1645ed45f40a2d73101c6237b19b28aad2b598 (patch) | |
tree | e2668c09d68544bab5130764b3154ea25cac58e2 /src/writer.c | |
parent | 4a731906879cd11f51c08764552c04375844f0ba (diff) | |
download | serd-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.c | 12 |
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); |