@@ -451,6 +451,137 @@ static int mount_filesystems()
451
451
return 0 ;
452
452
}
453
453
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
+
454
585
static void config_parse_env (char * data , jsmntok_t * token )
455
586
{
456
587
jsmntok_t * tenv ;
@@ -464,6 +595,8 @@ static void config_parse_env(char *data, jsmntok_t *token)
464
595
env = data + tenv -> start ;
465
596
len = tenv -> end - tenv -> start ;
466
597
598
+ unescape_string (env , len );
599
+
467
600
env_val = strstr (env , "=" );
468
601
if (!env_val ) {
469
602
continue ;
@@ -503,6 +636,8 @@ static char ** config_parse_args(char *data, jsmntok_t *token)
503
636
memcpy (arg , value , len );
504
637
arg [len ] = '\0' ;
505
638
639
+ unescape_string (arg , len );
640
+
506
641
argv [j ] = arg ;
507
642
j ++ ;
508
643
}
@@ -537,6 +672,8 @@ static char * config_parse_string(char *data, jsmntok_t *token)
537
672
memcpy (string , val , len );
538
673
string [len ] = '\0' ;
539
674
675
+ unescape_string (string , len );
676
+
540
677
return string ;
541
678
}
542
679
0 commit comments