Commits

Ruslan Osmanov committed 8b85a8b

Fix: segmentation fault on gc_collect_cycles() after calling Event::free(), 5lava @ Bitbucket reported

  • Participants
  • Parent commits 3b9a125

Comments (0)

Files changed (4)

     <email>osmanov@php.net</email>
     <active>yes</active>
   </lead>
-  <date>2013-07-18</date>
+  <date>2013-07-20</date>
   <!--{{{ Current version -->
   <version>
-    <release>1.7.0</release>
+    <release>1.7.1</release>
     <api>1.7.0</api>
   </version>
   <stability>
   </stability>
   <license uri="http://www.php.net/license">PHP</license>
   <notes><![CDATA[
-    Merged in 5lava/pecl-event (pull request #1) @bitbucket:
-    Fix: EventBufferEvent::setTimeouts() didn't work with double values
-    Fix: EventBuffer::copyout() didn't work in some cases
-    Add: EventBuffer::readFrom() method (corresponds to evbuffer_read())
-    Add: EventUtil::getSocketFD() method
+  Fix: segmentation fault on gc_collect_cycles() after calling Event::free(), 5lava @ Bitbucket reported
   ]]></notes>
   <!--}}}-->
   <!--{{{ Contents -->
         <file role="src" name="06-timer.phpt"/>
         <file role="src" name="07-listener-error.phpt"/>
         <file role="src" name="08-buffer.phpt"/>
+        <file role="src" name="09-gc-cycles.phpt"/>
       </dir>
     </dir>
   </contents>
   </extsrcrelease>
   <!--{{{ changelog-->
   <changelog>
+    <!--{{{ 1.7.1 -->
+    <release>
+      <version>
+        <release>1.7.1</release>
+        <api>1.7.0</api>
+      </version>
+      <stability>
+        <release>stable</release>
+        <api>stable</api>
+      </stability>
+      <license uri="http://www.php.net/license">PHP</license>
+      <notes><![CDATA[
+  Fix: segmentation fault on gc_collect_cycles() after calling Event::free(), 5lava @ Bitbucket reported
+  ]]></notes>
+    </release>
+    <!--}}}-->
     <!--{{{ 1.7.0 -->
     <release>
       <version>
 #ifndef PHP_EVENT_H
 #define PHP_EVENT_H
 
-#define PHP_EVENT_VERSION "1.7.0"
+#define PHP_EVENT_VERSION "1.7.1"
 
 #define PHP_EVENT_SUN_PREFIX "unix:"
 
 #include "src/priv.h"
 #include "src/util.h"
 
+#define PHP_EVENT_PROP_REQUIRE(x) \
+	do {                          \
+		if (!(x)) return FAILURE; \
+	} while (0);
+
 static inline void _prop_write_zval(zval **ppz, const zval *value)
 {
 	if (!*ppz) {
 {
 	php_event_t *e = (php_event_t *) obj;
 
-	PHP_EVENT_ASSERT(e->event);
+	PHP_EVENT_PROP_REQUIRE(e->event);
 
 	MAKE_STD_ZVAL(*retval);
 	ZVAL_BOOL(*retval, (php_event_is_pending(e->event) ? 1 : 0));
 {
 	php_event_t *e = (php_event_t *) obj;
 
-	PHP_EVENT_ASSERT(e->event);
+	if (!e->event) return NULL;
 
 	return (e->data ? &e->data : NULL);
 }
 {
 	php_event_t *e = (php_event_t *) obj;
 
-	PHP_EVENT_ASSERT(e->event);
+	PHP_EVENT_PROP_REQUIRE(e->event);
 
 	_prop_read_zval(e->data, retval);
 
 {
 	php_event_t *e = (php_event_t *) obj;
 
-	PHP_EVENT_ASSERT(e->event);
+	PHP_EVENT_PROP_REQUIRE(e->event);
 
 	_prop_write_zval(&e->data, value);
 
 {
 	php_event_buffer_t *b = (php_event_buffer_t *) obj;
 
-	PHP_EVENT_ASSERT(b->buf);
+	PHP_EVENT_PROP_REQUIRE(b->buf);
 
 	MAKE_STD_ZVAL(*retval);
 	ZVAL_LONG(*retval, evbuffer_get_length(b->buf));
 {
 	php_event_buffer_t *b = (php_event_buffer_t *) obj;
 
-	PHP_EVENT_ASSERT(b->buf);
+	PHP_EVENT_PROP_REQUIRE(b->buf);
 
 	MAKE_STD_ZVAL(*retval);
 	ZVAL_LONG(*retval, evbuffer_get_contiguous_space(b->buf));
 	MAKE_STD_ZVAL(*retval);
 
 	/* Uninitialized / free'd */
+#if 0
 	if (!b->bevent) {
 		ZVAL_NULL(*retval);
 		return SUCCESS;
 	}
-	PHP_EVENT_ASSERT(b->bevent);
+#endif
+	PHP_EVENT_PROP_REQUIRE(b->bevent);
 
 	fd = bufferevent_getfd(b->bevent);
 	if (fd == -1) {

tests/09-gc-cycles.phpt

+--TEST--
+Check for gc_collect_cycles appled after event free
+--SKIPIF--
+<?php if (!function_exists("gc_collect_cycles")) print "skip"; ?>
+--FILE--
+<?php
+$base = new EventBase();
+$e = new Event($base, 0, Event::READ, function(){});
+$e->free();
+gc_collect_cycles(); // segfaults if something goes wrong
+echo "ok";
+?>
+--EXPECT--
+ok