FAQ
Edit report at http://pear.php.net/bugs/bug.php?id=17039&edit=1

ID: 17039
Comment by: jon@siliconcircus.com
Reported By: jon at siliconcircus dot com
Summary: _skipDelimitedStrings getting confused by escaped
quotes
Status: Open
Type: Bug
Package: MDB2
Operating System: Debian Sid
Package Version: CVS
PHP Version: 5.2.5
Roadmap Versions:
New Comment:

The attached patch fixes the problem for me.


Previous Comments:
------------------------------------------------------------------------

[2010-01-27 18:58:59] sircus

Added #patch
bug:17039;patch:skip_delimited_strings_fix_quoting_array;revision:1264618739;.

------------------------------------------------------------------------

[2010-01-27 18:30:16] sircus

Description:
------------
Using prepare() on a query such as UPDATE user SET User='a\'b:+c'
results in the whole of the string after 'b' being replaced by a single
question mark.

The problem is that the MySQL driver's value for $string_quoting is an
array. The building of $ignores at the start of _skipDelimitedStrings
results in

array (
'start' => '\'',
'end' => '\'',
'escape' => '\\',
'escape_pattern' => '\\',
0 =>
array (
'start' => '`',
'end' => '`',
'escape' => '`',
),
...
)

foreach ($ignores as $ignore) then gets '\'' as its first value for
$ignore. This results in $ignore['escape'] being '\''. This results in
prepare only skipping as far as the first apostrophe, because it's
treated as unescaped. This results in modifyQuery() treating the colon
as a placeholder. The + then seems to result in the remainder of the
string being truncated.


Test script:
---------------
require_once 'MDB2.php';
$dsn='mysql://user:password@localhost/mysql';
$dbh = MDB2::connect($dsn, $db_options);
if (MDB2::isError($dbh))
die($dbh->getMessage());
$q = $dbh->prepare("UPDATE user SET User='a\'b:+c'", null,
MDB2_PREPARE_MANIP);
if ($dbh->isError($q))
die($q->userinfo);
echo("Test passed");

Expected result:
----------------
I expect the text "Test passed"

Actual result:
--------------
_doQuery: [Error message: Could not execute statement]
[Last executed query: PREPARE
mdb2_statement_mysql_1c2b48e2af2a575aff97b07a6b431d346f59b551e FROM
'UPDATE user SET User=\'a\\\'b?']
[Native code: 1064]
[Native message: You have an error in your SQL syntax; check the manual
that corresponds to your MySQL server version for the right syntax to
use near ''a\'b?' at line 1]

------------------------------------------------------------------------

