SQLite

Check-in [a98dd004c4]
Login

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

Overview
Comment:Coverage improvements for malloc and vdbemem.c (CVS 1781)
Downloads: Tarball | ZIP archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: a98dd004c4d328eb44a71fecdbf8c5ab416dc524
User & Date: danielk1977 2004-06-30 11:54:07.000
Context
2004-06-30
12:42
Fix a memory allocation problem in os_test.c (CVS 1782) (check-in: ed511c2ea9 user: danielk1977 tags: trunk)
11:54
Coverage improvements for malloc and vdbemem.c (CVS 1781) (check-in: a98dd004c4 user: danielk1977 tags: trunk)
11:41
Add the crashtest target to Makefile.in. Add LL suffix to long long constants in the vdbe. Comment changes to vdbeaux.c. (CVS 1780) (check-in: 4255300195 user: drh tags: trunk)
Changes
Unified Diff Ignore Whitespace Patch
Changes to src/main.c.
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
**
*************************************************************************
** Main file for the SQLite library.  The routines in this file
** implement the programmer interface to the library.  Routines in
** other files are for internal use by SQLite and should not be
** accessed by users of the library.
**
** $Id: main.c,v 1.243 2004/06/30 09:49:24 danielk1977 Exp $
*/
#include "sqliteInt.h"
#include "os.h"
#include <ctype.h>

/*
** A pointer to this structure is used to communicate information







|







10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
**
*************************************************************************
** Main file for the SQLite library.  The routines in this file
** implement the programmer interface to the library.  Routines in
** other files are for internal use by SQLite and should not be
** accessed by users of the library.
**
** $Id: main.c,v 1.244 2004/06/30 11:54:07 danielk1977 Exp $
*/
#include "sqliteInt.h"
#include "os.h"
#include <ctype.h>

/*
** A pointer to this structure is used to communicate information
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
    rc = sqlite3_create_function(db, zFunctionName, nArg, SQLITE_UTF16LE,
        pUserData, xFunc, xStep, xFinal);
    if( rc!=SQLITE_OK ) return rc;
    enc = SQLITE_UTF16BE;
  }

  p = sqlite3FindFunction(db, zFunctionName, nName, nArg, enc, 1);
  if( p==0 ) return 1;
  p->xFunc = xFunc;
  p->xStep = xStep;
  p->xFinalize = xFinal;
  p->pUserData = pUserData;
  return SQLITE_OK;
}
int sqlite3_create_function16(







|







744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
    rc = sqlite3_create_function(db, zFunctionName, nArg, SQLITE_UTF16LE,
        pUserData, xFunc, xStep, xFinal);
    if( rc!=SQLITE_OK ) return rc;
    enc = SQLITE_UTF16BE;
  }

  p = sqlite3FindFunction(db, zFunctionName, nName, nArg, enc, 1);
  if( p==0 ) return SQLITE_NOMEM;
  p->xFunc = xFunc;
  p->xStep = xStep;
  p->xFinalize = xFinal;
  p->pUserData = pUserData;
  return SQLITE_OK;
}
int sqlite3_create_function16(
1176
1177
1178
1179
1180
1181
1182



1183
1184
1185
1186
1187
1188
1189
  }else{
    sqlite3Error(db, rc, "%s", zErrMsg, 0);
    if( zErrMsg ) sqliteFree(zErrMsg);
    db->magic = SQLITE_MAGIC_CLOSED;
  }

opendb_out:



  *ppDb = db;
  return sqlite3_errcode(db);
}

/*
** Open a new database handle.
*/







>
>
>







1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
  }else{
    sqlite3Error(db, rc, "%s", zErrMsg, 0);
    if( zErrMsg ) sqliteFree(zErrMsg);
    db->magic = SQLITE_MAGIC_CLOSED;
  }

opendb_out:
  if( sqlite3_errcode(db)==SQLITE_OK && sqlite3_malloc_failed ){
    sqlite3Error(db, SQLITE_NOMEM, 0);
  }
  *ppDb = db;
  return sqlite3_errcode(db);
}

