From: Wez Furlong Date: Sun, 19 Sep 2004 12:42:39 +0000 (+0000) Subject: Add transaction support. X-Git-Tag: PRE_NEW_VM_GEN_PATCH~280 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=0d4869f24b02e1c0a205a9bf6bbe7ed8b89d09a2;p=php Add transaction support. Add authorizer/safe_mode support --- diff --git a/ext/pdo_sqlite/sqlite_driver.c b/ext/pdo_sqlite/sqlite_driver.c index bba16ec66d..8e2db506db 100644 --- a/ext/pdo_sqlite/sqlite_driver.c +++ b/ext/pdo_sqlite/sqlite_driver.c @@ -168,6 +168,48 @@ static int sqlite_handle_quoter(pdo_dbh_t *dbh, const char *unquoted, int unquot return 1; } +static int sqlite_handle_begin(pdo_dbh_t *dbh TSRMLS_DC) +{ + pdo_sqlite_db_handle *H = (pdo_sqlite_db_handle *)dbh->driver_data; + char *errmsg = NULL; + + if (sqlite3_exec(H->db, "BEGIN", NULL, NULL, &errmsg) != SQLITE_OK) { + pdo_sqlite_error(dbh); + if (errmsg) + sqlite3_free(errmsg); + return 0; + } + return 1; +} + +static int sqlite_handle_commit(pdo_dbh_t *dbh TSRMLS_DC) +{ + pdo_sqlite_db_handle *H = (pdo_sqlite_db_handle *)dbh->driver_data; + char *errmsg = NULL; + + if (sqlite3_exec(H->db, "COMMIT", NULL, NULL, &errmsg) != SQLITE_OK) { + pdo_sqlite_error(dbh); + if (errmsg) + sqlite3_free(errmsg); + return 0; + } + return 1; +} + +static int sqlite_handle_rollback(pdo_dbh_t *dbh TSRMLS_DC) +{ + pdo_sqlite_db_handle *H = (pdo_sqlite_db_handle *)dbh->driver_data; + char *errmsg = NULL; + + if (sqlite3_exec(H->db, "ROLLBACK", NULL, NULL, &errmsg) != SQLITE_OK) { + pdo_sqlite_error(dbh); + if (errmsg) + sqlite3_free(errmsg); + return 0; + } + return 1; +} + static int pdo_sqlite_get_attribute(pdo_dbh_t *dbh, long attr, zval *return_value TSRMLS_DC) { pdo_sqlite_db_handle *H = (pdo_sqlite_db_handle *)dbh->driver_data; @@ -190,20 +232,67 @@ static struct pdo_dbh_methods sqlite_methods = { sqlite_handle_preparer, sqlite_handle_doer, sqlite_handle_quoter, - NULL, - NULL, - NULL, - NULL, + sqlite_handle_begin, + sqlite_handle_commit, + sqlite_handle_rollback, + NULL, /* set_attribute */ pdo_sqlite_last_insert_id, pdo_sqlite_fetch_error_func, pdo_sqlite_get_attribute }; +static char *make_filename_safe(const char *filename TSRMLS_DC) +{ + if (strncmp(filename, ":memory:", sizeof(":memory:")-1)) { + char *fullpath = expand_filepath(filename, NULL TSRMLS_CC); + + if (PG(safe_mode) && (!php_checkuid(fullpath, NULL, CHECKUID_CHECK_FILE_AND_DIR))) { + efree(fullpath); + return NULL; + } + + if (php_check_open_basedir(fullpath TSRMLS_CC)) { + efree(fullpath); + return NULL; + } + return fullpath; + } + return estrdup(filename); +} + +static int authorizer(void *autharg, int access_type, const char *arg3, const char *arg4, + const char *arg5, const char *arg6) +{ + char *filename; + switch (access_type) { + case SQLITE_COPY: + filename = make_filename_safe(arg4); + if (!filename) { + return SQLITE_DENY; + } + efree(filename); + return SQLITE_OK; + + case SQLITE_ATTACH: + filename = make_filename_safe(arg3); + if (!filename) { + return SQLITE_DENY; + } + efree(filename); + return SQLITE_OK; + + default: + /* access allowed */ + return SQLITE_OK; + } +} + static int pdo_sqlite_handle_factory(pdo_dbh_t *dbh, zval *driver_options TSRMLS_DC) /* {{{ */ { pdo_sqlite_db_handle *H; int i, ret = 0; long timeout = 60; + char *filename; H = pecalloc(1, sizeof(pdo_sqlite_db_handle), dbh->is_persistent); @@ -211,13 +300,25 @@ static int pdo_sqlite_handle_factory(pdo_dbh_t *dbh, zval *driver_options TSRMLS H->einfo.errmsg = NULL; dbh->driver_data = H; - i = sqlite3_open(dbh->data_source, &H->db); + filename = make_filename_safe(dbh->data_source); + + if (!filename) { + zend_throw_exception_ex(php_pdo_get_exception(), PDO_ERR_CANT_MAP TSRMLS_CC, + "safe_mode/open_basedir prohibits opening %s", + dbh->data_source); + goto cleanup; + } + + i = sqlite3_open(filename, &H->db); + efree(filename); if (i != SQLITE_OK) { pdo_sqlite_error(dbh); goto cleanup; } + sqlite3_set_authorizer(H->db, authorizer, NULL); + if (driver_options) { timeout = pdo_attr_lval(driver_options, PDO_ATTR_TIMEOUT, timeout TSRMLS_CC); }