Example #1
0
static void
testXPath(const char *str) {
    xmlXPathObjectPtr res;
    xmlXPathContextPtr ctxt;

#if defined(LIBXML_XPTR_ENABLED)
    if (xptr) {
	ctxt = xmlXPtrNewContext(document, NULL, NULL);
	res = xmlXPtrEval(BAD_CAST str, ctxt);
    } else {
#endif
	ctxt = xmlXPathNewContext(document);
	ctxt->node = xmlDocGetRootElement(document);
	if (expr)
	    res = xmlXPathEvalExpression(BAD_CAST str, ctxt);
	else {
	    /* res = xmlXPathEval(BAD_CAST str, ctxt); */
	    xmlXPathCompExprPtr comp;

	    comp = xmlXPathCompile(BAD_CAST str);
	    if (comp != NULL) {
		if (tree)
		    xmlXPathDebugDumpCompExpr(stdout, comp, 0);

		res = xmlXPathCompiledEval(comp, ctxt);
		xmlXPathFreeCompExpr(comp);
	    } else
		res = NULL;
	}
#if defined(LIBXML_XPTR_ENABLED)
    }
#endif
    xmlXPathDebugDumpObject(stdout, res, 0);
    xmlXPathFreeObject(res);
    xmlXPathFreeContext(ctxt);
}
Example #2
0
static xmlSecNodeSetPtr
xmlSecXPathDataExecute(xmlSecXPathDataPtr data, xmlDocPtr doc, xmlNodePtr hereNode) {
    xmlXPathObjectPtr xpathObj = NULL;
    xmlSecNodeSetPtr nodes;

    xmlSecAssert2(data != NULL, NULL);
    xmlSecAssert2(data->expr != NULL, NULL);
    xmlSecAssert2(data->ctx != NULL, NULL);
    xmlSecAssert2(doc != NULL, NULL);
    xmlSecAssert2(hereNode != NULL, NULL);

    /* do not forget to set the doc */
    data->ctx->doc = doc;

    /* here function works only on the same document */
    if(hereNode->doc == doc) {
        xmlXPathRegisterFunc(data->ctx, (xmlChar *)"here", xmlSecXPathHereFunction);
        data->ctx->here = hereNode;
        data->ctx->xptr = 1;
    }

    /* execute xpath or xpointer expression */
    switch(data->type) {
    case xmlSecXPathDataTypeXPath:
    case xmlSecXPathDataTypeXPath2:
        xpathObj = xmlXPathEvalExpression(data->expr, data->ctx);
        if(xpathObj == NULL) {
            xmlSecError(XMLSEC_ERRORS_HERE,
                        NULL,
                        "xmlXPathEvalExpression",
                        XMLSEC_ERRORS_R_XML_FAILED,
                        "expr=%s",
                        xmlSecErrorsSafeString(data->expr));
            return(NULL);
        }
        break;
    case xmlSecXPathDataTypeXPointer:
        xpathObj = xmlXPtrEval(data->expr, data->ctx);
        if(xpathObj == NULL) {
            xmlSecError(XMLSEC_ERRORS_HERE,
                        NULL,
                        "xmlXPtrEval",
                        XMLSEC_ERRORS_R_XML_FAILED,
                        "expr=%s",
                        xmlSecErrorsSafeString(data->expr));
            return(NULL);
        }
        break;
    }

    /* sometime LibXML2 returns an empty nodeset or just NULL, we want
    to reserve NULL for our own purposes so we simply create an empty
    node set here */
    if(xpathObj->nodesetval == NULL) {
    	xpathObj->nodesetval = xmlXPathNodeSetCreate(NULL);
    	if(xpathObj->nodesetval == NULL) {
    		xmlXPathFreeObject(xpathObj);
    		xmlSecError(XMLSEC_ERRORS_HERE,
        				NULL,
                        "xmlXPathNodeSetCreate",
                        XMLSEC_ERRORS_R_XML_FAILED,
                        "expr=%s",
                        xmlSecErrorsSafeString(data->expr));
    		return(NULL);
    	}
    }

    nodes = xmlSecNodeSetCreate(doc, xpathObj->nodesetval, data->nodeSetType);
    if(nodes == NULL) {
        xmlSecError(XMLSEC_ERRORS_HERE,
                    NULL,
                    "xmlSecNodeSetCreate",
                    XMLSEC_ERRORS_R_XMLSEC_FAILED,
                    "type=%d", data->nodeSetType);
        xmlXPathFreeObject(xpathObj);
        return(NULL);
    }
    xpathObj->nodesetval = NULL;
    xmlXPathFreeObject(xpathObj);

    return(nodes);
}
Example #3
0
static void
xsltDocumentFunctionLoadDocument(xmlXPathParserContextPtr ctxt, xmlChar* URI)
{
    xsltTransformContextPtr tctxt;
    xmlURIPtr uri;
    xmlChar *fragment;
    xsltDocumentPtr idoc; /* document info */
    xmlDocPtr doc;
    xmlXPathContextPtr xptrctxt = NULL;
    xmlXPathObjectPtr resObj = NULL;

    tctxt = xsltXPathGetTransformContext(ctxt);
    if (tctxt == NULL) {
	xsltTransformError(NULL, NULL, NULL,
	    "document() : internal error tctxt == NULL\n");
	valuePush(ctxt, xmlXPathNewNodeSet(NULL));
	return;
    }

    uri = xmlParseURI((const char *) URI);
    if (uri == NULL) {
	xsltTransformError(tctxt, NULL, NULL,
	    "document() : failed to parse URI\n");
	valuePush(ctxt, xmlXPathNewNodeSet(NULL));
	return;
    }

    /*
     * check for and remove fragment identifier
     */
    fragment = (xmlChar *)uri->fragment;
    if (fragment != NULL) {
        xmlChar *newURI;
	uri->fragment = NULL;
	newURI = xmlSaveUri(uri);
	idoc = xsltLoadDocument(tctxt, newURI);
	xmlFree(newURI);
    } else
	idoc = xsltLoadDocument(tctxt, URI);
    xmlFreeURI(uri);

    if (idoc == NULL) {
	if ((URI == NULL) ||
	    (URI[0] == '#') ||
	    ((tctxt->style->doc != NULL) &&
	    (xmlStrEqual(tctxt->style->doc->URL, URI))))
	{
	    /*
	    * This selects the stylesheet's doc itself.
	    */
	    doc = tctxt->style->doc;
	} else {
	    valuePush(ctxt, xmlXPathNewNodeSet(NULL));

	    if (fragment != NULL)
		xmlFree(fragment);

	    return;
	}
    } else
	doc = idoc->doc;

    if (fragment == NULL) {
	valuePush(ctxt, xmlXPathNewNodeSet((xmlNodePtr) doc));
	return;
    }

    /* use XPointer of HTML location for fragment ID */
#ifdef LIBXML_XPTR_ENABLED
    xptrctxt = xmlXPtrNewContext(doc, NULL, NULL);
    if (xptrctxt == NULL) {
	xsltTransformError(tctxt, NULL, NULL,
	    "document() : internal error xptrctxt == NULL\n");
	goto out_fragment;
    }

    resObj = xmlXPtrEval(fragment, xptrctxt);
    xmlXPathFreeContext(xptrctxt);
#endif

    if (resObj == NULL)
	goto out_fragment;

    switch (resObj->type) {
	case XPATH_NODESET:
	    break;
	case XPATH_UNDEFINED:
	case XPATH_BOOLEAN:
	case XPATH_NUMBER:
	case XPATH_STRING:
	case XPATH_POINT:
	case XPATH_USERS:
	case XPATH_XSLT_TREE:
	case XPATH_RANGE:
	case XPATH_LOCATIONSET:
	    xsltTransformError(tctxt, NULL, NULL,
		"document() : XPointer does not select a node set: #%s\n",
		fragment);
	goto out_object;
    }

    valuePush(ctxt, resObj);
    xmlFree(fragment);
    return;

out_object:
    xmlXPathFreeObject(resObj);

out_fragment:
    valuePush(ctxt, xmlXPathNewNodeSet(NULL));
    xmlFree(fragment);
}
Example #4
0
/**
 * xmlXIncludeLoadDoc:
 * @ctxt:  the XInclude context
 * @url:  the associated URL
 * @nr:  the xinclude node number
 *
 * Load the document, and store the result in the XInclude context
 */
