[tor-commits] [stem/master] Validating the order of fields in documents

atagar at torproject.org atagar at torproject.org
Sat Oct 13 18:35:45 UTC 2012


commit f23c5312b671dd2bd41baa5a0c24568592ac3241
Author: Damian Johnson <atagar at torproject.org>
Date:   Sat Sep 8 11:23:08 2012 -0700

    Validating the order of fields in documents
    
    As mentioned in the prior commit, to be valid network status fields need to
    appear in a particular order. Checking for this as part of document validation.
---
 stem/descriptor/networkstatus.py |   33 ++++++++++++++++++++++++++++++++-
 1 files changed, 32 insertions(+), 1 deletions(-)

diff --git a/stem/descriptor/networkstatus.py b/stem/descriptor/networkstatus.py
index e55c06f..5676c16 100644
--- a/stem/descriptor/networkstatus.py
+++ b/stem/descriptor/networkstatus.py
@@ -255,8 +255,8 @@ class NetworkStatusDocument(stem.descriptor.Descriptor):
     document_file = StringIO(raw_content)
     header, footer, routers_end = _get_document_content(document_file, validate)
     
-    self._parse(header, footer, validate)
     self._parse_old(header + footer, validate)
+    self._parse(header, footer, validate)
     
     if document_file.tell() < routers_end:
       self.routers = tuple(_get_routers(document_file, validate, self, routers_end, self._get_router_type()))
@@ -298,6 +298,7 @@ class NetworkStatusDocument(stem.descriptor.Descriptor):
       
       is_consensus = header_entries['vote-status'][0][0] == "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)
   
   def _parse_old(self, raw_content, validate):
     # preamble
@@ -430,6 +431,36 @@ class NetworkStatusDocument(stem.descriptor.Descriptor):
     
     if disallowed_fields:
       raise ValueError("Network status document has fields that shouldn't appear in this document type: %s" % ', '.join(disallowed_fields))
+  
+  def _check_for_misordered_fields(self, is_consensus, header_entries, footer_entries):
+    """
+    To be valid a network status document's fiends need to appear in a specific
+    order. Checks that known fields appear in that order (unrecognized fields
+    are ignored).
+    """
+    
+    # Earlier validation has ensured that our fields either belong to our
+    # document type or are unknown. Remove the unknown fields since they
+    # reflect a spec change and can appear anywhere in the document.
+    
+    expected_header = [attr[0] for attr in HEADER_STATUS_DOCUMENT_FIELDS]
+    expected_footer = [attr[0] for attr in FOOTER_STATUS_DOCUMENT_FIELDS]
+    
+    actual_header = filter(lambda field: field in expected_header, header_entries.keys())
+    actual_footer = filter(lambda field: field in expected_footer, footer_entries.keys())
+    
+    # Narrow the expected_header and expected_footer to just what we have. If
+    # the lists then match then the order's valid.
+    
+    expected_header = filter(lambda field: field in actual_header, expected_header)
+    expected_footer = filter(lambda field: field in actual_footer, expected_footer)
+    
+    for label, actual, expected in (('header', actual_header, expected_header),
+                                    ('footer', actual_footer, expected_footer)):
+      if actual != expected:
+        actual_label = ', '.join(actual)
+        expected_label = ', '.join(expected)
+        raise ValueError("The fields in the document's %s are misordered. It should be '%s' but was '%s'" % (lable, actual_label, expected_label))
 
 class DirectoryAuthority(stem.descriptor.Descriptor):
   """





More information about the tor-commits mailing list