]> granicus.if.org Git - php/commitdiff
Fix memory error when throwing into a generator
authorNikita Popov <nikic@php.net>
Fri, 17 Apr 2015 20:19:41 +0000 (22:19 +0200)
committerNikita Popov <nikic@php.net>
Fri, 17 Apr 2015 20:19:41 +0000 (22:19 +0200)
throw_exception_internal will access opline+1, which is not always
defined at the current opline of the generator. To avoid this
decrement the opline before throwing (so the throw occurs at the
YIELD opcode instead of one after it).

Zend/zend_generators.c

index 7d2472a1458d9ce45c6718f519098dc70a1cc214..ea84950691d27e2bd0aa02cc2fe3ded6fc14e624 100644 (file)
@@ -313,14 +313,17 @@ ZEND_API zend_execute_data *zend_generator_check_placeholder_frame(zend_execute_
 
 static void zend_generator_throw_exception(zend_generator *generator, zval *exception)
 {
-       /* Throw the exception in the context of the generator */
+       /* Throw the exception in the context of the generator. Decrementing the opline
+        * to pretend the exception happened during the YIELD opcode. */
        zend_execute_data *original_execute_data = EG(current_execute_data);
        EG(current_execute_data) = generator->execute_data;
+       generator->execute_data->opline--;
        if (exception) {
                zend_throw_exception_object(exception);
        } else {
                zend_throw_exception_internal(NULL);
        }
+       generator->execute_data->opline++;
        EG(current_execute_data) = original_execute_data;
 }