Report on non-printing characters in bad column headings
authorKarl O. Pinc <kop@karlpinc.com>
Thu, 15 Aug 2024 20:26:32 +0000 (15:26 -0500)
committerKarl O. Pinc <kop@karlpinc.com>
Thu, 15 Aug 2024 20:26:32 +0000 (15:26 -0500)
src/pgwui_upload_core/views/upload.py

index 39aa3d6cf681b1b8a84d1022706efe46934ac5b6..17a4522e78d1a811274ee0428ecdfb893e4d172b 100644 (file)
@@ -277,6 +277,21 @@ class InsertStmt:
     stmt = attrs.field(default=None)
     cols = attrs.field(default=None)
 
+    def report_nonprintable(self, chars):
+        if chars.isprintable():
+            return ''
+
+        positions = []
+        values = []
+        for pos, char in enumerate(chars, start=1):
+            if not char.isprintable():
+                positions.append(str(pos))
+                values.append(char.encode(errors='ignore').hex())
+
+        return (' [Note: The character(s) in position(s)'
+                f' {", ".join(positions)}'
+                f' are non-printable, in hex: {", ".join(values)}]')
+
     def report_bad_cols(self, qualified_table, bad_cols, quotecols):
         if quotecols:
             detail = ('<p>The following columns are not in the ({0})'
@@ -297,14 +312,15 @@ class InsertStmt:
                       ' or the table has column names containing'
                       ' upper case characters, or you do not have'
                       ' permission to access the columns:</p><ul>')
-        detail = detail.format(markupsafe.escape(qualified_table))
+        detail = [detail.format(markupsafe.escape(qualified_table))]
 
         for bad_col in bad_cols:
-            detail += '<li>{0}</li>'.format(markupsafe.escape(bad_col))
-        detail += '</ul>'
+            detail.append(f'<li>{markupsafe.escape(bad_col)}'
+                          f'{self.report_nonprintable(bad_col)}</li>')
+        detail.append('</ul>')
         raise upload_ex.BadHeadersError(
             'Header line contains unknown column names',
-            detail=detail)
+            detail=''.join(detail))
 
     def build_insert_stmt(
             self, tuh, data, qualified_table, quotecols, column_quoter):