/*
** Open a new database handle.
*/
Changes to src/pager.c.
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
** The pager is used to access a database disk file.  It implements
** atomic commit and rollback through the use of a journal file that
** is separate from the database file.  The pager also implements file
** locking to prevent two processes from writing the same database
** file simultaneously, or one process from reading the database while
** another is writing.
**
** @(#) $Id: pager.c,v 1.148 2004/06/30 09:49:24 danielk1977 Exp $
*/
#include "os.h"         /* Must be first to enable large file support */
#include "sqliteInt.h"
#include "pager.h"
#include <assert.h>
#include <string.h>








|







14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
** The pager is used to access a database disk file.  It implements
** atomic commit and rollback through the use of a journal file that
** is separate from the database file.  The pager also implements file
** locking to prevent two processes from writing the same database
** file simultaneously, or one process from reading the database while
** another is writing.
**
** @(#) $Id: pager.c,v 1.149 2004/06/30 11:54:07 danielk1977 Exp $
*/
#include "os.h"         /* Must be first to enable large file support */
#include "sqliteInt.h"
#include "pager.h"
#include <assert.h>
#include <string.h>

1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
static int sqlite3pager_opentemp(char *zFile, OsFile *fd){
  int cnt = 8;
  int rc;
  do{
    cnt--;
    sqlite3OsTempFileName(zFile);
    rc = sqlite3OsOpenExclusive(zFile, fd, 1);
  }while( cnt>0 && rc!=SQLITE_OK );
  return rc;
}

/*
** Create a new page cache and put a pointer to the page cache in *ppPager.
** The file to be cached need not exist.  The file is not locked until
** the first call to sqlite3pager_get() and is only held open until the







|







1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
static int sqlite3pager_opentemp(char *zFile, OsFile *fd){
  int cnt = 8;
  int rc;
  do{
    cnt--;
    sqlite3OsTempFileName(zFile);
    rc = sqlite3OsOpenExclusive(zFile, fd, 1);
  }while( cnt>0 && rc!=SQLITE_OK && rc!=SQLITE_NOMEM );
  return rc;
}

/*
** Create a new page cache and put a pointer to the page cache in *ppPager.
** The file to be cached need not exist.  The file is not locked until
** the first call to sqlite3pager_get() and is only held open until the
Changes to src/tclsqlite.c.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
/*
** 2001 September 15
**
** The author disclaims copyright to this source code.  In place of
** a legal notice, here is a blessing:
**
**    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.
**
*************************************************************************
** A TCL Interface to SQLite
**
** $Id: tclsqlite.c,v 1.93 2004/06/29 13:41:21 danielk1977 Exp $
*/
#ifndef NO_TCL     /* Omit this whole file if TCL is unavailable */

#include "sqliteInt.h"
#include "tcl.h"
#include <stdlib.h>
#include <string.h>













|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
/*
** 2001 September 15
**
** The author disclaims copyright to this source code.  In place of
** a legal notice, here is a blessing:
**
**    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.
**
*************************************************************************
** A TCL Interface to SQLite
**
** $Id: tclsqlite.c,v 1.94 2004/06/30 11:54:07 danielk1977 Exp $
*/
#ifndef NO_TCL     /* Omit this whole file if TCL is unavailable */

#include "sqliteInt.h"
#include "tcl.h"
#include <stdlib.h>
#include <string.h>
1077
1078
1079
1080
1081
1082
1083


1084

1085
1086
1087
1088
1089
1090
1091

  /* If compiled with SQLITE_TEST turned on, then register the "md5sum"
  ** SQL function.
  */
#ifdef SQLITE_TEST
  {
    extern void Md5_Register(sqlite*);


    Md5_Register(p->db);

   }
#endif  
  p->interp = interp;
  return TCL_OK;
}

/*







>
>

>







1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094

  /* If compiled with SQLITE_TEST turned on, then register the "md5sum"
  ** SQL function.
  */
#ifdef SQLITE_TEST
  {
    extern void Md5_Register(sqlite*);
    int mallocfail = sqlite3_iMallocFail;
    sqlite3_iMallocFail = 0;
    Md5_Register(p->db);
    sqlite3_iMallocFail = mallocfail;
   }
#endif  
  p->interp = interp;
  return TCL_OK;
}

