/*
 * xinclude.c : Code to implement XInclude processing
 *
 * World Wide Web Consortium W3C Last Call Working Draft 10 November 2003
 * http://www.w3.org/TR/2003/WD-xinclude-20031110
 *
 * See Copyright for the status of this software.
 *
 * daniel@veillard.com
 */

#define IN_LIBXML
#include "libxml.h"

#include <string.h>
#include <libxml/xmlmemory.h>
#include <libxml/tree.h>
#include <libxml/parser.h>
#include <libxml/uri.h>
#include <libxml/xpath.h>
#include <libxml/xpointer.h>
#include <libxml/parserInternals.h>
#include <libxml/xmlerror.h>
#include <libxml/encoding.h>

#ifdef LIBXML_XINCLUDE_ENABLED
#include <libxml/xinclude.h>

#include "private/buf.h"
#include "private/error.h"
#include "private/tree.h"
#include "private/xinclude.h"

#define XINCLUDE_MAX_DEPTH 40

/************************************************************************
 *									*
 *			XInclude context handling			*
 *									*
 ************************************************************************/

/*
 * An XInclude context
 */
typedef xmlChar *xmlURL;

typedef struct _xmlXIncludeRef xmlXIncludeRef;
typedef xmlXIncludeRef *xmlXIncludeRefPtr;
struct _xmlXIncludeRef {
    xmlChar              *URI; /* the fully resolved resource URL */
    xmlChar         *fragment; /* the fragment in the URI */
    xmlChar             *base; /* base URI of xi:include element */
    xmlNodePtr           elem; /* the xi:include element */
    xmlNodePtr            inc; /* the included copy */
    int                   xml; /* xml or txt */
    int	             fallback; /* fallback was loaded */
    int		    expanding; /* flag to detect inclusion loops */
    int		      replace; /* should the node be replaced? */
};

typedef struct _xmlXIncludeDoc xmlXIncludeDoc;
typedef xmlXIncludeDoc *xmlXIncludeDocPtr;
struct _xmlXIncludeDoc {
    xmlDocPtr             doc; /* the parsed document */
    xmlChar              *url; /* the URL */
    int             expanding; /* flag to detect inclusion loops */
};

typedef struct _xmlXIncludeTxt xmlXIncludeTxt;
typedef xmlXIncludeTxt *xmlXIncludeTxtPtr;
struct _xmlXIncludeTxt {
    xmlChar		*text; /* text string */
    xmlChar              *url; /* the URL */
};

struct _xmlXIncludeCtxt {
    xmlDocPtr             doc; /* the source document */
    int                 incNr; /* number of includes */
    int                incMax; /* size of includes tab */
    xmlXIncludeRefPtr *incTab; /* array of included references */

    int                 txtNr; /* number of unparsed documents */
    int                txtMax; /* size of unparsed documents tab */
    xmlXIncludeTxt    *txtTab; /* array of unparsed documents */

    int                 urlNr; /* number of documents stacked */
    int                urlMax; /* size of document stack */
    xmlXIncludeDoc    *urlTab; /* document stack */

    int              nbErrors; /* the number of errors detected */
    int              fatalErr; /* abort processing */
    int                 errNo; /* error code */
    int                legacy; /* using XINCLUDE_OLD_NS */
    int            parseFlags; /* the flags used for parsing XML documents */

    void            *_private; /* application data */

#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
    unsigned long    incTotal; /* total number of processed inclusions */
#endif
    int			depth; /* recursion depth */
    int		     isStream; /* streaming mode */

    xmlXPathContextPtr xpctxt;

    xmlStructuredErrorFunc errorHandler;
    void *errorCtxt;
};

static xmlXIncludeRefPtr
xmlXIncludeExpandNode(xmlXIncludeCtxtPtr ctxt, xmlNodePtr node);

static int
xmlXIncludeLoadNode(xmlXIncludeCtxtPtr ctxt, xmlXIncludeRefPtr ref);

static int
xmlXIncludeDoProcess(xmlXIncludeCtxtPtr ctxt, xmlNodePtr tree);


/************************************************************************
 *									*
 *			XInclude error handler				*
 *									*
 ************************************************************************/

/**
 * xmlXIncludeErrMemory:
 * @extra:  extra information
 *
 * Handle an out of memory condition
 */
static void
xmlXIncludeErrMemory(xmlXIncludeCtxtPtr ctxt)
{
    ctxt->errNo = XML_ERR_NO_MEMORY;
    ctxt->fatalErr = 1;
    ctxt->nbErrors++;

    xmlRaiseMemoryError(ctxt->errorHandler, NULL, ctxt->errorCtxt,
                        XML_FROM_XINCLUDE, NULL);
}

/**
 * xmlXIncludeErr:
 * @ctxt: the XInclude context
 * @node: the context node
 * @msg:  the error message
 * @extra:  extra information
 *
 * Handle an XInclude error
 */
static void LIBXML_ATTR_FORMAT(4,0)
xmlXIncludeErr(xmlXIncludeCtxtPtr ctxt, xmlNodePtr node, int error,
               const char *msg, const xmlChar *extra)
{
    xmlStructuredErrorFunc schannel = NULL;
    xmlGenericErrorFunc channel = NULL;
    void *data = NULL;
    int res;

    if (ctxt->fatalErr != 0)
        return;
    ctxt->nbErrors++;

    schannel = ctxt->errorHandler;
    data = ctxt->errorCtxt;

    if (schannel == NULL) {
        channel = xmlGenericError;
        data = xmlGenericErrorContext;
    }

    res = __xmlRaiseError(schannel, channel, data, ctxt, node,
                          XML_FROM_XINCLUDE, error, XML_ERR_ERROR,
                          NULL, 0, (const char *) extra, NULL, NULL, 0, 0,
		          msg, (const char *) extra);
    if (res < 0) {
        ctxt->errNo = XML_ERR_NO_MEMORY;
        ctxt->fatalErr = 1;
    } else {
        ctxt->errNo = error;
    }
}

/**
 * xmlXIncludeGetProp:
 * @ctxt:  the XInclude context
 * @cur:  the node
 * @name:  the attribute name
 *
 * Get an XInclude attribute
 *
 * Returns the value (to be freed) or NULL if not found
 */
static xmlChar *
xmlXIncludeGetProp(xmlXIncludeCtxtPtr ctxt, xmlNodePtr cur,
                   const xmlChar *name) {
    xmlChar *ret;

    if (xmlNodeGetAttrValue(cur, name, XINCLUDE_NS, &ret) < 0)
        xmlXIncludeErrMemory(ctxt);
    if (ret != NULL)
        return(ret);

    if (ctxt->legacy != 0) {
        if (xmlNodeGetAttrValue(cur, name, XINCLUDE_OLD_NS, &ret) < 0)
            xmlXIncludeErrMemory(ctxt);
        if (ret != NULL)
            return(ret);
    }

    if (xmlNodeGetAttrValue(cur, name, NULL, &ret) < 0)
        xmlXIncludeErrMemory(ctxt);
    return(ret);
}
/**
 * xmlXIncludeFreeRef:
 * @ref: the XInclude reference
 *
 * Free an XInclude reference
 */
static void
xmlXIncludeFreeRef(xmlXIncludeRefPtr ref) {
    if (ref == NULL)
	return;
    if (ref->URI != NULL)
	xmlFree(ref->URI);
    if (ref->fragment != NULL)
	xmlFree(ref->fragment);
    if (ref->base != NULL)
	xmlFree(ref->base);
    xmlFree(ref);
}

/**
 * xmlXIncludeNewContext:
 * @doc:  an XML Document
 *
 * Creates a new XInclude context
 *
 * Returns the new set
 */
xmlXIncludeCtxtPtr
xmlXIncludeNewContext(xmlDocPtr doc) {
    xmlXIncludeCtxtPtr ret;

    if (doc == NULL)
	return(NULL);
    ret = (xmlXIncludeCtxtPtr) xmlMalloc(sizeof(xmlXIncludeCtxt));
    if (ret == NULL)
	return(NULL);
    memset(ret, 0, sizeof(xmlXIncludeCtxt));
    ret->doc = doc;
    ret->incNr = 0;
    ret->incMax = 0;
    ret->incTab = NULL;
    ret->nbErrors = 0;
    return(ret);
}

/**
 * xmlXIncludeFreeContext:
 * @ctxt: the XInclude context
 *
 * Free an XInclude context
 */
void
xmlXIncludeFreeContext(xmlXIncludeCtxtPtr ctxt) {
    int i;

    if (ctxt == NULL)
	return;
    if (ctxt->urlTab != NULL) {
	for (i = 0; i < ctxt->urlNr; i++) {
	    xmlFreeDoc(ctxt->urlTab[i].doc);
	    xmlFree(ctxt->urlTab[i].url);
	}
	xmlFree(ctxt->urlTab);
    }
    for (i = 0;i < ctxt->incNr;i++) {
	if (ctxt->incTab[i] != NULL)
	    xmlXIncludeFreeRef(ctxt->incTab[i]);
    }
    if (ctxt->incTab != NULL)
	xmlFree(ctxt->incTab);
    if (ctxt->txtTab != NULL) {
	for (i = 0;i < ctxt->txtNr;i++) {
	    xmlFree(ctxt->txtTab[i].text);
	    xmlFree(ctxt->txtTab[i].url);
	}
	xmlFree(ctxt->txtTab);
    }
    if (ctxt->xpctxt != NULL)
	xmlXPathFreeContext(ctxt->xpctxt);
    xmlFree(ctxt);
}

/**
 * xmlXIncludeParseFile:
 * @ctxt:  the XInclude context
 * @URL:  the URL or file path
 *
 * parse a document for XInclude
 */
