aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRaymond Hettinger <python@rcn.com>2003-06-12 03:01:55 +0000
committerRaymond Hettinger <python@rcn.com>2003-06-12 03:01:55 +0000
commit39a55920018ef19cc01b53063a2f090fe05d4982 (patch)
tree675c2a6abb335aaf42e6bd368a877dfed05459b0 /Lib/csv.py
parentadd a couple test cases which involve longs and floats in 'e' format. (diff)
downloadcpython-39a55920018ef19cc01b53063a2f090fe05d4982.tar.gz
cpython-39a55920018ef19cc01b53063a2f090fe05d4982.tar.bz2
cpython-39a55920018ef19cc01b53063a2f090fe05d4982.zip
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.py35
1 files changed, 18 insertions, 17 deletions
diff --git a/Lib/csv.py b/Lib/csv.py
index 83b8aa447de..851150218fc 100644
--- a/Lib/csv.py
+++ b/Lib/csv.py
@@ -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