protected function findPositionWithinString($sql, $value, $expr_type)
{
$offset = 0;
$ok = false;
while (true) {
$pos = strpos($sql, $value, $offset);
// error_log("pos:$pos value:$value sql:$sql");
if ($pos === false) {
break;
}
$before = "";
if ($pos > 0) {
$before = $sql[$pos - 1];
}
// if we have a quoted string, we every character is allowed after it
// see issue 137
$quoted = $sql[$pos + strlen($value) - 1] === '`';
$after = "";
if (isset($sql[$pos + strlen($value)])) {
$after = $sql[$pos + strlen($value)];
}
// if we have an operator, it should be surrounded by
// whitespace, comma, parenthesis, digit or letter, end_of_string
// an operator should not be surrounded by another operator
if (in_array($expr_type, array('operator', 'column-list'), true)) {
$ok = $before === "" || in_array($before, self::$allowedOnOperator, true) || strtolower($before) >= 'a' && strtolower($before) <= 'z';
$ok = $ok && ($after === "" || in_array($after, self::$allowedOnOperator, true) || strtolower($after) >= 'a' && strtolower($after) <= 'z');
if (!$ok) {
$offset = $pos + 1;
continue;
}
break;
}
// in all other cases we accept
// whitespace, comma, operators, parenthesis and end_of_string
$ok = $before === "" || in_array($before, self::$allowedOnOther, true);
$ok = $ok && ($after === "" || in_array($after, self::$allowedOnOther, true) || $quoted && (strtolower($after) >= 'a' && strtolower($after) <= 'z'));
if ($ok) {
break;
}
$offset = $pos + 1;
}
return $pos;
}