From 864672eb692038eec660b41dc51e2d2d8ae02bd7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Brzuchalski?= Date: Mon, 7 May 2018 07:39:51 +0200 Subject: [PATCH 1/6] Initial resourceless ext/sysvshm --- .../tests/001.phpt => standard/ftok.phpt} | 0 ext/sysvshm/php_sysvshm.h | 75 +++ ext/sysvshm/sysvshm.c | 568 ++++++++++++------ ext/sysvshm/tests/002.phpt | 92 ++- ext/sysvshm/tests/003.phpt | 55 +- 5 files changed, 526 insertions(+), 264 deletions(-) rename ext/{sysvshm/tests/001.phpt => standard/ftok.phpt} (100%) diff --git a/ext/sysvshm/tests/001.phpt b/ext/standard/ftok.phpt similarity index 100% rename from ext/sysvshm/tests/001.phpt rename to ext/standard/ftok.phpt diff --git a/ext/sysvshm/php_sysvshm.h b/ext/sysvshm/php_sysvshm.h index 24d9675a69d8b..9523d3ca88e81 100644 --- a/ext/sysvshm/php_sysvshm.h +++ b/ext/sysvshm/php_sysvshm.h @@ -26,6 +26,7 @@ extern zend_module_entry sysvshm_module_entry; #define sysvshm_module_ptr &sysvshm_module_entry +// #include "php.h" #include "php_version.h" #define PHP_SYSVSHM_VERSION PHP_VERSION @@ -42,6 +43,11 @@ extern zend_module_entry sysvshm_module_entry; # include #endif +#include "zend_exceptions.h" +#include "ext/spl/spl_exceptions.h" + +zend_class_entry *shm_ce_ptr; + #define PHP_SHM_RSRC_NAME "sysvshm" typedef struct { @@ -70,6 +76,75 @@ typedef struct { sysvshm_chunk_head *ptr; /* memory address of shared memory */ } sysvshm_shm; +typedef struct { + sysvshm_shm *shm_object_ptr; + zend_object std; +} shm_object; +static zend_object_handlers shm_object_handlers; + +/* {{{ arginfo */ +ZEND_BEGIN_ARG_INFO_EX(arginfo_shm_object___construct, 0, 0, 1) + ZEND_ARG_TYPE_INFO(0, key, IS_LONG, 0) + ZEND_ARG_TYPE_INFO(0, size, IS_LONG, 1) + ZEND_ARG_TYPE_INFO(0, perm, IS_LONG, 1) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_shm_object_has, 0, 0, _IS_BOOL, NULL) + ZEND_ARG_TYPE_INFO(0, variable_key, IS_LONG, 0) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_shm_object_free, 0, 0, IS_VOID, NULL) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_shm_object_set, 0, 2, IS_VOID, NULL) + ZEND_ARG_TYPE_INFO(0, variable_key, IS_LONG, 0) + ZEND_ARG_INFO(0, variable) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_shm_object_get, 0, 0, 2) + ZEND_ARG_TYPE_INFO(0, variable_key, IS_LONG, 0) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_shm_object_remove, 0, 1, IS_VOID, NULL) + ZEND_ARG_TYPE_INFO(0, variable_key, IS_LONG, 0) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_WITH_RETURN_OBJ_INFO_EX(arginfo_shm_attach, 0, 1, SharedMemoryBlock, 0) + ZEND_ARG_TYPE_INFO(0, key, IS_LONG, 0) + ZEND_ARG_TYPE_INFO(0, size, IS_LONG, 1) + ZEND_ARG_TYPE_INFO(0, mode, IS_LONG, 1) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_shm_detach, 0, 1, _IS_BOOL, NULL) + ZEND_ARG_OBJ_INFO(0, object, SharedMemoryBlock, 0) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_shm_has_var, 0, 2, _IS_BOOL, NULL) + ZEND_ARG_OBJ_INFO(0, object, SharedMemoryBlock, 0) + ZEND_ARG_TYPE_INFO(0, variable_key, IS_LONG, 0) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_shm_remove, 0, 1, IS_VOID, NULL) + ZEND_ARG_OBJ_INFO(0, object, SharedMemoryBlock, 0) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_shm_put_var, 0, 3, _IS_BOOL, NULL) + ZEND_ARG_OBJ_INFO(0, object, SharedMemoryBlock, 0) + ZEND_ARG_TYPE_INFO(0, variable_key, IS_LONG, 0) + ZEND_ARG_INFO(0, variable) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_shm_get_var, 0, 0, 2) + ZEND_ARG_OBJ_INFO(0, object, SharedMemoryBlock, 0) + ZEND_ARG_TYPE_INFO(0, variable_key, IS_LONG, 0) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_shm_remove_var, 0, 0, 2) + ZEND_ARG_OBJ_INFO(0, object, SharedMemoryBlock, 0) + ZEND_ARG_TYPE_INFO(0, variable_key, IS_LONG, 0) +ZEND_END_ARG_INFO() +/* }}} */ + PHP_MINIT_FUNCTION(sysvshm); PHP_FUNCTION(shm_attach); PHP_FUNCTION(shm_detach); diff --git a/ext/sysvshm/sysvshm.c b/ext/sysvshm/sysvshm.c index d30d826238c83..7f1983c8c943f 100644 --- a/ext/sysvshm/sysvshm.c +++ b/ext/sysvshm/sysvshm.c @@ -29,59 +29,52 @@ #endif #include "php.h" +#include "zend_types.h" -#if HAVE_SYSVSHM +// #if HAVE_SYSVSHM #include #include "php_sysvshm.h" #include "ext/standard/php_var.h" #include "zend_smart_str.h" +#include "zend_interfaces.h" #include "php_ini.h" -/* {{{ arginfo */ -ZEND_BEGIN_ARG_INFO_EX(arginfo_shm_attach, 0, 0, 1) - ZEND_ARG_INFO(0, key) - ZEND_ARG_INFO(0, memsize) - ZEND_ARG_INFO(0, perm) -ZEND_END_ARG_INFO() - -ZEND_BEGIN_ARG_INFO_EX(arginfo_shm_detach, 0, 0, 1) - ZEND_ARG_INFO(0, shm_identifier) -ZEND_END_ARG_INFO() - -ZEND_BEGIN_ARG_INFO_EX(arginfo_shm_has_var, 0, 0, 2) - ZEND_ARG_INFO(0, id) - ZEND_ARG_INFO(0, variable_key) -ZEND_END_ARG_INFO() - -ZEND_BEGIN_ARG_INFO_EX(arginfo_shm_remove, 0, 0, 1) - ZEND_ARG_INFO(0, shm_identifier) -ZEND_END_ARG_INFO() - -ZEND_BEGIN_ARG_INFO_EX(arginfo_shm_put_var, 0, 0, 3) - ZEND_ARG_INFO(0, shm_identifier) - ZEND_ARG_INFO(0, variable_key) - ZEND_ARG_INFO(0, variable) -ZEND_END_ARG_INFO() - -ZEND_BEGIN_ARG_INFO_EX(arginfo_shm_get_var, 0, 0, 2) - ZEND_ARG_INFO(0, id) - ZEND_ARG_INFO(0, variable_key) -ZEND_END_ARG_INFO() - -ZEND_BEGIN_ARG_INFO_EX(arginfo_shm_remove_var, 0, 0, 2) - ZEND_ARG_INFO(0, id) - ZEND_ARG_INFO(0, variable_key) -ZEND_END_ARG_INFO() +static inline shm_object *shm_object_from_zend_object(zend_object *object) { + return (shm_object*)((char*)(object) - XtOffsetOf(shm_object, std)); +} +static zend_object *shm_object_new(zend_class_entry *class_type) /* {{{ */ +{ + shm_object *intern = ecalloc(1, sizeof(shm_object) + zend_object_properties_size(class_type)); + + zend_object_std_init(&intern->std, class_type); + object_properties_init(&intern->std, class_type); + intern->std.handlers = &shm_object_handlers; + + return &intern->std; +} +/* }}} */ +static void shm_object_free_storage(zend_object *object) /* {{{ */ +{ + shm_object *intern = shm_object_from_zend_object(object); + + if (intern->shm_object_ptr) { + sysvshm_shm *shm_ptr = intern->shm_object_ptr; + shmdt((void *) shm_ptr->ptr); + efree(shm_ptr); + } + + zend_object_std_dtor(&intern->std); +} /* }}} */ /* {{{ sysvshm_functions[] */ static const zend_function_entry sysvshm_functions[] = { PHP_FE(shm_attach, arginfo_shm_attach) - PHP_FE(shm_remove, arginfo_shm_detach) - PHP_FE(shm_detach, arginfo_shm_remove) + PHP_FE(shm_detach, arginfo_shm_detach) + PHP_FE(shm_remove, arginfo_shm_remove) PHP_FE(shm_put_var, arginfo_shm_put_var) PHP_FE(shm_has_var, arginfo_shm_has_var) PHP_FE(shm_get_var, arginfo_shm_get_var) @@ -112,79 +105,50 @@ ZEND_GET_MODULE(sysvshm) #undef shm_ptr /* undefine AIX-specific macro */ -#define SHM_FETCH_RESOURCE(shm_ptr, z_ptr) do { \ - if ((shm_ptr = (sysvshm_shm *)zend_fetch_resource(Z_RES_P(z_ptr), PHP_SHM_RSRC_NAME, php_sysvshm.le_shm)) == NULL) { \ - RETURN_FALSE; \ - } \ -} while (0) - THREAD_LS sysvshm_module php_sysvshm; -static int php_put_shm_data(sysvshm_chunk_head *ptr, zend_long key, const char *data, zend_long len); -static zend_long php_check_shm_data(sysvshm_chunk_head *ptr, zend_long key); +static int shm_set_shm_data(sysvshm_chunk_head *ptr, zend_long key, const char *data, zend_long len); +static zend_long shm_has_shm_data(sysvshm_chunk_head *ptr, zend_long key); static int php_remove_shm_data(sysvshm_chunk_head *ptr, zend_long shm_varpos); -/* {{{ php_release_sysvshm - */ -static void php_release_sysvshm(zend_resource *rsrc) -{ - sysvshm_shm *shm_ptr = (sysvshm_shm *) rsrc->ptr; - shmdt((void *) shm_ptr->ptr); - efree(shm_ptr); -} -/* }}} */ - -/* {{{ PHP_MINIT_FUNCTION - */ -PHP_MINIT_FUNCTION(sysvshm) +static void shm_object_ctor(INTERNAL_FUNCTION_PARAMETERS) { - php_sysvshm.le_shm = zend_register_list_destructors_ex(php_release_sysvshm, NULL, PHP_SHM_RSRC_NAME, module_number); + shm_object *intern; + sysvshm_shm *shm_object_ptr; - if (cfg_get_long("sysvshm.init_mem", &php_sysvshm.init_mem) == FAILURE) { - php_sysvshm.init_mem=10000; - } - return SUCCESS; -} -/* }}} */ - -/* {{{ proto int shm_attach(int key [, int memsize [, int perm]]) - Creates or open a shared memory segment */ -PHP_FUNCTION(shm_attach) -{ - sysvshm_shm *shm_list_ptr; char *shm_ptr; sysvshm_chunk_head *chunk_ptr; zend_long shm_key, shm_id, shm_size = php_sysvshm.init_mem, shm_flag = 0666; - if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS(), "l|ll", &shm_key, &shm_size, &shm_flag)) { + if (SUCCESS != zend_parse_parameters_throw(ZEND_NUM_ARGS(), "l|ll", &shm_key, &shm_size, &shm_flag)) { return; } if (shm_size < 1) { - php_error_docref(NULL, E_WARNING, "Segment size must be greater than zero"); - RETURN_FALSE; + zend_throw_exception_ex(spl_ce_InvalidArgumentException, 0, "Segment size " ZEND_LONG_FMT " must be greater than zero", shm_size); + RETURN_NULL(); } - shm_list_ptr = (sysvshm_shm *) emalloc(sizeof(sysvshm_shm)); + shm_object_ptr = (sysvshm_shm *) emalloc(sizeof(sysvshm_shm)); /* get the id from a specified key or create new shared memory */ if ((shm_id = shmget(shm_key, 0, 0)) < 0) { if (shm_size < (zend_long)sizeof(sysvshm_chunk_head)) { - php_error_docref(NULL, E_WARNING, "failed for key 0x" ZEND_XLONG_FMT ": memorysize too small", shm_key); - efree(shm_list_ptr); - RETURN_FALSE; + zend_throw_exception_ex(spl_ce_InvalidArgumentException, 0, "Failed for key 0x" ZEND_XLONG_FMT ": memorysize too small", shm_key); + efree(shm_object_ptr); + RETURN_NULL(); } if ((shm_id = shmget(shm_key, shm_size, shm_flag | IPC_CREAT | IPC_EXCL)) < 0) { - php_error_docref(NULL, E_WARNING, "failed for key 0x" ZEND_XLONG_FMT ": %s", shm_key, strerror(errno)); - efree(shm_list_ptr); - RETURN_FALSE; + zend_throw_exception_ex(spl_ce_RuntimeException, 0, "Failed for key 0x" ZEND_XLONG_FMT ": %s", shm_key, strerror(errno)); + efree(shm_object_ptr); + RETURN_NULL(); } } if ((shm_ptr = shmat(shm_id, NULL, 0)) == (void *) -1) { - php_error_docref(NULL, E_WARNING, "failed for key 0x" ZEND_XLONG_FMT ": %s", shm_key, strerror(errno)); - efree(shm_list_ptr); - RETURN_FALSE; + zend_throw_exception_ex(spl_ce_RuntimeException, 0, "Failed for key 0x" ZEND_XLONG_FMT ": %s", shm_key, strerror(errno)); + efree(shm_object_ptr); + RETURN_NULL(); } /* check if shm is already initialized */ @@ -197,181 +161,401 @@ PHP_FUNCTION(shm_attach) chunk_ptr->free = shm_size-chunk_ptr->end; } - shm_list_ptr->key = shm_key; - shm_list_ptr->id = shm_id; - shm_list_ptr->ptr = chunk_ptr; + shm_object_ptr->key = shm_key; + shm_object_ptr->id = shm_id; + shm_object_ptr->ptr = chunk_ptr; - RETURN_RES(zend_register_resource(shm_list_ptr, php_sysvshm.le_shm)); + intern = shm_object_from_zend_object(Z_OBJ_P(return_value)); + intern->shm_object_ptr = shm_object_ptr; } -/* }}} */ +static int shm_set(sysvshm_shm *shm_object_ptr, zend_long shm_key, zval *arg_var) +{ + int ret; + smart_str shm_var = {0}; + php_serialize_data_t var_hash; -/* {{{ proto bool shm_detach(resource shm_identifier) - Disconnects from shared memory segment */ -PHP_FUNCTION(shm_detach) + if (!shm_object_ptr) { + smart_str_free(&shm_var); + return 0; + } + + /* setup string-variable and serialize */ + PHP_VAR_SERIALIZE_INIT(var_hash); + php_var_serialize(&shm_var, arg_var, &var_hash); + PHP_VAR_SERIALIZE_DESTROY(var_hash); + + /* insert serialized variable into shared memory */ + ret = shm_set_shm_data(shm_object_ptr->ptr, shm_key, shm_var.s? ZSTR_VAL(shm_var.s) : NULL, shm_var.s? ZSTR_LEN(shm_var.s) : 0); + + /* free string */ + smart_str_free(&shm_var); + + return ret; +} +static void shm_get(sysvshm_shm *shm_object_ptr, zend_long shm_key, zval *return_value) { zval *shm_id; - sysvshm_shm *shm_list_ptr; + char *shm_data; + zend_long shm_varpos; + sysvshm_chunk *shm_var; + php_unserialize_data_t var_hash; - if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS(), "r", &shm_id)) { - return; + /* setup string-variable and serialize */ + /* get serialized variable from shared memory */ + shm_varpos = shm_has_shm_data((shm_object_ptr->ptr), shm_key); + + if (shm_varpos < 0) { + zend_throw_exception_ex(spl_ce_OutOfBoundsException, 0, "Variable key " ZEND_LONG_FMT " doesn't exist", shm_key); + RETURN_NULL(); } - SHM_FETCH_RESOURCE(shm_list_ptr, shm_id); - RETURN_BOOL(SUCCESS == zend_list_close(Z_RES_P(shm_id))); + shm_var = (sysvshm_chunk*) ((char *)shm_object_ptr->ptr + shm_varpos); + shm_data = &shm_var->mem; + + PHP_VAR_UNSERIALIZE_INIT(var_hash); + if (php_var_unserialize(return_value, (const unsigned char **) &shm_data, (unsigned char *) shm_data + shm_var->length, &var_hash) != 1) { + zend_throw_exception(spl_ce_RuntimeException, "Variable data in shared memory is corrupted", 0); + RETURN_NULL(); + } + PHP_VAR_UNSERIALIZE_DESTROY(var_hash); +} + +/* {{{ proto void SharedMemoryBlock::__construct(int key [, int memsize [, int perm]]) + Argument constructor */ +ZEND_METHOD(SharedMemoryBlock, __construct) +{ + return_value = getThis(); + shm_object_ctor(INTERNAL_FUNCTION_PARAM_PASSTHRU); } /* }}} */ -/* {{{ proto bool shm_remove(resource shm_identifier) - Removes shared memory from Unix systems */ -PHP_FUNCTION(shm_remove) +/* {{{ proto void SharedMemoryBlock::has(int variable_key) + Check whether a specific entry exists */ +ZEND_METHOD(SharedMemoryBlock, has) { - zval *shm_id; - sysvshm_shm *shm_list_ptr; + zend_long shm_key; + shm_object *intern; + sysvshm_shm *shm_object_ptr; - if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS(), "r", &shm_id)) { - return; - } - SHM_FETCH_RESOURCE(shm_list_ptr, shm_id); + ZEND_PARSE_PARAMETERS_START(1, 1) + Z_PARAM_LONG(shm_key) + ZEND_PARSE_PARAMETERS_END_EX(RETURN_FALSE); - if (shmctl(shm_list_ptr->id, IPC_RMID, NULL) < 0) { - php_error_docref(NULL, E_WARNING, "failed for key 0x%x, id " ZEND_LONG_FMT ": %s", shm_list_ptr->key, Z_LVAL_P(shm_id), strerror(errno)); - RETURN_FALSE; - } + intern = shm_object_from_zend_object(Z_OBJ_P(getThis())); + shm_object_ptr = intern->shm_object_ptr; - RETURN_TRUE; + RETURN_BOOL(shm_has_shm_data(shm_object_ptr->ptr, shm_key) >= 0); } /* }}} */ -/* {{{ proto bool shm_put_var(resource shm_identifier, int variable_key, mixed variable) - Inserts or updates a variable in shared memory */ -PHP_FUNCTION(shm_put_var) +/* {{{ proto void SharedMemoryBlock::get(int variable_key) + Returns a variable from shared memory */ +ZEND_METHOD(SharedMemoryBlock, get) { - zval *shm_id, *arg_var; - int ret; zend_long shm_key; - sysvshm_shm *shm_list_ptr; - smart_str shm_var = {0}; - php_serialize_data_t var_hash; + shm_object *intern; + sysvshm_shm *shm_object_ptr; - if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS(), "rlz", &shm_id, &shm_key, &arg_var)) { - return; + ZEND_PARSE_PARAMETERS_START(1, 1) + Z_PARAM_LONG(shm_key) + ZEND_PARSE_PARAMETERS_END_EX(RETURN_FALSE); + + intern = shm_object_from_zend_object(Z_OBJ_P(getThis())); + shm_get(intern->shm_object_ptr, shm_key, return_value); +} +/* }}} */ + +/* {{{ proto void SharedMemoryBlock::set(int variable_key, mixed arg_var) + Inserts or updates a variable in shared memory + */ +ZEND_METHOD(SharedMemoryBlock, set) +{ + zval *arg_var; + zend_long shm_key; + shm_object *intern; + sysvshm_shm *shm_object_ptr; + int ret; + + ZEND_PARSE_PARAMETERS_START(2, 2) + Z_PARAM_LONG(shm_key) + Z_PARAM_ZVAL(arg_var) + ZEND_PARSE_PARAMETERS_END_EX(RETURN_FALSE); + + intern = shm_object_from_zend_object(Z_OBJ_P(getThis())); + ret = shm_set(intern->shm_object_ptr, shm_key, arg_var); + + if (ret == -1) { + zend_throw_exception(spl_ce_RuntimeException, "Not enough shared memory left", 0); } +} +/* }}} */ - /* setup string-variable and serialize */ - PHP_VAR_SERIALIZE_INIT(var_hash); - php_var_serialize(&shm_var, arg_var, &var_hash); - PHP_VAR_SERIALIZE_DESTROY(var_hash); +/* {{{ proto void SharedMemoryBlock::remove() + Removes a variable from shared memory */ +ZEND_METHOD(SharedMemoryBlock, remove) +{ + zend_long shm_key, shm_varpos; + shm_object *intern; + sysvshm_shm *shm_object_ptr; - shm_list_ptr = zend_fetch_resource(Z_RES_P(shm_id), PHP_SHM_RSRC_NAME, php_sysvshm.le_shm); - if (!shm_list_ptr) { - smart_str_free(&shm_var); - RETURN_FALSE; + ZEND_PARSE_PARAMETERS_START(1, 1) + Z_PARAM_LONG(shm_key) + ZEND_PARSE_PARAMETERS_END_EX(RETURN_FALSE); + + intern = shm_object_from_zend_object(Z_OBJ_P(getThis())); + shm_object_ptr = intern->shm_object_ptr; + shm_varpos = shm_has_shm_data((shm_object_ptr->ptr), shm_key); + + if (shm_varpos < 0) { + zend_throw_exception_ex(spl_ce_OutOfBoundsException, 0, "Variable key " ZEND_LONG_FMT " doesn't exist", shm_key); + RETURN_NULL(); } + php_remove_shm_data((shm_object_ptr->ptr), shm_varpos); + RETURN_NULL(); +} +/* }}} */ - /* insert serialized variable into shared memory */ - ret = php_put_shm_data(shm_list_ptr->ptr, shm_key, shm_var.s? ZSTR_VAL(shm_var.s) : NULL, shm_var.s? ZSTR_LEN(shm_var.s) : 0); +/* {{{ proto void SharedMemoryBlock::free() + Removes shared memory from Unix systems */ +ZEND_METHOD(SharedMemoryBlock, free) +{ + shm_object *intern; + sysvshm_shm *shm_object_ptr; - /* free string */ - smart_str_free(&shm_var); + ZEND_PARSE_PARAMETERS_START(0, 0) + ZEND_PARSE_PARAMETERS_END_EX(RETURN_FALSE); - if (ret == -1) { - php_error_docref(NULL, E_WARNING, "not enough shared memory left"); - RETURN_FALSE; + intern = shm_object_from_zend_object(Z_OBJ_P(getThis())); + shm_object_ptr = intern->shm_object_ptr; + if (shmctl(shm_object_ptr->id, IPC_RMID, NULL) < 0) { + zend_throw_exception_ex(spl_ce_RuntimeException, 0, "Failed for key 0x%x, id " ZEND_LONG_FMT ": %s", shm_object_ptr->key, shm_object_ptr->id, strerror(errno)); } - RETURN_TRUE; + RETURN_NULL(); } /* }}} */ -/* {{{ proto mixed shm_get_var(resource id, int variable_key) - Returns a variable from shared memory */ -PHP_FUNCTION(shm_get_var) +/* {{{ PHP_MINIT_FUNCTION + */ +PHP_MINIT_FUNCTION(sysvshm) { - zval *shm_id; + zend_class_entry tmp_ce; + zend_function_entry shm_object_methods[] = { + PHP_ME(SharedMemoryBlock, __construct, arginfo_shm_object___construct, ZEND_ACC_CTOR|ZEND_ACC_PUBLIC) + PHP_ME(SharedMemoryBlock, has, arginfo_shm_object_has, ZEND_ACC_PUBLIC) + PHP_ME(SharedMemoryBlock, get, arginfo_shm_object_get, ZEND_ACC_PUBLIC) + PHP_ME(SharedMemoryBlock, set, arginfo_shm_object_set, ZEND_ACC_PUBLIC) + PHP_ME(SharedMemoryBlock, remove, arginfo_shm_object_remove, ZEND_ACC_PUBLIC) + PHP_ME(SharedMemoryBlock, free, arginfo_shm_object_free, ZEND_ACC_PUBLIC) + PHP_FE_END + }; + INIT_CLASS_ENTRY(tmp_ce, "SharedMemoryBlock", shm_object_methods); + tmp_ce.create_object = shm_object_new; + shm_ce_ptr = zend_register_internal_class_ex(&tmp_ce, NULL); + memcpy(&shm_object_handlers, zend_get_std_object_handlers(), sizeof(zend_object_handlers)); + shm_object_handlers.offset = XtOffsetOf(shm_object, std); + shm_object_handlers.free_obj = shm_object_free_storage; + + if (cfg_get_long("sysvshm.init_mem", &php_sysvshm.init_mem) == FAILURE) { + php_sysvshm.init_mem=10000; + } + return SUCCESS; +} +/* }}} */ + +/* {{{ proto SharedMemoryBlock shm_attach(int key [, int memsize [, int perm]]) + Creates or open a shared memory segment */ +PHP_FUNCTION(shm_attach) +{ + object_init_ex(return_value, shm_ce_ptr); + shm_object_ctor(INTERNAL_FUNCTION_PARAM_PASSTHRU); +} +/* }}} */ + +/* {{{ proto void shm_detach(SharedMemoryBlock object) + Disconnects from shared memory segment */ +PHP_FUNCTION(shm_detach) +{ + zval *object; + shm_object *intern; + sysvshm_shm *shm_object_ptr; + + ZEND_PARSE_PARAMETERS_START(1, 1) + Z_PARAM_OBJECT_OF_CLASS_EX(object, shm_ce_ptr, 1, 0) + ZEND_PARSE_PARAMETERS_END_EX(RETURN_NULL()); + + intern = shm_object_from_zend_object(Z_OBJ_P(object)); + if (!intern->shm_object_ptr) { + zend_throw_exception_ex(spl_ce_InvalidArgumentException, 0, "Invalid object %s internal state", ZSTR_VAL(Z_OBJCE_P(object)->name)); + } + + shm_object_free_storage(Z_OBJ_P(object)); +} +/* }}} */ + +/* {{{ proto bool shm_remove(SharedMemoryBlock object) + Removes shared memory from Unix systems */ +PHP_FUNCTION(shm_remove) +{ + zval *object; + shm_object *intern; + sysvshm_shm *shm_object_ptr; + + ZEND_PARSE_PARAMETERS_START(1, 1) + Z_PARAM_OBJECT_OF_CLASS_EX(object, shm_ce_ptr, 1, 0) + ZEND_PARSE_PARAMETERS_END_EX(RETURN_FALSE); + + intern = shm_object_from_zend_object(Z_OBJ_P(object)); + if (!intern->shm_object_ptr) { + zend_throw_exception_ex(spl_ce_InvalidArgumentException, 0, "Invalid object %s internal state", ZSTR_VAL(Z_OBJCE_P(object)->name)); + } + shm_object_ptr = intern->shm_object_ptr; + + if (shmctl(shm_object_ptr->id, IPC_RMID, NULL) < 0) { + zend_throw_exception_ex(spl_ce_RuntimeException, 0, "Failed for key 0x%x, id " ZEND_LONG_FMT ": %s", shm_object_ptr->key, shm_object_ptr->id, strerror(errno)); + } + shm_object_free_storage(Z_OBJ_P(object)); +} +/* }}} */ + +/* {{{ proto bool shm_put_var(resource object, int variable_key, mixed variable) + Inserts or updates a variable in shared memory */ +PHP_FUNCTION(shm_put_var) +{ + zval *object, *arg_var; zend_long shm_key; - sysvshm_shm *shm_list_ptr; - char *shm_data; - zend_long shm_varpos; - sysvshm_chunk *shm_var; - php_unserialize_data_t var_hash; + shm_object *intern; + sysvshm_shm *shm_object_ptr; + int ret; - if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS(), "rl", &shm_id, &shm_key)) { - return; + ZEND_PARSE_PARAMETERS_START(3, 3) + Z_PARAM_OBJECT_OF_CLASS_EX(object, shm_ce_ptr, 1, 0) + Z_PARAM_LONG(shm_key) + Z_PARAM_ZVAL(arg_var) + ZEND_PARSE_PARAMETERS_END_EX(RETURN_FALSE); + + intern = (shm_object *)shm_object_from_zend_object(Z_OBJ_P(object)); + if (intern == NULL) { + printf("\e[0;31mintern is NULL\3[0m\n\n"); + } + printf("key: %d, id: " ZEND_LONG_FMT, intern->shm_object_ptr->key, intern->shm_object_ptr->id); + if (((shm_object_ptr = (sysvshm_shm *)intern->shm_object_ptr) == NULL) || (((sysvshm_chunk_head *)intern->shm_object_ptr->ptr) == NULL)) { + zend_throw_exception_ex(spl_ce_InvalidArgumentException, 0, "Invalid object %s internal state", ZSTR_VAL(Z_OBJCE_P(object)->name)); + RETURN_NULL(); + } + printf("####\n"); + if (intern->shm_object_ptr == NULL) { + printf("\e[0;32mshm_set_shm_data BREAKE1;\e[0m\n"); + } + if (!(sysvshm_shm *)intern->shm_object_ptr->ptr) { + printf("\e[0;32mshm_set_shm_data BREAKE2;\e[0m\n"); + } + if (!(zend_long *)intern->shm_object_ptr->ptr->start) { + printf("\e[0;32mshm_set_shm_data BREAKE3;\e[0m\n"); } - SHM_FETCH_RESOURCE(shm_list_ptr, shm_id); - /* setup string-variable and serialize */ - /* get serialized variable from shared memory */ - shm_varpos = php_check_shm_data((shm_list_ptr->ptr), shm_key); + ret = shm_set(intern->shm_object_ptr, shm_key, arg_var); - if (shm_varpos < 0) { - php_error_docref(NULL, E_WARNING, "variable key " ZEND_LONG_FMT " doesn't exist", shm_key); + if (ret == -1) { + zend_throw_exception(spl_ce_RuntimeException, "Not enough shared memory left", 0); RETURN_FALSE; } - shm_var = (sysvshm_chunk*) ((char *)shm_list_ptr->ptr + shm_varpos); - shm_data = &shm_var->mem; + RETURN_TRUE; +} +/* }}} */ - PHP_VAR_UNSERIALIZE_INIT(var_hash); - if (php_var_unserialize(return_value, (const unsigned char **) &shm_data, (unsigned char *) shm_data + shm_var->length, &var_hash) != 1) { - php_error_docref(NULL, E_WARNING, "variable data in shared memory is corrupted"); - RETVAL_FALSE; - } - PHP_VAR_UNSERIALIZE_DESTROY(var_hash); +/* {{{ proto mixed shm_get_var(SharedMemoryBlock object, int variable_key) + Returns a variable from shared memory */ +PHP_FUNCTION(shm_get_var) +{ + zval *object; + zend_long shm_key; + shm_object *intern; + sysvshm_shm *shm_object_ptr; + + ZEND_PARSE_PARAMETERS_START(2, 2) + Z_PARAM_OBJECT_OF_CLASS_EX(object, shm_ce_ptr, 1, 0) + Z_PARAM_LONG(shm_key) + ZEND_PARSE_PARAMETERS_END_EX(RETURN_FALSE); + + intern = shm_object_from_zend_object(Z_OBJ_P(object)); + if (!intern->shm_object_ptr) { + zend_throw_exception_ex(spl_ce_InvalidArgumentException, 0, "Invalid object %s internal state", ZSTR_VAL(Z_OBJCE_P(object)->name)); + } + shm_get(intern->shm_object_ptr, shm_key, return_value); } /* }}} */ -/* {{{ proto bool shm_has_var(resource id, int variable_key) +/* {{{ proto bool shm_has_var(SharedMemoryBlock object, int variable_key) Checks whether a specific entry exists */ PHP_FUNCTION(shm_has_var) { - zval *shm_id; + zval *object; zend_long shm_key; - sysvshm_shm *shm_list_ptr; + shm_object *intern; + sysvshm_shm *shm_object_ptr; - if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS(), "rl", &shm_id, &shm_key)) { - return; - } - SHM_FETCH_RESOURCE(shm_list_ptr, shm_id); - RETURN_BOOL(php_check_shm_data(shm_list_ptr->ptr, shm_key) >= 0); + ZEND_PARSE_PARAMETERS_START(2, 2) + Z_PARAM_OBJECT_OF_CLASS_EX(object, shm_ce_ptr, 1, 0) + Z_PARAM_LONG(shm_key) + ZEND_PARSE_PARAMETERS_END_EX(RETURN_FALSE); + + intern = shm_object_from_zend_object(Z_OBJ_P(object)); + if (!intern->shm_object_ptr) { + zend_throw_exception_ex(spl_ce_InvalidArgumentException, 0, "Invalid object %s internal state", ZSTR_VAL(Z_OBJCE_P(object)->name)); + } + shm_object_ptr = intern->shm_object_ptr; + + RETURN_BOOL(shm_has_shm_data(shm_object_ptr->ptr, shm_key) >= 0); } /* }}} */ -/* {{{ proto bool shm_remove_var(resource id, int variable_key) +/* {{{ proto bool shm_remove_var(SharedMemoryBlock object, int variable_key) Removes variable from shared memory */ PHP_FUNCTION(shm_remove_var) { - zval *shm_id; + zval *object; zend_long shm_key, shm_varpos; - sysvshm_shm *shm_list_ptr; + shm_object *intern; + sysvshm_shm *shm_object_ptr; - if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS(), "rl", &shm_id, &shm_key)) { - return; - } - SHM_FETCH_RESOURCE(shm_list_ptr, shm_id); + ZEND_PARSE_PARAMETERS_START(2, 2) + Z_PARAM_OBJECT_OF_CLASS_EX(object, shm_ce_ptr, 1, 0) + Z_PARAM_LONG(shm_key) + ZEND_PARSE_PARAMETERS_END_EX(RETURN_FALSE); - shm_varpos = php_check_shm_data((shm_list_ptr->ptr), shm_key); + intern = shm_object_from_zend_object(Z_OBJ_P(object)); + if (!intern->shm_object_ptr) { + zend_throw_exception_ex(spl_ce_InvalidArgumentException, 0, "Invalid object %s internal state", ZSTR_VAL(Z_OBJCE_P(object)->name)); + } + shm_object_ptr = intern->shm_object_ptr; + shm_varpos = shm_has_shm_data((shm_object_ptr->ptr), shm_key); if (shm_varpos < 0) { - php_error_docref(NULL, E_WARNING, "variable key " ZEND_LONG_FMT " doesn't exist", shm_key); + zend_throw_exception_ex(spl_ce_OutOfBoundsException, 0, "Variable key " ZEND_LONG_FMT " doesn't exist", shm_key); RETURN_FALSE; } - php_remove_shm_data((shm_list_ptr->ptr), shm_varpos); + php_remove_shm_data((shm_object_ptr->ptr), shm_varpos); RETURN_TRUE; } /* }}} */ -/* {{{ php_put_shm_data +/* {{{ shm_set_shm_data * inserts an ascii-string into shared memory */ -static int php_put_shm_data(sysvshm_chunk_head *ptr, zend_long key, const char *data, zend_long len) +static int shm_set_shm_data(sysvshm_chunk_head *ptr, zend_long key, const char *data, zend_long len) { sysvshm_chunk *shm_var; zend_long total_size; zend_long shm_varpos; - total_size = ((zend_long) (len + sizeof(sysvshm_chunk) - 1) / sizeof(zend_long)) * sizeof(zend_long) + sizeof(zend_long); /* zend_long alligment */ + if (((zend_long *)ptr->start) == NULL) { +printf("\e[0;32mshm_set_shm_data BREAKE;\e[0m\n"); + } - if ((shm_varpos = php_check_shm_data(ptr, key)) > 0) { + total_size = ((zend_long) (len + sizeof(sysvshm_chunk) - 1) / sizeof(zend_long)) * sizeof(zend_long) + sizeof(zend_long); /* zend_long alligment */ +printf("\e[0;32mshm_set_shm_data\e[0m\n"); + if ((shm_varpos = shm_has_shm_data(ptr, key)) > 0) { php_remove_shm_data(ptr, shm_varpos); } - +printf("\e[0;32mshm_set_shm_data2\e[0m\n"); if (ptr->free < total_size) { return -1; /* not enough memory */ } @@ -387,21 +571,21 @@ static int php_put_shm_data(sysvshm_chunk_head *ptr, zend_long key, const char * } /* }}} */ -/* {{{ php_check_shm_data +/* {{{ shm_has_shm_data */ -static zend_long php_check_shm_data(sysvshm_chunk_head *ptr, zend_long key) +static zend_long shm_has_shm_data(sysvshm_chunk_head *ptr, zend_long key) { zend_long pos; sysvshm_chunk *shm_var; - +printf("\e[0;32mshm_has_shm_data: ptr->start: %d\e[0m\n", (zend_long *)ptr->start); pos = ptr->start; - +printf("\e[0;32mshm_has_shm_data\e[0m\n"); for (;;) { if (pos >= ptr->end) { return -1; } shm_var = (sysvshm_chunk*) ((char *) ptr + pos); - if (shm_var->key == key) { + if (shm_var->key == key) {printf("\e[0;32mshm_has_shm_data2\e[0m\n"); return pos; } pos += shm_var->next; @@ -434,7 +618,7 @@ static int php_remove_shm_data(sysvshm_chunk_head *ptr, zend_long shm_varpos) } /* }}} */ -#endif /* HAVE_SYSVSHM */ +// #endif /* HAVE_SYSVSHM */ /* * Local variables: diff --git a/ext/sysvshm/tests/002.phpt b/ext/sysvshm/tests/002.phpt index b28bd0c31a29a..c61381e9ea594 100644 --- a/ext/sysvshm/tests/002.phpt +++ b/ext/sysvshm/tests/002.phpt @@ -8,63 +8,61 @@ if (!function_exists('ftok')){ print 'skip'; } --FILE-- getMessage() . PHP_EOL; +} +try { + shm_attach(1,2,3,4); +} catch (ArgumentCountError $error) { + echo $error->getMessage() . PHP_EOL; +} -var_dump(shm_attach()); -var_dump(shm_attach(1,2,3,4)); +try { + shm_attach(-1, 0); +} catch (InvalidArgumentException $exception) { + echo $exception->getMessage() . PHP_EOL; +} +try { + shm_attach(0, -1); +} catch (InvalidArgumentException $exception) { + echo $exception->getMessage() . PHP_EOL; +} +try { + shm_attach(123, -1); +} catch (InvalidArgumentException $exception) { + echo $exception->getMessage() . PHP_EOL; +} +echo '====' . PHP_EOL; -var_dump(shm_attach(-1, 0)); -var_dump(shm_attach(0, -1)); -var_dump(shm_attach(123, -1)); -var_dump($s = shm_attach($key, -1)); -shm_remove($s); -var_dump($s = shm_attach($key, 0)); +var_dump($s = shm_attach(123, 1024)); shm_remove($s); -var_dump($s = shm_attach($key, 1024)); -shm_remove($key); -var_dump($s = shm_attach($key, 1024)); -shm_remove($s); -var_dump($s = shm_attach($key, 1024, 0666)); +var_dump($s = shm_attach(123, 1024, 0666)); shm_remove($s); -var_dump($s = shm_attach($key, 1024)); +var_dump($s = shm_attach(123, 1024)); shm_remove($s); -var_dump($s = shm_attach($key)); + +var_dump($s = shm_attach(123)); shm_remove($s); echo "Done\n"; ?> --EXPECTF-- -Warning: shm_attach() expects at least 1 parameter, 0 given in %s on line %d -NULL - -Warning: shm_attach() expects at most 3 parameters, 4 given in %s on line %d -NULL - -Warning: shm_attach(): Segment size must be greater than zero in %s on line %d -bool(false) - -Warning: shm_attach(): Segment size must be greater than zero in %s on line %d -bool(false) - -Warning: shm_attach(): Segment size must be greater than zero in %s on line %d -bool(false) - -Warning: shm_attach(): Segment size must be greater than zero in %s on line %d -bool(false) - -Warning: shm_remove() expects parameter 1 to be resource, bool given in %s on line %d - -Warning: shm_attach(): Segment size must be greater than zero in %s on line %d -bool(false) - -Warning: shm_remove() expects parameter 1 to be resource, bool given in %s on line %d -resource(%d) of type (sysvshm) - -Warning: shm_remove() expects parameter 1 to be resource, int given in %s on line %d -resource(%d) of type (sysvshm) -resource(%d) of type (sysvshm) -resource(%d) of type (sysvshm) -resource(%d) of type (sysvshm) +shm_attach() expects at least 1 parameter, 0 given +shm_attach() expects at most 3 parameters, 4 given +Segment size 0 must be greater than zero +Segment size -1 must be greater than zero +Segment size -1 must be greater than zero +==== +object(SharedMemoryBlock)#%d (0) { +} +object(SharedMemoryBlock)#%d (0) { +} +object(SharedMemoryBlock)#%d (0) { +} +object(SharedMemoryBlock)#%d (0) { +} Done diff --git a/ext/sysvshm/tests/003.phpt b/ext/sysvshm/tests/003.phpt index 565c7c454ea3a..10231fab7db3e 100644 --- a/ext/sysvshm/tests/003.phpt +++ b/ext/sysvshm/tests/003.phpt @@ -3,55 +3,60 @@ shm_detach() tests --SKIPIF-- --FILE-- getMessage() . PHP_EOL; +} $s = shm_attach($key); - -var_dump(shm_detach($s)); +var_dump($s); var_dump(shm_detach($s)); +try { + var_dump(shm_detach($s)); +} catch (TypeError $error) { + echo $error->getMessage() . PHP_EOL; +} shm_remove($s); - -var_dump(shm_detach(0)); -var_dump(shm_detach(1)); -var_dump(shm_detach(-1)); - +var_dump($s); +var_dump(shm_detach($s)); +var_dump($s); +echo '=====' . PHP_EOL; +shm_put_var($s, 1, "value!"); +var_dump(shm_get_var($s, 1)); echo "Done\n"; ?> --CLEAN-- --EXPECTF-- -Warning: shm_detach() expects exactly 1 parameter, 0 given in %s003.php on line %d +Warning: shm_detach() expects exactly 1 parameter, 0 given in %s003.php on line 5 NULL +Argument 1 passed to shm_detach() must be an instance of SharedMemoryBlock, int given +object(SharedMemoryBlock)#2 (0) { +} -Warning: shm_detach() expects exactly 1 parameter, 2 given in %s003.php on line %d +Warning: shm_detach() expects parameter 1 to be SharedMemoryBlock, object given in %s003.php on line 14 NULL -bool(true) - -Warning: shm_detach(): supplied resource is not a valid sysvshm resource in %s003.php on line %d -bool(false) -Warning: shm_remove(): supplied resource is not a valid sysvshm resource in %s003.php on line %d - -Warning: shm_detach() expects parameter 1 to be resource, int given in %s003.php on line %d +Warning: shm_detach() expects parameter 1 to be SharedMemoryBlock, object given in %s003.php on line 16 NULL -Warning: shm_detach() expects parameter 1 to be resource, int given in %s003.php on line %d -NULL +Warning: shm_remove() expects parameter 1 to be SharedMemoryBlock, object given in %s003.php on line 20 +object(SharedMemoryBlock)#2 (0) { +} -Warning: shm_detach() expects parameter 1 to be resource, int given in %s003.php on line %d +Warning: shm_detach() expects parameter 1 to be SharedMemoryBlock, object given in %s003.php on line 22 NULL -Done +Done \ No newline at end of file From cd8f53ecddd0400c9439bb3516b19df847487f1a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Brzuchalski?= Date: Mon, 7 May 2018 07:42:25 +0200 Subject: [PATCH 2/6] Removed resource from ext/sysvshm --- ext/sysvshm/php_sysvshm.h | 1 - ext/sysvshm/sysvshm.c | 4 ++-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/ext/sysvshm/php_sysvshm.h b/ext/sysvshm/php_sysvshm.h index 9523d3ca88e81..6ad889b2355cd 100644 --- a/ext/sysvshm/php_sysvshm.h +++ b/ext/sysvshm/php_sysvshm.h @@ -26,7 +26,6 @@ extern zend_module_entry sysvshm_module_entry; #define sysvshm_module_ptr &sysvshm_module_entry -// #include "php.h" #include "php_version.h" #define PHP_SYSVSHM_VERSION PHP_VERSION diff --git a/ext/sysvshm/sysvshm.c b/ext/sysvshm/sysvshm.c index 7f1983c8c943f..f1bab48504803 100644 --- a/ext/sysvshm/sysvshm.c +++ b/ext/sysvshm/sysvshm.c @@ -31,7 +31,7 @@ #include "php.h" #include "zend_types.h" -// #if HAVE_SYSVSHM +#if HAVE_SYSVSHM #include @@ -618,7 +618,7 @@ static int php_remove_shm_data(sysvshm_chunk_head *ptr, zend_long shm_varpos) } /* }}} */ -// #endif /* HAVE_SYSVSHM */ +#endif /* HAVE_SYSVSHM */ /* * Local variables: From 332049a70a1791034554e23e9256da9194ab801b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Brzuchalski?= Date: Mon, 7 May 2018 07:53:53 +0200 Subject: [PATCH 3/6] Removed printf left unwittingly --- ext/sysvshm/sysvshm.c | 28 +++++----------------------- 1 file changed, 5 insertions(+), 23 deletions(-) diff --git a/ext/sysvshm/sysvshm.c b/ext/sysvshm/sysvshm.c index f1bab48504803..f1d4d9221c52c 100644 --- a/ext/sysvshm/sysvshm.c +++ b/ext/sysvshm/sysvshm.c @@ -433,24 +433,10 @@ PHP_FUNCTION(shm_put_var) ZEND_PARSE_PARAMETERS_END_EX(RETURN_FALSE); intern = (shm_object *)shm_object_from_zend_object(Z_OBJ_P(object)); - if (intern == NULL) { - printf("\e[0;31mintern is NULL\3[0m\n\n"); - } - printf("key: %d, id: " ZEND_LONG_FMT, intern->shm_object_ptr->key, intern->shm_object_ptr->id); if (((shm_object_ptr = (sysvshm_shm *)intern->shm_object_ptr) == NULL) || (((sysvshm_chunk_head *)intern->shm_object_ptr->ptr) == NULL)) { zend_throw_exception_ex(spl_ce_InvalidArgumentException, 0, "Invalid object %s internal state", ZSTR_VAL(Z_OBJCE_P(object)->name)); RETURN_NULL(); } - printf("####\n"); - if (intern->shm_object_ptr == NULL) { - printf("\e[0;32mshm_set_shm_data BREAKE1;\e[0m\n"); - } - if (!(sysvshm_shm *)intern->shm_object_ptr->ptr) { - printf("\e[0;32mshm_set_shm_data BREAKE2;\e[0m\n"); - } - if (!(zend_long *)intern->shm_object_ptr->ptr->start) { - printf("\e[0;32mshm_set_shm_data BREAKE3;\e[0m\n"); - } ret = shm_set(intern->shm_object_ptr, shm_key, arg_var); @@ -546,16 +532,12 @@ static int shm_set_shm_data(sysvshm_chunk_head *ptr, zend_long key, const char * zend_long total_size; zend_long shm_varpos; - if (((zend_long *)ptr->start) == NULL) { -printf("\e[0;32mshm_set_shm_data BREAKE;\e[0m\n"); - } - total_size = ((zend_long) (len + sizeof(sysvshm_chunk) - 1) / sizeof(zend_long)) * sizeof(zend_long) + sizeof(zend_long); /* zend_long alligment */ -printf("\e[0;32mshm_set_shm_data\e[0m\n"); + if ((shm_varpos = shm_has_shm_data(ptr, key)) > 0) { php_remove_shm_data(ptr, shm_varpos); } -printf("\e[0;32mshm_set_shm_data2\e[0m\n"); + if (ptr->free < total_size) { return -1; /* not enough memory */ } @@ -577,15 +559,15 @@ static zend_long shm_has_shm_data(sysvshm_chunk_head *ptr, zend_long key) { zend_long pos; sysvshm_chunk *shm_var; -printf("\e[0;32mshm_has_shm_data: ptr->start: %d\e[0m\n", (zend_long *)ptr->start); + pos = ptr->start; -printf("\e[0;32mshm_has_shm_data\e[0m\n"); + for (;;) { if (pos >= ptr->end) { return -1; } shm_var = (sysvshm_chunk*) ((char *) ptr + pos); - if (shm_var->key == key) {printf("\e[0;32mshm_has_shm_data2\e[0m\n"); + if (shm_var->key == key) { return pos; } pos += shm_var->next; From e550d69bb4d9b3608a00a7b3fdb1259d0fb934a1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Brzuchalski?= Date: Wed, 16 May 2018 20:46:31 +0200 Subject: [PATCH 4/6] Added exception on wrong internal state --- ext/sysvshm/sysvshm.c | 68 ++++++++++++++++++++++++++++++------------- 1 file changed, 48 insertions(+), 20 deletions(-) diff --git a/ext/sysvshm/sysvshm.c b/ext/sysvshm/sysvshm.c index f1d4d9221c52c..76c034ae5a170 100644 --- a/ext/sysvshm/sysvshm.c +++ b/ext/sysvshm/sysvshm.c @@ -59,10 +59,11 @@ static void shm_object_free_storage(zend_object *object) /* {{{ */ { shm_object *intern = shm_object_from_zend_object(object); - if (intern->shm_object_ptr) { + if (intern->shm_object_ptr != NULL) { sysvshm_shm *shm_ptr = intern->shm_object_ptr; shmdt((void *) shm_ptr->ptr); efree(shm_ptr); + intern->shm_object_ptr = NULL; } zend_object_std_dtor(&intern->std); @@ -241,6 +242,10 @@ ZEND_METHOD(SharedMemoryBlock, has) ZEND_PARSE_PARAMETERS_END_EX(RETURN_FALSE); intern = shm_object_from_zend_object(Z_OBJ_P(getThis())); + if (intern->shm_object_ptr == NULL) { + zend_throw_exception_ex(spl_ce_InvalidArgumentException, 0, "Invalid SHaredMemoryBlock object internal state"); + RETURN_NULL(); + } shm_object_ptr = intern->shm_object_ptr; RETURN_BOOL(shm_has_shm_data(shm_object_ptr->ptr, shm_key) >= 0); @@ -260,6 +265,10 @@ ZEND_METHOD(SharedMemoryBlock, get) ZEND_PARSE_PARAMETERS_END_EX(RETURN_FALSE); intern = shm_object_from_zend_object(Z_OBJ_P(getThis())); + if (intern->shm_object_ptr == NULL) { + zend_throw_exception_ex(spl_ce_InvalidArgumentException, 0, "Invalid SHaredMemoryBlock object internal state"); + RETURN_NULL(); + } shm_get(intern->shm_object_ptr, shm_key, return_value); } /* }}} */ @@ -281,6 +290,10 @@ ZEND_METHOD(SharedMemoryBlock, set) ZEND_PARSE_PARAMETERS_END_EX(RETURN_FALSE); intern = shm_object_from_zend_object(Z_OBJ_P(getThis())); + if (intern->shm_object_ptr == NULL) { + zend_throw_exception_ex(spl_ce_InvalidArgumentException, 0, "Invalid SHaredMemoryBlock object internal state"); + RETURN_NULL(); + } ret = shm_set(intern->shm_object_ptr, shm_key, arg_var); if (ret == -1) { @@ -302,6 +315,10 @@ ZEND_METHOD(SharedMemoryBlock, remove) ZEND_PARSE_PARAMETERS_END_EX(RETURN_FALSE); intern = shm_object_from_zend_object(Z_OBJ_P(getThis())); + if (intern->shm_object_ptr == NULL) { + zend_throw_exception_ex(spl_ce_InvalidArgumentException, 0, "Invalid SHaredMemoryBlock object internal state"); + RETURN_NULL(); + } shm_object_ptr = intern->shm_object_ptr; shm_varpos = shm_has_shm_data((shm_object_ptr->ptr), shm_key); @@ -325,10 +342,17 @@ ZEND_METHOD(SharedMemoryBlock, free) ZEND_PARSE_PARAMETERS_END_EX(RETURN_FALSE); intern = shm_object_from_zend_object(Z_OBJ_P(getThis())); + if (intern->shm_object_ptr == NULL) { + zend_throw_exception_ex(spl_ce_InvalidArgumentException, 0, "Invalid SHaredMemoryBlock object internal state"); + RETURN_NULL(); + } shm_object_ptr = intern->shm_object_ptr; if (shmctl(shm_object_ptr->id, IPC_RMID, NULL) < 0) { zend_throw_exception_ex(spl_ce_RuntimeException, 0, "Failed for key 0x%x, id " ZEND_LONG_FMT ": %s", shm_object_ptr->key, shm_object_ptr->id, strerror(errno)); } + + shm_object_free_storage(Z_OBJ_P(getThis())); + RETURN_NULL(); } /* }}} */ @@ -383,10 +407,10 @@ PHP_FUNCTION(shm_detach) ZEND_PARSE_PARAMETERS_END_EX(RETURN_NULL()); intern = shm_object_from_zend_object(Z_OBJ_P(object)); - if (!intern->shm_object_ptr) { - zend_throw_exception_ex(spl_ce_InvalidArgumentException, 0, "Invalid object %s internal state", ZSTR_VAL(Z_OBJCE_P(object)->name)); - } - + if (intern->shm_object_ptr == NULL) { + zend_throw_exception_ex(spl_ce_InvalidArgumentException, 0, "Invalid SHaredMemoryBlock object internal state"); + RETURN_NULL(); + } shm_object_free_storage(Z_OBJ_P(object)); } /* }}} */ @@ -404,9 +428,10 @@ PHP_FUNCTION(shm_remove) ZEND_PARSE_PARAMETERS_END_EX(RETURN_FALSE); intern = shm_object_from_zend_object(Z_OBJ_P(object)); - if (!intern->shm_object_ptr) { - zend_throw_exception_ex(spl_ce_InvalidArgumentException, 0, "Invalid object %s internal state", ZSTR_VAL(Z_OBJCE_P(object)->name)); - } + if (intern->shm_object_ptr == NULL) { + zend_throw_exception_ex(spl_ce_InvalidArgumentException, 0, "Invalid SHaredMemoryBlock object internal state"); + RETURN_NULL(); + } shm_object_ptr = intern->shm_object_ptr; if (shmctl(shm_object_ptr->id, IPC_RMID, NULL) < 0) { @@ -433,10 +458,10 @@ PHP_FUNCTION(shm_put_var) ZEND_PARSE_PARAMETERS_END_EX(RETURN_FALSE); intern = (shm_object *)shm_object_from_zend_object(Z_OBJ_P(object)); - if (((shm_object_ptr = (sysvshm_shm *)intern->shm_object_ptr) == NULL) || (((sysvshm_chunk_head *)intern->shm_object_ptr->ptr) == NULL)) { - zend_throw_exception_ex(spl_ce_InvalidArgumentException, 0, "Invalid object %s internal state", ZSTR_VAL(Z_OBJCE_P(object)->name)); + if (intern->shm_object_ptr == NULL) { + zend_throw_exception_ex(spl_ce_InvalidArgumentException, 0, "Invalid SHaredMemoryBlock object internal state"); RETURN_NULL(); - } + } ret = shm_set(intern->shm_object_ptr, shm_key, arg_var); @@ -463,9 +488,10 @@ PHP_FUNCTION(shm_get_var) ZEND_PARSE_PARAMETERS_END_EX(RETURN_FALSE); intern = shm_object_from_zend_object(Z_OBJ_P(object)); - if (!intern->shm_object_ptr) { - zend_throw_exception_ex(spl_ce_InvalidArgumentException, 0, "Invalid object %s internal state", ZSTR_VAL(Z_OBJCE_P(object)->name)); - } + if (intern->shm_object_ptr == NULL) { + zend_throw_exception_ex(spl_ce_InvalidArgumentException, 0, "Invalid SHaredMemoryBlock object internal state"); + RETURN_NULL(); + } shm_get(intern->shm_object_ptr, shm_key, return_value); } /* }}} */ @@ -485,9 +511,10 @@ PHP_FUNCTION(shm_has_var) ZEND_PARSE_PARAMETERS_END_EX(RETURN_FALSE); intern = shm_object_from_zend_object(Z_OBJ_P(object)); - if (!intern->shm_object_ptr) { - zend_throw_exception_ex(spl_ce_InvalidArgumentException, 0, "Invalid object %s internal state", ZSTR_VAL(Z_OBJCE_P(object)->name)); - } + if (intern->shm_object_ptr == NULL) { + zend_throw_exception_ex(spl_ce_InvalidArgumentException, 0, "Invalid SHaredMemoryBlock object internal state"); + RETURN_NULL(); + } shm_object_ptr = intern->shm_object_ptr; RETURN_BOOL(shm_has_shm_data(shm_object_ptr->ptr, shm_key) >= 0); @@ -509,9 +536,10 @@ PHP_FUNCTION(shm_remove_var) ZEND_PARSE_PARAMETERS_END_EX(RETURN_FALSE); intern = shm_object_from_zend_object(Z_OBJ_P(object)); - if (!intern->shm_object_ptr) { - zend_throw_exception_ex(spl_ce_InvalidArgumentException, 0, "Invalid object %s internal state", ZSTR_VAL(Z_OBJCE_P(object)->name)); - } + if (intern->shm_object_ptr == NULL) { + zend_throw_exception_ex(spl_ce_InvalidArgumentException, 0, "Invalid SHaredMemoryBlock object internal state"); + RETURN_NULL(); + } shm_object_ptr = intern->shm_object_ptr; shm_varpos = shm_has_shm_data((shm_object_ptr->ptr), shm_key); From c3999a1a5e2cfc49175e237df6209e8cf7071c02 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Brzuchalski?= Date: Fri, 18 May 2018 16:50:55 +0200 Subject: [PATCH 5/6] Added exceptions on wrong internal state --- ext/sysvshm/sysvshm.c | 22 +++++++++++----------- ext/sysvshm/tests/002.phpt | 13 ++++++++----- ext/sysvshm/tests/003.phpt | 31 +++++++++++++++++++++++-------- 3 files changed, 42 insertions(+), 24 deletions(-) diff --git a/ext/sysvshm/sysvshm.c b/ext/sysvshm/sysvshm.c index 76c034ae5a170..8a604800d0620 100644 --- a/ext/sysvshm/sysvshm.c +++ b/ext/sysvshm/sysvshm.c @@ -243,7 +243,7 @@ ZEND_METHOD(SharedMemoryBlock, has) intern = shm_object_from_zend_object(Z_OBJ_P(getThis())); if (intern->shm_object_ptr == NULL) { - zend_throw_exception_ex(spl_ce_InvalidArgumentException, 0, "Invalid SHaredMemoryBlock object internal state"); + zend_throw_exception_ex(spl_ce_InvalidArgumentException, 0, "Invalid SharedMemoryBlock object internal state"); RETURN_NULL(); } shm_object_ptr = intern->shm_object_ptr; @@ -266,7 +266,7 @@ ZEND_METHOD(SharedMemoryBlock, get) intern = shm_object_from_zend_object(Z_OBJ_P(getThis())); if (intern->shm_object_ptr == NULL) { - zend_throw_exception_ex(spl_ce_InvalidArgumentException, 0, "Invalid SHaredMemoryBlock object internal state"); + zend_throw_exception_ex(spl_ce_InvalidArgumentException, 0, "Invalid SharedMemoryBlock object internal state"); RETURN_NULL(); } shm_get(intern->shm_object_ptr, shm_key, return_value); @@ -291,7 +291,7 @@ ZEND_METHOD(SharedMemoryBlock, set) intern = shm_object_from_zend_object(Z_OBJ_P(getThis())); if (intern->shm_object_ptr == NULL) { - zend_throw_exception_ex(spl_ce_InvalidArgumentException, 0, "Invalid SHaredMemoryBlock object internal state"); + zend_throw_exception_ex(spl_ce_InvalidArgumentException, 0, "Invalid SharedMemoryBlock object internal state"); RETURN_NULL(); } ret = shm_set(intern->shm_object_ptr, shm_key, arg_var); @@ -316,7 +316,7 @@ ZEND_METHOD(SharedMemoryBlock, remove) intern = shm_object_from_zend_object(Z_OBJ_P(getThis())); if (intern->shm_object_ptr == NULL) { - zend_throw_exception_ex(spl_ce_InvalidArgumentException, 0, "Invalid SHaredMemoryBlock object internal state"); + zend_throw_exception_ex(spl_ce_InvalidArgumentException, 0, "Invalid SharedMemoryBlock object internal state"); RETURN_NULL(); } shm_object_ptr = intern->shm_object_ptr; @@ -343,7 +343,7 @@ ZEND_METHOD(SharedMemoryBlock, free) intern = shm_object_from_zend_object(Z_OBJ_P(getThis())); if (intern->shm_object_ptr == NULL) { - zend_throw_exception_ex(spl_ce_InvalidArgumentException, 0, "Invalid SHaredMemoryBlock object internal state"); + zend_throw_exception_ex(spl_ce_InvalidArgumentException, 0, "Invalid SharedMemoryBlock object internal state"); RETURN_NULL(); } shm_object_ptr = intern->shm_object_ptr; @@ -408,7 +408,7 @@ PHP_FUNCTION(shm_detach) intern = shm_object_from_zend_object(Z_OBJ_P(object)); if (intern->shm_object_ptr == NULL) { - zend_throw_exception_ex(spl_ce_InvalidArgumentException, 0, "Invalid SHaredMemoryBlock object internal state"); + zend_throw_exception_ex(spl_ce_InvalidArgumentException, 0, "Invalid SharedMemoryBlock object internal state"); RETURN_NULL(); } shm_object_free_storage(Z_OBJ_P(object)); @@ -429,7 +429,7 @@ PHP_FUNCTION(shm_remove) intern = shm_object_from_zend_object(Z_OBJ_P(object)); if (intern->shm_object_ptr == NULL) { - zend_throw_exception_ex(spl_ce_InvalidArgumentException, 0, "Invalid SHaredMemoryBlock object internal state"); + zend_throw_exception_ex(spl_ce_InvalidArgumentException, 0, "Invalid SharedMemoryBlock object internal state"); RETURN_NULL(); } shm_object_ptr = intern->shm_object_ptr; @@ -459,7 +459,7 @@ PHP_FUNCTION(shm_put_var) intern = (shm_object *)shm_object_from_zend_object(Z_OBJ_P(object)); if (intern->shm_object_ptr == NULL) { - zend_throw_exception_ex(spl_ce_InvalidArgumentException, 0, "Invalid SHaredMemoryBlock object internal state"); + zend_throw_exception_ex(spl_ce_InvalidArgumentException, 0, "Invalid SharedMemoryBlock object internal state"); RETURN_NULL(); } @@ -489,7 +489,7 @@ PHP_FUNCTION(shm_get_var) intern = shm_object_from_zend_object(Z_OBJ_P(object)); if (intern->shm_object_ptr == NULL) { - zend_throw_exception_ex(spl_ce_InvalidArgumentException, 0, "Invalid SHaredMemoryBlock object internal state"); + zend_throw_exception_ex(spl_ce_InvalidArgumentException, 0, "Invalid SharedMemoryBlock object internal state"); RETURN_NULL(); } shm_get(intern->shm_object_ptr, shm_key, return_value); @@ -512,7 +512,7 @@ PHP_FUNCTION(shm_has_var) intern = shm_object_from_zend_object(Z_OBJ_P(object)); if (intern->shm_object_ptr == NULL) { - zend_throw_exception_ex(spl_ce_InvalidArgumentException, 0, "Invalid SHaredMemoryBlock object internal state"); + zend_throw_exception_ex(spl_ce_InvalidArgumentException, 0, "Invalid SharedMemoryBlock object internal state"); RETURN_NULL(); } shm_object_ptr = intern->shm_object_ptr; @@ -537,7 +537,7 @@ PHP_FUNCTION(shm_remove_var) intern = shm_object_from_zend_object(Z_OBJ_P(object)); if (intern->shm_object_ptr == NULL) { - zend_throw_exception_ex(spl_ce_InvalidArgumentException, 0, "Invalid SHaredMemoryBlock object internal state"); + zend_throw_exception_ex(spl_ce_InvalidArgumentException, 0, "Invalid SharedMemoryBlock object internal state"); RETURN_NULL(); } shm_object_ptr = intern->shm_object_ptr; diff --git a/ext/sysvshm/tests/002.phpt b/ext/sysvshm/tests/002.phpt index c61381e9ea594..30a099e425109 100644 --- a/ext/sysvshm/tests/002.phpt +++ b/ext/sysvshm/tests/002.phpt @@ -13,6 +13,7 @@ try { } catch (ArgumentCountError $error) { echo $error->getMessage() . PHP_EOL; } + try { shm_attach(1,2,3,4); } catch (ArgumentCountError $error) { @@ -24,11 +25,13 @@ try { } catch (InvalidArgumentException $exception) { echo $exception->getMessage() . PHP_EOL; } + try { shm_attach(0, -1); } catch (InvalidArgumentException $exception) { echo $exception->getMessage() . PHP_EOL; } + try { shm_attach(123, -1); } catch (InvalidArgumentException $exception) { @@ -57,12 +60,12 @@ Segment size 0 must be greater than zero Segment size -1 must be greater than zero Segment size -1 must be greater than zero ==== -object(SharedMemoryBlock)#%d (0) { +object(SharedMemoryBlock)#5 (0) { } -object(SharedMemoryBlock)#%d (0) { +object(SharedMemoryBlock)#7 (0) { } -object(SharedMemoryBlock)#%d (0) { +object(SharedMemoryBlock)#5 (0) { } -object(SharedMemoryBlock)#%d (0) { +object(SharedMemoryBlock)#7 (0) { } -Done +Done \ No newline at end of file diff --git a/ext/sysvshm/tests/003.phpt b/ext/sysvshm/tests/003.phpt index 10231fab7db3e..5729fb58508c9 100644 --- a/ext/sysvshm/tests/003.phpt +++ b/ext/sysvshm/tests/003.phpt @@ -7,9 +7,9 @@ if (!extension_loaded("sysvshm")){ print 'skip'; } --FILE-- getMessage() . PHP_EOL; +} catch (InvalidArgumentException $exception) { + echo $exception->getMessage() . PHP_EOL; } -shm_remove($s); +echo '{{{ #1'.PHP_EOL; var_dump($s); -var_dump(shm_detach($s)); +echo '/eof#1 }}}'.PHP_EOL; +try { + shm_remove($s); +} catch (InvalidArgumentException $exception) { + echo $exception->getMessage() . PHP_EOL; +} var_dump($s); + echo '=====' . PHP_EOL; -shm_put_var($s, 1, "value!"); -var_dump(shm_get_var($s, 1)); +try { + shm_put_var($s, 1, "value!"); +} catch (InvalidArgumentException $exception) { + echo $exception->getMessage() . PHP_EOL; +} +try { + var_dump(shm_get_var($s, 1)); +} catch(InvalidArgumentException $excception) { + echo $excception->getMessage() . PHP_EOL; +} echo "Done\n"; ?> --CLEAN-- From e592b741c3dacfcff393a9d4ad3d50880f4ecc24 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Brzuchalski?= Date: Mon, 21 May 2018 08:12:36 +0200 Subject: [PATCH 6/6] Added tests and throwing exceptions on argument parse error --- ext/sysvshm/sysvshm.c | 49 ++++++++++++------------- ext/sysvshm/tests/000.phpt | 37 +++++++++++++++++++ ext/sysvshm/tests/001.phpt | 38 +++++++++++++++++++ ext/sysvshm/tests/002.phpt | 3 +- ext/sysvshm/tests/003.phpt | 46 +++++++++++------------ ext/sysvshm/tests/004.phpt | 58 +++++++++++++++++------------ ext/sysvshm/tests/005.phpt | 65 ++++++++++++++++++++------------- ext/sysvshm/tests/006.phpt | 75 +++++++++++++++++++++----------------- ext/sysvshm/tests/007.phpt | 68 ++++++++++++++++++++-------------- 9 files changed, 277 insertions(+), 162 deletions(-) create mode 100644 ext/sysvshm/tests/000.phpt create mode 100644 ext/sysvshm/tests/001.phpt diff --git a/ext/sysvshm/sysvshm.c b/ext/sysvshm/sysvshm.c index 8a604800d0620..f5a9c9ba57960 100644 --- a/ext/sysvshm/sysvshm.c +++ b/ext/sysvshm/sysvshm.c @@ -65,8 +65,6 @@ static void shm_object_free_storage(zend_object *object) /* {{{ */ efree(shm_ptr); intern->shm_object_ptr = NULL; } - - zend_object_std_dtor(&intern->std); } /* }}} */ @@ -237,9 +235,9 @@ ZEND_METHOD(SharedMemoryBlock, has) shm_object *intern; sysvshm_shm *shm_object_ptr; - ZEND_PARSE_PARAMETERS_START(1, 1) + ZEND_PARSE_PARAMETERS_START_EX(ZEND_PARSE_PARAMS_THROW, 1, 1) Z_PARAM_LONG(shm_key) - ZEND_PARSE_PARAMETERS_END_EX(RETURN_FALSE); + ZEND_PARSE_PARAMETERS_END_EX(RETURN_NULL()); intern = shm_object_from_zend_object(Z_OBJ_P(getThis())); if (intern->shm_object_ptr == NULL) { @@ -260,9 +258,9 @@ ZEND_METHOD(SharedMemoryBlock, get) shm_object *intern; sysvshm_shm *shm_object_ptr; - ZEND_PARSE_PARAMETERS_START(1, 1) + ZEND_PARSE_PARAMETERS_START_EX(ZEND_PARSE_PARAMS_THROW, 1, 1) Z_PARAM_LONG(shm_key) - ZEND_PARSE_PARAMETERS_END_EX(RETURN_FALSE); + ZEND_PARSE_PARAMETERS_END_EX(RETURN_NULL()); intern = shm_object_from_zend_object(Z_OBJ_P(getThis())); if (intern->shm_object_ptr == NULL) { @@ -284,10 +282,10 @@ ZEND_METHOD(SharedMemoryBlock, set) sysvshm_shm *shm_object_ptr; int ret; - ZEND_PARSE_PARAMETERS_START(2, 2) + ZEND_PARSE_PARAMETERS_START_EX(ZEND_PARSE_PARAMS_THROW, 2, 2) Z_PARAM_LONG(shm_key) Z_PARAM_ZVAL(arg_var) - ZEND_PARSE_PARAMETERS_END_EX(RETURN_FALSE); + ZEND_PARSE_PARAMETERS_END_EX(RETURN_NULL()); intern = shm_object_from_zend_object(Z_OBJ_P(getThis())); if (intern->shm_object_ptr == NULL) { @@ -310,9 +308,9 @@ ZEND_METHOD(SharedMemoryBlock, remove) shm_object *intern; sysvshm_shm *shm_object_ptr; - ZEND_PARSE_PARAMETERS_START(1, 1) + ZEND_PARSE_PARAMETERS_START_EX(ZEND_PARSE_PARAMS_THROW, 1, 1) Z_PARAM_LONG(shm_key) - ZEND_PARSE_PARAMETERS_END_EX(RETURN_FALSE); + ZEND_PARSE_PARAMETERS_END_EX(RETURN_NULL()); intern = shm_object_from_zend_object(Z_OBJ_P(getThis())); if (intern->shm_object_ptr == NULL) { @@ -338,8 +336,8 @@ ZEND_METHOD(SharedMemoryBlock, free) shm_object *intern; sysvshm_shm *shm_object_ptr; - ZEND_PARSE_PARAMETERS_START(0, 0) - ZEND_PARSE_PARAMETERS_END_EX(RETURN_FALSE); + ZEND_PARSE_PARAMETERS_START_EX(ZEND_PARSE_PARAMS_THROW, 0, 0) + ZEND_PARSE_PARAMETERS_END_EX(RETURN_NULL()); intern = shm_object_from_zend_object(Z_OBJ_P(getThis())); if (intern->shm_object_ptr == NULL) { @@ -373,6 +371,8 @@ PHP_MINIT_FUNCTION(sysvshm) }; INIT_CLASS_ENTRY(tmp_ce, "SharedMemoryBlock", shm_object_methods); tmp_ce.create_object = shm_object_new; + tmp_ce.serialize = zend_class_serialize_deny; + tmp_ce.unserialize = zend_class_unserialize_deny; shm_ce_ptr = zend_register_internal_class_ex(&tmp_ce, NULL); memcpy(&shm_object_handlers, zend_get_std_object_handlers(), sizeof(zend_object_handlers)); shm_object_handlers.offset = XtOffsetOf(shm_object, std); @@ -402,7 +402,7 @@ PHP_FUNCTION(shm_detach) shm_object *intern; sysvshm_shm *shm_object_ptr; - ZEND_PARSE_PARAMETERS_START(1, 1) + ZEND_PARSE_PARAMETERS_START_EX(ZEND_PARSE_PARAMS_THROW, 1, 1) Z_PARAM_OBJECT_OF_CLASS_EX(object, shm_ce_ptr, 1, 0) ZEND_PARSE_PARAMETERS_END_EX(RETURN_NULL()); @@ -423,9 +423,9 @@ PHP_FUNCTION(shm_remove) shm_object *intern; sysvshm_shm *shm_object_ptr; - ZEND_PARSE_PARAMETERS_START(1, 1) + ZEND_PARSE_PARAMETERS_START_EX(ZEND_PARSE_PARAMS_THROW, 1, 1) Z_PARAM_OBJECT_OF_CLASS_EX(object, shm_ce_ptr, 1, 0) - ZEND_PARSE_PARAMETERS_END_EX(RETURN_FALSE); + ZEND_PARSE_PARAMETERS_END_EX(RETURN_NULL()); intern = shm_object_from_zend_object(Z_OBJ_P(object)); if (intern->shm_object_ptr == NULL) { @@ -451,11 +451,11 @@ PHP_FUNCTION(shm_put_var) sysvshm_shm *shm_object_ptr; int ret; - ZEND_PARSE_PARAMETERS_START(3, 3) + ZEND_PARSE_PARAMETERS_START_EX(ZEND_PARSE_PARAMS_THROW, 3, 3) Z_PARAM_OBJECT_OF_CLASS_EX(object, shm_ce_ptr, 1, 0) Z_PARAM_LONG(shm_key) Z_PARAM_ZVAL(arg_var) - ZEND_PARSE_PARAMETERS_END_EX(RETURN_FALSE); + ZEND_PARSE_PARAMETERS_END_EX(RETURN_NULL()); intern = (shm_object *)shm_object_from_zend_object(Z_OBJ_P(object)); if (intern->shm_object_ptr == NULL) { @@ -467,9 +467,8 @@ PHP_FUNCTION(shm_put_var) if (ret == -1) { zend_throw_exception(spl_ce_RuntimeException, "Not enough shared memory left", 0); - RETURN_FALSE; } - RETURN_TRUE; + RETURN_NULL(); } /* }}} */ @@ -482,10 +481,10 @@ PHP_FUNCTION(shm_get_var) shm_object *intern; sysvshm_shm *shm_object_ptr; - ZEND_PARSE_PARAMETERS_START(2, 2) + ZEND_PARSE_PARAMETERS_START_EX(ZEND_PARSE_PARAMS_THROW, 2, 2) Z_PARAM_OBJECT_OF_CLASS_EX(object, shm_ce_ptr, 1, 0) Z_PARAM_LONG(shm_key) - ZEND_PARSE_PARAMETERS_END_EX(RETURN_FALSE); + ZEND_PARSE_PARAMETERS_END_EX(RETURN_NULL()); intern = shm_object_from_zend_object(Z_OBJ_P(object)); if (intern->shm_object_ptr == NULL) { @@ -505,10 +504,10 @@ PHP_FUNCTION(shm_has_var) shm_object *intern; sysvshm_shm *shm_object_ptr; - ZEND_PARSE_PARAMETERS_START(2, 2) + ZEND_PARSE_PARAMETERS_START_EX(ZEND_PARSE_PARAMS_THROW, 2, 2) Z_PARAM_OBJECT_OF_CLASS_EX(object, shm_ce_ptr, 1, 0) Z_PARAM_LONG(shm_key) - ZEND_PARSE_PARAMETERS_END_EX(RETURN_FALSE); + ZEND_PARSE_PARAMETERS_END_EX(RETURN_NULL()); intern = shm_object_from_zend_object(Z_OBJ_P(object)); if (intern->shm_object_ptr == NULL) { @@ -530,10 +529,10 @@ PHP_FUNCTION(shm_remove_var) shm_object *intern; sysvshm_shm *shm_object_ptr; - ZEND_PARSE_PARAMETERS_START(2, 2) + ZEND_PARSE_PARAMETERS_START_EX(ZEND_PARSE_PARAMS_THROW, 2, 2) Z_PARAM_OBJECT_OF_CLASS_EX(object, shm_ce_ptr, 1, 0) Z_PARAM_LONG(shm_key) - ZEND_PARSE_PARAMETERS_END_EX(RETURN_FALSE); + ZEND_PARSE_PARAMETERS_END_EX(RETURN_NULL()); intern = shm_object_from_zend_object(Z_OBJ_P(object)); if (intern->shm_object_ptr == NULL) { diff --git a/ext/sysvshm/tests/000.phpt b/ext/sysvshm/tests/000.phpt new file mode 100644 index 0000000000000..4c03fd7d44f2c --- /dev/null +++ b/ext/sysvshm/tests/000.phpt @@ -0,0 +1,37 @@ +--TEST-- +shm_detach() tests +--SKIPIF-- + +--FILE-- +getMessage().PHP_EOL; +} + +var_dump($s); +echo "Done\n"; +?> +--CLEAN-- + +--EXPECT-- +object(SharedMemoryBlock)#1 (0) { +} +Invalid SharedMemoryBlock object internal state +object(SharedMemoryBlock)#1 (0) { +} +Done \ No newline at end of file diff --git a/ext/sysvshm/tests/001.phpt b/ext/sysvshm/tests/001.phpt new file mode 100644 index 0000000000000..89bda33cfb167 --- /dev/null +++ b/ext/sysvshm/tests/001.phpt @@ -0,0 +1,38 @@ +--TEST-- +SharedMemoryBlock::__destruct() tests +--SKIPIF-- + +--FILE-- + +--CLEAN-- + +--EXPECTF-- +object(SharedMemoryBlock)#1 (0) { +} + +Notice: Undefined variable: s in %s on line %d +NULL +object(SharedMemoryBlock)#1 (0) { +} + +Notice: Undefined variable: s in %s on line %d +NULL +Done \ No newline at end of file diff --git a/ext/sysvshm/tests/002.phpt b/ext/sysvshm/tests/002.phpt index 30a099e425109..11b1afce82ab4 100644 --- a/ext/sysvshm/tests/002.phpt +++ b/ext/sysvshm/tests/002.phpt @@ -3,7 +3,6 @@ shm_attach() tests --SKIPIF-- --FILE-- ---EXPECTF-- +--EXPECT-- shm_attach() expects at least 1 parameter, 0 given shm_attach() expects at most 3 parameters, 4 given Segment size 0 must be greater than zero diff --git a/ext/sysvshm/tests/003.phpt b/ext/sysvshm/tests/003.phpt index 5729fb58508c9..73a7efed91d2c 100644 --- a/ext/sysvshm/tests/003.phpt +++ b/ext/sysvshm/tests/003.phpt @@ -7,8 +7,11 @@ if (!extension_loaded("sysvshm")){ print 'skip'; } --FILE-- getMessage() . PHP_EOL; +} $key = 456; try { var_dump(shm_detach($key,1)); @@ -25,15 +28,12 @@ try { } catch (InvalidArgumentException $exception) { echo $exception->getMessage() . PHP_EOL; } -echo '{{{ #1'.PHP_EOL; -var_dump($s); -echo '/eof#1 }}}'.PHP_EOL; + try { shm_remove($s); } catch (InvalidArgumentException $exception) { echo $exception->getMessage() . PHP_EOL; } -var_dump($s); echo '=====' . PHP_EOL; try { @@ -42,7 +42,12 @@ try { echo $exception->getMessage() . PHP_EOL; } try { - var_dump(shm_get_var($s, 1)); + shm_has_var($s, 1); +} catch (InvalidArgumentException $exception) { + echo $exception->getMessage() . PHP_EOL; +} +try { + shm_get_var($s, 1); } catch(InvalidArgumentException $excception) { echo $excception->getMessage() . PHP_EOL; } @@ -51,27 +56,20 @@ echo "Done\n"; --CLEAN-- ---EXPECTF-- -Warning: shm_detach() expects exactly 1 parameter, 0 given in %s003.php on line 5 -NULL +--EXPECT-- +shm_detach() expects exactly 1 parameter, 0 given Argument 1 passed to shm_detach() must be an instance of SharedMemoryBlock, int given -object(SharedMemoryBlock)#2 (0) { +object(SharedMemoryBlock)#1 (0) { } - -Warning: shm_detach() expects parameter 1 to be SharedMemoryBlock, object given in %s003.php on line 14 -NULL - -Warning: shm_detach() expects parameter 1 to be SharedMemoryBlock, object given in %s003.php on line 16 -NULL - -Warning: shm_remove() expects parameter 1 to be SharedMemoryBlock, object given in %s003.php on line 20 -object(SharedMemoryBlock)#2 (0) { -} - -Warning: shm_detach() expects parameter 1 to be SharedMemoryBlock, object given in %s003.php on line 22 NULL +Invalid SharedMemoryBlock object internal state +Invalid SharedMemoryBlock object internal state +===== +Invalid SharedMemoryBlock object internal state +Invalid SharedMemoryBlock object internal state +Invalid SharedMemoryBlock object internal state Done \ No newline at end of file diff --git a/ext/sysvshm/tests/004.phpt b/ext/sysvshm/tests/004.phpt index ea931cbca2df3..5ca9ce07f5363 100644 --- a/ext/sysvshm/tests/004.phpt +++ b/ext/sysvshm/tests/004.phpt @@ -3,41 +3,53 @@ shm_put_var() tests --SKIPIF-- --FILE-- getMessage(); +} +try { + shm_put_var(-1, -1, -1); +} catch (Throwable $error) { + echo get_class($error) . PHP_EOL; +} +try { + shm_put_var(-1, 10, "qwerty"); +} catch (Throwable $error) { + echo get_class($error) . PHP_EOL; +} var_dump(shm_put_var($s, -1, "qwerty")); var_dump(shm_put_var($s, 10, "qwerty")); var_dump(shm_put_var($s, 10, "qwerty")); - -$string = str_repeat("test", 512); -var_dump(shm_put_var($s, 11, $string)); +try { + $string = str_repeat("test", 512); + var_dump(shm_put_var($s, 11, $string)); +} catch (Throwable $error) { + echo get_class($error) . PHP_EOL; +} shm_remove($s); echo "Done\n"; ?> ---EXPECTF-- -Warning: shm_put_var() expects exactly 3 parameters, 0 given in %s004.php on line %d -NULL +--CLEAN-- + +--EXPECT-- +shm_put_var() expects exactly 3 parameters, 0 givenTypeError +TypeError NULL -bool(true) -bool(true) -bool(true) - -Warning: shm_put_var(): not enough shared memory left in %s004.php on line 14 -bool(false) -Done +NULL +NULL +RuntimeException +Done \ No newline at end of file diff --git a/ext/sysvshm/tests/005.phpt b/ext/sysvshm/tests/005.phpt index 6608aba2c7393..2a839ed6b875d 100644 --- a/ext/sysvshm/tests/005.phpt +++ b/ext/sysvshm/tests/005.phpt @@ -3,13 +3,11 @@ shm_get_var() tests --SKIPIF-- --FILE-- getMessage() . PHP_EOL; +} +try { + shm_get_var(-1, -1); +} catch (TypeError $error) { + echo $error->getMessage() . PHP_EOL; +} +try { + shm_get_var($s, 1000); +} catch (OutOfBoundsException $exception) { + echo $exception->getMessage() . PHP_EOL; +} +try { + shm_get_var($s, -10000); +} catch (OutOfBoundsException $exception) { + echo $exception->getMessage() . PHP_EOL; +} -var_dump(shm_get_var($s, array())); +try { + shm_get_var($s, array()); +} catch (TypeError $error) { + echo $error->getMessage() . PHP_EOL; +} var_dump(shm_get_var($s, -1)); var_dump(shm_get_var($s, 0)); var_dump(shm_get_var($s, 1)); @@ -40,24 +56,21 @@ shm_remove($s); echo "Done\n"; ?> ---EXPECTF-- - -Warning: shm_get_var() expects exactly 2 parameters, 0 given in %s005.php on line %d -NULL - -Warning: shm_get_var() expects parameter 1 to be resource, int given in %s005.php on line %d -NULL - -Warning: shm_get_var(): variable key 1000 doesn't exist in %s005.php on line %d -bool(false) +--CLEAN-- + +--EXPECT-- +shm_get_var() expects exactly 2 parameters, 0 given +Argument 1 passed to shm_get_var() must be an instance of SharedMemoryBlock, int given +Variable key 1000 doesn't exist +Variable key -10000 doesn't exist +Argument 2 passed to shm_get_var() must be of the type int, array given string(11) "test string" -object(stdClass)#%d (0) { +object(stdClass)#3 (0) { } array(3) { [0]=> @@ -70,4 +83,4 @@ array(3) { bool(false) NULL NULL -Done +Done \ No newline at end of file diff --git a/ext/sysvshm/tests/006.phpt b/ext/sysvshm/tests/006.phpt index a8f5064b4b5c0..f8a50519878b7 100644 --- a/ext/sysvshm/tests/006.phpt +++ b/ext/sysvshm/tests/006.phpt @@ -3,50 +3,57 @@ shm_remove_var() tests --SKIPIF-- --FILE-- getMessage() . PHP_EOL; +} +try { + shm_remove_var(-1, -1); +} catch (TypeError $error) { + echo $error->getMessage() . PHP_EOL; +} +try { + shm_remove_var($s, -10); +} catch (OutOfBoundsException $error) { + echo $error->getMessage() . PHP_EOL; +} var_dump(shm_get_var($s, 1)); +shm_remove_var($s, 1); +try { + shm_get_var($s, 1); +} catch (OutOfBoundsException $error) { + echo $error->getMessage() . PHP_EOL; +} + +try { + shm_remove_var($s, 1); +} catch (OutOfBoundsException $error) { + echo $error->getMessage() . PHP_EOL; +} +try { + shm_get_var($s, 1); +} catch (OutOfBoundsException $error) { + echo $error->getMessage() . PHP_EOL; +} shm_remove($s); echo "Done\n"; ?> ---EXPECTF-- - -Warning: shm_remove_var() expects exactly 2 parameters, 0 given in %s006.php on line %d -NULL - -Warning: shm_remove_var() expects parameter 1 to be resource, int given in %s006.php on line %d -NULL - -Warning: shm_remove_var(): variable key -10 doesn't exist in %s006.php on line %d -bool(false) +--EXPECT-- +shm_remove_var() expects exactly 2 parameters, 0 given +Argument 1 passed to shm_remove_var() must be an instance of SharedMemoryBlock, int given +Variable key -10 doesn't exist string(11) "test string" -bool(true) - -Warning: shm_get_var(): variable key 1 doesn't exist in %s006.php on line %d -bool(false) - -Warning: shm_remove_var(): variable key 1 doesn't exist in %s006.php on line %d -bool(false) - -Warning: shm_get_var(): variable key 1 doesn't exist in %s006.php on line %d -bool(false) -Done +Variable key 1 doesn't exist +Variable key 1 doesn't exist +Variable key 1 doesn't exist +Done \ No newline at end of file diff --git a/ext/sysvshm/tests/007.phpt b/ext/sysvshm/tests/007.phpt index 89e32e6c4f838..c11ff53f8d7f2 100644 --- a/ext/sysvshm/tests/007.phpt +++ b/ext/sysvshm/tests/007.phpt @@ -3,42 +3,54 @@ shm_remove() tests --SKIPIF-- --FILE-- getMessage() . PHP_EOL; +} +try { + shm_remove(-1); +} catch (TypeError $error) { + echo $error->getMessage() . PHP_EOL; +} +try { + shm_remove(0); +} catch (TypeError $error) { + echo $error->getMessage() . PHP_EOL; +} +try { + shm_remove(""); +} catch (TypeError $error) { + echo $error->getMessage() . PHP_EOL; +} var_dump(shm_remove($s)); -shm_detach($s); -var_dump(shm_remove($s)); +try { + shm_detach($s); +} catch (InvalidArgumentException $exception) { + echo $exception->getMessage() . PHP_EOL; +} +try { + shm_remove($s); +} catch (InvalidArgumentException $exception) { + echo $exception->getMessage() . PHP_EOL; +} echo "Done\n"; ?> ---EXPECTF-- - -Warning: shm_remove() expects exactly 1 parameter, 0 given in %s007.php on line %d +--EXPECT-- +shm_remove() expects exactly 1 parameter, 0 given +Argument 1 passed to shm_remove() must be an instance of SharedMemoryBlock, int given +Argument 1 passed to shm_remove() must be an instance of SharedMemoryBlock, int given +Argument 1 passed to shm_remove() must be an instance of SharedMemoryBlock, string given NULL - -Warning: shm_remove() expects parameter 1 to be resource, int given in %s007.php on line %d -NULL - -Warning: shm_remove() expects parameter 1 to be resource, int given in %s007.php on line %d -NULL - -Warning: shm_remove() expects parameter 1 to be resource, string given in %s007.php on line %d -NULL -bool(true) - -Warning: shm_remove(): supplied resource is not a valid sysvshm resource in %s007.php on line %d -bool(false) -Done - +Invalid SharedMemoryBlock object internal state +Invalid SharedMemoryBlock object internal state +Done \ No newline at end of file