Skip to content

Commit

Permalink
Fixed incorrect variable substitution (https://issues.redhat.com/brow…
Browse files Browse the repository at this point in the history
  • Loading branch information
belaban committed Aug 2, 2024
1 parent 00423bf commit 2a5480e
Show file tree
Hide file tree
Showing 3 changed files with 98 additions and 44 deletions.
13 changes: 4 additions & 9 deletions src/org/jgroups/conf/ProtocolConfiguration.java
Original file line number Diff line number Diff line change
Expand Up @@ -111,19 +111,15 @@ public void substituteVariables() {
Map.Entry<String, String> entry=it.next();
String key=entry.getKey();
String val=entry.getValue();
String tmp=Util.substituteVariable(val);
if(!val.equals(tmp)) {
properties.put(key, tmp);
}
else {
if(tmp.contains("${"))
it.remove();
if(val.contains("${")) {
String replacement=Util.substituteVariable(val);
if(replacement != null)
properties.put(key, replacement);
}
}
properties_str=propertiesToString();
}


public String toString() {
StringBuilder retval=new StringBuilder();
retval.append(Objects.requireNonNullElse(protocol_name, "<unknown>"));
Expand Down Expand Up @@ -159,7 +155,6 @@ public String getProtocolString() {
return buf.toString();
}


public String getProtocolStringNewXml() {
StringBuilder buf=new StringBuilder(protocol_name + ' ');
if(!properties.isEmpty()) {
Expand Down
58 changes: 57 additions & 1 deletion src/org/jgroups/util/Util.java
Original file line number Diff line number Diff line change
Expand Up @@ -4934,7 +4934,7 @@ public static String substituteVariable(String val) {
* @param p
* @return A string with vars replaced, or the same string if no vars found
*/
public static String substituteVariable(String val, Properties p) {
public static String substituteVariableOld(String val, Properties p) {
if(val == null)
return val;
String retval=val, prev;
Expand All @@ -4948,6 +4948,62 @@ public static String substituteVariable(String val, Properties p) {
return retval;
}

/**
* Replaces variables in a string.
* @param input The input string
* @param p A Properties hashmap, may be null
* @return The string with replaced variables, might be the same string as the input string if no substitution took place.
*/
public static String substituteVariable(String input, Properties p) {
if(input == null)
return input;
StringBuilder sb=new StringBuilder(input.length()), cache=null;
for(int i=0; i < input.length(); i++) {
char ch=input.charAt(i);
switch(ch) {
case '$':
char next=nextChar(input, i+1);
if(next == 0) { // end of string
sb.append(ch);
continue; // will terminate
}
if(next == '{') { // found '${'
i++;
if(cache != null) // we've already encountered a '${', but it is ignored
sb.append(cache);
cache=new StringBuilder(input.length()).append(ch).append(next);
}
else
sb.append(ch); // .append(next);
break;
case '}':
if(cache != null) {
String val=cache.substring(2);
String tmp=getProperty(val, p);
if(tmp != null)
sb.append(tmp);
cache=null;
}
else
sb.append(ch);
break;
default:
if(cache != null)
cache.append(ch);
else
sb.append(ch);
break;
}
}
if(cache != null)
sb.append(cache);
return sb.toString();
}

protected static char nextChar(String s, int index) {
return index >= s.length()? 0 : s.charAt(index);
}

private static String _substituteVar(String val, Properties p) {
int start_index, end_index;
start_index=val.indexOf("${");
Expand Down
71 changes: 37 additions & 34 deletions tests/junit-functional/org/jgroups/tests/UtilTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -182,35 +182,20 @@ public void testBeginWithDollar() {

public void testReplaceProperties() {
String input="hello ${my.name:Bela}";

String out=Util.substituteVariable(input);
System.out.println("out = " + out);

assert out.equals("hello Bela");

Properties props=new Properties();
props.put("my.name", "Michelle");
out=Util.substituteVariable(input, props);
System.out.println("out = " + out);
assert out.equals("hello Michelle");

input="hello \\${my.name:Bela}"; // no replacement as the trailing slash prevents this
out=Util.substituteVariable(input, props);
System.out.println("out = " + out);

assert out.equals(input);

input="\\${escape:bla}";
out=Util.substituteVariable(input);
System.out.println("out = " + out);

assert input.equals(out);


input="<UDP bind_addr=\"\\${my.bind_addr:127.0.0.1}\" ... />";
input="<UDP bind_addr=\"${my.bind_addr:127.0.0.1}\" ... />";
out=Util.substituteVariable(input);
System.out.println("out = " + out);

assert input.equals(out);
assert out.equals("<UDP bind_addr=\"127.0.0.1\" ... />");
}


Expand Down Expand Up @@ -1237,43 +1222,61 @@ public void testReadLine() throws IOException {
public void testVariableSubstitution() {
String val="hello world", replacement;
replacement=Util.substituteVariable(val);
Assert.assertEquals(val, replacement);
assert val.equals(replacement);

val="my name is ${user.name}";
replacement=Util.substituteVariable(val);
Assert.assertNotSame(val, replacement);
assert !(val.equals(replacement));
assert !val.equals(replacement);

val="my name is ${user.name} and ${user.name}";
replacement=Util.substituteVariable(val);
assert !(val.equals(replacement));
Assert.assertEquals(-1, replacement.indexOf("${"));

val="my name is ${unknown.var:Bela Ban}";
replacement=Util.substituteVariable(val);
assert replacement.contains("Bela Ban");
Assert.assertEquals(-1, replacement.indexOf("${"));
assert !replacement.contains("${");

val="my name is ${unknown.var}";
replacement=Util.substituteVariable(val);
assert replacement.contains("${");
assert replacement.equals("my name is ");

val="here is an invalid ${argument because it doesn't contains a closing bracket";
try {
replacement=Util.substituteVariable(val);
assert false : "should be an IllegalArgumentException";
}
catch(Throwable t) {
Assert.assertEquals(IllegalArgumentException.class, t.getClass());
}
replacement=Util.substituteVariable(val);
assert val.equals(replacement);

System.setProperty("name", "Bela");
val="bela${ban ${name} bong}done";
replacement=Util.substituteVariable(val);
assert val.equals("bela${ban bela bong}done");
assert replacement.equals("bela${ban Bela bong}done");

val="be}la${ban ${name} bong}done ${name}. done ";
replacement=Util.substituteVariable(val);
assert replacement.equals("be}la${ban Bela bong}done Bela. done ");

val="bla$";
replacement=Util.substituteVariable(val);
assert val.equals(replacement);

val="bla${";
replacement=Util.substituteVariable(val);
assert val.equals(replacement);

val="bla${b";
replacement=Util.substituteVariable(val);
assert val.equals(replacement);

val="bla}";
replacement=Util.substituteVariable(val);
assert val.equals(replacement);

val="hello $Bela{";
replacement=Util.substituteVariable(val);
assert val.equals(replacement);

val="be}la${ban ${name} bong}done ${name}";
val="hello ${name and end";
replacement=Util.substituteVariable(val);
assert val.equals("be}la${ban bela bong}done bela");
assert val.equals(replacement);
}


Expand Down

0 comments on commit 2a5480e

Please sign in to comment.