Skip to content
This repository has been archived by the owner on Dec 18, 2024. It is now read-only.

Commit

Permalink
Separate pattern and path validation
Browse files Browse the repository at this point in the history
  • Loading branch information
rafaeling committed Oct 17, 2023
1 parent b0fc44d commit ca8a3eb
Show file tree
Hide file tree
Showing 3 changed files with 60 additions and 11 deletions.
2 changes: 1 addition & 1 deletion kuksa_databroker/databroker/src/broker.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1026,7 +1026,7 @@ impl<'a, 'b> DatabaseWriteAccess<'a, 'b> {
allowed: Option<types::DataValue>,
datapoint: Option<Datapoint>,
) -> Result<i32, RegistrationError> {
if !glob::is_valid_pattern(name.as_str()) {
if !glob::is_valid_path(name.as_str()) {
return Err(RegistrationError::ValidationError);
}

Expand Down
57 changes: 47 additions & 10 deletions kuksa_databroker/databroker/src/glob.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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::*;
Expand Down Expand Up @@ -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"));
Expand All @@ -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\\:]+$");
Expand Down
12 changes: 12 additions & 0 deletions kuksa_databroker/databroker/src/grpc/kuksa_val_v1/val.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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))
})?;
Expand Down

0 comments on commit ca8a3eb

Please sign in to comment.