diff --git a/.github/workflows/rust.yml b/.github/workflows/rust.yml index ad33e37..c600890 100644 --- a/.github/workflows/rust.yml +++ b/.github/workflows/rust.yml @@ -2,21 +2,22 @@ name: master on: push: - branches: [ "master" ] + branches: ["master"] pull_request: - branches: [ "master" ] + branches: ["master"] env: CARGO_TERM_COLOR: always jobs: build: - runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4 - - name: Build - run: cargo build --verbose - - name: Run tests - run: cargo test --verbose --features mtk + - uses: actions/checkout@v4 + - name: Build + run: cargo build --verbose + - name: Run tests strict + run: cargo test --no-default-features -F mtk,strict + - name: Run tests non strict + run: cargo test --no-default-features -F mtk diff --git a/Cargo.toml b/Cargo.toml index 86a2ab3..1372c76 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -14,12 +14,13 @@ readme = "README.md" [dependencies] [features] -default = [] +default = ["strict"] mtk = [] +strict = [] [badges] travis-ci = { repository = "nsforth/nmea0183", branch = "v0.4.0" } -codecov = { repository = "nsforth/nmea0183"} +codecov = { repository = "nsforth/nmea0183" } is-it-maintained-issue-resolution = { repository = "nsforth/nmea0183" } is-it-maintained-open-issues = { repository = "nsforth/nmea0183" } maintenance = { status = "actively-developed" } diff --git a/README.md b/README.md index bde0939..060e3f0 100644 --- a/README.md +++ b/README.md @@ -13,6 +13,7 @@ You do not need to do any preprocessing such as split data to strings or NMEA se # Optional features Parser supports Mediatek-related PMTKSPF non-standard sentence. It is disabled by default. Use "mtk" feature if you need it. +If your receives somehow violates NMEA spec, try disable "strict" feature which enabled by default. For example, without "strict" feauture sentence size is set to 120 chars instead of standart NMEA 79 chars. # Examples @@ -77,5 +78,3 @@ Should not panic. If so please report issue on project page. `NMEA format error!` - Possible data corruption. Parser drops all accumulated data and starts seek new sentences. It's possible to got other very rare error messages that relates to protocol errors. Receivers nowadays mostly do not violate NMEA specs. - - diff --git a/src/lib.rs b/src/lib.rs index b57a6d3..891dba3 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -175,8 +175,8 @@ impl TryFrom<&str> for Source { "GL" => Ok(Source::GLONASS), "GA" => Ok(Source::Gallileo), "BD" => Ok(Source::Beidou), - "GN" => Ok(Source::GNSS), - #[cfg(feature = "mtk")] + "GN" => Ok(Source::GNSS), + #[cfg(feature = "mtk")] "PM" => Ok(Source::MTK), _ => Err("Source is not supported!"), } @@ -280,10 +280,18 @@ pub enum ParseResult { GSA(Option), } +#[cfg(feature = "strict")] +/// Maximum allowed sentence length, according to NMEA 183 docs should be not more than 79 chars. Disable strict feature to parse up to 120 chars. +pub const MAX_SENTENCE_LENGTH: usize = 79usize; + +#[cfg(not(feature = "strict"))] +/// Maximum allowed sentence length. +pub const MAX_SENTENCE_LENGTH: usize = 120usize; + /// Parses NMEA sentences and stores intermediate parsing state. /// Parser is tolerant for errors so you should not reinitialize it after errors. pub struct Parser { - buffer: [u8; 79], + buffer: [u8; MAX_SENTENCE_LENGTH], buflen: usize, chksum: u8, expected_chksum: u8, @@ -334,7 +342,7 @@ impl Parser { /// Constructs new Parser. pub fn new() -> Parser { Parser { - buffer: [0u8; 79], + buffer: [0u8; MAX_SENTENCE_LENGTH], buflen: 0, chksum: 0, expected_chksum: 0, diff --git a/tests/parsing.rs b/tests/parsing.rs index 8c55db7..28ee28c 100644 --- a/tests/parsing.rs +++ b/tests/parsing.rs @@ -17,6 +17,7 @@ use nmea0183::VTG; use nmea0183::{ParseResult, Parser, Source}; #[test] +#[cfg(feature = "strict")] fn test_too_long_sentence() { let line = "$01234567890123456789012345678901234567890123456789012345678901234567890123456789"; let mut caught_error = false; @@ -33,6 +34,24 @@ fn test_too_long_sentence() { assert!(caught_error); } +#[test] +#[cfg(not(feature = "strict"))] +fn test_too_long_sentence_non_strict() { + let line = "$01234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890012345678901234567890"; + let mut caught_error = false; + for result in Parser::new().parse_from_bytes(line.as_bytes()) { + match result { + Ok(_) => continue, + Err("NMEA sentence is too long!") => { + caught_error = true; + break; + } + Err(_) => panic!("Unexpected error caught in test!"), + } + } + assert!(caught_error); +} + #[test] fn test_correct_but_unsupported_source() { let mut p = Parser::new();