Hello community,

here is the log from the commit of package python-Werkzeug for openSUSE:Factory 
checked in at 2012-03-13 09:39:19
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/python-Werkzeug (Old)
 and      /work/SRC/openSUSE:Factory/.python-Werkzeug.new (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "python-Werkzeug", Maintainer is ""

Changes:
--------
--- /work/SRC/openSUSE:Factory/python-Werkzeug/python-Werkzeug.changes  
2011-11-14 13:38:24.000000000 +0100
+++ /work/SRC/openSUSE:Factory/.python-Werkzeug.new/python-Werkzeug.changes     
2012-03-13 09:39:20.000000000 +0100
@@ -1,0 +2,27 @@
+Mon Mar 12 21:35:29 UTC 2012 - [email protected]
+
+- Update to version 0.8.3:
+  - Fixed another issue with :func:`werkzeug.wsgi.make_line_iter`
+    where lines longer than the buffer size were not handled
+    properly.
+  - Restore stdout after debug console finished executing so
+    that the debugger can be used on GAE better.
+  - Fixed a bug with the redis cache for int subclasses
+    (affects bool caching).
+  - Fixed an XSS problem with redirect targets coming from
+    untrusted sources.
+- Changes from version 0.8.2:
+  - Fixed a problem with request handling of the builtin server
+    not repsonding to socket errors properly.
+  - The routing request redirect exception's code attribute is now
+    used properly.
+  - Fixed a bug with shutdowns on Windows.
+  - Fixed a few unicode issues with non-ascii characters being
+    hardcoded in URL rules.
+  - Fixed two property docstrings being assigned to fdel instead
+    of ``__doc__``.
+  - Fixed an issue where CRLF line endings could be split into two
+    by the line iter function, causing problems with multipart file
+    uploads.
+
+-------------------------------------------------------------------

Old:
----
  Werkzeug-0.8.1.tar.gz

New:
----
  Werkzeug-0.8.3.tar.gz

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ python-Werkzeug.spec ++++++
--- /var/tmp/diff_new_pack.xAiv04/_old  2012-03-13 09:39:21.000000000 +0100
+++ /var/tmp/diff_new_pack.xAiv04/_new  2012-03-13 09:39:21.000000000 +0100
@@ -1,7 +1,7 @@
 #
 # spec file for package python-Werkzeug
 #
-# Copyright (c) 2011 SUSE LINUX Products GmbH, Nuernberg, Germany.
+# Copyright (c) 2012 SUSE LINUX Products GmbH, Nuernberg, Germany.
 #
 # All modifications and additions to the file contributed by third parties
 # remain the property of their copyright owners, unless otherwise agreed
@@ -16,9 +16,8 @@
 #
 
 
-
 Name:           python-Werkzeug
-Version:        0.8.1
+Version:        0.8.3
 Release:        0
 Url:            http://werkzeug.pocoo.org/
 Summary:        The Swiss Army knife of Python web development
@@ -26,19 +25,17 @@
 Group:          Development/Languages/Python
 Source:         
http://pypi.python.org/packages/source/W/Werkzeug/Werkzeug-%{version}.tar.gz
 BuildRoot:      %{_tmppath}/%{name}-%{version}-build
+BuildRequires:  python-Sphinx
 BuildRequires:  python-devel
 BuildRequires:  python-distribute
 BuildRequires:  python-nose
-BuildRequires:  python-Sphinx
-%if 0%{?suse_version}
-%py_requires
-%if 0%{?suse_version} > 1110
-BuildArch:      noarch
-%endif
-%endif
 Provides:       python-werkzeug = %{version}
 Obsoletes:      python-werkzeug < %{version}
-%{!?python_sitelib: %global python_sitelib %(%{__python} -c "from 
distutils.sysconfig import get_python_lib; print get_python_lib()")}
+%if 0%{?suse_version} && 0%{?suse_version} <= 1110
+%{!?python_sitelib: %global python_sitelib %(python -c "from 
distutils.sysconfig import get_python_lib; print get_python_lib()")}
+%else
+BuildArch:      noarch
+%endif
 
 %description
 Werkzeug started as simple collection of various utilities for WSGI

++++++ Werkzeug-0.8.1.tar.gz -> Werkzeug-0.8.3.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/Werkzeug-0.8.1/AUTHORS new/Werkzeug-0.8.3/AUTHORS
--- old/Werkzeug-0.8.1/AUTHORS  2011-07-24 15:42:54.000000000 +0200
+++ new/Werkzeug-0.8.3/AUTHORS  2012-01-21 15:43:50.000000000 +0100
@@ -24,6 +24,7 @@
 - Pedro Algarvio
 - Zahari Petkov
 - Ludvig Ericson
+- Kenneth Reitz
 
 Contributors of code for werkzeug/examples are:
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/Werkzeug-0.8.1/CHANGES new/Werkzeug-0.8.3/CHANGES
--- old/Werkzeug-0.8.1/CHANGES  2011-09-30 12:49:51.000000000 +0200
+++ new/Werkzeug-0.8.3/CHANGES  2012-02-05 11:10:04.000000000 +0100
@@ -1,6 +1,39 @@
 Werkzeug Changelog
 ==================
 
+Version 0.8.3
+-------------
+
+(bugfix release, released on February 5th 2012)
+
+- Fixed another issue with :func:`werkzeug.wsgi.make_line_iter`
+  where lines longer than the buffer size were not handled
+  properly.
+- Restore stdout after debug console finished executing so
+  that the debugger can be used on GAE better.
+- Fixed a bug with the redis cache for int subclasses
+  (affects bool caching).
+- Fixed an XSS problem with redirect targets coming from
+  untrusted sources.
+
+Version 0.8.2
+-------------
+
+(bugfix release, released on December 16th 2011)
+
+- Fixed a problem with request handling of the builtin server
+  not repsonding to socket errors properly.
+- The routing request redirect exception's code attribute is now
+  used properly.
+- Fixed a bug with shutdowns on Windows.
+- Fixed a few unicode issues with non-ascii characters being
+  hardcoded in URL rules.
+- Fixed two property docstrings being assigned to fdel instead
+  of ``__doc__``.
+- Fixed an issue where CRLF line endings could be split into two
+  by the line iter function, causing problems with multipart file
+  uploads.
+
 Version 0.8.1
 -------------
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/Werkzeug-0.8.1/PKG-INFO new/Werkzeug-0.8.3/PKG-INFO
--- old/Werkzeug-0.8.1/PKG-INFO 2011-09-30 12:50:07.000000000 +0200
+++ new/Werkzeug-0.8.3/PKG-INFO 2012-02-05 11:10:20.000000000 +0100
@@ -1,6 +1,6 @@
 Metadata-Version: 1.0
 Name: Werkzeug
-Version: 0.8.1
+Version: 0.8.3
 Summary: The Swiss Army knife of Python web development
 Home-page: http://werkzeug.pocoo.org/
 Author: Armin Ronacher
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/Werkzeug-0.8.1/Werkzeug.egg-info/PKG-INFO 
new/Werkzeug-0.8.3/Werkzeug.egg-info/PKG-INFO
--- old/Werkzeug-0.8.1/Werkzeug.egg-info/PKG-INFO       2011-09-30 
12:50:07.000000000 +0200
+++ new/Werkzeug-0.8.3/Werkzeug.egg-info/PKG-INFO       2012-02-05 
11:10:17.000000000 +0100
@@ -1,6 +1,6 @@
 Metadata-Version: 1.0
 Name: Werkzeug
-Version: 0.8.1
+Version: 0.8.3
 Summary: The Swiss Army knife of Python web development
 Home-page: http://werkzeug.pocoo.org/
 Author: Armin Ronacher
Files old/Werkzeug-0.8.1/artwork/._.DS_Store and 
new/Werkzeug-0.8.3/artwork/._.DS_Store differ
Files old/Werkzeug-0.8.1/docs/._.DS_Store and 
new/Werkzeug-0.8.3/docs/._.DS_Store differ
Files old/Werkzeug-0.8.1/docs/_static/._.DS_Store and 
new/Werkzeug-0.8.3/docs/_static/._.DS_Store differ
Files old/Werkzeug-0.8.1/docs/_static/._shortly.png and 
new/Werkzeug-0.8.3/docs/_static/._shortly.png differ
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/Werkzeug-0.8.1/setup.py new/Werkzeug-0.8.3/setup.py
--- old/Werkzeug-0.8.1/setup.py 2011-09-30 12:50:06.000000000 +0200
+++ new/Werkzeug-0.8.3/setup.py 2012-02-05 11:10:15.000000000 +0100
@@ -61,7 +61,7 @@
 
 setup(
     name='Werkzeug',
-    version='0.8.1',
+    version='0.8.3',
     url='http://werkzeug.pocoo.org/',
     license='BSD',
     author='Armin Ronacher',
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/Werkzeug-0.8.1/werkzeug/__init__.py 
new/Werkzeug-0.8.3/werkzeug/__init__.py
--- old/Werkzeug-0.8.1/werkzeug/__init__.py     2011-09-30 12:50:06.000000000 
+0200
+++ new/Werkzeug-0.8.3/werkzeug/__init__.py     2012-02-05 11:10:15.000000000 
+0100
@@ -19,7 +19,7 @@
 
 
 # the version.  Usually set automatically by a script.
-__version__ = '0.8.1'
+__version__ = '0.8.3'
 
 
 # This import magic raises concerns quite often which is why the implementation
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/Werkzeug-0.8.1/werkzeug/contrib/cache.py 
new/Werkzeug-0.8.3/werkzeug/contrib/cache.py
--- old/Werkzeug-0.8.1/werkzeug/contrib/cache.py        2011-09-30 
12:49:32.000000000 +0200
+++ new/Werkzeug-0.8.3/werkzeug/contrib/cache.py        2012-01-25 
00:54:51.000000000 +0100
@@ -471,15 +471,15 @@
     :param key_prefix: A prefix that should be added to all keys.
     """
 
-    def __init__(self, host='localhost', port=6379, default_timeout=300,
-                 key_prefix=None):
+    def __init__(self, host='localhost', port=6379, password=None,
+                 default_timeout=300, key_prefix=None):
         BaseCache.__init__(self, default_timeout)
         if isinstance(host, basestring):
             try:
                 import redis
             except ImportError:
                 raise RuntimeError('no redis module found')
-            self._client = redis.Redis(host=host, port=port)
+            self._client = redis.Redis(host=host, port=port, password=password)
         else:
             self._client = host
         self.key_prefix = key_prefix or ''
@@ -488,7 +488,8 @@
         """Dumps an object into a string for redis.  By default it serializes
         integers as regular string and pickle dumps everything else.
         """
-        if isinstance(value, (int, long)):
+        t = type(value)
+        if t is int or t is long:
             return str(value)
         return '!' + pickle.dumps(value)
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/Werkzeug-0.8.1/werkzeug/debug/console.py 
new/Werkzeug-0.8.3/werkzeug/debug/console.py
--- old/Werkzeug-0.8.1/werkzeug/debug/console.py        2011-07-05 
01:21:51.000000000 +0200
+++ new/Werkzeug-0.8.3/werkzeug/debug/console.py        2012-01-21 
15:42:28.000000000 +0100
@@ -201,4 +201,8 @@
         self._ipy = _InteractiveConsole(globals, locals)
 
     def eval(self, code):
-        return self._ipy.runsource(code)
+        old_sys_stdout = sys.stdout
+        try:
+            return self._ipy.runsource(code)
+        finally:
+            sys.stdout = old_sys_stdout
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/Werkzeug-0.8.1/werkzeug/routing.py 
new/Werkzeug-0.8.3/werkzeug/routing.py
--- old/Werkzeug-0.8.1/werkzeug/routing.py      2011-09-30 12:49:32.000000000 
+0200
+++ new/Werkzeug-0.8.3/werkzeug/routing.py      2012-02-05 11:08:36.000000000 
+0100
@@ -240,7 +240,7 @@
         self.new_url = new_url
 
     def get_response(self, environ):
-        return redirect(self.new_url, 301)
+        return redirect(self.new_url, self.code)
 
 
 class RequestSlash(RoutingException):
@@ -715,7 +715,7 @@
                     return
                 processed.add(data)
             else:
-                add(data)
+                add(url_quote(data, self.map.charset, safe='/:|'))
         domain_part, url = (u''.join(tmp)).split('|', 1)
 
         if append_unknown:
@@ -1121,6 +1121,8 @@
             subdomain = self.default_subdomain
         if script_name is None:
             script_name = '/'
+        if isinstance(server_name, unicode):
+            server_name = server_name.encode('idna')
         return MapAdapter(self, server_name, script_name, subdomain,
                           url_scheme, path_info, default_method, query_args)
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/Werkzeug-0.8.1/werkzeug/serving.py 
new/Werkzeug-0.8.3/werkzeug/serving.py
--- old/Werkzeug-0.8.1/werkzeug/serving.py      2011-09-30 12:49:32.000000000 
+0200
+++ new/Werkzeug-0.8.3/werkzeug/serving.py      2012-02-05 11:08:36.000000000 
+0100
@@ -177,6 +177,7 @@
 
     def handle(self):
         """Handles a request ignoring dropped connections."""
+        rv = None
         try:
             rv = BaseHTTPRequestHandler.handle(self)
         except (socket.error, socket.timeout), e:
@@ -192,9 +193,11 @@
         """A horrible, horrible way to kill the server for Python 2.6 and
         later.  It's the best we can do.
         """
+        # Windows does not provide SIGKILL, go with SIGTERM then.
+        sig = getattr(signal, 'SIGKILL', signal.SIGTERM)
         # reloader active
         if os.environ.get('WERKZEUG_RUN_MAIN') == 'true':
-            os.kill(os.getpid(), signal.SIGKILL)
+            os.kill(os.getpid(), sig)
         # python 2.7
         self.server._BaseServer__shutdown_request = True
         # python 2.6
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/Werkzeug-0.8.1/werkzeug/testsuite/contrib/cache.py 
new/Werkzeug-0.8.3/werkzeug/testsuite/contrib/cache.py
--- old/Werkzeug-0.8.1/werkzeug/testsuite/contrib/cache.py      2011-09-30 
12:49:32.000000000 +0200
+++ new/Werkzeug-0.8.3/werkzeug/testsuite/contrib/cache.py      2012-01-25 
00:54:51.000000000 +0100
@@ -149,6 +149,14 @@
         c.delete('foo')
 
 
+    def test_true_false(self):
+        c = self.make_cache()
+        c.set('foo', True)
+        assert c.get('foo') == True
+        c.set('bar', False)
+        assert c.get('bar') == False
+
+
 def suite():
     suite = unittest.TestSuite()
     suite.addTest(unittest.makeSuite(SimpleCacheTestCase))
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/Werkzeug-0.8.1/werkzeug/testsuite/exceptions.py 
new/Werkzeug-0.8.3/werkzeug/testsuite/exceptions.py
--- old/Werkzeug-0.8.1/werkzeug/testsuite/exceptions.py 2011-09-30 
12:49:32.000000000 +0200
+++ new/Werkzeug-0.8.3/werkzeug/testsuite/exceptions.py 2012-01-21 
15:41:00.000000000 +0100
@@ -23,7 +23,6 @@
 class ExceptionsTestCase(WerkzeugTestCase):
 
     def test_proxy_exception(self):
-        """Proxy exceptions"""
         orig_resp = Response('Hello World')
         try:
             exceptions.abort(orig_resp)
@@ -35,7 +34,6 @@
         self.assert_equal(resp.data, 'Hello World')
 
     def test_aborter(self):
-        """Exception aborter"""
         abort = exceptions.abort
         self.assert_raises(exceptions.BadRequest, abort, 400)
         self.assert_raises(exceptions.Unauthorized, abort, 401)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/Werkzeug-0.8.1/werkzeug/testsuite/formparser.py 
new/Werkzeug-0.8.3/werkzeug/testsuite/formparser.py
--- old/Werkzeug-0.8.1/werkzeug/testsuite/formparser.py 2011-09-30 
12:49:32.000000000 +0200
+++ new/Werkzeug-0.8.3/werkzeug/testsuite/formparser.py 2012-01-21 
15:41:00.000000000 +0100
@@ -48,7 +48,6 @@
 class FormParserTestCase(WerkzeugTestCase):
 
     def test_limiting(self):
-        """Test the limiting features"""
         data = 'foo=Hello+World&bar=baz'
         req = Request.from_values(input_stream=StringIO(data),
                                   content_length=len(data),
@@ -104,13 +103,12 @@
         self.assert_equal(req.form['foo'], 'Hello World')
 
     def test_parse_form_data_put_without_content(self):
-        """A PUT without a Content-Type header returns empty data
+        # A PUT without a Content-Type header returns empty data
 
-        Both rfc1945 and rfc2616 (1.0 and 1.1) say "Any HTTP/[1.0/1.1] message
-        containing an entity-body SHOULD include a Content-Type header field
-        defining the media type of that body."  In the case where either
-        headers are omitted, parse_form_data should still work.
-        """
+        # Both rfc1945 and rfc2616 (1.0 and 1.1) say "Any HTTP/[1.0/1.1] 
message
+        # containing an entity-body SHOULD include a Content-Type header field
+        # defining the media type of that body."  In the case where either
+        # headers are omitted, parse_form_data should still work.
         env = create_environ('/foo', 'http://example.org/', method='PUT')
         del env['CONTENT_TYPE']
         del env['CONTENT_LENGTH']
@@ -121,7 +119,6 @@
         self.assert_equal(len(files), 0)
 
     def test_parse_form_data_get_without_content(self):
-        """GET requests without data, content type and length returns no 
data"""
         env = create_environ('/foo', 'http://example.org/', method='GET')
         del env['CONTENT_TYPE']
         del env['CONTENT_LENGTH']
@@ -132,7 +129,6 @@
         self.assert_equal(len(files), 0)
 
     def test_large_file(self):
-        """Test a largish file."""
         data = 'x' * (1024 * 600)
         req = Request.from_values(data={'foo': (StringIO(data), 'test.txt')},
                                   method='POST')
@@ -144,7 +140,6 @@
 class MultiPartTestCase(WerkzeugTestCase):
 
     def test_basic(self):
-        """Tests multipart parsing against data collected from webbrowsers"""
         resources = join(dirname(__file__), 'multipart')
         client = Client(form_data_consumer, Response)
 
@@ -200,7 +195,6 @@
                           repr(u'Sellersburg Town Council Meeting 
02-22-2010doc.doc'))
 
     def test_end_of_file(self):
-        """Test for multipart files ending unexpectedly"""
         # This test looks innocent but it was actually timeing out in
         # the Werkzeug 0.5 release version (#394)
         data = (
@@ -217,7 +211,6 @@
         self.assert_(not data.form)
 
     def test_broken(self):
-        """Broken multipart does not break the applicaiton"""
         data = (
             '--foo\r\n'
             'Content-Disposition: form-data; name="test"; 
filename="test.txt"\r\n'
@@ -237,7 +230,6 @@
                       silent=False)
 
     def test_file_no_content_type(self):
-        """Chrome does not always provide a content type."""
         data = (
             '--foo\r\n'
             'Content-Disposition: form-data; name="test"; 
filename="test.txt"\r\n\r\n'
@@ -251,7 +243,6 @@
         self.assert_equal(data.files['test'].read(), 'file contents')
 
     def test_extra_newline(self):
-        """Test for multipart uploads with extra newlines"""
         # this test looks innocent but it was actually timeing out in
         # the Werkzeug 0.5 release version (#394)
         data = (
@@ -268,7 +259,6 @@
         self.assert_equal(data.form['foo'], 'a string')
 
     def test_headers(self):
-        """Test access to multipart headers"""
         data = ('--foo\r\n'
                 'Content-Disposition: form-data; name="foo"; 
filename="foo.txt"\r\n'
                 'X-Custom-Header: blah\r\n'
@@ -287,7 +277,6 @@
         self.assert_equal(foo.headers['x-custom-header'], 'blah')
 
     def test_nonstandard_line_endings(self):
-        """Test nonstandard line endings of multipart form data"""
         for nl in '\n', '\r', '\r\n':
             data = nl.join((
                 '--foo',
@@ -330,7 +319,6 @@
                            ['foo: bar\r\n', ' x test'])
 
     def test_bad_newline_bad_newline_assumption(self):
-        """Make sure we don't eat up stuff that is not a newline"""
         class ISORequest(Request):
             charset = 'latin1'
         contents = 'U2vlbmUgbORu'
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/Werkzeug-0.8.1/werkzeug/testsuite/routing.py 
new/Werkzeug-0.8.3/werkzeug/testsuite/routing.py
--- old/Werkzeug-0.8.1/werkzeug/testsuite/routing.py    2011-09-30 
12:49:32.000000000 +0200
+++ new/Werkzeug-0.8.3/werkzeug/testsuite/routing.py    2012-02-05 
11:08:36.000000000 +0100
@@ -603,6 +603,29 @@
         else:
             assert False, 'Expected not found exception'
 
+    def test_redirect_request_exception_code(self):
+        exc = r.RequestRedirect('http://www.google.com/')
+        exc.code = 307
+        env = create_environ()
+        self.assert_equal(exc.get_response(env).status_code, exc.code)
+
+    def test_unicode_rules(self):
+        m = r.Map([
+            r.Rule(u'/войти/', endpoint='enter')
+        ])
+        a = m.bind(u'☃.example.com')
+        try:
+            a.match(u'/войти')
+        except r.RequestRedirect, e:
+            self.assert_equal(e.new_url, 'http://xn--n3h.example.com/'
+                              '%D0%B2%D0%BE%D0%B9%D1%82%D0%B8/')
+        endpoint, values = a.match(u'/войти/')
+        self.assert_equal(endpoint, 'enter')
+        self.assert_equal(values, {})
+
+        url = a.build('enter', {}, force_external=True)
+        self.assert_equal(url, 
'http://xn--n3h.example.com/%D0%B2%D0%BE%D0%B9%D1%82%D0%B8/')
+
 
 def suite():
     suite = unittest.TestSuite()
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/Werkzeug-0.8.1/werkzeug/testsuite/utils.py 
new/Werkzeug-0.8.3/werkzeug/testsuite/utils.py
--- old/Werkzeug-0.8.1/werkzeug/testsuite/utils.py      2011-09-30 
12:49:32.000000000 +0200
+++ new/Werkzeug-0.8.3/werkzeug/testsuite/utils.py      2012-02-05 
11:08:19.000000000 +0100
@@ -40,6 +40,15 @@
         assert resp.headers['Location'] == 'http://example.com/'
         assert resp.status_code == 305
 
+    def test_redirect_xss(self):
+        location = 'http://example.com/?xss=";><script>alert(1)</script>'
+        resp = utils.redirect(location)
+        assert '<script>alert(1)</script>' not in resp.data
+
+        location = 'http://example.com/?xss="onmouseover="alert(1)'
+        resp = utils.redirect(location)
+        assert 'href="http://example.com/?xss="onmouseover="alert(1)"' not in 
resp.data
+
     def test_cached_property(self):
         foo = []
         class A(object):
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/Werkzeug-0.8.1/werkzeug/testsuite/wsgi.py 
new/Werkzeug-0.8.3/werkzeug/testsuite/wsgi.py
--- old/Werkzeug-0.8.1/werkzeug/testsuite/wsgi.py       2011-09-30 
12:49:32.000000000 +0200
+++ new/Werkzeug-0.8.3/werkzeug/testsuite/wsgi.py       2012-02-05 
11:08:36.000000000 +0100
@@ -210,6 +210,19 @@
         lines = list(wsgi.make_line_iter(test_stream, limit=len(data), 
buffer_size=24))
         assert lines == ['abc\r\n', 'This line is broken by the buffer 
length.\r\n', 'Foo bar baz']
 
+    def test_multi_part_line_breaks_problematic(self):
+        data = 'abc\rdef\r\nghi'
+        for x in xrange(1, 10):
+            test_stream = StringIO(data)
+            lines = list(wsgi.make_line_iter(test_stream, limit=len(data), 
buffer_size=4))
+            assert lines == ['abc\r', 'def\r\n', 'ghi']
+
+    def test_lines_longer_buffer_size(self):
+        data = '1234567890\n1234567890\n'
+        for bufsize in xrange(1, 15):
+            lines = list(wsgi.make_line_iter(StringIO(data), limit=len(data), 
buffer_size=4))
+            self.assert_equal(lines, ['1234567890\n', '1234567890\n'])
+
 
 def suite():
     suite = unittest.TestSuite()
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/Werkzeug-0.8.1/werkzeug/utils.py 
new/Werkzeug-0.8.3/werkzeug/utils.py
--- old/Werkzeug-0.8.1/werkzeug/utils.py        2011-09-30 12:49:32.000000000 
+0200
+++ new/Werkzeug-0.8.3/werkzeug/utils.py        2012-02-05 11:08:19.000000000 
+0100
@@ -189,10 +189,10 @@
                     buffer += '>'
                 return buffer
             buffer += '>'
-            
+
             children_as_string = ''.join([unicode(x) for x in children
                                          if x is not None])
-            
+
             if children_as_string:
                 if tag in self._plaintext_elements:
                     children_as_string = escape(children_as_string)
@@ -353,7 +353,7 @@
     :param code: the redirect status code. defaults to 302.
     """
     from werkzeug.wrappers import BaseResponse
-    display_location = location
+    display_location = escape(location)
     if isinstance(location, unicode):
         from werkzeug.urls import iri_to_uri
         location = iri_to_uri(location)
@@ -363,7 +363,7 @@
         '<h1>Redirecting...</h1>\n'
         '<p>You should be redirected automatically to target URL: '
         '<a href="%s">%s</a>.  If not click the link.' %
-        (location, display_location), code, mimetype='text/html')
+        (escape(location, True), display_location), code, mimetype='text/html')
     response.headers['Location'] = location
     return response
 
@@ -586,7 +586,7 @@
             name += (name and '.') + part
             imported = import_string(name, silent=True)
             if imported:
-                tracked.append((name, imported.__file__))
+                tracked.append((name, getattr(imported, '__file__', None)))
             else:
                 track = ['- %r found in %r.' % (n, i) for n, i in tracked]
                 track.append('- %r not found.' % name)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/Werkzeug-0.8.1/werkzeug/wrappers.py 
new/Werkzeug-0.8.3/werkzeug/wrappers.py
--- old/Werkzeug-0.8.1/werkzeug/wrappers.py     2011-09-30 12:49:32.000000000 
+0200
+++ new/Werkzeug-0.8.3/werkzeug/wrappers.py     2012-01-21 15:41:00.000000000 
+0100
@@ -737,7 +737,7 @@
         except KeyError:
             self._status = '%d UNKNOWN' % code
     status_code = property(_get_status_code, _set_status_code,
-                           'The HTTP Status code as number')
+                           doc='The HTTP Status code as number')
     del _get_status_code, _set_status_code
 
     def _get_status(self):
@@ -748,7 +748,7 @@
             self._status_code = int(self._status.split(None, 1)[0])
         except ValueError:
             self._status_code = 0
-    status = property(_get_status, _set_status, 'The HTTP Status code')
+    status = property(_get_status, _set_status, doc='The HTTP Status code')
     del _get_status, _set_status
 
     def _get_data(self):
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/Werkzeug-0.8.1/werkzeug/wsgi.py 
new/Werkzeug-0.8.3/werkzeug/wsgi.py
--- old/Werkzeug-0.8.1/werkzeug/wsgi.py 2011-09-30 12:49:32.000000000 +0200
+++ new/Werkzeug-0.8.3/werkzeug/wsgi.py 2012-02-05 11:08:36.000000000 +0100
@@ -604,30 +604,52 @@
     :param buffer_size: The optional buffer size.
     """
     stream = make_limited_stream(stream, limit)
-    _read = stream.read
-    buffer = []
-    while 1:
-        if len(buffer) > 1:
-            yield buffer.pop()
-            continue
-
-        # we reverse the chunks because popping from the last
-        # position of the list is O(1) and the number of chunks
-        # read will be quite large for binary files.
-        chunks = _read(buffer_size).splitlines(True)
-        chunks.reverse()
-
-        first_chunk = buffer and buffer[0] or ''
-        if chunks:
-            if first_chunk.endswith('\n') or first_chunk.endswith('\r'):
+    def _iter_basic_lines():
+        _read = stream.read
+        buffer = []
+        while 1:
+            if len(buffer) > 1:
+                yield buffer.pop()
+                continue
+
+            # we reverse the chunks because popping from the last
+            # position of the list is O(1) and the number of chunks
+            # read will be quite large for binary files.
+            chunks = _read(buffer_size).splitlines(True)
+            chunks.reverse()
+
+            first_chunk = buffer and buffer[0] or ''
+            if chunks:
+                if first_chunk and first_chunk[-1] in '\r\n':
+                    yield first_chunk
+                    first_chunk = ''
+                first_chunk += chunks.pop()
+            else:
+                yield first_chunk
+                break
+
+            buffer = chunks
+
+            # in case the line is longer than the buffer size we
+            # can't yield yet.  This will only happen if the buffer
+            # is empty.
+            if not buffer and first_chunk[-1] not in '\r\n':
+                buffer = [first_chunk]
+            else:
                 yield first_chunk
-                first_chunk = ''
-            first_chunk += chunks.pop()
-        if not first_chunk:
-            return
 
-        buffer = chunks
-        yield first_chunk
+    # This hackery is necessary to merge 'foo\r' and '\n' into one item
+    # of 'foo\r\n' if we were unlucky and we hit a chunk boundary.
+    previous = ''
+    for item in _iter_basic_lines():
+        if item == '\n' and previous[-1:] == '\r':
+            previous += '\n'
+            item = ''
+        if previous:
+            yield previous
+        previous = item
+    if previous:
+        yield previous
 
 
 def make_chunk_iter(stream, separator, limit=None, buffer_size=10 * 1024):

-- 
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to