Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 12 additions & 5 deletions Lib/netrc.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,11 +48,12 @@ def _read_char(self):
def get_token(self):
if self.pushback:
return self.pushback.pop(0)
token = ""
token = None
fiter = iter(self._read_char, "")
for ch in fiter:
if ch in self.whitespace:
continue
token = ""
if ch == '"':
for ch in fiter:
if ch == '"':
Expand Down Expand Up @@ -96,9 +97,9 @@ def _parse(self, file, fp, default_netrc):
# Look for a machine, default, or macdef top-level keyword
saved_lineno = lexer.lineno
tt = lexer.get_token()
if not tt:
if tt is None:
break
elif tt[0] == '#':
elif tt.startswith('#'):
if lexer.lineno == saved_lineno and len(tt) == 1:
lexer.instream.readline()
continue
Expand Down Expand Up @@ -135,20 +136,26 @@ def _parse(self, file, fp, default_netrc):
while 1:
prev_lineno = lexer.lineno
tt = lexer.get_token()
if tt.startswith('#'):
if tt is not None and tt.startswith('#'):
if lexer.lineno == prev_lineno:
lexer.instream.readline()
continue
if tt in {'', 'machine', 'default', 'macdef'}:
if tt is None or tt in {'machine', 'default', 'macdef'}:
self.hosts[entryname] = (login, account, password)
lexer.push_token(tt)
break
elif tt == 'login' or tt == 'user':
login = lexer.get_token()
if login is None:
login = ''
elif tt == 'account':
account = lexer.get_token()
if account is None:
account = ''
elif tt == 'password':
password = lexer.get_token()
if password is None:
password = ''
else:
raise NetrcParseError("bad follower token %r" % tt,
file, lexer.lineno)
Expand Down
9 changes: 9 additions & 0 deletions Lib/test/test_netrc.py
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,15 @@ def test_optional_tokens(self):
nrc = self.make_nrc(item)
self.assertEqual(nrc.hosts['default'], ('', '', ''))

def test_empty_quoted_token_is_not_eof(self):
data = (
'"" invalid',
'machine host.domain.com "" invalid',
)
for item in data:
with self.subTest(item=item):
self.assertRaises(netrc.NetrcParseError, self.make_nrc, item)

def test_invalid_tokens(self):
data = (
"invalid host.domain.com",
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
Fix :mod:`netrc` to distinguish empty quoted tokens from end-of-file, so
malformed files no longer cause the remaining content to be silently ignored.
Loading