diff options
| author | Hauke Mehrtens | 2026-04-23 22:18:50 +0000 |
|---|---|---|
| committer | Hauke Mehrtens | 2026-06-07 11:24:00 +0000 |
| commit | 8658324bd23479021465dcf0698c51fb77184c1e (patch) | |
| tree | 3aca1ba832da6622d16b07412e8b5ee82ce68627 | |
| parent | 440ca260622dd0701c343e40b1142a98e9ddd24c (diff) | |
uclient: cast to unsigned char before ctype classifications
C specifies that the ctype functions (isspace, isalpha, isxdigit,
tolower, ...) have defined behaviour only for values that are
representable as unsigned char or equal to EOF. Passing a plain char
with a negative value is undefined behaviour and can trigger asan
reports or wrong results depending on the libc implementation.
Cast the argument to unsigned char at every call site.
Assisted-by: Claude:claude-opus-4-7
Link: https://github.com/openwrt/uclient/pull/16
Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
| -rw-r--r-- | uclient-fetch.c | 6 | ||||
| -rw-r--r-- | uclient-http.c | 8 | ||||
| -rw-r--r-- | uclient-utils.c | 2 |
3 files changed, 8 insertions, 8 deletions
diff --git a/uclient-fetch.c b/uclient-fetch.c index 2afa3fd..3a6389d 100644 --- a/uclient-fetch.c +++ b/uclient-fetch.c @@ -591,12 +591,12 @@ static bool is_valid_header(char *str) char *tmp = str; /* First character must be a letter */ - if (!isalpha(*tmp)) + if (!isalpha((unsigned char)*tmp)) return false; /* Subsequent characters must be letters, numbers or dashes */ while (*(++tmp) != '\0') { - if (!isalnum(*tmp) && *tmp != '-') + if (!isalnum((unsigned char)*tmp) && *tmp != '-') return false; } @@ -771,7 +771,7 @@ int main(int argc, char **argv) goto out; } *(tmp++) = '\0'; - while (isspace(*tmp)) + while (isspace((unsigned char)*tmp)) ++tmp; if (*tmp == '\0' || !is_valid_header(optarg) || strchr(tmp, '\n')) { diff --git a/uclient-http.c b/uclient-http.c index 6663628..7b25e89 100644 --- a/uclient-http.c +++ b/uclient-http.c @@ -531,7 +531,7 @@ uclient_http_add_auth_digest(struct uclient_http *uh) const char **dest = NULL; const char *tmp; - while (*next && isspace(*next)) + while (*next && isspace((unsigned char)*next)) next++; if (strmatch(&next, "realm")) @@ -765,10 +765,10 @@ static void uclient_parse_http_line(struct uclient_http *uh, char *data) *(sep++) = 0; for (name = data; *name; name++) - *name = tolower(*name); + *name = tolower((unsigned char)*name); name = data; - while (isspace(*sep)) + while (isspace((unsigned char)*sep)) sep++; blobmsg_add_string(&uh->meta, name, sep); @@ -815,7 +815,7 @@ static void __uclient_notify_read(struct uclient_http *uh) if (!*next) return; - if (isspace(*next) && *next != '\r' && *next != '\n') { + if (isspace((unsigned char)*next) && *next != '\r' && *next != '\n') { sep[0] = ' '; if (sep + 1 < next) sep[1] = ' '; diff --git a/uclient-utils.c b/uclient-utils.c index 3eaf2d5..71c30e2 100644 --- a/uclient-utils.c +++ b/uclient-utils.c @@ -78,7 +78,7 @@ int uclient_urldecode(const char *in, char *out, bool decode_plus) while ((c = *(in++))) { if (c == '%') { - if (!isxdigit(in[0]) || !isxdigit(in[1])) + if (!isxdigit((unsigned char)in[0]) || !isxdigit((unsigned char)in[1])) return -1; dec[0] = in[0]; |