Merge "Only match addresses without zip codes if at the end." into pi-dev
am: 7385a2c5e0

Change-Id: Ia65a52139742464b7d886d239d2670efe594cfbd
diff --git a/compat/src/androidTest/java/androidx/core/text/util/FindAddressTest.java b/compat/src/androidTest/java/androidx/core/text/util/FindAddressTest.java
index 292f5b1..9cfa78a 100644
--- a/compat/src/androidTest/java/androidx/core/text/util/FindAddressTest.java
+++ b/compat/src/androidTest/java/androidx/core/text/util/FindAddressTest.java
@@ -138,6 +138,15 @@
     public void testFullAddressWithoutZipCode() {
         assertIsAddress("1600 Amphitheatre Parkway Mountain View, CA");
         assertIsAddress("201 S. Division St. Suite 500 Ann Arbor, MI");
+
+        // Check that addresses without a zip code are only accepted at the end of the string.
+        // This isn't implied by the documentation but was the case in the old implementation
+        // and fixing this bug creates a lot of false positives while fixing relatively few
+        // false negatives. In these examples, "one point" is parsed as a street and "as" is a
+        // state abbreviation (this is taken from a false positive reported in a bug).
+        Assert.assertTrue(containsAddress("one point I was as"));
+        Assert.assertTrue(containsAddress("At one point I was as ignorant as"));
+        Assert.assertFalse(containsAddress("At one point I was as ignorant as them"));
     }
 
     @Test
diff --git a/compat/src/androidTest/java/androidx/core/text/util/LinkifyCompatTest.java b/compat/src/androidTest/java/androidx/core/text/util/LinkifyCompatTest.java
index 8435df1..4400d22 100644
--- a/compat/src/androidTest/java/androidx/core/text/util/LinkifyCompatTest.java
+++ b/compat/src/androidTest/java/androidx/core/text/util/LinkifyCompatTest.java
@@ -781,12 +781,6 @@
     // ADDRESS RELATED TESTS
 
     @Test
-    public void testFindAddress_withoutZipcode() {
-        final String address = "455 LARKSPUR DRIVE CALIFORNIA SPRINGS CALIFORNIA";
-        verifyAddLinksWithMapAddressSucceeds("Should match map address: " + address, address);
-    }
-
-    @Test
     public void testFindAddress_withZipcode() {
         final String address = "455 LARKSPUR DRIVE CALIFORNIA SPRINGS CALIFORNIA 92826";
         verifyAddLinksWithMapAddressSucceeds("Should match map address: " + address, address);
diff --git a/compat/src/main/java/androidx/core/text/util/FindAddress.java b/compat/src/main/java/androidx/core/text/util/FindAddress.java
index 0602428..916db2b 100644
--- a/compat/src/main/java/androidx/core/text/util/FindAddress.java
+++ b/compat/src/main/java/androidx/core/text/util/FindAddress.java
@@ -466,20 +466,21 @@
 
                     // At this point we've matched a state; try to match a zip code after it.
                     Matcher zipMatcher = sWordRe.matcher(content);
-                    if (zipMatcher.find(stateMatch.end())
-                            && isValidZipCode(zipMatcher.group(0), stateMatch)) {
-                        return zipMatcher.end();
+                    if (zipMatcher.find(stateMatch.end())) {
+                        if (isValidZipCode(zipMatcher.group(0), stateMatch)) {
+                            return zipMatcher.end();
+                        }
+                    } else {
+                        // The content ends with a state but no zip
+                        // code. This is a legal match according to the
+                        // documentation. N.B. This is equivalent to the
+                        // original c++ implementation, which only allowed
+                        // the zip code to be optional at the end of the
+                        // string, which presumably is a bug.  We tried
+                        // relaxing this to work in other places but it
+                        // caused too many false positives.
+                        nonZipMatch = stateMatch.end();
                     }
-                    // The content ends with a state but no zip
-                    // code. This is a legal match according to the
-                    // documentation. N.B. This differs from the
-                    // original c++ implementation, which only allowed
-                    // the zip code to be optional at the end of the
-                    // string, which presumably is a bug.  Now we
-                    // prefer to find a match with a zip code, but
-                    // remember non-zip matches and return them if
-                    // necessary.
-                    nonZipMatch = stateMatch.end();
                 }
             }
         }