/*
Changes to src/vdbeapi.c.
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
  if( p->flags & (MEM_Blob|MEM_Str) ){
    return p->z;
  }else{
    return sqlite3_value_text(pVal);
  }
}
int sqlite3_value_bytes(sqlite3_value *pVal){
  Mem *p = (Mem*)pVal;
  if( (p->flags & MEM_Blob)!=0 || sqlite3_value_text(pVal) ){
    return p->n;
  }
  return 0;
}
int sqlite3_value_bytes16(sqlite3_value *pVal){
  Mem *p = (Mem*)pVal;
  if( (p->flags & MEM_Blob)!=0 || sqlite3_value_text16(pVal) ){
    return ((Mem *)pVal)->n;
  }
  return 0;
}
double sqlite3_value_double(sqlite3_value *pVal){
  return sqlite3VdbeRealValue((Mem*)pVal);
}
int sqlite3_value_int(sqlite3_value *pVal){
  return sqlite3VdbeIntValue((Mem*)pVal);
}







<
<
<
<
|


<
<
<
<
|







25
26
27
28
29
30
31




32
33
34




35
36
37
38
39
40
41
42
  if( p->flags & (MEM_Blob|MEM_Str) ){
    return p->z;
  }else{
    return sqlite3_value_text(pVal);
  }
}
int sqlite3_value_bytes(sqlite3_value *pVal){




  return sqlite3ValueBytes(pVal, SQLITE_UTF8);
}
int sqlite3_value_bytes16(sqlite3_value *pVal){




  return sqlite3ValueBytes(pVal, SQLITE_UTF16NATIVE);
}
double sqlite3_value_double(sqlite3_value *pVal){
  return sqlite3VdbeRealValue((Mem*)pVal);
}
int sqlite3_value_int(sqlite3_value *pVal){
  return sqlite3VdbeIntValue((Mem*)pVal);
}
Changes to src/vdbemem.c.
100
101
102
103
104
105
106












107
108
109
110
111
112
113
114
115
116
117
118
119

120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151





152
153
154
155

156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
  return SQLITE_OK;
}

/*
** Make sure the given Mem is \u0000 terminated.
*/
int sqlite3VdbeMemNulTerminate(Mem *pMem){












  if( (pMem->flags & MEM_Term)!=0 || (pMem->flags & (MEM_Str|MEM_Blob))==0 ){
    return SQLITE_OK;   /* Nothing to do */
  }

  if( pMem->flags & (MEM_Static|MEM_Ephem) ){
    return sqlite3VdbeMemMakeWriteable(pMem);
  }else{
    if( pMem->flags & MEM_Dyn ){
      if( pMem->xDel ){
        char *z = sqliteMalloc(pMem->n+2);
        if( !z ) return SQLITE_NOMEM;
        memcpy(z, pMem->z, pMem->n);
        pMem->xDel(pMem->z);

        pMem->xDel = 0;
        pMem->z = z;
      }else{
        pMem->z = sqliteRealloc(pMem->z, pMem->n+2);
        if( !pMem->z ) return SQLITE_NOMEM;
      }
    }else{
      assert( pMem->flags & MEM_Short );
      if( pMem->n+2>NBFS ){
        char *z = sqliteMalloc(pMem->n+2);
        if( !z ) return SQLITE_NOMEM;
        memcpy(z, pMem->z, pMem->n);
        pMem->flags &= !(MEM_Short);
        pMem->flags |= MEM_Dyn;
        pMem->xDel = 0;
        pMem->z = z;
      }
    }
    pMem->z[pMem->n++] = 0;
    pMem->z[pMem->n++] = 0;
  }
  return SQLITE_OK;
}

