Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit85c8155

Browse files
authored
Merge pull request#2048 from EliahKagan/conservative-quote-removal
Don't remove quotes if `\` or `"` are present inside
2 parents17d53b0 +f2b8041 commit85c8155

File tree

3 files changed

+41
-4
lines changed

3 files changed

+41
-4
lines changed

‎git/config.py

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -496,18 +496,26 @@ def string_decode(v: str) -> str:
496496
ifmo:
497497
# We might just have handled the last line, which could contain a quotation we want to remove.
498498
optname,vi,optval=mo.group("option","vi","value")
499+
optname=self.optionxform(optname.rstrip())
500+
499501
ifviin ("=",":")and";"inoptvalandnotoptval.strip().startswith('"'):
500502
pos=optval.find(";")
501503
ifpos!=-1andoptval[pos-1].isspace():
502504
optval=optval[:pos]
503505
optval=optval.strip()
504-
optname=self.optionxform(optname.rstrip())
505-
iflen(optval)>1andoptval[0]=='"'andoptval[-1]!='"':
506+
507+
iflen(optval)<2oroptval[0]!='"':
508+
# Does not open quoting.
509+
pass
510+
elifoptval[-1]!='"':
511+
# Opens quoting and does not close: appears to start multi-line quoting.
506512
is_multi_line=True
507513
optval=string_decode(optval[1:])
508-
eliflen(optval)>1andoptval[0]=='"'andoptval[-1]=='"':
514+
elifoptval.find("\\",1,-1)==-1andoptval.find('"',1,-1)==-1:
515+
# Opens and closes quoting. Single line, and all we need is quote removal.
509516
optval=optval[1:-1]
510-
# END handle multi-line
517+
# TODO: Handle other quoted content, especially well-formed backslash escapes.
518+
511519
# Preserves multiple values for duplicate optnames.
512520
cursect.add(optname,optval)
513521
else:
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
[custom]
2+
hasnewline = "first\nsecond"
3+
hasbackslash = "foo\\bar"
4+
hasquote = "ab\"cd"
5+
hastrailingbackslash = "word\\"
6+
hasunrecognized = "p\qrs"
7+
hasunescapedquotes = "ab"cd"e"
8+
ordinary = "hello world"
9+
unquoted = good evening

‎test/test_config.py

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -428,6 +428,26 @@ def test_config_with_quotes_with_whitespace_outside_value(self):
428428
cr=GitConfigParser(fixture_path("git_config_with_quotes_whitespace_outside"),read_only=True)
429429
self.assertEqual(cr.get("init","defaultBranch"),"trunk")
430430

431+
deftest_config_with_quotes_containing_escapes(self):
432+
"""For now just suppress quote removal. But it would be good to interpret most of these."""
433+
cr=GitConfigParser(fixture_path("git_config_with_quotes_escapes"),read_only=True)
434+
435+
# These can eventually be supported by substituting the represented character.
436+
self.assertEqual(cr.get("custom","hasnewline"),R'"first\nsecond"')
437+
self.assertEqual(cr.get("custom","hasbackslash"),R'"foo\\bar"')
438+
self.assertEqual(cr.get("custom","hasquote"),R'"ab\"cd"')
439+
self.assertEqual(cr.get("custom","hastrailingbackslash"),R'"word\\"')
440+
self.assertEqual(cr.get("custom","hasunrecognized"),R'"p\qrs"')
441+
442+
# It is less obvious whether and what to eventually do with this.
443+
self.assertEqual(cr.get("custom","hasunescapedquotes"),'"ab"cd"e"')
444+
445+
# Cases where quote removal is clearly safe should happen even after those.
446+
self.assertEqual(cr.get("custom","ordinary"),"hello world")
447+
448+
# Cases without quotes should still parse correctly even after those, too.
449+
self.assertEqual(cr.get("custom","unquoted"),"good evening")
450+
431451
deftest_get_values_works_without_requiring_any_other_calls_first(self):
432452
file_obj=self._to_memcache(fixture_path("git_config_multiple"))
433453
cr=GitConfigParser(file_obj,read_only=True)

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp