[Author Prev][Author Next][Thread Prev][Thread Next][Author Index][Thread Index]
[tor-commits] [onionoo/master] Support quoted qualified search terms.
commit 75981fe7d03091c78f901e1589288be4a27ce56c
Author: Karsten Loesing <karsten.loesing@xxxxxxx>
Date: Thu Oct 19 14:46:28 2017 +0200
Support quoted qualified search terms.
With this patch, the "search" parameter does not only accept unquoted
qualified search terms like `search=contact:John Doe` where "John"
would be looked up in the contact line and "Doe" in the nickname or
base64-encoded fingerprint. It also accepts quoted qualified search
terms like `search=contact:"John Doe"` where "John Doe" would be
looked up in the contact line. It further accepts escaped double
quotes (\") within quoted qualified search terms.
Implements #21366.
---
CHANGELOG.md | 8 ++++-
.../torproject/onionoo/server/ResourceServlet.java | 38 ++++++++++++++++++++--
.../onionoo/server/ResourceServletTest.java | 36 +++++++++++++++++++-
3 files changed, 77 insertions(+), 5 deletions(-)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index ca17fa7..74f29b7 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,4 +1,10 @@
-# Changes in version 4.2-1.6.1 - 2017-10-2?
+# Changes in version 4.3-1.7.0 - 2017-1?-??
+
+ * Medium changes
+ - Support quoted qualified search terms.
+
+
+# Changes in version 4.2-1.6.1 - 2017-10-26
* Medium changes
- Fix two NullPointerExceptions caused by accessing optional parts
diff --git a/src/main/java/org/torproject/onionoo/server/ResourceServlet.java b/src/main/java/org/torproject/onionoo/server/ResourceServlet.java
index 31244c2..2fff913 100644
--- a/src/main/java/org/torproject/onionoo/server/ResourceServlet.java
+++ b/src/main/java/org/torproject/onionoo/server/ResourceServlet.java
@@ -3,6 +3,8 @@
package org.torproject.onionoo.server;
+import org.apache.commons.lang3.StringUtils;
+
import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;
@@ -169,6 +171,12 @@ public class ResourceServlet extends HttpServlet {
}
if (!parameterMap.containsKey(parameterKey)) {
String parameterValue = parts[1];
+ if (parameterValue.startsWith("\"")
+ && parameterValue.endsWith("\"")) {
+ parameterValue = parameterValue
+ .substring(1, parameterValue.length() - 1)
+ .replaceAll("\\\\\"", "\"");
+ }
parameterMap.put(parameterKey, parameterValue);
}
} else {
@@ -388,7 +396,7 @@ public class ResourceServlet extends HttpServlet {
+ "^[0-9a-zA-Z+/]{1,27}$|" /* Base64 fingerprint. */
+ "^[0-9a-zA-Z\\.]{1,19}$|" /* Nickname or IPv4 address. */
+ ipv6AddressPatternString + "|" /* IPv6 address. */
- + "^[a-zA-Z_]+:\\p{Graph}+$" /* Qualified search term. */);
+ + "^[a-zA-Z_]+:\"?[\\p{Graph} ]+\"?$"); /* Qualified search term. */
protected static String[] parseSearchParameters(String queryString) {
Matcher searchQueryStringMatcher = searchQueryStringPattern.matcher(
@@ -398,15 +406,39 @@ public class ResourceServlet extends HttpServlet {
return null;
}
String parameter = searchQueryStringMatcher.group(1);
- String[] searchParameters =
+ String[] spaceSeparatedParts =
parameter.replaceAll("%20", " ").split(" ");
+ List<String> searchParameters = new ArrayList<>();
+ StringBuilder doubleQuotedSearchTerm = null;
+ for (String spaceSeparatedPart : spaceSeparatedParts) {
+ if ((StringUtils.countMatches(spaceSeparatedPart, '"')
+ - StringUtils.countMatches(spaceSeparatedPart, "\\\"")) % 2 == 0) {
+ if (null == doubleQuotedSearchTerm) {
+ searchParameters.add(spaceSeparatedPart);
+ } else {
+ doubleQuotedSearchTerm.append(' ').append(spaceSeparatedPart);
+ }
+ } else {
+ if (null == doubleQuotedSearchTerm) {
+ doubleQuotedSearchTerm = new StringBuilder(spaceSeparatedPart);
+ } else {
+ doubleQuotedSearchTerm.append(' ').append(spaceSeparatedPart);
+ searchParameters.add(doubleQuotedSearchTerm.toString());
+ doubleQuotedSearchTerm = null;
+ }
+ }
+ }
+ if (null != doubleQuotedSearchTerm) {
+ /* Opening double quote is not followed by closing double quote. */
+ return null;
+ }
for (String searchParameter : searchParameters) {
if (!searchParameterPattern.matcher(searchParameter).matches()) {
/* Illegal search term. */
return null;
}
}
- return searchParameters;
+ return searchParameters.toArray(new String[0]);
}
private static Pattern fingerprintParameterPattern =
diff --git a/src/test/java/org/torproject/onionoo/server/ResourceServletTest.java b/src/test/java/org/torproject/onionoo/server/ResourceServletTest.java
index 303cf21..1588f8a 100644
--- a/src/test/java/org/torproject/onionoo/server/ResourceServletTest.java
+++ b/src/test/java/org/torproject/onionoo/server/ResourceServletTest.java
@@ -169,7 +169,7 @@ public class ResourceServletTest {
new TreeSet<>(Arrays.asList(new String[] { "Fast",
"Running", "Unnamed", "V2Dir", "Valid" })), 63L, "a1",
DateTimeHelper.parse("2013-04-16 18:00:00"), "AS6830",
- "1024D/51E2A1C7 steven j. murdoch "
+ "1024d/51e2a1c7 \"steven j. murdoch\" "
+ "<tor+steven.murdoch@xxxxxxxxxxxx> <fb-token:5sr_k_zs2wm=>",
new TreeSet<String>(), new TreeSet<String>(), "0.2.3.25");
this.relays.put("0025C136C1F3A9EEFE2AE3F918F03BFA21B5070B",
@@ -933,6 +933,40 @@ public class ResourceServletTest {
}
@Test(timeout = 100)
+ public void testSearchDoubleQuotedEmailAddress() {
+ this.assertSummaryDocument(
+ "/summary?search=contact:\"klaus dot zufall at gmx dot de\"", 1,
+ new String[] { "TorkaZ" }, 0, null);
+ }
+
+ @Test(timeout = 100)
+ public void testSearchDoubleQuotedContactAndNickname() {
+ this.assertSummaryDocument(
+ "/summary?search=contact:\"dot de\" TorkaZ", 1,
+ new String[] { "TorkaZ" }, 0, null);
+ }
+
+ @Test(timeout = 100)
+ public void testSearchMissingEndingDoubleQuote() {
+ this.assertErrorStatusCode(
+ "/summary?search=contact:\"klaus dot zufall at gmx dot de", 400);
+ }
+
+ @Test(timeout = 100)
+ public void testSearchEvenNumberOfDoubleQuotes() {
+ this.assertSummaryDocument(
+ "/summary?search=contact:\"\"\" \"\"\"", 0,
+ null, 0, null);
+ }
+
+ @Test(timeout = 100)
+ public void testSearchContactEscapedDoubleQuotes() {
+ this.assertSummaryDocument(
+ "/summary?search=contact:\"1024D/51E2A1C7 \\\"Steven J. Murdoch\\\"\"",
+ 1, new String[] { "TimMayTribute" }, 0, null);
+ }
+
+ @Test(timeout = 100)
public void testLookupFingerprint() {
this.assertSummaryDocument(
"/summary?lookup=000C5F55BD4814B917CC474BD537F1A3B33CCE2A", 1,
_______________________________________________
tor-commits mailing list
tor-commits@xxxxxxxxxxxxxxxxxxxx
https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits