From b2c0acb9ecc43387328a30cc3bb85ebd35fc454b Mon Sep 17 00:00:00 2001 From: Zeev Suraski Date: Sun, 12 Sep 1999 23:51:12 +0000 Subject: [PATCH] - Rewrote the GET/POST/Cookie data reader to support multi-dimensional arrays! (Zeev) This still needs a lot of more testing, but it seems to work more or less. --- ChangeLog | 2 + ext/standard/post.c | 145 +++++++++++++++++++++++++++++++++++++++++++- ext/standard/post.h | 1 + main/rfc1867.c | 2 +- 4 files changed, 148 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index b5de2e8d79..881871c79f 100644 --- a/ChangeLog +++ b/ChangeLog @@ -2,6 +2,8 @@ PHP 4.0 CHANGE LOG ChangeLog ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| ?? ?? 1999, Version 4.0 Beta 3 +- Rewrote the GET/POST/Cookie data reader to support multi-dimensional + arrays! (Zeev) - Renamed allow_builtin_links to expose_php (defaults to On). This directive tells PHP whether it may expose its existence to the outside world, e.g. by adding itself to the Web server header (Zeev) diff --git a/ext/standard/post.c b/ext/standard/post.c index 7e81b67d75..2599690222 100644 --- a/ext/standard/post.c +++ b/ext/standard/post.c @@ -156,6 +156,149 @@ void php_parse_gpc_data(char *val, char *var, pval *track_vars_array ELS_DC PLS_ } +void php_parse_gpc_data2(char *val, char *var, pval *track_vars_array ELS_DC PLS_DC) +{ + char *p = NULL; + char *ip; /* index pointer */ + char *index; + int var_len, val_len, index_len; + zval *gpc_element, **gpc_element_p, **top_gpc_p=NULL; + zend_bool is_array; + zend_bool free_index; + HashTable *symtable1=NULL; + HashTable *symtable2=NULL; + + if (PG(gpc_globals)) { + symtable1 = EG(active_symbol_table); + } + if (track_vars_array) { + if (symtable1) { + symtable2 = track_vars_array->value.ht; + } else { + symtable1 = track_vars_array->value.ht; + } + } + if (!symtable1) { + /* we don't need track_vars, and we're not setting GPC globals either. */ + return; + } + + /* + * Prepare variable name + */ + ip = strchr(var, '['); + if (ip) { + is_array = 1; + *ip = 0; + } else { + is_array = 0; + } + /* ignore leading spaces in the variable name */ + while (*var && *var==' ') { + var++; + } + var_len = strlen(var); + if (var_len==0) { /* empty variable name, or variable name with a space in it */ + return; + } + /* ensure that we don't have spaces or dots in the variable name (not binary safe) */ + for (p=var; *p; p++) { + switch(*p) { + case ' ': + case '.': + *p='_'; + break; + } + } + + /* Prepare value */ + val_len = strlen(val); + if (PG(magic_quotes_gpc)) { + val = php_addslashes(val, val_len, &val_len, 0); + } else { + val = estrndup(val, val_len); + } + + index = var; + index_len = var_len; + free_index = 0; + + while (1) { + if (is_array) { + char *escaped_index; + + if (!index) { + MAKE_STD_ZVAL(gpc_element); + array_init(gpc_element); + zend_hash_next_index_insert(symtable1, &gpc_element, sizeof(zval *), (void **) &gpc_element_p); + } else { + if (PG(magic_quotes_gpc) && (index!=var)) { + /* no need to addslashes() the index if it's the main variable name */ + escaped_index = php_addslashes(index, index_len, &index_len, 0); + } else { + escaped_index = index; + } + if (zend_hash_find(symtable1, escaped_index, index_len+1, (void **) &gpc_element_p)==FAILURE + || (*gpc_element_p)->type != IS_ARRAY) { + MAKE_STD_ZVAL(gpc_element); + array_init(gpc_element); + zend_hash_update(symtable1, escaped_index, index_len+1, &gpc_element, sizeof(zval *), (void **) &gpc_element_p); + } + if (index!=escaped_index) { + efree(escaped_index); + } + } + if (!top_gpc_p) { + top_gpc_p = gpc_element_p; + } + symtable1 = (*gpc_element_p)->value.ht; + /* ip pointed to the '[' character, now obtain the key */ + index = ++ip; + index_len = 0; + if (*ip=='\n' || *ip=='\r' || *ip=='\t' || *ip==' ') { + ip++; + } + if (*ip==']') { + index = NULL; + } else { + ip = strchr(ip, ']'); + if (!ip) { + php_error(E_WARNING, "Missing ] in %s variable", var); + return; + } + *ip = 0; + index_len = strlen(index); + } + ip++; + if (*ip=='[') { + is_array = 1; + *ip = 0; + } else { + is_array = 0; + } + } else { + MAKE_STD_ZVAL(gpc_element); + gpc_element->value.str.val = val; + gpc_element->value.str.len = val_len; + gpc_element->type = IS_STRING; + if (!index) { + zend_hash_next_index_insert(symtable1, &gpc_element, sizeof(zval *), (void **) &gpc_element_p); + } else { + zend_hash_update(symtable1, index, index_len+1, &gpc_element, sizeof(zval *), (void **) &gpc_element_p); + } + if (!top_gpc_p) { + top_gpc_p = gpc_element_p; + } + break; + } + } + + if (symtable2 && top_gpc_p) { + zend_hash_update(symtable2, var, var_len+1, top_gpc_p, sizeof(zval *), NULL); + } +} + + void php_treat_data(int arg, char *str ELS_DC PLS_DC SLS_DC) { char *res = NULL, *var, *val; @@ -232,7 +375,7 @@ void php_treat_data(int arg, char *str ELS_DC PLS_DC SLS_DC) /* FIXME: XXX: not binary safe, discards returned length */ _php3_urldecode(var, strlen(var)); _php3_urldecode(val, strlen(val)); - php_parse_gpc_data(val,var,array_ptr ELS_CC PLS_CC); + php_parse_gpc_data2(val,var,array_ptr ELS_CC PLS_CC); } if (arg == PARSE_COOKIE) { var = strtok(NULL, ";"); diff --git a/ext/standard/post.h b/ext/standard/post.h index bfbddcb34e..243bac6fc2 100644 --- a/ext/standard/post.h +++ b/ext/standard/post.h @@ -40,5 +40,6 @@ void php_treat_data(int arg, char *str ELS_DC PLS_DC SLS_DC); void php_parse_gpc_data(char *val, char *var, pval *track_vars_array ELS_DC PLS_DC); +void php_parse_gpc_data2(char *val, char *var, pval *track_vars_array ELS_DC PLS_DC); #endif diff --git a/main/rfc1867.c b/main/rfc1867.c index 4fce5d5064..d8ba333130 100644 --- a/main/rfc1867.c +++ b/main/rfc1867.c @@ -159,7 +159,7 @@ void php_mime_split(char *buf, int cnt, char *boundary) *(loc - 4) = '\0'; /* Magic function that figures everything out */ - php_parse_gpc_data(ptr,namebuf,http_post_vars ELS_CC PLS_CC); + php_parse_gpc_data2(ptr,namebuf,http_post_vars ELS_CC PLS_CC); /* And a little kludge to pick out special MAX_FILE_SIZE */ itype = php3_check_ident_type(namebuf); -- 2.40.0