[eluser]xwero[/eluser]
The bug also can cause other problems, for example inside the query building.
Code:
$this->db->select(‘UNIX_TIMESTAMP(`timestamp`) AS `date`’, FALSE);
$this->db->select('YEAR(timestamp) year');
The fields in the second select will not be protected because of the change in the global setting.
As i browsed through the code i have seen no reason why the fields should go through the _protect_identifiers method, which is a confusing name as the db library has a class value by the same name, in the _compile_select method.
Code:
if (count($this->ar_select) == 0)
{
$sql .= '*';
}
else
{
// Cycle through the "select" portion of the query and prep each column name.
// The reason we protect identifiers here rather then in the select() function
// is because until the user calls the from() function we don't know if there are aliases
foreach ($this->ar_select as $key => $val)
{
$this->ar_select[$key] = $this->_protect_identifiers($val);
}
$sql .= implode(', ', $this->ar_select);
}
select fields from the select_max, select_min, select_avg and select_sum method who's value has gone through the _protect_identifiers method already have to go through it again.
A thorough fix would be to change the _compile_select code to
Code:
$sql = (count($this->ar_select) == 0) ? '*' : implode(', ', $this->ar_select) ;
And because _protect_identifiers class variable is set to true by default the second parameter the select method is likely to only be set to false so the method code can change to
Code:
function select($select = '*', $escape = TRUE)
{
if (is_string($select))
{
$select = explode(',', $select);
}
foreach ($select as $val)
{
$val = trim($val);
if ($val != '')
{
if($escape != FALSE)
{
$val = $this->_protect_identifiers($val);
}
$this->ar_select[] = $val;
if ($this->ar_caching === TRUE)
{
$this->ar_cache_select[] = $val;
$this->ar_cache_exists[] = 'select';
}
}
}
return $this;
}
It's an whole other ballgame if a method like set_identifier_protection(BOOLEAN) is added to the library.