Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 39a5592

Browse files
committed
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.
1 parent 1546bc4 commit 39a5592

1 file changed

Lines changed: 18 additions & 17 deletions

File tree

Lib/csv.py

Lines changed: 18 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -148,6 +148,11 @@ def writerows(self, rowdicts):
148148
rows.append(self._dict_to_list(rowdict))
149149
return self.writer.writerows(rows)
150150

151+
# Guard Sniffer's type checking against builds that exclude complex()
152+
try:
153+
complex
154+
except NameError:
155+
complex = float
151156

152157
class Sniffer:
153158
'''
@@ -360,13 +365,6 @@ def has_header(self, sample):
360365
# Finally, a 'vote' is taken at the end for each column, adding or
361366
# subtracting from the likelihood of the first row being a header.
362367

363-
def seval(item):
364-
"""
365-
Strips parens from item prior to calling eval in an
366-
attempt to make it safer
367-
"""
368-
return eval(item.replace('(', '').replace(')', ''))
369-
370368
rdr = reader(StringIO(sample), self.sniff(sample))
371369

372370
header = rdr.next() # assume first row is header
@@ -386,18 +384,21 @@ def seval(item):
386384
continue # skip rows that have irregular number of columns
387385

388386
for col in columnTypes.keys():
389-
try:
387+
388+
for thisType in [int, long, float, complex]:
390389
try:
391-
# is it a built-in type (besides string)?
392-
thisType = type(seval(row[col]))
393-
except OverflowError:
394-
# a long int?
395-
thisType = type(seval(row[col] + 'L'))
396-
thisType = type(0) # treat long ints as int
397-
except:
390+
thisType(row[col])
391+
break
392+
except ValueError, OverflowError:
393+
pass
394+
else:
398395
# fallback to length of string
399396
thisType = len(row[col])
400397

398+
# treat longs as ints
399+
if thisType == long:
400+
thisType = int
401+
401402
if thisType != columnTypes[col]:
402403
if columnTypes[col] is None: # add new column type
403404
columnTypes[col] = thisType
@@ -417,8 +418,8 @@ def seval(item):
417418
hasHeader -= 1
418419
else: # attempt typecast
419420
try:
420-
eval("%s(%s)" % (colType.__name__, header[col]))
421-
except:
421+
colType(header[col])
422+
except ValueError, TypeError:
422423
hasHeader += 1
423424
else:
424425
hasHeader -= 1

0 commit comments

Comments
 (0)