/ 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 Unified Diffs Show Whitespace Changes Patch

Changes to src/test1.c.

9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
....
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
....
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607



1608
1609
1610
1611
1612
1613
1614
**    May you share freely, never taking more than you give.
**
*************************************************************************
** Code for testing all sorts of SQLite interfaces.  This code
** is not included in the SQLite library.  It is used for automated
** testing of the SQLite library.
**
** $Id: test1.c,v 1.325 2008/09/11 10:29:16 danielk1977 Exp $
*/
#include "sqliteInt.h"
#include "tcl.h"
#include <stdlib.h>
#include <string.h>

/*
................................................................................
  }
  Tcl_Free((char *)zBuf);

  return (rc==SQLITE_OK ? TCL_OK : TCL_ERROR);
}

/*
** sqlite3_blob_write CHANNEL OFFSET DATA
**
**   This command is used to test the sqlite3_blob_write() in ways that
**   the Tcl channel interface does not. The first argument should
**   be the name of a valid channel created by the [incrblob] method
**   of a database handle. This function calls sqlite3_blob_write()
**   to write the DATA byte-array to the underlying SQLite blob handle.
**   at offset OFFSET.
................................................................................
  int notUsed;
  int iOffset;
  int rc;

  unsigned char *zBuf;
  int nBuf;
  
  if( objc!=4 ){
    Tcl_WrongNumArgs(interp, 1, objv, "CHANNEL OFFSET DATA");
    return TCL_ERROR;
  }

  channel = Tcl_GetChannel(interp, Tcl_GetString(objv[1]), &notUsed);
  if( !channel
   || TCL_OK!=Tcl_GetIntFromObj(interp, objv[2], &iOffset)
   || iOffset<0
  ){ 
    return TCL_ERROR;
  }

  instanceData = Tcl_GetChannelInstanceData(channel);
  pBlob = *((sqlite3_blob **)instanceData);

  zBuf = Tcl_GetByteArrayFromObj(objv[3], &nBuf);



  rc = sqlite3_blob_write(pBlob, zBuf, nBuf, iOffset);
  if( rc!=SQLITE_OK ){
    Tcl_SetResult(interp, (char *)sqlite3TestErrorName(rc), TCL_VOLATILE);
  }

  return (rc==SQLITE_OK ? TCL_OK : TCL_ERROR);
}







|







 







|







 







|
|




<
|
<
<







>
>
>







9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
....
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
....
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596

1597


1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
**    May you share freely, never taking more than you give.
**
*************************************************************************
** Code for testing all sorts of SQLite interfaces.  This code
** is not included in the SQLite library.  It is used for automated
** testing of the SQLite library.
**
** $Id: test1.c,v 1.326 2008/10/02 14:49:02 danielk1977 Exp $
*/
#include "sqliteInt.h"
#include "tcl.h"
#include <stdlib.h>
#include <string.h>

/*
................................................................................
  }
  Tcl_Free((char *)zBuf);

  return (rc==SQLITE_OK ? TCL_OK : TCL_ERROR);
}

/*
** sqlite3_blob_write CHANNEL OFFSET DATA ?NDATA?
**
**   This command is used to test the sqlite3_blob_write() in ways that
**   the Tcl channel interface does not. The first argument should
**   be the name of a valid channel created by the [incrblob] method
**   of a database handle. This function calls sqlite3_blob_write()
**   to write the DATA byte-array to the underlying SQLite blob handle.
**   at offset OFFSET.
................................................................................
  int notUsed;
  int iOffset;
  int rc;

  unsigned char *zBuf;
  int nBuf;
  
  if( objc!=4 && objc!=5 ){
    Tcl_WrongNumArgs(interp, 1, objv, "CHANNEL OFFSET DATA ?NDATA?");
    return TCL_ERROR;
  }

  channel = Tcl_GetChannel(interp, Tcl_GetString(objv[1]), &notUsed);

  if( !channel || TCL_OK!=Tcl_GetIntFromObj(interp, objv[2], &iOffset) ){ 


    return TCL_ERROR;
  }

  instanceData = Tcl_GetChannelInstanceData(channel);
  pBlob = *((sqlite3_blob **)instanceData);

  zBuf = Tcl_GetByteArrayFromObj(objv[3], &nBuf);
  if( objc==5 && Tcl_GetIntFromObj(interp, objv[4], &nBuf) ){
    return TCL_ERROR;
  }
  rc = sqlite3_blob_write(pBlob, zBuf, nBuf, iOffset);
  if( rc!=SQLITE_OK ){
    Tcl_SetResult(interp, (char *)sqlite3TestErrorName(rc), TCL_VOLATILE);
  }

  return (rc==SQLITE_OK ? TCL_OK : TCL_ERROR);
}

Changes to src/vdbeblob.c.

8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
...
283
284
285
286
287
288
289
290
291
292
293
294

295





296
297
298
299
300
301
302
303
304
305
306
307
**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
*************************************************************************
**
** This file contains code used to implement incremental BLOB I/O.
**
** $Id: vdbeblob.c,v 1.25 2008/07/28 19:34:54 drh Exp $
*/

#include "sqliteInt.h"
#include "vdbeInt.h"

#ifndef SQLITE_OMIT_INCRBLOB

