mirror of /home/gitosis/repositories/libowfat.git
parent
0abea6af07
commit
0482a9ec04
6 changed files with 151 additions and 17 deletions
@ -0,0 +1,42 @@ |
||||
#include "fmt.h" |
||||
#include "textcode.h" |
||||
#include "str.h" |
||||
#include "haveinline.h" |
||||
|
||||
/* src is UTF-8 encoded */ |
||||
size_t fmt_jsonescape(char* dest,const char* src,size_t len) { |
||||
register const unsigned char* s=(const unsigned char*) src; |
||||
size_t written=0,i; |
||||
for (i=0; i<len; ++i) { |
||||
switch (s[i]) { |
||||
case '\\': |
||||
case '"': |
||||
if (dest) { |
||||
dest[written]='\\'; |
||||
dest[written+1]=s[i]; |
||||
} |
||||
written+=2; |
||||
break; |
||||
default: |
||||
if (s[i]<' ') { |
||||
if (dest) { |
||||
dest[written]='\\'; |
||||
dest[written+1]='u'; |
||||
dest[written+2]='0'; |
||||
dest[written+3]='0'; |
||||
dest[written+4]=fmt_tohex(s[i]>>4); |
||||
dest[written+5]=fmt_tohex(s[i]&0xf); |
||||
} |
||||
written+=6; |
||||
} else { |
||||
if (dest) dest[written]=s[i]; |
||||
++written; |
||||
} |
||||
break; |
||||
} |
||||
/* in case someone gives us malicious input */ |
||||
if (written>((size_t)-1)/2) return (size_t)-1; |
||||
} |
||||
return written; |
||||
} |
||||
|
@ -0,0 +1,54 @@ |
||||
#include "fmt.h" |
||||
#include "textcode.h" |
||||
#include "scan.h" |
||||
|
||||
size_t scan_jsonescape(const char *src,char *dest,size_t *destlen) { |
||||
register const unsigned char* s=(const unsigned char*) src; |
||||
size_t written=0,i; |
||||
char c; |
||||
unsigned int prev,cur,todo; |
||||
prev=cur=(unsigned int)-1; |
||||
for (i=0; s[i]; ++i) { |
||||
if ((c=s[i])=='\\') { |
||||
switch (s[i+1]) { |
||||
case '\\': |
||||
if (prev!=(unsigned int)-1) return 0; // lead surrogate not followed by tail surrogate
|
||||
// c='\\'; // c already is backslash
|
||||
break; |
||||
case 'u': |
||||
{ |
||||
size_t j; |
||||
for (cur=j=0; j<4; ++j) { |
||||
char x=scan_fromhex(s[i+2+j]); |
||||
if (x<0) return 0; // not hex -> invalid input
|
||||
cur=(cur<<4) | x; |
||||
} |
||||
if (cur>=0xd800 && cur<=0xdbff) { |
||||
// utf-16 surrogate pair; needs to be followed by another
|
||||
// surrogate. We need to read both and convert to UTF-8
|
||||
if (prev!=(unsigned int)-1) return 0; // two lead surrogates
|
||||
prev=cur; |
||||
i+=5; // we want i to go up by 6, 1 is done by the for loop
|
||||
continue; // write nothing!
|
||||
} else if (cur>=0xdc00 && cur<=0xdfff) { |
||||
todo=(cur&0x3ff) | ((prev&0x3ff) << 10) + 0x100000; |
||||
} else |
||||
todo=cur; |
||||
written+=fmt_utf8(dest?dest+written:dest,todo); |
||||
i+=5; |
||||
prev=-1; |
||||
continue; |
||||
} |
||||
default: |
||||
if (prev!=(unsigned int)-1) return 0; // lead surrogate not followed by tail surrogate
|
||||
c=s[i+1]; |
||||
break; |
||||
} |
||||
++i; |
||||
} |
||||
if (dest) dest[written]=c; |
||||
++written; |
||||
} |
||||
*destlen=written; |
||||
return i; |
||||
} |
Loading…
Reference in new issue