From 4e0f05f0a1c3517c596c4196ffd25f2be3b2e3f0 Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Wed, 8 Jan 2020 10:51:18 +0100 Subject: [PATCH] refactored xmpp uri parsing to expose all params --- .../eu/siacs/conversations/utils/XmppUri.java | 127 ++++++++---------- 1 file changed, 58 insertions(+), 69 deletions(-) diff --git a/src/main/java/eu/siacs/conversations/utils/XmppUri.java b/src/main/java/eu/siacs/conversations/utils/XmppUri.java index de18aa596..8feae0b15 100644 --- a/src/main/java/eu/siacs/conversations/utils/XmppUri.java +++ b/src/main/java/eu/siacs/conversations/utils/XmppUri.java @@ -1,15 +1,19 @@ package eu.siacs.conversations.utils; import android.net.Uri; -import android.util.Log; +import android.support.annotation.NonNull; + +import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableMap; import java.io.UnsupportedEncodingException; import java.net.URLDecoder; import java.util.ArrayList; +import java.util.Collections; import java.util.List; import java.util.Locale; +import java.util.Map; -import eu.siacs.conversations.Config; import rocks.xmpp.addr.Jid; public class XmppUri { @@ -17,9 +21,7 @@ public class XmppUri { protected Uri uri; protected String jid; private List fingerprints = new ArrayList<>(); - private String body; - private String name; - private String action; + private Map parameters = Collections.emptyMap(); private boolean safeSource = true; private static final String OMEMO_URI_PARAM = "omemo-sid-"; @@ -66,7 +68,6 @@ public class XmppUri { try { jid = Jid.of(lameUrlDecode(segments.get(1))).toString(); } catch (Exception e) { - Log.d(Config.LOGTAG, "parsing failed ", e); jid = null; } } else if (segments.size() >= 3) { @@ -74,33 +75,24 @@ public class XmppUri { jid = segments.get(1) + "@" + segments.get(2); } if (segments.size() > 1 && "j".equalsIgnoreCase(segments.get(0))) { - action = ACTION_JOIN; + this.parameters = ImmutableMap.of(ACTION_JOIN, ""); } - fingerprints = parseFingerprints(uri.getQuery(), '&'); + final Map parameters = parseParameters(uri.getQuery(), '&'); + this.fingerprints = parseFingerprints(parameters); } else if ("xmpp".equalsIgnoreCase(scheme)) { // sample: xmpp:foo@bar.com - - final String query = uri.getQuery(); - - if (hasAction(query, ACTION_JOIN)) { - this.action = ACTION_JOIN; - } else if (hasAction(query, ACTION_MESSAGE)) { - this.action = ACTION_MESSAGE; - } - + this.parameters = parseParameters(uri.getQuery(), ';'); if (uri.getAuthority() != null) { jid = uri.getAuthority(); } else { - String[] parts = uri.getSchemeSpecificPart().split("\\?"); + final String[] parts = uri.getSchemeSpecificPart().split("\\?"); if (parts.length > 0) { jid = parts[0]; } else { return; } } - this.fingerprints = parseFingerprints(uri.getQuery()); - this.body = parseParameter("body", uri.getQuery()); - this.name = parseParameter("name", uri.getQuery()); + this.fingerprints = parseFingerprints(parameters); } else if ("imto".equalsIgnoreCase(scheme)) { // sample: imto://xmpp/foo@bar.com try { @@ -117,65 +109,61 @@ public class XmppUri { } } - public String toString() { - if (uri != null) { - return uri.toString(); - } - return ""; - } - - private List parseFingerprints(String query) { - return parseFingerprints(query, ';'); - } - private List parseFingerprints(String query, char seperator) { - List fingerprints = new ArrayList<>(); - String[] pairs = query == null ? new String[0] : query.split(String.valueOf(seperator)); + private static Map parseParameters(final String query, final char seperator) { + final ImmutableMap.Builder builder = new ImmutableMap.Builder<>(); + final String[] pairs = query == null ? new String[0] : query.split(String.valueOf(seperator)); for (String pair : pairs) { - String[] parts = pair.split("=", 2); + final String[] parts = pair.split("=", 2); + if (parts.length == 0) { + continue; + } + final String key = parts[0].toLowerCase(Locale.US); + final String value; if (parts.length == 2) { - String key = parts[0].toLowerCase(Locale.US); - String value = parts[1].toLowerCase(Locale.US); - if (key.startsWith(OMEMO_URI_PARAM)) { - try { - int id = Integer.parseInt(key.substring(OMEMO_URI_PARAM.length())); - fingerprints.add(new Fingerprint(FingerprintType.OMEMO, value, id)); - } catch (Exception e) { - //ignoring invalid device id - } + String decoded; + try { + decoded = URLDecoder.decode(parts[1],"UTF-8"); + } catch (UnsupportedEncodingException e) { + decoded = ""; } + value = decoded; + } else { + value = ""; } + builder.put(key, value); } - return fingerprints; + return builder.build(); } - private String parseParameter(String key, String query) { - for (String pair : query == null ? new String[0] : query.split(";")) { - final String[] parts = pair.split("=", 2); - if (parts.length == 2 && key.equals(parts[0].toLowerCase(Locale.US))) { - try { - return URLDecoder.decode(parts[1], "UTF-8"); - } catch (UnsupportedEncodingException e) { - return null; - } - } + @Override + @NonNull + public String toString() { + if (uri != null) { + return uri.toString(); } - return null; + return ""; } - private boolean hasAction(String query, String action) { - for (String pair : query == null ? new String[0] : query.split(";")) { - final String[] parts = pair.split("=", 2); - if (parts.length == 1 && parts[0].toLowerCase(Locale.US).startsWith(action)) { - return true; + private static List parseFingerprints(Map parameters) { + ImmutableList.Builder builder = new ImmutableList.Builder<>(); + for (Map.Entry parameter : parameters.entrySet()) { + final String key = parameter.getKey(); + final String value = parameter.getValue().toLowerCase(Locale.US); + if (key.startsWith(OMEMO_URI_PARAM)) { + try { + final int id = Integer.parseInt(key.substring(OMEMO_URI_PARAM.length())); + builder.add(new Fingerprint(FingerprintType.OMEMO, value, id)); + } catch (Exception e) { + //ignoring invalid device id + } } } - return false; + return builder.build(); } public boolean isAction(final String action) { - return this.action != null && this.action.equals(action); - + return parameters.containsKey(action); } public Jid getJid() { @@ -199,11 +187,11 @@ public class XmppUri { } public String getBody() { - return body; + return parameters.get("body"); } public String getName() { - return name; + return parameters.get("name"); } public List getFingerprints() { @@ -218,7 +206,7 @@ public class XmppUri { OMEMO } - public static String getFingerprintUri(String base, List fingerprints, char seperator) { + public static String getFingerprintUri(String base, List fingerprints, char separator) { StringBuilder builder = new StringBuilder(base); builder.append('?'); for (int i = 0; i < fingerprints.size(); ++i) { @@ -230,7 +218,7 @@ public class XmppUri { builder.append('='); builder.append(fingerprints.get(i).fingerprint); if (i != fingerprints.size() - 1) { - builder.append(seperator); + builder.append(separator); } } return builder.toString(); @@ -247,9 +235,10 @@ public class XmppUri { this.deviceId = deviceId; } + @NonNull @Override public String toString() { - return type.toString() + ": " + fingerprint + (deviceId != 0 ? " " + String.valueOf(deviceId) : ""); + return type.toString() + ": " + fingerprint + (deviceId != 0 ? " " + deviceId : ""); } } -- 2.45.2