Changeset 11014 in josm


Ignore:
Timestamp:
2016-09-17T21:57:10+02:00 (3 years ago)
Author:
Don-vip
Message:

fix #13630 - proper validation of invalid mapcss rules

Location:
trunk
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/org/openstreetmap/josm/data/validation/tests/MapCSSTagChecker.java

    r10921 r11014  
    301301                        continue;
    302302                    }
    303                     final String val = ai.val instanceof Expression
    304                             ? (String) ((Expression) ai.val).evaluate(new Environment())
    305                             : ai.val instanceof String
    306                             ? (String) ai.val
    307                             : ai.val instanceof Keyword
    308                             ? ((Keyword) ai.val).val
    309                             : null;
    310                     if (ai.key.startsWith("throw")) {
    311                         try {
    312                             final Severity severity = Severity.valueOf(ai.key.substring("throw".length()).toUpperCase(Locale.ENGLISH));
    313                             check.errors.put(ai, severity);
    314                         } catch (IllegalArgumentException e) {
    315                             Main.warn(e, "Unsupported "+ai.key+" instruction. Allowed instructions are "+POSSIBLE_THROWS+'.');
     303                    try {
     304                        final String val = ai.val instanceof Expression
     305                                ? (String) ((Expression) ai.val).evaluate(new Environment())
     306                                : ai.val instanceof String
     307                                ? (String) ai.val
     308                                : ai.val instanceof Keyword
     309                                ? ((Keyword) ai.val).val
     310                                : null;
     311                        if (ai.key.startsWith("throw")) {
     312                            try {
     313                                final Severity severity = Severity.valueOf(ai.key.substring("throw".length()).toUpperCase(Locale.ENGLISH));
     314                                check.errors.put(ai, severity);
     315                            } catch (IllegalArgumentException e) {
     316                                Main.warn(e, "Unsupported "+ai.key+" instruction. Allowed instructions are "+POSSIBLE_THROWS+'.');
     317                            }
     318                        } else if ("fixAdd".equals(ai.key)) {
     319                            check.fixCommands.add(FixCommand.fixAdd(ai.val));
     320                        } else if ("fixRemove".equals(ai.key)) {
     321                            CheckParameterUtil.ensureThat(!(ai.val instanceof String) || !(val != null && val.contains("=")),
     322                                    "Unexpected '='. Please only specify the key to remove!");
     323                            check.fixCommands.add(FixCommand.fixRemove(ai.val));
     324                        } else if ("fixChangeKey".equals(ai.key) && val != null) {
     325                            CheckParameterUtil.ensureThat(val.contains("=>"), "Separate old from new key by '=>'!");
     326                            final String[] x = val.split("=>", 2);
     327                            check.fixCommands.add(FixCommand.fixChangeKey(Tag.removeWhiteSpaces(x[0]), Tag.removeWhiteSpaces(x[1])));
     328                        } else if ("fixDeleteObject".equals(ai.key) && val != null) {
     329                            CheckParameterUtil.ensureThat("this".equals(val), "fixDeleteObject must be followed by 'this'");
     330                            check.deletion = true;
     331                        } else if ("suggestAlternative".equals(ai.key) && val != null) {
     332                            check.alternatives.add(val);
     333                        } else if ("assertMatch".equals(ai.key) && val != null) {
     334                            check.assertions.put(val, Boolean.TRUE);
     335                        } else if ("assertNoMatch".equals(ai.key) && val != null) {
     336                            check.assertions.put(val, Boolean.FALSE);
     337                        } else if ("group".equals(ai.key) && val != null) {
     338                            check.group = val;
     339                        } else {
     340                            throw new IllegalDataException("Cannot add instruction " + ai.key + ": " + ai.val + '!');
    316341                        }
    317                     } else if ("fixAdd".equals(ai.key)) {
    318                         check.fixCommands.add(FixCommand.fixAdd(ai.val));
    319                     } else if ("fixRemove".equals(ai.key)) {
    320                         CheckParameterUtil.ensureThat(!(ai.val instanceof String) || !(val != null && val.contains("=")),
    321                                 "Unexpected '='. Please only specify the key to remove!");
    322                         check.fixCommands.add(FixCommand.fixRemove(ai.val));
    323                     } else if ("fixChangeKey".equals(ai.key) && val != null) {
    324                         CheckParameterUtil.ensureThat(val.contains("=>"), "Separate old from new key by '=>'!");
    325                         final String[] x = val.split("=>", 2);
    326                         check.fixCommands.add(FixCommand.fixChangeKey(Tag.removeWhiteSpaces(x[0]), Tag.removeWhiteSpaces(x[1])));
    327                     } else if ("fixDeleteObject".equals(ai.key) && val != null) {
    328                         CheckParameterUtil.ensureThat("this".equals(val), "fixDeleteObject must be followed by 'this'");
    329                         check.deletion = true;
    330                     } else if ("suggestAlternative".equals(ai.key) && val != null) {
    331                         check.alternatives.add(val);
    332                     } else if ("assertMatch".equals(ai.key) && val != null) {
    333                         check.assertions.put(val, Boolean.TRUE);
    334                     } else if ("assertNoMatch".equals(ai.key) && val != null) {
    335                         check.assertions.put(val, Boolean.FALSE);
    336                     } else if ("group".equals(ai.key) && val != null) {
    337                         check.group = val;
    338                     } else {
    339                         throw new IllegalDataException("Cannot add instruction " + ai.key + ": " + ai.val + '!');
     342                    } catch (IllegalArgumentException e) {
     343                        throw new IllegalDataException(e);
    340344                    }
    341345                }
     
    357361            final MapCSSStyleSource source = new MapCSSStyleSource("");
    358362            final MapCSSParser preprocessor = new MapCSSParser(css, MapCSSParser.LexicalState.PREPROCESSOR);
    359 
    360             css = new StringReader(preprocessor.pp_root(source));
    361             final MapCSSParser parser = new MapCSSParser(css, MapCSSParser.LexicalState.DEFAULT);
     363            final StringReader mapcss = new StringReader(preprocessor.pp_root(source));
     364            final MapCSSParser parser = new MapCSSParser(mapcss, MapCSSParser.LexicalState.DEFAULT);
    362365            parser.sheet(source);
    363             Collection<Throwable> parseErrors = source.getErrors();
    364             assert parseErrors.isEmpty();
    365366            // Ignore "meta" rule(s) from external rules of JOSM wiki
    366367            removeMetaRules(source);
     
    383384                } catch (IllegalDataException e) {
    384385                    Main.error("Cannot add MapCss rule: "+e.getMessage());
    385                     parseErrors.add(e);
    386                 }
    387             }
    388             return new ParseResult(parseChecks, parseErrors);
     386                    source.logError(e);
     387                }
     388            }
     389            return new ParseResult(parseChecks, source.getErrors());
    389390        }
    390391
  • trunk/test/unit/org/openstreetmap/josm/data/validation/tests/MapCSSTagCheckerTest.java

    r10945 r11014  
    5252    }
    5353
     54    /**
     55     * Test {@code natural=marsh}.
     56     * @throws ParseException if a parsing error occurs
     57     */
    5458    @Test
    55     public void testNaturalMarsh() throws Exception {
    56         ParseResult result = MapCSSTagChecker.TagCheck.readMapCSS(new StringReader("" +
     59    public void testNaturalMarsh() throws ParseException {
     60        ParseResult result = MapCSSTagChecker.TagCheck.readMapCSS(new StringReader(
    5761                "*[natural=marsh] {\n" +
    5862                "   group: tr(\"deprecated\");\n" +
     
    8690    }
    8791
     92    /**
     93     * Non-regression test for <a href="https://josm.openstreetmap.de/ticket/10913">Bug #10913</a>.
     94     * @throws ParseException if a parsing error occurs
     95     */
    8896    @Test
    89     public void testTicket10913() throws Exception {
     97    public void testTicket10913() throws ParseException {
    9098        final OsmPrimitive p = OsmUtils.createPrimitive("way highway=tertiary construction=yes");
    9199        final TagCheck check = TagCheck.readMapCSS(new StringReader("way {" +
     
    101109    }
    102110
     111    /**
     112     * Non-regression test for <a href="https://josm.openstreetmap.de/ticket/9782">Bug #9782</a>.
     113     * @throws ParseException if a parsing error occurs
     114     */
    103115    @Test
    104     public void testTicket9782() throws Exception {
     116    public void testTicket9782() throws ParseException {
    105117        final MapCSSTagChecker test = buildTagChecker("*[/.+_name/][!name] {" +
    106118                "throwWarning: tr(\"has {0} but not {1}\", \"{0.key}\", \"{1.key}\");}");
     
    112124    }
    113125
     126    /**
     127     * Non-regression test for <a href="https://josm.openstreetmap.de/ticket/10859">Bug #10859</a>.
     128     * @throws ParseException if a parsing error occurs
     129     */
    114130    @Test
    115     public void testTicket10859() throws Exception {
     131    public void testTicket10859() throws ParseException {
    116132        final MapCSSTagChecker test = buildTagChecker("way[highway=footway][foot?!] {\n" +
    117133                "  throwWarning: tr(\"{0} used with {1}\", \"{0.value}\", \"{1.tag}\");}");
     
    123139    }
    124140
     141    /**
     142     * Non-regression test for <a href="https://josm.openstreetmap.de/ticket/13630">Bug #13630</a>.
     143     * @throws ParseException if a parsing error occurs
     144     */
    125145    @Test
    126     public void testPreprocessing() throws Exception {
     146    public void testTicket13630() throws ParseException {
     147        ParseResult result = MapCSSTagChecker.TagCheck.readMapCSS(new StringReader(
     148                "node[crossing=zebra] {fixRemove: \"crossing=zebra\";}"));
     149        assertTrue(result.parseChecks.isEmpty());
     150        assertEquals(1, result.parseErrors.size());
     151    }
     152
     153    @Test
     154    public void testPreprocessing() throws ParseException {
    127155        final MapCSSTagChecker test = buildTagChecker("" +
    128156                "@supports (min-josm-version: 1) { *[foo] { throwWarning: \"!\"; } }\n" +
Note: See TracChangeset for help on using the changeset viewer.