Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit fcdb8fe0 authored by Myles Watson's avatar Myles Watson
Browse files

PDL: Check sizes before validating constraints

Test: bluetooth_packet_parser_test  --gtest_filter=*WayTooSmall*
Change-Id: Ia43c066c11b83f1e9b651ffdd85c6e0196c45332
parent 668e9de8
Loading
Loading
Loading
Loading
+17 −14
Original line number Diff line number Diff line
@@ -398,20 +398,6 @@ void PacketDef::GenValidator(std::ostream& s) const {

  s << "protected:";
  s << "virtual bool IsValid_() const {";
  if (parent_constraints_.size() > 0 && parent_ == nullptr) {
    ERROR() << "Can't have a constraint on a NULL parent";
  }

  for (const auto& constraint : parent_constraints_) {
    s << "if (Get" << util::UnderscoreToCamelCase(constraint.first) << "() != ";
    const auto& field = parent_->GetParamList().GetField(constraint.first);
    if (field->GetFieldType() == PacketField::Type::SCALAR) {
      s << std::get<int64_t>(constraint.second);
    } else {
      s << std::get<std::string>(constraint.second);
    }
    s << ") return false;";
  }

  // Offset by the parents known size. We know that any dynamic fields can
  // already be called since the parent must have already been validated by
@@ -514,6 +500,23 @@ void PacketDef::GenValidator(std::ostream& s) const {
    }
  }

  // Validate constraints after validating the size
  if (parent_constraints_.size() > 0 && parent_ == nullptr) {
    ERROR() << "Can't have a constraint on a NULL parent";
  }

  for (const auto& constraint : parent_constraints_) {
    s << "if (Get" << util::UnderscoreToCamelCase(constraint.first) << "() != ";
    const auto& field = parent_->GetParamList().GetField(constraint.first);
    if (field->GetFieldType() == PacketField::Type::SCALAR) {
      s << std::get<int64_t>(constraint.second);
    } else {
      s << std::get<std::string>(constraint.second);
    }
    s << ") return false;";
  }

  // Validate the packets fields last
  for (const auto& field : fields_) {
    field->GenValidator(s);
    s << "\n";
+38 −0
Original line number Diff line number Diff line
@@ -125,6 +125,44 @@ TEST(GeneratedPacketTest, testChild) {
  ASSERT_EQ(field_name, child_view.GetFieldName());
}

TEST(GeneratedPacketTest, testValidateWayTooSmall) {
  std::vector<uint8_t> too_small_bytes = {0x34};
  auto too_small = std::make_shared<std::vector<uint8_t>>(too_small_bytes.begin(), too_small_bytes.end());

  ParentWithAddressView invalid_parent = ParentWithAddressView::Create(too_small);
  ASSERT_FALSE(invalid_parent.IsValid());
  ChildWithAddressView invalid = ChildWithAddressView::Create(ParentWithAddressView::Create(too_small));
  ASSERT_FALSE(invalid.IsValid());
}

TEST(GeneratedPacketTest, testValidateTooSmall) {
  std::vector<uint8_t> too_small_bytes = {0x34, 0x12, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x11};
  auto too_small = std::make_shared<std::vector<uint8_t>>(too_small_bytes.begin(), too_small_bytes.end());

  ParentWithAddressView valid_parent = ParentWithAddressView::Create(too_small);
  ASSERT_TRUE(valid_parent.IsValid());
  ChildWithAddressView invalid = ChildWithAddressView::Create(ParentWithAddressView::Create(too_small));
  ASSERT_FALSE(invalid.IsValid());
}

TEST(GeneratedPacketTest, testValidateJustRight) {
  std::vector<uint8_t> just_right_bytes = {0x34, 0x12, 0x01, 0x02, 0x03, 0x04, 0x05,
                                           0x06, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16};
  auto just_right = std::make_shared<std::vector<uint8_t>>(just_right_bytes.begin(), just_right_bytes.end());

  ChildWithAddressView valid = ChildWithAddressView::Create(ParentWithAddressView::Create(just_right));
  ASSERT_TRUE(valid.IsValid());
}

TEST(GeneratedPacketTest, testValidateTooBig) {
  std::vector<uint8_t> too_big_bytes = {0x34, 0x12, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06,
                                        0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x20};
  auto too_big = std::make_shared<std::vector<uint8_t>>(too_big_bytes.begin(), too_big_bytes.end());

  ChildWithAddressView lenient = ChildWithAddressView::Create(ParentWithAddressView::Create(too_big));
  ASSERT_TRUE(lenient.IsValid());
}

TEST(GeneratedPacketTest, testValidateDeath) {
  auto packet = ChildTwoTwoThreeBuilder::Create();