Generate correct Parcel verification code.

Make sure we pass in correct sizes into readBuffer()
and readEmbeddedBuffer() calls.

Same thing for HwBlob.readBuffer() and
HwBlob.readEmbeddedBuffer().

Bug: 30498700
Test: hidl_test, hidl_test_java, Youtube, Maps, Netflix, Camera

Change-Id: Ied2d9dc46538da3fcf5b1acbf1e7558e0743d3a2
Merged-In: Ied2d9dc46538da3fcf5b1acbf1e7558e0743d3a2
diff --git a/ArrayType.cpp b/ArrayType.cpp
index 3d34a9f..8168992 100644
--- a/ArrayType.cpp
+++ b/ArrayType.cpp
@@ -153,10 +153,18 @@
     const std::string parcelObjDeref =
         parcelObj + (parcelObjIsPointer ? "->" : ".");
 
+    size_t numArrayElements = 1;
+    for (auto size : mSizes) {
+        numArrayElements *= size->castSizeT();
+    }
     if (isReader) {
         out << "_hidl_err = "
             << parcelObjDeref
-            << "readBuffer(&"
+            << "readBuffer("
+            << numArrayElements
+            << " * sizeof("
+            << baseType
+            << "), &"
             << parentName
             << ", "
             << " reinterpret_cast<const void **>("
@@ -165,10 +173,6 @@
 
         handleError(out, mode);
     } else {
-        size_t numArrayElements = 1;
-        for (auto size : mSizes) {
-            numArrayElements *= size->castSizeT();
-        }
 
         out << "_hidl_err = "
             << parcelObjDeref
@@ -356,6 +360,9 @@
         const std::string &parcelObj,
         const std::string &argName,
         bool isReader) const {
+    size_t align, size;
+    getAlignmentAndSize(&align, &size);
+
     if (isReader) {
         out << "new "
             << getJavaType(true /* forInitializer */)
@@ -369,11 +376,10 @@
 
     if (isReader) {
         out << parcelObj
-            << ".readBuffer();\n";
+            << ".readBuffer("
+            << size
+            << " /* size */);\n";
     } else {
-        size_t align, size;
-        getAlignmentAndSize(&align, &size);
-
         out << "new android.os.HwBlob("
             << size
             << " /* size */);\n";
diff --git a/CompoundType.cpp b/CompoundType.cpp
index 1bd9aef..b70c998 100644
--- a/CompoundType.cpp
+++ b/CompoundType.cpp
@@ -134,7 +134,9 @@
         out << "_hidl_err = "
             << parcelObjDeref
             << "readBuffer("
-            << "&"
+            << "sizeof(*"
+            << name
+            << "), &"
             << parentName
             << ", "
             << " reinterpret_cast<const void **>("
@@ -443,7 +445,7 @@
 
         out.indent(2);
 
-        out << fullName() << " *obj,\n"
+        out << "const " << fullName() << " &obj,\n"
             << "const ::android::hardware::Parcel &parcel,\n"
             << "size_t parentHandle,\n"
             << "size_t parentOffset);\n\n";
@@ -632,17 +634,24 @@
         out << "builder.append(\"}\");\nreturn builder.toString();\n";
     }).endl().endl();
 
+    size_t structAlign, structSize;
+    getAlignmentAndSize(&structAlign, &structSize);
+
     ////////////////////////////////////////////////////////////////////////////
 
     out << "public final void readFromParcel(android.os.HwParcel parcel) {\n";
     out.indent();
-    out << "android.os.HwBlob blob = parcel.readBuffer();\n";
+    out << "android.os.HwBlob blob = parcel.readBuffer(";
+    out << structSize << "/* size */);\n";
     out << "readEmbeddedFromParcel(parcel, blob, 0 /* parentOffset */);\n";
     out.unindent();
     out << "}\n\n";
 
     ////////////////////////////////////////////////////////////////////////////
 
+    size_t vecAlign, vecSize;
+    VectorType::getAlignmentAndSizeStatic(&vecAlign, &vecSize);
+
     out << "public static final java.util.ArrayList<"
         << localName()
         << "> readVectorFromParcel(android.os.HwParcel parcel) {\n";
@@ -652,7 +661,8 @@
         << localName()
         << "> _hidl_vec = new java.util.ArrayList();\n";
 
-    out << "android.os.HwBlob _hidl_blob = parcel.readBuffer();\n\n";
+    out << "android.os.HwBlob _hidl_blob = parcel.readBuffer(";
+    out << vecSize << " /* sizeof hidl_vec<T> */);\n\n";
 
     VectorType::EmitJavaFieldReaderWriterForElementType(
             out,
@@ -703,9 +713,6 @@
 
     ////////////////////////////////////////////////////////////////////////////
 
-    size_t structAlign, structSize;
-    getAlignmentAndSize(&structAlign, &structSize);
-
     out << "public final void writeToParcel(android.os.HwParcel parcel) {\n";
     out.indent();
 
@@ -728,7 +735,8 @@
         << "> _hidl_vec) {\n";
     out.unindent();
 
-    out << "android.os.HwBlob _hidl_blob = new android.os.HwBlob(24 /* sizeof(hidl_vec<T>) */);\n";
+    out << "android.os.HwBlob _hidl_blob = new android.os.HwBlob("
+        << vecSize << " /* sizeof(hidl_vec<T>) */);\n";
 
     VectorType::EmitJavaFieldReaderWriterForElementType(
             out,
@@ -808,7 +816,7 @@
     std::string error = useName ? "" : "\n#error\n";
 
     if (isReader) {
-        out << space << localName() << " *" << name << ",\n";
+        out << "const " << space << localName() << " &" << name << ",\n";
         out << "const ::android::hardware::Parcel &parcel,\n";
     } else {
         out << "const " << space << localName() << " &" << name << ",\n";
@@ -833,7 +841,7 @@
         field->type().emitReaderWriterEmbedded(
                 out,
                 0 /* depth */,
-                name + (isReader ? "->" : ".") + field->name() + error,
+                name + "." + field->name() + error,
                 field->name() /* sanitizedName */,
                 false /* nameIsPointer */,
                 "parcel",
diff --git a/FmqType.cpp b/FmqType.cpp
index e3a8ae6..f9812cf 100644
--- a/FmqType.cpp
+++ b/FmqType.cpp
@@ -72,7 +72,10 @@
     if (isReader) {
         out << "_hidl_err = "
             << parcelObjDeref
-            << "readBuffer(&"
+            << "readBuffer("
+            << "sizeof(*"
+            << name
+            << "), &"
             << parentName
             << ", "
             << " reinterpret_cast<const void **>("
diff --git a/MemoryType.cpp b/MemoryType.cpp
index f685cfc..f27439b 100644
--- a/MemoryType.cpp
+++ b/MemoryType.cpp
@@ -67,7 +67,10 @@
     if (isReader) {
         out << "_hidl_err = "
             << parcelObjDeref
-            << "readBuffer(&"
+            << "readBuffer("
+            << "sizeof(*"
+            << name
+            << "), &"
             << parentName
             << ", "
             << " reinterpret_cast<const void **>("
diff --git a/StringType.cpp b/StringType.cpp
index 5571504..4051267 100644
--- a/StringType.cpp
+++ b/StringType.cpp
@@ -82,7 +82,10 @@
     if (isReader) {
         out << "_hidl_err = "
             << parcelObjDeref
-            << "readBuffer(&"
+            << "readBuffer("
+            << "sizeof(*"
+            << name
+            << "), &"
             << parentName
             << ", "
             << " reinterpret_cast<const void **>("
@@ -161,6 +164,13 @@
         const std::string &offset,
         bool isReader) const {
     if (isReader) {
+        out << fieldName
+            << " = "
+            << blobName
+            << ".getString("
+            << offset
+            << ");\n";
+
         out << "\n"
             << parcelName
             << ".readEmbeddedBuffer(\n";
@@ -170,7 +180,8 @@
 
         // hidl_string's embedded buffer is never null(able), because it defaults to a
         // buffer containing an empty string.
-        out << blobName
+        out << fieldName << ".length() + 1,\n"
+            << blobName
             << ".handle(),\n"
             << offset
             << " + 0 /* offsetof(hidl_string, mBuffer) */,"
@@ -179,13 +190,6 @@
         out.unindent();
         out.unindent();
 
-        out << fieldName
-            << " = "
-            << blobName
-            << ".getString("
-            << offset
-            << ");\n";
-
         return;
     }
 
diff --git a/Type.cpp b/Type.cpp
index 8ad1ce5..b2efc20 100644
--- a/Type.cpp
+++ b/Type.cpp
@@ -343,8 +343,8 @@
     if (isReader) {
         out << "const_cast<"
             << typeName
-            << " *>("
-            << namePointer
+            << " &>("
+            << nameDerefed
             << "),\n";
     } else {
         out << nameDerefed
diff --git a/VectorType.cpp b/VectorType.cpp
index 237113e..9bdd91e 100644
--- a/VectorType.cpp
+++ b/VectorType.cpp
@@ -156,7 +156,10 @@
     if (isReader) {
         out << "_hidl_err = "
             << parcelObjDeref
-            << "readBuffer(&"
+            << "readBuffer("
+            << "sizeof(*"
+            << name
+            << "), &"
             << parentName
             << ", "
             << " reinterpret_cast<const void **>("
@@ -485,6 +488,8 @@
     }
 
     if (mElementType->isArray()) {
+        size_t align, size;
+        getAlignmentAndSize(&align, &size);
         if (isReader) {
             out << " new "
                 << getJavaType(false /* forInitializer */)
@@ -498,10 +503,10 @@
 
         if (isReader) {
             out << parcelObj
-                << ".readBuffer();\n";
+                << ".readBuffer("
+                << size
+                << " /* size */);\n";
         } else {
-            size_t align, size;
-            getAlignmentAndSize(&align, &size);
 
             out << "new android.os.HwBlob("
                 << size
@@ -578,10 +583,19 @@
         const std::string &fieldName,
         const std::string &offset,
         bool isReader) {
+    size_t elementAlign, elementSize;
+    elementType->getAlignmentAndSize(&elementAlign, &elementSize);
+
     if (isReader) {
         out << "{\n";
         out.indent();
 
+        out << "int _hidl_vec_size = "
+            << blobName
+            << ".getInt32("
+            << offset
+            << " + 8 /* offsetof(hidl_vec<T>, mSize) */);\n";
+
         out << "android.os.HwBlob childBlob = "
             << parcelName
             << ".readEmbeddedBuffer(\n";
@@ -589,7 +603,9 @@
         out.indent();
         out.indent();
 
-        out << blobName
+        out << "_hidl_vec_size * "
+            << elementSize << ","
+            << blobName
             << ".handle(),\n"
             << offset
             << " + 0 /* offsetof(hidl_vec<T>, mBuffer) */,"
@@ -599,12 +615,6 @@
         out.unindent();
 
         out << fieldName << ".clear();\n";
-        out << "int _hidl_vec_size = "
-            << blobName
-            << ".getInt32("
-            << offset
-            << " + 8 /* offsetof(hidl_vec<T>, mSize) */);\n";
-
         std::string iteratorName = "_hidl_index_" + std::to_string(depth);
 
         out << "for (int "
@@ -620,9 +630,6 @@
 
         elementType->emitJavaFieldInitializer(out, "_hidl_vec_element");
 
-        size_t elementAlign, elementSize;
-        elementType->getAlignmentAndSize(&elementAlign, &elementSize);
-
         elementType->emitJavaFieldReaderWriter(
                 out,
                 depth + 1,
@@ -662,9 +669,6 @@
         << offset
         << " + 12 /* offsetof(hidl_vec<T>, mOwnsBuffer) */, false);\n";
 
-    size_t elementAlign, elementSize;
-    elementType->getAlignmentAndSize(&elementAlign, &elementSize);
-
     // XXX make HwBlob constructor take a long instead of an int?
     out << "android.os.HwBlob childBlob = new android.os.HwBlob((int)(_hidl_vec_size * "
         << elementSize
@@ -743,10 +747,16 @@
 
 // All hidl_vec<T> have the same size.
 static HidlTypeAssertion assertion("hidl_vec<char>", 16 /* size */);
-void VectorType::getAlignmentAndSize(size_t *align, size_t *size) const {
+
+// static
+void VectorType::getAlignmentAndSizeStatic(size_t *align, size_t *size) {
     *align = 8;  // hidl_vec<T>
     *size = assertion.size();
 }
 
+void VectorType::getAlignmentAndSize(size_t *align, size_t *size) const {
+    VectorType::getAlignmentAndSizeStatic(align, size);
+}
+
 }  // namespace android
 
diff --git a/VectorType.h b/VectorType.h
index 73ce814..1b3f06d 100644
--- a/VectorType.h
+++ b/VectorType.h
@@ -124,7 +124,7 @@
     bool containsPointer() const override;
 
     void getAlignmentAndSize(size_t *align, size_t *size) const override;
-
+    static void getAlignmentAndSizeStatic(size_t *align, size_t *size);
  private:
     // Helper method for emitResolveReferences[Embedded].
     // Pass empty childName and childOffsetText if the original