Exemplo n.º 1
0
static void print_hash(smart_str *buf, HashTable *ht, int indent, zend_bool is_object) /* {{{ */
{
	zval *tmp;
	zend_string *string_key;
	zend_ulong num_key;
	int i;

	for (i = 0; i < indent; i++) {
		smart_str_appendc(buf, ' ');
	}
	smart_str_appends(buf, "(\n");
	indent += PRINT_ZVAL_INDENT;
	ZEND_HASH_FOREACH_KEY_VAL_IND(ht, num_key, string_key, tmp) {
		for (i = 0; i < indent; i++) {
			smart_str_appendc(buf, ' ');
		}
		smart_str_appendc(buf, '[');
		if (string_key) {
			if (is_object) {
				const char *prop_name, *class_name;
				size_t prop_len;
				int mangled = zend_unmangle_property_name_ex(string_key, &class_name, &prop_name, &prop_len);

				smart_str_appendl(buf, prop_name, prop_len);
				if (class_name && mangled == SUCCESS) {
					if (class_name[0] == '*') {
						smart_str_appends(buf, ":protected");
					} else {
						smart_str_appends(buf, ":");
						smart_str_appends(buf, class_name);
						smart_str_appends(buf, ":private");
					}
				}
			} else {
				smart_str_append(buf, string_key);
			}
		} else {
			smart_str_append_long(buf, num_key);
		}
		smart_str_appends(buf, "] => ");
		zend_print_zval_r_to_buf(buf, tmp, indent+PRINT_ZVAL_INDENT);
		smart_str_appends(buf, "\n");
	} ZEND_HASH_FOREACH_END();
	indent -= PRINT_ZVAL_INDENT;
	for (i = 0; i < indent; i++) {
		smart_str_appendc(buf, ' ');
	}
	smart_str_appends(buf, ")\n");
}
Exemplo n.º 2
0
static void php_mail_build_headers_elem(smart_str *s, zend_string *key, zval *val)
{
	switch(Z_TYPE_P(val)) {
		case IS_STRING:
			if (php_mail_build_headers_check_field_name(key) != SUCCESS) {
				php_error_docref(NULL, E_WARNING, "Header field name (%s) contains invalid chars", ZSTR_VAL(key));
				return;
			}
			if (php_mail_build_headers_check_field_value(val) != SUCCESS) {
				php_error_docref(NULL, E_WARNING, "Header field value (%s => %s) contains invalid chars or format", ZSTR_VAL(key), Z_STRVAL_P(val));
				return;
			}
			smart_str_append(s, key);
			smart_str_appendl(s, ": ", 2);
			smart_str_appends(s, Z_STRVAL_P(val));
			smart_str_appendl(s, "\r\n", 2);
			break;
		case IS_ARRAY:
			php_mail_build_headers_elems(s, key, val);
			break;
		default:
			php_error_docref(NULL, E_WARNING, "headers array elements must be string or array (%s)", ZSTR_VAL(key));
	}
}
Exemplo n.º 3
0
static inline void handle_tag(STD_PARA) 
{
	int ok = 0;
	unsigned int i;

	if (ctx->tag.s) {
		ctx->tag.s->len = 0;
	}
	smart_str_appendl(&ctx->tag, start, YYCURSOR - start);
	for (i = 0; i < ctx->tag.s->len; i++)
		ctx->tag.s->val[i] = tolower((int)(unsigned char)ctx->tag.s->val[i]);
    /* intentionally using str_find here, in case the hash value is set, but the string val is changed later */
	if ((ctx->lookup_data = zend_hash_str_find_ptr(ctx->tags, ctx->tag.s->val, ctx->tag.s->len)) != NULL)
		ok = 1;
	STATE = ok ? STATE_NEXT_ARG : STATE_PLAIN;
}
Exemplo n.º 4
0
static size_t readline_shell_write(const char *str, size_t str_length TSRMLS_DC) /* {{{ */
{
	if (CLIR_G(prompt_str)) {
		smart_str_appendl(CLIR_G(prompt_str), str, str_length);
		return str_length;
	}

	if (CLIR_G(pager) && *CLIR_G(pager) && !pager_pipe) {
		pager_pipe = VCWD_POPEN(CLIR_G(pager), "w");
	}
	if (pager_pipe) {
		return fwrite(str, 1, MIN(str_length, 16384), pager_pipe);
	}

	return -1;
}
Exemplo n.º 5
0
PHPAPI static void php_discuz_auth_encode(smart_str *buf, const char *str, int str_len, const char *key, int keylen, long expiry)
{
	char keya[33], keyb[33], keyc[DISCUZ_AUTH_CKEYLEN+1], cryptkey[65]={0};
        char ret[100], retmd5[33];
        char *pc;
	struct timeval tp = {0};
        smart_str strbuf = {0};
        if (gettimeofday(&tp, NULL)) {
                return;
        }
        snprintf(ret, 100, "%.8F %ld", tp.tv_usec / MICRO_IN_SEC, tp.tv_sec);

        php_md5(retmd5, ret, strlen(ret));
        bzero(keyc, sizeof(keyc));
        memcpy(keyc, retmd5 + 32 - DISCUZ_AUTH_CKEYLEN, DISCUZ_AUTH_CKEYLEN);

	php_discuz_auth_initkey(keya, keyb, cryptkey, keyc, key, keylen);
	//$string = sprintf('%010d', $expiry ? $expiry + time() : 0).substr(md5($string.$keyb), 0, 16).$string;
	smart_str_appendl(&strbuf, str, str_len);
	smart_str_appendl(&strbuf, keyb, 32);
	php_md5(retmd5, strbuf.c, strbuf.len);
	smart_str_free(&strbuf);

	snprintf(ret, sizeof(ret), "%010d", expiry ? expiry + time(NULL) : 0);
	smart_str_appendl(&strbuf, ret, 10);
	smart_str_appendl(&strbuf, retmd5, 16);
	smart_str_appendl(&strbuf, str, str_len);

	pc = (unsigned char *)safe_emalloc(strbuf.len, sizeof(char), 1);
	php_discuz_authcode(pc, strbuf.c, strbuf.len, cryptkey);

	//return $keyc.str_replace('=', '', base64_encode($result));
	char *result;
	int retlen;
	result = php_base64_encode((unsigned char*)pc, strbuf.len, &retlen);
	efree(pc);	

	int index, to;
	for(index = 0, to = 0; index <= retlen; index++) {
		if(*(result+index) != '=') {
			*(result+to) = *(result+index);
			to++;
		}
	}
	smart_str_appendl(buf, keyc, DISCUZ_AUTH_CKEYLEN);
	smart_str_appendl(buf, result, retlen - (index - to));
	smart_str_free(&strbuf);
}
Exemplo n.º 6
0
int php_ds_default_cast_object(zval *obj, zval *return_value, int type)
{
    switch (type) {
        case IS_STRING: {
            smart_str buffer = {0};

            smart_str_appendl(&buffer, "object(", 7);
            smart_str_append (&buffer, Z_OBJCE_P(obj)->name);
            smart_str_appendc(&buffer, ')');

            smart_str_0(&buffer);
            ZVAL_STR(return_value, buffer.s);
            return SUCCESS;
        }
    }

    return FAILURE;
}
Exemplo n.º 7
0
zend_string *ds_join_zval_buffer(
    zval        *buffer,
    zend_long    size,
    char        *glue,
    size_t       len
) {
    smart_str str = {0};

    if (size <= 0) {
        return ZSTR_EMPTY_ALLOC();
    }

    if (size == 1) {
        return zval_get_string(buffer);
    }

    // Glue is optional, will use empty string by default if NULL
    if (glue && len) {
        zval *pos = buffer;
        zval *end = buffer + size - 1; // Exclude last value

        // Append each part and the glue right up to the last value.
        do {
            smart_str_appendz(&str, pos);
            smart_str_appendl(&str, glue, len);
        } while (++pos != end);

        // Append last value
        smart_str_appendz(&str, pos);

    } else {
        zval *pos = buffer;
        zval *end = buffer + size;

        // Append each part including the last, without glue.
        do {
            smart_str_appendz(&str, pos);
        } while (++pos != end);
    }

    smart_str_0(&str);
    return str.s;
}
Exemplo n.º 8
0
static inline void handle_tag(STD_PARA)
{
	int ok = 0;
	unsigned int i;

	if (ctx->tag.s) {
		ZSTR_LEN(ctx->tag.s) = 0;
	}
	smart_str_appendl(&ctx->tag, start, YYCURSOR - start);
	for (i = 0; i < ZSTR_LEN(ctx->tag.s); i++)
		ZSTR_VAL(ctx->tag.s)[i] = tolower((int)(unsigned char)ZSTR_VAL(ctx->tag.s)[i]);
    /* intentionally using str_find here, in case the hash value is set, but the string val is changed later */
	if ((ctx->lookup_data = zend_hash_str_find_ptr(ctx->tags, ZSTR_VAL(ctx->tag.s), ZSTR_LEN(ctx->tag.s))) != NULL) {
		ok = 1;
		if (ZSTR_LEN(ctx->tag.s) == sizeof("form")-1
			&& !strncasecmp(ZSTR_VAL(ctx->tag.s), "form", ZSTR_LEN(ctx->tag.s))) {
			ctx->tag_type = TAG_FORM;
		} else {
			ctx->tag_type = TAG_NORMAL;
		}
	}
	STATE = ok ? STATE_NEXT_ARG : STATE_PLAIN;
}
Exemplo n.º 9
0
/**
 * Replaces directory separators by the virtual separator
 */
void zephir_prepare_virtual_path(zval *return_value, zval *path, zval *virtual_separator)
{

	unsigned int i;
	unsigned char ch;
	smart_str virtual_str = {0};

	if (Z_TYPE_P(path) != IS_STRING || Z_TYPE_P(virtual_separator) != IS_STRING) {
		if (Z_TYPE_P(path) == IS_STRING) {
			RETURN_STR(zval_get_string(path));
		} else {
			RETURN_EMPTY_STRING();
		}
		return;
	}

	for (i = 0; i < Z_STRLEN_P(path); i++) {
		ch = Z_STRVAL_P(path)[i];
		if (ch == '\0') {
			break;
		}
		if (ch == '/' || ch == '\\' || ch == ':') {
			smart_str_appendl(&virtual_str, Z_STRVAL_P(virtual_separator), Z_STRLEN_P(virtual_separator));
		}
		else {
			smart_str_appendc(&virtual_str, tolower(ch));
		}
	}

	smart_str_0(&virtual_str);

	if (virtual_str.s) {
		RETURN_STR(virtual_str.s);
	} else {
		RETURN_EMPTY_STRING();
	}
}
Exemplo n.º 10
0
static inline void php_url_scanner_session_handler_impl(char *output, size_t output_len, char **handled_output, size_t *handled_output_len, int mode, int type)
{
	size_t len;
	url_adapt_state_ex_t *url_state;

	if (type) {
		url_state = &BG(url_adapt_session_ex);
	} else {
		url_state = &BG(url_adapt_output_ex);
	}

	if (ZSTR_LEN(url_state->url_app.s) != 0) {
		*handled_output = url_adapt_ext(output, output_len, &len, (zend_bool) (mode & (PHP_OUTPUT_HANDLER_END | PHP_OUTPUT_HANDLER_CONT | PHP_OUTPUT_HANDLER_FLUSH | PHP_OUTPUT_HANDLER_FINAL) ? 1 : 0), url_state);
		if (sizeof(uint32_t) < sizeof(size_t)) {
			if (len > UINT_MAX)
				len = UINT_MAX;
		}
		*handled_output_len = len;
	} else if (ZSTR_LEN(url_state->url_app.s) == 0) {
		url_adapt_state_ex_t *ctx = url_state;
		if (ctx->buf.s && ZSTR_LEN(ctx->buf.s)) {
			smart_str_append(&ctx->result, ctx->buf.s);
			smart_str_appendl(&ctx->result, output, output_len);

			*handled_output = estrndup(ZSTR_VAL(ctx->result.s), ZSTR_LEN(ctx->result.s));
			*handled_output_len = ZSTR_LEN(ctx->buf.s) + output_len;

			smart_str_free(&ctx->buf);
			smart_str_free(&ctx->result);
		} else {
			*handled_output = estrndup(output, *handled_output_len = output_len);
		}
	} else {
		*handled_output = NULL;
	}
}
Exemplo n.º 11
0
static char *url_adapt_ext(const char *src, size_t srclen, size_t *newlen, zend_bool do_flush, url_adapt_state_ex_t *ctx)
{
	char *retval;

	xx_mainloop(ctx, src, srclen);

	if (!ctx->result.s) {
		smart_str_appendl(&ctx->result, "", 0);
		*newlen = 0;
	} else {
		*newlen = ZSTR_LEN(ctx->result.s);
	}
	smart_str_0(&ctx->result);
	if (do_flush) {
		smart_str_append(&ctx->result, ctx->buf.s);
		*newlen += ZSTR_LEN(ctx->buf.s);
		smart_str_free(&ctx->buf);
		smart_str_free(&ctx->val);
		smart_str_free(&ctx->attr_val);
	}
	retval = estrndup(ZSTR_VAL(ctx->result.s), ZSTR_LEN(ctx->result.s));
	smart_str_free(&ctx->result);
	return retval;
}
Exemplo n.º 12
0
/**
 * Gets HTTP raw request body
 *
 * @return string
 */
PHP_METHOD(Phalcon_Http_Request, getRawBody){

	zval *raw;
	if (SG(request_info).raw_post_data) {
		RETURN_STRINGL(SG(request_info).raw_post_data, SG(request_info).raw_post_data_length, 1);
	}

	phalcon_read_property_this(&raw, getThis(), SL("_rawBody"), PH_NOISY TSRMLS_CC);
	if (Z_TYPE_P(raw) == IS_STRING) {
		RETURN_ZVAL(raw, 1, 1);
	}
	else if (sapi_module.read_post) {
		int read_bytes;
		char *buf          = emalloc(8192);
		smart_str raw_data = { NULL, 0, 0 };

		while ((read_bytes = sapi_module.read_post(buf, 8192 TSRMLS_CC)) > 0) {
			smart_str_appendl(&raw_data, buf, read_bytes);
			SG(read_post_bytes) += read_bytes;
		}

		efree(buf);
		if (raw_data.c) {
			smart_str_0(&raw_data);
			RETVAL_STRINGL(raw_data.c, raw_data.len, 0);
		}
		else {
			RETVAL_EMPTY_STRING();
		}

		phalcon_update_property_this(getThis(), SL("_rawBody"), return_value TSRMLS_CC);
	}
	else {
		RETURN_EMPTY_STRING();
	}
}
Exemplo n.º 13
0
zend_string *php_yar_packager_pack(char *packager_name, zval *pzval, char **msg) /* {{{ */ {
	char header[8];
	smart_str buf = {0};
	const yar_packager_t *packager = packager_name ?
		php_yar_packager_get(packager_name, strlen(packager_name)) : YAR_G(packager);

	if (!packager) {
		php_error_docref(NULL, E_ERROR, "unsupported packager %s", packager_name);
		return 0;
	}
	memcpy(header, packager->name, 8);
	smart_str_alloc(&buf, YAR_PACKAGER_BUFFER_SIZE /* 1M */, 0);
	smart_str_appendl(&buf, header, 8);
    packager->pack(packager, pzval, &buf, msg); 

	if (buf.s) {
		smart_str_0(&buf);
		return buf.s;
	}

	smart_str_free(&buf);

	return NULL;
} /* }}} */
Exemplo n.º 14
0
/**
 * Gets HTTP raw request body
 *
 * @return string
 */
