Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Binary file I/O infrastructure added and used to increase test coverage for detection of corrupt database files. (CVS 3822) |
---|---|
Downloads: | Tarball | ZIP archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA1: |
479b3d965b19c3ec4cb72542718751de |
User & Date: | drh 2007-04-06 15:02:13.000 |
Context
2007-04-06
| ||
18:23 | Additional coverage testing. (CVS 3823) (check-in: 26b2e1aede user: drh tags: trunk) | |
15:02 | Binary file I/O infrastructure added and used to increase test coverage for detection of corrupt database files. (CVS 3822) (check-in: 479b3d965b user: drh tags: trunk) | |
11:26 | The FOR EACH STATEMENT clause in a trigger is now a syntax error. It used to be silently ignored. STATEMENT is no longer a keyword. (CVS 3821) (check-in: 8e2559b4da user: drh tags: trunk) | |
Changes
Changes to Makefile.in.
︙ | ︙ | |||
218 219 220 221 222 223 224 225 226 227 228 229 230 231 | $(TOP)/src/test5.c \ $(TOP)/src/test6.c \ $(TOP)/src/test7.c \ $(TOP)/src/test8.c \ $(TOP)/src/test9.c \ $(TOP)/src/test_autoext.c \ $(TOP)/src/test_async.c \ $(TOP)/src/test_md5.c \ $(TOP)/src/test_schema.c \ $(TOP)/src/test_server.c \ $(TOP)/src/test_tclvar.c \ $(TOP)/src/utf.c \ $(TOP)/src/util.c \ $(TOP)/src/vdbe.c \ | > | 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 | $(TOP)/src/test5.c \ $(TOP)/src/test6.c \ $(TOP)/src/test7.c \ $(TOP)/src/test8.c \ $(TOP)/src/test9.c \ $(TOP)/src/test_autoext.c \ $(TOP)/src/test_async.c \ $(TOP)/src/test_hexio.c \ $(TOP)/src/test_md5.c \ $(TOP)/src/test_schema.c \ $(TOP)/src/test_server.c \ $(TOP)/src/test_tclvar.c \ $(TOP)/src/utf.c \ $(TOP)/src/util.c \ $(TOP)/src/vdbe.c \ |
︙ | ︙ |
Changes to main.mk.
︙ | ︙ | |||
173 174 175 176 177 178 179 180 181 182 183 184 185 186 | $(TOP)/src/test5.c \ $(TOP)/src/test6.c \ $(TOP)/src/test7.c \ $(TOP)/src/test8.c \ $(TOP)/src/test9.c \ $(TOP)/src/test_autoext.c \ $(TOP)/src/test_async.c \ $(TOP)/src/test_md5.c \ $(TOP)/src/test_schema.c \ $(TOP)/src/test_server.c \ $(TOP)/src/test_tclvar.c \ $(TOP)/src/utf.c \ $(TOP)/src/util.c \ $(TOP)/src/vdbe.c \ | > | 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 | $(TOP)/src/test5.c \ $(TOP)/src/test6.c \ $(TOP)/src/test7.c \ $(TOP)/src/test8.c \ $(TOP)/src/test9.c \ $(TOP)/src/test_autoext.c \ $(TOP)/src/test_async.c \ $(TOP)/src/test_hexio.c \ $(TOP)/src/test_md5.c \ $(TOP)/src/test_schema.c \ $(TOP)/src/test_server.c \ $(TOP)/src/test_tclvar.c \ $(TOP)/src/utf.c \ $(TOP)/src/util.c \ $(TOP)/src/vdbe.c \ |
︙ | ︙ |
Changes to src/btree.c.
1 2 3 4 5 6 7 8 9 10 11 | /* ** 2004 April 6 ** ** 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. ** ************************************************************************* | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | /* ** 2004 April 6 ** ** 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. ** ************************************************************************* ** $Id: btree.c,v 1.352 2007/04/06 15:02:14 drh Exp $ ** ** This file implements a external (disk-based) database using BTrees. ** For a detailed discussion of BTrees, refer to ** ** Donald E. Knuth, THE ART OF COMPUTER PROGRAMMING, Volume 3: ** "Sorting And Searching", pages 473-480. Addison-Wesley ** Publishing Company, Reading, Massachusetts. |
︙ | ︙ | |||
1866 1867 1868 1869 1870 1871 1872 | if( memcmp(page1, zMagicHeader, 16)!=0 ){ goto page1_init_failed; } if( page1[18]>1 || page1[19]>1 ){ goto page1_init_failed; } pageSize = get2byte(&page1[16]); | | | 1866 1867 1868 1869 1870 1871 1872 1873 1874 1875 1876 1877 1878 1879 1880 | if( memcmp(page1, zMagicHeader, 16)!=0 ){ goto page1_init_failed; } if( page1[18]>1 || page1[19]>1 ){ goto page1_init_failed; } pageSize = get2byte(&page1[16]); if( ((pageSize-1)&pageSize)!=0 || pageSize<512 ){ goto page1_init_failed; } assert( (pageSize & 7)==0 ); pBt->pageSize = pageSize; pBt->usableSize = pageSize - page1[20]; if( pBt->usableSize<500 ){ goto page1_init_failed; |
︙ | ︙ |
Changes to src/parse.y.
︙ | ︙ | |||
10 11 12 13 14 15 16 | ** ************************************************************************* ** This file contains SQLite's grammar for SQL. Process this file ** using the lemon parser generator to generate C code that runs ** the parser. Lemon will also generate a header file containing ** numeric codes for all of the tokens. ** | | | 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | ** ************************************************************************* ** This file contains SQLite's grammar for SQL. Process this file ** using the lemon parser generator to generate C code that runs ** the parser. Lemon will also generate a header file containing ** numeric codes for all of the tokens. ** ** @(#) $Id: parse.y,v 1.218 2007/04/06 15:02:14 drh Exp $ */ // All token codes are small integers with #defines that begin with "TK_" %token_prefix TK_ // The type of the data attached to each token is Token. This is also the // default type for non-terminals. |
︙ | ︙ | |||
538 539 540 541 542 543 544 | %type having_opt {Expr*} %destructor having_opt {sqlite3ExprDelete($$);} having_opt(A) ::= . {A = 0;} having_opt(A) ::= HAVING expr(X). {A = X;} %type limit_opt {struct LimitVal} | > > > > > > > > | | | < > | 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 | %type having_opt {Expr*} %destructor having_opt {sqlite3ExprDelete($$);} having_opt(A) ::= . {A = 0;} having_opt(A) ::= HAVING expr(X). {A = X;} %type limit_opt {struct LimitVal} // The destructor for limit_opt will never fire in the current grammar. // The limit_opt non-terminal only occurs at the end of a single production // rule for SELECT statements. As soon as the rule that create the // limit_opt non-terminal reduces, the SELECT statement rule will also // reduce. So there is never a limit_opt non-terminal on the stack // except as a transient. So there is never anything to destroy. // //%destructor limit_opt { // sqlite3ExprDelete($$.pLimit); // sqlite3ExprDelete($$.pOffset); //} limit_opt(A) ::= . {A.pLimit = 0; A.pOffset = 0;} limit_opt(A) ::= LIMIT expr(X). {A.pLimit = X; A.pOffset = 0;} limit_opt(A) ::= LIMIT expr(X) OFFSET expr(Y). {A.pLimit = X; A.pOffset = Y;} limit_opt(A) ::= LIMIT expr(X) COMMA expr(Y). {A.pOffset = X; A.pLimit = Y;} |
︙ | ︙ |
Changes to src/tclsqlite.c.
︙ | ︙ | |||
8 9 10 11 12 13 14 | ** May you find forgiveness for yourself and forgive others. ** May you share freely, never taking more than you give. ** ************************************************************************* ** A TCL Interface to SQLite. Append this file to sqlite3.c and ** compile the whole thing to build a TCL-enabled version of SQLite. ** | | | 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | ** May you find forgiveness for yourself and forgive others. ** May you share freely, never taking more than you give. ** ************************************************************************* ** A TCL Interface to SQLite. Append this file to sqlite3.c and ** compile the whole thing to build a TCL-enabled version of SQLite. ** ** $Id: tclsqlite.c,v 1.179 2007/04/06 15:02:14 drh Exp $ */ #include "tcl.h" /* ** Some additional include files are needed if this file is not ** appended to the amalgamation. */ |
︙ | ︙ | |||
2214 2215 2216 2217 2218 2219 2220 2221 2222 2223 2224 2225 2226 2227 2228 2229 2230 2231 2232 2233 2234 2235 2236 2237 2238 2239 2240 2241 | extern int Sqlitetest9_Init(Tcl_Interp*); extern int Md5_Init(Tcl_Interp*); extern int Sqlitetestsse_Init(Tcl_Interp*); extern int Sqlitetestasync_Init(Tcl_Interp*); extern int Sqlitetesttclvar_Init(Tcl_Interp*); extern int Sqlitetestschema_Init(Tcl_Interp*); extern int Sqlitetest_autoext_Init(Tcl_Interp*); Sqlitetest1_Init(interp); Sqlitetest2_Init(interp); Sqlitetest3_Init(interp); Sqlitetest4_Init(interp); Sqlitetest5_Init(interp); Sqlitetest6_Init(interp); Sqlitetest7_Init(interp); Sqlitetest8_Init(interp); Sqlitetest9_Init(interp); Sqlitetestasync_Init(interp); Sqlitetesttclvar_Init(interp); Sqlitetestschema_Init(interp); Sqlitetest_autoext_Init(interp); Md5_Init(interp); #ifdef SQLITE_SSE Sqlitetestsse_Init(interp); #endif } #endif if( argc>=2 || TCLSH==2 ){ | > > | 2214 2215 2216 2217 2218 2219 2220 2221 2222 2223 2224 2225 2226 2227 2228 2229 2230 2231 2232 2233 2234 2235 2236 2237 2238 2239 2240 2241 2242 2243 | extern int Sqlitetest9_Init(Tcl_Interp*); extern int Md5_Init(Tcl_Interp*); extern int Sqlitetestsse_Init(Tcl_Interp*); extern int Sqlitetestasync_Init(Tcl_Interp*); extern int Sqlitetesttclvar_Init(Tcl_Interp*); extern int Sqlitetestschema_Init(Tcl_Interp*); extern int Sqlitetest_autoext_Init(Tcl_Interp*); extern int Sqlitetest_hexio_Init(Tcl_Interp*); Sqlitetest1_Init(interp); Sqlitetest2_Init(interp); Sqlitetest3_Init(interp); Sqlitetest4_Init(interp); Sqlitetest5_Init(interp); Sqlitetest6_Init(interp); Sqlitetest7_Init(interp); Sqlitetest8_Init(interp); Sqlitetest9_Init(interp); Sqlitetestasync_Init(interp); Sqlitetesttclvar_Init(interp); Sqlitetestschema_Init(interp); Sqlitetest_autoext_Init(interp); Sqlitetest_hexio_Init(interp); Md5_Init(interp); #ifdef SQLITE_SSE Sqlitetestsse_Init(interp); #endif } #endif if( argc>=2 || TCLSH==2 ){ |
︙ | ︙ |
Added src/test_hexio.c.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 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 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 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 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 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 308 309 310 311 | /* ** 2007 April 6 ** ** 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. ** ************************************************************************* ** Code for testing all sorts of SQLite interfaces. This code ** implements TCL commands for reading and writing the binary ** database files and displaying the content of those files as ** hexadecimal. We could, in theory, use the built-in "binary" ** command of TCL to do a lot of this, but there are some issues ** with historical versions of the "binary" command. So it seems ** easier and safer to build our own mechanism. ** ** $Id: test_hexio.c,v 1.1 2007/04/06 15:02:14 drh Exp $ */ #include "tcl.h" #include <stdlib.h> #include <string.h> #include <assert.h> /* hexio_read filename offset amt hexio_write filename offset hexdata hexio_get_int hexdata hexio_get_varint hexdata hexio_render_int8 integer hexio_render_int16 integer hexio_render_int38 integer hexio_render_varint integer */ /* ** Convert binary to hex. The input zBuf[] contains N bytes of ** binary data. zBuf[] is 2*n+1 bytes long. Overwrite zBuf[] ** with a hexadecimal representation of its original binary input. */ static void binToHex(unsigned char *zBuf, int N){ const unsigned char zHex[] = "0123456789ABCDEF"; int i, j; unsigned char c; i = N*2; zBuf[i--] = 0; for(j=N-1; j>=0; j--){ c = zBuf[j]; zBuf[i--] = zHex[c&0xf]; zBuf[i--] = zHex[c>>4]; } assert( i==-1 ); } /* ** Convert hex to binary. The input zIn[] contains N bytes of ** hexadecimal. Convert this into binary and write aOut[] with ** the binary data. Spaces in the original input are ignored. ** Return the number of bytes of binary rendered. */ static int hexToBin(const unsigned char *zIn, int N, unsigned char *aOut){ const unsigned char aMap[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10, 0, 0, 0, 0, 0, 0, 0,11,12,13,14,15,16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,11,12,13,14,15,16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }; int i, j; int hi=1; unsigned char c; for(i=j=0; i<N; i++){ c = aMap[zIn[i]]; if( c==0 ) continue; if( hi ){ aOut[j] = (c-1)<<4; hi = 0; }else{ aOut[j++] |= c-1; hi = 1; } } return j; } /* ** Usage: hexio_read FILENAME OFFSET AMT ** ** Read AMT bytes from file FILENAME beginning at OFFSET from the ** beginning of the file. Convert that information to hexadecimal ** and return the resulting HEX string. */ static int hexio_read( void * clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[] ){ int offset; int amt, got; const char *zFile; unsigned char *zBuf; FILE *in; if( objc!=4 ){ Tcl_WrongNumArgs(interp, 1, objv, "FILENAME OFFSET AMT"); return TCL_ERROR; } if( Tcl_GetIntFromObj(interp, objv[2], &offset) ) return TCL_ERROR; if( Tcl_GetIntFromObj(interp, objv[3], &amt) ) return TCL_ERROR; zFile = Tcl_GetString(objv[1]); zBuf = malloc( amt*2+1 ); if( zBuf==0 ){ return TCL_ERROR; } in = fopen(zFile, "r"); if( in==0 ){ Tcl_AppendResult(interp, "cannot open input file ", zFile, 0); return TCL_ERROR; } fseek(in, offset, SEEK_SET); got = fread(zBuf, 1, amt, in); fclose(in); if( got<0 ){ got = 0; } binToHex(zBuf, got); Tcl_AppendResult(interp, zBuf, 0); free(zBuf); return TCL_OK; } /* ** Usage: hexio_write FILENAME OFFSET DATA ** ** Write DATA into file FILENAME beginning at OFFSET from the ** beginning of the file. DATA is expressed in hexadecimal. */ static int hexio_write( void * clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[] ){ int offset; int nIn, nOut, written; const char *zFile; const unsigned char *zIn; unsigned char *aOut; FILE *out; if( objc!=4 ){ Tcl_WrongNumArgs(interp, 1, objv, "FILENAME OFFSET HEXDATA"); return TCL_ERROR; } if( Tcl_GetIntFromObj(interp, objv[2], &offset) ) return TCL_ERROR; zFile = Tcl_GetString(objv[1]); zIn = (const unsigned char *)Tcl_GetStringFromObj(objv[3], &nIn); aOut = malloc( nIn/2 ); if( aOut==0 ){ return TCL_ERROR; } nOut = hexToBin(zIn, nIn, aOut); out = fopen(zFile, "r+"); if( out==0 ){ Tcl_AppendResult(interp, "cannot open output file ", zFile, 0); return TCL_ERROR; } fseek(out, offset, SEEK_SET); written = fwrite(aOut, 1, nOut, out); free(aOut); fclose(out); Tcl_SetObjResult(interp, Tcl_NewIntObj(written)); return TCL_OK; } /* ** USAGE: hexio_get_int HEXDATA ** ** Interpret the HEXDATA argument as a big-endian integer. Return ** the value of that integer. HEXDATA can contain between 2 and 8 ** hexadecimal digits. */ static int hexio_get_int( void * clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[] ){ int val; int nIn, nOut; const unsigned char *zIn; unsigned char *aOut; unsigned char aNum[4]; if( objc!=2 ){ Tcl_WrongNumArgs(interp, 1, objv, "HEXDATA"); return TCL_ERROR; } zIn = (const unsigned char *)Tcl_GetStringFromObj(objv[1], &nIn); aOut = malloc( nIn/2 ); if( aOut==0 ){ return TCL_ERROR; } nOut = hexToBin(zIn, nIn, aOut); if( nOut>=4 ){ memcpy(aNum, aOut, 4); }else{ memset(aNum, 0, sizeof(aNum)); memcpy(&aNum[4-nOut], aOut, 4-nOut); } free(aOut); val = (aNum[0]<<24) | (aNum[1]<<16) | (aNum[2]<<8) | aNum[3]; Tcl_SetObjResult(interp, Tcl_NewIntObj(val)); return TCL_OK; } /* ** USAGE: hexio_render_int16 INTEGER ** ** Render INTEGER has a 16-bit big-endian integer in hexadecimal. */ static int hexio_render_int16( void * clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[] ){ int val; unsigned char aNum[10]; if( objc!=2 ){ Tcl_WrongNumArgs(interp, 1, objv, "INTEGER"); return TCL_ERROR; } if( Tcl_GetIntFromObj(interp, objv[1], &val) ) return TCL_ERROR; aNum[0] = val>>8; aNum[1] = val; binToHex(aNum, 2); Tcl_SetObjResult(interp, Tcl_NewStringObj((char*)aNum, 4)); return TCL_OK; } /* ** USAGE: hexio_render_int32 INTEGER ** ** Render INTEGER has a 32-bit big-endian integer in hexadecimal. */ static int hexio_render_int32( void * clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[] ){ int val; unsigned char aNum[10]; if( objc!=2 ){ Tcl_WrongNumArgs(interp, 1, objv, "INTEGER"); return TCL_ERROR; } if( Tcl_GetIntFromObj(interp, objv[1], &val) ) return TCL_ERROR; aNum[0] = val>>24; aNum[1] = val>>16; aNum[2] = val>>8; aNum[3] = val; binToHex(aNum, 4); Tcl_SetObjResult(interp, Tcl_NewStringObj((char*)aNum, 8)); return TCL_OK; } /* ** Register commands with the TCL interpreter. */ int Sqlitetest_hexio_Init(Tcl_Interp *interp){ static struct { char *zName; Tcl_ObjCmdProc *xProc; } aObjCmd[] = { { "hexio_read", hexio_read }, { "hexio_write", hexio_write }, { "hexio_get_int", hexio_get_int }, { "hexio_render_int16", hexio_render_int16 }, { "hexio_render_int32", hexio_render_int32 }, }; int i; for(i=0; i<sizeof(aObjCmd)/sizeof(aObjCmd[0]); i++){ Tcl_CreateObjCommand(interp, aObjCmd[i].zName, aObjCmd[i].xProc, 0, 0); } return TCL_OK; } |
Added test/corrupt3.test.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 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 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 | # 2007 April 6 # # 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. # #*********************************************************************** # This file implements regression tests for SQLite library. # # This file implements tests to make sure SQLite does not crash or # segfault if it sees a corrupt database file. # # $Id: corrupt3.test,v 1.1 2007/04/06 15:02:14 drh Exp $ set testdir [file dirname $argv0] source $testdir/tester.tcl # We must have the page_size pragma for these tests to work. # ifcapable !pager_pragmas { finish_test return } # Create a database with an overflow page. # do_test corrupt3-1.1 { set bigstring [string repeat 0123456789 200] execsql { PRAGMA page_size=1024; CREATE TABLE t1(x); INSERT INTO t1 VALUES($bigstring); } file size test.db } [expr {1024*3}] # Verify that the file format is as we expect. The page size # should be 1024 bytes. The only record should have a single # overflow page. The overflow page is page 3. The pointer to # the overflow page is on the last 4 bytes of page 2. # do_test corrupt3-1.2 { hexio_get_int [hexio_read test.db 16 2] } 1024 ;# The page size is 1024 do_test corrupt3-1.3 { hexio_get_int [hexio_read test.db 20 1] } 0 ;# Unused bytes per page is 0 do_test corrupt3-1.4 { hexio_get_int [hexio_read test.db 2044 4] } 3 ;# Overflow page is 3 do_test corrupt3-1.5 { hexio_get_int [hexio_read test.db 2048 4] } 0 ;# First chained overflow is 0 integrity_check corrupt3-1.6 # Make the overflow chain loop back on itself. See if the # corruption is detected. (Actually, the last pointer in # an overflow chain is ignored, so this is not an error.) # do_test corrupt3-1.7 { db close hexio_write test.db 2048 [hexio_render_int32 3] sqlite3 db test.db catchsql { SELECT x FROM t1 } } [list 0 $bigstring] integrity_check corrupt3-1.8 # Change the pointer for the first page of the overflow # change to be a non-existant page. # do_test corrupt3-1.9 { db close hexio_write test.db 2044 [hexio_render_int32 4] sqlite3 db test.db catchsql { SELECT substr(x,1,10) FROM t1 } } [list 0 0123456789] do_test corrupt3-1.10 { catchsql { PRAGMA integrity_check } } {0 {{*** in database main *** On tree page 2 cell 0: invalid page number 4 Page 3 is never used}}} do_test corrupt3-1.11 { db close hexio_write test.db 2044 [hexio_render_int32 0] sqlite3 db test.db catchsql { SELECT substr(x,1,10) FROM t1 } } [list 1 {database disk image is malformed}] do_test corrupt3-1.12 { catchsql { PRAGMA integrity_check } } {0 {{*** in database main *** On tree page 2 cell 0: 1 of 1 pages missing from overflow list starting at 0 Page 3 is never used}}} finish_test |
Added test/filefmt.test.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 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 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 | # 2007 April 6 # # 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. # #*********************************************************************** # This file implements regression tests for SQLite library. # # This file implements tests to verify database file format. # # $Id: filefmt.test,v 1.1 2007/04/06 15:02:14 drh Exp $ set testdir [file dirname $argv0] source $testdir/tester.tcl db close file delete -force test.db test.db-journal # Database begins with valid 16-byte header string. # do_test filefmt-1.1 { sqlite3 db test.db db eval {CREATE TABLE t1(x)} db close hexio_read test.db 0 16 } {53514C69746520666F726D6174203300} # If the 16-byte header is changed, the file will not open # do_test filefmt-1.2 { hexio_write test.db 0 54 set x [catch {sqlite3 db test.db} err] lappend x $err } {0 {}} do_test filefmt-1.3 { catchsql { SELECT count(*) FROM sqlite_master } } {1 {file is encrypted or is not a database}} do_test filefmt-1.4 { db close hexio_write test.db 0 53 sqlite3 db test.db catchsql { SELECT count(*) FROM sqlite_master } } {0 1} # The page-size is stored at offset 16 # ifcapable pager_pragmas { foreach pagesize {512 1024 2048 4096 8192 16384 32768} { do_test filefmt-1.5.$pagesize.1 { db close file delete -force test.db sqlite3 db test.db db eval "PRAGMA page_size=$pagesize" db eval {CREATE TABLE t1(x)} file size test.db } [expr $pagesize*2] do_test filefmt-1.5.$pagesize.2 { hexio_get_int [hexio_read test.db 16 2] } $pagesize } } # The page-size must be a power of 2 # do_test filefmt-1.6 { db close hexio_write test.db 16 [hexio_render_int16 1025] sqlite3 db test.db catchsql { SELECT count(*) FROM sqlite_master } } {1 {file is encrypted or is not a database}} # The page-size must be at least 512 bytes # do_test filefmt-1.7 { db close hexio_write test.db 16 [hexio_render_int16 256] sqlite3 db test.db catchsql { SELECT count(*) FROM sqlite_master } } {1 {file is encrypted or is not a database}} # Usable space per page (page-size minus unused space per page) # must be at least 500 bytes # ifcapable pager_pragmas { do_test filefmt-1.8 { db close file delete -force test.db sqlite3 db test.db db eval {PRAGMA page_size=512; CREATE TABLE t1(x)} db close hexio_write test.db 20 10 sqlite3 db test.db catchsql { SELECT count(*) FROM sqlite_master } } {1 {file is encrypted or is not a database}} } finish_test |
Changes to test/select1.test.
1 2 3 4 5 6 7 8 9 10 11 12 13 | # 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. # #*********************************************************************** # This file implements regression tests for SQLite library. The # focus of this file is testing the SELECT statement. # | | | 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. # #*********************************************************************** # This file implements regression tests for SQLite library. The # focus of this file is testing the SELECT statement. # # $Id: select1.test,v 1.52 2007/04/06 15:02:14 drh Exp $ set testdir [file dirname $argv0] source $testdir/tester.tcl # Try to select on a non-existant table. # do_test select1-1.1 { |
︙ | ︙ | |||
542 543 544 545 546 547 548 549 550 551 552 553 554 555 | } {1 {near ")": syntax error}} do_test select1-7.8 { set v [catch {execsql { SELECT f1 FROM test1 ORDER BY f2, f1+; }} msg] lappend v $msg } {1 {near ";": syntax error}} do_test select1-8.1 { execsql {SELECT f1 FROM test1 WHERE 4.3+2.4 OR 1 ORDER BY f1} } {11 33} do_test select1-8.2 { execsql { SELECT f1 FROM test1 WHERE ('x' || f1) BETWEEN 'x10' AND 'x20' | > > > > > | 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 | } {1 {near ")": syntax error}} do_test select1-7.8 { set v [catch {execsql { SELECT f1 FROM test1 ORDER BY f2, f1+; }} msg] lappend v $msg } {1 {near ";": syntax error}} do_test select1-7.9 { catchsql { SELECT f1 FROM test1 LIMIT 5+3 OFFSET 11 ORDER BY f2; } } {1 {near "ORDER": syntax error}} do_test select1-8.1 { execsql {SELECT f1 FROM test1 WHERE 4.3+2.4 OR 1 ORDER BY f1} } {11 33} do_test select1-8.2 { execsql { SELECT f1 FROM test1 WHERE ('x' || f1) BETWEEN 'x10' AND 'x20' |
︙ | ︙ |