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",