static xmlDocPtr
xmlXIncludeParseFile(xmlXIncludeCtxtPtr ctxt, const char *URL) {
    xmlDocPtr ret = NULL;
    xmlParserCtxtPtr pctxt;
    xmlParserInputPtr inputStream;

    xmlInitParser();

    pctxt = xmlNewParserCtxt();
    if (pctxt == NULL) {
	xmlXIncludeErrMemory(ctxt);
	return(NULL);
    }
    if (ctxt->errorHandler != NULL)
        xmlCtxtSetErrorHandler(pctxt, ctxt->errorHandler, ctxt->errorCtxt);

    /*
     * pass in the application data to the parser context.
     */
    pctxt->_private = ctxt->_private;

    /*
     * try to ensure that new documents included are actually
     * built with the same dictionary as the including document.
     */
    if ((ctxt->doc != NULL) && (ctxt->doc->dict != NULL)) {
       if (pctxt->dict != NULL)
            xmlDictFree(pctxt->dict);
	pctxt->dict = ctxt->doc->dict;
	xmlDictReference(pctxt->dict);
    }

    xmlCtxtUseOptions(pctxt, ctxt->parseFlags);

    inputStream = xmlLoadExternalEntity(URL, NULL, pctxt);
    if (inputStream == NULL)
        goto error;

    inputPush(pctxt, inputStream);

    xmlParseDocument(pctxt);

    if (pctxt->wellFormed) {
        ret = pctxt->myDoc;
    }
    else {
        ret = NULL;
	if (pctxt->myDoc != NULL)
	    xmlFreeDoc(pctxt->myDoc);
        pctxt->myDoc = NULL;
    }

error:
    if (pctxt->errNo == XML_ERR_NO_MEMORY)
        xmlXIncludeErrMemory(ctxt);
    xmlFreeParserCtxt(pctxt);

    return(ret);
}

/**
 * xmlXIncludeAddNode:
 * @ctxt:  the XInclude context
 * @cur:  the new node
 *
 * Add a new node to process to an XInclude context
 */
static xmlXIncludeRefPtr
xmlXIncludeAddNode(xmlXIncludeCtxtPtr ctxt, xmlNodePtr cur) {
    xmlXIncludeRefPtr ref = NULL;
    xmlXIncludeRefPtr ret = NULL;
    xmlURIPtr uri = NULL;
    xmlChar *href = NULL;
    xmlChar *parse = NULL;
    xmlChar *fragment = NULL;
    xmlChar *base = NULL;
    xmlChar *tmp;
    int xml = 1;
    int local = 0;
    int res;

    if (ctxt == NULL)
	return(NULL);
    if (cur == NULL)
	return(NULL);

    /*
     * read the attributes
     */

    fragment = xmlXIncludeGetProp(ctxt, cur, XINCLUDE_PARSE_XPOINTER);

    href = xmlXIncludeGetProp(ctxt, cur, XINCLUDE_HREF);
    if (href == NULL) {
        if (fragment == NULL) {
	    xmlXIncludeErr(ctxt, cur, XML_XINCLUDE_NO_HREF,
	                   "href or xpointer must be present\n", parse);
	    goto error;
        }

	href = xmlStrdup(BAD_CAST ""); /* @@@@ href is now optional */
	if (href == NULL) {
            xmlXIncludeErrMemory(ctxt);
	    goto error;
        }
    }

    parse = xmlXIncludeGetProp(ctxt, cur, XINCLUDE_PARSE);
    if (parse != NULL) {
	if (xmlStrEqual(parse, XINCLUDE_PARSE_XML))
	    xml = 1;
	else if (xmlStrEqual(parse, XINCLUDE_PARSE_TEXT))
	    xml = 0;
	else {
	    xmlXIncludeErr(ctxt, cur, XML_XINCLUDE_PARSE_VALUE,
	                   "invalid value %s for 'parse'\n", parse);
	    goto error;
	}
    }

    /*
     * Check the URL and remove any fragment identifier
     */
    res = xmlParseURISafe((const char *)href, &uri);
    if (uri == NULL) {
        if (res < 0)
            xmlXIncludeErrMemory(ctxt);
        else
            xmlXIncludeErr(ctxt, cur, XML_XINCLUDE_HREF_URI,
                           "invalid value href %s\n", href);
        goto error;
    }

    if (uri->fragment != NULL) {
        if (ctxt->legacy != 0) {
	    if (fragment == NULL) {
		fragment = (xmlChar *) uri->fragment;
	    } else {
		xmlFree(uri->fragment);
	    }
	} else {
	    xmlXIncludeErr(ctxt, cur, XML_XINCLUDE_FRAGMENT_ID,
       "Invalid fragment identifier in URI %s use the xpointer attribute\n",
                           href);
	    goto error;
	}
	uri->fragment = NULL;
    }
    tmp = xmlSaveUri(uri);
    if (tmp == NULL) {
	xmlXIncludeErrMemory(ctxt);
	goto error;
    }
    xmlFree(href);
    href = tmp;

    /*
     * Resolve URI
     */

    if (xmlNodeGetBaseSafe(ctxt->doc, cur, &base) < 0) {
        xmlXIncludeErrMemory(ctxt);
        goto error;
    }

    if (href[0] != 0) {
        if (xmlBuildURISafe(href, base, &tmp) < 0) {
            xmlXIncludeErrMemory(ctxt);
            goto error;
        }
        if (tmp == NULL) {
            xmlXIncludeErr(ctxt, cur, XML_XINCLUDE_HREF_URI,
                           "failed build URL\n", NULL);
            goto error;
        }
        xmlFree(href);
        href = tmp;

        if (xmlStrEqual(href, ctxt->doc->URL))
            local = 1;
    } else {
        local = 1;
    }

    /*
     * If local and xml then we need a fragment
     */
    if ((local == 1) && (xml == 1) &&
        ((fragment == NULL) || (fragment[0] == 0))) {
	xmlXIncludeErr(ctxt, cur, XML_XINCLUDE_RECURSION,
	               "detected a local recursion with no xpointer in %s\n",
		       href);
	goto error;
    }

    ref = (xmlXIncludeRefPtr) xmlMalloc(sizeof(xmlXIncludeRef));
    if (ref == NULL) {
        xmlXIncludeErrMemory(ctxt);
        goto error;
    }
    memset(ref, 0, sizeof(xmlXIncludeRef));

    ref->elem = cur;
    ref->xml = xml;
    ref->URI = href;
    href = NULL;
    ref->fragment = fragment;
    fragment = NULL;

    /*
     * xml:base fixup
     */
    if (((ctxt->parseFlags & XML_PARSE_NOBASEFIX) == 0) &&
        (cur->doc != NULL) &&
        ((cur->doc->parseFlags & XML_PARSE_NOBASEFIX) == 0)) {
        if (base != NULL) {
            ref->base = base;
            base = NULL;
        } else {
            ref->base = xmlStrdup(BAD_CAST "");
            if (ref->base == NULL) {
	        xmlXIncludeErrMemory(ctxt);
                goto error;
            }
        }
    }

    if (ctxt->incNr >= ctxt->incMax) {
        xmlXIncludeRefPtr *table;
#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
        size_t newSize = ctxt->incMax ? ctxt->incMax * 2 : 1;
#else
        size_t newSize = ctxt->incMax ? ctxt->incMax * 2 : 4;
#endif

        table = (xmlXIncludeRefPtr *) xmlRealloc(ctxt->incTab,
	             newSize * sizeof(ctxt->incTab[0]));
        if (table == NULL) {
	    xmlXIncludeErrMemory(ctxt);
	    goto error;
	}
        ctxt->incTab = table;
        ctxt->incMax = newSize;
    }
    ctxt->incTab[ctxt->incNr++] = ref;

    ret = ref;
    ref = NULL;

error:
    xmlXIncludeFreeRef(ref);
    xmlFreeURI(uri);
    xmlFree(href);
    xmlFree(parse);
    xmlFree(fragment);
    xmlFree(base);
    return(ret);
}

/**
 * xmlXIncludeRecurseDoc:
 * @ctxt:  the XInclude context
 * @doc:  the new document
 * @url:  the associated URL
 *
 * The XInclude recursive nature is handled at this point.
 */
static void
xmlXIncludeRecurseDoc(xmlXIncludeCtxtPtr ctxt, xmlDocPtr doc) {
    xmlDocPtr oldDoc;
    xmlXIncludeRefPtr *oldIncTab;
    int oldIncMax, oldIncNr, oldIsStream;
    int i;

    oldDoc = ctxt->doc;
    oldIncMax = ctxt->incMax;
    oldIncNr = ctxt->incNr;
    oldIncTab = ctxt->incTab;
    oldIsStream = ctxt->isStream;
    ctxt->doc = doc;
    ctxt->incMax = 0;
    ctxt->incNr = 0;
    ctxt->incTab = NULL;
    ctxt->isStream = 0;

    xmlXIncludeDoProcess(ctxt, xmlDocGetRootElement(doc));

    if (ctxt->incTab != NULL) {
        for (i = 0; i < ctxt->incNr; i++)
            xmlXIncludeFreeRef(ctxt->incTab[i]);
        xmlFree(ctxt->incTab);
    }

    ctxt->doc = oldDoc;
    ctxt->incMax = oldIncMax;
    ctxt->incNr = oldIncNr;
    ctxt->incTab = oldIncTab;
    ctxt->isStream = oldIsStream;
}

/************************************************************************
 *									*
 *			Node copy with specific semantic		*
 *									*
 ************************************************************************/

