Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 9 additions & 12 deletions ext/pdo/pdo_dbh.c
Original file line numberDiff line numberDiff line change
Expand Up@@ -34,7 +34,7 @@
#include "zend_interfaces.h"
#include "pdo_dbh_arginfo.h"

static int pdo_dbh_attribute_set(pdo_dbh_t *dbh, zend_long attr, zval *value);
static zend_result pdo_dbh_attribute_set(pdo_dbh_t *dbh, zend_long attr, zval *value);

void pdo_throw_exception(unsigned int driver_errcode, char *driver_errmsg, pdo_error_type *pdo_error)
{
Expand DownExpand Up@@ -405,6 +405,7 @@ PHP_METHOD(PDO, __construct)
continue;
}
ZVAL_DEREF(attr_value);
/* TODO: Check that this doesn't fail? */
pdo_dbh_attribute_set(dbh, long_key, attr_value);
} ZEND_HASH_FOREACH_END();
}
Expand DownExpand Up@@ -434,6 +435,9 @@ static zval *pdo_stmt_instantiate(pdo_dbh_t *dbh, zval *object, zend_class_entry
}

if (UNEXPECTED(object_init_ex(object, dbstmt_ce) != SUCCESS)) {
if (EXPECTED(!EG(exception))) {
zend_throw_error(NULL, "Cannot instantiate user-supplied statement class");
}
return NULL;
}

Expand DownExpand Up@@ -544,13 +548,8 @@ PHP_METHOD(PDO, prepare)
ZVAL_COPY_VALUE(&ctor_args, &dbh->def_stmt_ctor_args);
}

/* Need to check if pdo_stmt_instantiate() throws an exception unconditionally to see if can change the RETURN_FALSE; */
if (!pdo_stmt_instantiate(dbh, return_value, dbstmt_ce, &ctor_args)) {
if (EXPECTED(!EG(exception))) {
zend_throw_error(NULL, "Cannot instantiate user-supplied statement class");
}
PDO_HANDLE_DBH_ERR();
RETURN_FALSE;
RETURN_THROWS();
}
stmt = Z_PDO_STMT_P(return_value);

Expand DownExpand Up@@ -674,7 +673,7 @@ PHP_METHOD(PDO, inTransaction)
}
/* }}} */

static int pdo_dbh_attribute_set(pdo_dbh_t *dbh, zend_long attr, zval *value) /* {{{ */
static zend_result pdo_dbh_attribute_set(pdo_dbh_t *dbh, zend_long attr, zval *value) /* {{{ */
{
zend_long lval;

Expand DownExpand Up@@ -752,6 +751,7 @@ static int pdo_dbh_attribute_set(pdo_dbh_t *dbh, zend_long attr, zval *value) /*
zval *item;

if (dbh->is_persistent) {
/* TODO: ValueError/ PDOException? */
pdo_raise_impl_error(dbh, NULL, "HY000",
"PDO::ATTR_STATEMENT_CLASS cannot be used with persistent PDO instances"
);
Expand DownExpand Up@@ -1070,10 +1070,7 @@ PHP_METHOD(PDO, query)
PDO_DBH_CLEAR_ERR();

if (!pdo_stmt_instantiate(dbh, return_value, dbh->def_stmt_ce, &dbh->def_stmt_ctor_args)) {
if (EXPECTED(!EG(exception))) {
pdo_raise_impl_error(dbh, NULL, "HY000", "failed to instantiate user supplied statement class");
}
return;
RETURN_THROWS();
}
stmt = Z_PDO_STMT_P(return_value);

Expand Down
29 changes: 13 additions & 16 deletions ext/pdo/pdo_stmt.c
Original file line numberDiff line numberDiff line change
Expand Up@@ -41,7 +41,7 @@
RETURN_THROWS(); \
} \

