From 90f49eab6d671c45bf7107868dc41c872aad4a49 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Renault?= Date: Tue, 7 Dec 2021 16:32:48 +0100 Subject: [PATCH] Check the filter max depth limit and reject the invalid ones --- milli/src/search/facet/filter.rs | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/milli/src/search/facet/filter.rs b/milli/src/search/facet/filter.rs index e994f36d9..5a88c14dc 100644 --- a/milli/src/search/facet/filter.rs +++ b/milli/src/search/facet/filter.rs @@ -15,6 +15,9 @@ use crate::heed_codec::facet::{ }; use crate::{distance_between_two_points, CboRoaringBitmapCodec, FieldId, Index, Result}; +/// The maximum number of filters the filter AST can process. +const MAX_FILTER_DEPTH: usize = 1000; + #[derive(Debug, Clone, PartialEq, Eq)] pub struct Filter<'a> { condition: FilterCondition<'a>, @@ -27,6 +30,7 @@ enum FilterError<'a> { BadGeoLat(f64), BadGeoLng(f64), Reserved(&'a str), + TooDeep, InternalError, } impl<'a> std::error::Error for FilterError<'a> {} @@ -40,6 +44,10 @@ impl<'a> Display for FilterError<'a> { attribute, filterable, ), + Self::TooDeep => write!(f, + "Too many filter conditions, can't process more than {} filters.", + MAX_FILTER_DEPTH + ), Self::Reserved(keyword) => write!( f, "`{}` is a reserved keyword and thus can't be used as a filter expression.", @@ -108,6 +116,10 @@ impl<'a> Filter<'a> { } } + if let Some(token) = ands.as_ref().and_then(|fc| fc.token_at_depth(MAX_FILTER_DEPTH)) { + return Err(token.as_external_error(FilterError::TooDeep).into()); + } + Ok(ands.map(|ands| Self { condition: ands })) }