Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 5932e8b8 authored by Siyamed Sinir's avatar Siyamed Sinir
Browse files

Update autoLink URL regex to match empty path, $ and _

Update URL regular expression to match
- path and query that contains dollar sign
- domain name that contains underscore
- empty path with query parameters. i.e. a.com?q=v

Bug: 27436084
Bug: 27501264
Change-Id: I3884624e145ccc1175915327dc2f280ef4e55ce1
parent 6a150faa
Loading
Loading
Loading
Loading
+5 −5
Original line number Diff line number Diff line
@@ -287,7 +287,7 @@ public class Patterns {
     * RFC 1035 Section 2.3.4 limits the labels to a maximum 63 octets.
     */
    private static final String IRI_LABEL =
            "[" + LABEL_CHAR + "](?:[" + LABEL_CHAR + "\\-]{0,61}[" + LABEL_CHAR + "]){0,1}";
            "[" + LABEL_CHAR + "](?:[" + LABEL_CHAR + "_\\-]{0,61}[" + LABEL_CHAR + "]){0,1}";

    /**
     * RFC 3492 references RFC 1034 and limits Punycode algorithm output to 63 characters.
@@ -301,7 +301,7 @@ public class Patterns {
    public static final Pattern DOMAIN_NAME
        = Pattern.compile("(" + HOST_NAME + "|" + IP_ADDRESS + ")");

    private static final String PROTOCOL = "(?i:http|https|rtsp):\\/\\/";
    private static final String PROTOCOL = "(?i:http|https|rtsp)://";

    /* A word boundary or end of input.  This is to stop foo.sure from matching as foo.su */
    private static final String WORD_BOUNDARY = "(?:\\b|$|^)";
@@ -312,9 +312,9 @@ public class Patterns {

    private static final String PORT_NUMBER = "\\:\\d{1,5}";

    private static final String PATH_AND_QUERY = "\\/(?:(?:[" + LABEL_CHAR
            + "\\;\\/\\?\\:\\@\\&\\=\\#\\~"  // plus optional query params
            + "\\-\\.\\+\\!\\*\\'\\(\\)\\,\\_])|(?:\\%[a-fA-F0-9]{2}))*";
    private static final String PATH_AND_QUERY = "[/\\?](?:(?:[" + LABEL_CHAR
            + ";/\\?:@&=#~"  // plus optional query params
            + "\\-\\.\\+!\\*'\\(\\),_\\$])|(?:%[a-fA-F0-9]{2}))*";

    /**
     *  Regular expression pattern to match most part of RFC 3987
+157 −9
Original line number Diff line number Diff line
@@ -16,7 +16,6 @@
package android.util;

import android.test.suitebuilder.annotation.SmallTest;
import android.test.suitebuilder.annotation.Suppress;

import java.util.regex.Matcher;
import java.util.regex.Pattern;
@@ -131,7 +130,6 @@ public class PatternsTest extends TestCase {
                Patterns.WEB_URL.matcher(url).matches());
    }


    @SmallTest
    public void testWebUrl_matchesArabicPunycodeUrlWithProtocol() throws Exception {
        String url = "http://xn--4gbrim.xn----rmckbbajlc6dj7bxne2c.xn--wgbh1c/ar/default.aspx";
@@ -208,6 +206,58 @@ public class PatternsTest extends TestCase {
                Patterns.WEB_URL.matcher(url).matches());
    }

    @SmallTest
    public void testWebUrl_matchesDomainNameWithDash() throws Exception {
        String url = "http://a-nd.r-oid.com";
        assertTrue("Should match dash in domain name",
                Patterns.WEB_URL.matcher(url).matches());

        url = "a-nd.r-oid.com";
        assertTrue("Should match dash in domain name",
                Patterns.WEB_URL.matcher(url).matches());
    }

    @SmallTest
    public void testWebUrl_matchesDomainNameWithUnderscore() throws Exception {
        String url = "http://a_nd.r_oid.com";
        assertTrue("Should match underscore in domain name",
                Patterns.WEB_URL.matcher(url).matches());

        url = "a_nd.r_oid.com";
        assertTrue("Should match underscore in domain name",
                Patterns.WEB_URL.matcher(url).matches());
    }

    @SmallTest
    public void testWebUrl_matchesPathAndQueryWithDollarSign() throws Exception {
        String url = "http://android.com/path$?v=$val";
        assertTrue("Should match dollar sign in path/query",
                Patterns.WEB_URL.matcher(url).matches());

        url = "android.com/path$?v=$val";
        assertTrue("Should match dollar sign in path/query",
                Patterns.WEB_URL.matcher(url).matches());
    }

    @SmallTest
    public void testWebUrl_matchesEmptyPathWithQueryParams() throws Exception {
        String url = "http://android.com?q=v";
        assertTrue("Should match empty path with query param",
                Patterns.WEB_URL.matcher(url).matches());

        url = "android.com?q=v";
        assertTrue("Should match empty path with query param",
                Patterns.WEB_URL.matcher(url).matches());

        url = "http://android.com/?q=v";
        assertTrue("Should match empty path with query param",
                Patterns.WEB_URL.matcher(url).matches());

        url = "android.com/?q=v";
        assertTrue("Should match empty path with query param",
                Patterns.WEB_URL.matcher(url).matches());
    }

    // Tests for Patterns.AUTOLINK_WEB_URL

    @SmallTest
@@ -354,13 +404,6 @@ public class PatternsTest extends TestCase {
                Patterns.AUTOLINK_WEB_URL.matcher(url).matches());
    }

    @SmallTest
    public void testAutoLinkWebUrl_doesNotMatchUrlWithInvalidRequestParameter() throws Exception {
        String url = "http://android.com?p=value";
        assertFalse("Should not match URL with invalid request parameter",
                Patterns.AUTOLINK_WEB_URL.matcher(url).matches());
    }

    @SmallTest
    public void testAutoLinkWebUrl_doesNotPartiallyMatchUnknownProtocol() throws Exception {
        String url = "ftp://foo.bar/baz";
@@ -449,6 +492,58 @@ public class PatternsTest extends TestCase {
        }
    }

    @SmallTest
    public void testAutoLinkWebUrl_matchesDomainNameWithDash() throws Exception {
        String url = "http://a-nd.r-oid.com";
        assertTrue("Should match dash in domain name",
                Patterns.AUTOLINK_WEB_URL.matcher(url).matches());

        url = "a-nd.r-oid.com";
        assertTrue("Should match dash in domain name",
                Patterns.AUTOLINK_WEB_URL.matcher(url).matches());
    }

    @SmallTest
    public void testAutoLinkWebUrl_matchesDomainNameWithUnderscore() throws Exception {
        String url = "http://a_nd.r_oid.com";
        assertTrue("Should match underscore in domain name",
                Patterns.AUTOLINK_WEB_URL.matcher(url).matches());

        url = "a_nd.r_oid.com";
        assertTrue("Should match underscore in domain name",
                Patterns.AUTOLINK_WEB_URL.matcher(url).matches());
    }

    @SmallTest
    public void testAutoLinkWebUrl_matchesPathAndQueryWithDollarSign() throws Exception {
        String url = "http://android.com/path$?v=$val";
        assertTrue("Should match dollar sign in path/query",
                Patterns.AUTOLINK_WEB_URL.matcher(url).matches());

        url = "android.com/path$?v=$val";
        assertTrue("Should match dollar sign in path/query",
                Patterns.AUTOLINK_WEB_URL.matcher(url).matches());
    }

    @SmallTest
    public void testAutoLinkWebUrl_matchesEmptyPathWithQueryParams() throws Exception {
        String url = "http://android.com?q=v";
        assertTrue("Should match empty path with query param",
                Patterns.AUTOLINK_WEB_URL.matcher(url).matches());

        url = "android.com?q=v";
        assertTrue("Should match empty path with query param",
                Patterns.AUTOLINK_WEB_URL.matcher(url).matches());

        url = "http://android.com/?q=v";
        assertTrue("Should match empty path with query param",
                Patterns.AUTOLINK_WEB_URL.matcher(url).matches());

        url = "android.com/?q=v";
        assertTrue("Should match empty path with query param",
                Patterns.AUTOLINK_WEB_URL.matcher(url).matches());
    }

    // Tests for Patterns.IP_ADDRESS

    @SmallTest
@@ -538,110 +633,150 @@ public class PatternsTest extends TestCase {
                Patterns.DOMAIN_NAME.matcher(domain).matches());
    }

    @SmallTest
    public void testDomain_matchesDomainNameWithDash() throws Exception {
        String url = "http://a-nd.r-oid.com";
        assertTrue("Should match dash in domain name",
                Patterns.AUTOLINK_WEB_URL.matcher(url).matches());

        url = "a-nd.r-oid.com";
        assertTrue("Should match dash in domain name",
                Patterns.AUTOLINK_WEB_URL.matcher(url).matches());
    }

    @SmallTest
    public void testDomain_matchesDomainNameWithUnderscore() throws Exception {
        String url = "http://a_nd.r_oid.com";
        assertTrue("Should match underscore in domain name",
                Patterns.AUTOLINK_WEB_URL.matcher(url).matches());

        url = "a_nd.r_oid.com";
        assertTrue("Should match underscore in domain name",
                Patterns.AUTOLINK_WEB_URL.matcher(url).matches());
    }

    // Tests for Patterns.AUTOLINK_EMAIL_ADDRESS

    @SmallTest
    public void testAutoLinkEmailAddress_matchesShortValidEmail() throws Exception {
        String email = "a@a.co";
        assertTrue("Should match short valid email: " + email,
                Patterns.AUTOLINK_EMAIL_ADDRESS.matcher(email).matches());
    }

    @SmallTest
    public void testAutoLinkEmailAddress_matchesRegularEmail() throws Exception {
        String email = "email@android.com";
        assertTrue("Should match email: " + email,
                Patterns.AUTOLINK_EMAIL_ADDRESS.matcher(email).matches());
    }

    @SmallTest
    public void testAutoLinkEmailAddress_matchesEmailWithMultipleSubdomains() throws Exception {
        String email = "email@e.somelongdomainnameforandroid.abc.uk";
        assertTrue("Should match email: " + email,
                Patterns.AUTOLINK_EMAIL_ADDRESS.matcher(email).matches());
    }

    @SmallTest
    public void testAutoLinkEmailAddress_matchesLocalPartWithDot() throws Exception {
        String email = "e.mail@android.com";
        assertTrue("Should match email: " + email,
                Patterns.AUTOLINK_EMAIL_ADDRESS.matcher(email).matches());
    }

    @SmallTest
    public void testAutoLinkEmailAddress_matchesLocalPartWithPlus() throws Exception {
        String email = "e+mail@android.com";
        assertTrue("Should match email: " + email,
                Patterns.AUTOLINK_EMAIL_ADDRESS.matcher(email).matches());
    }

    @SmallTest
    public void testAutoLinkEmailAddress_matchesLocalPartWithUnderscore() throws Exception {
        String email = "e_mail@android.com";
        assertTrue("Should match email: " + email,
                Patterns.AUTOLINK_EMAIL_ADDRESS.matcher(email).matches());
    }

    @SmallTest
    public void testAutoLinkEmailAddress_matchesLocalPartWithDash() throws Exception {
        String email = "e-mail@android.com";
        assertTrue("Should match email: " + email,
                Patterns.AUTOLINK_EMAIL_ADDRESS.matcher(email).matches());
    }

    @SmallTest
    public void testAutoLinkEmailAddress_matchesLocalPartWithApostrophe() throws Exception {
        String email = "e'mail@android.com";
        assertTrue("Should match email: " + email,
                Patterns.AUTOLINK_EMAIL_ADDRESS.matcher(email).matches());
    }

    @SmallTest
    public void testAutoLinkEmailAddress_matchesLocalPartWithDigits() throws Exception {
        String email = "123@android.com";
        assertTrue("Should match email: " + email,
                Patterns.AUTOLINK_EMAIL_ADDRESS.matcher(email).matches());
    }

    @SmallTest
    public void testAutoLinkEmailAddress_matchesUnicodeLocalPart() throws Exception {
        String email = "\uD604\uAE08\uC601\uC218\uC99D@android.kr";
        assertTrue("Should match email: " + email,
                Patterns.AUTOLINK_EMAIL_ADDRESS.matcher(email).matches());
    }

    @SmallTest
    public void testAutoLinkEmailAddress_matchesLocalPartWithEmoji() throws Exception {
        String email = "smiley\u263A@android.com";
        assertTrue("Should match email: " + email,
                Patterns.AUTOLINK_EMAIL_ADDRESS.matcher(email).matches());
    }

    @SmallTest
    public void testAutoLinkEmailAddress_matchesLocalPartWithSurrogatePairs() throws Exception {
        String email = "\uD83C\uDF38@android.com";
        assertTrue("Should match email: " + email,
                Patterns.AUTOLINK_EMAIL_ADDRESS.matcher(email).matches());
    }

    @SmallTest
    public void testAutoLinkEmailAddress_matchesDomainWithDash() throws Exception {
        String email = "email@an-droid.com";
        assertTrue("Should match email: " + email,
                Patterns.AUTOLINK_EMAIL_ADDRESS.matcher(email).matches());
    }

    @SmallTest
    public void testAutoLinkEmailAddress_matchesUnicodeDomain() throws Exception {
        String email = "email@\uD604\uAE08\uC601\uC218\uC99D.kr";
        assertTrue("Should match email: " + email,
                Patterns.AUTOLINK_EMAIL_ADDRESS.matcher(email).matches());
    }

    @SmallTest
    public void testAutoLinkEmailAddress_matchesUnicodeLocalPartAndDomain() throws Exception {
        String email = "\uD604\uAE08\uC601\uC218\uC99D@\uD604\uAE08\uC601\uC218\uC99D.kr";
        assertTrue("Should match email: " + email,
                Patterns.AUTOLINK_EMAIL_ADDRESS.matcher(email).matches());
    }

    @SmallTest
    public void testAutoLinkEmailAddress_matchesDomainWithEmoji() throws Exception {
        String email = "smiley@\u263Aandroid.com";
        assertTrue("Should match email: " + email,
                Patterns.AUTOLINK_EMAIL_ADDRESS.matcher(email).matches());
    }

    @SmallTest
    public void testAutoLinkEmailAddress_matchesDomainWithSurrogatePairs() throws Exception {
        String email = "email@\uD83C\uDF38android.com";
        assertTrue("Should match email: " + email,
                Patterns.AUTOLINK_EMAIL_ADDRESS.matcher(email).matches());
    }

    @SmallTest
    public void testAutoLinkEmailAddress_matchesLocalPartAndDomainWithSurrogatePairs()
            throws Exception {
        String email = "\uD83C\uDF38@\uD83C\uDF38android.com";
@@ -649,66 +784,77 @@ public class PatternsTest extends TestCase {
                Patterns.AUTOLINK_EMAIL_ADDRESS.matcher(email).matches());
    }

    @SmallTest
    public void testAutoLinkEmailAddress_doesNotMatchStringWithoutAtSign() throws Exception {
        String email = "android.com";
        assertFalse("Should not match email: " + email,
                Patterns.AUTOLINK_EMAIL_ADDRESS.matcher(email).matches());
    }

    @SmallTest
    public void testAutoLinkEmailAddress_doesNotMatchPlainString() throws Exception {
        String email = "email";
        assertFalse("Should not match email: " + email,
                Patterns.AUTOLINK_EMAIL_ADDRESS.matcher(email).matches());
    }

    @SmallTest
    public void testAutoLinkEmailAddress_doesNotMatchStringWithMultipleAtSigns() throws Exception {
        String email = "email@android@android.com";
        assertFalse("Should not match email: " + email,
                Patterns.AUTOLINK_EMAIL_ADDRESS.matcher(email).matches());
    }

    @SmallTest
    public void testAutoLinkEmailAddress_doesNotMatchEmailWithoutTld() throws Exception {
        String email = "email@android";
        assertFalse("Should not match email: " + email,
                Patterns.AUTOLINK_EMAIL_ADDRESS.matcher(email).matches());
    }

    @SmallTest
    public void testAutoLinkEmailAddress_doesNotMatchLocalPartEndingWithDot() throws Exception {
        String email = "email.@android.com";
        assertFalse("Should not match email: " + email,
                Patterns.AUTOLINK_EMAIL_ADDRESS.matcher(email).matches());
    }

    @SmallTest
    public void testAutoLinkEmailAddress_doesNotMatchLocalPartStartingWithDot() throws Exception {
        String email = ".email@android.com";
        assertFalse("Should not match email: " + email,
                Patterns.AUTOLINK_EMAIL_ADDRESS.matcher(email).matches());
    }

    @SmallTest
    public void testAutoLinkEmailAddress_doesNotMatchDomainStartingWithDash() throws Exception {
        String email = "email@-android.com";
        assertFalse("Should not match email: " + email,
                Patterns.AUTOLINK_EMAIL_ADDRESS.matcher(email).matches());
    }

    @SmallTest
    public void testAutoLinkEmailAddress_doesNotMatchDomainWithConsecutiveDots() throws Exception {
        String email = "email@android..com";
        assertFalse("Should not match email: " + email,
                Patterns.AUTOLINK_EMAIL_ADDRESS.matcher(email).matches());
    }

    @SmallTest
    public void testAutoLinkEmailAddress_doesNotMatchEmailWithIpAsDomain() throws Exception {
        String email = "email@127.0.0.1";
        assertFalse("Should not match email: " + email,
                Patterns.AUTOLINK_EMAIL_ADDRESS.matcher(email).matches());
    }

    @SmallTest
    public void testAutoLinkEmailAddress_doesNotMatchEmailWithInvalidTld() throws Exception {
        String email = "email@android.c";
        assertFalse("Should not match email: " + email,
                Patterns.AUTOLINK_EMAIL_ADDRESS.matcher(email).matches());
    }

    @SmallTest
    public void testAutoLinkEmailAddress_matchesLocalPartUpTo64Chars() throws Exception {
        String localPart = "";
        for (int i = 0; i < 64; i++) {
@@ -724,6 +870,7 @@ public class PatternsTest extends TestCase {
                Patterns.AUTOLINK_EMAIL_ADDRESS.matcher(email).matches());
    }

    @SmallTest
    public void testAutoLinkEmailAddress_matchesSubdomainUpTo63Chars() throws Exception {
        String subdomain = "";
        for (int i = 0; i < 63; i++) {
@@ -740,6 +887,7 @@ public class PatternsTest extends TestCase {
                Patterns.AUTOLINK_EMAIL_ADDRESS.matcher(email).matches());
    }

    @SmallTest
    public void testAutoLinkEmailAddress_matchesDomainUpTo255Chars() throws Exception {
        String longDomain = "";
        while (longDomain.length() <= 250) {