Skip to content

Commit 83b8a92

Browse files
committed
Handle freeing of fetched data at call site
1 parent 44b1d2b commit 83b8a92

File tree

1 file changed

+20
-14
lines changed

1 file changed

+20
-14
lines changed

ext/pdo/pdo_stmt.c

Lines changed: 20 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -730,8 +730,6 @@ static bool do_fetch(pdo_stmt_t *stmt, zval *return_value, enum pdo_fetch_type h
730730
return true;
731731
}
732732

733-
RETVAL_FALSE;
734-
735733
switch (how) {
736734
case PDO_FETCH_USE_DEFAULT:
737735
case PDO_FETCH_ASSOC:
@@ -852,8 +850,6 @@ static bool do_fetch(pdo_stmt_t *stmt, zval *return_value, enum pdo_fetch_type h
852850
zval_ptr_dtor(&unserialization_string);
853851
if (unserialize_res == FAILURE) {
854852
pdo_raise_impl_error(stmt->dbh, stmt, "HY000", "cannot unserialize class");
855-
zval_ptr_dtor(return_value);
856-
ZVAL_NULL(return_value);
857853
return false;
858854
}
859855
column_index_to_fetch++;
@@ -925,20 +921,14 @@ static bool do_fetch(pdo_stmt_t *stmt, zval *return_value, enum pdo_fetch_type h
925921
case PDO_FETCH_FUNC:
926922
ZVAL_COPY_VALUE(&fetch_function_params[fetch_function_param_num++], &val);
927923
break;
928-
929-
default:
930-
zval_ptr_dtor(&val);
931-
zend_value_error("Fetch mode must be a bitmask of PDO::FETCH_* constants");
932-
return 0;
924+
EMPTY_SWITCH_DEFAULT_CASE();
933925
}
934926
}
935927

936928
/* Run constructor for objects if not already run and not unserialized */
937929
if (how == PDO_FETCH_CLASS && ce->constructor && !(flags & (PDO_FETCH_PROPS_LATE | PDO_FETCH_SERIALIZE))) {
938930
bool failed = pdo_call_fetch_object_constructor(ce->constructor, ctor_arguments, return_value);
939931
if (UNEXPECTED(failed)) {
940-
zval_ptr_dtor(return_value);
941-
RETVAL_FALSE;
942932
return false;
943933
}
944934
} else if (how == PDO_FETCH_FUNC) {
@@ -1046,6 +1036,7 @@ PHP_METHOD(PDOStatement, fetch)
10461036
return;
10471037
}
10481038
if (!do_fetch(stmt, return_value, how, ori, off, NULL)) {
1039+
zval_ptr_dtor(return_value);
10491040
PDO_HANDLE_STMT_ERR();
10501041
RETURN_FALSE;
10511042
}
@@ -1083,6 +1074,7 @@ PHP_METHOD(PDOStatement, fetchObject)
10831074
stmt->fetch.cls.ctor_args = ctor_args;
10841075

10851076
if (!do_fetch(stmt, return_value, PDO_FETCH_CLASS, PDO_FETCH_ORI_NEXT, /* offset */ 0, NULL)) {
1077+
zval_ptr_dtor(return_value);
10861078
PDO_HANDLE_STMT_ERR();
10871079
RETVAL_FALSE;
10881080
}
@@ -1254,8 +1246,14 @@ PHP_METHOD(PDOStatement, fetchAll)
12541246

12551247
if (fetch_mode == PDO_FETCH_KEY_PAIR) {
12561248
while (pdo_do_key_pair_fetch(stmt, PDO_FETCH_ORI_NEXT, /* offset */ 0, Z_ARRVAL_P(return_value)));
1257-
PDO_HANDLE_STMT_ERR();
1258-
return;
1249+
/* Inline PDO_HANDLE_STMT_ERR(); as we need to free the return value */
1250+
if (UNEXPECTED(EG(exception) || strcmp(stmt->error_code, PDO_ERR_NONE) != 0)) {
1251+
zval_ptr_dtor(return_value);
1252+
if (strcmp(stmt->error_code, PDO_ERR_NONE) != 0) {
1253+
pdo_handle_error(stmt->dbh, stmt);
1254+
}
1255+
RETURN_EMPTY_ARRAY();
1256+
}
12591257
}
12601258

12611259
// Need to handle the "broken" PDO_FETCH_GROUP|PDO_FETCH_UNIQUE fetch case
@@ -1287,7 +1285,15 @@ PHP_METHOD(PDOStatement, fetchAll)
12871285
stmt->fetch.cls.ce = old_ce;
12881286
stmt->fetch.cls.ctor_args = old_ctor_args;
12891287

1290-
PDO_HANDLE_STMT_ERR();
1288+
/* Inline PDO_HANDLE_STMT_ERR(); as we need to free the return value */
1289+
if (UNEXPECTED(EG(exception) || strcmp(stmt->error_code, PDO_ERR_NONE) != 0)) {
1290+
zval_ptr_dtor(&data);
1291+
zval_ptr_dtor(return_value);
1292+
if (strcmp(stmt->error_code, PDO_ERR_NONE) != 0) {
1293+
pdo_handle_error(stmt->dbh, stmt);
1294+
}
1295+
RETURN_EMPTY_ARRAY();
1296+
}
12911297
}
12921298
/* }}} */
12931299

0 commit comments

Comments
 (0)