Skip to content
This repository was archived by the owner on Jan 29, 2020. It is now read-only.

Commit 14c5f0b

Browse files
committed
Merge branch 'hotfix/289'
Close #289 Fixes #288
2 parents 9f589dd + 1a37459 commit 14c5f0b

File tree

5 files changed

+53
-38
lines changed

5 files changed

+53
-38
lines changed

CHANGELOG.md

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,24 @@
22

33
All notable changes to this project will be documented in this file, in reverse chronological order by release.
44

5-
## 2.9.1 - TBD
5+
## 2.9.1 - 2017-12-07
66

77
### Added
88

99
- Nothing.
1010

11+
### Changed
12+
13+
- [#289](https://github.com/zendframework/zend-db/pull/289) reverts a change
14+
introduced in 2.9.0 and modifies the behavior of the PDO adapter slightly
15+
to remove a regression. In 2.9.0, when binding parameters with names that
16+
contained characters not supported by PDO, we would pass the parameter names
17+
to `md5()`; this caused a regression, as the SQL string containing the
18+
parameter name was not also updated.
19+
20+
This patch modifies the behavior during a bind-operation to instead raise an
21+
exception if a parameter name contains characters not supported by PDO.
22+
1123
### Deprecated
1224

1325
- Nothing.

src/Adapter/Driver/Pdo/Pdo.php

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -304,8 +304,16 @@ public function getPrepareType()
304304
public function formatParameterName($name, $type = null)
305305
{
306306
if ($type === null && ! is_numeric($name) || $type == self::PARAMETERIZATION_NAMED) {
307-
// using MD5 because of the PDO restriction [A-Za-z0-9_] for bindParam name
308-
return ':' . md5($name);
307+
// @see https://bugs.php.net/bug.php?id=43130
308+
if (preg_match('/[^a-zA-Z0-9_]/', $name)) {
309+
throw new Exception\RuntimeException(sprintf(
310+
'The PDO param %s contains invalid characters.'
311+
. ' Only alphabetic characters, digits, and underscores (_)'
312+
. ' are allowed.',
313+
$name
314+
));
315+
}
316+
return ':' . $name;
309317
}
310318

311319
return '?';

test/Adapter/Driver/Pdo/PdoTest.php

Lines changed: 28 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -43,16 +43,16 @@ public function testGetDatabasePlatformName()
4343
public function getParamsAndType()
4444
{
4545
return [
46-
[ 'foo', null, ':' . md5('foo')],
47-
[ 'foo-', null, ':' . md5('foo-')],
48-
[ 'foo$', null, ':' . md5('foo$')],
46+
[ 'foo', null, ':foo' ],
47+
[ 'foo_bar', null, ':foo_bar' ],
48+
[ '123foo', null, ':123foo' ],
4949
[ 1, null, '?' ],
50-
[ '1', null, '?'],
51-
[ 'foo', Pdo::PARAMETERIZATION_NAMED, ':' . md5('foo')],
52-
[ 'foo-', Pdo::PARAMETERIZATION_NAMED, ':' . md5('foo-')],
53-
[ 'foo$', Pdo::PARAMETERIZATION_NAMED, ':' . md5('foo$')],
54-
[ 1, Pdo::PARAMETERIZATION_NAMED, ':' . md5('1')],
55-
[ '1', Pdo::PARAMETERIZATION_NAMED, ':' . md5('1')],
50+
[ '1', null, '?' ],
51+
[ 'foo', Pdo::PARAMETERIZATION_NAMED, ':foo' ],
52+
[ 'foo_bar', Pdo::PARAMETERIZATION_NAMED, ':foo_bar' ],
53+
[ '123foo', Pdo::PARAMETERIZATION_NAMED, ':123foo' ],
54+
[ 1, Pdo::PARAMETERIZATION_NAMED, ':1' ],
55+
[ '1', Pdo::PARAMETERIZATION_NAMED, ':1' ],
5656
];
5757
}
5858

@@ -64,4 +64,23 @@ public function testFormatParameterName($name, $type, $expected)
6464
$result = $this->pdo->formatParameterName($name, $type);
6565
$this->assertEquals($expected, $result);
6666
}
67+
68+
public function getInvalidParamName()
69+
{
70+
return [
71+
[ 'foo%' ],
72+
[ 'foo-' ],
73+
[ 'foo$' ],
74+
[ 'foo0!' ]
75+
];
76+
}
77+
78+
/**
79+
* @dataProvider getInvalidParamName
80+
* @expectedException Zend\Db\Exception\RuntimeException
81+
*/
82+
public function testFormatParameterNameWithInvalidCharacters($name)
83+
{
84+
$this->pdo->formatParameterName($name);
85+
}
6786
}

test/Adapter/Driver/Pdo/StatementIntegrationTest.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ protected function tearDown()
5555
public function testStatementExecuteWillConvertPhpBoolToPdoBoolWhenBinding()
5656
{
5757
$this->pdoStatementMock->expects($this->any())->method('bindParam')->with(
58-
$this->equalTo(':' . md5('foo')),
58+
$this->equalTo(':foo'),
5959
$this->equalTo(false),
6060
$this->equalTo(\PDO::PARAM_BOOL)
6161
);
@@ -65,7 +65,7 @@ public function testStatementExecuteWillConvertPhpBoolToPdoBoolWhenBinding()
6565
public function testStatementExecuteWillUsePdoStrByDefaultWhenBinding()
6666
{
6767
$this->pdoStatementMock->expects($this->any())->method('bindParam')->with(
68-
$this->equalTo(':' . md5('foo')),
68+
$this->equalTo(':foo'),
6969
$this->equalTo('bar'),
7070
$this->equalTo(\PDO::PARAM_STR)
7171
);

test/Adapter/Driver/Pdo/StatementTest.php

Lines changed: 0 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -128,28 +128,4 @@ public function testExecute()
128128
$this->statement->prepare('SELECT 1');
129129
self::assertInstanceOf('Zend\Db\Adapter\Driver\Pdo\Result', $this->statement->execute());
130130
}
131-
132-
/**
133-
* @see https://github.com/zendframework/zend-db/pull/224
134-
*/
135-
public function testExecuteWithSpecialCharInBindParam()
136-
{
137-
$testSqlite = new TestAsset\SqliteMemoryPdo('CREATE TABLE test (text_ TEXT, text$ TEXT);');
138-
$this->statement->setDriver(new Pdo(new Connection($testSqlite)));
139-
$this->statement->initialize($testSqlite);
140-
141-
$this->statement->prepare(sprintf(
142-
'INSERT INTO test (text_, text$) VALUES (:%s, :%s)',
143-
md5('text_'),
144-
md5('text$')
145-
));
146-
$result = $this->statement->execute([ 'text_' => 'foo', 'text$' => 'bar']);
147-
$this->assertInstanceOf(Result::class, $result);
148-
$this->assertTrue($result->valid());
149-
150-
$result = $testSqlite->query('SELECT * FROM test');
151-
$values = $result->fetch();
152-
$this->assertEquals('foo', $values['text_']);
153-
$this->assertEquals('bar', $values['text$']);
154-
}
155131
}

0 commit comments

Comments
 (0)