Snap for 6533464 from 1f776e9ec28b29076e500a5920d9d30299495436 to sdk-release

Change-Id: I388a4fbcb4ec37307cbed3aaf60a95057c828aa0
diff --git a/Android.bp b/Android.bp
index 58af2eb..61fbc3d 100644
--- a/Android.bp
+++ b/Android.bp
@@ -51,6 +51,7 @@
         "//apex_available:anyapex",
         "//apex_available:platform",
     ],
+    min_sdk_version: "29",
 }
 
 cc_defaults {
@@ -132,6 +133,7 @@
         "//apex_available:anyapex",
         "//apex_available:platform",
     ],
+    min_sdk_version: "29",
 }
 
 cc_library_static {
diff --git a/TEST_MAPPING b/TEST_MAPPING
new file mode 100644
index 0000000..3659bee
--- /dev/null
+++ b/TEST_MAPPING
@@ -0,0 +1,7 @@
+{
+  "presubmit": [
+    {
+      "name": "libbase_test"
+    }
+  ]
+}
diff --git a/file.cpp b/file.cpp
index 6321fc6..97cc2b2 100644
--- a/file.cpp
+++ b/file.cpp
@@ -225,7 +225,7 @@
     content->reserve(sb.st_size);
   }
 
-  char buf[BUFSIZ];
+  char buf[BUFSIZ] __attribute__((__uninitialized__));
   ssize_t n;
   while ((n = TEMP_FAILURE_RETRY(read(fd.get(), &buf[0], sizeof(buf)))) > 0) {
     content->append(buf, n);
diff --git a/include/android-base/properties.h b/include/android-base/properties.h
index 49f1f31..8b34573 100644
--- a/include/android-base/properties.h
+++ b/include/android-base/properties.h
@@ -99,3 +99,10 @@
 
 } // namespace base
 } // namespace android
+
+#if !defined(__BIONIC__)
+/** Implementation detail. */
+extern "C" int __system_property_set(const char*, const char*);
+/** Implementation detail. */
+extern "C" int __system_property_get(const char*, char*);
+#endif
diff --git a/logging.cpp b/logging.cpp
index 6e9c67f..5bd21da 100644
--- a/logging.cpp
+++ b/logging.cpp
@@ -260,7 +260,7 @@
   // The kernel's printk buffer is only 1024 bytes.
   // TODO: should we automatically break up long lines into multiple lines?
   // Or we could log but with something like "..." at the end?
-  char buf[1024];
+  char buf[1024] __attribute__((__uninitialized__));
   size_t size = snprintf(buf, sizeof(buf), "<%d>%s: %.*s\n", level, tag, length, msg);
   if (size > sizeof(buf)) {
     size = snprintf(buf, sizeof(buf), "<%d>%s: %zu-byte message too long for printk\n",
diff --git a/properties.cpp b/properties.cpp
index 5c9ec7e..8190987 100644
--- a/properties.cpp
+++ b/properties.cpp
@@ -32,6 +32,39 @@
 #include <android-base/parseint.h>
 #include <android-base/strings.h>
 
+#if !defined(__BIONIC__)
+
+#define PROP_VALUE_MAX 92
+
+static std::map<std::string, std::string>& g_properties = *new std::map<std::string, std::string>;
+
+int __system_property_set(const char* key, const char* value) {
+  if (key == nullptr || *key == '\0') return -1;
+  if (value == nullptr) value = "";
+
+  bool read_only = !strncmp(key, "ro.", 3);
+  if (read_only) {
+    const auto [it, success] = g_properties.insert({key, value});
+    return success ? 0 : -1;
+  }
+
+  if (strlen(value) >= 92) return -1;
+  g_properties[key] = value;
+  return 0;
+}
+
+int __system_property_get(const char* key, char* value) {
+  auto it = g_properties.find(key);
+  if (it == g_properties.end()) {
+    *value = '\0';
+    return 0;
+  }
+  snprintf(value, PROP_VALUE_MAX, "%s", it->second.c_str());
+  return strlen(value);
+}
+
+#endif
+
 namespace android {
 namespace base {
 
@@ -73,14 +106,6 @@
 template uint32_t GetUintProperty(const std::string&, uint32_t, uint32_t);
 template uint64_t GetUintProperty(const std::string&, uint64_t, uint64_t);
 
-#if !defined(__BIONIC__)
-static std::map<std::string, std::string>& g_properties = *new std::map<std::string, std::string>;
-static int __system_property_set(const char* key, const char* value) {
-  g_properties[key] = value;
-  return 0;
-}
-#endif
-
 std::string GetProperty(const std::string& key, const std::string& default_value) {
   std::string property_value;
 #if defined(__BIONIC__)
@@ -94,6 +119,7 @@
                                   },
                                   &property_value);
 #else
+  // TODO: implement host __system_property_find()/__system_property_read_callback()?
   auto it = g_properties.find(key);
   if (it == g_properties.end()) return default_value;
   property_value = it->second;
diff --git a/properties_test.cpp b/properties_test.cpp
index c30c41e..94ae690 100644
--- a/properties_test.cpp
+++ b/properties_test.cpp
@@ -44,13 +44,33 @@
   ASSERT_EQ("default", s);
 }
 
-TEST(properties, empty) {
+TEST(properties, too_long) {
+  // Properties have a fixed limit on the size of their value.
+  std::string key("debug.libbase.property_too_long");
+  std::string value(92, 'a');
+  ASSERT_FALSE(android::base::SetProperty(key, value));
+  ASSERT_EQ("missing", android::base::GetProperty(key, "missing"));
+
+  // Except for "ro." properties, which can have arbitrarily-long values.
+  key = "ro." + key + std::to_string(time(nullptr));
+  ASSERT_TRUE(android::base::SetProperty(key, value));
+  ASSERT_EQ(value, android::base::GetProperty(key, "missing"));
+  // ...because you can't change them.
+  ASSERT_FALSE(android::base::SetProperty(key, "hello"));
+  ASSERT_EQ(value, android::base::GetProperty(key, "missing"));
+}
+
+TEST(properties, empty_key) {
+  ASSERT_FALSE(android::base::SetProperty("", "hello"));
+  ASSERT_EQ("default", android::base::GetProperty("", "default"));
+}
+
+TEST(properties, empty_value) {
   // Because you can't delete a property, people "delete" them by
   // setting them to the empty string. In that case we'd want to
   // keep the default value (like cutils' property_get did).
-  android::base::SetProperty("debug.libbase.property_test", "");
-  std::string s = android::base::GetProperty("debug.libbase.property_test", "default");
-  ASSERT_EQ("default", s);
+  ASSERT_TRUE(android::base::SetProperty("debug.libbase.property_empty_value", ""));
+  ASSERT_EQ("default", android::base::GetProperty("debug.libbase.property_empty_value", "default"));
 }
 
 static void CheckGetBoolProperty(bool expected, const std::string& value, bool default_value) {
diff --git a/stringprintf.cpp b/stringprintf.cpp
index 78e1e8d..e83ab13 100644
--- a/stringprintf.cpp
+++ b/stringprintf.cpp
@@ -25,7 +25,7 @@
 
 void StringAppendV(std::string* dst, const char* format, va_list ap) {
   // First try with a small fixed size buffer
-  char space[1024];
+  char space[1024] __attribute__((__uninitialized__));
 
   // It's possible for methods that use a va_list to invalidate
   // the data in it upon use.  The fix is to make a copy