250 |
kaklik |
1 |
<?php |
|
|
2 |
/* $Id: string.lib.php,v 2.14 2006/01/17 17:02:30 cybot_tm Exp $ */ |
|
|
3 |
// vim: expandtab sw=4 ts=4 sts=4: |
|
|
4 |
|
|
|
5 |
/** Specialized String Functions for phpMyAdmin |
|
|
6 |
* |
|
|
7 |
* Copyright 2002 Robin Johnson <robbat2@users.sourceforge.net> |
|
|
8 |
* http://www.orbis-terrarum.net/?l=people.robbat2 |
|
|
9 |
* |
|
|
10 |
* Defines a set of function callbacks that have a pure C version available if |
|
|
11 |
* the "ctype" extension is available, but otherwise have PHP versions to use |
|
|
12 |
* (that are slower). |
|
|
13 |
* |
|
|
14 |
* The SQL Parser code relies heavily on these functions. |
|
|
15 |
*/ |
|
|
16 |
|
|
|
17 |
/* Try to load mbstring, unless we're using buggy php version */ |
|
|
18 |
if (PMA_PHP_INT_VERSION != 40203) { |
|
|
19 |
if (!@extension_loaded('mbstring')) { |
|
|
20 |
PMA_dl('mbstring'); |
|
|
21 |
} |
|
|
22 |
} |
|
|
23 |
|
|
|
24 |
/* windows-* and tis-620 are not supported and are not multibyte, |
|
|
25 |
* others can be ignored as they're not multibyte */ |
|
|
26 |
$GLOBALS['using_mb_charset'] = |
|
|
27 |
substr($GLOBALS['charset'], 0, 8) != 'windows-' && |
|
|
28 |
substr($GLOBALS['charset'], 0, 9) != 'iso-8859-' && |
|
|
29 |
substr($GLOBALS['charset'], 0, 3) != 'cp-' && |
|
|
30 |
$GLOBALS['charset'] != 'koi8-r' && |
|
|
31 |
$GLOBALS['charset'] != 'tis-620'; |
|
|
32 |
|
|
|
33 |
$GLOBALS['PMA_allow_mbstr'] = @function_exists('mb_strlen') && $GLOBALS['using_mb_charset']; |
|
|
34 |
|
|
|
35 |
if ($GLOBALS['PMA_allow_mbstr']) { |
|
|
36 |
// the hebrew lang file uses iso-8859-8-i, encoded RTL, |
|
|
37 |
// but mb_internal_encoding only supports iso-8859-8 |
|
|
38 |
if ($GLOBALS['charset'] == 'iso-8859-8-i'){ |
|
|
39 |
mb_internal_encoding('iso-8859-8'); |
|
|
40 |
} else { |
|
|
41 |
mb_internal_encoding($GLOBALS['charset']); |
|
|
42 |
} |
|
|
43 |
} |
|
|
44 |
|
|
|
45 |
// This is for handling input better |
|
|
46 |
if (defined('PMA_MULTIBYTE_ENCODING') || $GLOBALS['PMA_allow_mbstr']) { |
|
|
47 |
$GLOBALS['PMA_strpos'] = 'mb_strpos'; |
|
|
48 |
$GLOBALS['PMA_strrpos'] = 'mb_strrpos'; |
|
|
49 |
} else { |
|
|
50 |
$GLOBALS['PMA_strpos'] = 'strpos'; |
|
|
51 |
$GLOBALS['PMA_strrpos'] = 'strrpos'; |
|
|
52 |
} |
|
|
53 |
|
|
|
54 |
/** |
|
|
55 |
* Returns length of string depending on current charset. |
|
|
56 |
* |
|
|
57 |
* @param string string to count |
|
|
58 |
* |
|
|
59 |
* @return int string length |
|
|
60 |
* |
|
|
61 |
* @access public |
|
|
62 |
* |
|
|
63 |
* @author nijel |
|
|
64 |
*/ |
|
|
65 |
function PMA_strlen($string) |
|
|
66 |
{ |
|
|
67 |
// windows-* charsets are not multibyte and not supported by mb_* |
|
|
68 |
if (defined('PMA_MULTIBYTE_ENCODING') || $GLOBALS['PMA_allow_mbstr']) { |
|
|
69 |
return mb_strlen($string); |
|
|
70 |
} else { |
|
|
71 |
return strlen($string); |
|
|
72 |
} |
|
|
73 |
} |
|
|
74 |
|
|
|
75 |
/** |
|
|
76 |
* Returns substring from string, works depending on current charset. |
|
|
77 |
* |
|
|
78 |
* @param string string to count |
|
|
79 |
* @param int start of substring |
|
|
80 |
* @param int length of substring |
|
|
81 |
* |
|
|
82 |
* @return int substring |
|
|
83 |
* |
|
|
84 |
* @access public |
|
|
85 |
* |
|
|
86 |
* @author nijel |
|
|
87 |
*/ |
|
|
88 |
function PMA_substr($string, $start, $length = 2147483647) |
|
|
89 |
{ |
|
|
90 |
if (defined('PMA_MULTIBYTE_ENCODING') || $GLOBALS['PMA_allow_mbstr']) { |
|
|
91 |
return mb_substr($string, $start, $length); |
|
|
92 |
} else { |
|
|
93 |
return substr($string, $start, $length); |
|
|
94 |
} |
|
|
95 |
} |
|
|
96 |
|
|
|
97 |
|
|
|
98 |
/** |
|
|
99 |
* This checks if a string actually exists inside another string |
|
|
100 |
* We try to do it in a PHP3-portable way. |
|
|
101 |
* We don't care about the position it is in. |
|
|
102 |
* |
|
|
103 |
* @param string string to search for |
|
|
104 |
* @param string string to search in |
|
|
105 |
* |
|
|
106 |
* @return boolean whether the needle is in the haystack or not |
|
|
107 |
*/ |
|
|
108 |
function PMA_STR_strInStr($needle, $haystack) |
|
|
109 |
{ |
|
|
110 |
// $GLOBALS['PMA_strpos']($haystack, $needle) !== FALSE |
|
|
111 |
// return (is_integer($GLOBALS['PMA_strpos']($haystack, $needle))); |
|
|
112 |
return $GLOBALS['PMA_strpos'](' ' . $haystack, $needle); |
|
|
113 |
} // end of the "PMA_STR_strInStr()" function |
|
|
114 |
|
|
|
115 |
|
|
|
116 |
/** |
|
|
117 |
* Checks if a given character position in the string is escaped or not |
|
|
118 |
* |
|
|
119 |
* @param string string to check for |
|
|
120 |
* @param integer the character to check for |
|
|
121 |
* @param integer starting position in the string |
|
|
122 |
* |
|
|
123 |
* @return boolean whether the character is escaped or not |
|
|
124 |
*/ |
|
|
125 |
function PMA_STR_charIsEscaped($string, $pos, $start = 0) |
|
|
126 |
{ |
|
|
127 |
$len = PMA_strlen($string); |
|
|
128 |
// Base case: |
|
|
129 |
// Check for string length or invalid input or special case of input |
|
|
130 |
// (pos == $start) |
|
|
131 |
if (($pos == $start) || ($len <= $pos)) { |
|
|
132 |
return FALSE; |
|
|
133 |
} |
|
|
134 |
|
|
|
135 |
$p = $pos - 1; |
|
|
136 |
$escaped = FALSE; |
|
|
137 |
while (($p >= $start) && (PMA_substr($string, $p, 1) == '\\')) { |
|
|
138 |
$escaped = !$escaped; |
|
|
139 |
$p--; |
|
|
140 |
} // end while |
|
|
141 |
|
|
|
142 |
if ($pos < $start) { |
|
|
143 |
// throw error about strings |
|
|
144 |
} |
|
|
145 |
|
|
|
146 |
return $escaped; |
|
|
147 |
} // end of the "PMA_STR_charIsEscaped()" function |
|
|
148 |
|
|
|
149 |
|
|
|
150 |
/** |
|
|
151 |
* Checks if a number is in a range |
|
|
152 |
* |
|
|
153 |
* @param integer number to check for |
|
|
154 |
* @param integer lower bound |
|
|
155 |
* @param integer upper bound |
|
|
156 |
* |
|
|
157 |
* @return boolean whether the number is in the range or not |
|
|
158 |
*/ |
|
|
159 |
function PMA_STR_numberInRangeInclusive($num, $lower, $upper) |
|
|
160 |
{ |
|
|
161 |
return (($num >= $lower) && ($num <= $upper)); |
|
|
162 |
} // end of the "PMA_STR_numberInRangeInclusive()" function |
|
|
163 |
|
|
|
164 |
|
|
|
165 |
/** |
|
|
166 |
* Checks if a character is a digit |
|
|
167 |
* |
|
|
168 |
* @param string character to check for |
|
|
169 |
* |
|
|
170 |
* @return boolean whether the character is a digit or not |
|
|
171 |
* |
|
|
172 |
* @see PMA_STR_numberInRangeInclusive() |
|
|
173 |
*/ |
|
|
174 |
function PMA_STR_isDigit($c) |
|
|
175 |
{ |
|
|
176 |
$ord_zero = 48; //ord('0'); |
|
|
177 |
$ord_nine = 57; //ord('9'); |
|
|
178 |
$ord_c = ord($c); |
|
|
179 |
|
|
|
180 |
return PMA_STR_numberInRangeInclusive($ord_c, $ord_zero, $ord_nine); |
|
|
181 |
} // end of the "PMA_STR_isDigit()" function |
|
|
182 |
|
|
|
183 |
|
|
|
184 |
/** |
|
|
185 |
* Checks if a character is an hexadecimal digit |
|
|
186 |
* |
|
|
187 |
* @param string character to check for |
|
|
188 |
* |
|
|
189 |
* @return boolean whether the character is an hexadecimal digit or not |
|
|
190 |
* |
|
|
191 |
* @see PMA_STR_numberInRangeInclusive() |
|
|
192 |
*/ |
|
|
193 |
function PMA_STR_isHexDigit($c) |
|
|
194 |
{ |
|
|
195 |
$ord_Aupper = 65; //ord('A'); |
|
|
196 |
$ord_Fupper = 70; //ord('F'); |
|
|
197 |
$ord_Alower = 97; //ord('a'); |
|
|
198 |
$ord_Flower = 102; //ord('f'); |
|
|
199 |
$ord_zero = 48; //ord('0'); |
|
|
200 |
$ord_nine = 57; //ord('9'); |
|
|
201 |
$ord_c = ord($c); |
|
|
202 |
|
|
|
203 |
return (PMA_STR_numberInRangeInclusive($ord_c, $ord_zero, $ord_nine) |
|
|
204 |
|| PMA_STR_numberInRangeInclusive($ord_c, $ord_Aupper, $ord_Fupper) |
|
|
205 |
|| PMA_STR_numberInRangeInclusive($ord_c, $ord_Alower, $ord_Flower)); |
|
|
206 |
} // end of the "PMA_STR_isHexDigit()" function |
|
|
207 |
|
|
|
208 |
|
|
|
209 |
/** |
|
|
210 |
* Checks if a character is an upper alphabetic one |
|
|
211 |
* |
|
|
212 |
* @param string character to check for |
|
|
213 |
* |
|
|
214 |
* @return boolean whether the character is an upper alphabetic one or |
|
|
215 |
* not |
|
|
216 |
* |
|
|
217 |
* @see PMA_STR_numberInRangeInclusive() |
|
|
218 |
*/ |
|
|
219 |
function PMA_STR_isUpper($c) |
|
|
220 |
{ |
|
|
221 |
$ord_zero = 65; //ord('A'); |
|
|
222 |
$ord_nine = 90; //ord('Z'); |
|
|
223 |
$ord_c = ord($c); |
|
|
224 |
|
|
|
225 |
return PMA_STR_numberInRangeInclusive($ord_c, $ord_zero, $ord_nine); |
|
|
226 |
} // end of the "PMA_STR_isUpper()" function |
|
|
227 |
|
|
|
228 |
|
|
|
229 |
/** |
|
|
230 |
* Checks if a character is a lower alphabetic one |
|
|
231 |
* |
|
|
232 |
* @param string character to check for |
|
|
233 |
* |
|
|
234 |
* @return boolean whether the character is a lower alphabetic one or |
|
|
235 |
* not |
|
|
236 |
* |
|
|
237 |
* @see PMA_STR_numberInRangeInclusive() |
|
|
238 |
*/ |
|
|
239 |
function PMA_STR_isLower($c) |
|
|
240 |
{ |
|
|
241 |
$ord_zero = 97; //ord('a'); |
|
|
242 |
$ord_nine = 122; //ord('z'); |
|
|
243 |
$ord_c = ord($c); |
|
|
244 |
|
|
|
245 |
return PMA_STR_numberInRangeInclusive($ord_c, $ord_zero, $ord_nine); |
|
|
246 |
} // end of the "PMA_STR_isLower()" function |
|
|
247 |
|
|
|
248 |
|
|
|
249 |
/** |
|
|
250 |
* Checks if a character is an alphabetic one |
|
|
251 |
* |
|
|
252 |
* @param string character to check for |
|
|
253 |
* |
|
|
254 |
* @return boolean whether the character is an alphabetic one or not |
|
|
255 |
* |
|
|
256 |
* @see PMA_STR_isUpper() |
|
|
257 |
* @see PMA_STR_isLower() |
|
|
258 |
*/ |
|
|
259 |
function PMA_STR_isAlpha($c) |
|
|
260 |
{ |
|
|
261 |
return (PMA_STR_isUpper($c) || PMA_STR_isLower($c)); |
|
|
262 |
} // end of the "PMA_STR_isAlpha()" function |
|
|
263 |
|
|
|
264 |
|
|
|
265 |
/** |
|
|
266 |
* Checks if a character is an alphanumeric one |
|
|
267 |
* |
|
|
268 |
* @param string character to check for |
|
|
269 |
* |
|
|
270 |
* @return boolean whether the character is an alphanumeric one or not |
|
|
271 |
* |
|
|
272 |
* @see PMA_STR_isUpper() |
|
|
273 |
* @see PMA_STR_isLower() |
|
|
274 |
* @see PMA_STR_isDigit() |
|
|
275 |
*/ |
|
|
276 |
function PMA_STR_isAlnum($c) |
|
|
277 |
{ |
|
|
278 |
return (PMA_STR_isUpper($c) || PMA_STR_isLower($c) || PMA_STR_isDigit($c)); |
|
|
279 |
} // end of the "PMA_STR_isAlnum()" function |
|
|
280 |
|
|
|
281 |
|
|
|
282 |
/** |
|
|
283 |
* Checks if a character is a space one |
|
|
284 |
* |
|
|
285 |
* @param string character to check for |
|
|
286 |
* |
|
|
287 |
* @return boolean whether the character is a space one or not |
|
|
288 |
* |
|
|
289 |
* @see PMA_STR_numberInRangeInclusive() |
|
|
290 |
*/ |
|
|
291 |
function PMA_STR_isSpace($c) |
|
|
292 |
{ |
|
|
293 |
$ord_space = 32; //ord(' ') |
|
|
294 |
$ord_tab = 9; //ord('\t') |
|
|
295 |
$ord_CR = 13; //ord('\n') |
|
|
296 |
$ord_NOBR = 160; //ord('U+00A0); |
|
|
297 |
$ord_c = ord($c); |
|
|
298 |
|
|
|
299 |
return (($ord_c == $ord_space) |
|
|
300 |
|| ($ord_c == $ord_NOBR) |
|
|
301 |
|| PMA_STR_numberInRangeInclusive($ord_c, $ord_tab, $ord_CR)); |
|
|
302 |
} // end of the "PMA_STR_isSpace()" function |
|
|
303 |
|
|
|
304 |
|
|
|
305 |
/** |
|
|
306 |
* Checks if a character is an accented character |
|
|
307 |
* |
|
|
308 |
* @note Presently this only works for some character sets. More work |
|
|
309 |
* may be needed to fix it. |
|
|
310 |
* |
|
|
311 |
* @param string character to check for |
|
|
312 |
* |
|
|
313 |
* @return boolean whether the character is an accented one or not |
|
|
314 |
* |
|
|
315 |
* @see PMA_STR_numberInRangeInclusive() |
|
|
316 |
*/ |
|
|
317 |
function PMA_STR_isAccented($c) |
|
|
318 |
{ |
|
|
319 |
$ord_min1 = 192; //ord('A'); |
|
|
320 |
$ord_max1 = 214; //ord('Z'); |
|
|
321 |
$ord_min2 = 216; //ord('A'); |
|
|
322 |
$ord_max2 = 246; //ord('Z'); |
|
|
323 |
$ord_min3 = 248; //ord('A'); |
|
|
324 |
$ord_max3 = 255; //ord('Z'); |
|
|
325 |
|
|
|
326 |
$ord_c = ord($c); |
|
|
327 |
|
|
|
328 |
return PMA_STR_numberInRangeInclusive($ord_c, $ord_min1, $ord_max1) |
|
|
329 |
|| PMA_STR_numberInRangeInclusive($ord_c, $ord_min2, $ord_max2) |
|
|
330 |
|| PMA_STR_numberInRangeInclusive($ord_c, $ord_min2, $ord_max2); |
|
|
331 |
} // end of the "PMA_STR_isAccented()" function |
|
|
332 |
|
|
|
333 |
|
|
|
334 |
/** |
|
|
335 |
* Checks if a character is an SQL identifier |
|
|
336 |
* |
|
|
337 |
* @param string character to check for |
|
|
338 |
* @param boolean whether the dot character is valid or not |
|
|
339 |
* |
|
|
340 |
* @return boolean whether the character is an SQL identifier or not |
|
|
341 |
* |
|
|
342 |
* @see PMA_STR_isAlnum() |
|
|
343 |
*/ |
|
|
344 |
function PMA_STR_isSqlIdentifier($c, $dot_is_valid = FALSE) |
|
|
345 |
{ |
|
|
346 |
return (PMA_STR_isAlnum($c) |
|
|
347 |
|| PMA_STR_isAccented($c) |
|
|
348 |
|| ($c == '_') || ($c == '$') |
|
|
349 |
|| (($dot_is_valid != FALSE) && ($c == '.'))); |
|
|
350 |
} // end of the "PMA_STR_isSqlIdentifier()" function |
|
|
351 |
|
|
|
352 |
|
|
|
353 |
/** |
|
|
354 |
* Binary search of a value in a sorted array |
|
|
355 |
* |
|
|
356 |
* @param string string to search for |
|
|
357 |
* @param array sorted array to search into |
|
|
358 |
* @param integer size of sorted array to search into |
|
|
359 |
* |
|
|
360 |
* @return boolean whether the string has been found or not |
|
|
361 |
*/ |
|
|
362 |
function PMA_STR_binarySearchInArr($str, $arr, $arrsize) |
|
|
363 |
{ |
|
|
364 |
// $arr MUST be sorted, due to binary search |
|
|
365 |
$top = $arrsize - 1; |
|
|
366 |
$bottom = 0; |
|
|
367 |
$found = FALSE; |
|
|
368 |
|
|
|
369 |
while (($top >= $bottom) && ($found == FALSE)) { |
|
|
370 |
$mid = intval(($top + $bottom) / 2); |
|
|
371 |
$res = strcmp($str, $arr[$mid]); |
|
|
372 |
if ($res == 0) { |
|
|
373 |
$found = TRUE; |
|
|
374 |
} elseif ($res < 0) { |
|
|
375 |
$top = $mid - 1; |
|
|
376 |
} else { |
|
|
377 |
$bottom = $mid + 1; |
|
|
378 |
} |
|
|
379 |
} // end while |
|
|
380 |
|
|
|
381 |
return $found; |
|
|
382 |
} // end of the "PMA_STR_binarySearchInArr()" function |
|
|
383 |
|
|
|
384 |
?> |