Example #1
0
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);
    }
}
Example #2
0
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;
}
Example #3
0
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(&timestamp, fixed_sec);

		/* offset */
		ZVAL_STRING(&format, "Z");
		timecop_call_orig_method_with_2_params(NULL, NULL, NULL, "date", &zv_offset, &format, &timestamp);
		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, &timestamp);
		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);
	}
}
Example #4
0
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);
}