static void
xmlXIncludeBaseFixup(xmlXIncludeCtxtPtr ctxt, xmlNodePtr cur, xmlNodePtr copy,
                     const xmlChar *targetBase) {
    xmlChar *base = NULL;
    xmlChar *relBase = NULL;
    xmlNs ns;
    int res;

    if (cur->type != XML_ELEMENT_NODE)
        return;

    if (xmlNodeGetBaseSafe(cur->doc, cur, &base) < 0)
        xmlXIncludeErrMemory(ctxt);

    if ((base != NULL) && !xmlStrEqual(base, targetBase)) {
        if (xmlBuildRelativeURISafe(base, targetBase, &relBase) < 0) {
            xmlXIncludeErrMemory(ctxt);
            goto done;
        }
        if (relBase == NULL) {
            xmlXIncludeErr(ctxt, cur,
                    XML_XINCLUDE_HREF_URI,
                    "Building relative URI failed: %s\n",
                    base);
            goto done;
        }

        /*
         * If the new base doesn't contain a slash, it can be omitted.
         */
        if (xmlStrchr(relBase, '/') != NULL) {
            res = xmlNodeSetBase(copy, relBase);
            if (res < 0)
                xmlXIncludeErrMemory(ctxt);
            goto done;
        }
    }

    /*
     * Delete existing xml:base if bases are equal
     */
    memset(&ns, 0, sizeof(ns));
    ns.href = XML_XML_NAMESPACE;
    xmlUnsetNsProp(copy, &ns, BAD_CAST "base");

done:
    xmlFree(base);
    xmlFree(relBase);
}

/**
 * xmlXIncludeCopyNode:
 * @ctxt:  the XInclude context
 * @elem:  the element
 * @copyChildren:  copy children instead of node if true
 *
 * Make a copy of the node while expanding nested XIncludes.
 *
 * Returns a node list, not a single node.
 */
static xmlNodePtr
xmlXIncludeCopyNode(xmlXIncludeCtxtPtr ctxt, xmlNodePtr elem,
                    int copyChildren, const xmlChar *targetBase) {
    xmlNodePtr result = NULL;
    xmlNodePtr insertParent = NULL;
    xmlNodePtr insertLast = NULL;
    xmlNodePtr cur;
    xmlNodePtr item;
    int depth = 0;

    if (copyChildren) {
        cur = elem->children;
        if (cur == NULL)
            return(NULL);
    } else {
        cur = elem;
    }

    while (1) {
        xmlNodePtr copy = NULL;
        int recurse = 0;

        if ((cur->type == XML_DOCUMENT_NODE) ||
            (cur->type == XML_DTD_NODE)) {
            ;
        } else if ((cur->type == XML_ELEMENT_NODE) &&
                   (cur->ns != NULL) &&
                   (xmlStrEqual(cur->name, XINCLUDE_NODE)) &&
                   ((xmlStrEqual(cur->ns->href, XINCLUDE_NS)) ||
                    (xmlStrEqual(cur->ns->href, XINCLUDE_OLD_NS)))) {
            xmlXIncludeRefPtr ref = xmlXIncludeExpandNode(ctxt, cur);

            if (ref == NULL)
                goto error;
            /*
             * TODO: Insert XML_XINCLUDE_START and XML_XINCLUDE_END nodes
             */
            for (item = ref->inc; item != NULL; item = item->next) {
                copy = xmlStaticCopyNode(item, ctxt->doc, insertParent, 1);
                if (copy == NULL) {
                    xmlXIncludeErrMemory(ctxt);
                    goto error;
                }

                if (result == NULL)
                    result = copy;
                if (insertLast != NULL) {
                    insertLast->next = copy;
                    copy->prev = insertLast;
                } else if (insertParent != NULL) {
                    insertParent->children = copy;
                }
                insertLast = copy;

                if ((depth == 0) && (targetBase != NULL))
                    xmlXIncludeBaseFixup(ctxt, item, copy, targetBase);
            }
        } else {
            copy = xmlStaticCopyNode(cur, ctxt->doc, insertParent, 2);
            if (copy == NULL) {
                xmlXIncludeErrMemory(ctxt);
                goto error;
            }

            if (result == NULL)
                result = copy;
            if (insertLast != NULL) {
                insertLast->next = copy;
                copy->prev = insertLast;
            } else if (insertParent != NULL) {
                insertParent->children = copy;
            }
            insertLast = copy;

            if ((depth == 0) && (targetBase != NULL))
                xmlXIncludeBaseFixup(ctxt, cur, copy, targetBase);

            recurse = (cur->type != XML_ENTITY_REF_NODE) &&
                      (cur->children != NULL);
        }

        if (recurse) {
            cur = cur->children;
            insertParent = insertLast;
            insertLast = NULL;
            depth += 1;
            continue;
        }

        if (cur == elem)
            return(result);

        while (cur->next == NULL) {
            if (insertParent != NULL)
                insertParent->last = insertLast;
            cur = cur->parent;
            if (cur == elem)
                return(result);
            insertLast = insertParent;
            insertParent = insertParent->parent;
            depth -= 1;
        }

        cur = cur->next;
    }

error:
    xmlFreeNodeList(result);
    return(NULL);
}

#ifdef LIBXML_XPTR_LOCS_ENABLED
/**
 * xmlXIncludeGetNthChild:
 * @cur:  the node
 * @no:  the child number
 *
 * Returns the @n'th element child of @cur or NULL
 */
static xmlNodePtr
xmlXIncludeGetNthChild(xmlNodePtr cur, int no) {
    int i;
    if ((cur == NULL) || (cur->type == XML_NAMESPACE_DECL))
        return(NULL);
    cur = cur->children;
    for (i = 0;i <= no;cur = cur->next) {
	if (cur == NULL)
	    return(cur);
	if ((cur->type == XML_ELEMENT_NODE) ||
	    (cur->type == XML_DOCUMENT_NODE) ||
	    (cur->type == XML_HTML_DOCUMENT_NODE)) {
	    i++;
	    if (i == no)
		break;
	}
    }
    return(cur);
}

xmlNodePtr xmlXPtrAdvanceNode(xmlNodePtr cur, int *level); /* in xpointer.c */
/**
 * xmlXIncludeCopyRange:
 * @ctxt:  the XInclude context
 * @obj:  the XPointer result from the evaluation.
 *
 * Build a node list tree copy of the XPointer result.
 *
 * Returns an xmlNodePtr list or NULL.
 *         The caller has to free the node tree.
 */
static xmlNodePtr
xmlXIncludeCopyRange(xmlXIncludeCtxtPtr ctxt, xmlXPathObjectPtr range) {
    /* pointers to generated nodes */
    xmlNodePtr list = NULL, last = NULL, listParent = NULL;
    xmlNodePtr tmp, tmp2;
    /* pointers to traversal nodes */
    xmlNodePtr start, cur, end;
    int index1, index2;
    int level = 0, lastLevel = 0, endLevel = 0, endFlag = 0;

    if ((ctxt == NULL) || (range == NULL))
	return(NULL);
    if (range->type != XPATH_RANGE)
	return(NULL);
    start = (xmlNodePtr) range->user;

    if ((start == NULL) || (start->type == XML_NAMESPACE_DECL))
	return(NULL);
    end = range->user2;
    if (end == NULL)
	return(xmlDocCopyNode(start, ctxt->doc, 1));
    if (end->type == XML_NAMESPACE_DECL)
        return(NULL);

    cur = start;
    index1 = range->index;
    index2 = range->index2;
    /*
     * level is depth of the current node under consideration
     * list is the pointer to the root of the output tree
     * listParent is a pointer to the parent of output tree (within
       the included file) in case we need to add another level
     * last is a pointer to the last node added to the output tree
     * lastLevel is the depth of last (relative to the root)
     */
    while (cur != NULL) {
	/*
	 * Check if our output tree needs a parent
	 */
	if (level < 0) {
	    while (level < 0) {
	        /* copy must include namespaces and properties */
	        tmp2 = xmlDocCopyNode(listParent, ctxt->doc, 2);
	        xmlAddChild(tmp2, list);
	        list = tmp2;
	        listParent = listParent->parent;
	        level++;
	    }
	    last = list;
	    lastLevel = 0;
	}
	/*
	 * Check whether we need to change our insertion point
	 */
	while (level < lastLevel) {
	    last = last->parent;
	    lastLevel --;
	}
	if (cur == end) {	/* Are we at the end of the range? */
	    if (cur->type == XML_TEXT_NODE) {
		const xmlChar *content = cur->content;
		int len;

		if (content == NULL) {
		    tmp = xmlNewDocTextLen(ctxt->doc, NULL, 0);
		} else {
		    len = index2;
		    if ((cur == start) && (index1 > 1)) {
			content += (index1 - 1);
			len -= (index1 - 1);
		    } else {
			len = index2;
		    }
		    tmp = xmlNewDocTextLen(ctxt->doc, content, len);
		}
		/* single sub text node selection */
		if (list == NULL)
		    return(tmp);
		/* prune and return full set */
		if (level == lastLevel)
		    xmlAddNextSibling(last, tmp);
		else
		    xmlAddChild(last, tmp);
		return(list);
	    } else {	/* ending node not a text node */
	        endLevel = level;	/* remember the level of the end node */
		endFlag = 1;
		/* last node - need to take care of properties + namespaces */
		tmp = xmlDocCopyNode(cur, ctxt->doc, 2);
		if (list == NULL) {
		    list = tmp;
		    listParent = cur->parent;
		    last = tmp;
		} else {
		    if (level == lastLevel)
			last = xmlAddNextSibling(last, tmp);
		    else {
			last = xmlAddChild(last, tmp);
			lastLevel = level;
		    }
		}

		if (index2 > 1) {
		    end = xmlXIncludeGetNthChild(cur, index2 - 1);
		    index2 = 0;
		}
		if ((cur == start) && (index1 > 1)) {
		    cur = xmlXIncludeGetNthChild(cur, index1 - 1);
		    index1 = 0;
		}  else {
		    cur = cur->children;
		}
		level++;	/* increment level to show change */
		/*
		 * Now gather the remaining nodes from cur to end
		 */
		continue;	/* while */
	    }
	} else if (cur == start) {	/* Not at the end, are we at start? */
	    if ((cur->type == XML_TEXT_NODE) ||
		(cur->type == XML_CDATA_SECTION_NODE)) {
		const xmlChar *content = cur->content;

		if (content == NULL) {
		    tmp = xmlNewDocTextLen(ctxt->doc, NULL, 0);
		} else {
		    if (index1 > 1) {
			content += (index1 - 1);
			index1 = 0;
		    }
		    tmp = xmlNewDocText(ctxt->doc, content);
		}
		last = list = tmp;
		listParent = cur->parent;
	    } else {		/* Not text node */
	        /*
		 * start of the range - need to take care of
		 * properties and namespaces
		 */
		tmp = xmlDocCopyNode(cur, ctxt->doc, 2);
		list = last = tmp;
		listParent = cur->parent;
		if (index1 > 1) {	/* Do we need to position? */
		    cur = xmlXIncludeGetNthChild(cur, index1 - 1);
		    level = lastLevel = 1;
		    index1 = 0;
		    /*
		     * Now gather the remaining nodes from cur to end
		     */
		    continue; /* while */
		}
	    }
	} else {
	    tmp = NULL;
	    switch (cur->type) {
		case XML_DTD_NODE:
		case XML_ELEMENT_DECL:
		case XML_ATTRIBUTE_DECL:
		case XML_ENTITY_NODE:
		    /* Do not copy DTD information */
		    break;
		case XML_ENTITY_DECL:
		    /* handle crossing entities -> stack needed */
		    break;
		case XML_XINCLUDE_START:
		case XML_XINCLUDE_END:
		    /* don't consider it part of the tree content */
		    break;
		case XML_ATTRIBUTE_NODE:
		    /* Humm, should not happen ! */
		    break;
		default:
		    /*
		     * Middle of the range - need to take care of
		     * properties and namespaces
		     */
		    tmp = xmlDocCopyNode(cur, ctxt->doc, 2);
		    break;
	    }
	    if (tmp != NULL) {
		if (level == lastLevel)
		    last = xmlAddNextSibling(last, tmp);
		else {
		    last = xmlAddChild(last, tmp);
		    lastLevel = level;
		}
	    }
	}
	/*
	 * Skip to next node in document order
	 */
	cur = xmlXPtrAdvanceNode(cur, &level);
	if (endFlag && (level >= endLevel))
	    break;
    }
    return(list);
}
#endif /* LIBXML_XPTR_LOCS_ENABLED */

