Fix abort for nullable parcelable array.

The direction here should be:
- deduping 'has' type information from backends (this is what
  validatable types did, but oh well)
- (best) simplify by supporting types across all backends

However, making error consistent with other strategies for now, so that
we unblock the fuzzer.

Fixes: 148252544
Test: aidl_parser_fuzzer w/ added case
Test: atest aidl_unittests
Change-Id: Ib69b297bdfa376104666c6058f88e707c283ef49
diff --git a/aidl_language.cpp b/aidl_language.cpp
index 7af6036..d891c3c 100644
--- a/aidl_language.cpp
+++ b/aidl_language.cpp
@@ -822,7 +822,15 @@
 }
 
 // TODO: we should treat every backend all the same in future.
-bool AidlTypeSpecifier::LanguageSpecificCheckValid(Options::Language lang) const {
+bool AidlTypeSpecifier::LanguageSpecificCheckValid(const AidlTypenames& typenames,
+                                                   Options::Language lang) const {
+  if (lang == Options::Language::NDK && IsArray() && IsNullable()) {
+    const auto defined_type = typenames.TryGetDefinedType(GetName());
+    if (defined_type != nullptr && defined_type->AsParcelable() != nullptr) {
+      AIDL_ERROR(this) << "The NDK backend does not support nullable array of parcelable";
+      return false;
+    }
+  }
   if (lang != Options::Language::JAVA) {
     if (this->GetName() == "List" && !this->IsGeneric()) {
       AIDL_ERROR(this) << "Currently, only the Java backend supports non-generic List.";
@@ -881,7 +889,8 @@
 }
 
 // TODO: we should treat every backend all the same in future.
-bool AidlParcelable::LanguageSpecificCheckValid(Options::Language lang) const {
+bool AidlParcelable::LanguageSpecificCheckValid(const AidlTypenames& /*typenames*/,
+                                                Options::Language lang) const {
   if (lang != Options::Language::JAVA) {
     const AidlParcelable* unstructured_parcelable = this->AsUnstructuredParcelable();
     if (unstructured_parcelable != nullptr) {
@@ -896,12 +905,13 @@
 }
 
 // TODO: we should treat every backend all the same in future.
-bool AidlStructuredParcelable::LanguageSpecificCheckValid(Options::Language lang) const {
-  if (!AidlParcelable::LanguageSpecificCheckValid(lang)) {
+bool AidlStructuredParcelable::LanguageSpecificCheckValid(const AidlTypenames& typenames,
+                                                          Options::Language lang) const {
+  if (!AidlParcelable::LanguageSpecificCheckValid(typenames, lang)) {
     return false;
   }
   for (const auto& v : this->GetFields()) {
-    if (!v->GetType().LanguageSpecificCheckValid(lang)) {
+    if (!v->GetType().LanguageSpecificCheckValid(typenames, lang)) {
       return false;
     }
   }
@@ -997,13 +1007,14 @@
 }
 
 // TODO: we should treat every backend all the same in future.
-bool AidlInterface::LanguageSpecificCheckValid(Options::Language lang) const {
+bool AidlInterface::LanguageSpecificCheckValid(const AidlTypenames& typenames,
+                                               Options::Language lang) const {
   for (const auto& m : this->GetMethods()) {
-    if (!m->GetType().LanguageSpecificCheckValid(lang)) {
+    if (!m->GetType().LanguageSpecificCheckValid(typenames, lang)) {
       return false;
     }
     for (const auto& arg : m->GetArguments()) {
-      if (!arg->GetType().LanguageSpecificCheckValid(lang)) {
+      if (!arg->GetType().LanguageSpecificCheckValid(typenames, lang)) {
         return false;
       }
     }