/ Check-in [f6074c0b]
Login

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

Overview
Comment:Fix for sqlite3_blob_write(): If either 3rd or 4th argument is less than zero, return SQLITE_ERROR. H17879. (CVS 5762)
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: f6074c0b9b5ba51d131509dba2aec80d0fcf3b7e
User & Date: danielk1977 2008-10-02 14:49:02
Context
2008-10-02
16:42
Change to reduce the number of OP_Null opcodes in "WHERE <rowid> IN (x,y,z)" queries. (CVS 5763) check-in: 33b59a3d user: danielk1977 tags: trunk
14:49
Fix for sqlite3_blob_write(): If either 3rd or 4th argument is less than zero, return SQLITE_ERROR. H17879. (CVS 5762) check-in: f6074c0b user: danielk1977 tags: trunk
14:33
Fix a typo that prevents the sqlite3_sql() interface from appearing in the official documentation. (CVS 5761) check-in: b46814b2 user: drh tags: trunk
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Changes to src/test1.c.

     9      9   **    May you share freely, never taking more than you give.
    10     10   **
    11     11   *************************************************************************
    12     12   ** Code for testing all sorts of SQLite interfaces.  This code
    13     13   ** is not included in the SQLite library.  It is used for automated
    14     14   ** testing of the SQLite library.
    15     15   **
    16         -** $Id: test1.c,v 1.325 2008/09/11 10:29:16 danielk1977 Exp $
           16  +** $Id: test1.c,v 1.326 2008/10/02 14:49:02 danielk1977 Exp $
    17     17   */
    18     18   #include "sqliteInt.h"
    19     19   #include "tcl.h"
    20     20   #include <stdlib.h>
    21     21   #include <string.h>
    22     22   
    23     23   /*
................................................................................
  1555   1555     }
  1556   1556     Tcl_Free((char *)zBuf);
  1557   1557   
  1558   1558     return (rc==SQLITE_OK ? TCL_OK : TCL_ERROR);
  1559   1559   }
  1560   1560   
  1561   1561   /*
  1562         -** sqlite3_blob_write CHANNEL OFFSET DATA
         1562  +** sqlite3_blob_write CHANNEL OFFSET DATA ?NDATA?
  1563   1563   **
  1564   1564   **   This command is used to test the sqlite3_blob_write() in ways that
  1565   1565   **   the Tcl channel interface does not. The first argument should
  1566   1566   **   be the name of a valid channel created by the [incrblob] method
  1567   1567   **   of a database handle. This function calls sqlite3_blob_write()
  1568   1568   **   to write the DATA byte-array to the underlying SQLite blob handle.
  1569   1569   **   at offset OFFSET.
................................................................................
  1584   1584     int notUsed;
  1585   1585     int iOffset;
  1586   1586     int rc;
  1587   1587   
  1588   1588     unsigned char *zBuf;
  1589   1589     int nBuf;
  1590   1590     
  1591         -  if( objc!=4 ){
  1592         -    Tcl_WrongNumArgs(interp, 1, objv, "CHANNEL OFFSET DATA");
         1591  +  if( objc!=4 && objc!=5 ){
         1592  +    Tcl_WrongNumArgs(interp, 1, objv, "CHANNEL OFFSET DATA ?NDATA?");
  1593   1593       return TCL_ERROR;
  1594   1594     }
  1595   1595   
  1596   1596     channel = Tcl_GetChannel(interp, Tcl_GetString(objv[1]), &notUsed);
  1597         -  if( !channel
  1598         -   || TCL_OK!=Tcl_GetIntFromObj(interp, objv[2], &iOffset)
  1599         -   || iOffset<0
  1600         -  ){ 
         1597  +  if( !channel || TCL_OK!=Tcl_GetIntFromObj(interp, objv[2], &iOffset) ){ 
  1601   1598       return TCL_ERROR;
  1602   1599     }
  1603   1600   
  1604   1601     instanceData = Tcl_GetChannelInstanceData(channel);
  1605   1602     pBlob = *((sqlite3_blob **)instanceData);
  1606   1603   
  1607   1604     zBuf = Tcl_GetByteArrayFromObj(objv[3], &nBuf);
         1605  +  if( objc==5 && Tcl_GetIntFromObj(interp, objv[4], &nBuf) ){
         1606  +    return TCL_ERROR;
         1607  +  }
  1608   1608     rc = sqlite3_blob_write(pBlob, zBuf, nBuf, iOffset);
  1609   1609     if( rc!=SQLITE_OK ){
  1610   1610       Tcl_SetResult(interp, (char *)sqlite3TestErrorName(rc), TCL_VOLATILE);
  1611   1611     }
  1612   1612   
  1613   1613     return (rc==SQLITE_OK ? TCL_OK : TCL_ERROR);
  1614   1614   }

Changes to src/vdbeblob.c.

     8      8   **    May you find forgiveness for yourself and forgive others.
     9      9   **    May you share freely, never taking more than you give.
    10     10   **
    11     11   *************************************************************************
    12     12   **
    13     13   ** This file contains code used to implement incremental BLOB I/O.
    14     14   **
    15         -** $Id: vdbeblob.c,v 1.25 2008/07/28 19:34:54 drh Exp $
           15  +** $Id: vdbeblob.c,v 1.26 2008/10/02 14:49:02 danielk1977 Exp $
    16     16   */
    17     17   
    18     18   #include "sqliteInt.h"
    19     19   #include "vdbeInt.h"
    20     20   
    21     21   #ifndef SQLITE_OMIT_INCRBLOB
    22     22   
