Browse Source
Trivial to use as a string, but it still means you should be careful around it. Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>ppa-0.6.1
Rusty Russell
7 years ago
12 changed files with 207 additions and 96 deletions
@ -0,0 +1,86 @@ |
|||
#include <common/json_escaped.h> |
|||
#include <stdio.h> |
|||
|
|||
struct json_escaped *json_escaped_string_(const tal_t *ctx, |
|||
const void *bytes, size_t len) |
|||
{ |
|||
struct json_escaped *esc; |
|||
|
|||
esc = tal_alloc_arr_(ctx, 1, len + 1, false, true, |
|||
TAL_LABEL(struct json_escaped, "")); |
|||
memcpy(esc->s, bytes, len); |
|||
esc->s[len] = '\0'; |
|||
return esc; |
|||
} |
|||
|
|||
struct json_escaped *json_tok_escaped_string(const tal_t *ctx, |
|||
const char *buffer, |
|||
const jsmntok_t *tok) |
|||
{ |
|||
if (tok->type != JSMN_STRING) |
|||
return NULL; |
|||
/* jsmn always gives us ~ well-formed strings. */ |
|||
return json_escaped_string_(ctx, buffer + tok->start, |
|||
tok->end - tok->start); |
|||
} |
|||
|
|||
bool json_escaped_streq(const struct json_escaped *esc, const char *str) |
|||
{ |
|||
return streq(esc->s, str); |
|||
} |
|||
|
|||
bool json_escaped_eq(const struct json_escaped *a, |
|||
const struct json_escaped *b) |
|||
{ |
|||
return streq(a->s, b->s); |
|||
} |
|||
|
|||
struct json_escaped *json_escape(const tal_t *ctx, const char *str TAKES) |
|||
{ |
|||
struct json_escaped *esc; |
|||
size_t i, n; |
|||
|
|||
/* Worst case: all \uXXXX */ |
|||
esc = (struct json_escaped *)tal_arr(ctx, char, strlen(str) * 6 + 1); |
|||
|
|||
for (i = n = 0; str[i]; i++, n++) { |
|||
char escape = 0; |
|||
switch (str[i]) { |
|||
case '\n': |
|||
escape = 'n'; |
|||
break; |
|||
case '\b': |
|||
escape = 'b'; |
|||
break; |
|||
case '\f': |
|||
escape = 'f'; |
|||
break; |
|||
case '\t': |
|||
escape = 't'; |
|||
break; |
|||
case '\r': |
|||
escape = 'r'; |
|||
break; |
|||
case '\\': |
|||
case '"': |
|||
escape = str[i]; |
|||
break; |
|||
default: |
|||
if ((unsigned)str[i] < ' ' || str[i] == 127) { |
|||
sprintf(esc->s + n, "\\u%04X", str[i]); |
|||
n += 5; |
|||
continue; |
|||
} |
|||
} |
|||
if (escape) { |
|||
esc->s[n++] = '\\'; |
|||
esc->s[n] = escape; |
|||
} else |
|||
esc->s[n] = str[i]; |
|||
} |
|||
|
|||
esc->s[n] = '\0'; |
|||
if (taken(str)) |
|||
tal_free(str); |
|||
return esc; |
|||
} |
@ -0,0 +1,36 @@ |
|||
#ifndef LIGHTNING_COMMON_JSON_ESCAPED_H |
|||
#define LIGHTNING_COMMON_JSON_ESCAPED_H |
|||
#include "config.h" |
|||
#include <common/json.h> |
|||
|
|||
/* Type differentiation for a correctly-escaped JSON string */ |
|||
struct json_escaped { |
|||
/* NUL terminated string. */ |
|||
char s[1]; |
|||
}; |
|||
|
|||
/* @str be a valid UTF-8 string */ |
|||
struct json_escaped *json_escape(const tal_t *ctx, const char *str TAKES); |
|||
|
|||
/* Extract a JSON-escaped string. */ |
|||
struct json_escaped *json_tok_escaped_string(const tal_t *ctx, |
|||
const char *buffer, |
|||
const jsmntok_t *tok); |
|||
|
|||
/* Is @esc equal to @str */ |
|||
bool json_escaped_streq(const struct json_escaped *esc, const char *str); |
|||
|
|||
|
|||
/* Are two escaped json strings identical? */ |
|||
bool json_escaped_eq(const struct json_escaped *a, |
|||
const struct json_escaped *b); |
|||
|
|||
void json_add_escaped_string(struct json_result *result, |
|||
const char *fieldname, |
|||
const struct json_escaped *esc TAKES); |
|||
|
|||
/* Internal routine for creating json_escaped from bytes. */ |
|||
struct json_escaped *json_escaped_string_(const tal_t *ctx, |
|||
const void *bytes, size_t len); |
|||
|
|||
#endif /* LIGHTNING_COMMON_JSON_ESCAPED_H */ |
Loading…
Reference in new issue