@@ -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 ;
@@ -701,6 +705,10 @@ static void pdo_sqlite_get_gc(pdo_dbh_t *dbh, zend_get_gc_buffer *gc_buffer)
701
705
{
702
706
pdo_sqlite_db_handle * H = dbh -> driver_data ;
703
707
708
+ if (ZEND_FCC_INITIALIZED (H -> authorizer_fcc )) {
709
+ zend_get_gc_buffer_add_fcc (gc_buffer , & H -> authorizer_fcc );
710
+ }
711
+
704
712
struct pdo_sqlite_func * func = H -> funcs ;
705
713
while (func ) {
706
714
if (ZEND_FCC_INITIALIZED (func -> func )) {
@@ -771,24 +779,69 @@ static char *make_filename_safe(const char *filename)
771
779
return estrdup (filename );
772
780
}
773
781
774
- static int authorizer (void * autharg , int access_type , const char * arg3 , const char * arg4 ,
775
- const char * arg5 , const char * arg6 )
782
+ #define ZVAL_NULLABLE_STRING (zv , str ) do { \
783
+ if ((str)) { \
784
+ ZVAL_STRING((zv), (str)); \
785
+ } else { \
786
+ ZVAL_NULL(zv); \
787
+ } \
788
+ } while (0)
789
+
790
+ static int authorizer (void * autharg , int access_type , const char * arg1 , const char * arg2 ,
791
+ const char * arg3 , const char * arg4 )
776
792
{
777
- char * filename ;
778
- switch (access_type ) {
779
- case SQLITE_ATTACH : {
780
- filename = make_filename_safe (arg3 );
793
+ if (PG (open_basedir ) && * PG (open_basedir )) {
794
+ if (access_type == SQLITE_ATTACH ) {
795
+ char * filename = make_filename_safe (arg1 );
781
796
if (!filename ) {
782
797
return SQLITE_DENY ;
783
798
}
784
799
efree (filename );
785
- return SQLITE_OK ;
786
800
}
801
+ }
787
802
788
- default :
789
- /* access allowed */
790
- return SQLITE_OK ;
803
+ pdo_sqlite_db_handle * db_obj = autharg ;
804
+
805
+ /* fallback to access allowed if authorizer callback is not defined */
806
+ if (!ZEND_FCC_INITIALIZED (db_obj -> authorizer_fcc )) {
807
+ return SQLITE_OK ;
808
+ }
809
+
810
+ /* call userland authorizer callback, if set */
811
+ zval retval ;
812
+ zval argv [5 ];
813
+
814
+ ZVAL_LONG (& argv [0 ], access_type );
815
+ ZVAL_NULLABLE_STRING (& argv [1 ], arg1 );
816
+ ZVAL_NULLABLE_STRING (& argv [2 ], arg2 );
817
+ ZVAL_NULLABLE_STRING (& argv [3 ], arg3 );
818
+ ZVAL_NULLABLE_STRING (& argv [4 ], arg4 );
819
+
820
+ int authreturn = SQLITE_DENY ;
821
+
822
+ zend_call_known_fcc (& db_obj -> authorizer_fcc , & retval , /* argc */ 5 , argv , /* named_params */ NULL );
823
+ if (Z_ISUNDEF (retval )) {
824
+ ZEND_ASSERT (EG (exception ));
825
+ } else {
826
+ if (Z_TYPE (retval ) != IS_LONG ) {
827
+ zend_throw_exception_ex (php_pdo_get_exception (), 0 , "The authorizer callback returned an invalid type: expected int" );
828
+ } else {
829
+ authreturn = Z_LVAL (retval );
830
+
831
+ if (authreturn != SQLITE_OK && authreturn != SQLITE_IGNORE && authreturn != SQLITE_DENY ) {
832
+ zend_throw_exception_ex (php_pdo_get_exception (), 0 , "The authorizer callback returned an invalid value: %d" , authreturn );
833
+ authreturn = SQLITE_DENY ;
834
+ }
835
+ }
791
836
}
837
+
838
+ zval_ptr_dtor (& retval );
839
+ zval_ptr_dtor (& argv [1 ]);
840
+ zval_ptr_dtor (& argv [2 ]);
841
+ zval_ptr_dtor (& argv [3 ]);
842
+ zval_ptr_dtor (& argv [4 ]);
843
+
844
+ return authreturn ;
792
845
}
793
846
794
847
static int pdo_sqlite_handle_factory (pdo_dbh_t * dbh , zval * driver_options ) /* {{{ */
@@ -830,9 +883,7 @@ static int pdo_sqlite_handle_factory(pdo_dbh_t *dbh, zval *driver_options) /* {{
830
883
goto cleanup ;
831
884
}
832
885
833
- if (PG (open_basedir ) && * PG (open_basedir )) {
834
- sqlite3_set_authorizer (H -> db , authorizer , NULL );
835
- }
886
+ sqlite3_set_authorizer (H -> db , authorizer , H );
836
887
837
888
if (driver_options ) {
838
889
timeout = pdo_attr_lval (driver_options , PDO_ATTR_TIMEOUT , timeout );
0 commit comments