svn commit: r346610 - user/ngie/bug-237403/tests/sys/opencrypto

Enji Cooper ngie at FreeBSD.org
Tue Sep 3 14:07:27 UTC 2019


Author: ngie
Date: Tue Apr 23 22:37:49 2019
New Revision: 346610
URL: https://svnweb.freebsd.org/changeset/base/346610

Log:
  KATParser: don't leak `self.fp`
  
  As noted by the python 3 interpreter, self.fp is leaked every time KATParser
  is called (it raises a `ResourceWarning`).
  
  Refactor KATParser in order to not leak `self.fp`:
  
  * Don't allocate `self.fp` in `__init__()`. Doing so requires adding
    `self.fp.close()`, and as noted before, makes for very fragile code when the
    interpreter is tearing down objects (it can result in crashes in some
    interpreter versions if triggered with the right conditions). Limit `self.fp`
    allocation/use to context suites ("the with statement") instead, as this is
    more likely to not cause non-deterministic weirdness issues with the
    interpreter.
  * Rename `__iter__` to `__next__` as it was providing `__next__` support and
    return the KATParser object instead with `__iter__`, as `__iter__` is meant
    to return an iterator and `__next__` is meant to help iterate over an
    iterator.

Modified:
  user/ngie/bug-237403/tests/sys/opencrypto/cryptodev.py
  user/ngie/bug-237403/tests/sys/opencrypto/cryptotest.py

Modified: user/ngie/bug-237403/tests/sys/opencrypto/cryptodev.py
==============================================================================
--- user/ngie/bug-237403/tests/sys/opencrypto/cryptodev.py	Tue Apr 23 22:34:32 2019	(r346609)
+++ user/ngie/bug-237403/tests/sys/opencrypto/cryptodev.py	Tue Apr 23 22:37:49 2019	(r346610)
@@ -316,11 +316,23 @@ class MismatchError(Exception):
 
 class KATParser:
     def __init__(self, fname, fields):
-        self.fp = open(fname)
         self.fields = set(fields)
         self._pending = None
+        self.fname = fname
+        self.fp = None
 
+    def __enter__(self):
+        self.fp = open(self.fname)
+        return self
+
+    def __exit__(self, exc_type, exc_value, exc_tb):
+        if self.fp is not None:
+            self.fp.close()
+
     def __iter__(self):
+        return self
+
+    def __next__(self):
         while True:
             didread = False
             if self._pending is not None:
@@ -331,14 +343,15 @@ class KATParser:
                 didread = True
 
             if didread and not i:
-                return
+                raise StopIteration
 
-            if (i and i[0] == '#') or not i.strip():
-                continue
-            if i[0] == '[':
-                yield i[1:].split(']', 1)[0], self.fielditer()
-            else:
-                raise ValueError('unknown line: %r' % repr(i))
+            if not i.startswith('#') and i.strip():
+                break
+
+        if i[0] == '[':
+            yield i[1:].split(']', 1)[0], self.fielditer()
+        else:
+            raise ValueError('unknown line: %r' % repr(i))
 
     def eatblanks(self):
         while True:

Modified: user/ngie/bug-237403/tests/sys/opencrypto/cryptotest.py
==============================================================================
--- user/ngie/bug-237403/tests/sys/opencrypto/cryptotest.py	Tue Apr 23 22:34:32 2019	(r346609)
+++ user/ngie/bug-237403/tests/sys/opencrypto/cryptotest.py	Tue Apr 23 22:37:49 2019	(r346610)
@@ -94,8 +94,12 @@ def GenTestCase(cname):
             else:
                 raise RuntimeError('unknown mode: %r' % repr(mode))
 
-            for bogusmode, lines in cryptodev.KATParser(fname,
-                [ 'Count', 'Key', 'IV', 'CT', 'AAD', 'Tag', 'PT', ]):
+            columns = [ 'Count', 'Key', 'IV', 'CT', 'AAD', 'Tag', 'PT', ]
+            with cryptodev.KATParser(fname, columns) as parser:
+                self.runGCMWithParser(parser, mode)
+
+        def runGCMWithParser(self, parser, mode):
+            for _, lines in next(parser):
                 for data in lines:
                     curcnt = int(data['Count'])
                     cipherkey = binascii.unhexlify(data['Key'])
@@ -155,9 +159,13 @@ def GenTestCase(cname):
                                 repr(data))
 
         def runCBC(self, fname):
+            columns = [ 'COUNT', 'KEY', 'IV', 'PLAINTEXT', 'CIPHERTEXT', ]
+            with cryptodev.KATParser(fname, columns) as parser:
+                self.runCBCWithParser(parser)
+
+        def runCBCWithParser(self, parser):
             curfun = None
-            for mode, lines in cryptodev.KATParser(fname,
-                [ 'COUNT', 'KEY', 'IV', 'PLAINTEXT', 'CIPHERTEXT', ]):
+            for mode, lines in next(parser):
                 if mode == 'ENCRYPT':
                     swapptct = False
                     curfun = Crypto.encrypt
@@ -182,10 +190,14 @@ def GenTestCase(cname):
                     self.assertEqual(r, ct)
 
         def runXTS(self, fname, meth):
+            columns = [ 'COUNT', 'DataUnitLen', 'Key', 'DataUnitSeqNumber', 'PT',
+                        'CT']
+            with cryptodev.KATParser(fname, columns) as parser:
+                self.runXTSWithParser(parser, meth)
+
+        def runXTSWithParser(self, parser, meth):
             curfun = None
-            for mode, lines in cryptodev.KATParser(fname,
-                [ 'COUNT', 'DataUnitLen', 'Key', 'DataUnitSeqNumber', 'PT',
-                'CT' ]):
+            for mode, lines in next(parser):
                 if mode == 'ENCRYPT':
                     swapptct = False
                     curfun = Crypto.encrypt
@@ -228,9 +240,13 @@ def GenTestCase(cname):
                 self.runTDES(i)
 
         def runTDES(self, fname):
+            columns = [ 'COUNT', 'KEYs', 'IV', 'PLAINTEXT', 'CIPHERTEXT', ]
+            with cryptodev.KATParser(fname, columns) as parser:
+                self.runTDESWithParser(parser)
+
+        def runTDESWithParser(self, parser):
             curfun = None
-            for mode, lines in cryptodev.KATParser(fname,
-                [ 'COUNT', 'KEYs', 'IV', 'PLAINTEXT', 'CIPHERTEXT', ]):
+            for mode, lines in next(parser):
                 if mode == 'ENCRYPT':
                     swapptct = False
                     curfun = Crypto.encrypt
@@ -271,8 +287,12 @@ def GenTestCase(cname):
                 self.runSHA1HMAC(i)
 
         def runSHA1HMAC(self, fname):
-            for hashlength, lines in cryptodev.KATParser(fname,
-                [ 'Count', 'Klen', 'Tlen', 'Key', 'Msg', 'Mac' ]):
+            columns = [ 'Count', 'Klen', 'Tlen', 'Key', 'Msg', 'Mac' ]
+            with cryptodev.KATParser(fname, columns) as parser:
+                self.runSHA1HMACWithParser(parser)
+
+        def runSHA1HMACWithParser(self, parser):
+            for hashlength, lines in next(parser):
                 # E.g., hashlength will be "L=20" (bytes)
                 hashlen = int(hashlength.split("=")[1])
 




More information about the svn-src-user mailing list