[Python-checkins] cpython: Fix formatting memory consumption with very large padding specifications

antoine.pitrou python-checkins at python.org
Fri Oct 7 12:39:28 CEST 2011


http://hg.python.org/cpython/rev/023ca78c67a0
changeset:   72786:023ca78c67a0
user:        Antoine Pitrou <solipsis at pitrou.net>
date:        Fri Oct 07 12:35:48 2011 +0200
summary:
  Fix formatting memory consumption with very large padding specifications

files:
  Objects/unicodeobject.c |  36 ++++++++++++++++++++++------
  1 files changed, 28 insertions(+), 8 deletions(-)


diff --git a/Objects/unicodeobject.c b/Objects/unicodeobject.c
--- a/Objects/unicodeobject.c
+++ b/Objects/unicodeobject.c
@@ -12727,6 +12727,29 @@
     return (Py_UCS4) -1;
 }
 
+static int
+repeat_accumulate(_PyAccu *acc, PyObject *obj, Py_ssize_t count)
+{
+    int r;
+    assert(count > 0);
+    assert(PyUnicode_Check(obj));
+    if (count > 5) {
+        PyObject *repeated = unicode_repeat((PyUnicodeObject *) obj, count);
+        if (repeated == NULL)
+            return -1;
+        r = _PyAccu_Accumulate(acc, repeated);
+        Py_DECREF(repeated);
+        return r;
+    }
+    else {
+        do {
+            if (_PyAccu_Accumulate(acc, obj))
+                return -1;
+        } while (--count);
+        return 0;
+    }
+}
+
 PyObject *
 PyUnicode_Format(PyObject *format, PyObject *args)
 {
@@ -13145,10 +13168,9 @@
             }
             if (width > len && !(flags & F_LJUST)) {
                 assert(fillobj != NULL);
-                do {
-                    if (_PyAccu_Accumulate(&acc, fillobj))
-                        goto onError;
-                } while (--width > len);
+                if (repeat_accumulate(&acc, fillobj, width - len))
+                    goto onError;
+                width = len;
             }
             if (fill == ' ') {
                 if (sign) {
@@ -13186,10 +13208,8 @@
             Py_DECREF(v);
             if (r)
                 goto onError;
-            while (--width >= len) {
-                if (_PyAccu_Accumulate(&acc, blank))
-                    goto onError;
-            }
+            if (width > len && repeat_accumulate(&acc, blank, width - len))
+                goto onError;
             if (dict && (argidx < arglen) && c != '%') {
                 PyErr_SetString(PyExc_TypeError,
                                 "not all arguments converted during string formatting");

-- 
Repository URL: http://hg.python.org/cpython


More information about the Python-checkins mailing list