Fix readFromParcel in every backend

readFromParcel should check the size before reading a field and set
Parcel's data position on successful exit.

Previously, the first field was read without checking the available
data, which fails when the older version is empty.

Bug: 186632725
Bug: 186633641
Test: aidl_integration_test
Change-Id: I8cbe9cd280833e04ee5f1c58f26eca0a9bdf1076
diff --git a/generate_rust.cpp b/generate_rust.cpp
index 0b36ff6..3d8be91 100644
--- a/generate_rust.cpp
+++ b/generate_rust.cpp
@@ -562,25 +562,29 @@
   out << "let parcelable_size: i32 = parcel.read()?;\n";
   out << "if parcelable_size < 0 { return Err(binder::StatusCode::BAD_VALUE); }\n";
 
-  // Pre-emit the common field epilogue code, shared between all fields:
-  ostringstream epilogue;
-  epilogue << "if (parcel.get_data_position() - start_pos) == parcelable_size {\n";
+  // Pre-emit the common field prolog code, shared between all fields:
+  ostringstream prolog;
+  prolog << "if (parcel.get_data_position() - start_pos) == parcelable_size {\n";
   // We assume the lhs can never be > parcelable_size, because then the read
   // immediately preceding this check would have returned NOT_ENOUGH_DATA
-  epilogue << "  return Ok(Some(result));\n";
-  epilogue << "}\n";
-  string epilogue_str = epilogue.str();
+  prolog << "  return Ok(Some(result));\n";
+  prolog << "}\n";
+  string prolog_str = prolog.str();
 
   out << "let mut result = Self::default();\n";
   for (const auto& variable : parcel->GetFields()) {
+    out << prolog_str;
     if (!TypeHasDefault(variable->GetType(), typenames)) {
       out << "result." << variable->GetName() << " = Some(parcel.read()?);\n";
     } else {
       out << "result." << variable->GetName() << " = parcel.read()?;\n";
     }
-    out << epilogue_str;
   }
-
+  // Now we read all fields.
+  // Skip remaining data in case we're reading from a newer version
+  out << "unsafe {\n";
+  out << "  parcel.set_data_position(start_pos + parcelable_size)?;\n";
+  out << "}\n";
   out << "Ok(Some(result))\n";
 }