OSDN Git Service

RESTRICT AUTOMERGE Do not linkify text with RLO/LRO characters.
authorTony Mak <tonymak@google.com>
Thu, 29 Nov 2018 17:37:42 +0000 (17:37 +0000)
committerAbodunrinwa Toki <toki@google.com>
Thu, 3 Jan 2019 17:10:46 +0000 (17:10 +0000)
Also don't show smart actions for selections in text with unsupported
characters.

Bug: 116321860
Test: runtest -x cts/tests/tests/text/src/android/text/util/cts/LinkifyTest.java
Change-Id: Ib2ee544b5783234fba8ee2f93adf0b36b039520f
Merged-In: Ib2ee544b5783234fba8ee2f93adf0b36b039520f

core/java/android/text/util/Linkify.java
core/java/android/view/textclassifier/TextClassification.java
core/java/android/widget/SelectionActionModeHelper.java
core/tests/coretests/src/android/widget/TextViewActivityTest.java

index 7e6eb49..63929ea 100644 (file)
@@ -26,6 +26,7 @@ import android.text.Spanned;
 import android.text.method.LinkMovementMethod;
 import android.text.method.MovementMethod;
 import android.text.style.URLSpan;
+import android.util.Log;
 import android.util.Patterns;
 import android.webkit.WebView;
 import android.widget.TextView;
@@ -64,6 +65,9 @@ import java.util.regex.Pattern;
  */
 
 public class Linkify {
+
+    private static final String LOG_TAG = "Linkify";
+
     /**
      *  Bit field indicating that web URLs should be matched in methods that
      *  take an options mask
@@ -221,6 +225,11 @@ public class Linkify {
      *  @return True if at least one link is found and applied.
      */
     public static final boolean addLinks(@NonNull Spannable text, @LinkifyMask int mask) {
+        if (text != null && containsUnsupportedCharacters(text.toString())) {
+            android.util.EventLog.writeEvent(0x534e4554, "116321860", -1, "");
+            return false;
+        }
+
         if (mask == 0) {
             return false;
         }
@@ -267,6 +276,29 @@ public class Linkify {
     }
 
     /**
+     * Returns true if the specified text contains at least one unsupported character for applying
+     * links. Also logs the error.
+     *
+     * @param text the text to apply links to
+     * @hide
+     */
+    public static boolean containsUnsupportedCharacters(String text) {
+        if (text.contains("\u202C")) {
+            Log.e(LOG_TAG, "Unsupported character for applying links: u202C");
+            return true;
+        }
+        if (text.contains("\u202D")) {
+            Log.e(LOG_TAG, "Unsupported character for applying links: u202D");
+            return true;
+        }
+        if (text.contains("\u202E")) {
+            Log.e(LOG_TAG, "Unsupported character for applying links: u202E");
+            return true;
+        }
+        return false;
+    }
+
+    /**
      *  Scans the text of the provided TextView and turns all occurrences of
      *  the link types indicated in the mask into clickable links.  If matches
      *  are found the movement method for the TextView is set to
@@ -413,6 +445,10 @@ public class Linkify {
     public static final boolean addLinks(@NonNull Spannable spannable, @NonNull Pattern pattern,
             @Nullable String scheme, @Nullable MatchFilter matchFilter,
             @Nullable TransformFilter transformFilter) {
+        if (spannable != null && containsUnsupportedCharacters(spannable.toString())) {
+            android.util.EventLog.writeEvent(0x534e4554, "116321860", -1, "");
+            return false;
+        }
         return addLinks(spannable, pattern, scheme, null, matchFilter,
                 transformFilter);
     }
index b6dd0b9..961e15b 100644 (file)
@@ -38,7 +38,7 @@ public final class TextClassification {
     /**
      * @hide
      */
-    static final TextClassification EMPTY = new TextClassification.Builder().build();
+    public static final TextClassification EMPTY = new TextClassification.Builder().build();
 
     @NonNull private final String mText;
     @Nullable private final Drawable mIcon;
index 227ef4c..72d87ee 100644 (file)
@@ -25,6 +25,7 @@ import android.os.LocaleList;
 import android.text.Selection;
 import android.text.Spannable;
 import android.text.TextUtils;
+import android.text.util.Linkify;
 import android.view.ActionMode;
 import android.view.textclassifier.TextClassification;
 import android.view.textclassifier.TextClassifier;
@@ -454,11 +455,19 @@ final class SelectionActionModeHelper {
                 mLastClassificationLocales = mLocales;
 
                 trimText();
+                final TextClassification classification;
+                if (Linkify.containsUnsupportedCharacters(mText)) {
+                    // Do not show smart actions for text containing unsupported characters.
+                    android.util.EventLog.writeEvent(0x534e4554, "116321860", -1, "");
+                    classification = TextClassification.EMPTY;
+                } else {
+                    classification = mTextClassifier.classifyText(
+                            mTrimmedText, mRelativeStart, mRelativeEnd, mLocales);
+                }
                 mLastClassificationResult = new SelectionResult(
                         mSelectionStart,
                         mSelectionEnd,
-                        mTextClassifier.classifyText(
-                                mTrimmedText, mRelativeStart, mRelativeEnd, mLocales));
+                        classification);
 
             }
             return mLastClassificationResult;
index 5a7bca4..a4f6987 100644 (file)
@@ -761,6 +761,7 @@ public class TextViewActivityTest extends ActivityInstrumentationTestCase2<TextV
                     public void onDestroyActionMode(ActionMode actionMode) {
                     }
                 }));
+        getInstrumentation().waitForIdleSync();
         final String text = "droid@android.com";
 
         onView(withId(R.id.textview)).perform(replaceText(text));
@@ -769,6 +770,18 @@ public class TextViewActivityTest extends ActivityInstrumentationTestCase2<TextV
         assertFloatingToolbarItemIndex(android.R.id.textAssist, 0);
     }
 
+    public void testNoAssistItemForTextFieldWithUnsupportedCharacters() throws Throwable {
+        getActivity().getSystemService(TextClassificationManager.class).setTextClassifier(null);
+        final String text = "\u202Emoc.diordna.com";
+        final TextView textView = getActivity().findViewById(R.id.textview);
+        textView.post(() -> textView.setText(text));
+        getInstrumentation().waitForIdleSync();
+
+        onView(withId(R.id.textview)).perform(longPressOnTextAtIndex(text.indexOf('.')));
+        sleepForFloatingToolbarPopup();
+        assertFloatingToolbarItemIndex(android.R.id.cut, 0);
+    }
+
     public void testPastePlainText_menuAction() throws Exception {
         initializeClipboardWithText(TextStyle.STYLED);