/ Check-in [40e29a47]
Login

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

Overview
Comment:Add extra tests for the handling of corrupt records in fts3.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA3-256: 40e29a47d1266c16a4992e43579a51addcc632503099c4cd128f77dd4e67da3c
User & Date: dan 2019-09-18 17:22:00
Context
2019-09-18
20:34
Always clear the temporary register cache after coding a subroutine. check-in: b6f2a7f9 user: drh tags: trunk
17:22
Add extra tests for the handling of corrupt records in fts3. check-in: 40e29a47 user: dan tags: trunk
12:49
Fix another potential "jump depends on uninitialized value" warning. check-in: 633b214e user: drh tags: trunk
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Changes to ext/fts3/fts3.c.

  2576   2576         fts3PoslistCopy(&p, &p1);
  2577   2577         fts3GetDeltaVarint3(&p1, pEnd1, bDescDoclist, &i1);
  2578   2578       }else{
  2579   2579         fts3PutDeltaVarint3(&p, bDescDoclist, &iPrev, &bFirstOut, i2);
  2580   2580         fts3PoslistCopy(&p, &p2);
  2581   2581         fts3GetDeltaVarint3(&p2, pEnd2, bDescDoclist, &i2);
  2582   2582       }
         2583  +    
         2584  +    assert( (p-aOut)<=((p1?(p1-a1):n1)+(p2?(p2-a2):n2)+FTS3_VARINT_MAX-1) );
  2583   2585     }
  2584   2586   
  2585   2587     if( rc!=SQLITE_OK ){
  2586   2588       sqlite3_free(aOut);
  2587   2589       p = aOut = 0;
  2588   2590     }else{
  2589   2591       assert( (p-aOut)<=n1+n2+FTS3_VARINT_MAX-1 );

Changes to src/test_hexio.c.

   333    333       y <<= 7;
   334    334     }
   335    335     x += y * (*q++);
   336    336     *v = (sqlite_int64) x;
   337    337     return (int) (q - (unsigned char *)p);
   338    338   }
   339    339   
          340  +static int putFts3Varint(char *p, sqlite_int64 v){
          341  +  unsigned char *q = (unsigned char *) p;
          342  +  sqlite_uint64 vu = v;
          343  +  do{
          344  +    *q++ = (unsigned char) ((vu & 0x7f) | 0x80);
          345  +    vu >>= 7;
          346  +  }while( vu!=0 );
          347  +  q[-1] &= 0x7f;  /* turn off high bit in final byte */
          348  +  assert( q - (unsigned char *)p <= 10 );
          349  +  return (int) (q - (unsigned char *)p);
          350  +}
   340    351   
   341    352   /*
   342    353   ** USAGE:  read_fts3varint BLOB VARNAME
   343    354   **
   344    355   ** Read a varint from the start of BLOB. Set variable VARNAME to contain
   345    356   ** the interpreted value. Return the number of bytes of BLOB consumed.
   346    357   */
