Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Tree: 7a1ce8162f
Fetching contributors…

Cannot retrieve contributors at this time

270 lines (241 sloc) 9.137 kB
<?php
/*
* Project: SafeSQL: db access library extension
* File: SafeSQL.class.php
* Author: Monte Ohrt <monte@ispi.net>
*
* Version: 2.1
* Date: August 13, 2004
* Copyright: 2001,2002,2003,2004 ispi of Lincoln, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*/
class SafeSQL
{
// values that determine dropping bracketed sections
var $_drop_values = array('');
/*======================================================================*\
Function: SafeSQL
Purpose: constructor
\*======================================================================*/
function SafeSQL() { }
/*======================================================================*\
Function: query
Purpose: process the query string
\*======================================================================*/
function query($query_string, $query_vars)
{
if(is_array($query_vars)) {
$_var_count = count($query_vars);
if($_var_count != preg_match_all('!%[sSiIfFcClLqQ]!', $query_string, $_match)) {
$this->_error_msg('unmatched number of vars and % placeholders: ' . $query_string);
}
// get string position for each element
$_var_pos = array();
$_curr_pos = 0;
for( $_x = 0; $_x < $_var_count; $_x++ ) {
$_var_pos[$_x] = strpos($query_string, $_match[0][$_x], $_curr_pos);
$_curr_pos = $_var_pos[$_x] + 1;
}
// build query from passed in variables, escape them
// start from end of query and work backwards so string
// positions are not altered during replacement
$_last_removed_pos = null;
$_last_var_pos = null;
for( $_x = $_var_count-1; $_x >= 0; $_x-- ) {
if(isset($_last_removed_pos) && $_last_removed_pos < $_var_pos[$_x]) {
// already removed, skip
continue;
}
// escape string
$query_vars[$_x] = $this->_sql_escape($query_vars[$_x]);
if(in_array($_match[0][$_x], array('%S','%I','%F','%C','%L','%Q'))) {
// get positions of [ and ]
if(isset($_last_var_pos))
$_right_pos = strpos($query_string, ']', $_last_var_pos);
else
$_right_pos = strpos($query_string, ']', $_var_pos[$_x]);
// no way to get strpos from the right side starting in the middle
// of the string, so slice the first part out then find it
$_str_slice = substr($query_string, 0, $_var_pos[$_x]);
$_left_pos = strrpos($_str_slice, '[');
if($_right_pos === false || $_left_pos === false) {
$this->_error_msg('missing or unmatched brackets: ' . $query_string);
}
if(in_array($query_vars[$_x], $this->_drop_values, true)) {
$_last_removed_pos = $_left_pos;
// remove entire part of string
$query_string = substr_replace($query_string, '', $_left_pos, $_right_pos - $_left_pos + 1);
$_last_var_pos = null;
} else if ($_x > 0 && $_var_pos[$_x-1] > $_left_pos) {
// still variables left in brackets, leave them and just replace var
$_convert_var = $this->_convert_var($query_vars[$_x], $_match[0][$_x]);
$query_string = substr_replace($query_string, $_convert_var, $_var_pos[$_x], 2);
$_last_var_pos = $_var_pos[$_x] + strlen($_convert_var);
} else {
// remove the brackets only, and replace %S
$query_string = substr_replace($query_string, '', $_right_pos, 1);
$query_string = substr_replace($query_string, $this->_convert_var($query_vars[$_x], $_match[0][$_x]), $_var_pos[$_x], 2);
$query_string = substr_replace($query_string, '', $_left_pos, 1);
$_last_var_pos = null;
}
} else {
$query_string = substr_replace($query_string, $this->_convert_var($query_vars[$_x], $_match[0][$_x]), $_var_pos[$_x], 2);
}
}
}
return $query_string;
}
/*======================================================================*\
Function: _convert_var
Purpose: convert a variable to the given type
Input: $var - the variable
$type - the type to convert to:
%i, %I - cast to integer
%f, %F - cast to float
%c, %C - comma separate, cast each element to integer
%l, %L - comma separate, no quotes, no casting
%q, %Q - quote/comma separate
\*======================================================================*/
function _convert_var($var, $type) {
switch($type) {
case '%i':
case '%I':
// cast to integer
settype($var, 'integer');
break;
case '%f':
case '%F':
// cast to float
settype($var, 'float');
break;
case '%c':
case '%C':
// comma separate
settype($var, 'array');
for($_x = 0 , $_y = count($var); $_x < $_y; $_x++) {
// cast to integers
settype($var[$_x], 'integer');
}
$var = implode(',', $var);
if($var == '') {
// force 0, keep syntax from breaking
$var = '0';
}
break;
case '%l':
case '%L':
// comma separate
settype($var, 'array');
$var = implode(',', $var);
break;
case '%q':
case '%Q':
settype($var, 'array');
// quote comma separate
$var = "'" . implode("','", $var) . "'";
break;
}
return $var;
}
/*======================================================================*\
Function: error
Purpose: handle error messages
\*======================================================================*/
function _error_msg($error_msg) {
trigger_error('SafeSQL: ' . $error_msg);
}
/*======================================================================*\
Function: SetDropValues
Purpose:
\*======================================================================*/
function set_drop_values($drop_values) {
if(is_array($drop_values)) {
$this->_drop_values = $drop_values;
} else {
$this->_error_msg('drop values must be an array');
}
}
/*======================================================================*\
Function: GetDropValues
Purpose:
\*======================================================================*/
function get_drop_values() {
return $this->_drop_values;
}
/*======================================================================*\
Function: _sql_escape
Purpose: method overridden by subclass
\*======================================================================*/
function _sql_escape() { }
}
class SafeSQL_MySQL extends SafeSQL {
var $_link_id;
/*======================================================================*\
Function: SafeSQL_MySQL
Purpose: constructor
\*======================================================================*/
function SafeSQL_MySQL($link_id = null) {
$this->_link_id = $link_id;
}
/*======================================================================*\
Function: _sql_escape
Purpose: recursively escape variables/arrays for SQL use
\*======================================================================*/
function _sql_escape($var) {
if(is_array($var)) {
$_newvar = array();
foreach($var as $_element) {
$_newvar[] = $this->_sql_escape($_element);
}
return $_newvar;
}
if(function_exists('mysql_real_escape_string')) {
if(!isset($this->_link_id)) {
return mysql_real_escape_string($var);
} else {
return mysql_real_escape_string($var, $this->_link_id);
}
} elseif(function_exists('mysql_escape_string')) {
return mysql_escape_string($var);
} else {
return addslashes($var);
}
break;
}
}
class SafeSQL_ANSI extends SafeSQL {
/*======================================================================*\
Function: SafeSQL_ANSI
Purpose: constructor
\*======================================================================*/
function SafeSQL_ANSI() { }
/*======================================================================*\
Function: _sql_escape
Purpose: recursively escape variables/arrays for SQL use
\*======================================================================*/
function _sql_escape($var) {
if(is_array($var)) {
foreach($var as $_element) {
$_newvar[] = $this->_sql_escape($_element);
}
return $_newvar;
}
return str_replace("'", "''", $var);
break;
}
}
?>
Jump to Line
Something went wrong with that request. Please try again.