cvs: pecl /valkyrie CREDITS EXPERIMENTAL config.m4 package.xml php_valkyrie.h valkyrie.c
| From: | Xavier Noguer Gallego | Date: | Thu, 30 Oct 2003 11:59:13 +0000 |
| Subject: | cvs: pecl /valkyrie CREDITS EXPERIMENTAL config.m4 package.xml php_valkyrie.h valkyrie.c | ||
| Groups: | php.pecl.cvs | ||
| Request: | Send a blank email to pecl-cvs+get-512@lists.php.net to get a copy of this message | ||
xnoguer Thu Oct 30 06:59:13 2003 EDT
Added files:
/pecl/valkyrie CREDITS EXPERIMENTAL config.m4 package.xml
php_valkyrie.h valkyrie.c
Log:
commiting valkyrie
Index: pecl/valkyrie/config.m4 +++ pecl/valkyrie/config.m4 dnl $Id: config.m4,v 1.1 2003/10/30 11:59:13 xnoguer Exp $ dnl config.m4 for extension valkyrie dnl Comments in this file start with the string 'dnl'. dnl Remove where necessary. This file will not work dnl without editing. PHP_ARG_WITH(valkyrie, for valkyrie support, [ --with-valkyrie=DIR Include valkyrie support DIR is the libxml install directory]) if test "$PHP_VALKYRIE" != "no"; then dnl Write more examples of tests here... dnl # --with-valkyrie -> check with-path dnl SEARCH_PATH="/usr/local /usr" dnl SEARCH_FOR="/include/libxml/tree.h" VALKYRIE_DIR_ADD="" if test -r $PHP_VALKYRIE/include/libxml2/libxml/tree.h; then VALKYRIE_DIR=$PHP_VALKYRIE VALKYRIE_DIR_ADD="/libxml2" elif test -r $PHP_VALKYRIE/include/libxml/tree.h; then VALKYRIE_DIR=$PHP_VALKYRIE else for i in /usr/local /usr; do test -r $i/include/libxml/tree.h && VALKYRIE_DIR=$i test -r $i/include/libxml2/libxml/tree.h && VALKYRIE_DIR=$i && VALKYRIE_DIR_ADD="/libxml2" done fi dnl if test -r $PHP_VALKYRIE/; then dnl VALKYRIE_DIR=$PHP_VALKYRIE dnl else # search default path list dnl AC_MSG_CHECKING([for libxml files in default path]) dnl for i in $SEARCH_PATH ; do dnl if test -r $i/$SEARCH_FOR; then dnl VALKYRIE_DIR=$i dnl AC_MSG_RESULT(found in $i) dnl fi dnl done dnl fi if test -z "$VALKYRIE_DIR"; then AC_MSG_RESULT([not found]) AC_MSG_ERROR([Please reinstall the libxml distribution]) fi dnl checking for lib if test -f $VALKYRIE_DIR/lib/libxml2.a -o -f $VALKYRIE_DIR/lib/libxml2.$SHLIB_SUFFIX_NAME ; then VALKYRIE_LIBNAME=xml2 else VALKYRIE_LIBNAME=xml fi XML2_CONFIG=$VALKYRIE_DIR/bin/xml2-config if test -x $XML2_CONFIG; then VALKYRIE_LIBS=`$XML2_CONFIG --libs` PHP_EVAL_LIBLINE($VALKYRIE_LIBS, VALKYRIE_SHARED_LIBADD) else PHP_ADD_LIBRARY_WITH_PATH($VALKYRIE_LIBNAME, $VALKYRIE_DIR/lib, VALKYRIE_SHARED_LIBADD) fi dnl # --with-valkyrie -> add include path PHP_ADD_INCLUDE($VALKYRIE_DIR/include$VALKYRIE_DIR_ADD) dnl # --with-valkyrie -> chech for lib and symbol presence dnl LIBNAME=valkyrie # you may want to change this dnl LIBSYMBOL=valkyrie # you most likely want to change this dnl PHP_CHECK_LIBRARY($LIBNAME,$LIBSYMBOL, dnl [ dnl PHP_ADD_LIBRARY_WITH_PATH($LIBNAME, $VALKYRIE_DIR/lib, VALKYRIE_SHARED_LIBADD) dnl AC_DEFINE(HAVE_VALKYRIELIB,1,[ ]) dnl ],[ dnl AC_MSG_ERROR([wrong valkyrie lib version or lib not found]) dnl ],[ dnl -L$VALKYRIE_DIR/lib -lm -ldl dnl ]) dnl dnl PHP_SUBST(VALKYRIE_SHARED_LIBADD) PHP_NEW_EXTENSION(valkyrie, valkyrie.c, $ext_shared) fi Index: pecl/valkyrie/package.xml +++ pecl/valkyrie/package.xml <?xml version="1.0" encoding="ISO-8859-1" ?> <package version="1.0"> <name>valkyrie</name> <summary>Validation Valkyrie (temporary name)</summary> <description>This thing (for lack of a better name) makes validating POST and GET parameters easier, through the use of a single XML file for declaring all parameters to be received by all files of an application.</description> <maintainers> <maintainer> <user>xnoguer</user> <name>Xavier Noguer</name> <email>xnoguer@php.net</email> <role>lead</role> </maintainer> </maintainers> <release> <version>0.1</version> <date>2003-09-15</date> <license>PHP</license> <state>alpha</state> <notes>First release.</notes> <deps> <dep type="php" rel="ge">4.3.0</dep> </deps> <configureoptions> <configureoption name="with-valkyrie" default="autodetect" prompt="libxml library installation dir?"/> </configureoptions> <filelist> <file role="src" md5sum="ca7639cca73be8d526e7a8a1d36343ae" name="config.m4"/> <file role="src" md5sum="8762166f52cf9eee9bbead544b71873c" name="valkyrie.c"/> <file role="src" md5sum="dcc2c27c5f7ed8a05b64a2e9794b4fd8" name="php_valkyrie.h"/> <file role="doc" md5sum="2148b828b4a2a57197309f5a009dcf17" name="CREDITS"/> <file role="doc" md5sum="7581680efa1c832fa52ffed03964542c" name="EXPERIMENTAL"/> </filelist> </release> </package> Index: pecl/valkyrie/php_valkyrie.h +++ pecl/valkyrie/php_valkyrie.h /* +----------------------------------------------------------------------+ | PHP Version 4 | +----------------------------------------------------------------------+ | Copyright (c) 1997-2002 The PHP Group | +----------------------------------------------------------------------+ | This source file is subject to version 2.02 of the PHP license, | | that is bundled with this package in the file LICENSE, and is | | available at through the world-wide-web at | | http://www.php.net/license/2_02.txt. | | If you did not receive a copy of the PHP license and are unable to | | obtain it through the world-wide-web, please send a note to | | license@php.net so we can mail you a copy immediately. | +----------------------------------------------------------------------+ | Author: Xavier Noguer <xnoguer@php.net> | +----------------------------------------------------------------------+ $Id: php_valkyrie.h,v 1.1 2003/10/30 11:59:13 xnoguer Exp $ */ #ifndef PHP_VALKYRIE_H #define PHP_VALKYRIE_H #include <libxml/parser.h> #include <libxml/xpath.h> extern zend_module_entry valkyrie_module_entry; #define phpext_valkyrie_ptr &valkyrie_module_entry #ifdef PHP_WIN32 #define PHP_VALKYRIE_API __declspec(dllexport) #else #define PHP_VALKYRIE_API #endif #ifdef ZTS #include "TSRM.h" #endif PHP_MINIT_FUNCTION(valkyrie); PHP_MSHUTDOWN_FUNCTION(valkyrie); PHP_RINIT_FUNCTION(valkyrie); PHP_MINFO_FUNCTION(valkyrie); PHP_FUNCTION(valkyrie_validate); PHP_FUNCTION(valkyrie_reload_config); ZEND_BEGIN_MODULE_GLOBALS(valkyrie) long auto_validate; int config_parsed; int strict; char *config_path, *application_path, *validation_funcs_path; xmlNodeSet *modules; xmlDoc *doc_ptr; zval *obj; zend_class_entry *zce; ZEND_END_MODULE_GLOBALS(valkyrie) /* In every utility function you add that needs to use variables in php_valkyrie_globals, call TSRM_FETCH(); after declaring other variables used by that function, or better yet, pass in TSRMLS_CC after the last function argument and declare your utility function with TSRMLS_DC after the last declared argument. Always refer to the globals in your function as VALKYRIE_G(variable). You are encouraged to rename these macros something shorter, see examples in any other php module directory. */ typedef struct _valkyrie_param_to_receive { char *name; zend_uchar received; } valkyrie_param_to_receive; #ifdef ZTS #define VALKYRIE_G(v) TSRMG(valkyrie_globals_id, zend_valkyrie_globals *, v) #else #define VALKYRIE_G(v) (valkyrie_globals.v) #endif #endif /* PHP_VALKYRIE_H */ /* * Local variables: * tab-width: 4 * c-basic-offset: 4 * indent-tabs-mode: t * End: */ Index: pecl/valkyrie/valkyrie.c +++ pecl/valkyrie/valkyrie.c /* +----------------------------------------------------------------------+ | PHP Version 4 | +----------------------------------------------------------------------+ | Copyright (c) 1997-2002 The PHP Group | +----------------------------------------------------------------------+ | This source file is subject to version 2.02 of the PHP license, | | that is bundled with this package in the file LICENSE, and is | | available at through the world-wide-web at | | http://www.php.net/license/2_02.txt. | | If you did not receive a copy of the PHP license and are unable to | | obtain it through the world-wide-web, please send a note to | | license@php.net so we can mail you a copy immediately. | +----------------------------------------------------------------------+ | Author: Xavier Noguer <xnoguer@php.net> | +----------------------------------------------------------------------+ $Id: valkyrie.c,v 1.1 2003/10/30 11:59:13 xnoguer Exp $ */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "php.h" #include "php_ini.h" #include "ext/standard/info.h" #include "php_valkyrie.h" ZEND_DECLARE_MODULE_GLOBALS(valkyrie) /* True global resources - no need for thread safety here */ /*static int le_valkyrie; */ /* {{{ valkyrie_functions[] * * Every user visible function must have an entry in valkyrie_functions[]. */ function_entry valkyrie_functions[] = { PHP_FE(valkyrie_validate, NULL) PHP_FE(valkyrie_reload_config, NULL) {NULL, NULL, NULL} /* Must be the last line in valkyrie_functions[] */ }; /* }}} */ /* {{{ valkyrie_module_entry */ zend_module_entry valkyrie_module_entry = { #if ZEND_MODULE_API_NO >= 20010901 STANDARD_MODULE_HEADER, #endif "valkyrie", valkyrie_functions, PHP_MINIT(valkyrie), PHP_MSHUTDOWN(valkyrie), PHP_RINIT(valkyrie), /* Replace with NULL if there's nothing to do at request start */ NULL, PHP_MINFO(valkyrie), #if ZEND_MODULE_API_NO >= 20010901 "0.1", /* Replace with version number for your extension */ #endif STANDARD_MODULE_PROPERTIES }; /* }}} */ #ifdef COMPILE_DL_VALKYRIE ZEND_GET_MODULE(valkyrie) #endif /* {{{ PHP_INI */ PHP_INI_BEGIN() STD_PHP_INI_ENTRY ("valkyrie.config_path", NULL, PHP_INI_ALL, OnUpdateString, config_path, zend_valkyrie_globals, valkyrie_globals) STD_PHP_INI_BOOLEAN ("valkyrie.auto_validate", "0", PHP_INI_ALL, OnUpdateInt, auto_validate, zend_valkyrie_globals, valkyrie_globals) PHP_INI_END() /* }}} */ /* {{{ php_valkyrie_init_globals */ static int php_valkyrie_init_globals(zend_valkyrie_globals *valkyrie_globals) { valkyrie_globals->config_parsed = 0; valkyrie_globals->doc_ptr = NULL; return SUCCESS; } /* }}} */ /* {{{ PHP_MINIT_FUNCTION */ PHP_MINIT_FUNCTION(valkyrie) { REGISTER_INI_ENTRIES(); ZEND_INIT_MODULE_GLOBALS(valkyrie, php_valkyrie_init_globals, NULL); /* TODO: can't access php.ini values here. Find out why */ return SUCCESS; } /* }}} */ /* {{{ PHP_MSHUTDOWN_FUNCTION */ PHP_MSHUTDOWN_FUNCTION(valkyrie) { UNREGISTER_INI_ENTRIES(); /* free the whole XML document (config file) */ xmlFreeDoc(VALKYRIE_G(doc_ptr)); return SUCCESS; } /* }}} */ /* {{{ get_elements_by_tagname, stolen from domxml extension */ xmlNodeSetPtr get_elements_by_tagname(xmlNodePtr n, xmlChar* name, xmlNodeSet *rv ) { xmlNodePtr cld = NULL; /* TODO (from domxml extension!!) Namespace support */ if ( n != NULL && name != NULL ) { cld = n->children; while ( cld != NULL ) { if ( xmlStrcmp( name, cld->name ) == 0 ){ if ( rv == NULL ) { rv = xmlXPathNodeSetCreate( cld ) ; } else { xmlXPathNodeSetAdd( rv, cld ); } } rv = get_elements_by_tagname(cld, name, rv); cld = cld->next; } } return rv; } /* }}} */ /* {{{ parse_config Parses the config file. Returns SUCCESS or FAILURE */ int parse_config(TSRMLS_D) { xmlDoc *docp = NULL; xmlNode *root; char *path, *validationfuncs, *validationfuncs_real_path, *strict; int ini_result; zend_op_array *dummy_op_array; zval *zval_validationfuncs_path; /* nothing we can do without config_path */ if (VALKYRIE_G(config_path) == NULL) { return FAILURE; } /* parse the config file */ if (VALKYRIE_G(doc_ptr) != NULL) { xmlFreeDoc(VALKYRIE_G(doc_ptr)); } docp = xmlParseFile(VALKYRIE_G(config_path)); if (!docp) { return FAILURE; /* TODO: more friendly error */ } /* save pointer for freeing mem at MSHUTDOWN */ VALKYRIE_G(doc_ptr) = docp; root = xmlDocGetRootElement(docp); if (!root) { return FAILURE; /* TODO: more friendly error */ } if (strcmp(root->name,"app") != 0) { return FAILURE; /* TODO: more friendly error */ } /* get the path for the app */ path = xmlGetProp(root, "path"); if (path == NULL) { return FAILURE; /* TODO: more friendly error */ } if (strcmp(path,".") == 0) { VALKYRIE_G(application_path) = (char *)emalloc(1); strcpy(VALKYRIE_G(application_path), ""); } else { /* change here for CLI testing */ VALKYRIE_G(application_path) = (char *) emalloc(1 + strlen(path) + 1); strcpy(VALKYRIE_G(application_path), "/"); strcat(VALKYRIE_G(application_path), path); } /* FIXME: check VALKYRIE_G(application_path) for safe_mode */ /* get the path for validationfuncs file */ validationfuncs = xmlGetProp(root, "validationfuncs"); if (validationfuncs == NULL) { return FAILURE; /* TODO: more friendly error */ } validationfuncs_real_path = expand_filepath(validationfuncs, NULL TSRMLS_CC); VALKYRIE_G(validation_funcs_path) = (char *) emalloc(strlen(validationfuncs_real_path) + 1); strcpy(VALKYRIE_G(validation_funcs_path), validationfuncs_real_path); /* check the strict (check all received params) attribute */ strict = xmlGetProp(root, "strict"); if (strict == NULL) { VALKYRIE_G(strict) = 0; /* if not received it is assumed as "no" */ } else { if (strcmp(strict, "yes") == 0) { VALKYRIE_G(strict) = 1; } else if (strcmp(strict, "no") == 0) { VALKYRIE_G(strict) = 0; } else { return FAILURE; /* unrecognized value */ } } /* get all modules */ VALKYRIE_G(modules) = get_elements_by_tagname(root, "module", NULL); if (VALKYRIE_G(modules) == NULL) { return FAILURE; /* TODO: more friendly error if there are no modules? */ } /* compile the validations funcs file */ MAKE_STD_ZVAL(zval_validationfuncs_path); ZVAL_STRING(zval_validationfuncs_path, VALKYRIE_G(validation_funcs_path), 1); dummy_op_array = compile_filename(ZEND_INCLUDE, zval_validationfuncs_path TSRMLS_CC); if (dummy_op_array == NULL) { return FAILURE; } zval_dtor(zval_validationfuncs_path); if (zend_hash_find(EG(class_table), "valkyrie_validate", strlen("valkyrie_validate") + 1, (void **)&VALKYRIE_G(zce)) == FAILURE) { return FAILURE; } /* don't let RINIT parse again */ VALKYRIE_G(config_parsed) = 1; return SUCCESS; } /* }}} */ /* {{{ PHP_RINIT_FUNCTION */ PHP_RINIT_FUNCTION(valkyrie) { int validated; /* FIXME: auto_validate doesn't work (problem with php.ini values) */ /* if auto_validate is On call valkyrie_validate() on every request and parse_config() only if necessary */ if (VALKYRIE_G(auto_validate) == 1) { if ((VALKYRIE_G(config_path) != NULL) && (VALKYRIE_G(config_parsed) == 0)) { if (parse_config(TSRMLS_C) == FAILURE) { return FAILURE; } } else { return FAILURE; /* nothing we can do without config_path */ } validated = valkyrie_validate(TSRMLS_C); if (validated == 0) { return FAILURE; /* TODO: log failure?? */ } } return SUCCESS; } /* }}} */ /* {{{ PHP_MINFO_FUNCTION */ PHP_MINFO_FUNCTION(valkyrie) { php_info_print_table_start(); php_info_print_table_header(2, "valkyrie support", "enabled"); php_info_print_table_end(); DISPLAY_INI_ENTRIES(); } /* }}} */ /* {{{ get_input_params Get GET and POST params and create arrays for "strict" validation if needed Returns FAILURE or SUCCESS */ int get_input_params(zval **get_data, zval **post_data TSRMLS_DC) { zval *tmp; char *string_key; ulong num_key; int key_type; valkyrie_param_to_receive **params; if (zend_hash_find(&EG(symbol_table), "_GET", sizeof("_GET"), (void **) &get_data) != SUCCESS || Z_TYPE_PP(get_data) != IS_ARRAY) { return FAILURE; /* php_error(E_ERROR, "_GET array not found"); */ } if (zend_hash_find(&EG(symbol_table), "_POST", sizeof("_POST"), (void **) &post_data) != SUCCESS || Z_TYPE_PP(post_data) != IS_ARRAY) { return FAILURE; /* php_error(E_ERROR, "_POST array not found"); */ } #if 0 if (VALKYRIE_G(strict) == 1) { if (zend_hash_num_elements(Z_ARRVAL_PP(get_data))) { zend_hash_internal_pointer_reset(Z_ARRVAL_PP(get_data)); do { valkyrie_param_to_receive param; key_type = zend_hash_get_current_key(Z_ARRVAL_PP(get_data), &string_key, &num_key, 0); if (key_type == HASH_KEY_IS_LONG) { return FAILURE;/* something bad happened */ } param.name = (char *)emalloc(strlen(string_key) + 1); strcpy(param.name, string_key); param.received = 0; } while (zend_hash_move_forward(Z_ARRVAL_PP(get_data)) == SUCCESS); } } #endif return SUCCESS; } /* }}} */ /* {{{ valkyrie_validate Validate GET and/or POST params for the currently executed script */ int valkyrie_validate(TSRMLS_D) { int i, j; int result, file_found = 0; zval *zvalidate_func, *retval; zval **post_data, **get_data, **zscript_name, **tmp; zval ***argv; char *script_name, *file; xmlNodeSet *params; /* get SCRIPT_NAME instead of zend_get_executed_filename(), because we are only interested in path starting from document root */ if (zend_hash_find(&EG(symbol_table), "SCRIPT_NAME", sizeof("SCRIPT_NAME"), (void **) &zscript_name) == SUCCESS && Z_TYPE_PP(zscript_name) == IS_STRING) { script_name = Z_STRVAL_PP(zscript_name); } else { php_error(E_ERROR, "Could not determine script name"); return 0; } //printf("script_name : %s\n", script_name); /* loop through the modules in order to find what module the current script belongs to */ for (i = 0; i < VALKYRIE_G(modules)->nodeNr; i++) { xmlNodePtr module_node = VALKYRIE_G(modules)->nodeTab[i]; char *path, *module_path, *temp_path, *module_name; xmlNodeSet *files; /* get attributes from module element */ module_name = xmlGetProp(module_node, "name"); if (module_name == NULL) { php_error(E_ERROR, "Module element missing its name attribute\n"); return 0; } path = xmlGetProp(module_node, "path"); if (path == NULL) { php_error(E_ERROR, "Module element %s missing its path attribute\n", module_name); return 0; } /* initialize temp_path with app + current module path */ if (strcmp(path,".") == 0) { module_path = (char *) emalloc(1); strcpy(module_path, ""); } else { module_path = (char *) emalloc(1 + strlen(path) + 1); strcpy(module_path, path); /* TODO: use DEFAULT_SLASH */ strcat(module_path, "/"); } temp_path = (char *) emalloc(strlen(VALKYRIE_G(application_path)) + strlen(module_path) + 1 + 1); strcpy(temp_path, VALKYRIE_G(application_path)); strcat(temp_path, "/"); /* TODO: use DEFAULT_SLASH */ strcat(temp_path, module_path); /*printf("temp_path : %s\n", temp_path);*/ /* what the name of the file should be according to SCRIPT_NAME */ if (strlen(temp_path) >= strlen(script_name)) { continue; } file = estrdup(script_name + strlen(temp_path)); /*printf("file : %s\n", file);*/ /* compare application and module path to SCRIPT_NAME */ if (strcmp(temp_path, estrndup(script_name, strlen(temp_path))) == 0) { files = get_elements_by_tagname(module_node, "file", NULL); if (files != NULL) { /* loop through the files */ for (j = 0; j < files->nodeNr; j++) { xmlNodePtr file_node = files->nodeTab[j]; char *file_name; file_name = xmlGetProp(file_node, "name"); if (file_name == NULL) { php_error(E_ERROR, "File element missing its name attribute for module %s\n", module_name); return 0; } /* compare file names from config file and SCRIPT_NAME */ if (strcmp(file, file_name) == 0) { file_found = 1; /* if there are no params defined just return */ params = get_elements_by_tagname(file_node, "param", NULL); if (params == NULL) { return 1; } /* free mem and leave modules/files loops */ efree(module_path); efree(temp_path); break; } } if (file_found == 1) { break; } } } efree(module_path); efree(temp_path); } if (file_found == 0) { php_error(E_ERROR, "File %s is not defined", script_name); return 0; } /* get REQUEST parameters (TODO: move this to get_input_params()) */ if (zend_hash_find(&EG(symbol_table), "_POST", sizeof("_POST"), (void **) &post_data) != SUCCESS || Z_TYPE_PP(post_data) != IS_ARRAY) { php_error(E_ERROR, "_POST array not found"); return 0; } if (zend_hash_find(&EG(symbol_table), "_GET", sizeof("_GET"), (void **) &get_data) != SUCCESS || Z_TYPE_PP(get_data) != IS_ARRAY) { php_error(E_ERROR, "_GET array not found"); return 0; } /*if (get_input_params(get_data, post_data) == FAILURE) { php_error(E_ERROR, "Error getting GET and POST params"); return 0; }*/ MAKE_STD_ZVAL(zvalidate_func); MAKE_STD_ZVAL(retval); /* loop through params defined in config file */ for (i = 0; i < params->nodeNr; i++) { xmlNodePtr param_node = params->nodeTab[i]; char *is_optional, *param_name, *param_type, *param_method; char *validate_func; zval **param_received; /* get attributes for param element */ param_name = xmlGetProp(param_node, "name"); if (param_name == NULL) { php_error(E_ERROR, "Param element missing its name attribute for file %s\n", file); return 0; } param_type = xmlGetProp(param_node, "type"); if (param_type == NULL) { php_error(E_ERROR, "Param %s missing its type attribute for file %s\n", param_name, file); return 0; } param_method = xmlGetProp(param_node, "method"); /* method attribute is obligatory. This may change in the future */ /* if it changes get the _REQUEST array too */ if (param_method == NULL) { php_error(E_ERROR, "Param %s missing its method attribute for file %s\n", param_name, file); return 0; } is_optional = xmlGetProp(param_node, "optional"); /* find the parameter if it's post */ if (strcmp(param_method, "post") == 0) { if (zend_hash_find(Z_ARRVAL_PP(post_data), param_name, strlen(param_name) + 1, (void **) ¶m_received) != SUCCESS) { if ((is_optional == NULL) || (strcmp(is_optional, "no") == 0)) { php_error(E_ERROR, "Post param %s not received\n", param_name); return 0; } else { /* if it's optional continue */ continue; } } } /* find the parameter if it's get */ else if (strcmp(param_method, "get") == 0) { if (zend_hash_find(Z_ARRVAL_PP(get_data), param_name, strlen(param_name) + 1, (void **) ¶m_received) != SUCCESS) { if ((is_optional == NULL) || (strcmp(is_optional, "no") == 0)) { php_error(E_ERROR, "Get param %s not received\n", param_name); return 0; } else { /* if it's optional continue */ continue; } } } /* TODO: search on _COOKIES and finally on _REQUEST too ? */ /* param was not received */ if (param_received == NULL) { php_error(E_ERROR, "Param %s not received\n", param_name); return 0; } validate_func = (char *)emalloc(8 + strlen(param_type) + 1); strcpy(validate_func, "validate"); strcat(validate_func, param_type); /*printf("validate_func = %s\n", validate_func);*/ /* call validation function */ ZVAL_STRING(zvalidate_func, validate_func, 1); ZVAL_FALSE(retval); argv = emalloc(sizeof(zval **)); argv[0] = ¶m_received[0]; result = call_user_function_ex(&(VALKYRIE_G(zce)->function_table), NULL, zvalidate_func, &retval, 1, argv, 0, NULL TSRMLS_CC); if (result == FAILURE) { php_error(E_ERROR, "Could not call function Valkyrie_Validate::%s\n", validate_func); return 0; } if (Z_TYPE_P(retval) != IS_BOOL) { php_error(E_ERROR, "Invalid return type for Valkyrie_Validate::%s", validate_func); return 0; } if (Z_BVAL_P(retval) == 0) { php_error(E_ERROR, "Invalid type for parameter %s", param_name); return 0; } efree(file); efree(validate_func); efree(argv); } zval_dtor(zvalidate_func); zval_dtor(retval); return 1; } /* }}} */ /* {{{ proto bool valkyrie_validate() Validate GET and/or POST params for the currently executed script */ PHP_FUNCTION(valkyrie_validate) { int validated; /* parse config on demand */ if (VALKYRIE_G(config_parsed) == 0) { if (parse_config(TSRMLS_C) == FAILURE) { php_error(E_ERROR, "Could not parse config file"); RETURN_BOOL(0); } } validated = valkyrie_validate(TSRMLS_C); RETURN_BOOL(validated); } /* }}} */ /* {{{ proto bool valkyrie_reload_config() Reload configuration file */ PHP_FUNCTION(valkyrie_reload_config) { if (parse_config(TSRMLS_C) == FAILURE) { RETURN_BOOL(0); } else { RETURN_BOOL(1); } } /* }}} */ /* * Local variables: * tab-width: 4 * c-basic-offset: 4 * End: * vim600: noet sw=4 ts=4 fdm=marker * vim<600: noet sw=4 ts=4 */
Index: pecl/valkyrie/config.m4 +++ pecl/valkyrie/config.m4 dnl $Id: config.m4,v 1.1 2003/10/30 11:59:13 xnoguer Exp $ dnl config.m4 for extension valkyrie dnl Comments in this file start with the string 'dnl'. dnl Remove where necessary. This file will not work dnl without editing. PHP_ARG_WITH(valkyrie, for valkyrie support, [ --with-valkyrie=DIR Include valkyrie support DIR is the libxml install directory]) if test "$PHP_VALKYRIE" != "no"; then dnl Write more examples of tests here... dnl # --with-valkyrie -> check with-path dnl SEARCH_PATH="/usr/local /usr" dnl SEARCH_FOR="/include/libxml/tree.h" VALKYRIE_DIR_ADD="" if test -r $PHP_VALKYRIE/include/libxml2/libxml/tree.h; then VALKYRIE_DIR=$PHP_VALKYRIE VALKYRIE_DIR_ADD="/libxml2" elif test -r $PHP_VALKYRIE/include/libxml/tree.h; then VALKYRIE_DIR=$PHP_VALKYRIE else for i in /usr/local /usr; do test -r $i/include/libxml/tree.h && VALKYRIE_DIR=$i test -r $i/include/libxml2/libxml/tree.h && VALKYRIE_DIR=$i && VALKYRIE_DIR_ADD="/libxml2" done fi dnl if test -r $PHP_VALKYRIE/; then dnl VALKYRIE_DIR=$PHP_VALKYRIE dnl else # search default path list dnl AC_MSG_CHECKING([for libxml files in default path]) dnl for i in $SEARCH_PATH ; do dnl if test -r $i/$SEARCH_FOR; then dnl VALKYRIE_DIR=$i dnl AC_MSG_RESULT(found in $i) dnl fi dnl done dnl fi if test -z "$VALKYRIE_DIR"; then AC_MSG_RESULT([not found]) AC_MSG_ERROR([Please reinstall the libxml distribution]) fi dnl checking for lib if test -f $VALKYRIE_DIR/lib/libxml2.a -o -f $VALKYRIE_DIR/lib/libxml2.$SHLIB_SUFFIX_NAME ; then VALKYRIE_LIBNAME=xml2 else VALKYRIE_LIBNAME=xml fi XML2_CONFIG=$VALKYRIE_DIR/bin/xml2-config if test -x $XML2_CONFIG; then VALKYRIE_LIBS=`$XML2_CONFIG --libs` PHP_EVAL_LIBLINE($VALKYRIE_LIBS, VALKYRIE_SHARED_LIBADD) else PHP_ADD_LIBRARY_WITH_PATH($VALKYRIE_LIBNAME, $VALKYRIE_DIR/lib, VALKYRIE_SHARED_LIBADD) fi dnl # --with-valkyrie -> add include path PHP_ADD_INCLUDE($VALKYRIE_DIR/include$VALKYRIE_DIR_ADD) dnl # --with-valkyrie -> chech for lib and symbol presence dnl LIBNAME=valkyrie # you may want to change this dnl LIBSYMBOL=valkyrie # you most likely want to change this dnl PHP_CHECK_LIBRARY($LIBNAME,$LIBSYMBOL, dnl [ dnl PHP_ADD_LIBRARY_WITH_PATH($LIBNAME, $VALKYRIE_DIR/lib, VALKYRIE_SHARED_LIBADD) dnl AC_DEFINE(HAVE_VALKYRIELIB,1,[ ]) dnl ],[ dnl AC_MSG_ERROR([wrong valkyrie lib version or lib not found]) dnl ],[ dnl -L$VALKYRIE_DIR/lib -lm -ldl dnl ]) dnl dnl PHP_SUBST(VALKYRIE_SHARED_LIBADD) PHP_NEW_EXTENSION(valkyrie, valkyrie.c, $ext_shared) fi Index: pecl/valkyrie/package.xml +++ pecl/valkyrie/package.xml <?xml version="1.0" encoding="ISO-8859-1" ?> <package version="1.0"> <name>valkyrie</name> <summary>Validation Valkyrie (temporary name)</summary> <description>This thing (for lack of a better name) makes validating POST and GET parameters easier, through the use of a single XML file for declaring all parameters to be received by all files of an application.</description> <maintainers> <maintainer> <user>xnoguer</user> <name>Xavier Noguer</name> <email>xnoguer@php.net</email> <role>lead</role> </maintainer> </maintainers> <release> <version>0.1</version> <date>2003-09-15</date> <license>PHP</license> <state>alpha</state> <notes>First release.</notes> <deps> <dep type="php" rel="ge">4.3.0</dep> </deps> <configureoptions> <configureoption name="with-valkyrie" default="autodetect" prompt="libxml library installation dir?"/> </configureoptions> <filelist> <file role="src" md5sum="ca7639cca73be8d526e7a8a1d36343ae" name="config.m4"/> <file role="src" md5sum="8762166f52cf9eee9bbead544b71873c" name="valkyrie.c"/> <file role="src" md5sum="dcc2c27c5f7ed8a05b64a2e9794b4fd8" name="php_valkyrie.h"/> <file role="doc" md5sum="2148b828b4a2a57197309f5a009dcf17" name="CREDITS"/> <file role="doc" md5sum="7581680efa1c832fa52ffed03964542c" name="EXPERIMENTAL"/> </filelist> </release> </package> Index: pecl/valkyrie/php_valkyrie.h +++ pecl/valkyrie/php_valkyrie.h /* +----------------------------------------------------------------------+ | PHP Version 4 | +----------------------------------------------------------------------+ | Copyright (c) 1997-2002 The PHP Group | +----------------------------------------------------------------------+ | This source file is subject to version 2.02 of the PHP license, | | that is bundled with this package in the file LICENSE, and is | | available at through the world-wide-web at | | http://www.php.net/license/2_02.txt. | | If you did not receive a copy of the PHP license and are unable to | | obtain it through the world-wide-web, please send a note to | | license@php.net so we can mail you a copy immediately. | +----------------------------------------------------------------------+ | Author: Xavier Noguer <xnoguer@php.net> | +----------------------------------------------------------------------+ $Id: php_valkyrie.h,v 1.1 2003/10/30 11:59:13 xnoguer Exp $ */ #ifndef PHP_VALKYRIE_H #define PHP_VALKYRIE_H #include <libxml/parser.h> #include <libxml/xpath.h> extern zend_module_entry valkyrie_module_entry; #define phpext_valkyrie_ptr &valkyrie_module_entry #ifdef PHP_WIN32 #define PHP_VALKYRIE_API __declspec(dllexport) #else #define PHP_VALKYRIE_API #endif #ifdef ZTS #include "TSRM.h" #endif PHP_MINIT_FUNCTION(valkyrie); PHP_MSHUTDOWN_FUNCTION(valkyrie); PHP_RINIT_FUNCTION(valkyrie); PHP_MINFO_FUNCTION(valkyrie); PHP_FUNCTION(valkyrie_validate); PHP_FUNCTION(valkyrie_reload_config); ZEND_BEGIN_MODULE_GLOBALS(valkyrie) long auto_validate; int config_parsed; int strict; char *config_path, *application_path, *validation_funcs_path; xmlNodeSet *modules; xmlDoc *doc_ptr; zval *obj; zend_class_entry *zce; ZEND_END_MODULE_GLOBALS(valkyrie) /* In every utility function you add that needs to use variables in php_valkyrie_globals, call TSRM_FETCH(); after declaring other variables used by that function, or better yet, pass in TSRMLS_CC after the last function argument and declare your utility function with TSRMLS_DC after the last declared argument. Always refer to the globals in your function as VALKYRIE_G(variable). You are encouraged to rename these macros something shorter, see examples in any other php module directory. */ typedef struct _valkyrie_param_to_receive { char *name; zend_uchar received; } valkyrie_param_to_receive; #ifdef ZTS #define VALKYRIE_G(v) TSRMG(valkyrie_globals_id, zend_valkyrie_globals *, v) #else #define VALKYRIE_G(v) (valkyrie_globals.v) #endif #endif /* PHP_VALKYRIE_H */ /* * Local variables: * tab-width: 4 * c-basic-offset: 4 * indent-tabs-mode: t * End: */ Index: pecl/valkyrie/valkyrie.c +++ pecl/valkyrie/valkyrie.c /* +----------------------------------------------------------------------+ | PHP Version 4 | +----------------------------------------------------------------------+ | Copyright (c) 1997-2002 The PHP Group | +----------------------------------------------------------------------+ | This source file is subject to version 2.02 of the PHP license, | | that is bundled with this package in the file LICENSE, and is | | available at through the world-wide-web at | | http://www.php.net/license/2_02.txt. | | If you did not receive a copy of the PHP license and are unable to | | obtain it through the world-wide-web, please send a note to | | license@php.net so we can mail you a copy immediately. | +----------------------------------------------------------------------+ | Author: Xavier Noguer <xnoguer@php.net> | +----------------------------------------------------------------------+ $Id: valkyrie.c,v 1.1 2003/10/30 11:59:13 xnoguer Exp $ */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "php.h" #include "php_ini.h" #include "ext/standard/info.h" #include "php_valkyrie.h" ZEND_DECLARE_MODULE_GLOBALS(valkyrie) /* True global resources - no need for thread safety here */ /*static int le_valkyrie; */ /* {{{ valkyrie_functions[] * * Every user visible function must have an entry in valkyrie_functions[]. */ function_entry valkyrie_functions[] = { PHP_FE(valkyrie_validate, NULL) PHP_FE(valkyrie_reload_config, NULL) {NULL, NULL, NULL} /* Must be the last line in valkyrie_functions[] */ }; /* }}} */ /* {{{ valkyrie_module_entry */ zend_module_entry valkyrie_module_entry = { #if ZEND_MODULE_API_NO >= 20010901 STANDARD_MODULE_HEADER, #endif "valkyrie", valkyrie_functions, PHP_MINIT(valkyrie), PHP_MSHUTDOWN(valkyrie), PHP_RINIT(valkyrie), /* Replace with NULL if there's nothing to do at request start */ NULL, PHP_MINFO(valkyrie), #if ZEND_MODULE_API_NO >= 20010901 "0.1", /* Replace with version number for your extension */ #endif STANDARD_MODULE_PROPERTIES }; /* }}} */ #ifdef COMPILE_DL_VALKYRIE ZEND_GET_MODULE(valkyrie) #endif /* {{{ PHP_INI */ PHP_INI_BEGIN() STD_PHP_INI_ENTRY ("valkyrie.config_path", NULL, PHP_INI_ALL, OnUpdateString, config_path, zend_valkyrie_globals, valkyrie_globals) STD_PHP_INI_BOOLEAN ("valkyrie.auto_validate", "0", PHP_INI_ALL, OnUpdateInt, auto_validate, zend_valkyrie_globals, valkyrie_globals) PHP_INI_END() /* }}} */ /* {{{ php_valkyrie_init_globals */ static int php_valkyrie_init_globals(zend_valkyrie_globals *valkyrie_globals) { valkyrie_globals->config_parsed = 0; valkyrie_globals->doc_ptr = NULL; return SUCCESS; } /* }}} */ /* {{{ PHP_MINIT_FUNCTION */ PHP_MINIT_FUNCTION(valkyrie) { REGISTER_INI_ENTRIES(); ZEND_INIT_MODULE_GLOBALS(valkyrie, php_valkyrie_init_globals, NULL); /* TODO: can't access php.ini values here. Find out why */ return SUCCESS; } /* }}} */ /* {{{ PHP_MSHUTDOWN_FUNCTION */ PHP_MSHUTDOWN_FUNCTION(valkyrie) { UNREGISTER_INI_ENTRIES(); /* free the whole XML document (config file) */ xmlFreeDoc(VALKYRIE_G(doc_ptr)); return SUCCESS; } /* }}} */ /* {{{ get_elements_by_tagname, stolen from domxml extension */ xmlNodeSetPtr get_elements_by_tagname(xmlNodePtr n, xmlChar* name, xmlNodeSet *rv ) { xmlNodePtr cld = NULL; /* TODO (from domxml extension!!) Namespace support */ if ( n != NULL && name != NULL ) { cld = n->children; while ( cld != NULL ) { if ( xmlStrcmp( name, cld->name ) == 0 ){ if ( rv == NULL ) { rv = xmlXPathNodeSetCreate( cld ) ; } else { xmlXPathNodeSetAdd( rv, cld ); } } rv = get_elements_by_tagname(cld, name, rv); cld = cld->next; } } return rv; } /* }}} */ /* {{{ parse_config Parses the config file. Returns SUCCESS or FAILURE */ int parse_config(TSRMLS_D) { xmlDoc *docp = NULL; xmlNode *root; char *path, *validationfuncs, *validationfuncs_real_path, *strict; int ini_result; zend_op_array *dummy_op_array; zval *zval_validationfuncs_path; /* nothing we can do without config_path */ if (VALKYRIE_G(config_path) == NULL) { return FAILURE; } /* parse the config file */ if (VALKYRIE_G(doc_ptr) != NULL) { xmlFreeDoc(VALKYRIE_G(doc_ptr)); } docp = xmlParseFile(VALKYRIE_G(config_path)); if (!docp) { return FAILURE; /* TODO: more friendly error */ } /* save pointer for freeing mem at MSHUTDOWN */ VALKYRIE_G(doc_ptr) = docp; root = xmlDocGetRootElement(docp); if (!root) { return FAILURE; /* TODO: more friendly error */ } if (strcmp(root->name,"app") != 0) { return FAILURE; /* TODO: more friendly error */ } /* get the path for the app */ path = xmlGetProp(root, "path"); if (path == NULL) { return FAILURE; /* TODO: more friendly error */ } if (strcmp(path,".") == 0) { VALKYRIE_G(application_path) = (char *)emalloc(1); strcpy(VALKYRIE_G(application_path), ""); } else { /* change here for CLI testing */ VALKYRIE_G(application_path) = (char *) emalloc(1 + strlen(path) + 1); strcpy(VALKYRIE_G(application_path), "/"); strcat(VALKYRIE_G(application_path), path); } /* FIXME: check VALKYRIE_G(application_path) for safe_mode */ /* get the path for validationfuncs file */ validationfuncs = xmlGetProp(root, "validationfuncs"); if (validationfuncs == NULL) { return FAILURE; /* TODO: more friendly error */ } validationfuncs_real_path = expand_filepath(validationfuncs, NULL TSRMLS_CC); VALKYRIE_G(validation_funcs_path) = (char *) emalloc(strlen(validationfuncs_real_path) + 1); strcpy(VALKYRIE_G(validation_funcs_path), validationfuncs_real_path); /* check the strict (check all received params) attribute */ strict = xmlGetProp(root, "strict"); if (strict == NULL) { VALKYRIE_G(strict) = 0; /* if not received it is assumed as "no" */ } else { if (strcmp(strict, "yes") == 0) { VALKYRIE_G(strict) = 1; } else if (strcmp(strict, "no") == 0) { VALKYRIE_G(strict) = 0; } else { return FAILURE; /* unrecognized value */ } } /* get all modules */ VALKYRIE_G(modules) = get_elements_by_tagname(root, "module", NULL); if (VALKYRIE_G(modules) == NULL) { return FAILURE; /* TODO: more friendly error if there are no modules? */ } /* compile the validations funcs file */ MAKE_STD_ZVAL(zval_validationfuncs_path); ZVAL_STRING(zval_validationfuncs_path, VALKYRIE_G(validation_funcs_path), 1); dummy_op_array = compile_filename(ZEND_INCLUDE, zval_validationfuncs_path TSRMLS_CC); if (dummy_op_array == NULL) { return FAILURE; } zval_dtor(zval_validationfuncs_path); if (zend_hash_find(EG(class_table), "valkyrie_validate", strlen("valkyrie_validate") + 1, (void **)&VALKYRIE_G(zce)) == FAILURE) { return FAILURE; } /* don't let RINIT parse again */ VALKYRIE_G(config_parsed) = 1; return SUCCESS; } /* }}} */ /* {{{ PHP_RINIT_FUNCTION */ PHP_RINIT_FUNCTION(valkyrie) { int validated; /* FIXME: auto_validate doesn't work (problem with php.ini values) */ /* if auto_validate is On call valkyrie_validate() on every request and parse_config() only if necessary */ if (VALKYRIE_G(auto_validate) == 1) { if ((VALKYRIE_G(config_path) != NULL) && (VALKYRIE_G(config_parsed) == 0)) { if (parse_config(TSRMLS_C) == FAILURE) { return FAILURE; } } else { return FAILURE; /* nothing we can do without config_path */ } validated = valkyrie_validate(TSRMLS_C); if (validated == 0) { return FAILURE; /* TODO: log failure?? */ } } return SUCCESS; } /* }}} */ /* {{{ PHP_MINFO_FUNCTION */ PHP_MINFO_FUNCTION(valkyrie) { php_info_print_table_start(); php_info_print_table_header(2, "valkyrie support", "enabled"); php_info_print_table_end(); DISPLAY_INI_ENTRIES(); } /* }}} */ /* {{{ get_input_params Get GET and POST params and create arrays for "strict" validation if needed Returns FAILURE or SUCCESS */ int get_input_params(zval **get_data, zval **post_data TSRMLS_DC) { zval *tmp; char *string_key; ulong num_key; int key_type; valkyrie_param_to_receive **params; if (zend_hash_find(&EG(symbol_table), "_GET", sizeof("_GET"), (void **) &get_data) != SUCCESS || Z_TYPE_PP(get_data) != IS_ARRAY) { return FAILURE; /* php_error(E_ERROR, "_GET array not found"); */ } if (zend_hash_find(&EG(symbol_table), "_POST", sizeof("_POST"), (void **) &post_data) != SUCCESS || Z_TYPE_PP(post_data) != IS_ARRAY) { return FAILURE; /* php_error(E_ERROR, "_POST array not found"); */ } #if 0 if (VALKYRIE_G(strict) == 1) { if (zend_hash_num_elements(Z_ARRVAL_PP(get_data))) { zend_hash_internal_pointer_reset(Z_ARRVAL_PP(get_data)); do { valkyrie_param_to_receive param; key_type = zend_hash_get_current_key(Z_ARRVAL_PP(get_data), &string_key, &num_key, 0); if (key_type == HASH_KEY_IS_LONG) { return FAILURE;/* something bad happened */ } param.name = (char *)emalloc(strlen(string_key) + 1); strcpy(param.name, string_key); param.received = 0; } while (zend_hash_move_forward(Z_ARRVAL_PP(get_data)) == SUCCESS); } } #endif return SUCCESS; } /* }}} */ /* {{{ valkyrie_validate Validate GET and/or POST params for the currently executed script */ int valkyrie_validate(TSRMLS_D) { int i, j; int result, file_found = 0; zval *zvalidate_func, *retval; zval **post_data, **get_data, **zscript_name, **tmp; zval ***argv; char *script_name, *file; xmlNodeSet *params; /* get SCRIPT_NAME instead of zend_get_executed_filename(), because we are only interested in path starting from document root */ if (zend_hash_find(&EG(symbol_table), "SCRIPT_NAME", sizeof("SCRIPT_NAME"), (void **) &zscript_name) == SUCCESS && Z_TYPE_PP(zscript_name) == IS_STRING) { script_name = Z_STRVAL_PP(zscript_name); } else { php_error(E_ERROR, "Could not determine script name"); return 0; } //printf("script_name : %s\n", script_name); /* loop through the modules in order to find what module the current script belongs to */ for (i = 0; i < VALKYRIE_G(modules)->nodeNr; i++) { xmlNodePtr module_node = VALKYRIE_G(modules)->nodeTab[i]; char *path, *module_path, *temp_path, *module_name; xmlNodeSet *files; /* get attributes from module element */ module_name = xmlGetProp(module_node, "name"); if (module_name == NULL) { php_error(E_ERROR, "Module element missing its name attribute\n"); return 0; } path = xmlGetProp(module_node, "path"); if (path == NULL) { php_error(E_ERROR, "Module element %s missing its path attribute\n", module_name); return 0; } /* initialize temp_path with app + current module path */ if (strcmp(path,".") == 0) { module_path = (char *) emalloc(1); strcpy(module_path, ""); } else { module_path = (char *) emalloc(1 + strlen(path) + 1); strcpy(module_path, path); /* TODO: use DEFAULT_SLASH */ strcat(module_path, "/"); } temp_path = (char *) emalloc(strlen(VALKYRIE_G(application_path)) + strlen(module_path) + 1 + 1); strcpy(temp_path, VALKYRIE_G(application_path)); strcat(temp_path, "/"); /* TODO: use DEFAULT_SLASH */ strcat(temp_path, module_path); /*printf("temp_path : %s\n", temp_path);*/ /* what the name of the file should be according to SCRIPT_NAME */ if (strlen(temp_path) >= strlen(script_name)) { continue; } file = estrdup(script_name + strlen(temp_path)); /*printf("file : %s\n", file);*/ /* compare application and module path to SCRIPT_NAME */ if (strcmp(temp_path, estrndup(script_name, strlen(temp_path))) == 0) { files = get_elements_by_tagname(module_node, "file", NULL); if (files != NULL) { /* loop through the files */ for (j = 0; j < files->nodeNr; j++) { xmlNodePtr file_node = files->nodeTab[j]; char *file_name; file_name = xmlGetProp(file_node, "name"); if (file_name == NULL) { php_error(E_ERROR, "File element missing its name attribute for module %s\n", module_name); return 0; } /* compare file names from config file and SCRIPT_NAME */ if (strcmp(file, file_name) == 0) { file_found = 1; /* if there are no params defined just return */ params = get_elements_by_tagname(file_node, "param", NULL); if (params == NULL) { return 1; } /* free mem and leave modules/files loops */ efree(module_path); efree(temp_path); break; } } if (file_found == 1) { break; } } } efree(module_path); efree(temp_path); } if (file_found == 0) { php_error(E_ERROR, "File %s is not defined", script_name); return 0; } /* get REQUEST parameters (TODO: move this to get_input_params()) */ if (zend_hash_find(&EG(symbol_table), "_POST", sizeof("_POST"), (void **) &post_data) != SUCCESS || Z_TYPE_PP(post_data) != IS_ARRAY) { php_error(E_ERROR, "_POST array not found"); return 0; } if (zend_hash_find(&EG(symbol_table), "_GET", sizeof("_GET"), (void **) &get_data) != SUCCESS || Z_TYPE_PP(get_data) != IS_ARRAY) { php_error(E_ERROR, "_GET array not found"); return 0; } /*if (get_input_params(get_data, post_data) == FAILURE) { php_error(E_ERROR, "Error getting GET and POST params"); return 0; }*/ MAKE_STD_ZVAL(zvalidate_func); MAKE_STD_ZVAL(retval); /* loop through params defined in config file */ for (i = 0; i < params->nodeNr; i++) { xmlNodePtr param_node = params->nodeTab[i]; char *is_optional, *param_name, *param_type, *param_method; char *validate_func; zval **param_received; /* get attributes for param element */ param_name = xmlGetProp(param_node, "name"); if (param_name == NULL) { php_error(E_ERROR, "Param element missing its name attribute for file %s\n", file); return 0; } param_type = xmlGetProp(param_node, "type"); if (param_type == NULL) { php_error(E_ERROR, "Param %s missing its type attribute for file %s\n", param_name, file); return 0; } param_method = xmlGetProp(param_node, "method"); /* method attribute is obligatory. This may change in the future */ /* if it changes get the _REQUEST array too */ if (param_method == NULL) { php_error(E_ERROR, "Param %s missing its method attribute for file %s\n", param_name, file); return 0; } is_optional = xmlGetProp(param_node, "optional"); /* find the parameter if it's post */ if (strcmp(param_method, "post") == 0) { if (zend_hash_find(Z_ARRVAL_PP(post_data), param_name, strlen(param_name) + 1, (void **) ¶m_received) != SUCCESS) { if ((is_optional == NULL) || (strcmp(is_optional, "no") == 0)) { php_error(E_ERROR, "Post param %s not received\n", param_name); return 0; } else { /* if it's optional continue */ continue; } } } /* find the parameter if it's get */ else if (strcmp(param_method, "get") == 0) { if (zend_hash_find(Z_ARRVAL_PP(get_data), param_name, strlen(param_name) + 1, (void **) ¶m_received) != SUCCESS) { if ((is_optional == NULL) || (strcmp(is_optional, "no") == 0)) { php_error(E_ERROR, "Get param %s not received\n", param_name); return 0; } else { /* if it's optional continue */ continue; } } } /* TODO: search on _COOKIES and finally on _REQUEST too ? */ /* param was not received */ if (param_received == NULL) { php_error(E_ERROR, "Param %s not received\n", param_name); return 0; } validate_func = (char *)emalloc(8 + strlen(param_type) + 1); strcpy(validate_func, "validate"); strcat(validate_func, param_type); /*printf("validate_func = %s\n", validate_func);*/ /* call validation function */ ZVAL_STRING(zvalidate_func, validate_func, 1); ZVAL_FALSE(retval); argv = emalloc(sizeof(zval **)); argv[0] = ¶m_received[0]; result = call_user_function_ex(&(VALKYRIE_G(zce)->function_table), NULL, zvalidate_func, &retval, 1, argv, 0, NULL TSRMLS_CC); if (result == FAILURE) { php_error(E_ERROR, "Could not call function Valkyrie_Validate::%s\n", validate_func); return 0; } if (Z_TYPE_P(retval) != IS_BOOL) { php_error(E_ERROR, "Invalid return type for Valkyrie_Validate::%s", validate_func); return 0; } if (Z_BVAL_P(retval) == 0) { php_error(E_ERROR, "Invalid type for parameter %s", param_name); return 0; } efree(file); efree(validate_func); efree(argv); } zval_dtor(zvalidate_func); zval_dtor(retval); return 1; } /* }}} */ /* {{{ proto bool valkyrie_validate() Validate GET and/or POST params for the currently executed script */ PHP_FUNCTION(valkyrie_validate) { int validated; /* parse config on demand */ if (VALKYRIE_G(config_parsed) == 0) { if (parse_config(TSRMLS_C) == FAILURE) { php_error(E_ERROR, "Could not parse config file"); RETURN_BOOL(0); } } validated = valkyrie_validate(TSRMLS_C); RETURN_BOOL(validated); } /* }}} */ /* {{{ proto bool valkyrie_reload_config() Reload configuration file */ PHP_FUNCTION(valkyrie_reload_config) { if (parse_config(TSRMLS_C) == FAILURE) { RETURN_BOOL(0); } else { RETURN_BOOL(1); } } /* }}} */ /* * Local variables: * tab-width: 4 * c-basic-offset: 4 * End: * vim600: noet sw=4 ts=4 fdm=marker * vim<600: noet sw=4 ts=4 */