string_list_join_concat_special - specialized version without bounds

check
This commit is contained in:
libretroadmin 2024-12-24 06:14:26 +01:00
parent 67b0147a59
commit 279270ae5f
3 changed files with 68 additions and 24 deletions

View File

@ -104,7 +104,7 @@ bool string_split_noalloc(struct string_list *list,
**/
struct string_list *string_separate(char *str, const char *delim);
bool string_separate_noalloc(struct string_list *list,
bool string_separate_noalloc(struct string_list *list,
char *str, const char *delim);
bool string_list_deinitialize(struct string_list *list);
@ -166,23 +166,39 @@ void string_list_free(struct string_list *list);
/**
* string_list_join_concat:
* @buffer : buffer that @list will be joined to.
* @size : length of @buffer.
* @s : buffer that @list will be joined to.
* @len : length of @s.
* @list : pointer to string list.
* @delim : delimiter character for @list.
*
* A string list will be joined/concatenated as a
* string to @buffer, delimited by @delim.
* string to @s, delimited by @delim.
*
* NOTE: @buffer must be NULL-terminated.
* NOTE: @s must be NULL-terminated.
*
* Hidden non-leaf function cost:
* - Calls strlen_size()
* - Calls strlcat x times in a loop
**/
void string_list_join_concat(char *buffer, size_t size,
void string_list_join_concat(char *s, size_t len,
const struct string_list *list, const char *sep);
/**
* string_list_join_concat:
* @s : buffer that @list will be joined to.
* @len : length of @s.
* @list : pointer to string list.
* @delim : delimiter character for @list.
*
* Specialized version of string_list_join_concat
* without the bounds check.
*
* A string list will be joined/concatenated as a
* string to @s, delimited by @delim.
**/
void string_list_join_concat_special(char *s, size_t len,
const struct string_list *list, const char *delim);
/**
* string_list_set:
* @list : pointer to string list

View File

@ -241,38 +241,66 @@ void string_list_set(struct string_list *list,
/**
* string_list_join_concat:
* @buffer : buffer that @list will be joined to.
* @size : length of @buffer.
* @s : buffer that @list will be joined to.
* @len : length of @s.
* @list : pointer to string list.
* @delim : delimiter character for @list.
*
* A string list will be joined/concatenated as a
* string to @buffer, delimited by @delim.
**/
void string_list_join_concat(char *buffer, size_t size,
void string_list_join_concat(char *s, size_t len,
const struct string_list *list, const char *delim)
{
size_t i;
size_t len = strlen_size(buffer, size);
size_t _len = strlen_size(s, len);
/* If buffer is already 'full', nothing
/* If @s is already 'full', nothing
* further can be added
* > This condition will also be triggered
* if buffer is not NULL-terminated,
* if @s is not NULL-terminated,
* in which case any attempt to increment
* buffer or decrement size would lead to
* @s or decrement @len would lead to
* undefined behaviour */
if (len >= size)
if (_len >= len)
return;
buffer += len;
size -= len;
s += _len;
len -= _len;
for (i = 0; i < list->size; i++)
{
size_t _len = strlcat(buffer, list->elems[i].data, size);
size_t __len = strlcat(s, list->elems[i].data, len);
if ((i + 1) < list->size)
strlcpy(buffer + _len, delim, size - _len);
strlcpy(s + __len, delim, len - __len);
}
}
/**
* string_list_join_concat:
* @s : buffer that @list will be joined to.
* @len : length of @s.
* @list : pointer to string list.
* @delim : delimiter character for @list.
*
* Specialized version of string_list_join_concat
* without the bounds check.
*
* A string list will be joined/concatenated as a
* string to @s, delimited by @delim.
*
* TODO/FIXME - eliminate the strlcat
**/
void string_list_join_concat_special(char *s, size_t len,
const struct string_list *list, const char *delim)
{
size_t i;
for (i = 0; i < list->size; i++)
{
size_t __len = strlcat(s, list->elems[i].data, len);
if ((i + 1) < list->size)
strlcpy(s + __len, delim, len - __len);
}
}

View File

@ -634,7 +634,7 @@ static int menu_displaylist_parse_core_info(
tmp[ _len] = ':';
tmp[++_len] = ' ';
tmp[++_len] = '\0';
string_list_join_concat(tmp, sizeof(tmp),
string_list_join_concat_special(tmp + _len, sizeof(tmp) - _len,
core_info->categories_list, ", ");
if (menu_entries_append(list, tmp, "",
MENU_ENUM_LABEL_CORE_INFO_ENTRY, MENU_SETTINGS_CORE_INFO_NONE, 0, 0, NULL))
@ -649,7 +649,7 @@ static int menu_displaylist_parse_core_info(
tmp[ _len] = ':';
tmp[++_len] = ' ';
tmp[++_len] = '\0';
string_list_join_concat(tmp, sizeof(tmp),
string_list_join_concat_special(tmp + _len, sizeof(tmp) - _len,
core_info->authors_list, ", ");
if (menu_entries_append(list, tmp, "",
MENU_ENUM_LABEL_CORE_INFO_ENTRY, MENU_SETTINGS_CORE_INFO_NONE, 0, 0, NULL))
@ -664,7 +664,7 @@ static int menu_displaylist_parse_core_info(
tmp[ _len] = ':';
tmp[++_len] = ' ';
tmp[++_len] = '\0';
string_list_join_concat(tmp, sizeof(tmp),
string_list_join_concat_special(tmp + _len, sizeof(tmp) - _len,
core_info->permissions_list, ", ");
if (menu_entries_append(list, tmp, "",
MENU_ENUM_LABEL_CORE_INFO_ENTRY, MENU_SETTINGS_CORE_INFO_NONE, 0, 0, NULL))
@ -679,7 +679,7 @@ static int menu_displaylist_parse_core_info(
tmp[ _len] = ':';
tmp[++_len] = ' ';
tmp[++_len] = '\0';
string_list_join_concat(tmp, sizeof(tmp),
string_list_join_concat_special(tmp + _len, sizeof(tmp) - _len,
core_info->licenses_list, ", ");
if (menu_entries_append(list, tmp, "",
MENU_ENUM_LABEL_CORE_INFO_ENTRY, MENU_SETTINGS_CORE_INFO_NONE, 0, 0, NULL))
@ -695,7 +695,7 @@ static int menu_displaylist_parse_core_info(
tmp[ _len] = ':';
tmp[++_len] = ' ';
tmp[++_len] = '\0';
string_list_join_concat(tmp, sizeof(tmp),
string_list_join_concat_special(tmp + _len, sizeof(tmp) - _len,
core_info->supported_extensions_list, ", ");
if (menu_entries_append(list, tmp, "",
MENU_ENUM_LABEL_CORE_INFO_ENTRY, MENU_SETTINGS_CORE_INFO_NONE, 0, 0, NULL))
@ -710,7 +710,7 @@ static int menu_displaylist_parse_core_info(
tmp[ _len] = ':';
tmp[++_len] = ' ';
tmp[++_len] = '\0';
string_list_join_concat(tmp, sizeof(tmp),
string_list_join_concat_special(tmp + _len, sizeof(tmp) - _len,
core_info->required_hw_api_list, ", ");
if (menu_entries_append(list, tmp, "",
MENU_ENUM_LABEL_CORE_INFO_ENTRY, MENU_SETTINGS_CORE_INFO_NONE, 0, 0, NULL))