/ Check-in [4f1b5229]
Login
SQLite training in Houston TX on 2019-11-05 (details)
Part of the 2019 Tcl Conference

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Escape control characters in JSON. Fix for ticket [ad2559db380abf8].
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: 4f1b5229a3bbc9d40b7433a5eb3139d59d31dcb1
User & Date: drh 2016-02-04 10:28:57
Context
2016-02-04
11:15
Use sqlite3_malloc64() instead of sqlite3_malloc() in the spellfix extension. check-in: 634d008c user: drh tags: trunk
10:28
Escape control characters in JSON. Fix for ticket [ad2559db380abf8]. check-in: 4f1b5229 user: drh tags: trunk
09:48
Refinements to synchronous logic: (1) Use PAGER_SYNCHRONOUS_FULL rather than the corresponding magic number. (2) Honor SQLITE_NO_SYNC on xDelete calls with sync (3) Count xDelete syncs during testing (4) Fix #ifs on SQLITE_EXTRA_DURABLE so that directory syncs on journal unlink are off by default. check-in: e3157cb5 user: drh tags: trunk
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Changes to ext/misc/json1.c.

   272    272   ** string.
   273    273   */
   274    274   static void jsonAppendString(JsonString *p, const char *zIn, u32 N){
   275    275     u32 i;
   276    276     if( (N+p->nUsed+2 >= p->nAlloc) && jsonGrow(p,N+2)!=0 ) return;
   277    277     p->zBuf[p->nUsed++] = '"';
   278    278     for(i=0; i<N; i++){
   279         -    char c = zIn[i];
          279  +    unsigned char c = ((unsigned const char*)zIn)[i];
   280    280       if( c=='"' || c=='\\' ){
          281  +      json_simple_escape:
   281    282         if( (p->nUsed+N+3-i > p->nAlloc) && jsonGrow(p,N+3-i)!=0 ) return;
   282    283         p->zBuf[p->nUsed++] = '\\';
          284  +    }else if( c<=0x1f ){
          285  +      static const char aSpecial[] = {
          286  +         0, 0, 0, 0, 0, 0, 0, 0, 'b', 't', 'n', 0, 'f', 'r', 0, 0,
          287  +         0, 0, 0, 0, 0, 0, 0, 0,   0,   0,   0, 0,   0,   0, 0, 0
          288  +      };
          289  +      assert( sizeof(aSpecial)==32 );
          290  +      assert( aSpecial['\b']=='b' );
          291  +      assert( aSpecial['\f']=='f' );
          292  +      assert( aSpecial['\n']=='n' );
          293  +      assert( aSpecial['\r']=='r' );
          294  +      assert( aSpecial['\t']=='t' );
          295  +      if( aSpecial[c] ){
          296  +        c = aSpecial[c];
          297  +        goto json_simple_escape;
          298  +      }
          299  +      if( (p->nUsed+N+7+i > p->nAlloc) && jsonGrow(p,N+7-i)!=0 ) return;
          300  +      p->zBuf[p->nUsed++] = '\\';
          301  +      p->zBuf[p->nUsed++] = 'u';
          302  +      p->zBuf[p->nUsed++] = '0';
          303  +      p->zBuf[p->nUsed++] = '0';
          304  +      p->zBuf[p->nUsed++] = '0' + (c>>4);
          305  +      c = "0123456789abcdef"[c&0xf];
   283    306       }
   284    307       p->zBuf[p->nUsed++] = c;
   285    308     }
   286    309     p->zBuf[p->nUsed++] = '"';
   287    310     assert( p->nUsed<p->nAlloc );
   288    311   }
   289    312   

Changes to test/json101.test.

   337    337     7.7  0  char(0x20,0x09,0x0a,0x0c,0x0d,0x20)
   338    338   } {
   339    339     do_execsql_test json-$tn.1 \
   340    340       "SELECT json_valid(printf('%s{%s\"x\"%s:%s9%s}%s',
   341    341            $::ws,$::ws,$::ws,$::ws,$::ws,$::ws));" \
   342    342     $isvalid
   343    343   }
          344  +
          345  +# Ticket https://www.sqlite.org/src/info/ad2559db380abf8e
          346  +# Control characters must be escaped in JSON strings.
          347  +#
          348  +do_execsql_test json-8.1 {
          349  +  DROP TABLE IF EXISTS t8;
          350  +  CREATE TABLE t8(a,b);
          351  +  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');
          352  +  UPDATE t8 SET b=json_array(a);
          353  +  SELECT b FROM t8;
          354  +} {{["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"]}}
          355  +do_execsql_test json-8.2 {
          356  +  SELECT a=json_extract(b,'$[0]') FROM t8;
          357  +} {1}
          358  +
   344    359   
   345    360   finish_test