qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Qemu-devel] [PATCH v4 16/28] qapi: Factor out JSON string escaping


From: Markus Armbruster
Subject: Re: [Qemu-devel] [PATCH v4 16/28] qapi: Factor out JSON string escaping
Date: Thu, 02 Jun 2016 16:53:33 +0200
User-agent: Gnus/5.13 (Gnus v5.13) Emacs/24.5 (gnu/linux)

Eric Blake <address@hidden> writes:

> Pull out a new qstring_append_json_string() helper, so that all
> JSON output producers can use the same output escaping rules.
>
> While it appears that vmstate's use of the simpler qjson.c
> formatter is not currently encountering any string that needs
> escapes to be valid JSON, it is better to be safe than sorry,
> and this substitution is not adding any potential asserts
> during migration.
>
> Adding a return value will let callers that care diagnose the
> situation where an attempt was made to output invalid JSON (we
> use substitute characters, and in fact guarantee that our
> output is ASCII via escapes even if the input was UTF-8).  None
> of the current callers care, but a future patch wants to make
> it possible to turn this situation into an error.
>
> Signed-off-by: Eric Blake <address@hidden>
[...]
> @@ -290,3 +238,68 @@ QString *qobject_to_json_pretty(const QObject *obj)
>
>      return str;
>  }
> +
> +/**
> + * Append a JSON string to @qstring that encodes the C string @str.
> + *
> + * The JSON string is enclosed in double quotes and has funny
> + * characters escaped.  Returns -1 if encoding errors were replaced,
> + * or 0 if the input was already valid UTF-8.
> + */

Suggest:

    * @str is in UTF-8.  The JSON string is enclosed in double quotes
    * and has funny characters escaped.  Invalid UTF-8 sequences are
    * replaced by (properly escaped) U+0xFFFD replacement characters.
    * Return -1 if invalid sequences were replaced, else 0.

> +int qstring_append_json_string(QString *qstring, const char *str)
> +{
> +    const char *ptr;
> +    int cp;
> +    char buf[16];
> +    char *end;
> +    int result = 0;
> +
> +    qstring_append(qstring, "\"");
> +
> +    for (ptr = str; *ptr; ptr = end) {
> +        cp = mod_utf8_codepoint(ptr, 6, &end);
> +        switch (cp) {
> +        case '\"':
> +            qstring_append(qstring, "\\\"");
> +            break;
> +        case '\\':
> +            qstring_append(qstring, "\\\\");
> +            break;
> +        case '\b':
> +            qstring_append(qstring, "\\b");
> +            break;
> +        case '\f':
> +            qstring_append(qstring, "\\f");
> +            break;
> +        case '\n':
> +            qstring_append(qstring, "\\n");
> +            break;
> +        case '\r':
> +            qstring_append(qstring, "\\r");
> +            break;
> +        case '\t':
> +            qstring_append(qstring, "\\t");
> +            break;
> +        default:
> +            if (cp < 0) {
> +                cp = 0xFFFD; /* replacement character */
> +                result = -1;
> +            }
> +            if (cp > 0xFFFF) {
> +                /* beyond BMP; need a surrogate pair */
> +                snprintf(buf, sizeof(buf), "\\u%04X\\u%04X",
> +                         0xD800 + ((cp - 0x10000) >> 10),
> +                         0xDC00 + ((cp - 0x10000) & 0x3FF));
> +            } else if (cp < 0x20 || cp >= 0x7F) {
> +                snprintf(buf, sizeof(buf), "\\u%04X", cp);
> +            } else {
> +                buf[0] = cp;
> +                buf[1] = 0;
> +            }
> +            qstring_append(qstring, buf);
> +        }
> +    };
> +
> +    qstring_append(qstring, "\"");
> +    return result;
> +}



reply via email to

[Prev in Thread] Current Thread [Next in Thread]