/**
 * xmlXIncludeCopyXPointer:
 * @ctxt:  the XInclude context
 * @obj:  the XPointer result from the evaluation.
 *
 * Build a node list tree copy of the XPointer result.
 * This will drop Attributes and Namespace declarations.
 *
 * Returns an xmlNodePtr list or NULL.
 *         the caller has to free the node tree.
 */
static xmlNodePtr
xmlXIncludeCopyXPointer(xmlXIncludeCtxtPtr ctxt, xmlXPathObjectPtr obj,
                        const xmlChar *targetBase) {
    xmlNodePtr list = NULL, last = NULL, copy;
    int i;

    if ((ctxt == NULL) || (obj == NULL))
	return(NULL);
    switch (obj->type) {
        case XPATH_NODESET: {
	    xmlNodeSetPtr set = obj->nodesetval;
	    if (set == NULL)
		break;
	    for (i = 0;i < set->nodeNr;i++) {
                xmlNodePtr node;

		if (set->nodeTab[i] == NULL)
		    continue;
		switch (set->nodeTab[i]->type) {
		    case XML_DOCUMENT_NODE:
		    case XML_HTML_DOCUMENT_NODE:
                        node = xmlDocGetRootElement(
                                (xmlDocPtr) set->nodeTab[i]);
                        if (node == NULL) {
                            xmlXIncludeErr(ctxt, set->nodeTab[i],
                                           XML_ERR_INTERNAL_ERROR,
                                          "document without root\n", NULL);
                            continue;
                        }
                        break;
                    case XML_TEXT_NODE:
		    case XML_CDATA_SECTION_NODE:
		    case XML_ELEMENT_NODE:
		    case XML_PI_NODE:
		    case XML_COMMENT_NODE:
                        node = set->nodeTab[i];
			break;
                    default:
                        xmlXIncludeErr(ctxt, set->nodeTab[i],
                                       XML_XINCLUDE_XPTR_RESULT,
                                       "invalid node type in XPtr result\n",
                                       NULL);
			continue; /* for */
		}
                /*
                 * OPTIMIZE TODO: External documents should already be
                 * expanded, so xmlDocCopyNode should work as well.
                 * xmlXIncludeCopyNode is only required for the initial
                 * document.
                 */
		copy = xmlXIncludeCopyNode(ctxt, node, 0, targetBase);
                if (copy == NULL) {
                    xmlFreeNodeList(list);
                    return(NULL);
                }
		if (last == NULL) {
                    list = copy;
                } else {
                    while (last->next != NULL)
                        last = last->next;
                    copy->prev = last;
                    last->next = copy;
		}
                last = copy;
	    }
	    break;
	}
#ifdef LIBXML_XPTR_LOCS_ENABLED
	case XPATH_LOCATIONSET: {
	    xmlLocationSetPtr set = (xmlLocationSetPtr) obj->user;
	    if (set == NULL)
		return(NULL);
	    for (i = 0;i < set->locNr;i++) {
		if (last == NULL)
		    list = last = xmlXIncludeCopyXPointer(ctxt,
			                                  set->locTab[i],
                                                          targetBase);
		else
		    xmlAddNextSibling(last,
			    xmlXIncludeCopyXPointer(ctxt, set->locTab[i],
                                                    targetBase));
		if (last != NULL) {
		    while (last->next != NULL)
			last = last->next;
		}
	    }
	    break;
	}
	case XPATH_RANGE:
	    return(xmlXIncludeCopyRange(ctxt, obj));
	case XPATH_POINT:
	    /* points are ignored in XInclude */
	    break;
#endif
	default:
	    break;
    }
    return(list);
}
/************************************************************************
 *									*
 *			XInclude I/O handling				*
 *									*
 ************************************************************************/

typedef struct _xmlXIncludeMergeData xmlXIncludeMergeData;
typedef xmlXIncludeMergeData *xmlXIncludeMergeDataPtr;
struct _xmlXIncludeMergeData {
    xmlDocPtr doc;
    xmlXIncludeCtxtPtr ctxt;
};

/**
 * xmlXIncludeMergeOneEntity:
 * @ent: the entity
 * @doc:  the including doc
 * @name: the entity name
 *
 * Implements the merge of one entity
 */
static void
xmlXIncludeMergeEntity(void *payload, void *vdata,
	               const xmlChar *name ATTRIBUTE_UNUSED) {
    xmlEntityPtr ent = (xmlEntityPtr) payload;
    xmlXIncludeMergeDataPtr data = (xmlXIncludeMergeDataPtr) vdata;
    xmlEntityPtr ret, prev;
    xmlDocPtr doc;
    xmlXIncludeCtxtPtr ctxt;

    if ((ent == NULL) || (data == NULL))
	return;
    ctxt = data->ctxt;
    doc = data->doc;
    if ((ctxt == NULL) || (doc == NULL))
	return;
    switch (ent->etype) {
        case XML_INTERNAL_PARAMETER_ENTITY:
        case XML_EXTERNAL_PARAMETER_ENTITY:
        case XML_INTERNAL_PREDEFINED_ENTITY:
	    return;
        case XML_INTERNAL_GENERAL_ENTITY:
        case XML_EXTERNAL_GENERAL_PARSED_ENTITY:
        case XML_EXTERNAL_GENERAL_UNPARSED_ENTITY:
	    break;
    }
    prev = xmlGetDocEntity(doc, ent->name);
    if (prev == NULL) {
        ret = xmlAddDocEntity(doc, ent->name, ent->etype, ent->ExternalID,
                              ent->SystemID, ent->content);
        if (ret == NULL) {
            xmlXIncludeErrMemory(ctxt);
            return;
        }
	if (ent->URI != NULL) {
	    ret->URI = xmlStrdup(ent->URI);
            if (ret->URI == 0)
                xmlXIncludeErrMemory(ctxt);
        }
    } else {
        if (ent->etype != prev->etype)
            goto error;

        if ((ent->SystemID != NULL) && (prev->SystemID != NULL)) {
            if (!xmlStrEqual(ent->SystemID, prev->SystemID))
                goto error;
        } else if ((ent->ExternalID != NULL) &&
                   (prev->ExternalID != NULL)) {
            if (!xmlStrEqual(ent->ExternalID, prev->ExternalID))
                goto error;
        } else if ((ent->content != NULL) && (prev->content != NULL)) {
            if (!xmlStrEqual(ent->content, prev->content))
                goto error;
        } else {
            goto error;
        }
    }
    return;
error:
    switch (ent->etype) {
        case XML_INTERNAL_PARAMETER_ENTITY:
        case XML_EXTERNAL_PARAMETER_ENTITY:
        case XML_INTERNAL_PREDEFINED_ENTITY:
        case XML_INTERNAL_GENERAL_ENTITY:
        case XML_EXTERNAL_GENERAL_PARSED_ENTITY:
	    return;
        case XML_EXTERNAL_GENERAL_UNPARSED_ENTITY:
	    break;
    }
    xmlXIncludeErr(ctxt, (xmlNodePtr) ent, XML_XINCLUDE_ENTITY_DEF_MISMATCH,
                   "mismatch in redefinition of entity %s\n",
		   ent->name);
}

/**
 * xmlXIncludeMergeEntities:
 * @ctxt: an XInclude context
 * @doc:  the including doc
 * @from:  the included doc
 *
 * Implements the entity merge
 *
 * Returns 0 if merge succeeded, -1 if some processing failed
 */
