Add timeout to regex masking

This commit is contained in:
dordsor21 2021-09-18 15:01:09 +01:00
parent dbbb450172
commit 54398ebe1c
No known key found for this signature in database
GPG Key ID: 1E53E88969FFCF0B

View File

@ -30,6 +30,12 @@ import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import java.util.function.BiPredicate;
import java.util.function.Predicate;
import java.util.stream.Collectors;
@ -45,11 +51,16 @@ public class BlockMaskBuilder {
private static final Operator NOT = (a, b) -> a != b;
private static final long[] ALL = new long[0];
private final long[][] bitSets;
private boolean[] ordinals;
private boolean optimizedStates = true;
private interface Operator {
boolean test(int left, int right);
public BlockMaskBuilder() {
this(new long[BlockTypes.size()][]);
}
protected BlockMaskBuilder(long[][] bitSets) {
this.bitSets = bitSets;
}
private boolean filterRegex(BlockType blockType, PropertyKey key, String regex) {
@ -106,11 +117,13 @@ public class BlockMaskBuilder {
return result;
}
public BlockMaskBuilder addRegex(String input) throws InputParseException {
public BlockMaskBuilder addRegex(final String input) throws InputParseException {
ExecutorService executor = Executors.newSingleThreadExecutor();
Future<?> fut = executor.submit(() -> {
if (input.charAt(input.length() - 1) == ']') {
int propStart = StringMan.findMatchingBracket(input, input.length() - 1);
if (propStart == -1) {
return this;
return;
}
MutableCharSequence charSequence = MutableCharSequence.getTemporal();
@ -160,7 +173,11 @@ public class BlockMaskBuilder {
case ',': {
charSequence.setSubstring(last, i);
if (key == null && PropertyKey.getByName(charSequence) == null) {
suggest(input, charSequence.toString(), type != null ? Collections.singleton(type) : blockTypeList);
suggest(
input,
charSequence.toString(),
type != null ? Collections.singleton(type) : blockTypeList
);
}
if (operator == null) {
throw new SuggestInputParseException(
@ -258,6 +275,17 @@ public class BlockMaskBuilder {
}
}
}
});
try {
fut.get(5L, TimeUnit.MILLISECONDS);
} catch (ExecutionException e) {
if (e.getCause() instanceof InputParseException) {
throw (InputParseException) e.getCause();
}
} catch (InterruptedException | TimeoutException ignored) {
} finally {
executor.shutdown();
}
return this;
}
@ -282,25 +310,10 @@ public class BlockMaskBuilder {
});
}
///// end internal /////
private final long[][] bitSets;
private boolean[] ordinals;
private boolean optimizedStates = true;
public boolean isEmpty() {
return Arrays.stream(bitSets).noneMatch(Objects::nonNull);
}
public BlockMaskBuilder() {
this(new long[BlockTypes.size()][]);
}
protected BlockMaskBuilder(long[][] bitSets) {
this.bitSets = bitSets;
}
public BlockMaskBuilder addAll() {
Arrays.fill(bitSets, ALL);
reset(true);
@ -660,4 +673,10 @@ public class BlockMaskBuilder {
return new BlockMask(extent, getOrdinals());
}
private interface Operator {
boolean test(int left, int right);
}
}