From 73f5fb9d7dc01dacbc45ff48fcb68ce35d6ba243 Mon Sep 17 00:00:00 2001 From: yahaha5788 Date: Sun, 30 Nov 2025 13:19:01 -0500 Subject: [PATCH 1/5] add logic to catch NPE thrown by Preconditions.checkNotNull called by LocalCache.getIfPresent on a null value --- .../additionallogistics/common/SafeRegex.java | 39 +++++++++++++++---- 1 file changed, 31 insertions(+), 8 deletions(-) diff --git a/src/main/java/dev/khloeleclair/create/additionallogistics/common/SafeRegex.java b/src/main/java/dev/khloeleclair/create/additionallogistics/common/SafeRegex.java index e887cb6..d6cdcac 100644 --- a/src/main/java/dev/khloeleclair/create/additionallogistics/common/SafeRegex.java +++ b/src/main/java/dev/khloeleclair/create/additionallogistics/common/SafeRegex.java @@ -69,9 +69,15 @@ public boolean isError() { public static void assertReplacementSafe(@NotNull String regex, @NotNull String replacement) { var key = ObjectObjectImmutablePair.of(regex, replacement); - CachedReplacementResult cached = REPLACEMENT_CACHE.getIfPresent(key); + CachedReplacementResult cached; - if (cached == null) { + try { + cached = REPLACEMENT_CACHE.getIfPresent(key); + + if (cached == null) { + throw new NullPointerException(); //see L176 + } + } catch (NullPointerException npe) { try { var rcache = processRegex(regex); if (rcache.isError()) @@ -156,8 +162,16 @@ public static void assertReplacementSafe(@NotNull String regex, @NotNull String @NotNull private static CachedRegexResult processRegex(@NotNull String regex) { - CachedRegexResult cached = REGEX_CACHE.getIfPresent(regex); - if (cached == null) { + CachedRegexResult cached; + try { + cached = REGEX_CACHE.getIfPresent(regex); + + if (cached == null) { + throw new NullPointerException(); + // direct a null result to the catch logic so that it doesn't have to be written twice (yes i know it's stupid but it looks nicer) + // basically keep the same logic for dealing with a null result but also use that logic for dealing with a null regex + } + } catch (NullPointerException npe) { try { var pattern = Pattern.compile(regex); @@ -170,7 +184,7 @@ private static CachedRegexResult processRegex(@NotNull String regex) { RegexTokenizer.visitNodes(node, x -> x instanceof RegexTokenizer.ReferenceNode) ); - } catch(PatternSyntaxException ex) { + } catch (PatternSyntaxException ex) { cached = new CachedRegexResult(ex); } @@ -218,13 +232,22 @@ public static boolean isSafe(String regex, int starHeightLimit, int repetitionLi } private static String cachedToRegexPattern(String address) { - var cached = GLOB_CACHE.getIfPresent(address); - if (cached == null) { + CachedGlobResult cached; + + try { + cached = GLOB_CACHE.getIfPresent(address); + + if (cached == null) { + throw new NullPointerException(); // see L176 + } + } catch (NullPointerException npe) { try { cached = new CachedGlobResult(Glob.toRegexPattern(address), null); - } catch(PatternSyntaxException ex) { + + } catch (PatternSyntaxException ex) { cached = new CachedGlobResult(null, ex); } + GLOB_CACHE.put(address, cached); } From 31454359cccab88e44789d30dc7cbe56f5c272a2 Mon Sep 17 00:00:00 2001 From: yahaha5788 Date: Sun, 30 Nov 2025 13:28:15 -0500 Subject: [PATCH 2/5] removed unnecessary logic in assertReplacementSafe (oops) --- .../create/additionallogistics/common/SafeRegex.java | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/src/main/java/dev/khloeleclair/create/additionallogistics/common/SafeRegex.java b/src/main/java/dev/khloeleclair/create/additionallogistics/common/SafeRegex.java index d6cdcac..0e51013 100644 --- a/src/main/java/dev/khloeleclair/create/additionallogistics/common/SafeRegex.java +++ b/src/main/java/dev/khloeleclair/create/additionallogistics/common/SafeRegex.java @@ -69,15 +69,9 @@ public boolean isError() { public static void assertReplacementSafe(@NotNull String regex, @NotNull String replacement) { var key = ObjectObjectImmutablePair.of(regex, replacement); - CachedReplacementResult cached; + CachedReplacementResult cached = REPLACEMENT_CACHE.getIfPresent(key); - try { - cached = REPLACEMENT_CACHE.getIfPresent(key); - - if (cached == null) { - throw new NullPointerException(); //see L176 - } - } catch (NullPointerException npe) { + if (cached == null) { try { var rcache = processRegex(regex); if (rcache.isError()) From caad6af625a0c148d8b91e5edaf671473fb79474 Mon Sep 17 00:00:00 2001 From: yahaha5788 Date: Sun, 30 Nov 2025 15:48:39 -0500 Subject: [PATCH 3/5] ngl should've just done this in the first place --- .../additionallogistics/common/SafeRegex.java | 23 ++++++++----------- 1 file changed, 9 insertions(+), 14 deletions(-) diff --git a/src/main/java/dev/khloeleclair/create/additionallogistics/common/SafeRegex.java b/src/main/java/dev/khloeleclair/create/additionallogistics/common/SafeRegex.java index 0e51013..76eac6a 100644 --- a/src/main/java/dev/khloeleclair/create/additionallogistics/common/SafeRegex.java +++ b/src/main/java/dev/khloeleclair/create/additionallogistics/common/SafeRegex.java @@ -156,16 +156,13 @@ public static void assertReplacementSafe(@NotNull String regex, @NotNull String @NotNull private static CachedRegexResult processRegex(@NotNull String regex) { - CachedRegexResult cached; - try { + CachedRegexResult cached = null; + + if (regex != null) { cached = REGEX_CACHE.getIfPresent(regex); + } - if (cached == null) { - throw new NullPointerException(); - // direct a null result to the catch logic so that it doesn't have to be written twice (yes i know it's stupid but it looks nicer) - // basically keep the same logic for dealing with a null result but also use that logic for dealing with a null regex - } - } catch (NullPointerException npe) { + if (cached == null) { try { var pattern = Pattern.compile(regex); @@ -226,15 +223,13 @@ public static boolean isSafe(String regex, int starHeightLimit, int repetitionLi } private static String cachedToRegexPattern(String address) { - CachedGlobResult cached; + CachedGlobResult cached = null; - try { + if (address != null) { cached = GLOB_CACHE.getIfPresent(address); + } - if (cached == null) { - throw new NullPointerException(); // see L176 - } - } catch (NullPointerException npe) { + if (cached == null) { try { cached = new CachedGlobResult(Glob.toRegexPattern(address), null); From 64501939ea9128eb6261f03005c2eb0e4b9daab5 Mon Sep 17 00:00:00 2001 From: yahaha5788 Date: Mon, 1 Dec 2025 16:30:19 -0500 Subject: [PATCH 4/5] final fixes i think --- .../create/additionallogistics/common/SafeRegex.java | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/src/main/java/dev/khloeleclair/create/additionallogistics/common/SafeRegex.java b/src/main/java/dev/khloeleclair/create/additionallogistics/common/SafeRegex.java index 76eac6a..c48ad07 100644 --- a/src/main/java/dev/khloeleclair/create/additionallogistics/common/SafeRegex.java +++ b/src/main/java/dev/khloeleclair/create/additionallogistics/common/SafeRegex.java @@ -177,9 +177,13 @@ private static CachedRegexResult processRegex(@NotNull String regex) { } catch (PatternSyntaxException ex) { cached = new CachedRegexResult(ex); + } catch (NullPointerException ex) { + cached = new CachedRegexResult(new PatternSyntaxException("the regex is a lie (regex is null)", "there is no regex", -1)); } - REGEX_CACHE.put(regex, cached); + if (regex != null) { + REGEX_CACHE.put(regex, cached); + } } return cached; @@ -235,9 +239,13 @@ private static String cachedToRegexPattern(String address) { } catch (PatternSyntaxException ex) { cached = new CachedGlobResult(null, ex); + } catch (NullPointerException npe) { + cached = new CachedGlobResult(null, new PatternSyntaxException("address is null", "no", -1)); // uh idk the best way to handle this } - GLOB_CACHE.put(address, cached); + if (address != null) { + GLOB_CACHE.put(address, cached); + } } return cached.regex; From 5d89b4aefd6527098e69a04c37831c4afac0d959 Mon Sep 17 00:00:00 2001 From: yahaha5788 Date: Tue, 2 Dec 2025 15:16:51 -0500 Subject: [PATCH 5/5] revert and fix for better logic (thanks) --- .../additionallogistics/common/SafeRegex.java | 55 +++++++++---------- 1 file changed, 27 insertions(+), 28 deletions(-) diff --git a/src/main/java/dev/khloeleclair/create/additionallogistics/common/SafeRegex.java b/src/main/java/dev/khloeleclair/create/additionallogistics/common/SafeRegex.java index c48ad07..fe10670 100644 --- a/src/main/java/dev/khloeleclair/create/additionallogistics/common/SafeRegex.java +++ b/src/main/java/dev/khloeleclair/create/additionallogistics/common/SafeRegex.java @@ -31,7 +31,11 @@ public class SafeRegex { .build(); - private record CachedGlobResult(@Nullable String regex, @Nullable PatternSyntaxException error) {} + private record CachedGlobResult(@Nullable String regex, @Nullable PatternSyntaxException error) { + public boolean isError() { + return this.error != null; + } + } private record CachedReplacementResult(@Nullable PatternSyntaxException error) { boolean isError() { return this.error != null; } @@ -155,13 +159,23 @@ public static void assertReplacementSafe(@NotNull String regex, @NotNull String } @NotNull - private static CachedRegexResult processRegex(@NotNull String regex) { - CachedRegexResult cached = null; + private static CachedRegexResult processRegex(@NotNull CachedGlobResult cachedResult) { + CachedRegexResult cached; + + if (cachedResult.isError()) { // return a cached regex result with the error from cachedResult + cached = new CachedRegexResult(cachedResult.error); + } else { + String regex = cachedResult.regex; - if (regex != null) { - cached = REGEX_CACHE.getIfPresent(regex); + cached = processRegex(regex); } + return cached; + } + + @NotNull + private static CachedRegexResult processRegex(@NotNull String regex) { + CachedRegexResult cached = REGEX_CACHE.getIfPresent(regex); if (cached == null) { try { var pattern = Pattern.compile(regex); @@ -175,15 +189,11 @@ private static CachedRegexResult processRegex(@NotNull String regex) { RegexTokenizer.visitNodes(node, x -> x instanceof RegexTokenizer.ReferenceNode) ); - } catch (PatternSyntaxException ex) { + } catch(PatternSyntaxException ex) { cached = new CachedRegexResult(ex); - } catch (NullPointerException ex) { - cached = new CachedRegexResult(new PatternSyntaxException("the regex is a lie (regex is null)", "there is no regex", -1)); } - if (regex != null) { - REGEX_CACHE.put(regex, cached); - } + REGEX_CACHE.put(regex, cached); } return cached; @@ -226,29 +236,18 @@ public static boolean isSafe(String regex, int starHeightLimit, int repetitionLi } - private static String cachedToRegexPattern(String address) { - CachedGlobResult cached = null; - - if (address != null) { - cached = GLOB_CACHE.getIfPresent(address); - } - + private static CachedGlobResult cachedToRegexPattern(String address) { + var cached = GLOB_CACHE.getIfPresent(address); if (cached == null) { try { cached = new CachedGlobResult(Glob.toRegexPattern(address), null); - - } catch (PatternSyntaxException ex) { + } catch(PatternSyntaxException ex) { cached = new CachedGlobResult(null, ex); - } catch (NullPointerException npe) { - cached = new CachedGlobResult(null, new PatternSyntaxException("address is null", "no", -1)); // uh idk the best way to handle this - } - - if (address != null) { - GLOB_CACHE.put(address, cached); } + GLOB_CACHE.put(address, cached); } - return cached.regex; + return cached; } /// An optimized version of PackageItem.matchAddress that uses caching and optimized logic. @@ -281,4 +280,4 @@ else if (info.pattern != null && info.pattern.matcher(address).matches()) return false; } -} +} \ No newline at end of file