This is an automated email from the ASF dual-hosted git repository.

cziegeler pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/felix-dev.git


The following commit(s) were added to refs/heads/master by this push:
     new 98da5cd  FELIX-6455 : configadmin.plugin.interpolation: default Value 
with ] is interpreted wrong
98da5cd is described below

commit 98da5cd36521856c9f1c32099b1485321921ec16
Author: Carsten Ziegeler <[email protected]>
AuthorDate: Sat Sep 4 16:36:38 2021 +0200

    FELIX-6455 : configadmin.plugin.interpolation: default Value with ] is 
interpreted wrong
---
 .../plugin/interpolation/Interpolator.java         | 110 ++++++++++++---------
 1 file changed, 63 insertions(+), 47 deletions(-)

diff --git 
a/configadmin-plugins/interpolation/src/main/java/org/apache/felix/configadmin/plugin/interpolation/Interpolator.java
 
b/configadmin-plugins/interpolation/src/main/java/org/apache/felix/configadmin/plugin/interpolation/Interpolator.java
index ceddb92..fa39cd9 100755
--- 
a/configadmin-plugins/interpolation/src/main/java/org/apache/felix/configadmin/plugin/interpolation/Interpolator.java
+++ 
b/configadmin-plugins/interpolation/src/main/java/org/apache/felix/configadmin/plugin/interpolation/Interpolator.java
@@ -19,6 +19,7 @@ package org.apache.felix.configadmin.plugin.interpolation;
 import java.util.Collections;
 import java.util.HashMap;
 import java.util.Map;
+import java.util.concurrent.atomic.AtomicReference;
 
 /**
  * Replace place holders in a string
@@ -40,6 +41,54 @@ public class Interpolator {
         Object provide(String type, String name, Map<String, String> 
directives);
     }
 
+    private static int getNextStartMarker(final AtomicReference<String> 
valueRef, final int pos) {
+        final String value = valueRef.get();
+        final int start = value.indexOf(START, pos);
+        if (start == -1) {
+            // no placeholder found
+            return -1;
+        }
+    
+        if (start > 0 && value.charAt(start - 1) == ESCAPE
+            && (start == 1 || value.charAt(start - 2) != ESCAPE)) {
+            // placeholder is escaped -> remove escape and continue
+            valueRef.set(value.substring(0, start - 
1).concat(value.substring(start)));
+    
+            return getNextStartMarker(valueRef, start + 1);
+        }
+        return start;    
+    }
+
+    private static int[] getMarkerBoundaries(final AtomicReference<String> 
valueRef, final int pos) {
+        final int start = getNextStartMarker(valueRef, pos);
+        if ( start == -1 ) {
+            return null;
+        }
+
+        // find END marker
+        final String value = valueRef.get();
+        int index = start + START.length();
+        int end = -1;
+        int count = 1;
+        while ( index < value.length() && count > 0 ) {            
+            if ( value.charAt(index) == END 
+                 && (value.charAt(index - 1) != ESCAPE || value.charAt(index - 
2) == ESCAPE) ) {
+                end = index;
+                count--;
+            }
+            if ( value.charAt(index) == '['
+                 && (value.charAt(index - 1) != ESCAPE || value.charAt(index - 
2) == ESCAPE) ) {
+                count++;
+            }
+            index++;
+        }
+        if ( count > 0 ) {
+            // no end marker found
+            return null;
+        }
+        return new int[] {start, end};
+    } 
+
     /**
      * Replace all place holders
      *
@@ -49,54 +98,22 @@ public class Interpolator {
      */
     public static Object replace(final String value, final Provider provider) {
         String result = value;
-        int start = -1;
-        while (start < result.length()) {
-            start = result.indexOf(START, start);
-            if (start == -1) {
+        int index = -1;
+        while (index < result.length()) {
+            final AtomicReference<String> ref = new AtomicReference<>(result);
+            final int[] boundaries = getMarkerBoundaries(ref, index);
+            result = ref.get();
+            if (boundaries == null) {
                 // no placeholder found -> end
-                start = result.length();
-                continue;
-            }
-
-            boolean replace = true;
-            if (start > 0 && result.charAt(start - 1) == ESCAPE) {
-                if (start == 1 || result.charAt(start - 2) != ESCAPE) {
-                    replace = false;
-                }
-            }
-
-            if (!replace) {
-                // placeholder is escaped -> remove placeholder and continue
-                result = result.substring(0, start - 
1).concat(result.substring(start));
-                start = start + START.length();
-                continue;
-            }
-
-            int count = 1;
-            int index = start + START.length();
-            while (index < result.length() && count > 0) {
-                if (result.charAt(index) == '[' && result.charAt(index - 1) == 
'$') {
-                    count++;
-                } else if (result.charAt(index) == '[' && index < 
result.length() - 1
-                        && result.charAt(index + 1) == ']') {
-                    count++;
-                } else if (result.charAt(index) == END) {
-                    count--;
-                }
-                index++;
-            }
-
-            if (count > 0) {
-                // no matching end found -> end
-                start = result.length();
+                index = result.length();
                 continue;
             }
 
-            final String key = result.substring(start + START.length(), index 
- 1);
+            final String key = result.substring(boundaries[0] + 
START.length(), boundaries[1]);
             final int sep = key.indexOf(':');
             if (sep == -1) {
                 // invalid key
-                start = index;
+                index = index + START.length();
                 continue;
             }
 
@@ -128,15 +145,14 @@ public class Interpolator {
             Object replacement = provider.provide(type, newName.toString(), 
directives);
             if (replacement == null) {
                 // no replacement found -> leave as is and continue
-                start = index;
+                index = index + START.length();
             } else {
-                if (!(replacement instanceof String)) {
-                    if (start == 0 && index == result.length()) {
-                        return replacement;
-                    }
+                // if replacement is not a string and placeholder is complete 
string, return that object
+                if (!(replacement instanceof String) && boundaries[0] == 0 && 
boundaries[1] == result.length() - 1) {
+                    return replacement;
                 }
                 // replace and continue with replacement
-                result = result.substring(0, 
start).concat(replacement.toString()).concat(result.substring(index));
+                result = result.substring(0, 
boundaries[0]).concat(replacement.toString()).concat(result.substring(boundaries[1]
 + 1));
             }
         }
         return result;

Reply via email to