Merge pull request #525 from 17dec/eof-numbers
Return EOF on truncated numbers
diff --git a/src/de.rs b/src/de.rs
index e3effc3..f8d4ace 100644
--- a/src/de.rs
+++ b/src/de.rs
@@ -380,7 +380,14 @@
}
fn parse_integer(&mut self, positive: bool) -> Result<ParserNumber> {
- match try!(self.next_char_or_null()) {
+ let next = match try!(self.next_char()) {
+ Some(b) => b,
+ None => {
+ return Err(self.error(ErrorCode::EofWhileParsingValue));
+ }
+ };
+
+ match next {
b'0' => {
// There can be only one leading '0'.
match try!(self.peek_or_null()) {
@@ -496,7 +503,10 @@
}
if !at_least_one_digit {
- return Err(self.peek_error(ErrorCode::InvalidNumber));
+ match try!(self.peek()) {
+ Some(_) => return Err(self.peek_error(ErrorCode::InvalidNumber)),
+ None => return Err(self.peek_error(ErrorCode::EofWhileParsingValue)),
+ }
}
match try!(self.peek_or_null()) {
@@ -525,8 +535,15 @@
_ => true,
};
+ let next = match try!(self.next_char()) {
+ Some(b) => b,
+ None => {
+ return Err(self.error(ErrorCode::EofWhileParsingValue));
+ }
+ };
+
// Make sure a digit follows the exponent place.
- let mut exp = match try!(self.next_char_or_null()) {
+ let mut exp = match next {
c @ b'0'...b'9' => (c - b'0') as i32,
_ => {
return Err(self.error(ErrorCode::InvalidNumber));
@@ -623,19 +640,19 @@
}
#[cfg(feature = "arbitrary_precision")]
- fn scan_or_null(&mut self, buf: &mut String) -> Result<u8> {
+ fn scan_or_eof(&mut self, buf: &mut String) -> Result<u8> {
match try!(self.next_char()) {
Some(b) => {
buf.push(b as char);
Ok(b)
}
- None => Ok(b'\x00'),
+ None => Err(self.error(ErrorCode::EofWhileParsingValue))
}
}
#[cfg(feature = "arbitrary_precision")]
fn scan_integer(&mut self, buf: &mut String) -> Result<()> {
- match try!(self.scan_or_null(buf)) {
+ match try!(self.scan_or_eof(buf)) {
b'0' => {
// There can be only one leading '0'.
match try!(self.peek_or_null()) {
@@ -680,7 +697,10 @@
}
if !at_least_one_digit {
- return Err(self.peek_error(ErrorCode::InvalidNumber));
+ match try!(self.peek()) {
+ Some(_) => return Err(self.peek_error(ErrorCode::InvalidNumber)),
+ None => return Err(self.peek_error(ErrorCode::EofWhileParsingValue)),
+ }
}
match try!(self.peek_or_null()) {
@@ -706,7 +726,7 @@
}
// Make sure a digit follows the exponent place.
- match try!(self.scan_or_null(buf)) {
+ match try!(self.scan_or_eof(buf)) {
b'0'...b'9' => {}
_ => {
return Err(self.error(ErrorCode::InvalidNumber));
diff --git a/tests/stream.rs b/tests/stream.rs
index 7127b25..88a3952 100644
--- a/tests/stream.rs
+++ b/tests/stream.rs
@@ -82,6 +82,36 @@
}
#[test]
+fn test_json_stream_truncated_decimal() {
+ let data = "{\"x\":4.";
+
+ test_stream!(data, Value, |stream| {
+ assert!(stream.next().unwrap().unwrap_err().is_eof());
+ assert_eq!(stream.byte_offset(), 0);
+ });
+}
+
+#[test]
+fn test_json_stream_truncated_negative() {
+ let data = "{\"x\":-";
+
+ test_stream!(data, Value, |stream| {
+ assert!(stream.next().unwrap().unwrap_err().is_eof());
+ assert_eq!(stream.byte_offset(), 0);
+ });
+}
+
+#[test]
+fn test_json_stream_truncated_exponent() {
+ let data = "{\"x\":4e";
+
+ test_stream!(data, Value, |stream| {
+ assert!(stream.next().unwrap().unwrap_err().is_eof());
+ assert_eq!(stream.byte_offset(), 0);
+ });
+}
+
+#[test]
fn test_json_stream_empty() {
let data = "";
diff --git a/tests/test.rs b/tests/test.rs
index 6948ee2..afa6a01 100644
--- a/tests/test.rs
+++ b/tests/test.rs
@@ -737,15 +737,15 @@
test_parse_err::<f64>(&[
("+", "expected value at line 1 column 1"),
(".", "expected value at line 1 column 1"),
- ("-", "invalid number at line 1 column 1"),
+ ("-", "EOF while parsing a value at line 1 column 1"),
("00", "invalid number at line 1 column 2"),
("0x80", "trailing characters at line 1 column 2"),
("\\0", "expected value at line 1 column 1"),
- ("1.", "invalid number at line 1 column 2"),
+ ("1.", "EOF while parsing a value at line 1 column 2"),
("1.a", "invalid number at line 1 column 3"),
("1.e1", "invalid number at line 1 column 3"),
- ("1e", "invalid number at line 1 column 2"),
- ("1e+", "invalid number at line 1 column 3"),
+ ("1e", "EOF while parsing a value at line 1 column 2"),
+ ("1e+", "EOF while parsing a value at line 1 column 3"),
("1a", "trailing characters at line 1 column 2"),
(
"100e777777777777777777777777777",