Ticket #21300: 21300.patch

File 21300.patch, 6.0 KB (added by taylor.smock, 5 years ago)

Add validate function to Match to ensure that all required information is present. Currently only overriden in ValueComparison.

  • src/org/openstreetmap/josm/data/osm/search/SearchCompiler.java

    diff --git a/src/org/openstreetmap/josm/data/osm/search/SearchCompiler.java b/src/org/openstreetmap/josm/data/osm/search/SearchCompiler.java
    index c5b17638f1..ca5773ef0b 100644
    a b public class SearchCompiler {  
    290290        public final boolean test(OsmPrimitive object) {
    291291            return match(object);
    292292        }
     293
     294        /**
     295         * Check if this is a valid match object
     296         * @return {@code this}, for easy chaining
     297         * @throws SearchParseError If the match is not valid
     298         */
     299        public Match validate() throws SearchParseError {
     300            // Default to no-op
     301            return this;
     302        }
    293303    }
    294304
    295305    public abstract static class TaggedMatch extends Match {
    public class SearchCompiler {  
    861871                return false;
    862872            return true;
    863873        }
     874
     875        @Override
     876        public Match validate() throws SearchParseError {
     877            if (this.referenceValue == null) {
     878                throw new SearchParseError(tr("Reference value must not be null"));
     879            }
     880            return this;
     881        }
    864882    }
    865883
    866884    /**
    public class SearchCompiler {  
    21082126            // factor consists of key:value or key=value
    21092127            String key = tokenizer.getText();
    21102128            if (tokenizer.readIfEqual(Token.EQUALS)) {
    2111                 return new ExactKeyValue(regexSearch, caseSensitive, key, tokenizer.readTextOrNumber());
     2129                return new ExactKeyValue(regexSearch, caseSensitive, key, tokenizer.readTextOrNumber()).validate();
    21122130            } else if (tokenizer.readIfEqual(Token.TILDE)) {
    2113                 return new ExactKeyValue(true, caseSensitive, key, tokenizer.readTextOrNumber());
     2131                return new ExactKeyValue(true, caseSensitive, key, tokenizer.readTextOrNumber()).validate();
    21142132            } else if (tokenizer.readIfEqual(Token.LESS_THAN)) {
    2115                 return new ValueComparison(key, tokenizer.readTextOrNumber(), -1);
     2133                return new ValueComparison(key, tokenizer.readTextOrNumber(), -1).validate();
    21162134            } else if (tokenizer.readIfEqual(Token.GREATER_THAN)) {
    2117                 return new ValueComparison(key, tokenizer.readTextOrNumber(), +1);
     2135                return new ValueComparison(key, tokenizer.readTextOrNumber(), +1).validate();
    21182136            } else if (tokenizer.readIfEqual(Token.COLON)) {
    21192137                // see if we have a Match that takes a data parameter
    21202138                SimpleMatchFactory factory = simpleMatchFactoryMap.get(key);
    public class SearchCompiler {  
    21232141
    21242142                UnaryMatchFactory unaryFactory = unaryMatchFactoryMap.get(key);
    21252143                if (unaryFactory != null)
    2126                     return unaryFactory.get(key, parseFactor(), tokenizer);
     2144                    return unaryFactory.get(key, parseFactor(), tokenizer).validate();
    21272145
    21282146                // key:value form where value is a string (may be OSM key search)
    21292147                final String value = tokenizer.readTextOrNumber();
    2130                 return new KeyValue(key, value != null ? value : "", regexSearch, caseSensitive);
     2148                return new KeyValue(key, value != null ? value : "", regexSearch, caseSensitive).validate();
    21312149            } else if (tokenizer.readIfEqual(Token.QUESTION_MARK))
    21322150                return new BooleanMatch(key, false);
    21332151            else {
    21342152                SimpleMatchFactory factory = simpleMatchFactoryMap.get(key);
    21352153                if (factory != null)
    2136                     return factory.get(key, caseSensitive, regexSearch, null);
     2154                    return factory.get(key, caseSensitive, regexSearch, null).validate();
    21372155
    21382156                UnaryMatchFactory unaryFactory = unaryMatchFactoryMap.get(key);
    21392157                if (unaryFactory != null)
    2140                     return unaryFactory.get(key, parseFactor(), null);
     2158                    return unaryFactory.get(key, parseFactor(), null).validate();
    21412159
    21422160                // match string in any key or value
    2143                 return new Any(key, regexSearch, caseSensitive);
     2161                return new Any(key, regexSearch, caseSensitive).validate();
    21442162            }
    21452163        } else
    21462164            return null;
  • test/unit/org/openstreetmap/josm/data/osm/search/SearchCompilerTest.java

    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 9545c88cd7..1e34009fb6 100644
    a b import java.util.Collection;  
    1818import java.util.Collections;
    1919import java.util.Set;
    2020
     21import nl.jqno.equalsverifier.EqualsVerifier;
     22import nl.jqno.equalsverifier.Warning;
     23import org.junit.Assert;
     24import org.junit.jupiter.api.Test;
     25import org.junit.jupiter.api.Timeout;
     26import org.junit.jupiter.params.ParameterizedTest;
     27import org.junit.jupiter.params.provider.ValueSource;
    2128import org.openstreetmap.josm.TestUtils;
    2229import org.openstreetmap.josm.data.coor.LatLon;
    2330import org.openstreetmap.josm.data.osm.DataSet;
    import org.openstreetmap.josm.gui.tagging.presets.items.Key;  
    4249import org.openstreetmap.josm.testutils.annotations.BasicPreferences;
    4350import org.openstreetmap.josm.tools.Logging;
    4451
    45 import nl.jqno.equalsverifier.EqualsVerifier;
    46 import nl.jqno.equalsverifier.Warning;
    47 import org.junit.Assert;
    48 import org.junit.jupiter.api.Test;
    49 import org.junit.jupiter.api.Timeout;
    50 
    5152/**
    5253 * Unit tests for class {@link SearchCompiler}.
    5354 */
    class SearchCompilerTest {  
    828829        sc.match(sc.n1, true);
    829830        sc.match(sc.n2, false);
    830831    }
     832
     833    /**
     834     * Non-regression test for JOSM #21300
     835     */
     836    @ParameterizedTest
     837    @ValueSource(strings = {"maxweight<" /* #21300 */, "maxweight>"})
     838    void testNonRegression21300(final String searchString) {
     839        assertThrows(SearchParseError.class, () -> SearchCompiler.compile(searchString));
     840    }
    831841}