Rev Author Line No. Line
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 ?>