libbinder: Return UNEXPECTED_NULL when appropriate

Return a meaningful and consistent error code when libbinder encounters
a null reference that it didn't expect.  This allows us to detect these
situations and cause a corresponding NullPointerException to be thrown
on the remote callsite.

While here, consolidate places we read vector<T> from a parcel into a
single templated version.  This dramatically reduces code duplication.

Bug: 25617251
Test: Integration tests asserting that vectors serialize correctly
      passes.  Integration test asserting that we throw
      NullPointerException on seeing a null reference also passes.

Change-Id: Ia59c264884ec89539c1b99cd7bd28ac201b5b7ac
diff --git a/libs/binder/Parcel.cpp b/libs/binder/Parcel.cpp
index db1fc5c..45bf636 100644
--- a/libs/binder/Parcel.cpp
+++ b/libs/binder/Parcel.cpp
@@ -310,6 +310,39 @@
     return BAD_TYPE;
 }
 
+namespace {
+
+template<typename T>
+status_t readTypedVector(std::vector<T>* val, const Parcel* p,
+                         status_t(Parcel::*read_func)(T*) const) {
+    val->clear();
+
+    int32_t size;
+    status_t status = p->readInt32(&size);
+
+    if (status != OK) {
+        return status;
+    }
+
+    if (size < 0) {
+        return UNEXPECTED_NULL;
+    }
+
+    val->resize(size);
+
+    for (auto& v: *val) {
+        status = (p->*read_func)(&v);
+
+        if (status != OK) {
+            return status;
+        }
+    }
+
+    return OK;
+}
+
+}  // namespace
+
 // ---------------------------------------------------------------------------
 
 Parcel::Parcel()
@@ -1069,30 +1102,7 @@
 }
 
 status_t Parcel::readStrongBinderVector(std::vector<sp<IBinder>>* val) const {
-    val->clear();
-
-    int32_t size;
-    status_t status = readInt32(&size);
-
-    if (status != OK) {
-        return status;
-    }
-
-    if (size < 0) {
-        return BAD_VALUE;
-    }
-
-    val->resize(size);
-
-    for (auto& v : *val) {
-        status = readStrongBinder(&v);
-
-        if (status != OK) {
-            return status;
-        }
-    }
-
-    return OK;
+    return readTypedVector(val, this, &Parcel::readStrongBinder);
 }
 
 status_t Parcel::writeWeakBinder(const wp<IBinder>& val)
@@ -1393,10 +1403,15 @@
         return status;
     }
 
-    if (size < 0 || size_t(size) > dataAvail()) {
+    if (size < 0) {
+        status = UNEXPECTED_NULL;
+        return status;
+    }
+    if (size_t(size) > dataAvail()) {
         status = BAD_VALUE;
         return status;
     }
+
     const void* data = readInplace(size);
     if (!data) {
         status = BAD_VALUE;
@@ -1409,111 +1424,19 @@
 }
 
 status_t Parcel::readInt32Vector(std::vector<int32_t>* val) const {
-    val->clear();
-
-    int32_t size;
-    status_t status = readInt32(&size);
-
-    if (status != OK) {
-        return status;
-    }
-
-    if (size < 0) {
-        return BAD_VALUE;
-    }
-
-    val->resize(size);
-
-    for (auto& v: *val) {
-        status = readInt32(&v);
-
-        if (status != OK) {
-            return status;
-        }
-    }
-
-    return OK;
+    return readTypedVector(val, this, &Parcel::readInt32);
 }
 
 status_t Parcel::readInt64Vector(std::vector<int64_t>* val) const {
-    val->clear();
-
-    int32_t size;
-    status_t status = readInt32(&size);
-
-    if (status != OK) {
-        return status;
-    }
-
-    if (size < 0) {
-        return BAD_VALUE;
-    }
-
-    val->resize(size);
-
-    for (auto& v : *val) {
-        status = readInt64(&v);
-
-        if (status != OK) {
-            return status;
-        }
-    }
-
-    return OK;
+    return readTypedVector(val, this, &Parcel::readInt64);
 }
 
 status_t Parcel::readFloatVector(std::vector<float>* val) const {
-    val->clear();
-
-    int32_t size;
-    status_t status = readInt32(&size);
-
-    if (status != OK) {
-        return status;
-    }
-
-    if (size < 0) {
-        return BAD_VALUE;
-    }
-
-    val->resize(size);
-
-    for (auto& v : *val) {
-        status = readFloat(&v);
-
-        if (status != OK) {
-            return status;
-        }
-    }
-
-    return OK;
+    return readTypedVector(val, this, &Parcel::readFloat);
 }
 
 status_t Parcel::readDoubleVector(std::vector<double>* val) const {
-    val->clear();
-
-    int32_t size;
-    status_t status = readInt32(&size);
-
-    if (status != OK) {
-        return status;
-    }
-
-    if (size < 0) {
-        return BAD_VALUE;
-    }
-
-    val->resize(size);
-
-    for (auto& v : *val) {
-        status = readDouble(&v);
-
-        if (status != OK) {
-            return status;
-        }
-    }
-
-    return OK;
+    return readTypedVector(val, this, &Parcel::readDouble);
 }
 
 status_t Parcel::readBoolVector(std::vector<bool>* val) const {
@@ -1527,7 +1450,7 @@
     }
 
     if (size < 0) {
-        return BAD_VALUE;
+        return UNEXPECTED_NULL;
     }
 
     val->resize(size);
@@ -1549,61 +1472,11 @@
 }
 
 status_t Parcel::readCharVector(std::vector<char16_t>* val) const {
-    val->clear();
-
-    int32_t size;
-    status_t status = readInt32(&size);
-
-    if (status != OK) {
-        return status;
-    }
-
-    if (size < 0) {
-        return BAD_VALUE;
-    }
-
-    val->resize(size);
-
-    for (auto& v : *val) {
-        status = readChar(&v);
-
-        if (status != OK) {
-            return status;
-        }
-    }
-
-    return OK;
+    return readTypedVector(val, this, &Parcel::readChar);
 }
 
 status_t Parcel::readString16Vector(std::vector<String16>* val) const {
-    val->clear();
-
-    int32_t size;
-    status_t status = readInt32(&size);
-
-    if (status != OK) {
-        return status;
-    }
-
-    if (size < 0) {
-        return BAD_VALUE;
-    }
-
-    val->reserve(size);
-
-    while (size-- > 0) {
-        const char16_t *data;
-        size_t size;
-        data = readString16Inplace(&size);
-
-        if (data == nullptr) {
-            return UNKNOWN_ERROR;
-        }
-
-        val->emplace_back(data, size);
-    }
-
-    return OK;
+    return readTypedVector(val, this, &Parcel::readString16);
 }
 
 
@@ -1810,7 +1683,7 @@
         return 0;
     } else {
         *pArg = String16();
-        return UNKNOWN_ERROR;
+        return UNEXPECTED_NULL;
     }
 }