aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.travis.yml4
-rw-r--r--Cargo.toml11
-rw-r--r--src/lib.rs84
3 files changed, 77 insertions, 22 deletions
diff --git a/.travis.yml b/.travis.yml
index 998e56d..5bd24ea 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -7,5 +7,5 @@ rust:
- nightly
script:
- - cargo test --all
-
+ - cargo test --no-default-features
+ - cargo test
diff --git a/Cargo.toml b/Cargo.toml
index 2d7a457..f6a4b55 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -9,9 +9,10 @@ repository = "https://github.com/jwilm/vte"
documentation = "https://docs.rs/vte/"
readme = "README.md"
-[dependencies.utf8parse]
-path = "utf8parse"
-version = "0.1"
-
-[workspace]
+[dependencies]
+arrayvec = { version = "0.5.1", default-features = false, optional = true }
+utf8parse = { path = "utf8parse", version = "0.1.0" }
+[features]
+default = ["no_std"]
+no_std = ["arrayvec"]
diff --git a/src/lib.rs b/src/lib.rs
index 1b9f58c..4daeba2 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -30,12 +30,19 @@
//! [`Parser`]: struct.Parser.html
//! [`Perform`]: trait.Perform.html
//! [Paul Williams' ANSI parser state machine]: https://vt100.net/emu/dec_ansi_parser
-#![no_std]
+#![cfg_attr(feature = "no_std", no_std)]
+#[cfg(feature = "no_std")]
+extern crate arrayvec;
+#[cfg(not(feature = "no_std"))]
+extern crate core;
extern crate utf8parse as utf8;
use core::mem::{self, MaybeUninit};
+#[cfg(feature = "no_std")]
+use arrayvec::ArrayVec;
+
mod definitions;
mod table;
@@ -58,6 +65,7 @@ impl State {
}
const MAX_INTERMEDIATES: usize = 2;
+#[cfg(any(feature = "no_std", test))]
const MAX_OSC_RAW: usize = 1024;
const MAX_PARAMS: usize = 16;
@@ -85,9 +93,11 @@ pub struct Parser {
params: [i64; MAX_PARAMS],
param: i64,
num_params: usize,
- osc_raw: [u8; MAX_OSC_RAW],
+ #[cfg(feature = "no_std")]
+ osc_raw: ArrayVec<[u8; MAX_OSC_RAW]>,
+ #[cfg(not(feature = "no_std"))]
+ osc_raw: Vec<u8>,
osc_params: [(usize, usize); MAX_PARAMS],
- osc_idx: usize,
osc_num_params: usize,
ignoring: bool,
utf8_parser: utf8::Parser,
@@ -103,9 +113,11 @@ impl Parser {
params: [0i64; MAX_PARAMS],
param: 0,
num_params: 0,
- osc_raw: [0; MAX_OSC_RAW],
+ #[cfg(feature = "no_std")]
+ osc_raw: ArrayVec::new(),
+ #[cfg(not(feature = "no_std"))]
+ osc_raw: Vec::new(),
osc_params: [(0, 0); MAX_PARAMS],
- osc_idx: 0,
osc_num_params: 0,
ignoring: false,
utf8_parser: utf8::Parser::new(),
@@ -235,15 +247,19 @@ impl Parser {
}
Action::Put => performer.put(byte),
Action::OscStart => {
- self.osc_idx = 0;
+ self.osc_raw.clear();
self.osc_num_params = 0;
}
Action::OscPut => {
- let idx = self.osc_idx;
- if idx == self.osc_raw.len() {
- return;
+ #[cfg(feature = "no_std")]
+ {
+ if self.osc_raw.is_full() {
+ return;
+ }
}
+ let idx = self.osc_raw.len();
+
// Param separator
if byte == b';' {
let param_idx = self.osc_num_params;
@@ -266,13 +282,12 @@ impl Parser {
self.osc_num_params += 1;
} else {
- self.osc_raw[idx] = byte;
- self.osc_idx += 1;
+ self.osc_raw.push(byte);
}
}
Action::OscEnd => {
let param_idx = self.osc_num_params;
- let idx = self.osc_idx;
+ let idx = self.osc_raw.len();
match param_idx {
// Finish last parameter if not already maxed
@@ -405,15 +420,16 @@ pub trait Perform {
fn esc_dispatch(&mut self, params: &[i64], intermediates: &[u8], ignore: bool, byte: u8);
}
-#[cfg(test)]
+#[cfg(all(test, feature = "no_std"))]
#[macro_use]
extern crate std;
#[cfg(test)]
mod tests {
- use super::{Parser, Perform};
- use core::i64;
+ use super::*;
+
use std::vec::Vec;
+ use core::i64;
static OSC_BYTES: &'static [u8] = &[
0x1b, 0x5d, // Begin OSC
@@ -694,4 +710,42 @@ mod tests {
assert_eq!(dispatcher.c, Some('|'));
assert_eq!(dispatcher.s, b"17/ab".to_vec());
}
+
+ #[test]
+ fn exceed_max_buffer_size() {
+ static NUM_BYTES: usize = MAX_OSC_RAW + 100;
+ static INPUT_START: &'static [u8] = &[
+ 0x1b, b']', b'5', b'2', b';', b's'
+ ];
+ static INPUT_END: &'static [u8] = &[b'\x07'];
+
+ let mut dispatcher = OscDispatcher::default();
+ let mut parser = Parser::new();
+
+ // Create valid OSC escape
+ for byte in INPUT_START {
+ parser.advance(&mut dispatcher, *byte);
+ }
+
+ // Exceed max buffer size
+ for _ in 0..NUM_BYTES {
+ parser.advance(&mut dispatcher, b'a');
+ }
+
+ // Terminate escape for dispatch
+ for byte in INPUT_END {
+ parser.advance(&mut dispatcher, *byte);
+ }
+
+ assert!(dispatcher.dispatched_osc);
+
+ assert_eq!(dispatcher.params.len(), 2);
+ assert_eq!(dispatcher.params[0], b"52");
+
+ #[cfg(not(feature = "no_std"))]
+ assert_eq!(dispatcher.params[1].len(), NUM_BYTES + INPUT_END.len());
+
+ #[cfg(feature = "no_std")]
+ assert_eq!(dispatcher.params[1].len(), MAX_OSC_RAW - dispatcher.params[0].len());
+ }
}