diff options
author | Shunkai Yao <yaoshunkai@google.com> | 2023-11-30 18:41:59 +0000 |
---|---|---|
committer | Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com> | 2023-11-30 18:41:59 +0000 |
commit | d6ae776d45ecfe04f3ce51b040d6374c04d851af (patch) | |
tree | b69a73f2bc1d287bead3552eff29f6698deb2803 | |
parent | b4f923ef2402d750726dcc4d6082c0209d43af5c (diff) | |
parent | f2501e9a79f5d6f3bf784b49583475477aeadf95 (diff) | |
download | aidl-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.cpp | 33 | ||||
-rw-r--r-- | aidl_language.h | 6 | ||||
-rw-r--r-- | aidl_unittest.cpp | 43 |
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)); |