aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAlex Crichton <alex@alexcrichton.com>2019-01-07 09:06:04 -0800
committerAlex Crichton <alex@alexcrichton.com>2019-01-07 09:06:04 -0800
commit7ee1c1b4798f18135ee618e30ccedfdf1f365451 (patch)
treee68d6abaaa3a5e142980b728672915ae8df7a600 /src
parentad5ea1d904d5196fa63b77e826f82c377b604602 (diff)
downloadmilf-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.rs36
1 files changed, 30 insertions, 6 deletions
diff --git a/src/de.rs b/src/de.rs
index 5f04027..85aef61 100644
--- a/src/de.rs
+++ b/src/de.rs
@@ -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 {