]> granicus.if.org Git - python/commitdiff
Issue #17089: Expat parser now correctly works with string input not only when
authorSerhiy Storchaka <storchaka@gmail.com>
Mon, 4 Feb 2013 16:28:01 +0000 (18:28 +0200)
committerSerhiy Storchaka <storchaka@gmail.com>
Mon, 4 Feb 2013 16:28:01 +0000 (18:28 +0200)
an internal XML encoding is UTF-8 or US-ASCII.  It now accepts bytes and
strings larger than 2 GiB.

1  2 
Misc/NEWS
Modules/pyexpat.c

diff --cc Misc/NEWS
index 8ca4b01c6183aa47e5b04adbe5f9d5e14bd4e410,07a33cee710650a9f11da8911702799b36026535..ce24d0e4ab5f86edc9ba05d2a6b322662f0daab4
+++ b/Misc/NEWS
@@@ -163,6 -212,13 +163,10 @@@ Core and Builtin
  Library
  -------
  
 -- Issue #16903: Popen.communicate() on Unix now accepts strings when
 -  universal_newlines is true as on Windows.
 -
+ - Issue #17089: Expat parser now correctly works with string input not only when
+   an internal XML encoding is UTF-8 or US-ASCII.  It now accepts bytes and
+   strings larger than 2 GiB.
  - Issue #6083: Fix multiple segmentation faults occured when PyArg_ParseTuple
    parses nested mutating sequence.
  
index 3f59f0fdc15c12cd6c98349a3538e9d77ca6600a,9d22d3a0518e6aab7bf77da05201309b8adc1b38..022b0cbaf92af9959ca847d6d079746da7d97344
@@@ -781,14 -782,47 +783,44 @@@ Parse XML data.  `isfinal' should be tr
  static PyObject *
  xmlparse_Parse(xmlparseobject *self, PyObject *args)
  {
-     char *s;
-     int slen;
+     PyObject *data;
      int isFinal = 0;
+     const char *s;
+     Py_ssize_t slen;
+     Py_buffer view;
+     int rc;
  
-     if (!PyArg_ParseTuple(args, "s#|i:Parse", &s, &slen, &isFinal))
+     if (!PyArg_ParseTuple(args, "O|i:Parse", &data, &isFinal))
          return NULL;
  
-     return get_parse_result(self, XML_Parse(self->itself, s, slen, isFinal));
+     if (PyUnicode_Check(data)) {
 -        PyObject *bytes;
 -        bytes = PyUnicode_AsUTF8String(data);
 -        if (bytes == NULL)
 -            return NULL;
+         view.buf = NULL;
 -        s = PyBytes_AS_STRING(bytes);
 -        slen = PyBytes_GET_SIZE(bytes);
++        s = PyUnicode_AsUTF8AndSize(data, &slen);
++        if (s == NULL)
++            return NULL;
+         /* Explicitly set UTF-8 encoding. Return code ignored. */
+         (void)XML_SetEncoding(self->itself, "utf-8");
+     }
+     else {
+         if (PyObject_GetBuffer(data, &view, PyBUF_SIMPLE) < 0)
+             return NULL;
+         s = view.buf;
+         slen = view.len;
+     }
+     while (slen > MAX_CHUNK_SIZE) {
+         rc = XML_Parse(self->itself, s, MAX_CHUNK_SIZE, 0);
+         if (!rc)
+             goto done;
+         s += MAX_CHUNK_SIZE;
+         slen -= MAX_CHUNK_SIZE;
+     }
+     rc = XML_Parse(self->itself, s, slen, isFinal);
+ done:
+     if (view.buf != NULL)
+         PyBuffer_Release(&view);
+     return get_parse_result(self, rc);
  }
  
  /* File reading copied from cPickle */