static inline int rewrite_name_to_position(pdo_stmt_t *stmt, struct pdo_bound_param_data *param) /* {{{ */
static inline bool rewrite_name_to_position(pdo_stmt_t *stmt, struct pdo_bound_param_data *param) /* {{{ */
{
if (stmt->bound_param_map) {
/* rewriting :name to ? style.
Expand DownExpand Up@@ -90,9 +90,9 @@ static inline int rewrite_name_to_position(pdo_stmt_t *stmt, struct pdo_bound_pa
/* }}} */

/* trigger callback hook for parameters */
static int dispatch_param_event(pdo_stmt_t *stmt, enum pdo_param_event event_type) /* {{{ */
static bool dispatch_param_event(pdo_stmt_t *stmt, enum pdo_param_event event_type) /* {{{ */
{
int ret = 1, is_param = 1;
bool ret = 1, is_param = 1;
struct pdo_bound_param_data *param;
HashTable *ht;

Expand DownExpand Up@@ -212,7 +212,7 @@ static void param_dtor(zval *el) /* {{{ */
}
/* }}} */

static int really_register_bound_param(struct pdo_bound_param_data *param, pdo_stmt_t *stmt, int is_param) /* {{{ */
static bool really_register_bound_param(struct pdo_bound_param_data *param, pdo_stmt_t *stmt, bool is_param) /* {{{ */
{
HashTable *hash;
zval *parameter;
Expand DownExpand Up@@ -381,12 +381,7 @@ PHP_METHOD(PDOStatement, execute)
param.paramno = -1;
} else {
/* we're okay to be zero based here */
/* num_index is unsignend
if (num_index < 0) {
pdo_raise_impl_error(stmt->dbh, stmt, "HY093", NULL);
RETURN_FALSE;
}
*/
/* num_index is unsignend */
param.paramno = num_index;
}

Expand DownExpand Up@@ -601,7 +596,7 @@ static inline void fetch_value(pdo_stmt_t *stmt, zval *dest, int colno, int *typ
}
/* }}} */

static int do_fetch_common(pdo_stmt_t *stmt, enum pdo_fetch_orientation ori, zend_long offset) /* {{{ */
static bool do_fetch_common(pdo_stmt_t *stmt, enum pdo_fetch_orientation ori, zend_long offset) /* {{{ */
{
if (!stmt->executed) {
return 0;
Expand DownExpand Up@@ -652,7 +647,7 @@ static int do_fetch_common(pdo_stmt_t *stmt, enum pdo_fetch_orientation ori, zen
}
/* }}} */

static int do_fetch_class_prepare(pdo_stmt_t *stmt) /* {{{ */
static bool do_fetch_class_prepare(pdo_stmt_t *stmt) /* {{{ */
{
zend_class_entry *ce = stmt->fetch.cls.ce;
zend_fcall_info *fci = &stmt->fetch.cls.fci;
Expand All@@ -677,16 +672,15 @@ static int do_fetch_class_prepare(pdo_stmt_t *stmt) /* {{{ */
fcc->called_scope = ce;
return 1;
} else if (!Z_ISUNDEF(stmt->fetch.cls.ctor_args)) {
/* TODO Error? */
pdo_raise_impl_error(stmt->dbh, stmt, "HY000", "user-supplied class does not have a constructor, use NULL for the ctor_params parameter, or simply omit it");
zend_throw_error(NULL, "User-supplied statement does not accept constructor arguments");
return 0;
} else {
return 1; /* no ctor no args is also ok */
}
}
/* }}} */

static int make_callable_ex(pdo_stmt_t *stmt, zval *callable, zend_fcall_info * fci, zend_fcall_info_cache * fcc, int num_args) /* {{{ */
static bool make_callable_ex(pdo_stmt_t *stmt, zval *callable, zend_fcall_info * fci, zend_fcall_info_cache * fcc, int num_args) /* {{{ */
{
char *is_callable_error = NULL;

Expand DownExpand Up@@ -809,6 +803,7 @@ static bool do_fetch(pdo_stmt_t *stmt, zval *return_value, enum pdo_fetch_type h

case PDO_FETCH_KEY_PAIR:
if (stmt->column_count != 2) {
/* TODO: Error? */
pdo_raise_impl_error(stmt->dbh, stmt, "HY000", "PDO::FETCH_KEY_PAIR fetch mode requires the result set to contain exactly 2 columns.");
return 0;
}
Expand DownExpand Up@@ -904,6 +899,7 @@ static bool do_fetch(pdo_stmt_t *stmt, zval *return_value, enum pdo_fetch_type h
break;

case PDO_FETCH_INTO:
/* TODO: Make this an assertion and ensure this is true higher up? */
if (Z_ISUNDEF(stmt->fetch.into)) {
/* TODO ArgumentCountError? */
pdo_raise_impl_error(stmt->dbh, stmt, "HY000", "No fetch-into object specified.");
Expand All@@ -919,6 +915,7 @@ static bool do_fetch(pdo_stmt_t *stmt, zval *return_value, enum pdo_fetch_type h
break;

case PDO_FETCH_FUNC:
/* TODO: Make this an assertion and ensure this is true higher up? */
if (Z_ISUNDEF(stmt->fetch.func.function)) {
/* TODO ArgumentCountError? */
pdo_raise_impl_error(stmt->dbh, stmt, "HY000", "No fetch function specified");
Expand DownExpand Up@@ -1633,7 +1630,7 @@ PHP_METHOD(PDOStatement, setAttribute)

/* {{{ Get an attribute */

static int generic_stmt_attr_get(pdo_stmt_t *stmt, zval *return_value, zend_long attr)
static bool generic_stmt_attr_get(pdo_stmt_t *stmt, zval *return_value, zend_long attr)
{
switch (attr) {
case PDO_ATTR_EMULATE_PREPARES:
Expand Down
19 changes: 8 additions & 11 deletions ext/pdo_mysql/tests/pdo_mysql_attr_statement_class.phpt
Original file line numberDiff line numberDiff line change
Expand Up@@ -114,13 +114,15 @@ $db = MySQLPDOTest::factory();
// Yes, this is a fatal error and I want it to fail.
abstract class mystatement6 extends mystatement5 {
}
if (true !== ($tmp = $db->setAttribute(PDO::ATTR_STATEMENT_CLASS, array('mystatement6', array('mystatement6')))))
printf("[011] Expecting boolean/true got %s\n", var_export($tmp, true));
$stmt = $db->query('SELECT id, label FROM test ORDER BY id ASC LIMIT 1');
try {
$db->setAttribute(PDO::ATTR_STATEMENT_CLASS, ['mystatement6', ['mystatement6']]);
$stmt = $db->query('SELECT id, label FROM test ORDER BY id ASC LIMIT 1');
} catch (\Error $e) {
echo get_class($e), ': ', $e->getMessage(), \PHP_EOL;
}

print "done!";
?>
--EXPECTF--
--EXPECT--
array(1) {
[0]=>
string(12) "PDOStatement"
Expand DownExpand Up@@ -157,9 +159,4 @@ array(1) {
string(1) "a"
}
}

Fatal error: Uncaught Error: Cannot instantiate abstract class mystatement6 in %s:%d
Stack trace:
#0 %s(%d): PDO->query('SELECT id, labe...')
#1 {main}
thrown in %s on line %d
Error: Cannot instantiate abstract class mystatement6