aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChristian Schneppe <christian@pix-art.de>2018-04-07 22:59:43 +0200
committerChristian Schneppe <christian@pix-art.de>2018-04-07 22:59:43 +0200
commit19e8116742267235a222b83abbc99ad2ce5d2895 (patch)
tree00d9e62e298b84d9c3f21732d396676d749ad018
parent6b3e3a0831099c84def024a5bfe6036c2c53b04a (diff)
detect irregular unicode in domain part
-rw-r--r--src/main/java/de/pixart/messenger/ui/ContactDetailsActivity.java4
-rw-r--r--src/main/java/de/pixart/messenger/ui/TrustKeysActivity.java4
-rw-r--r--src/main/java/de/pixart/messenger/ui/adapter/ListItemAdapter.java4
-rw-r--r--src/main/java/de/pixart/messenger/utils/IrregularUnicodeDetector.java (renamed from src/main/java/de/pixart/messenger/utils/IrregularUnicodeBlockDetector.java)110
4 files changed, 86 insertions, 36 deletions
diff --git a/src/main/java/de/pixart/messenger/ui/ContactDetailsActivity.java b/src/main/java/de/pixart/messenger/ui/ContactDetailsActivity.java
index 984a9c58a..4726922bf 100644
--- a/src/main/java/de/pixart/messenger/ui/ContactDetailsActivity.java
+++ b/src/main/java/de/pixart/messenger/ui/ContactDetailsActivity.java
@@ -44,7 +44,7 @@ import de.pixart.messenger.entities.ListItem;
import de.pixart.messenger.services.XmppConnectionService.OnAccountUpdate;
import de.pixart.messenger.services.XmppConnectionService.OnRosterUpdate;
import de.pixart.messenger.utils.CryptoHelper;
-import de.pixart.messenger.utils.IrregularUnicodeBlockDetector;
+import de.pixart.messenger.utils.IrregularUnicodeDetector;
import de.pixart.messenger.utils.Namespace;
import de.pixart.messenger.utils.TimeframeUtils;
import de.pixart.messenger.utils.UIHelper;
@@ -509,7 +509,7 @@ public class ContactDetailsActivity extends OmemoActivity implements OnAccountUp
}
}
- binding.detailsContactjid.setText(IrregularUnicodeBlockDetector.style(this, contact.getJid()));
+ binding.detailsContactjid.setText(IrregularUnicodeDetector.style(this, contact.getJid()));
String account;
if (Config.DOMAIN_LOCK != null) {
account = contact.getAccount().getJid().getLocal();
diff --git a/src/main/java/de/pixart/messenger/ui/TrustKeysActivity.java b/src/main/java/de/pixart/messenger/ui/TrustKeysActivity.java
index d401a3c39..1f408138d 100644
--- a/src/main/java/de/pixart/messenger/ui/TrustKeysActivity.java
+++ b/src/main/java/de/pixart/messenger/ui/TrustKeysActivity.java
@@ -31,7 +31,7 @@ import de.pixart.messenger.databinding.KeysCardBinding;
import de.pixart.messenger.entities.Account;
import de.pixart.messenger.entities.Conversation;
import de.pixart.messenger.utils.CryptoHelper;
-import de.pixart.messenger.utils.IrregularUnicodeBlockDetector;
+import de.pixart.messenger.utils.IrregularUnicodeDetector;
import de.pixart.messenger.utils.XmppUri;
import de.pixart.messenger.xmpp.OnKeyStatusUpdated;
import rocks.xmpp.addr.Jid;
@@ -191,7 +191,7 @@ public class TrustKeysActivity extends OmemoActivity implements OnKeyStatusUpdat
hasForeignKeys = true;
KeysCardBinding keysCardBinding = DataBindingUtil.inflate(getLayoutInflater(),R.layout.keys_card, binding.foreignKeys,false);
final Jid jid = entry.getKey();
- keysCardBinding.foreignKeysTitle.setText(IrregularUnicodeBlockDetector.style(this, jid));
+ keysCardBinding.foreignKeysTitle.setText(IrregularUnicodeDetector.style(this, jid));
keysCardBinding.foreignKeysTitle.setOnClickListener(v -> switchToContactDetails(mAccount.getRoster().getContact(jid)));
final Map<String, Boolean> fingerprints = entry.getValue();
for (final String fingerprint : fingerprints.keySet()) {
diff --git a/src/main/java/de/pixart/messenger/ui/adapter/ListItemAdapter.java b/src/main/java/de/pixart/messenger/ui/adapter/ListItemAdapter.java
index 821483f33..432bc0d4b 100644
--- a/src/main/java/de/pixart/messenger/ui/adapter/ListItemAdapter.java
+++ b/src/main/java/de/pixart/messenger/ui/adapter/ListItemAdapter.java
@@ -27,7 +27,7 @@ import de.pixart.messenger.databinding.ContactBinding;
import de.pixart.messenger.entities.ListItem;
import de.pixart.messenger.ui.SettingsActivity;
import de.pixart.messenger.ui.XmppActivity;
-import de.pixart.messenger.utils.IrregularUnicodeBlockDetector;
+import de.pixart.messenger.utils.IrregularUnicodeDetector;
import de.pixart.messenger.utils.UIHelper;
import rocks.xmpp.addr.Jid;
@@ -92,7 +92,7 @@ public class ListItemAdapter extends ArrayAdapter<ListItem> {
final Jid jid = item.getJid();
if (jid != null) {
viewHolder.jid.setVisibility(View.VISIBLE);
- viewHolder.jid.setText(IrregularUnicodeBlockDetector.style(activity, jid));
+ viewHolder.jid.setText(IrregularUnicodeDetector.style(activity, jid));
} else {
viewHolder.jid.setVisibility(View.GONE);
}
diff --git a/src/main/java/de/pixart/messenger/utils/IrregularUnicodeBlockDetector.java b/src/main/java/de/pixart/messenger/utils/IrregularUnicodeDetector.java
index c1e4ba88b..2e7f221c9 100644
--- a/src/main/java/de/pixart/messenger/utils/IrregularUnicodeBlockDetector.java
+++ b/src/main/java/de/pixart/messenger/utils/IrregularUnicodeDetector.java
@@ -53,12 +53,13 @@ import de.pixart.messenger.R;
import de.pixart.messenger.ui.util.Color;
import rocks.xmpp.addr.Jid;
-public class IrregularUnicodeBlockDetector {
+public class IrregularUnicodeDetector {
- private static final Map<Character.UnicodeBlock,Character.UnicodeBlock> NORMALIZATION_MAP;
+ private static final Map<Character.UnicodeBlock, Character.UnicodeBlock> NORMALIZATION_MAP;
+ private static final LruCache<Jid, PatternTuple> CACHE = new LruCache<>(100);
static {
- Map<Character.UnicodeBlock,Character.UnicodeBlock> temp = new HashMap<>();
+ Map<Character.UnicodeBlock, Character.UnicodeBlock> temp = new HashMap<>();
temp.put(Character.UnicodeBlock.LATIN_1_SUPPLEMENT, Character.UnicodeBlock.BASIC_LATIN);
NORMALIZATION_MAP = Collections.unmodifiableMap(temp);
}
@@ -71,27 +72,31 @@ public class IrregularUnicodeBlockDetector {
}
}
- private static final LruCache<Jid, Pattern> CACHE = new LruCache<>(100);
-
public static Spannable style(Context context, Jid jid) {
return style(jid, Color.get(context, R.attr.color_warning));
}
private static Spannable style(Jid jid, @ColorInt int color) {
+ PatternTuple patternTuple = find(jid);
SpannableStringBuilder builder = new SpannableStringBuilder();
- if (jid.getLocal() != null) {
+ if (jid.getLocal() != null && patternTuple.local != null) {
SpannableString local = new SpannableString(jid.getLocal());
- Matcher matcher = find(jid).matcher(local);
- while (matcher.find()) {
- if (matcher.start() < matcher.end()) {
- local.setSpan(new ForegroundColorSpan(color), matcher.start(), matcher.end(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
- }
- }
+ colorize(local, patternTuple.local, color);
builder.append(local);
builder.append('@');
}
if (jid.getDomain() != null) {
- builder.append(jid.getDomain());
+ int i = jid.getDomain().lastIndexOf('.');
+ if (i != -1) {
+ String second = jid.getDomain().substring(0, i);
+ String top = jid.getDomain().substring(i, jid.getDomain().length());
+ SpannableString secondSpannableString = new SpannableString(second);
+ colorize(secondSpannableString, patternTuple.domain, color);
+ builder.append(secondSpannableString);
+ builder.append(top);
+ } else {
+ builder.append(jid.getDomain());
+ }
}
if (builder.length() != 0 && jid.getResource() != null) {
builder.append('/');
@@ -100,12 +105,20 @@ public class IrregularUnicodeBlockDetector {
return builder;
}
- private static Map<Character.UnicodeBlock, List<String>> mapCompat(Jid jid) {
+ private static void colorize(SpannableString spannableString, Pattern pattern, @ColorInt int color) {
+ Matcher matcher = pattern.matcher(spannableString);
+ while (matcher.find()) {
+ if (matcher.start() < matcher.end()) {
+ spannableString.setSpan(new ForegroundColorSpan(color), matcher.start(), matcher.end(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
+ }
+ }
+ }
+
+ private static Map<Character.UnicodeBlock, List<String>> mapCompat(String word) {
Map<Character.UnicodeBlock, List<String>> map = new HashMap<>();
- String local = jid.getLocal();
- final int length = local.length();
+ final int length = word.length();
for (int offset = 0; offset < length; ) {
- final int codePoint = local.codePointAt(offset);
+ final int codePoint = word.codePointAt(offset);
Character.UnicodeBlock block = normalize(Character.UnicodeBlock.of(codePoint));
List<String> codePoints;
if (map.containsKey(block)) {
@@ -121,12 +134,11 @@ public class IrregularUnicodeBlockDetector {
}
@TargetApi(Build.VERSION_CODES.N)
- private static Map<Character.UnicodeScript, List<String>> map(Jid jid) {
+ private static Map<Character.UnicodeScript, List<String>> map(String word) {
Map<Character.UnicodeScript, List<String>> map = new HashMap<>();
- String local = jid.getLocal();
- final int length = local.length();
+ final int length = word.length();
for (int offset = 0; offset < length; ) {
- final int codePoint = local.codePointAt(offset);
+ final int codePoint = word.codePointAt(offset);
Character.UnicodeScript script = Character.UnicodeScript.of(codePoint);
if (script != Character.UnicodeScript.COMMON) {
List<String> codePoints;
@@ -169,19 +181,24 @@ public class IrregularUnicodeBlockDetector {
return all;
}
- private static Pattern find(Jid jid) {
+ private static Set<String> findIrregularCodePoints(String word) {
+ Set<String> codePoints;
+ if (Build.VERSION.SDK_INT < Build.VERSION_CODES.N) {
+ codePoints = eliminateFirstAndGetCodePointsCompat(mapCompat(word));
+ } else {
+ codePoints = eliminateFirstAndGetCodePoints(map(word));
+ }
+ return codePoints;
+ }
+
+ private static PatternTuple find(Jid jid) {
synchronized (CACHE) {
- Pattern pattern = CACHE.get(jid);
+ PatternTuple pattern = CACHE.get(jid);
if (pattern != null) {
return pattern;
}
- Set<String> codePoints;
- if (Build.VERSION.SDK_INT < Build.VERSION_CODES.N) {
- codePoints = eliminateFirstAndGetCodePointsCompat(mapCompat(jid));
- } else {
- codePoints = eliminateFirstAndGetCodePoints(map(jid));
- }
- pattern = create(codePoints);
+ ;
+ pattern = PatternTuple.of(jid);
CACHE.put(jid, pattern);
return pattern;
}
@@ -197,4 +214,37 @@ public class IrregularUnicodeBlockDetector {
}
return Pattern.compile(pattern.toString());
}
+
+ private static class PatternTuple {
+ private final Pattern local;
+ private final Pattern domain;
+
+ private PatternTuple(Pattern local, Pattern domain) {
+ this.local = local;
+ this.domain = domain;
+ }
+
+ private static PatternTuple of(Jid jid) {
+ final Pattern localPattern;
+ if (jid.getLocal() != null) {
+ localPattern = create(findIrregularCodePoints(jid.getLocal()));
+ } else {
+ localPattern = null;
+ }
+ String domain = jid.getDomain();
+ final Pattern domainPattern;
+ if (domain != null) {
+ int i = domain.lastIndexOf('.');
+ if (i != -1) {
+ String secondLevel = domain.substring(0, i);
+ domainPattern = create(findIrregularCodePoints(secondLevel));
+ } else {
+ domainPattern = null;
+ }
+ } else {
+ domainPattern = null;
+ }
+ return new PatternTuple(localPattern, domainPattern);
+ }
+ }
} \ No newline at end of file