[OpenWrt-Devel] [PATCH 1/3] [rpcd][v2] file: add support for base64

Felix Fietkau nbd at openwrt.org
Mon May 11 05:36:46 EDT 2015


On 2015-05-11 00:26, Luka Perkov wrote:
> Signed-off-by: Luka Perkov <luka at openwrt.org>
> ---
> => changes in v2:
> 
> Use new libubox base64 provided API.
> 
>  file.c | 118 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++------
>  1 file changed, 107 insertions(+), 11 deletions(-)
> 
> diff --git a/file.c b/file.c
> index 9c1b301..c3671bb 100644
> --- a/file.c
> +++ b/file.c
> @@ -182,7 +206,17 @@ rpc_file_read(struct ubus_context *ctx, struct ubus_object *obj,
>  
>  	blob_buf_init(&buf, 0);
>  
> -	wbuf = blobmsg_alloc_string_buffer(&buf, "data", s.st_size + 1);
> +	if (tb[RPC_F_RB_BASE64])
> +		base64 = blobmsg_get_bool(tb[RPC_F_RB_BASE64]);
> +
> +	if (base64)
> +	{
> +		wbuf = blobmsg_alloc_string_buffer(&buf, "data", B64_ENCODE_LEN(s.st_size));
> +	}
> +	else
> +	{
> +		wbuf = blobmsg_alloc_string_buffer(&buf, "data", s.st_size + 1);
> +	}
How about using the 'len' variable to avoid duplicating most of the code
here. You can also get rid of unnecessary {} lines.

> @@ -196,14 +230,35 @@ rpc_file_read(struct ubus_context *ctx, struct ubus_object *obj,
>  		goto out;
>  	}
>  
> +	if (base64)
> +	{
> +		uint8_t *data = calloc(B64_ENCODE_LEN(len), sizeof(uint8_t));
> +		if (!data)
> +		{
> +			rv = UBUS_STATUS_UNKNOWN_ERROR;
> +			goto out;
> +		}
You can reduce allocation/copy size if you copy wbuf to a temporary
buffer and then use it as output for b64_encode.

> +		len = b64_encode(wbuf, len, data, B64_ENCODE_LEN(len));
> +		if (len < 0)
> +		{
> +			free(data);
> +			rv = UBUS_STATUS_UNKNOWN_ERROR;
> +			goto out;
> +		}
> +
> +		memcpy(wbuf, data, len);
> +		free(data);
> +	}
> +
>  	*(wbuf + len) = 0;
>  	blobmsg_add_string_buffer(&buf);
>  
>  	ubus_send_reply(ctx, req, buf.head);
> -	blob_buf_free(&buf);
>  	rv = UBUS_STATUS_OK;
>  
>  out:
> +	blob_buf_free(&buf);
>  	close(fd);
>  	return rv;
>  }
> @@ -222,18 +282,54 @@ rpc_file_write(struct ubus_context *ctx, struct ubus_object *obj,
>  	if (!tb[RPC_F_RW_PATH] || !tb[RPC_F_RW_DATA])
>  		return UBUS_STATUS_INVALID_ARGUMENT;
>  
> +	data = blobmsg_data(tb[RPC_F_RW_DATA]);
> +	data_len = blobmsg_data_len(tb[RPC_F_RW_DATA]) - 1;
> +
>  	if ((fd = open(blobmsg_data(tb[RPC_F_RW_PATH]), O_CREAT | O_TRUNC | O_WRONLY, 0666)) < 0)
>  		return rpc_errno_status();
>  
> -	if (write(fd, blobmsg_data(tb[RPC_F_RW_DATA]), blobmsg_data_len(tb[RPC_F_RW_DATA])) < 0)
> -		return rpc_errno_status();
> +	if (tb[RPC_F_RW_BASE64])
> +		base64 = blobmsg_get_bool(tb[RPC_F_RW_BASE64]);
> +
> +	if (base64)
> +	{
> +		rbuf_len = B64_DECODE_LEN(data_len);
> +		rbuf = calloc(rbuf_len, sizeof(uint8_t));
> +		if (!rbuf)
> +		{
> +			rv = UBUS_STATUS_UNKNOWN_ERROR;
> +			goto out;
> +		}
> +
> +		rbuf_len = b64_decode(data, rbuf, rbuf_len);
> +		if (rbuf_len < 0)
> +		{
> +			rv = UBUS_STATUS_UNKNOWN_ERROR;
> +			goto out;
> +		}
> +	}
> +	else
> +	{
> +		rbuf = data;
> +		rbuf_len = data_len;
> +	}
It is safe to overwrite the data area in this function, as long as you
don't overstep attribute bounds. This means you can reuse the input
buffer as output buffer for b64_decode and get rid of the temporary
allocation.

- Felix
_______________________________________________
openwrt-devel mailing list
openwrt-devel at lists.openwrt.org
https://lists.openwrt.org/cgi-bin/mailman/listinfo/openwrt-devel



More information about the openwrt-devel mailing list