Skip to content

Commit 7f23398

Browse files
committed
Address comments
1 parent b14f535 commit 7f23398

File tree

2 files changed

+64
-24
lines changed

2 files changed

+64
-24
lines changed

ext/pdo_mysql/mysql_statement.c

Lines changed: 21 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
#include "pdo/php_pdo_driver.h"
2828
#include "php_pdo_mysql.h"
2929
#include "php_pdo_mysql_int.h"
30+
#include "zend_interfaces.h"
3031

3132
#ifdef PDO_USE_MYSQLND
3233
# define pdo_mysql_stmt_execute_prepared(stmt) pdo_mysql_stmt_execute_prepared_mysqlnd(stmt)
@@ -490,11 +491,15 @@ static int pdo_mysql_stmt_param_hook(pdo_stmt_t *stmt, struct pdo_bound_param_da
490491
case IS_DOUBLE:
491492
mysqlnd_stmt_bind_one_param(S->stmt, param->paramno, parameter, MYSQL_TYPE_DOUBLE);
492493
break;
493-
default:
494-
if (!try_convert_to_string(parameter)) {
495-
PDO_DBG_RETURN(0);
494+
case IS_OBJECT:
495+
if(zend_class_implements_interface(Z_OBJCE_P(parameter), zend_ce_stringable)) {
496+
mysqlnd_stmt_bind_one_param(S->stmt, param->paramno, parameter, MYSQL_TYPE_VAR_STRING);
497+
break;
496498
}
497-
mysqlnd_stmt_bind_one_param(S->stmt, param->paramno, parameter, MYSQL_TYPE_VAR_STRING);
499+
ZEND_FALLTHROUGH;
500+
default:
501+
pdo_raise_impl_error(stmt->dbh, stmt, "HY105", "Expected a scalar value or null");
502+
PDO_DBG_RETURN(0);
498503
}
499504

500505
PDO_DBG_RETURN(1);
@@ -533,15 +538,19 @@ static int pdo_mysql_stmt_param_hook(pdo_stmt_t *stmt, struct pdo_bound_param_da
533538
b->buffer = &Z_DVAL_P(parameter);
534539
PDO_DBG_RETURN(1);
535540

536-
default:
537-
if (!try_convert_to_string(parameter)) {
538-
PDO_DBG_RETURN(0);
541+
case IS_OBJECT:
542+
if(zend_class_implements_interface(Z_OBJCE_P(parameter), zend_ce_stringable)) {
543+
b->buffer_type = MYSQL_TYPE_STRING;
544+
b->buffer = Z_STRVAL_P(parameter);
545+
b->buffer_length = Z_STRLEN_P(parameter);
546+
*b->length = Z_STRLEN_P(parameter);
547+
PDO_DBG_RETURN(1);
539548
}
540-
b->buffer_type = MYSQL_TYPE_STRING;
541-
b->buffer = Z_STRVAL_P(parameter);
542-
b->buffer_length = Z_STRLEN_P(parameter);
543-
*b->length = Z_STRLEN_P(parameter);
544-
PDO_DBG_RETURN(1);
549+
ZEND_FALLTHROUGH;
550+
551+
default:
552+
pdo_raise_impl_error(stmt->dbh, stmt, "HY105", "Expected a scalar value or null");
553+
PDO_DBG_RETURN(0);
545554
}
546555
#endif /* PDO_USE_MYSQLND */
547556
case PDO_PARAM_EVT_FREE:

ext/pdo_mysql/tests/gh13384.phpt

Lines changed: 43 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
--TEST--
2-
GH-13384 Fixed GH-13167 Fixed the behavior when an inappropriate value was passed to `bindValue`.
2+
GH-13384 Fixed GH-13167 Fixed the behavior when an inappropriate value was passed to `bindValue` and `bindParam`.
33
--EXTENSIONS--
44
pdo_mysql
55
--SKIPIF--
@@ -16,22 +16,53 @@ $db->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
1616

1717
$db->exec('CREATE TABLE test_gh13384 (mode TINYINT)');
1818

19-
$stmt = $db->prepare('INSERT INTO test_gh13384 (mode) VALUES (?)');
20-
$stmt->bindValue(1, new DateTime(), PDO::PARAM_INT);
19+
$stringableObject = new class () {
20+
public function __toString(): string
21+
{
22+
return 'I am stringable object';
23+
}
24+
};
2125

22-
var_dump($stmt->execute());
23-
var_dump($db->errorInfo());
24-
var_dump($db->query('SELECT * FROM test_gh13384')->fetchAll());
26+
echo "Stringable object, bindValue:\n";
27+
try {
28+
$stmt = $db->prepare('INSERT INTO test_gh13384 (mode) VALUES (?)');
29+
$stmt->bindValue(1, $stringableObject, PDO::PARAM_INT);
30+
$stmt->execute();
31+
} catch (Throwable $e) {
32+
echo $e->getMessage()."\n\n";
33+
}
34+
35+
echo "Normal object, bindValue:\n";
36+
try {
37+
$stmt = $db->prepare('INSERT INTO test_gh13384 (mode) VALUES (?)');
38+
$stmt->bindValue(1, new DateTime(), PDO::PARAM_INT);
39+
$stmt->execute();
40+
} catch (Throwable $e) {
41+
echo $e->getMessage()."\n\n";
42+
}
43+
44+
echo "Array, bindParam:\n";
45+
try {
46+
$stmt = $db->prepare('INSERT INTO test_gh13384 (mode) VALUES (?)');
47+
$param = ['aaa'];
48+
$stmt->bindParam(1, $param, PDO::PARAM_INT);
49+
$stmt->execute();
50+
} catch (Throwable $e) {
51+
echo $e->getMessage();
52+
}
2553
?>
2654
--CLEAN--
2755
<?php
2856
require_once __DIR__ . '/inc/mysql_pdo_test.inc';
2957
$db = MySQLPDOTest::factory();
3058
$db->exec('DROP TABLE IF EXISTS test_gh13384');
3159
?>
32-
--EXPECTF--
33-
Fatal error: Uncaught Error: Object of class DateTime could not be converted to string in %s
34-
Stack trace:
35-
#0 %s: PDOStatement->execute()
36-
#1 {main}
37-
thrown in %s
60+
--EXPECT--
61+
Stringable object, bindValue:
62+
SQLSTATE[HY000]: General error: 1366 Incorrect integer value: 'I am stringable object' for column 'mode' at row 1
63+
64+
Normal object, bindValue:
65+
SQLSTATE[HY105]: Invalid parameter type: Expected a scalar value or null
66+
67+
Array, bindParam:
68+
SQLSTATE[HY105]: Invalid parameter type: Expected a scalar value or null

0 commit comments

Comments
 (0)