................................................................................
   283    283     int (*xCall)(BtCursor*, u32, u32, void*)
   284    284   ){
   285    285     int rc;
   286    286     Incrblob *p = (Incrblob *)pBlob;
   287    287     Vdbe *v;
   288    288     sqlite3 *db = p->db;  
   289    289   
   290         -  /* Request is out of range. Return a transient error. */
   291         -  if( (iOffset+n)>p->nByte ){
   292         -    return SQLITE_ERROR;
   293         -  }
   294    290     sqlite3_mutex_enter(db->mutex);
          291  +  v = (Vdbe*)p->pStmt;
   295    292   
   296         -  /* If there is no statement handle, then the blob-handle has
   297         -  ** already been invalidated. Return SQLITE_ABORT in this case.
   298         -  */
   299         -  v = (Vdbe*)p->pStmt;
   300         -  if( v==0 ){
          293  +  if( n<0 || iOffset<0 || (iOffset+n)>p->nByte ){
          294  +    /* Request is out of range. Return a transient error. */
          295  +    rc = SQLITE_ERROR;
          296  +    sqlite3Error(db, SQLITE_ERROR, 0);
          297  +  } else if( v==0 ){
          298  +    /* If there is no statement handle, then the blob-handle has
          299  +    ** already been invalidated. Return SQLITE_ABORT in this case.
          300  +    */
   301    301       rc = SQLITE_ABORT;
   302    302     }else{
   303    303       /* Call either BtreeData() or BtreePutData(). If SQLITE_ABORT is
   304    304       ** returned, clean-up the statement handle.
   305    305       */
   306    306       assert( db == v->db );
   307    307       sqlite3BtreeEnterCursor(p->pCsr);

Changes to test/incrblob.test.

     5      5   #
     6      6   #    May you do good and not evil.
     7      7   #    May you find forgiveness for yourself and forgive others.
     8      8   #    May you share freely, never taking more than you give.
     9      9   #
    10     10   #***********************************************************************
    11     11   #
    12         -# $Id: incrblob.test,v 1.21 2008/09/11 11:28:00 danielk1977 Exp $
           12  +# $Id: incrblob.test,v 1.22 2008/10/02 14:49:02 danielk1977 Exp $
    13     13   #
    14     14   
    15     15   set testdir [file dirname $argv0]
    16     16   source $testdir/tester.tcl
    17     17   
    18     18   ifcapable {!autovacuum || !pragma || !incrblob} {
    19     19     finish_test
................................................................................
   613    613   } {1 SQLITE_READONLY}
   614    614   do_test incrblob-7.5 {
   615    615     sqlite3_errcode db
   616    616   } {SQLITE_READONLY}
   617    617   do_test incrblob-7.6 {
   618    618     sqlite3_errmsg db
   619    619   } {attempt to write a readonly database}
          620  +
          621  +# Test that if either the "offset" or "amount" arguments to
          622  +# sqlite3_blob_write() are less than zero, SQLITE_ERROR is returned.
          623  +# 
          624  +do_test incrblob-8.1 {
          625  +  execsql { INSERT INTO t1 VALUES(314159, 'sqlite') }
          626  +  set ::b [db incrblob t1 b 314159]
          627  +  fconfigure $::b -translation binary
          628  +  set rc [catch {sqlite3_blob_write $::b 10 HELLO -1} msg]
          629  +  lappend rc $msg
          630  +} {1 SQLITE_ERROR}
          631  +do_test incrblob-8.2 {
          632  +  sqlite3_errcode db
          633  +} {SQLITE_ERROR}
          634  +do_test incrblob-8.3 {
          635  +  set rc [catch {sqlite3_blob_write $::b -1 HELLO 5} msg]
          636  +  lappend rc $msg
          637  +} {1 SQLITE_ERROR}
          638  +do_test incrblob-8.4 {
          639  +  sqlite3_errcode db
          640  +} {SQLITE_ERROR}
          641  +do_test incrblob-8.5 {
          642  +  execsql {SELECT b FROM t1 WHERE a = 314159}
          643  +} {sqlite}
          644  +do_test incrblob-8.6 {
          645  +  set rc [catch {sqlite3_blob_write $::b 0 etilqs 6} msg]
          646  +  lappend rc $msg
          647  +} {0 {}}
          648  +do_test incrblob-8.7 {
          649  +  execsql {SELECT b FROM t1 WHERE a = 314159}
          650  +} {etilqs}
          651  +
   620    652   
   621    653   finish_test