summaryrefslogtreecommitdiffstats
path: root/system/database/DB_driver.php
diff options
context:
space:
mode:
Diffstat (limited to 'system/database/DB_driver.php')
-rw-r--r--system/database/DB_driver.php32
1 files changed, 29 insertions, 3 deletions
diff --git a/system/database/DB_driver.php b/system/database/DB_driver.php
index 88a3b388f..d056bdb90 100644
--- a/system/database/DB_driver.php
+++ b/system/database/DB_driver.php
@@ -596,25 +596,51 @@ abstract class CI_DB_driver {
*/
public function compile_binds($sql, $binds)
{
- if (preg_match_all('/(>|<|=|!)\s*('.preg_quote($this->bind_marker).')/i', $sql, $matches, PREG_SET_ORDER | PREG_OFFSET_CAPTURE) !== count($binds))
+ if (empty($binds) OR empty($this->bind_marker) OR strpos($sql, $this->bind_marker) === FALSE)
{
return $sql;
}
elseif ( ! is_array($binds))
{
$binds = array($binds);
+ $bind_count = 1;
}
else
{
// Make sure we're using numeric keys
$binds = array_values($binds);
+ $bind_count = count($binds);
}
+ // We'll need the marker length later
+ $ml = strlen($this->bind_marker);
- for ($i = count($matches) - 1; $i >= 0; $i--)
+ // Make sure not to replace a chunk inside a string that happens to match the bind marker
+ if ($c = preg_match_all("/'[^']*'/i", $sql, $matches))
{
- $sql = substr_replace($sql, $this->escape($binds[$i]), $matches[$i][2][1], 1);
+ $c = preg_match_all('/'.preg_quote($this->bind_marker).'/i',
+ str_replace($matches[0],
+ str_replace($this->bind_marker, str_repeat(' ', $ml), $matches[0]),
+ $sql, $c),
+ $matches, PREG_OFFSET_CAPTURE);
+
+ // Bind values' count must match the count of markers in the query
+ if ($bind_count !== $c)
+ {
+ return $sql;
+ }
+ }
+ elseif (($c = preg_match_all('/'.preg_quote($this->bind_marker).'/i', $sql, $matches, PREG_OFFSET_CAPTURE)) !== $bind_count)
+ {
+ return $sql;
+ }
+
+ do
+ {
+ $c--;
+ $sql = substr_replace($sql, $this->escape($binds[$c]), $matches[0][$c][1], $ml);
}
+ while ($c !== 0);
return $sql;
}