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.Map;
import java.util.Objects; import java.util.Objects;
import java.util.Set; 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.BiPredicate;
import java.util.function.Predicate; import java.util.function.Predicate;
import java.util.stream.Collectors; import java.util.stream.Collectors;
@ -45,11 +51,16 @@ public class BlockMaskBuilder {
private static final Operator NOT = (a, b) -> a != b; private static final Operator NOT = (a, b) -> a != b;
private static final long[] ALL = new long[0]; private static final long[] ALL = new long[0];
private final long[][] bitSets;
private boolean[] ordinals;
private boolean optimizedStates = true;
private interface Operator { public BlockMaskBuilder() {
this(new long[BlockTypes.size()][]);
boolean test(int left, int right); }
protected BlockMaskBuilder(long[][] bitSets) {
this.bitSets = bitSets;
} }
private boolean filterRegex(BlockType blockType, PropertyKey key, String regex) { private boolean filterRegex(BlockType blockType, PropertyKey key, String regex) {
@ -106,11 +117,13 @@ public class BlockMaskBuilder {
return result; 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) == ']') { if (input.charAt(input.length() - 1) == ']') {
int propStart = StringMan.findMatchingBracket(input, input.length() - 1); int propStart = StringMan.findMatchingBracket(input, input.length() - 1);
if (propStart == -1) { if (propStart == -1) {
return this; return;
} }
MutableCharSequence charSequence = MutableCharSequence.getTemporal(); MutableCharSequence charSequence = MutableCharSequence.getTemporal();
@ -160,7 +173,11 @@ public class BlockMaskBuilder {
case ',': { case ',': {
charSequence.setSubstring(last, i); charSequence.setSubstring(last, i);
if (key == null && PropertyKey.getByName(charSequence) == null) { 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) { if (operator == null) {
throw new SuggestInputParseException( 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; 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() { public boolean isEmpty() {
return Arrays.stream(bitSets).noneMatch(Objects::nonNull); return Arrays.stream(bitSets).noneMatch(Objects::nonNull);
} }
public BlockMaskBuilder() {
this(new long[BlockTypes.size()][]);
}
protected BlockMaskBuilder(long[][] bitSets) {
this.bitSets = bitSets;
}
public BlockMaskBuilder addAll() { public BlockMaskBuilder addAll() {
Arrays.fill(bitSets, ALL); Arrays.fill(bitSets, ALL);
reset(true); reset(true);
@ -660,4 +673,10 @@ public class BlockMaskBuilder {
return new BlockMask(extent, getOrdinals()); return new BlockMask(extent, getOrdinals());
} }
private interface Operator {
boolean test(int left, int right);
}
} }