diff options
author | Alex Crichton <alex@alexcrichton.com> | 2019-01-07 09:06:04 -0800 |
---|---|---|
committer | Alex Crichton <alex@alexcrichton.com> | 2019-01-07 09:06:04 -0800 |
commit | 7ee1c1b4798f18135ee618e30ccedfdf1f365451 (patch) | |
tree | e68d6abaaa3a5e142980b728672915ae8df7a600 /src | |
parent | ad5ea1d904d5196fa63b77e826f82c377b604602 (diff) | |
download | milf-rs-7ee1c1b4798f18135ee618e30ccedfdf1f365451.tar.gz milf-rs-7ee1c1b4798f18135ee618e30ccedfdf1f365451.zip |
Fix disallowing duplicate table headers
This commit fixes #279 where a case of duplicate table headers slipped
through the cracks. This also adds an option to disable this new
validation to allow Cargo to preserve backwards compatibility.
Diffstat (limited to 'src')
-rw-r--r-- | src/de.rs | 36 |
1 files changed, 30 insertions, 6 deletions
@@ -197,6 +197,7 @@ enum ErrorKind { /// Deserialization implementation for TOML. pub struct Deserializer<'a> { require_newline_after_table: bool, + allow_duplciate_after_longer_table: bool, input: &'a str, tokens: Tokenizer<'a>, } @@ -335,12 +336,24 @@ impl<'de, 'b> de::MapAccess<'de> for MapVisitor<'de, 'b> { // Test to see if we're duplicating our parent's table, and if so // then this is an error in the toml format - if self.cur_parent != pos - && self.tables[self.cur_parent].header == self.tables[pos].header - { - let at = self.tables[pos].at; - let name = self.tables[pos].header.join("."); - return Err(self.de.error(at, ErrorKind::DuplicateTable(name))); + if self.cur_parent != pos { + if self.tables[self.cur_parent].header == self.tables[pos].header { + let at = self.tables[pos].at; + let name = self.tables[pos].header.join("."); + return Err(self.de.error(at, ErrorKind::DuplicateTable(name))); + } + + // If we're here we know we should share the same prefix, and if + // the longer table was defined first then we want to narrow + // down our parent's length if possible to ensure that we catch + // duplicate tables defined afterwards. + if !self.de.allow_duplciate_after_longer_table { + let parent_len = self.tables[self.cur_parent].header.len(); + let cur_len = self.tables[pos].header.len(); + if cur_len < parent_len { + self.cur_parent = pos; + } + } } let table = &mut self.tables[pos]; @@ -965,6 +978,7 @@ impl<'a> Deserializer<'a> { tokens: Tokenizer::new(input), input: input, require_newline_after_table: true, + allow_duplciate_after_longer_table: false, } } @@ -986,6 +1000,16 @@ impl<'a> Deserializer<'a> { self.require_newline_after_table = require; } + /// Historical versions of toml-rs accidentally allowed a duplicate table + /// header after a longer table header was previously defined. This is + /// invalid according to the TOML spec, however. + /// + /// This option can be set to `true` (the default is `false`) to emulate + /// this behavior for backwards compatibility with older toml-rs versions. + pub fn set_allow_duplicate_after_longer_table(&mut self, allow: bool) { + self.allow_duplciate_after_longer_table = allow; + } + fn tables(&mut self) -> Result<Vec<Table<'a>>, Error> { let mut tables = Vec::new(); let mut cur_table = Table { |