Changeset 19571 in josm


Ignore:
Timestamp:
2026-05-07T15:11:23+02:00 (2 days ago)
Author:
stoecker
Message:

fix #14490 - patch by ToniE - Support for escaping pipe character in remote control addtags parameters

Location:
trunk
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/org/openstreetmap/josm/io/remotecontrol/AddTagsDialog.java

    r19101 r19571  
    284284     */
    285285    public static Map<String, String> parseUrlTagsToKeyValues(String urlSection) {
    286         Map<String, String> tags = TextTagParser.readTagsByRegexp(urlSection, "\\|", "(.*?)=(.*?)", false);
     286        Map<String, String> tags = TextTagParser.readTagsByRegexp(urlSection, "(?<!\\\\)\\|", "(.*?)=(.*?)", false, true);
    287287        return tags == null ? Collections.emptyMap() : tags;
    288288    }
  • trunk/src/org/openstreetmap/josm/tools/TextTagParser.java

    r19437 r19571  
    4747     * @param tagRegex - each part is matched against this regex
    4848     * @param unescapeTextInQuotes - if true, matched tag and value will be analyzed more thoroughly
     49     * @param unescapePipe - if true, then replace all '\|' by '|' (issue #14490)
    4950     * @return map of tags
     51     * @since 19570 (parameter unescapePipe added)
    5052     */
    51     public static Map<String, String> readTagsByRegexp(String text, String splitRegex, String tagRegex, boolean unescapeTextInQuotes) {
    52          String[] lines = text.split(splitRegex, -1);
    53          Pattern p = Pattern.compile(tagRegex);
    54          Map<String, String> tags = new LinkedHashMap<>();
    55          String k;
    56          String v;
    57          for (String line: lines) {
     53    public static Map<String, String> readTagsByRegexp(String text, String splitRegex, String tagRegex,
     54            boolean unescapeTextInQuotes, boolean unescapePipe) {
     55        String[] lines = text.split(splitRegex, -1);
     56        Pattern p = Pattern.compile(tagRegex);
     57        Map<String, String> tags = new LinkedHashMap<>();
     58        String k;
     59        String v;
     60        for (String line: lines) {
    5861            if (line.trim().isEmpty()) continue; // skip empty lines
    5962            Matcher m = p.matcher(line);
     
    6669                     if (k == null || v == null) return null;
    6770                 }
     71                 if (unescapePipe) {
     72                     k = k.replaceAll("\\\\\\|", "|");
     73                     v = v.replaceAll("\\\\\\|", "|");
     74                 }
    6875                 tags.put(k, v);
    6976            } else {
    7077                return null;
    7178            }
    72          }
    73          if (!tags.isEmpty()) {
    74             return tags;
    75          } else {
    76             return null;
    77          }
     79        }
     80        if (!tags.isEmpty()) {
     81           return tags;
     82        } else {
     83           return null;
     84        }
    7885    }
    7986
     
    100107        // Format
    101108        // tag1\tval1\ntag2\tval2\n
    102         tags = readTagsByRegexp(buf, "[\\r\\n]+", ".*?([a-zA-Z0-9:_]+).*\\t(.*?)", false);
     109        tags = readTagsByRegexp(buf, "[\\r\\n]+", ".*?([a-zA-Z0-9:_]+).*\\t(.*?)", false, false);
    103110        // try "tag\tvalue\n" format
    104111        if (tags != null) return tags;
     
    109116        // a = "b=c" is OK
    110117        // a = b=c  - this method of parsing fails intentionally
    111         tags = readTagsByRegexp(buf, "[\\n\\t\\r]+", "(.*?)=(.*?)", true);
     118        tags = readTagsByRegexp(buf, "[\\n\\t\\r]+", "(.*?)=(.*?)", true, false);
    112119        // try format  t1=v1\n t2=v2\n ...
    113120        if (tags != null) return tags;
     
    119126            bufJson = bufJson.substring(1, bufJson.length()-1);
    120127        tags = readTagsByRegexp(bufJson, "[\\s]*,[\\s]*",
    121                 "[\\s]*(\\\".*?[^\\\\]\\\")"+"[\\s]*:[\\s]*"+"(\\\".*?[^\\\\]\\\")[\\s]*", true);
     128                "[\\s]*(\\\".*?[^\\\\]\\\")"+"[\\s]*:[\\s]*"+"(\\\".*?[^\\\\]\\\")[\\s]*", true, false);
    122129        if (tags != null) return tags;
    123130
  • trunk/test/unit/org/openstreetmap/josm/io/remotecontrol/AddTagsDialogTest.java

    r19519 r19571  
    2424        assertEquals("Dresden Castle", strings.get("name:en"));
    2525    }
     26
     27    /**
     28     * Unit test for issue #14490 "Support for escaping pipe character in remote control addtags parameters"
     29     * A single URL section (value of addtags=...) with a single escaped pipe sysmbol
     30     */
     31    @Test
     32    void testParseUrlTagsToKeyValues_OneKeyValuePair_OneEscapedPipe() {
     33        Map<String, String> strings = AddTagsDialog.parseUrlTagsToKeyValues("gtfs:route_id=de:mvv-muenchen:19-210\\|210");
     34        assertEquals(1, strings.size());
     35        assertEquals("de:mvv-muenchen:19-210|210", strings.get("gtfs:route_id"));
     36    }
     37
     38    /**
     39     * Unit test for issue #14490 "Support for escaping pipe character in remote control addtags parameters"
     40     * A single URL section (value of addtags=...) with two escaped pipe sysmbols
     41     */
     42    @Test
     43    void testParseUrlTagsToKeyValues_OneKeyValuePair_TwoEscapedPipe() {
     44        Map<String, String> strings = AddTagsDialog.parseUrlTagsToKeyValues("gtfs:route_id=de:mvv-muenchen:19-210\\|210\\|RegionalBus:1179_3");
     45        assertEquals(1, strings.size());
     46        assertEquals("de:mvv-muenchen:19-210|210|RegionalBus:1179_3", strings.get("gtfs:route_id"));
     47    }
     48
     49    /**
     50     * Unit test for issue #14490 "Support for escaping pipe character in remote control addtags parameters"
     51     * Two URL sections (values of addtags=...) with two escaped pipe sysmbols each
     52     */
     53    @Test
     54    void testParseUrlTagsToKeyValues_TwoKeyValuePairs_FourEscapedPipe() {
     55        Map<String, String> strings = AddTagsDialog.parseUrlTagsToKeyValues("gtfs:route_id=de:mvv-muenchen:19-210\\|210\\|"
     56        + "RegionalBus:1179_3|gtfs:trip_id:sample=de:mvv-muenchen:19-210\\|210\\|RegionalBus:1179-1-1-H-0-We#3-320-333");
     57        assertEquals(2, strings.size());
     58        assertEquals("de:mvv-muenchen:19-210|210|RegionalBus:1179_3", strings.get("gtfs:route_id"));
     59        assertEquals("de:mvv-muenchen:19-210|210|RegionalBus:1179-1-1-H-0-We#3-320-333", strings.get("gtfs:trip_id:sample"));
     60    }
     61
     62    /**
     63     * Unit test for issue #14490 "Support for escaping pipe character in remote control addtags parameters"
     64     * Two URL sections (values of addtags=...) with four unescaped pipe sysmbols in the value parts
     65     * Same as the test above, but without escapeing the pipe symbols
     66     * This is how it worked before the patch, even if the pipe symbols would have been escaped
     67     */
     68    @Test
     69    void testParseUrlTagsToKeyValues_PipeInValue_NoEscapedPipe() {
     70        Map<String, String> strings = AddTagsDialog.parseUrlTagsToKeyValues("gtfs:route_id=de:mvv-muenchen:19-210|210|"
     71        + "RegionalBus:1179_3|gtfs:trip_id:sample=de:mvv-muenchen:19-210|210|RegionalBus:1179-1-1-H-0-We#3-320-333");
     72        assertEquals(0, strings.size());
     73    }
    2674}
  • trunk/test/unit/org/openstreetmap/josm/tools/TextTagParserTest.java

    r18037 r19571  
    176176        List<String> expected = Arrays.asList("foo4", "foo3", "foo2", "foo1");
    177177        ArrayList<String> actual = new ArrayList<>(TextTagParser.readTagsByRegexp(
    178                 "foo4=bar4 foo3=bar3 foo2=bar2 foo1=bar1", " ", "(.*?)=(.*?)", true).keySet());
     178                "foo4=bar4 foo3=bar3 foo2=bar2 foo1=bar1", " ", "(.*?)=(.*?)", true, false).keySet());
    179179        assertEquals(expected, actual);
    180180    }
Note: See TracChangeset for help on using the changeset viewer.