Browse Source

escape </script> in fmt_jsonescape

master
Felix von Leitner 1 year ago
parent
commit
b8fd3b6bc9
  1. 11
      textcode/fmt_jsonescape.c

11
textcode/fmt_jsonescape.c

@ -3,6 +3,7 @@
#include "textcode.h"
#include "str.h"
#include "scan.h"
#include "case.h"
#include "haveinline.h"
/* src is UTF-8 encoded */
@ -12,6 +13,13 @@ size_t fmt_jsonescape(char* dest,const char* src,size_t len) {
char c;
for (i=0; i<len; ++i) {
switch (s[i]) {
case '<':
/* If you are outputting the json inside a <script> tag in HTML,
* and the string is attacker controlled and contains "</script>",
* that would allow cross site scripting. So we escape that here. */
if (len-i>=9 && case_equalb(s+i+1,8,"/script>"))
goto unicodeescape;
goto noneed;
case '\\':
case '"':
c=s[i];
@ -29,6 +37,7 @@ escape:
case '\f': c='f'; goto escape;
default:
if (s[i]<' ') {
unicodeescape:
if (dest) {
dest[written]='\\';
dest[written+1]='u';
@ -68,6 +77,7 @@ escape:
i+=j-1; /* -1 because the for loop will also add 1 */
break;
} else {
noneed:
if (dest) dest[written]=s[i];
++written;
}
@ -94,5 +104,6 @@ int main() {
* anymore. This test will fail now:
assert(fmt_jsonescape(buf,"\xf0\x9f\x92\xa9x",5)==13 && !memcmp(buf,"\\ud83d\\udca9x",13)); */
assert(fmt_jsonescape(buf,"a\x81x",3)==4 && !memcmp(buf,"a\xc2\x81x",4));
assert(fmt_jsonescape(buf,"</Script>",9)==14 && !memcmp(buf,"\\u003c/Script>",14));
}
#endif

Loading…
Cancel
Save