summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEmiel Bruijntjes <emiel.bruijntjes@copernica.com>2014-03-17 18:52:31 +0100
committerEmiel Bruijntjes <emiel.bruijntjes@copernica.com>2014-03-17 18:52:31 +0100
commit342d57ee250e976c51b970584e6286ad489e6594 (patch)
treea3a3296acc0296ecd65e78b27822f9df78dd22b2
parentda370694802b426190e1f071f2d3c12ea24253c2 (diff)
in php 5.3 environments, not all code was correctly initialized which resulted in access to uninitialized data
-rw-r--r--include/argument.h10
-rw-r--r--src/callable.cpp39
-rw-r--r--src/callable.h13
3 files changed, 43 insertions, 19 deletions
diff --git a/include/argument.h b/include/argument.h
index c75abc1..68ac7df 100644
--- a/include/argument.h
+++ b/include/argument.h
@@ -71,6 +71,16 @@ public:
* @internal
*/
void fill(struct _zend_arg_info *info) const;
+
+ /**
+ * Is this a required argument?
+ * @return bool
+ * @internal
+ */
+ bool required() const
+ {
+ return _required;
+ }
private:
/**
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: