@@ -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,77 @@ 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
+ 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 )
789
807
{
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 );
794
811
if (!filename ) {
795
812
return SQLITE_DENY ;
796
813
}
797
814
efree (filename );
798
- return SQLITE_OK ;
799
815
}
816
+ }
800
817
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
+ }
804
857
}
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 ;
805
866
}
806
867
807
868
static 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) /* {{
843
904
goto cleanup ;
844
905
}
845
906
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 );
849
908
850
909
if (driver_options ) {
851
910
timeout = pdo_attr_lval (driver_options , PDO_ATTR_TIMEOUT , timeout );
0 commit comments