udev-util: bound leading whitespace skip in udev_replace_whitespace (#42757)

udev_replace_whitespace() is documented to read at most 'len' bytes from
'str':
- the strspn() skip of leading whitespace stops at a non-space byte or
NUL, not at 'len'
- ata_id passes the space padded, non-NUL-terminated ATA IDENTIFY
model/serial/fw fields
- an all-blank field reads off the end of the 512-byte hd_driveid stack
struct
Capped the skip to 'len'; existing outputs are unchanged. Added a
regression test.
This commit is contained in:
Yu Watanabe
2026-07-17 01:16:07 +09:00
committed by GitHub
5 changed files with 80 additions and 1 deletions
+17
View File
@@ -1428,6 +1428,23 @@ size_t strspn_from_end(const char *str, const char *accept) {
return n;
}
size_t strnspn(const char *str, const char *accept, size_t n) {
size_t i;
/* Like strspn(), but reads at most 'n' bytes from 'str'. Returns the length of the initial
* run of 'str' (capped at 'n') that consists solely of bytes found in 'accept'. Stops at a
* NUL byte too. Unlike strspn() this is safe on a buffer that is not NUL terminated within
* 'n' bytes. */
assert(str || n == 0);
assert(accept);
for (i = 0; i < n && str[i] != '\0' && strchr(accept, str[i]); i++)
;
return i;
}
char* strdupspn(const char *a, const char *accept) {
if (isempty(a) || isempty(accept))
return strdup("");