diff options
author | wtc%google.com <devnull@localhost> | 2012-12-07 01:59:38 +0000 |
---|---|---|
committer | wtc%google.com <devnull@localhost> | 2012-12-07 01:59:38 +0000 |
commit | 4cef7c531c4098642e8211b8a2be2cd25ae5e037 (patch) | |
tree | 3ceabb218562bcd36384fd461dabcdf48d768a75 | |
parent | 6044db0799bfb61e51f6543a7adc6d5c469b6b61 (diff) | |
download | nss-hg-4cef7c531c4098642e8211b8a2be2cd25ae5e037.tar.gz |
Bug 578561: Remove the old sdb_getTempDir() code because it always fails
with current versions of SQLite. Reimplement sdb_getTempDir() to replicate
how SQLite determines its temp directory. r=rrelyea.
-rw-r--r-- | security/nss/lib/softoken/sdb.c | 155 |
1 files changed, 60 insertions, 95 deletions
diff --git a/security/nss/lib/softoken/sdb.c b/security/nss/lib/softoken/sdb.c index c6ff11037..8ab757c45 100644 --- a/security/nss/lib/softoken/sdb.c +++ b/security/nss/lib/softoken/sdb.c @@ -30,8 +30,11 @@ #include "prenv.h" #include "prsystem.h" /* for PR_GetDirectorySeparator() */ #include "sys/stat.h" -#if defined (_WIN32) +#if defined(_WIN32) #include <io.h> +#include <windows.h> +#elif defined(XP_UNIX) +#include <unistd.h> #endif #ifdef SQLITE_UNSAFE_THREADS @@ -187,106 +190,68 @@ sdb_done(int err, int *count) } /* - * - * strdup limited to 'n' bytes. (Note: len of file is assumed to be >= len) - * - * We don't have a PORT_ version of this function, - * I suspect it's only normally available in glib, + * find out where sqlite stores the temp tables. We do this by replicating + * the logic from sqlite. */ +#if defined(_WIN32) static char * -sdb_strndup(const char *file, int len) +sdb_getTempDir(void) { - char *result = PORT_Alloc(len+1); - - if (result == NULL) { - return result; - } - - PORT_Memcpy(result, file, len); - result[len] = 0; - return result; -} - -/* - * call back from sqlite3_exec("Pragma database_list"). Looks for the - * temp directory, then return the file the temp directory is stored - * at. */ -static int -sdb_getTempDirCallback(void *arg, int columnCount, char **cval, char **cname) -{ - int i; - int found = 0; - char *file = NULL; - char *end, *dir; - char dirsep; - - /* we've already found the temp directory, don't look at any more records*/ - if (*(char **)arg) { - return SQLITE_OK; - } - - /* look at the columns to see if this record is the temp database, - * and does it say where it is stored */ - for (i=0; i < columnCount; i++) { - if (PORT_Strcmp(cname[i],"name") == 0) { - if (PORT_Strcmp(cval[i], "temp") == 0) { - found++; - continue; - } - } - if (PORT_Strcmp(cname[i],"file") == 0) { - if (cval[i] && (*cval[i] != 0)) { - file = cval[i]; - } - } - } - - /* if we couldn't find it, ask for the next record */ - if (!found || !file) { - return SQLITE_OK; - } - - /* drop of the database file name and just return the directory */ - dirsep = PR_GetDirectorySeparator(); - end = PORT_Strrchr(file, dirsep); - if (!end) { - return SQLITE_OK; - } - dir = sdb_strndup(file, end-file); - - *(char **)arg = dir; - return SQLITE_OK; + /* sqlite uses sqlite3_temp_directory if it is not NULL. We don't have + * access to sqlite3_temp_directory because it is not exported from + * sqlite3.dll. Assume sqlite3_win32_set_directory isn't called and + * sqlite3_temp_directory is NULL. + */ + char path[MAX_PATH]; + DWORD rv; + size_t len; + + rv = GetTempPathA(MAX_PATH, path); + if (rv > MAX_PATH || rv == 0) + return NULL; + len = strlen(path); + if (len == 0) + return NULL; + /* The returned string ends with a backslash, for example, "C:\TEMP\". */ + if (path[len - 1] == '\\') + path[len - 1] = '\0'; + return PORT_Strdup(path); } - -/* - * find out where sqlite stores the temp tables. We do this by creating - * a temp table, then looking for the database name that sqlite3 creates. - */ +#elif defined(XP_UNIX) static char * -sdb_getTempDir(sqlite3 *sqlDB) +sdb_getTempDir(void) { - char *tempDir = NULL; - int sqlerr; - - /* create a temporary table */ - sqlerr = sqlite3_exec(sqlDB, "CREATE TEMPORARY TABLE myTemp (id)", - NULL, 0, NULL); - if (sqlerr != SQLITE_OK) { - return NULL; - } - /* look for through the database list for the temp directory */ - sqlerr = sqlite3_exec(sqlDB, "PRAGMA database_list", - sdb_getTempDirCallback, &tempDir, NULL); - - /* drop the temp table we created */ - sqlite3_exec(sqlDB, "DROP TABLE myTemp", NULL, 0, NULL); - - if (sqlerr != SQLITE_OK) { - return NULL; - } - return tempDir; + const char *azDirs[] = { + NULL, + NULL, + "/var/tmp", + "/usr/tmp", + "/tmp", + NULL /* List terminator */ + }; + unsigned int i; + struct stat buf; + const char *zDir = NULL; + + azDirs[0] = sqlite3_temp_directory; + azDirs[1] = getenv("TMPDIR"); + + for (i = 0; i < PR_ARRAY_SIZE(azDirs); i++) { + zDir = azDirs[i]; + if (zDir == NULL) continue; + if (stat(zDir, &buf)) continue; + if (!S_ISDIR(buf.st_mode)) continue; + if (access(zDir, 07)) continue; + break; + } + + if (zDir == NULL) + return NULL; + return PORT_Strdup(zDir); } - +#else +#error "sdb_getTempDir not implemented" +#endif /* * Map SQL_LITE errors to PKCS #11 errors as best we can. @@ -1827,7 +1792,7 @@ sdb_init(char *dbname, char *table, sdbDataType type, int *inUpdate, * is to check for the existance of a local file compared to the same * check in the temp directory. If the temp directory is faster, cache * the database there. */ - tempDir = sdb_getTempDir(sqlDB); + tempDir = sdb_getTempDir(); if (tempDir) { tempOps = sdb_measureAccess(tempDir); PORT_Free(tempDir); |