diff --git a/kuksa_databroker/databroker/src/broker.rs b/kuksa_databroker/databroker/src/broker.rs index 7bbe4410..9ba3091d 100644 --- a/kuksa_databroker/databroker/src/broker.rs +++ b/kuksa_databroker/databroker/src/broker.rs @@ -1026,7 +1026,7 @@ impl<'a, 'b> DatabaseWriteAccess<'a, 'b> { allowed: Option, datapoint: Option, ) -> Result { - if !glob::is_valid_pattern(name.as_str()) { + if !glob::is_valid_path(name.as_str()) { return Err(RegistrationError::ValidationError); } diff --git a/kuksa_databroker/databroker/src/glob.rs b/kuksa_databroker/databroker/src/glob.rs index 72f5a3ea..1c26e25b 100644 --- a/kuksa_databroker/databroker/src/glob.rs +++ b/kuksa_databroker/databroker/src/glob.rs @@ -105,6 +105,32 @@ pub fn is_valid_pattern(input: &str) -> bool { REGEX_VALID_PATTERN.is_match(input) } +lazy_static! { + static ref REGEX_VALID_PATH: regex::Regex = regex::Regex::new( + r"(?x) + ^ # anchor at start (only match full paths) + # At least one subpath (consisting of either of three): + (?: + [^\.\s\:\*]+ # Any character except :, whitespace and . + ) + # which can be followed by ( separator + another subpath ) + # repeated any number of times + (?: + \. # Separator, literal dot + (?: + [^\.\s\:\*]+ # Any character except :, whitespace and . + )+ + )* + $ # anchor at end (to match only full paths) + ", + ) + .expect("regex compilation (of static pattern) should always succeed"); +} + +pub fn is_valid_path(input: &str) -> bool { + REGEX_VALID_PATH.is_match(input) +} + #[cfg(test)] mod tests { use super::*; @@ -1401,7 +1427,6 @@ mod tests { assert!(is_valid_pattern("Vehicle.Chassis.Axle.Row2.Wheel.*")); assert!(is_valid_pattern("String.String.String.String.*")); assert!(is_valid_pattern("String.String.String.String.**")); - assert!(is_valid_pattern("String.String.String.String")); assert!(is_valid_pattern("String.String.String.String.String.**")); assert!(is_valid_pattern("String.String.String.*.String")); assert!(is_valid_pattern("String.String.String.**.String")); @@ -1424,23 +1449,35 @@ mod tests { assert!(is_valid_pattern("*.String")); assert!(is_valid_pattern("*.String._")); - assert!(is_valid_pattern("Vehicle.Con_ñ_de_España,_sí")); - assert!(is_valid_pattern("Vehicle.Do_you_not_like_smörgåstårta")); - assert!(is_valid_pattern("Vehicle.tschö_mit_ö")); - assert!(is_valid_pattern("Vehicle.wie_heißt_das_lied")); - assert!(is_valid_pattern("Vehicle.東京_Москва_r#true")); - - assert!(!is_valid_pattern("String.String.String.")); - assert!(!is_valid_pattern("String.String.String.String..")); assert!(!is_valid_pattern("String.*.String.String..")); assert!(!is_valid_pattern("*.String.String.String..")); - assert!(!is_valid_pattern("String:String.String")); assert!(!is_valid_pattern("String.**.St ring.String")); assert!(!is_valid_pattern("String.**:String. String")); assert!(!is_valid_pattern("String.**.St. .ring.String")); assert!(!is_valid_pattern("String.**.St. : .ring.String")); } + #[test] + fn test_is_valid_path() { + assert!(is_valid_path("String.String.String.String")); + assert!(is_valid_path("String._kuksa.tring.9tring")); + + assert!(is_valid_path("Vehicle.Con_ñ_de_España,_sí")); + assert!(is_valid_path("Vehicle.Do_you_not_like_smörgåstårta")); + assert!(is_valid_path("Vehicle.tschö_mit_ö")); + assert!(is_valid_path("Vehicle.wie_heißt_das_lied")); + assert!(is_valid_path("Vehicle.東京_Москва_r#true")); + + assert!(!is_valid_path("String.String.String.")); + assert!(!is_valid_path("String.String.String.String..")); + assert!(!is_valid_path("String:String.String")); + assert!(!is_valid_path("String.St ring.String")); + assert!(!is_valid_path("String:String. String")); + assert!(!is_valid_path("String.St. .ring.String")); + assert!(!is_valid_path("String.St. : .ring.String")); + assert!(!is_valid_path("*.String:String. String")); + } + #[test] fn test_valid_regex_path() { assert_eq!(to_regex_string("String.*"), "^String\\.[^.\\s\\:]+$"); diff --git a/kuksa_databroker/databroker/src/grpc/kuksa_val_v1/val.rs b/kuksa_databroker/databroker/src/grpc/kuksa_val_v1/val.rs index b22e335c..9fce1d22 100644 --- a/kuksa_databroker/databroker/src/grpc/kuksa_val_v1/val.rs +++ b/kuksa_databroker/databroker/src/grpc/kuksa_val_v1/val.rs @@ -72,6 +72,18 @@ impl proto::val_server::Val for broker::DataBroker { // Fill valid_requests structure. for request in requested { + if request.path.contains('*') && !glob::is_valid_pattern(&request.path) { + errors.push(proto::DataEntryError { + path: request.path, + error: Some(proto::Error { + code: 400, + reason: "bad_request".to_owned(), + message: "Bad Wildcard Pattern Request".to_owned(), + }), + }); + continue; + } + let view = proto::View::from_i32(request.view).ok_or_else(|| { tonic::Status::invalid_argument(format!("Invalid View (id: {}", request.view)) })?;