summaryrefslogtreecommitdiff
path: root/tools/aapt2/ResourceUtils.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'tools/aapt2/ResourceUtils.cpp')
-rw-r--r--tools/aapt2/ResourceUtils.cpp20
1 files changed, 19 insertions, 1 deletions
diff --git a/tools/aapt2/ResourceUtils.cpp b/tools/aapt2/ResourceUtils.cpp
index 5a118a902963..91f4d60317da 100644
--- a/tools/aapt2/ResourceUtils.cpp
+++ b/tools/aapt2/ResourceUtils.cpp
@@ -670,8 +670,26 @@ 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)) {
- return std::move(floating_point);
+ const bool mayOnlyBeFloat = (type_mask & ~float_mask) == 0;
+ const bool parsedAsFloat = floating_point->value.dataType == android::Res_value::TYPE_FLOAT;
+ if (!mayOnlyBeFloat && parsedAsFloat) {
+ float f = reinterpret_cast<float&>(floating_point->value.data);
+ std::u16string str16 = android::util::Utf8ToUtf16(util::TrimWhitespace(value));
+ double d;
+ if (android::ResTable::stringToDouble(str16.data(), str16.size(), d)) {
+ // Parse as a float only if the difference between float and double parsed from the
+ // same string is smaller than 1, otherwise return as raw string.
+ if (fabs(f - d) < 1) {
+ return std::move(floating_point);
+ }
+ }
+ } else {
+ return std::move(floating_point);
+ }
}
}
}