Changeset 18195 in josm


Ignore:
Timestamp:
2021-09-07T23:46:34+02:00 (3 years ago)
Author:
Don-vip
Message:

fix #21300 - NPE in search compiler (patch by taylor.smock)

Location:
trunk
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/org/openstreetmap/josm/data/osm/search/SearchCompiler.java

    r17787 r18195  
    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
     
    861871                return false;
    862872            return true;
     873        }
     874
     875        @Override
     876        public Match validate() throws SearchParseError {
     877            if (this.referenceValue == null) {
     878                final String referenceType;
     879                if (this.compareMode == +1) {
     880                    referenceType = ">";
     881                } else if (this.compareMode == -1) {
     882                    referenceType = "<";
     883                } else {
     884                    referenceType = "<unknown>";
     885                }
     886                throw new SearchParseError(tr("Reference value for ''{0}'' expected", referenceType));
     887            }
     888            return this;
    863889        }
    864890    }
     
    21092135            String key = tokenizer.getText();
    21102136            if (tokenizer.readIfEqual(Token.EQUALS)) {
    2111                 return new ExactKeyValue(regexSearch, caseSensitive, key, tokenizer.readTextOrNumber());
     2137                return new ExactKeyValue(regexSearch, caseSensitive, key, tokenizer.readTextOrNumber()).validate();
    21122138            } else if (tokenizer.readIfEqual(Token.TILDE)) {
    2113                 return new ExactKeyValue(true, caseSensitive, key, tokenizer.readTextOrNumber());
     2139                return new ExactKeyValue(true, caseSensitive, key, tokenizer.readTextOrNumber()).validate();
    21142140            } else if (tokenizer.readIfEqual(Token.LESS_THAN)) {
    2115                 return new ValueComparison(key, tokenizer.readTextOrNumber(), -1);
     2141                return new ValueComparison(key, tokenizer.readTextOrNumber(), -1).validate();
    21162142            } else if (tokenizer.readIfEqual(Token.GREATER_THAN)) {
    2117                 return new ValueComparison(key, tokenizer.readTextOrNumber(), +1);
     2143                return new ValueComparison(key, tokenizer.readTextOrNumber(), +1).validate();
    21182144            } else if (tokenizer.readIfEqual(Token.COLON)) {
    21192145                // see if we have a Match that takes a data parameter
     
    21242150                UnaryMatchFactory unaryFactory = unaryMatchFactoryMap.get(key);
    21252151                if (unaryFactory != null)
    2126                     return unaryFactory.get(key, parseFactor(), tokenizer);
     2152                    return unaryFactory.get(key, parseFactor(), tokenizer).validate();
    21272153
    21282154                // key:value form where value is a string (may be OSM key search)
    21292155                final String value = tokenizer.readTextOrNumber();
    2130                 return new KeyValue(key, value != null ? value : "", regexSearch, caseSensitive);
     2156                return new KeyValue(key, value != null ? value : "", regexSearch, caseSensitive).validate();
    21312157            } else if (tokenizer.readIfEqual(Token.QUESTION_MARK))
    21322158                return new BooleanMatch(key, false);
     
    21342160                SimpleMatchFactory factory = simpleMatchFactoryMap.get(key);
    21352161                if (factory != null)
    2136                     return factory.get(key, caseSensitive, regexSearch, null);
     2162                    return factory.get(key, caseSensitive, regexSearch, null).validate();
    21372163
    21382164                UnaryMatchFactory unaryFactory = unaryMatchFactoryMap.get(key);
    21392165                if (unaryFactory != null)
    2140                     return unaryFactory.get(key, parseFactor(), null);
     2166                    return unaryFactory.get(key, parseFactor(), null).validate();
    21412167
    21422168                // match string in any key or value
    2143                 return new Any(key, regexSearch, caseSensitive);
     2169                return new Any(key, regexSearch, caseSensitive).validate();
    21442170            }
    21452171        } else
  • trunk/test/unit/org/openstreetmap/josm/data/osm/search/SearchCompilerTest.java

    r18037 r18195  
    1919import java.util.Set;
    2020
     21import org.junit.Assert;
     22import org.junit.jupiter.api.Test;
     23import org.junit.jupiter.api.Timeout;
     24import org.junit.jupiter.params.ParameterizedTest;
     25import org.junit.jupiter.params.provider.ValueSource;
    2126import org.openstreetmap.josm.TestUtils;
    2227import org.openstreetmap.josm.data.coor.LatLon;
     
    4550import nl.jqno.equalsverifier.EqualsVerifier;
    4651import nl.jqno.equalsverifier.Warning;
    47 import org.junit.Assert;
    48 import org.junit.jupiter.api.Test;
    49 import org.junit.jupiter.api.Timeout;
    5052
    5153/**
     
    145147     */
    146148    @Test
    147     void testRegexpCaseSensitive() throws Exception {
     149    void testRegexpCaseSensitive() throws SearchParseError {
    148150        SearchSetting searchSetting = new SearchSetting();
    149151        searchSetting.regexSearch = true;
     
    829831        sc.match(sc.n2, false);
    830832    }
     833
     834    /**
     835     * Non-regression test for JOSM #21300
     836     * @param searchString search string to test
     837     */
     838    @ParameterizedTest
     839    @ValueSource(strings = {"maxweight<" /* #21300 */, "maxweight>"})
     840    void testNonRegression21300(final String searchString) {
     841        assertThrows(SearchParseError.class, () -> SearchCompiler.compile(searchString));
     842    }
    831843}
Note: See TracChangeset for help on using the changeset viewer.