[Python-checkins] r71573 - in python/branches/py3k-short-float-repr: Lib/test/test_types.py Objects/stringlib/formatter.h

eric.smith python-checkins at python.org
Mon Apr 13 15:26:20 CEST 2009


Author: eric.smith
Date: Mon Apr 13 15:26:19 2009
New Revision: 71573

Log:
Enabled error checking with better messages, added tests.

Modified:
   python/branches/py3k-short-float-repr/Lib/test/test_types.py
   python/branches/py3k-short-float-repr/Objects/stringlib/formatter.h

Modified: python/branches/py3k-short-float-repr/Lib/test/test_types.py
==============================================================================
--- python/branches/py3k-short-float-repr/Lib/test/test_types.py	(original)
+++ python/branches/py3k-short-float-repr/Lib/test/test_types.py	Mon Apr 13 15:26:19 2009
@@ -604,6 +604,20 @@
         self.assertRaises(ValueError, format, 0.0, '#')
         self.assertRaises(ValueError, format, 0.0, '#20f')
 
+    def test_format_spec_errors(self):
+        # int, float, and string all share the same format spec
+        # mini-language parser.
+
+        # Check that we can't ask for too many digits. This is
+        # probably a CPython specific test. It tries to put the width
+        # into a C long.
+        self.assertRaises(ValueError, format, 0, '1'*10000 + 'd')
+
+        # Similar with the precision.
+        self.assertRaises(ValueError, format, 0, '.' + '1'*10000 + 'd')
+
+        # And may as well test both.
+        self.assertRaises(ValueError, format, 0, '1'*1000 + '.' + '1'*10000 + 'd')
 
 def test_main():
     run_unittest(TypesTests)

Modified: python/branches/py3k-short-float-repr/Objects/stringlib/formatter.h
==============================================================================
--- python/branches/py3k-short-float-repr/Objects/stringlib/formatter.h	(original)
+++ python/branches/py3k-short-float-repr/Objects/stringlib/formatter.h	Mon Apr 13 15:26:19 2009
@@ -140,7 +140,7 @@
     /* end-ptr is used throughout this code to specify the length of
        the input string */
 
-    Py_ssize_t specified_width;
+    Py_ssize_t consumed;
 
     format->fill_char = '\0';
     format->align = '\0';
@@ -185,15 +185,17 @@
         ++ptr;
     }
 
-    /* XXX add error checking */
-    specified_width = get_integer(&ptr, end, &format->width);
+    consumed = get_integer(&ptr, end, &format->width);
+    if (consumed == -1)
+        /* Overflow error. Exception already set. */
+        return 0;
 
-    /* If specified_width is 0, we didn't consume any characters for
-       the width. In that case, reset the width to -1, because
-       get_integer() will have set it to zero */
-    if (specified_width == 0) {
+    /* If consumed is 0, we didn't consume any characters for the
+       width. In that case, reset the width to -1, because
+       get_integer() will have set it to zero. -1 is how we record
+       that the width wasn't specified. */
+    if (consumed == 0)
         format->width = -1;
-    }
 
     /* Comma signifies add thousands separators */
     if (end-ptr && ptr[0] == ',') {
@@ -205,11 +207,13 @@
     if (end-ptr && ptr[0] == '.') {
         ++ptr;
 
-        /* XXX add error checking */
-        specified_width = get_integer(&ptr, end, &format->precision);
+        consumed = get_integer(&ptr, end, &format->precision);
+        if (consumed == -1)
+            /* Overflow error. Exception already set. */
+            return 0;
 
         /* Not having a precision after a dot is an error. */
-        if (specified_width == 0) {
+        if (consumed == 0) {
             PyErr_Format(PyExc_ValueError,
                          "Format specifier missing precision");
             return 0;


More information about the Python-checkins mailing list