Esempio n. 1
0
static void to_zval_read_aggregation(const char *structure,
									 zval *zarr, /* initialized array */
									 const field_descriptor *descriptors,
									 res_context *ctx)
{
	const field_descriptor	*descr;

	assert(Z_TYPE_P(zarr) == IS_ARRAY);
	assert(Z_ARRVAL_P(zarr) != NULL);

	for (descr = descriptors; descr->name != NULL && !ctx->err.has_error; descr++) {
		zval *new_zv, tmp;

		if (descr->to_zval == NULL) {
			do_to_zval_err(ctx, "No information on how to convert native "
					"field into value for key '%s'", descr->name);
			break;
		}

		ZVAL_NULL(&tmp);
		new_zv = zend_symtable_str_update(Z_ARRVAL_P(zarr), descr->name, descr->name_size - 1, &tmp);

		zend_llist_add_element(&ctx->keys, (void*)&descr->name);
		descr->to_zval(structure + descr->field_offset, new_zv, ctx);
		zend_llist_remove_tail(&ctx->keys);
	}
}
Esempio n. 2
0
/* Generic Aggregated conversions */
static void from_zval_write_aggregation(const zval *container,
										char *structure,
										const field_descriptor *descriptors,
										ser_context *ctx)
{
	const field_descriptor	*descr;
	zval					*elem;

	if (Z_TYPE_P(container) != IS_ARRAY) {
		do_from_zval_err(ctx, "%s", "expected an array here");
	}

	for (descr = descriptors; descr->name != NULL && !ctx->err.has_error; descr++) {
		if ((elem = zend_hash_str_find(Z_ARRVAL_P(container),
				descr->name, descr->name_size - 1)) != NULL) {

			if (descr->from_zval == NULL) {
				do_from_zval_err(ctx, "No information on how to convert value "
						"of key '%s'", descr->name);
				break;
			}

			zend_llist_add_element(&ctx->keys, (void*)&descr->name);
			descr->from_zval(elem, ((char*)structure) + descr->field_offset, ctx);
			zend_llist_remove_tail(&ctx->keys);

		} else if (descr->required) {
			do_from_zval_err(ctx, "The key '%s' is required", descr->name);
			break;
		}
	}
}
Esempio n. 3
0
static unsigned from_array_iterate(const zval *arr,
								   void (*func)(zval *elem, unsigned i, void **args, ser_context *ctx),
								   void **args,
								   ser_context *ctx)
{
	HashPosition	pos;
	unsigned		i;
	zval			*elem;
	char			buf[sizeof("element #4294967295")];
	char			*bufp = buf;

	/* Note i starts at 1, not 0! */
    for (zend_hash_internal_pointer_reset_ex(Z_ARRVAL_P(arr), &pos), i = 1;
			!ctx->err.has_error
			&& (elem = zend_hash_get_current_data_ex(Z_ARRVAL_P(arr), &pos)) != NULL;
			zend_hash_move_forward_ex(Z_ARRVAL_P(arr), &pos), i++) {
		if (snprintf(buf, sizeof(buf), "element #%u", i) >= sizeof(buf)) {
			memcpy(buf, "element", sizeof("element"));
		}
		zend_llist_add_element(&ctx->keys, &bufp);

		func(elem, i, args, ctx);

		zend_llist_remove_tail(&ctx->keys);
    }

    return i -1;
}
Esempio n. 4
0
static unsigned from_array_iterate(const zval *arr,
								   void (*func)(zval *elem, unsigned i, void **args, ser_context *ctx),
								   void **args,
								   ser_context *ctx)
{
	unsigned		i;
	zval			*elem;
	char			buf[sizeof("element #4294967295")];
	char			*bufp = buf;

	/* Note i starts at 1, not 0! */
	i = 1;
	ZEND_HASH_FOREACH_VAL(Z_ARRVAL_P(arr), elem) {
		if ((size_t)snprintf(buf, sizeof(buf), "element #%u", i) >= sizeof(buf)) {
			memcpy(buf, "element", sizeof("element"));
		}
		zend_llist_add_element(&ctx->keys, &bufp);

		func(elem, i, args, ctx);

		zend_llist_remove_tail(&ctx->keys);
		if (ctx->err.has_error) {
			break;
		}
		i++;
    } ZEND_HASH_FOREACH_END();

    return i -1;
}
Esempio n. 5
0
/* parse headers */
static int multipart_buffer_headers(multipart_buffer *self, zend_llist *header)
{
	char *line;
	mime_header_entry prev_entry = {0}, entry;
	int prev_len, cur_len;

	/* didn't find boundary, abort */
	if (!find_boundary(self, self->boundary)) {
		return 0;
	}

	/* get lines of text, or CRLF_CRLF */

	while( (line = get_line(self)) && line[0] != '\0' )
	{
		/* add header to table */
		char *key = line;
		char *value = NULL;

		if (php_rfc1867_encoding_translation()) {
			self->input_encoding = zend_multibyte_encoding_detector(line, strlen(line), self->detect_order, self->detect_order_size);
		}

		/* space in the beginning means same header */
		if (!isspace(line[0])) {
			value = strchr(line, ':');
		}

		if (value) {
			*value = 0;
			do { value++; } while(isspace(*value));

			entry.value = estrdup(value);
			entry.key = estrdup(key);

		} else if (zend_llist_count(header)) { /* If no ':' on the line, add to previous line */

			prev_len = (int)strlen(prev_entry.value);
			cur_len = (int)strlen(line);

			entry.value = emalloc(prev_len + cur_len + 1);
			memcpy(entry.value, prev_entry.value, prev_len);
			memcpy(entry.value + prev_len, line, cur_len);
			entry.value[cur_len + prev_len] = '\0';

			entry.key = estrdup(prev_entry.key);

			zend_llist_remove_tail(header);
		} else {
			continue;
		}

		zend_llist_add_element(header, &entry);
		prev_entry = entry;
	}

	return 1;
}
Esempio n. 6
0
static void from_zval_write_sockaddr_aux(const zval *container,
										 struct sockaddr **sockaddr_ptr,
										 socklen_t *sockaddr_len,
										 ser_context *ctx)
{
	int		family;
	zval	*elem;
	int		fill_sockaddr;

	if (Z_TYPE_P(container) != IS_ARRAY) {
		do_from_zval_err(ctx, "%s", "expected an array here");
		return;
	}

	fill_sockaddr = param_get_bool(ctx, KEY_FILL_SOCKADDR, 1);

	if ((elem = zend_hash_str_find(Z_ARRVAL_P(container), "family", sizeof("family") - 1)) != NULL
			&& Z_TYPE_P(elem) != IS_NULL) {
		const char *node = "family";
		zend_llist_add_element(&ctx->keys, &node);
		from_zval_write_int(elem, (char*)&family, ctx);
		zend_llist_remove_tail(&ctx->keys);
	} else {
		family = ctx->sock->type;
	}

	switch (family) {
	case AF_INET:
		/* though not all OSes support sockaddr_in used in IPv6 sockets */
		if (ctx->sock->type != AF_INET && ctx->sock->type != AF_INET6) {
			do_from_zval_err(ctx, "the specified family (number %d) is not "
					"supported on this socket", family);
			return;
		}
		*sockaddr_ptr = accounted_ecalloc(1, sizeof(struct sockaddr_in), ctx);
		*sockaddr_len = sizeof(struct sockaddr_in);
		if (fill_sockaddr) {
			from_zval_write_sockaddr_in(container, (char*)*sockaddr_ptr, ctx);
			(*sockaddr_ptr)->sa_family = AF_INET;
		}
		break;

#if HAVE_IPV6
	case AF_INET6:
		if (ctx->sock->type != AF_INET6) {
			do_from_zval_err(ctx, "the specified family (AF_INET6) is not "
					"supported on this socket");
			return;
		}
		*sockaddr_ptr = accounted_ecalloc(1, sizeof(struct sockaddr_in6), ctx);
		*sockaddr_len = sizeof(struct sockaddr_in6);
		if (fill_sockaddr) {
			from_zval_write_sockaddr_in6(container, (char*)*sockaddr_ptr, ctx);
			(*sockaddr_ptr)->sa_family = AF_INET6;
		}
		break;
#endif /* HAVE_IPV6 */

	case AF_UNIX:
		if (ctx->sock->type != AF_UNIX) {
			do_from_zval_err(ctx, "the specified family (AF_UNIX) is not "
					"supported on this socket");
			return;
		}
		*sockaddr_ptr = accounted_ecalloc(1, sizeof(struct sockaddr_un), ctx);
		if (fill_sockaddr) {
			struct sockaddr_un *sock_un = (struct sockaddr_un*)*sockaddr_ptr;

			from_zval_write_sockaddr_un(container, (char*)*sockaddr_ptr, ctx);
			(*sockaddr_ptr)->sa_family = AF_UNIX;

			/* calculating length is more complicated here. Giving the size of
			 * struct sockaddr_un here and relying on the nul termination of
			 * sun_path does not work for paths in the abstract namespace. Note
			 * that we always assume the path is not empty and nul terminated */
			*sockaddr_len = offsetof(struct sockaddr_un, sun_path) +
					(sock_un->sun_path[0] == '\0'
					? (1 + strlen(&sock_un->sun_path[1]))
					: strlen(sock_un->sun_path));
		} else {
			*sockaddr_len = sizeof(struct sockaddr_un);
		}
		break;

	default:
		do_from_zval_err(ctx, "%s", "the only families currently supported are "
				"AF_INET, AF_INET6 and AF_UNIX");
		break;
	}