Skip to content

Commit 75b85f4

Browse files
committed
init: escape json strings
Closes: #276 Signed-off-by: Giuseppe Scrivano <gscrivan@redhat.com>
1 parent 8e62bf5 commit 75b85f4

File tree

1 file changed

+137
-0
lines changed

1 file changed

+137
-0
lines changed

init/init.c

+137
Original file line numberDiff line numberDiff line change
@@ -451,6 +451,137 @@ static int mount_filesystems()
451451
return 0;
452452
}
453453

454+
/*
455+
* hexToDigit, Utf32toUtf8 and parts of unescape_string are taken from libyajl:
456+
*
457+
* Copyright (c) 2007-2014, Lloyd Hilaiel <me@lloyd.io>
458+
*
459+
* Permission to use, copy, modify, and/or distribute this software for any
460+
* purpose with or without fee is hereby granted, provided that the above
461+
* copyright notice and this permission notice appear in all copies.
462+
*
463+
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
464+
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
465+
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
466+
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
467+
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
468+
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
469+
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
470+
*/
471+
static void hexToDigit(unsigned int * val, const unsigned char * hex)
472+
{
473+
unsigned int i;
474+
for (i=0;i<4;i++) {
475+
unsigned char c = hex[i];
476+
if (c >= 'A') c = (c & ~0x20) - 7;
477+
c -= '0';
478+
*val = (*val << 4) | c;
479+
}
480+
}
481+
482+
static void Utf32toUtf8(unsigned int codepoint, char * utf8Buf)
483+
{
484+
if (codepoint < 0x80) {
485+
utf8Buf[0] = (char) codepoint;
486+
utf8Buf[1] = 0;
487+
} else if (codepoint < 0x0800) {
488+
utf8Buf[0] = (char) ((codepoint >> 6) | 0xC0);
489+
utf8Buf[1] = (char) ((codepoint & 0x3F) | 0x80);
490+
utf8Buf[2] = 0;
491+
} else if (codepoint < 0x10000) {
492+
utf8Buf[0] = (char) ((codepoint >> 12) | 0xE0);
493+
utf8Buf[1] = (char) (((codepoint >> 6) & 0x3F) | 0x80);
494+
utf8Buf[2] = (char) ((codepoint & 0x3F) | 0x80);
495+
utf8Buf[3] = 0;
496+
} else if (codepoint < 0x200000) {
497+
utf8Buf[0] =(char)((codepoint >> 18) | 0xF0);
498+
utf8Buf[1] =(char)(((codepoint >> 12) & 0x3F) | 0x80);
499+
utf8Buf[2] =(char)(((codepoint >> 6) & 0x3F) | 0x80);
500+
utf8Buf[3] =(char)((codepoint & 0x3F) | 0x80);
501+
utf8Buf[4] = 0;
502+
} else {
503+
utf8Buf[0] = '?';
504+
utf8Buf[1] = 0;
505+
}
506+
}
507+
508+
509+
/* Do not worry about invalid JSON, it was already parsed by jsmn. */
510+
static void unescape_string(char *string, int len)
511+
{
512+
unsigned char *val = (unsigned char *) string;
513+
unsigned char *end;
514+
int i = 0;
515+
516+
end = val + len;
517+
while (val < end) {
518+
if (*val != '\\') {
519+
string[i++] = *val++;
520+
continue;
521+
}
522+
switch (*++val) {
523+
case 'n':
524+
string[i++] = '\n';
525+
break;
526+
case 't':
527+
string[i++] = '\t';
528+
break;
529+
case 'r':
530+
string[i++] = '\r';
531+
break;
532+
case 'b':
533+
string[i++] = '\b';
534+
break;
535+
case 'f':
536+
string[i++] = '\f';
537+
break;
538+
case '\\':
539+
string[i++] = '\\';
540+
break;
541+
case '\"':
542+
string[i++] = '\"';
543+
break;
544+
case '/':
545+
string[i++] = '/';
546+
break;
547+
case 'u': {
548+
const char * unescaped = "?";
549+
char utf8Buf[5];
550+
unsigned int codepoint = 0;
551+
hexToDigit(&codepoint, val++);
552+
val+=3;
553+
/* check if this is a surrogate */
554+
if ((codepoint & 0xFC00) == 0xD800) {
555+
val++;
556+
if (val[0] == '\\' && val[1] == 'u') {
557+
unsigned int surrogate = 0;
558+
hexToDigit(&surrogate, val + 2);
559+
codepoint =
560+
(((codepoint & 0x3F) << 10) |
561+
((((codepoint >> 6) & 0xF) + 1) << 16) |
562+
(surrogate & 0x3FF));
563+
val += 5;
564+
} else {
565+
unescaped = "?";
566+
break;
567+
}
568+
}
569+
570+
Utf32toUtf8(codepoint, utf8Buf);
571+
unescaped = utf8Buf;
572+
573+
if (codepoint == 0) {
574+
memcpy(&string[i++], unescaped, 1);
575+
continue;
576+
}
577+
memcpy(&string[i], unescaped, (unsigned int)strlen(unescaped));
578+
break;
579+
}
580+
}
581+
}
582+
string[i] = '\0';
583+
}
584+
454585
static void config_parse_env(char *data, jsmntok_t *token)
455586
{
456587
jsmntok_t *tenv;
@@ -464,6 +595,8 @@ static void config_parse_env(char *data, jsmntok_t *token)
464595
env = data + tenv->start;
465596
len = tenv->end - tenv->start;
466597

598+
unescape_string(env, len);
599+
467600
env_val = strstr(env, "=");
468601
if (!env_val) {
469602
continue;
@@ -503,6 +636,8 @@ static char ** config_parse_args(char *data, jsmntok_t *token)
503636
memcpy(arg, value, len);
504637
arg[len] = '\0';
505638

639+
unescape_string(arg, len);
640+
506641
argv[j] = arg;
507642
j++;
508643
}
@@ -537,6 +672,8 @@ static char * config_parse_string(char *data, jsmntok_t *token)
537672
memcpy(string, val, len);
538673
string[len] = '\0';
539674

675+
unescape_string(string, len);
676+
540677
return string;
541678
}
542679

0 commit comments

Comments
 (0)