Hello list, i've extended sqlite_driver to get access to the authorizer-feature of sqlite. This is my first contact with the Zend-API and my last c skill is more than a bit outdated. Could someone review/cleanup my code to get it merged to the distribution? Hint and comment welcome! Thanks, Mario Wolff
PS: Patch applys against 5.2.0!
*** php-5.2.0/ext/pdo_sqlite/sqlite_driver.c Sat Sep 16 20:30:03 2006 --- php-5.2.0-new/ext/pdo_sqlite/sqlite_driver.c Thu Nov 16 13:38:33 2006 *************** *** 31,36 **** --- 31,38 ---- #include "php_pdo_sqlite_int.h" #include "zend_exceptions.h" + static int authorizer(void *autharg, int access_type, const char *arg3, const char *arg4, + const char *arg5, const char *arg6); int _pdo_sqlite_error(pdo_dbh_t *dbh, pdo_stmt_t *stmt, const char *file, int line TSRMLS_DC) /* {{{ */ { pdo_sqlite_db_handle *H = (pdo_sqlite_db_handle *)dbh->driver_data; *************** *** 593,601 **** --- 595,653 ---- RETURN_FALSE; } /* }}} */ + + /* {{{ bool SQLite::sqliteSetAuthorizer(string name, mixed callback [, int argcount]) + Registers a UDF with the sqlite db handle */ + static PHP_METHOD(SQLite, sqliteSetAuthorizer) + { + static zval*user_authorizer=NULL; + struct pdo_sqlite_func *func; + zval *callback=NULL; + char *cbname = NULL; + pdo_dbh_t *dbh; + pdo_sqlite_db_handle *H; + int ret; + + if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|z", + &callback)) { + RETURN_FALSE; + } + + dbh = zend_object_store_get_object(getThis() TSRMLS_CC); + PDO_CONSTRUCT_CHECK; + H = (pdo_sqlite_db_handle *)dbh->driver_data; + + if( callback==NULL || callback->type == IS_STRING && ! strcmp(callback->value.str.val,"") ){ + if (user_authorizer!=NULL){ + FREE_ZVAL(user_authorizer); + sqlite3_set_authorizer(H->db, authorizer,NULL); + } + RETURN_TRUE; + } + + if (!zend_is_callable(callback, 0, &cbname)) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "function '%s' is not callable", cbname); + efree(cbname); + RETURN_FALSE; + } + efree(cbname); + + + if (user_authorizer!=NULL){ + FREE_ZVAL(user_authorizer); + } + + MAKE_STD_ZVAL(user_authorizer); + ZVAL_STRING(user_authorizer, callback->value.str.val, 1); + sqlite3_set_authorizer(H->db, authorizer, user_authorizer); + RETURN_TRUE; + } + /* }}} */ + static zend_function_entry dbh_methods[] = { PHP_ME(SQLite, sqliteCreateFunction, NULL, ZEND_ACC_PUBLIC) PHP_ME(SQLite, sqliteCreateAggregate, NULL, ZEND_ACC_PUBLIC) + PHP_ME(SQLite, sqliteSetAuthorizer, NULL, ZEND_ACC_PUBLIC) {NULL, NULL, NULL} }; *************** *** 663,694 **** 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: { ! TSRMLS_FETCH(); ! filename = make_filename_safe(arg4 TSRMLS_CC); ! if (!filename) { ! return SQLITE_DENY; } - efree(filename); - return SQLITE_OK; - } ! case SQLITE_ATTACH: { ! TSRMLS_FETCH(); ! filename = make_filename_safe(arg3 TSRMLS_CC); ! 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) /* {{{ */ --- 715,861 ---- static int authorizer(void *autharg, int access_type, const char *arg3, const char *arg4, const char *arg5, const char *arg6) { + zval *callback=NULL,*zaccess_type,*zarg3,*zarg4,*zarg5,*zarg6; + int retval=SQLITE_OK; char *filename; ! if (PG(safe_mode) || (PG(open_basedir) && *PG(open_basedir))) { ! switch (access_type) { ! case SQLITE_COPY: { ! TSRMLS_FETCH(); ! filename = make_filename_safe(arg4 TSRMLS_CC); ! if (!filename) { ! retval=SQLITE_DENY; ! }else{ ! efree(filename); ! retval=SQLITE_OK; ! } } ! case SQLITE_ATTACH: { ! TSRMLS_FETCH(); ! filename = make_filename_safe(arg3 TSRMLS_CC); ! if (!filename) { ! retval=SQLITE_DENY; ! }else{ ! efree(filename); ! retval=SQLITE_OK; ! } } ! default: ! /* access allowed */ ! retval=SQLITE_OK; ! } ! } ! if( retval==SQLITE_OK && autharg!=NULL ){ ! callback=(zval*)autharg; ! zval **args[5]; ! zend_fcall_info_cache fci_cache = empty_fcall_info_cache; ! zval *result = NULL; ! zend_fcall_info fci; ! char* zCode; ! switch( access_type ){ ! case SQLITE_COPY : zCode="SQLITE_COPY"; break; ! case SQLITE_CREATE_INDEX : zCode="SQLITE_CREATE_INDEX"; break; ! case SQLITE_CREATE_TABLE : zCode="SQLITE_CREATE_TABLE"; break; ! case SQLITE_CREATE_TEMP_INDEX : zCode="SQLITE_CREATE_TEMP_INDEX"; break; ! case SQLITE_CREATE_TEMP_TABLE : zCode="SQLITE_CREATE_TEMP_TABLE"; break; ! case SQLITE_CREATE_TEMP_TRIGGER: zCode="SQLITE_CREATE_TEMP_TRIGGER"; break; ! case SQLITE_CREATE_TEMP_VIEW : zCode="SQLITE_CREATE_TEMP_VIEW"; break; ! case SQLITE_CREATE_TRIGGER : zCode="SQLITE_CREATE_TRIGGER"; break; ! case SQLITE_CREATE_VIEW : zCode="SQLITE_CREATE_VIEW"; break; ! case SQLITE_DELETE : zCode="SQLITE_DELETE"; break; ! case SQLITE_DROP_INDEX : zCode="SQLITE_DROP_INDEX"; break; ! case SQLITE_DROP_TABLE : zCode="SQLITE_DROP_TABLE"; break; ! case SQLITE_DROP_TEMP_INDEX : zCode="SQLITE_DROP_TEMP_INDEX"; break; ! case SQLITE_DROP_TEMP_TABLE : zCode="SQLITE_DROP_TEMP_TABLE"; break; ! case SQLITE_DROP_TEMP_TRIGGER : zCode="SQLITE_DROP_TEMP_TRIGGER"; break; ! case SQLITE_DROP_TEMP_VIEW : zCode="SQLITE_DROP_TEMP_VIEW"; break; ! case SQLITE_DROP_TRIGGER : zCode="SQLITE_DROP_TRIGGER"; break; ! case SQLITE_DROP_VIEW : zCode="SQLITE_DROP_VIEW"; break; ! case SQLITE_INSERT : zCode="SQLITE_INSERT"; break; ! case SQLITE_PRAGMA : zCode="SQLITE_PRAGMA"; break; ! case SQLITE_READ : zCode="SQLITE_READ"; break; ! case SQLITE_SELECT : zCode="SQLITE_SELECT"; break; ! case SQLITE_TRANSACTION : zCode="SQLITE_TRANSACTION"; break; ! case SQLITE_UPDATE : zCode="SQLITE_UPDATE"; break; ! case SQLITE_ATTACH : zCode="SQLITE_ATTACH"; break; ! case SQLITE_DETACH : zCode="SQLITE_DETACH"; break; ! case SQLITE_ALTER_TABLE : zCode="SQLITE_ALTER_TABLE"; break; ! case SQLITE_REINDEX : zCode="SQLITE_REINDEX"; break; ! case SQLITE_ANALYZE : zCode="SQLITE_ANALYZE"; break; ! case SQLITE_CREATE_VTABLE : zCode="SQLITE_CREATE_VTABLE"; break; ! case SQLITE_DROP_VTABLE : zCode="SQLITE_DROP_VTABLE"; break; ! default : zCode="????"; break; ! } ! MAKE_STD_ZVAL(zaccess_type); ! ZVAL_STRING(zaccess_type,zCode, 1); ! args[0]=&zaccess_type; ! ! MAKE_STD_ZVAL(zarg3); ! if( arg3!=NULL ){ ! ZVAL_STRING(zarg3,(char*)arg3, 1); ! }else{ ! ZVAL_STRING(zarg3,"", 1); ! } ! args[1]=&zarg3; ! ! MAKE_STD_ZVAL(zarg4); ! if( arg4!=NULL ){ ! ZVAL_STRING(zarg4,(char*)arg4, 1); ! }else{ ! ZVAL_STRING(zarg4,"", 1); ! } ! args[2]=&zarg4; ! ! MAKE_STD_ZVAL(zarg5); ! if( arg5!=NULL ){ ! ZVAL_STRING(zarg5,(char*)arg5, 1); ! }else{ ! ZVAL_STRING(zarg5,"", 1); ! } ! args[3]=&zarg5; ! ! MAKE_STD_ZVAL(zarg6); ! if( arg6!=NULL ){ ! ZVAL_STRING(zarg6,(char*)arg6, 1); ! }else{ ! ZVAL_STRING(zarg6,"", 1); ! } ! args[4]=&zarg6; ! ! fci.size = sizeof(fci); ! fci.function_table = EG(function_table); ! fci.function_name = callback; ! fci.symbol_table = NULL; ! fci.object_pp = NULL; ! fci.retval_ptr_ptr = &result; ! fci.param_count = 5; ! fci.params = args; ! fci.no_separation = 0; ! ! if (zend_call_function(&fci, &fci_cache TSRMLS_CC) == SUCCESS && result) { ! if( result->type==IS_BOOL ){ ! retval=(result->value.lval==0); ! }else if( result->type==IS_LONG ){ ! retval=result->value.lval; ! }else{ ! php_error_docref(NULL TSRMLS_CC, E_WARNING, "invalid return from authorizer, need bool or int"); ! retval=SQLITE_DENY; ! } ! } else { ! php_error_docref(NULL TSRMLS_CC, E_WARNING, "An error occurred while invoking the reduction callback"); ! retval=SQLITE_DENY; ! } ! ! FREE_ZVAL(zaccess_type); ! FREE_ZVAL(zarg3); ! FREE_ZVAL(zarg4); ! FREE_ZVAL(zarg5); ! FREE_ZVAL(zarg6); ! } + return retval; } static int pdo_sqlite_handle_factory(pdo_dbh_t *dbh, zval *driver_options TSRMLS_DC) /* {{{ */ *************** *** 721,729 **** goto cleanup; } ! if (PG(safe_mode) || (PG(open_basedir) && *PG(open_basedir))) { ! sqlite3_set_authorizer(H->db, authorizer, NULL); ! } if (driver_options) { timeout = pdo_attr_lval(driver_options, PDO_ATTR_TIMEOUT, timeout TSRMLS_CC); --- 888,894 ---- goto cleanup; } ! sqlite3_set_authorizer(H->db, authorizer, NULL); if (driver_options) { timeout = pdo_attr_lval(driver_options, PDO_ATTR_TIMEOUT, timeout TSRMLS_CC);
-- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php