Skip to content

Commit 86d5b5e

Browse files
author
kohsuke
committed
1 parent ec2a8e6 commit 86d5b5e

File tree

2 files changed

+19
-6
lines changed

2 files changed

+19
-6
lines changed

core/src/main/java/hudson/Util.java

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,7 @@ public static <T> List<T> filter( List<?> base, Class<T> type ) {
9292
/**
9393
* Pattern for capturing variables. Either $xyz or ${xyz}, while ignoring "$$"
9494
*/
95-
private static final Pattern VARIABLE = Pattern.compile("(?<!\\$)\\$([A-Za-z0-9_]+|\\{[A-Za-z0-9_]+\\})");
95+
private static final Pattern VARIABLE = Pattern.compile("\\$([A-Za-z0-9_]+|\\{[A-Za-z0-9_]+\\}|\\$)");
9696

9797
/**
9898
* Replaces the occurrence of '$key' by <tt>properties.get('key')</tt>.
@@ -118,14 +118,21 @@ public static String replaceMacro(String s, VariableResolver<String> resolver) {
118118
if(!m.find(idx)) return s;
119119

120120
String key = m.group().substring(1);
121-
if(key.charAt(0)=='{') key = key.substring(1,key.length()-1);
122121

123-
String value = resolver.resolve(key);
122+
// escape the dollar sign or get the key to resolve
123+
String value;
124+
if(key.charAt(0)=='$') {
125+
value = "$";
126+
} else {
127+
if(key.charAt(0)=='{') key = key.substring(1,key.length()-1);
128+
value = resolver.resolve(key);
129+
}
130+
124131
if(value==null)
125-
idx = m.start()+1; // skip this
132+
idx = m.end(); // skip this
126133
else {
127134
s = s.substring(0,m.start())+value+s.substring(m.end());
128-
idx = m.start();
135+
idx = m.start() + value.length();
129136
}
130137
}
131138
}

core/src/test/java/hudson/UtilTest.java

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@ public void testReplaceMacro() {
1414
m.put("A","a");
1515
m.put("AA","aa");
1616
m.put("B","B");
17+
m.put("DOLLAR", "$");
18+
m.put("ENCLOSED", "a${A}");
1719

1820
// longest match
1921
assertEquals("aa",Util.replaceMacro("$AA",m));
@@ -24,10 +26,14 @@ public void testReplaceMacro() {
2426
assertEquals("aaB",Util.replaceMacro("${AA}B",m));
2527
assertEquals("${AAB}",Util.replaceMacro("${AAB}",m));
2628

29+
// $ escaping
30+
assertEquals("asd$${AA}dd", Util.replaceMacro("asd$$$${AA}dd",m));
31+
2732
// test that more complex scenarios work
28-
assertEquals("/a/B/aa", Util.replaceMacro("/$A/$B/$AA",m));
33+
assertEquals("/a/B/aa", Util.replaceMacro("/$A/$B/$AA",m));
2934
assertEquals("a-aa", Util.replaceMacro("$A-$AA",m));
3035
assertEquals("/a/foo/can/B/you-believe_aa~it?", Util.replaceMacro("/$A/foo/can/$B/you-believe_$AA~it?",m));
36+
assertEquals("$$aa$Ba${A}$it", Util.replaceMacro("$$$DOLLAR${AA}$$B${ENCLOSED}$it",m));
3137
}
3238

3339

0 commit comments

Comments
 (0)