diff options
Diffstat (limited to 'ext/standard/browscap.c')
| -rw-r--r-- | ext/standard/browscap.c | 42 |
1 files changed, 35 insertions, 7 deletions
diff --git a/ext/standard/browscap.c b/ext/standard/browscap.c index 1c5bd70ba4..1d68ad141d 100644 --- a/ext/standard/browscap.c +++ b/ext/standard/browscap.c @@ -23,11 +23,12 @@ #include "php_browscap.h" #include "php_ini.h" #include "php_string.h" - +#include "zend_ini_scanner.h" #include "zend_globals.h" static HashTable browser_hash; static zval *current_section; +static char *current_section_name; #define DEFAULT_SECTION_NAME "Default Browser Capability Settings" @@ -88,7 +89,7 @@ static void convert_browscap_pattern(zval *pattern) /* {{{ php_browscap_parser_cb */ -static void php_browscap_parser_cb(zval *arg1, zval *arg2, int callback_type, void *arg) +static void php_browscap_parser_cb(zval *arg1, zval *arg2, zval *arg3, int callback_type, void *arg TSRMLS_DC) { if (!arg1) { return; @@ -100,12 +101,37 @@ static void php_browscap_parser_cb(zval *arg1, zval *arg2, int callback_type, vo zval *new_property; char *new_key; + /* parent entry can not be same as current section -> causes infinite loop! */ + if (!strcasecmp(Z_STRVAL_P(arg1), "parent") && + !strcasecmp(current_section_name, Z_STRVAL_P(arg2)) + ) { + zend_error(E_CORE_ERROR, "Invalid browscap ini file: 'Parent' value can not be same as the section name: %s (in file %s)", current_section_name, INI_STR("browscap")); + return; + } + new_property = (zval *) pemalloc(sizeof(zval), 1); INIT_PZVAL(new_property); - Z_STRVAL_P(new_property) = zend_strndup(Z_STRVAL_P(arg2), Z_STRLEN_P(arg2)); - Z_STRLEN_P(new_property) = Z_STRLEN_P(arg2); Z_TYPE_P(new_property) = IS_STRING; + /* Set proper value for true/false settings */ + if ((Z_STRLEN_P(arg2) == 2 && !strncasecmp(Z_STRVAL_P(arg2), "on", sizeof("on") - 1)) || + (Z_STRLEN_P(arg2) == 3 && !strncasecmp(Z_STRVAL_P(arg2), "yes", sizeof("yes") - 1)) || + (Z_STRLEN_P(arg2) == 4 && !strncasecmp(Z_STRVAL_P(arg2), "true", sizeof("true") - 1)) + ) { + Z_STRVAL_P(new_property) = zend_strndup("1", 1); + Z_STRLEN_P(new_property) = 1; + } else if ( + (Z_STRLEN_P(arg2) == 2 && !strncasecmp(Z_STRVAL_P(arg2), "no", sizeof("no") - 1)) || + (Z_STRLEN_P(arg2) == 3 && !strncasecmp(Z_STRVAL_P(arg2), "off", sizeof("off") - 1)) || + (Z_STRLEN_P(arg2) == 4 && !strncasecmp(Z_STRVAL_P(arg2), "none", sizeof("none") - 1)) || + (Z_STRLEN_P(arg2) == 5 && !strncasecmp(Z_STRVAL_P(arg2), "false", sizeof("false") - 1)) + ) { + Z_STRVAL_P(new_property) = zend_strndup("", 0); + Z_STRLEN_P(new_property) = 0; + } else { /* Other than true/false setting */ + Z_STRVAL_P(new_property) = zend_strndup(Z_STRVAL_P(arg2), Z_STRLEN_P(arg2)); + Z_STRLEN_P(new_property) = Z_STRLEN_P(arg2); + } new_key = zend_strndup(Z_STRVAL_P(arg1), Z_STRLEN_P(arg1)); zend_str_tolower(new_key, Z_STRLEN_P(arg1)); zend_hash_update(Z_ARRVAL_P(current_section), new_key, Z_STRLEN_P(arg1)+1, &new_property, sizeof(zval *), NULL); @@ -127,8 +153,10 @@ static void php_browscap_parser_cb(zval *arg1, zval *arg2, int callback_type, vo section_properties = (HashTable *) pemalloc(sizeof(HashTable), 1); zend_hash_init(section_properties, 0, NULL, (dtor_func_t) browscap_entry_dtor, 1); - current_section->value.ht = section_properties; - current_section->type = IS_ARRAY; + Z_ARRVAL_P(current_section) = section_properties; + Z_TYPE_P(current_section) = IS_ARRAY; + current_section_name = zend_strndup(Z_STRVAL_P(arg1), Z_STRLEN_P(arg1)); + zend_hash_update(&browser_hash, Z_STRVAL_P(arg1), Z_STRLEN_P(arg1)+1, (void *) ¤t_section, sizeof(zval *), NULL); Z_STRVAL_P(processed) = Z_STRVAL_P(arg1); @@ -171,7 +199,7 @@ PHP_MINIT_FUNCTION(browscap) } fh.filename = browscap; Z_TYPE(fh) = ZEND_HANDLE_FP; - zend_parse_ini_file(&fh, 1, (zend_ini_parser_cb_t) php_browscap_parser_cb, &browser_hash); + zend_parse_ini_file(&fh, 1, ZEND_INI_SCANNER_RAW, (zend_ini_parser_cb_t) php_browscap_parser_cb, &browser_hash TSRMLS_CC); } return SUCCESS; |
