Re: [BlueZ, v2 1/3] avrcp: Split off name parsing from parse_*_element()

Luiz Augusto von Dentz <[email protected]>
Newsgroups org.kernel.vger.linux-bluetooth
Message-ID <CABBYNZKb7_6CBD_Aq27PHUqA5=_P_NeyY4qcKOjCNk-dRN6-cw@mail.gmail.com>
Hi Bastien,

On Tue, Aug 4, 2026 at 10:31 AM Bastien Nocera <[email protected]> wrote:
>
> This will allow us to use the name extraction code in
> parse_media_element() and parse_folder_element() separately, such
> as in tests.
> ---
>  Makefile.plugins             |  1 +
>  profiles/audio/avrcp-parse.c | 47 ++++++++++++++++++++++++++++++++++++
>  profiles/audio/avrcp-parse.h | 19 +++++++++++++++
>  profiles/audio/avrcp.c       | 26 +++++---------------
>  4 files changed, 73 insertions(+), 20 deletions(-)
>  create mode 100644 profiles/audio/avrcp-parse.c
>  create mode 100644 profiles/audio/avrcp-parse.h
>
> diff --git a/Makefile.plugins b/Makefile.plugins
> index ac667beda847..a505fcd6691f 100644
> --- a/Makefile.plugins
> +++ b/Makefile.plugins
> @@ -37,6 +37,7 @@ builtin_modules += avrcp
>  builtin_sources += profiles/audio/control.h profiles/audio/control.c \
>                         profiles/audio/avctp.h profiles/audio/avctp.c \
>                         profiles/audio/avrcp.h profiles/audio/avrcp.c \
> +                       profiles/audio/avrcp-parse.h profiles/audio/avrcp-parse.c \
>                         profiles/audio/avrcp-player.c
>  endif
>
> diff --git a/profiles/audio/avrcp-parse.c b/profiles/audio/avrcp-parse.c
> new file mode 100644
> index 000000000000..d3d0a070a4da
> --- /dev/null
> +++ b/profiles/audio/avrcp-parse.c
> @@ -0,0 +1,47 @@
> +// SPDX-License-Identifier: GPL-2.0-or-later
> +/*
> + *
> + *  BlueZ - Bluetooth protocol stack for Linux
> + *
> + *  Copyright (C) 2026  Red Hat Inc.
> + *
> + *
> + */
> +
> +#include "avrcp-parse.h"
> +#include "src/shared/util.h"
> +
> +gboolean parse_media_element_name(uint8_t *operands, uint16_t len,
> +                                        char *name, uint16_t *namesize)
> +{
> +       uint16_t namelen;
> +
> +       if (len < 13)
> +               return FALSE;
> +
> +       memset(name, 0, NAME_MAX_LEN);
> +       *namesize = get_be16(&operands[11]);
> +       namelen = MIN(*namesize, NAME_MAX_LEN - 1);
> +       if (namelen > 0) {
> +               memcpy(name, &operands[13], namelen);
> +               strtoutf8(name, namelen);
> +       }
> +
> +       return TRUE;
> +}
> +
> +gboolean parse_media_folder_name(uint8_t *operands, uint16_t len,
> +                                       char *name)
> +{
> +       uint16_t namelen;
> +
> +       if (len < 12)
> +               return FALSE;
> +
> +       memset(name, 0, NAME_MAX_LEN);
> +       namelen = MIN(get_be16(&operands[12]), NAME_MAX_LEN - 1);
> +       if (namelen > 0)
> +               memcpy(name, &operands[14], namelen);
> +
> +       return TRUE;
> +}

Rather than creating yet another file how about hosting this under
shared/util.h directly? It already depends on it anyway, we could got
with something like strntoutf8 or a similar function that checks the
length, etc, actually be maybe better to do it under
util_iov_pull_utf8(iov, len, str, str_max_len) so we can load the pdu
into the iov then use iov_pull_mem, etc, to verify that we have enough
bytes in a generic manner.

> diff --git a/profiles/audio/avrcp-parse.h b/profiles/audio/avrcp-parse.h
> new file mode 100644
> index 000000000000..f7a33c854442
> --- /dev/null
> +++ b/profiles/audio/avrcp-parse.h
> @@ -0,0 +1,19 @@
> +// SPDX-License-Identifier: GPL-2.0-or-later
> +/*
> + *
> + *  BlueZ - Bluetooth protocol stack for Linux
> + *
> + *  Copyright (C) 2026  Red Hat Inc.
> + *
> + *
> + */
> +
> +#include <glib.h>
> +#include <inttypes.h>
> +
> +#define NAME_MAX_LEN 255
> +
> +gboolean parse_media_element_name(uint8_t *operands, uint16_t len,
> +                                        char *name, uint16_t *namesize);
> +gboolean parse_media_folder_name(uint8_t *operands, uint16_t len,
> +                                       char *name);
> diff --git a/profiles/audio/avrcp.c b/profiles/audio/avrcp.c
> index 2194a913580f..af3c72174764 100644
> --- a/profiles/audio/avrcp.c
> +++ b/profiles/audio/avrcp.c
> @@ -52,6 +52,7 @@
>
>  #include "avctp.h"
>  #include "avrcp.h"
> +#include "avrcp-parse.h"
>  #include "control.h"
>  #include "media.h"
>  #include "player.h"
> @@ -2614,24 +2615,15 @@ static struct media_item *parse_media_element(struct avrcp *session,
>         struct avrcp_player *player;
>         struct media_player *mp;
>         struct media_item *item;
> -       uint16_t namelen, namesize;
> -       char name[255];
> +       uint16_t namesize;
> +       char name[NAME_MAX_LEN];
>         uint64_t uid;
>         uint8_t count;
>
> -       if (len < 13)
> +       if (!parse_media_element_name(operands, len, name, &namesize))
>                 return NULL;
>
>         uid = get_be64(&operands[0]);
> -
> -       memset(name, 0, sizeof(name));
> -       namesize = get_be16(&operands[11]);
> -       namelen = MIN(namesize, sizeof(name) - 1);
> -       if (namelen > 0) {
> -               memcpy(name, &operands[13], namelen);
> -               strtoutf8(name, namelen);
> -       }
> -
>         count = operands[13 + namesize];
>
>         player = session->controller->player;
> @@ -2655,24 +2647,18 @@ static struct media_item *parse_media_folder(struct avrcp *session,
>         struct avrcp_player *player = session->controller->player;
>         struct media_player *mp = player->user_data;
>         struct media_item *item;
> -       uint16_t namelen;
> -       char name[255];
> +       char name[NAME_MAX_LEN];
>         uint64_t uid;
>         uint8_t type;
>         uint8_t playable;
>
> -       if (len < 12)
> +       if (!parse_media_folder_name(operands, len, name))
>                 return NULL;
>
>         uid = get_be64(&operands[0]);
>         type = operands[8];
>         playable = operands[9];
>
> -       memset(name, 0, sizeof(name));
> -       namelen = MIN(get_be16(&operands[12]), sizeof(name) - 1);
> -       if (namelen > 0)
> -               memcpy(name, &operands[14], namelen);
> -
>         item = media_player_create_folder(mp, name, type, uid);
>         if (!item)
>                 return NULL;
> --
> 2.55.0
>
>


-- 
Luiz Augusto von Dentz
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.