fix(indexer): reject truncated feeds
This commit is contained in:
@@ -221,6 +221,7 @@ fn parse_releases(indexer_id: i64, body: &[u8]) -> Result<Vec<SearchRelease>, Se
|
||||
let mut item = None;
|
||||
let mut field = None;
|
||||
let mut releases = Vec::new();
|
||||
let mut depth = 0_u32;
|
||||
|
||||
loop {
|
||||
match reader
|
||||
@@ -228,6 +229,7 @@ fn parse_releases(indexer_id: i64, body: &[u8]) -> Result<Vec<SearchRelease>, Se
|
||||
.map_err(|_| SearchError::InvalidResponse)?
|
||||
{
|
||||
Event::Start(element) => {
|
||||
depth = depth.checked_add(1).ok_or(SearchError::InvalidResponse)?;
|
||||
let name = element.local_name();
|
||||
if root.is_none() {
|
||||
root = Some(name.as_ref().to_vec());
|
||||
@@ -268,6 +270,7 @@ fn parse_releases(indexer_id: i64, body: &[u8]) -> Result<Vec<SearchRelease>, Se
|
||||
}
|
||||
}
|
||||
Event::End(element) => {
|
||||
depth = depth.checked_sub(1).ok_or(SearchError::InvalidResponse)?;
|
||||
if element.local_name().as_ref() == b"item" {
|
||||
if let Some(release) =
|
||||
item.take().and_then(|builder| builder.finish(indexer_id))
|
||||
@@ -277,7 +280,8 @@ fn parse_releases(indexer_id: i64, body: &[u8]) -> Result<Vec<SearchRelease>, Se
|
||||
}
|
||||
field = None;
|
||||
}
|
||||
Event::Eof => break,
|
||||
Event::Eof if depth == 0 => break,
|
||||
Event::Eof => return Err(SearchError::InvalidResponse),
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
@@ -298,15 +302,21 @@ fn read_element_attributes(
|
||||
let name = attribute(reader, element, b"name")?;
|
||||
let value = attribute(reader, element, b"value")?;
|
||||
match name.as_deref() {
|
||||
Some("size") => builder.size = value.and_then(|value| value.parse().ok()),
|
||||
Some("size") => {
|
||||
builder.size = value.and_then(|value| value.parse().ok()).or(builder.size);
|
||||
}
|
||||
Some("seeders" | "seed") => {
|
||||
builder.seeders = value.and_then(|value| value.parse().ok());
|
||||
builder.seeders = value
|
||||
.and_then(|value| value.parse().ok())
|
||||
.or(builder.seeders);
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
b"enclosure" => {
|
||||
builder.enclosure_url = attribute(reader, element, b"url")?;
|
||||
if let Some(url) = attribute(reader, element, b"url")? {
|
||||
builder.enclosure_url = Some(url);
|
||||
}
|
||||
if builder.size.is_none() {
|
||||
builder.size =
|
||||
attribute(reader, element, b"length")?.and_then(|value| value.parse().ok());
|
||||
|
||||
@@ -4,5 +4,3 @@
|
||||
<item>
|
||||
<title>Broken tracker response</title>
|
||||
<guid>broken-1</guid>
|
||||
</channel>
|
||||
</rss>
|
||||
|
||||
Reference in New Issue
Block a user