From a12761ac2a9091ff37fc69d6b9d89c1ffdfbd963 Mon Sep 17 00:00:00 2001
Message-Id: <a12761ac2a9091ff37fc69d6b9d89c1ffdfbd963.1329732660.git.dmitriy.trt@gmail.com>
From: "Dmitriy.trt" <dmitriy.trt@gmail.com>
Date: Mon, 20 Feb 2012 17:10:51 +0700
Subject: [PATCH] Fix infinite loop in text pattern replace component

---
 flexifilter.components.inc |   32 ++++++++++++++++----------------
 1 files changed, 16 insertions(+), 16 deletions(-)

diff --git a/flexifilter.components.inc b/flexifilter.components.inc
index fa2affd..2cbdd36 100644
--- a/flexifilter.components.inc
+++ b/flexifilter.components.inc
@@ -408,15 +408,24 @@ function flexifilter_component_text_pattern_replace($op, $settings, $text) {
     case 'prepare':
     case 'process':
       $find    = $settings['find'];
+      $find_length = strlen($find);
       $i       = 0;
       $count   = 1;
-      $replace = explode("\n", $settings['replace']);
+      $replace = array_map('trim', explode("\n", $settings['replace']));
       $max     = count($replace);
-      foreach ($replace as $key => $value) {
-        $replace[$key] = trim($value);
-      }
-      while (($pos = strpos($text, $find)) !== FALSE) {
-        $text = flexifilter_component_text_pattern_replace_once($pos, $find, str_replace('[[flexifilter_count]]', $count, $replace[$i]), $text);
+      $offset  = 0;
+      $result  = '';
+      while (($pos = strpos($text, $find, $offset)) !== FALSE) {
+        // Add part before match to result.
+        $result .= substr($text, $offset, $pos - $offset);
+
+        // Add replacement to result.
+        $result .= str_replace('[[flexifilter_count]]', $count, $replace[$i]);
+
+        // Set offset right after found string.
+        $offset = $pos + $find_length;
+
+        // Update counter and current replacement index.
         $i++;
         $count++;
         if ($i >= $max) {
@@ -424,20 +433,11 @@ function flexifilter_component_text_pattern_replace($op, $settings, $text) {
           $i = $i - $max;
         }
       }
-      return $text;
+      return $result . substr($text, $offset);
   }
 }
 
 /**
- * Helper function for flexifilter_component_text_pattern_replace. Replaces text only once.
- * Cannot use str_replace with $count because Drupal supports PHP 4.
- * GCI TODO: replace this with str_replace since D7 supports str_replace with $count.
- */
-function flexifilter_component_text_pattern_replace_once($pos, $search, $replace, $subject) {
-  return drupal_substr($subject, 0, $pos) . $replace . drupal_substr($subject, $pos + drupal_strlen($search));
-}
-
-/**
  * Flexifilter component callback.
  * Grabs chunks of text based on starting and ending tags.
  */
-- 
1.7.8.3

