summaryrefslogtreecommitdiff
path: root/src/classinfo.cpp
diff options
context:
space:
mode:
authorMartijn Otto <martijn.otto@copernica.com>2014-02-07 10:32:28 +0100
committerMartijn Otto <martijn.otto@copernica.com>2014-02-07 10:32:28 +0100
commit1a557938e18fb3cf60fbfb7471448fff3ea61c03 (patch)
tree2f71f6cb05ad912bba9a5f7203f641d1159afd41 /src/classinfo.cpp
parent7c3c6cb385543dd5a3730f6cce8337ae3c1307f7 (diff)
Fix segfault in module_shutdown under PHP5.3
Diffstat (limited to 'src/classinfo.cpp')
-rw-r--r--src/classinfo.cpp26
1 files changed, 22 insertions, 4 deletions
diff --git a/src/classinfo.cpp b/src/classinfo.cpp
index 04123b3..8778981 100644
--- a/src/classinfo.cpp
+++ b/src/classinfo.cpp
@@ -64,7 +64,7 @@ static zend_object_value create_object(zend_class_entry *type TSRMLS_DC)
#if PHP_VERSION_ID >= 50400
_ClassInfo *info = (_ClassInfo *)base->info.user.doc_comment;
#else
- _ClassInfo *info = (_ClassInfo *)base->doc_comment;
+ _ClassInfo *info = *((_ClassInfo **)base->doc_comment);
#endif
// store the class
@@ -138,9 +138,27 @@ void _ClassInfo::initialize(TSRMLS_DC)
#if PHP_VERSION_ID >= 50400
_entry->info.user.doc_comment = (const char *)this;
#else
- _entry->doc_comment = (char *)this;
-#endif
-
+ /**
+ * PHP 5.3 will free the doc_comment pointer if it
+ * is not NULL, which will result in the classinfo
+ * object being freed without being destructed
+ * properly, leading to segfaults when the destruct
+ * is called at a later stage (during module_shutdown).
+ *
+ * To prevent this we create an extra pointer that
+ * points to our this pointer. We do *not* free this
+ * pointer ourselves, because PHP does this. This
+ * way it does not free the classinfo.
+ */
+ char **wrapper = (char**)malloc(sizeof(char**));
+
+ // have the wrapper point to us
+ *wrapper = (char *)this;
+
+ // and store the wrapper inside the comment
+ _entry->doc_comment = (char *)wrapper;
+#endif
+
// initialize the entry
initialize(_entry);
}