diff options
Diffstat (limited to 'tools/aapt2/ResourceUtils.cpp')
-rw-r--r-- | tools/aapt2/ResourceUtils.cpp | 20 |
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); + } } } } |