static void litespeed_php_import_environment_variables(zval *array_ptr) { char buf[128]; char **env, *p, *t = buf; size_t alloc_size = sizeof(buf); unsigned long nlen; /* ptrdiff_t is not portable */ if (Z_TYPE(PG(http_globals)[TRACK_VARS_ENV]) == IS_ARRAY && Z_ARR_P(array_ptr) != Z_ARR(PG(http_globals)[TRACK_VARS_ENV]) && zend_hash_num_elements(Z_ARRVAL(PG(http_globals)[TRACK_VARS_ENV])) > 0 ) { zval_ptr_dtor_nogc(array_ptr); ZVAL_DUP(array_ptr, &PG(http_globals)[TRACK_VARS_ENV]); return; } else if (Z_TYPE(PG(http_globals)[TRACK_VARS_SERVER]) == IS_ARRAY && Z_ARR_P(array_ptr) != Z_ARR(PG(http_globals)[TRACK_VARS_SERVER]) && zend_hash_num_elements(Z_ARRVAL(PG(http_globals)[TRACK_VARS_SERVER])) > 0 ) { zval_ptr_dtor_nogc(array_ptr); ZVAL_DUP(array_ptr, &PG(http_globals)[TRACK_VARS_SERVER]); return; } tsrm_env_lock(); for (env = environ; env != NULL && *env != NULL; env++) { p = strchr(*env, '='); if (!p) { /* malformed entry? */ continue; } nlen = p - *env; if (nlen >= alloc_size) { alloc_size = nlen + 64; t = (t == buf ? emalloc(alloc_size): erealloc(t, alloc_size)); } memcpy(t, *env, nlen); t[nlen] = '\0'; add_variable(t, nlen, p + 1, strlen( p + 1 ), array_ptr); } tsrm_env_unlock(); if (t != buf && t != NULL) { efree(t); } }
static int add_variable( const char * pKey, int keyLen, const char * pValue, int valLen, void * arg ) { int filter_arg = (Z_ARR_P((zval *)arg) == Z_ARR(PG(http_globals)[TRACK_VARS_ENV])) ? PARSE_ENV : PARSE_SERVER; char * new_val = (char *) pValue; size_t new_val_len; if (sapi_module.input_filter(filter_arg, (char *)pKey, &new_val, valLen, &new_val_len)) { php_register_variable_safe((char *)pKey, new_val, new_val_len, (zval *)arg ); } return 1; }
static void _timecop_gettimeofday(INTERNAL_FUNCTION_PARAMETERS, int mode) { zend_bool get_as_float = 0; long fixed_sec = 0, fixed_usec = 0; if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|b", &get_as_float) == FAILURE) { return; } switch (TIMECOP_G(timecop_mode)) { case TIMECOP_MODE_FREEZE: fixed_sec = TIMECOP_G(freezed_timestamp); fixed_usec = 0; break; case TIMECOP_MODE_TRAVEL: { zval timeofday, *zv_sec, *zv_usec; timecop_call_orig_method_with_0_params(NULL, NULL, NULL, "gettimeofday", &timeofday); zv_sec = zend_hash_str_find(Z_ARR(timeofday), "sec", sizeof("sec")-1); if (zv_sec) { fixed_sec = Z_LVAL_P(zv_sec) + TIMECOP_G(travel_offset); } zv_usec = zend_hash_str_find(Z_ARR(timeofday), "usec", sizeof("usec")-1); if (zv_sec) { fixed_usec = Z_LVAL_P(zv_usec); } zval_ptr_dtor(&timeofday); } break; default: { const char *func_name; size_t func_name_len; zval *arg1 = NULL, tmp; int param_count = 0; if (mode) { func_name = ORIG_FUNC_NAME("gettimeofday"); func_name_len = ORIG_FUNC_NAME_SIZEOF("gettimeofday")-1; } else { func_name = ORIG_FUNC_NAME("microtime"); func_name_len = ORIG_FUNC_NAME_SIZEOF("microtime")-1; } if (get_as_float) { ZVAL_TRUE(&tmp); arg1 = &tmp; param_count = 1; } zend_call_method(NULL, NULL, NULL, func_name, func_name_len, return_value, param_count, arg1, NULL); return; } } if (get_as_float) { RETURN_DOUBLE((double)(fixed_sec + fixed_usec / MICRO_IN_SEC)); } if (mode) { zval zv_offset, zv_dst, format, timestamp; long offset = 0, is_dst = 0; ZVAL_LONG(×tamp, fixed_sec); /* offset */ ZVAL_STRING(&format, "Z"); timecop_call_orig_method_with_2_params(NULL, NULL, NULL, "date", &zv_offset, &format, ×tamp); convert_to_long(&zv_offset); offset = Z_LVAL(zv_offset); zval_ptr_dtor(&zv_offset); zval_ptr_dtor(&format); /* is_dst */ ZVAL_STRING(&format, "I"); timecop_call_orig_method_with_2_params(NULL, NULL, NULL, "date", &zv_dst, &format, ×tamp); convert_to_long(&zv_dst); is_dst = Z_LVAL(zv_dst); zval_ptr_dtor(&zv_dst); zval_ptr_dtor(&format); array_init(return_value); add_assoc_long(return_value, "sec", fixed_sec); add_assoc_long(return_value, "usec", fixed_usec); add_assoc_long(return_value, "minuteswest", -offset / SEC_IN_MIN); add_assoc_long(return_value, "dsttime", is_dst); } else { char ret[100]; snprintf(ret, 100, "%.8F %ld", fixed_usec / MICRO_IN_SEC, fixed_sec); RETURN_STRING(ret); } }
PHPAPI void php_register_variable_ex(char *var_name, zval *val, zval *track_vars_array) { char *p = NULL; char *ip = NULL; /* index pointer */ char *index; char *var, *var_orig; size_t var_len, index_len; zval gpc_element, *gpc_element_p; zend_bool is_array = 0; HashTable *symtable1 = NULL; ALLOCA_FLAG(use_heap) assert(var_name != NULL); if (track_vars_array && Z_TYPE_P(track_vars_array) == IS_ARRAY) { symtable1 = Z_ARRVAL_P(track_vars_array); } if (!symtable1) { /* Nothing to do */ zval_ptr_dtor_nogc(val); return; } /* ignore leading spaces in the variable name */ while (*var_name==' ') { var_name++; } /* * Prepare variable name */ var_len = strlen(var_name); var = var_orig = do_alloca(var_len + 1, use_heap); memcpy(var_orig, var_name, var_len + 1); /* ensure that we don't have spaces or dots in the variable name (not binary safe) */ for (p = var; *p; p++) { if (*p == ' ' || *p == '.') { *p='_'; } else if (*p == '[') { is_array = 1; ip = p; *p = 0; break; } } var_len = p - var; if (var_len==0) { /* empty variable name, or variable name with a space in it */ zval_ptr_dtor_nogc(val); free_alloca(var_orig, use_heap); return; } if (var_len == sizeof("this")-1 && EG(current_execute_data)) { zend_execute_data *ex = EG(current_execute_data); while (ex) { if (ex->func && ZEND_USER_CODE(ex->func->common.type)) { if ((ZEND_CALL_INFO(ex) & ZEND_CALL_HAS_SYMBOL_TABLE) && ex->symbol_table == symtable1) { if (memcmp(var, "this", sizeof("this")-1) == 0) { zend_throw_error(NULL, "Cannot re-assign $this"); zval_ptr_dtor_nogc(val); free_alloca(var_orig, use_heap); return; } } break; } ex = ex->prev_execute_data; } } /* GLOBALS hijack attempt, reject parameter */ if (symtable1 == &EG(symbol_table) && var_len == sizeof("GLOBALS")-1 && !memcmp(var, "GLOBALS", sizeof("GLOBALS")-1)) { zval_ptr_dtor_nogc(val); free_alloca(var_orig, use_heap); return; } index = var; index_len = var_len; if (is_array) { int nest_level = 0; while (1) { char *index_s; size_t new_idx_len = 0; if(++nest_level > PG(max_input_nesting_level)) { HashTable *ht; /* too many levels of nesting */ if (track_vars_array) { ht = Z_ARRVAL_P(track_vars_array); zend_symtable_str_del(ht, var, var_len); } zval_ptr_dtor_nogc(val); /* do not output the error message to the screen, this helps us to to avoid "information disclosure" */ if (!PG(display_errors)) { php_error_docref(NULL, E_WARNING, "Input variable nesting level exceeded " ZEND_LONG_FMT ". To increase the limit change max_input_nesting_level in php.ini.", PG(max_input_nesting_level)); } free_alloca(var_orig, use_heap); return; } ip++; index_s = ip; if (isspace(*ip)) { ip++; } if (*ip==']') { index_s = NULL; } else { ip = strchr(ip, ']'); if (!ip) { /* PHP variables cannot contain '[' in their names, so we replace the character with a '_' */ *(index_s - 1) = '_'; index_len = 0; if (index) { index_len = strlen(index); } goto plain_var; return; } *ip = 0; new_idx_len = strlen(index_s); } if (!index) { array_init(&gpc_element); if ((gpc_element_p = zend_hash_next_index_insert(symtable1, &gpc_element)) == NULL) { zend_array_destroy(Z_ARR(gpc_element)); zval_ptr_dtor_nogc(val); free_alloca(var_orig, use_heap); return; } } else { gpc_element_p = zend_symtable_str_find(symtable1, index, index_len); if (!gpc_element_p) { zval tmp; array_init(&tmp); gpc_element_p = zend_symtable_str_update_ind(symtable1, index, index_len, &tmp); } else { if (Z_TYPE_P(gpc_element_p) == IS_INDIRECT) { gpc_element_p = Z_INDIRECT_P(gpc_element_p); } if (Z_TYPE_P(gpc_element_p) != IS_ARRAY) { zval_ptr_dtor_nogc(gpc_element_p); array_init(gpc_element_p); } else { SEPARATE_ARRAY(gpc_element_p); } } } symtable1 = Z_ARRVAL_P(gpc_element_p); /* ip pointed to the '[' character, now obtain the key */ index = index_s; index_len = new_idx_len; ip++; if (*ip == '[') { is_array = 1; *ip = 0; } else { goto plain_var; } } } else { plain_var: if (!index) { if (zend_hash_next_index_insert(symtable1, val) == NULL) { zval_ptr_dtor_nogc(val); } } else { zend_ulong idx; /* * According to rfc2965, more specific paths are listed above the less specific ones. * If we encounter a duplicate cookie name, we should skip it, since it is not possible * to have the same (plain text) cookie name for the same path and we should not overwrite * more specific cookies with the less specific ones. */ if (Z_TYPE(PG(http_globals)[TRACK_VARS_COOKIE]) != IS_UNDEF && symtable1 == Z_ARRVAL(PG(http_globals)[TRACK_VARS_COOKIE]) && zend_symtable_str_exists(symtable1, index, index_len)) { zval_ptr_dtor_nogc(val); } else if (ZEND_HANDLE_NUMERIC_STR(index, index_len, idx)) { zend_hash_index_update(symtable1, idx, val); } else { php_register_variable_quick(index, index_len, val, symtable1); } } } free_alloca(var_orig, use_heap); }