Skip to content

Commit 529cbc7

Browse files
committed
init: fix unescape_string not advancing past escape characters
After processing a \X escape sequence in the switch block, the read pointer (val) was not advanced past the matched character. The next loop iteration re-processed it as a literal, producing a spurious extra byte for every escape sequence. For example, JSON "\n" decoded to {0x0A, 'n'} instead of {0x0A}, and JSON "\\" decoded to {'\', <next char interpreted as escape>} instead of {'\'}. Also fix the \u case: hexToDigit was called with a pointer to 'u' instead of the first hex digit (val++ vs ++val), and the write index was not advanced after memcpy, so decoded Unicode characters were silently dropped. This caused e.g. \u0026 ('&') to be lost, breaking any container command containing '&&'.
1 parent 391409d commit 529cbc7

1 file changed

Lines changed: 4 additions & 1 deletion

File tree

init/init.c

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -666,7 +666,8 @@ static void unescape_string(char *string, int len)
666666
const char *unescaped = "?";
667667
char utf8Buf[5];
668668
unsigned int codepoint = 0;
669-
hexToDigit(&codepoint, val++);
669+
/* skip 'u', point at first hex digit */
670+
hexToDigit(&codepoint, ++val);
670671
val += 3;
671672
/* check if this is a surrogate */
672673
if ((codepoint & 0xFC00) == 0xD800) {
@@ -692,9 +693,11 @@ static void unescape_string(char *string, int len)
692693
continue;
693694
}
694695
memcpy(&string[i], unescaped, (unsigned int)strlen(unescaped));
696+
i += strlen(unescaped);
695697
break;
696698
}
697699
}
700+
val++;
698701
}
699702
string[i] = '\0';
700703
}

0 commit comments

Comments
 (0)