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); 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); char *str, const char *delim);
bool string_list_deinitialize(struct string_list *list); bool string_list_deinitialize(struct string_list *list);
@ -166,23 +166,39 @@ void string_list_free(struct string_list *list);
/** /**
* string_list_join_concat: * string_list_join_concat:
* @buffer : buffer that @list will be joined to. * @s : buffer that @list will be joined to.
* @size : length of @buffer. * @len : length of @s.
* @list : pointer to string list. * @list : pointer to string list.
* @delim : delimiter character for @list. * @delim : delimiter character for @list.
* *
* A string list will be joined/concatenated as a * 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: * Hidden non-leaf function cost:
* - Calls strlen_size() * - Calls strlen_size()
* - Calls strlcat x times in a loop * - 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); 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: * string_list_set:
* @list : pointer to string list * @list : pointer to string list

View File

@ -241,38 +241,66 @@ void string_list_set(struct string_list *list,
/** /**
* string_list_join_concat: * string_list_join_concat:
* @buffer : buffer that @list will be joined to. * @s : buffer that @list will be joined to.
* @size : length of @buffer. * @len : length of @s.
* @list : pointer to string list. * @list : pointer to string list.
* @delim : delimiter character for @list. * @delim : delimiter character for @list.
* *
* A string list will be joined/concatenated as a * A string list will be joined/concatenated as a
* string to @buffer, delimited by @delim. * 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) const struct string_list *list, const char *delim)
{ {
size_t i; 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 * further can be added
* > This condition will also be triggered * > 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 * in which case any attempt to increment
* buffer or decrement size would lead to * @s or decrement @len would lead to
* undefined behaviour */ * undefined behaviour */
if (len >= size) if (_len >= len)
return; return;
buffer += len; s += _len;
size -= len; len -= _len;
for (i = 0; i < list->size; i++) 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) 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] = ' '; tmp[++_len] = ' ';
tmp[++_len] = '\0'; tmp[++_len] = '\0';
string_list_join_concat(tmp, sizeof(tmp), string_list_join_concat_special(tmp + _len, sizeof(tmp) - _len,
core_info->categories_list, ", "); core_info->categories_list, ", ");
if (menu_entries_append(list, tmp, "", if (menu_entries_append(list, tmp, "",
MENU_ENUM_LABEL_CORE_INFO_ENTRY, MENU_SETTINGS_CORE_INFO_NONE, 0, 0, NULL)) 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] = ' '; tmp[++_len] = ' ';
tmp[++_len] = '\0'; tmp[++_len] = '\0';
string_list_join_concat(tmp, sizeof(tmp), string_list_join_concat_special(tmp + _len, sizeof(tmp) - _len,
core_info->authors_list, ", "); core_info->authors_list, ", ");
if (menu_entries_append(list, tmp, "", if (menu_entries_append(list, tmp, "",
MENU_ENUM_LABEL_CORE_INFO_ENTRY, MENU_SETTINGS_CORE_INFO_NONE, 0, 0, NULL)) 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] = ' '; tmp[++_len] = ' ';
tmp[++_len] = '\0'; tmp[++_len] = '\0';
string_list_join_concat(tmp, sizeof(tmp), string_list_join_concat_special(tmp + _len, sizeof(tmp) - _len,
core_info->permissions_list, ", "); core_info->permissions_list, ", ");
if (menu_entries_append(list, tmp, "", if (menu_entries_append(list, tmp, "",
MENU_ENUM_LABEL_CORE_INFO_ENTRY, MENU_SETTINGS_CORE_INFO_NONE, 0, 0, NULL)) 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] = ' '; tmp[++_len] = ' ';
tmp[++_len] = '\0'; tmp[++_len] = '\0';
string_list_join_concat(tmp, sizeof(tmp), string_list_join_concat_special(tmp + _len, sizeof(tmp) - _len,
core_info->licenses_list, ", "); core_info->licenses_list, ", ");
if (menu_entries_append(list, tmp, "", if (menu_entries_append(list, tmp, "",
MENU_ENUM_LABEL_CORE_INFO_ENTRY, MENU_SETTINGS_CORE_INFO_NONE, 0, 0, NULL)) 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] = ' '; tmp[++_len] = ' ';
tmp[++_len] = '\0'; 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, ", "); core_info->supported_extensions_list, ", ");
if (menu_entries_append(list, tmp, "", if (menu_entries_append(list, tmp, "",
MENU_ENUM_LABEL_CORE_INFO_ENTRY, MENU_SETTINGS_CORE_INFO_NONE, 0, 0, NULL)) 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] = ' '; tmp[++_len] = ' ';
tmp[++_len] = '\0'; 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, ", "); core_info->required_hw_api_list, ", ");
if (menu_entries_append(list, tmp, "", if (menu_entries_append(list, tmp, "",
MENU_ENUM_LABEL_CORE_INFO_ENTRY, MENU_SETTINGS_CORE_INFO_NONE, 0, 0, NULL)) MENU_ENUM_LABEL_CORE_INFO_ENTRY, MENU_SETTINGS_CORE_INFO_NONE, 0, 0, NULL))