Details

[Home]

Issue of the Implementation # S0752

Brief

Some functions from libxml2 print message "Document is empty" for any input data

Detailed Description

Functions xmlCtxtReadIO, xmlReadIO, htmlCtxtReadIO, htmlReadIO print message "Document is empty" independently from input data.

Problem location(s) in the standard

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

Example

#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;
}

Possible solutions

Analyze the source code to understand the reason of the error:
The message is printed in the following line:

parse.c:10008:
    if (CUR == 0) {
	xmlFatalErr(ctxt, XML_ERR_DOCUMENT_EMPTY, NULL);
    }
CUR is a macros and equals *ctxt->input->cur. The way of initializing of ctxt variable is:
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);
    }
}
So input data don't influence on the *ctxt->input->cur. And in any case the error message is printed.
Functions htmlCtxtReadIO, xmlReadIO, htmlReadIO have the same problem in the source code.

Component

libxml2 2.6.16 and later

[Home]