mirror of
https://github.com/facebook/react-native.git
synced 2025-11-01 09:14:26 +00:00
Filter and Box Shadow Conversion Tests and Fixes (#49418)
Summary: Pull Request resolved: https://github.com/facebook/react-native/pull/49418 This adds some missing validation for negative blurs which should be considered parse error. Unit tests added for the forked props parsing code to validate more generally. Changelog: [Internal] Reviewed By: joevilches Differential Revision: D69628917 fbshipit-source-id: 1451b53cfa673443f01d38bd0097c4e85c83db8b
This commit is contained in:
committed by
Facebook GitHub Bot
parent
05856b4681
commit
4fa516987c
+3
@@ -187,6 +187,9 @@ inline std::optional<BoxShadow> parseBoxShadowRawValue(
|
||||
auto rawBlurRadius = boxShadow.find("blurRadius");
|
||||
if (rawBlurRadius != boxShadow.end()) {
|
||||
if (auto blurRadiusValue = coerceLength(rawBlurRadius->second)) {
|
||||
if (*blurRadiusValue < 0) {
|
||||
return {};
|
||||
}
|
||||
blurRadius = *blurRadiusValue;
|
||||
} else {
|
||||
return {};
|
||||
|
||||
+9
@@ -283,6 +283,9 @@ inline std::optional<FilterFunction> parseDropShadow(
|
||||
if (standardDeviation != rawDropShadow.end()) {
|
||||
if (auto parsedStandardDeviation =
|
||||
coerceLength(standardDeviation->second)) {
|
||||
if (*parsedStandardDeviation < 0.0f) {
|
||||
return {};
|
||||
}
|
||||
dropShadowParams.standardDeviation = *parsedStandardDeviation;
|
||||
} else {
|
||||
return {};
|
||||
@@ -320,6 +323,9 @@ inline std::optional<FilterFunction> parseFilterRawValue(
|
||||
return parseDropShadow(context, rawFilter.begin()->second);
|
||||
} else if (filterKey == "blur") {
|
||||
if (auto length = coerceLength(rawFilter.begin()->second)) {
|
||||
if (*length < 0.0f) {
|
||||
return {};
|
||||
}
|
||||
return FilterFunction{FilterType::Blur, *length};
|
||||
}
|
||||
return {};
|
||||
@@ -330,6 +336,9 @@ inline std::optional<FilterFunction> parseFilterRawValue(
|
||||
return {};
|
||||
} else {
|
||||
if (auto amount = coerceAmount(rawFilter.begin()->second)) {
|
||||
if (*amount < 0.0f) {
|
||||
return {};
|
||||
}
|
||||
return FilterFunction{filterTypeFromString(filterKey), *amount};
|
||||
}
|
||||
return {};
|
||||
|
||||
+239
@@ -0,0 +1,239 @@
|
||||
/*
|
||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
#include <react/renderer/components/view/BoxShadowPropsConversions.h>
|
||||
#include <react/renderer/components/view/FilterPropsConversions.h>
|
||||
|
||||
namespace facebook::react {
|
||||
|
||||
TEST(ConversionsTest, unprocessed_box_shadow_string) {
|
||||
RawValue value{
|
||||
folly::dynamic("10px 2px 0 5px #fff, inset 20px 10px 5px 0 #000")};
|
||||
|
||||
std::vector<BoxShadow> boxShadows;
|
||||
parseUnprocessedBoxShadow(
|
||||
PropsParserContext{-1, ContextContainer{}}, value, boxShadows);
|
||||
|
||||
EXPECT_EQ(boxShadows.size(), 2);
|
||||
EXPECT_EQ(boxShadows[0].offsetX, 10);
|
||||
EXPECT_EQ(boxShadows[0].offsetY, 2);
|
||||
EXPECT_EQ(boxShadows[0].blurRadius, 0);
|
||||
EXPECT_EQ(boxShadows[0].spreadDistance, 5);
|
||||
EXPECT_EQ(boxShadows[0].color, colorFromRGBA(255, 255, 255, 255));
|
||||
EXPECT_FALSE(boxShadows[0].inset);
|
||||
|
||||
EXPECT_EQ(boxShadows[1].offsetX, 20);
|
||||
EXPECT_EQ(boxShadows[1].offsetY, 10);
|
||||
EXPECT_EQ(boxShadows[1].blurRadius, 5);
|
||||
EXPECT_EQ(boxShadows[1].spreadDistance, 0);
|
||||
EXPECT_EQ(boxShadows[1].color, colorFromRGBA(0, 0, 0, 255));
|
||||
EXPECT_TRUE(boxShadows[1].inset);
|
||||
}
|
||||
|
||||
TEST(ConversionsTest, unprocessed_box_shadow_objects) {
|
||||
RawValue value{folly::dynamic::array(
|
||||
folly::dynamic::object("offsetX", 10)("offsetY", 2)("blurRadius", 3)(
|
||||
"spreadDistance", 5),
|
||||
folly::dynamic::object("offsetX", 20)("offsetY", 10)("spreadDistance", 2)(
|
||||
"color", "#fff")("inset", true))};
|
||||
|
||||
std::vector<BoxShadow> boxShadows;
|
||||
parseUnprocessedBoxShadow(
|
||||
PropsParserContext{-1, ContextContainer{}}, value, boxShadows);
|
||||
|
||||
EXPECT_EQ(boxShadows.size(), 2);
|
||||
EXPECT_EQ(boxShadows[0].offsetX, 10);
|
||||
EXPECT_EQ(boxShadows[0].offsetY, 2);
|
||||
EXPECT_EQ(boxShadows[0].blurRadius, 3);
|
||||
EXPECT_EQ(boxShadows[0].spreadDistance, 5);
|
||||
EXPECT_EQ(boxShadows[0].color, SharedColor{});
|
||||
EXPECT_FALSE(boxShadows[0].inset);
|
||||
|
||||
EXPECT_EQ(boxShadows[1].offsetX, 20);
|
||||
EXPECT_EQ(boxShadows[1].offsetY, 10);
|
||||
EXPECT_EQ(boxShadows[1].blurRadius, 0);
|
||||
EXPECT_EQ(boxShadows[1].spreadDistance, 2);
|
||||
EXPECT_EQ(boxShadows[1].color, colorFromRGBA(255, 255, 255, 255));
|
||||
EXPECT_TRUE(boxShadows[1].inset);
|
||||
}
|
||||
|
||||
TEST(ConversionsTest, unprocessed_box_object_invalid_color) {
|
||||
RawValue value{folly::dynamic::array(folly::dynamic::object("offsetX", 10)(
|
||||
"offsetY", 2)("blurRadius", 3)("spreadDistance", 5)("color", "hello"))};
|
||||
|
||||
std::vector<BoxShadow> boxShadows;
|
||||
parseUnprocessedBoxShadow(
|
||||
PropsParserContext{-1, ContextContainer{}}, value, boxShadows);
|
||||
|
||||
EXPECT_TRUE(boxShadows.empty());
|
||||
}
|
||||
|
||||
TEST(ConversionsTest, unprocessed_box_object_negative_blur) {
|
||||
RawValue value{folly::dynamic::array(folly::dynamic::object("offsetX", 10)(
|
||||
"offsetY", 2)("blurRadius", -3)("spreadDistance", 5))};
|
||||
|
||||
std::vector<BoxShadow> boxShadows;
|
||||
parseUnprocessedBoxShadow(
|
||||
PropsParserContext{-1, ContextContainer{}}, value, boxShadows);
|
||||
|
||||
EXPECT_TRUE(boxShadows.empty());
|
||||
}
|
||||
|
||||
TEST(ConversionsTest, unprocessed_filter_string) {
|
||||
RawValue value{folly::dynamic(
|
||||
"drop-shadow(10px -2px 0.5px #fff) blur(5px) hue-rotate(90deg) saturate(2) brightness(50%)")};
|
||||
|
||||
std::vector<FilterFunction> filters;
|
||||
parseUnprocessedFilter(
|
||||
PropsParserContext{-1, ContextContainer{}}, value, filters);
|
||||
|
||||
EXPECT_EQ(filters.size(), 5);
|
||||
|
||||
EXPECT_EQ(filters[0].type, FilterType::DropShadow);
|
||||
EXPECT_TRUE(std::holds_alternative<DropShadowParams>(filters[0].parameters));
|
||||
EXPECT_EQ(std::get<DropShadowParams>(filters[0].parameters).offsetX, 10);
|
||||
EXPECT_EQ(std::get<DropShadowParams>(filters[0].parameters).offsetY, -2);
|
||||
EXPECT_EQ(
|
||||
std::get<DropShadowParams>(filters[0].parameters).standardDeviation, 0.5);
|
||||
EXPECT_EQ(
|
||||
std::get<DropShadowParams>(filters[0].parameters).color,
|
||||
colorFromRGBA(255, 255, 255, 255));
|
||||
|
||||
EXPECT_EQ(filters[1].type, FilterType::Blur);
|
||||
EXPECT_TRUE(std::holds_alternative<Float>(filters[1].parameters));
|
||||
EXPECT_EQ(std::get<Float>(filters[1].parameters), 5.0f);
|
||||
|
||||
EXPECT_EQ(filters[2].type, FilterType::HueRotate);
|
||||
EXPECT_TRUE(std::holds_alternative<Float>(filters[2].parameters));
|
||||
EXPECT_EQ(std::get<Float>(filters[2].parameters), 90.0f);
|
||||
|
||||
EXPECT_EQ(filters[3].type, FilterType::Saturate);
|
||||
EXPECT_TRUE(std::holds_alternative<Float>(filters[3].parameters));
|
||||
EXPECT_EQ(std::get<Float>(filters[3].parameters), 2.0f);
|
||||
|
||||
EXPECT_EQ(filters[4].type, FilterType::Brightness);
|
||||
EXPECT_TRUE(std::holds_alternative<Float>(filters[4].parameters));
|
||||
EXPECT_EQ(std::get<Float>(filters[4].parameters), 0.5f);
|
||||
}
|
||||
|
||||
TEST(ConversionsTest, unprocessed_filter_objects) {
|
||||
RawValue value{folly::dynamic::array(
|
||||
folly::dynamic::object(
|
||||
"drop-shadow",
|
||||
folly::dynamic::object("offsetX", 10)("offsetY", "-2px")(
|
||||
"standardDeviation", 0.5)),
|
||||
folly::dynamic::object("drop-shadow", "2px 0 0.5px #fff"),
|
||||
folly::dynamic::object("blur", 5),
|
||||
folly::dynamic::object("hue-rotate", "90deg"),
|
||||
folly::dynamic::object("saturate", 2),
|
||||
folly::dynamic::object("brightness", "50%"))};
|
||||
|
||||
std::vector<FilterFunction> filters;
|
||||
parseUnprocessedFilter(
|
||||
PropsParserContext{-1, ContextContainer{}}, value, filters);
|
||||
|
||||
EXPECT_EQ(filters.size(), 6);
|
||||
|
||||
EXPECT_EQ(filters[0].type, FilterType::DropShadow);
|
||||
EXPECT_TRUE(std::holds_alternative<DropShadowParams>(filters[0].parameters));
|
||||
EXPECT_EQ(std::get<DropShadowParams>(filters[0].parameters).offsetX, 10);
|
||||
EXPECT_EQ(std::get<DropShadowParams>(filters[0].parameters).offsetY, -2);
|
||||
EXPECT_EQ(
|
||||
std::get<DropShadowParams>(filters[0].parameters).standardDeviation, 0.5);
|
||||
EXPECT_EQ(
|
||||
std::get<DropShadowParams>(filters[0].parameters).color, SharedColor{});
|
||||
|
||||
EXPECT_EQ(filters[1].type, FilterType::DropShadow);
|
||||
EXPECT_TRUE(std::holds_alternative<DropShadowParams>(filters[1].parameters));
|
||||
EXPECT_EQ(std::get<DropShadowParams>(filters[1].parameters).offsetX, 2);
|
||||
EXPECT_EQ(std::get<DropShadowParams>(filters[1].parameters).offsetY, 0);
|
||||
EXPECT_EQ(
|
||||
std::get<DropShadowParams>(filters[1].parameters).standardDeviation, 0.5);
|
||||
EXPECT_EQ(
|
||||
std::get<DropShadowParams>(filters[1].parameters).color,
|
||||
colorFromRGBA(255, 255, 255, 255));
|
||||
|
||||
EXPECT_EQ(filters[2].type, FilterType::Blur);
|
||||
EXPECT_TRUE(std::holds_alternative<Float>(filters[2].parameters));
|
||||
EXPECT_EQ(std::get<Float>(filters[2].parameters), 5.0f);
|
||||
|
||||
EXPECT_EQ(filters[3].type, FilterType::HueRotate);
|
||||
EXPECT_TRUE(std::holds_alternative<Float>(filters[3].parameters));
|
||||
EXPECT_EQ(std::get<Float>(filters[3].parameters), 90.0f);
|
||||
|
||||
EXPECT_EQ(filters[4].type, FilterType::Saturate);
|
||||
EXPECT_TRUE(std::holds_alternative<Float>(filters[4].parameters));
|
||||
EXPECT_EQ(std::get<Float>(filters[4].parameters), 2.0f);
|
||||
|
||||
EXPECT_EQ(filters[5].type, FilterType::Brightness);
|
||||
EXPECT_TRUE(std::holds_alternative<Float>(filters[5].parameters));
|
||||
EXPECT_EQ(std::get<Float>(filters[5].parameters), 0.5f);
|
||||
}
|
||||
|
||||
TEST(ConversionsTest, unprocessed_filter_objects_negative_shadow_blur) {
|
||||
RawValue value{folly::dynamic::array(folly::dynamic::object(
|
||||
"drop-shadow",
|
||||
folly::dynamic::object("offsetX", 10)("offsetY", "-2px")(
|
||||
"standardDeviation", -0.5)))};
|
||||
|
||||
std::vector<FilterFunction> filters;
|
||||
parseUnprocessedFilter(
|
||||
PropsParserContext{-1, ContextContainer{}}, value, filters);
|
||||
|
||||
EXPECT_TRUE(filters.empty());
|
||||
}
|
||||
|
||||
TEST(ConversionsTest, unprocessed_filter_objects_negative_blur) {
|
||||
RawValue value{folly::dynamic::array(folly::dynamic::object("blur", -5))};
|
||||
|
||||
std::vector<FilterFunction> filters;
|
||||
parseUnprocessedFilter(
|
||||
PropsParserContext{-1, ContextContainer{}}, value, filters);
|
||||
|
||||
EXPECT_TRUE(filters.empty());
|
||||
}
|
||||
|
||||
TEST(ConversionsTest, unprocessed_filter_objects_negative_contrast) {
|
||||
RawValue value{
|
||||
folly::dynamic::array(folly::dynamic::object("constrast", -5))};
|
||||
|
||||
std::vector<FilterFunction> filters;
|
||||
parseUnprocessedFilter(
|
||||
PropsParserContext{-1, ContextContainer{}}, value, filters);
|
||||
|
||||
EXPECT_TRUE(filters.empty());
|
||||
}
|
||||
|
||||
TEST(ConversionsTest, unprocessed_filter_objects_negative_hue_rotate) {
|
||||
RawValue value{
|
||||
folly::dynamic::array(folly::dynamic::object("hue-rotate", -5))};
|
||||
|
||||
std::vector<FilterFunction> filters;
|
||||
parseUnprocessedFilter(
|
||||
PropsParserContext{-1, ContextContainer{}}, value, filters);
|
||||
|
||||
EXPECT_EQ(filters.size(), 1);
|
||||
|
||||
EXPECT_EQ(filters[0].type, FilterType::HueRotate);
|
||||
EXPECT_TRUE(std::holds_alternative<Float>(filters[0].parameters));
|
||||
EXPECT_EQ(std::get<Float>(filters[0].parameters), -5.0f);
|
||||
}
|
||||
|
||||
TEST(ConversionsTest, unprocessed_filter_objects_multiple_objects) {
|
||||
RawValue value{folly::dynamic::array(
|
||||
folly::dynamic::object("blur", 5)("hue-rotate", "90deg"))};
|
||||
|
||||
std::vector<FilterFunction> filters;
|
||||
parseUnprocessedFilter(
|
||||
PropsParserContext{-1, ContextContainer{}}, value, filters);
|
||||
|
||||
EXPECT_TRUE(filters.empty());
|
||||
}
|
||||
|
||||
} // namespace facebook::react
|
||||
Reference in New Issue
Block a user