Search Discussions

  • Jon at Jan 27, 2010 at 7:50 pm
    Edit report at http://pear.php.net/bugs/bug.php?id=17039&edit=1

    ID: 17039
    Comment by: jon@siliconcircus.com
    Reported By: jon at siliconcircus dot com
    Summary: _skipDelimitedStrings getting confused by escaped
    quotes
    Status: Open
    Type: Bug
    Package: MDB2
    Operating System: Debian Sid
    Package Version: CVS
    PHP Version: 5.2.5
    Roadmap Versions:
    New Comment:

    This bug should probably be marked as a duplicate of 16973.


    Previous Comments:
    ------------------------------------------------------------------------

    [2010-01-27 18:59:24] sircus

    The attached patch fixes the problem for me.

    ------------------------------------------------------------------------

    [2010-01-27 18:58:59] sircus

    Added #patch
    bug:17039;patch:skip_delimited_strings_fix_quoting_array;revision:1264618739;.

    ------------------------------------------------------------------------

    [2010-01-27 18:30:16] sircus

    Description:
    ------------
    Using prepare() on a query such as UPDATE user SET User='a\'b:+c'
    results in the whole of the string after 'b' being replaced by a single
    question mark.

    The problem is that the MySQL driver's value for $string_quoting is an
    array. The building of $ignores at the start of _skipDelimitedStrings
    results in

    array (
    'start' => '\'',
    'end' => '\'',
    'escape' => '\\',
    'escape_pattern' => '\\',
    0 =>
    array (
    'start' => '`',
    'end' => '`',
    'escape' => '`',
    ),
    ...
    )

    foreach ($ignores as $ignore) then gets '\'' as its first value for
    $ignore. This results in $ignore['escape'] being '\''. This results in
    prepare only skipping as far as the first apostrophe, because it's
    treated as unescaped. This results in modifyQuery() treating the colon
    as a placeholder. The + then seems to result in the remainder of the
    string being truncated.


    Test script:
    ---------------
    require_once 'MDB2.php';
    $dsn='mysql://user:password@localhost/mysql';
    $dbh = MDB2::connect($dsn, $db_options);
    if (MDB2::isError($dbh))
    die($dbh->getMessage());
    $q = $dbh->prepare("UPDATE user SET User='a\'b:+c'", null,
    MDB2_PREPARE_MANIP);
    if ($dbh->isError($q))
    die($q->userinfo);
    echo("Test passed");

    Expected result:
    ----------------
    I expect the text "Test passed"

    Actual result:
    --------------
    _doQuery: [Error message: Could not execute statement]
    [Last executed query: PREPARE
    mdb2_statement_mysql_1c2b48e2af2a575aff97b07a6b431d346f59b551e FROM
    'UPDATE user SET User=\'a\\\'b?']
    [Native code: 1064]
    [Native message: You have an error in your SQL syntax; check the manual
    that corresponds to your MySQL server version for the right syntax to
    use near ''a\'b?' at line 1]

    ------------------------------------------------------------------------
  • L Alberton at Jan 31, 2010 at 5:28 pm
    Edit report at http://pear.php.net/bugs/bug.php?id=17039&edit=1

    ID: 17039
    Updated by: l.alberton@quipo.it
    Reported By: jon at siliconcircus dot com
    Summary: _skipDelimitedStrings getting confused by escaped
    quotes
    -Status: Open
    +Status: Closed
    Type: Bug
    Package: MDB2
    Operating System: Debian Sid
    Package Version: CVS
    PHP Version: 5.2.5
    -Assigned To:
    +Assigned To: quipo
    Roadmap Versions:
    New Comment:

    -Status: Open
    +Status: Closed
    -Assigned To:
    +Assigned To: quipo
    This bug has been fixed in SVN.

    If this was a documentation problem, the fix will appear on
    pear.php.net by the end of next Sunday (CET).

    If this was a problem with the pear.php.net website, the change should
    be live shortly.

    Otherwise, the fix will appear in the package's next release.

    Thank you for the report and for helping us make PEAR better.




    Previous Comments:
    ------------------------------------------------------------------------

    [2010-01-27 19:49:03] sircus

    This bug should probably be marked as a duplicate of 16973.

    ------------------------------------------------------------------------

    [2010-01-27 18:59:24] sircus

    The attached patch fixes the problem for me.

    ------------------------------------------------------------------------

    [2010-01-27 18:58:59] sircus

    Added #patch
    bug:17039;patch:skip_delimited_strings_fix_quoting_array;revision:1264618739;.

    ------------------------------------------------------------------------

    [2010-01-27 18:30:16] sircus

    Description:
    ------------
    Using prepare() on a query such as UPDATE user SET User='a\'b:+c'
    results in the whole of the string after 'b' being replaced by a single
    question mark.

    The problem is that the MySQL driver's value for $string_quoting is an
    array. The building of $ignores at the start of _skipDelimitedStrings
    results in

    array (
    'start' => '\'',
    'end' => '\'',
    'escape' => '\\',
    'escape_pattern' => '\\',
    0 =>
    array (
    'start' => '`',
    'end' => '`',
    'escape' => '`',
    ),
    ...
    )

    foreach ($ignores as $ignore) then gets '\'' as its first value for
    $ignore. This results in $ignore['escape'] being '\''. This results in
    prepare only skipping as far as the first apostrophe, because it's
    treated as unescaped. This results in modifyQuery() treating the colon
    as a placeholder. The + then seems to result in the remainder of the
    string being truncated.


    Test script:
    ---------------
    require_once 'MDB2.php';
    $dsn='mysql://user:password@localhost/mysql';
    $dbh = MDB2::connect($dsn, $db_options);
    if (MDB2::isError($dbh))
    die($dbh->getMessage());
    $q = $dbh->prepare("UPDATE user SET User='a\'b:+c'", null,
    MDB2_PREPARE_MANIP);
    if ($dbh->isError($q))
    die($q->userinfo);
    echo("Test passed");

    Expected result:
    ----------------
    I expect the text "Test passed"

    Actual result:
    --------------
    _doQuery: [Error message: Could not execute statement]
    [Last executed query: PREPARE
    mdb2_statement_mysql_1c2b48e2af2a575aff97b07a6b431d346f59b551e FROM
    'UPDATE user SET User=\'a\\\'b?']
    [Native code: 1064]
    [Native message: You have an error in your SQL syntax; check the manual
    that corresponds to your MySQL server version for the right syntax to
    use near ''a\'b?' at line 1]

    ------------------------------------------------------------------------

Related Discussions

Discussion Navigation
viewthread | post
Discussion Overview
grouppear-bugs @
categoriesphp
postedJan 27, '10 at 7:01p
activeJan 31, '10 at 5:28p
posts3
users2
websitepear.php.net

2 users in discussion

Jon: 2 posts L Alberton: 1 post

People

Translate

site design / logo © 2022 Grokbase