@@ -97,6 +97,10 @@ static void pdo_sqlite_cleanup_callbacks(pdo_sqlite_db_handle *H)
9797{
9898	struct  pdo_sqlite_func  * func ;
9999
100+ 	if  (ZEND_FCC_INITIALIZED (H -> authorizer_fcc )) {
101+ 		zend_fcc_dtor (& H -> authorizer_fcc );
102+ 	}
103+ 
100104	while  (H -> funcs ) {
101105		func  =  H -> funcs ;
102106		H -> funcs  =  func -> next ;
@@ -714,6 +718,10 @@ static void pdo_sqlite_get_gc(pdo_dbh_t *dbh, zend_get_gc_buffer *gc_buffer)
714718{
715719	pdo_sqlite_db_handle  * H  =  dbh -> driver_data ;
716720
721+ 	if  (ZEND_FCC_INITIALIZED (H -> authorizer_fcc )) {
722+ 		zend_get_gc_buffer_add_fcc (gc_buffer , & H -> authorizer_fcc );
723+ 	}
724+ 
717725	struct  pdo_sqlite_func  * func  =  H -> funcs ;
718726	while  (func ) {
719727		if  (ZEND_FCC_INITIALIZED (func -> func )) {
@@ -784,24 +792,77 @@ static char *make_filename_safe(const char *filename)
784792	return  estrdup (filename );
785793}
786794
787- static  int  authorizer (void  * autharg , int  access_type , const  char  * arg3 , const  char  * arg4 ,
788- 		const  char  * arg5 , const  char  * arg6 )
795+ #define  ZVAL_NULLABLE_STRING (zv , str ) do { \
796+ 	zval *zv_ = zv; \
797+ 	const char *str_ = str; \
798+ 	if (str_) { \
799+ 		ZVAL_STRING(zv_, str_); \
800+ 	} else { \
801+ 		ZVAL_NULL(zv_); \
802+ 	} \
803+ } while (0)
804+ 
805+ static  int  authorizer (void  * autharg , int  access_type , const  char  * arg1 , const  char  * arg2 ,
806+ 		const  char  * arg3 , const  char  * arg4 )
789807{
790- 	char  * filename ;
791- 	switch  (access_type ) {
792- 		case  SQLITE_ATTACH : {
793- 			filename  =  make_filename_safe (arg3 );
808+ 	if  (PG (open_basedir ) &&  * PG (open_basedir )) {
809+ 		if  (access_type  ==  SQLITE_ATTACH ) {
810+ 			char  * filename  =  make_filename_safe (arg1 );
794811			if  (!filename ) {
795812				return  SQLITE_DENY ;
796813			}
797814			efree (filename );
798- 			return  SQLITE_OK ;
799815		}
816+ 	}
800817
801- 		default :
802- 			/* access allowed */ 
803- 			return  SQLITE_OK ;
818+ 	pdo_sqlite_db_handle  * db_obj  =  autharg ;
819+ 
820+ 	/* fallback to access allowed if authorizer callback is not defined */ 
821+ 	if  (!ZEND_FCC_INITIALIZED (db_obj -> authorizer_fcc )) {
822+ 		return  SQLITE_OK ;
823+ 	}
824+ 
825+ 	/* call userland authorizer callback, if set */ 
826+ 	zval  retval ;
827+ 	zval  argv [5 ];
828+ 
829+ 	ZVAL_LONG (& argv [0 ], access_type );
830+ 	ZVAL_NULLABLE_STRING (& argv [1 ], arg1 );
831+ 	ZVAL_NULLABLE_STRING (& argv [2 ], arg2 );
832+ 	ZVAL_NULLABLE_STRING (& argv [3 ], arg3 );
833+ 	ZVAL_NULLABLE_STRING (& argv [4 ], arg4 );
834+ 
835+ 	int  authreturn  =  SQLITE_DENY ;
836+ 
837+ 	zend_call_known_fcc (& db_obj -> authorizer_fcc , & retval , /* argc */  5 , argv , /* named_params */  NULL );
838+ 	if  (Z_ISUNDEF (retval )) {
839+ 		ZEND_ASSERT (EG (exception ));
840+ 	} else  {
841+ 		if  (Z_TYPE (retval ) !=  IS_LONG ) {
842+ 			zend_string  * func_name  =  get_active_function_or_method_name ();
843+ 			zend_type_error ("%s(): Return value of the authorizer callback must be of type int, %s returned" ,
844+ 				ZSTR_VAL (func_name ), zend_zval_value_name (& retval ));
845+ 			zend_string_release (func_name );
846+ 		} else  {
847+ 			authreturn  =  Z_LVAL (retval );
848+ 
849+ 			if  (authreturn  !=  SQLITE_OK  &&  authreturn  !=  SQLITE_IGNORE  &&  authreturn  !=  SQLITE_DENY ) {
850+ 				zend_string  * func_name  =  get_active_function_or_method_name ();
851+ 				zend_value_error ("%s(): Return value of the authorizer callback must be one of Pdo\\Sqlite::OK, Pdo\\Sqlite::DENY, or Pdo\\Sqlite::IGNORE" ,
852+ 					ZSTR_VAL (func_name ));
853+ 				zend_string_release (func_name );
854+ 				authreturn  =  SQLITE_DENY ;
855+ 			}
856+ 		}
804857	}
858+ 
859+ 	zval_ptr_dtor (& retval );
860+ 	zval_ptr_dtor (& argv [1 ]);
861+ 	zval_ptr_dtor (& argv [2 ]);
862+ 	zval_ptr_dtor (& argv [3 ]);
863+ 	zval_ptr_dtor (& argv [4 ]);
864+ 
865+ 	return  authreturn ;
805866}
806867
807868static  int  pdo_sqlite_handle_factory (pdo_dbh_t  * dbh , zval  * driver_options ) /* {{{ */ 
@@ -843,9 +904,7 @@ static int pdo_sqlite_handle_factory(pdo_dbh_t *dbh, zval *driver_options) /* {{
843904		goto cleanup ;
844905	}
845906
846- 	if  (PG (open_basedir ) &&  * PG (open_basedir )) {
847- 		sqlite3_set_authorizer (H -> db , authorizer , NULL );
848- 	}
907+ 	sqlite3_set_authorizer (H -> db , authorizer , H );
849908
850909	if  (driver_options ) {
851910		timeout  =  pdo_attr_lval (driver_options , PDO_ATTR_TIMEOUT , timeout );
0 commit comments