aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorShunkai Yao <yaoshunkai@google.com>2023-11-30 18:41:59 +0000
committerAutomerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>2023-11-30 18:41:59 +0000
commitd6ae776d45ecfe04f3ce51b040d6374c04d851af (patch)
treeb69a73f2bc1d287bead3552eff29f6698deb2803
parentb4f923ef2402d750726dcc4d6082c0209d43af5c (diff)
parentf2501e9a79f5d6f3bf784b49583475477aeadf95 (diff)
downloadaidl-d6ae776d45ecfe04f3ce51b040d6374c04d851af.tar.gz
Fix aidl_parser_fuzzer abort am: c6f0c2daef am: f50853df68 am: f2501e9a79
Original change: https://android-review.googlesource.com/c/platform/system/tools/aidl/+/2853448 Change-Id: I9717befa2c4d5be85b5253236a1024793a12fd98 Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
-rw-r--r--aidl_const_expressions.cpp33
-rw-r--r--aidl_language.h6
-rw-r--r--aidl_unittest.cpp43
3 files changed, 72 insertions, 10 deletions
diff --git a/aidl_const_expressions.cpp b/aidl_const_expressions.cpp
index 73771bd6..14b98c54 100644
--- a/aidl_const_expressions.cpp
+++ b/aidl_const_expressions.cpp
@@ -345,12 +345,21 @@ bool AidlUnaryConstExpression::IsCompatibleType(Type type, const string& op) {
}
}
-bool AidlBinaryConstExpression::AreCompatibleTypes(Type t1, Type t2) {
- if (t1 == t2) {
- return true;
- }
-
+bool AidlBinaryConstExpression::AreCompatibleOperandTypes(Type t1, Type t2) {
switch (t1) {
+ case Type::ARRAY:
+ if (t2 == Type::ARRAY) {
+ return true;
+ }
+ break;
+ case Type::STRING:
+ if (t2 == Type::STRING) {
+ return true;
+ }
+ break;
+ case Type::FLOATING:
+ // TODO: b/313951203, check op for supported floating operands (+ - * / < > <= >= == !=)
+ return false;
case Type::BOOLEAN: // fall-through
case Type::INT8: // fall-through
case Type::INT32: // fall-through
@@ -373,10 +382,18 @@ bool AidlBinaryConstExpression::AreCompatibleTypes(Type t1, Type t2) {
return false;
}
+bool AidlBinaryConstExpression::AreCompatibleArrayTypes(Type t1, Type t2) {
+ // treat floating type differently here, because float array is supported but not operand
+ if (t1 == Type::FLOATING && t2 == Type::FLOATING) return true;
+
+ return AreCompatibleOperandTypes(t1, t2);
+}
+
// Returns the promoted kind for both operands
AidlConstantValue::Type AidlBinaryConstExpression::UsualArithmeticConversion(Type left,
Type right) {
// These are handled as special cases
+ // TODO: b/313951203, remove this after support string and floating operands
AIDL_FATAL_IF(left == Type::STRING || right == Type::STRING, AIDL_LOCATION_HERE);
AIDL_FATAL_IF(left == Type::FLOATING || right == Type::FLOATING, AIDL_LOCATION_HERE);
@@ -770,8 +787,8 @@ bool AidlConstantValue::evaluate() const {
}
if (array_type == Type::ERROR) {
array_type = value->final_type_;
- } else if (!AidlBinaryConstExpression::AreCompatibleTypes(array_type,
- value->final_type_)) {
+ } else if (!AidlBinaryConstExpression::AreCompatibleArrayTypes(array_type,
+ value->final_type_)) {
AIDL_ERROR(this) << "Incompatible array element type: " << ToString(value->final_type_)
<< ". Expecting type compatible with " << ToString(array_type);
success = false;
@@ -1033,7 +1050,7 @@ bool AidlBinaryConstExpression::evaluate() const {
is_valid_ = false;
return false;
}
- is_valid_ = AreCompatibleTypes(left_val_->final_type_, right_val_->final_type_);
+ is_valid_ = AreCompatibleOperandTypes(left_val_->final_type_, right_val_->final_type_);
if (!is_valid_) {
AIDL_ERROR(this) << "Cannot perform operation '" << op_ << "' on "
<< ToString(right_val_->GetType()) << " and " << ToString(left_val_->GetType())
diff --git a/aidl_language.h b/aidl_language.h
index 83ae3f17..8480fcb6 100644
--- a/aidl_language.h
+++ b/aidl_language.h
@@ -704,6 +704,7 @@ class AidlConstantValue : public AidlNode {
void DispatchVisit(AidlVisitor& visitor) const override { visitor.Visit(*this); }
size_t Size() const { return values_.size(); }
const AidlConstantValue& ValueAt(size_t index) const { return *values_.at(index); }
+ static string ToString(Type type);
private:
AidlConstantValue(const AidlLocation& location, Type parsed_type, int64_t parsed_value,
@@ -712,7 +713,6 @@ class AidlConstantValue : public AidlNode {
AidlConstantValue(const AidlLocation& location, Type type,
std::unique_ptr<vector<unique_ptr<AidlConstantValue>>> values,
const std::string& value);
- static string ToString(Type type);
static bool ParseIntegral(const string& value, int64_t* parsed_value, Type* parsed_type);
static bool IsHex(const string& value);
@@ -790,7 +790,9 @@ class AidlBinaryConstExpression : public AidlConstantValue {
bool CheckValid() const override;
- static bool AreCompatibleTypes(Type t1, Type t2);
+ static bool AreCompatibleOperandTypes(Type t1, Type t2);
+ static bool AreCompatibleArrayTypes(Type t1, Type t2);
+
// Returns the promoted kind for both operands
static Type UsualArithmeticConversion(Type left, Type right);
// Returns the promoted integral type where INT32 is the smallest type
diff --git a/aidl_unittest.cpp b/aidl_unittest.cpp
index 2dcca1f9..3ddbb36b 100644
--- a/aidl_unittest.cpp
+++ b/aidl_unittest.cpp
@@ -25,6 +25,8 @@
#include <memory>
#include <set>
#include <string>
+#include <unordered_map>
+#include <unordered_set>
#include <variant>
#include <vector>
@@ -1441,6 +1443,47 @@ TEST_F(AidlTest, AidlConstantValue_EvaluatedValue) {
->EvaluatedValue<vector<float>>());
}
+// TODO: b/313951203 add floating/string operands test
+TEST_F(AidlTest, AidlBinaryConstExpression_CompatibleTypes) {
+ const AidlLocation& loc = AIDL_LOCATION_HERE;
+ static const std::unordered_map<AidlConstantValue::Type,
+ const std::unordered_set<AidlConstantValue::Type>>
+ compatibleTypesMap({{AidlConstantValue::Type::BOOLEAN,
+ {AidlConstantValue::Type::BOOLEAN, AidlConstantValue::Type::INT8,
+ AidlConstantValue::Type::INT32, AidlConstantValue::Type::INT64}},
+ {AidlConstantValue::Type::INT8,
+ {AidlConstantValue::Type::BOOLEAN, AidlConstantValue::Type::INT8,
+ AidlConstantValue::Type::INT32, AidlConstantValue::Type::INT64}},
+ {AidlConstantValue::Type::INT32,
+ {AidlConstantValue::Type::BOOLEAN, AidlConstantValue::Type::INT8,
+ AidlConstantValue::Type::INT32, AidlConstantValue::Type::INT64}},
+ {AidlConstantValue::Type::INT64,
+ {AidlConstantValue::Type::BOOLEAN, AidlConstantValue::Type::INT8,
+ AidlConstantValue::Type::INT32, AidlConstantValue::Type::INT64}},
+ {AidlConstantValue::Type::ARRAY, {AidlConstantValue::Type::ARRAY}},
+ {AidlConstantValue::Type::STRING, {AidlConstantValue::Type::STRING}}});
+
+ // go over all possible combination
+ for (int l = 0; l <= (int)AidlConstantValue::Type::ERROR; ++l) {
+ for (int r = 0; r <= (int)AidlConstantValue::Type::ERROR; ++r) {
+ const AidlConstantValue::Type lType = static_cast<AidlConstantValue::Type>(l),
+ rType = static_cast<AidlConstantValue::Type>(r);
+ const auto typeItor = compatibleTypesMap.find(lType);
+ const bool isCompatibleOperandType = typeItor != compatibleTypesMap.end() &&
+ typeItor->second.find(rType) != typeItor->second.end();
+ const bool isCompatibleArrayType =
+ isCompatibleOperandType || (lType == AidlConstantValue::Type::FLOATING &&
+ rType == AidlConstantValue::Type::FLOATING);
+ EXPECT_EQ(isCompatibleOperandType,
+ AidlBinaryConstExpression::AreCompatibleOperandTypes(lType, rType))
+ << AidlConstantValue::ToString(lType) << ", " << AidlConstantValue::ToString(rType);
+ EXPECT_EQ(isCompatibleArrayType,
+ AidlBinaryConstExpression::AreCompatibleArrayTypes(lType, rType))
+ << AidlConstantValue::ToString(lType) << ", " << AidlConstantValue::ToString(rType);
+ }
+ }
+}
+
TEST_F(AidlTest, AidlConstantCharacterDefault) {
auto char_type = typenames_.MakeResolvedType(AIDL_LOCATION_HERE, "char", false);
auto default_value = unique_ptr<AidlConstantValue>(AidlConstantValue::Default(*char_type));