Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/parsers.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
///! Parsers shared by both protocols.
//! Parsers shared by both protocols.
use nom::{
bytes::complete::take_while1, character::complete::digit1, combinator::map,
combinator::map_res, IResult,
Expand Down
2 changes: 1 addition & 1 deletion src/rfc3164.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
///! Parsers for rfc 3164 specific formats.
//! Parsers for rfc 3164 specific formats.
use crate::{
message::{Message, Protocol},
parsers::{hostname, tagname},
Expand Down
2 changes: 1 addition & 1 deletion src/rfc5424.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
///! Parsers for rfc 5424 specific formats.
//! Parsers for rfc 5424 specific formats.
use crate::{
message::{Message, Protocol},
parsers::{appname, digits, hostname, msgid, procid},
Expand Down
175 changes: 93 additions & 82 deletions src/structured_data.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use nom::{
branch::alt,
bytes::complete::{escaped, tag, take_till1, take_until, take_while1},
character::complete::{one_of, space0},
character::complete::{anychar, space0},
combinator::map,
multi::{many1, separated_list0},
sequence::{delimited, separated_pair, terminated, tuple},
Expand Down Expand Up @@ -97,6 +97,11 @@ impl<'a, S: AsRef<str> + Ord + Clone> Iterator for ParamsIter<'a, S> {
} else if c == 'n' && escaped {
escaped = false;
trimmed.push('\n');
} else if c != '"' && c != ']' && c != '\\' && escaped {
// If the character following the escape isn't a \, " or ] we treat it like an normal unescaped character.
escaped = false;
trimmed.push('\\');
trimmed.push(c);
} else {
escaped = false;
trimmed.push(c);
Expand All @@ -115,11 +120,7 @@ fn param_value(input: &str) -> IResult<&str, &str> {
map(tag(r#""""#), |_| ""),
delimited(
tag("\""),
escaped(
take_while1(|c: char| c != '\\' && c != '"'),
'\\',
one_of(r#""n\]"#),
),
escaped(take_while1(|c: char| c != '\\' && c != '"'), '\\', anychar),
tag("\""),
),
))(input)
Expand Down Expand Up @@ -190,86 +191,86 @@ pub(crate) fn structured_data_optional(
}
}

#[test]
fn parse_param_value() {
assert_eq!(
param_value("\"Some \\\"lovely\\\" string\"").unwrap(),
("", "Some \\\"lovely\\\" string")
);
}
#[cfg(test)]
mod tests {
use super::*;

#[test]
fn parse_empty_param_value() {
assert_eq!(param_value(r#""""#).unwrap(), ("", ""));
}
#[test]
fn parse_param_value() {
assert_eq!(
param_value("\"Some \\\"lovely\\\" string\"").unwrap(),
("", "Some \\\"lovely\\\" string")
);
}

#[test]
fn parse_structured_data() {
assert_eq!(
structured_datum_strict(
"[exampleSDID@32473 iut=\"3\" eventSource=\"Application\" eventID=\"1011\"]"
)
.unwrap(),
(
"",
Some(StructuredElement {
id: "exampleSDID@32473",
params: vec![
("iut", "3"),
("eventSource", "Application"),
("eventID", "1011"),
]
})
)
);
}
#[test]
fn parse_empty_param_value() {
assert_eq!(param_value(r#""""#).unwrap(), ("", ""));
}

#[test]
fn parse_structured_data_no_values() {
assert_eq!(
structured_datum(false)("[exampleSDID@32473]").unwrap(),
(
"",
Some(StructuredElement {
id: "exampleSDID@32473",
params: vec![]
})
)
);
}
#[test]
fn parse_structured_data() {
assert_eq!(
structured_datum_strict(
"[exampleSDID@32473 iut=\"3\" eventSource=\"Application\" eventID=\"1011\"]"
)
.unwrap(),
(
"",
Some(StructuredElement {
id: "exampleSDID@32473",
params: vec![
("iut", "3"),
("eventSource", "Application"),
("eventID", "1011"),
]
})
)
);
}

#[test]
fn parse_structured_data_with_space() {
assert_eq!(
structured_datum(false)(
"[exampleSDID@32473 iut=\"3\" eventSource= \"Application\" eventID=\"1011\"]"
)
.unwrap(),
(
"",
Some(StructuredElement {
id: "exampleSDID@32473",
params: vec![
("iut", "3"),
("eventSource", "Application"),
("eventID", "1011"),
]
})
)
);
}
#[test]
fn parse_structured_data_no_values() {
assert_eq!(
structured_datum(false)("[exampleSDID@32473]").unwrap(),
(
"",
Some(StructuredElement {
id: "exampleSDID@32473",
params: vec![]
})
)
);
}

#[test]
fn parse_invalid_structured_data() {
assert_eq!(
structured_datum(true)("[exampleSDID@32473 iut=]"),
Ok(("", None))
);
}
#[test]
fn parse_structured_data_with_space() {
assert_eq!(
structured_datum(false)(
"[exampleSDID@32473 iut=\"3\" eventSource= \"Application\" eventID=\"1011\"]"
)
.unwrap(),
(
"",
Some(StructuredElement {
id: "exampleSDID@32473",
params: vec![
("iut", "3"),
("eventSource", "Application"),
("eventID", "1011"),
]
})
)
);
}

#[cfg(test)]
mod tests {
use super::*;
#[test]
fn parse_invalid_structured_data() {
assert_eq!(
structured_datum(true)("[exampleSDID@32473 iut=]"),
Ok(("", None))
);
}

#[test]
fn parse_multiple_structured_data() {
Expand Down Expand Up @@ -351,7 +352,7 @@ mod tests {
#[test]
fn params_remove_escapes() {
let data = structured_data(
r#"[id aa="hullo \"there\"" bb="let's \\\\do this\\\\" cc="hello [bye\]" dd="hello\nbye"]"#,
r#"[id aa="hullo \"there\"" bb="let's \\\\do this\\\\" cc="hello [bye\]" dd="hello\nbye" ee="not \esc\aped"]"#,
)
.unwrap();
let params = data.1[0].params().collect::<Vec<_>>();
Expand All @@ -367,8 +368,18 @@ mod tests {
r#"hello
bye"#
.to_string(),
)
),
(&"ee", r#"not \esc\aped"#.to_string())
]
);
}

#[test]
fn sd_param_escapes() {
let (_, value) = param_value(r#""Here are some escaped characters -> \"\\\]""#).unwrap();
assert_eq!(r#"Here are some escaped characters -> \"\\\]"#, value);

let (_, value) = param_value(r#""These should not be escaped -> \n\m\o""#).unwrap();
assert_eq!(r#"These should not be escaped -> \n\m\o"#, value);
}
}