diff options
author | Dmitry Stogov <dmitry@zend.com> | 2019-09-10 11:34:08 +0300 |
---|---|---|
committer | Dmitry Stogov <dmitry@zend.com> | 2019-09-10 11:34:08 +0300 |
commit | 0128f6eb8466cacfac5141382490bc385c9db8c0 (patch) | |
tree | d4c3b4f77a1337aacf30358312cb2cc45cdb7c72 | |
parent | 989959fb164906044aef5c8fdbc222a5e25d52dc (diff) | |
parent | 21c3cdf66824a0522779fa252a675173d02dc724 (diff) | |
download | php-git-0128f6eb8466cacfac5141382490bc385c9db8c0.tar.gz |
Merge branch 'PHP-7.4'
* PHP-7.4:
NEWS entry, test and minor cleanup for FFI::isNull()
add FFI::isNull() to check whether a FFI\CData is a null pointer
-rw-r--r-- | ext/ffi/ffi.c | 30 | ||||
-rw-r--r-- | ext/ffi/ffi.stub.php | 5 | ||||
-rw-r--r-- | ext/ffi/ffi_arginfo.h | 2 | ||||
-rw-r--r-- | ext/ffi/tests/045.phpt | 27 |
4 files changed, 64 insertions, 0 deletions
diff --git a/ext/ffi/ffi.c b/ext/ffi/ffi.c index 765b63181e..aae8b3ab21 100644 --- a/ext/ffi/ffi.c +++ b/ext/ffi/ffi.c @@ -4329,6 +4329,35 @@ ZEND_METHOD(FFI, string) /* {{{ */ } /* }}} */ +ZEND_METHOD(FFI, isNull) /* {{{ */ +{ + zval *zv; + zend_ffi_cdata *cdata; + zend_ffi_type *type; + + ZEND_FFI_VALIDATE_API_RESTRICTION(); + ZEND_PARSE_PARAMETERS_START(1, 1) + Z_PARAM_ZVAL(zv); + ZEND_PARSE_PARAMETERS_END(); + + ZVAL_DEREF(zv); + if (Z_TYPE_P(zv) != IS_OBJECT || Z_OBJCE_P(zv) != zend_ffi_cdata_ce) { + zend_wrong_parameter_class_error(1, "FFI\\CData", zv); + return; + } + + cdata = (zend_ffi_cdata*)Z_OBJ_P(zv); + type = ZEND_FFI_TYPE(cdata->type); + + if (type->kind != ZEND_FFI_TYPE_POINTER){ + zend_throw_error(zend_ffi_exception_ce, "FFI\\Cdata is not a pointer"); + return; + } + + RETURN_BOOL(*(void**)cdata->ptr == NULL); +} +/* }}} */ + static const zend_function_entry zend_ffi_functions[] = { ZEND_ME(FFI, cdef, arginfo_class_FFI_cdef, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC) ZEND_ME(FFI, load, arginfo_class_FFI_load, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC) @@ -4346,6 +4375,7 @@ static const zend_function_entry zend_ffi_functions[] = { ZEND_ME(FFI, memcmp, arginfo_class_FFI_memcmp, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC) ZEND_ME(FFI, memset, arginfo_class_FFI_memset, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC) ZEND_ME(FFI, string, arginfo_class_FFI_string, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC) + ZEND_ME(FFI, isNull, arginfo_class_FFI_isNull, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC) ZEND_FE_END }; diff --git a/ext/ffi/ffi.stub.php b/ext/ffi/ffi.stub.php index c315c55a1c..812217f990 100644 --- a/ext/ffi/ffi.stub.php +++ b/ext/ffi/ffi.stub.php @@ -88,4 +88,9 @@ class FFI * @return ?string */ static function string(FFI\CData $ptr, int $size = UNKNOWN) {} + + /** + * @prefer-ref $ptr + */ + static function isNull(FFI\CData $ptr) {} } diff --git a/ext/ffi/ffi_arginfo.h b/ext/ffi/ffi_arginfo.h index 0dfcd858ae..48fc90c2cd 100644 --- a/ext/ffi/ffi_arginfo.h +++ b/ext/ffi/ffi_arginfo.h @@ -69,3 +69,5 @@ ZEND_BEGIN_ARG_INFO_EX(arginfo_class_FFI_string, 0, 0, 1) ZEND_ARG_OBJ_INFO(ZEND_SEND_PREFER_REF, ptr, FFI\\CData, 0) ZEND_ARG_TYPE_INFO(0, size, IS_LONG, 0) ZEND_END_ARG_INFO() + +#define arginfo_class_FFI_isNull arginfo_class_FFI_free diff --git a/ext/ffi/tests/045.phpt b/ext/ffi/tests/045.phpt new file mode 100644 index 0000000000..8d4558e0d3 --- /dev/null +++ b/ext/ffi/tests/045.phpt @@ -0,0 +1,27 @@ +--TEST-- +FFI 045: FFI::isNull() +--SKIPIF-- +<?php require_once('skipif.inc'); ?> +--INI-- +ffi.enable=1 +--FILE-- +<?php +var_dump(FFI::isNull(FFI::new("int*"))); +$i = FFI::new("int"); +var_dump(FFI::isNull(FFI::addr($i))); +try { + var_dump(FFI::isNull(null)); +} catch (Throwable $e) { + echo get_class($e) . ": " . $e->getMessage()."\n"; +} +try { + var_dump(FFI::isNull(FFI::new("int[0]"))); +} catch (Throwable $e) { + echo get_class($e) . ": " . $e->getMessage()."\n"; +} +?> +--EXPECTF-- +bool(true) +bool(false) +TypeError: FFI::isNull() expects parameter 1 to be FFI\CData, null given +FFI\Exception: FFI\Cdata is not a pointer |