static void
xmlXIncludeLoadDoc(xmlXIncludeCtxtPtr ctxt, const xmlChar *url, int nr) {
    xmlDocPtr doc;
    xmlURIPtr uri;
    xmlChar *URL;
    xmlChar *fragment = NULL;
    int i;
    /*
     * Check the URL and remove any fragment identifier
     */
    uri = xmlParseURI((const char *)url);
    if (uri == NULL) {
        xmlGenericError(xmlGenericErrorContext,
                        "XInclude: invalid value URI %s\n", url);
        return;
    }
    if (uri->fragment != NULL) {
        fragment = (xmlChar *) uri->fragment;
        uri->fragment = NULL;
    }
    URL = xmlSaveUri(uri);
    xmlFreeURI(uri);
    if (URL == NULL) {
        xmlGenericError(xmlGenericErrorContext,
                        "XInclude: invalid value URI %s\n", url);
        if (fragment != NULL)
            xmlFree(fragment);
        return;
    }

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

    /*
     * Prevent reloading twice the document.
     */
    for (i = 0; i < ctxt->docNr; i++) {
        if (xmlStrEqual(URL, ctxt->urlTab[i])) {
            doc = ctxt->docTab[i];
            goto loaded;
        }
    }
    /*
     * Load it.
     */
    doc = xmlParseFile((const char *)URL);
    if (doc == NULL) {
        xmlGenericError(xmlGenericErrorContext,
                        "XInclude: could not load %s\n", URL);
        xmlFree(URL);
        if (fragment != NULL)
            xmlFree(fragment);
        return;
    }
    xmlXIncludeAddDoc(ctxt, doc, URL);

loaded:
    if (fragment == NULL) {
        /*
         * Add the top children list as the replacement copy.
         */
        if (doc == NULL)
        {
            /* Hopefully a DTD declaration won't be copied from
             * the same document */
            ctxt->repTab[nr] = xmlCopyNodeList(ctxt->doc->children);
        } else {
            ctxt->repTab[nr] = xmlXIncludeCopyNodeList(ctxt, ctxt->doc,
                               doc, doc->children);
        }
    } else {
        /*
         * Computes the XPointer expression and make a copy used
         * as the replacement copy.
         */
        xmlXPathObjectPtr xptr;
        xmlXPathContextPtr xptrctxt;
        xmlNodeSetPtr set;

        if (doc == NULL) {
            xptrctxt = xmlXPtrNewContext(ctxt->doc, ctxt->incTab[nr], NULL);
        } else {
            xptrctxt = xmlXPtrNewContext(doc, NULL, NULL);
        }
        if (xptrctxt == NULL) {
            xmlGenericError(xmlGenericErrorContext,
                            "XInclude: could create XPointer context\n");
            xmlFree(URL);
            xmlFree(fragment);
            return;
        }
        xptr = xmlXPtrEval(fragment, xptrctxt);
        if (xptr == NULL) {
            xmlGenericError(xmlGenericErrorContext,
                            "XInclude: XPointer evaluation failed: #%s\n",
                            fragment);
            xmlXPathFreeContext(xptrctxt);
            xmlFree(URL);
            xmlFree(fragment);
            return;
        }
        switch (xptr->type) {
        case XPATH_UNDEFINED:
        case XPATH_BOOLEAN:
        case XPATH_NUMBER:
        case XPATH_STRING:
        case XPATH_POINT:
        case XPATH_USERS:
        case XPATH_XSLT_TREE:
            xmlGenericError(xmlGenericErrorContext,
                            "XInclude: XPointer is not a range: #%s\n",
                            fragment);
            xmlXPathFreeContext(xptrctxt);
            xmlFree(URL);
            xmlFree(fragment);
            return;
        case XPATH_NODESET:
        case XPATH_RANGE:
        case XPATH_LOCATIONSET:
            break;
        }
        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_TEXT_NODE:
                case XML_CDATA_SECTION_NODE:
                case XML_ELEMENT_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:
#ifdef LIBXML_DOCB_ENABLED
                case XML_DOCB_DOCUMENT_NODE:
#endif
                    continue;
                case XML_ATTRIBUTE_NODE:
                    xmlGenericError(xmlGenericErrorContext,
                                    "XInclude: XPointer selects an attribute: #%s\n",
                                    fragment);
                    set->nodeTab[i] = NULL;
                    continue;
                case XML_NAMESPACE_DECL:
                    xmlGenericError(xmlGenericErrorContext,
                                    "XInclude: 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:
                    xmlGenericError(xmlGenericErrorContext,
                                    "XInclude: XPointer selects unexpected nodes: #%s\n",
                                    fragment);
                    set->nodeTab[i] = NULL;
                    set->nodeTab[i] = NULL;
                    continue; /* for */
                }
            }
        }
        ctxt->repTab[nr] = xmlXIncludeCopyXPointer(ctxt, ctxt->doc, doc, xptr);
        xmlXPathFreeObject(xptr);
        xmlXPathFreeContext(xptrctxt);
        xmlFree(fragment);
    }
    xmlFree(URL);
}