diff --git a/ChangeLog b/ChangeLog index 234077f2..dccc733d 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +* 2019-??-??: Version 1.?.? + * Issue #419: Escape backslashed when printing in JSON format. + Thanks boB Rudis + * 2019-01-11: Version 1.5.1 * Introduce proof of concept GnuTLS implementation. Incomplete support for Trust Anchor validation. Requires GnuTLS DANE library. Currently diff --git a/src/dict.c b/src/dict.c index d2ce53a9..69c8d06d 100644 --- a/src/dict.c +++ b/src/dict.c @@ -782,13 +782,31 @@ getdns_pp_bindata(gldns_buffer *buf, getdns_bindata *bindata, if (bindata->size > 0 && i == bindata->size) { /* all printable? */ - if (json) - (void)snprintf(spc, sizeof(spc), "\"%%.%ds\"", (int)i); - else + if (json) { + const uint8_t *s = bindata->data; + const uint8_t *e = s + bindata->size; + const uint8_t *b; + + if (!gldns_buffer_reserve(buf, (e - s) + 2)) + return -1; + gldns_buffer_write_u8(buf, '"'); + while ((b = memchr(s, '\\', e - s))) { + if (!gldns_buffer_reserve(buf, (b - s) + 3)) + return -1; + gldns_buffer_write(buf, s, b - s); + gldns_buffer_write_u8(buf, '\\'); + gldns_buffer_write_u8(buf, '\\'); + s = b + 1; + } + if (s < e) + gldns_buffer_write(buf, s, e - s); + gldns_buffer_write_u8(buf, '"'); + } else { (void)snprintf(spc, sizeof(spc), "of \"%%.%ds\"%s>", (int)(i > 32 ? 32 : i), (i > 32 ? "..." : "")); - if (gldns_buffer_printf(buf, spc, bindata->data) < 0) - return -1; + if (gldns_buffer_printf(buf, spc, bindata->data) < 0) + return -1; + } } else if (bindata->size > 1 && /* null terminated printable */ i == bindata->size - 1 && bindata->data[i] == 0) { diff --git a/src/gldns/gbuffer.c b/src/gldns/gbuffer.c index 180fa631..3b39f438 100644 --- a/src/gldns/gbuffer.c +++ b/src/gldns/gbuffer.c @@ -106,6 +106,8 @@ int gldns_buffer_reserve(gldns_buffer *buffer, size_t amount) { gldns_buffer_invariant(buffer); + if (buffer->_vfixed) + return 1; assert(!buffer->_fixed); if (buffer->_capacity < buffer->_position + amount) { size_t new_capacity = buffer->_capacity * 3 / 2;