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

Commit f24b9a43 authored by Brandon Liu's avatar Brandon Liu
Browse files

Add additional check on float precision after parsing, only compile the

value when precision is not lost.

Bug: b/69347762
Test: Verified affected atests pass
Change-Id: I8e4fcd420a924f0e949bfd3a8aae23d1e7d582b1
parent 00558ac5
Loading
Loading
Loading
Loading
+12 −1
Original line number Diff line number Diff line
@@ -670,9 +670,20 @@ std::unique_ptr<Item> TryParseItemForAttribute(
    // Try parsing this as a float.
    auto floating_point = TryParseFloat(value);
    if (floating_point) {
      // Only check if the parsed result lost precision when the parsed item is
      // android::Res_value::TYPE_FLOAT and there is other possible types saved in type_mask, like
      // ResTable_map::TYPE_INTEGER.
      if (type_mask & AndroidTypeToAttributeTypeMask(floating_point->value.dataType)) {
        const bool mayOnlyBeFloat = (type_mask & ~float_mask) == 0;
        const bool parsedAsFloat = floating_point->value.dataType == android::Res_value::TYPE_FLOAT;
        if (!mayOnlyBeFloat && parsedAsFloat) {
          if (floating_point->toPrettyString() == value.data()) {
            return std::move(floating_point);
          }
        } else {
          return std::move(floating_point);
        }
      }
    }
  }
  return {};
+15 −0
Original line number Diff line number Diff line
@@ -228,6 +228,21 @@ TEST(ResourceUtilsTest, ItemsWithWhitespaceAreParsedCorrectly) {
              Pointee(ValueEq(BinaryPrimitive(Res_value::TYPE_FLOAT, expected_float_flattened))));
}

TEST(ResourceUtilsTest, FloatAndBigIntegerParsedCorrectly) {
  const float expected_float = 0.125f;
  const uint32_t expected_float_flattened = *(uint32_t*)&expected_float;
  EXPECT_THAT(ResourceUtils::TryParseItemForAttribute("0.125", ResTable_map::TYPE_FLOAT),
              Pointee(ValueEq(BinaryPrimitive(Res_value::TYPE_FLOAT, expected_float_flattened))));

  EXPECT_EQ(ResourceUtils::TryParseItemForAttribute("1099511627776", ResTable_map::TYPE_INTEGER),
            std::unique_ptr<Item>(nullptr));

  const float big_float = 1099511627776.0f;
  const uint32_t big_flattened = *(uint32_t*)&big_float;
  EXPECT_THAT(ResourceUtils::TryParseItemForAttribute("1099511627776", ResTable_map::TYPE_FLOAT),
              Pointee(ValueEq(BinaryPrimitive(Res_value::TYPE_FLOAT, big_flattened))));
}

TEST(ResourceUtilsTest, ParseSdkVersionWithCodename) {
  EXPECT_THAT(ResourceUtils::ParseSdkVersion("Q"), Eq(std::optional<int>(10000)));
  EXPECT_THAT(ResourceUtils::ParseSdkVersion("Q.fingerprint"), Eq(std::optional<int>(10000)));
+12 −3
Original line number Diff line number Diff line
@@ -22,12 +22,12 @@
#include <set>
#include <sstream>

#include "android-base/stringprintf.h"
#include "androidfw/ResourceTypes.h"

#include "Resource.h"
#include "ResourceUtils.h"
#include "ValueVisitor.h"
#include "android-base/stringprintf.h"
#include "androidfw/ResourceTypes.h"
#include "io/StringStream.h"
#include "util/Util.h"

using ::aapt::text::Printer;
@@ -487,6 +487,15 @@ void BinaryPrimitive::PrettyPrint(Printer* printer) const {
  }
}

std::string BinaryPrimitive::toPrettyString() const {
  std::string str;
  io::StringOutputStream out(&str);
  text::Printer printer(&out);
  this->PrettyPrint(&printer);
  out.Flush();
  return str;
}

Attribute::Attribute(uint32_t t)
    : type_mask(t),
      min_int(std::numeric_limits<int32_t>::min()),
+1 −0
Original line number Diff line number Diff line
@@ -285,6 +285,7 @@ struct BinaryPrimitive : public TransformableItem<BinaryPrimitive, BaseItem<Bina
  bool Flatten(android::Res_value* out_value) const override;
  void Print(std::ostream* out) const override;
  void PrettyPrint(text::Printer* printer) const override;
  std::string toPrettyString() const;
};

struct Attribute : public TransformableValue<Attribute, BaseValue<Attribute>> {