diff options
author | Karel Zak | 2016-08-02 11:58:50 +0200 |
---|---|---|
committer | Karel Zak | 2016-08-02 12:05:05 +0200 |
commit | 1ca2661bb8c4021aac2130536d846d6276448f53 (patch) | |
tree | 0021e9af03b0afe7ecb21af72d6895403b5cd0e0 /include/carefulputc.h | |
parent | agetty: call uname() only when necessary (diff) | |
download | kernel-qcow2-util-linux-1ca2661bb8c4021aac2130536d846d6276448f53.tar.gz kernel-qcow2-util-linux-1ca2661bb8c4021aac2130536d846d6276448f53.tar.xz kernel-qcow2-util-linux-1ca2661bb8c4021aac2130536d846d6276448f53.zip |
libsmartcols: Corrected JSON escaping
Based on patch set https://github.com/karelzak/util-linux/pull/331
from Fordi.
Addresses: https://github.com/karelzak/util-linux/issues/330
Co-Author: Bryan Elliott <fordiman@gmail.com>
Signed-off-by: Karel Zak <kzak@redhat.com>
Diffstat (limited to 'include/carefulputc.h')
-rw-r--r-- | include/carefulputc.h | 80 |
1 files changed, 80 insertions, 0 deletions
diff --git a/include/carefulputc.h b/include/carefulputc.h index 681e66660..688435ed5 100644 --- a/include/carefulputc.h +++ b/include/carefulputc.h @@ -26,6 +26,82 @@ static inline int fputc_careful(int c, FILE *fp, const char fail) return (ret < 0) ? EOF : 0; } +/* + * Requirements enumerated via testing (V8, Firefox, IE11): + * + * var charsToEscape = []; + * for (var i = 0; i < 65535; i += 1) { + * try { + * JSON.parse('{"sample": "' + String.fromCodePoint(i) + '"}'); + * } catch (e) { + * charsToEscape.push(i); + * } + * } + */ +static inline void fputs_quoted_case_json(const char *data, FILE *out, int dir) +{ + const char *p; + + fputc('"', out); + for (p = data; p && *p; p++) { + + const unsigned char c = (unsigned char) *p; + + /* From http://www.json.org + * + * The double-quote and backslashes would break out a string or + * init an escape sequence if not escaped. + * + * Note that single-quotes and forward slashes, while they're + * in the JSON spec, don't break double-quoted strings. + */ + if (c == '"' || c == '\\') { + fputc('\\', out); + fputc(c, out); + continue; + } + + /* All non-control characters OK; do the case swap as required. */ + if (c >= 0x20) { + fputc(dir == 1 ? toupper(c) : + dir == -1 ? tolower(c) : *p, out); + continue; + } + + /* In addition, all chars under ' ' break Node's/V8/Chrome's, and + * Firefox's JSON.parse function + */ + switch (c) { + /* Handle short-hand cases to reduce output size. C + * has most of the same stuff here, so if there's an + * "Escape for C" function somewhere in the STL, we + * should probably be using it. + */ + case '\b': + fputs("\\b", out); + break; + case '\t': + fputs("\\t", out); + break; + case '\n': + fputs("\\n", out); + break; + case '\f': + fputs("\\f", out); + break; + case '\r': + fputs("\\r", out); + break; + default: + /* Other assorted control characters */ + fprintf(out, "\\u00%02x", c); + break; + } + } + fputc('"', out); +} + + static inline void fputs_quoted_case(const char *data, FILE *out, int dir) { const char *p; @@ -52,6 +128,10 @@ static inline void fputs_quoted_case(const char *data, FILE *out, int dir) #define fputs_quoted_upper(_d, _o) fputs_quoted_case(_d, _o, 1) #define fputs_quoted_lower(_d, _o) fputs_quoted_case(_d, _o, -1) +#define fputs_quoted_json(_d, _o) fputs_quoted_case_json(_d, _o, 0) +#define fputs_quoted_json_upper(_d, _o) fputs_quoted_case_json(_d, _o, 1) +#define fputs_quoted_json_lower(_d, _o) fputs_quoted_case_json(_d, _o, -1) + static inline void fputs_nonblank(const char *data, FILE *out) { const char *p; |