/*
** Add MEM_Str to the set of representations for the given Mem.
** A NULL is converted into an empty string.  Numbers are converted
** using sqlite3_snprintf().  Converting a BLOB to a string is a
** no-op.
**
** Existing representations MEM_Int and MEM_Real are *not* invalidated.
** But MEM_Null is.





*/
int sqlite3VdbeMemStringify(Mem *pMem, int enc){
  int rc = SQLITE_OK;
  int fg = pMem->flags;


  assert( !(fg&(MEM_Str|MEM_Blob)) );
  assert( fg&(MEM_Int|MEM_Real|MEM_Null) );

  if( fg & MEM_Null ){      
    /* A NULL value is converted to a zero length string */
    u8 *z = pMem->zShort;
    z[0] = 0;
    z[1] = 0;
    pMem->flags = MEM_Str | MEM_Short | MEM_Term;
    pMem->z = z;
    pMem->n = 0;
    pMem->enc = enc;
  }else{
    /* For a Real or Integer, use sqlite3_snprintf() to produce the UTF-8
    ** string representation of the value. Then, if the required encoding
    ** is UTF-16le or UTF-16be do a translation.
    ** 
    ** FIX ME: It would be better if sqlite3_snprintf() could do UTF-16.
    */
    u8 *z = pMem->zShort;
    if( fg & MEM_Real || (pMem->type==SQLITE_FLOAT) ){
      sqlite3_snprintf(NBFS, z, "%.15g", pMem->r);
    }else{
      assert( fg & MEM_Int );
      sqlite3_snprintf(NBFS, z, "%lld", pMem->i);
    }
    pMem->n = strlen(z);
    pMem->z = z;
    pMem->enc = SQLITE_UTF8;
    pMem->flags |= MEM_Str | MEM_Short | MEM_Term;
    sqlite3VdbeChangeEncoding(pMem, enc);
  }
  return rc;
}

/*
** Release any memory held by the Mem. This may leave the Mem in an
** inconsistent state, for example with (Mem.z==0) and
** (Mem.type==SQLITE_TEXT).







>
>
>
>
>
>
>
>
>
>
>
>
|






<
<
|
|
|
|
>
|
<
<
<
<
<
<
<
<
<
<
<
<
<
|
|
<
<
<
<





|
<
|
|


|
>
>
>
>
>




>


|

<
<
<
<
<
<
<
<
<
<
|
|
|
|
|
|
<
|
|
|
|
|
|
|
|
|
|
|
<







100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125


126
127
128
129
130
131













132
133




134
135
136
137
138
139

140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158










159
160
161
162
163
164

165
166
167
168
169
170
171
172
173
174
175

176
177
178
179
180
181
182
  return SQLITE_OK;
}

/*
** Make sure the given Mem is \u0000 terminated.
*/
int sqlite3VdbeMemNulTerminate(Mem *pMem){
  /* In SQLite, a string without a nul terminator occurs when a string
  ** is loaded from disk (in this case the memory management is ephemeral),
  ** or when it is supplied by the user as a bound variable or function
  ** return value. Therefore, the memory management of the string must be
  ** either ephemeral, static or controlled by a user-supplied destructor.
  */
  assert(                         
    !(pMem->flags&MEM_Str) ||                /* it's not a string, or      */
    (pMem->flags&MEM_Term) ||                /* it's nul term. already, or */
    (pMem->flags&(MEM_Ephem|MEM_Static)) ||  /* it's static or ephem, or   */
    (pMem->flags&MEM_Dyn && pMem->xDel)      /* external management        */
  );
  if( (pMem->flags & MEM_Term)!=0 || (pMem->flags & MEM_Str)==0 ){
    return SQLITE_OK;   /* Nothing to do */
  }

  if( pMem->flags & (MEM_Static|MEM_Ephem) ){
    return sqlite3VdbeMemMakeWriteable(pMem);
  }else{


    char *z = sqliteMalloc(pMem->n+2);
    if( !z ) return SQLITE_NOMEM;
    memcpy(z, pMem->z, pMem->n);
    z[pMem->n] = 0;
    z[pMem->n+1] = 0;
    pMem->xDel(pMem->z);













    pMem->xDel = 0;
    pMem->z = z;




  }
  return SQLITE_OK;
}

