From a3e52afebe77517ca10d98ba57fefe3f178d56b6 Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Fri, 29 Mar 2019 00:02:26 +0300 Subject: [PATCH] Fixed bug #77768 (FFI: Builtin Types Should Not Raise Error On Redeclaration) --- ext/ffi/ffi.c | 30 +++++++++++++++++++++++++++- ext/ffi/tests/bug77768.phpt | 39 +++++++++++++++++++++++++++++++++++++ 2 files changed, 68 insertions(+), 1 deletion(-) create mode 100644 ext/ffi/tests/bug77768.phpt diff --git a/ext/ffi/ffi.c b/ext/ffi/ffi.c index ba15151dd5..e8061a4682 100644 --- a/ext/ffi/ffi.c +++ b/ext/ffi/ffi.c @@ -5772,11 +5772,39 @@ void zend_ffi_declare(const char *name, size_t name_len, zend_ffi_dcl *dcl) /* { FFI_G(symbols) = pemalloc(sizeof(HashTable), FFI_G(persistent)); zend_hash_init(FFI_G(symbols), 0, NULL, FFI_G(persistent) ? zend_ffi_symbol_hash_persistent_dtor : zend_ffi_symbol_hash_dtor, FFI_G(persistent)); } + zend_ffi_finalize_type(dcl); sym = zend_hash_str_find_ptr(FFI_G(symbols), name, name_len); if (sym) { + if ((dcl->flags & ZEND_FFI_DCL_STORAGE_CLASS) == ZEND_FFI_DCL_TYPEDEF + && sym->kind == ZEND_FFI_SYM_TYPE + && zend_ffi_is_same_type(ZEND_FFI_TYPE(sym->type), ZEND_FFI_TYPE(dcl->type)) + && sym->is_const == (zend_bool)(dcl->attr & ZEND_FFI_ATTR_CONST)) { + /* allowed redeclaration */ + zend_ffi_type_dtor(dcl->type); + return; + } else if ((dcl->flags & ZEND_FFI_DCL_STORAGE_CLASS) == 0 + || (dcl->flags & ZEND_FFI_DCL_STORAGE_CLASS) == ZEND_FFI_DCL_EXTERN) { + zend_ffi_type *type = ZEND_FFI_TYPE(dcl->type); + + if (type->kind == ZEND_FFI_TYPE_FUNC) { + if (sym->kind == ZEND_FFI_SYM_FUNC + && zend_ffi_same_types(ZEND_FFI_TYPE(sym->type), type)) { + /* allowed redeclaration */ + zend_ffi_type_dtor(dcl->type); + return; + } + } else { + if (sym->kind == ZEND_FFI_SYM_VAR + && zend_ffi_is_same_type(ZEND_FFI_TYPE(sym->type), type) + && sym->is_const == (zend_bool)(dcl->attr & ZEND_FFI_ATTR_CONST)) { + /* allowed redeclaration */ + zend_ffi_type_dtor(dcl->type); + return; + } + } + } zend_ffi_parser_error("redeclaration of '%.*s' at line %d", name_len, name, FFI_G(line)); } else { - zend_ffi_finalize_type(dcl); if ((dcl->flags & ZEND_FFI_DCL_STORAGE_CLASS) == ZEND_FFI_DCL_TYPEDEF) { if (zend_ffi_validate_vla(ZEND_FFI_TYPE(dcl->type)) != SUCCESS) { zend_ffi_cleanup_dcl(dcl); diff --git a/ext/ffi/tests/bug77768.phpt b/ext/ffi/tests/bug77768.phpt new file mode 100644 index 0000000000..6c29db59d7 --- /dev/null +++ b/ext/ffi/tests/bug77768.phpt @@ -0,0 +1,39 @@ +--TEST-- +Bug #77768 (Redeclaration of builtin types and repeated declarations) +--SKIPIF-- + +--INI-- +ffi.enable=1 +--FILE-- +new("uint8_t"))); +var_dump(FFI::sizeof(FFI::new("uint8_t"))); +?> +--EXPECT-- +int(4) +int(1) -- 2.40.0