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;
}
-C Refinements\sto\ssynchronous\slogic:\s\n(1)\sUse\sPAGER_SYNCHRONOUS_FULL\srather\sthan\sthe\scorresponding\smagic\snumber.\n(2)\sHonor\sSQLITE_NO_SYNC\son\sxDelete\scalls\swith\ssync\n(3)\sCount\sxDelete\ssyncs\sduring\stesting\n(4)\sFix\s#ifs\son\sSQLITE_EXTRA_DURABLE\sso\sthat\sdirectory\ssyncs\son\sjournal\nunlink\sare\soff\sby\sdefault.
-D 2016-02-04T09:48:12.199
+C Escape\scontrol\scharacters\sin\sJSON.\nFix\sfor\sticket\s[ad2559db380abf8].
+D 2016-02-04T10:28:57.253
F Makefile.in 027c1603f255390c43a426671055a31c0a65fdb4
F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434
F Makefile.msc 72b7858f02017611c3ac1ddc965251017fed0845
F ext/misc/fileio.c d4171c815d6543a9edef8308aab2951413cd8d0f
F ext/misc/fuzzer.c 4c84635c71c26cfa7c2e5848cf49fe2d2cfcd767
F ext/misc/ieee754.c f190d0cc5182529acb15babd177781be1ac1718c
-F ext/misc/json1.c 7b1155f520d5e8ec1c005d978ac675e8a7f2688a
+F ext/misc/json1.c 8698ea0ce24bda23bd8ad4a124620d758f92760b
F ext/misc/nextchar.c 35c8b8baacb96d92abbb34a83a997b797075b342
F ext/misc/percentile.c bcbee3c061b884eccb80e21651daaae8e1e43c63
F ext/misc/regexp.c af92cdaa5058fcec1451e49becc7ba44dba023dc
F test/jrnlmode.test 7864d59cf7f6e552b9b99ba0f38acd167edc10fa
F test/jrnlmode2.test 81610545a4e6ed239ea8fa661891893385e23a1d
F test/jrnlmode3.test 556b447a05be0e0963f4311e95ab1632b11c9eaa
-F test/json101.test f0178422b3a2418f423fd0d3caf3571c8d1b9863
+F test/json101.test ef42283f0b60d8bacbc2243448e7c84988578e52
F test/json102.test bf3fe7a706d30936a76a0f7a0375e1e8e73aff5a
F test/json103.test c5f6b85e69de05f6b3195f9f9d5ce9cd179099a0
F test/keyword1.test 37ef6bba5d2ed5b07ecdd6810571de2956599dff
F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4
F tool/warnings.sh 48bd54594752d5be3337f12c72f28d2080cb630b
F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f
-P 632071bac5ff324a74cec9bdbba2deb60c0945e9
-R 3746b9c792f29a07d873215ad89cd62c
+P e3157cb5ad0d22758e766a95fb1463a7810f7d7f
+R b212639d5d48b990a29409ffb71a1dde
U drh
-Z 6297b2dadaa7144af31b30e87beaeee7
+Z b8b1a6316f2eff8be617256b6e3556cd
-e3157cb5ad0d22758e766a95fb1463a7810f7d7f
\ No newline at end of file
+4f1b5229a3bbc9d40b7433a5eb3139d59d31dcb1
\ No newline at end of file
$isvalid
}
+# Ticket https://www.sqlite.org/src/info/ad2559db380abf8e
+# Control characters must be escaped in JSON strings.
+#
+do_execsql_test json-8.1 {
+ DROP TABLE IF EXISTS t8;
+ CREATE TABLE t8(a,b);
+ INSERT INTO t8(a) VALUES('abc' || char(1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35) || 'xyz');
+ UPDATE t8 SET b=json_array(a);
+ SELECT b FROM t8;
+} {{["abc\u0001\u0002\u0003\u0004\u0005\u0006\u0007\b\t\n\u000b\f\r\u000e\u000f\u0010\u0011\u0012\u0013\u0014\u0015\u0016\u0017\u0018\u0019\u001a\u001b\u001c\u001d\u001e\u001f !\"#xyz"]}}
+do_execsql_test json-8.2 {
+ SELECT a=json_extract(b,'$[0]') FROM t8;
+} {1}
+
+
finish_test