Skip to content

Commit 6c29d2a

Browse files
sethmlarsonmiss-islington
authored andcommitted
gh-143927: Normalize all line endings (CR, CRLF, and LF) in configparser (GH-143929)
(cherry picked from commit 5858e42) Co-authored-by: Seth Larson <seth@python.org>
1 parent 79f6614 commit 6c29d2a

3 files changed

Lines changed: 16 additions & 1 deletion

File tree

Lib/configparser.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -945,7 +945,9 @@ def _write_section(self, fp, section_name, section_items, delimiter):
945945
value = self._interpolation.before_write(self, section_name, key,
946946
value)
947947
if value is not None or not self._allow_no_value:
948-
value = delimiter + str(value).replace('\n', '\n\t')
948+
# Convert all possible line-endings into '\n\t'
949+
value = (delimiter + str(value).replace('\r\n', '\n')
950+
.replace('\r', '\n').replace('\n', '\n\t'))
949951
else:
950952
value = ""
951953
fp.write("{}{}\n".format(key, value))

Lib/test/test_configparser.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -528,6 +528,17 @@ def test_default_case_sensitivity(self):
528528
cf.get(self.default_section, "Foo"), "Bar",
529529
"could not locate option, expecting case-insensitive defaults")
530530

531+
def test_crlf_normalization(self):
532+
cf = self.newconfig({"key1": "a\nb","key2": "a\rb", "key3": "a\r\nb", "key4": "a\r\nb"})
533+
buf = io.StringIO()
534+
cf.write(buf)
535+
cf_str = buf.getvalue()
536+
self.assertNotIn("\r", cf_str)
537+
self.assertNotIn("\r\n", cf_str)
538+
self.assertEqual(cf_str.count("\n"), 10)
539+
self.assertEqual(cf_str.count("\n\t"), 4)
540+
self.assertTrue(cf_str.endswith("\n\n"))
541+
531542
def test_parse_errors(self):
532543
cf = self.newconfig()
533544
self.parse_error(cf, configparser.ParsingError,
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
Normalize all line endings (CR, CRLF, and LF) to LF+TAB when writing
2+
multi-line configparser values.

0 commit comments

Comments
 (0)