/ Check-in [92fc146b]
Login

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

Overview
Comment:Fix a buffer overwrite in fts5 that could occur when processing a prefix query.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA3-256: 92fc146bc2b781e7e2d7138b00e5ea649c6fee1c2b8449420460a1b3e5c9661b
User & Date: dan 2017-12-11 17:20:37
Context
2017-12-13
10:11
Minor enhancement to two assert() statements in the default VFSes. check-in: 9cede8a8 user: drh tags: trunk
2017-12-11
17:20
Fix a buffer overwrite in fts5 that could occur when processing a prefix query. check-in: 92fc146b user: dan tags: trunk
2017-12-09
01:02
Fix a harmless API signature mismatch in the unix VFS. check-in: bab9de7f user: drh tags: trunk
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Changes to ext/fts5/fts5_index.c.

  4905   4905     if( p2->n ){
  4906   4906       i64 iLastRowid = 0;
  4907   4907       Fts5DoclistIter i1;
  4908   4908       Fts5DoclistIter i2;
  4909   4909       Fts5Buffer out = {0, 0, 0};
  4910   4910       Fts5Buffer tmp = {0, 0, 0};
  4911   4911   
  4912         -    if( sqlite3Fts5BufferSize(&p->rc, &out, p1->n + p2->n) ) return;
         4912  +    /* The maximum size of the output is equal to the sum of the two 
         4913  +    ** input sizes + 1 varint (9 bytes). The extra varint is because if the
         4914  +    ** first rowid in one input is a large negative number, and the first in
         4915  +    ** the other a non-negative number, the delta for the non-negative
         4916  +    ** number will be larger on disk than the literal integer value
         4917  +    ** was.  */
         4918  +    if( sqlite3Fts5BufferSize(&p->rc, &out, p1->n + p2->n + 9) ) return;
  4913   4919       fts5DoclistIterInit(p1, &i1);
  4914   4920       fts5DoclistIterInit(p2, &i2);
  4915   4921   
  4916   4922       while( 1 ){
  4917   4923         if( i1.iRowid<i2.iRowid ){
  4918   4924           /* Copy entry from i1 */
  4919   4925           fts5MergeAppendDocid(&out, iLastRowid, i1.iRowid);
................................................................................
  4999   5005         fts5MergeAppendDocid(&out, iLastRowid, i1.iRowid);
  5000   5006         fts5BufferSafeAppendBlob(&out, i1.aPoslist, i1.aEof - i1.aPoslist);
  5001   5007       }
  5002   5008       else if( i2.aPoslist ){
  5003   5009         fts5MergeAppendDocid(&out, iLastRowid, i2.iRowid);
  5004   5010         fts5BufferSafeAppendBlob(&out, i2.aPoslist, i2.aEof - i2.aPoslist);
  5005   5011       }
         5012  +    assert( out.n<=(p1->n+p2->n+9) );
  5006   5013   
  5007   5014       fts5BufferSet(&p->rc, p1, out.n, out.p);
  5008   5015       fts5BufferFree(&tmp);
  5009   5016       fts5BufferFree(&out);
  5010   5017     }
  5011   5018   }
  5012   5019   

Changes to ext/fts5/test/fts5query.test.

    60     60       foreach x [list bbb ddd fff hhh jjj lll nnn ppp rrr ttt] {
    61     61         set doc [string repeat "$x " 30]
    62     62         execsql { INSERT INTO t1 VALUES($doc) }
    63     63       }
    64     64       execsql COMMIT
    65     65     } {}
    66     66   
    67         -  do_execsql_test 1.$tn.2 {
           67  +  do_execsql_test 2.$tn.2 {
    68     68       INSERT INTO t1(t1) VALUES('integrity-check');
    69     69     }
    70     70   
    71     71     set ret 1
    72     72     foreach x [list a c e g i k m o q s u] {
    73     73       do_execsql_test 2.$tn.3.$ret {
    74     74         SELECT rowid FROM t1 WHERE t1 MATCH $x || '*';
    75     75       } {}
    76     76       incr ret
    77     77     }
    78     78   }
    79     79   
           80  +reset_db
           81  +do_execsql_test 3.0 {
           82  +  CREATE VIRTUAL TABLE x1 USING fts5(a);
           83  +  INSERT INTO x1(rowid, a) VALUES(-1000000000000, 'toyota');
           84  +  INSERT INTO x1(rowid, a) VALUES(1, 'tarago');
           85  +}
           86  +do_execsql_test 3.1 {
           87  +  SELECT rowid FROM x1('t*');
           88  +} {-1000000000000 1}
           89  +
    80     90   
    81     91   finish_test