Skip to content

Commit a85c4d3

Browse files
committed
[GR-54974] Escape possible future wildcards in globs
PullRequest: graal/18164
2 parents dce9001 + 4254a0a commit a85c4d3

File tree

3 files changed

+45
-5
lines changed

3 files changed

+45
-5
lines changed

substratevm/src/com.oracle.svm.configure/src/com/oracle/svm/configure/config/ResourceConfiguration.java

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@
4848
import com.oracle.svm.core.configure.ConfigurationParser;
4949
import com.oracle.svm.core.configure.ResourceConfigurationParser;
5050
import com.oracle.svm.core.configure.ResourcesRegistry;
51+
import com.oracle.svm.core.jdk.resources.CompressedGlobTrie.GlobUtils;
5152
import com.oracle.svm.core.util.VMError;
5253

5354
import jdk.graal.compiler.util.json.JsonPrinter;
@@ -209,12 +210,21 @@ public void addResourcePattern(UnresolvedConfigurationCondition condition, Strin
209210
}
210211

211212
public void addGlobPattern(UnresolvedConfigurationCondition condition, String pattern, String module) {
212-
ResourceEntry element = new ResourceEntry(pattern, module);
213+
ResourceEntry element = new ResourceEntry(escapePossibleGlobWildcards(pattern), module);
213214
addedGlobs.add(new ConditionalElement<>(condition, element));
214215
}
215216

216-
private static String unquotePattern(String pattern) {
217-
return pattern.replace("\\Q", "").replace("\\E", "");
217+
private static String escapePossibleGlobWildcards(String pattern) {
218+
String escapedPattern = pattern;
219+
for (char wildcard : GlobUtils.ALWAYS_ESCAPED_GLOB_WILDCARDS) {
220+
escapedPattern = escapedPattern.replace(String.valueOf(wildcard), "\\" + wildcard);
221+
}
222+
223+
return escapedPattern;
224+
}
225+
226+
private static String convertSimpleRegexToGlob(String pattern) {
227+
return escapePossibleGlobWildcards(pattern.replace("\\Q", "").replace("\\E", ""));
218228
}
219229

220230
private static boolean isModuleIdentifierChar(int c) {
@@ -255,7 +265,7 @@ private static boolean isSimpleQuotedPattern(String pattern) {
255265
private void classifyAndAddPattern(ConditionalElement<String> entry) {
256266
String pattern = entry.element();
257267
if (isSimpleQuotedPattern(pattern)) {
258-
String unquotedPattern = unquotePattern(pattern);
268+
String unquotedPattern = convertSimpleRegexToGlob(pattern);
259269
String module = null;
260270
int moduleSplitter = pattern.indexOf(':');
261271
if (moduleSplitter != -1) {

substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jdk/resources/CompressedGlobTrie/CompressedGlobTrie.java

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -127,8 +127,22 @@ public static GlobTrieNode build(List<GlobWithInfo> patterns) {
127127
return root;
128128
}
129129

130+
/*
131+
* this function should be called only when we are certain that all possible wildcards are
132+
* actually escaped (i.e. only after validatePattern function)
133+
*/
134+
private static String unescapePossibleWildcards(String pattern) {
135+
String unescapedPattern = pattern;
136+
for (char esc : GlobUtils.ALWAYS_ESCAPED_GLOB_WILDCARDS) {
137+
unescapedPattern = unescapedPattern.replace("\\" + esc, String.valueOf(esc));
138+
}
139+
140+
return unescapedPattern;
141+
}
142+
130143
private static void addPattern(GlobTrieNode root, GlobWithInfo pattern) {
131-
List<GlobTrieNode> parts = getPatternParts(pattern.pattern());
144+
String unescapedPattern = unescapePossibleWildcards(pattern.pattern());
145+
List<GlobTrieNode> parts = getPatternParts(unescapedPattern);
132146

133147
/*
134148
* if this pattern can be matched with some other existing pattern, we should just
@@ -384,6 +398,17 @@ public static String validatePattern(String pattern) {
384398
sb.append("Pattern contains invalid sequence **/**. Valid pattern should have ** followed by something other than **. ");
385399
}
386400

401+
/* check if there are unescaped wildcards */
402+
boolean escapeMode = false;
403+
for (int i = 0; i < pattern.length(); i++) {
404+
char current = pattern.charAt(i);
405+
if (GlobUtils.ALWAYS_ESCAPED_GLOB_WILDCARDS.contains(current) && !escapeMode) {
406+
sb.append("Pattern contains unescaped character ").append(current).append(". ");
407+
}
408+
409+
escapeMode = current == '\\';
410+
}
411+
387412
// check if pattern contains ** without previous Literal parent. Example: */**/... or **/...
388413
List<GlobTrieNode> patternParts = getPatternParts(pattern);
389414
for (GlobTrieNode part : patternParts) {

substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jdk/resources/CompressedGlobTrie/GlobUtils.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,10 +25,15 @@
2525

2626
package com.oracle.svm.core.jdk.resources.CompressedGlobTrie;
2727

28+
import java.util.List;
29+
2830
import com.oracle.svm.util.StringUtil;
2931

3032
public class GlobUtils {
3133

34+
/* list of glob wildcards we are always escaping because they are not supported yet */
35+
public static final List<Character> ALWAYS_ESCAPED_GLOB_WILDCARDS = List.of('?', '[', ']', '{', '}');
36+
3237
public static String transformToTriePath(String resource, String module) {
3338
String resolvedModuleName;
3439
if (module == null || module.isEmpty()) {

0 commit comments

Comments
 (0)