diff --git a/store.py b/store.py index 68504b6d..8c9d22f0 100755 --- a/store.py +++ b/store.py @@ -718,15 +718,18 @@ def get_package_urls(self, name, relative=None): file_urls = [] # uploaded files - safe_execute(cursor, '''select filename, python_version, md5_digest - from release_files where name=%s''', (name,)) - for fname, pyversion, md5 in cursor.fetchall(): + safe_execute(cursor, + ''' + SELECT filename, requires_python, md5_digest + FROM release_files + WHERE release_files.name=%s + ''', (name,)) + for fname, requires_python, md5 in cursor.fetchall(): # Put files first, to have setuptools consider # them before going to other sites - url = self.gen_file_url(pyversion, name, fname, relative) + \ + url = self.gen_file_url('', name, fname, relative) + \ "#md5=" + md5 - file_urls.append((url, "internal", fname)) - + file_urls.append((url, "internal", fname, requires_python)) return sorted(file_urls) def get_uploaded_file_urls(self, name): diff --git a/webui.py b/webui.py index 0ae37307..965c8cfa 100644 --- a/webui.py +++ b/webui.py @@ -331,6 +331,34 @@ def _valid_platform_tag(platform_tag): return True return False +def _simple_body_internal(path, urls): + """ + Inner method for testing sql injections of requires_python + """ + html = [] + html.append("""Links for %s""" + % cgi.escape(path)) + html.append("

Links for %s

" % cgi.escape(path)) + for href, rel, text, requires_python in urls: + if href.startswith('http://cheeseshop.python.org/pypi') or \ + href.startswith('http://pypi.python.org/pypi') or \ + href.startswith('http://www.python.org/pypi'): + # Suppress URLs that point to us + continue + if rel: + rel = ' rel="{}"'.format(cgi.escape(rel, quote=True)) + else: + rel = '' + href = cgi.escape(href, quote=True) + text = cgi.escape(text) + data_attr = '' + if requires_python: + data_attr = ' data-requires-python="{}"'.format(cgi.escape(requires_python, quote=True)) + html.append("""{}
\n""".format(data_attr, href, rel, text)) + html.append("") + html = ''.join(html) + return html + class WebUI: ''' Handle a request as defined by the "env" parameter. "handler" gives @@ -1038,27 +1066,8 @@ def simple_body(self, path): if urls is None: raise NotFound, path + " does not have any releases" - html = [] - html.append("""Links for %s""" - % cgi.escape(path)) - html.append("

Links for %s

" % cgi.escape(path)) - for href, rel, text in urls: - if href.startswith('http://cheeseshop.python.org/pypi') or \ - href.startswith('http://pypi.python.org/pypi') or \ - href.startswith('http://www.python.org/pypi'): - # Suppress URLs that point to us - continue - if rel: - rel = ' rel="%s"' % rel - else: - rel = '' - href = cgi.escape(href, quote=True) - text = cgi.escape(text) - html.append("""%s
\n""" % (href, rel, text)) - html.append("") - html = ''.join(html) - return html - + return _simple_body_internal(path, urls) + def get_accept_encoding(self, supported): accept_encoding = self.env.get('HTTP_ACCEPT_ENCODING') if not accept_encoding: