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;