Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
39 changes: 31 additions & 8 deletions Kitodo/src/main/java/org/kitodo/production/filters/FilterMenu.java
Original file line number Diff line number Diff line change
Expand Up @@ -162,21 +162,21 @@ public void updateSuggestions(String input) {
suggestions = createSuggestionsForProcessCategory(matcherNextCategory.group());
} else {
// process value should be suggested
Pattern patternPreviousCategory = Pattern.compile("\\w+:(?!.*:)");
Matcher matcherPreviousCategory = patternPreviousCategory.matcher(input);
String category = matcherPreviousCategory.find() ? matcherPreviousCategory.group() : "";
suggestions = createSuggestionsForProcessValue(checkFilterCategory(category, processCategories), lastPart);
suggestions = createSuggestionsForProcessValue(
checkFilterCategory(findSuggestionCategory(input), processCategories),
lastPart
);
}
} else if (Objects.nonNull(taskListView)) {
if (matcherNextCategory.find()) {
// strings ends with " | "
suggestions = createSuggestionsForTaskCategory(matcherNextCategory.group());
} else {
// process/task value should be suggested
Pattern patternPreviousCategory = Pattern.compile("\\w+:(?!.*:)");
Matcher matcherPreviousCategory = patternPreviousCategory.matcher(input);
String category = matcherPreviousCategory.find() ? matcherPreviousCategory.group() : "";
suggestions = createSuggestionsForTaskValue(checkFilterCategory(category, taskCategories), lastPart);
suggestions = createSuggestionsForTaskValue(
checkFilterCategory(findSuggestionCategory(input), taskCategories),
lastPart
);
}
} else if (Objects.nonNull(userListView)) {
if (matcherNextCategory.find()) {
Expand All @@ -187,6 +187,29 @@ public void updateSuggestions(String input) {
}
}

/**
* Return the last category in the filter string that is used for displaying suggestions.
*
* <p>Does not use regular expression matching with negative lookahead to prevent possible
* denial of service attack from user input. Instead, split input at colon symbol by adding
* space at the end such that the potential category is always split as the second last
* array element. Finally, finds last word in string by revesering it and finding first
* word instead, which has linear search complexity.
*
* @param input the filter string
* @return the last category in this filter string
*/
private String findSuggestionCategory(String input) {
//

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is a comment missing here? Otherwise "//" can go.

String[] colonSplit = (input + " ").split(":");
String secondLastSplit = colonSplit.length > 1 ? colonSplit[colonSplit.length - 2] : "";
// find the last word by reversing the string and finding the first word
String reversed = new StringBuilder(secondLastSplit).reverse().toString();
Matcher firstWordMatcher = Pattern.compile("^\\w+").matcher(reversed);
String firstReversedWord = firstWordMatcher.find() ? ":" + firstWordMatcher.group() : "";
return new StringBuilder(firstReversedWord).reverse().toString();
}

private List<Suggestion> filterSuggestionsForCategory(String input, List<FilterString> suggestions) {
return suggestions.stream()
.filter(filterString -> filterString.getFilterEnglish().startsWith(input.toLowerCase())
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -69,10 +69,13 @@ private enum MetadataLevel {
/**
* This regular expression is used to search for placeholders that need to
* be replaced.
*
* <p>Uses regular expression possesive quantifier ++ in order to prevent
* possible denial of service attack from user input.
*/
private static final Pattern VARIABLE_FINDER_REGEX = Pattern.compile(
"(\\$?)\\((?:(prefs|processid|processtitle|projectid|stepid|stepname|generatorsource|generatorsourcepath|ocrdworkflowid)|"
+ "(?:(meta|process|product|template)\\.(?:(firstchild|topstruct)\\.)?([^)]+)|"
+ "(?:(meta|process|product|template)\\.(?:(firstchild|topstruct)\\.)?([^)]++)|"
+ "(?:(filename|basename|relativepath))))\\)");
/**
* The map is filled with replacement instructions that are required for
Expand Down
Loading