summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorToon Schoenmakers <toon.schoenmakers@copernica.com>2014-11-25 11:45:47 +0100
committerToon Schoenmakers <toon.schoenmakers@copernica.com>2014-11-25 11:45:47 +0100
commitda4de6cb1097471b2659c102d55a646cbc9e0f41 (patch)
tree1d3cdff8d534b76c5e1e4f8855a7f706516aa4a2
parent945748c19b966fff297d9a7a1e2dfda3b0a80754 (diff)
Fixed a memory leak when returning a Php::Object with an already allocated Basev1.2.2
-rw-r--r--include/object.h22
-rw-r--r--zend/callable.cpp6
-rw-r--r--zend/callable.h2
-rw-r--r--zend/object.cpp12
-rw-r--r--zend/value.cpp3
5 files changed, 21 insertions, 24 deletions
diff --git a/include/object.h b/include/object.h
index 29f4110..9387408 100644
--- a/include/object.h
+++ b/include/object.h
@@ -82,17 +82,17 @@ public:
* @param arg8 Optional argument 9
* @param arg9 Optional argument 10
*/
- Object(const char *name) : Value(Type::Object) { if (instantiate(name)) call("__construct"); }
- Object(const char *name, Value p0) : Value(Type::Object) { if (instantiate(name)) call("__construct", p0); }
- Object(const char *name, Value p0, Value p1) : Value(Type::Object) { if (instantiate(name)) call("__construct", p0, p1); }
- Object(const char *name, Value p0, Value p1, Value p2) : Value(Type::Object) { if (instantiate(name)) call("__construct", p0, p1, p2); }
- Object(const char *name, Value p0, Value p1, Value p2, Value p3) : Value(Type::Object) { if (instantiate(name)) call("__construct", p0, p1, p2, p3); }
- Object(const char *name, Value p0, Value p1, Value p2, Value p3, Value p4) : Value(Type::Object) { if (instantiate(name)) call("__construct", p0, p1, p2, p3, p4); }
- Object(const char *name, Value p0, Value p1, Value p2, Value p3, Value p4, Value p5) : Value(Type::Object) { if (instantiate(name)) call("__construct", p0, p1, p2, p3, p4, p5); }
- Object(const char *name, Value p0, Value p1, Value p2, Value p3, Value p4, Value p5, Value p6) : Value(Type::Object) { if (instantiate(name)) call("__construct", p0, p1, p2, p3, p4, p5, p6); }
- Object(const char *name, Value p0, Value p1, Value p2, Value p3, Value p4, Value p5, Value p6, Value p7) : Value(Type::Object) { if (instantiate(name)) call("__construct", p0, p1, p2, p3, p4, p5, p6, p7); }
- Object(const char *name, Value p0, Value p1, Value p2, Value p3, Value p4, Value p5, Value p6, Value p7, Value p8) : Value(Type::Object) { if (instantiate(name)) call("__construct", p0, p1, p2, p3, p4, p5, p6, p7, p8); }
- Object(const char *name, Value p0, Value p1, Value p2, Value p3, Value p4, Value p5, Value p6, Value p7, Value p8, Value p9) : Value(Type::Object) { if (instantiate(name)) call("__construct", p0, p1, p2, p3, p4, p5, p6, p7, p8, p9); }
+ Object(const char *name) : Value() { if (instantiate(name)) call("__construct"); }
+ Object(const char *name, Value p0) : Value() { if (instantiate(name)) call("__construct", p0); }
+ Object(const char *name, Value p0, Value p1) : Value() { if (instantiate(name)) call("__construct", p0, p1); }
+ Object(const char *name, Value p0, Value p1, Value p2) : Value() { if (instantiate(name)) call("__construct", p0, p1, p2); }
+ Object(const char *name, Value p0, Value p1, Value p2, Value p3) : Value() { if (instantiate(name)) call("__construct", p0, p1, p2, p3); }
+ Object(const char *name, Value p0, Value p1, Value p2, Value p3, Value p4) : Value() { if (instantiate(name)) call("__construct", p0, p1, p2, p3, p4); }
+ Object(const char *name, Value p0, Value p1, Value p2, Value p3, Value p4, Value p5) : Value() { if (instantiate(name)) call("__construct", p0, p1, p2, p3, p4, p5); }
+ Object(const char *name, Value p0, Value p1, Value p2, Value p3, Value p4, Value p5, Value p6) : Value() { if (instantiate(name)) call("__construct", p0, p1, p2, p3, p4, p5, p6); }
+ Object(const char *name, Value p0, Value p1, Value p2, Value p3, Value p4, Value p5, Value p6, Value p7) : Value() { if (instantiate(name)) call("__construct", p0, p1, p2, p3, p4, p5, p6, p7); }
+ Object(const char *name, Value p0, Value p1, Value p2, Value p3, Value p4, Value p5, Value p6, Value p7, Value p8) : Value() { if (instantiate(name)) call("__construct", p0, p1, p2, p3, p4, p5, p6, p7, p8); }
+ Object(const char *name, Value p0, Value p1, Value p2, Value p3, Value p4, Value p5, Value p6, Value p7, Value p8, Value p9) : Value() { if (instantiate(name)) call("__construct", p0, p1, p2, p3, p4, p5, p6, p7, p8, p9); }
/**
* Destructor
diff --git a/zend/callable.cpp b/zend/callable.cpp
index 7505bbf..f0dc3e8 100644
--- a/zend/callable.cpp
+++ b/zend/callable.cpp
@@ -51,12 +51,12 @@ void Callable::invoke(INTERNAL_FUNCTION_PARAMETERS)
{
// get the result
Value result(callable->invoke(params));
-
+
// we're ready if the return value is not even used
if (!return_value_used) return;
-
+
// @todo php 5.6 has a RETVAL_ZVAL_FAST macro that can be used instead (and is faster)
-
+
// return a full copy of the zval, and do not destruct it
RETVAL_ZVAL(result._val, 1, 0);
}
diff --git a/zend/callable.h b/zend/callable.h
index 9958a2a..bd74f27 100644
--- a/zend/callable.h
+++ b/zend/callable.h
@@ -144,7 +144,7 @@ protected:
{
// fill members
info->name = arg.name();
- info->name_len = ::strlen(arg.name());
+ info->name_len = ::strlen(arg.name());
#if PHP_VERSION_ID >= 50400
diff --git a/zend/object.cpp b/zend/object.cpp
index a4eaf1e..4af6204 100644
--- a/zend/object.cpp
+++ b/zend/object.cpp
@@ -17,7 +17,7 @@ namespace Php {
* @param name Name of the class to instantiate
* @param base Implementation of the class
*/
-Object::Object(const char *name, Base *base) : Value(Type::Object)
+Object::Object(const char *name, Base *base) : Value()
{
// does the object already have a handle?
if (base->implementation())
@@ -29,7 +29,7 @@ Object::Object(const char *name, Base *base) : Value(Type::Object)
{
// we need the tsrm_ls variable
TSRMLS_FETCH();
-
+
// this is a brand new object that should be allocated, the C++ instance
// is already there (created by the extension) but it is not yet stored
// in PHP, find out the classname first (we use the FatalError class
@@ -38,14 +38,14 @@ Object::Object(const char *name, Base *base) : Value(Type::Object)
// by the extension).
auto *entry = zend_fetch_class(name, ::strlen(name), ZEND_FETCH_CLASS_SILENT TSRMLS_CC);
if (!entry) throw FatalError(std::string("Unknown class name ") + name);
-
+
// construct an implementation (this will also set the implementation
// member in the base object)
new ObjectImpl(entry, base TSRMLS_CC);
-
+
// now we can store it
operator=(Value(base));
-
+
// install the object handlers
Z_OBJVAL_P(_val).handlers = ClassImpl::objectHandlers(entry);
}
@@ -56,7 +56,7 @@ Object::Object(const char *name, Base *base) : Value(Type::Object)
* or when it is a string holding a classname
* @param that An other object
*/
-Object::Object(const Value &value) : Value(Type::Object)
+Object::Object(const Value &value) : Value()
{
// when a string is passed in, we are going to make a new instance of the
// passed in string
diff --git a/zend/value.cpp b/zend/value.cpp
index 946a41d..501feb7 100644
--- a/zend/value.cpp
+++ b/zend/value.cpp
@@ -210,9 +210,6 @@ Value::Value(const Base *object)
// store the handlers in the zval too (cast is necessary for php 5.3)
Z_OBJ_HT_P(_val) = (zend_object_handlers*)obj_bucket->bucket.obj.handlers;
-
- // run the copy constructor
- zval_copy_ctor(_val);
}
/**