]> granicus.if.org Git - python/commitdiff
Merged revisions 61034-61036,61038-61048 via svnmerge from
authorChristian Heimes <christian@cheimes.de>
Sun, 24 Feb 2008 13:08:18 +0000 (13:08 +0000)
committerChristian Heimes <christian@cheimes.de>
Sun, 24 Feb 2008 13:08:18 +0000 (13:08 +0000)
svn+ssh://pythondev@svn.python.org/python/trunk

........
  r61034 | georg.brandl | 2008-02-24 01:03:22 +0100 (Sun, 24 Feb 2008) | 4 lines

  #900744: If an invalid chunked-encoding header is sent by a server,
  httplib will now raise IncompleteRead and close the connection instead
  of raising ValueError.
........
  r61035 | georg.brandl | 2008-02-24 01:14:24 +0100 (Sun, 24 Feb 2008) | 2 lines

  #1627: httplib now ignores negative Content-Length headers.
........
  r61039 | andrew.kuchling | 2008-02-24 03:39:15 +0100 (Sun, 24 Feb 2008) | 1 line

  Remove stray word
........
  r61040 | neal.norwitz | 2008-02-24 03:40:58 +0100 (Sun, 24 Feb 2008) | 3 lines

  Add a little info to the 3k deprecation warnings about what to use instead.
  Suggested by Raymond Hettinger.
........
  r61041 | facundo.batista | 2008-02-24 04:17:21 +0100 (Sun, 24 Feb 2008) | 4 lines

  Issue 1742669. Now %d accepts very big float numbers.
  Thanks Gabriel Genellina.
........
  r61046 | neal.norwitz | 2008-02-24 08:21:56 +0100 (Sun, 24 Feb 2008) | 5 lines

  Get ctypes working on the Alpha (Tru64).  The problem was that there
  were two module_methods and the one used depended on the order the
  modules were loaded.  By making the test module_methods static,
  it is not exported and the correct version is picked up.
........
  r61048 | neal.norwitz | 2008-02-24 09:27:49 +0100 (Sun, 24 Feb 2008) | 1 line

  Fix typo of hexidecimal
........

Doc/howto/regex.rst
Lib/httplib.py
Lib/test/string_tests.py
Lib/test/test_format.py
Lib/test/test_httplib.py
Misc/cheatsheet
Modules/_ctypes/_ctypes_test.c
Objects/unicodeobject.c

index 406ce1c8cb2eca3ba923af309afdaca0557feb2e..40f5fdb5fa705a7a1a517d161d529df0c71df847 100644 (file)
@@ -203,7 +203,7 @@ this RE against the string ``abcbd``.
 |      |           | ``bc``.                         |
 +------+-----------+---------------------------------+
 | 6    | ``abcb``  | Try ``b`` again.  This time     |
-|      |           | but the character at the        |
+|      |           | the character at the            |
 |      |           | current position is ``'b'``, so |
 |      |           | it succeeds.                    |
 +------+-----------+---------------------------------+
index 638a92b039d1eead41edb9b5626ab787a573f182..de27c17b4cff261b3f914b75ac64d167d477798e 100644 (file)
@@ -448,7 +448,12 @@ class HTTPResponse:
             try:
                 self.length = int(length)
             except ValueError:
