diff options
Diffstat (limited to 'python/libxml.c')
-rw-r--r-- | python/libxml.c | 89 |
1 files changed, 67 insertions, 22 deletions
diff --git a/python/libxml.c b/python/libxml.c index 9e24314..bb2649a 100644 --- a/python/libxml.c +++ b/python/libxml.c @@ -512,6 +512,11 @@ libxml_xmlOutputBufferClose(PyObject *self ATTRIBUTE_UNUSED, PyObject *args) { if (!PyArg_ParseTuple(args, (char *)"O:xmlOutputBufferClose", &pyobj_out)) return(NULL); out = (xmlOutputBufferPtr) PyoutputBuffer_Get(pyobj_out); + /* Buffer may already have been destroyed elsewhere. This is harmless. */ + if (out == NULL) { + Py_INCREF(Py_None); + return(Py_None); + } c_retval = xmlOutputBufferClose(out); py_retval = libxml_intWrap((int) c_retval); @@ -533,6 +538,53 @@ libxml_xmlOutputBufferFlush(PyObject *self ATTRIBUTE_UNUSED, PyObject *args) { py_retval = libxml_intWrap((int) c_retval); return(py_retval); } + +static PyObject * +libxml_xmlSaveFileTo(PyObject *self ATTRIBUTE_UNUSED, PyObject *args) { + PyObject *py_retval; + int c_retval; + xmlOutputBufferPtr buf; + PyObject *pyobj_buf; + xmlDocPtr cur; + PyObject *pyobj_cur; + char * encoding; + + if (!PyArg_ParseTuple(args, (char *)"OOz:xmlSaveFileTo", &pyobj_buf, &pyobj_cur, &encoding)) + return(NULL); + buf = (xmlOutputBufferPtr) PyoutputBuffer_Get(pyobj_buf); + cur = (xmlDocPtr) PyxmlNode_Get(pyobj_cur); + + c_retval = xmlSaveFileTo(buf, cur, encoding); + /* xmlSaveTo() freed the memory pointed to by buf, so record that in the + * Python object. */ + ((PyoutputBuffer_Object *)(pyobj_buf))->obj = NULL; + py_retval = libxml_intWrap((int) c_retval); + return(py_retval); +} + +static PyObject * +libxml_xmlSaveFormatFileTo(PyObject *self ATTRIBUTE_UNUSED, PyObject *args) { + PyObject *py_retval; + int c_retval; + xmlOutputBufferPtr buf; + PyObject *pyobj_buf; + xmlDocPtr cur; + PyObject *pyobj_cur; + char * encoding; + int format; + + if (!PyArg_ParseTuple(args, (char *)"OOzi:xmlSaveFormatFileTo", &pyobj_buf, &pyobj_cur, &encoding, &format)) + return(NULL); + buf = (xmlOutputBufferPtr) PyoutputBuffer_Get(pyobj_buf); + cur = (xmlDocPtr) PyxmlNode_Get(pyobj_cur); + + c_retval = xmlSaveFormatFileTo(buf, cur, encoding, format); + /* xmlSaveFormatFileTo() freed the memory pointed to by buf, so record that + * in the Python object */ + ((PyoutputBuffer_Object *)(pyobj_buf))->obj = NULL; + py_retval = libxml_intWrap((int) c_retval); + return(py_retval); +} #endif /* LIBXML_OUTPUT_ENABLED */ @@ -1375,34 +1427,24 @@ static PyObject *libxml_xmlPythonErrorFuncHandler = NULL; static PyObject *libxml_xmlPythonErrorFuncCtxt = NULL; /* helper to build a xmlMalloc'ed string from a format and va_list */ +/* + * disabled the loop, the repeated call to vsnprintf without reset of ap + * in case the initial buffer was too small segfaulted on x86_64 + * we now directly vsnprintf on a large buffer. + */ static char * libxml_buildMessage(const char *msg, va_list ap) { - int size; int chars; - char *larger; char *str; - str = (char *) xmlMalloc(150); + str = (char *) xmlMalloc(1000); if (str == NULL) return NULL; - size = 150; - - while (1) { - chars = vsnprintf(str, size, msg, ap); - if ((chars > -1) && (chars < size)) - break; - if (chars > -1) - size += chars + 1; - else - size += 100; - if ((larger = (char *) xmlRealloc(str, size)) == NULL) { - xmlFree(str); - return NULL; - } - str = larger; - } + chars = vsnprintf(str, 999, msg, ap); + if (chars >= 998) + str[999] = 0; return str; } @@ -1412,10 +1454,10 @@ libxml_xmlErrorFuncHandler(ATTRIBUTE_UNUSED void *ctx, const char *msg, ...) { va_list ap; - char *str; PyObject *list; PyObject *message; PyObject *result; + char str[1000]; #ifdef DEBUG_ERROR printf("libxml_xmlErrorFuncHandler(%p, %s, ...) called\n", ctx, msg); @@ -1428,13 +1470,14 @@ libxml_xmlErrorFuncHandler(ATTRIBUTE_UNUSED void *ctx, const char *msg, va_end(ap); } else { va_start(ap, msg); - str = libxml_buildMessage(msg,ap); + if (vsnprintf(str, 999, msg, ap) >= 998) + str[999] = 0; va_end(ap); list = PyTuple_New(2); PyTuple_SetItem(list, 0, libxml_xmlPythonErrorFuncCtxt); Py_XINCREF(libxml_xmlPythonErrorFuncCtxt); - message = libxml_charPtrWrap(str); + message = libxml_charPtrConstWrap(str); PyTuple_SetItem(list, 1, message); result = PyEval_CallObject(libxml_xmlPythonErrorFuncHandler, list); Py_XDECREF(list); @@ -3446,6 +3489,8 @@ static PyMethodDef libxmlMethods[] = { {(char *) "outputBufferGetPythonFile", libxml_outputBufferGetPythonFile, METH_VARARGS, NULL}, {(char *) "xmlOutputBufferClose", libxml_xmlOutputBufferClose, METH_VARARGS, NULL}, { (char *)"xmlOutputBufferFlush", libxml_xmlOutputBufferFlush, METH_VARARGS, NULL }, + { (char *)"xmlSaveFileTo", libxml_xmlSaveFileTo, METH_VARARGS, NULL }, + { (char *)"xmlSaveFormatFileTo", libxml_xmlSaveFormatFileTo, METH_VARARGS, NULL }, #endif /* LIBXML_OUTPUT_ENABLED */ {(char *) "inputBufferCreate", libxml_xmlCreateInputBuffer, METH_VARARGS, NULL}, {(char *) "setEntityLoader", libxml_xmlSetEntityLoader, METH_VARARGS, NULL}, |