| 1 | Index: src/org/openstreetmap/josm/io/remotecontrol/AddTagsDialog.java
|
|---|
| 2 | ===================================================================
|
|---|
| 3 | --- src/org/openstreetmap/josm/io/remotecontrol/AddTagsDialog.java (revision 19570)
|
|---|
| 4 | +++ src/org/openstreetmap/josm/io/remotecontrol/AddTagsDialog.java (working copy)
|
|---|
| 5 | @@ -283,7 +283,7 @@
|
|---|
| 6 | * @since 15316
|
|---|
| 7 | */
|
|---|
| 8 | public static Map<String, String> parseUrlTagsToKeyValues(String urlSection) {
|
|---|
| 9 | - Map<String, String> tags = TextTagParser.readTagsByRegexp(urlSection, "\\|", "(.*?)=(.*?)", false);
|
|---|
| 10 | + Map<String, String> tags = TextTagParser.readTagsByRegexp(urlSection, "(?<!\\\\)\\|", "(.*?)=(.*?)", false, true);
|
|---|
| 11 | return tags == null ? Collections.emptyMap() : tags;
|
|---|
| 12 | }
|
|---|
| 13 |
|
|---|
| 14 | Index: src/org/openstreetmap/josm/tools/TextTagParser.java
|
|---|
| 15 | ===================================================================
|
|---|
| 16 | --- src/org/openstreetmap/josm/tools/TextTagParser.java (revision 19570)
|
|---|
| 17 | +++ src/org/openstreetmap/josm/tools/TextTagParser.java (working copy)
|
|---|
| 18 | @@ -46,9 +46,10 @@
|
|---|
| 19 | * @param splitRegex - text is split into parts with this delimiter
|
|---|
| 20 | * @param tagRegex - each part is matched against this regex
|
|---|
| 21 | * @param unescapeTextInQuotes - if true, matched tag and value will be analyzed more thoroughly
|
|---|
| 22 | + * @param unescapePipe - if true, then replace all '\|' by '|' (issue #14490)
|
|---|
| 23 | * @return map of tags
|
|---|
| 24 | */
|
|---|
| 25 | - public static Map<String, String> readTagsByRegexp(String text, String splitRegex, String tagRegex, boolean unescapeTextInQuotes) {
|
|---|
| 26 | + public static Map<String, String> readTagsByRegexp(String text, String splitRegex, String tagRegex, boolean unescapeTextInQuotes, boolean unescapePipe) {
|
|---|
| 27 | String[] lines = text.split(splitRegex, -1);
|
|---|
| 28 | Pattern p = Pattern.compile(tagRegex);
|
|---|
| 29 | Map<String, String> tags = new LinkedHashMap<>();
|
|---|
| 30 | @@ -65,6 +66,10 @@
|
|---|
| 31 | v = unescape(v);
|
|---|
| 32 | if (k == null || v == null) return null;
|
|---|
| 33 | }
|
|---|
| 34 | + if (unescapePipe) {
|
|---|
| 35 | + k = k.replaceAll("\\\\\\|","|");
|
|---|
| 36 | + v = v.replaceAll("\\\\\\|","|");
|
|---|
| 37 | + }
|
|---|
| 38 | tags.put(k, v);
|
|---|
| 39 | } else {
|
|---|
| 40 | return null;
|
|---|
| 41 | @@ -99,7 +104,7 @@
|
|---|
| 42 |
|
|---|
| 43 | // Format
|
|---|
| 44 | // tag1\tval1\ntag2\tval2\n
|
|---|
| 45 | - tags = readTagsByRegexp(buf, "[\\r\\n]+", ".*?([a-zA-Z0-9:_]+).*\\t(.*?)", false);
|
|---|
| 46 | + tags = readTagsByRegexp(buf, "[\\r\\n]+", ".*?([a-zA-Z0-9:_]+).*\\t(.*?)", false, false);
|
|---|
| 47 | // try "tag\tvalue\n" format
|
|---|
| 48 | if (tags != null) return tags;
|
|---|
| 49 |
|
|---|
| 50 | @@ -108,7 +113,7 @@
|
|---|
| 51 | // SORRY: "a=b" = c is not supported for now, only first = will be considered
|
|---|
| 52 | // a = "b=c" is OK
|
|---|
| 53 | // a = b=c - this method of parsing fails intentionally
|
|---|
| 54 | - tags = readTagsByRegexp(buf, "[\\n\\t\\r]+", "(.*?)=(.*?)", true);
|
|---|
| 55 | + tags = readTagsByRegexp(buf, "[\\n\\t\\r]+", "(.*?)=(.*?)", true, false );
|
|---|
| 56 | // try format t1=v1\n t2=v2\n ...
|
|---|
| 57 | if (tags != null) return tags;
|
|---|
| 58 |
|
|---|
| 59 | @@ -118,7 +123,7 @@
|
|---|
| 60 | if (bufJson.startsWith("{") && bufJson.endsWith("}"))
|
|---|
| 61 | bufJson = bufJson.substring(1, bufJson.length()-1);
|
|---|
| 62 | tags = readTagsByRegexp(bufJson, "[\\s]*,[\\s]*",
|
|---|
| 63 | - "[\\s]*(\\\".*?[^\\\\]\\\")"+"[\\s]*:[\\s]*"+"(\\\".*?[^\\\\]\\\")[\\s]*", true);
|
|---|
| 64 | + "[\\s]*(\\\".*?[^\\\\]\\\")"+"[\\s]*:[\\s]*"+"(\\\".*?[^\\\\]\\\")[\\s]*", true, false);
|
|---|
| 65 | if (tags != null) return tags;
|
|---|
| 66 |
|
|---|
| 67 | // Free format
|
|---|
| 68 | Index: test/unit/org/openstreetmap/josm/io/remotecontrol/AddTagsDialogTest.java
|
|---|
| 69 | ===================================================================
|
|---|
| 70 | --- test/unit/org/openstreetmap/josm/io/remotecontrol/AddTagsDialogTest.java (revision 19570)
|
|---|
| 71 | +++ test/unit/org/openstreetmap/josm/io/remotecontrol/AddTagsDialogTest.java (working copy)
|
|---|
| 72 | @@ -23,4 +23,46 @@
|
|---|
| 73 | assertEquals("Residenzschloss Dresden", strings.get("wikipedia:de"));
|
|---|
| 74 | assertEquals("Dresden Castle", strings.get("name:en"));
|
|---|
| 75 | }
|
|---|
| 76 | +
|
|---|
| 77 | + /**
|
|---|
| 78 | + * Unit test for issue #14490 "Support for escaping pipe character in remote control addtags parameters"
|
|---|
| 79 | + * A single URL section (value of addtags=...) with a single escaped pipe sysmbol
|
|---|
| 80 | + */
|
|---|
| 81 | + @Test
|
|---|
| 82 | + void testParseUrlTagsToKeyValues_OneKeyValuePair_OneEscapedPipe() {
|
|---|
| 83 | + Map<String, String> strings = AddTagsDialog.parseUrlTagsToKeyValues("gtfs:route_id=de:mvv-muenchen:19-210\\|210");
|
|---|
| 84 | + assertEquals(1, strings.size());
|
|---|
| 85 | + assertEquals("de:mvv-muenchen:19-210|210", strings.get("gtfs:route_id"));
|
|---|
| 86 | + }
|
|---|
| 87 | +
|
|---|
| 88 | + /**
|
|---|
| 89 | + * Unit test for issue #14490 "Support for escaping pipe character in remote control addtags parameters"
|
|---|
| 90 | + * A single URL section (value of addtags=...) with two escaped pipe sysmbols
|
|---|
| 91 | + */
|
|---|
| 92 | + @Test
|
|---|
| 93 | + void testParseUrlTagsToKeyValues_OneKeyValuePair_TwoEscapedPipe() {
|
|---|
| 94 | + Map<String, String> strings = AddTagsDialog.parseUrlTagsToKeyValues("gtfs:route_id=de:mvv-muenchen:19-210\\|210\\|RegionalBus:1179_3");
|
|---|
| 95 | + assertEquals(1, strings.size());
|
|---|
| 96 | + assertEquals("de:mvv-muenchen:19-210|210|RegionalBus:1179_3", strings.get("gtfs:route_id"));
|
|---|
| 97 | + }
|
|---|
| 98 | + /**
|
|---|
| 99 | + * Unit test for issue #14490 "Support for escaping pipe character in remote control addtags parameters"
|
|---|
| 100 | + * Two URL sections (values of addtags=...) with a single escaped pipe sysmbol each
|
|---|
| 101 | + */
|
|---|
| 102 | + @Test
|
|---|
| 103 | + void testParseUrlTagsToKeyValues_TwoKeyValuePairs_FourEscapedPipe() {
|
|---|
| 104 | + Map<String, String> strings = AddTagsDialog.parseUrlTagsToKeyValues("gtfs:route_id=de:mvv-muenchen:19-210\\|210\\|RegionalBus:1179_3|gtfs:trip_id:sample=de:mvv-muenchen:19-210\\|210\\|RegionalBus:1179-1-1-H-0-We#3-320-333");
|
|---|
| 105 | + assertEquals(2, strings.size());
|
|---|
| 106 | + assertEquals("de:mvv-muenchen:19-210|210|RegionalBus:1179_3", strings.get("gtfs:route_id"));
|
|---|
| 107 | + assertEquals("de:mvv-muenchen:19-210|210|RegionalBus:1179-1-1-H-0-We#3-320-333", strings.get("gtfs:trip_id:sample"));
|
|---|
| 108 | + }
|
|---|
| 109 | + /**
|
|---|
| 110 | + * Unit test for issue #14490 "Support for escaping pipe character in remote control addtags parameters"
|
|---|
| 111 | + * Two URL sections (values of addtags=...) with four un escaped pipe sysmbols in the value parts
|
|---|
| 112 | + */
|
|---|
| 113 | + @Test
|
|---|
| 114 | + void testParseUrlTagsToKeyValues_PipeInValue_NoEscapedPipe() {
|
|---|
| 115 | + Map<String, String> strings = AddTagsDialog.parseUrlTagsToKeyValues("gtfs:route_id=de:mvv-muenchen:19-210|210|RegionalBus:1179_3|gtfs:trip_id:sample=de:mvv-muenchen:19-210|210|RegionalBus:1179-1-1-H-0-We#3-320-333");
|
|---|
| 116 | + assertEquals(0, strings.size());
|
|---|
| 117 | + }
|
|---|
| 118 | }
|
|---|
| 119 | Index: test/unit/org/openstreetmap/josm/tools/TextTagParserTest.java
|
|---|
| 120 | ===================================================================
|
|---|
| 121 | --- test/unit/org/openstreetmap/josm/tools/TextTagParserTest.java (revision 19570)
|
|---|
| 122 | +++ test/unit/org/openstreetmap/josm/tools/TextTagParserTest.java (working copy)
|
|---|
| 123 | @@ -175,7 +175,7 @@
|
|---|
| 124 | void testStableOrder() {
|
|---|
| 125 | List<String> expected = Arrays.asList("foo4", "foo3", "foo2", "foo1");
|
|---|
| 126 | ArrayList<String> actual = new ArrayList<>(TextTagParser.readTagsByRegexp(
|
|---|
| 127 | - "foo4=bar4 foo3=bar3 foo2=bar2 foo1=bar1", " ", "(.*?)=(.*?)", true).keySet());
|
|---|
| 128 | + "foo4=bar4 foo3=bar3 foo2=bar2 foo1=bar1", " ", "(.*?)=(.*?)", true, false).keySet());
|
|---|
| 129 | assertEquals(expected, actual);
|
|---|
| 130 | }
|
|---|
| 131 | }
|
|---|