]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
[3.13] gh-143346: Fix calculation of the line width for wrapped Base64 in plistlib...
authorMiss Islington (bot) <31488909+miss-islington@users.noreply.github.com>
Mon, 12 Jan 2026 09:04:00 +0000 (10:04 +0100)
committerGitHub <noreply@github.com>
Mon, 12 Jan 2026 09:04:00 +0000 (09:04 +0000)
It was incorrect in case of mixed tabs and spaces in indentation.
(cherry picked from commit 5f28aa2f372339ba0c70373b96d33ec4d2879e04)

Co-authored-by: Serhiy Storchaka <storchaka@gmail.com>
Lib/plistlib.py
Lib/test/test_plistlib.py
Misc/NEWS.d/next/Library/2026-01-02-12-55-52.gh-issue-143346.iTekce.rst [new file with mode: 0644]

index 655c51eea3da5d5d41f2c4b1c751a715a7cdecaf..5b2b4e42c95a83b63d99a8fe873c715f64c0712e 100644 (file)
@@ -384,7 +384,7 @@ class _PlistWriter(_DumbXMLWriter):
         self._indent_level -= 1
         maxlinelength = max(
             16,
-            76 - len(self.indent.replace(b"\t", b" " * 8) * self._indent_level))
+            76 - len((self.indent * self._indent_level).expandtabs()))
 
         for line in _encode_base64(data, maxlinelength).split(b"\n"):
             if line:
index 3813227bd93964e6fdb0bf9e00c65d68e0e4c800..760db4372a6570abae365e4dd5aca59f533c5bf2 100644 (file)
@@ -510,6 +510,69 @@ class TestPlistlib(unittest.TestCase):
         data2 = plistlib.dumps(pl2)
         self.assertEqual(data, data2)
 
+    def test_bytes_indent(self):
+        header = (
+            b'<?xml version="1.0" encoding="UTF-8"?>\n'
+            b'<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">\n'
+            b'<plist version="1.0">\n')
+        data = [{'bytes': bytes(range(50))}]
+        pl = plistlib.dumps(data)
+        self.assertEqual(pl, header +
+            b'<array>\n'
+            b'\t<dict>\n'
+            b'\t\t<key>bytes</key>\n'
+            b'\t\t<data>\n'
+            b'\t\tAAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBkaGxwdHh8gISIjJCUmJygpKiss\n'
+            b'\t\tLS4vMDE=\n'
+            b'\t\t</data>\n'
+            b'\t</dict>\n'
+            b'</array>\n'
+            b'</plist>\n')
+
+        def dumps_with_indent(data, indent):
+            fp = BytesIO()
+            writer = plistlib._PlistWriter(fp, indent=indent)
+            writer.write(data)
+            return fp.getvalue()
+
+        pl = dumps_with_indent(data, b' ')
+        self.assertEqual(pl, header +
+            b'<array>\n'
+            b' <dict>\n'
+            b'  <key>bytes</key>\n'
+            b'  <data>\n'
+            b'  AAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBkaGxwdHh8gISIjJCUmJygpKissLS4vMDE=\n'
+            b'  </data>\n'
+            b' </dict>\n'
+            b'</array>\n'
+            b'</plist>\n')
+
+        pl = dumps_with_indent(data, b' \t')
+        self.assertEqual(pl, header +
+            b'<array>\n'
+            b' \t<dict>\n'
+            b' \t \t<key>bytes</key>\n'
+            b' \t \t<data>\n'
+            b' \t \tAAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBkaGxwdHh8gISIjJCUmJygpKiss\n'
+            b' \t \tLS4vMDE=\n'
+            b' \t \t</data>\n'
+            b' \t</dict>\n'
+            b'</array>\n'
+            b'</plist>\n')
+
+        pl = dumps_with_indent(data, b'\t   ')
+        self.assertEqual(pl, header +
+            b'<array>\n'
+            b'\t   <dict>\n'
+            b'\t   \t   <key>bytes</key>\n'
+            b'\t   \t   <data>\n'
+            b'\t   \t   AAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBkaGxwdHh8gISIjJCUmJygp\n'
+            b'\t   \t   KissLS4vMDE=\n'
+            b'\t   \t   </data>\n'
+            b'\t   </dict>\n'
+            b'</array>\n'
+            b'</plist>\n')
+
     def test_loads_str_with_xml_fmt(self):
         pl = self._create()
         b = plistlib.dumps(pl)
@@ -582,7 +645,6 @@ class TestPlistlib(unittest.TestCase):
                 self.assertEqual(data, TESTDATA[fmt],
                     "generated data was not identical to Apple's output")
 
-
     def test_appleformattingfromliteral(self):
         self.maxDiff = None
         for fmt in ALL_FORMATS:
diff --git a/Misc/NEWS.d/next/Library/2026-01-02-12-55-52.gh-issue-143346.iTekce.rst b/Misc/NEWS.d/next/Library/2026-01-02-12-55-52.gh-issue-143346.iTekce.rst
new file mode 100644 (file)
index 0000000..93c45ee
--- /dev/null
@@ -0,0 +1,2 @@
+Fix incorrect wrapping of the Base64 data in :class:`!plistlib._PlistWriter`
+when the indent contains a mix of tabs and spaces.