[PATCH v5 01/17] lib/charset: add u16_strlcat() function

Heinrich Schuchardt xypron.glpk at gmx.de
Fri Apr 29 21:36:24 CEST 2022


On 4/28/22 10:09, Masahisa Kojima wrote:
> Provide u16 string version of strlcat().
>
> Signed-off-by: Masahisa Kojima <masahisa.kojima at linaro.org>
> ---
> Changes in v5:
> - change 3rd argument from size to count, it indicates
>    the maximum u16 string count that dest buffer can have.
>    Other u16_strXXX functions in U-Boot use string count, not the
>    buffer size. u16_strlcat() should follow.
> - update function comment to clealy describe the behavior
> - use strlen() instead of strnlen(), to correctly handle
>    the case if the count is smaller than or equal to initial dest count
>
> Changes in v4:
> - add blank line above the return statement
>
> Changes in v2:
> - implement u16_strlcat(with the destination buffer size in argument)
>    instead of u16_strcat
>   include/charset.h | 17 +++++++++++++++++
>   lib/charset.c     | 22 ++++++++++++++++++++++
>   2 files changed, 39 insertions(+)
>
> diff --git a/include/charset.h b/include/charset.h
> index 38908e08f0..ae356ad9a5 100644
> --- a/include/charset.h
> +++ b/include/charset.h
> @@ -261,6 +261,23 @@ u16 *u16_strcpy(u16 *dest, const u16 *src);
>    */
>   u16 *u16_strdup(const void *src);
>
> +/**
> + * u16_strlcat() - Append a length-limited, %NUL-terminated string to another
> + *
> + * Append the src string to the dest string, overwriting the terminating
> + * null word at the end of dest, and then adds a terminating null word.
> + *
> + * @dest:		destination buffer (must include the trailing 0x0000)
> + * @src:		source buffer (must include the trailing 0x0000)
> + * @count:		maximum number of code points that dest buffer can have,
> + *			including the trailing 0x0000
> + * Return:		total count of the created u16 string
> + *			u16_strlen(src) + min(count, u16_strlen(initial dest)),
> + *			does not include trailing 0x0000.
> + *			If return value >= count, truncation occurred.
> + */
> +size_t u16_strlcat(u16 *dest, const u16 *src, size_t size);
> +
>   /**
>    * utf16_to_utf8() - Convert an utf16 string to utf8
>    *
> diff --git a/lib/charset.c b/lib/charset.c
> index de201cf3b9..f295dfc11a 100644
> --- a/lib/charset.c
> +++ b/lib/charset.c
> @@ -416,6 +416,28 @@ u16 *u16_strdup(const void *src)
>   	return new;
>   }
>
> +size_t u16_strlcat(u16 *dest, const u16 *src, size_t count)
> +{
> +	size_t destlen, srclen, ret;
> +
> +	destlen = u16_strlen(dest);
> +	srclen = u16_strlen(src);
> +	ret = min(count, destlen) + srclen; /* does not include trailing 0x0000 */

Why should count influence the return value?

Using a first call with count = 0 and src = NULL to retrieve the buffer
size to realloc() and a second call after re-allocation would be a
typical usage scenario.

Best regards

Heinrich

> +
> +	if (destlen >= count)
> +		return ret;
> +
> +	dest += destlen;
> +	count -= destlen;
> +	if (srclen >= count)
> +		srclen = count - 1 /* for trailing 0x0000 */;
> +
> +	memcpy(dest, src, srclen * sizeof(u16));
> +	dest[srclen] = u'\0';
> +
> +	return ret;
> +}
> +
>   /* Convert UTF-16 to UTF-8.  */
>   uint8_t *utf16_to_utf8(uint8_t *dest, const uint16_t *src, size_t size)
>   {



More information about the U-Boot mailing list