From 769e97e0323443bb57434418e33afb96ec993032 Mon Sep 17 00:00:00 2001 From: drh Date: Wed, 1 Apr 2009 16:33:37 +0000 Subject: [PATCH] Remove dead code from the UTF conversion routines. Fix a bug in sqlite3_prepare16_v2() in which an out-of-memory error fails to set the statement return pointer to NULL. (CVS 6423) FossilOrigin-Name: 94e2f815ebb38981a2226d8aed9f3731f8833f7c --- manifest | 20 ++++++++++---------- manifest.uuid | 2 +- src/func.c | 36 ++++++++++++++++++------------------ src/prepare.c | 3 ++- src/sqliteInt.h | 4 ++-- src/utf.c | 38 +++++++++++++++++++++++--------------- 6 files changed, 56 insertions(+), 47 deletions(-) diff --git a/manifest b/manifest index 7b7e75f0d0..33eaeccc87 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Remove\san\sunreachable\sbranch\sfrom\sallocateSpace()\sin\sbtree.c.\sAdd\scomments\sand\sasserts\sto\sthe\ssame\sfunction.\s(CVS\s6422) -D 2009-04-01T16:25:33 +C Remove\sdead\scode\sfrom\sthe\sUTF\sconversion\sroutines.\s\sFix\sa\sbug\sin\nsqlite3_prepare16_v2()\sin\swhich\san\sout-of-memory\serror\sfails\sto\nset\sthe\sstatement\sreturn\spointer\sto\sNULL.\s(CVS\s6423) +D 2009-04-01T16:33:38 F Makefile.arm-wince-mingw32ce-gcc fcd5e9cd67fe88836360bb4f9ef4cb7f8e2fb5a0 F Makefile.in 583e87706abc3026960ed759aff6371faf84c211 F Makefile.linux-gcc d53183f4aa6a9192d249731c90dbdffbd2c68654 @@ -113,7 +113,7 @@ F src/date.c 0d804df3bbda46329946a01ff5c75c3f4f135218 F src/delete.c eb1066b2f35489fee46ad765d2b66386fc7d8adf F src/expr.c 14853cd56107292de6af664a24c6255111a4257d F src/fault.c dc88c821842157460750d2d61a8a8b4197d047ff -F src/func.c 42d12d31d350defcabb8f3f476cdaeedfc9e9615 +F src/func.c 1d6a8689443b15a3845e805a6ad97317b37af3fb F src/global.c 448419c44ce0701104c2121b0e06919b44514c0c F src/hash.c 5824e6ff7ba78cd34c8d6cd724367713583e5b55 F src/hash.h 28f38ebb1006a5beedcb013bcdfe31befe7437ae @@ -150,7 +150,7 @@ F src/pcache.c 395f752a13574120bd7513a400ba02a265aaa76d F src/pcache.h 9b927ccc5a538e31b4c3bc7eec4f976db42a1324 F src/pcache1.c f587565f4ba0fd1772067eaa96814dce761b7a4c F src/pragma.c 22ed04836aab8ce134c53be1ca896f3ad20fabdb -F src/prepare.c 157a7528ba686964ab0e0687749ca30adb9ab614 +F src/prepare.c aa3e7dc01a011269b9152e5103fad2eea2c96e7a F src/printf.c 9866a9a9c4a90f6d4147407f373df3fd5d5f9b6f F src/random.c 676b9d7ac820fe81e6fb2394ac8c10cff7f38628 F src/resolve.c 094e44450371fb27869eb8bf679aacbe51fdc56d @@ -159,7 +159,7 @@ F src/select.c bd494b68a54a51de3df94ecdd6d24fa7598929d1 F src/shell.c 0a11f831603f17fea20ca97133c0f64e716af4a7 F src/sqlite.h.in 0db1e59d89aeacb8fe64a19fd14c13a796060ccb F src/sqlite3ext.h 1db7d63ab5de4b3e6b83dd03d1a4e64fef6d2a17 -F src/sqliteInt.h 7fe33227434a3e54e3056cbe95800bd09a636fbe +F src/sqliteInt.h afc93df0ddc3661b9b31b51edf43635b8df4e4de F src/sqliteLimit.h ffe93f5a0c4e7bd13e70cd7bf84cfb5c3465f45d F src/status.c 237b193efae0cf6ac3f0817a208de6c6c6ef6d76 F src/table.c 332ab0ea691e63862e2a8bdfe2c0617ee61062a3 @@ -197,7 +197,7 @@ F src/test_wsd.c 3ae5101de6cbfda2720152ab659ea84079719241 F src/tokenize.c 7bd3b6dd56566604ad24ed4aa017e6618166b500 F src/trigger.c 21f39db410cdc32166a94900ac1b3df98ea560e6 F src/update.c 8ededddcde6f7b6da981dd0429a5d34518a475b7 -F src/utf.c f9ed1ca795933e82675865ef15ed4852e0b19db3 +F src/utf.c 7bec2eeae2b26f28b8a8ede529705ccf531cd21b F src/util.c 469d74f5bf09ed6398702c7da2ef8a34e979a1c1 F src/vacuum.c 4929a585ef0fb1dfaf46302f8a9c4aa30c2d9cf5 F src/vdbe.c 624922027b8b5fe203bd89e204aaed447e8b7ce7 @@ -714,7 +714,7 @@ F tool/speedtest16.c c8a9c793df96db7e4933f0852abb7a03d48f2e81 F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224 F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e -P 3e3b5e861aeff2e4ef568c422236fdf7fa22bed3 -R 3682da7f79f43466521202126b407df7 -U danielk1977 -Z 15174c0778c01e00d98a68566fd435b4 +P f8e15a542df67fd9dc1c91c7d9e1c4df59acb82b +R 0f32d6c1480412f4597b43816b3f4d1f +U drh +Z 65f1d97cdae9710553c2d01cde604d65 diff --git a/manifest.uuid b/manifest.uuid index fedb2812e3..0a0b437eb8 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -f8e15a542df67fd9dc1c91c7d9e1c4df59acb82b \ No newline at end of file +94e2f815ebb38981a2226d8aed9f3731f8833f7c \ No newline at end of file diff --git a/src/func.c b/src/func.c index 154c4eb6e9..85ec68b73f 100644 --- a/src/func.c +++ b/src/func.c @@ -16,7 +16,7 @@ ** sqliteRegisterBuildinFunctions() found at the bottom of the file. ** All other code has file scope. ** -** $Id: func.c,v 1.225 2009/03/27 15:26:03 danielk1977 Exp $ +** $Id: func.c,v 1.226 2009/04/01 16:33:38 drh Exp $ */ #include "sqliteInt.h" #include @@ -444,7 +444,7 @@ struct compareInfo { ** whereas only characters less than 0x80 do in ASCII. */ #if defined(SQLITE_EBCDIC) -# define sqlite3Utf8Read(A,B,C) (*(A++)) +# define sqlite3Utf8Read(A,C) (*(A++)) # define GlogUpperToLower(A) A = sqlite3UpperToLower[A] #else # define GlogUpperToLower(A) if( A<0x80 ){ A = sqlite3UpperToLower[A]; } @@ -501,18 +501,18 @@ static int patternCompare( u8 noCase = pInfo->noCase; int prevEscape = 0; /* True if the previous character was 'escape' */ - while( (c = sqlite3Utf8Read(zPattern,0,&zPattern))!=0 ){ + while( (c = sqlite3Utf8Read(zPattern,&zPattern))!=0 ){ if( !prevEscape && c==matchAll ){ - while( (c=sqlite3Utf8Read(zPattern,0,&zPattern)) == matchAll + while( (c=sqlite3Utf8Read(zPattern,&zPattern)) == matchAll || c == matchOne ){ - if( c==matchOne && sqlite3Utf8Read(zString, 0, &zString)==0 ){ + if( c==matchOne && sqlite3Utf8Read(zString, &zString)==0 ){ return 0; } } if( c==0 ){ return 1; }else if( c==esc ){ - c = sqlite3Utf8Read(zPattern, 0, &zPattern); + c = sqlite3Utf8Read(zPattern, &zPattern); if( c==0 ){ return 0; } @@ -524,17 +524,17 @@ static int patternCompare( } return *zString!=0; } - while( (c2 = sqlite3Utf8Read(zString,0,&zString))!=0 ){ + while( (c2 = sqlite3Utf8Read(zString,&zString))!=0 ){ if( noCase ){ GlogUpperToLower(c2); GlogUpperToLower(c); while( c2 != 0 && c2 != c ){ - c2 = sqlite3Utf8Read(zString, 0, &zString); + c2 = sqlite3Utf8Read(zString, &zString); GlogUpperToLower(c2); } }else{ while( c2 != 0 && c2 != c ){ - c2 = sqlite3Utf8Read(zString, 0, &zString); + c2 = sqlite3Utf8Read(zString, &zString); } } if( c2==0 ) return 0; @@ -542,7 +542,7 @@ static int patternCompare( } return 0; }else if( !prevEscape && c==matchOne ){ - if( sqlite3Utf8Read(zString, 0, &zString)==0 ){ + if( sqlite3Utf8Read(zString, &zString)==0 ){ return 0; } }else if( c==matchSet ){ @@ -550,20 +550,20 @@ static int patternCompare( assert( esc==0 ); /* This only occurs for GLOB, not LIKE */ seen = 0; invert = 0; - c = sqlite3Utf8Read(zString, 0, &zString); + c = sqlite3Utf8Read(zString, &zString); if( c==0 ) return 0; - c2 = sqlite3Utf8Read(zPattern, 0, &zPattern); + c2 = sqlite3Utf8Read(zPattern, &zPattern); if( c2=='^' ){ invert = 1; - c2 = sqlite3Utf8Read(zPattern, 0, &zPattern); + c2 = sqlite3Utf8Read(zPattern, &zPattern); } if( c2==']' ){ if( c==']' ) seen = 1; - c2 = sqlite3Utf8Read(zPattern, 0, &zPattern); + c2 = sqlite3Utf8Read(zPattern, &zPattern); } while( c2 && c2!=']' ){ if( c2=='-' && zPattern[0]!=']' && zPattern[0]!=0 && prior_c>0 ){ - c2 = sqlite3Utf8Read(zPattern, 0, &zPattern); + c2 = sqlite3Utf8Read(zPattern, &zPattern); if( c>=prior_c && c<=c2 ) seen = 1; prior_c = 0; }else{ @@ -572,7 +572,7 @@ static int patternCompare( } prior_c = c2; } - c2 = sqlite3Utf8Read(zPattern, 0, &zPattern); + c2 = sqlite3Utf8Read(zPattern, &zPattern); } if( c2==0 || (seen ^ invert)==0 ){ return 0; @@ -580,7 +580,7 @@ static int patternCompare( }else if( esc==c && !prevEscape ){ prevEscape = 1; }else{ - c2 = sqlite3Utf8Read(zString, 0, &zString); + c2 = sqlite3Utf8Read(zString, &zString); if( noCase ){ GlogUpperToLower(c); GlogUpperToLower(c2); @@ -649,7 +649,7 @@ static void likeFunc( "ESCAPE expression must be a single character", -1); return; } - escape = sqlite3Utf8Read(zEsc, 0, &zEsc); + escape = sqlite3Utf8Read(zEsc, &zEsc); } if( zA && zB ){ struct compareInfo *pInfo = sqlite3_user_data(context); diff --git a/src/prepare.c b/src/prepare.c index dc576959fa..c4d88a3beb 100644 --- a/src/prepare.c +++ b/src/prepare.c @@ -13,7 +13,7 @@ ** interface, and routines that contribute to loading the database schema ** from disk. ** -** $Id: prepare.c,v 1.114 2009/03/24 15:08:10 drh Exp $ +** $Id: prepare.c,v 1.115 2009/04/01 16:33:38 drh Exp $ */ #include "sqliteInt.h" @@ -773,6 +773,7 @@ static int sqlite3Prepare16( const char *zTail8 = 0; int rc = SQLITE_OK; + *ppStmt = 0; if( !sqlite3SafetyCheckOk(db) ){ return SQLITE_MISUSE; } diff --git a/src/sqliteInt.h b/src/sqliteInt.h index 46b87b7be2..8446ddbeb3 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -11,7 +11,7 @@ ************************************************************************* ** Internal interface definitions for SQLite. ** -** @(#) $Id: sqliteInt.h,v 1.848 2009/03/25 16:51:43 drh Exp $ +** @(#) $Id: sqliteInt.h,v 1.849 2009/04/01 16:33:38 drh Exp $ */ #ifndef _SQLITEINT_H_ #define _SQLITEINT_H_ @@ -2564,7 +2564,7 @@ int sqlite3GetInt32(const char *, int*); int sqlite3FitsIn64Bits(const char *, int); int sqlite3Utf16ByteLen(const void *pData, int nChar); int sqlite3Utf8CharLen(const char *pData, int nByte); -int sqlite3Utf8Read(const u8*, const u8*, const u8**); +int sqlite3Utf8Read(const u8*, const u8**); /* ** Routines to read and write variable-length integers. These used to diff --git a/src/utf.c b/src/utf.c index 685ed27974..9540e285c2 100644 --- a/src/utf.c +++ b/src/utf.c @@ -12,7 +12,7 @@ ** This file contains routines used to translate between UTF-8, ** UTF-16, UTF-16BE, and UTF-16LE. ** -** $Id: utf.c,v 1.71 2009/03/31 03:41:57 shane Exp $ +** $Id: utf.c,v 1.72 2009/04/01 16:33:38 drh Exp $ ** ** Notes on UTF-8: ** @@ -110,22 +110,20 @@ static const unsigned char sqlite3Utf8Trans1[] = { #define READ_UTF16LE(zIn, c){ \ c = (*zIn++); \ c += ((*zIn++)<<8); \ - if( c>=0xD800 && c<0xE000 ){ \ + if( c>=0xD800 && c<0xE000 ){ \ int c2 = (*zIn++); \ c2 += ((*zIn++)<<8); \ c = (c2&0x03FF) + ((c&0x003F)<<10) + (((c&0x03C0)+0x0040)<<10); \ - if( (c & 0xFFFF0000)==0 ) c = 0xFFFD; \ } \ } #define READ_UTF16BE(zIn, c){ \ c = ((*zIn++)<<8); \ c += (*zIn++); \ - if( c>=0xD800 && c<0xE000 ){ \ + if( c>=0xD800 && c<0xE000 ){ \ int c2 = ((*zIn++)<<8); \ c2 += (*zIn++); \ c = (c2&0x03FF) + ((c&0x003F)<<10) + (((c&0x03C0)+0x0040)<<10); \ - if( (c & 0xFFFF0000)==0 ) c = 0xFFFD; \ } \ } @@ -168,13 +166,25 @@ static const unsigned char sqlite3Utf8Trans1[] = { || (c&0xFFFFFFFE)==0xFFFE ){ c = 0xFFFD; } \ } int sqlite3Utf8Read( - const unsigned char *z, /* First byte of UTF-8 character */ - const unsigned char *zTerm, /* Pretend this byte is 0x00 */ + const unsigned char *zIn, /* First byte of UTF-8 character */ const unsigned char **pzNext /* Write first byte past UTF-8 char here */ ){ int c; - READ_UTF8(z, zTerm, c); - *pzNext = z; + + /* Same as READ_UTF8() above but without the zTerm parameter. + ** For this routine, we assume the UTF8 string is always zero-terminated. + */ + c = *(zIn++); + if( c>=0xc0 ){ + c = sqlite3Utf8Trans1[c-0xc0]; + while( (*zIn & 0xc0)==0x80 ){ + c = (c<<6) + (0x3f & *(zIn++)); + } + if( c<0x80 + || (c&0xFFFFF800)==0xD800 + || (c&0xFFFFFFFE)==0xFFFE ){ c = 0xFFFD; } + } + *pzNext = zIn; return c; } @@ -341,7 +351,8 @@ int sqlite3VdbeMemHandleBom(Mem *pMem){ int rc = SQLITE_OK; u8 bom = 0; - if( pMem->n<0 || pMem->n>1 ){ + assert( pMem->n>=0 ); + if( pMem->n>1 ){ u8 b1 = *(u8 *)pMem->z; u8 b2 = *(((u8 *)pMem->z) + 1); if( b1==0xFE && b2==0xFF ){ @@ -407,11 +418,10 @@ int sqlite3Utf8CharLen(const char *zIn, int nByte){ int sqlite3Utf8To8(unsigned char *zIn){ unsigned char *zOut = zIn; unsigned char *zStart = zIn; - unsigned char *zTerm = &zIn[sqlite3Strlen30((char *)zIn)]; u32 c; while( zIn[0] ){ - c = sqlite3Utf8Read(zIn, zTerm, (const u8**)&zIn); + c = sqlite3Utf8Read(zIn, (const u8**)&zIn); if( c!=0xfffd ){ WRITE_UTF8(zOut, c); } @@ -488,7 +498,6 @@ void sqlite3UtfSelfTest(void){ unsigned int i, t; unsigned char zBuf[20]; unsigned char *z; - unsigned char *zTerm; int n; unsigned int c; @@ -498,9 +507,8 @@ void sqlite3UtfSelfTest(void){ n = (int)(z-zBuf); assert( n>0 && n<=4 ); z[0] = 0; - zTerm = z; z = zBuf; - c = sqlite3Utf8Read(z, zTerm, (const u8**)&z); + c = sqlite3Utf8Read(z, (const u8**)&z); t = i; if( i>=0xD800 && i<=0xDFFF ) t = 0xFFFD; if( (i&0xFFFFFFFE)==0xFFFE ) t = 0xFFFD;