static int
xmlXIncludeMergeEntities(xmlXIncludeCtxtPtr ctxt, xmlDocPtr doc,
	                 xmlDocPtr from) {
    xmlNodePtr cur;
    xmlDtdPtr target, source;

    if (ctxt == NULL)
	return(-1);

    if ((from == NULL) || (from->intSubset == NULL))
	return(0);

    target = doc->intSubset;
    if (target == NULL) {
	cur = xmlDocGetRootElement(doc);
	if (cur == NULL)
	    return(-1);
        target = xmlCreateIntSubset(doc, cur->name, NULL, NULL);
	if (target == NULL) {
            xmlXIncludeErrMemory(ctxt);
	    return(-1);
        }
    }

    source = from->intSubset;
    if ((source != NULL) && (source->entities != NULL)) {
	xmlXIncludeMergeData data;

	data.ctxt = ctxt;
	data.doc = doc;

	xmlHashScan((xmlHashTablePtr) source->entities,
		    xmlXIncludeMergeEntity, &data);
    }
    source = from->extSubset;
    if ((source != NULL) && (source->entities != NULL)) {
	xmlXIncludeMergeData data;

	data.ctxt = ctxt;
	data.doc = doc;

	/*
	 * don't duplicate existing stuff when external subsets are the same
	 */
	if ((!xmlStrEqual(target->ExternalID, source->ExternalID)) &&
	    (!xmlStrEqual(target->SystemID, source->SystemID))) {
	    xmlHashScan((xmlHashTablePtr) source->entities,
			xmlXIncludeMergeEntity, &data);
	}
    }
    return(0);
}

/**
 * xmlXIncludeLoadDoc:
 * @ctxt:  the XInclude context
 * @url:  the associated URL
 * @ref:  an XMLXincludeRefPtr
 *
 * Load the document, and store the result in the XInclude context
 *
 * Returns 0 in case of success, -1 in case of failure
 */
static int
xmlXIncludeLoadDoc(xmlXIncludeCtxtPtr ctxt, xmlXIncludeRefPtr ref) {
    xmlXIncludeDocPtr cache;
    xmlDocPtr doc;
    const xmlChar *url = ref->URI;
    const xmlChar *fragment = ref->fragment;
    int i = 0;
    int ret = -1;
    int cacheNr;
#ifdef LIBXML_XPTR_ENABLED
    int saveFlags;
#endif

    /*
     * Handling of references to the local document are done
     * directly through ctxt->doc.
     */
    if ((url[0] == 0) || (url[0] == '#') ||
	((ctxt->doc != NULL) && (xmlStrEqual(url, ctxt->doc->URL)))) {
	doc = ctxt->doc;
        goto loaded;
    }

    /*
     * Prevent reloading the document twice.
     */
    for (i = 0; i < ctxt->urlNr; i++) {
	if (xmlStrEqual(url, ctxt->urlTab[i].url)) {
            if (ctxt->urlTab[i].expanding) {
                xmlXIncludeErr(ctxt, ref->elem, XML_XINCLUDE_RECURSION,
                               "inclusion loop detected\n", NULL);
                goto error;
            }
	    doc = ctxt->urlTab[i].doc;
            if (doc == NULL)
                goto error;
	    goto loaded;
	}
    }

    /*
     * Load it.
     */
#ifdef LIBXML_XPTR_ENABLED
    /*
     * If this is an XPointer evaluation, we want to assure that
     * all entities have been resolved prior to processing the
     * referenced document
     */
    saveFlags = ctxt->parseFlags;
    if (fragment != NULL) {	/* if this is an XPointer eval */
	ctxt->parseFlags |= XML_PARSE_NOENT;
    }
#endif

    doc = xmlXIncludeParseFile(ctxt, (const char *)url);
#ifdef LIBXML_XPTR_ENABLED
    ctxt->parseFlags = saveFlags;
#endif

    /* Also cache NULL docs */
    if (ctxt->urlNr >= ctxt->urlMax) {
        xmlXIncludeDoc *tmp;
#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
        size_t newSize = ctxt->urlMax ? ctxt->urlMax * 2 : 1;
#else
        size_t newSize = ctxt->urlMax ? ctxt->urlMax * 2 : 8;
#endif

        tmp = xmlRealloc(ctxt->urlTab, sizeof(xmlXIncludeDoc) * newSize);
        if (tmp == NULL) {
            xmlXIncludeErrMemory(ctxt);
            xmlFreeDoc(doc);
            goto error;
        }
        ctxt->urlMax = newSize;
        ctxt->urlTab = tmp;
    }
    cache = &ctxt->urlTab[ctxt->urlNr];
    cache->doc = doc;
    cache->url = xmlStrdup(url);
    if (cache->url == NULL) {
        xmlXIncludeErrMemory(ctxt);
        xmlFreeDoc(doc);
        goto error;
    }
    cache->expanding = 0;
    cacheNr = ctxt->urlNr++;

    if (doc == NULL)
        goto error;
    /*
     * It's possible that the requested URL has been mapped to a
     * completely different location (e.g. through a catalog entry).
     * To check for this, we compare the URL with that of the doc
     * and change it if they disagree (bug 146988).
     */
    if ((doc->URL != NULL) && (!xmlStrEqual(url, doc->URL)))
        url = doc->URL;

    /*
     * Make sure we have all entities fixed up
     */
    xmlXIncludeMergeEntities(ctxt, ctxt->doc, doc);

    /*
     * We don't need the DTD anymore, free up space
    if (doc->intSubset != NULL) {
	xmlUnlinkNode((xmlNodePtr) doc->intSubset);
	xmlFreeNode((xmlNodePtr) doc->intSubset);
	doc->intSubset = NULL;
    }
    if (doc->extSubset != NULL) {
	xmlUnlinkNode((xmlNodePtr) doc->extSubset);
	xmlFreeNode((xmlNodePtr) doc->extSubset);
	doc->extSubset = NULL;
    }
     */
    cache->expanding = 1;
    xmlXIncludeRecurseDoc(ctxt, doc);
    /* urlTab might be reallocated. */
    cache = &ctxt->urlTab[cacheNr];
    cache->expanding = 0;

loaded:
    if (fragment == NULL) {
        xmlNodePtr root;

        root = xmlDocGetRootElement(doc);
        if (root == NULL) {
            xmlXIncludeErr(ctxt, ref->elem, XML_ERR_INTERNAL_ERROR,
                           "document without root\n", NULL);
            goto error;
        }

        ref->inc = xmlDocCopyNode(root, ctxt->doc, 1);
        if (ref->inc == NULL) {
            xmlXIncludeErrMemory(ctxt);
            goto error;
        }

        if (ref->base != NULL)
            xmlXIncludeBaseFixup(ctxt, root, ref->inc, ref->base);
    }
#ifdef LIBXML_XPTR_ENABLED
    else {
	/*
	 * Computes the XPointer expression and make a copy used
	 * as the replacement copy.
	 */
	xmlXPathObjectPtr xptr;
	xmlNodeSetPtr set;

        if (ctxt->isStream && doc == ctxt->doc) {
	    xmlXIncludeErr(ctxt, ref->elem, XML_XINCLUDE_XPTR_FAILED,
			   "XPointer expressions not allowed in streaming"
                           " mode\n", NULL);
            goto error;
        }

        if (ctxt->xpctxt == NULL) {
            ctxt->xpctxt = xmlXPtrNewContext(doc, NULL, NULL);
            if (ctxt->xpctxt == NULL) {
                xmlXIncludeErrMemory(ctxt);
                goto error;
            }
            if (ctxt->errorHandler != NULL)
                xmlXPathSetErrorHandler(ctxt->xpctxt, ctxt->errorHandler,
                                        ctxt->errorCtxt);
#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
            ctxt->xpctxt->opLimit = 100000;
#endif
        }
	xptr = xmlXPtrEval(fragment, ctxt->xpctxt);
	if (xptr == NULL) {
            if (ctxt->xpctxt->lastError.code == XML_ERR_NO_MEMORY)
                xmlXIncludeErrMemory(ctxt);
            else
                xmlXIncludeErr(ctxt, ref->elem, XML_XINCLUDE_XPTR_FAILED,
                               "XPointer evaluation failed: #%s\n",
                               fragment);
            goto error;
	}
	switch (xptr->type) {
	    case XPATH_UNDEFINED:
	    case XPATH_BOOLEAN:
	    case XPATH_NUMBER:
	    case XPATH_STRING:
#ifdef LIBXML_XPTR_LOCS_ENABLED
	    case XPATH_POINT:
#endif
	    case XPATH_USERS:
	    case XPATH_XSLT_TREE:
		xmlXIncludeErr(ctxt, ref->elem, XML_XINCLUDE_XPTR_RESULT,
			       "XPointer is not a range: #%s\n",
			       fragment);
                xmlXPathFreeObject(xptr);
                goto error;
	    case XPATH_NODESET:
                break;

#ifdef LIBXML_XPTR_LOCS_ENABLED
	    case XPATH_RANGE:
	    case XPATH_LOCATIONSET:
		break;
#endif
	}
	set = xptr->nodesetval;
	if (set != NULL) {
	    for (i = 0;i < set->nodeNr;i++) {
		if (set->nodeTab[i] == NULL)
		    continue;
		switch (set->nodeTab[i]->type) {
		    case XML_ELEMENT_NODE:
		    case XML_TEXT_NODE:
		    case XML_CDATA_SECTION_NODE:
		    case XML_ENTITY_REF_NODE:
		    case XML_ENTITY_NODE:
		    case XML_PI_NODE:
		    case XML_COMMENT_NODE:
		    case XML_DOCUMENT_NODE:
		    case XML_HTML_DOCUMENT_NODE:
			continue;

		    case XML_ATTRIBUTE_NODE:
			xmlXIncludeErr(ctxt, ref->elem,
			               XML_XINCLUDE_XPTR_RESULT,
				       "XPointer selects an attribute: #%s\n",
				       fragment);
			set->nodeTab[i] = NULL;
			continue;
		    case XML_NAMESPACE_DECL:
			xmlXIncludeErr(ctxt, ref->elem,
			               XML_XINCLUDE_XPTR_RESULT,
				       "XPointer selects a namespace: #%s\n",
				       fragment);
			set->nodeTab[i] = NULL;
			continue;
		    case XML_DOCUMENT_TYPE_NODE:
		    case XML_DOCUMENT_FRAG_NODE:
		    case XML_NOTATION_NODE:
		    case XML_DTD_NODE:
		    case XML_ELEMENT_DECL:
		    case XML_ATTRIBUTE_DECL:
		    case XML_ENTITY_DECL:
		    case XML_XINCLUDE_START:
		    case XML_XINCLUDE_END:
			xmlXIncludeErr(ctxt, ref->elem,
			               XML_XINCLUDE_XPTR_RESULT,
				   "XPointer selects unexpected nodes: #%s\n",
				       fragment);
			set->nodeTab[i] = NULL;
			set->nodeTab[i] = NULL;
			continue; /* for */
		}
	    }
	}
        ref->inc = xmlXIncludeCopyXPointer(ctxt, xptr, ref->base);
        xmlXPathFreeObject(xptr);
    }
#endif

    ret = 0;

error:
    return(ret);
}

