Add a json_do_string() a function to print a JSON string.
This function does the needed encoding of control chars and escape chars.
I skipped the optional encoding of the forward slash (/) since this is
only needed if the json output is embedded in HTML/SGML/XML.
People putting JSON into such documents need to pass this through an extra
step.
This implements json_do_printf() now as a wrapper around json_do_string().
All users of json_do_printf(name, "%s", value) can be converted to
json_do_string(). I will do this is a subsequent step.
--
:wq Claudio
Index: json.c
===================================================================
RCS file: /cvs/src/usr.sbin/rpki-client/json.c,v
retrieving revision 1.1
diff -u -p -r1.1 json.c
--- json.c 27 Apr 2023 07:57:25 -0000 1.1
+++ json.c 1 May 2023 20:07:26 -0000
@@ -19,6 +19,7 @@
#include <err.h>
#include <stdarg.h>
#include <stdint.h>
+#include <stdlib.h>
#include <stdio.h>
#include <string.h>
@@ -179,16 +180,64 @@ void
json_do_printf(const char *name, const char *fmt, ...)
{
va_list ap;
+ char *str;
- do_comma_indent();
+ va_start(ap, fmt);
+ if (!eb) {
+ if (vasprintf(&str, fmt, ap) == -1)
+ errx(1, "json printf failed");
+ json_do_string(name, str);
+ free(str);
+ }
+ va_end(ap);
+}
+void
+json_do_string(const char *name, const char *v)
+{
+ int c;
+
+ do_comma_indent();
do_name(name);
if (!eb)
eb = fprintf(jsonfh, "\"") < 0;
- va_start(ap, fmt);
- if (!eb)
- eb = vfprintf(jsonfh, fmt, ap) < 0;
- va_end(ap);
+ while ((c = *v++) != '\0') {
+ /* skip escaping '/' since our use case does not require it */
+ switch(c) {
+ case '"':
+ if (!eb)
+ eb = fprintf(jsonfh, "\\\"") < 0;
+ break;
+ case '\\':
+ if (!eb)
+ eb = fprintf(jsonfh, "\\\\") < 0;
+ break;
+ case '\b':
+ if (!eb)
+ eb = fprintf(jsonfh, "\\b") < 0;
+ break;
+ case '\f':
+ if (!eb)
+ eb = fprintf(jsonfh, "\\f") < 0;
+ break;
+ case '\n':
+ if (!eb)
+ eb = fprintf(jsonfh, "\\n") < 0;
+ break;
+ case '\r':
+ if (!eb)
+ eb = fprintf(jsonfh, "\\r") < 0;
+ break;
+ case '\t':
+ if (!eb)
+ eb = fprintf(jsonfh, "\\t") < 0;
+ break;
+ default:
+ if (!eb)
+ eb = putc(c, jsonfh) == EOF;
+ break;
+ }
+ }
if (!eb)
eb = fprintf(jsonfh, "\"") < 0;
}
Index: json.h
===================================================================
RCS file: /cvs/src/usr.sbin/rpki-client/json.h,v
retrieving revision 1.1
diff -u -p -r1.1 json.h
--- json.h 27 Apr 2023 07:57:25 -0000 1.1
+++ json.h 30 Apr 2023 15:11:36 -0000
@@ -26,6 +26,7 @@ void json_do_object(const char *);
void json_do_end(void);
void json_do_printf(const char *, const char *, ...)
__attribute__((__format__ (printf, 2, 3)));
+void json_do_string(const char *, const char *);
void json_do_hexdump(const char *, void *, size_t);
void json_do_bool(const char *, int);
void json_do_uint(const char *, unsigned long long);