Подробности

[В начало]

Проблема в реализации № S0752

Краткое описание

Некоторые функции из libxml2 выдают сообщение о пустом документе на любых входных данных

Подробное описание

Функции xmlCtxtReadIO, xmlReadIO, htmlCtxtReadIO, htmlReadIO выдают сообщение "Пустой документ" на любых входных данных.

Раздел стандарта

http://xmlsoft.org/html/libxml-parser.html#xmlCtxtReadIO

Пример

#include <libxml2/libxml/parser.h>
#include <libxml2/libxml/parserInternals.h>

int xmlInputReadCallback_Function (void * context, char * buffer, int length ) {
	return 0;
}
int xmlInputCloseCallback_Function(void * context) {
	return 0;
}

int main()
{
   xmlCtxtReadIO(
       xmlCreateFileParserCtxt("test.xml"),  // this can be any xml file
       &xmlInputReadCallback_Function,
       &xmlInputCloseCallback_Function,
       NULL,
       "test.xml",
       NULL,
       0
   );

   return 0;
}

Способы устранения

Причину ошибки можно понять, проанализировав исходный код.
Сообщение выдается в следующей строке:

parse.c:10008:
    if (CUR == 0) {
	xmlFatalErr(ctxt, XML_ERR_DOCUMENT_EMPTY, NULL);
    }
При этом CUR - это макрос равный *ctxt->input->cur.
Путь создания и инициализации переменной ctxt следующий:
xmlBufferCreateSize()
{
...
tree.c:6687: ret->content[0] = 0;
...
return ret
}

xmlAllocParserInputBuffer{
...
xmlIO.c:2236: ret->buffer = xmlBufferCreateSize(). // *ret->buffer->content = 0;
...
return ret
}

xmlParserInputBufferCreateIO {
...
xmlIO.c:2900: ret = xmlAllocParserInputBuffer(enc); // *ret->buffer->content = 0;
...
return ret;
}

xmlCtxtReadIO {
...
parser.c:14608: input = xmlParserInputBufferCreateIO() // *input->buffer->content = 0;
...
parser.c:14612: stream = xmlNewIOInputStream(ctxt, input, XML_CHAR_ENCODING_NONE);
}

xmlNewIOInputStream {
...
parserInternals.c:1338: inputStream->buf = input;                        // *inputStream->buf->buffer->content = 0;
parserInternals.c:1340: inputStream->cur = inputStream->buf->buffer->content;  // *inputStream->cur = 0;
...
return inputStream;
}

xmlCtxtReadIO {
...
parser.c:14612: stream = xmlNewIOInputStream(ctxt, input, XML_CHAR_ENCODING_NONE); // *stream->cur = 0;
inputPush(ctxt, stream);
}

inputPush(ctxt, value) {  // value = stream
...
parser.c:1495:  ctxt->input = value;  // *ctxt->input->cur = 0;
...
}

xmlCtxtReadIO {
...
inputPush(ctxt, stream);
parser.c:14618: return (xmlDoRead(ctxt, URL, encoding, options, 1));
}

xmlDoRead() {
...
parse.c:10008:
    if (CUR == 0) {    // CUR = *ctxt->input->cur = 0;
	xmlFatalErr(ctxt, XML_ERR_DOCUMENT_EMPTY, NULL);
    }
}
Получается, что исходные данные никак не повлияли на значение поля *ctxt->input->cur. И в любом случае выдается сообщение об ошибке.
Для функций htmlCtxtReadIO, xmlReadIO, htmlReadIO ситуация аналогичная.

Компонент

libxml2 2.6.16 and later

[В начало]