使用反序列化時,如何添加對String(Vec或Array)長度的限制serde?
最好的猜測是:
use serde::Deserialize;
use arrayvec::ArrayString;
#[derive(Deserialize)]
pub struct Foo {
#[serde(try_from = "ArrayString<4096>")] // FAILS!
bar: String,
}
這不起作用,因為try_from屬性僅適用于“容器”而不適用于“欄位”。
如果有辦法使這個解決方案起作用,主要關注的是效率和安全性。這個解決方案是否快速(短期內不會顯著減慢反序列化程序String)和安全(它是否可以防止記憶體被惡意請求耗盡),并且是慣用的嗎?
uj5u.com熱心網友回復:
正如 @cafce25 所指出的,當您的Deserializeimpl 獲取字串時,它已經從輸入流中完全決議出來了。這就是serde作業原理,因此此限制不會提供任何保護。
您必須在請求級別或使用您自己的決議器實施此類限制。
如果您仍然希望實施這樣的限制,使用委托給的新型別非常簡單String::deserialize:
use std::ops::Deref;
use serde::de;
use serde::Deserialize;
struct LimitedString<const MAX_LENGTH: usize>(String);
impl<const MAX_LENGTH: usize> Deref for LimitedString<MAX_LENGTH> {
type Target = String;
fn deref(&self) -> &Self::Target {
&self.0
}
}
impl<'de, const MAX_LENGTH: usize> de::Deserialize<'de> for LimitedString<MAX_LENGTH> {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: de::Deserializer<'de>,
{
<String as de::Deserialize>::deserialize(deserializer).and_then(|inner| {
if inner.len() > MAX_LENGTH {
Err(de::Error::invalid_length(inner.len(), &"an integer lower than the maximum"))
} else {
Ok(Self(inner))
}
})
}
}
#[derive(Deserialize)]
pub struct Foo {
bar: LimitedString<4096>,
}
操場
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/536930.html
標籤:安全锈反序列化塞尔德
下一篇:條形圖中錯誤條的錯誤位置
