Skip to content

Commit 2b7975c

Browse files
committed
Fixed quotes and backslashes handling in GitConfigParser
1 parent d78a82d commit 2b7975c

File tree

1 file changed

+22
-3
lines changed

1 file changed

+22
-3
lines changed

git/config.py

+22-3
Original file line numberDiff line numberDiff line change
@@ -245,8 +245,23 @@ def _read(self, fp, fpname):
245245
if pos != -1 and optval[pos-1].isspace():
246246
optval = optval[:pos]
247247
optval = optval.strip()
248-
if optval == '""':
249-
optval = ''
248+
249+
# Remove paired unescaped-quotes
250+
unquoted_optval = ''
251+
escaped = False
252+
in_quote = False
253+
for c in optval:
254+
if not escaped and c == '"':
255+
in_quote = not in_quote
256+
else:
257+
escaped = (c == '\\')
258+
unquoted_optval += c
259+
260+
optval = unquoted_optval
261+
262+
optval = optval.replace('\\\\', '\\') # Unescape backslashes
263+
optval = optval.replace(r'\"', '"') # Unescape quotes
264+
250265
optname = self.optionxform(optname.rstrip())
251266
cursect[optname] = optval
252267
else:
@@ -303,7 +318,11 @@ def write_section(name, section_dict):
303318
fp.write("[%s]\n" % name)
304319
for (key, value) in section_dict.items():
305320
if key != "__name__":
306-
fp.write("\t%s = %s\n" % (key, str(value).replace('\n', '\n\t')))
321+
value = str(value)
322+
value = value.replace('\\', '\\\\') # Escape backslashes
323+
value = value.replace('"', r'\"') # Escape quotes
324+
value = value.replace('\n', '\n\t')
325+
fp.write("\t%s = %s\n" % (key, value))
307326
# END if key is not __name__
308327
# END section writing
309328

0 commit comments

Comments
 (0)