1 : <?php
2 :
3 : /**
4 : * PHPIDS
5 : *
6 : * Requirements: PHP5, SimpleXML
7 : *
8 : * Copyright (c) 2008 PHPIDS group (http://php-ids.org)
9 : *
10 : * PHPIDS is free software; you can redistribute it and/or modify
11 : * it under the terms of the GNU Lesser General Public License as published by
12 : * the Free Software Foundation, version 3 of the License, or
13 : * (at your option) any later version.
14 : *
15 : * PHPIDS is distributed in the hope that it will be useful,
16 : * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 : * GNU Lesser General Public License for more details.
19 : *
20 : * You should have received a copy of the GNU Lesser General Public License
21 : * along with PHPIDS. If not, see <http://www.gnu.org/licenses/>.
22 : *
23 : * PHP version 5.1.6+
24 : *
25 : * @category Security
26 : * @package PHPIDS
27 : * @author Mario Heiderich <mario.heiderich@gmail.com>
28 : * @author Christian Matthies <ch0012@gmail.com>
29 : * @author Lars Strojny <lars@strojny.net>
30 : * @license http://www.gnu.org/licenses/lgpl.html LGPL
31 : * @link http://php-ids.org/
32 : */
33 :
34 : /**
35 : * PHPIDS specific utility class to convert charsets manually
36 : *
37 : * Note that if you make use of IDS_Converter::runAll(), existing class
38 : * methods will be executed in the same order as they are implemented in the
39 : * class tree!
40 : *
41 : * @category Security
42 : * @package PHPIDS
43 : * @author Christian Matthies <ch0012@gmail.com>
44 : * @author Mario Heiderich <mario.heiderich@gmail.com>
45 : * @author Lars Strojny <lars@strojny.net>
46 : * @copyright 2007 The PHPIDS Group
47 : * @license http://www.gnu.org/licenses/lgpl.html LGPL
48 : * @version Release: $Id:Converter.php 517 2007-09-15 15:04:13Z mario $
49 : * @link http://php-ids.org/
50 : */
51 : class IDS_Converter
52 1 : {
53 : /**
54 : * Runs all converter functions
55 : *
56 : * Note that if you make use of IDS_Converter::runAll(), existing class
57 : * methods will be executed in the same order as they are implemented in the
58 : * class tree!
59 : *
60 : * @param string $value the value to convert
61 : *
62 : * @static
63 : * @return string
64 : */
65 : public static function runAll($value)
66 : {
67 35 : foreach (get_class_methods(__CLASS__) as $method) {
68 :
69 35 : if (strpos($method, 'run') === 0) {
70 35 : continue;
71 : }
72 35 : $value = self::$method($value);
73 35 : }
74 :
75 35 : return $value;
76 : }
77 :
78 : /**
79 : * Check for comments and erases them if available
80 : *
81 : * @param string $value the value to convert
82 : *
83 : * @static
84 : * @return string
85 : */
86 : public static function convertFromCommented($value)
87 : {
88 : // check for existing comments
89 35 : if (preg_match('/(?:\<!-|-->|\/\*|\*\/|\/\/\W*\w+\s*$)|' .
90 35 : '(?:--[^-]*-)/ms', $value)) {
91 :
92 : $pattern = array(
93 8 : '/(?:(?:<!)(?:(?:--(?:[^-]*(?:-[^-]+)*)--\s*)*)(?:>))/ms',
94 8 : '/(?:(?:\/\*\/*[^\/\*]*)+\*\/)/ms',
95 : '/(?:--[^-]*-)/ms'
96 8 : );
97 :
98 8 : $converted = preg_replace($pattern, ';', $value);
99 8 : $value .= "\n" . $converted;
100 8 : }
101 : //make sure inline comments are detected and converted correctly
102 35 : $value = preg_replace('/(<\w+)\/+(\w+=?)/m', '$1/$2', $value);
103 35 : $value = preg_replace('/[^\\\:]\/\/(.*)$/m', '/**/$1', $value);
104 :
105 35 : return $value;
106 : }
107 :
108 : /**
109 : * Strip newlines
110 : *
111 : * @param string $value the value to convert
112 : *
113 : * @static
114 : * @return string
115 : */
116 : public static function convertFromNewLines($value)
117 : {
118 : //check for inline linebreaks
119 35 : $search = array('\r', '\n', '\f', '\t', '\v');
120 35 : $value = str_replace($search, ';', $value);
121 :
122 : //convert real linebreaks
123 35 : return preg_replace('/(?:\n|\r|\v)/m', ' ', $value);
124 : }
125 :
126 : /**
127 : * Checks for common charcode pattern and decodes them
128 : *
129 : * @param string $value the value to convert
130 : *
131 : * @static
132 : * @return string
133 : */
134 : public static function convertFromJSCharcode($value)
135 : {
136 35 : $matches = array();
137 :
138 : // check if value matches typical charCode pattern
139 35 : if (preg_match_all('/(?:[\d+-=\/\* ]+(?:\s?,\s?[\d+-=\/\* ]+)){4,}/ms',
140 35 : $value, $matches)) {
141 :
142 1 : $converted = '';
143 1 : $string = implode(',', $matches[0]);
144 1 : $string = preg_replace('/\s/', '', $string);
145 1 : $string = preg_replace('/\w+=/', '', $string);
146 1 : $charcode = explode(',', $string);
147 :
148 1 : foreach ($charcode as $char) {
149 1 : $char = preg_replace('/\W0/s', '', $char);
150 :
151 1 : if (preg_match_all('/\d*[+-\/\* ]\d+/', $char, $matches)) {
152 1 : $match = preg_split('/(\W?\d+)/',
153 1 : (implode('', $matches[0])),
154 1 : null,
155 1 : PREG_SPLIT_DELIM_CAPTURE);
156 :
157 1 : if (array_sum($match) >= 20 && array_sum($match) <= 127) {
158 1 : $converted .= chr(array_sum($match));
159 1 : }
160 :
161 1 : } elseif (!empty($char) && $char >= 20 && $char <= 127) {
162 1 : $converted .= chr($char);
163 1 : }
164 1 : }
165 :
166 1 : $value .= "\n" . $converted;
167 1 : }
168 :
169 : // check for octal charcode pattern
170 35 : if (preg_match_all('/(?:(?:[\\\]+\d+[ \t]*){8,})/ims', $value, $matches)) {
171 :
172 1 : $converted = '';
173 1 : $charcode = explode('\\', preg_replace('/\s/', '', implode(',',
174 1 : $matches[0])));
175 :
176 1 : foreach ($charcode as $char) {
177 1 : if (!empty($char)) {
178 1 : if (octdec($char) >= 20 && octdec($char) <= 127) {
179 1 : $converted .= chr(octdec($char));
180 1 : }
181 1 : }
182 1 : }
183 1 : $value .= "\n" . $converted;
184 1 : }
185 :
186 : // check for hexadecimal charcode pattern
187 35 : if (preg_match_all('/(?:(?:[\\\]+\w+\s*){8,})/ims', $value, $matches)) {
188 :
189 2 : $converted = '';
190 2 : $charcode = explode('\\', preg_replace('/[ux]/', '', implode(',',
191 2 : $matches[0])));
192 :
193 2 : foreach ($charcode as $char) {
194 2 : if (!empty($char)) {
195 2 : if (hexdec($char) >= 20 && hexdec($char) <= 127) {
196 2 : $converted .= chr(hexdec($char));
197 2 : }
198 2 : }
199 2 : }
200 2 : $value .= "\n" . $converted;
201 2 : }
202 :
203 35 : return $value;
204 : }
205 :
206 : /**
207 : * Eliminate JS regex modifiers
208 : *
209 : * @param string $value the value to convert
210 : *
211 : * @static
212 : * @return string
213 : */
214 : public static function convertJSRegexModifiers($value)
215 : {
216 35 : $value = preg_replace('/\/[gim]/', '/', $value);
217 :
218 35 : return $value;
219 : }
220 :
221 : /**
222 : * Converts from hex/dec entities
223 : *
224 : * @param string $value the value to convert
225 : *
226 : * @static
227 : * @return string
228 : */
229 : public static function convertEntities($value)
230 : {
231 35 : $converted = null;
232 35 : if (preg_match('/&#x?[\w]+/ms', $value)) {
233 6 : $converted = preg_replace('/(&#x?[\w]{2}\d?);?/ms', '$1;', $value);
234 6 : $converted = html_entity_decode($converted, ENT_QUOTES, 'UTF-8');
235 6 : $value .= "\n" . str_replace(';;', ';', $converted);
236 6 : }
237 :
238 35 : return $value;
239 : }
240 :
241 : /**
242 : * Normalize quotes
243 : *
244 : * @param string $value the value to convert
245 : *
246 : * @static
247 : * @return string
248 : */
249 : public static function convertQuotes($value)
250 : {
251 : // normalize different quotes to "
252 35 : $pattern = array('\'', '`', '´', '’', '‘');
253 35 : $value = str_replace($pattern, '"', $value);
254 :
255 35 : return $value;
256 : }
257 :
258 : /**
259 : * Converts SQLHEX to plain text
260 : *
261 : * @param string $value the value to convert
262 : *
263 : * @static
264 : * @return string
265 : */
266 : public static function convertFromSQLHex($value)
267 : {
268 35 : $matches = array();
269 35 : if(preg_match_all('/(?:0x[a-f\d]{2,}[a-f\d\s]*)+/im', $value, $matches)) {
270 3 : foreach($matches[0] as $match) {
271 3 : $converted = '';
272 3 : foreach(str_split($match, 2) as $hex_index) {
273 3 : if(preg_match('/[a-f\d]{2,3}/i', $hex_index)) {
274 3 : $converted .= chr(hexdec($hex_index));
275 3 : }
276 3 : }
277 3 : $value = str_replace($match, $converted, $value);
278 3 : }
279 3 : }
280 35 : return $value;
281 : }
282 :
283 : /**
284 : * Converts basic SQL keywords and obfuscations
285 : *
286 : * @param string $value the value to convert
287 : *
288 : * @static
289 : * @return string
290 : */
291 : public static function convertFromSQLKeywords($value)
292 : {
293 : $pattern = array('/(?:IS\s+null)|(LIKE\s+null)|' .
294 35 : '(?:(?:^|\W)IN[+\s]*\([\s\d"]+[^()]*\))/ims');
295 35 : $value = preg_replace($pattern, '"=0', $value);
296 35 : $value = preg_replace('/null,/ims', ',0', $value);
297 35 : $value = preg_replace('/,null/ims', ',0', $value);
298 : $pattern = array('/[^\w,]NULL|\\\N|TRUE|FALSE|UTC_TIME|' .
299 35 : 'LOCALTIME(?:STAMP)?|CURRENT_\w+|BINARY|' .
300 35 : '(?:(?:ASCII|SOUNDEX|' .
301 35 : 'MD5|R?LIKE)[+\s]*\([^()]+\))|(?:-+\d)/ims');
302 35 : $value = preg_replace($pattern, 0, $value);
303 : $pattern = array('/(?:NOT\s+BETWEEN)|(?:IS\s+NOT)|(?:NOT\s+IN)|' .
304 35 : '(?:XOR|\WDIV\W|\WNOT\W|<>|RLIKE(?:\s+BINARY)?)|' .
305 35 : '(?:REGEXP\s+BINARY)|' .
306 35 : '(?:SOUNDS\s+LIKE)/ims');
307 35 : $value = preg_replace($pattern, '!', $value);
308 35 : $value = preg_replace('/"\s+\d/', '"', $value);
309 :
310 35 : return $value;
311 : }
312 :
313 : /**
314 : * Detects nullbytes and controls chars via ord()
315 : *
316 : * @param string $value the value to convert
317 : *
318 : * @static
319 : * @return string
320 : */
321 : public static function convertFromControlChars($value)
322 : {
323 : // critical ctrl values
324 35 : $search = array(chr(0), chr(1), chr(2),
325 35 : chr(3), chr(4), chr(5),
326 35 : chr(6), chr(7), chr(8),
327 35 : chr(11), chr(12), chr(14),
328 35 : chr(15), chr(16), chr(17),
329 35 : chr(18), chr(19));
330 35 : $value = str_replace($search, '%00', $value);
331 35 : $urlencoded = urlencode($value);
332 :
333 : //take care for malicious unicode characters
334 35 : $value = urldecode(preg_replace('/(?:%E(?:2|3)%8(?:0|1)%(?:A|8|9)' .
335 35 : '\w|%EF%BB%BF|%EF%BF%BD)|(?:&#(?:65|8)\d{3};?)/i', null,
336 35 : $urlencoded));
337 :
338 35 : $value = preg_replace('/(?:&[#x]*(200|820|200|820|zwn?j|lrm|rlm)\w?;?)/i', null,
339 35 : $value);
340 :
341 35 : $value = preg_replace('/(?:&#(?:65|8)\d{3};?)|' .
342 35 : '(?:&#(?:56|7)3\d{2};?)|' .
343 35 : '(?:&#x(?:fe|20)\w{2};?)|' .
344 35 : '(?:&#x(?:d[c-f])\w{2};?)/i', null,
345 35 : $value);
346 :
347 35 : return $value;
348 : }
349 :
350 : /**
351 : * This method matches and translates base64 strings and fragments
352 : * used in data URIs
353 : *
354 : * @param string $value the value to convert
355 : *
356 : * @static
357 : * @return string
358 : */
359 : public static function convertFromNestedBase64($value)
360 : {
361 35 : $matches = array();
362 35 : preg_match_all('/(?:^|[,&?])\s*([a-z0-9]{30,}=*)(?:\W|$)/im',
363 35 : $value,
364 35 : $matches);
365 :
366 35 : foreach ($matches[1] as $item) {
367 2 : if (isset($item) && !preg_match('/[a-f0-9]{32}/i', $item)) {
368 2 : $value = str_replace($item, base64_decode($item), $value);
369 2 : }
370 35 : }
371 :
372 35 : return $value;
373 : }
374 :
375 : /**
376 : * Detects nullbytes and controls chars via ord()
377 : *
378 : * @param string $value the value to convert
379 : *
380 : * @static
381 : * @return string
382 : */
383 : public static function convertFromOutOfRangeChars($value)
384 : {
385 35 : $values = str_split($value);
386 35 : foreach ($values as $item) {
387 35 : if (ord($item) >= 127) {
388 8 : $value = str_replace($item, 'U', $value);
389 8 : }
390 35 : }
391 :
392 35 : return $value;
393 : }
394 :
395 : /**
396 : * Strip XML patterns
397 : *
398 : * @param string $value the value to convert
399 : *
400 : * @static
401 : * @return string
402 : */
403 : public static function convertFromXML($value)
404 : {
405 35 : $converted = strip_tags($value);
406 :
407 35 : if ($converted && ($converted != $value)) {
408 24 : return $value . "\n" . $converted;
409 : }
410 30 : return $value;
411 : }
412 :
413 : /**
414 : * This method converts JS unicode code points to
415 : * regular characters
416 : *
417 : * @param string $value the value to convert
418 : *
419 : * @static
420 : * @return string
421 : */
422 : public static function convertFromJSUnicode($value)
423 : {
424 35 : $matches = array();
425 :
426 35 : preg_match_all('/\\\u[0-9a-f]{4}/ims', $value, $matches);
427 :
428 35 : if (!empty($matches[0])) {
429 0 : foreach ($matches[0] as $match) {
430 0 : $value = str_replace($match,
431 0 : chr(hexdec(substr($match, 2, 4))),
432 0 : $value);
433 0 : }
434 0 : $value .= "\n\u0001";
435 0 : }
436 :
437 35 : return $value;
438 : }
439 :
440 :
441 : /**
442 : * Converts relevant UTF-7 tags to UTF-8
443 : *
444 : * @param string $value the value to convert
445 : *
446 : * @static
447 : * @return string
448 : */
449 : public static function convertFromUTF7($value)
450 : {
451 35 : if(preg_match('/\+A\w+-/m', $value)) {
452 1 : if (function_exists('mb_convert_encoding')) {
453 1 : if(version_compare(PHP_VERSION, '5.2.8', '<')) {
454 0 : $tmp_chars = str_split($value);
455 0 : $value = '';
456 0 : foreach($tmp_chars as $char) {
457 0 : if(ord($char) <= 127) {
458 0 : $value .= $char;
459 0 : }
460 0 : }
461 0 : }
462 1 : $value .= "\n" . mb_convert_encoding($value, 'UTF-8', 'UTF-7');
463 1 : } else {
464 : //list of all critical UTF7 codepoints
465 : $schemes = array(
466 0 : '+ACI-' => '"',
467 0 : '+ADw-' => '<',
468 0 : '+AD4-' => '>',
469 0 : '+AFs-' => '[',
470 0 : '+AF0-' => ']',
471 0 : '+AHs-' => '{',
472 0 : '+AH0-' => '}',
473 0 : '+AFw-' => '\\',
474 0 : '+ADs-' => ';',
475 0 : '+ACM-' => '#',
476 0 : '+ACY-' => '&',
477 0 : '+ACU-' => '%',
478 0 : '+ACQ-' => '$',
479 0 : '+AD0-' => '=',
480 0 : '+AGA-' => '`',
481 0 : '+ALQ-' => '"',
482 0 : '+IBg-' => '"',
483 0 : '+IBk-' => '"',
484 0 : '+AHw-' => '|',
485 0 : '+ACo-' => '*',
486 0 : '+AF4-' => '^',
487 0 : '+ACIAPg-' => '">',
488 : '+ACIAPgA8-' => '">'
489 0 : );
490 :
491 0 : $value = str_ireplace(array_keys($schemes),
492 0 : array_values($schemes), $value);
493 : }
494 1 : }
495 35 : return $value;
496 : }
497 :
498 : /**
499 : * Converts basic concatenations
500 : *
501 : * @param string $value the value to convert
502 : *
503 : * @static
504 : * @return string
505 : */
506 : public static function convertConcatenations($value)
507 : {
508 : //normalize remaining backslashes
509 35 : if ($value != preg_replace('/(\w)\\\/', "$1", $value)) {
510 3 : $value .= preg_replace('/(\w)\\\/', "$1", $value);
511 3 : }
512 :
513 35 : $compare = stripslashes($value);
514 :
515 35 : $pattern = array('/(?:<\/\w+>\+<\w+>)/s',
516 35 : '/(?:":\d+[^"[]+")/s',
517 35 : '/(?:"?"\+\w+\+")/s',
518 35 : '/(?:"\s*;[^"]+")|(?:";[^"]+:\s*")/s',
519 35 : '/(?:"\s*(?:;|\+).{8,18}:\s*")/s',
520 35 : '/(?:";\w+=)|(?:!""&&")|(?:~)/s',
521 35 : '/(?:"?"\+""?\+?"?)|(?:;\w+=")|(?:"[|&]{2,})/s',
522 35 : '/(?:"\s*\W+")/s',
523 35 : '/(?:";\w\s*\+=\s*\w?\s*")/s',
524 35 : '/(?:"[|&;]+\s*[^|&\n]*[|&]+\s*"?)/s',
525 35 : '/(?:";\s*\w+\W+\w*\s*[|&]*")/s',
526 35 : '/(?:"\s*"\s*\.)/s',
527 35 : '/(?:\s*new\s+\w+\s*[+"])/',
528 35 : '/(?:(?:^|\s+)(?:do|else)\s+)/',
529 35 : '/(?:\{\s*new\s+\w+\s*\})/',
530 35 : '/(?:(this|self).)/');
531 :
532 : // strip out concatenations
533 35 : $converted = preg_replace($pattern, null, $compare);
534 :
535 : //strip object traversal
536 35 : $converted = preg_replace('/\w(\.\w\()/', "$1", $converted);
537 :
538 : //convert JS special numbers
539 35 : $converted = preg_replace('/(?:\(*[.\d]e[+-]*[^a-z\W]+\)*)' .
540 35 : '|(?:NaN|Infinity)\W/ms', 1, $converted);
541 :
542 35 : if ($converted && ($compare != $converted)) {
543 15 : $value .= "\n" . $converted;
544 15 : }
545 :
546 35 : return $value;
547 : }
548 :
549 : /**
550 : * This method collects and decodes proprietary encoding types
551 : *
552 : * @param string $value the value to convert
553 : * @param IDS_Monitor $monitor the monitor object
554 : *
555 : * @static
556 : * @return string
557 : */
558 : public static function convertFromProprietaryEncodings($value) {
559 :
560 : //Xajax error reportings
561 35 : $value = preg_replace('/<!\[CDATA\[(\W+)\]\]>/im', '$1', $value);
562 :
563 : //strip false alert triggering apostrophes
564 35 : $value = preg_replace('/(\w)\"(s)/m', '$1$2', $value);
565 :
566 : //strip quotes within typical search patterns
567 35 : $value = preg_replace('/^"([^"=\\!><~]+)"$/', '$1', $value);
568 :
569 : //OpenID login tokens
570 35 : $value = preg_replace('/{[\w-]{8,9}\}(?:\{[\w=]{8}\}){2}/', null, $value);
571 :
572 : //convert Content and \sdo\s to null
573 35 : $value = preg_replace('/Content|\Wdo\s/', null, $value);
574 :
575 : //strip emoticons
576 35 : $value = preg_replace(
577 35 : '/(?:[:;]-[()\/PD]+)|(?:\s;[()PD]+)|(?::[()PD]+)|-\.-|\^\^/m',
578 35 : null,
579 : $value
580 35 : );
581 :
582 : // normalize separation char repetion
583 35 : $value = preg_replace('/([.+~=*_\-])\1{2,}/m', '$1', $value);
584 :
585 : //remove parenthesis inside sentences
586 35 : $value = preg_replace('/(\w\s)\(([&\w]+)\)(\s\w|$)/', '$1$2$3', $value);
587 :
588 : //normalize ampersand listings
589 35 : $value = preg_replace('/(\w\s)&\s(\w)/', '$1$2', $value);
590 :
591 35 : return $value;
592 : }
593 :
594 : /**
595 : * This method is the centrifuge prototype
596 : *
597 : * @param string $value the value to convert
598 : * @param IDS_Monitor $monitor the monitor object
599 : *
600 : * @static
601 : * @return string
602 : */
603 : public static function runCentrifuge($value, IDS_Monitor $monitor = null)
604 : {
605 35 : $threshold = 3.49;
606 :
607 35 : $unserialized = false;
608 35 : if(preg_match('/^\w:\d+:\{/', $value)) {
609 0 : $unserialized = @unserialize($value);
610 0 : }
611 :
612 35 : if (strlen($value) > 25 && !$unserialized) {
613 : // Check for the attack char ratio
614 33 : $tmp_value = $value;
615 33 : $tmp_value = preg_replace('/([*.!?+-])\1{1,}/m', '$1', $tmp_value);
616 33 : $tmp_value = preg_replace('/"[\p{L}\d\s]+"/m', null, $tmp_value);
617 :
618 33 : $stripped_length = strlen(preg_replace('/[\d\s\p{L}.:,%\/><-]+/m',
619 33 : null, $tmp_value));
620 33 : $overall_length = strlen(preg_replace('/([\d\s\p{L}]{3,})+/m', 'aaa',
621 33 : preg_replace('/\s{2,}/m', null, $tmp_value)));
622 :
623 : if ($stripped_length != 0
624 33 : && $overall_length/$stripped_length <= $threshold) {
625 :
626 16 : $monitor->centrifuge['ratio'] =
627 16 : $overall_length/$stripped_length;
628 16 : $monitor->centrifuge['threshold'] =
629 : $threshold;
630 :
631 16 : $value .= "\n$[!!!]";
632 16 : }
633 33 : }
634 :
635 35 : if (strlen($value) > 40) {
636 : // Replace all non-special chars
637 32 : $converted = preg_replace('/[\w\s\p{L},.!]/', null, $value);
638 :
639 : // Split string into an array, unify and sort
640 32 : $array = str_split($converted);
641 32 : $array = array_unique($array);
642 32 : asort($array);
643 :
644 : // Normalize certain tokens
645 : $schemes = array(
646 32 : '~' => '+',
647 32 : '^' => '+',
648 32 : '|' => '+',
649 32 : '*' => '+',
650 32 : '%' => '+',
651 32 : '&' => '+',
652 : '/' => '+'
653 32 : );
654 :
655 32 : $converted = implode($array);
656 32 : $converted = str_replace(array_keys($schemes),
657 32 : array_values($schemes), $converted);
658 32 : $converted = preg_replace('/[+-]\s*\d+/', '+', $converted);
659 32 : $converted = preg_replace('/[()[\]{}]/', '(', $converted);
660 32 : $converted = preg_replace('/[!?:=]/', ':', $converted);
661 32 : $converted = preg_replace('/[^:(+]/', null, stripslashes($converted));
662 :
663 : // Sort again and implode
664 32 : $array = str_split($converted);
665 32 : asort($array);
666 :
667 32 : $converted = implode($array);
668 :
669 32 : if (preg_match('/(?:\({2,}\+{2,}:{2,})|(?:\({2,}\+{2,}:+)|' .
670 32 : '(?:\({3,}\++:{2,})/', $converted)) {
671 :
672 15 : $monitor->centrifuge['converted'] = $converted;
673 :
674 15 : return $value . "\n" . $converted;
675 : }
676 31 : }
677 :
678 35 : return $value;
679 : }
680 : }
681 :
682 : /*
683 : * Local variables:
684 : * tab-width: 4
685 : * c-basic-offset: 4
686 : * End:
687 : */
|