--- /dev/null
+--TEST--
+Generators can't be serialized or unserialized
+--FILE--
+<?php
+
+function gen() { yield; }
+
+$gen = gen();
+
+try {
+ serialize($gen);
+} catch (Exception $e) {
+ echo $e, "\n\n";
+}
+
+try {
+ var_dump(unserialize('O:9:"Generator":0:{}'));
+} catch (Exception $e) {
+ echo $e, "\n\n";
+}
+
+try {
+ var_dump(unserialize('C:9:"Generator":0:{}'));
+} catch (Exception $e) {
+ echo $e;
+}
+
+?>
+--EXPECTF--
+exception 'Exception' with message 'Serialization of 'Generator' is not allowed' in %s:%d
+Stack trace:
+#0 %s(%d): serialize(Object(Generator))
+#1 {main}
+
+exception 'Exception' with message 'Unserialization of 'Generator' is not allowed' in %s:%d
+Stack trace:
+#0 [internal function]: Generator->__wakeup()
+#1 %s(%d): unserialize('O:9:"Generator"...')
+#2 {main}
+
+
+Notice: unserialize(): Error at offset 19 of 20 bytes in %s on line %d
+exception 'Exception' with message 'Unserialization of 'Generator' is not allowed' in %s:%d
+Stack trace:
+#0 %s(%d): unserialize('C:9:"Generator"...')
+#1 {main}
}
}
+
+/* {{{ proto void Generator::__wakeup
+ * Throws an Exception as generators can't be serialized */
+ZEND_METHOD(Generator, __wakeup)
+{
+ /* Just specifying the zend_class_unserialize_deny handler is not enough,
+ * because it is only invoked for C unserialization. For O the error has
+ * to be thrown in __wakeup. */
+
+ if (zend_parse_parameters_none() == FAILURE) {
+ return;
+ }
+
+ zend_throw_exception(NULL, "Unserialization of 'Generator' is not allowed", 0 TSRMLS_CC);
+}
+/* }}} */
+
/* get_iterator implementation */
typedef struct _zend_generator_iterator {
ZEND_END_ARG_INFO()
static const zend_function_entry generator_functions[] = {
- ZEND_ME(Generator, rewind, arginfo_generator_void, ZEND_ACC_PUBLIC)
- ZEND_ME(Generator, valid, arginfo_generator_void, ZEND_ACC_PUBLIC)
- ZEND_ME(Generator, current, arginfo_generator_void, ZEND_ACC_PUBLIC)
- ZEND_ME(Generator, key, arginfo_generator_void, ZEND_ACC_PUBLIC)
- ZEND_ME(Generator, next, arginfo_generator_void, ZEND_ACC_PUBLIC)
- ZEND_ME(Generator, send, arginfo_generator_send, ZEND_ACC_PUBLIC)
+ ZEND_ME(Generator, rewind, arginfo_generator_void, ZEND_ACC_PUBLIC)
+ ZEND_ME(Generator, valid, arginfo_generator_void, ZEND_ACC_PUBLIC)
+ ZEND_ME(Generator, current, arginfo_generator_void, ZEND_ACC_PUBLIC)
+ ZEND_ME(Generator, key, arginfo_generator_void, ZEND_ACC_PUBLIC)
+ ZEND_ME(Generator, next, arginfo_generator_void, ZEND_ACC_PUBLIC)
+ ZEND_ME(Generator, send, arginfo_generator_send, ZEND_ACC_PUBLIC)
+ ZEND_ME(Generator, __wakeup, arginfo_generator_void, ZEND_ACC_PUBLIC)
ZEND_FE_END
};
zend_ce_generator = zend_register_internal_class(&ce TSRMLS_CC);
zend_ce_generator->ce_flags |= ZEND_ACC_FINAL_CLASS;
zend_ce_generator->create_object = zend_generator_create;
+ zend_ce_generator->serialize = zend_class_serialize_deny;
+ zend_ce_generator->unserialize = zend_class_unserialize_deny;
/* get_iterator has to be assigned *after* implementing the inferface */
zend_class_implements(zend_ce_generator TSRMLS_CC, 1, zend_ce_iterator);