Validate tag when deserializing values (#805)
Signed-off-by: Nico Burns <nico@nicoburns.com>
bd0150f5fca7eadd62553898d3b064ccc3c54897 · por Nico Burns · (hace 1 año) · padre 8d2a036c1 · ver el árbol en este commit
Delta semántico · 6
src/style/compact_length.rs
diff --git a/src/style/compact_length.rs b/src/style/compact_length.rs
index 7e6be88f8..89280f621 100644
--- a/src/style/compact_length.rs
+++ b/src/style/compact_length.rs
@@ -506,10 +506,21 @@ impl<'de> serde::Deserialize<'de> for CompactLength {
{
let bits: u64 = u64::deserialize(deserializer)?;
let value = Self(CompactLengthInner::from_serialized(bits));
- if value.is_calc() {
- Err(serde::de::Error::custom("Cannot deserialize Calc value"))
- } else {
+ // Note: validation intentionally excludes the CALC_TAG as deserializing calc() values is not supported
+ if matches!(
+ value.tag(),
+ CompactLength::LENGTH_TAG
+ | CompactLength::PERCENT_TAG
+ | CompactLength::AUTO_TAG
+ | CompactLength::MIN_CONTENT_TAG
+ | CompactLength::MAX_CONTENT_TAG
+ | CompactLength::FIT_CONTENT_PX_TAG
+ | CompactLength::FIT_CONTENT_PERCENT_TAG
+ | CompactLength::FR_TAG
+ ) {
Ok(value)
+ } else {
+ Err(serde::de::Error::custom("Cannot deserialize Calc value"))
}
}
}
diff --git a/src/style/dimension.rs b/src/style/dimension.rs
index 83cddd79b..2391d5ba3 100644
--- a/src/style/dimension.rs
+++ b/src/style/dimension.rs
@@ -7,7 +7,7 @@ use crate::style_helpers::{FromLength, FromPercent, TaffyAuto, TaffyZero};
///
/// This is commonly combined with [`Rect`], [`Point`](crate::geometry::Point) and [`Size<T>`](crate::geometry::Size).
#[derive(Copy, Clone, PartialEq, Debug)]
-#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
+#[cfg_attr(feature = "serde", derive(Serialize))]
pub struct LengthPercentage(pub(crate) CompactLength);
impl TaffyZero for LengthPercentage {
const ZERO: Self = Self(CompactLength::ZERO);
@@ -61,11 +61,27 @@ impl LengthPercentage {
}
}
+#[cfg(feature = "serde")]
+impl<'de> serde::Deserialize<'de> for LengthPercentage {
+ fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
+ where
+ D: serde::Deserializer<'de>,
+ {
+ let inner = CompactLength::deserialize(deserializer)?;
+ // Note: validation intentionally excludes the CALC_TAG as deserializing calc() values is not supported
+ if matches!(inner.tag(), CompactLength::LENGTH_TAG | CompactLength::PERCENT_TAG) {
+ Ok(Self(inner))
+ } else {
+ Err(serde::de::Error::custom("Invalid tag"))
+ }
+ }
+}
+
/// A unit of linear measurement
///
/// This is commonly combined with [`Rect`], [`Point`](crate::geometry::Point) and [`Size<T>`](crate::geometry::Size).
#[derive(Copy, Clone, PartialEq, Debug)]
-#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
+#[cfg_attr(feature = "serde", derive(Serialize))]
pub struct LengthPercentageAuto(pub(crate) CompactLength);
impl TaffyZero for LengthPercentageAuto {
const ZERO: Self = Self(CompactLength::ZERO);
@@ -156,11 +172,27 @@ impl LengthPercentageAuto {
}
}
+#[cfg(feature = "serde")]
+impl<'de> serde::Deserialize<'de> for LengthPercentageAuto {
+ fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
+ where
+ D: serde::Deserializer<'de>,
+ {
+ let inner = CompactLength::deserialize(deserializer)?;
+ // Note: validation intentionally excludes the CALC_TAG as deserializing calc() values is not supported
+ if matches!(inner.tag(), CompactLength::LENGTH_TAG | CompactLength::PERCENT_TAG | CompactLength::AUTO_TAG) {
+ Ok(Self(inner))
+ } else {
+ Err(serde::de::Error::custom("Invalid tag"))
+ }
+ }
+}
+
/// A unit of linear measurement
///
/// This is commonly combined with [`Rect`], [`Point`](crate::geometry::Point) and [`Size<T>`](crate::geometry::Size).
#[derive(Copy, Clone, PartialEq, Debug)]
-#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
+#[cfg_attr(feature = "serde", derive(Serialize))]
pub struct Dimension(pub(crate) CompactLength);
impl TaffyZero for Dimension {
const ZERO: Self = Self(CompactLength::ZERO);
@@ -259,6 +291,22 @@ impl Dimension {
}
}
+#[cfg(feature = "serde")]
+impl<'de> serde::Deserialize<'de> for Dimension {
+ fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
+ where
+ D: serde::Deserializer<'de>,
+ {
+ let inner = CompactLength::deserialize(deserializer)?;
+ // Note: validation intentionally excludes the CALC_TAG as deserializing calc() values is not supported
+ if matches!(inner.tag(), CompactLength::LENGTH_TAG | CompactLength::PERCENT_TAG | CompactLength::AUTO_TAG) {
+ Ok(Self(inner))
+ } else {
+ Err(serde::de::Error::custom("Invalid tag"))
+ }
+ }
+}
+
impl Rect<Dimension> {
/// Create a new Rect with length values
#[must_use]
diff --git a/src/style/grid.rs b/src/style/grid.rs
index 28c71dd6c..9f800a25b 100644
--- a/src/style/grid.rs
+++ b/src/style/grid.rs
@@ -366,7 +366,7 @@ impl Default for Line<GridPlacement> {
/// on the size of it's contents, the amount of available space, and the sizing constraint the grid is being size under.
/// See <https://developer.mozilla.org/en-US/docs/Web/CSS/grid-template-columns>
#[derive(Copy, Clone, PartialEq, Debug)]
-#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
+#[cfg_attr(feature = "serde", derive(Serialize))]
pub struct MaxTrackSizingFunction(pub(crate) CompactLength);
impl TaffyZero for MaxTrackSizingFunction {
const ZERO: Self = Self(CompactLength::ZERO);
@@ -420,6 +420,31 @@ impl From<MinTrackSizingFunction> for MaxTrackSizingFunction {
Self(input.0)
}
}
+#[cfg(feature = "serde")]
+impl<'de> serde::Deserialize<'de> for MaxTrackSizingFunction {
+ fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
+ where
+ D: serde::Deserializer<'de>,
+ {
+ let inner = CompactLength::deserialize(deserializer)?;
+ // Note: validation intentionally excludes the CALC_TAG as deserializing calc() values is not supported
+ if matches!(
+ inner.tag(),
+ CompactLength::LENGTH_TAG
+ | CompactLength::PERCENT_TAG
+ | CompactLength::AUTO_TAG
+ | CompactLength::MIN_CONTENT_TAG
+ | CompactLength::MAX_CONTENT_TAG
+ | CompactLength::FIT_CONTENT_PX_TAG
+ | CompactLength::FIT_CONTENT_PERCENT_TAG
+ | CompactLength::FR_TAG
+ ) {
+ Ok(Self(inner))
+ } else {
+ Err(serde::de::Error::custom("Invalid tag"))
+ }
+ }
+}
impl MaxTrackSizingFunction {
/// An absolute length in some abstract units. Users of Taffy may define what they correspond
@@ -637,7 +662,7 @@ impl MaxTrackSizingFunction {
/// on the size of it's contents, the amount of available space, and the sizing constraint the grid is being size under.
/// See <https://developer.mozilla.org/en-US/docs/Web/CSS/grid-template-columns>
#[derive(Copy, Clone, PartialEq, Debug)]
-#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
+#[cfg_attr(feature = "serde", derive(Serialize))]
pub struct MinTrackSizingFunction(pub(crate) CompactLength);
impl TaffyZero for MinTrackSizingFunction {
const ZERO: Self = Self(CompactLength::ZERO);
@@ -676,6 +701,30 @@ impl From<Dimension> for MinTrackSizingFunction {
Self(input.0)
}
}
+#[cfg(feature = "serde")]
+impl<'de> serde::Deserialize<'de> for MinTrackSizingFunction {
+ fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
+ where
+ D: serde::Deserializer<'de>,
+ {
+ let inner = CompactLength::deserialize(deserializer)?;
+ // Note: validation intentionally excludes the CALC_TAG as deserializing calc() values is not supported
+ if matches!(
+ inner.tag(),
+ CompactLength::LENGTH_TAG
+ | CompactLength::PERCENT_TAG
+ | CompactLength::AUTO_TAG
+ | CompactLength::MIN_CONTENT_TAG
+ | CompactLength::MAX_CONTENT_TAG
+ | CompactLength::FIT_CONTENT_PX_TAG
+ | CompactLength::FIT_CONTENT_PERCENT_TAG
+ ) {
+ Ok(Self(inner))
+ } else {
+ Err(serde::de::Error::custom("Invalid tag"))
+ }
+ }
+}
impl MinTrackSizingFunction {
/// An absolute length in some abstract units. Users of Taffy may define what they correspond