Skip to content

Commit cb36fc5

Browse files
committed
Properly quote binary strings
1 parent dd983d9 commit cb36fc5

File tree

2 files changed

+25
-10
lines changed

2 files changed

+25
-10
lines changed

ext/pdo_mysql/mysql_driver.c

Lines changed: 21 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -309,26 +309,37 @@ static zend_string* mysql_handle_quoter(pdo_dbh_t *dbh, const zend_string *unquo
309309
{
310310
pdo_mysql_db_handle *H = (pdo_mysql_db_handle *)dbh->driver_data;
311311
bool use_national_character_set = 0;
312+
bool use_binary = 0;
312313
char *quoted;
313314
size_t quotedlen;
314315
zend_string *quoted_str;
315316

316-
if (H->assume_national_character_set_strings) {
317-
use_national_character_set = 1;
318-
}
319-
if ((paramtype & PDO_PARAM_STR_NATL) == PDO_PARAM_STR_NATL) {
320-
use_national_character_set = 1;
321-
}
322-
if ((paramtype & PDO_PARAM_STR_CHAR) == PDO_PARAM_STR_CHAR) {
323-
use_national_character_set = 0;
317+
if ((paramtype & PDO_PARAM_LOB) == PDO_PARAM_LOB) {
318+
use_binary = 1;
319+
} else {
320+
if (H->assume_national_character_set_strings) {
321+
use_national_character_set = 1;
322+
}
323+
if ((paramtype & PDO_PARAM_STR_NATL) == PDO_PARAM_STR_NATL) {
324+
use_national_character_set = 1;
325+
}
326+
if ((paramtype & PDO_PARAM_STR_CHAR) == PDO_PARAM_STR_CHAR) {
327+
use_national_character_set = 0;
328+
}
324329
}
325330

326331
PDO_DBG_ENTER("mysql_handle_quoter");
327332
PDO_DBG_INF_FMT("dbh=%p", dbh);
328333
PDO_DBG_INF_FMT("unquoted=%.*s", (int)ZSTR_LEN(unquoted), ZSTR_VAL(unquoted));
329-
quoted = safe_emalloc(2, ZSTR_LEN(unquoted), 3 + (use_national_character_set ? 1 : 0));
334+
quoted = safe_emalloc(2, ZSTR_LEN(unquoted), 3 + (use_national_character_set ? 1 : 0) +
335+
(use_binary ? 7 : 0));
336+
337+
if (use_binary) {
338+
quotedlen = mysql_real_escape_string_quote(H->server, quoted + 8, ZSTR_VAL(unquoted), ZSTR_LEN(unquoted), '\'');
339+
memcpy(quoted, "_binary'", 8);
330340

331-
if (use_national_character_set) {
341+
quotedlen += 7; /* _binary prefix */
342+
} else if (use_national_character_set) {
332343
quotedlen = mysql_real_escape_string_quote(H->server, quoted + 2, ZSTR_VAL(unquoted), ZSTR_LEN(unquoted), '\'');
333344
quoted[0] = 'N';
334345
quoted[1] = '\'';

ext/pdo_mysql/tests/pdo_mysql_prepare_emulated_binary.phpt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,10 @@ $db = MySQLPDOTest::factory();
1414
$db = MySQLPDOTest::factory();
1515
$db->setAttribute(PDO::ATTR_EMULATE_PREPARES, true);
1616

17+
// Force the connection to utf8, which is enough to make the test fail
18+
// MySQL 5.6+ would be required for utf8mb4
19+
$db->exec("SET NAMES 'utf8'");
20+
1721
$content = '0191D886E6DC73E7AF1FEE7F99EC6235';
1822

1923
$statement = $db->prepare('SELECT HEX(?) as test');

0 commit comments

Comments
 (0)