From 6a4c366975dde87175b356084f2c258e782134e0 Mon Sep 17 00:00:00 2001 From: Christian Schneppe Date: Sat, 5 May 2018 20:56:55 +0200 Subject: encode and decode % and # in invite links --- .../java/de/pixart/messenger/entities/Account.java | 2 +- .../messenger/ui/ConferenceDetailsActivity.java | 3 +- .../messenger/ui/ContactDetailsActivity.java | 7 ++-- .../pixart/messenger/ui/ConversationFragment.java | 12 +++++++ .../messenger/ui/adapter/MessageAdapter.java | 7 +--- .../de/pixart/messenger/ui/util/ShareUtil.java | 41 ++++++++++++++++++++++ .../java/de/pixart/messenger/utils/Patterns.java | 6 ++++ .../java/de/pixart/messenger/utils/XmppUri.java | 13 ++++++- src/main/res/menu/message_context.xml | 4 +++ src/main/res/values/strings.xml | 4 +++ 10 files changed, 86 insertions(+), 13 deletions(-) (limited to 'src/main') diff --git a/src/main/java/de/pixart/messenger/entities/Account.java b/src/main/java/de/pixart/messenger/entities/Account.java index 127d4a845..9831d091c 100644 --- a/src/main/java/de/pixart/messenger/entities/Account.java +++ b/src/main/java/de/pixart/messenger/entities/Account.java @@ -661,7 +661,7 @@ public class Account extends AbstractEntity { } public String getShareableLink() { List fingerprints = this.getFingerprints(); - String uri = Config.inviteUserURL + this.getJid().asBareJid().toEscapedString(); + String uri = Config.inviteUserURL + XmppUri.lameUrlEncode(this.getJid().asBareJid().toEscapedString()); if (fingerprints.size() > 0) { return XmppUri.getFingerprintUri(uri,fingerprints,'&'); } else { diff --git a/src/main/java/de/pixart/messenger/ui/ConferenceDetailsActivity.java b/src/main/java/de/pixart/messenger/ui/ConferenceDetailsActivity.java index 7c2f51bbb..8d9fefe05 100644 --- a/src/main/java/de/pixart/messenger/ui/ConferenceDetailsActivity.java +++ b/src/main/java/de/pixart/messenger/ui/ConferenceDetailsActivity.java @@ -51,6 +51,7 @@ import de.pixart.messenger.services.XmppConnectionService.OnMucRosterUpdate; import de.pixart.messenger.utils.MenuDoubleTabUtil; import de.pixart.messenger.utils.TimeframeUtils; import de.pixart.messenger.utils.UIHelper; +import de.pixart.messenger.utils.XmppUri; import rocks.xmpp.addr.Jid; public class ConferenceDetailsActivity extends XmppActivity implements OnConversationUpdate, OnMucRosterUpdate, XmppConnectionService.OnAffiliationChanged, XmppConnectionService.OnRoleChanged, XmppConnectionService.OnConfigurationPushed { @@ -344,7 +345,7 @@ public class ConferenceDetailsActivity extends XmppActivity implements OnConvers protected String getShareableUri(boolean http) { if (mConversation != null) { if (http) { - return Config.inviteMUCURL + mConversation.getJid().asBareJid().toEscapedString(); + return Config.inviteMUCURL + XmppUri.lameUrlEncode(mConversation.getJid().asBareJid().toEscapedString()); } else { return "xmpp:" + mConversation.getJid().asBareJid().toEscapedString() + "?join"; } diff --git a/src/main/java/de/pixart/messenger/ui/ContactDetailsActivity.java b/src/main/java/de/pixart/messenger/ui/ContactDetailsActivity.java index 0c2d1bb1d..d2aa75ca3 100644 --- a/src/main/java/de/pixart/messenger/ui/ContactDetailsActivity.java +++ b/src/main/java/de/pixart/messenger/ui/ContactDetailsActivity.java @@ -228,11 +228,10 @@ public class ContactDetailsActivity extends OmemoActivity implements OnAccountUp @Override protected String getShareableUri(boolean http) { - final String prefix = http ? Config.inviteUserURL : "xmpp:"; - if (contact != null) { - return prefix + contact.getJid().asBareJid().toEscapedString(); + if (http) { + return Config.inviteUserURL + XmppUri.lameUrlEncode(contact.getJid().asBareJid().toEscapedString()); } else { - return ""; + return "xmpp:" + contact.getJid().asBareJid().toEscapedString(); } } diff --git a/src/main/java/de/pixart/messenger/ui/ConversationFragment.java b/src/main/java/de/pixart/messenger/ui/ConversationFragment.java index fdcbf29b3..cdbdbd069 100644 --- a/src/main/java/de/pixart/messenger/ui/ConversationFragment.java +++ b/src/main/java/de/pixart/messenger/ui/ConversationFragment.java @@ -110,6 +110,7 @@ import de.pixart.messenger.utils.FileUtils; import de.pixart.messenger.utils.MenuDoubleTabUtil; import de.pixart.messenger.utils.MessageUtils; import de.pixart.messenger.utils.NickValidityChecker; +import de.pixart.messenger.utils.Patterns; import de.pixart.messenger.utils.QuickLoader; import de.pixart.messenger.utils.StylingHelper; import de.pixart.messenger.utils.UIHelper; @@ -1278,6 +1279,7 @@ public class ConversationFragment extends XmppFragment implements EditMessage.Ke activity.getMenuInflater().inflate(R.menu.message_context, menu); menu.setHeaderTitle(R.string.message_options); MenuItem copyMessage = menu.findItem(R.id.copy_message); + MenuItem copyLink = menu.findItem(R.id.copy_link); MenuItem quoteMessage = menu.findItem(R.id.quote_message); MenuItem retryDecryption = menu.findItem(R.id.retry_decryption); MenuItem correctMessage = menu.findItem(R.id.correct_message); @@ -1291,6 +1293,13 @@ public class ConversationFragment extends XmppFragment implements EditMessage.Ke if (!m.isFileOrImage() && !encrypted && !m.isGeoUri() && !m.treatAsDownloadable()) { copyMessage.setVisible(true); quoteMessage.setVisible(MessageUtils.prepareQuote(m).length() > 0); + String body = m.getMergedBody().toString(); + if (ShareUtil.containsXmppUri(body)) { + copyLink.setTitle(R.string.copy_jabber_id); + copyLink.setVisible(true); + } else if (Patterns.AUTOLINK_WEB_URL.matcher(body).find()) { + copyLink.setVisible(true); + } } if (m.getEncryption() == Message.ENCRYPTION_DECRYPTION_FAILED) { retryDecryption.setVisible(true); @@ -1351,6 +1360,9 @@ public class ConversationFragment extends XmppFragment implements EditMessage.Ke case R.id.copy_message: ShareUtil.copyToClipboard(activity, selectedMessage); return true; + case R.id.copy_link: + ShareUtil.copyLinkToClipboard(activity, selectedMessage); + return true; case R.id.quote_message: quoteMessage(selectedMessage); return true; diff --git a/src/main/java/de/pixart/messenger/ui/adapter/MessageAdapter.java b/src/main/java/de/pixart/messenger/ui/adapter/MessageAdapter.java index a14e1057b..f97ca0beb 100644 --- a/src/main/java/de/pixart/messenger/ui/adapter/MessageAdapter.java +++ b/src/main/java/de/pixart/messenger/ui/adapter/MessageAdapter.java @@ -102,11 +102,6 @@ public class MessageAdapter extends ArrayAdapter implements CopyTextVie private static final int DATE_SEPARATOR = 3; - private static final Pattern XMPP_PATTERN = Pattern - .compile("xmpp\\:(?:(?:[" - + Patterns.GOOD_IRI_CHAR - + "\\;\\/\\?\\@\\&\\=\\#\\~\\-\\.\\+\\!\\*\\'\\(\\)\\,\\_])" - + "|(?:\\%[a-fA-F0-9]{2}))+"); boolean isResendable = false; private List highlightedTerm = null; @@ -600,7 +595,7 @@ public class MessageAdapter extends ArrayAdapter implements CopyTextVie if (highlightedTerm != null) { StylingHelper.highlight(activity, body, highlightedTerm, StylingHelper.isDarkText(viewHolder.messageBody)); } - Linkify.addLinks(body, XMPP_PATTERN, "xmpp", XMPPURI_MATCH_FILTER, null); + Linkify.addLinks(body, Patterns.XMPP_PATTERN, "xmpp", XMPPURI_MATCH_FILTER, null); Linkify.addLinks(body, Patterns.AUTOLINK_WEB_URL, "http", WEBURL_MATCH_FILTER, WEBURL_TRANSFORM_FILTER); Linkify.addLinks(body, GeoHelper.GEO_URI, "geo"); FixedURLSpan.fix(body); diff --git a/src/main/java/de/pixart/messenger/ui/util/ShareUtil.java b/src/main/java/de/pixart/messenger/ui/util/ShareUtil.java index 63c505284..ee72649b8 100644 --- a/src/main/java/de/pixart/messenger/ui/util/ShareUtil.java +++ b/src/main/java/de/pixart/messenger/ui/util/ShareUtil.java @@ -33,11 +33,16 @@ import android.content.ActivityNotFoundException; import android.content.Intent; import android.widget.Toast; +import java.util.regex.Matcher; + import de.pixart.messenger.R; import de.pixart.messenger.entities.DownloadableFile; import de.pixart.messenger.entities.Message; import de.pixart.messenger.persistance.FileBackend; import de.pixart.messenger.ui.XmppActivity; +import de.pixart.messenger.utils.Patterns; +import de.pixart.messenger.utils.XmppUri; +import rocks.xmpp.addr.Jid; public class ShareUtil { @@ -96,4 +101,40 @@ public class ShareUtil { Toast.makeText(activity, R.string.url_copied_to_clipboard, Toast.LENGTH_SHORT).show(); } } + + public static void copyLinkToClipboard(XmppActivity activity, Message message) { + String body = message.getMergedBody().toString(); + Matcher xmppPatternMatcher = Patterns.XMPP_PATTERN.matcher(body); + if (xmppPatternMatcher.find()) { + try { + Jid jid = new XmppUri(body.substring(xmppPatternMatcher.start(), xmppPatternMatcher.end())).getJid(); + if (activity.copyTextToClipboard(jid.asBareJid().toString(), R.string.account_settings_jabber_id)) { + Toast.makeText(activity, R.string.jabber_id_copied_to_clipboard, Toast.LENGTH_SHORT).show(); + } + return; + } catch (Exception e) { + e.printStackTrace(); + return; + } + } + Matcher webUrlPatternMatcher = Patterns.AUTOLINK_WEB_URL.matcher(body); + if (webUrlPatternMatcher.find()) { + String url = body.substring(webUrlPatternMatcher.start(), webUrlPatternMatcher.end()); + if (activity.copyTextToClipboard(url, R.string.web_address)) { + Toast.makeText(activity, R.string.url_copied_to_clipboard, Toast.LENGTH_SHORT).show(); + } + } + } + + public static boolean containsXmppUri(String body) { + Matcher xmppPatternMatcher = Patterns.XMPP_PATTERN.matcher(body); + if (xmppPatternMatcher.find()) { + try { + return new XmppUri(body.substring(xmppPatternMatcher.start(), xmppPatternMatcher.end())).isJidValid(); + } catch (Exception e) { + return false; + } + } + return false; + } } \ No newline at end of file diff --git a/src/main/java/de/pixart/messenger/utils/Patterns.java b/src/main/java/de/pixart/messenger/utils/Patterns.java index a41f828c8..38f5641b0 100644 --- a/src/main/java/de/pixart/messenger/utils/Patterns.java +++ b/src/main/java/de/pixart/messenger/utils/Patterns.java @@ -28,6 +28,12 @@ import java.util.regex.Pattern; * Commonly used regular expression patterns. */ public class Patterns { + public static final Pattern XMPP_PATTERN = Pattern + .compile("xmpp\\:(?:(?:[" + + Patterns.GOOD_IRI_CHAR + + "\\;\\/\\?\\@\\&\\=\\#\\~\\-\\.\\+\\!\\*\\'\\(\\)\\,\\_])" + + "|(?:\\%[a-fA-F0-9]{2}))+"); + /** * Regular expression to match all IANA top-level domains. * List accurate as of 2011/07/18. List taken from: diff --git a/src/main/java/de/pixart/messenger/utils/XmppUri.java b/src/main/java/de/pixart/messenger/utils/XmppUri.java index 9ab3f1769..04b9f1d93 100644 --- a/src/main/java/de/pixart/messenger/utils/XmppUri.java +++ b/src/main/java/de/pixart/messenger/utils/XmppUri.java @@ -1,6 +1,7 @@ package de.pixart.messenger.utils; import android.net.Uri; +import android.util.Log; import java.io.UnsupportedEncodingException; import java.net.URLDecoder; @@ -8,6 +9,7 @@ import java.util.ArrayList; import java.util.List; import java.util.Locale; +import de.pixart.messenger.Config; import rocks.xmpp.addr.Jid; public class XmppUri { @@ -64,8 +66,9 @@ public class XmppUri { if (segments.size() >= 2 && segments.get(1).contains("@")) { // sample : https://conversations.im/i/foo@bar.com try { - jid = Jid.of(segments.get(1)).toString(); + 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) { @@ -261,4 +264,12 @@ public class XmppUri { return type.toString() + ": " + fingerprint + (deviceId != 0 ? " " + String.valueOf(deviceId) : ""); } } + + public static String lameUrlDecode(String url) { + return url.replace("%23", "#").replace("%25", "%"); + } + + public static String lameUrlEncode(String url) { + return url.replace("%", "%25").replace("#", "%23"); + } } diff --git a/src/main/res/menu/message_context.xml b/src/main/res/menu/message_context.xml index 66b26d907..84ed0fb9f 100644 --- a/src/main/res/menu/message_context.xml +++ b/src/main/res/menu/message_context.xml @@ -9,6 +9,10 @@ android:id="@+id/copy_message" android:title="@string/copy_to_clipboard" android:visible="false" /> + Search messages GIF View conversation + web address + Copied JID to clipboard + Copy JID + Copy web address -- cgit v1.2.3