diff options
author | Raymond Hettinger <python@rcn.com> | 2003-06-12 03:01:55 (GMT) |
---|---|---|
committer | Raymond Hettinger <python@rcn.com> | 2003-06-12 03:01:55 (GMT) |
commit | 39a55920018ef19cc01b53063a2f090fe05d4982 (patch) | |
tree | 675c2a6abb335aaf42e6bd368a877dfed05459b0 /Lib/csv.py | |
parent | 1546bc43feb5f0ccb09710342ac3267fcf8cf55d (diff) | |
download | cpython-39a55920018ef19cc01b53063a2f090fe05d4982.zip cpython-39a55920018ef19cc01b53063a2f090fe05d4982.tar.gz cpython-39a55920018ef19cc01b53063a2f090fe05d4982.tar.bz2 |
SF Patch #744104: Remove eval() from csv
Eliminates the eval() step in the csv module resulting in better
security, more clarity, and a little speed.
The idea is to make successive attempts to coerce the string to
a python type:
int(s), long(s), float(s), etc.
As a by-product, eliminates a bare 'except' statement.
Diffstat (limited to 'Lib/csv.py')
-rw-r--r-- | Lib/csv.py | 35 |
1 files changed, 18 insertions, 17 deletions
@@ -148,6 +148,11 @@ class DictWriter: rows.append(self._dict_to_list(rowdict)) return self.writer.writerows(rows) +# Guard Sniffer's type checking against builds that exclude complex() +try: + complex +except NameError: + complex = float class Sniffer: ''' @@ -360,13 +365,6 @@ class Sniffer: # Finally, a 'vote' is taken at the end for each column, adding or # subtracting from the likelihood of the first row being a header. - def seval(item): - """ - Strips parens from item prior to calling eval in an - attempt to make it safer - """ - return eval(item.replace('(', '').replace(')', '')) - rdr = reader(StringIO(sample), self.sniff(sample)) header = rdr.next() # assume first row is header @@ -386,18 +384,21 @@ class Sniffer: continue # skip rows that have irregular number of columns for col in columnTypes.keys(): - try: + + for thisType in [int, long, float, complex]: try: - # is it a built-in type (besides string)? - thisType = type(seval(row[col])) - except OverflowError: - # a long int? - thisType = type(seval(row[col] + 'L')) - thisType = type(0) # treat long ints as int - except: + thisType(row[col]) + break + except ValueError, OverflowError: + pass + else: # fallback to length of string thisType = len(row[col]) + # treat longs as ints + if thisType == long: + thisType = int + if thisType != columnTypes[col]: if columnTypes[col] is None: # add new column type columnTypes[col] = thisType @@ -417,8 +418,8 @@ class Sniffer: hasHeader -= 1 else: # attempt typecast try: - eval("%s(%s)" % (colType.__name__, header[col])) - except: + colType(header[col]) + except ValueError, TypeError: hasHeader += 1 else: hasHeader -= 1 |