Skip to content

Commit 389a103

Browse files
gh-143346: Fix calculation of the line width for wrapped Base64 in plistlib
It was incorrect in case of mixed tabs and spaces in indentation.
1 parent 61fc72a commit 389a103

File tree

3 files changed

+66
-2
lines changed

3 files changed

+66
-2
lines changed

Lib/plistlib.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -384,7 +384,7 @@ def write_bytes(self, data):
384384
self._indent_level -= 1
385385
maxlinelength = max(
386386
16,
387-
76 - len(self.indent.replace(b"\t", b" " * 8) * self._indent_level))
387+
76 - len((self.indent * self._indent_level).expandtabs()))
388388

389389
for line in _encode_base64(data, maxlinelength).split(b"\n"):
390390
if line:

Lib/test/test_plistlib.py

Lines changed: 63 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -509,6 +509,69 @@ def test_bytes(self):
509509
data2 = plistlib.dumps(pl2)
510510
self.assertEqual(data, data2)
511511

512+
def test_bytes_indent(self):
513+
header = (
514+
b'<?xml version="1.0" encoding="UTF-8"?>\n'
515+
b'<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">\n'
516+
b'<plist version="1.0">\n')
517+
data = [{'bytes': bytes(range(50))}]
518+
pl = plistlib.dumps(data)
519+
self.assertEqual(pl, header +
520+
b'<array>\n'
521+
b'\t<dict>\n'
522+
b'\t\t<key>bytes</key>\n'
523+
b'\t\t<data>\n'
524+
b'\t\tAAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBkaGxwdHh8gISIjJCUmJygpKiss\n'
525+
b'\t\tLS4vMDE=\n'
526+
b'\t\t</data>\n'
527+
b'\t</dict>\n'
528+
b'</array>\n'
529+
b'</plist>\n')
530+
531+
def dumps_with_indent(data, indent):
532+
fp = BytesIO()
533+
writer = plistlib._PlistWriter(fp, indent=indent)
534+
writer.write(data)
535+
return fp.getvalue()
536+
537+
pl = dumps_with_indent(data, b' ')
538+
self.assertEqual(pl, header +
539+
b'<array>\n'
540+
b' <dict>\n'
541+
b' <key>bytes</key>\n'
542+
b' <data>\n'
543+
b' AAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBkaGxwdHh8gISIjJCUmJygpKissLS4vMDE=\n'
544+
b' </data>\n'
545+
b' </dict>\n'
546+
b'</array>\n'
547+
b'</plist>\n')
548+
549+
pl = dumps_with_indent(data, b' \t')
550+
self.assertEqual(pl, header +
551+
b'<array>\n'
552+
b' \t<dict>\n'
553+
b' \t \t<key>bytes</key>\n'
554+
b' \t \t<data>\n'
555+
b' \t \tAAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBkaGxwdHh8gISIjJCUmJygpKiss\n'
556+
b' \t \tLS4vMDE=\n'
557+
b' \t \t</data>\n'
558+
b' \t</dict>\n'
559+
b'</array>\n'
560+
b'</plist>\n')
561+
562+
pl = dumps_with_indent(data, b'\t ')
563+
self.assertEqual(pl, header +
564+
b'<array>\n'
565+
b'\t <dict>\n'
566+
b'\t \t <key>bytes</key>\n'
567+
b'\t \t <data>\n'
568+
b'\t \t AAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBkaGxwdHh8gISIjJCUmJygp\n'
569+
b'\t \t KissLS4vMDE=\n'
570+
b'\t \t </data>\n'
571+
b'\t </dict>\n'
572+
b'</array>\n'
573+
b'</plist>\n')
574+
512575
def test_loads_str_with_xml_fmt(self):
513576
pl = self._create()
514577
b = plistlib.dumps(pl)
@@ -581,7 +644,6 @@ def test_appleformatting(self):
581644
self.assertEqual(data, TESTDATA[fmt],
582645
"generated data was not identical to Apple's output")
583646

584-
585647
def test_appleformattingfromliteral(self):
586648
self.maxDiff = None
587649
for fmt in ALL_FORMATS:
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
Fix incorrect wrapping of the Base64 data in :class:`!plistlib._PlistWriter`
2+
when the indent contains a mix of tabs and spaces.

0 commit comments

Comments
 (0)