/**
 * xmlXIncludeLoadTxt:
 * @ctxt:  the XInclude context
 * @ref:  an XMLXincludeRefPtr
 *
 * Load the content, and store the result in the XInclude context
 *
 * Returns 0 in case of success, -1 in case of failure
 */
static int
xmlXIncludeLoadTxt(xmlXIncludeCtxtPtr ctxt, xmlXIncludeRefPtr ref) {
    xmlParserInputBufferPtr buf;
    xmlNodePtr node = NULL;
    const xmlChar *url = ref->URI;
    int i;
    int ret = -1;
    xmlChar *encoding = NULL;
    xmlCharEncodingHandlerPtr handler = NULL;
    xmlParserCtxtPtr pctxt = NULL;
    xmlParserInputPtr inputStream = NULL;
    int len;
    int res;
    const xmlChar *content;

    /*
     * Handling of references to the local document are done
     * directly through ctxt->doc.
     */
    if (url[0] == 0) {
	xmlXIncludeErr(ctxt, ref->elem, XML_XINCLUDE_TEXT_DOCUMENT,
		       "text serialization of document not available\n", NULL);
	goto error;
    }

    /*
     * Prevent reloading the document twice.
     */
    for (i = 0; i < ctxt->txtNr; i++) {
	if (xmlStrEqual(url, ctxt->txtTab[i].url)) {
            node = xmlNewDocText(ctxt->doc, ctxt->txtTab[i].text);
            if (node == NULL)
                xmlXIncludeErrMemory(ctxt);
	    goto loaded;
	}
    }

    /*
     * Try to get the encoding if available
     */
    if (ref->elem != NULL) {
	encoding = xmlXIncludeGetProp(ctxt, ref->elem, XINCLUDE_PARSE_ENCODING);
    }
    if (encoding != NULL) {
        res = xmlOpenCharEncodingHandler((const char *) encoding,
                                         /* output */ 0, &handler);

        if (res != 0) {
            if (res == XML_ERR_NO_MEMORY) {
                xmlXIncludeErrMemory(ctxt);
            } else if (res == XML_ERR_UNSUPPORTED_ENCODING) {
                xmlXIncludeErr(ctxt, ref->elem, XML_XINCLUDE_UNKNOWN_ENCODING,
                               "encoding %s not supported\n", encoding);
                goto error;
            } else {
                xmlXIncludeErr(ctxt, ref->elem, res,
                               "unexpected error from iconv or ICU\n", NULL);
                goto error;
            }
        }
    }

    /*
     * Load it.
     */
    pctxt = xmlNewParserCtxt();
    if (pctxt == NULL) {
        xmlXIncludeErrMemory(ctxt);
        goto error;
    }
    inputStream = xmlLoadExternalEntity((const char*)url, NULL, pctxt);
    if (inputStream == NULL) {
        if (pctxt->errNo == XML_ERR_NO_MEMORY)
            xmlXIncludeErrMemory(ctxt);
        else
            xmlXIncludeErr(ctxt, NULL, pctxt->errNo, "load error", NULL);
	goto error;
    }
    buf = inputStream->buf;
    if (buf == NULL)
	goto error;
    if (buf->encoder)
	xmlCharEncCloseFunc(buf->encoder);
    buf->encoder = handler;
    handler = NULL;

    node = xmlNewDocText(ctxt->doc, NULL);
    if (node == NULL) {
        xmlXIncludeErrMemory(ctxt);
	goto error;
    }

    /*
     * Scan all chars from the resource and add the to the node
     */
    do {
        res = xmlParserInputBufferRead(buf, 4096);
    } while (res > 0);
    if (res < 0) {
        if (buf->error == XML_ERR_NO_MEMORY)
            xmlXIncludeErrMemory(ctxt);
        else
            xmlXIncludeErr(ctxt, NULL, buf->error, "read error", NULL);
        goto error;
    }

    content = xmlBufContent(buf->buffer);
    len = xmlBufLength(buf->buffer);
    for (i = 0; i < len;) {
        int cur;
        int l;

        l = len - i;
        cur = xmlGetUTF8Char(&content[i], &l);
        if ((cur < 0) || (!IS_CHAR(cur))) {
            xmlXIncludeErr(ctxt, ref->elem, XML_XINCLUDE_INVALID_CHAR,
                           "%s contains invalid char\n", url);
            goto error;
        }

        i += l;
    }

    if (xmlNodeAddContentLen(node, content, len) < 0)
        xmlXIncludeErrMemory(ctxt);

    if (ctxt->txtNr >= ctxt->txtMax) {
        xmlXIncludeTxt *tmp;
#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
        size_t newSize = ctxt->txtMax ? ctxt->txtMax * 2 : 1;
#else
        size_t newSize = ctxt->txtMax ? ctxt->txtMax * 2 : 8;
#endif

        tmp = xmlRealloc(ctxt->txtTab, sizeof(xmlXIncludeTxt) * newSize);
        if (tmp == NULL) {
            xmlXIncludeErrMemory(ctxt);
	    goto error;
        }
        ctxt->txtMax = newSize;
        ctxt->txtTab = tmp;
    }
    ctxt->txtTab[ctxt->txtNr].text = xmlStrdup(node->content);
    if ((node->content != NULL) &&
        (ctxt->txtTab[ctxt->txtNr].text == NULL)) {
        xmlXIncludeErrMemory(ctxt);
        goto error;
    }
    ctxt->txtTab[ctxt->txtNr].url = xmlStrdup(url);
    if (ctxt->txtTab[ctxt->txtNr].url == NULL) {
        xmlXIncludeErrMemory(ctxt);
        xmlFree(ctxt->txtTab[ctxt->txtNr].text);
        goto error;
    }
    ctxt->txtNr++;

loaded:
    /*
     * Add the element as the replacement copy.
     */
    ref->inc = node;
    node = NULL;
    ret = 0;

error:
    xmlFreeNode(node);
    xmlFreeInputStream(inputStream);
    xmlFreeParserCtxt(pctxt);
    xmlCharEncCloseFunc(handler);
    xmlFree(encoding);
    return(ret);
}

/**
 * xmlXIncludeLoadFallback:
 * @ctxt:  the XInclude context
 * @fallback:  the fallback node
 * @ref:  an XMLXincludeRefPtr
 *
 * Load the content of the fallback node, and store the result
 * in the XInclude context
 *
 * Returns 0 in case of success, -1 in case of failure
 */
static int
xmlXIncludeLoadFallback(xmlXIncludeCtxtPtr ctxt, xmlNodePtr fallback,
                        xmlXIncludeRefPtr ref) {
    int ret = 0;
    int oldNbErrors;

    if ((fallback == NULL) || (fallback->type == XML_NAMESPACE_DECL) ||
        (ctxt == NULL))
	return(-1);
    if (fallback->children != NULL) {
	/*
	 * It's possible that the fallback also has 'includes'
	 * (Bug 129969), so we re-process the fallback just in case
	 */
        oldNbErrors = ctxt->nbErrors;
	ref->inc = xmlXIncludeCopyNode(ctxt, fallback, 1, ref->base);
	if (ctxt->nbErrors > oldNbErrors)
	    ret = -1;
    } else {
        ref->inc = NULL;
    }
    ref->fallback = 1;
    return(ret);
}

/************************************************************************
 *									*
 *			XInclude Processing				*
 *									*
 ************************************************************************/

/**
 * xmlXIncludeExpandNode:
 * @ctxt: an XInclude context
 * @node: an XInclude node
 *
 * If the XInclude node wasn't processed yet, create a new RefPtr,
 * add it to ctxt->incTab and load the included items.
 *
 * Returns the new or existing xmlXIncludeRefPtr, or NULL in case of error.
 */