PHP_METHOD(Phalcon_Http_Request, getRawBody){

	if (SG(request_info).raw_post_data) {
		RETURN_STRINGL(SG(request_info).raw_post_data, SG(request_info).raw_post_data_length, 1);
	}

	if (sapi_module.read_post) {
		int read_bytes;
		char *buf          = emalloc(8192);
		smart_str raw_data = { NULL, 0, 0 };

		while ((read_bytes = sapi_module.read_post(buf, 8192 TSRMLS_CC)) > 0) {
			smart_str_appendl(&raw_data, buf, read_bytes);
			SG(read_post_bytes) += read_bytes;
		}

		efree(buf);
		if (raw_data.c) {
			RETURN_STRINGL(raw_data.c, raw_data.len, 0);
		}
	}

	RETURN_EMPTY_STRING();
}
Exemplo n.º 15
0
smart_str intl_parse_error_to_string( UParseError* pe )
{
	smart_str  ret = {0};
	char       *buf;
	size_t     u8len;
	UErrorCode status;
	int        any = 0;

	assert( pe != NULL );

	smart_str_appends( &ret, "parse error " );
	if( pe->line > 0 )
	{
		smart_str_appends( &ret, "on line " );
		smart_str_append_long( &ret, (zend_long ) pe->line );
		any = 1;
	}
	if( pe->offset >= 0 ) {
		if( any )
			smart_str_appends( &ret, ", " );
		else
			smart_str_appends( &ret, "at " );

		smart_str_appends( &ret, "offset " );
		smart_str_append_long( &ret, (zend_long ) pe->offset ); 
		any = 1;
	}

	if (pe->preContext[0] != 0 ) {
		if( any )
			smart_str_appends( &ret, ", " );

		smart_str_appends( &ret, "after \"" );
		intl_convert_utf16_to_utf8( &buf, &u8len, pe->preContext, -1, &status );
		if( U_FAILURE( status ) )
		{
			smart_str_appends( &ret, "(could not convert parser error pre-context to UTF-8)" );
		}
		else {
			smart_str_appendl( &ret, buf, u8len );
			efree( buf );
		}
		smart_str_appends( &ret, "\"" );
		any = 1;
	}

	if( pe->postContext[0] != 0 )
	{
		if( any )
			smart_str_appends( &ret, ", " );

		smart_str_appends( &ret, "before or at \"" );
		intl_convert_utf16_to_utf8( &buf, &u8len, pe->postContext, -1, &status );
		if( U_FAILURE( status ) )
		{
			smart_str_appends( &ret, "(could not convert parser error post-context to UTF-8)" );
		}
		else
		{
			smart_str_appendl( &ret, buf, u8len );
			efree( buf );
		}
		smart_str_appends( &ret, "\"" );
		any = 1;
	}

	if( !any )
	{
		smart_str_free( &ret );
		smart_str_appends( &ret, "no parse error" );
	}
	
	smart_str_0( &ret );
	return ret;
}
Exemplo n.º 16
0
php_stream *php_stream_url_wrap_http_ex(php_stream_wrapper *wrapper, 
		const char *path, const char *mode, int options, char **opened_path, 
		php_stream_context *context, int redirect_max, int flags STREAMS_DC TSRMLS_DC) /* {{{ */
{
	php_stream *stream = NULL;
	php_url *resource = NULL;
	int use_ssl;
	int use_proxy = 0;
	char *scratch = NULL;
	char *tmp = NULL;
	char *ua_str = NULL;
	zval **ua_zval = NULL, **tmpzval = NULL, *ssl_proxy_peer_name = NULL;
	int scratch_len = 0;
	int body = 0;
	char location[HTTP_HEADER_BLOCK_SIZE];
	zval *response_header = NULL;
	int reqok = 0;
	char *http_header_line = NULL;
	char tmp_line[128];
	size_t chunk_size = 0, file_size = 0;
	int eol_detect = 0;
	char *transport_string, *errstr = NULL;
	int transport_len, have_header = 0, request_fulluri = 0, ignore_errors = 0;
	char *protocol_version = NULL;
	int protocol_version_len = 3; /* Default: "1.0" */
	struct timeval timeout;
	char *user_headers = NULL;
	int header_init = ((flags & HTTP_WRAPPER_HEADER_INIT) != 0);
	int redirected = ((flags & HTTP_WRAPPER_REDIRECTED) != 0);
	int follow_location = 1;
	php_stream_filter *transfer_encoding = NULL;
	int response_code;

	tmp_line[0] = '\0';

	if (redirect_max < 1) {
		php_stream_wrapper_log_error(wrapper, options TSRMLS_CC, "Redirection limit reached, aborting");
		return NULL;
	}

	resource = php_url_parse(path);
	if (resource == NULL) {
		return NULL;
	}

	if (strncasecmp(resource->scheme, "http", sizeof("http")) && strncasecmp(resource->scheme, "https", sizeof("https"))) {
		if (!context || 
			php_stream_context_get_option(context, wrapper->wops->label, "proxy", &tmpzval) == FAILURE ||
			Z_TYPE_PP(tmpzval) != IS_STRING ||
			Z_STRLEN_PP(tmpzval) <= 0) {
			php_url_free(resource);
			return php_stream_open_wrapper_ex(path, mode, REPORT_ERRORS, NULL, context);
		}
		/* Called from a non-http wrapper with http proxying requested (i.e. ftp) */
		request_fulluri = 1;
		use_ssl = 0;
		use_proxy = 1;

		transport_len = Z_STRLEN_PP(tmpzval);
		transport_string = estrndup(Z_STRVAL_PP(tmpzval), Z_STRLEN_PP(tmpzval));
	} else {
		/* Normal http request (possibly with proxy) */
	
		if (strpbrk(mode, "awx+")) {
			php_stream_wrapper_log_error(wrapper, options TSRMLS_CC, "HTTP wrapper does not support writeable connections");
			php_url_free(resource);
			return NULL;
		}

		use_ssl = resource->scheme && (strlen(resource->scheme) > 4) && resource->scheme[4] == 's';
		/* choose default ports */
		if (use_ssl && resource->port == 0)
			resource->port = 443;
		else if (resource->port == 0)
			resource->port = 80;

		if (context &&
			php_stream_context_get_option(context, wrapper->wops->label, "proxy", &tmpzval) == SUCCESS &&
			Z_TYPE_PP(tmpzval) == IS_STRING &&
			Z_STRLEN_PP(tmpzval) > 0) {
			use_proxy = 1;
			transport_len = Z_STRLEN_PP(tmpzval);
			transport_string = estrndup(Z_STRVAL_PP(tmpzval), Z_STRLEN_PP(tmpzval));
		} else {
			transport_len = spprintf(&transport_string, 0, "%s://%s:%d", use_ssl ? "ssl" : "tcp", resource->host, resource->port);
		}
	}

	if (context && php_stream_context_get_option(context, wrapper->wops->label, "timeout", &tmpzval) == SUCCESS) {
		SEPARATE_ZVAL(tmpzval);
		convert_to_double_ex(tmpzval);
		timeout.tv_sec = (time_t) Z_DVAL_PP(tmpzval);
		timeout.tv_usec = (size_t) ((Z_DVAL_PP(tmpzval) - timeout.tv_sec) * 1000000);
	} else {
		timeout.tv_sec = FG(default_socket_timeout);
		timeout.tv_usec = 0;
	}

	stream = php_stream_xport_create(transport_string, transport_len, options,
			STREAM_XPORT_CLIENT | STREAM_XPORT_CONNECT,
			NULL, &timeout, context, &errstr, NULL);
    
	if (stream) {
		php_stream_set_option(stream, PHP_STREAM_OPTION_READ_TIMEOUT, 0, &timeout);
	}
			
	if (errstr) {
		php_stream_wrapper_log_error(wrapper, options TSRMLS_CC, "%s", errstr);
		efree(errstr);
		errstr = NULL;
	}

	efree(transport_string);

	if (stream && use_proxy && use_ssl) {
		smart_str header = {0};

		/* Set peer_name or name verification will try to use the proxy server name */
		if (!context || php_stream_context_get_option(context, "ssl", "peer_name", &tmpzval) == FAILURE) {
			MAKE_STD_ZVAL(ssl_proxy_peer_name);
			ZVAL_STRING(ssl_proxy_peer_name, resource->host, 1);
			php_stream_context_set_option(stream->context, "ssl", "peer_name", ssl_proxy_peer_name);
		}

		smart_str_appendl(&header, "CONNECT ", sizeof("CONNECT ")-1);
		smart_str_appends(&header, resource->host);
		smart_str_appendc(&header, ':');
		smart_str_append_unsigned(&header, resource->port);
		smart_str_appendl(&header, " HTTP/1.0\r\n", sizeof(" HTTP/1.0\r\n")-1);

	    /* check if we have Proxy-Authorization header */
		if (context && php_stream_context_get_option(context, "http", "header", &tmpzval) == SUCCESS) {
			char *s, *p;

			if (Z_TYPE_PP(tmpzval) == IS_ARRAY) {
				HashPosition pos;
				zval **tmpheader = NULL;

				for (zend_hash_internal_pointer_reset_ex(Z_ARRVAL_PP(tmpzval), &pos);
					SUCCESS == zend_hash_get_current_data_ex(Z_ARRVAL_PP(tmpzval), (void *)&tmpheader, &pos);
					zend_hash_move_forward_ex(Z_ARRVAL_PP(tmpzval), &pos)) {
					if (Z_TYPE_PP(tmpheader) == IS_STRING) {
						s = Z_STRVAL_PP(tmpheader);
						do {
							while (*s == ' ' || *s == '\t') s++;
							p = s;
							while (*p != 0 && *p != ':' && *p != '\r' && *p !='\n') p++;
							if (*p == ':') {
								p++;
								if (p - s == sizeof("Proxy-Authorization:") - 1 &&
								    zend_binary_strcasecmp(s, sizeof("Proxy-Authorization:") - 1,
								        "Proxy-Authorization:", sizeof("Proxy-Authorization:") - 1) == 0) {
									while (*p != 0 && *p != '\r' && *p !='\n') p++;
									smart_str_appendl(&header, s, p - s);
									smart_str_appendl(&header, "\r\n", sizeof("\r\n")-1);
									goto finish;
								} else {
									while (*p != 0 && *p != '\r' && *p !='\n') p++;
								}
							}
							s = p;
							while (*s == '\r' || *s == '\n') s++;
						} while (*s != 0);
					}
				}
			} else if (Z_TYPE_PP(tmpzval) == IS_STRING && Z_STRLEN_PP(tmpzval)) {
				s = Z_STRVAL_PP(tmpzval);
				do {
					while (*s == ' ' || *s == '\t') s++;
					p = s;
					while (*p != 0 && *p != ':' && *p != '\r' && *p !='\n') p++;
					if (*p == ':') {
						p++;
						if (p - s == sizeof("Proxy-Authorization:") - 1 &&
						    zend_binary_strcasecmp(s, sizeof("Proxy-Authorization:") - 1,
						        "Proxy-Authorization:", sizeof("Proxy-Authorization:") - 1) == 0) {
							while (*p != 0 && *p != '\r' && *p !='\n') p++;
							smart_str_appendl(&header, s, p - s);
							smart_str_appendl(&header, "\r\n", sizeof("\r\n")-1);
							goto finish;
						} else {
							while (*p != 0 && *p != '\r' && *p !='\n') p++;
						}
					}
					s = p;
					while (*s == '\r' || *s == '\n') s++;
				} while (*s != 0);
			}
		}
finish:
		smart_str_appendl(&header, "\r\n", sizeof("\r\n")-1);

		if (php_stream_write(stream, header.c, header.len) != header.len) {
			php_stream_wrapper_log_error(wrapper, options TSRMLS_CC, "Cannot connect to HTTPS server through proxy");
			php_stream_close(stream);
			stream = NULL;
		}
 	 	smart_str_free(&header);

 	 	if (stream) {
 	 		char header_line[HTTP_HEADER_BLOCK_SIZE];

			/* get response header */
			while (php_stream_gets(stream, header_line, HTTP_HEADER_BLOCK_SIZE-1) != NULL) {
				if (header_line[0] == '\n' ||
				    header_line[0] == '\r' ||
				    header_line[0] == '\0') {
				  break;
				}
			}
		}

		/* enable SSL transport layer */
		if (stream) {
			if (php_stream_xport_crypto_setup(stream, STREAM_CRYPTO_METHOD_ANY_CLIENT, NULL TSRMLS_CC) < 0 ||
			    php_stream_xport_crypto_enable(stream, 1 TSRMLS_CC) < 0) {
				php_stream_wrapper_log_error(wrapper, options TSRMLS_CC, "Cannot connect to HTTPS server through proxy");
				php_stream_close(stream);
				stream = NULL;
			}
		}
	}

	if (stream == NULL)
		goto out;

	/* avoid buffering issues while reading header */
	if (options & STREAM_WILL_CAST)
		chunk_size = php_stream_set_chunk_size(stream, 1);
	
	/* avoid problems with auto-detecting when reading the headers -> the headers
	 * are always in canonical \r\n format */
	eol_detect = stream->flags & (PHP_STREAM_FLAG_DETECT_EOL | PHP_STREAM_FLAG_EOL_MAC);
	stream->flags &= ~(PHP_STREAM_FLAG_DETECT_EOL | PHP_STREAM_FLAG_EOL_MAC);

	php_stream_context_set(stream, context TSRMLS_CC);

	php_stream_notify_info(context, PHP_STREAM_NOTIFY_CONNECT, NULL, 0);

	if (header_init && context && php_stream_context_get_option(context, "http", "max_redirects", &tmpzval) == SUCCESS) {
		SEPARATE_ZVAL(tmpzval);
		convert_to_long_ex(tmpzval);
		redirect_max = Z_LVAL_PP(tmpzval);
	}

	if (context && php_stream_context_get_option(context, "http", "method", &tmpzval) == SUCCESS) {
		if (Z_TYPE_PP(tmpzval) == IS_STRING && Z_STRLEN_PP(tmpzval) > 0) {
			/* As per the RFC, automatically redirected requests MUST NOT use other methods than
			 * GET and HEAD unless it can be confirmed by the user */
			if (!redirected
				|| (Z_STRLEN_PP(tmpzval) == 3 && memcmp("GET", Z_STRVAL_PP(tmpzval), 3) == 0)
				|| (Z_STRLEN_PP(tmpzval) == 4 && memcmp("HEAD",Z_STRVAL_PP(tmpzval), 4) == 0)
			) {
				scratch_len = strlen(path) + 29 + Z_STRLEN_PP(tmpzval);
				scratch = emalloc(scratch_len);
				strlcpy(scratch, Z_STRVAL_PP(tmpzval), Z_STRLEN_PP(tmpzval) + 1);
				strncat(scratch, " ", 1);
			}
		}
	}
 
	if (context && php_stream_context_get_option(context, "http", "protocol_version", &tmpzval) == SUCCESS) {
		SEPARATE_ZVAL(tmpzval);
		convert_to_double_ex(tmpzval);
		protocol_version_len = spprintf(&protocol_version, 0, "%.1F", Z_DVAL_PP(tmpzval));
	}

	if (!scratch) {
		scratch_len = strlen(path) + 29 + protocol_version_len;
		scratch = emalloc(scratch_len);
		strncpy(scratch, "GET ", scratch_len);
	}

	/* Should we send the entire path in the request line, default to no. */
	if (!request_fulluri &&
		context &&
		php_stream_context_get_option(context, "http", "request_fulluri", &tmpzval) == SUCCESS) {
		zval ztmp = **tmpzval;

		zval_copy_ctor(&ztmp);
		convert_to_boolean(&ztmp);
		request_fulluri = Z_BVAL(ztmp) ? 1 : 0;
		zval_dtor(&ztmp);
	}

	if (request_fulluri) {
		/* Ask for everything */
		strcat(scratch, path);
	} else {
		/* Send the traditional /path/to/file?query_string */

		/* file */
		if (resource->path && *resource->path) {
			strlcat(scratch, resource->path, scratch_len);
		} else {
			strlcat(scratch, "/", scratch_len);
		}

		/* query string */
		if (resource->query) {
			strlcat(scratch, "?", scratch_len);
			strlcat(scratch, resource->query, scratch_len);
		}
	}

	/* protocol version we are speaking */
	if (protocol_version) {
		strlcat(scratch, " HTTP/", scratch_len);
		strlcat(scratch, protocol_version, scratch_len);
		strlcat(scratch, "\r\n", scratch_len);
	} else {
		strlcat(scratch, " HTTP/1.0\r\n", scratch_len);
	}

	/* send it */
	php_stream_write(stream, scratch, strlen(scratch));

	if (context && php_stream_context_get_option(context, "http", "header", &tmpzval) == SUCCESS) {
		tmp = NULL;
		
		if (Z_TYPE_PP(tmpzval) == IS_ARRAY) {
			HashPosition pos;
			zval **tmpheader = NULL;
			smart_str tmpstr = {0};

			for (zend_hash_internal_pointer_reset_ex(Z_ARRVAL_PP(tmpzval), &pos);
				SUCCESS == zend_hash_get_current_data_ex(Z_ARRVAL_PP(tmpzval), (void *)&tmpheader, &pos);
				zend_hash_move_forward_ex(Z_ARRVAL_PP(tmpzval), &pos)
			) {
				if (Z_TYPE_PP(tmpheader) == IS_STRING) {
					smart_str_appendl(&tmpstr, Z_STRVAL_PP(tmpheader), Z_STRLEN_PP(tmpheader));
					smart_str_appendl(&tmpstr, "\r\n", sizeof("\r\n") - 1);
				}
			}
			smart_str_0(&tmpstr);
			/* Remove newlines and spaces from start and end. there's at least one extra \r\n at the end that needs to go. */
			if (tmpstr.c) {
				tmp = php_trim(tmpstr.c, strlen(tmpstr.c), NULL, 0, NULL, 3 TSRMLS_CC);
				smart_str_free(&tmpstr);
			}
		}
		if (Z_TYPE_PP(tmpzval) == IS_STRING && Z_STRLEN_PP(tmpzval)) {
			/* Remove newlines and spaces from start and end php_trim will estrndup() */
			tmp = php_trim(Z_STRVAL_PP(tmpzval), Z_STRLEN_PP(tmpzval), NULL, 0, NULL, 3 TSRMLS_CC);
		}
		if (tmp && strlen(tmp) > 0) {
			char *s;

			user_headers = estrdup(tmp);

			/* Make lowercase for easy comparison against 'standard' headers */
			php_strtolower(tmp, strlen(tmp));

			if (!header_init) {
				/* strip POST headers on redirect */
				strip_header(user_headers, tmp, "content-length:");
				strip_header(user_headers, tmp, "content-type:");
			}

			if ((s = strstr(tmp, "user-agent:")) && 
			    (s == tmp || *(s-1) == '\r' || *(s-1) == '\n' || 
			                 *(s-1) == '\t' || *(s-1) == ' ')) {
				 have_header |= HTTP_HEADER_USER_AGENT;
			}
			if ((s = strstr(tmp, "host:")) &&
			    (s == tmp || *(s-1) == '\r' || *(s-1) == '\n' || 
			                 *(s-1) == '\t' || *(s-1) == ' ')) {
				 have_header |= HTTP_HEADER_HOST;
			}
			if ((s = strstr(tmp, "from:")) &&
			    (s == tmp || *(s-1) == '\r' || *(s-1) == '\n' || 
			                 *(s-1) == '\t' || *(s-1) == ' ')) {
				 have_header |= HTTP_HEADER_FROM;
				}
			if ((s = strstr(tmp, "authorization:")) &&
			    (s == tmp || *(s-1) == '\r' || *(s-1) == '\n' || 
			                 *(s-1) == '\t' || *(s-1) == ' ')) {
				 have_header |= HTTP_HEADER_AUTH;
			}
			if ((s = strstr(tmp, "content-length:")) &&
			    (s == tmp || *(s-1) == '\r' || *(s-1) == '\n' || 
			                 *(s-1) == '\t' || *(s-1) == ' ')) {
				 have_header |= HTTP_HEADER_CONTENT_LENGTH;
			}
			if ((s = strstr(tmp, "content-type:")) &&
			    (s == tmp || *(s-1) == '\r' || *(s-1) == '\n' || 
			                 *(s-1) == '\t' || *(s-1) == ' ')) {
				 have_header |= HTTP_HEADER_TYPE;
			}
			if ((s = strstr(tmp, "connection:")) &&
			    (s == tmp || *(s-1) == '\r' || *(s-1) == '\n' || 
			                 *(s-1) == '\t' || *(s-1) == ' ')) {
				 have_header |= HTTP_HEADER_CONNECTION;
			}
			/* remove Proxy-Authorization header */
			if (use_proxy && use_ssl && (s = strstr(tmp, "proxy-authorization:")) &&
			    (s == tmp || *(s-1) == '\r' || *(s-1) == '\n' || 
			                 *(s-1) == '\t' || *(s-1) == ' ')) {
				char *p = s + sizeof("proxy-authorization:") - 1;
				
				while (s > tmp && (*(s-1) == ' ' || *(s-1) == '\t')) s--;
				while (*p != 0 && *p != '\r' && *p != '\n') p++;
				while (*p == '\r' || *p == '\n') p++;
				if (*p == 0) {
					if (s == tmp) {
						efree(user_headers);
						user_headers = NULL;
					} else {
						while (s > tmp && (*(s-1) == '\r' || *(s-1) == '\n')) s--;
						user_headers[s - tmp] = 0;
					}
				} else {
					memmove(user_headers + (s - tmp), user_headers + (p - tmp), strlen(p) + 1);
				}
			}

		}
		if (tmp) {
			efree(tmp);
		}
	}

	/* auth header if it was specified */
	if (((have_header & HTTP_HEADER_AUTH) == 0) && resource->user) {
		/* decode the strings first */
		php_url_decode(resource->user, strlen(resource->user));

		/* scratch is large enough, since it was made large enough for the whole URL */
		strcpy(scratch, resource->user);
		strcat(scratch, ":");

		/* Note: password is optional! */
		if (resource->pass) {
			php_url_decode(resource->pass, strlen(resource->pass));
			strcat(scratch, resource->pass);
		}

		tmp = (char*)php_base64_encode((unsigned char*)scratch, strlen(scratch), NULL);
		
		if (snprintf(scratch, scratch_len, "Authorization: Basic %s\r\n", tmp) > 0) {
			php_stream_write(stream, scratch, strlen(scratch));
			php_stream_notify_info(context, PHP_STREAM_NOTIFY_AUTH_REQUIRED, NULL, 0);
		}

		efree(tmp);
		tmp = NULL;
	}

	/* if the user has configured who they are, send a From: line */
	if (((have_header & HTTP_HEADER_FROM) == 0) && FG(from_address)) {
		if (snprintf(scratch, scratch_len, "From: %s\r\n", FG(from_address)) > 0)
			php_stream_write(stream, scratch, strlen(scratch));
	}

	/* Send Host: header so name-based virtual hosts work */
	if ((have_header & HTTP_HEADER_HOST) == 0) {
		if ((use_ssl && resource->port != 443 && resource->port != 0) || 
			(!use_ssl && resource->port != 80 && resource->port != 0)) {
			if (snprintf(scratch, scratch_len, "Host: %s:%i\r\n", resource->host, resource->port) > 0)
				php_stream_write(stream, scratch, strlen(scratch));
		} else {
			if (snprintf(scratch, scratch_len, "Host: %s\r\n", resource->host) > 0) {
				php_stream_write(stream, scratch, strlen(scratch));
			}
		}
	}

	/* Send a Connection: close header when using HTTP 1.1 or later to avoid
	 * hanging when the server interprets the RFC literally and establishes a
	 * keep-alive connection, unless the user specifically requests something
	 * else by specifying a Connection header in the context options. */
	if (protocol_version &&
	    ((have_header & HTTP_HEADER_CONNECTION) == 0) &&
	    (strncmp(protocol_version, "1.0", MIN(protocol_version_len, 3)) > 0)) {
		php_stream_write_string(stream, "Connection: close\r\n");
	}

	if (context && 
	    php_stream_context_get_option(context, "http", "user_agent", &ua_zval) == SUCCESS &&
		Z_TYPE_PP(ua_zval) == IS_STRING) {
		ua_str = Z_STRVAL_PP(ua_zval);
	} else if (FG(user_agent)) {
		ua_str = FG(user_agent);
	}

	if (((have_header & HTTP_HEADER_USER_AGENT) == 0) && ua_str) {
#define _UA_HEADER "User-Agent: %s\r\n"
		char *ua;
		size_t ua_len;
		
		ua_len = sizeof(_UA_HEADER) + strlen(ua_str);
		
		/* ensure the header is only sent if user_agent is not blank */
		if (ua_len > sizeof(_UA_HEADER)) {
			ua = emalloc(ua_len + 1);
			if ((ua_len = slprintf(ua, ua_len, _UA_HEADER, ua_str)) > 0) {
				ua[ua_len] = 0;
				php_stream_write(stream, ua, ua_len);
			} else {
				php_error_docref(NULL TSRMLS_CC, E_WARNING, "Cannot construct User-agent header");
			}

			if (ua) {
				efree(ua);
			}
		}	
	}

	if (user_headers) {
		/* A bit weird, but some servers require that Content-Length be sent prior to Content-Type for POST
		 * see bug #44603 for details. Since Content-Type maybe part of user's headers we need to do this check first.
		 */
		if (
				header_init &&
				context &&
				!(have_header & HTTP_HEADER_CONTENT_LENGTH) &&
				php_stream_context_get_option(context, "http", "content", &tmpzval) == SUCCESS &&
				Z_TYPE_PP(tmpzval) == IS_STRING && Z_STRLEN_PP(tmpzval) > 0
		) {
			scratch_len = slprintf(scratch, scratch_len, "Content-Length: %d\r\n", Z_STRLEN_PP(tmpzval));
			php_stream_write(stream, scratch, scratch_len);
			have_header |= HTTP_HEADER_CONTENT_LENGTH;
		}

		php_stream_write(stream, user_headers, strlen(user_headers));
		php_stream_write(stream, "\r\n", sizeof("\r\n")-1);
		efree(user_headers);
	}

	/* Request content, such as for POST requests */
	if (header_init && context &&
		php_stream_context_get_option(context, "http", "content", &tmpzval) == SUCCESS &&
		Z_TYPE_PP(tmpzval) == IS_STRING && Z_STRLEN_PP(tmpzval) > 0) {
		if (!(have_header & HTTP_HEADER_CONTENT_LENGTH)) {
			scratch_len = slprintf(scratch, scratch_len, "Content-Length: %d\r\n", Z_STRLEN_PP(tmpzval));
			php_stream_write(stream, scratch, scratch_len);
		}
		if (!(have_header & HTTP_HEADER_TYPE)) {
			php_stream_write(stream, "Content-Type: application/x-www-form-urlencoded\r\n",
				sizeof("Content-Type: application/x-www-form-urlencoded\r\n") - 1);
			php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Content-type not specified assuming application/x-www-form-urlencoded");
		}
		php_stream_write(stream, "\r\n", sizeof("\r\n")-1);
		php_stream_write(stream, Z_STRVAL_PP(tmpzval), Z_STRLEN_PP(tmpzval));
	} else {
		php_stream_write(stream, "\r\n", sizeof("\r\n")-1);
	}

	location[0] = '\0';

	if (!EG(active_symbol_table)) {
		zend_rebuild_symbol_table(TSRMLS_C);
	}

	if (header_init) {
		zval *ztmp;
		MAKE_STD_ZVAL(ztmp);
		array_init(ztmp);
		ZEND_SET_SYMBOL(EG(active_symbol_table), "http_response_header", ztmp);
	}

	{
		zval **rh;
		zend_hash_find(EG(active_symbol_table), "http_response_header", sizeof("http_response_header"), (void **) &rh);
		response_header = *rh;
	}

	if (!php_stream_eof(stream)) {
		size_t tmp_line_len;
		/* get response header */

		if (php_stream_get_line(stream, tmp_line, sizeof(tmp_line) - 1, &tmp_line_len) != NULL) {
			zval *http_response;

			if (tmp_line_len > 9) {
				response_code = atoi(tmp_line + 9);
			} else {
				response_code = 0;
			}
			if (context && SUCCESS==php_stream_context_get_option(context, "http", "ignore_errors", &tmpzval)) {
				ignore_errors = zend_is_true(*tmpzval TSRMLS_CC);
			}
			/* when we request only the header, don't fail even on error codes */
			if ((options & STREAM_ONLY_GET_HEADERS) || ignore_errors) {
				reqok = 1;
			}
			/* all status codes in the 2xx range are defined by the specification as successful;
			 * all status codes in the 3xx range are for redirection, and so also should never
			 * fail */
			if (response_code >= 200 && response_code < 400) {
				reqok = 1;
			} else {
				switch(response_code) {
					case 403:
						php_stream_notify_error(context, PHP_STREAM_NOTIFY_AUTH_RESULT,
								tmp_line, response_code);
						break;
					default:
						/* safety net in the event tmp_line == NULL */
						if (!tmp_line_len) {
							tmp_line[0] = '\0';
						}
						php_stream_notify_error(context, PHP_STREAM_NOTIFY_FAILURE,
								tmp_line, response_code);
				}
			}
			if (tmp_line[tmp_line_len - 1] == '\n') {
				--tmp_line_len;
				if (tmp_line[tmp_line_len - 1] == '\r') {
					--tmp_line_len;
				}
			}
			MAKE_STD_ZVAL(http_response);
			ZVAL_STRINGL(http_response, tmp_line, tmp_line_len, 1);
			zend_hash_next_index_insert(Z_ARRVAL_P(response_header), &http_response, sizeof(zval *), NULL);
		}
	} else {
		php_stream_wrapper_log_error(wrapper, options TSRMLS_CC, "HTTP request failed, unexpected end of socket!");
		goto out;
	}
	
	/* read past HTTP headers */
	
	http_header_line = emalloc(HTTP_HEADER_BLOCK_SIZE);

	while (!body && !php_stream_eof(stream)) {
		size_t http_header_line_length;
		if (php_stream_get_line(stream, http_header_line, HTTP_HEADER_BLOCK_SIZE, &http_header_line_length) && *http_header_line != '\n' && *http_header_line != '\r') {
			char *e = http_header_line + http_header_line_length - 1;
			if (*e != '\n') {
				do { /* partial header */
					if (php_stream_get_line(stream, http_header_line, HTTP_HEADER_BLOCK_SIZE, &http_header_line_length) == NULL) {
						php_stream_wrapper_log_error(wrapper, options TSRMLS_CC, "Failed to read HTTP headers");
						goto out;
					}
					e = http_header_line + http_header_line_length - 1;
				} while (*e != '\n');
				continue;
			}
			while (*e == '\n' || *e == '\r') {
				e--;
			}
			http_header_line_length = e - http_header_line + 1;
			http_header_line[http_header_line_length] = '\0';

			if (!strncasecmp(http_header_line, "Location: ", 10)) {
				if (context && php_stream_context_get_option(context, "http", "follow_location", &tmpzval) == SUCCESS) {
					SEPARATE_ZVAL(tmpzval);
					convert_to_long_ex(tmpzval);
					follow_location = Z_LVAL_PP(tmpzval);
				} else if (!(response_code >= 300 && response_code < 304 || 307 == response_code || 308 == response_code)) {
					/* we shouldn't redirect automatically
					if follow_location isn't set and response_code not in (300, 301, 302, 303 and 307) 
					see http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.3.1
					RFC 7238 defines 308: http://tools.ietf.org/html/rfc7238 */
					follow_location = 0;
				}
				strlcpy(location, http_header_line + 10, sizeof(location));
			} else if (!strncasecmp(http_header_line, "Content-Type: ", 14)) {
				php_stream_notify_info(context, PHP_STREAM_NOTIFY_MIME_TYPE_IS, http_header_line + 14, 0);
			} else if (!strncasecmp(http_header_line, "Content-Length: ", 16)) {
				file_size = atoi(http_header_line + 16);
				php_stream_notify_file_size(context, file_size, http_header_line, 0);
			} else if (!strncasecmp(http_header_line, "Transfer-Encoding: chunked", sizeof("Transfer-Encoding: chunked"))) {

				/* create filter to decode response body */
				if (!(options & STREAM_ONLY_GET_HEADERS)) {
					long decode = 1;

					if (context && php_stream_context_get_option(context, "http", "auto_decode", &tmpzval) == SUCCESS) {
						SEPARATE_ZVAL(tmpzval);
						convert_to_boolean(*tmpzval);
						decode = Z_LVAL_PP(tmpzval);
					}
					if (decode) {
						transfer_encoding = php_stream_filter_create("dechunk", NULL, php_stream_is_persistent(stream) TSRMLS_CC);
						if (transfer_encoding) {
							/* don't store transfer-encodeing header */
							continue;
						}
					}
				}
			}

			if (http_header_line[0] == '\0') {
				body = 1;
			} else {
				zval *http_header;

				MAKE_STD_ZVAL(http_header);

				ZVAL_STRINGL(http_header, http_header_line, http_header_line_length, 1);
				
				zend_hash_next_index_insert(Z_ARRVAL_P(response_header), &http_header, sizeof(zval *), NULL);
			}
		} else {
			break;
		}
	}

	if (!reqok || (location[0] != '\0' && follow_location)) {
		if (!follow_location || (((options & STREAM_ONLY_GET_HEADERS) || ignore_errors) && redirect_max <= 1)) {
			goto out;
		}

		if (location[0] != '\0')
			php_stream_notify_info(context, PHP_STREAM_NOTIFY_REDIRECTED, location, 0);

		php_stream_close(stream);
		stream = NULL;

		if (location[0] != '\0') {

			char new_path[HTTP_HEADER_BLOCK_SIZE];
			char loc_path[HTTP_HEADER_BLOCK_SIZE];

			*new_path='\0';
			if (strlen(location)<8 || (strncasecmp(location, "http://", sizeof("http://")-1) && 
							strncasecmp(location, "https://", sizeof("https://")-1) && 
							strncasecmp(location, "ftp://", sizeof("ftp://")-1) && 
							strncasecmp(location, "ftps://", sizeof("ftps://")-1))) 
			{
				if (*location != '/') {
					if (*(location+1) != '\0' && resource->path) {
						char *s = strrchr(resource->path, '/');
						if (!s) {
							s = resource->path;
							if (!s[0]) {
								efree(s);
								s = resource->path = estrdup("/");
							} else {
								*s = '/';
							}
						}
						s[1] = '\0'; 
						if (resource->path && *(resource->path) == '/' && *(resource->path + 1) == '\0') {
							snprintf(loc_path, sizeof(loc_path) - 1, "%s%s", resource->path, location);
						} else {
							snprintf(loc_path, sizeof(loc_path) - 1, "%s/%s", resource->path, location);
						}
					} else {
						snprintf(loc_path, sizeof(loc_path) - 1, "/%s", location);
					}
				} else {
					strlcpy(loc_path, location, sizeof(loc_path));
				}
				if ((use_ssl && resource->port != 443) || (!use_ssl && resource->port != 80)) {
					snprintf(new_path, sizeof(new_path) - 1, "%s://%s:%d%s", resource->scheme, resource->host, resource->port, loc_path);
				} else {
					snprintf(new_path, sizeof(new_path) - 1, "%s://%s%s", resource->scheme, resource->host, loc_path);
				}
			} else {
				strlcpy(new_path, location, sizeof(new_path));
			}

			php_url_free(resource);
			/* check for invalid redirection URLs */
			if ((resource = php_url_parse(new_path)) == NULL) {
				php_stream_wrapper_log_error(wrapper, options TSRMLS_CC, "Invalid redirect URL! %s", new_path);
				goto out;
			}

#define CHECK_FOR_CNTRL_CHARS(val) { \
	if (val) { \
		unsigned char *s, *e; \
		int l; \
		l = php_url_decode(val, strlen(val)); \
		s = (unsigned char*)val; e = s + l; \
		while (s < e) { \
			if (iscntrl(*s)) { \
				php_stream_wrapper_log_error(wrapper, options TSRMLS_CC, "Invalid redirect URL! %s", new_path); \
				goto out; \
			} \
			s++; \
		} \
	} \
}
			/* check for control characters in login, password & path */
			if (strncasecmp(new_path, "http://", sizeof("http://") - 1) || strncasecmp(new_path, "https://", sizeof("https://") - 1)) {
				CHECK_FOR_CNTRL_CHARS(resource->user)
				CHECK_FOR_CNTRL_CHARS(resource->pass)
				CHECK_FOR_CNTRL_CHARS(resource->path)
			}
			stream = php_stream_url_wrap_http_ex(wrapper, new_path, mode, options, opened_path, context, --redirect_max, HTTP_WRAPPER_REDIRECTED STREAMS_CC TSRMLS_CC);
		} else {
Exemplo n.º 17
0
/* {{{ php_url_encode_hash */
PHPAPI int php_url_encode_hash_ex(HashTable *ht, smart_str *formstr,
				const char *num_prefix, int num_prefix_len,
				const char *key_prefix, int key_prefix_len,
				const char *key_suffix, int key_suffix_len,
			  zval *type, char *arg_sep, int enc_type TSRMLS_DC)
{
	char *key = NULL;
	char *ekey, *newprefix, *p;
	int arg_sep_len, ekey_len, key_type, newprefix_len;
	uint key_len;
	ulong idx;
	zval **zdata = NULL, *copyzval;

	if (!ht) {
		return FAILURE;
	}

	if (ht->nApplyCount > 0) {
		/* Prevent recursion */
		return SUCCESS;
	}

	if (!arg_sep) {
		arg_sep = INI_STR("arg_separator.output");
		if (!arg_sep || !strlen(arg_sep)) {
			arg_sep = URL_DEFAULT_ARG_SEP;
		}
	}
	arg_sep_len = strlen(arg_sep);

	for (zend_hash_internal_pointer_reset(ht);
		(key_type = zend_hash_get_current_key_ex(ht, &key, &key_len, &idx, 0, NULL)) != HASH_KEY_NON_EXISTANT;
		zend_hash_move_forward(ht)
	) {
		if (key_type == HASH_KEY_IS_STRING && key_len && key[key_len-1] == '\0') {
			/* We don't want that trailing NULL */
			key_len -= 1;
		}

		/* handling for private & protected object properties */
		if (key && *key == '\0' && type != NULL) {
			const char *tmp;

			zend_object *zobj = zend_objects_get_address(type TSRMLS_CC);
			if (zend_check_property_access(zobj, key, key_len-1 TSRMLS_CC) != SUCCESS) {
				/* private or protected property access outside of the class */
				continue;
			}
			zend_unmangle_property_name(key, key_len-1, &tmp, (const char**)&key);
			key_len = strlen(key);		
		}

		if (zend_hash_get_current_data_ex(ht, (void **)&zdata, NULL) == FAILURE || !zdata || !(*zdata)) {
			php_error_docref(NULL TSRMLS_CC, E_WARNING, "Error traversing form data array");
			return FAILURE;
		}
		if (Z_TYPE_PP(zdata) == IS_ARRAY || Z_TYPE_PP(zdata) == IS_OBJECT) {
			if (key_type == HASH_KEY_IS_STRING) {
				if (enc_type == PHP_QUERY_RFC3986) {
					ekey = php_raw_url_encode(key, key_len, &ekey_len);
				} else {
					ekey = php_url_encode(key, key_len, &ekey_len);
				}
				newprefix_len = key_suffix_len + ekey_len + key_prefix_len + 3 /* %5B */;
				newprefix = emalloc(newprefix_len + 1);
				p = newprefix;

				if (key_prefix) {
					memcpy(p, key_prefix, key_prefix_len);
					p += key_prefix_len;
				}

				memcpy(p, ekey, ekey_len);
				p += ekey_len;
				efree(ekey);

				if (key_suffix) {
					memcpy(p, key_suffix, key_suffix_len);
					p += key_suffix_len;
				}
				*(p++) = '%';
				*(p++) = '5';
				*(p++) = 'B';
				*p = '\0';
			} else {
				/* Is an integer key */
				ekey_len = spprintf(&ekey, 0, "%ld", idx);
				newprefix_len = key_prefix_len + num_prefix_len + ekey_len + key_suffix_len + 3 /* %5B */;
				newprefix = emalloc(newprefix_len + 1);
				p = newprefix;

				if (key_prefix) {
					memcpy(p, key_prefix, key_prefix_len);
					p += key_prefix_len;
				}

				memcpy(p, num_prefix, num_prefix_len);
				p += num_prefix_len;

				memcpy(p, ekey, ekey_len);
				p += ekey_len;
				efree(ekey);

				if (key_suffix) {
					memcpy(p, key_suffix, key_suffix_len);
					p += key_suffix_len;
				}
				*(p++) = '%';
				*(p++) = '5';
				*(p++) = 'B';
				*p = '\0';
			}
			ht->nApplyCount++;
			php_url_encode_hash_ex(HASH_OF(*zdata), formstr, NULL, 0, newprefix, newprefix_len, "%5D", 3, (Z_TYPE_PP(zdata) == IS_OBJECT ? *zdata : NULL), arg_sep, enc_type TSRMLS_CC);
			ht->nApplyCount--;
			efree(newprefix);
		} else if (Z_TYPE_PP(zdata) == IS_NULL || Z_TYPE_PP(zdata) == IS_RESOURCE) {
			/* Skip these types */
			continue;
		} else {
			if (formstr->len) {
				smart_str_appendl(formstr, arg_sep, arg_sep_len);
			}
			/* Simple key=value */
			smart_str_appendl(formstr, key_prefix, key_prefix_len);
			if (key_type == HASH_KEY_IS_STRING) {
				if (enc_type == PHP_QUERY_RFC3986) {
					ekey = php_raw_url_encode(key, key_len, &ekey_len);
				} else {
					ekey = php_url_encode(key, key_len, &ekey_len);
				}
				smart_str_appendl(formstr, ekey, ekey_len);
				efree(ekey);
			} else {
				/* Numeric key */
				if (num_prefix) {
					smart_str_appendl(formstr, num_prefix, num_prefix_len);
				}
				ekey_len = spprintf(&ekey, 0, "%ld", idx);
				smart_str_appendl(formstr, ekey, ekey_len);
				efree(ekey);
			}
			smart_str_appendl(formstr, key_suffix, key_suffix_len);
			smart_str_appendl(formstr, "=", 1);
			switch (Z_TYPE_PP(zdata)) {
				case IS_STRING:
					if (enc_type == PHP_QUERY_RFC3986) {
						ekey = php_raw_url_encode(Z_STRVAL_PP(zdata), Z_STRLEN_PP(zdata), &ekey_len);
					} else {
						ekey = php_url_encode(Z_STRVAL_PP(zdata), Z_STRLEN_PP(zdata), &ekey_len);						
					}
					break;
				case IS_LONG:
				case IS_BOOL:
					ekey_len = spprintf(&ekey, 0, "%ld", Z_LVAL_PP(zdata));
					break;
				case IS_DOUBLE:
					ekey_len = spprintf(&ekey, 0, "%.*G", (int) EG(precision), Z_DVAL_PP(zdata));
					break;
				default:
					/* fall back on convert to string */
					MAKE_STD_ZVAL(copyzval);
					*copyzval = **zdata;
					zval_copy_ctor(copyzval);
					convert_to_string_ex(&copyzval);
					if (enc_type == PHP_QUERY_RFC3986) {
						ekey = php_raw_url_encode(Z_STRVAL_P(copyzval), Z_STRLEN_P(copyzval), &ekey_len);
					} else {
						ekey = php_url_encode(Z_STRVAL_P(copyzval), Z_STRLEN_P(copyzval), &ekey_len);
					}
					zval_ptr_dtor(&copyzval);
			}
			smart_str_appendl(formstr, ekey, ekey_len);
			efree(ekey);
		}
	}

	return SUCCESS;
}
Exemplo n.º 18
0
php_stream *php_stream_url_wrap_http_ex(php_stream_wrapper *wrapper,
		const char *path, const char *mode, int options, zend_string **opened_path,
		php_stream_context *context, int redirect_max, int flags STREAMS_DC) /* {{{ */
{
	php_stream *stream = NULL;
	php_url *resource = NULL;
	int use_ssl;
	int use_proxy = 0;
	zend_string *tmp = NULL;
	char *ua_str = NULL;
	zval *ua_zval = NULL, *tmpzval = NULL, ssl_proxy_peer_name;
	int body = 0;
	char location[HTTP_HEADER_BLOCK_SIZE];
	zval response_header;
	int reqok = 0;
	char *http_header_line = NULL;
	char tmp_line[128];
	size_t chunk_size = 0, file_size = 0;
	int eol_detect = 0;
	char *transport_string;
	zend_string *errstr = NULL;
	size_t transport_len;
	int have_header = 0;
	zend_bool request_fulluri = 0, ignore_errors = 0;
	struct timeval timeout;
	char *user_headers = NULL;
	int header_init = ((flags & HTTP_WRAPPER_HEADER_INIT) != 0);
	int redirected = ((flags & HTTP_WRAPPER_REDIRECTED) != 0);
	zend_bool follow_location = 1;
	php_stream_filter *transfer_encoding = NULL;
	int response_code;
	zend_array *symbol_table;
	smart_str req_buf = {0};
	zend_bool custom_request_method;

	ZVAL_UNDEF(&response_header);
	tmp_line[0] = '\0';

	if (redirect_max < 1) {
		php_stream_wrapper_log_error(wrapper, options, "Redirection limit reached, aborting");
		return NULL;
	}

	resource = php_url_parse(path);
	if (resource == NULL) {
		return NULL;
	}

	if (strncasecmp(resource->scheme, "http", sizeof("http")) && strncasecmp(resource->scheme, "https", sizeof("https"))) {
		if (!context ||
			(tmpzval = php_stream_context_get_option(context, wrapper->wops->label, "proxy")) == NULL ||
			Z_TYPE_P(tmpzval) != IS_STRING ||
			Z_STRLEN_P(tmpzval) <= 0) {
			php_url_free(resource);
			return php_stream_open_wrapper_ex(path, mode, REPORT_ERRORS, NULL, context);
		}
		/* Called from a non-http wrapper with http proxying requested (i.e. ftp) */
		request_fulluri = 1;
		use_ssl = 0;
		use_proxy = 1;

		transport_len = Z_STRLEN_P(tmpzval);
		transport_string = estrndup(Z_STRVAL_P(tmpzval), Z_STRLEN_P(tmpzval));
	} else {
		/* Normal http request (possibly with proxy) */

		if (strpbrk(mode, "awx+")) {
			php_stream_wrapper_log_error(wrapper, options, "HTTP wrapper does not support writeable connections");
			php_url_free(resource);
			return NULL;
		}

		use_ssl = resource->scheme && (strlen(resource->scheme) > 4) && resource->scheme[4] == 's';
		/* choose default ports */
		if (use_ssl && resource->port == 0)
			resource->port = 443;
		else if (resource->port == 0)
			resource->port = 80;

		if (context &&
			(tmpzval = php_stream_context_get_option(context, wrapper->wops->label, "proxy")) != NULL &&
			Z_TYPE_P(tmpzval) == IS_STRING &&
			Z_STRLEN_P(tmpzval) > 0) {
			use_proxy = 1;
			transport_len = Z_STRLEN_P(tmpzval);
			transport_string = estrndup(Z_STRVAL_P(tmpzval), Z_STRLEN_P(tmpzval));
		} else {
			transport_len = spprintf(&transport_string, 0, "%s://%s:%d", use_ssl ? "ssl" : "tcp", resource->host, resource->port);
		}
	}

	if (context && (tmpzval = php_stream_context_get_option(context, wrapper->wops->label, "timeout")) != NULL) {
		double d = zval_get_double(tmpzval);
#ifndef PHP_WIN32
		timeout.tv_sec = (time_t) d;
		timeout.tv_usec = (size_t) ((d - timeout.tv_sec) * 1000000);
#else
		timeout.tv_sec = (long) d;
		timeout.tv_usec = (long) ((d - timeout.tv_sec) * 1000000);
#endif
	} else {
#ifndef PHP_WIN32
		timeout.tv_sec = FG(default_socket_timeout);
#else
		timeout.tv_sec = (long)FG(default_socket_timeout);
#endif
		timeout.tv_usec = 0;
	}

	stream = php_stream_xport_create(transport_string, transport_len, options,
			STREAM_XPORT_CLIENT | STREAM_XPORT_CONNECT,
			NULL, &timeout, context, &errstr, NULL);

	if (stream) {
		php_stream_set_option(stream, PHP_STREAM_OPTION_READ_TIMEOUT, 0, &timeout);
	}

	if (errstr) {
		php_stream_wrapper_log_error(wrapper, options, "%s", ZSTR_VAL(errstr));
		zend_string_release(errstr);
		errstr = NULL;
	}

	efree(transport_string);

	if (stream && use_proxy && use_ssl) {
		smart_str header = {0};

		/* Set peer_name or name verification will try to use the proxy server name */
		if (!context || (tmpzval = php_stream_context_get_option(context, "ssl", "peer_name")) == NULL) {
			ZVAL_STRING(&ssl_proxy_peer_name, resource->host);
			php_stream_context_set_option(PHP_STREAM_CONTEXT(stream), "ssl", "peer_name", &ssl_proxy_peer_name);
			zval_ptr_dtor(&ssl_proxy_peer_name);
		}

		smart_str_appendl(&header, "CONNECT ", sizeof("CONNECT ")-1);
		smart_str_appends(&header, resource->host);
		smart_str_appendc(&header, ':');
		smart_str_append_unsigned(&header, resource->port);
		smart_str_appendl(&header, " HTTP/1.0\r\n", sizeof(" HTTP/1.0\r\n")-1);

	    /* check if we have Proxy-Authorization header */
		if (context && (tmpzval = php_stream_context_get_option(context, "http", "header")) != NULL) {
			char *s, *p;

			if (Z_TYPE_P(tmpzval) == IS_ARRAY) {
				zval *tmpheader = NULL;

				ZEND_HASH_FOREACH_VAL(Z_ARRVAL_P(tmpzval), tmpheader) {
					if (Z_TYPE_P(tmpheader) == IS_STRING) {
						s = Z_STRVAL_P(tmpheader);
						do {
							while (*s == ' ' || *s == '\t') s++;
							p = s;
							while (*p != 0 && *p != ':' && *p != '\r' && *p !='\n') p++;
							if (*p == ':') {
								p++;
								if (p - s == sizeof("Proxy-Authorization:") - 1 &&
								    zend_binary_strcasecmp(s, sizeof("Proxy-Authorization:") - 1,
								        "Proxy-Authorization:", sizeof("Proxy-Authorization:") - 1) == 0) {
									while (*p != 0 && *p != '\r' && *p !='\n') p++;
									smart_str_appendl(&header, s, p - s);
									smart_str_appendl(&header, "\r\n", sizeof("\r\n")-1);
									goto finish;
								} else {
									while (*p != 0 && *p != '\r' && *p !='\n') p++;
								}
							}
							s = p;
							while (*s == '\r' || *s == '\n') s++;
						} while (*s != 0);
					}
				} ZEND_HASH_FOREACH_END();
			} else if (Z_TYPE_P(tmpzval) == IS_STRING && Z_STRLEN_P(tmpzval)) {
Exemplo n.º 19
0
/** {{{ zend_string * yaf_route_simple_assemble(zval *info, zval *query)
 */
zend_string * yaf_route_simple_assemble(yaf_route_t *this_ptr, zval *info, zval *query) {
	smart_str uri = {0};
	zend_string *val;
	zval *nmodule, *ncontroller, *naction;

	smart_str_appendc(&uri, '?');

	nmodule = zend_read_property(yaf_route_simple_ce,
			this_ptr, ZEND_STRL(YAF_ROUTE_SIMPLE_VAR_NAME_MODULE), 1, NULL);
	ncontroller = zend_read_property(yaf_route_simple_ce,
			this_ptr, ZEND_STRL(YAF_ROUTE_SIMPLE_VAR_NAME_CONTROLLER), 1, NULL);
	naction = zend_read_property(yaf_route_simple_ce,
			this_ptr, ZEND_STRL(YAF_ROUTE_SIMPLE_VAR_NAME_ACTION), 1, NULL);

	do {
		zval *zv;

		if ((zv = zend_hash_str_find(Z_ARRVAL_P(info), ZEND_STRL(YAF_ROUTE_ASSEMBLE_MOUDLE_FORMAT))) != NULL) {
			val = zval_get_string(zv);
			smart_str_appendl(&uri, Z_STRVAL_P(nmodule), Z_STRLEN_P(nmodule));
			smart_str_appendc(&uri, '=');
			smart_str_appendl(&uri, ZSTR_VAL(val), ZSTR_LEN(val));
			smart_str_appendc(&uri, '&');
			zend_string_release(val);
		} 

		if ((zv = zend_hash_str_find(Z_ARRVAL_P(info), ZEND_STRL(YAF_ROUTE_ASSEMBLE_CONTROLLER_FORMAT))) == NULL) {
			yaf_trigger_error(YAF_ERR_TYPE_ERROR, "%s", "You need to specify the controller by ':c'");
			break;
		}

		val = zval_get_string(zv);
		smart_str_appendl(&uri, Z_STRVAL_P(ncontroller), Z_STRLEN_P(ncontroller));
		smart_str_appendc(&uri, '=');
		smart_str_appendl(&uri, ZSTR_VAL(val), ZSTR_LEN(val));
		smart_str_appendc(&uri, '&');
		zend_string_release(val);

		if ((zv = zend_hash_str_find(Z_ARRVAL_P(info), ZEND_STRL(YAF_ROUTE_ASSEMBLE_ACTION_FORMAT))) == NULL) {
			yaf_trigger_error(YAF_ERR_TYPE_ERROR, "%s", "You need to specify the action by ':a'");
			break;
		}

		val = zval_get_string(zv);
		smart_str_appendl(&uri, Z_STRVAL_P(naction), Z_STRLEN_P(naction));
		smart_str_appendc(&uri, '=');
		smart_str_appendl(&uri, ZSTR_VAL(val), ZSTR_LEN(val));
		zend_string_release(val);

		if (query && IS_ARRAY == Z_TYPE_P(query)) {
			zend_string *key;

            ZEND_HASH_FOREACH_STR_KEY_VAL(Z_ARRVAL_P(query), key, zv) {
				if (key) {
					val = zval_get_string(zv);
					smart_str_appendc(&uri, '&');
					smart_str_appendl(&uri, ZSTR_VAL(key), ZSTR_LEN(key));
					smart_str_appendc(&uri, '=');
					smart_str_appendl(&uri, ZSTR_VAL(val), ZSTR_LEN(val));
					zend_string_release(val);
				}
			} ZEND_HASH_FOREACH_END();
		}

		smart_str_0(&uri);
		return uri.s;
	} while (0);
Exemplo n.º 20
0
/* {{{ _php_mb_regex_ereg_replace_exec */
static void _php_mb_regex_ereg_replace_exec(INTERNAL_FUNCTION_PARAMETERS, OnigOptionType options, int is_callable)
{
	zval *arg_pattern_zval;

	char *arg_pattern;
	size_t arg_pattern_len;

	char *replace;
	size_t replace_len;

	zend_fcall_info arg_replace_fci;
	zend_fcall_info_cache arg_replace_fci_cache;

	char *string;
	size_t string_len;

	char *p;
	php_mb_regex_t *re;
	OnigSyntaxType *syntax;
	OnigRegion *regs = NULL;
	smart_str out_buf = {0};
	smart_str eval_buf = {0};
	smart_str *pbuf;
	size_t i;
	int err, eval, n;
	OnigUChar *pos;
	OnigUChar *string_lim;
	char *description = NULL;
	char pat_buf[6];

	const mbfl_encoding *enc;

	{
		const char *current_enc_name;
		current_enc_name = _php_mb_regex_mbctype2name(MBREX(current_mbctype));
		if (current_enc_name == NULL ||
			(enc = mbfl_name2encoding(current_enc_name)) == NULL) {
			php_error_docref(NULL, E_WARNING, "Unknown error");
			RETURN_FALSE;
		}
	}
	eval = 0;
	{
		char *option_str = NULL;
		size_t option_str_len = 0;

		if (!is_callable) {
			if (zend_parse_parameters(ZEND_NUM_ARGS(), "zss|s",
						&arg_pattern_zval,
						&replace, &replace_len,
						&string, &string_len,
						&option_str, &option_str_len) == FAILURE) {
				RETURN_FALSE;
			}
		} else {
			if (zend_parse_parameters(ZEND_NUM_ARGS(), "zfs|s",
						&arg_pattern_zval,
						&arg_replace_fci, &arg_replace_fci_cache,
						&string, &string_len,
						&option_str, &option_str_len) == FAILURE) {
				RETURN_FALSE;
			}
		}

		if (!php_mb_check_encoding(
		string,
		string_len,
		_php_mb_regex_mbctype2name(MBREX(current_mbctype))
		)) {
			RETURN_NULL();
		}

		if (option_str != NULL) {
			_php_mb_regex_init_options(option_str, option_str_len, &options, &syntax, &eval);
		} else {
			options |= MBREX(regex_default_options);
			syntax = MBREX(regex_default_syntax);
		}
	}
	if (eval && !is_callable) {
		php_error_docref(NULL, E_DEPRECATED, "The 'e' option is deprecated, use mb_ereg_replace_callback instead");
	}
	if (Z_TYPE_P(arg_pattern_zval) == IS_STRING) {
		arg_pattern = Z_STRVAL_P(arg_pattern_zval);
		arg_pattern_len = Z_STRLEN_P(arg_pattern_zval);
	} else {
		/* FIXME: this code is not multibyte aware! */
		convert_to_long_ex(arg_pattern_zval);
		pat_buf[0] = (char)Z_LVAL_P(arg_pattern_zval);
		pat_buf[1] = '\0';
		pat_buf[2] = '\0';
		pat_buf[3] = '\0';
		pat_buf[4] = '\0';
		pat_buf[5] = '\0';

		arg_pattern = pat_buf;
		arg_pattern_len = 1;
	}
	/* create regex pattern buffer */
	re = php_mbregex_compile_pattern(arg_pattern, arg_pattern_len, options, MBREX(current_mbctype), syntax);
	if (re == NULL) {
		RETURN_FALSE;
	}

	if (eval || is_callable) {
		pbuf = &eval_buf;
		description = zend_make_compiled_string_description("mbregex replace");
	} else {
		pbuf = &out_buf;
		description = NULL;
	}

	if (is_callable) {
		if (eval) {
			php_error_docref(NULL, E_WARNING, "Option 'e' cannot be used with replacement callback");
			RETURN_FALSE;
		}
	}

	/* do the actual work */
	err = 0;
	pos = (OnigUChar *)string;
	string_lim = (OnigUChar*)(string + string_len);
	regs = onig_region_new();
	while (err >= 0) {
		err = onig_search(re, (OnigUChar *)string, (OnigUChar *)string_lim, pos, (OnigUChar *)string_lim, regs, 0);
		if (err <= -2) {
			OnigUChar err_str[ONIG_MAX_ERROR_MESSAGE_LEN];
			onig_error_code_to_str(err_str, err);
			php_error_docref(NULL, E_WARNING, "mbregex search failure in php_mbereg_replace_exec(): %s", err_str);
			break;
		}
		if (err >= 0) {
#if moriyoshi_0
			if (regs->beg[0] == regs->end[0]) {
				php_error_docref(NULL, E_WARNING, "Empty regular expression");
				break;
			}
#endif
			/* copy the part of the string before the match */
			smart_str_appendl(&out_buf, (char *)pos, (size_t)((OnigUChar *)(string + regs->beg[0]) - pos));

			if (!is_callable) {
				/* copy replacement and backrefs */
				i = 0;
				p = replace;
				while (i < replace_len) {
					int fwd = (int) php_mb_mbchar_bytes_ex(p, enc);
					n = -1;
					if ((replace_len - i) >= 2 && fwd == 1 &&
					p[0] == '\\' && p[1] >= '0' && p[1] <= '9') {
						n = p[1] - '0';
					}
					if (n >= 0 && n < regs->num_regs) {
						if (regs->beg[n] >= 0 && regs->beg[n] < regs->end[n] && (size_t)regs->end[n] <= string_len) {
							smart_str_appendl(pbuf, string + regs->beg[n], regs->end[n] - regs->beg[n]);
						}
						p += 2;
						i += 2;
					} else {
						smart_str_appendl(pbuf, p, fwd);
						p += fwd;
						i += fwd;
					}
				}
			}

			if (eval) {
				zval v;
				zend_string *eval_str;
				/* null terminate buffer */
				smart_str_0(&eval_buf);

				if (eval_buf.s) {
					eval_str = eval_buf.s;
				} else {
					eval_str = ZSTR_EMPTY_ALLOC();
				}

				/* do eval */
				if (zend_eval_stringl(ZSTR_VAL(eval_str), ZSTR_LEN(eval_str), &v, description) == FAILURE) {
					efree(description);
					zend_throw_error(NULL, "Failed evaluating code: %s%s", PHP_EOL, ZSTR_VAL(eval_str));
					onig_region_free(regs, 0);
					smart_str_free(&out_buf);
					smart_str_free(&eval_buf);
					RETURN_FALSE;
				}

				/* result of eval */
				convert_to_string(&v);
				smart_str_appendl(&out_buf, Z_STRVAL(v), Z_STRLEN(v));
				/* Clean up */
				smart_str_free(&eval_buf);
				zval_dtor(&v);
			} else if (is_callable) {
				zval args[1];
				zval subpats, retval;
				int i;

				array_init(&subpats);
				for (i = 0; i < regs->num_regs; i++) {
					add_next_index_stringl(&subpats, string + regs->beg[i], regs->end[i] - regs->beg[i]);
				}

				ZVAL_COPY_VALUE(&args[0], &subpats);
				/* null terminate buffer */
				smart_str_0(&eval_buf);

				arg_replace_fci.param_count = 1;
				arg_replace_fci.params = args;
				arg_replace_fci.retval = &retval;
				if (zend_call_function(&arg_replace_fci, &arg_replace_fci_cache) == SUCCESS &&
						!Z_ISUNDEF(retval)) {
					convert_to_string_ex(&retval);
					smart_str_appendl(&out_buf, Z_STRVAL(retval), Z_STRLEN(retval));
					smart_str_free(&eval_buf);
					zval_ptr_dtor(&retval);
				} else {
					if (!EG(exception)) {
						php_error_docref(NULL, E_WARNING, "Unable to call custom replacement function");
					}
				}
				zval_ptr_dtor(&subpats);
			}

			n = regs->end[0];
			if ((pos - (OnigUChar *)string) < n) {
				pos = (OnigUChar *)string + n;
			} else {
				if (pos < string_lim) {
					smart_str_appendl(&out_buf, (char *)pos, 1);
				}
				pos++;
			}
		} else { /* nomatch */
			/* stick that last bit of string on our output */
			if (string_lim - pos > 0) {
				smart_str_appendl(&out_buf, (char *)pos, string_lim - pos);
			}
		}
		onig_region_free(regs, 0);
	}

	if (description) {
		efree(description);
	}
	if (regs != NULL) {
		onig_region_free(regs, 1);
	}
	smart_str_free(&eval_buf);

	if (err <= -2) {
		smart_str_free(&out_buf);
		RETVAL_FALSE;
	} else if (out_buf.s) {
		smart_str_0(&out_buf);
		RETVAL_STR(out_buf.s);
	} else {
		RETVAL_EMPTY_STRING();
	}
}
Exemplo n.º 21
0
/**
 * Applies a format to a message before sending it to the log
 *
 * @param string $message
 * @param int $type
 * @param int $timestamp
 * @param array $context
 * @return string
 */
PHP_METHOD(Phalcon_Logger_Formatter_Firephp, format) {

	zval *message, *type, *type_str = NULL, *timestamp, *context, *interpolated = NULL;
	zval *payload, *body, *backtrace = NULL, *meta, *encoded;
	zval *show_backtrace, *enable_labels;
	int i_show_backtrace, i_enable_labels;
	smart_str result = { NULL, 0, 0 };
	uint i;
	Bucket *p;

	phalcon_fetch_params(0, 4, 0, &message, &type, &timestamp, &context);

	/*
	 * We intentionally do not use Phalcon's MM for better performance.
	 * All variables allocated with ALLOC_INIT_ZVAL() will have
	 * their reference count set to 1 and therefore they can be nicely
	 * put into the result array; when that array will be destroyed,
	 * all inserted variables will be automatically destroyed, too
	 * and we will just save some time by not using Z_ADDREF_P and Z_DELREF_P
	 */

	if (Z_TYPE_P(context) == IS_ARRAY) {
		PHALCON_CALL_METHODW(&interpolated, this_ptr, "interpolate", message, context);
	}
	else {
		interpolated = message;
		Z_ADDREF_P(interpolated);
	}

	{
		zval *params[] = { type };
		if (FAILURE == phalcon_call_method(&type_str, this_ptr, "gettypestring", 1, params TSRMLS_CC)) {
			zval_ptr_dtor(&interpolated);
			return;
		}
	}

	show_backtrace   = phalcon_fetch_nproperty_this(getThis(), SL("_showBacktrace"), PH_NOISY TSRMLS_CC);
	enable_labels    = phalcon_fetch_nproperty_this(getThis(), SL("_enableLabels"), PH_NOISY TSRMLS_CC);
	i_show_backtrace = zend_is_true(show_backtrace);
	i_enable_labels  = zend_is_true(enable_labels);

	/*
	 * Get the backtrace. This differs for different PHP versions.
	 * 5.3.6+ allows us to skip the function arguments which will save some memory
	 * For 5.4+ there is an extra argument.
	 */
	if (i_show_backtrace) {
		ALLOC_INIT_ZVAL(backtrace);

#if PHP_VERSION_ID < 50306
		zend_fetch_debug_backtrace(backtrace, 1, 0 TSRMLS_CC);
#elif PHP_VERSION_ID < 50400
		zend_fetch_debug_backtrace(backtrace, 1, DEBUG_BACKTRACE_IGNORE_ARGS TSRMLS_CC);
#else
		zend_fetch_debug_backtrace(backtrace, 1, DEBUG_BACKTRACE_IGNORE_ARGS, 0 TSRMLS_CC);
#endif

		if (Z_TYPE_P(backtrace) == IS_ARRAY) {
			HashPosition pos;
			HashTable *ht = Z_ARRVAL_P(backtrace);
			zval **ppzval;
			int found = 0;
			ulong idx;
			char *key;
			uint key_len;

			/*
			 * At this point we know that the backtrace is the array.
			 * Again, we intentionally do not use Phalcon's API because we know
			 * that we are working with the array / hash table and thus we can
			 * save some time by omitting Z_TYPE_P(x) == IS_ARRAY checks
			 */

			for (
				zend_hash_internal_pointer_reset_ex(ht, &pos);
				zend_hash_has_more_elements_ex(ht, &pos) == SUCCESS;
			) {
				zend_hash_get_current_data_ex(ht, (void**)&ppzval, &pos);
				zend_hash_get_current_key_ex(ht, &key, &key_len, &idx, 0, &pos);
				zend_hash_move_forward_ex(ht, &pos);

				if (Z_TYPE_PP(ppzval) == IS_ARRAY) {
					/*
					 * Here we need to skip the latest calls into Phalcon's core.
					 * Calls to Zend internal functions will have "file" index not set.
					 * We remove these entries from the array.
					 */
					if (!found && !zend_hash_quick_exists(Z_ARRVAL_PP(ppzval), SS("file"), zend_inline_hash_func(SS("file")))) {
						zend_hash_index_del(ht, idx);
					}
					else {
						/*
						 * Remove args and object indices. They usually give
						 * too much information; this is not suitable to send
						 * in the HTTP headers
						 */
						zend_hash_quick_del(Z_ARRVAL_PP(ppzval), "args", sizeof("args"), zend_inline_hash_func(SS("args")));
						zend_hash_quick_del(Z_ARRVAL_PP(ppzval), "object", sizeof("object"), zend_inline_hash_func(SS("object")));
						found = 1;
					}
				}
			}

			/*
			 * Now we need to renumber the hash table because we removed several
			 * heading elements. If we don't do this, json_encode() will convert
			 * this array to a JavaScript object which is an unwanted side effect
			 */
			p = ht->pListHead;
			i = 0;
			while (p != NULL) {
				p->nKeyLength = 0;
				p->h = i++;
				p = p->pListNext;
			}

			ht->nNextFreeElement = i;
			zend_hash_rehash(ht);
		}
	}

	/*
	 * The result will looks like this:
	 *
	 * array(
	 *     array('Type' => 'message type', 'Label' => 'message'),
	 *     array('backtrace' => array(backtrace goes here)
	 * )
	 */
	MAKE_STD_ZVAL(payload);
	array_init_size(payload, 2);

	MAKE_STD_ZVAL(meta);
	array_init_size(meta, 4);
	add_assoc_zval_ex(meta, SS("Type"), type_str);

	if (i_show_backtrace && Z_TYPE_P(backtrace) == IS_ARRAY) {
		zval **ppzval;

		if (likely(SUCCESS == zend_hash_index_find(Z_ARRVAL_P(backtrace), 0, (void**)&ppzval)) && likely(Z_TYPE_PP(ppzval) == IS_ARRAY)) {
			zval **file = NULL, **line = NULL;

			zend_hash_quick_find(Z_ARRVAL_PP(ppzval), SS("file"), zend_inline_hash_func(SS("file")), (void**)&file);
			zend_hash_quick_find(Z_ARRVAL_PP(ppzval), SS("line"), zend_inline_hash_func(SS("line")), (void**)&line);

			if (likely(file != NULL)) {
				Z_ADDREF_PP(file);
				add_assoc_zval_ex(meta, SS("File"), *file);
			}

			if (likely(line != NULL)) {
				Z_ADDREF_PP(line);
				add_assoc_zval_ex(meta, SS("Line"), *line);
			}
		}
	}

	if (i_enable_labels) {
		add_assoc_zval_ex(meta, SS("Label"), interpolated);
	}

	if (!i_enable_labels && !i_show_backtrace) {
		body = interpolated;
	}
	else if (i_enable_labels && !i_show_backtrace) {
		MAKE_STD_ZVAL(body);
		ZVAL_EMPTY_STRING(body);
	}
	else {
		MAKE_STD_ZVAL(body);
		array_init_size(body, 2);

		if (i_show_backtrace) {
			add_assoc_zval_ex(body, SS("backtrace"), backtrace);
		}

		if (!i_enable_labels) {
			add_assoc_zval_ex(body, SS("message"), interpolated);
		}
	}

	add_next_index_zval(payload, meta);
	add_next_index_zval(payload, body);

	/* Convert everything to JSON */
	ALLOC_INIT_ZVAL(encoded);
	if (FAILURE == phalcon_json_encode(encoded, payload, 0 TSRMLS_CC)) {
		zval_ptr_dtor(&payload);
		zval_ptr_dtor(&encoded);
		return;
	}

	/* As promised, kill the payload and all associated elements */
	zval_ptr_dtor(&payload);

	/*
	 * We don't want to use Phalcon's concatenation API because it
	 * requires the memory manager. Therefore we fall back to using smart strings.
	 * smart_str_alloc4() will allocate all required memory amount (plus some more)
	 * in one go and this allows us to avoid performance penalties due to
	 * memory reallocations.
	 */
	if (Z_TYPE_P(encoded) == IS_STRING && Z_STRVAL_P(encoded) != NULL) {
		smart_str_alloc4(&result, (uint)(Z_STRLEN_P(encoded) + 2 + 5), 0, i);

		/*
		 * The format is:
		 *
		 * <size>|[meta,body]|
		 *
		 * Meta and body are contained in encoded inside the array, as required
		 * by the protocol specification
		 * @see http://www.firephp.org/Wiki/Reference/Protocol
		 */
		smart_str_append_long(&result, Z_STRLEN_P(encoded));
		smart_str_appendc(&result, '|');
		smart_str_appendl(&result, Z_STRVAL_P(encoded), Z_STRLEN_P(encoded));
		smart_str_appendc(&result, '|');
		smart_str_0(&result);
	}

	/* We don't need the JSON message anymore */
	zval_ptr_dtor(&encoded);
	/* Do not free the smart string because we steal its data for zval */
	RETURN_STRINGL(result.c, result.len, 0);
}
Exemplo n.º 22
0
static inline void xx_mainloop(url_adapt_state_ex_t *ctx, const char *newdata, size_t newlen TSRMLS_DC)
{
	char *end, *q;
	char *xp;
	char *start;
	int rest;

	smart_str_appendl(&ctx->buf, newdata, newlen);
	
	YYCURSOR = ctx->buf.c;
	YYLIMIT = ctx->buf.c + ctx->buf.len;

	switch (STATE) {
		case STATE_PLAIN: goto state_plain;
		case STATE_TAG: goto state_tag;
		case STATE_NEXT_ARG: goto state_next_arg;
		case STATE_ARG: goto state_arg;
		case STATE_BEFORE_VAL: goto state_before_val;
		case STATE_VAL: goto state_val;
	}
	

state_plain_begin:
	STATE = STATE_PLAIN;
	
state_plain:
	start = YYCURSOR;

{
	YYCTYPE yych;
	static const unsigned char yybm[] = {
		128, 128, 128, 128, 128, 128, 128, 128, 
		128, 128, 128, 128, 128, 128, 128, 128, 
		128, 128, 128, 128, 128, 128, 128, 128, 
		128, 128, 128, 128, 128, 128, 128, 128, 
		128, 128, 128, 128, 128, 128, 128, 128, 
		128, 128, 128, 128, 128, 128, 128, 128, 
		128, 128, 128, 128, 128, 128, 128, 128, 
		128, 128, 128, 128,   0, 128, 128, 128, 
		128, 128, 128, 128, 128, 128, 128, 128, 
		128, 128, 128, 128, 128, 128, 128, 128, 
		128, 128, 128, 128, 128, 128, 128, 128, 
		128, 128, 128, 128, 128, 128, 128, 128, 
		128, 128, 128, 128, 128, 128, 128, 128, 
		128, 128, 128, 128, 128, 128, 128, 128, 
		128, 128, 128, 128, 128, 128, 128, 128, 
		128, 128, 128, 128, 128, 128, 128, 128, 
		128, 128, 128, 128, 128, 128, 128, 128, 
		128, 128, 128, 128, 128, 128, 128, 128, 
		128, 128, 128, 128, 128, 128, 128, 128, 
		128, 128, 128, 128, 128, 128, 128, 128, 
		128, 128, 128, 128, 128, 128, 128, 128, 
		128, 128, 128, 128, 128, 128, 128, 128, 
		128, 128, 128, 128, 128, 128, 128, 128, 
		128, 128, 128, 128, 128, 128, 128, 128, 
		128, 128, 128, 128, 128, 128, 128, 128, 
		128, 128, 128, 128, 128, 128, 128, 128, 
		128, 128, 128, 128, 128, 128, 128, 128, 
		128, 128, 128, 128, 128, 128, 128, 128, 
		128, 128, 128, 128, 128, 128, 128, 128, 
		128, 128, 128, 128, 128, 128, 128, 128, 
		128, 128, 128, 128, 128, 128, 128, 128, 
		128, 128, 128, 128, 128, 128, 128, 128, 
	};
	if (YYLIMIT <= YYCURSOR) YYFILL(1);
	yych = *YYCURSOR;
	if (yybm[0+yych] & 128) {
		goto yy15;
	}
	++YYCURSOR;
	{ passthru(STD_ARGS); STATE = STATE_TAG; goto state_tag; }
yy15:
	++YYCURSOR;
	if (YYLIMIT <= YYCURSOR) YYFILL(1);
	yych = *YYCURSOR;
	if (yybm[0+yych] & 128) {
		goto yy15;
	}
	{ passthru(STD_ARGS); goto state_plain; }
}


state_tag:	
	start = YYCURSOR;

{
	YYCTYPE yych;
	static const unsigned char yybm[] = {
		  0,   0,   0,   0,   0,   0,   0,   0, 
		  0,   0,   0,   0,   0,   0,   0,   0, 
		  0,   0,   0,   0,   0,   0,   0,   0, 
		  0,   0,   0,   0,   0,   0,   0,   0, 
		  0,   0,   0,   0,   0,   0,   0,   0, 
		  0,   0,   0,   0,   0,   0,   0,   0, 
		  0,   0,   0,   0,   0,   0,   0,   0, 
		  0,   0, 128,   0,   0,   0,   0,   0, 
		  0, 128, 128, 128, 128, 128, 128, 128, 
		128, 128, 128, 128, 128, 128, 128, 128, 
		128, 128, 128, 128, 128, 128, 128, 128, 
		128, 128, 128,   0,   0,   0,   0,   0, 
		  0, 128, 128, 128, 128, 128, 128, 128, 
		128, 128, 128, 128, 128, 128, 128, 128, 
		128, 128, 128, 128, 128, 128, 128, 128, 
		128, 128, 128,   0,   0,   0,   0,   0, 
		  0,   0,   0,   0,   0,   0,   0,   0, 
		  0,   0,   0,   0,   0,   0,   0,   0, 
		  0,   0,   0,   0,   0,   0,   0,   0, 
		  0,   0,   0,   0,   0,   0,   0,   0, 
		  0,   0,   0,   0,   0,   0,   0,   0, 
		  0,   0,   0,   0,   0,   0,   0,   0, 
		  0,   0,   0,   0,   0,   0,   0,   0, 
		  0,   0,   0,   0,   0,   0,   0,   0, 
		  0,   0,   0,   0,   0,   0,   0,   0, 
		  0,   0,   0,   0,   0,   0,   0,   0, 
		  0,   0,   0,   0,   0,   0,   0,   0, 
		  0,   0,   0,   0,   0,   0,   0,   0, 
		  0,   0,   0,   0,   0,   0,   0,   0, 
		  0,   0,   0,   0,   0,   0,   0,   0, 
		  0,   0,   0,   0,   0,   0,   0,   0, 
		  0,   0,   0,   0,   0,   0,   0,   0, 
	};
	if ((YYLIMIT - YYCURSOR) < 2) YYFILL(2);
	yych = *YYCURSOR;
	if (yych <= '@') {
		if (yych != ':') goto yy22;
	} else {
		if (yych <= 'Z') goto yy20;
		if (yych <= '`') goto yy22;
		if (yych >= '{') goto yy22;
	}
yy20:
	++YYCURSOR;
	yych = *YYCURSOR;
	goto yy25;
yy21:
	{ handle_tag(STD_ARGS); /* Sets STATE */; passthru(STD_ARGS); if (STATE == STATE_PLAIN) goto state_plain; else goto state_next_arg; }
yy22:
	++YYCURSOR;
	{ passthru(STD_ARGS); goto state_plain_begin; }
yy24:
	++YYCURSOR;
	if (YYLIMIT <= YYCURSOR) YYFILL(1);
	yych = *YYCURSOR;
yy25:
	if (yybm[0+yych] & 128) {
		goto yy24;
	}
	goto yy21;
}


state_next_arg_begin:
	STATE = STATE_NEXT_ARG;
	
state_next_arg:
	start = YYCURSOR;

{
	YYCTYPE yych;
	static const unsigned char yybm[] = {
		  0,   0,   0,   0,   0,   0,   0,   0, 
		  0, 128, 128, 128,   0, 128,   0,   0, 
		  0,   0,   0,   0,   0,   0,   0,   0, 
		  0,   0,   0,   0,   0,   0,   0,   0, 
		128,   0,   0,   0,   0,   0,   0,   0, 
		  0,   0,   0,   0,   0,   0,   0,   0, 
		  0,   0,   0,   0,   0,   0,   0,   0, 
		  0,   0,   0,   0,   0,   0,   0,   0, 
		  0,   0,   0,   0,   0,   0,   0,   0, 
		  0,   0,   0,   0,   0,   0,   0,   0, 
		  0,   0,   0,   0,   0,   0,   0,   0, 
		  0,   0,   0,   0,   0,   0,   0,   0, 
		  0,   0,   0,   0,   0,   0,   0,   0, 
		  0,   0,   0,   0,   0,   0,   0,   0, 
		  0,   0,   0,   0,   0,   0,   0,   0, 
		  0,   0,   0,   0,   0,   0,   0,   0, 
		  0,   0,   0,   0,   0,   0,   0,   0, 
		  0,   0,   0,   0,   0,   0,   0,   0, 
		  0,   0,   0,   0,   0,   0,   0,   0, 
		  0,   0,   0,   0,   0,   0,   0,   0, 
		  0,   0,   0,   0,   0,   0,   0,   0, 
		  0,   0,   0,   0,   0,   0,   0,   0, 
		  0,   0,   0,   0,   0,   0,   0,   0, 
		  0,   0,   0,   0,   0,   0,   0,   0, 
		  0,   0,   0,   0,   0,   0,   0,   0, 
		  0,   0,   0,   0,   0,   0,   0,   0, 
		  0,   0,   0,   0,   0,   0,   0,   0, 
		  0,   0,   0,   0,   0,   0,   0,   0, 
		  0,   0,   0,   0,   0,   0,   0,   0, 
		  0,   0,   0,   0,   0,   0,   0,   0, 
		  0,   0,   0,   0,   0,   0,   0,   0, 
		  0,   0,   0,   0,   0,   0,   0,   0, 
	};
	if ((YYLIMIT - YYCURSOR) < 2) YYFILL(2);
	yych = *YYCURSOR;
	if (yych <= ' ') {
		if (yych <= '\f') {
			if (yych <= 0x08) goto yy34;
			if (yych <= '\v') goto yy30;
			goto yy34;
		} else {
			if (yych <= '\r') goto yy30;
			if (yych <= 0x1F) goto yy34;
			goto yy30;
		}
	} else {
		if (yych <= '@') {
			if (yych != '>') goto yy34;
		} else {
			if (yych <= 'Z') goto yy32;
			if (yych <= '`') goto yy34;
			if (yych <= 'z') goto yy32;
			goto yy34;
		}
	}
	++YYCURSOR;
	{ passthru(STD_ARGS); handle_form(STD_ARGS); goto state_plain_begin; }
yy30:
	++YYCURSOR;
	yych = *YYCURSOR;
	goto yy37;
yy31:
	{ passthru(STD_ARGS); goto state_next_arg; }
yy32:
	++YYCURSOR;
	{ --YYCURSOR; STATE = STATE_ARG; goto state_arg; }
yy34:
	++YYCURSOR;
	{ passthru(STD_ARGS); goto state_plain_begin; }
yy36:
	++YYCURSOR;
	if (YYLIMIT <= YYCURSOR) YYFILL(1);
	yych = *YYCURSOR;
yy37:
	if (yybm[0+yych] & 128) {
		goto yy36;
	}
	goto yy31;
}


state_arg:
	start = YYCURSOR;

{
	YYCTYPE yych;
	static const unsigned char yybm[] = {
		  0,   0,   0,   0,   0,   0,   0,   0, 
		  0,   0,   0,   0,   0,   0,   0,   0, 
		  0,   0,   0,   0,   0,   0,   0,   0, 
		  0,   0,   0,   0,   0,   0,   0,   0, 
		  0,   0,   0,   0,   0,   0,   0,   0, 
		  0,   0,   0,   0,   0, 128,   0,   0, 
		  0,   0,   0,   0,   0,   0,   0,   0, 
		  0,   0,   0,   0,   0,   0,   0,   0, 
		  0, 128, 128, 128, 128, 128, 128, 128, 
		128, 128, 128, 128, 128, 128, 128, 128, 
		128, 128, 128, 128, 128, 128, 128, 128, 
		128, 128, 128,   0,   0,   0,   0,   0, 
		  0, 128, 128, 128, 128, 128, 128, 128, 
		128, 128, 128, 128, 128, 128, 128, 128, 
		128, 128, 128, 128, 128, 128, 128, 128, 
		128, 128, 128,   0,   0,   0,   0,   0, 
		  0,   0,   0,   0,   0,   0,   0,   0, 
		  0,   0,   0,   0,   0,   0,   0,   0, 
		  0,   0,   0,   0,   0,   0,   0,   0, 
		  0,   0,   0,   0,   0,   0,   0,   0, 
		  0,   0,   0,   0,   0,   0,   0,   0, 
		  0,   0,   0,   0,   0,   0,   0,   0, 
		  0,   0,   0,   0,   0,   0,   0,   0, 
		  0,   0,   0,   0,   0,   0,   0,   0, 
		  0,   0,   0,   0,   0,   0,   0,   0, 
		  0,   0,   0,   0,   0,   0,   0,   0, 
		  0,   0,   0,   0,   0,   0,   0,   0, 
		  0,   0,   0,   0,   0,   0,   0,   0, 
		  0,   0,   0,   0,   0,   0,   0,   0, 
		  0,   0,   0,   0,   0,   0,   0,   0, 
		  0,   0,   0,   0,   0,   0,   0,   0, 
		  0,   0,   0,   0,   0,   0,   0,   0, 
	};
	if ((YYLIMIT - YYCURSOR) < 2) YYFILL(2);
	yych = *YYCURSOR;
	if (yych <= '@') goto yy42;
	if (yych <= 'Z') goto yy40;
	if (yych <= '`') goto yy42;
	if (yych >= '{') goto yy42;
yy40:
	++YYCURSOR;
	yych = *YYCURSOR;
	goto yy45;
yy41:
	{ passthru(STD_ARGS); handle_arg(STD_ARGS); STATE = STATE_BEFORE_VAL; goto state_before_val; }
yy42:
	++YYCURSOR;
	{ passthru(STD_ARGS); STATE = STATE_NEXT_ARG; goto state_next_arg; }
yy44:
	++YYCURSOR;
	if (YYLIMIT <= YYCURSOR) YYFILL(1);
	yych = *YYCURSOR;
yy45:
	if (yybm[0+yych] & 128) {
		goto yy44;
	}
	goto yy41;
}


state_before_val:
	start = YYCURSOR;

{
	YYCTYPE yych;
	static const unsigned char yybm[] = {
		  0,   0,   0,   0,   0,   0,   0,   0, 
		  0,   0,   0,   0,   0,   0,   0,   0, 
		  0,   0,   0,   0,   0,   0,   0,   0, 
		  0,   0,   0,   0,   0,   0,   0,   0, 
		128,   0,   0,   0,   0,   0,   0,   0, 
		  0,   0,   0,   0,   0,   0,   0,   0, 
		  0,   0,   0,   0,   0,   0,   0,   0, 
		  0,   0,   0,   0,   0,   0,   0,   0, 
		  0,   0,   0,   0,   0,   0,   0,   0, 
		  0,   0,   0,   0,   0,   0,   0,   0, 
		  0,   0,   0,   0,   0,   0,   0,   0, 
		  0,   0,   0,   0,   0,   0,   0,   0, 
		  0,   0,   0,   0,   0,   0,   0,   0, 
		  0,   0,   0,   0,   0,   0,   0,   0, 
		  0,   0,   0,   0,   0,   0,   0,   0, 
		  0,   0,   0,   0,   0,   0,   0,   0, 
		  0,   0,   0,   0,   0,   0,   0,   0, 
		  0,   0,   0,   0,   0,   0,   0,   0, 
		  0,   0,   0,   0,   0,   0,   0,   0, 
		  0,   0,   0,   0,   0,   0,   0,   0, 
		  0,   0,   0,   0,   0,   0,   0,   0, 
		  0,   0,   0,   0,   0,   0,   0,   0, 
		  0,   0,   0,   0,   0,   0,   0,   0, 
		  0,   0,   0,   0,   0,   0,   0,   0, 
		  0,   0,   0,   0,   0,   0,   0,   0, 
		  0,   0,   0,   0,   0,   0,   0,   0, 
		  0,   0,   0,   0,   0,   0,   0,   0, 
		  0,   0,   0,   0,   0,   0,   0,   0, 
		  0,   0,   0,   0,   0,   0,   0,   0, 
		  0,   0,   0,   0,   0,   0,   0,   0, 
		  0,   0,   0,   0,   0,   0,   0,   0, 
		  0,   0,   0,   0,   0,   0,   0,   0, 
	};
	if ((YYLIMIT - YYCURSOR) < 2) YYFILL(2);
	yych = *YYCURSOR;
	if (yych == ' ') goto yy48;
	if (yych == '=') goto yy50;
	goto yy52;
yy48:
	yych = *(YYMARKER = ++YYCURSOR);
	if (yych == ' ') goto yy55;
	if (yych == '=') goto yy53;
yy49:
	{ --YYCURSOR; goto state_next_arg_begin; }
yy50:
	++YYCURSOR;
	yych = *YYCURSOR;
	goto yy54;
yy51:
	{ passthru(STD_ARGS); STATE = STATE_VAL; goto state_val; }
yy52:
	yych = *++YYCURSOR;
	goto yy49;
yy53:
	++YYCURSOR;
	if (YYLIMIT <= YYCURSOR) YYFILL(1);
	yych = *YYCURSOR;
yy54:
	if (yybm[0+yych] & 128) {
		goto yy53;
	}
	goto yy51;
yy55:
	++YYCURSOR;
	if (YYLIMIT <= YYCURSOR) YYFILL(1);
	yych = *YYCURSOR;
	if (yych == ' ') goto yy55;
	if (yych == '=') goto yy53;
	YYCURSOR = YYMARKER;
	goto yy49;
}



state_val:
	start = YYCURSOR;

{
	YYCTYPE yych;
	static const unsigned char yybm[] = {
		248, 248, 248, 248, 248, 248, 248, 248, 
		248, 160, 160, 248, 248, 160, 248, 248, 
		248, 248, 248, 248, 248, 248, 248, 248, 
		248, 248, 248, 248, 248, 248, 248, 248, 
		160, 248,  56, 248, 248, 248, 248, 200, 
		248, 248, 248, 248, 248, 248, 248, 248, 
		248, 248, 248, 248, 248, 248, 248, 248, 
		248, 248, 248, 248, 248, 248,   0, 248, 
		248, 248, 248, 248, 248, 248, 248, 248, 
		248, 248, 248, 248, 248, 248, 248, 248, 
		248, 248, 248, 248, 248, 248, 248, 248, 
		248, 248, 248, 248, 248, 248, 248, 248, 
		248, 248, 248, 248, 248, 248, 248, 248, 
		248, 248, 248, 248, 248, 248, 248, 248, 
		248, 248, 248, 248, 248, 248, 248, 248, 
		248, 248, 248, 248, 248, 248, 248, 248, 
		248, 248, 248, 248, 248, 248, 248, 248, 
		248, 248, 248, 248, 248, 248, 248, 248, 
		248, 248, 248, 248, 248, 248, 248, 248, 
		248, 248, 248, 248, 248, 248, 248, 248, 
		248, 248, 248, 248, 248, 248, 248, 248, 
		248, 248, 248, 248, 248, 248, 248, 248, 
		248, 248, 248, 248, 248, 248, 248, 248, 
		248, 248, 248, 248, 248, 248, 248, 248, 
		248, 248, 248, 248, 248, 248, 248, 248, 
		248, 248, 248, 248, 248, 248, 248, 248, 
		248, 248, 248, 248, 248, 248, 248, 248, 
		248, 248, 248, 248, 248, 248, 248, 248, 
		248, 248, 248, 248, 248, 248, 248, 248, 
		248, 248, 248, 248, 248, 248, 248, 248, 
		248, 248, 248, 248, 248, 248, 248, 248, 
		248, 248, 248, 248, 248, 248, 248, 248, 
	};
	if ((YYLIMIT - YYCURSOR) < 3) YYFILL(3);
	yych = *YYCURSOR;
	if (yych <= ' ') {
		if (yych <= '\f') {
			if (yych <= 0x08) goto yy63;
			if (yych <= '\n') goto yy64;
			goto yy63;
		} else {
			if (yych <= '\r') goto yy64;
			if (yych <= 0x1F) goto yy63;
			goto yy64;
		}
	} else {
		if (yych <= '&') {
			if (yych != '"') goto yy63;
		} else {
			if (yych <= '\'') goto yy62;
			if (yych == '>') goto yy64;
			goto yy63;
		}
	}
	yych = *(YYMARKER = ++YYCURSOR);
	goto yy77;
yy61:
	{ handle_val(STD_ARGS, 0, ' '); goto state_next_arg_begin; }
yy62:
	yych = *(YYMARKER = ++YYCURSOR);
	goto yy69;
yy63:
	yych = *++YYCURSOR;
	goto yy67;
yy64:
	++YYCURSOR;
	{ passthru(STD_ARGS); goto state_next_arg_begin; }
yy66:
	++YYCURSOR;
	if (YYLIMIT <= YYCURSOR) YYFILL(1);
	yych = *YYCURSOR;
yy67:
	if (yybm[0+yych] & 8) {
		goto yy66;
	}
	goto yy61;
yy68:
	YYMARKER = ++YYCURSOR;
	if ((YYLIMIT - YYCURSOR) < 2) YYFILL(2);
	yych = *YYCURSOR;
yy69:
	if (yybm[0+yych] & 16) {
		goto yy68;
	}
	if (yych <= '&') goto yy72;
	if (yych >= '(') goto yy61;
	++YYCURSOR;
	if (yybm[0+(yych = *YYCURSOR)] & 8) {
		goto yy66;
	}
yy71:
	{ handle_val(STD_ARGS, 1, '\''); goto state_next_arg_begin; }
yy72:
	++YYCURSOR;
	if (YYLIMIT <= YYCURSOR) YYFILL(1);
	yych = *YYCURSOR;
	if (yybm[0+yych] & 32) {
		goto yy72;
	}
	if (yych <= '=') goto yy75;
yy74:
	YYCURSOR = YYMARKER;
	goto yy61;
yy75:
	yych = *++YYCURSOR;
	goto yy71;
yy76:
	YYMARKER = ++YYCURSOR;
	if ((YYLIMIT - YYCURSOR) < 2) YYFILL(2);
	yych = *YYCURSOR;
yy77:
	if (yybm[0+yych] & 64) {
		goto yy76;
	}
	if (yych <= '!') goto yy80;
	if (yych >= '#') goto yy61;
	++YYCURSOR;
	if (yybm[0+(yych = *YYCURSOR)] & 8) {
		goto yy66;
	}
yy79:
	{ handle_val(STD_ARGS, 1, '"'); goto state_next_arg_begin; }
yy80:
	++YYCURSOR;
	if (YYLIMIT <= YYCURSOR) YYFILL(1);
	yych = *YYCURSOR;
	if (yybm[0+yych] & 128) {
		goto yy80;
	}
	if (yych >= '>') goto yy74;
	++YYCURSOR;
	yych = *YYCURSOR;
	goto yy79;
}


stop:
	rest = YYLIMIT - start;
	scdebug(("stopped in state %d at pos %d (%d:%c) %d\n", STATE, YYCURSOR - ctx->buf.c, *YYCURSOR, *YYCURSOR, rest));
	/* XXX: Crash avoidance. Need to work with reporter to figure out what goes wrong */	
	if (rest < 0) rest = 0;
	
	if (rest) memmove(ctx->buf.c, start, rest);
	ctx->buf.len = rest;
}
Exemplo n.º 23
0
static inline void handle_arg(STD_PARA) 
{
	ctx->arg.len = 0;
	smart_str_appendl(&ctx->arg, start, YYCURSOR - start);
}
Exemplo n.º 24
0
Arquivo: http.c Projeto: IMSoP/php-src
/* {{{ php_url_encode_hash */
PHPAPI int php_url_encode_hash_ex(HashTable *ht, smart_str *formstr,
				const char *num_prefix, size_t num_prefix_len,
				const char *key_prefix, size_t key_prefix_len,
				const char *key_suffix, size_t key_suffix_len,
			  zval *type, char *arg_sep, int enc_type)
{
	zend_string *key = NULL;
	char *newprefix, *p;
	const char *prop_name;
	size_t arg_sep_len, newprefix_len, prop_len;
	zend_ulong idx;
	zval *zdata = NULL;

	if (!ht) {
		return FAILURE;
	}

	if (GC_IS_RECURSIVE(ht)) {
		/* Prevent recursion */
		return SUCCESS;
	}

	if (!arg_sep) {
		arg_sep = INI_STR("arg_separator.output");
		if (!arg_sep || !strlen(arg_sep)) {
			arg_sep = URL_DEFAULT_ARG_SEP;
		}
	}
	arg_sep_len = strlen(arg_sep);

	ZEND_HASH_FOREACH_KEY_VAL(ht, idx, key, zdata) {
		zend_bool is_dynamic = 1;
		if (Z_TYPE_P(zdata) == IS_INDIRECT) {
			zdata = Z_INDIRECT_P(zdata);
			if (Z_ISUNDEF_P(zdata)) {
				continue;
			}

			is_dynamic = 0;
		}

		/* handling for private & protected object properties */
		if (key) {
			prop_name = ZSTR_VAL(key);
			prop_len = ZSTR_LEN(key);

			if (type != NULL && zend_check_property_access(Z_OBJ_P(type), key, is_dynamic) != SUCCESS) {
				/* property not visible in this scope */
				continue;
			}

			if (ZSTR_VAL(key)[0] == '\0' && type != NULL) {
				const char *tmp;
				zend_unmangle_property_name_ex(key, &tmp, &prop_name, &prop_len);
			} else {
				prop_name = ZSTR_VAL(key);
				prop_len = ZSTR_LEN(key);
			}
		} else {
			prop_name = NULL;
			prop_len = 0;
		}

		ZVAL_DEREF(zdata);
		if (Z_TYPE_P(zdata) == IS_ARRAY || Z_TYPE_P(zdata) == IS_OBJECT) {
			if (key) {
				zend_string *ekey;
				if (enc_type == PHP_QUERY_RFC3986) {
					ekey = php_raw_url_encode(prop_name, prop_len);
				} else {
					ekey = php_url_encode(prop_name, prop_len);
				}
				newprefix_len = key_suffix_len + ZSTR_LEN(ekey) + key_prefix_len + 3 /* %5B */;
				newprefix = emalloc(newprefix_len + 1);
				p = newprefix;

				if (key_prefix) {
					memcpy(p, key_prefix, key_prefix_len);
					p += key_prefix_len;
				}

				memcpy(p, ZSTR_VAL(ekey), ZSTR_LEN(ekey));
				p += ZSTR_LEN(ekey);
				zend_string_free(ekey);

				if (key_suffix) {
					memcpy(p, key_suffix, key_suffix_len);
					p += key_suffix_len;
				}
				*(p++) = '%';
				*(p++) = '5';
				*(p++) = 'B';
				*p = '\0';
			} else {
				char *ekey;
				size_t ekey_len;
				/* Is an integer key */
				ekey_len = spprintf(&ekey, 0, ZEND_LONG_FMT, idx);
				newprefix_len = key_prefix_len + num_prefix_len + ekey_len + key_suffix_len + 3 /* %5B */;
				newprefix = emalloc(newprefix_len + 1);
				p = newprefix;

				if (key_prefix) {
					memcpy(p, key_prefix, key_prefix_len);
					p += key_prefix_len;
				}

				memcpy(p, num_prefix, num_prefix_len);
				p += num_prefix_len;

				memcpy(p, ekey, ekey_len);
				p += ekey_len;
				efree(ekey);

				if (key_suffix) {
					memcpy(p, key_suffix, key_suffix_len);
					p += key_suffix_len;
				}
				*(p++) = '%';
				*(p++) = '5';
				*(p++) = 'B';
				*p = '\0';
			}
			if (!(GC_FLAGS(ht) & GC_IMMUTABLE)) {
				GC_PROTECT_RECURSION(ht);
			}
			php_url_encode_hash_ex(HASH_OF(zdata), formstr, NULL, 0, newprefix, newprefix_len, "%5D", 3, (Z_TYPE_P(zdata) == IS_OBJECT ? zdata : NULL), arg_sep, enc_type);
			if (!(GC_FLAGS(ht) & GC_IMMUTABLE)) {
				GC_UNPROTECT_RECURSION(ht);
			}
			efree(newprefix);
		} else if (Z_TYPE_P(zdata) == IS_NULL || Z_TYPE_P(zdata) == IS_RESOURCE) {
			/* Skip these types */
			continue;
		} else {
			if (formstr->s) {
				smart_str_appendl(formstr, arg_sep, arg_sep_len);
			}
			/* Simple key=value */
			smart_str_appendl(formstr, key_prefix, key_prefix_len);
			if (key) {
				zend_string *ekey;
				if (enc_type == PHP_QUERY_RFC3986) {
					ekey = php_raw_url_encode(prop_name, prop_len);
				} else {
					ekey = php_url_encode(prop_name, prop_len);
				}
				smart_str_append(formstr, ekey);
				zend_string_free(ekey);
			} else {
				/* Numeric key */
				if (num_prefix) {
					smart_str_appendl(formstr, num_prefix, num_prefix_len);
				}
				smart_str_append_long(formstr, idx);
			}
			smart_str_appendl(formstr, key_suffix, key_suffix_len);
			smart_str_appendl(formstr, "=", 1);
			switch (Z_TYPE_P(zdata)) {
				case IS_STRING: {
						zend_string *ekey;
						if (enc_type == PHP_QUERY_RFC3986) {
							ekey = php_raw_url_encode(Z_STRVAL_P(zdata), Z_STRLEN_P(zdata));
						} else {
							ekey = php_url_encode(Z_STRVAL_P(zdata), Z_STRLEN_P(zdata));
						}
						smart_str_append(formstr, ekey);
						zend_string_free(ekey);
					}
					break;
				case IS_LONG:
					smart_str_append_long(formstr, Z_LVAL_P(zdata));
					break;
				case IS_FALSE:
					smart_str_appendl(formstr, "0", sizeof("0")-1);
					break;
				case IS_TRUE:
					smart_str_appendl(formstr, "1", sizeof("1")-1);
					break;
				case IS_DOUBLE:
					{
						char *ekey;
					  	size_t ekey_len;
						ekey_len = spprintf(&ekey, 0, "%.*G", (int) EG(precision), Z_DVAL_P(zdata));
						smart_str_appendl(formstr, ekey, ekey_len);
						efree(ekey);
				  	}
					break;
				default:
					{
						zend_string *ekey;
						zend_string *tmp;
						zend_string *str= zval_get_tmp_string(zdata, &tmp);
						if (enc_type == PHP_QUERY_RFC3986) {
							ekey = php_raw_url_encode(ZSTR_VAL(str), ZSTR_LEN(str));
						} else {
							ekey = php_url_encode(ZSTR_VAL(str), ZSTR_LEN(str));
						}
						smart_str_append(formstr, ekey);
						zend_tmp_string_release(tmp);
						zend_string_free(ekey);
					}
			}
		}
	} ZEND_HASH_FOREACH_END();
Exemplo n.º 25
0
/**
 * Perform escaping of non-alphanumeric characters to different formats
 */
void zephir_escape_multi(zval *return_value, zval *param, const char *escape_char, unsigned int escape_length, char escape_extra, int use_whitelist)
{

	unsigned int i;
	zval copy;
	smart_str escaped_str = {0};
	char machine_little_endian, *hex;
	int big_endian_long_map[4];
	int use_copy = 0, machine_endian_check = 1;
	int issigned = 0;
	long value;

	if (Z_TYPE_P(param) != IS_STRING) {
		use_copy = zend_make_printable_zval(param, &copy);
		if (use_copy) {
			param = &copy;
		}
	}

	if (Z_STRLEN_P(param) <= 0) {
		RETURN_FALSE;
	}

	/**
	 * This is how the big_ending_long_map is calculated as in 'pack'
	 */
	machine_little_endian = ((char *) &machine_endian_check)[0];
	if (machine_little_endian) {
		big_endian_long_map[0] = 3;
		big_endian_long_map[1] = 2;
		big_endian_long_map[2] = 1;
		big_endian_long_map[3] = 0;
	} else {
		int size = sizeof(Z_LVAL_P(param));
		big_endian_long_map[0] = size - 4;
		big_endian_long_map[1] = size - 3;
		big_endian_long_map[2] = size - 2;
		big_endian_long_map[3] = size - 1;
	}

	/**
	 * The input must be a valid UTF-32 string
	 */
	if ((Z_STRLEN_P(param) % 4) != 0) {
		RETURN_FALSE;
	}

	for (i = 0; i < Z_STRLEN_P(param); i += 4) {

		issigned = Z_STRVAL_P(param)[i] & 0x80;

		value = 0;
		if (sizeof(long) > 4 && issigned) {
			value = ~INT_MAX;
		}

		value |= zephir_unpack(&Z_STRVAL_P(param)[i], 4, issigned, big_endian_long_map);
		if (sizeof(long) > 4) {
			value = (unsigned int) value;
		}

		/**
		 * CSS 2.1 section 4.1.3: "It is undefined in CSS 2.1 what happens if a
		 * style sheet does contain a character with Unicode codepoint zero."
		 */
		if (value == '\0') {
			RETURN_FALSE;
		}

		/**
		 * Alphanumeric characters are not escaped
		 */
		if (value < 256 && isalnum(value)) {
			smart_str_appendc(&escaped_str, (unsigned char) value);
			continue;
		}

		/**
		 * Chararters in the whitelist are left as they are
		 */
		if (use_whitelist) {
			switch (value) {
				case ' ':
				case '/':
				case '*':
				case '+':
				case '-':
				case '\t':
				case '\n':
				case '^':
				case '$':
				case '!':
				case '?':
				case '\\':
				case '#':
				case '}':
				case '{':
				case ')':
				case '(':
				case ']':
				case '[':
				case '.':
				case ',':
				case ':':
				case ';':
				case '_':
				case '|':
					smart_str_appendc(&escaped_str, (unsigned char) value);
					continue;
			}
		}

		/**
		 * Convert character to hexadecimal
		 */
		hex = zephir_longtohex(value);

		/**
		 * Append the escaped character
		 */
		smart_str_appendl(&escaped_str, escape_char, escape_length);
		smart_str_appendl(&escaped_str, hex, strlen(hex));
		if (escape_extra != '\0') {
			smart_str_appendc(&escaped_str, escape_extra);
		}

		efree(hex);
	}

	if (use_copy) {
		zval_dtor(param);
	}

	smart_str_0(&escaped_str);

	if (escaped_str.s) {
		RETURN_STR(escaped_str.s);
	} else {
		RETURN_EMPTY_STRING();
	}
}
Exemplo n.º 26
0
zval * php_can_strtr_array(char *str, int slen, HashTable *hash)
{
    zval **entry;
    char  *string_key;
    uint   string_key_len;
    zval **trans;
    zval   ctmp;
    ulong num_key;
    int minlen = 128*1024;
    int maxlen = 0, pos, len, found;
    char *key;
    HashPosition hpos;
    smart_str result = {0};
    HashTable tmp_hash;

    zend_hash_init(&tmp_hash, zend_hash_num_elements(hash), NULL, NULL, 0);
    zend_hash_internal_pointer_reset_ex(hash, &hpos);
    while (zend_hash_get_current_data_ex(hash, (void **)&entry, &hpos) == SUCCESS) {
        switch (zend_hash_get_current_key_ex(hash, &string_key, &string_key_len, &num_key, 0, &hpos)) {
            case HASH_KEY_IS_STRING:
                len = string_key_len-1;
                if (len < 1) {
                    zend_hash_destroy(&tmp_hash);
                    return NULL;
                }
                zend_hash_add(&tmp_hash, string_key, string_key_len, entry, sizeof(zval*), NULL);
                if (len > maxlen) {
                    maxlen = len;
                }
                if (len < minlen) {
                    minlen = len;
                }
                break;

            case HASH_KEY_IS_LONG:
                Z_TYPE(ctmp) = IS_LONG;
                Z_LVAL(ctmp) = num_key;

                convert_to_string(&ctmp);
                len = Z_STRLEN(ctmp);
                zend_hash_add(&tmp_hash, Z_STRVAL(ctmp), len+1, entry, sizeof(zval*), NULL);
                zval_dtor(&ctmp);

                if (len > maxlen) {
                    maxlen = len;
                }
                if (len < minlen) {
                    minlen = len;
                }
                break;
        }
        zend_hash_move_forward_ex(hash, &hpos);
    }

    key = emalloc(maxlen+1);
    pos = 0;

    while (pos < slen) {
        if ((pos + maxlen) > slen) {
            maxlen = slen - pos;
        }

        found = 0;
        memcpy(key, str+pos, maxlen);

        for (len = maxlen; len >= minlen; len--) {
            key[len] = 0;

            if (zend_hash_find(&tmp_hash, key, len+1, (void**)&trans) == SUCCESS) {
                char *tval;
                int tlen;
                zval tmp;

                if (Z_TYPE_PP(trans) != IS_STRING) {
                    tmp = **trans;
                    zval_copy_ctor(&tmp);
                    convert_to_string(&tmp);
                    tval = Z_STRVAL(tmp);
                    tlen = Z_STRLEN(tmp);
                } else {
                    tval = Z_STRVAL_PP(trans);
                    tlen = Z_STRLEN_PP(trans);
                }

                smart_str_appendl(&result, tval, tlen);
                pos += len;
                found = 1;

                if (Z_TYPE_PP(trans) != IS_STRING) {
                    zval_dtor(&tmp);
                }
                break;
            }
        }

        if (! found) {
            smart_str_appendc(&result, str[pos++]);
        }
    }

    efree(key);
    zend_hash_destroy(&tmp_hash);
    smart_str_0(&result);

    zval *retval;
    MAKE_STD_ZVAL(retval);
    ZVAL_STRINGL(retval, result.c, result.len, 0);
    return retval;
}
Exemplo n.º 27
0
zval *air_router_route(air_router_t *self) {
	zval *return_value;
	MAKE_STD_ZVAL(return_value);
	ZVAL_NULL(return_value);

	pcre_cache_entry *pce;
	HashTable *ht_or, *ht_cr;
	zval *original_rules, *compiled_rules, **entry, *r;
	zval *url;

	url = zend_read_property(air_router_ce, self, ZEND_STRL("_url"), 0 TSRMLS_CC);
	original_rules = zend_read_property(air_router_ce, self, ZEND_STRL("_original_rules"), 0 TSRMLS_CC);
	compiled_rules = zend_read_property(air_router_ce, self, ZEND_STRL("_compiled_rules"), 0 TSRMLS_CC);
	ht_or = Z_ARRVAL_P(original_rules);
	ht_cr = Z_ARRVAL_P(compiled_rules);
	for(
		/*zend_hash_internal_pointer_reset(ht_or)*/;
		zend_hash_has_more_elements(ht_or) == SUCCESS;
		zend_hash_move_forward(ht_or)
	){
		if (zend_hash_get_current_data(ht_or, (void**)&entry) == FAILURE) {
			continue;
		}
		char *key;
		uint key_len = 0;
		ulong idx = 0;

		smart_str ss = {0};
		char *regex = NULL;
		uint regex_len = 0;
		//lazy compiling
		zend_hash_get_current_key_ex(ht_or, &key, &key_len, &idx, 0, NULL);
		r = air_arr_find(compiled_rules, key, key_len);
		if (r == NULL){
			MAKE_STD_ZVAL(r);
			array_init(r);
			regex = air_router_compile(key, key_len, &regex_len);
			char *ca = Z_STRVAL_PP(entry);
			int size = 0;
			while(size<Z_STRLEN_PP(entry)) {
				if(ca[size] == '.'){
					break;
				}
				size++;
			}
			if(size==0){
				add_assoc_stringl_ex(r, ZEND_STRS(air_c_key), ZEND_STRS("index"), 1);
			}else{
				add_assoc_stringl_ex(r, ZEND_STRS(air_c_key), ca, size, 1);
			}
			if(size+1>=Z_STRLEN_PP(entry)){
				add_assoc_stringl_ex(r, ZEND_STRS(air_a_key), ZEND_STRS("index"), 1);
			}else{
				add_assoc_stringl_ex(r, ZEND_STRS(air_a_key), ca+size+1, Z_STRLEN_PP(entry)-size-1, 1);
			}
			add_assoc_zval_ex(compiled_rules, key, key_len, r);
			smart_str_appendc(&ss, '#');
			smart_str_appendl(&ss, regex, regex_len-1);
			smart_str_appendc(&ss, '#');
			smart_str_0(&ss);
			efree(regex);
			add_assoc_stringl_ex(r, ZEND_STRS("regex"), ss.c, ss.len, 1);
		}else{
			zval *r_r = air_arr_find(r, ZEND_STRS("regex"));
			if (r_r == NULL){
				continue;
			}
			smart_str_appendl(&ss, Z_STRVAL_P(r_r), Z_STRLEN_P(r_r));
			smart_str_0(&ss);
		}
		if(ss.len > 0){
			zval *ret;
			pce = pcre_get_compiled_regex_cache(ss.c, ss.len TSRMLS_CC);
			smart_str_free(&ss);
			if(pce){
				zval matches, *subpats;
				MAKE_STD_ZVAL(subpats);
				ZVAL_NULL(subpats);
				php_pcre_match_impl(pce, Z_STRVAL_P(url), Z_STRLEN_P(url), &matches, subpats/* subpats */, 0/* global */, 0/* ZEND_NUM_ARGS() >= 4 */, 0/*flags PREG_OFFSET_CAPTURE*/, 0/* start_offset */ TSRMLS_CC);
				if (zend_hash_num_elements(Z_ARRVAL_P(subpats)) > 0) {
					ret = air_arr_del_index_el(subpats);
					air_router_route_apply_subpats(r, ret, ZEND_STRS(air_c_key), key, key_len);
					air_router_route_apply_subpats(r, ret, ZEND_STRS(air_a_key), key, key_len);
					ZVAL_ZVAL(return_value, ret, 1, 0);
					zval_ptr_dtor(&ret);
					zval_ptr_dtor(&subpats);
					//move forward specially
					zend_hash_move_forward(ht_or);
					break;
				}
				zval_ptr_dtor(&subpats);
			}
		}
	}
	return return_value;
}
Exemplo n.º 28
0
static inline void append_modified_url(smart_str *url, smart_str *dest, smart_str *url_app, const char *separator)
{
	register const char *p, *q;
	const char *bash = NULL;
	const char *sep = "?";
	
	q = (p = url->c) + url->len;

scan:

{
	YYCTYPE yych;
	static const unsigned char yybm[] = {
		128, 128, 128, 128, 128, 128, 128, 128, 
		128, 128, 128, 128, 128, 128, 128, 128, 
		128, 128, 128, 128, 128, 128, 128, 128, 
		128, 128, 128, 128, 128, 128, 128, 128, 
		128, 128, 128,   0, 128, 128, 128, 128, 
		128, 128, 128, 128, 128, 128, 128, 128, 
		128, 128, 128, 128, 128, 128, 128, 128, 
		128, 128,   0, 128, 128, 128, 128,   0, 
		128, 128, 128, 128, 128, 128, 128, 128, 
		128, 128, 128, 128, 128, 128, 128, 128, 
		128, 128, 128, 128, 128, 128, 128, 128, 
		128, 128, 128, 128, 128, 128, 128, 128, 
		128, 128, 128, 128, 128, 128, 128, 128, 
		128, 128, 128, 128, 128, 128, 128, 128, 
		128, 128, 128, 128, 128, 128, 128, 128, 
		128, 128, 128, 128, 128, 128, 128, 128, 
		128, 128, 128, 128, 128, 128, 128, 128, 
		128, 128, 128, 128, 128, 128, 128, 128, 
		128, 128, 128, 128, 128, 128, 128, 128, 
		128, 128, 128, 128, 128, 128, 128, 128, 
		128, 128, 128, 128, 128, 128, 128, 128, 
		128, 128, 128, 128, 128, 128, 128, 128, 
		128, 128, 128, 128, 128, 128, 128, 128, 
		128, 128, 128, 128, 128, 128, 128, 128, 
		128, 128, 128, 128, 128, 128, 128, 128, 
		128, 128, 128, 128, 128, 128, 128, 128, 
		128, 128, 128, 128, 128, 128, 128, 128, 
		128, 128, 128, 128, 128, 128, 128, 128, 
		128, 128, 128, 128, 128, 128, 128, 128, 
		128, 128, 128, 128, 128, 128, 128, 128, 
		128, 128, 128, 128, 128, 128, 128, 128, 
		128, 128, 128, 128, 128, 128, 128, 128, 
	};

	if (YYLIMIT <= YYCURSOR) YYFILL(1);
	yych = *YYCURSOR;
	if (yybm[0+yych] & 128) {
		goto yy8;
	}
	if (yych <= '9') goto yy6;
	if (yych >= ';') goto yy4;
	++YYCURSOR;
	{ smart_str_append(dest, url); return; }
yy4:
	++YYCURSOR;
	{ sep = separator; goto scan; }
yy6:
	++YYCURSOR;
	{ bash = p - 1; goto done; }
yy8:
	++YYCURSOR;
	if (YYLIMIT <= YYCURSOR) YYFILL(1);
	yych = *YYCURSOR;
	if (yybm[0+yych] & 128) {
		goto yy8;
	}
	{ goto scan; }
}

done:
	
	/* Don't modify URLs of the format "#mark" */
	if (bash && bash - url->c == 0) {
		smart_str_append(dest, url);
		return;
	}

	if (bash)
		smart_str_appendl(dest, url->c, bash - url->c);
	else
		smart_str_append(dest, url);

	smart_str_appends(dest, sep);
	smart_str_append(dest, url_app);

	if (bash)
		smart_str_appendl(dest, bash, q - bash);
}
Exemplo n.º 29
0
PHP_METHOD(air_view, render){
	AIR_INIT_THIS;

	char *tpl_str;
	int tpl_len = 0;
	zend_bool ret_res = 0;
	if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sb", &tpl_str, &tpl_len, &ret_res) == FAILURE)
	{
		RETURN_FALSE;
	}

	smart_str ss_path = {0};
	if(tpl_str[0] != '/'){
		zval *root_path = NULL;
		MAKE_STD_ZVAL(root_path);
		if(zend_get_constant(ZEND_STRL("ROOT_PATH"), root_path) == FAILURE){
			php_error_docref(NULL TSRMLS_CC, E_ERROR,  "ROOT_PATH not defined");
		}
		smart_str_appendl(&ss_path, Z_STRVAL_P(root_path), Z_STRLEN_P(root_path));
		smart_str_appendc(&ss_path, '/');
		if(root_path != NULL){
			zval_ptr_dtor(&root_path);
		}

		zval *tmp = NULL;
		zval **tmp_pp;
		zval *config = zend_read_property(air_view_ce, getThis(), ZEND_STRL("_config"), 0 TSRMLS_CC);
		if(config != NULL && Z_TYPE_P(config) == IS_ARRAY
				&& zend_hash_find(Z_ARRVAL_P(config), ZEND_STRL("path"), (void **)&tmp_pp) == SUCCESS){
			smart_str_appendl(&ss_path, Z_STRVAL_PP(tmp_pp), Z_STRLEN_PP(tmp_pp));
		}else{
			zval *app_conf;
			zval *view_conf;
			if(air_config_get(NULL, ZEND_STRS("app"), &app_conf TSRMLS_CC) == FAILURE){
				AIR_NEW_EXCEPTION(1, "@error config: app");
			}
			zval *app_path = NULL;
			if(air_config_get(app_conf, ZEND_STRS("path"), &app_path) == FAILURE){
				AIR_NEW_EXCEPTION(1, "@error config: app.path");
			}
			zval *view_path = NULL;
			if(air_config_get_path(app_conf, ZEND_STRS("view.path"), &view_path) == FAILURE){
				AIR_NEW_EXCEPTION(1, "@view config not found");
			}
			smart_str_appendl(&ss_path, Z_STRVAL_P(app_path), Z_STRLEN_P(app_path));
			smart_str_appendc(&ss_path, '/');
			smart_str_appendl(&ss_path, Z_STRVAL_P(view_path), Z_STRLEN_P(view_path));
		}
		smart_str_appendc(&ss_path, '/');
	}
	smart_str_appendl(&ss_path, tpl_str, tpl_len);
	smart_str_0(&ss_path);

	//php_printf("full view path: %s\n", ss_path.c);

	//构造运行时所需基本变量
	HashTable *origin_symbol_table = NULL;
	zval *output_handler = NULL;
	long chunk_size = 0;
	long flags = PHP_OUTPUT_HANDLER_STDFLAGS;
	zval *view_ret = NULL;

	//尝试缓存当前符号表
	if(EG(active_symbol_table)){
		origin_symbol_table = EG(active_symbol_table);
	}

	if (ret_res) {
		MAKE_STD_ZVAL(view_ret);
		if(php_output_start_user(output_handler, chunk_size, flags TSRMLS_CC) == FAILURE)
		{
			php_error_docref("ref.outcontrol" TSRMLS_CC, E_NOTICE, "failed to create buffer");
			RETURN_FALSE;
		}
	}
	ALLOC_HASHTABLE(EG(active_symbol_table));
	zval *data = zend_read_property(air_view_ce, getThis(), ZEND_STRL("_data"), 0 TSRMLS_CC);
	zend_hash_init(EG(active_symbol_table), 0, NULL, ZVAL_PTR_DTOR, 0);
	//将当前的模板变量放到符号表去
	ZEND_SET_SYMBOL_WITH_LENGTH(EG(active_symbol_table), "var", 4, data, Z_REFCOUNT_P(data) + 1, PZVAL_IS_REF(data));
	if(air_loader_include_file(ss_path.c TSRMLS_CC) == FAILURE){
		air_throw_exception_ex(1, "tpl %s render failed!\n", ss_path.c);
		return ;
	}

	if(ret_res){
		php_output_get_contents(view_ret TSRMLS_CC);
		php_output_discard(TSRMLS_C);
		RETVAL_ZVAL(view_ret, 1, 0);
		zval_ptr_dtor(&view_ret);
	}

	zend_hash_destroy(EG(active_symbol_table));
	FREE_HASHTABLE(EG(active_symbol_table));
	EG(active_symbol_table) = origin_symbol_table;

	smart_str_free(&ss_path);
}
Exemplo n.º 30
0
static inline void passthru(STD_PARA) 
{
	scdebug(("appending %d chars, starting with %c\n", YYCURSOR-start, *start));
	smart_str_appendl(&ctx->result, start, YYCURSOR - start);
}