................................................................................
  int (*xCall)(BtCursor*, u32, u32, void*)
){
  int rc;
  Incrblob *p = (Incrblob *)pBlob;
  Vdbe *v;
  sqlite3 *db = p->db;  

  /* Request is out of range. Return a transient error. */
  if( (iOffset+n)>p->nByte ){
    return SQLITE_ERROR;
  }
  sqlite3_mutex_enter(db->mutex);







  /* If there is no statement handle, then the blob-handle has
  ** already been invalidated. Return SQLITE_ABORT in this case.
  */
  v = (Vdbe*)p->pStmt;
  if( v==0 ){
    rc = SQLITE_ABORT;
  }else{
    /* Call either BtreeData() or BtreePutData(). If SQLITE_ABORT is
    ** returned, clean-up the statement handle.
    */
    assert( db == v->db );
    sqlite3BtreeEnterCursor(p->pCsr);







|







 







<
<
<
<

>

>
>
>
>
>



<
<







8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
...
283
284
285
286
287
288
289




290
291
292
293
294
295
296
297
298
299
300


301
302
303
304
305
306
307
**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
*************************************************************************
**
** This file contains code used to implement incremental BLOB I/O.
**
** $Id: vdbeblob.c,v 1.26 2008/10/02 14:49:02 danielk1977 Exp $
*/

#include "sqliteInt.h"
#include "vdbeInt.h"

#ifndef SQLITE_OMIT_INCRBLOB

................................................................................
  int (*xCall)(BtCursor*, u32, u32, void*)
){
  int rc;
  Incrblob *p = (Incrblob *)pBlob;
  Vdbe *v;
  sqlite3 *db = p->db;  





  sqlite3_mutex_enter(db->mutex);
  v = (Vdbe*)p->pStmt;

  if( n<0 || iOffset<0 || (iOffset+n)>p->nByte ){
    /* Request is out of range. Return a transient error. */
    rc = SQLITE_ERROR;
    sqlite3Error(db, SQLITE_ERROR, 0);
  } else if( v==0 ){
    /* If there is no statement handle, then the blob-handle has
    ** already been invalidated. Return SQLITE_ABORT in this case.
    */


    rc = SQLITE_ABORT;
  }else{
    /* Call either BtreeData() or BtreePutData(). If SQLITE_ABORT is
    ** returned, clean-up the statement handle.
    */
    assert( db == v->db );
    sqlite3BtreeEnterCursor(p->pCsr);

Changes to test/incrblob.test.

5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
...
613
614
615
616
617
618
619
620
































621
#
#    May you do good and not evil.
#    May you find forgiveness for yourself and forgive others.
#    May you share freely, never taking more than you give.
#
#***********************************************************************
#
# $Id: incrblob.test,v 1.21 2008/09/11 11:28:00 danielk1977 Exp $
#

set testdir [file dirname $argv0]
source $testdir/tester.tcl

ifcapable {!autovacuum || !pragma || !incrblob} {
  finish_test
................................................................................
} {1 SQLITE_READONLY}
do_test incrblob-7.5 {
  sqlite3_errcode db
} {SQLITE_READONLY}
do_test incrblob-7.6 {
  sqlite3_errmsg db
} {attempt to write a readonly database}

































finish_test







|







 








>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>

5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
...
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
#
#    May you do good and not evil.
#    May you find forgiveness for yourself and forgive others.
#    May you share freely, never taking more than you give.
#
#***********************************************************************
#
# $Id: incrblob.test,v 1.22 2008/10/02 14:49:02 danielk1977 Exp $
#

set testdir [file dirname $argv0]
source $testdir/tester.tcl

ifcapable {!autovacuum || !pragma || !incrblob} {
  finish_test
................................................................................
} {1 SQLITE_READONLY}
do_test incrblob-7.5 {
  sqlite3_errcode db
} {SQLITE_READONLY}
do_test incrblob-7.6 {
  sqlite3_errmsg db
} {attempt to write a readonly database}

# Test that if either the "offset" or "amount" arguments to
# sqlite3_blob_write() are less than zero, SQLITE_ERROR is returned.
# 
do_test incrblob-8.1 {
  execsql { INSERT INTO t1 VALUES(314159, 'sqlite') }
  set ::b [db incrblob t1 b 314159]
  fconfigure $::b -translation binary
  set rc [catch {sqlite3_blob_write $::b 10 HELLO -1} msg]
  lappend rc $msg
} {1 SQLITE_ERROR}
do_test incrblob-8.2 {
  sqlite3_errcode db
} {SQLITE_ERROR}
do_test incrblob-8.3 {
  set rc [catch {sqlite3_blob_write $::b -1 HELLO 5} msg]
  lappend rc $msg
} {1 SQLITE_ERROR}
do_test incrblob-8.4 {
  sqlite3_errcode db
} {SQLITE_ERROR}
do_test incrblob-8.5 {
  execsql {SELECT b FROM t1 WHERE a = 314159}
} {sqlite}
do_test incrblob-8.6 {
  set rc [catch {sqlite3_blob_write $::b 0 etilqs 6} msg]
  lappend rc $msg
} {0 {}}
do_test incrblob-8.7 {
  execsql {SELECT b FROM t1 WHERE a = 314159}
} {etilqs}


finish_test