mirror of
https://github.com/serde-rs/json.git
synced 2025-10-03 07:46:05 +00:00
Merge pull request #353 from fmoor/feature/trailing_comma
change error type for trailing commas, fixes #352
This commit is contained in:
commit
adade3344a
25
src/de.rs
25
src/de.rs
@ -105,6 +105,7 @@ impl<'de, R: Read<'de>> Deserializer<R> {
|
|||||||
/// only has trailing whitespace.
|
/// only has trailing whitespace.
|
||||||
pub fn end(&mut self) -> Result<()> {
|
pub fn end(&mut self) -> Result<()> {
|
||||||
match try!(self.parse_whitespace()) {
|
match try!(self.parse_whitespace()) {
|
||||||
|
Some(b',') => Err(self.peek_error(ErrorCode::TrailingComma)),
|
||||||
Some(_) => Err(self.peek_error(ErrorCode::TrailingCharacters)),
|
Some(_) => Err(self.peek_error(ErrorCode::TrailingCharacters)),
|
||||||
None => Ok(()),
|
None => Ok(()),
|
||||||
}
|
}
|
||||||
@ -517,6 +518,13 @@ impl<'de, R: Read<'de>> Deserializer<R> {
|
|||||||
self.eat_char();
|
self.eat_char();
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
Some(b',') => {
|
||||||
|
self.eat_char();
|
||||||
|
match self.parse_whitespace() {
|
||||||
|
Ok(Some(b']')) => Err(self.peek_error(ErrorCode::TrailingComma)),
|
||||||
|
_ => Err(self.peek_error(ErrorCode::TrailingCharacters)),
|
||||||
|
}
|
||||||
|
}
|
||||||
Some(_) => Err(self.peek_error(ErrorCode::TrailingCharacters)),
|
Some(_) => Err(self.peek_error(ErrorCode::TrailingCharacters)),
|
||||||
None => Err(self.peek_error(ErrorCode::EofWhileParsingList)),
|
None => Err(self.peek_error(ErrorCode::EofWhileParsingList)),
|
||||||
}
|
}
|
||||||
@ -528,6 +536,7 @@ impl<'de, R: Read<'de>> Deserializer<R> {
|
|||||||
self.eat_char();
|
self.eat_char();
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
Some(b',') => Err(self.peek_error(ErrorCode::TrailingComma)),
|
||||||
Some(_) => Err(self.peek_error(ErrorCode::TrailingCharacters)),
|
Some(_) => Err(self.peek_error(ErrorCode::TrailingCharacters)),
|
||||||
None => Err(self.peek_error(ErrorCode::EofWhileParsingObject)),
|
None => Err(self.peek_error(ErrorCode::EofWhileParsingObject)),
|
||||||
}
|
}
|
||||||
@ -994,16 +1003,18 @@ impl<'de, 'a, R: Read<'de> + 'a> de::SeqAccess<'de> for SeqAccess<'a, R> {
|
|||||||
where
|
where
|
||||||
T: de::DeserializeSeed<'de>,
|
T: de::DeserializeSeed<'de>,
|
||||||
{
|
{
|
||||||
match try!(self.de.parse_whitespace()) {
|
let peek = match try!(self.de.parse_whitespace()) {
|
||||||
Some(b']') => {
|
Some(b']') => {
|
||||||
return Ok(None);
|
return Ok(None);
|
||||||
}
|
}
|
||||||
Some(b',') if !self.first => {
|
Some(b',') if !self.first => {
|
||||||
self.de.eat_char();
|
self.de.eat_char();
|
||||||
|
try!(self.de.parse_whitespace())
|
||||||
}
|
}
|
||||||
Some(_) => {
|
Some(b) => {
|
||||||
if self.first {
|
if self.first {
|
||||||
self.first = false;
|
self.first = false;
|
||||||
|
Some(b)
|
||||||
} else {
|
} else {
|
||||||
return Err(self.de.peek_error(ErrorCode::ExpectedListCommaOrEnd));
|
return Err(self.de.peek_error(ErrorCode::ExpectedListCommaOrEnd));
|
||||||
}
|
}
|
||||||
@ -1011,10 +1022,13 @@ impl<'de, 'a, R: Read<'de> + 'a> de::SeqAccess<'de> for SeqAccess<'a, R> {
|
|||||||
None => {
|
None => {
|
||||||
return Err(self.de.peek_error(ErrorCode::EofWhileParsingList));
|
return Err(self.de.peek_error(ErrorCode::EofWhileParsingList));
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
let value = try!(seed.deserialize(&mut *self.de));
|
match peek {
|
||||||
Ok(Some(value))
|
Some(b']') => Err(self.de.peek_error(ErrorCode::TrailingComma)),
|
||||||
|
Some(_) => Ok(Some(try!(seed.deserialize(&mut *self.de)))),
|
||||||
|
None => Err(self.de.peek_error(ErrorCode::EofWhileParsingValue)),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1062,6 +1076,7 @@ impl<'de, 'a, R: Read<'de> + 'a> de::MapAccess<'de> for MapAccess<'a, R> {
|
|||||||
|
|
||||||
match peek {
|
match peek {
|
||||||
Some(b'"') => seed.deserialize(MapKey { de: &mut *self.de }).map(Some),
|
Some(b'"') => seed.deserialize(MapKey { de: &mut *self.de }).map(Some),
|
||||||
|
Some(b'}') => Err(self.de.peek_error(ErrorCode::TrailingComma)),
|
||||||
Some(_) => Err(self.de.peek_error(ErrorCode::KeyMustBeAString)),
|
Some(_) => Err(self.de.peek_error(ErrorCode::KeyMustBeAString)),
|
||||||
None => Err(self.de.peek_error(ErrorCode::EofWhileParsingValue)),
|
None => Err(self.de.peek_error(ErrorCode::EofWhileParsingValue)),
|
||||||
}
|
}
|
||||||
|
@ -75,6 +75,7 @@ impl Error {
|
|||||||
ErrorCode::InvalidUnicodeCodePoint |
|
ErrorCode::InvalidUnicodeCodePoint |
|
||||||
ErrorCode::KeyMustBeAString |
|
ErrorCode::KeyMustBeAString |
|
||||||
ErrorCode::LoneLeadingSurrogateInHexEscape |
|
ErrorCode::LoneLeadingSurrogateInHexEscape |
|
||||||
|
ErrorCode::TrailingComma |
|
||||||
ErrorCode::TrailingCharacters |
|
ErrorCode::TrailingCharacters |
|
||||||
ErrorCode::UnexpectedEndOfHexEscape |
|
ErrorCode::UnexpectedEndOfHexEscape |
|
||||||
ErrorCode::RecursionLimitExceeded => Category::Syntax,
|
ErrorCode::RecursionLimitExceeded => Category::Syntax,
|
||||||
@ -244,6 +245,9 @@ pub enum ErrorCode {
|
|||||||
/// Lone leading surrogate in hex escape.
|
/// Lone leading surrogate in hex escape.
|
||||||
LoneLeadingSurrogateInHexEscape,
|
LoneLeadingSurrogateInHexEscape,
|
||||||
|
|
||||||
|
/// JSON has a comma after the last value in an array or map.
|
||||||
|
TrailingComma,
|
||||||
|
|
||||||
/// JSON has non-whitespace trailing characters after the value.
|
/// JSON has non-whitespace trailing characters after the value.
|
||||||
TrailingCharacters,
|
TrailingCharacters,
|
||||||
|
|
||||||
@ -321,6 +325,7 @@ impl Display for ErrorCode {
|
|||||||
ErrorCode::LoneLeadingSurrogateInHexEscape => {
|
ErrorCode::LoneLeadingSurrogateInHexEscape => {
|
||||||
f.write_str("lone leading surrogate in hex escape")
|
f.write_str("lone leading surrogate in hex escape")
|
||||||
}
|
}
|
||||||
|
ErrorCode::TrailingComma => f.write_str("trailing comma"),
|
||||||
ErrorCode::TrailingCharacters => f.write_str("trailing characters"),
|
ErrorCode::TrailingCharacters => f.write_str("trailing characters"),
|
||||||
ErrorCode::UnexpectedEndOfHexEscape => f.write_str("unexpected end of hex escape"),
|
ErrorCode::UnexpectedEndOfHexEscape => f.write_str("unexpected end of hex escape"),
|
||||||
ErrorCode::RecursionLimitExceeded => f.write_str("recursion limit exceeded"),
|
ErrorCode::RecursionLimitExceeded => f.write_str("recursion limit exceeded"),
|
||||||
|
@ -894,7 +894,7 @@ fn test_parse_list() {
|
|||||||
("[ ", "EOF while parsing a list at line 1 column 2"),
|
("[ ", "EOF while parsing a list at line 1 column 2"),
|
||||||
("[1", "EOF while parsing a list at line 1 column 2"),
|
("[1", "EOF while parsing a list at line 1 column 2"),
|
||||||
("[1,", "EOF while parsing a value at line 1 column 3"),
|
("[1,", "EOF while parsing a value at line 1 column 3"),
|
||||||
("[1,]", "expected value at line 1 column 4"),
|
("[1,]", "trailing comma at line 1 column 4"),
|
||||||
("[1 2]", "expected `,` or `]` at line 1 column 4"),
|
("[1 2]", "expected `,` or `]` at line 1 column 4"),
|
||||||
("[]a", "trailing characters at line 1 column 3"),
|
("[]a", "trailing characters at line 1 column 3"),
|
||||||
],
|
],
|
||||||
@ -1111,9 +1111,14 @@ fn test_parse_enum_errors() {
|
|||||||
"invalid type: map, expected tuple variant Animal::Frog at line 1 column 10"),
|
"invalid type: map, expected tuple variant Animal::Frog at line 1 column 10"),
|
||||||
("{\"Cat\":[]}", "invalid length 0, expected tuple of 2 elements at line 1 column 9"),
|
("{\"Cat\":[]}", "invalid length 0, expected tuple of 2 elements at line 1 column 9"),
|
||||||
("{\"Cat\":[0]}", "invalid length 1, expected tuple of 2 elements at line 1 column 10"),
|
("{\"Cat\":[0]}", "invalid length 1, expected tuple of 2 elements at line 1 column 10"),
|
||||||
("{\"Cat\":[0, \"\", 2]}", "trailing characters at line 1 column 14"),
|
("{\"Cat\":[0, \"\", 2]}", "trailing characters at line 1 column 16"),
|
||||||
("{\"Cat\":{\"age\": 5, \"name\": \"Kate\", \"foo\":\"bar\"}",
|
("{\"Cat\":{\"age\": 5, \"name\": \"Kate\", \"foo\":\"bar\"}",
|
||||||
"unknown field `foo`, expected `age` or `name` at line 1 column 39"),
|
"unknown field `foo`, expected `age` or `name` at line 1 column 39"),
|
||||||
|
|
||||||
|
// JSON does not allow trailing commas in data structures
|
||||||
|
("{\"Cat\":[0, \"Kate\",]}", "trailing comma at line 1 column 19"),
|
||||||
|
("{\"Cat\":{\"age\": 2, \"name\": \"Kate\",}}",
|
||||||
|
"trailing comma at line 1 column 34"),
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user