................................................................................
   363    374   
   364    375     nVal = getFts3Varint((char*)zBlob, (sqlite3_int64 *)(&iVal));
   365    376     Tcl_ObjSetVar2(interp, objv[2], 0, Tcl_NewWideIntObj(iVal), 0);
   366    377     Tcl_SetObjResult(interp, Tcl_NewIntObj(nVal));
   367    378     return TCL_OK;
   368    379   }
   369    380   
          381  +/*
          382  +** USAGE:  make_fts3record ARGLIST
          383  +*/
          384  +static int SQLITE_TCLAPI make_fts3record(
          385  +  void * clientData,
          386  +  Tcl_Interp *interp,
          387  +  int objc,
          388  +  Tcl_Obj *CONST objv[]
          389  +){
          390  +  Tcl_Obj **aArg = 0;
          391  +  int nArg = 0;
          392  +  unsigned char *aOut = 0;
          393  +  int nOut = 0;
          394  +  int nAlloc = 0;
          395  +  int i;
          396  +  int rc = TCL_OK;
          397  +
          398  +  if( objc!=2 ){
          399  +    Tcl_WrongNumArgs(interp, 1, objv, "LIST");
          400  +    return TCL_ERROR;
          401  +  }
          402  +  if( Tcl_ListObjGetElements(interp, objv[1], &nArg, &aArg) ){
          403  +    return TCL_ERROR;
          404  +  }
          405  +
          406  +  for(i=0; i<nArg; i++){
          407  +    sqlite3_int64 iVal;
          408  +    if( TCL_OK==Tcl_GetWideIntFromObj(0, aArg[i], &iVal) ){
          409  +      if( nOut+10>nAlloc ){
          410  +        int nNew = nAlloc?nAlloc*2:128;
          411  +        unsigned char *aNew = sqlite3_realloc(aOut, nNew);
          412  +        if( aNew==0 ){
          413  +          sqlite3_free(aOut);
          414  +          return TCL_ERROR;
          415  +        }
          416  +        aOut = aNew;
          417  +        nAlloc = nNew;
          418  +      }
          419  +      nOut += putFts3Varint((char*)&aOut[nOut], iVal);
          420  +    }else{
          421  +      int nVal = 0;
          422  +      char *zVal = Tcl_GetStringFromObj(aArg[i], &nVal);
          423  +      while( (nOut + nVal)>nAlloc ){
          424  +        int nNew = nAlloc?nAlloc*2:128;
          425  +        unsigned char *aNew = sqlite3_realloc(aOut, nNew);
          426  +        if( aNew==0 ){
          427  +          sqlite3_free(aOut);
          428  +          return TCL_ERROR;
          429  +        }
          430  +        aOut = aNew;
          431  +        nAlloc = nNew;
          432  +      }
          433  +      memcpy(&aOut[nOut], zVal, nVal);
          434  +      nOut += nVal;
          435  +    }
          436  +  }
          437  +
          438  +  Tcl_SetObjResult(interp, Tcl_NewByteArrayObj(aOut, nOut));
          439  +  sqlite3_free(aOut);
          440  +  return TCL_OK;
          441  +}
          442  +
   370    443   
   371    444   /*
   372    445   ** Register commands with the TCL interpreter.
   373    446   */
   374    447   int Sqlitetest_hexio_Init(Tcl_Interp *interp){
   375    448     static struct {
   376    449        char *zName;
................................................................................
   379    452        { "hexio_read",                   hexio_read            },
   380    453        { "hexio_write",                  hexio_write           },
   381    454        { "hexio_get_int",                hexio_get_int         },
   382    455        { "hexio_render_int16",           hexio_render_int16    },
   383    456        { "hexio_render_int32",           hexio_render_int32    },
   384    457        { "utf8_to_utf8",                 utf8_to_utf8          },
   385    458        { "read_fts3varint",              read_fts3varint       },
          459  +     { "make_fts3record",              make_fts3record       },
   386    460     };
   387    461     int i;
   388    462     for(i=0; i<sizeof(aObjCmd)/sizeof(aObjCmd[0]); i++){
   389    463       Tcl_CreateObjCommand(interp, aObjCmd[i].zName, aObjCmd[i].xProc, 0, 0);
   390    464     }
   391    465     return TCL_OK;
   392    466   }

