Skip to content

Commit

Permalink
Merge branch 'PHP-8.3'
Browse files Browse the repository at this point in the history
* PHP-8.3:
  Fix GH-12905: FFI::new interacts badly with observers
  • Loading branch information
nielsdos committed Dec 19, 2023
2 parents b6a0e3d + 87c906c commit 1fc85a3
Show file tree
Hide file tree
Showing 2 changed files with 56 additions and 0 deletions.
23 changes: 23 additions & 0 deletions ext/ffi/ffi.c
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
#include "zend_closures.h"
#include "zend_weakrefs.h"
#include "main/SAPI.h"
#include "zend_observer.h"

#include <ffi.h>

Expand Down Expand Up @@ -5373,6 +5374,25 @@ static zend_result zend_ffi_preload(char *preload) /* {{{ */
}
/* }}} */

/* The startup code for observers adds a temporary to each function for internal use.
* The "new", "cast", and "type" functions in FFI are both static and non-static.
* Only the static versions are in the function table and the non-static versions are not.
* This means the non-static versions will be skipped by the observers startup code.
* This function fixes that by incrementing the temporary count for the non-static versions.
*/
static zend_result (*prev_zend_post_startup_cb)(void);
static zend_result ffi_fixup_temporaries(void) {
if (ZEND_OBSERVER_ENABLED) {
++zend_ffi_new_fn.T;
++zend_ffi_cast_fn.T;
++zend_ffi_type_fn.T;
}
if (prev_zend_post_startup_cb) {
return prev_zend_post_startup_cb();
}
return SUCCESS;
}

/* {{{ ZEND_MINIT_FUNCTION */
ZEND_MINIT_FUNCTION(ffi)
{
Expand All @@ -5395,6 +5415,9 @@ ZEND_MINIT_FUNCTION(ffi)
memcpy(&zend_ffi_type_fn, zend_hash_str_find_ptr(&zend_ffi_ce->function_table, "type", sizeof("type")-1), sizeof(zend_internal_function));
zend_ffi_type_fn.fn_flags &= ~ZEND_ACC_STATIC;

prev_zend_post_startup_cb = zend_post_startup_cb;
zend_post_startup_cb = ffi_fixup_temporaries;

memcpy(&zend_ffi_handlers, zend_get_std_object_handlers(), sizeof(zend_object_handlers));
zend_ffi_handlers.get_constructor = zend_fake_get_constructor;
zend_ffi_handlers.free_obj = zend_ffi_free_obj;
Expand Down
33 changes: 33 additions & 0 deletions ext/ffi/tests/gh12905.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
--TEST--
GH-12905 (FFI::new interacts badly with observers)
--EXTENSIONS--
ffi
zend_test
--SKIPIF--
<?php
try {
$libc = FFI::cdef("int printf(const char *format, ...);", "libc.so.6");
} catch (Throwable $_) {
die('skip libc.so.6 not available');
}
?>
--INI--
ffi.enable=1
zend_test.observer.enabled=1
zend_test.observer.observe_all=1
zend_test.observer.show_return_value=0
--FILE--
<?php
$ffi = FFI::cdef("", "libc.so.6");
$ffi->new("int");
?>
--EXPECTF--
<!-- init '%sgh12905.php' -->
<file '%sgh12905.php'>
<!-- init FFI::cdef() -->
<FFI::cdef>
</FFI::cdef>
<!-- init FFI::new() -->
<FFI::new>
</FFI::new>
</file '%sgh12905.php'>

0 comments on commit 1fc85a3

Please sign in to comment.