[tor-commits] [stem/master] Fix unicode normalization for python3 compatibility

atagar at torproject.org atagar at torproject.org
Sun Jul 2 21:54:56 UTC 2017


commit 0d7a3d12174eab9a3fe4d91a1a13998311014df9
Author: Damian Johnson <atagar at torproject.org>
Date:   Sun Jul 2 14:52:24 2017 -0700

    Fix unicode normalization for python3 compatibility
    
    Recent descriptor creation work had a few bytes/unicode normalizaiton issues
    breaking python3 compatibility.
---
 stem/descriptor/__init__.py                               |  3 ++-
 stem/descriptor/server_descriptor.py                      | 12 ++++++++----
 test/settings.cfg                                         |  4 ++--
 test/unit/descriptor/networkstatus/directory_authority.py |  2 +-
 4 files changed, 13 insertions(+), 8 deletions(-)

diff --git a/stem/descriptor/__init__.py b/stem/descriptor/__init__.py
index 806e3e3..e61d205 100644
--- a/stem/descriptor/__init__.py
+++ b/stem/descriptor/__init__.py
@@ -1062,7 +1062,8 @@ def _random_crypto_blob(block_type = None):
   Provides a random string that can be used for crypto blocks.
   """
 
-  crypto_blob = '\n'.join(stem.util.str_tools._split_by_length(base64.b64encode('%0140x' % random.randrange(16 ** 140)), 64))
+  random_base64 = stem.util.str_tools._to_unicode(base64.b64encode(os.urandom(140)))
+  crypto_blob = '\n'.join(stem.util.str_tools._split_by_length(random_base64, 64))
 
   if block_type:
     return '\n-----BEGIN %s-----\n%s\n-----END %s-----' % (block_type, crypto_blob, block_type)
diff --git a/stem/descriptor/server_descriptor.py b/stem/descriptor/server_descriptor.py
index 180fe53..2e1c776 100644
--- a/stem/descriptor/server_descriptor.py
+++ b/stem/descriptor/server_descriptor.py
@@ -120,6 +120,10 @@ DEFAULT_IPV6_EXIT_POLICY = stem.exit_policy.MicroExitPolicy('reject 1-65535')
 REJECT_ALL_POLICY = stem.exit_policy.ExitPolicy('reject *:*')
 
 
+def _truncated_b64encode(content):
+  return stem.util.str_tools._to_unicode(base64.b64encode(content).rstrip(b'='))
+
+
 def _parse_file(descriptor_file, is_bridge = False, validate = False, **kwargs):
   """
   Iterates over the server descriptors in a file.
@@ -829,7 +833,7 @@ class RelayDescriptor(ServerDescriptor):
         signing_key = create_signing_key()
 
       if 'fingerprint' not in attr:
-        fingerprint = hashlib.sha1(_bytes_for_block(signing_key.public_digest.strip())).hexdigest().upper()
+        fingerprint = hashlib.sha1(_bytes_for_block(stem.util.str_tools._to_unicode(signing_key.public_digest.strip()))).hexdigest().upper()
         attr['fingerprint'] = ' '.join(stem.util.str_tools._split_by_length(fingerprint, 4))
 
       attr['signing-key'] = signing_key.public_digest
@@ -874,8 +878,8 @@ class RelayDescriptor(ServerDescriptor):
     attr = {
       'r': ' '.join([
         self.nickname,
-        base64.b64encode(binascii.unhexlify(self.fingerprint)).rstrip('='),
-        base64.b64encode(binascii.unhexlify(self.digest())).rstrip('='),
+        _truncated_b64encode(binascii.unhexlify(stem.util.str_tools._to_bytes(self.fingerprint))),
+        _truncated_b64encode(binascii.unhexlify(stem.util.str_tools._to_bytes(self.digest()))),
         self.published.strftime('%Y-%m-%d %H:%M:%S'),
         self.address,
         str(self.or_port),
@@ -892,7 +896,7 @@ class RelayDescriptor(ServerDescriptor):
       attr['a'] = ['%s:%s' % (addr, port) for addr, port, _ in self.or_addresses]
 
     if self.certificate:
-      attr['id'] = 'ed25519 %s' % base64.b64encode(self.certificate.key).rstrip('=')
+      attr['id'] = 'ed25519 %s' % _truncated_b64encode(self.certificate.key)
 
     return RouterStatusEntryV3.create(attr)
 
diff --git a/test/settings.cfg b/test/settings.cfg
index 4854c24..963ba59 100644
--- a/test/settings.cfg
+++ b/test/settings.cfg
@@ -146,8 +146,8 @@ pycodestyle.ignore test/unit/util/connection.py => W291: _tor     tor        158
 # issue.
 
 pyflakes.ignore run_tests.py => 'unittest' imported but unused
-pyflakes.ignore stem/__init__.py => undefined name 'long'
-pyflakes.ignore stem/__init__.py => undefined name 'unicode'
+pyflakes.ignore stem/util/__init__.py => undefined name 'long'
+pyflakes.ignore stem/util/__init__.py => undefined name 'unicode'
 pyflakes.ignore stem/control.py => undefined name 'controller'
 pyflakes.ignore stem/manual.py => undefined name 'unichr'
 pyflakes.ignore stem/prereq.py => 'int_to_bytes' imported but unused
diff --git a/test/unit/descriptor/networkstatus/directory_authority.py b/test/unit/descriptor/networkstatus/directory_authority.py
index 8c1e64e..81ad4a5 100644
--- a/test/unit/descriptor/networkstatus/directory_authority.py
+++ b/test/unit/descriptor/networkstatus/directory_authority.py
@@ -271,7 +271,7 @@ class TestDirectoryAuthority(unittest.TestCase):
 
     # exclude  key cert from a vote
 
-    content = '\n'.join(DirectoryAuthority.content(is_vote = True).splitlines()[:-5])
+    content = b'\n'.join(DirectoryAuthority.content(is_vote = True).splitlines()[:-5])
     self.assertRaises(ValueError, DirectoryAuthority, content, True, True)
 
     authority = DirectoryAuthority(content, False, True)





More information about the tor-commits mailing list