[tor-commits] [stem/master] Validating that fields aren't duplicated
atagar at torproject.org
atagar at torproject.org
Sat Oct 13 18:35:45 UTC 2012
commit db87c88965806ec13f9888c220879af45fc65e44
Author: Damian Johnson <atagar at torproject.org>
Date: Sat Sep 8 11:54:33 2012 -0700
Validating that fields aren't duplicated
Almost all of the fields in a network status document can only appear once.
Checking that this is a case. This also includes a unit test for the
validation. I'm a little surprised that the old parser doesn't choke on
duplicated content, but I'm about to replace it so probably not worth
investigating.
---
stem/descriptor/networkstatus.py | 19 ++++++++++++++++
test/unit/descriptor/networkstatus/document.py | 28 ++++++++++++++++++++++++
2 files changed, 47 insertions(+), 0 deletions(-)
diff --git a/stem/descriptor/networkstatus.py b/stem/descriptor/networkstatus.py
index 5676c16..2140b4d 100644
--- a/stem/descriptor/networkstatus.py
+++ b/stem/descriptor/networkstatus.py
@@ -297,8 +297,27 @@ class NetworkStatusDocument(stem.descriptor.Descriptor):
raise ValueError("Network status documents must have a 'vote-status' line to say if they're a vote or consensus")
is_consensus = header_entries['vote-status'][0][0] == "consensus"
+ is_vote = not is_consensus
self._check_for_missing_and_disallowed_fields(is_consensus, header_entries, footer_entries)
self._check_for_misordered_fields(is_consensus, header_entries, footer_entries)
+
+ known_fields = [attr[0] for attr in HEADER_STATUS_DOCUMENT_FIELDS + FOOTER_STATUS_DOCUMENT_FIELDS]
+ content = header + '\n' + footer
+
+ entries = dict()
+ entries.update(header_entries)
+ entries.update(footer_entries)
+
+ for keyword, values in entries.items():
+ value, block_contents = values[0]
+ line = "%s %s" % (keyword, value)
+
+ # All known fields can only appear once except...
+ # * 'directory-signature' in a consensus
+
+ if validate and len(values) > 1 and keyword in known_fields:
+ if not (keyword == 'directory-signature' and is_consensus):
+ raise ValueError("Network status documents can only have a single '%s' line, got %i:\n%s" % (keyword, len(values), content))
def _parse_old(self, raw_content, validate):
# preamble
diff --git a/test/unit/descriptor/networkstatus/document.py b/test/unit/descriptor/networkstatus/document.py
index d2bbe90..ef77391 100644
--- a/test/unit/descriptor/networkstatus/document.py
+++ b/test/unit/descriptor/networkstatus/document.py
@@ -186,4 +186,32 @@ class TestNetworkStatusDocument(unittest.TestCase):
content = "\n".join(test_lines)
self.assertRaises(ValueError, NetworkStatusDocument, content)
NetworkStatusDocument(content, False) # constructs without validation
+
+ def test_duplicate_fields(self):
+ """
+ Almost all fields can only appear once. Checking that duplicates cause
+ validation errors.
+ """
+
+ for is_consensus in (True, False):
+ attr = {"vote-status": "consensus"} if is_consensus else {"vote-status": "vote"}
+ lines = get_network_status_document(attr).split("\n")
+
+ for i in xrange(len(lines)):
+ # Stop when we hit the 'directory-signature' for a couple reasons...
+ # - that is the one field that can validly appear multiple times
+ # - after it is a crypto blob, which won't trigger this kind of
+ # validation failure
+
+ test_lines = list(lines)
+ if test_lines[i].startswith("directory-signature "):
+ break
+
+ # duplicates the line
+ test_lines.insert(i, test_lines[i])
+
+ content = "\n".join(test_lines)
+ self.assertRaises(ValueError, NetworkStatusDocument, content)
+ NetworkStatusDocument(content, False) # constructs without validation
+
More information about the tor-commits
mailing list