Skip to content
This repository has been archived by the owner on Jun 9, 2018. It is now read-only.

Commit

Permalink
Fixed an endless loop when a ClosePath segment was followed by a number.
Browse files Browse the repository at this point in the history
'.' was parsed as '0' by 'Steam::parse_number'. Now it's an error.
  • Loading branch information
RazrFalcon committed Feb 23, 2017
1 parent 5130824 commit c55d9a7
Show file tree
Hide file tree
Showing 6 changed files with 36 additions and 8 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ and this project adheres to [Semantic Versioning](http://semver.org/).

### Fixed
- Few panics that can be triggered by an invalid input.
- `.` was parsed as `0` by `Steam::parse_number`. Now it's an error.
- Endless loop when a ClosePath segment was followed by a number.

## [0.2.1] - 2017-02-01
### Fixed
Expand Down
5 changes: 5 additions & 0 deletions src/path.rs
Original file line number Diff line number Diff line change
Expand Up @@ -177,6 +177,11 @@ impl<'a> Tokenizer<'a> {
// unwrap is safe, because we checked 'has_prev_cmd'
let prev_cmd = self.prev_cmd.unwrap();

// ClosePath can't be followed by a number
if prev_cmd == b'Z' || prev_cmd == b'z' {
data_error!();
}

if prev_cmd == b'M' || prev_cmd == b'm' {
// 'If a moveto is followed by multiple pairs of coordinates, the subsequent
// pairs are treated as implicit lineto commands.'
Expand Down
7 changes: 7 additions & 0 deletions src/stream.rs
Original file line number Diff line number Diff line change
Expand Up @@ -816,6 +816,13 @@ impl<'a> Stream<'a> {

let mut fraction: f64;
if mant_size == 0 {
// check that input is not equal to '.', which is not a number(0)
if self.is_char_eq(b'.')? {
// back to start
self.pos = start;
return Err(Error::InvalidNumber(self.gen_error_pos()));
}

return Ok(0.0);
} else {
let mut frac1 = 0.0;
Expand Down
1 change: 0 additions & 1 deletion src/svg.rs
Original file line number Diff line number Diff line change
Expand Up @@ -396,7 +396,6 @@ impl<'a> Tokenizer<'a> {

// check that element has tag name
if start_pos == self.stream.pos() {
// return Err(Error::ElementWithoutTagName(self.stream.gen_error_pos()));
return Err(Error::InvalidSvgToken(self.stream.gen_error_pos()));
}

Expand Down
15 changes: 15 additions & 0 deletions tests/path.rs
Original file line number Diff line number Diff line change
Expand Up @@ -221,3 +221,18 @@ test!(close_path_3, b"M10 20 L 30 40 Z Z Z",
Segment { cmd: b'Z', data: SegmentData::ClosePath },
Segment { cmd: b'Z', data: SegmentData::ClosePath }
);

// first token should be EndOfStream
test!(invalid_1, b"M\t.", );

#[test]
fn invalid_2() {
// ClosePath can't be followed by a number
let stream = Stream::new(b"M0 0 Z 2");
let mut s = Tokenizer::new(stream);
assert_eq!(s.parse_next().unwrap(),
SegmentToken::Segment(Segment { cmd: b'M', data: SegmentData::MoveTo { x: 0.0, y: 0.0 } }));
assert_eq!(s.parse_next().unwrap(),
SegmentToken::Segment(Segment { cmd: b'Z', data: SegmentData::ClosePath }));
assert_eq!(s.parse_next().unwrap(), SegmentToken::EndOfStream);
}
14 changes: 7 additions & 7 deletions tests/stream.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,6 @@ test_number!(number_19, b"1ex", 1.0);
test_number!(number_20, b"1em", 1.0);
test_number!(number_21, b"12345678901234567890", 12345678901234567000.0);
test_number!(number_22, b"0.", 0.0);
test_number!(number_23, b".", 0.0); // TODO: probably wrong

// ---

Expand All @@ -52,12 +51,13 @@ macro_rules! test_number_err {
)
}

test_number_err!(number_err_1, b"q", Error::InvalidNumber(ErrorPos::new(1,1)));
test_number_err!(number_err_2, b"", Error::InvalidNumber(ErrorPos::new(1,1)));
test_number_err!(number_err_3, b"-", Error::UnexpectedEndOfStream(ErrorPos::new(1,2)));
test_number_err!(number_err_4, b"+", Error::UnexpectedEndOfStream(ErrorPos::new(1,2)));
test_number_err!(number_err_5, b"-q", Error::InvalidNumber(ErrorPos::new(1,1)));
test_number_err!(number_err_6, b"1e1111", Error::InvalidNumber(ErrorPos::new(1,1)));
test_number_err!(number_err_1, b"q", Error::InvalidNumber(ErrorPos::new(1,1)));
test_number_err!(number_err_2, b"", Error::InvalidNumber(ErrorPos::new(1,1)));
test_number_err!(number_err_3, b"-", Error::UnexpectedEndOfStream(ErrorPos::new(1,2)));
test_number_err!(number_err_4, b"+", Error::UnexpectedEndOfStream(ErrorPos::new(1,2)));
test_number_err!(number_err_5, b"-q", Error::InvalidNumber(ErrorPos::new(1,1)));
test_number_err!(number_err_6, b"1e1111", Error::InvalidNumber(ErrorPos::new(1,1)));
test_number_err!(number_err_7, b".", Error::InvalidNumber(ErrorPos::new(1,1)));

// ---

Expand Down

0 comments on commit c55d9a7

Please sign in to comment.