From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([2001:4830:134:3::10]:51891) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1b8U0C-0002Cm-Kw for qemu-devel@nongnu.org; Thu, 02 Jun 2016 10:53:41 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1b8U08-0000ZA-7Y for qemu-devel@nongnu.org; Thu, 02 Jun 2016 10:53:39 -0400 Received: from mx1.redhat.com ([209.132.183.28]:51690) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1b8U07-0000Z0-Um for qemu-devel@nongnu.org; Thu, 02 Jun 2016 10:53:36 -0400 Received: from int-mx09.intmail.prod.int.phx2.redhat.com (int-mx09.intmail.prod.int.phx2.redhat.com [10.5.11.22]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 5CA4E80086 for ; Thu, 2 Jun 2016 14:53:35 +0000 (UTC) From: Markus Armbruster References: <1463632874-28559-1-git-send-email-eblake@redhat.com> <1463632874-28559-17-git-send-email-eblake@redhat.com> Date: Thu, 02 Jun 2016 16:53:33 +0200 In-Reply-To: <1463632874-28559-17-git-send-email-eblake@redhat.com> (Eric Blake's message of "Wed, 18 May 2016 22:41:02 -0600") Message-ID: <877fe7ej6a.fsf@dusky.pond.sub.org> MIME-Version: 1.0 Content-Type: text/plain Subject: Re: [Qemu-devel] [PATCH v4 16/28] qapi: Factor out JSON string escaping List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: Eric Blake Cc: qemu-devel@nongnu.org, Amit Shah , Juan Quintela , Luiz Capitulino Eric Blake 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 [...] > @@ -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; > +}