]> granicus.if.org Git - php/commitdiff
Check PDOStatement initialization during iteration
authorNikita Popov <nikita.ppv@gmail.com>
Mon, 19 Oct 2020 08:22:08 +0000 (10:22 +0200)
committerNikita Popov <nikita.ppv@gmail.com>
Mon, 19 Oct 2020 08:22:56 +0000 (10:22 +0200)
ext/pdo/pdo_stmt.c
ext/pdo/tests/pdo_uninitialized.phpt [new file with mode: 0644]

index 3222a617f07e9b72c1abf0edcbb24e346e9021f7..f8ff90ba9b425f0746091668ed7b4205c9c741eb 100644 (file)
@@ -2287,15 +2287,18 @@ static const zend_object_iterator_funcs pdo_stmt_iter_funcs = {
 
 zend_object_iterator *pdo_stmt_iter_get(zend_class_entry *ce, zval *object, int by_ref)
 {
-       pdo_stmt_t *stmt = Z_PDO_STMT_P(object);
-       struct php_pdo_iterator *I;
-
        if (by_ref) {
                zend_throw_error(NULL, "An iterator cannot be used with foreach by reference");
                return NULL;
        }
 
-       I = ecalloc(1, sizeof(struct php_pdo_iterator));
+       pdo_stmt_t *stmt = Z_PDO_STMT_P(object);
+       if (!stmt->dbh) {
+               zend_throw_error(NULL, "PDO object is uninitialized");
+               return NULL;
+       }
+
+       struct php_pdo_iterator *I = ecalloc(1, sizeof(struct php_pdo_iterator));
        zend_iterator_init(&I->iter);
        I->iter.funcs = &pdo_stmt_iter_funcs;
        Z_ADDREF_P(object);
diff --git a/ext/pdo/tests/pdo_uninitialized.phpt b/ext/pdo/tests/pdo_uninitialized.phpt
new file mode 100644 (file)
index 0000000..4ddfa75
--- /dev/null
@@ -0,0 +1,39 @@
+--TEST--
+Uninitialized PDO objects
+--SKIPIF--
+<?php if (!extension_loaded('pdo')) die('skip'); ?>
+--FILE--
+<?php
+
+class MyPDO extends PDO {
+    public function __construct() {}
+}
+class MyPDOStatement extends PDOStatement {
+    public function __construct() {}
+}
+
+$pdo = new MyPDO;
+try {
+    $pdo->query("foo");
+} catch (Error $e) {
+    echo $e->getMessage(), "\n";
+}
+
+$stmt = new MyPDOStatement;
+try {
+    $stmt->fetch();
+} catch (Error $e) {
+    echo $e->getMessage(), "\n";
+}
+$stmt = new MyPDOStatement;
+try {
+    foreach ($stmt as $row) {}
+} catch (Error $e) {
+    echo $e->getMessage(), "\n";
+}
+
+?>
+--EXPECT--
+PDO object is not initialized, constructor was not called
+PDO object is uninitialized
+PDO object is uninitialized