diff options
author | drh <drh@noemail.net> | 2012-05-10 12:17:18 +0000 |
---|---|---|
committer | drh <drh@noemail.net> | 2012-05-10 12:17:18 +0000 |
commit | caee673b0d506d1e5d77a68692b67392323dbb1a (patch) | |
tree | 7b218f4642ab035c0b20cb4b990ac80e3d9f33f6 /src | |
parent | 0d7706f41a23c2c12201109cee0aace4e243cd95 (diff) | |
parent | aeb281c2ea466efc179686f192be4f62387ab472 (diff) | |
download | sqlite-caee673b0d506d1e5d77a68692b67392323dbb1a.tar.gz sqlite-caee673b0d506d1e5d77a68692b67392323dbb1a.zip |
Merge in the windows AV-defense enhancements for open() and the table
constraint parser fixes for legacy schemas, all from trunk.
FossilOrigin-Name: 323570b8bd52c7e1b0c8c7a0e4f57f6fdebead11
Diffstat (limited to 'src')
-rw-r--r-- | src/os_win.c | 93 | ||||
-rw-r--r-- | src/parse.y | 13 | ||||
-rw-r--r-- | src/sqlite.h.in | 1 |
3 files changed, 88 insertions, 19 deletions
diff --git a/src/os_win.c b/src/os_win.c index 358b70c12..fcfe0118e 100644 --- a/src/os_win.c +++ b/src/os_win.c @@ -3032,6 +3032,35 @@ static int getTempname(int nBuf, char *zBuf){ } /* +** Return TRUE if the named file is really a directory. Return false if +** it is something other than a directory, or if there is any kind of memory +** allocation failure. +*/ +static int winIsDir(const void *zConverted){ + DWORD attr; + int rc = 0; + DWORD lastErrno; + + if( isNT() ){ + int cnt = 0; + WIN32_FILE_ATTRIBUTE_DATA sAttrData; + memset(&sAttrData, 0, sizeof(sAttrData)); + while( !(rc = osGetFileAttributesExW((LPCWSTR)zConverted, + GetFileExInfoStandard, + &sAttrData)) && retryIoerr(&cnt, &lastErrno) ){} + if( !rc ){ + return 0; /* Invalid name? */ + } + attr = sAttrData.dwFileAttributes; +#if SQLITE_OS_WINCE==0 + }else{ + attr = osGetFileAttributesA((char*)zConverted); +#endif + } + return (attr!=INVALID_FILE_ATTRIBUTES) && (attr&FILE_ATTRIBUTE_DIRECTORY); +} + +/* ** Open a file. */ static int winOpen( @@ -3137,6 +3166,11 @@ static int winOpen( return SQLITE_IOERR_NOMEM; } + if( winIsDir(zConverted) ){ + sqlite3_free(zConverted); + return SQLITE_CANTOPEN_ISDIR; + } + if( isReadWrite ){ dwDesiredAccess = GENERIC_READ | GENERIC_WRITE; }else{ @@ -3186,11 +3220,9 @@ static int winOpen( dwCreationDisposition, dwFlagsAndAttributes, NULL))==INVALID_HANDLE_VALUE && - retryIoerr(&cnt, &lastErrno) ){} -/* isNT() is 1 if SQLITE_OS_WINCE==1, so this else is never executed. -** Since the ANSI version of these Windows API do not exist for WINCE, -** it's important to not reference them for WINCE builds. -*/ + retryIoerr(&cnt, &lastErrno) ){ + /* Noop */ + } #if SQLITE_OS_WINCE==0 }else{ while( (h = osCreateFileA((LPCSTR)zConverted, @@ -3199,7 +3231,9 @@ static int winOpen( dwCreationDisposition, dwFlagsAndAttributes, NULL))==INVALID_HANDLE_VALUE && - retryIoerr(&cnt, &lastErrno) ){} + retryIoerr(&cnt, &lastErrno) ){ + /* Noop */ + } #endif } @@ -3279,6 +3313,7 @@ static int winDelete( ){ int cnt = 0; int rc; + DWORD attr; DWORD lastErrno; void *zConverted; UNUSED_PARAMETER(pVfs); @@ -3290,20 +3325,50 @@ static int winDelete( return SQLITE_IOERR_NOMEM; } if( isNT() ){ - rc = 1; - while( osGetFileAttributesW(zConverted)!=INVALID_FILE_ATTRIBUTES && - (rc = osDeleteFileW(zConverted))==0 && retryIoerr(&cnt, &lastErrno) ){} - rc = rc ? SQLITE_OK : SQLITE_ERROR; + do { + attr = osGetFileAttributesW(zConverted); + if ( attr==INVALID_FILE_ATTRIBUTES ){ + rc = SQLITE_OK; /* Already gone? */ + break; + } + if ( attr&FILE_ATTRIBUTE_DIRECTORY ){ + rc = SQLITE_ERROR; /* Files only. */ + break; + } + if ( osDeleteFileW(zConverted) ){ + rc = SQLITE_OK; /* Deleted OK. */ + break; + } + if ( !retryIoerr(&cnt, &lastErrno) ){ + rc = SQLITE_ERROR; /* No more retries. */ + break; + } + } while(1); /* isNT() is 1 if SQLITE_OS_WINCE==1, so this else is never executed. ** Since the ANSI version of these Windows API do not exist for WINCE, ** it's important to not reference them for WINCE builds. */ #if SQLITE_OS_WINCE==0 }else{ - rc = 1; - while( osGetFileAttributesA(zConverted)!=INVALID_FILE_ATTRIBUTES && - (rc = osDeleteFileA(zConverted))==0 && retryIoerr(&cnt, &lastErrno) ){} - rc = rc ? SQLITE_OK : SQLITE_ERROR; + do { + attr = osGetFileAttributesA(zConverted); + if ( attr==INVALID_FILE_ATTRIBUTES ){ + rc = SQLITE_OK; /* Already gone? */ + break; + } + if ( attr&FILE_ATTRIBUTE_DIRECTORY ){ + rc = SQLITE_ERROR; /* Files only. */ + break; + } + if ( osDeleteFileA(zConverted) ){ + rc = SQLITE_OK; /* Deleted OK. */ + break; + } + if ( !retryIoerr(&cnt, &lastErrno) ){ + rc = SQLITE_ERROR; /* No more retries. */ + break; + } + } while(1); #endif } if( rc ){ diff --git a/src/parse.y b/src/parse.y index 49406e1e7..8b5635c67 100644 --- a/src/parse.y +++ b/src/parse.y @@ -185,6 +185,7 @@ column(A) ::= columnid(X) type carglist. { columnid(A) ::= nm(X). { sqlite3AddColumn(pParse,&X); A = X; + pParse->constraintName.n = 0; } @@ -273,10 +274,9 @@ signed ::= minus_num. // "carglist" is a list of additional constraints that come after the // column name and column type in a CREATE TABLE statement. // -carglist ::= carglist cname ccons. +carglist ::= carglist ccons. carglist ::= . -cname ::= CONSTRAINT nm(X). {pParse->constraintName = X;} -cname ::= . {pParse->constraintName.n = 0;} +ccons ::= CONSTRAINT nm(X). {pParse->constraintName = X;} ccons ::= DEFAULT term(X). {sqlite3AddDefaultValue(pParse,&X);} ccons ::= DEFAULT LP expr(X) RP. {sqlite3AddDefaultValue(pParse,&X);} ccons ::= DEFAULT PLUS term(X). {sqlite3AddDefaultValue(pParse,&X);} @@ -339,10 +339,13 @@ init_deferred_pred_opt(A) ::= . {A = 0;} init_deferred_pred_opt(A) ::= INITIALLY DEFERRED. {A = 1;} init_deferred_pred_opt(A) ::= INITIALLY IMMEDIATE. {A = 0;} -conslist_opt(A) ::= . {A.n = 0; A.z = 0;} -conslist_opt(A) ::= COMMA(X) conslist. {A = X;} +conslist_opt(A) ::= . {A.n = 0; A.z = 0;} +conslist_opt(A) ::= COMMA(X) conslist cname. {A = X;} conslist ::= conslist COMMA cname tcons. +conslist ::= conslist cname tcons. conslist ::= cname tcons. +cname ::= . {pParse->constraintName.n = 0;} +cname ::= CONSTRAINT nm(X). {pParse->constraintName = X;} tcons ::= PRIMARY KEY LP idxlist(X) autoinc(I) RP onconf(R). {sqlite3AddPrimaryKey(pParse,X,R,I,0);} tcons ::= UNIQUE LP idxlist(X) RP onconf(R). diff --git a/src/sqlite.h.in b/src/sqlite.h.in index 035cf6437..6bb92ee9d 100644 --- a/src/sqlite.h.in +++ b/src/sqlite.h.in @@ -453,6 +453,7 @@ int sqlite3_exec( #define SQLITE_LOCKED_SHAREDCACHE (SQLITE_LOCKED | (1<<8)) #define SQLITE_BUSY_RECOVERY (SQLITE_BUSY | (1<<8)) #define SQLITE_CANTOPEN_NOTEMPDIR (SQLITE_CANTOPEN | (1<<8)) +#define SQLITE_CANTOPEN_ISDIR (SQLITE_CANTOPEN | (2<<8)) #define SQLITE_CORRUPT_VTAB (SQLITE_CORRUPT | (1<<8)) #define SQLITE_READONLY_RECOVERY (SQLITE_READONLY | (1<<8)) #define SQLITE_READONLY_CANTLOCK (SQLITE_READONLY | (2<<8)) |