diff options
author | Giampaolo Rodola' <g.rodola@gmail.com> | 2012-05-15 20:21:01 (GMT) |
---|---|---|
committer | Giampaolo Rodola' <g.rodola@gmail.com> | 2012-05-15 20:21:01 (GMT) |
commit | 12ea86adcea986c5572c597b72253d839f4d303a (patch) | |
tree | db1cf22fe78ad8f96da1f2d47a1928854b3564dd /Lib | |
parent | b28df76ee2cdd0bb2a941bc179f347c26e4254f5 (diff) | |
parent | 9b704ec9e1049788157a7f042ef765a4bb058b68 (diff) | |
download | cpython-12ea86adcea986c5572c597b72253d839f4d303a.zip cpython-12ea86adcea986c5572c597b72253d839f4d303a.tar.gz cpython-12ea86adcea986c5572c597b72253d839f4d303a.tar.bz2 |
merge heads
Diffstat (limited to 'Lib')
-rw-r--r-- | Lib/os.py | 24 | ||||
-rw-r--r-- | Lib/test/test_os.py | 9 | ||||
-rw-r--r-- | Lib/test/test_urllib2.py | 16 | ||||
-rw-r--r-- | Lib/urllib/request.py | 5 |
4 files changed, 45 insertions, 9 deletions
@@ -353,13 +353,23 @@ if _exists("openat"): names = flistdir(topfd) dirs, nondirs = [], [] for name in names: - # Here, we don't use AT_SYMLINK_NOFOLLOW to be consistent with - # walk() which reports symlinks to directories as directories. We do - # however check for symlinks before recursing into a subdirectory. - if st.S_ISDIR(fstatat(topfd, name).st_mode): - dirs.append(name) - else: - nondirs.append(name) + try: + # Here, we don't use AT_SYMLINK_NOFOLLOW to be consistent with + # walk() which reports symlinks to directories as directories. + # We do however check for symlinks before recursing into + # a subdirectory. + if st.S_ISDIR(fstatat(topfd, name).st_mode): + dirs.append(name) + else: + nondirs.append(name) + except FileNotFoundError: + try: + # Add dangling symlinks, ignore disappeared files + if st.S_ISLNK(fstatat(topfd, name, AT_SYMLINK_NOFOLLOW) + .st_mode): + nondirs.append(name) + except FileNotFoundError: + continue if topdown: yield toppath, dirs, nondirs, topfd diff --git a/Lib/test/test_os.py b/Lib/test/test_os.py index 066bf72..9b29b37 100644 --- a/Lib/test/test_os.py +++ b/Lib/test/test_os.py @@ -651,6 +651,7 @@ class WalkTests(unittest.TestCase): # SUB2/ a file kid and a dirsymlink kid # tmp3 # link/ a symlink to TESTFN.2 + # broken_link # TEST2/ # tmp4 a lone file walk_path = join(support.TESTFN, "TEST1") @@ -663,6 +664,8 @@ class WalkTests(unittest.TestCase): link_path = join(sub2_path, "link") t2_path = join(support.TESTFN, "TEST2") tmp4_path = join(support.TESTFN, "TEST2", "tmp4") + link_path = join(sub2_path, "link") + broken_link_path = join(sub2_path, "broken_link") # Create stuff. os.makedirs(sub11_path) @@ -679,7 +682,8 @@ class WalkTests(unittest.TestCase): else: symlink_to_dir = os.symlink symlink_to_dir(os.path.abspath(t2_path), link_path) - sub2_tree = (sub2_path, ["link"], ["tmp3"]) + symlink_to_dir('broken', broken_link_path) + sub2_tree = (sub2_path, ["link"], ["broken_link", "tmp3"]) else: sub2_tree = (sub2_path, [], ["tmp3"]) @@ -691,6 +695,7 @@ class WalkTests(unittest.TestCase): # flipped: TESTFN, SUB2, SUB1, SUB11 flipped = all[0][1][0] != "SUB1" all[0][1].sort() + all[3 - 2 * flipped][-1].sort() self.assertEqual(all[0], (walk_path, ["SUB1", "SUB2"], ["tmp1"])) self.assertEqual(all[1 + flipped], (sub1_path, ["SUB11"], ["tmp2"])) self.assertEqual(all[2 + flipped], (sub11_path, [], [])) @@ -706,6 +711,7 @@ class WalkTests(unittest.TestCase): dirs.remove('SUB1') self.assertEqual(len(all), 2) self.assertEqual(all[0], (walk_path, ["SUB2"], ["tmp1"])) + all[1][-1].sort() self.assertEqual(all[1], sub2_tree) # Walk bottom-up. @@ -716,6 +722,7 @@ class WalkTests(unittest.TestCase): # flipped: SUB2, SUB11, SUB1, TESTFN flipped = all[3][1][0] != "SUB1" all[3][1].sort() + all[2 - 2 * flipped][-1].sort() self.assertEqual(all[3], (walk_path, ["SUB1", "SUB2"], ["tmp1"])) self.assertEqual(all[flipped], (sub11_path, [], [])) self.assertEqual(all[flipped + 1], (sub1_path, ["SUB11"], ["tmp2"])) diff --git a/Lib/test/test_urllib2.py b/Lib/test/test_urllib2.py index fad95cc..b2cec7e 100644 --- a/Lib/test/test_urllib2.py +++ b/Lib/test/test_urllib2.py @@ -1252,6 +1252,22 @@ class HandlerTests(unittest.TestCase): def test_basic_auth_with_single_quoted_realm(self): self.test_basic_auth(quote_char="'") + def test_basic_auth_with_unquoted_realm(self): + opener = OpenerDirector() + password_manager = MockPasswordManager() + auth_handler = urllib.request.HTTPBasicAuthHandler(password_manager) + realm = "ACME Widget Store" + http_handler = MockHTTPHandler( + 401, 'WWW-Authenticate: Basic realm=%s\r\n\r\n' % realm) + opener.add_handler(auth_handler) + opener.add_handler(http_handler) + with self.assertWarns(UserWarning): + self._test_basic_auth(opener, auth_handler, "Authorization", + realm, http_handler, password_manager, + "http://acme.example.com/protected", + "http://acme.example.com/protected", + ) + def test_proxy_basic_auth(self): opener = OpenerDirector() ph = urllib.request.ProxyHandler(dict(http="proxy.example.com:3128")) diff --git a/Lib/urllib/request.py b/Lib/urllib/request.py index a5f0866..96bb8d7 100644 --- a/Lib/urllib/request.py +++ b/Lib/urllib/request.py @@ -895,7 +895,7 @@ class AbstractBasicAuthHandler: # allow for double- and single-quoted realm values # (single quotes are a violation of the RFC, but appear in the wild) rx = re.compile('(?:.*,)*[ \t]*([^ \t]+)[ \t]+' - 'realm=(["\'])(.*?)\\2', re.I) + 'realm=(["\']?)([^"\']*)\\2', re.I) # XXX could pre-emptively send auth info already accepted (RFC 2617, # end of section 2, and section 1.2 immediately after "credentials" @@ -934,6 +934,9 @@ class AbstractBasicAuthHandler: mo = AbstractBasicAuthHandler.rx.search(authreq) if mo: scheme, quote, realm = mo.groups() + if quote not in ['"',"'"]: + warnings.warn("Basic Auth Realm was unquoted", + UserWarning, 2) if scheme.lower() == 'basic': response = self.retry_http_basic_auth(host, req, realm) if response and response.code != 401: |