1
0
mirror of https://github.com/php/php-src.git synced 2026-03-24 00:02:20 +01:00

Merge branch 'PHP-8.4'

* PHP-8.4:
  PDO_MYSQL: Properly quote binary strings
  Reproduce unexpected MySQL warnings for binary values
This commit is contained in:
Matteo Beccati
2024-10-07 11:17:46 +02:00
3 changed files with 96 additions and 9 deletions

View File

@@ -309,23 +309,29 @@ static zend_string* mysql_handle_quoter(pdo_dbh_t *dbh, const zend_string *unquo
{
pdo_mysql_db_handle *H = (pdo_mysql_db_handle *)dbh->driver_data;
bool use_national_character_set = 0;
bool use_binary = 0;
size_t quotedlen;
if (H->assume_national_character_set_strings) {
use_national_character_set = 1;
}
if ((paramtype & PDO_PARAM_STR_NATL) == PDO_PARAM_STR_NATL) {
use_national_character_set = 1;
}
if ((paramtype & PDO_PARAM_STR_CHAR) == PDO_PARAM_STR_CHAR) {
use_national_character_set = 0;
if ((paramtype & PDO_PARAM_LOB) == PDO_PARAM_LOB) {
use_binary = 1;
} else {
if (H->assume_national_character_set_strings) {
use_national_character_set = 1;
}
if ((paramtype & PDO_PARAM_STR_NATL) == PDO_PARAM_STR_NATL) {
use_national_character_set = 1;
}
if ((paramtype & PDO_PARAM_STR_CHAR) == PDO_PARAM_STR_CHAR) {
use_national_character_set = 0;
}
}
PDO_DBG_ENTER("mysql_handle_quoter");
PDO_DBG_INF_FMT("dbh=%p", dbh);
PDO_DBG_INF_FMT("unquoted=%.*s", (int)ZSTR_LEN(unquoted), ZSTR_VAL(unquoted));
zend_string *quoted_str = zend_string_safe_alloc(2, ZSTR_LEN(unquoted), 3 + (use_national_character_set ? 1 : 0), false);
zend_string *quoted_str = zend_string_safe_alloc(2, ZSTR_LEN(unquoted),
3 + (use_national_character_set ? 1 : 0) + (use_binary ? 7 : 0), false);
char *quoted = ZSTR_VAL(quoted_str);
if (use_national_character_set) {
@@ -334,6 +340,11 @@ static zend_string* mysql_handle_quoter(pdo_dbh_t *dbh, const zend_string *unquo
quoted[1] = '\'';
++quotedlen; /* N prefix */
} else if (use_binary) {
quotedlen = mysql_real_escape_string_quote(H->server, quoted + 8, ZSTR_VAL(unquoted), ZSTR_LEN(unquoted), '\'');
memcpy(quoted, "_binary'", 8);
quotedlen += 7; /* _binary prefix */
} else {
quotedlen = mysql_real_escape_string_quote(H->server, quoted + 1, ZSTR_VAL(unquoted), ZSTR_LEN(unquoted), '\'');
quoted[0] = '\'';

View File

@@ -0,0 +1,48 @@
--TEST--
MySQL PDO->prepare(), no warnings should be raised for binary values using emulated PS
--EXTENSIONS--
pdo_mysql
--SKIPIF--
<?php
require_once __DIR__ . '/inc/mysql_pdo_test.inc';
MySQLPDOTest::skip();
?>
--FILE--
<?php
require_once __DIR__ . '/inc/mysql_pdo_test.inc';
$db = MySQLPDOTest::factory();
$db->setAttribute(PDO::ATTR_EMULATE_PREPARES, true);
// Force the connection to utf8, which is enough to make the test fail
// MySQL 5.6+ would be required for utf8mb4
$db->exec("SET NAMES 'utf8'");
$content = '0191D886E6DC73E7AF1FEE7F99EC6235';
$statement = $db->prepare('SELECT HEX(?) as test');
$statement->bindValue(1, hex2bin($content), PDO::PARAM_LOB);
$statement->execute();
var_dump($statement->fetchAll(PDO::FETCH_ASSOC)[0]['test'] === $content);
var_dump($db->query('SHOW WARNINGS')->fetchAll(PDO::FETCH_ASSOC));
$db->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
$statement2 = $db->prepare('SELECT HEX(?) as test');
$statement2->bindValue(1, hex2bin($content), PDO::PARAM_LOB);
$statement2->execute();
var_dump($statement2->fetchAll(PDO::FETCH_ASSOC)[0]['test'] === $content);
$db->setAttribute(PDO::ATTR_EMULATE_PREPARES, true); // SHOW WARNINGS can only be used when PDO::ATTR_EMULATE_PREPARES=true
var_dump($db->query('SHOW WARNINGS')->fetchAll(PDO::FETCH_ASSOC));
print "done!";
?>
--EXPECTF--
bool(true)
array(0) {
}
bool(true)
array(0) {
}
done!

View File

@@ -0,0 +1,28 @@
--TEST--
MySQL PDO->quote(), properly handle binary data
--EXTENSIONS--
pdo_mysql
--SKIPIF--
<?php
require_once __DIR__ . '/inc/mysql_pdo_test.inc';
MySQLPDOTest::skip();
?>
--FILE--
<?php
require_once __DIR__ . '/inc/mysql_pdo_test.inc';
$db = MySQLPDOTest::factory();
$db->setAttribute(PDO::ATTR_EMULATE_PREPARES, true);
// Force the connection to utf8, which is enough to make the test fail
// MySQL 5.6+ would be required for utf8mb4
$db->exec("SET NAMES 'utf8'");
$content = "\xC3\xA1\xC3";
$quoted = $db->quote($content, PDO::PARAM_LOB);
var_dump($quoted);
var_dump($db->query("SELECT HEX({$quoted})")->fetch(PDO::FETCH_NUM)[0]);
?>
--EXPECTF--
string(%d) "_binary'%s'"
string(6) "C3A1C3"