diff options
author | Emiel Bruijntjes <emiel.bruijntjes@copernica.com> | 2014-03-17 18:52:31 +0100 |
---|---|---|
committer | Emiel Bruijntjes <emiel.bruijntjes@copernica.com> | 2014-03-17 18:52:31 +0100 |
commit | 342d57ee250e976c51b970584e6286ad489e6594 (patch) | |
tree | a3a3296acc0296ecd65e78b27822f9df78dd22b2 /src | |
parent | da370694802b426190e1f071f2d3c12ea24253c2 (diff) |
in php 5.3 environments, not all code was correctly initialized which resulted in access to uninitialized data
Diffstat (limited to 'src')
-rw-r--r-- | src/callable.cpp | 39 | ||||
-rw-r--r-- | src/callable.h | 13 |
2 files changed, 33 insertions, 19 deletions
diff --git a/src/callable.cpp b/src/callable.cpp index c3db05d..e68ab98 100644 --- a/src/callable.cpp +++ b/src/callable.cpp @@ -70,9 +70,7 @@ void Callable::initialize(zend_function_entry *entry, const char *classname, int entry->flags = flags; // we should fill the first argument as well -#if PHP_VERSION_ID >= 50400 - initialize((zend_internal_function_info *)entry->arg_info, classname); -#endif + initialize((zend_arg_info *)entry->arg_info, classname); } /** @@ -80,27 +78,42 @@ void Callable::initialize(zend_function_entry *entry, const char *classname, int * @param info Info to be filled * @param classname Optional classname */ -#if PHP_VERSION_ID >= 50400 -void Callable::initialize(zend_internal_function_info *info, const char *classname) const +void Callable::initialize(zend_arg_info *info, const char *classname) const { +#if PHP_VERSION_ID >= 50400 + // up until php 5.3, the first info object is filled with alternative information, + // later it is casted to a zend_internal_function object + auto *finfo = (zend_internal_function_info *)info; + // fill in all the members, note that return reference is false by default, // because we do not support returning references in PHP-CPP, although Zend // engine allows it. Inside the name we hide a pointer to the current object - info->_name = _ptr; - info->_name_len = strlen(_ptr); - info->_class_name = classname; + finfo->_name = _ptr; + finfo->_name_len = strlen(_ptr); + finfo->_class_name = classname; // number of required arguments, and the expected return type - info->required_num_args = _required; - info->_type_hint = (unsigned char)_return; + finfo->required_num_args = _required; + finfo->_type_hint = (unsigned char)_return; // we do not support return-by-reference - info->return_reference = false; + finfo->return_reference = false; // passing by reference is not used - info->pass_rest_by_reference = false; -} + finfo->pass_rest_by_reference = false; +#else + // php 5.3 code + info->name = nullptr; + info->name_len = 0; + info->class_name = nullptr; + info->class_name_len = 0; + info->array_type_hint = false; + info->allow_null = false; + info->pass_by_reference = false; + info->return_reference = false; + info->required_num_args = _required; #endif +} /** * End of namespace diff --git a/src/callable.h b/src/callable.h index 9b5cdcd..f123c8b 100644 --- a/src/callable.h +++ b/src/callable.h @@ -12,7 +12,7 @@ * Forward definitions */ struct _zend_function_entry; -struct _zend_internal_function_info; +struct _zend_arg_info; /** * Set up namespace @@ -36,18 +36,19 @@ public: _argc = arguments.size(); _argv = new zend_arg_info[_argc+1]; - // counter + // the first record is initialized with information about the function, + // so we skip that here int i=1; // loop through the arguments for (auto it = arguments.begin(); it != arguments.end(); it++) { + // increment required + if (it->required()) _required++; + // fill the arg info it->fill(&_argv[i++]); } - - // @todo find out number of required arguments - _required = _argc; } /** @@ -106,7 +107,7 @@ public: * @param ns Active namespace * @param classname Optional class name */ - void initialize(struct _zend_internal_function_info *info, const char *classname = nullptr) const; + void initialize(struct _zend_arg_info *info, const char *classname = nullptr) const; protected: |