diff options
author | drh <drh@noemail.net> | 2016-02-04 10:28:57 +0000 |
---|---|---|
committer | drh <drh@noemail.net> | 2016-02-04 10:28:57 +0000 |
commit | 3b7f9a68d5172c215fe56dc5dc60378aec268820 (patch) | |
tree | d3d2a4483c1fbe5398194c44a4f32a60bef8579e /ext/misc/json1.c | |
parent | 6d258995e65e606f65b9189c409801c3da01f4ef (diff) | |
download | sqlite-3b7f9a68d5172c215fe56dc5dc60378aec268820.tar.gz sqlite-3b7f9a68d5172c215fe56dc5dc60378aec268820.zip |
Escape control characters in JSON.
Fix for ticket [ad2559db380abf8].
FossilOrigin-Name: 4f1b5229a3bbc9d40b7433a5eb3139d59d31dcb1
Diffstat (limited to 'ext/misc/json1.c')
-rw-r--r-- | ext/misc/json1.c | 25 |
1 files changed, 24 insertions, 1 deletions
diff --git a/ext/misc/json1.c b/ext/misc/json1.c index 370751666..e4ea4fb9f 100644 --- a/ext/misc/json1.c +++ b/ext/misc/json1.c @@ -276,10 +276,33 @@ static void jsonAppendString(JsonString *p, const char *zIn, u32 N){ if( (N+p->nUsed+2 >= p->nAlloc) && jsonGrow(p,N+2)!=0 ) return; p->zBuf[p->nUsed++] = '"'; for(i=0; i<N; i++){ - char c = zIn[i]; + unsigned char c = ((unsigned const char*)zIn)[i]; if( c=='"' || c=='\\' ){ + json_simple_escape: if( (p->nUsed+N+3-i > p->nAlloc) && jsonGrow(p,N+3-i)!=0 ) return; p->zBuf[p->nUsed++] = '\\'; + }else if( c<=0x1f ){ + static const char aSpecial[] = { + 0, 0, 0, 0, 0, 0, 0, 0, 'b', 't', 'n', 0, 'f', 'r', 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 + }; + assert( sizeof(aSpecial)==32 ); + assert( aSpecial['\b']=='b' ); + assert( aSpecial['\f']=='f' ); + assert( aSpecial['\n']=='n' ); + assert( aSpecial['\r']=='r' ); + assert( aSpecial['\t']=='t' ); + if( aSpecial[c] ){ + c = aSpecial[c]; + goto json_simple_escape; + } + if( (p->nUsed+N+7+i > p->nAlloc) && jsonGrow(p,N+7-i)!=0 ) return; + p->zBuf[p->nUsed++] = '\\'; + p->zBuf[p->nUsed++] = 'u'; + p->zBuf[p->nUsed++] = '0'; + p->zBuf[p->nUsed++] = '0'; + p->zBuf[p->nUsed++] = '0' + (c>>4); + c = "0123456789abcdef"[c&0xf]; } p->zBuf[p->nUsed++] = c; } |