-
Notifications
You must be signed in to change notification settings - Fork 7.9k
Add new PDO mysql connection attr to control multi statements option #896
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
e34e4b8
to
31ae76a
Compare
cross-reference to feature request: https://bugs.php.net/bug.php?id=68424 |
31ae76a
to
462a65d
Compare
I just rebased on master, so let's see if Travis is happier |
@@ -126,7 +126,7 @@ static PHP_MINIT_FUNCTION(pdo_mysql) | |||
#if MYSQL_VERSION_ID > 50605 || defined(PDO_USE_MYSQLND) | |||
REGISTER_PDO_CLASS_CONST_LONG("MYSQL_ATTR_SERVER_PUBLIC_KEY", (zend_long)PDO_MYSQL_ATTR_SERVER_PUBLIC_KEY); | |||
#endif | |||
|
|||
REGISTER_PDO_CLASS_CONST_LONG("MYSQL_ATTR_MULTI_STATEMENTS", (zend_long)PDO_MYSQL_ATTR_MULTI_STATEMENTS); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This needs to be guarded like the previous constant — we still support MySQL 4.1 (not entirely clear on why, admittedly), and it doesn't support CLIENT_MULTI_STATEMENTS.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So, the connection code is guarded with:
#ifdef CLIENT_MULTI_STATEMENTS
not by MySQL version. In fact, it looks like the 4.1 API supports it:
http://dev.mysql.com/doc/refman/4.1/en/c-api-multiple-queries.html
So, I think guarding the constant with the same check would make sense, though I'm not sure at this point when it would be undefined.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think I got tricked by a sentence in the MySQL 5.0 manual implying it was new in that version. Sorry about that! Disregard what I said.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok, so does it make sense to guard the class constant using
#ifdef CLIENT_MULTI_STATEMENTS
or since it would be ignored if somehow that wan't defined, it's better to always define it to avoid PHP code having to check if it exists?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If you're sure it's always defined in MySQL >= 4.1, then let's not bother with the #ifdef. No point cluttering the code unnecessarily. :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Well, it's actually defined by default by mysqlnd:
mysqlnd/mysqlnd_enum_n_def.h
96:#define CLIENT_MULTI_STATEMENTS (1UL << 16) /* Enable/disable multi-stmt support */
It's also available in the C API since January 2003
http://bazaar.launchpad.net/~mysql/libmysql/1.0/view/1412/include/mysql_com.h#L109
http://bazaar.launchpad.net/~mysql/libmysql/1.0/revision/1403.62.1
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So, my conclusion is we really don't need the #ifdef anywhere any more, but I guess leaving it in where it is might be fine for now.
I'd like to really emphasize the importance of this flag for systems that use MySQL with PDO and how lacking we will be without it in older versions of PHP. Myself and many others cannot disable emulated prepared statements for various reasons. Would this be accepted in a PHP I would be more than willing to help however I can to get this feature into older versions, although I am a bit unclear on the processes involved in doing so. |
1767df2
to
2102800
Compare
…imiting connection to a single statement
2102800
to
294bfb1
Compare
Comment on behalf of jpauli at php.net: Squashed and merged against 5.5 & up |
mysqli does not set the CLIENT_MULTI_STATEMENTS flag on connect, so a query with multiple statements fails.
For PDO mysql, it hard-codes the CLIENT_MULTI_STATEMENTS flag in the connection, so there is no way to disable it. However, if using native prepares, sending multiple statements fails on the server. This is inconsistent.
This PR adds a new MySQL-specific attribute that can be only set at connection time to explicitly enable or disable multi statements. As written, it leaves the default the same as current master (enabled).
While this PR is against master, I think this change falls somewhere between a feature and a bugfix and should be back-ported to all supported versions.
The motivation for this is the severity of the recent SQL injection vulnerability in Drupal. If we had any way to disable multi statement in PDO (which is used in Drupal 7.x but not 6.x), we would have, and the vulnerability would have been significantly mitigated. see: https://www.drupal.org/SA-CORE-2014-005