Merge pull request #141 from googlei18n/opensource_update_5677

(AUTOMATIC) opensource update
diff --git a/android/src/main/java/com/android/i18n/addressinput/AddressWidget.java b/android/src/main/java/com/android/i18n/addressinput/AddressWidget.java
index e534327..4684341 100644
--- a/android/src/main/java/com/android/i18n/addressinput/AddressWidget.java
+++ b/android/src/main/java/com/android/i18n/addressinput/AddressWidget.java
@@ -442,8 +442,10 @@
     for (RegionData regionData : formController.getRegionData(new LookupKey.Builder(
         KeyType.DATA).build())) {
       String regionKey = regionData.getKey();
+      Log.i(this.toString(), "Looking at regionKey: " + regionKey);
       // ZZ represents an unknown region code.
-      if (!regionKey.equals("ZZ")) {
+      if (!regionKey.equals("ZZ") && !formOptions.isBlacklistedRegion(regionKey)) {
+        Log.i(this.toString(), "Adding " + regionKey);
         String localCountryName = getLocalCountryName(regionKey);
         RegionData country = new RegionData.Builder().setKey(regionKey).setName(
             localCountryName).build();
diff --git a/android/src/main/java/com/android/i18n/addressinput/PlaceDetailsClient.java b/android/src/main/java/com/android/i18n/addressinput/PlaceDetailsClient.java
index e778911..56f31b7 100644
--- a/android/src/main/java/com/android/i18n/addressinput/PlaceDetailsClient.java
+++ b/android/src/main/java/com/android/i18n/addressinput/PlaceDetailsClient.java
@@ -23,7 +23,7 @@
  * (https://developers.google.com/places/web-service/details). Unfortunately, the Google Place
  * Details API for Android does not include a structured representation of the address.
  */
-class PlaceDetailsClient implements PlaceDetailsApi {
+public class PlaceDetailsClient implements PlaceDetailsApi {
 
   private AsyncRequestApi asyncRequestApi;
   private String apiKey;
@@ -32,7 +32,7 @@
 
   private static final String TAG = "PlaceDetailsClient";
 
-  PlaceDetailsClient(String apiKey, AsyncRequestApi asyncRequestApi) {
+  public PlaceDetailsClient(String apiKey, AsyncRequestApi asyncRequestApi) {
     this.asyncRequestApi = asyncRequestApi;
     this.apiKey = apiKey;
   }
diff --git a/common/src/main/java/com/google/i18n/addressinput/common/FormOptions.java b/common/src/main/java/com/google/i18n/addressinput/common/FormOptions.java
index 8956419..0704fc6 100644
--- a/common/src/main/java/com/google/i18n/addressinput/common/FormOptions.java
+++ b/common/src/main/java/com/google/i18n/addressinput/common/FormOptions.java
@@ -179,7 +179,7 @@
       return customFieldOrder.get(regionCode);
     }
 
-    boolean isBlacklistedRegion(String regionCode) {
+    public boolean isBlacklistedRegion(String regionCode) {
       return blacklistedRegions.contains(Util.toUpperCaseLocaleIndependent(regionCode));
     }
   }
diff --git a/cpp/re2.gyp b/cpp/re2.gyp
index 4ac1da1..c17d8b9 100644
--- a/cpp/re2.gyp
+++ b/cpp/re2.gyp
@@ -13,7 +13,7 @@
 # limitations under the License.
 {
   'variables': {
-    're2_dir%': '/usr/include',
+    're2_root%': '/usr',
     're2_lib%': '-lre2',
   },
   'targets': [
@@ -22,11 +22,25 @@
       'type': 'none',
       'all_dependent_settings': {
         'include_dirs': [
-          '<(re2_dir)',
+          '<(re2_root)/include',
+        ],
+        'library_dirs': [
+          '<(re2_root)/lib',
         ],
         'libraries': [
           '<(re2_lib)',
         ],
+        'conditions': [
+          [ 'OS == "mac"', {
+            'link_settings': {
+              'xcode_settings': {
+                'OTHER_LDFLAGS': [
+                  '<(re2_lib)',
+                ],
+              },
+            }
+          }],
+        ],
       },
     },
   ],
diff --git a/cpp/src/address_normalizer.cc b/cpp/src/address_normalizer.cc
index a63b674..0075a74 100644
--- a/cpp/src/address_normalizer.cc
+++ b/cpp/src/address_normalizer.cc
@@ -47,6 +47,8 @@
   LookupKey parent_key;
   parent_key.FromAddress(region_address);
   const Rule* parent_rule = supplier_->GetRule(parent_key);
+  // Since we only set the |region_code| in the |region_address|, and the rule
+  // for the |region_code| is already loaded, |parent_rule| should not be null.
   assert(parent_rule != nullptr);
 
   std::vector<std::string> languages(parent_rule->GetLanguages());
@@ -77,7 +79,11 @@
         lookup_key.set_language(language);
         lookup_key.FromLookupKey(parent_key, sub_key);
         const Rule* rule = supplier_->GetRule(lookup_key);
-        assert(rule != nullptr);
+
+        // A rule with key = |subkey| and specified |language| was expected to
+        // be found in a certain format (e.g. data/CA/QC--fr), but it was not.
+        // This is due to a possible inconsistency in the data format.
+        if (rule == nullptr) continue;
 
         bool matches_latin_name =
             compare_->NaturalEquals(field_value, rule->GetLatinName());
diff --git a/cpp/test/address_normalizer_test.cc b/cpp/test/address_normalizer_test.cc
index edf92d7..4560cb7 100644
--- a/cpp/test/address_normalizer_test.cc
+++ b/cpp/test/address_normalizer_test.cc
@@ -123,6 +123,17 @@
   EXPECT_EQ("CA", address.administrative_area);
 }
 
+TEST_F(AddressNormalizerTest, CountryWithNonStandardData) {
+  // This test is to make sure that Normalize would not crash for the case where
+  // the data is not standard and key--language does not exist.
+  supplier_.LoadRules("HK", *loaded_);
+  i18n::addressinput::AddressData address;
+  address.region_code = "HK";
+  address.administrative_area = "香港島";
+  normalizer_.Normalize(&address);
+  EXPECT_EQ("香港島", address.administrative_area);
+}
+
 TEST_F(AddressNormalizerTest, GangwonLatinNameStaysUnchanged) {
   supplier_.LoadRules("KR", *loaded_);
   AddressData address;