Added test/fts4record.test.

            1  +# 2019 September 18
            2  +#
            3  +# The author disclaims copyright to this source code.  In place of
            4  +# a legal notice, here is a blessing:
            5  +#
            6  +#    May you do good and not evil.
            7  +#    May you find forgiveness for yourself and forgive others.
            8  +#    May you share freely, never taking more than you give.
            9  +#
           10  +#*************************************************************************
           11  +# This file implements regression tests for SQLite library.  The
           12  +# focus of this script is testing the FTS4 module.
           13  +#
           14  +#
           15  +
           16  +set testdir [file dirname $argv0]
           17  +source $testdir/tester.tcl
           18  +source $testdir/fts3_common.tcl
           19  +set testprefix fts4record
           20  +
           21  +# If SQLITE_ENABLE_FTS3 is defined, omit this file.
           22  +ifcapable !fts3 {
           23  +  finish_test
           24  +  return
           25  +}
           26  +
           27  +sqlite3_fts3_may_be_corrupt 1
           28  +
           29  +do_execsql_test 1.0 {
           30  +  CREATE VIRTUAL TABLE t1 USING fts4(x);
           31  +  INSERT INTO t1 VALUES('terma terma terma termb');
           32  +}
           33  +
           34  +do_execsql_test 1.1 {
           35  +  SELECT quote(root) FROM t1_segdir
           36  +} {
           37  +  X'00057465726D6105010203030004016203010500'
           38  +}
           39  +
           40  +proc make_record_wrapper {args} { make_fts3record $args }
           41  +db func record make_record_wrapper
           42  +
           43  +do_execsql_test 1.2 {
           44  +  select quote( 
           45  +    record(0,    5, 'terma', 5, 1, 2, 3, 3, 0, 
           46  +              4, 1, 'b'    , 3, 1, 5, 0
           47  +  ) );
           48  +} {
           49  +  X'00057465726D6105010203030004016203010500'
           50  +}
           51  +
           52  +do_execsql_test 1.3.1 {
           53  +  UPDATE t1_segdir SET root = 
           54  +    record(0,    5, 'terma', 5, 1, 2, 3, 3, 0, 
           55  +              4, 1, 'b'    , 3, 1, 5, 
           56  +              1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
           57  +              1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
           58  +              1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0
           59  +          );
           60  +}
           61  +
           62  +do_catchsql_test 1.3.2 {
           63  +  SELECT snippet(t1) FROM t1 WHERE t1 MATCH 'term*'
           64  +} {1 {database disk image is malformed}}
           65  +
           66  +do_execsql_test 1.4.1 {
           67  +  UPDATE t1_segdir SET root = 
           68  +    record(0,    5, 'terma', 5, 1, 2, 3, 3, 0, 
           69  +              4, 1, 'b'    , 4, 1, 5, 
           70  +              256, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
           71  +              1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
           72  +              1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0
           73  +          );
           74  +}
           75  +
           76  +do_catchsql_test 1.4.2 {
           77  +  SELECT snippet(t1) FROM t1 WHERE t1 MATCH 'term*'
           78  +} {1 {database disk image is malformed}}
           79  +
           80  +do_execsql_test 1.4.3 {
           81  +  SELECT quote(root) FROM t1_segdir
           82  +} {
           83  +  X'00057465726D610501020303000401620401058002010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010100'
           84  +}
           85  +
           86  +do_execsql_test 1.5.1 {
           87  +  UPDATE t1_segdir SET root = 
           88  +    record(0,    5, 'terma', 5, 1, 2, 3, 3, 0, 
           89  +              4, 1, 'b'    , 4, 1, 5, 
           90  +              256, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
           91  +              1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
           92  +              1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0
           93  +          );
           94  +}
           95  +
           96  +do_catchsql_test 1.4.2 {
           97  +  SELECT snippet(t1) FROM t1 WHERE t1 MATCH 'term*'
           98  +} {1 {database disk image is malformed}}
           99  +
          100  +do_execsql_test 1.4.3 {
          101  +  SELECT quote(root) FROM t1_segdir
          102  +} {
          103  +  X'00057465726D610501020303000401620401058002010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010100'
          104  +}
          105  +
          106  +
          107  +do_execsql_test 1.5.1 {
          108  +  UPDATE t1_segdir SET root = 
          109  +  X'00057465726D61050102030300040162040105FF00010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010100'
          110  +}
          111  +
          112  +do_catchsql_test 1.5.2 {
          113  +  SELECT snippet(t1) FROM t1 WHERE t1 MATCH 'term*'
          114  +} {1 {database disk image is malformed}}
          115  +
          116  +do_catchsql_test 1.5.3 {
          117  +  INSERT INTO t1(t1) VALUES('integrity-check');
          118  +} {1 {database disk image is malformed}}
          119  +
          120  +finish_test