-                pass
+                self.length = None
+            else:
+                if self.length < 0:  # ignore nonsensical negative lengths
+                    self.length = None
+        else:
+            self.length = None
 
         # does the body have a fixed length? (of zero)
         if (status == NO_CONTENT or status == NOT_MODIFIED or
@@ -569,7 +574,13 @@ class HTTPResponse:
                 i = line.find(b";")
                 if i >= 0:
                     line = line[:i] # strip chunk-extensions
-                chunk_left = int(line, 16)
+                try:
+                    chunk_left = int(line, 16)
+                except ValueError:
+                    # close the connection as protocol synchronisation is
+                    # probably lost
+                    self.close()
+                    raise IncompleteRead(value)
                 if chunk_left == 0:
                     break
             if amt is None:
index 24fca598d74d9ec7cc92decf2afb68100f784b10..caafb31388837a7fd90fb44c7eee396397ef4262 100644 (file)
@@ -1053,7 +1053,13 @@ class MixinStrUnicodeUserStringTest:
             # unicode raises ValueError, str raises OverflowError
             self.checkraises((ValueError, OverflowError), '%c', '__mod__', ordinal)
 
+        longvalue = sys.maxsize + 10
+        slongvalue = str(longvalue)
+        if slongvalue[-1] in ("L","l"): slongvalue = slongvalue[:-1]
         self.checkequal(' 42', '%3ld', '__mod__', 42)
+        self.checkequal('42', '%d', '__mod__', 42.0)
+        self.checkequal(slongvalue, '%d', '__mod__', longvalue)
+        self.checkcall('%d', '__mod__', float(longvalue))
         self.checkequal('0042.00', '%07.2f', '__mod__', 42)
         self.checkequal('0042.00', '%07.2F', '__mod__', 42)
 
@@ -1063,6 +1069,8 @@ class MixinStrUnicodeUserStringTest:
         self.checkraises(TypeError, '%c', '__mod__', (None,))
         self.checkraises(ValueError, '%(foo', '__mod__', {})
         self.checkraises(TypeError, '%(foo)s %(bar)s', '__mod__', ('foo', 42))
+        self.checkraises(TypeError, '%d', '__mod__', "42") # not numeric
+        self.checkraises(TypeError, '%d', '__mod__', (42+0j)) # no int/long conversion provided
 
         # argument names with properly nested brackets are supported
         self.checkequal('bar', '%((foo))s', '__mod__', {'(foo)': 'bar'})
index 9f4528c2c978764a4c651667d4ae8021cca04e73..7070286b38aad2401dfb2a8ec728ff9796ae2d69 100644 (file)
@@ -11,7 +11,7 @@ maxsize = MAX_Py_ssize_t
 overflowok = 1
 overflowrequired = 0
 
-def testformat(formatstr, args, output=None):
+def testformat(formatstr, args, output=None, limit=None):
     if verbose:
         if output:
             print("%r %% %r =? %r ..." %\
@@ -30,11 +30,22 @@ def testformat(formatstr, args, output=None):
             if verbose:
                 print('no')
             print("overflow expected on %r %% %r" % (formatstr, args))
-        elif output and result != output:
+        elif output and limit is None and result != output:
             if verbose:
                 print('no')
             print("%r %% %r == %r != %r" %\
                 (formatstr, args, result, output))
+        # when 'limit' is specified, it determines how many characters
+        # must match exactly; lengths must always match.
+        # ex: limit=5, '12345678' matches '12345___'
+        # (mainly for floating point format tests for which an exact match
+        # can't be guaranteed due to rounding and representation errors)
+        elif output and limit is not None and (
+                len(result)!=len(output) or result[:limit]!=output[:limit]):
+            if verbose:
+                print('no')
+            print("%s %% %s == %s != %s" % \
+                  (repr(formatstr), repr(args), repr(result), repr(output)))
         else:
             if verbose:
                 print('yes')
@@ -91,6 +102,7 @@ testformat("%.2d", big, "123456789012345678901234567890")
 testformat("%.30d", big, "123456789012345678901234567890")
 testformat("%.31d", big, "0123456789012345678901234567890")
 testformat("%32.31d", big, " 0123456789012345678901234567890")
+testformat("%d", float(big), "123456________________________", 6)
 
 big = 0x1234567890abcdef12345  # 21 hex digits
 testformat("%x", big, "1234567890abcdef12345")
@@ -128,6 +140,7 @@ testformat("%#+27.23X", big, " +0X001234567890ABCDEF12345")
 testformat("%#+027.23X", big, "+0X0001234567890ABCDEF12345")
 # same, except no 0 flag
 testformat("%#+27.23X", big, " +0X001234567890ABCDEF12345")
+testformat("%x", float(big), "123456_______________", 6)
 
 big = 0o12345670123456701234567012345670  # 32 octal digits
 testformat("%o", big, "12345670123456701234567012345670")
@@ -169,6 +182,7 @@ testformat("%034.33o", big, "0012345670123456701234567012345670")
 testformat("%0#38.33o", big, "0o000012345670123456701234567012345670")
 # padding spaces come before marker
 testformat("%#36.33o", big, " 0o012345670123456701234567012345670")
+testformat("%o", float(big), "123456__________________________", 6)
 
 # Some small ints, in both Python int and long flavors).
 testformat("%d", 42, "42")
@@ -186,11 +200,13 @@ testformat("%#X", 0, "0X0")
 
 testformat("%x", 0x42, "42")
 testformat("%x", -0x42, "-42")
+testformat("%x", float(0x42), "42")
 
 testformat("%o", 0o42, "42")
 testformat("%o", -0o42, "-42")
 testformat("%o", 0o42, "42")
 testformat("%o", -0o42, "-42")
+testformat("%o", float(0o42), "42")
 
 # Test exception for unknown format characters
 if verbose:
index 4caf9960cce0c5e4d1fdec4d73f15e8628e50a4d..ca801da9ffdd8df6c0289d00b0488a5ee02c239a 100644 (file)
@@ -159,6 +159,42 @@ class BasicTest(TestCase):
         self.assertTrue(sock.data.startswith(expected), '%r != %r' %
                 (sock.data[:len(expected)], expected))
 
+    def test_chunked(self):
+        chunked_start = (
+            'HTTP/1.1 200 OK\r\n'
+            'Transfer-Encoding: chunked\r\n\r\n'
+            'a\r\n'
+            'hello worl\r\n'
+            '1\r\n'
+            'd\r\n'
+        )
+        sock = FakeSocket(chunked_start + '0\r\n')
+        resp = httplib.HTTPResponse(sock, method="GET")
+        resp.begin()
+        self.assertEquals(resp.read(), b'hello world')
+        resp.close()
+
+        for x in ('', 'foo\r\n'):
+            sock = FakeSocket(chunked_start + x)
+            resp = httplib.HTTPResponse(sock, method="GET")
+            resp.begin()
+            try:
+                resp.read()
+            except httplib.IncompleteRead as i:
+                self.assertEquals(i.partial, b'hello world')
+            else:
+                self.fail('IncompleteRead expected')
+            finally:
+                resp.close()
+
+    def test_negative_content_length(self):
+        sock = FakeSocket('HTTP/1.1 200 OK\r\nContent-Length: -1\r\n\r\nHello\r\n')
+        resp = httplib.HTTPResponse(sock, method="GET")
+        resp.begin()
+        self.assertEquals(resp.read(), b'Hello\r\n')
+        resp.close()
+
+
 class OfflineTest(TestCase):
     def test_responses(self):
         self.assertEquals(httplib.responses[httplib.NOT_FOUND], "Not Found")
index c5304426996557c6e8a8a914d634df74b610997f..cc5603667efe1176e7f6e9bfde90ad53108e458b 100644 (file)
@@ -561,8 +561,8 @@ d          Signed integer decimal.
 i          Signed integer decimal.
 o          Unsigned octal.
 u          Unsigned decimal.
-x          Unsigned hexidecimal (lowercase).
-X          Unsigned hexidecimal (uppercase).
+x          Unsigned hexadecimal (lowercase).
+X          Unsigned hexadecimal (uppercase).
 e          Floating point exponential format (lowercase).
 E          Floating point exponential format (uppercase).
 f          Floating point decimal format.
index 7048a2efc5119ae00e1e2fb1d2312bc935727d9f..63fb580fe132c8a84f02d8f6c0c7e755e5486fca 100644 (file)
@@ -398,7 +398,7 @@ EXPORT(int) unpack_bitfields(struct BITS *bits, char name)
        return 0;
 }
 
-PyMethodDef module_methods[] = {
+static PyMethodDef module_methods[] = {
 /*     {"get_last_tf_arg_s", get_last_tf_arg_s, METH_NOARGS},
        {"get_last_tf_arg_u", get_last_tf_arg_u, METH_NOARGS},
 */
index 86d8b547bfd225c8448c55f3f4ca71a967e369f9..73598213bb4c3403ca9f18809bf955b1cc68bb60 100644 (file)
@@ -8600,6 +8600,7 @@ PyObject *PyUnicode_Format(PyObject *format,
            int prec = -1;
            Py_UNICODE c = '\0';
            Py_UNICODE fill;
+           int isnumok;
            PyObject *v = NULL;
            PyObject *temp = NULL;
            Py_UNICODE *pbuf;
@@ -8804,21 +8805,38 @@ PyObject *PyUnicode_Format(PyObject *format,
            case 'X':
                if (c == 'i')
                    c = 'd';
-               if (PyLong_Check(v)) {
-                   temp = formatlong(v, flags, prec, c);
-                   if (!temp)
-                       goto onError;
-                   pbuf = PyUnicode_AS_UNICODE(temp);
-                   len = PyUnicode_GET_SIZE(temp);
-                   sign = 1;
+               isnumok = 0;
+               if (PyNumber_Check(v)) {
+                       PyObject *iobj=NULL;
+
+                       if (PyLong_Check(v)) {
+                               iobj = v;
+                               Py_INCREF(iobj);
+                       }
+                       else {
+                               iobj = PyNumber_Long(v);
+                       }
+                       if (iobj!=NULL) {
+                               if (PyLong_Check(iobj)) {
+                                       isnumok = 1;
+                                       temp = formatlong(iobj, flags, prec, c);
+                                       Py_DECREF(iobj);
+                                       if (!temp)
+                                           goto onError;
+                                       pbuf = PyUnicode_AS_UNICODE(temp);
+                                       len = PyUnicode_GET_SIZE(temp);
+                                       sign = 1;
+                               }
+                               else {
+                                       Py_DECREF(iobj);
+                               }
+                       }
                }
-               else {
-                   pbuf = formatbuf;
-                   len = formatint(pbuf, sizeof(formatbuf)/sizeof(Py_UNICODE),
-                                   flags, prec, c, v);
-                   if (len < 0)
+               if (!isnumok) {
+                       PyErr_Format(PyExc_TypeError, 
+                           "%%%c format: a number is required, "
+                           "not %.200s", c, Py_TYPE(v)->tp_name);
                        goto onError;
-                   sign = 1;
                }
                if (flags & F_ZERO)
                    fill = '0';