Index: main/waeup.kofa/trunk/CHANGES.txt
===================================================================
--- main/waeup.kofa/trunk/CHANGES.txt	(revision 14935)
+++ main/waeup.kofa/trunk/CHANGES.txt	(revision 14939)
@@ -4,4 +4,6 @@
 1.6.dev0 (unreleased)
 =======================
+
+* Do not allow uploading data with trailing whitespaces.
 
 * Do no longer hide the 'Create students' buttons but switch the portal to
Index: main/waeup.kofa/trunk/src/waeup/kofa/browser/pages.py
===================================================================
--- main/waeup.kofa/trunk/src/waeup/kofa/browser/pages.py	(revision 14935)
+++ main/waeup.kofa/trunk/src/waeup/kofa/browser/pages.py	(revision 14939)
@@ -1345,9 +1345,14 @@
             invalid_line = check_csv_charset(filecontent.splitlines())
             if invalid_line:
-                self.flash(_(
-                    "Your file contains forbidden characters or "
-                    "has invalid CSV format. "
-                    "First problematic line detected: line %s. "
-                    "Please replace." % invalid_line), type='danger')
+                if invalid_line == -1:
+                    self.flash(_(
+                        "The data in your file contain trailing whitespaces."
+                        "Please replace."), type='danger')
+                else:
+                    self.flash(_(
+                        "Your file contains forbidden characters or "
+                        "has invalid CSV format. "
+                        "First problematic line detected: line %s. "
+                        "Please replace." % invalid_line), type='danger')
                 logger.info('%s - invalid file uploaded: %s' %
                             (ob_class, target))
Index: main/waeup.kofa/trunk/src/waeup/kofa/browser/tests/forbidden_file_2.csv
===================================================================
--- main/waeup.kofa/trunk/src/waeup/kofa/browser/tests/forbidden_file_2.csv	(revision 14939)
+++ main/waeup.kofa/trunk/src/waeup/kofa/browser/tests/forbidden_file_2.csv	(revision 14939)
@@ -0,0 +1,2 @@
+student_id,firstname,lastname,reg_number,date_of_birth,matric_number,email,phone,sex,state
+X666666,Aaren ,Pieri,1,1990-01-02,100000,,1234,M,courses validated
Index: main/waeup.kofa/trunk/src/waeup/kofa/browser/tests/test_browser.py
===================================================================
--- main/waeup.kofa/trunk/src/waeup/kofa/browser/tests/test_browser.py	(revision 14935)
+++ main/waeup.kofa/trunk/src/waeup/kofa/browser/tests/test_browser.py	(revision 14939)
@@ -40,4 +40,6 @@
 SAMPLE_FILE = os.path.join(os.path.dirname(__file__), 'test_file.csv')
 FORBIDDEN_FILE = os.path.join(os.path.dirname(__file__), 'forbidden_file.csv')
+FORBIDDEN_FILE_2 = os.path.join(
+    os.path.dirname(__file__), 'forbidden_file_2.csv')
 
 class UniversitySetup(FunctionalTestCase):
@@ -193,4 +195,25 @@
         self.assertTrue(
             'Your file contains forbidden characters or'
+            in self.browser.contents)
+        logfile = os.path.join(
+            self.app['datacenter'].storage, 'logs', 'datacenter.log')
+        logcontent = open(logfile).read()
+        self.assertTrue('zope.mgr - browser.pages.DatacenterUploadPage - '
+            'invalid file uploaded:' in logcontent)
+        return
+
+    def test_forbidden_file_upload_2(self):
+        self.browser.addHeader('Authorization', 'Basic mgr:mgrpw')
+        self.browser.open(self.datacenter_path)
+        self.assertEqual(self.browser.headers['Status'], '200 Ok')
+        self.assertEqual(self.browser.url, self.datacenter_path)
+        self.browser.getLink("Upload data").click()
+        file = open(FORBIDDEN_FILE_2)
+        ctrl = self.browser.getControl(name='uploadfile:file')
+        file_ctrl = ctrl.mech_control
+        file_ctrl.add_file(file, filename='my_corrupted_file.csv')
+        self.browser.getControl('Upload').click()
+        self.assertTrue(
+            'The data in your file contain trailing whitespaces.'
             in self.browser.contents)
         logfile = os.path.join(
Index: main/waeup.kofa/trunk/src/waeup/kofa/utils/helpers.py
===================================================================
--- main/waeup.kofa/trunk/src/waeup/kofa/utils/helpers.py	(revision 14935)
+++ main/waeup.kofa/trunk/src/waeup/kofa/utils/helpers.py	(revision 14939)
@@ -756,5 +756,6 @@
 
 def check_csv_charset(iterable):
-    """Check contents of `iterable` regarding valid CSV encoding.
+    """Check contents of `iterable` regarding valid CSV encoding and
+    trailing whitespaces in data.
 
     `iterable` is expected to be an iterable on _rows_ (not
@@ -764,5 +765,6 @@
 
     Returns line num of first illegal char or ``None``. Line nums
-    start counting with 1 (not zero).
+    start counting with 1 (not zero). Returns -1 if data contain
+    trailing whitespaces.
     """
     linenum = 1
@@ -771,4 +773,7 @@
         for row in reader:
             linenum += 1
+            for value in row.values():
+                if value.endswith(' '):
+                    return -1
     except UnicodeDecodeError:
         return linenum
Index: main/waeup.kofa/trunk/src/waeup/kofa/utils/tests/test_helpers.py
===================================================================
--- main/waeup.kofa/trunk/src/waeup/kofa/utils/tests/test_helpers.py	(revision 14935)
+++ main/waeup.kofa/trunk/src/waeup/kofa/utils/tests/test_helpers.py	(revision 14939)
@@ -537,4 +537,13 @@
         self.assertEqual(helpers.check_csv_charset(csv), 2)
 
+
+    def test_invalid_data3(self):
+        csv = (
+            "code,title,title_prefix\n"
+            "FAC1,Faculty 1,faculty\n"
+            "FAC2,Faculty 2 ,institute\n"
+            "FAC3,Fäcülty 3,school\n"
+            ).splitlines()
+        self.assertEqual(helpers.check_csv_charset(csv), -1)
 
 class MemInfoTestCase(unittest.TestCase):
