Merge "Fix handling of strings containing \0 in SQLite."

This commit is contained in:
daniel 2012-11-02 14:18:15 +00:00 committed by Gerrit Code Review
commit 7c94de3ca9
2 changed files with 54 additions and 0 deletions

View file

@ -705,6 +705,14 @@ class DatabaseSqlite extends DatabaseBase {
function addQuotes( $s ) {
if ( $s instanceof Blob ) {
return "x'" . bin2hex( $s->fetch() ) . "'";
} else if ( strpos( $s, "\0" ) !== false ) {
// SQLite doesn't support \0 in strings, so use the hex representation as a workaround.
// This is a known limitation of SQLite's mprintf function which PDO should work around,
// but doesn't. I have reported this to php.net as bug #63419:
// https://bugs.php.net/bug.php?id=63419
// There was already a similar report for SQLite3::escapeString, bug #62361:
// https://bugs.php.net/bug.php?id=62361
return "x'" . bin2hex( $s ) . "'";
} else {
return $this->mConn->quote( $s );
}

View file

@ -54,6 +54,52 @@ class DatabaseSqliteTest extends MediaWikiTestCase {
$this->assertEquals( count( $expected ), $i, 'Unexpected number of rows' );
}
public static function provideAddQuotes() {
return array(
array( // #0: empty
'', "''"
),
array( // #1: simple
'foo bar', "'foo bar'"
),
array( // #2: including quote
'foo\'bar', "'foo''bar'"
),
array( // #3: including \0 (must be represented as hex, per https://bugs.php.net/bug.php?id=63419)
"x\0y",
"x'780079'",
),
array( // #4: blob object (must be represented as hex)
new Blob( "hello" ),
"x'68656c6c6f'",
),
);
}
/**
* @dataProvider provideAddQuotes()
*/
public function testAddQuotes( $value, $expected ) {
// check quoting
$db = new DatabaseSqliteStandalone( ':memory:' );
$this->assertEquals( $expected, $db->addQuotes( $value ), 'string not quoted as expected' );
// ok, quoting works as expected, now try a round trip.
$re = $db->query( 'select ' . $db->addQuotes( $value ) );
$this->assertTrue( $re !== false, 'query failed' );
if ( $row = $re->fetchRow() ) {
if ( $value instanceof Blob ) {
$value = $value->fetch();
}
$this->assertEquals( $value, $row[0], 'string mangled by the database' );
} else {
$this->fail( 'query returned no result' );
}
}
public function testReplaceVars() {
$this->assertEquals( 'foo', $this->replaceVars( 'foo' ), "Don't break anything accidentally" );