/*
** Add MEM_Str to the set of representations for the given Mem.  Numbers

** are converted using sqlite3_snprintf().  Converting a BLOB to a string
** is a no-op.
**
** Existing representations MEM_Int and MEM_Real are *not* invalidated.
**
** A MEM_Null value will never be passed to this function. This function is
** used for converting values to text for returning to the user (i.e. via
** sqlite3_value_text()), or for ensuring that values to be used as btree
** keys are strings. In the former case a NULL pointer is returned the
** user and the later is an internal programming error.
*/
int sqlite3VdbeMemStringify(Mem *pMem, int enc){
  int rc = SQLITE_OK;
  int fg = pMem->flags;
  u8 *z = pMem->zShort;

  assert( !(fg&(MEM_Str|MEM_Blob)) );
  assert( fg&(MEM_Int|MEM_Real) );











  /* For a Real or Integer, use sqlite3_snprintf() to produce the UTF-8
  ** string representation of the value. Then, if the required encoding
  ** is UTF-16le or UTF-16be do a translation.
  ** 
  ** FIX ME: It would be better if sqlite3_snprintf() could do UTF-16.
  */

  if( fg & MEM_Real || (pMem->type==SQLITE_FLOAT) ){
    sqlite3_snprintf(NBFS, z, "%.15g", pMem->r);
  }else{
    assert( fg & MEM_Int );
    sqlite3_snprintf(NBFS, z, "%lld", pMem->i);
  }
  pMem->n = strlen(z);
  pMem->z = z;
  pMem->enc = SQLITE_UTF8;
  pMem->flags |= MEM_Str | MEM_Short | MEM_Term;
  sqlite3VdbeChangeEncoding(pMem, enc);

  return rc;
}

/*
** Release any memory held by the Mem. This may leave the Mem in an
** inconsistent state, for example with (Mem.z==0) and
** (Mem.type==SQLITE_TEXT).
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
}

/*
** Transfer the contents of pFrom to pTo. Any existing value in pTo is
** deleted. pFrom contains an SQL NULL when this routine returns.
*/
int sqlite3VdbeMemMove(Mem *pTo, Mem *pFrom){
  int rc = SQLITE_OK;
  if( !(pFrom->flags&MEM_Dyn && pFrom->xDel) ){
    memcpy(pTo, pFrom, sizeof(Mem));
    if( pFrom->flags & MEM_Short ){
      pTo->z = pTo->zShort;
    }
  }else{
    rc = sqlite3VdbeMemCopy(pTo, pFrom);
    sqlite3VdbeMemRelease(pFrom);
  }
  return SQLITE_OK;
}

/*
** Change the value of a Mem to be a string or a BLOB.
*/
int sqlite3VdbeMemSetStr(







<
<
|
|
|
|
<
|
|
<







314
315
316
317
318
319
320


321
322
323
324

325
326

327
328
329
330
331
332
333
}

/*
** Transfer the contents of pFrom to pTo. Any existing value in pTo is
** deleted. pFrom contains an SQL NULL when this routine returns.
*/
int sqlite3VdbeMemMove(Mem *pTo, Mem *pFrom){


  memcpy(pTo, pFrom, sizeof(Mem));
  if( pFrom->flags & MEM_Short ){
    pTo->z = pTo->zShort;
  }

  pFrom->flags = MEM_Null;
  pFrom->xDel = 0;

  return SQLITE_OK;
}

/*
** Change the value of a Mem to be a string or a BLOB.
*/
int sqlite3VdbeMemSetStr(