mirror of
				https://github.com/meilisearch/meilisearch.git
				synced 2025-10-30 23:46:28 +00:00 
			
		
		
		
	Merge pull request #5566 from meilisearch/bad-max-total-hits
Forbid 0 in maxTotalHits
This commit is contained in:
		| @@ -1,3 +1,4 @@ | |||||||
|  | use std::num::NonZeroUsize; | ||||||
| use std::str::FromStr; | use std::str::FromStr; | ||||||
|  |  | ||||||
| use super::v4_to_v5::{CompatIndexV4ToV5, CompatV4ToV5}; | use super::v4_to_v5::{CompatIndexV4ToV5, CompatV4ToV5}; | ||||||
| @@ -388,7 +389,13 @@ impl<T> From<v5::Settings<T>> for v6::Settings<v6::Unchecked> { | |||||||
|             }, |             }, | ||||||
|             pagination: match settings.pagination { |             pagination: match settings.pagination { | ||||||
|                 v5::Setting::Set(pagination) => v6::Setting::Set(v6::PaginationSettings { |                 v5::Setting::Set(pagination) => v6::Setting::Set(v6::PaginationSettings { | ||||||
|                     max_total_hits: pagination.max_total_hits.into(), |                     max_total_hits: match pagination.max_total_hits { | ||||||
|  |                         v5::Setting::Set(max_total_hits) => v6::Setting::Set( | ||||||
|  |                             max_total_hits.try_into().unwrap_or(NonZeroUsize::new(1).unwrap()), | ||||||
|  |                         ), | ||||||
|  |                         v5::Setting::Reset => v6::Setting::Reset, | ||||||
|  |                         v5::Setting::NotSet => v6::Setting::NotSet, | ||||||
|  |                     }, | ||||||
|                 }), |                 }), | ||||||
|                 v5::Setting::Reset => v6::Setting::Reset, |                 v5::Setting::Reset => v6::Setting::Reset, | ||||||
|                 v5::Setting::NotSet => v6::Setting::NotSet, |                 v5::Setting::NotSet => v6::Setting::NotSet, | ||||||
|   | |||||||
| @@ -132,7 +132,7 @@ pub struct PaginationSettings { | |||||||
|     #[serde(default, skip_serializing_if = "Setting::is_not_set")] |     #[serde(default, skip_serializing_if = "Setting::is_not_set")] | ||||||
|     #[deserr(default)] |     #[deserr(default)] | ||||||
|     #[schema(value_type = Option<usize>, example = json!(250))] |     #[schema(value_type = Option<usize>, example = json!(250))] | ||||||
|     pub max_total_hits: Setting<usize>, |     pub max_total_hits: Setting<NonZeroUsize>, | ||||||
| } | } | ||||||
|  |  | ||||||
| impl MergeWithError<milli::CriterionError> for DeserrJsonError<InvalidSettingsRankingRules> { | impl MergeWithError<milli::CriterionError> for DeserrJsonError<InvalidSettingsRankingRules> { | ||||||
| @@ -748,7 +748,7 @@ pub fn apply_settings_to_builder( | |||||||
|  |  | ||||||
|     match pagination { |     match pagination { | ||||||
|         Setting::Set(ref value) => match value.max_total_hits { |         Setting::Set(ref value) => match value.max_total_hits { | ||||||
|             Setting::Set(val) => builder.set_pagination_max_total_hits(val), |             Setting::Set(val) => builder.set_pagination_max_total_hits(val.into()), | ||||||
|             Setting::Reset => builder.reset_pagination_max_total_hits(), |             Setting::Reset => builder.reset_pagination_max_total_hits(), | ||||||
|             Setting::NotSet => (), |             Setting::NotSet => (), | ||||||
|         }, |         }, | ||||||
| @@ -867,8 +867,8 @@ pub fn settings( | |||||||
|         max_total_hits: Setting::Set( |         max_total_hits: Setting::Set( | ||||||
|             index |             index | ||||||
|                 .pagination_max_total_hits(rtxn)? |                 .pagination_max_total_hits(rtxn)? | ||||||
|                 .map(|x| x as usize) |                 .and_then(|x| (x as usize).try_into().ok()) | ||||||
|                 .unwrap_or(DEFAULT_PAGINATION_MAX_TOTAL_HITS), |                 .unwrap_or(NonZeroUsize::new(DEFAULT_PAGINATION_MAX_TOTAL_HITS).unwrap()), | ||||||
|         ), |         ), | ||||||
|     }; |     }; | ||||||
|  |  | ||||||
|   | |||||||
| @@ -454,7 +454,9 @@ pub struct PaginationAnalytics { | |||||||
|  |  | ||||||
| impl PaginationAnalytics { | impl PaginationAnalytics { | ||||||
|     pub fn new(setting: Option<&PaginationSettings>) -> Self { |     pub fn new(setting: Option<&PaginationSettings>) -> Self { | ||||||
|         Self { max_total_hits: setting.as_ref().and_then(|s| s.max_total_hits.set()) } |         Self { | ||||||
|  |             max_total_hits: setting.as_ref().and_then(|s| s.max_total_hits.set().map(|x| x.into())), | ||||||
|  |         } | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     pub fn into_settings(self) -> SettingsAnalytics { |     pub fn into_settings(self) -> SettingsAnalytics { | ||||||
|   | |||||||
| @@ -338,6 +338,47 @@ async fn settings_bad_pagination() { | |||||||
|     "###); |     "###); | ||||||
| } | } | ||||||
|  |  | ||||||
|  | #[actix_rt::test] | ||||||
|  | async fn settings_bad_max_total_hits() { | ||||||
|  |     let server = Server::new_shared(); | ||||||
|  |     let index = server.unique_index(); | ||||||
|  |  | ||||||
|  |     let (response, code) = | ||||||
|  |         index.update_settings(json!({ "pagination": { "maxTotalHits": "doggo" } })).await; | ||||||
|  |     snapshot!(code, @"400 Bad Request"); | ||||||
|  |     snapshot!(json_string!(response), @r###" | ||||||
|  |     { | ||||||
|  |       "message": "Invalid value type at `.pagination.maxTotalHits`: expected a positive integer, but found a string: `\"doggo\"`", | ||||||
|  |       "code": "invalid_settings_pagination", | ||||||
|  |       "type": "invalid_request", | ||||||
|  |       "link": "https://docs.meilisearch.com/errors#invalid_settings_pagination" | ||||||
|  |     } | ||||||
|  |     "###); | ||||||
|  |  | ||||||
|  |     let (response, code) = | ||||||
|  |         index.update_settings_pagination(json!({ "maxTotalHits": "doggo" } )).await; | ||||||
|  |     snapshot!(code, @"400 Bad Request"); | ||||||
|  |     snapshot!(json_string!(response), @r#" | ||||||
|  |     { | ||||||
|  |       "message": "Invalid value type at `.maxTotalHits`: expected a positive integer, but found a string: `\"doggo\"`", | ||||||
|  |       "code": "invalid_settings_pagination", | ||||||
|  |       "type": "invalid_request", | ||||||
|  |       "link": "https://docs.meilisearch.com/errors#invalid_settings_pagination" | ||||||
|  |     } | ||||||
|  |     "#); | ||||||
|  |  | ||||||
|  |     let (response, code) = index.update_settings_pagination(json!({ "maxTotalHits": 0 } )).await; | ||||||
|  |     snapshot!(code, @"400 Bad Request"); | ||||||
|  |     snapshot!(json_string!(response), @r#" | ||||||
|  |     { | ||||||
|  |       "message": "Invalid value at `.maxTotalHits`: a non-zero integer value lower than `18446744073709551615` was expected, but found a zero", | ||||||
|  |       "code": "invalid_settings_pagination", | ||||||
|  |       "type": "invalid_request", | ||||||
|  |       "link": "https://docs.meilisearch.com/errors#invalid_settings_pagination" | ||||||
|  |     } | ||||||
|  |     "#); | ||||||
|  | } | ||||||
|  |  | ||||||
| #[actix_rt::test] | #[actix_rt::test] | ||||||
| async fn settings_bad_search_cutoff_ms() { | async fn settings_bad_search_cutoff_ms() { | ||||||
|     let server = Server::new_shared(); |     let server = Server::new_shared(); | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user