aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authordrh <drh@noemail.net>2012-05-10 12:17:18 +0000
committerdrh <drh@noemail.net>2012-05-10 12:17:18 +0000
commitcaee673b0d506d1e5d77a68692b67392323dbb1a (patch)
tree7b218f4642ab035c0b20cb4b990ac80e3d9f33f6 /src
parent0d7706f41a23c2c12201109cee0aace4e243cd95 (diff)
parentaeb281c2ea466efc179686f192be4f62387ab472 (diff)
downloadsqlite-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.c93
-rw-r--r--src/parse.y13
-rw-r--r--src/sqlite.h.in1
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))