diff options
author | Christian Schneppe <christian@pix-art.de> | 2018-04-07 22:59:43 +0200 |
---|---|---|
committer | Christian Schneppe <christian@pix-art.de> | 2018-04-07 22:59:43 +0200 |
commit | 19e8116742267235a222b83abbc99ad2ce5d2895 (patch) | |
tree | 00d9e62e298b84d9c3f21732d396676d749ad018 | |
parent | 6b3e3a0831099c84def024a5bfe6036c2c53b04a (diff) |
detect irregular unicode in domain part
-rw-r--r-- | src/main/java/de/pixart/messenger/ui/ContactDetailsActivity.java | 4 | ||||
-rw-r--r-- | src/main/java/de/pixart/messenger/ui/TrustKeysActivity.java | 4 | ||||
-rw-r--r-- | src/main/java/de/pixart/messenger/ui/adapter/ListItemAdapter.java | 4 | ||||
-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 |