static xmlXIncludeRefPtr
xmlXIncludeExpandNode(xmlXIncludeCtxtPtr ctxt, xmlNodePtr node) {
    xmlXIncludeRefPtr ref;
    int i;

    if (ctxt->fatalErr)
        return(NULL);
    if (ctxt->depth >= XINCLUDE_MAX_DEPTH) {
        xmlXIncludeErr(ctxt, node, XML_XINCLUDE_RECURSION,
                       "maximum recursion depth exceeded\n", NULL);
        ctxt->fatalErr = 1;
        return(NULL);
    }

#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
    /*
     * The XInclude engine offers no protection against exponential
     * expansion attacks similar to "billion laughs". Avoid timeouts by
     * limiting the total number of replacements when fuzzing.
     *
     * Unfortuately, a single XInclude can already result in quadratic
     * behavior:
     *
     *     <doc xmlns:xi="http://www.w3.org/2001/XInclude">
     *       <xi:include xpointer="xpointer(//e)"/>
     *       <e>
     *         <e>
     *           <e>
     *             <!-- more nested elements -->
     *           </e>
     *         </e>
     *       </e>
     *     </doc>
     */
    if (ctxt->incTotal >= 20)
        return(NULL);
    ctxt->incTotal++;
#endif

    for (i = 0; i < ctxt->incNr; i++) {
        if (ctxt->incTab[i]->elem == node) {
            if (ctxt->incTab[i]->expanding) {
                xmlXIncludeErr(ctxt, node, XML_XINCLUDE_RECURSION,
                               "inclusion loop detected\n", NULL);
                return(NULL);
            }
            return(ctxt->incTab[i]);
        }
    }

    ref = xmlXIncludeAddNode(ctxt, node);
    if (ref == NULL)
        return(NULL);
    ref->expanding = 1;
    ctxt->depth++;
    xmlXIncludeLoadNode(ctxt, ref);
    ctxt->depth--;
    ref->expanding = 0;

    return(ref);
}

/**
 * xmlXIncludeLoadNode:
 * @ctxt: an XInclude context
 * @ref: an xmlXIncludeRefPtr
 *
 * Find and load the infoset replacement for the given node.
 *
 * Returns 0 if substitution succeeded, -1 if some processing failed
 */
static int
xmlXIncludeLoadNode(xmlXIncludeCtxtPtr ctxt, xmlXIncludeRefPtr ref) {
    xmlNodePtr cur;
    int ret;

    if ((ctxt == NULL) || (ref == NULL))
	return(-1);
    cur = ref->elem;
    if (cur == NULL)
	return(-1);

    if (ref->xml) {
	ret = xmlXIncludeLoadDoc(ctxt, ref);
	/* xmlXIncludeGetFragment(ctxt, cur, URI); */
    } else {
	ret = xmlXIncludeLoadTxt(ctxt, ref);
    }

    if (ret < 0) {
	xmlNodePtr children;

	/*
	 * Time to try a fallback if available
	 */
	children = cur->children;
	while (children != NULL) {
	    if ((children->type == XML_ELEMENT_NODE) &&
		(children->ns != NULL) &&
		(xmlStrEqual(children->name, XINCLUDE_FALLBACK)) &&
		((xmlStrEqual(children->ns->href, XINCLUDE_NS)) ||
		 (xmlStrEqual(children->ns->href, XINCLUDE_OLD_NS)))) {
		ret = xmlXIncludeLoadFallback(ctxt, children, ref);
		break;
	    }
	    children = children->next;
	}
    }
    if (ret < 0) {
	xmlXIncludeErr(ctxt, cur, XML_XINCLUDE_NO_FALLBACK,
		       "could not load %s, and no fallback was found\n",
		       ref->URI);
    }

    return(0);
}

/**
 * xmlXIncludeIncludeNode:
 * @ctxt: an XInclude context
 * @ref: an xmlXIncludeRefPtr
 *
 * Implement the infoset replacement for the given node
 *
 * Returns 0 if substitution succeeded, -1 if some processing failed
 */
static int
xmlXIncludeIncludeNode(xmlXIncludeCtxtPtr ctxt, xmlXIncludeRefPtr ref) {
    xmlNodePtr cur, end, list, tmp;

    if ((ctxt == NULL) || (ref == NULL))
	return(-1);
    cur = ref->elem;
    if ((cur == NULL) || (cur->type == XML_NAMESPACE_DECL))
	return(-1);

    list = ref->inc;
    ref->inc = NULL;

    /*
     * Check against the risk of generating a multi-rooted document
     */
    if ((cur->parent != NULL) &&
	(cur->parent->type != XML_ELEMENT_NODE)) {
	int nb_elem = 0;

	tmp = list;
	while (tmp != NULL) {
	    if (tmp->type == XML_ELEMENT_NODE)
		nb_elem++;
	    tmp = tmp->next;
	}
	if (nb_elem > 1) {
	    xmlXIncludeErr(ctxt, ref->elem, XML_XINCLUDE_MULTIPLE_ROOT,
		       "XInclude error: would result in multiple root nodes\n",
			   NULL);
            xmlFreeNodeList(list);
	    return(-1);
	}
    }

    if (ctxt->parseFlags & XML_PARSE_NOXINCNODE) {
	/*
	 * Add the list of nodes
         *
         * TODO: Coalesce text nodes unless we are streaming mode.
	 */
	while (list != NULL) {
	    end = list;
	    list = list->next;

	    if (xmlAddPrevSibling(cur, end) == NULL) {
                xmlUnlinkNode(end);
                xmlFreeNode(end);
                goto err_memory;
            }
	}
	xmlUnlinkNode(cur);
	xmlFreeNode(cur);
    } else {
        xmlNodePtr child, next;

	/*
	 * Change the current node as an XInclude start one, and add an
	 * XInclude end one
	 */
        if (ref->fallback)
            xmlUnsetProp(cur, BAD_CAST "href");
	cur->type = XML_XINCLUDE_START;
        /* Remove fallback children */
        for (child = cur->children; child != NULL; child = next) {
            next = child->next;
            xmlUnlinkNode(child);
            xmlFreeNode(child);
        }
	end = xmlNewDocNode(cur->doc, cur->ns, cur->name, NULL);
	if (end == NULL)
            goto err_memory;
	end->type = XML_XINCLUDE_END;
	if (xmlAddNextSibling(cur, end) == NULL) {
            xmlFreeNode(end);
            goto err_memory;
        }

	/*
	 * Add the list of nodes
	 */
	while (list != NULL) {
	    cur = list;
	    list = list->next;

	    if (xmlAddPrevSibling(end, cur) == NULL) {
                xmlUnlinkNode(cur);
                xmlFreeNode(cur);
                goto err_memory;
            }
	}
    }


    return(0);

err_memory:
    xmlXIncludeErrMemory(ctxt);
    xmlFreeNodeList(list);
    return(-1);
}

/**
 * xmlXIncludeTestNode:
 * @ctxt: the XInclude processing context
 * @node: an XInclude node
 *
 * test if the node is an XInclude node
 *
 * Returns 1 true, 0 otherwise
 */
static int
xmlXIncludeTestNode(xmlXIncludeCtxtPtr ctxt, xmlNodePtr node) {
    if (node == NULL)
	return(0);
    if (node->type != XML_ELEMENT_NODE)
	return(0);
    if (node->ns == NULL)
	return(0);
    if ((xmlStrEqual(node->ns->href, XINCLUDE_NS)) ||
        (xmlStrEqual(node->ns->href, XINCLUDE_OLD_NS))) {
	if (xmlStrEqual(node->ns->href, XINCLUDE_OLD_NS)) {
	    if (ctxt->legacy == 0) {
#if 0 /* wait for the XML Core Working Group to get something stable ! */
		xmlXIncludeWarn(ctxt, node, XML_XINCLUDE_DEPRECATED_NS,
	               "Deprecated XInclude namespace found, use %s",
		                XINCLUDE_NS);
#endif
	        ctxt->legacy = 1;
	    }
	}
	if (xmlStrEqual(node->name, XINCLUDE_NODE)) {
	    xmlNodePtr child = node->children;
	    int nb_fallback = 0;

	    while (child != NULL) {
		if ((child->type == XML_ELEMENT_NODE) &&
		    (child->ns != NULL) &&
		    ((xmlStrEqual(child->ns->href, XINCLUDE_NS)) ||
		     (xmlStrEqual(child->ns->href, XINCLUDE_OLD_NS)))) {
		    if (xmlStrEqual(child->name, XINCLUDE_NODE)) {
			xmlXIncludeErr(ctxt, node,
			               XML_XINCLUDE_INCLUDE_IN_INCLUDE,
				       "%s has an 'include' child\n",
				       XINCLUDE_NODE);
			return(0);
		    }
		    if (xmlStrEqual(child->name, XINCLUDE_FALLBACK)) {
			nb_fallback++;
		    }
		}
		child = child->next;
	    }
	    if (nb_fallback > 1) {
		xmlXIncludeErr(ctxt, node, XML_XINCLUDE_FALLBACKS_IN_INCLUDE,
			       "%s has multiple fallback children\n",
		               XINCLUDE_NODE);
		return(0);
	    }
	    return(1);
	}
	if (xmlStrEqual(node->name, XINCLUDE_FALLBACK)) {
	    if ((node->parent == NULL) ||
		(node->parent->type != XML_ELEMENT_NODE) ||
		(node->parent->ns == NULL) ||
		((!xmlStrEqual(node->parent->ns->href, XINCLUDE_NS)) &&
		 (!xmlStrEqual(node->parent->ns->href, XINCLUDE_OLD_NS))) ||
		(!xmlStrEqual(node->parent->name, XINCLUDE_NODE))) {
		xmlXIncludeErr(ctxt, node,
		               XML_XINCLUDE_FALLBACK_NOT_IN_INCLUDE,
			       "%s is not the child of an 'include'\n",
			       XINCLUDE_FALLBACK);
	    }
	}
    }
    return(0);
}

/**
 * xmlXIncludeDoProcess:
 * @ctxt: the XInclude processing context
 * @tree: the top of the tree to process
 *
 * Implement the XInclude substitution on the XML document @doc
 *
 * Returns 0 if no substitution were done, -1 if some processing failed
 *    or the number of substitutions done.
 */
