Changeset 10676


Ignore:
Timestamp:
31 Oct 2013, 17:51:25 (11 years ago)
Author:
uli
Message:

Check uploaded CSV files more thoroughly before processing.

Location:
main/waeup.kofa/trunk/src/waeup/kofa
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • main/waeup.kofa/trunk/src/waeup/kofa/browser/pages.py

    r10650 r10676  
    6969from waeup.kofa.authentication import LocalRoleSetEvent
    7070from waeup.kofa.widgets.htmlwidget import HTMLDisplayWidget
    71 from waeup.kofa.utils.helpers import get_user_account
     71from waeup.kofa.utils.helpers import get_user_account, check_csv_charset
    7272from waeup.kofa.mandates.mandate import PasswordMandate
    7373from waeup.kofa.datacenter import DataCenterFile
     
    10651065
    10661066            # Forbid certain characters in import files.
    1067             for element in filecontent:
    1068                 try:
    1069                     if ord(element) in FORBIDDEN_CHARACTERS:
    1070                       self.flash(_(
    1071                           "Your file contains forbidden characters. "
    1072                           "Please replace."))
    1073                       logger.info('%s - invalid file uploaded: %s' %
    1074                           (ob_class, target))
    1075                       return
    1076                 except TypeError:
    1077                     self.flash(_(
    1078                         "Your file contains forbidden characters. "
    1079                         "Please replace."))
    1080                     logger.info('%s - invalid file uploaded: %s' %
    1081                         (ob_class, target))
    1082                     return
     1067            invalid_line = check_csv_charset(filecontent.splitlines())
     1068            if invalid_line:
     1069                self.flash(_(
     1070                    "Your file contains forbidden characters or "
     1071                    "has invalid CSV format. "
     1072                    "First problematic line detected: line %s. "
     1073                    "Please replace." % invalid_line))
     1074                logger.info('%s - invalid file uploaded: %s' %
     1075                            (ob_class, target))
     1076                return
    10831077
    10841078            open(target, 'wb').write(filecontent)
  • main/waeup.kofa/trunk/src/waeup/kofa/browser/tests/test_browser.py

    r10634 r10676  
    157157        self.browser.getControl('Upload').click()
    158158        self.assertTrue(
    159             'Your file contains forbidden characters. Please replace.'
     159            'Your file contains forbidden characters or'
    160160            in self.browser.contents)
    161161        logfile = os.path.join(
  • main/waeup.kofa/trunk/src/waeup/kofa/utils/helpers.py

    r10028 r10676  
    713713    def emit(self, record):
    714714        pass
     715
     716
     717def check_csv_charset(iterable):
     718    """Check contents of `iterable` regarding valid CSV encoding.
     719
     720    `iterable` is expected to be an iterable on _rows_ (not
     721    chars). This is true for instance for
     722    filehandlers. `zope.publisher.browser.FileUpload` instances are
     723    _not_ iterable, unfortunately.
     724
     725    Returns line num of first illegal char or ``None``. Line nums
     726    start counting with 1 (not zero).
     727    """
     728    linenum = 1
     729    reader = csv.DictReader(iterable)
     730    try:
     731        for row in reader:
     732            linenum += 1
     733    except UnicodeDecodeError:
     734        return linenum
     735    except:
     736        return linenum + 1
     737    return None
  • main/waeup.kofa/trunk/src/waeup/kofa/utils/tests/test_helpers.py

    r9689 r10676  
    492492
    493493
     494class CheckCSVCharsetTestCase(unittest.TestCase):
     495
     496    def test_valid_data1(self):
     497        csv = (
     498            'col1,col2,col3\n'
     499            'val1,val2,val3\n'
     500            ).splitlines()
     501        self.assertEqual(helpers.check_csv_charset(csv), None)
     502
     503    def test_valid_data2(self):
     504        csv = (
     505            "code,title,title_prefix\n"
     506            "FAC1,Faculty 1,faculty\n"
     507            "FAC2,Faculty 2,institute\n"
     508            "FAC3,Fäcülty 3,school\n"
     509            ).splitlines()
     510        self.assertEqual(helpers.check_csv_charset(csv), None)
     511
     512    def test_invalid_data1(self):
     513        csv = (
     514            'col1,col2,col3\n' +
     515            chr(0x92) + 'val1,val2,val3\n'
     516            ).splitlines()
     517        self.assertEqual(helpers.check_csv_charset(csv), 1)
     518
     519    def test_invalid_data2(self):
     520        csv = (
     521            'some text that \n'
     522            '\n'      # this empty line will break
     523            'is not a csv file \n' + chr(0x92) + '\n'
     524            ).splitlines()
     525        self.assertEqual(helpers.check_csv_charset(csv), 2)
    494526
    495527def test_suite():
     
    509541        MergeCSVFileTestCase,
    510542        SimpleHelpersTestCase,
     543        CheckCSVCharsetTestCase,
    511544        ]:
    512545        suite.addTests(
Note: See TracChangeset for help on using the changeset viewer.