This commit is contained in:
Benjamin Peterson 2011-06-10 12:30:16 -05:00
commit ae10b3201c
4 changed files with 102 additions and 44 deletions

View File

@ -2,7 +2,7 @@
# Module and documentation by Eric S. Raymond, 21 Dec 1998 # Module and documentation by Eric S. Raymond, 21 Dec 1998
import os, shlex import io, os, shlex
__all__ = ["netrc", "NetrcParseError"] __all__ = ["netrc", "NetrcParseError"]
@ -37,12 +37,14 @@ class netrc:
lexer.commenters = lexer.commenters.replace('#', '') lexer.commenters = lexer.commenters.replace('#', '')
while 1: while 1:
# Look for a machine, default, or macdef top-level keyword # Look for a machine, default, or macdef top-level keyword
saved_lineno = lexer.lineno
toplevel = tt = lexer.get_token() toplevel = tt = lexer.get_token()
if not tt: if not tt:
break break
elif tt[0] == '#': elif tt[0] == '#':
fp.readline(); if lexer.lineno == saved_lineno and len(tt) == 1:
continue; lexer.instream.readline()
continue
elif tt == 'machine': elif tt == 'machine':
entryname = lexer.get_token() entryname = lexer.get_token()
elif tt == 'default': elif tt == 'default':
@ -68,8 +70,8 @@ class netrc:
self.hosts[entryname] = {} self.hosts[entryname] = {}
while 1: while 1:
tt = lexer.get_token() tt = lexer.get_token()
if (tt=='' or tt == 'machine' or if (tt.startswith('#') or
tt == 'default' or tt =='macdef'): tt in {'', 'machine', 'default', 'macdef'}):
if password: if password:
self.hosts[entryname] = (login, account, password) self.hosts[entryname] = (login, account, password)
lexer.push_token(tt) lexer.push_token(tt)

View File

@ -1,54 +1,107 @@
import netrc, os, unittest, sys, textwrap
import netrc, os, unittest, sys
from test import support from test import support
TEST_NETRC = """
#this is a comment
#this is a comment
# this is a comment
machine foo login log1 password pass1 account acct1
machine bar login log1 password pass# account acct1
macdef macro1
line1
line2
macdef macro2
line3
line4
default login log2 password pass2
"""
temp_filename = support.TESTFN temp_filename = support.TESTFN
class NetrcTestCase(unittest.TestCase): class NetrcTestCase(unittest.TestCase):
def setUp(self):
mode = 'w'
if sys.platform not in ['cygwin']:
mode += 't'
fp = open(temp_filename, mode)
fp.write(TEST_NETRC)
fp.close()
self.nrc = netrc.netrc(temp_filename)
def tearDown(self): def tearDown(self):
os.unlink(temp_filename) os.unlink(temp_filename)
def test_case_1(self): def make_nrc(self, test_data):
self.assertEqual(self.nrc.hosts['foo'], ('log1', 'acct1', 'pass1')) test_data = textwrap.dedent(test_data)
self.assertEqual(self.nrc.hosts['default'], ('log2', None, 'pass2')) mode = 'w'
if sys.platform != 'cygwin':
mode += 't'
with open(temp_filename, mode) as fp:
fp.write(test_data)
return netrc.netrc(temp_filename)
def test_default(self):
nrc = self.make_nrc("""\
machine host1.domain.com login log1 password pass1 account acct1
default login log2 password pass2
""")
self.assertEqual(nrc.hosts['host1.domain.com'],
('log1', 'acct1', 'pass1'))
self.assertEqual(nrc.hosts['default'], ('log2', None, 'pass2'))
def test_macros(self): def test_macros(self):
self.assertEqual(self.nrc.macros, {'macro1':['line1\n', 'line2\n'], nrc = self.make_nrc("""\
'macro2':['line3\n', 'line4\n']}) macdef macro1
line1
line2
macdef macro2
line3
line4
""")
self.assertEqual(nrc.macros, {'macro1': ['line1\n', 'line2\n'],
'macro2': ['line3\n', 'line4\n']})
def _test_passwords(self, nrc, passwd):
nrc = self.make_nrc(nrc)
self.assertEqual(nrc.hosts['host.domain.com'], ('log', 'acct', passwd))
def test_password_with_leading_hash(self):
self._test_passwords("""\
machine host.domain.com login log password #pass account acct
""", '#pass')
def test_password_with_trailing_hash(self):
self._test_passwords("""\
machine host.domain.com login log password pass# account acct
""", 'pass#')
def test_password_with_internal_hash(self):
self._test_passwords("""\
machine host.domain.com login log password pa#ss account acct
""", 'pa#ss')
def _test_comment(self, nrc, passwd='pass'):
nrc = self.make_nrc(nrc)
self.assertEqual(nrc.hosts['foo.domain.com'], ('bar', None, passwd))
self.assertEqual(nrc.hosts['bar.domain.com'], ('foo', None, 'pass'))
def test_comment_before_machine_line(self):
self._test_comment("""\
# comment
machine foo.domain.com login bar password pass
machine bar.domain.com login foo password pass
""")
def test_comment_before_machine_line_no_space(self):
self._test_comment("""\
#comment
machine foo.domain.com login bar password pass
machine bar.domain.com login foo password pass
""")
def test_comment_before_machine_line_hash_only(self):
self._test_comment("""\
#
machine foo.domain.com login bar password pass
machine bar.domain.com login foo password pass
""")
def test_comment_at_end_of_machine_line(self):
self._test_comment("""\
machine foo.domain.com login bar password pass # comment
machine bar.domain.com login foo password pass
""")
def test_comment_at_end_of_machine_line_no_space(self):
self._test_comment("""\
machine foo.domain.com login bar password pass #comment
machine bar.domain.com login foo password pass
""")
def test_comment_at_end_of_machine_line_pass_has_hash(self):
self._test_comment("""\
machine foo.domain.com login bar password #pass #comment
machine bar.domain.com login foo password pass
""", '#pass')
def test_parses_passwords_with_hash_character(self):
self.assertEqual(self.nrc.hosts['bar'], ('log1', 'acct1', 'pass#'))
def test_main(): def test_main():
support.run_unittest(NetrcTestCase) support.run_unittest(NetrcTestCase)

View File

@ -644,6 +644,7 @@ James A Morrison
Derek McTavish Mounce Derek McTavish Mounce
Pablo Mouzo Pablo Mouzo
Mher Movsisyan Mher Movsisyan
Ruslan Mstoi
Sjoerd Mullender Sjoerd Mullender
Sape Mullender Sape Mullender
Michael Muller Michael Muller

View File

@ -187,6 +187,8 @@ Core and Builtins
Library Library
------- -------
- Issue #12009: Fixed regression in netrc file comment handling.
- Issue #10694: zipfile now ignores garbage at the end of a zipfile. - Issue #10694: zipfile now ignores garbage at the end of a zipfile.
- Issue #12283: Fixed regression in smtplib quoting of leading dots in DATA. - Issue #12283: Fixed regression in smtplib quoting of leading dots in DATA.