static int
xmlXIncludeDoProcess(xmlXIncludeCtxtPtr ctxt, xmlNodePtr tree) {
    xmlXIncludeRefPtr ref;
    xmlNodePtr cur;
    int ret = 0;
    int i, start;

    /*
     * First phase: lookup the elements in the document
     */
    start = ctxt->incNr;
    cur = tree;
    do {
	/* TODO: need to work on entities -> stack */
        if (xmlXIncludeTestNode(ctxt, cur) == 1) {
            ref = xmlXIncludeExpandNode(ctxt, cur);
            /*
             * Mark direct includes.
             */
            if (ref != NULL)
                ref->replace = 1;
        } else if ((cur->children != NULL) &&
                   ((cur->type == XML_DOCUMENT_NODE) ||
                    (cur->type == XML_ELEMENT_NODE))) {
            cur = cur->children;
            continue;
        }
        do {
            if (cur == tree)
                break;
            if (cur->next != NULL) {
                cur = cur->next;
                break;
            }
            cur = cur->parent;
        } while (cur != NULL);
    } while ((cur != NULL) && (cur != tree));

    /*
     * Second phase: extend the original document infoset.
     */
    for (i = start; i < ctxt->incNr; i++) {
	if (ctxt->incTab[i]->replace != 0) {
            xmlXIncludeIncludeNode(ctxt, ctxt->incTab[i]);
            ctxt->incTab[i]->replace = 0;
        } else {
            /*
             * Ignore includes which were added indirectly, for example
             * inside xi:fallback elements.
             */
            if (ctxt->incTab[i]->inc != NULL) {
                xmlFreeNodeList(ctxt->incTab[i]->inc);
                ctxt->incTab[i]->inc = NULL;
            }
        }
	ret++;
    }

    if (ctxt->isStream) {
        /*
         * incTab references nodes which will eventually be deleted in
         * streaming mode. The table is only required for XPointer
         * expressions which aren't allowed in streaming mode.
         */
        for (i = 0;i < ctxt->incNr;i++) {
            xmlXIncludeFreeRef(ctxt->incTab[i]);
        }
        ctxt->incNr = 0;
    }

    return(ret);
}

/**
 * xmlXIncludeDoProcessRoot:
 * @ctxt: the XInclude processing context
 * @tree: the top of the tree to process
 *
 * Implement the XInclude substitution on the XML document @doc
 *
 * Returns 0 if no substitution were done, -1 if some processing failed
 *    or the number of substitutions done.
 */
static int
xmlXIncludeDoProcessRoot(xmlXIncludeCtxtPtr ctxt, xmlNodePtr tree) {
    if ((tree == NULL) || (tree->type == XML_NAMESPACE_DECL))
	return(-1);
    if (ctxt == NULL)
	return(-1);

    return(xmlXIncludeDoProcess(ctxt, tree));
}

/**
 * xmlXIncludeGetLastError:
 * @ctxt:  an XInclude processing context
 *
 * Returns the last error code.
 */
int
xmlXIncludeGetLastError(xmlXIncludeCtxtPtr ctxt) {
    if (ctxt == NULL)
        return(XML_ERR_ARGUMENT);
    return(ctxt->errNo);
}

/**
 * xmlXIncludeSetErrorHandler:
 * @ctxt:  an XInclude processing context
 * @handler:  error handler
 * @data:  user data which will be passed to the handler
 *
 * Register a callback function that will be called on errors and
 * warnings. If handler is NULL, the error handler will be deactivated.
 *
 * Available since 2.13.0.
 */
void
xmlXIncludeSetErrorHandler(xmlXIncludeCtxtPtr ctxt,
                           xmlStructuredErrorFunc handler, void *data) {
    if (ctxt == NULL)
        return;
    ctxt->errorHandler = handler;
    ctxt->errorCtxt = data;
}

/**
 * xmlXIncludeSetFlags:
 * @ctxt:  an XInclude processing context
 * @flags: a set of xmlParserOption used for parsing XML includes
 *
 * Set the flags used for further processing of XML resources.
 *
 * Returns 0 in case of success and -1 in case of error.
 */
int
xmlXIncludeSetFlags(xmlXIncludeCtxtPtr ctxt, int flags) {
    if (ctxt == NULL)
        return(-1);
    ctxt->parseFlags = flags;
    return(0);
}

/**
 * xmlXIncludeSetStreamingMode:
 * @ctxt:  an XInclude processing context
 * @mode:  whether streaming mode should be enabled
 *
 * In streaming mode, XPointer expressions aren't allowed.
 *
 * Returns 0 in case of success and -1 in case of error.
 */
int
xmlXIncludeSetStreamingMode(xmlXIncludeCtxtPtr ctxt, int mode) {
    if (ctxt == NULL)
        return(-1);
    ctxt->isStream = !!mode;
    return(0);
}

/**
 * xmlXIncludeProcessTreeFlagsData:
 * @tree: an XML node
 * @flags: a set of xmlParserOption used for parsing XML includes
 * @data: application data that will be passed to the parser context
 *        in the _private field of the parser context(s)
 *
 * Implement the XInclude substitution on the XML node @tree
 *
 * Returns 0 if no substitution were done, -1 if some processing failed
 *    or the number of substitutions done.
 */

int
xmlXIncludeProcessTreeFlagsData(xmlNodePtr tree, int flags, void *data) {
    xmlXIncludeCtxtPtr ctxt;
    int ret = 0;

    if ((tree == NULL) || (tree->type == XML_NAMESPACE_DECL) ||
        (tree->doc == NULL))
        return(-1);

    ctxt = xmlXIncludeNewContext(tree->doc);
    if (ctxt == NULL)
        return(-1);
    ctxt->_private = data;
    xmlXIncludeSetFlags(ctxt, flags);
    ret = xmlXIncludeDoProcessRoot(ctxt, tree);
    if ((ret >= 0) && (ctxt->nbErrors > 0))
        ret = -1;

    xmlXIncludeFreeContext(ctxt);
    return(ret);
}

/**
 * xmlXIncludeProcessFlagsData:
 * @doc: an XML document
 * @flags: a set of xmlParserOption used for parsing XML includes
 * @data: application data that will be passed to the parser context
 *        in the _private field of the parser context(s)
 *
 * Implement the XInclude substitution on the XML document @doc
 *
 * Returns 0 if no substitution were done, -1 if some processing failed
 *    or the number of substitutions done.
 */
int
xmlXIncludeProcessFlagsData(xmlDocPtr doc, int flags, void *data) {
    xmlNodePtr tree;

    if (doc == NULL)
	return(-1);
    tree = xmlDocGetRootElement(doc);
    if (tree == NULL)
	return(-1);
    return(xmlXIncludeProcessTreeFlagsData(tree, flags, data));
}

/**
 * xmlXIncludeProcessFlags:
 * @doc: an XML document
 * @flags: a set of xmlParserOption used for parsing XML includes
 *
 * Implement the XInclude substitution on the XML document @doc
 *
 * Returns 0 if no substitution were done, -1 if some processing failed
 *    or the number of substitutions done.
 */
int
xmlXIncludeProcessFlags(xmlDocPtr doc, int flags) {
    return xmlXIncludeProcessFlagsData(doc, flags, NULL);
}

/**
 * xmlXIncludeProcess:
 * @doc: an XML document
 *
 * Implement the XInclude substitution on the XML document @doc
 *
 * Returns 0 if no substitution were done, -1 if some processing failed
 *    or the number of substitutions done.
 */
int
xmlXIncludeProcess(xmlDocPtr doc) {
    return(xmlXIncludeProcessFlags(doc, 0));
}

/**
 * xmlXIncludeProcessTreeFlags:
 * @tree: a node in an XML document
 * @flags: a set of xmlParserOption used for parsing XML includes
 *
 * Implement the XInclude substitution for the given subtree
 *
 * Returns 0 if no substitution were done, -1 if some processing failed
 *    or the number of substitutions done.
 */
int
xmlXIncludeProcessTreeFlags(xmlNodePtr tree, int flags) {
    xmlXIncludeCtxtPtr ctxt;
    int ret = 0;

    if ((tree == NULL) || (tree->type == XML_NAMESPACE_DECL) ||
        (tree->doc == NULL))
	return(-1);
    ctxt = xmlXIncludeNewContext(tree->doc);
    if (ctxt == NULL)
	return(-1);
    xmlXIncludeSetFlags(ctxt, flags);
    ret = xmlXIncludeDoProcessRoot(ctxt, tree);
    if ((ret >= 0) && (ctxt->nbErrors > 0))
	ret = -1;

    xmlXIncludeFreeContext(ctxt);
    return(ret);
}

/**
 * xmlXIncludeProcessTree:
 * @tree: a node in an XML document
 *
 * Implement the XInclude substitution for the given subtree
 *
 * Returns 0 if no substitution were done, -1 if some processing failed
 *    or the number of substitutions done.
 */
int
xmlXIncludeProcessTree(xmlNodePtr tree) {
    return(xmlXIncludeProcessTreeFlags(tree, 0));
}

/**
 * xmlXIncludeProcessNode:
 * @ctxt: an existing XInclude context
 * @node: a node in an XML document
 *
 * Implement the XInclude substitution for the given subtree reusing
 * the information and data coming from the given context.
 *
 * Returns 0 if no substitution were done, -1 if some processing failed
 *    or the number of substitutions done.
 */
int
xmlXIncludeProcessNode(xmlXIncludeCtxtPtr ctxt, xmlNodePtr node) {
    int ret = 0;

    if ((node == NULL) || (node->type == XML_NAMESPACE_DECL) ||
        (node->doc == NULL) || (ctxt == NULL))
	return(-1);
    ret = xmlXIncludeDoProcessRoot(ctxt, node);
    if ((ret >= 0) && (ctxt->nbErrors > 0))
	ret = -1;
    return(ret);
}

#else /* !LIBXML_XINCLUDE_ENABLED */
#endif
