Repository: claudep/swiss-qr-bill

Issue:
line break in additional_information isnt shown and breaks many scanners
Providing a line break character "\n" in the string for the additional_information parameter will cause problems with many scanners. 

steps to reproduce:

QRBill(additional_information= f"Hello \n Line break")

The line break will not be visible in the human-readable text field, and will cause an error in the encoded bytes data of the qr code, which many scanners will be unable to decode

Even though some scanners can properly decode the resulting bytes, I do suggest sanitizing line breaks from the provided string, because the line break itself isnt properly displayed anyway, and this might cause many issues for users trying to use multiple lines in this section.

Discussion:

Patch:
diff --git a/qrbill/bill.py b/qrbill/bill.py
index 53bee98..4b1ca0c 100644
--- a/qrbill/bill.py
+++ b/qrbill/bill.py
@@ -404,7 +404,7 @@ class QRBill:
         values.extend([
             self.ref_type or '',
             self.reference_number or '',
-            self.additional_information or '',
+            replace_linebreaks(self.additional_information),
         ])
         values.append('EPD')
         values.extend(self.alt_procs)
@@ -794,7 +794,13 @@ def format_amount(amount_):
 
 
 def wrap_infos(infos):
-    for text in infos:
-        while(text):
-            yield text[:MAX_CHARS_PAYMENT_LINE]
-            text = text[MAX_CHARS_PAYMENT_LINE:]
+    for line in infos:
+        for text in line.splitlines():
+            while text:
+                yield text[:MAX_CHARS_PAYMENT_LINE]
+                text = text[MAX_CHARS_PAYMENT_LINE:]
+
+
+def replace_linebreaks(text):
+    text = text or ''
+    return ' '.join(text.splitlines())


Test patch:
diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml
index 37d0ba7..47eb061 100644
--- a/.github/workflows/test.yml
+++ b/.github/workflows/test.yml
@@ -7,8 +7,8 @@ jobs:
   lint:
     runs-on: ubuntu-latest
     steps:
-      - uses: actions/checkout@v2
-      - uses: actions/setup-python@v2
+      - uses: actions/checkout@v3
+      - uses: actions/setup-python@v4
         with:
           python-version: "3.9"
       - name: Install dependencies
@@ -25,9 +25,9 @@ jobs:
       matrix:
         python-version: ["3.6", "3.7", "3.8", "3.9", "3.10"]
     steps:
-      - uses: actions/checkout@v2
+      - uses: actions/checkout@v3
       - name: Set up Python ${{ matrix.python-version }}
-        uses: actions/setup-python@v2
+        uses: actions/setup-python@v4
         with:
           python-version: ${{ matrix.python-version }}
       - name: Install dependencies
diff --git a/tests/test_qrbill.py b/tests/test_qrbill.py
index 9ef2c93..3f571dc 100644
--- a/tests/test_qrbill.py
+++ b/tests/test_qrbill.py
@@ -238,6 +238,27 @@ class QRBillTests(unittest.TestCase):
             self.assertEqual(bill.amount, expected)
             self.assertEqual(format_amount(bill.amount), printed)
 
+    def test_additionnal_info_break(self):
+        """
+        Line breaks in additional_information are converted to space in QR data
+        (but still respected on info display)
+        """
+        bill = QRBill(
+            account="CH 53 8000 5000 0102 83664",
+            creditor={
+                'name': 'Jane', 'pcode': '1000', 'city': 'Lausanne',
+            },
+            additional_information="Hello\nLine break",
+        )
+        self.assertEqual(
+            bill.qr_data(),
+            'SPC\r\n0200\r\n1\r\nCH5380005000010283664\r\nS\r\nJane\r\n\r\n\r\n'
+            '1000\r\nLausanne\r\nCH\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\nCHF\r\n'
+            '\r\n\r\n\r\n\r\n\r\n\r\n\r\nNON\r\n\r\nHello Line break\r\nEPD'
+        )
+        with open("test1.svg", 'w') as fh:
+            bill.as_svg(fh.name)
+
     def test_minimal_data(self):
         bill = QRBill(
             account="CH 53 8000 5000 0102 83664",