From 13be09eaa80370d9af7bf2c599c0d83f81a62d93 Mon Sep 17 00:00:00 2001
From: Florian Kargl <f.kargl@posteo.de>
Date: Fri, 22 Oct 2021 13:43:01 +0200
Subject: [PATCH] Fix parsing of empty parenthesis pairs in search expressions

---
 .../josm/data/osm/search/SearchCompiler.java           |  2 +-
 .../josm/data/osm/search/SearchCompilerTest.java       | 10 ++++++++++
 2 files changed, 11 insertions(+), 1 deletion(-)

diff --git a/src/org/openstreetmap/josm/data/osm/search/SearchCompiler.java b/src/org/openstreetmap/josm/data/osm/search/SearchCompiler.java
index d299110d8b..0e6612d0d7 100644
--- a/src/org/openstreetmap/josm/data/osm/search/SearchCompiler.java
+++ b/src/org/openstreetmap/josm/data/osm/search/SearchCompiler.java
@@ -2128,7 +2128,7 @@ private Match parseFactor() throws SearchParseError {
             Match expression = parseExpression();
             if (!tokenizer.readIfEqual(Token.RIGHT_PARENT))
                 throw new SearchParseError(Token.RIGHT_PARENT, tokenizer.nextToken());
-            return expression;
+            return expression != null ? expression : Always.INSTANCE;
         } else if (tokenizer.readIfEqual(Token.NOT)) {
             return new Not(parseFactor(tr("Missing operator for NOT")));
         } else if (tokenizer.readIfEqual(Token.KEY)) {
diff --git a/test/unit/org/openstreetmap/josm/data/osm/search/SearchCompilerTest.java b/test/unit/org/openstreetmap/josm/data/osm/search/SearchCompilerTest.java
index d8d5b88dac..87ca23343e 100644
--- a/test/unit/org/openstreetmap/josm/data/osm/search/SearchCompilerTest.java
+++ b/test/unit/org/openstreetmap/josm/data/osm/search/SearchCompilerTest.java
@@ -840,4 +840,14 @@ void testRole() throws SearchParseError {
     void testNonRegression21300(final String searchString) {
         assertThrows(SearchParseError.class, () -> SearchCompiler.compile(searchString));
     }
+
+    /**
+     * Non-regression test for JOSM #21463
+     */
+    @Test
+    void testNonRegression21463() throws SearchParseError {
+        final SearchCompiler.Match c = SearchCompiler.compile("foo () () () bar");
+        assertTrue(c.match(OsmUtils.createPrimitive("node foo=bar")));
+        assertFalse(c.match(OsmUtils.createPrimitive("node name=bar")));
+    }
 }
