@@ -97,6 +97,10 @@ static void pdo_sqlite_cleanup_callbacks(pdo_sqlite_db_handle *H)
97
97
{
98
98
struct pdo_sqlite_func * func ;
99
99
100
+ if (ZEND_FCC_INITIALIZED (H -> authorizer_fcc )) {
101
+ zend_fcc_dtor (& H -> authorizer_fcc );
102
+ }
103
+
100
104
while (H -> funcs ) {
101
105
func = H -> funcs ;
102
106
H -> funcs = func -> next ;
@@ -714,6 +718,10 @@ static void pdo_sqlite_get_gc(pdo_dbh_t *dbh, zend_get_gc_buffer *gc_buffer)
714
718
{
715
719
pdo_sqlite_db_handle * H = dbh -> driver_data ;
716
720
721
+ if (ZEND_FCC_INITIALIZED (H -> authorizer_fcc )) {
722
+ zend_get_gc_buffer_add_fcc (gc_buffer , & H -> authorizer_fcc );
723
+ }
724
+
717
725
struct pdo_sqlite_func * func = H -> funcs ;
718
726
while (func ) {
719
727
if (ZEND_FCC_INITIALIZED (func -> func )) {
@@ -784,24 +792,75 @@ static char *make_filename_safe(const char *filename)
784
792
return estrdup (filename );
785
793
}
786
794
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
+ if ((str)) { \
797
+ ZVAL_STRING((zv), (str)); \
798
+ } else { \
799
+ ZVAL_NULL(zv); \
800
+ } \
801
+ } while (0)
802
+
803
+ static int authorizer (void * autharg , int access_type , const char * arg1 , const char * arg2 ,
804
+ const char * arg3 , const char * arg4 )
789
805
{
790
- char * filename ;
791
- switch (access_type ) {
792
- case SQLITE_ATTACH : {
793
- filename = make_filename_safe (arg3 );
806
+ if (PG (open_basedir ) && * PG (open_basedir )) {
807
+ if (access_type == SQLITE_ATTACH ) {
808
+ char * filename = make_filename_safe (arg1 );
794
809
if (!filename ) {
795
810
return SQLITE_DENY ;
796
811
}
797
812
efree (filename );
798
- return SQLITE_OK ;
799
813
}
814
+ }
800
815
801
- default :
802
- /* access allowed */
803
- return SQLITE_OK ;
816
+ pdo_sqlite_db_handle * db_obj = autharg ;
817
+
818
+ /* fallback to access allowed if authorizer callback is not defined */
819
+ if (!ZEND_FCC_INITIALIZED (db_obj -> authorizer_fcc )) {
820
+ return SQLITE_OK ;
804
821
}
822
+
823
+ /* call userland authorizer callback, if set */
824
+ zval retval ;
825
+ zval argv [5 ];
826
+
827
+ ZVAL_LONG (& argv [0 ], access_type );
828
+ ZVAL_NULLABLE_STRING (& argv [1 ], arg1 );
829
+ ZVAL_NULLABLE_STRING (& argv [2 ], arg2 );
830
+ ZVAL_NULLABLE_STRING (& argv [3 ], arg3 );
831
+ ZVAL_NULLABLE_STRING (& argv [4 ], arg4 );
832
+
833
+ int authreturn = SQLITE_DENY ;
834
+
835
+ zend_call_known_fcc (& db_obj -> authorizer_fcc , & retval , /* argc */ 5 , argv , /* named_params */ NULL );
836
+ if (Z_ISUNDEF (retval )) {
837
+ ZEND_ASSERT (EG (exception ));
838
+ } else {
839
+ if (Z_TYPE (retval ) != IS_LONG ) {
840
+ zend_string * func_name = get_active_function_or_method_name ();
841
+ zend_type_error ("%s(): Return value of the authorizer callback must be of type int, %s returned" ,
842
+ ZSTR_VAL (func_name ), zend_zval_value_name (& retval ));
843
+ zend_string_release (func_name );
844
+ } else {
845
+ authreturn = Z_LVAL (retval );
846
+
847
+ if (authreturn != SQLITE_OK && authreturn != SQLITE_IGNORE && authreturn != SQLITE_DENY ) {
848
+ zend_string * func_name = get_active_function_or_method_name ();
849
+ zend_value_error ("%s(): Return value of the authorizer callback must be one of Pdo\\Sqlite::OK, Pdo\\Sqlite::DENY, or Pdo\\Sqlite::IGNORE" ,
850
+ ZSTR_VAL (func_name ));
851
+ zend_string_release (func_name );
852
+ authreturn = SQLITE_DENY ;
853
+ }
854
+ }
855
+ }
856
+
857
+ zval_ptr_dtor (& retval );
858
+ zval_ptr_dtor (& argv [1 ]);
859
+ zval_ptr_dtor (& argv [2 ]);
860
+ zval_ptr_dtor (& argv [3 ]);
861
+ zval_ptr_dtor (& argv [4 ]);
862
+
863
+ return authreturn ;
805
864
}
806
865
807
866
static int pdo_sqlite_handle_factory (pdo_dbh_t * dbh , zval * driver_options ) /* {{{ */
@@ -843,9 +902,7 @@ static int pdo_sqlite_handle_factory(pdo_dbh_t *dbh, zval *driver_options) /* {{
843
902
goto cleanup ;
844
903
}
845
904
846
- if (PG (open_basedir ) && * PG (open_basedir )) {
847
- sqlite3_set_authorizer (H -> db , authorizer , NULL );
848
- }
905
+ sqlite3_set_authorizer (H -> db , authorizer , H );
849
906
850
907
if (driver_options ) {
851
908
timeout = pdo_attr_lval (driver_options , PDO_ATTR_TIMEOUT , timeout );
0 commit comments