[PATCH BlueZ v2 08/10] device: Fix the name truncation splitting UTF-8 sequences
Luiz Augusto von Dentz <[email protected]>
| Newsgroups | org.kernel.vger.linux-bluetooth |
|---|---|
| Message-ID | <[email protected]> |
From: Luiz Augusto von Dentz <[email protected]> btd_device_device_set_name() copies the name with strncpy(device->name, name, MAX_NAME_LENGTH); which cuts at 248 bytes without any regard for where the UTF-8 characters start and end, so a longer name can be left with a partial sequence. The result is no longer valid UTF-8 and D-Bus rejects it when the Name property is emitted. A name made of 249 U+FFFD characters is 747 bytes long and cutting it at 248 leaves a trailing "ef bf", two thirds of a character. Truncate on a character boundary instead. The same name now ends up 246 bytes long and stays valid. This also means a name that is not valid UTF-8 to begin with, as can be had from the neard and sixaxis plugins, is now cut at the first ill-formed sequence rather than passed on as is. Assisted-by: Claude:claude-opus-5 --- src/device.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/src/device.c b/src/device.c index 65d84be56ca5..df607f718be1 100644 --- a/src/device.c +++ b/src/device.c @@ -5103,12 +5103,22 @@ char *btd_device_get_storage_path(struct btd_device *device, const char *name) void btd_device_device_set_name(struct btd_device *device, const char *name) { + size_t len; + if (strncmp(name, device->name, MAX_NAME_LENGTH) == 0) return; DBG("%s %s", device->path, name); - strncpy(device->name, name, MAX_NAME_LENGTH); + /* + * Truncate on a character boundary, so that a name longer than + * MAX_NAME_LENGTH does not end up with a partial sequence, which + * would no longer be valid UTF-8 and would be rejected by D-Bus. + */ + len = strnlenutf8(name, MIN(strlen(name), (size_t) MAX_NAME_LENGTH)); + + memcpy(device->name, name, len); + device->name[len] = '\0'; store_device_info(device); -- 2.54.0