mirror of
https://github.com/TrianguloY/UrlChecker.git
synced 2024-09-19 20:02:16 +02:00
Pattern Checker: Fix optional groups giving a null instead of an empty string
Fixes #237
This commit is contained in:
parent
491cd17c64
commit
72f57e43d9
@ -1,5 +1,7 @@
|
||||
package com.trianguloy.urlchecker.modules.list;
|
||||
|
||||
import android.annotation.TargetApi;
|
||||
import android.os.Build;
|
||||
import android.view.View;
|
||||
import android.widget.Button;
|
||||
import android.widget.LinearLayout;
|
||||
@ -24,6 +26,7 @@ import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Random;
|
||||
import java.util.regex.Pattern;
|
||||
import java.util.regex.Matcher;
|
||||
|
||||
/**
|
||||
* This module checks for patterns characters in the url
|
||||
@ -122,7 +125,7 @@ class PatternDialog extends AModuleDialog {
|
||||
|
||||
// get regex (must exists)
|
||||
if (!data.has("regex")) continue;
|
||||
var regex = data.getString("regex");
|
||||
Pattern regex = Pattern.compile(data.getString("regex"));
|
||||
|
||||
// applied?
|
||||
message.applied = urlData.getData(APPLIED + pattern) != null;
|
||||
@ -130,7 +133,7 @@ class PatternDialog extends AModuleDialog {
|
||||
// check matches
|
||||
// if 'regexp' matches, the pattern can match
|
||||
// if 'regexp' doesn't match, the patter doesn't match
|
||||
var matches = Pattern.compile(regex).matcher(url).find();
|
||||
var matches = regex.matcher(url).find();
|
||||
if (matches && data.has("excludeRegex")) {
|
||||
// if 'excludeRegex' doesn't exist, the pattern can match
|
||||
// if 'excludeRegex' matches, the pattern doesn't matches
|
||||
@ -158,7 +161,7 @@ class PatternDialog extends AModuleDialog {
|
||||
|
||||
if (replacement != null) {
|
||||
// replace url
|
||||
message.newUrl = url.replaceAll(regex, replacement);
|
||||
message.newUrl = replaceAll(url, regex, replacement);
|
||||
|
||||
// automatic? apply
|
||||
if (data.optBoolean("automatic")) {
|
||||
@ -225,4 +228,100 @@ class PatternDialog extends AModuleDialog {
|
||||
this.pattern = pattern;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* On Android 10 and under, optional groups may yield a "null" in the replacement output instead of an empty string.
|
||||
* Therefore, we just copy the implementation from newer versions
|
||||
* https://github.com/TrianguloY/UrlChecker/issues/237
|
||||
*/
|
||||
private static String replaceAll(String text, Pattern pattern, String replacement) {
|
||||
// Copied from https://android.googlesource.com/platform/libcore/+/refs/heads/android13-release/ojluni/src/main/java/java/util/regex/Matcher.java#837
|
||||
Matcher matcher = pattern.matcher(text);
|
||||
boolean result = matcher.find();
|
||||
if (result) {
|
||||
StringBuffer sb = new StringBuffer();
|
||||
int appendPos = 0;
|
||||
do {
|
||||
appendPos = appendReplacement(text, matcher, sb, replacement, appendPos);
|
||||
result = matcher.find();
|
||||
} while (result);
|
||||
appendTail(text, sb, appendPos);
|
||||
return sb.toString();
|
||||
}
|
||||
return text.toString();
|
||||
}
|
||||
|
||||
private static int appendReplacement(String text, Matcher matcher, StringBuffer sb, String replacement, int appendPos) {
|
||||
// Copied from https://android.googlesource.com/platform/libcore/+/refs/heads/android13-release/ojluni/src/main/java/java/util/regex/Matcher.java#714
|
||||
sb.append(text.substring(appendPos, matcher.start()));
|
||||
appendEvaluated(matcher, sb, replacement);
|
||||
appendPos = matcher.end();
|
||||
|
||||
return appendPos;
|
||||
}
|
||||
|
||||
@TargetApi(Build.VERSION_CODES.O)
|
||||
private static void appendEvaluated(Matcher matcher, StringBuffer buffer, String s) {
|
||||
// Copied from https://android.googlesource.com/platform/libcore/+/refs/heads/android13-release/ojluni/src/main/java/java/util/regex/Matcher.java#731
|
||||
boolean escape = false;
|
||||
boolean dollar = false;
|
||||
boolean escapeNamedGroup = false;
|
||||
int escapeNamedGroupStart = -1;
|
||||
|
||||
for (int i = 0; i < s.length(); i++) {
|
||||
char c = s.charAt(i);
|
||||
if (c == '\\' && !escape) {
|
||||
escape = true;
|
||||
} else if (c == '$' && !escape) {
|
||||
dollar = true;
|
||||
} else if (c >= '0' && c <= '9' && dollar && !escapeNamedGroup) {
|
||||
String groupValue = matcher.group(c - '0');
|
||||
if (groupValue != null) {
|
||||
buffer.append(groupValue);
|
||||
}
|
||||
dollar = false;
|
||||
} else if (c == '{' && dollar) {
|
||||
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O) {
|
||||
throw new IllegalArgumentException("your android version does not support named-capturing groups");
|
||||
}
|
||||
escapeNamedGroup = true;
|
||||
escapeNamedGroupStart = i;
|
||||
} else if (c == '}' && dollar && escapeNamedGroup) {
|
||||
String groupValue = matcher.group(s.substring(escapeNamedGroupStart + 1, i));
|
||||
if (groupValue != null) {
|
||||
buffer.append(groupValue);
|
||||
}
|
||||
dollar = false;
|
||||
escapeNamedGroup = false;
|
||||
} else if (c != '}' && dollar && escapeNamedGroup) {
|
||||
continue;
|
||||
} else {
|
||||
buffer.append(c);
|
||||
dollar = false;
|
||||
escape = false;
|
||||
escapeNamedGroup = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (escape) {
|
||||
throw new IllegalArgumentException("character to be escaped is missing");
|
||||
}
|
||||
|
||||
if (dollar) {
|
||||
throw new IllegalArgumentException("Illegal group reference: group index is missing");
|
||||
}
|
||||
|
||||
if (escapeNamedGroup) {
|
||||
throw new IllegalArgumentException("Missing ending brace '}' from replacement string");
|
||||
}
|
||||
}
|
||||
|
||||
private static StringBuffer appendTail(String text, StringBuffer sb, int appendPos) {
|
||||
// Copied from https://android.googlesource.com/platform/libcore/+/refs/heads/android13-release/ojluni/src/main/java/java/util/regex/Matcher.java#796
|
||||
int to = text.length();
|
||||
if (appendPos < to) {
|
||||
sb.append(text.substring(appendPos, to));
|
||||
}
|
||||
return sb;
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user