Пример #1
0
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;
}
Пример #2
0
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;
}
Пример #3
0
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;
}
Пример #4
0
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;
}
Пример #5
0
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());
}
Пример #6
0
   /// 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;
   }
Пример #7
0
/*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;

}
Пример #8
0
void
RXSLT_source(xmlXPathParserContextPtr ctxt, int nargs)
{
   Rboolean ok;
   xmlXPathObjectPtr obj;

   obj = valuePop(ctxt); 
   ok = RXSLT_internalSource(xmlXPathCastToString(obj));
   valuePush(ctxt, xmlXPathNewBoolean(ok));
}
Пример #9
0
/**
 * 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;
}
Пример #11
0
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);
}
Пример #12
0
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;
}
Пример #13
0
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;
}
Пример #14
0
// ---------------------------------------------------------------------------
// 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");
  }
}
Пример #16
0
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);
	}
}
Пример #17
0
/**
 * 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);
}
Пример #18
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()));
    }
  }
}
Пример #19
0
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);
	}
}
Пример #20
0
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);
	}
}
Пример #21
0
/*
  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;
}
Пример #22
0
/* 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);
  }
}
Пример #23
0
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;
}