static int xmlSecXPathDataRegisterNamespaces(xmlSecXPathDataPtr data, xmlNodePtr node) { xmlNodePtr cur; xmlNsPtr ns; int ret; xmlSecAssert2(data != NULL, -1); xmlSecAssert2(data->ctx != NULL, -1); xmlSecAssert2(node != NULL, -1); /* register namespaces */ for(cur = node; cur != NULL; cur = cur->parent) { for(ns = cur->nsDef; ns != NULL; ns = ns->next) { /* check that we have no other namespace with same prefix already */ if((ns->prefix != NULL) && (xmlXPathNsLookup(data->ctx, ns->prefix) == NULL)){ ret = xmlXPathRegisterNs(data->ctx, ns->prefix, ns->href); if(ret != 0) { xmlSecError(XMLSEC_ERRORS_HERE, NULL, "xmlXPathRegisterNs", XMLSEC_ERRORS_R_XML_FAILED, "href=%s;prefix=%s", xmlSecErrorsSafeString(ns->href), xmlSecErrorsSafeString(ns->prefix)); return(-1); } } } } return(0); }
bool XPathContext::is_namespace_registered(const std::string& prefix) { if (NULL != xmlXPathNsLookup(m_cobj, reinterpret_cast<const xmlChar*>(prefix.c_str()))) { return true; } return false; }
/** * xsltElementAvailableFunction: * @ctxt: the XPath Parser context * @nargs: the number of arguments * * Implement the element-available() XSLT function * boolean element-available(string) */ void xsltElementAvailableFunction(xmlXPathParserContextPtr ctxt, int nargs){ xmlXPathObjectPtr obj; xmlChar *prefix, *name; const xmlChar *nsURI = NULL; xsltTransformContextPtr tctxt; if (nargs != 1) { xsltTransformError(xsltXPathGetTransformContext(ctxt), NULL, NULL, "element-available() : expects one string arg\n"); ctxt->error = XPATH_INVALID_ARITY; return; } xmlXPathStringFunction(ctxt, 1); if ((ctxt->value == NULL) || (ctxt->value->type != XPATH_STRING)) { xsltTransformError(xsltXPathGetTransformContext(ctxt), NULL, NULL, "element-available() : invalid arg expecting a string\n"); ctxt->error = XPATH_INVALID_TYPE; return; } obj = valuePop(ctxt); tctxt = xsltXPathGetTransformContext(ctxt); if (tctxt == NULL) { xsltTransformError(xsltXPathGetTransformContext(ctxt), NULL, NULL, "element-available() : internal error tctxt == NULL\n"); xmlXPathFreeObject(obj); valuePush(ctxt, xmlXPathNewBoolean(0)); return; } name = xmlSplitQName2(obj->stringval, &prefix); if (name == NULL) { xmlNsPtr ns; name = xmlStrdup(obj->stringval); ns = xmlSearchNs(tctxt->inst->doc, tctxt->inst, NULL); if (ns != NULL) nsURI = xmlStrdup(ns->href); } else { nsURI = xmlXPathNsLookup(ctxt->context, prefix); if (nsURI == NULL) { xsltTransformError(xsltXPathGetTransformContext(ctxt), NULL, NULL, "element-available() : prefix %s is not bound\n", prefix); } } if (xsltExtElementLookup(tctxt, name, nsURI) != NULL) { valuePush(ctxt, xmlXPathNewBoolean(1)); } else { valuePush(ctxt, xmlXPathNewBoolean(0)); } xmlXPathFreeObject(obj); if (name != NULL) xmlFree(name); if (prefix != NULL) xmlFree(prefix); }
/** * xslDbgShellPrintList: * @ctxt: The current shell context * @arg: What xpath to display and in UTF-8 * @dir: If 1 print in dir mode?, * otherwise ls mode * * Print list of nodes in either ls or dir format * * Returns 1 on success, * 0 otherwise */ int xslDbgShellPrintList(xmlShellCtxtPtr ctxt, xmlChar * arg, int dir) { xmlXPathObjectPtr list; int result = 0; if (!ctxt || !arg) { #ifdef WITH_XSLDBG_DEBUG_PROCESS xsltGenericError(xsltGenericErrorContext, "Error: NULL arguments provided\n"); #endif return result; } if (arg[0] == 0) { if (dir) xmlShellDir(ctxt, NULL, ctxt->node, NULL); else xmlShellList(ctxt, NULL, ctxt->node, NULL); result = 1; /*assume that this worked */ } else { ctxt->pctxt->node = ctxt->node; ctxt->pctxt->node = ctxt->node; if (!xmlXPathNsLookup(ctxt->pctxt, (xmlChar *) "xsl")) xmlXPathRegisterNs(ctxt->pctxt, (xmlChar *) "xsl", XSLT_NAMESPACE); list = xmlXPathEval(arg, ctxt->pctxt); if (list != NULL) { switch (list->type) { case XPATH_NODESET:{ int indx; for (indx = 0; indx < list->nodesetval->nodeNr; indx++) { if (dir) xmlShellList(ctxt, NULL, list->nodesetval-> nodeTab[indx], NULL); else xmlShellList(ctxt, NULL, list->nodesetval-> nodeTab[indx], NULL); } result = 1; break; } default: xmlShellPrintXPathError(list->type, (char *) arg); } xmlXPathFreeObject(list); } else { xsldbgGenericErrorFunc(i18n("Error: XPath %1 results in an empty Node Set.\n").arg(xsldbgText(arg))); } ctxt->pctxt->node = NULL; } return result; }
std::string XPathContext::lookup_namespace(const std::string& prefix) { const xmlChar* ns = xmlXPathNsLookup(m_cobj, reinterpret_cast<const xmlChar*>(prefix.c_str())); if (ns == NULL) { throw NoSuchNamespacePrefix(prefix); } return std::string(reinterpret_cast<const char*>(ns)); }
int xslDbgShellCat(xsltTransformContextPtr styleCtxt, xmlShellCtxtPtr ctxt, xmlChar * arg) { xmlXPathObjectPtr list; int result = 0; static const char * QUIET_STR = "-q"; bool silenceCtxtErrors = false; if ((arg == NULL) || (xmlStrLen(arg) == 0)) arg = (xmlChar *) "."; /* Do we quietly ingore style context errors */ if (strncasecmp((char*)arg, QUIET_STR, strlen(QUIET_STR))== 0){ silenceCtxtErrors = true; arg = arg + strlen(QUIET_STR); while (isspace(*arg)){ arg++; } } if (!styleCtxt || !ctxt || !ctxt->node) { if (!(!xsldbgReachedFirstTemplate && silenceCtxtErrors)) xsldbgGenericErrorFunc(i18n("Warning: Unable to print expression. No stylesheet was properly loaded.\n")); return 0; } if ((arg == NULL) || (xmlStrLen(arg) == 0)) arg = (xmlChar *) "."; ctxt->pctxt->node = ctxt->node; if (!styleCtxt) { list = xmlXPathEval((xmlChar *) arg, ctxt->pctxt); } else { xmlNodePtr savenode = styleCtxt->xpathCtxt->node; ctxt->pctxt->node = ctxt->node; styleCtxt->xpathCtxt->node = ctxt->node; if (!xmlXPathNsLookup(styleCtxt->xpathCtxt, (xmlChar *) "xsl")) xmlXPathRegisterNs(styleCtxt->xpathCtxt, (xmlChar *) "xsl", XSLT_NAMESPACE); list = xmlXPathEval((xmlChar *) arg, styleCtxt->xpathCtxt); styleCtxt->xpathCtxt->node = savenode; } if (list != NULL) { result = printXPathObject(list, arg); xmlXPathFreeObject(list); } else { xsldbgGenericErrorFunc(i18n("Error: XPath %1 results in an empty Node Set.\n").arg(xsldbgText(arg))); } ctxt->pctxt->node = NULL; return result; }
/** * xsltFunctionAvailableFunction: * @ctxt: the XPath Parser context * @nargs: the number of arguments * * Implement the function-available() XSLT function * boolean function-available(string) */ void xsltFunctionAvailableFunction(xmlXPathParserContextPtr ctxt, int nargs){ xmlXPathObjectPtr obj; xmlChar *prefix, *name; const xmlChar *nsURI = NULL; if (nargs != 1) { xsltPrintErrorContext(xsltXPathGetTransformContext(ctxt), NULL, NULL); xsltGenericError(xsltGenericErrorContext, "function-available() : expects one string arg\n"); ctxt->error = XPATH_INVALID_ARITY; return; } if ((ctxt->value == NULL) || (ctxt->value->type != XPATH_STRING)) { xsltPrintErrorContext(xsltXPathGetTransformContext(ctxt), NULL, NULL); xsltGenericError(xsltGenericErrorContext, "function-available() : invalid arg expecting a string\n"); ctxt->error = XPATH_INVALID_TYPE; return; } obj = valuePop(ctxt); name = xmlSplitQName2(obj->stringval, &prefix); if (name == NULL) { name = xmlStrdup(obj->stringval); } else { nsURI = xmlXPathNsLookup(ctxt->context, prefix); if (nsURI == NULL) { xsltPrintErrorContext(xsltXPathGetTransformContext(ctxt), NULL, NULL); xsltGenericError(xsltGenericErrorContext, "function-available() : prefix %s is not bound\n", prefix); } } if (xmlXPathFunctionLookupNS(ctxt->context, name, nsURI) != NULL) { valuePush(ctxt, xmlXPathNewBoolean(1)); } else { valuePush(ctxt, xmlXPathNewBoolean(0)); } xmlXPathFreeObject(obj); if (name != NULL) xmlFree(name); if (prefix != NULL) xmlFree(prefix); }
/** * xsltSystemPropertyFunction: * @ctxt: the XPath Parser context * @nargs: the number of arguments * * Implement the system-property() XSLT function * object system-property(string) */ void xsltSystemPropertyFunction(xmlXPathParserContextPtr ctxt, int nargs){ xmlXPathObjectPtr obj; xmlChar *prefix, *name; const xmlChar *nsURI = NULL; if (nargs != 1) { xsltTransformError(xsltXPathGetTransformContext(ctxt), NULL, NULL, "system-property() : expects one string arg\n"); ctxt->error = XPATH_INVALID_ARITY; return; } if ((ctxt->value == NULL) || (ctxt->value->type != XPATH_STRING)) { xsltTransformError(xsltXPathGetTransformContext(ctxt), NULL, NULL, "system-property() : invalid arg expecting a string\n"); ctxt->error = XPATH_INVALID_TYPE; return; } obj = valuePop(ctxt); if (obj->stringval == NULL) { valuePush(ctxt, xmlXPathNewString((const xmlChar *)"")); } else { name = xmlSplitQName2(obj->stringval, &prefix); if (name == NULL) { name = xmlStrdup(obj->stringval); } else { nsURI = xmlXPathNsLookup(ctxt->context, prefix); if (nsURI == NULL) { xsltTransformError(xsltXPathGetTransformContext(ctxt), NULL, NULL, "system-property() : prefix %s is not bound\n", prefix); } } if (xmlStrEqual(nsURI, XSLT_NAMESPACE)) { #ifdef DOCBOOK_XSL_HACK if (xmlStrEqual(name, (const xmlChar *)"vendor")) { xsltStylesheetPtr sheet; xsltTransformContextPtr tctxt; tctxt = xsltXPathGetTransformContext(ctxt); if ((tctxt != NULL) && (tctxt->inst != NULL) && (xmlStrEqual(tctxt->inst->name, BAD_CAST "variable")) && (tctxt->inst->parent != NULL) && (xmlStrEqual(tctxt->inst->parent->name, BAD_CAST "template"))) sheet = tctxt->style; else sheet = NULL; if ((sheet != NULL) && (sheet->doc != NULL) && (sheet->doc->URL != NULL) && (xmlStrstr(sheet->doc->URL, (const xmlChar *)"chunk") != NULL)) { valuePush(ctxt, xmlXPathNewString( (const xmlChar *)"libxslt (SAXON 6.2 compatible)")); } else { valuePush(ctxt, xmlXPathNewString( (const xmlChar *)XSLT_DEFAULT_VENDOR)); } } else #else if (xmlStrEqual(name, (const xmlChar *)"vendor")) { valuePush(ctxt, xmlXPathNewString( (const xmlChar *)XSLT_DEFAULT_VENDOR)); } else #endif if (xmlStrEqual(name, (const xmlChar *)"version")) { valuePush(ctxt, xmlXPathNewString( (const xmlChar *)XSLT_DEFAULT_VERSION)); } else if (xmlStrEqual(name, (const xmlChar *)"vendor-url")) { valuePush(ctxt, xmlXPathNewString( (const xmlChar *)XSLT_DEFAULT_URL)); } else { valuePush(ctxt, xmlXPathNewString((const xmlChar *)"")); } } else { valuePush(ctxt, xmlXPathNewString((const xmlChar *)"")); } if (name != NULL) xmlFree(name); if (prefix != NULL) xmlFree(prefix); } xmlXPathFreeObject(obj); }
/** * xsltKeyFunction: * @ctxt: the XPath Parser context * @nargs: the number of arguments * * Implement the key() XSLT function * node-set key(string, object) */ void xsltKeyFunction(xmlXPathParserContextPtr ctxt, int nargs){ xmlXPathObjectPtr obj1, obj2; if (nargs != 2) { xsltTransformError(xsltXPathGetTransformContext(ctxt), NULL, NULL, "key() : expects two arguments\n"); ctxt->error = XPATH_INVALID_ARITY; return; } /* * Get the key's value. */ obj2 = valuePop(ctxt); xmlXPathStringFunction(ctxt, 1); if ((obj2 == NULL) || (ctxt->value == NULL) || (ctxt->value->type != XPATH_STRING)) { xsltTransformError(xsltXPathGetTransformContext(ctxt), NULL, NULL, "key() : invalid arg expecting a string\n"); ctxt->error = XPATH_INVALID_TYPE; xmlXPathFreeObject(obj2); return; } /* * Get the key's name. */ obj1 = valuePop(ctxt); if ((obj2->type == XPATH_NODESET) || (obj2->type == XPATH_XSLT_TREE)) { int i; xmlXPathObjectPtr newobj, ret; ret = xmlXPathNewNodeSet(NULL); if (obj2->nodesetval != NULL) { for (i = 0; i < obj2->nodesetval->nodeNr; i++) { valuePush(ctxt, xmlXPathObjectCopy(obj1)); valuePush(ctxt, xmlXPathNewNodeSet(obj2->nodesetval->nodeTab[i])); xmlXPathStringFunction(ctxt, 1); xsltKeyFunction(ctxt, 2); newobj = valuePop(ctxt); ret->nodesetval = xmlXPathNodeSetMerge(ret->nodesetval, newobj->nodesetval); xmlXPathFreeObject(newobj); } } valuePush(ctxt, ret); } else { xmlNodeSetPtr nodelist = NULL; xmlChar *key = NULL, *value; const xmlChar *keyURI; xsltTransformContextPtr tctxt; xmlChar *qname, *prefix; xmlXPathContextPtr xpctxt = ctxt->context; xmlNodePtr tmpNode = NULL; xsltDocumentPtr oldDocInfo; tctxt = xsltXPathGetTransformContext(ctxt); oldDocInfo = tctxt->document; if (xpctxt->node == NULL) { xsltTransformError(tctxt, NULL, tctxt->inst, "Internal error in xsltKeyFunction(): " "The context node is not set on the XPath context.\n"); tctxt->state = XSLT_STATE_STOPPED; goto error; } /* * Get the associated namespace URI if qualified name */ qname = obj1->stringval; key = xmlSplitQName2(qname, &prefix); if (key == NULL) { key = xmlStrdup(obj1->stringval); keyURI = NULL; if (prefix != NULL) xmlFree(prefix); } else { if (prefix != NULL) { keyURI = xmlXPathNsLookup(xpctxt, prefix); if (keyURI == NULL) { xsltTransformError(tctxt, NULL, tctxt->inst, "key() : prefix %s is not bound\n", prefix); /* * TODO: Shouldn't we stop here? */ } xmlFree(prefix); } else { keyURI = NULL; } } /* * Force conversion of first arg to string */ valuePush(ctxt, obj2); xmlXPathStringFunction(ctxt, 1); if ((ctxt->value == NULL) || (ctxt->value->type != XPATH_STRING)) { xsltTransformError(tctxt, NULL, tctxt->inst, "key() : invalid arg expecting a string\n"); ctxt->error = XPATH_INVALID_TYPE; goto error; } obj2 = valuePop(ctxt); value = obj2->stringval; /* * We need to ensure that ctxt->document is available for * xsltGetKey(). * First find the relevant doc, which is the context node's * owner doc; using context->doc is not safe, since * the doc could have been acquired via the document() function, * or the doc might be a Result Tree Fragment. * FUTURE INFO: In XSLT 2.0 the key() function takes an additional * argument indicating the doc to use. */ if (xpctxt->node->type == XML_NAMESPACE_DECL) { /* * REVISIT: This is a libxml hack! Check xpath.c for details. * The XPath module sets the owner element of a ns-node on * the ns->next field. */ if ((((xmlNsPtr) xpctxt->node)->next != NULL) && (((xmlNsPtr) xpctxt->node)->next->type == XML_ELEMENT_NODE)) { tmpNode = (xmlNodePtr) ((xmlNsPtr) xpctxt->node)->next; } } else tmpNode = xpctxt->node; if ((tmpNode == NULL) || (tmpNode->doc == NULL)) { xsltTransformError(tctxt, NULL, tctxt->inst, "Internal error in xsltKeyFunction(): " "Couldn't get the doc of the XPath context node.\n"); goto error; } if ((tctxt->document == NULL) || (tctxt->document->doc != tmpNode->doc)) { if (tmpNode->doc->name && (tmpNode->doc->name[0] == ' ')) { /* * This is a Result Tree Fragment. */ if (tmpNode->doc->_private == NULL) { tmpNode->doc->_private = xsltNewDocument(tctxt, tmpNode->doc); if (tmpNode->doc->_private == NULL) goto error; } tctxt->document = (xsltDocumentPtr) tmpNode->doc->_private; } else { /* * May be the initial source doc or a doc acquired via the * document() function. */ tctxt->document = xsltFindDocument(tctxt, tmpNode->doc); } if (tctxt->document == NULL) { xsltTransformError(tctxt, NULL, tctxt->inst, "Internal error in xsltKeyFunction(): " "Could not get the document info of a context doc.\n"); tctxt->state = XSLT_STATE_STOPPED; goto error; } } /* * Get/compute the key value. */ nodelist = xsltGetKey(tctxt, key, keyURI, value); error: tctxt->document = oldDocInfo; valuePush(ctxt, xmlXPathWrapNodeSet( xmlXPathNodeSetMerge(NULL, nodelist))); if (key != NULL) xmlFree(key); } if (obj1 != NULL) xmlXPathFreeObject(obj1); if (obj2 != NULL) xmlXPathFreeObject(obj2); }
/** * xsltKeyFunction: * @ctxt: the XPath Parser context * @nargs: the number of arguments * * Implement the key() XSLT function * node-set key(string, object) */ void xsltKeyFunction(xmlXPathParserContextPtr ctxt, int nargs){ xmlNodeSetPtr nodelist; xmlXPathObjectPtr obj1, obj2; xmlChar *key = NULL, *value; const xmlChar *keyURI; xsltTransformContextPtr tctxt; if (nargs != 2) { xsltPrintErrorContext(xsltXPathGetTransformContext(ctxt), NULL, NULL); xsltGenericError(xsltGenericErrorContext, "key() : expects two arguments\n"); ctxt->error = XPATH_INVALID_ARITY; return; } obj2 = valuePop(ctxt); if ((obj2 == NULL) || (ctxt->value == NULL) || (ctxt->value->type != XPATH_STRING)) { xsltPrintErrorContext(xsltXPathGetTransformContext(ctxt), NULL, NULL); xsltGenericError(xsltGenericErrorContext, "key() : invalid arg expecting a string\n"); ctxt->error = XPATH_INVALID_TYPE; xmlXPathFreeObject(obj2); return; } obj1 = valuePop(ctxt); if (obj2->type == XPATH_NODESET) { int i; xmlXPathObjectPtr newobj, ret; ret = xmlXPathNewNodeSet(NULL); if (obj2->nodesetval != NULL) { for (i = 0; i < obj2->nodesetval->nodeNr; i++) { valuePush(ctxt, xmlXPathObjectCopy(obj1)); valuePush(ctxt, xmlXPathNewNodeSet(obj2->nodesetval->nodeTab[i])); xmlXPathStringFunction(ctxt, 1); xsltKeyFunction(ctxt, 2); newobj = valuePop(ctxt); ret->nodesetval = xmlXPathNodeSetMerge(ret->nodesetval, newobj->nodesetval); xmlXPathFreeObject(newobj); } } valuePush(ctxt, ret); } else { xmlChar *qname, *prefix; /* * Get the associated namespace URI if qualified name */ qname = obj1->stringval; key = xmlSplitQName2(qname, &prefix); if (key == NULL) { key = xmlStrdup(obj1->stringval); keyURI = NULL; if (prefix != NULL) xmlFree(prefix); } else { if (prefix != NULL) { keyURI = xmlXPathNsLookup(ctxt->context, prefix); if (keyURI == NULL) { xsltPrintErrorContext(xsltXPathGetTransformContext(ctxt), NULL, NULL); xsltGenericError(xsltGenericErrorContext, "key() : prefix %s is not bound\n", prefix); } xmlFree(prefix); } else { keyURI = NULL; } } /* * Force conversion of first arg to string */ valuePush(ctxt, obj2); xmlXPathStringFunction(ctxt, 1); if ((ctxt->value == NULL) || (ctxt->value->type != XPATH_STRING)) { xsltPrintErrorContext(xsltXPathGetTransformContext(ctxt), NULL, NULL); xsltGenericError(xsltGenericErrorContext, "key() : invalid arg expecting a string\n"); ctxt->error = XPATH_INVALID_TYPE; xmlXPathFreeObject(obj1); return; } obj2 = valuePop(ctxt); value = obj2->stringval; tctxt = xsltXPathGetTransformContext(ctxt); nodelist = xsltGetKey(tctxt, key, keyURI, value); valuePush(ctxt, xmlXPathWrapNodeSet( xmlXPathNodeSetMerge(NULL, nodelist))); } if (obj1 != NULL) xmlXPathFreeObject(obj1); if (obj2 != NULL) xmlXPathFreeObject(obj2); if (key != NULL) xmlFree(key); }