1 | <?php
|
---|
2 | /* $Id: string.lib.php 8301 2006-01-17 17:03:02Z cybot_tm $ */
|
---|
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 | ?>
|
---|