1 /* MIT (BSD) license - see LICENSE file for details */
2 #include <ccan/json_escape/json_escape.h>
5 struct json_escape *json_escape_string_(const tal_t *ctx,
6 const void *bytes, size_t len)
8 struct json_escape *esc;
10 esc = (void *)tal_arr_label(ctx, char, len + 1,
11 TAL_LABEL(struct json_escape, ""));
12 memcpy(esc->s, bytes, len);
17 bool json_escape_eq(const struct json_escape *a, const struct json_escape *b)
19 return streq(a->s, b->s);
22 bool json_escape_needed(const char *str, size_t len)
25 for (i = 0; i < len; i++) {
26 if ((unsigned)str[i] < ' '
35 static struct json_escape *escape(const tal_t *ctx,
36 const char *str TAKES,
40 struct json_escape *esc;
43 /* Fast path: can steal, and nothing to escape. */
45 && tal_count(str) > len
46 && !json_escape_needed(str, len)) {
48 esc = (struct json_escape *)tal_steal(ctx, str);
53 /* Worst case: all \uXXXX */
54 esc = (struct json_escape *)tal_arr(ctx, char, len * 6 + 1);
56 for (i = n = 0; i < len; i++, n++) {
76 /* Don't double-escape standard escapes. */
90 && cisxdigit(str[i+2])
91 && cisxdigit(str[i+3])
92 && cisxdigit(str[i+4])
93 && cisxdigit(str[i+5])) {
94 memcpy(esc->s + n, str + i, 6);
104 if ((unsigned)str[i] < ' ' || str[i] == 127) {
105 snprintf(esc->s + n, 7, "\\u%04X", str[i]);
123 struct json_escape *json_partial_escape(const tal_t *ctx, const char *str TAKES)
125 return escape(ctx, str, strlen(str), true);
128 struct json_escape *json_escape(const tal_t *ctx, const char *str TAKES)
130 return escape(ctx, str, strlen(str), false);
133 struct json_escape *json_escape_len(const tal_t *ctx, const char *str TAKES,
136 return escape(ctx, str, len, false);
139 /* By policy, we don't handle \u. Use UTF-8. */
140 const char *json_escape_unescape(const tal_t *ctx, const struct json_escape *esc)
142 char *unesc = tal_arr(ctx, char, strlen(esc->s) + 1);
145 for (i = n = 0; esc->s[i]; i++, n++) {
146 if (esc->s[i] != '\\') {
147 unesc[n] = esc->s[i];
171 unesc[n] = esc->s[i];
174 return tal_free(unesc);