Repository: serde-rs/json (language: rust)

Issue:
Get ExpectedSomeIdent error instead of Eof error if the input ends with a truncated "null"
```rust
extern crate serde_json;

fn main() {
    match serde_json::from_str::<serde_json::Value>("nu") {
        Ok(_) => unreachable!(),
        Err(err) => match err.classify() {
            serde_json::error::Category::Eof => println!("OK"),
            other => panic!("expected Eof but got {:?} {:?}", other, err),
        },
    };
}
```

```
thread 'main' panicked at 'expected Eof but got Syntax Error("expected ident", line: 1, column: 2)', src/main.rs:8:22
```

dtolnay said on IRC that this is a bug.


Discussion / hints:

Fix patch:
diff --git a/src/de.rs b/src/de.rs
index b154cad60..f1c5c3cff 100644
--- a/src/de.rs
+++ b/src/de.rs
@@ -308,9 +308,16 @@ impl<'de, R: Read<'de>> Deserializer<R> {
     }
 
     fn parse_ident(&mut self, ident: &[u8]) -> Result<()> {
-        for c in ident {
-            if Some(*c) != try!(self.next_char()) {
-                return Err(self.error(ErrorCode::ExpectedSomeIdent));
+        for expected in ident {
+            match try!(self.next_char()) {
+                None => {
+                    return Err(self.error(ErrorCode::EofWhileParsingValue));
+                }
+                Some(next) => {
+                    if next != *expected {
+                        return Err(self.error(ErrorCode::ExpectedSomeIdent));
+                    }
+                }
             }
         }
 


Test patch:
diff --git a/tests/test.rs b/tests/test.rs
index 0b84ce869..811c409af 100644
--- a/tests/test.rs
+++ b/tests/test.rs
@@ -613,6 +613,15 @@ where
         let mut de = Deserializer::from_str(&twoline);
         IgnoredAny::deserialize(&mut de).unwrap();
         assert_eq!(0xDEAD_BEEF, u64::deserialize(&mut de).unwrap());
+
+        // Make sure every prefix is an EOF error, except that a prefix of a
+        // number may be a valid number.
+        if !json_value.is_number() {
+            for (i, _) in s.trim_right().char_indices() {
+                assert!(from_str::<Value>(&s[..i]).unwrap_err().is_eof());
+                assert!(from_str::<IgnoredAny>(&s[..i]).unwrap_err().is_eof());
+            }
+        }
     }
 }
 
@@ -671,8 +680,8 @@ where
 #[test]
 fn test_parse_null() {
     test_parse_err::<()>(&[
-        ("n", "expected ident at line 1 column 1"),
-        ("nul", "expected ident at line 1 column 3"),
+        ("n", "EOF while parsing a value at line 1 column 1"),
+        ("nul", "EOF while parsing a value at line 1 column 3"),
         ("nulla", "trailing characters at line 1 column 5"),
     ]);
 
@@ -682,9 +691,9 @@ fn test_parse_null() {
 #[test]
 fn test_parse_bool() {
     test_parse_err::<bool>(&[
-        ("t", "expected ident at line 1 column 1"),
+        ("t", "EOF while parsing a value at line 1 column 1"),
         ("truz", "expected ident at line 1 column 4"),
-        ("f", "expected ident at line 1 column 1"),
+        ("f", "EOF while parsing a value at line 1 column 1"),
         ("faz", "expected ident at line 1 column 3"),
         ("truea", "trailing characters at line 1 column 5"),
         ("falsea", "trailing characters at line 1 column 6"),