[Python-checkins] python/dist/src/Lib csv.py,1.4,1.5

rhettinger@users.sourceforge.net rhettinger@users.sourceforge.net
Wed, 11 Jun 2003 20:01:57 -0700


Update of /cvsroot/python/python/dist/src/Lib
In directory sc8-pr-cvs1:/tmp/cvs-serv20789

Modified Files:
	csv.py 
Log Message:
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.



Index: csv.py
===================================================================
RCS file: /cvsroot/python/python/dist/src/Lib/csv.py,v
retrieving revision 1.4
retrieving revision 1.5
diff -C2 -d -r1.4 -r1.5
*** csv.py	19 May 2003 15:33:36 -0000	1.4
--- csv.py	12 Jun 2003 03:01:55 -0000	1.5
***************
*** 149,152 ****
--- 149,157 ----
          return self.writer.writerows(rows)
  
+ # Guard Sniffer's type checking against builds that exclude complex()
+ try:
+     complex
+ except NameError:
+     complex = float
  
  class Sniffer:
***************
*** 361,371 ****
          # 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))
  
--- 366,369 ----
***************
*** 387,402 ****
  
              for col in columnTypes.keys():
!                 try:
                      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:
                      # fallback to length of string
                      thisType = len(row[col])
  
                  if thisType != columnTypes[col]:
                      if columnTypes[col] is None: # add new column type
--- 385,403 ----
  
              for col in columnTypes.keys():
! 
!                 for thisType in [int, long, float, complex]:
                      try:
!                         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
***************
*** 418,423 ****
              else: # attempt typecast
                  try:
!                     eval("%s(%s)" % (colType.__name__, header[col]))
!                 except:
                      hasHeader += 1
                  else:
--- 419,424 ----
              else: # attempt typecast
                  try:
!                     colType(header[col])
!                 except ValueError, TypeError:
                      hasHeader += 1
                  else: