void RXSLT_callNamedFunction(const char *name, xmlXPathParserContextPtr ctxt, int nargs, int leaveAsRObject) { USER_OBJECT_ e, ans; // xmlXPathObjectPtr obj; int errorOccurred; int i, j; #if 0 PROTECT(e = allocVector(LANGSXP, 2)); SETCAR(e, Rf_install((char *) name)); SETCAR(CDR(e), tmp = NEW_CHARACTER(1)); obj = valuePop(ctxt); SET_STRING_ELT(tmp, 0, COPY_TO_USER_STRING(xmlXPathCastToString(obj))); #else PROTECT(e = allocVector(LANGSXP, nargs+1)); SETCAR(e, Rf_install((char *) name)); #if 0 for(i = 0; i < nargs; i++) { ans = CDR(e); for(j = nargs-1; j > i ; j--) { ans = CDR(ans); } SETCAR(ans, tmp = NEW_CHARACTER(1)); obj = valuePop(ctxt); SET_STRING_ELT(tmp, 0, COPY_TO_USER_STRING(xmlXPathCastToString(obj))); } #else for(i = 0; i < nargs; i++) { ans = CDR(e); for(j = nargs-1; j > i ; j--) { ans = CDR(ans); } SETCAR(ans, convertFromXPath(ctxt, valuePop(ctxt))); } #endif #endif ans = R_tryEval(e, R_GlobalEnv, &errorOccurred); if(errorOccurred) { RXSLT_Error(ctxt, "error in call to R function"); } else { PROTECT(ans); valuePush(ctxt, convertToXPath(ctxt, ans)); UNPROTECT(1); } UNPROTECT(1); return; }
int check_user_group(xmlXPathContextPtr xpath_ctx, const xmlChar *user_xexpr, const xmlChar *group_xexpr) { int status = 0; xmlXPathObjectPtr xpath_obj; char* temp_char = NULL; struct passwd *pwd; struct group *grp; /* Group if specified */ xpath_obj = xmlXPathEvalExpression(group_xexpr, xpath_ctx); if(xpath_obj == NULL) { dual_log("ERROR: unable to evaluate xpath expression: %s", group_xexpr); return(1); } if (xpath_obj->nodesetval != NULL && xpath_obj->nodesetval->nodeNr > 0) { temp_char = (char*) xmlXPathCastToString(xpath_obj); if ((grp = getgrnam(temp_char)) == NULL) { dual_log("ERROR: Group '%s' does not exist\n", temp_char); status += 1; } endgrent(); StrFree(temp_char); } xmlXPathFreeObject(xpath_obj); /* User if specified */ xpath_obj = xmlXPathEvalExpression(user_xexpr, xpath_ctx); if(xpath_obj == NULL) { dual_log("ERROR: unable to evaluate xpath expression: %s", user_xexpr); return(1); } if (xpath_obj->nodesetval != NULL && xpath_obj->nodesetval->nodeNr > 0) { temp_char = (char*) xmlXPathCastToString(xpath_obj); if ((pwd = getpwnam(temp_char)) == NULL) { dual_log("ERROR: User '%s' does not exist\n", temp_char); status += 1; } endpwent(); StrFree(temp_char); } xmlXPathFreeObject(xpath_obj); return status; }
int check_file_from_xpath(xmlXPathContextPtr xpath_ctx, const char *log_string, const xmlChar *file_xexpr) { int status = 0; xmlXPathObjectPtr xpath_obj; char* temp_char = NULL; char* str = NULL; xpath_obj = xmlXPathEvalExpression(file_xexpr, xpath_ctx); if(xpath_obj == NULL) { dual_log("ERROR: unable to evaluate xpath expression: %s", file_xexpr); return 1; } if (xpath_obj->nodesetval != NULL && xpath_obj->nodesetval->nodeNr > 0) { temp_char = (char*) xmlXPathCastToString(xpath_obj); /* strip off any trailing characters (needed for DSSub with cks_id) */ str = strrchr(temp_char, ' '); if (str) { *str = 0; } status = check_file(temp_char, log_string); StrFree(temp_char); } else { /* Not set; return -1 so that we can test the default path */ xmlXPathFreeObject(xpath_obj); return -1; } xmlXPathFreeObject(xpath_obj); return status; }
int check_path_from_xpath(xmlXPathContextPtr xpath_ctx, const char *log_string, const xmlChar *path_xexpr) { int status = 0; xmlXPathObjectPtr xpath_obj; char* temp_char = NULL; xpath_obj = xmlXPathEvalExpression(path_xexpr, xpath_ctx); if(xpath_obj == NULL) { dual_log("ERROR: unable to evaluate xpath expression: %s", path_xexpr); return 1; } if (xpath_obj->nodesetval != NULL && xpath_obj->nodesetval->nodeNr > 0) { temp_char = (char*) xmlXPathCastToString(xpath_obj); status = check_path(temp_char, log_string); StrFree(temp_char); } else { /* Not set; return -1 so that we can test the default path */ xmlXPathFreeObject(xpath_obj); return -1; } xmlXPathFreeObject(xpath_obj); return status; }
bool XmlDocument::XPath(StringPiece const &v, std::wstring *r) { WStringPiece str; xmlXPathObjectPtr xpath = xmlXPathEvalExpression((unsigned char const*)v.data(), libxml_stuff->xpath_context); if (xpath) { xmlChar *s_ = xmlXPathCastToString(xpath); if (s_) { StringPiece s((char*)s_); wchar_t *output = conv_buf.Alloc(s.length()); int const conv_result = cpcl::TryConvertUTF8_UTF16(s, output, conv_buf.Size()); if (conv_result == -1) { output = 0; Trace(CPCL_TRACE_LEVEL_ERROR, "XmlDocument::XPath(%s): utf_to_uc fails", v.as_string().c_str()); } else { output = conv_buf.Data() + conv_result; if (conv_result > ((int)(conv_buf.Size()&INT_MAX))) Trace(CPCL_TRACE_LEVEL_WARNING, "XmlDocument::XPath(%s): TryConvertUTF8_UTF16 okashi desu ne...", v.as_string().c_str()); } xmlFree(s_); if (output) { //*output = 0; str = WStringPiece(conv_buf.Data(), output - conv_buf.Data()); } } xmlXPathFreeObject(xpath); } if (TrimResults) str = str.trim(TrimChars); if ((!str.empty()) && (r)) r->assign(str.data(), str.size()); return (!str.empty()); }
/// Return the text result (if any) of the xpath expression TIXML_STRING S_xpath_expr (const xmlDoc * Dp_ptr, const char * cp_xpath_expr) { xmlXPathObjectPtr XPOp_ptr; xmlXPathContextPtr XPCp_ptr; const xmlChar * Cp_ptr; TIXML_STRING S_out; S_out = ""; if (Dp_ptr) { XPCp_ptr = xmlXPathNewContext ((xmlDoc *) Dp_ptr); if (XPCp_ptr) { // Evaluate XPOp_ptr = xmlXPathEval ((const xmlChar *) cp_xpath_expr, XPCp_ptr); if (XPOp_ptr) { Cp_ptr = xmlXPathCastToString (XPOp_ptr); if (Cp_ptr) S_out = (const char *) Cp_ptr; xmlXPathFreeObject (XPOp_ptr); } } if (XPCp_ptr) xmlXPathFreeContext (XPCp_ptr); } return S_out; }
/*Experimental*/ int messageGetSingleValue(char *messageReceived, int messageSize, char *path, char *value, int valueMaxSize, int decodeB64) { char *tempB64, *temp; int finalSize; xmlDocPtr doc = NULL;/* node pointers */ xmlXPathContextPtr xpathCtx; xmlXPathObjectPtr xpathObj; LIBXML_TEST_VERSION; xmlInitParser(); doc = xmlRecoverMemory(messageReceived, messageSize); if (doc == NULL) { return -1;} xpathCtx = xmlXPathNewContext(doc); if(xpathCtx == NULL) { xmlFreeDoc(doc); return -1; }; xpathObj = xmlXPathEvalExpression(BAD_CAST path, xpathCtx); if(xpathObj == NULL){ xmlXPathFreeContext(xpathCtx); xmlFreeDoc(doc); return(-1); }; tempB64 = (char *) xmlXPathCastToString (xpathObj); if(decodeB64) { temp = b64decode((unsigned char *) tempB64, strlen(tempB64) , &finalSize); free(tempB64); } else { temp = tempB64; finalSize = strlen(temp); } if( finalSize + 1 <= valueMaxSize) { memcpy (value, temp, finalSize); value[finalSize] = '\0'; } else finalSize = -1; free(temp); xmlXPathFreeObject(xpathObj); xmlXPathFreeContext(xpathCtx); xmlFreeDoc(doc); xmlCleanupParser(); return finalSize; }
void RXSLT_source(xmlXPathParserContextPtr ctxt, int nargs) { Rboolean ok; xmlXPathObjectPtr obj; obj = valuePop(ctxt); ok = RXSLT_internalSource(xmlXPathCastToString(obj)); valuePush(ctxt, xmlXPathNewBoolean(ok)); }
/** * Parse elements from the configuration file. * */ const char* parse_conf_string(const char* cfgfile, const char* expr, int required) { xmlDocPtr doc = NULL; xmlXPathContextPtr xpathCtx = NULL; xmlXPathObjectPtr xpathObj = NULL; xmlChar *xexpr = NULL; const char* string = NULL; ods_log_assert(expr); ods_log_assert(cfgfile); /* Load XML document */ doc = xmlParseFile(cfgfile); if (doc == NULL) { return NULL; } /* Create xpath evaluation context */ xpathCtx = xmlXPathNewContext(doc); if (xpathCtx == NULL) { ods_log_error("[%s] unable to create new XPath context for cfgile " "%s expr %s", parser_str, cfgfile, (char*) expr); xmlFreeDoc(doc); return NULL; } /* Get string */ xexpr = (unsigned char*) expr; xpathObj = xmlXPathEvalExpression(xexpr, xpathCtx); if (xpathObj == NULL || xpathObj->nodesetval == NULL || xpathObj->nodesetval->nodeNr <= 0) { if (required) { ods_log_error("[%s] unable to evaluate required element %s in " "cfgfile %s", parser_str, (char*) xexpr, cfgfile); } xmlXPathFreeContext(xpathCtx); if (xpathObj) { xmlXPathFreeObject(xpathObj); } xmlFreeDoc(doc); return NULL; } if (xpathObj->nodesetval != NULL && xpathObj->nodesetval->nodeNr > 0) { string = (const char*) xmlXPathCastToString(xpathObj); xmlXPathFreeContext(xpathCtx); xmlXPathFreeObject(xpathObj); xmlFreeDoc(doc); return string; } xmlXPathFreeContext(xpathCtx); xmlXPathFreeObject(xpathObj); xmlFreeDoc(doc); return NULL; }
char *_openslide_xml_xpath_get_string(xmlXPathContext *ctx, const char *xpath) { xmlXPathObject *result = xmlXPathEvalExpression(BAD_CAST xpath, ctx); char *str = NULL; if (result && result->nodesetval && result->nodesetval->nodeNr) { xmlChar *xmlstr = xmlXPathCastToString(result); str = g_strdup((char *) xmlstr); xmlFree(xmlstr); } xmlXPathFreeObject(result); return str; }
void _openslide_xml_set_prop_from_xpath(openslide_t *osr, xmlXPathContext *ctx, const char *property_name, const char *xpath) { xmlXPathObject *result = xmlXPathEvalExpression(BAD_CAST xpath, ctx); if (osr && result && result->nodesetval && result->nodesetval->nodeNr) { xmlChar *str = xmlXPathCastToString(result); g_hash_table_insert(osr->properties, g_strdup(property_name), g_strdup((char *) str)); xmlFree(str); } xmlXPathFreeObject(result); }
void RXSLT_init(xmlXPathParserContextPtr ctxt, int nargs) { const char *defaultArgs[] = {"Rxsltproc", "--silent"}; char **args; int argc, i; int mustFree; if(R_alreadyInitialized) return; #ifdef XSLT_DEBUG fprintf(stderr, "in RXSLT_init %d\n", nargs);fflush(stderr); #endif if(nargs == 0) { argc = sizeof(defaultArgs)/sizeof(defaultArgs[0]); args = (char **)defaultArgs; } else { args = (char **) malloc((nargs+1) * sizeof(char*)); args[0] = strdup("Rxsltproc"); argc = nargs+1; for(i = 0; i < nargs; i++) { xmlXPathObjectPtr obj = valuePop(ctxt); if(obj->type) { args[i+1] = strdup(xmlXPathCastToString(obj)); } } mustFree = TRUE; } Rf_initEmbeddedR(argc, args); loadXSLPackage(); valuePush(ctxt, xmlXPathNewBoolean(1)); if(mustFree) { for(i = 0; i < nargs+1; i++) { free(args[i]); } free(args); } #if DEBUG_REGISTRATION xsltRegisterExtFunction(getTransformCtxt(), "foo", R_URI, RXSLT_genericFunctionCall); RXSLT_addFunction("foo", NULL_USER_OBJECT); #endif R_alreadyInitialized = 1; return; }
int check_time_def_from_xpath(xmlXPathContextPtr xpath_ctx, const xmlChar *time_xexpr, const char *location, const char *field, const char *filename) { xmlXPathObjectPtr xpath_obj; char* temp_char = NULL; int status = 0; int ignore = 0; xpath_obj = xmlXPathEvalExpression(time_xexpr, xpath_ctx); if(xpath_obj == NULL) { dual_log("ERROR: unable to evaluate xpath expression: %s", time_xexpr); return 1; } if (xpath_obj->nodesetval != NULL && xpath_obj->nodesetval->nodeNr > 0) { temp_char = (char *)xmlXPathCastToString(xpath_obj); status += check_time_def(temp_char, location, field, filename, &ignore); StrFree(temp_char); } xmlXPathFreeObject(xpath_obj); return status; }
// --------------------------------------------------------------------------- // Retrieves copy of result as TXmlEngParserString. // In this version of API this method will make conversion from other types of // XPath result. In the future release there will be separate method for // conversion (this method will return TDOMString and conversion method - // TString) // NOTE: Returns a pointer to the copy of the string, the caller must free it // --------------------------------------------------------------------------- // EXPORT_C void RXmlEngXPathResult::AsStringL(RBuf8& aOutput) const { xmlChar* copy = NULL; if (RESULT_OBJ->type == XPATH_STRING) { if(RESULT_OBJ->stringval) { copy = xmlStrdup(RESULT_OBJ->stringval); OOM_IF_NULL(copy); } } else { copy = xmlXPathCastToString(RESULT_OBJ); if(OOM_FLAG) { if(copy) xmlFree(copy); OOM_HAPPENED; } } xmlCharAssignToRbuf8L(aOutput,copy); }
static void ruby_funcall(xmlXPathParserContextPtr ctx, int nargs) { VALUE xpath_handler = Qnil; VALUE result; VALUE *argv; VALUE doc; VALUE node_set = Qnil; xmlNodeSetPtr xml_node_set = NULL; xmlXPathObjectPtr obj; int i; nokogiriNodeSetTuple *node_set_tuple; assert(ctx); assert(ctx->context); assert(ctx->context->userData); assert(ctx->context->doc); assert(DOC_RUBY_OBJECT_TEST(ctx->context->doc)); xpath_handler = (VALUE)(ctx->context->userData); argv = (VALUE *)calloc((size_t)nargs, sizeof(VALUE)); for (i = 0 ; i < nargs ; ++i) { rb_gc_register_address(&argv[i]); } doc = DOC_RUBY_OBJECT(ctx->context->doc); if (nargs > 0) { i = nargs - 1; do { obj = valuePop(ctx); switch(obj->type) { case XPATH_STRING: argv[i] = NOKOGIRI_STR_NEW2(obj->stringval); break; case XPATH_BOOLEAN: argv[i] = obj->boolval == 1 ? Qtrue : Qfalse; break; case XPATH_NUMBER: argv[i] = rb_float_new(obj->floatval); break; case XPATH_NODESET: argv[i] = Nokogiri_wrap_xml_node_set(obj->nodesetval, doc); break; default: argv[i] = NOKOGIRI_STR_NEW2(xmlXPathCastToString(obj)); } xmlXPathFreeNodeSetList(obj); } while(i-- > 0); } result = rb_funcall2( xpath_handler, rb_intern((const char *)ctx->context->function), nargs, argv ); for (i = 0 ; i < nargs ; ++i) { rb_gc_unregister_address(&argv[i]); } free(argv); switch(TYPE(result)) { case T_FLOAT: case T_BIGNUM: case T_FIXNUM: xmlXPathReturnNumber(ctx, NUM2DBL(result)); break; case T_STRING: xmlXPathReturnString( ctx, (xmlChar *)xmlXPathWrapCString(StringValuePtr(result)) ); break; case T_TRUE: xmlXPathReturnTrue(ctx); break; case T_FALSE: xmlXPathReturnFalse(ctx); break; case T_NIL: break; case T_ARRAY: { VALUE args[2]; args[0] = doc; args[1] = result; node_set = rb_class_new_instance(2, args, cNokogiriXmlNodeSet); Data_Get_Struct(node_set, nokogiriNodeSetTuple, node_set_tuple); xml_node_set = node_set_tuple->node_set; xmlXPathReturnNodeSet(ctx, xmlXPathNodeSetMerge(NULL, xml_node_set)); } break; case T_DATA: if(rb_obj_is_kind_of(result, cNokogiriXmlNodeSet)) { Data_Get_Struct(result, nokogiriNodeSetTuple, node_set_tuple); xml_node_set = node_set_tuple->node_set; /* Copy the node set, otherwise it will get GC'd. */ xmlXPathReturnNodeSet(ctx, xmlXPathNodeSetMerge(NULL, xml_node_set)); break; } default: rb_raise(rb_eRuntimeError, "Invalid return type"); } }
static void dom_xpath_ext_function_php(xmlXPathParserContextPtr ctxt, int nargs, int type) /* {{{ */ { zval retval; int result, i; int error = 0; zend_fcall_info fci; xmlXPathObjectPtr obj; char *str; zend_string *callable = NULL; dom_xpath_object *intern; if (! zend_is_executing()) { xmlGenericError(xmlGenericErrorContext, "xmlExtFunctionTest: Function called from outside of PHP\n"); error = 1; } else { intern = (dom_xpath_object *) ctxt->context->userData; if (intern == NULL) { xmlGenericError(xmlGenericErrorContext, "xmlExtFunctionTest: failed to get the internal object\n"); error = 1; } else if (intern->registerPhpFunctions == 0) { xmlGenericError(xmlGenericErrorContext, "xmlExtFunctionTest: PHP Object did not register PHP functions\n"); error = 1; } } if (error == 1) { for (i = nargs - 1; i >= 0; i--) { obj = valuePop(ctxt); xmlXPathFreeObject(obj); } return; } fci.param_count = nargs - 1; if (fci.param_count > 0) { fci.params = safe_emalloc(fci.param_count, sizeof(zval), 0); } /* Reverse order to pop values off ctxt stack */ for (i = nargs - 2; i >= 0; i--) { obj = valuePop(ctxt); switch (obj->type) { case XPATH_STRING: ZVAL_STRING(&fci.params[i], (char *)obj->stringval); break; case XPATH_BOOLEAN: ZVAL_BOOL(&fci.params[i], obj->boolval); break; case XPATH_NUMBER: ZVAL_DOUBLE(&fci.params[i], obj->floatval); break; case XPATH_NODESET: if (type == 1) { str = (char *)xmlXPathCastToString(obj); ZVAL_STRING(&fci.params[i], str); xmlFree(str); } else if (type == 2) { int j; array_init(&fci.params[i]); if (obj->nodesetval && obj->nodesetval->nodeNr > 0) { for (j = 0; j < obj->nodesetval->nodeNr; j++) { xmlNodePtr node = obj->nodesetval->nodeTab[j]; zval child; /* not sure, if we need this... it's copied from xpath.c */ if (node->type == XML_NAMESPACE_DECL) { xmlNsPtr curns; xmlNodePtr nsparent; nsparent = node->_private; curns = xmlNewNs(NULL, node->name, NULL); if (node->children) { curns->prefix = xmlStrdup((xmlChar *) node->children); } if (node->children) { node = xmlNewDocNode(node->doc, NULL, (xmlChar *) node->children, node->name); } else { node = xmlNewDocNode(node->doc, NULL, (xmlChar *) "xmlns", node->name); } node->type = XML_NAMESPACE_DECL; node->parent = nsparent; node->ns = curns; } php_dom_create_object(node, &child, &intern->dom); add_next_index_zval(&fci.params[i], &child); } } } break; default: ZVAL_STRING(&fci.params[i], (char *)xmlXPathCastToString(obj)); } xmlXPathFreeObject(obj); } fci.size = sizeof(fci); fci.function_table = EG(function_table); obj = valuePop(ctxt); if (obj->stringval == NULL) { php_error_docref(NULL, E_WARNING, "Handler name must be a string"); xmlXPathFreeObject(obj); if (fci.param_count > 0) { for (i = 0; i < nargs - 1; i++) { zval_ptr_dtor(&fci.params[i]); } efree(fci.params); } return; } ZVAL_STRING(&fci.function_name, (char *) obj->stringval); xmlXPathFreeObject(obj); fci.symbol_table = NULL; fci.object = NULL; fci.retval = &retval; fci.no_separation = 0; if (!zend_make_callable(&fci.function_name, &callable)) { php_error_docref(NULL, E_WARNING, "Unable to call handler %s()", callable->val); } else if (intern->registerPhpFunctions == 2 && zend_hash_exists(intern->registered_phpfunctions, callable) == 0) { php_error_docref(NULL, E_WARNING, "Not allowed to call handler '%s()'.", callable->val); /* Push an empty string, so that we at least have an xslt result... */ valuePush(ctxt, xmlXPathNewString((xmlChar *)"")); } else { result = zend_call_function(&fci, NULL); if (result == SUCCESS && Z_TYPE(retval) != IS_UNDEF) { if (Z_TYPE(retval) == IS_OBJECT && instanceof_function(Z_OBJCE(retval), dom_node_class_entry)) { xmlNode *nodep; dom_object *obj; if (intern->node_list == NULL) { ALLOC_HASHTABLE(intern->node_list); zend_hash_init(intern->node_list, 0, NULL, ZVAL_PTR_DTOR, 0); } GC_REFCOUNT(&retval)++; zend_hash_next_index_insert(intern->node_list, &retval); obj = Z_DOMOBJ_P(&retval); nodep = dom_object_get_node(obj); valuePush(ctxt, xmlXPathNewNodeSet(nodep)); } else if (Z_TYPE(retval) == IS_FALSE || Z_TYPE(retval) == IS_TRUE) { valuePush(ctxt, xmlXPathNewBoolean(Z_TYPE(retval) == IS_TRUE)); } else if (Z_TYPE(retval) == IS_OBJECT) { php_error_docref(NULL, E_WARNING, "A PHP Object cannot be converted to a XPath-string"); valuePush(ctxt, xmlXPathNewString((xmlChar *)"")); } else { zend_string *str = zval_get_string(&retval); valuePush(ctxt, xmlXPathNewString((xmlChar *) str->val)); zend_string_release(str); } zval_ptr_dtor(&retval); } } zend_string_release(callable); zval_dtor(&fci.function_name); if (fci.param_count > 0) { for (i = 0; i < nargs - 1; i++) { zval_ptr_dtor(&fci.params[i]); } efree(fci.params); } }
/** * xsltInitCtxtKey: * @ctxt: an XSLT transformation context * @idoc: the document information (holds key values) * @keyDef: the key definition * * Computes the key tables this key and for the current input document. * * Returns: 0 on success, -1 on error */ int xsltInitCtxtKey(xsltTransformContextPtr ctxt, xsltDocumentPtr idoc, xsltKeyDefPtr keyDef) { int i, len, k; xmlNodeSetPtr matchList = NULL, keylist; xmlXPathObjectPtr matchRes = NULL, useRes = NULL; xmlChar *str = NULL; xsltKeyTablePtr table; xmlNodePtr oldInst, cur; xmlNodePtr oldContextNode; xsltDocumentPtr oldDocInfo; int oldXPPos, oldXPSize; xmlDocPtr oldXPDoc; int oldXPNsNr; xmlNsPtr *oldXPNamespaces; xmlXPathContextPtr xpctxt; #ifdef KEY_INIT_DEBUG fprintf(stderr, "xsltInitCtxtKey %s : %d\n", keyDef->name, ctxt->keyInitLevel); #endif if ((keyDef->comp == NULL) || (keyDef->usecomp == NULL)) return(-1); /* * Detect recursive keys */ if (ctxt->keyInitLevel > ctxt->nbKeys) { #ifdef WITH_XSLT_DEBUG_KEYS XSLT_TRACE(ctxt,XSLT_TRACE_KEYS, xsltGenericDebug(xsltGenericDebugContext, "xsltInitCtxtKey: key definition of %s is recursive\n", keyDef->name)); #endif xsltTransformError(ctxt, NULL, keyDef->inst, "Key definition for %s is recursive\n", keyDef->name); ctxt->state = XSLT_STATE_STOPPED; return(-1); } ctxt->keyInitLevel++; xpctxt = ctxt->xpathCtxt; idoc->nbKeysComputed++; /* * Save context state. */ oldInst = ctxt->inst; oldDocInfo = ctxt->document; oldContextNode = ctxt->node; oldXPDoc = xpctxt->doc; oldXPPos = xpctxt->proximityPosition; oldXPSize = xpctxt->contextSize; oldXPNsNr = xpctxt->nsNr; oldXPNamespaces = xpctxt->namespaces; /* * Set up contexts. */ ctxt->document = idoc; ctxt->node = (xmlNodePtr) idoc->doc; ctxt->inst = keyDef->inst; xpctxt->doc = idoc->doc; xpctxt->node = (xmlNodePtr) idoc->doc; /* TODO : clarify the use of namespaces in keys evaluation */ xpctxt->namespaces = keyDef->nsList; xpctxt->nsNr = keyDef->nsNr; /* * Evaluate the 'match' expression of the xsl:key. * TODO: The 'match' is a *pattern*. */ matchRes = xmlXPathCompiledEval(keyDef->comp, xpctxt); if (matchRes == NULL) { #ifdef WITH_XSLT_DEBUG_KEYS XSLT_TRACE(ctxt,XSLT_TRACE_KEYS,xsltGenericDebug(xsltGenericDebugContext, "xsltInitCtxtKey: %s evaluation failed\n", keyDef->match)); #endif xsltTransformError(ctxt, NULL, keyDef->inst, "Failed to evaluate the 'match' expression.\n"); ctxt->state = XSLT_STATE_STOPPED; goto error; } else { if (matchRes->type == XPATH_NODESET) { matchList = matchRes->nodesetval; #ifdef WITH_XSLT_DEBUG_KEYS if (matchList != NULL) XSLT_TRACE(ctxt,XSLT_TRACE_KEYS,xsltGenericDebug(xsltGenericDebugContext, "xsltInitCtxtKey: %s evaluates to %d nodes\n", keyDef->match, matchList->nodeNr)); #endif } else { /* * Is not a node set, but must be. */ #ifdef WITH_XSLT_DEBUG_KEYS XSLT_TRACE(ctxt,XSLT_TRACE_KEYS,xsltGenericDebug(xsltGenericDebugContext, "xsltInitCtxtKey: %s is not a node set\n", keyDef->match)); #endif xsltTransformError(ctxt, NULL, keyDef->inst, "The 'match' expression did not evaluate to a node set.\n"); ctxt->state = XSLT_STATE_STOPPED; goto error; } } if ((matchList == NULL) || (matchList->nodeNr <= 0)) goto exit; /** * Multiple key definitions for the same name are allowed, so * we must check if the key is already present for this doc */ table = (xsltKeyTablePtr) idoc->keys; while (table != NULL) { if (xmlStrEqual(table->name, keyDef->name) && (((keyDef->nameURI == NULL) && (table->nameURI == NULL)) || ((keyDef->nameURI != NULL) && (table->nameURI != NULL) && (xmlStrEqual(table->nameURI, keyDef->nameURI))))) break; table = table->next; } /** * If the key was not previously defined, create it now and * chain it to the list of keys for the doc */ if (table == NULL) { table = xsltNewKeyTable(keyDef->name, keyDef->nameURI); if (table == NULL) goto error; table->next = idoc->keys; idoc->keys = table; } /* * SPEC XSLT 1.0 (XSLT 2.0 does not clarify the context size!) * "...the use attribute of the xsl:key element is evaluated with x as " the current node and with a node list containing just x as the * current node list" */ xpctxt->contextSize = 1; xpctxt->proximityPosition = 1; for (i = 0; i < matchList->nodeNr; i++) { cur = matchList->nodeTab[i]; if (! IS_XSLT_REAL_NODE(cur)) continue; xpctxt->node = cur; /* * Process the 'use' of the xsl:key. * SPEC XSLT 1.0: * "The use attribute is an expression specifying the values of * the key; the expression is evaluated once for each node that * matches the pattern." */ if (useRes != NULL) xmlXPathFreeObject(useRes); useRes = xmlXPathCompiledEval(keyDef->usecomp, xpctxt); if (useRes == NULL) { xsltTransformError(ctxt, NULL, keyDef->inst, "Failed to evaluate the 'use' expression.\n"); ctxt->state = XSLT_STATE_STOPPED; break; } if (useRes->type == XPATH_NODESET) { if ((useRes->nodesetval != NULL) && (useRes->nodesetval->nodeNr != 0)) { len = useRes->nodesetval->nodeNr; str = xmlXPathCastNodeToString(useRes->nodesetval->nodeTab[0]); } else { continue; } } else { len = 1; if (useRes->type == XPATH_STRING) { /* * Consume the string value. */ str = useRes->stringval; useRes->stringval = NULL; } else { str = xmlXPathCastToString(useRes); } } /* * Process all strings. */ k = 0; while (1) { if (str == NULL) goto next_string; #ifdef WITH_XSLT_DEBUG_KEYS XSLT_TRACE(ctxt,XSLT_TRACE_KEYS,xsltGenericDebug(xsltGenericDebugContext, "xsl:key : node associated to ('%s', '%s')\n", keyDef->name, str)); #endif keylist = xmlHashLookup(table->keys, str); if (keylist == NULL) { keylist = xmlXPathNodeSetCreate(cur); if (keylist == NULL) goto error; xmlHashAddEntry(table->keys, str, keylist); } else { /* * TODO: How do we know if this function failed? */ xmlXPathNodeSetAdd(keylist, cur); } switch (cur->type) { case XML_ELEMENT_NODE: case XML_TEXT_NODE: case XML_CDATA_SECTION_NODE: case XML_PI_NODE: case XML_COMMENT_NODE: cur->psvi = keyDef; break; case XML_ATTRIBUTE_NODE: ((xmlAttrPtr) cur)->psvi = keyDef; break; case XML_DOCUMENT_NODE: case XML_HTML_DOCUMENT_NODE: ((xmlDocPtr) cur)->psvi = keyDef; break; default: break; } xmlFree(str); str = NULL; next_string: k++; if (k >= len) break; str = xmlXPathCastNodeToString(useRes->nodesetval->nodeTab[k]); } } exit: error: ctxt->keyInitLevel--; /* * Restore context state. */ xpctxt->doc = oldXPDoc; xpctxt->nsNr = oldXPNsNr; xpctxt->namespaces = oldXPNamespaces; xpctxt->proximityPosition = oldXPPos; xpctxt->contextSize = oldXPSize; ctxt->node = oldContextNode; ctxt->document = oldDocInfo; ctxt->inst = oldInst; if (str) xmlFree(str); if (useRes != NULL) xmlXPathFreeObject(useRes); if (matchRes != NULL) xmlXPathFreeObject(matchRes); return(0); }
static void xslt_ext_function_php(xmlXPathParserContextPtr ctxt, int nargs, int type) { XSLTProcessorData *intern = nullptr; int error = 0; xsltTransformContextPtr tctxt = xsltXPathGetTransformContext (ctxt); if (tctxt == nullptr) { xsltGenericError(xsltGenericErrorContext, "xsltExtFunctionTest: failed to get the transformation context\n" ); error = 1; } else { intern = (XSLTProcessorData*)tctxt->_private; if (intern == nullptr) { xsltGenericError(xsltGenericErrorContext, "xsltExtFunctionTest: failed to get the internal object\n" ); error = 1; } else { if (intern->m_registerPhpFunctions == 0) { xsltGenericError(xsltGenericErrorContext, "xsltExtFunctionTest: PHP Object did not register PHP functions\n" ); error = 1; } } } xmlXPathObjectPtr obj; if (error == 1) { for (int i = nargs - 1; i >= 0; i--) { obj = valuePop(ctxt); xmlXPathFreeObject(obj); } return; } Array args; // Reverse order to pop values off ctxt stack for (int i = nargs - 2; i >= 0; i--) { Variant arg; obj = valuePop(ctxt); switch (obj->type) { case XPATH_STRING: arg = String((char*)obj->stringval, CopyString); break; case XPATH_BOOLEAN: arg = (bool)obj->boolval; break; case XPATH_NUMBER: arg = (double)obj->floatval; break; case XPATH_NODESET: if (type == 1) { char *str = (char*)xmlXPathCastToString(obj); arg = String(str, CopyString); xmlFree(str); } else if (type == 2) { arg = Array::Create(); if (obj->nodesetval && obj->nodesetval->nodeNr > 0) { for (int j = 0; j < obj->nodesetval->nodeNr; j++) { // TODO: not sure this is the right thing to do. xmlNodePtr node = obj->nodesetval->nodeTab[j]; if (node->type == XML_ELEMENT_NODE) { Object element = newNode(s_DOMElement, xmlCopyNode(node, /*extended*/ 1)); arg.toArrRef().append(element); } else if (node->type == XML_ATTRIBUTE_NODE) { Object attribute = newNode(s_DOMAttr, (xmlNodePtr)xmlCopyProp(nullptr, (xmlAttrPtr)node)); arg.toArrRef().append(attribute); } else if (node->type == XML_TEXT_NODE) { Object text = newNode(s_DOMText, (xmlNodePtr)xmlNewText(xmlNodeGetContent(node))); arg.toArrRef().append(text); } else { raise_warning("Unhandled node type '%d'", node->type); // Use a generic DOMNode as fallback for now. Object nodeobj = newNode(s_DOMNode, xmlCopyNode(node, /*extended*/ 1)); arg.toArrRef().append(nodeobj); } } } } break; default: arg = String((char*)xmlXPathCastToString(obj), CopyString); } xmlXPathFreeObject(obj); args.prepend(arg); } obj = valuePop(ctxt); if (obj->stringval == nullptr) { raise_warning("Handler name must be a string"); xmlXPathFreeObject(obj); // Push an empty string to get an xslt result. valuePush(ctxt, xmlXPathNewString((xmlChar*)"")); return; } String handler((char*)obj->stringval, CopyString); xmlXPathFreeObject(obj); if (!HHVM_FN(is_callable)(handler)) { raise_warning("Unable to call handler %s()", handler.data()); // Push an empty string to get an xslt result. valuePush(ctxt, xmlXPathNewString((xmlChar*)"")); } else if (intern->m_registerPhpFunctions == 2 && !intern->m_registered_phpfunctions.exists(handler)) { raise_warning("Not allowed to call handler '%s()'", handler.data()); // Push an empty string to get an xslt result. valuePush(ctxt, xmlXPathNewString((xmlChar*)"")); } else { Variant retval = vm_call_user_func(handler, args); if (retval.isObject() && retval.getObjectData()->instanceof(s_DOMNode)) { ObjectData *retval_data = retval.asCObjRef().get(); xmlNode* nodep = Native::data<DOMNode>(retval_data)->nodep(); valuePush(ctxt, xmlXPathNewNodeSet(nodep)); intern->m_usedElements.prepend(retval); } else if (retval.is(KindOfBoolean)) { valuePush(ctxt, xmlXPathNewBoolean(retval.toBoolean())); } else if (retval.isObject()) { raise_warning("A PHP Object cannot be converted to an XPath-string"); // Push an empty string to get an xslt result. valuePush(ctxt, xmlXPathNewString((xmlChar*)"")); } else { String sretval = retval.toString(); valuePush(ctxt, xmlXPathNewString((xmlChar*)sretval.data())); } } }
static void dom_xpath_ext_function_php(xmlXPathParserContextPtr ctxt, int nargs, int type) /* {{{ */ { zval **args = NULL; zval *retval; int result, i, ret; int error = 0; zend_fcall_info fci; zval handler; xmlXPathObjectPtr obj; char *str; char *callable = NULL; dom_xpath_object *intern; TSRMLS_FETCH(); if (! zend_is_executing(TSRMLS_C)) { xmlGenericError(xmlGenericErrorContext, "xmlExtFunctionTest: Function called from outside of PHP\n"); error = 1; } else { intern = (dom_xpath_object *) ctxt->context->userData; if (intern == NULL) { xmlGenericError(xmlGenericErrorContext, "xmlExtFunctionTest: failed to get the internal object\n"); error = 1; } else if (intern->registerPhpFunctions == 0) { xmlGenericError(xmlGenericErrorContext, "xmlExtFunctionTest: PHP Object did not register PHP functions\n"); error = 1; } } if (error == 1) { for (i = nargs - 1; i >= 0; i--) { obj = valuePop(ctxt); xmlXPathFreeObject(obj); } return; } fci.param_count = nargs - 1; if (fci.param_count > 0) { fci.params = safe_emalloc(fci.param_count, sizeof(zval**), 0); args = safe_emalloc(fci.param_count, sizeof(zval *), 0); } /* Reverse order to pop values off ctxt stack */ for (i = nargs - 2; i >= 0; i--) { obj = valuePop(ctxt); MAKE_STD_ZVAL(args[i]); switch (obj->type) { case XPATH_STRING: ZVAL_STRING(args[i], (char *)obj->stringval, 1); break; case XPATH_BOOLEAN: ZVAL_BOOL(args[i], obj->boolval); break; case XPATH_NUMBER: ZVAL_DOUBLE(args[i], obj->floatval); break; case XPATH_NODESET: if (type == 1) { str = (char *)xmlXPathCastToString(obj); ZVAL_STRING(args[i], str, 1); xmlFree(str); } else if (type == 2) { int j; array_init(args[i]); if (obj->nodesetval && obj->nodesetval->nodeNr > 0) { for (j = 0; j < obj->nodesetval->nodeNr; j++) { xmlNodePtr node = obj->nodesetval->nodeTab[j]; zval *child; MAKE_STD_ZVAL(child); /* not sure, if we need this... it's copied from xpath.c */ if (node->type == XML_NAMESPACE_DECL) { xmlNsPtr curns; xmlNodePtr nsparent; nsparent = node->_private; curns = xmlNewNs(NULL, node->name, NULL); if (node->children) { curns->prefix = xmlStrdup((xmlChar *) node->children); } if (node->children) { node = xmlNewDocNode(node->doc, NULL, (xmlChar *) node->children, node->name); } else { node = xmlNewDocNode(node->doc, NULL, (xmlChar *) "xmlns", node->name); } node->type = XML_NAMESPACE_DECL; node->parent = nsparent; node->ns = curns; } child = php_dom_create_object(node, &ret, child, (dom_object *)intern TSRMLS_CC); add_next_index_zval(args[i], child); } } } break; default: ZVAL_STRING(args[i], (char *)xmlXPathCastToString(obj), 1); } xmlXPathFreeObject(obj); fci.params[i] = &args[i]; } fci.size = sizeof(fci); fci.function_table = EG(function_table); obj = valuePop(ctxt); if (obj->stringval == NULL) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "Handler name must be a string"); xmlXPathFreeObject(obj); if (fci.param_count > 0) { for (i = 0; i < nargs - 1; i++) { zval_ptr_dtor(&args[i]); } efree(args); efree(fci.params); } return; } INIT_PZVAL(&handler); ZVAL_STRING(&handler, obj->stringval, 1); xmlXPathFreeObject(obj); fci.function_name = &handler; fci.symbol_table = NULL; fci.object_ptr = NULL; fci.retval_ptr_ptr = &retval; fci.no_separation = 0; if (!zend_make_callable(&handler, &callable TSRMLS_CC)) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to call handler %s()", callable); } else if ( intern->registerPhpFunctions == 2 && zend_hash_exists(intern->registered_phpfunctions, callable, strlen(callable) + 1) == 0) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "Not allowed to call handler '%s()'.", callable); /* Push an empty string, so that we at least have an xslt result... */ valuePush(ctxt, xmlXPathNewString((xmlChar *)"")); } else { result = zend_call_function(&fci, NULL TSRMLS_CC); if (result == FAILURE) { if (Z_TYPE(handler) == IS_STRING) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to call handler %s()", Z_STRVAL_P(&handler)); } /* retval is == NULL, when an exception occurred, don't report anything, because PHP itself will handle that */ } else if (retval == NULL) { } else { if (retval->type == IS_OBJECT && instanceof_function( Z_OBJCE_P(retval), dom_node_class_entry TSRMLS_CC)) { xmlNode *nodep; dom_object *obj; if (intern->node_list == NULL) { ALLOC_HASHTABLE(intern->node_list); zend_hash_init(intern->node_list, 0, NULL, ZVAL_PTR_DTOR, 0); } zval_add_ref(&retval); zend_hash_next_index_insert(intern->node_list, &retval, sizeof(zval *), NULL); obj = (dom_object *)zend_object_store_get_object(retval TSRMLS_CC); nodep = dom_object_get_node(obj); valuePush(ctxt, xmlXPathNewNodeSet(nodep)); } else if (retval->type == IS_BOOL) { valuePush(ctxt, xmlXPathNewBoolean(retval->value.lval)); } else if (retval->type == IS_OBJECT) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "A PHP Object cannot be converted to a XPath-string"); valuePush(ctxt, xmlXPathNewString((xmlChar *)"")); } else { convert_to_string_ex(&retval); valuePush(ctxt, xmlXPathNewString( Z_STRVAL_P(retval))); } zval_ptr_dtor(&retval); } } efree(callable); zval_dtor(&handler); if (fci.param_count > 0) { for (i = 0; i < nargs - 1; i++) { zval_ptr_dtor(&args[i]); } efree(args); efree(fci.params); } }
static void xsl_ext_function_php(xmlXPathParserContextPtr ctxt, int nargs, int type) /* {{{ */ { xsltTransformContextPtr tctxt; zval *args; zval retval; int result, i; int error = 0; zend_fcall_info fci; zval handler; xmlXPathObjectPtr obj; char *str; xsl_object *intern; zend_string *callable = NULL; if (! zend_is_executing()) { xsltGenericError(xsltGenericErrorContext, "xsltExtFunctionTest: Function called from outside of PHP\n"); error = 1; } else { tctxt = xsltXPathGetTransformContext(ctxt); if (tctxt == NULL) { xsltGenericError(xsltGenericErrorContext, "xsltExtFunctionTest: failed to get the transformation context\n"); error = 1; } else { intern = (xsl_object*)tctxt->_private; if (intern == NULL) { xsltGenericError(xsltGenericErrorContext, "xsltExtFunctionTest: failed to get the internal object\n"); error = 1; } else if (intern->registerPhpFunctions == 0) { xsltGenericError(xsltGenericErrorContext, "xsltExtFunctionTest: PHP Object did not register PHP functions\n"); error = 1; } } } if (error == 1) { for (i = nargs - 1; i >= 0; i--) { obj = valuePop(ctxt); xmlXPathFreeObject(obj); } return; } fci.param_count = nargs - 1; if (fci.param_count > 0) { args = safe_emalloc(fci.param_count, sizeof(zval), 0); } /* Reverse order to pop values off ctxt stack */ for (i = nargs - 2; i >= 0; i--) { obj = valuePop(ctxt); switch (obj->type) { case XPATH_STRING: ZVAL_STRING(&args[i], (char *)obj->stringval); break; case XPATH_BOOLEAN: ZVAL_BOOL(&args[i], obj->boolval); break; case XPATH_NUMBER: ZVAL_DOUBLE(&args[i], obj->floatval); break; case XPATH_NODESET: if (type == 1) { str = (char*)xmlXPathCastToString(obj); ZVAL_STRING(&args[i], str); xmlFree(str); } else if (type == 2) { int j; dom_object *domintern = (dom_object *)intern->doc; array_init(&args[i]); if (obj->nodesetval && obj->nodesetval->nodeNr > 0) { for (j = 0; j < obj->nodesetval->nodeNr; j++) { xmlNodePtr node = obj->nodesetval->nodeTab[j]; zval child; /* not sure, if we need this... it's copied from xpath.c */ if (node->type == XML_NAMESPACE_DECL) { xmlNsPtr curns; xmlNodePtr nsparent; nsparent = node->_private; curns = xmlNewNs(NULL, node->name, NULL); if (node->children) { curns->prefix = xmlStrdup((char *)node->children); } if (node->children) { node = xmlNewDocNode(node->doc, NULL, (char *) node->children, node->name); } else { node = xmlNewDocNode(node->doc, NULL, (const xmlChar *) "xmlns", node->name); } node->type = XML_NAMESPACE_DECL; node->parent = nsparent; node->ns = curns; } else { node = xmlDocCopyNodeList(domintern->document->ptr, node); } php_dom_create_object(node, &child, domintern); add_next_index_zval(&args[i], &child); } } } break; default: str = (char *) xmlXPathCastToString(obj); ZVAL_STRING(&args[i], str); xmlFree(str); } xmlXPathFreeObject(obj); } fci.size = sizeof(fci); fci.function_table = EG(function_table); if (fci.param_count > 0) { fci.params = args; } else { fci.params = NULL; } obj = valuePop(ctxt); if (obj->stringval == NULL) { php_error_docref(NULL, E_WARNING, "Handler name must be a string"); xmlXPathFreeObject(obj); valuePush(ctxt, xmlXPathNewString((const xmlChar *) "")); if (fci.param_count > 0) { for (i = 0; i < nargs - 1; i++) { zval_ptr_dtor(&args[i]); } efree(args); } return; } ZVAL_STRING(&handler, (char *) obj->stringval); xmlXPathFreeObject(obj); ZVAL_COPY_VALUE(&fci.function_name, &handler); fci.symbol_table = NULL; fci.object = NULL; fci.retval = &retval; fci.no_separation = 0; /*fci.function_handler_cache = &function_ptr;*/ if (!zend_make_callable(&handler, &callable)) { php_error_docref(NULL, E_WARNING, "Unable to call handler %s()", ZSTR_VAL(callable)); valuePush(ctxt, xmlXPathNewString((const xmlChar *) "")); } else if ( intern->registerPhpFunctions == 2 && zend_hash_exists(intern->registered_phpfunctions, callable) == 0) { php_error_docref(NULL, E_WARNING, "Not allowed to call handler '%s()'", ZSTR_VAL(callable)); /* Push an empty string, so that we at least have an xslt result... */ valuePush(ctxt, xmlXPathNewString((const xmlChar *) "")); } else { result = zend_call_function(&fci, NULL); if (result == FAILURE) { if (Z_TYPE(handler) == IS_STRING) { php_error_docref(NULL, E_WARNING, "Unable to call handler %s()", Z_STRVAL(handler)); valuePush(ctxt, xmlXPathNewString((const xmlChar *) "")); } /* retval is == NULL, when an exception occurred, don't report anything, because PHP itself will handle that */ } else if (Z_ISUNDEF(retval)) { } else { if (Z_TYPE(retval) == IS_OBJECT && instanceof_function(Z_OBJCE(retval), dom_node_class_entry)) { xmlNode *nodep; dom_object *obj; if (intern->node_list == NULL) { ALLOC_HASHTABLE(intern->node_list); zend_hash_init(intern->node_list, 0, NULL, ZVAL_PTR_DTOR, 0); } Z_ADDREF(retval); zend_hash_next_index_insert(intern->node_list, &retval); obj = Z_DOMOBJ_P(&retval); nodep = dom_object_get_node(obj); valuePush(ctxt, xmlXPathNewNodeSet(nodep)); } else if (Z_TYPE(retval) == IS_TRUE || Z_TYPE(retval) == IS_FALSE) { valuePush(ctxt, xmlXPathNewBoolean(Z_LVAL(retval))); } else if (Z_TYPE(retval) == IS_OBJECT) { php_error_docref(NULL, E_WARNING, "A PHP Object cannot be converted to a XPath-string"); valuePush(ctxt, xmlXPathNewString((const xmlChar *) "")); } else { convert_to_string_ex(&retval); valuePush(ctxt, xmlXPathNewString((xmlChar *) Z_STRVAL(retval))); } zval_ptr_dtor(&retval); } } zend_string_release(callable); zval_ptr_dtor(&handler); if (fci.param_count > 0) { for (i = 0; i < nargs - 1; i++) { zval_ptr_dtor(&args[i]); } efree(args); } }
/* The implementation of the r:call() XSL function. */ void RXSLT_callConvert(xmlXPathParserContextPtr ctxt, int nargs, int leaveAsRObject) { USER_OBJECT_ e, ans, tmp, fun; xmlXPathObjectPtr obj, *xpathArgs; int i, errorOccurred = 0; int addContext = 0; const char *funName, *colon; xpathArgs = (xmlXPathObjectPtr*) malloc(nargs * sizeof(xmlXPathObjectPtr)); for(i = nargs-1; i >= 0; i--) xpathArgs[i] = valuePop(ctxt); funName = xmlXPathCastToString(xpathArgs[0]); colon = strchr(funName, ':'); if(!colon) { /* regular name of a function. */ fun = Rf_findFun(Rf_install(funName), R_GlobalEnv); } else { /* Handle a :: or ::: in the name by calling the corresponding function to get the value */ const char *realFunName = colon; char tmp[300], *p = tmp; do { p[0] = ':'; p++; realFunName++; } while(realFunName[0] == ':'); p[0] = '\0'; PROTECT(e = allocVector(LANGSXP, 3)); SETCAR(e, Rf_install(tmp)); memcpy(tmp, funName, colon - funName); SETCAR(CDR(e), mkString(tmp)); SETCAR(CDR(CDR(e)), mkString(realFunName)); /*??? Do we need to protect ? XXX If the symbol is not present, this seems to throw the error in R but using R_tryEval(), we should be gettting back to here. */ fun = R_tryEval(e, R_GlobalEnv, &errorOccurred); if(errorOccurred) RXSLT_Error(ctxt, "can't find R function %s", (char *) funName); UNPROTECT(1); } if(TYPEOF(fun) != CLOSXP && /*???*/ TYPEOF(fun) != FUNSXP && TYPEOF(fun) != BUILTINSXP) RXSLT_Error(ctxt, "%s does not correspond to an R function (%d)", funName, TYPEOF(fun)); addContext = OBJECT(fun) && R_isInstanceOf(fun, "XSLTContextFunction"); PROTECT(e = allocVector(LANGSXP, nargs + addContext)); obj = valuePop(ctxt); /* ?? what is here. */ #ifdef XSLT_DEBUG fprintf(stderr, "RXSLT_call for %s with %d args\n", xmlXPathCastToString(xpathArgs[0]), nargs);fflush(stderr); #endif SETCAR(e, fun); /* Rf_install(xmlXPathCastToString(xpathArgs[0])));*/ tmp = CDR(e); if(addContext) { SETCAR(tmp, RXSLT_exportPointer(ctxt, "XMLXPathParserContext")); tmp = CDR(tmp); } for(i = 1 ; i < nargs; i++) { obj = xpathArgs[i]; SETCAR(tmp, convertFromXPath(ctxt, obj)); tmp = CDR(tmp); } ans = R_tryEval(e, R_GlobalEnv, &errorOccurred); if(!errorOccurred) { xmlXPathObjectPtr val; PROTECT(ans); if(leaveAsRObject) { R_PreserveObject(ans); val = xmlXPathWrapExternal(ans); } else val = convertToXPath(ctxt, ans); if(val) valuePush(ctxt, val); UNPROTECT(1); } else { RXSLT_Error(ctxt, "[R:error] error calling R function %s\n", (char *) funName); } free(xpathArgs); UNPROTECT(1); return; }
/* Run an XPath query on XML on stdin, print results to stdout. */ static void do_xpath (const char *query) { CLEANUP_XMLFREEDOC xmlDocPtr doc = NULL; CLEANUP_XMLXPATHFREECONTEXT xmlXPathContextPtr xpathCtx = NULL; CLEANUP_XMLXPATHFREEOBJECT xmlXPathObjectPtr xpathObj = NULL; xmlNodeSetPtr nodes; char *r; size_t i; xmlSaveCtxtPtr saveCtx; xmlNodePtr wrnode; doc = xmlReadFd (STDIN_FILENO, NULL, "utf8", XML_PARSE_NOBLANKS); if (doc == NULL) { fprintf (stderr, _("%s: unable to parse XML from stdin\n"), guestfs_int_program_name); exit (EXIT_FAILURE); } xpathCtx = xmlXPathNewContext (doc); if (xpathCtx == NULL) { fprintf (stderr, _("%s: unable to create new XPath context\n"), guestfs_int_program_name); exit (EXIT_FAILURE); } xpathObj = xmlXPathEvalExpression (BAD_CAST query, xpathCtx); if (xpathObj == NULL) { fprintf (stderr, _("%s: unable to evaluate XPath expression\n"), guestfs_int_program_name); exit (EXIT_FAILURE); } switch (xpathObj->type) { case XPATH_NODESET: nodes = xpathObj->nodesetval; if (nodes == NULL) break; saveCtx = xmlSaveToFd (STDOUT_FILENO, NULL, XML_SAVE_NO_DECL | XML_SAVE_FORMAT); if (saveCtx == NULL) { fprintf (stderr, _("%s: xmlSaveToFd failed\n"), guestfs_int_program_name); exit (EXIT_FAILURE); } for (i = 0; i < (size_t) nodes->nodeNr; ++i) { CLEANUP_XMLFREEDOC xmlDocPtr wrdoc = xmlNewDoc (BAD_CAST "1.0"); if (wrdoc == NULL) { fprintf (stderr, _("%s: xmlNewDoc failed\n"), guestfs_int_program_name); exit (EXIT_FAILURE); } wrnode = xmlCopyNode (nodes->nodeTab[i], 1); if (wrnode == NULL) { fprintf (stderr, _("%s: xmlCopyNode failed\n"), guestfs_int_program_name); exit (EXIT_FAILURE); } xmlDocSetRootElement (wrdoc, wrnode); if (xmlSaveDoc (saveCtx, wrdoc) == -1) { fprintf (stderr, _("%s: xmlSaveDoc failed\n"), guestfs_int_program_name); exit (EXIT_FAILURE); } } xmlSaveClose (saveCtx); break; case XPATH_STRING: r = (char *) xpathObj->stringval; printf ("%s", r); i = strlen (r); if (i > 0 && r[i-1] != '\n') printf ("\n"); break; case XPATH_UNDEFINED: /* grrrrr ... switch-enum is a useless warning */ case XPATH_BOOLEAN: case XPATH_NUMBER: case XPATH_POINT: case XPATH_RANGE: case XPATH_LOCATIONSET: case XPATH_USERS: case XPATH_XSLT_TREE: default: r = (char *) xmlXPathCastToString (xpathObj); printf ("%s\n", r); free (r); } }
int check_conf(char** kasp) { int status = 0; int i = 0; int j = 0; int temp_status = 0; xmlDocPtr doc; xmlXPathContextPtr xpath_ctx; xmlXPathObjectPtr xpath_obj; xmlNode *curNode; xmlChar *xexpr; char* temp_char = NULL; KC_REPO* repo = NULL; int* repo_mods = NULL; /* To see if we have looked at this module before */ const char* rngfilename = OPENDNSSEC_SCHEMA_DIR "/conf.rng"; const char* zonerngfilename = OPENDNSSEC_SCHEMA_DIR "/zonelist.rng"; /* Check that the file is well-formed */ status = check_rng(config, rngfilename); if (status == 0) { dual_log("INFO: The XML in %s is valid\n", config); } else { return status; /* Don't try to read the file if it is invalid */ } /* Load XML document */ doc = xmlParseFile(config); if (doc == NULL) { return 1; } /* Create xpath evaluation context */ xpath_ctx = xmlXPathNewContext(doc); if(xpath_ctx == NULL) { xmlFreeDoc(doc); return 1; } /* REPOSITORY section */ xexpr = (xmlChar *)"//Configuration/RepositoryList/Repository"; xpath_obj = xmlXPathEvalExpression(xexpr, xpath_ctx); if(xpath_obj == NULL) { xmlXPathFreeContext(xpath_ctx); xmlFreeDoc(doc); return 1; } if (xpath_obj->nodesetval) { repo_count = xpath_obj->nodesetval->nodeNr; repo = (KC_REPO*)malloc(sizeof(KC_REPO) * repo_count); repo_mods = (int*)malloc(sizeof(int) * repo_count); repo_list = (char**)malloc(sizeof(char*) * repo_count); if (repo == NULL || repo_mods == NULL || repo_list == NULL) { dual_log("ERROR: malloc for repo information failed\n"); exit(1); } for (i = 0; i < repo_count; i++) { repo_mods[i] = 0; curNode = xpath_obj->nodesetval->nodeTab[i]->xmlChildrenNode; /* Default for capacity */ repo[i].name = (char *) xmlGetProp(xpath_obj->nodesetval->nodeTab[i], (const xmlChar *)"name"); repo_list[i] = StrStrdup(repo[i].name); while (curNode) { if (xmlStrEqual(curNode->name, (const xmlChar *)"TokenLabel")) repo[i].TokenLabel = (char *) xmlNodeGetContent(curNode); if (xmlStrEqual(curNode->name, (const xmlChar *)"Module")) repo[i].module = (char *) xmlNodeGetContent(curNode); curNode = curNode->next; } } } xmlXPathFreeObject(xpath_obj); /* Now we have all the information we need do the checks */ for (i = 0; i < repo_count; i++) { if (repo_mods[i] == 0) { /* 1) Check that the module exists */ status += check_file(repo[i].module, "Module"); repo_mods[i] = 1; /* Done this module */ /* 2) Check repos on the same modules have different TokenLabels */ for (j = i+1; j < repo_count; j++) { if ( repo_mods[j] == 0 && (strcmp(repo[i].module, repo[j].module) == 0) ) { repo_mods[j] = 1; /* done */ if (strcmp(repo[i].TokenLabel, repo[j].TokenLabel) == 0) { dual_log("ERROR: Multiple Repositories (%s and %s) in %s have the same Module (%s) and TokenLabel (%s)\n", repo[i].name, repo[j].name, config, repo[i].module, repo[i].TokenLabel); status += 1; } } } } /* 3) Check that the name is unique */ for (j = i+1; j < repo_count; j++) { if (strcmp(repo[i].name, repo[j].name) == 0) { dual_log("ERROR: Two repositories exist with the same name (%s)\n", repo[i].name); status += 1; } } } /* COMMON section */ /* PolicyFile (aka KASP); we will validate it later */ if (*kasp == NULL) { xexpr = (xmlChar *)"//Configuration/Common/PolicyFile"; xpath_obj = xmlXPathEvalExpression(xexpr, xpath_ctx); if(xpath_obj == NULL) { xmlXPathFreeContext(xpath_ctx); xmlFreeDoc(doc); for (i = 0; i < repo_count; i++) { free(repo[i].name); free(repo[i].module); free(repo[i].TokenLabel); } free(repo); free(repo_mods); return -1; } temp_char = (char*) xmlXPathCastToString(xpath_obj); StrAppend(kasp, temp_char); StrFree(temp_char); xmlXPathFreeObject(xpath_obj); } /* Check that the Zonelist file is well-formed */ xexpr = (xmlChar *)"//Configuration/Common/ZoneListFile"; xpath_obj = xmlXPathEvalExpression(xexpr, xpath_ctx); if(xpath_obj == NULL) { xmlXPathFreeContext(xpath_ctx); xmlFreeDoc(doc); for (i = 0; i < repo_count; i++) { free(repo[i].name); free(repo[i].module); free(repo[i].TokenLabel); } free(repo); free(repo_mods); return -1; } temp_char = (char*) xmlXPathCastToString(xpath_obj); if (check_rng(temp_char, zonerngfilename) == 0) { dual_log("INFO: The XML in %s is valid\n", temp_char); } else { status += 1; } xmlXPathFreeObject(xpath_obj); StrFree(temp_char); /* ENFORCER section */ /* Check defined user/group */ status += check_user_group(xpath_ctx, (xmlChar *)"//Configuration/Enforcer/Privileges/User", (xmlChar *)"//Configuration/Enforcer/Privileges/Group"); /* Check datastore exists (if sqlite) */ /* TODO check datastore matches libksm without building against libksm */ temp_status = check_file_from_xpath(xpath_ctx, "SQLite datastore", (xmlChar *)"//Configuration/Enforcer/Datastore/SQLite"); if (temp_status == -1) { /* Configured for Mysql DB */ /*if (DbFlavour() != MYSQL_DB) { dual_log("ERROR: libksm compiled for sqlite3 but conf.xml configured for MySQL\n"); }*/ } else { status += temp_status; /* Configured for sqlite DB */ /*if (DbFlavour() != SQLITE_DB) { dual_log("ERROR: libksm compiled for MySQL but conf.xml configured for sqlite3\n"); }*/ } /* Warn if Interval is M or Y */ status += check_time_def_from_xpath(xpath_ctx, (xmlChar *)"//Configuration/Enforcer/Interval", "Configuration", "Enforcer/Interval", config); /* Warn if RolloverNotification is M or Y */ status += check_time_def_from_xpath(xpath_ctx, (xmlChar *)"//Configuration/Enforcer/RolloverNotification", "Configuration", "Enforcer/RolloverNotification", config); /* Check DelegationSignerSubmitCommand exists (if set) */ temp_status = check_file_from_xpath(xpath_ctx, "DelegationSignerSubmitCommand", (xmlChar *)"//Configuration/Enforcer/DelegationSignerSubmitCommand"); if (temp_status > 0) { status += temp_status; } /* SIGNER section */ /* Check defined user/group */ status += check_user_group(xpath_ctx, (xmlChar *)"//Configuration/Signer/Privileges/User", (xmlChar *)"//Configuration/Signer/Privileges/Group"); /* Check WorkingDirectory exists (or default) */ temp_status = check_path_from_xpath(xpath_ctx, "WorkingDirectory", (xmlChar *)"//Configuration/Signer/WorkingDirectory"); if (temp_status == -1) { /* Check the default location */ check_path(OPENDNSSEC_STATE_DIR "/tmp", "default WorkingDirectory"); } else { status += temp_status; } xmlXPathFreeContext(xpath_ctx); xmlFreeDoc(doc); for (i = 0; i < repo_count; i++) { free(repo[i].name); free(repo[i].module); free(repo[i].TokenLabel); } free(repo); free(repo_mods); return status; }