Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions changelog.txt
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
This file shows the changes in this release of xPDO.

Unreleased
====================================
- [#54] Fix updateCollection/set() when string value contains SQL operator keywords (e.g. IN, LIKE)

xPDO 3.1.7 (December 4, 2025)
====================================
- PHP 8.5 compatibility (#264)
Expand Down
4 changes: 2 additions & 2 deletions src/xPDO/Om/mysql/xPDOQuery.php
Original file line number Diff line number Diff line change
Expand Up @@ -78,8 +78,8 @@ public function construct() {
foreach ($this->query['set'] as $setKey => $setVal) {
$value = $setVal['value'];
$type = $setVal['type'];
if ($value !== null && in_array($type, array(\PDO::PARAM_INT, \PDO::PARAM_STR))) {
$value = $this->xpdo->quote($value, $type);
if ($value !== null && ($type === null || in_array($type, array(\PDO::PARAM_INT, \PDO::PARAM_STR)))) {
$value = $this->xpdo->quote($value, $type === null ? \PDO::PARAM_STR : $type);
} elseif ($value === null) {
$value = 'NULL';
}
Expand Down
4 changes: 2 additions & 2 deletions src/xPDO/Om/pgsql/xPDOQuery.php
Original file line number Diff line number Diff line change
Expand Up @@ -69,8 +69,8 @@ public function construct() {
foreach ($this->query['set'] as $setKey => $setVal) {
$value = $setVal['value'];
$type = $setVal['type'];
if ($value !== null && in_array($type, array(\PDO::PARAM_INT, \PDO::PARAM_STR))) {
$value = $this->xpdo->quote($value, $type);
if ($value !== null && ($type === null || in_array($type, array(\PDO::PARAM_INT, \PDO::PARAM_STR)))) {
$value = $this->xpdo->quote($value, $type === null ? \PDO::PARAM_STR : $type);
} elseif ($value === null) {
$value = 'NULL';
}
Expand Down
4 changes: 2 additions & 2 deletions src/xPDO/Om/sqlite/xPDOQuery.php
Original file line number Diff line number Diff line change
Expand Up @@ -78,8 +78,8 @@ public function construct() {
foreach ($this->query['set'] as $setKey => $setVal) {
$value = $setVal['value'];
$type = $setVal['type'];
if ($value !== null && in_array($type, array(\PDO::PARAM_INT, \PDO::PARAM_STR))) {
$value = $this->xpdo->quote($value, $type);
if ($value !== null && ($type === null || in_array($type, array(\PDO::PARAM_INT, \PDO::PARAM_STR)))) {
$value = $this->xpdo->quote($value, $type === null ? \PDO::PARAM_STR : $type);
} elseif ($value === null) {
$value = 'NULL';
}
Expand Down
4 changes: 2 additions & 2 deletions src/xPDO/Om/sqlsrv/xPDOQuery.php
Original file line number Diff line number Diff line change
Expand Up @@ -249,8 +249,8 @@ public function construct() {
foreach ($this->query['set'] as $setKey => $setVal) {
$value = $setVal['value'];
$type = $setVal['type'];
if ($value !== null && in_array($type, array(\PDO::PARAM_INT, \PDO::PARAM_STR))) {
$value = $this->xpdo->quote($value, $type);
if ($value !== null && ($type === null || in_array($type, array(\PDO::PARAM_INT, \PDO::PARAM_STR)))) {
$value = $this->xpdo->quote($value, $type === null ? \PDO::PARAM_STR : $type);
} elseif ($value === null) {
$value = 'NULL';
}
Expand Down
2 changes: 1 addition & 1 deletion src/xPDO/Om/xPDOQuery.php
Original file line number Diff line number Diff line change
Expand Up @@ -264,7 +264,7 @@ public function set(array $values) {
elseif (!in_array($fieldMeta[$key]['phptype'], $this->_quotable)) {
$type= \PDO::PARAM_INT;
}
elseif (strpos($value, '(') === false && !$this->isConditionalClause($value)) {
else {
$type= \PDO::PARAM_STR;
}
$this->query['set'][$key]= array('value' => $value, 'type' => $type);
Expand Down
44 changes: 40 additions & 4 deletions test/xPDO/Legacy/Om/xPDOObjectTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -630,20 +630,56 @@ public function testUpdateCollection($class, $set, $criteria, $expected)
public function providerUpdateCollection()
{
return array(
array('Person', array('dob' => '2011-08-09'), array('dob:<' => '1951-01-01'), array(1, array())),
array('Person', array('security_level' => 5), array('security_level' => 3), array(1, array())),
array(
'no matches' => array('Person', array('dob' => '2011-08-09'), array('dob:<' => '1951-01-01'), array(1, array())),
'integer field' => array('Person', array('security_level' => 5), array('security_level' => 3), array(1, array())),
'update all records' => array(
'Person',
array('date_of_birth' => '2011-09-01'),
null,
array(2, array(array('date_of_birth' => '2011-09-01'), array('date_of_birth' => '2011-09-01')))
),
array(
'null value' => array(
'Person',
array('date_of_birth' => null),
array('security_level' => 3),
array(1, array(array('date_of_birth' => null)))
),
'string with IN' => array(
'Person',
array('first_name' => 'The word IN is IN this strINg'),
array('security_level' => 3),
array(1, array(array('first_name' => 'The word IN is IN this strINg')))
),
'string with LIKE' => array(
'Person',
array('first_name' => 'Something LIKE %test%'),
array('security_level' => 3),
array(1, array(array('first_name' => 'Something LIKE %test%')))
),
'string with BETWEEN' => array(
'Person',
array('first_name' => 'Value BETWEEN 1 AND 10'),
array('security_level' => 3),
array(1, array(array('first_name' => 'Value BETWEEN 1 AND 10')))
),
'string with equals' => array(
'Person',
array('first_name' => 'x = y'),
array('security_level' => 3),
array(1, array(array('first_name' => 'x = y')))
),
'empty string' => array(
'Person',
array('middle_name' => ''),
array('security_level' => 3),
array(1, array(array('middle_name' => '')))
),
'apostrophe SQL injection' => array(
'Person',
array('first_name' => "O'Brien"),
array('security_level' => 3),
array(1, array(array('first_name' => "O'Brien")))
),
);
}

Expand Down
44 changes: 40 additions & 4 deletions test/xPDO/Test/Om/xPDOObjectTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -661,20 +661,56 @@ public function testUpdateCollection($class, $set, $criteria, $expected)
public function providerUpdateCollection()
{
return array(
array('xPDO\\Test\\Sample\\Person', array('dob' => '2011-08-09'), array('dob:<' => '1951-01-01'), array(1, array())),
array('xPDO\\Test\\Sample\\Person', array('security_level' => 5), array('security_level' => 3), array(1, array())),
array(
'no matches' => array('xPDO\\Test\\Sample\\Person', array('dob' => '2011-08-09'), array('dob:<' => '1951-01-01'), array(1, array())),
'integer field' => array('xPDO\\Test\\Sample\\Person', array('security_level' => 5), array('security_level' => 3), array(1, array())),
'update all records' => array(
'xPDO\\Test\\Sample\\Person',
array('date_of_birth' => '2011-09-01'),
null,
array(2, array(array('date_of_birth' => '2011-09-01'), array('date_of_birth' => '2011-09-01')))
),
array(
'null value' => array(
'xPDO\\Test\\Sample\\Person',
array('date_of_birth' => null),
array('security_level' => 3),
array(1, array(array('date_of_birth' => null)))
),
'string with IN' => array(
'xPDO\\Test\\Sample\\Person',
array('first_name' => 'The word IN is IN this strINg'),
array('security_level' => 3),
array(1, array(array('first_name' => 'The word IN is IN this strINg')))
),
'string with LIKE' => array(
'xPDO\\Test\\Sample\\Person',
array('first_name' => 'Something LIKE %test%'),
array('security_level' => 3),
array(1, array(array('first_name' => 'Something LIKE %test%')))
),
'string with BETWEEN' => array(
'xPDO\\Test\\Sample\\Person',
array('first_name' => 'Value BETWEEN 1 AND 10'),
array('security_level' => 3),
array(1, array(array('first_name' => 'Value BETWEEN 1 AND 10')))
),
'string with equals' => array(
'xPDO\\Test\\Sample\\Person',
array('first_name' => 'x = y'),
array('security_level' => 3),
array(1, array(array('first_name' => 'x = y')))
),
'empty string' => array(
'xPDO\\Test\\Sample\\Person',
array('middle_name' => ''),
array('security_level' => 3),
array(1, array(array('middle_name' => '')))
),
'apostrophe SQL injection' => array(
'xPDO\\Test\\Sample\\Person',
array('first_name' => "O'Brien"),
array('security_level' => 3),
array(1, array(array('first_name' => "O'Brien")))
),
);
}

Expand Down