Skip to content

Commit ba4af66

Browse files
committed
gh-155468: Distinguish empty quoted tokens from EOF in netrc
1 parent 87b120f commit ba4af66

3 files changed

Lines changed: 23 additions & 5 deletions

File tree

Lib/netrc.py

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -48,11 +48,12 @@ def _read_char(self):
4848
def get_token(self):
4949
if self.pushback:
5050
return self.pushback.pop(0)
51-
token = ""
51+
token = None
5252
fiter = iter(self._read_char, "")
5353
for ch in fiter:
5454
if ch in self.whitespace:
5555
continue
56+
token = ""
5657
if ch == '"':
5758
for ch in fiter:
5859
if ch == '"':
@@ -96,9 +97,9 @@ def _parse(self, file, fp, default_netrc):
9697
# Look for a machine, default, or macdef top-level keyword
9798
saved_lineno = lexer.lineno
9899
tt = lexer.get_token()
99-
if not tt:
100+
if tt is None:
100101
break
101-
elif tt[0] == '#':
102+
elif tt.startswith('#'):
102103
if lexer.lineno == saved_lineno and len(tt) == 1:
103104
lexer.instream.readline()
104105
continue
@@ -135,20 +136,26 @@ def _parse(self, file, fp, default_netrc):
135136
while 1:
136137
prev_lineno = lexer.lineno
137138
tt = lexer.get_token()
138-
if tt.startswith('#'):
139+
if tt is not None and tt.startswith('#'):
139140
if lexer.lineno == prev_lineno:
140141
lexer.instream.readline()
141142
continue
142-
if tt in {'', 'machine', 'default', 'macdef'}:
143+
if tt is None or tt in {'machine', 'default', 'macdef'}:
143144
self.hosts[entryname] = (login, account, password)
144145
lexer.push_token(tt)
145146
break
146147
elif tt == 'login' or tt == 'user':
147148
login = lexer.get_token()
149+
if login is None:
150+
login = ''
148151
elif tt == 'account':
149152
account = lexer.get_token()
153+
if account is None:
154+
account = ''
150155
elif tt == 'password':
151156
password = lexer.get_token()
157+
if password is None:
158+
password = ''
152159
else:
153160
raise NetrcParseError("bad follower token %r" % tt,
154161
file, lexer.lineno)

Lib/test/test_netrc.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,15 @@ def test_optional_tokens(self):
8282
nrc = self.make_nrc(item)
8383
self.assertEqual(nrc.hosts['default'], ('', '', ''))
8484

85+
def test_empty_quoted_token_is_not_eof(self):
86+
data = (
87+
'"" invalid',
88+
'machine host.domain.com "" invalid',
89+
)
90+
for item in data:
91+
with self.subTest(item=item):
92+
self.assertRaises(netrc.NetrcParseError, self.make_nrc, item)
93+
8594
def test_invalid_tokens(self):
8695
data = (
8796
"invalid host.domain.com",
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
Fix :mod:`netrc` to distinguish empty quoted tokens from end-of-file, so
2+
malformed files no longer cause the remaining content to be silently ignored.

0 commit comments

Comments
 (0)