From b44c4c80d8a76d7df32985e4bbadb12c985d6a22 Mon Sep 17 00:00:00 2001 From: Ilija Tovilo Date: Sun, 3 May 2026 20:03:18 +0200 Subject: [PATCH 8/9] GHSA-m8rr-4c36-8gq4: Consistently pass unsigned char to ctype.h functions Fixes GHSA-m8rr-4c36-8gq4 Fixes CVE-2026-7258 (cherry picked from commit a38418777f65780d9d622197677e90567690fc07) (cherry picked from commit 07e5a9263314fd9a2a4479661353704e00dd8d0c) (cherry picked from commit 30de2f8492a06ebcf1659307f1f049e2799c7f21) --- Zend/zend_compile.c | 2 +- Zend/zend_operators.c | 8 ++++---- Zend/zend_virtual_cwd.c | 10 +++++----- Zend/zend_virtual_cwd.h | 2 +- ext/com_dotnet/com_extension.c | 4 ++-- ext/date/lib/parse_date.c | 10 +++++----- ext/date/lib/parse_date.re | 10 +++++----- ext/date/lib/parse_iso_intervals.c | 4 ++-- ext/date/lib/parse_iso_intervals.re | 4 ++-- ext/date/lib/timelib.c | 2 +- ext/filter/logical_filters.c | 10 +++++----- ext/ftp/ftp.c | 10 +++++----- ext/gd/libgd/gd_xbm.c | 2 +- ext/imap/php_imap.c | 2 +- ext/intl/locale/locale_methods.c | 2 +- ext/mbstring/mbstring.c | 4 ++-- ext/mbstring/php_mbregex.c | 2 +- ext/pcre/php_pcre.c | 4 ++-- ext/pdo/pdo.c | 2 +- ext/pdo/pdo_sql_parser.re | 2 +- ext/pdo/pdo_stmt.c | 2 +- ext/standard/dl.c | 2 +- ext/standard/file.c | 2 +- ext/standard/filters.c | 2 +- ext/standard/formatted_print.c | 8 ++++---- ext/standard/ftp_fopen_wrapper.c | 12 ++++++------ ext/standard/html.c | 4 ++-- ext/standard/math.c | 6 +++--- ext/standard/metaphone.c | 18 ++++++++--------- ext/standard/quot_print.c | 8 ++++---- ext/standard/scanf.c | 10 +++++----- ext/standard/soundex.c | 2 +- ext/standard/string.c | 14 +++++++------- ext/standard/strnatcmp.c | 30 ++++++++++++++--------------- ext/standard/type.c | 2 +- ext/standard/url.c | 20 +++++++++---------- ext/standard/url_scanner_ex.re | 6 +++--- ext/standard/versioning.c | 16 +++++++-------- main/SAPI.c | 6 +++--- main/fopen_wrappers.c | 6 +++--- main/php_ini.c | 2 +- main/php_variables.c | 4 ++-- main/rfc1867.c | 12 ++++++------ main/snprintf.c | 14 +++++++------- main/spprintf.c | 14 +++++++------- main/streams/streams.c | 4 ++-- main/streams/transports.c | 2 +- sapi/cli/php_cli_server.c | 2 +- sapi/fpm/fpm/fpm_conf.c | 4 ++-- sapi/litespeed/lsapi_main.c | 4 ++-- sapi/litespeed/lsapilib.c | 6 +++--- sapi/phpdbg/phpdbg_cmd.c | 4 ++-- sapi/phpdbg/phpdbg_prompt.c | 2 +- sapi/phpdbg/phpdbg_utils.c | 10 +++++----- win32/sendmail.c | 6 +++--- 55 files changed, 181 insertions(+), 181 deletions(-) diff --git a/Zend/zend_compile.c b/Zend/zend_compile.c index 8b8cc3015d9..7777b377816 100644 --- a/Zend/zend_compile.c +++ b/Zend/zend_compile.c @@ -1772,7 +1772,7 @@ ZEND_API size_t zend_dirname(char *path, size_t len) /* Note that on Win32 CWD is per drive (heritage from CP/M). * This means dirname("c:foo") maps to "c:." or "c:" - which means CWD on C: drive. */ - if ((2 <= len) && isalpha((int)((unsigned char *)path)[0]) && (':' == path[1])) { + if ((2 <= len) && isalpha((unsigned char)path[0]) && (':' == path[1])) { /* Skip over the drive spec (if any) so as not to change */ path += 2; len_adjust += 2; diff --git a/Zend/zend_operators.c b/Zend/zend_operators.c index 031894755c8..b4d804f0a2c 100644 --- a/Zend/zend_operators.c +++ b/Zend/zend_operators.c @@ -2804,8 +2804,8 @@ ZEND_API int ZEND_FASTCALL zend_binary_strcasecmp_l(const char *s1, size_t len1, len = MIN(len1, len2); while (len--) { - c1 = zend_tolower((int)*(unsigned char *)s1++); - c2 = zend_tolower((int)*(unsigned char *)s2++); + c1 = zend_tolower((unsigned char)*(s1++)); + c2 = zend_tolower((unsigned char)*(s2++)); if (c1 != c2) { return c1 - c2; } @@ -2825,8 +2825,8 @@ ZEND_API int ZEND_FASTCALL zend_binary_strncasecmp_l(const char *s1, size_t len1 } len = MIN(length, MIN(len1, len2)); while (len--) { - c1 = zend_tolower((int)*(unsigned char *)s1++); - c2 = zend_tolower((int)*(unsigned char *)s2++); + c1 = zend_tolower((unsigned char)*(s1++)); + c2 = zend_tolower((unsigned char)*(s2++)); if (c1 != c2) { return c1 - c2; } diff --git a/Zend/zend_virtual_cwd.c b/Zend/zend_virtual_cwd.c index e16ba50f135..679197c40f9 100644 --- a/Zend/zend_virtual_cwd.c +++ b/Zend/zend_virtual_cwd.c @@ -201,7 +201,7 @@ void virtual_cwd_main_cwd_init(uint8_t reinit) /* {{{ */ main_cwd_state.cwd_length = strlen(cwd); #ifdef ZEND_WIN32 if (main_cwd_state.cwd_length >= 2 && cwd[1] == ':') { - cwd[0] = toupper(cwd[0]); + cwd[0] = toupper((unsigned char)cwd[0]); } #endif main_cwd_state.cwd = strdup(cwd); @@ -279,7 +279,7 @@ CWD_API char *virtual_getcwd_ex(size_t *length) /* {{{ */ *length = state->cwd_length+1; retval = (char *) emalloc(*length+1); memcpy(retval, state->cwd, *length); - retval[0] = toupper(retval[0]); + retval[0] = toupper((unsigned char)retval[0]); retval[*length-1] = DEFAULT_SLASH; retval[*length] = '\0'; return retval; @@ -1120,7 +1120,7 @@ CWD_API int virtual_file_ex(cwd_state *state, const char *path, verify_path_func if (resolved_path[start] == 0) { goto verify; } - resolved_path[start] = toupper(resolved_path[start]); + resolved_path[start] = toupper((unsigned char)resolved_path[start]); start++; } resolved_path[start++] = DEFAULT_SLASH; @@ -1128,13 +1128,13 @@ CWD_API int virtual_file_ex(cwd_state *state, const char *path, verify_path_func if (resolved_path[start] == 0) { goto verify; } - resolved_path[start] = toupper(resolved_path[start]); + resolved_path[start] = toupper((unsigned char)resolved_path[start]); start++; } resolved_path[start++] = DEFAULT_SLASH; } else if (IS_ABSOLUTE_PATH(resolved_path, path_length)) { /* skip DRIVE name */ - resolved_path[0] = toupper(resolved_path[0]); + resolved_path[0] = toupper((unsigned char)resolved_path[0]); resolved_path[2] = DEFAULT_SLASH; start = 3; } diff --git a/Zend/zend_virtual_cwd.h b/Zend/zend_virtual_cwd.h index 574bee992bd..35053f4539c 100644 --- a/Zend/zend_virtual_cwd.h +++ b/Zend/zend_virtual_cwd.h @@ -84,7 +84,7 @@ typedef unsigned short mode_t; #define IS_UNC_PATH(path, len) \ (len >= 2 && IS_SLASH(path[0]) && IS_SLASH(path[1])) #define IS_ABSOLUTE_PATH(path, len) \ - (len >= 2 && (/* is local */isalpha(path[0]) && path[1] == ':' || /* is UNC */IS_SLASH(path[0]) && IS_SLASH(path[1]))) + (len >= 2 && (/* is local */isalpha((unsigned char)(path)[0]) && path[1] == ':' || /* is UNC */IS_SLASH(path[0]) && IS_SLASH(path[1]))) #else #ifdef HAVE_DIRENT_H diff --git a/ext/com_dotnet/com_extension.c b/ext/com_dotnet/com_extension.c index 5ae14815dd5..a3d4afdf133 100644 --- a/ext/com_dotnet/com_extension.c +++ b/ext/com_dotnet/com_extension.c @@ -241,11 +241,11 @@ static PHP_INI_MH(OnTypeLibFileUpdate) } /* Remove leading/training white spaces on search_string */ - while (isspace(*typelib_name)) {/* Ends on '\0' in worst case */ + while (isspace((unsigned char)*typelib_name)) {/* Ends on '\0' in worst case */ typelib_name ++; } ptr = typelib_name + strlen(typelib_name) - 1; - while ((ptr != typelib_name) && isspace(*ptr)) { + while ((ptr != typelib_name) && isspace((unsigned char)*ptr)) { *ptr = '\0'; ptr--; } diff --git a/ext/date/lib/parse_date.c b/ext/date/lib/parse_date.c index 266bad13a22..d5749b0bc76 100644 --- a/ext/date/lib/parse_date.c +++ b/ext/date/lib/parse_date.c @@ -479,7 +479,7 @@ static timelib_sll timelib_get_nr(char **ptr, int max_length) static void timelib_skip_day_suffix(char **ptr) { - if (isspace(**ptr)) { + if (isspace((unsigned char)**ptr)) { return; } if (!timelib_strncasecmp(*ptr, "nd", 2) || !timelib_strncasecmp(*ptr, "rd", 2) ||!timelib_strncasecmp(*ptr, "st", 2) || !timelib_strncasecmp(*ptr, "th", 2)) { @@ -744,7 +744,7 @@ static timelib_long timelib_parse_tz_cor(char **ptr) char *begin = *ptr, *end; timelib_long tmp; - while (isdigit(**ptr) || **ptr == ':') { + while (isdigit((unsigned char)**ptr) || **ptr == ':') { ++*ptr; } end = *ptr; @@ -786,7 +786,7 @@ static timelib_long timelib_parse_tz_minutes(char **ptr, timelib_time *t) } ++*ptr; - while (isdigit(**ptr)) { + while (isdigit((unsigned char)**ptr)) { ++*ptr; } @@ -24945,10 +24945,10 @@ timelib_time* timelib_strtotime(char *s, size_t len, timelib_error_container **e in.errors->error_messages = NULL; if (len > 0) { - while (isspace(*s) && s < e) { + while (isspace((unsigned char)*s) && s < e) { s++; } - while (isspace(*e) && e > s) { + while (isspace((unsigned char)*e) && e > s) { e--; } } diff --git a/ext/date/lib/parse_date.re b/ext/date/lib/parse_date.re index 3dcb8040349..40d50ee0a51 100644 --- a/ext/date/lib/parse_date.re +++ b/ext/date/lib/parse_date.re @@ -477,7 +477,7 @@ static timelib_sll timelib_get_nr(char **ptr, int max_length) static void timelib_skip_day_suffix(char **ptr) { - if (isspace(**ptr)) { + if (isspace((unsigned char)**ptr)) { return; } if (!timelib_strncasecmp(*ptr, "nd", 2) || !timelib_strncasecmp(*ptr, "rd", 2) ||!timelib_strncasecmp(*ptr, "st", 2) || !timelib_strncasecmp(*ptr, "th", 2)) { @@ -742,7 +742,7 @@ static timelib_long timelib_parse_tz_cor(char **ptr) char *begin = *ptr, *end; timelib_long tmp; - while (isdigit(**ptr) || **ptr == ':') { + while (isdigit((unsigned char)**ptr) || **ptr == ':') { ++*ptr; } end = *ptr; @@ -784,7 +784,7 @@ static timelib_long timelib_parse_tz_minutes(char **ptr, timelib_time *t) } ++*ptr; - while (isdigit(**ptr)) { + while (isdigit((unsigned char)**ptr)) { ++*ptr; } @@ -1837,10 +1837,10 @@ timelib_time* timelib_strtotime(char *s, size_t len, timelib_error_container **e in.errors->error_messages = NULL; if (len > 0) { - while (isspace(*s) && s < e) { + while (isspace((unsigned char)*s) && s < e) { s++; } - while (isspace(*e) && e > s) { + while (isspace((unsigned char)*e) && e > s) { e--; } } diff --git a/ext/date/lib/parse_iso_intervals.c b/ext/date/lib/parse_iso_intervals.c index 4f7e2d439cc..b56ccb0ebb5 100644 --- a/ext/date/lib/parse_iso_intervals.c +++ b/ext/date/lib/parse_iso_intervals.c @@ -946,10 +946,10 @@ void timelib_strtointerval(char *s, size_t len, in.errors->error_messages = NULL; if (len > 0) { - while (isspace(*s) && s < e) { + while (isspace((unsigned char)*s) && s < e) { s++; } - while (isspace(*e) && e > s) { + while (isspace((unsigned char)*e) && e > s) { e--; } } diff --git a/ext/date/lib/parse_iso_intervals.re b/ext/date/lib/parse_iso_intervals.re index 6e863eabf31..fd959c01a41 100644 --- a/ext/date/lib/parse_iso_intervals.re +++ b/ext/date/lib/parse_iso_intervals.re @@ -341,10 +341,10 @@ void timelib_strtointerval(char *s, size_t len, in.errors->error_messages = NULL; if (len > 0) { - while (isspace(*s) && s < e) { + while (isspace((unsigned char)*s) && s < e) { s++; } - while (isspace(*e) && e > s) { + while (isspace((unsigned char)*e) && e > s) { e--; } } diff --git a/ext/date/lib/timelib.c b/ext/date/lib/timelib.c index fc86619d632..d36768db92b 100644 --- a/ext/date/lib/timelib.c +++ b/ext/date/lib/timelib.c @@ -123,7 +123,7 @@ void timelib_time_tz_abbr_update(timelib_time* tm, char* tz_abbr) TIMELIB_TIME_FREE(tm->tz_abbr); tm->tz_abbr = timelib_strdup(tz_abbr); for (i = 0; i < tz_abbr_len; i++) { - tm->tz_abbr[i] = toupper(tz_abbr[i]); + tm->tz_abbr[i] = toupper((unsigned char)tz_abbr[i]); } } diff --git a/ext/filter/logical_filters.c b/ext/filter/logical_filters.c index 9c86ad072cc..5cc019e00e6 100644 --- a/ext/filter/logical_filters.c +++ b/ext/filter/logical_filters.c @@ -519,21 +519,21 @@ static int _php_filter_validate_domain(char * domain, int len, zend_long flags) } /* First char must be alphanumeric */ - if(*s == '.' || (hostname && !isalnum((int)*(unsigned char *)s))) { + if(*s == '.' || (hostname && !isalnum((unsigned char)*s))) { return 0; } while (s < e) { if (*s == '.') { /* The first and the last character of a label must be alphanumeric */ - if (*(s + 1) == '.' || (hostname && (!isalnum((int)*(unsigned char *)(s - 1)) || !isalnum((int)*(unsigned char *)(s + 1))))) { + if (*(s + 1) == '.' || (hostname && (!isalnum((unsigned char)s[-1]) || !isalnum((unsigned char)s[1])))) { return 0; } /* Reset label length counter */ i = 1; } else { - if (i > 63 || (hostname && *s != '-' && !isalnum((int)*(unsigned char *)s))) { + if (i > 63 || (hostname && *s != '-' && !isalnum((unsigned char)*s))) { return 0; } @@ -560,9 +560,9 @@ static int is_userinfo_valid(zend_string *str) const char *valid = "-._~!$&'()*+,;=:"; const char *p = ZSTR_VAL(str); while (p - ZSTR_VAL(str) < ZSTR_LEN(str)) { - if (isalpha(*p) || isdigit(*p) || strchr(valid, *p)) { + if (isalpha((unsigned char)*p) || isdigit((unsigned char)*p) || strchr(valid, *p)) { p++; - } else if (*p == '%' && p - ZSTR_VAL(str) <= ZSTR_LEN(str) - 3 && isdigit(*(p+1)) && isxdigit(*(p+2))) { + } else if (*p == '%' && p - ZSTR_VAL(str) <= ZSTR_LEN(str) - 3 && isdigit((unsigned char)p[1]) && isxdigit((unsigned char)p[2])) { p += 3; } else { return 0; diff --git a/ext/ftp/ftp.c b/ext/ftp/ftp.c index a11aa323c1c..13d3264febe 100644 --- a/ext/ftp/ftp.c +++ b/ext/ftp/ftp.c @@ -513,7 +513,7 @@ ftp_raw(ftpbuf_t *ftp, const char *cmd, const size_t cmd_len, zval *return_value array_init(return_value); while (ftp_readline(ftp)) { add_next_index_string(return_value, ftp->inbuf); - if (isdigit(ftp->inbuf[0]) && isdigit(ftp->inbuf[1]) && isdigit(ftp->inbuf[2]) && ftp->inbuf[3] == ' ') { + if (isdigit((unsigned char)ftp->inbuf[0]) && isdigit((unsigned char)ftp->inbuf[1]) && isdigit((unsigned char)ftp->inbuf[2]) && ftp->inbuf[3] == ' ') { return; } } @@ -867,7 +867,7 @@ ftp_pasv(ftpbuf_t *ftp, int pasv) return 0; } /* parse out the IP and port */ - for (ptr = ftp->inbuf; *ptr && !isdigit(*ptr); ptr++); + for (ptr = ftp->inbuf; *ptr && !isdigit((unsigned char)*ptr); ptr++); n = sscanf(ptr, "%lu,%lu,%lu,%lu,%lu,%lu", &b[0], &b[1], &b[2], &b[3], &b[4], &b[5]); if (n != 6) { return 0; @@ -1178,7 +1178,7 @@ ftp_mdtm(ftpbuf_t *ftp, const char *path, const size_t path_len) return -1; } /* parse out the timestamp */ - for (ptr = ftp->inbuf; *ptr && !isdigit(*ptr); ptr++); + for (ptr = ftp->inbuf; *ptr && !isdigit((unsigned char)*ptr); ptr++); n = sscanf(ptr, "%4u%2u%2u%2u%2u%2u", &tm.tm_year, &tm.tm_mon, &tm.tm_mday, &tm.tm_hour, &tm.tm_min, &tm.tm_sec); if (n != 6) { return -1; @@ -1382,13 +1382,13 @@ ftp_getresp(ftpbuf_t *ftp) } /* Break out when the end-tag is found */ - if (isdigit(ftp->inbuf[0]) && isdigit(ftp->inbuf[1]) && isdigit(ftp->inbuf[2]) && ftp->inbuf[3] == ' ') { + if (isdigit((unsigned char)ftp->inbuf[0]) && isdigit((unsigned char)ftp->inbuf[1]) && isdigit((unsigned char)ftp->inbuf[2]) && ftp->inbuf[3] == ' ') { break; } } /* translate the tag */ - if (!isdigit(ftp->inbuf[0]) || !isdigit(ftp->inbuf[1]) || !isdigit(ftp->inbuf[2])) { + if (!isdigit((unsigned char)ftp->inbuf[0]) || !isdigit((unsigned char)ftp->inbuf[1]) || !isdigit((unsigned char)ftp->inbuf[2])) { return 0; } diff --git a/ext/gd/libgd/gd_xbm.c b/ext/gd/libgd/gd_xbm.c index dae2e621520..b86dc10e6a9 100644 --- a/ext/gd/libgd/gd_xbm.c +++ b/ext/gd/libgd/gd_xbm.c @@ -193,7 +193,7 @@ void gdImageXbmCtx(gdImagePtr image, char* file_name, int fg, gdIOCtx * out) } else { for (i=0; i= 0x7f) /* validate a modified-base64 character */ -#define B64CHAR(c) (isalnum(c) || (c) == '+' || (c) == ',') +#define B64CHAR(c) (isalnum((unsigned char)(c)) || (c) == '+' || (c) == ',') /* map the low 64 bits of `n' to the modified-base64 characters */ #define B64(n) ("ABCDEFGHIJKLMNOPQRSTUVWXYZ" \ diff --git a/ext/intl/locale/locale_methods.c b/ext/intl/locale/locale_methods.c index 1bdfb27b7e2..127a12ef871 100644 --- a/ext/intl/locale/locale_methods.c +++ b/ext/intl/locale/locale_methods.c @@ -1216,7 +1216,7 @@ static int strToMatch(const char* str ,char *retstr) if( *str == '-' ){ *retstr = '_'; } else { - *retstr = tolower(*str); + *retstr = tolower((unsigned char)*str); } str++; retstr++; diff --git a/ext/mbstring/mbstring.c b/ext/mbstring/mbstring.c index f170b935b69..2d636939e4e 100644 --- a/ext/mbstring/mbstring.c +++ b/ext/mbstring/mbstring.c @@ -1176,7 +1176,7 @@ static char *php_mb_rfc1867_getword(const zend_encoding *encoding, char **line, static char *php_mb_rfc1867_getword_conf(const zend_encoding *encoding, char *str) /* {{{ */ { - while (*str && isspace(*(unsigned char *)str)) { + while (*str && isspace((unsigned char)*str)) { ++str; } @@ -1192,7 +1192,7 @@ static char *php_mb_rfc1867_getword_conf(const zend_encoding *encoding, char *st } else { char *strend = str; - while (*strend && !isspace(*(unsigned char *)strend)) { + while (*strend && !isspace((unsigned char)*strend)) { ++strend; } return php_mb_rfc1867_substring_conf(encoding, str, strend - str, 0); diff --git a/ext/mbstring/php_mbregex.c b/ext/mbstring/php_mbregex.c index 76aff4f244e..791d4b0bc08 100644 --- a/ext/mbstring/php_mbregex.c +++ b/ext/mbstring/php_mbregex.c @@ -777,7 +777,7 @@ static inline void mb_regex_substitute( continue; } if (name_end[0] == delim) break; - if (maybe_num && !isdigit(name_end[0])) maybe_num = 0; + if (maybe_num && !isdigit((unsigned char)name_end[0])) maybe_num = 0; name_end++; } p = name_end + 1; diff --git a/ext/pcre/php_pcre.c b/ext/pcre/php_pcre.c index a93b35c4f33..aacdf2b67c9 100644 --- a/ext/pcre/php_pcre.c +++ b/ext/pcre/php_pcre.c @@ -622,7 +622,7 @@ PHPAPI pcre_cache_entry* pcre_get_compiled_regex_cache_ex(zend_string *regex, in /* Parse through the leading whitespace, and display a warning if we get to the end without encountering a delimiter. */ - while (isspace((int)*(unsigned char *)p)) p++; + while (isspace((unsigned char)*p)) p++; if (*p == 0) { if (key != regex) { zend_string_release_ex(key, 0); @@ -636,7 +636,7 @@ PHPAPI pcre_cache_entry* pcre_get_compiled_regex_cache_ex(zend_string *regex, in /* Get the delimiter and display a warning if it is alphanumeric or a backslash. */ delimiter = *p++; - if (isalnum((int)*(unsigned char *)&delimiter) || delimiter == '\\') { + if (isalnum((unsigned char)delimiter) || delimiter == '\\') { if (key != regex) { zend_string_release_ex(key, 0); } diff --git a/ext/pdo/pdo.c b/ext/pdo/pdo.c index 88839bf61f6..b3953aaf0ca 100644 --- a/ext/pdo/pdo.c +++ b/ext/pdo/pdo.c @@ -262,7 +262,7 @@ PDO_API int php_pdo_parse_data_source(const char *data_source, zend_ulong data_s } } - while (i < data_source_len && isspace(data_source[i])) { + while (i < data_source_len && isspace((unsigned char)data_source[i])) { i++; } diff --git a/ext/pdo/pdo_sql_parser.re b/ext/pdo/pdo_sql_parser.re index 71d41002cf0..b077c529cc5 100644 --- a/ext/pdo/pdo_sql_parser.re +++ b/ext/pdo/pdo_sql_parser.re @@ -111,7 +111,7 @@ PDO_API int pdo_parse_params(pdo_stmt_t *stmt, char *inquery, size_t inquery_len if (t == PDO_PARSER_BIND) { ptrdiff_t len = s.cur - s.tok; - if ((inquery < (s.cur - len)) && isalnum(*(s.cur - len - 1))) { + if ((inquery < (s.cur - len)) && isalnum((unsigned char)s.cur[-len - 1])) { continue; } query_type |= PDO_PLACEHOLDER_NAMED; diff --git a/ext/pdo/pdo_stmt.c b/ext/pdo/pdo_stmt.c index adc921bbd74..0181c1c1a4b 100644 --- a/ext/pdo/pdo_stmt.c +++ b/ext/pdo/pdo_stmt.c @@ -210,7 +210,7 @@ int pdo_stmt_describe_columns(pdo_stmt_t *stmt) /* {{{ */ switch (stmt->dbh->desired_case) { case PDO_CASE_UPPER: while (*s != '\0') { - *s = toupper(*s); + *s = toupper((unsigned char)*s); s++; } break; diff --git a/ext/standard/dl.c b/ext/standard/dl.c index bef2e51e6f3..6e0aae72b2f 100644 --- a/ext/standard/dl.c +++ b/ext/standard/dl.c @@ -85,7 +85,7 @@ PHPAPI void *php_load_shlib(char *path, char **errp) size_t i = strlen(err); (*errp)=estrdup(err); php_win32_error_msg_free(err); - while (i > 0 && isspace((*errp)[i-1])) { (*errp)[i-1] = '\0'; i--; } + while (i > 0 && isspace((unsigned char)(*errp)[i-1])) { (*errp)[i-1] = '\0'; i--; } } else { (*errp) = estrdup(""); } diff --git a/ext/standard/file.c b/ext/standard/file.c index 3bd3421603f..bf9d45da55c 100644 --- a/ext/standard/file.c +++ b/ext/standard/file.c @@ -2118,7 +2118,7 @@ PHPAPI void php_fgetcsv(php_stream *stream, char delimiter, char enclosure, int inc_len = (bptr < limit ? (*bptr == '\0' ? 1 : php_mblen(bptr, limit - bptr)): 0); if (inc_len == 1) { char *tmp = bptr; - while ((*tmp != delimiter) && isspace((int)*(unsigned char *)tmp)) { + while ((*tmp != delimiter) && isspace((unsigned char)*tmp)) { tmp++; } if (*tmp == enclosure) { diff --git a/ext/standard/filters.c b/ext/standard/filters.c index 5d5745c6bec..bcf5e1f6f16 100644 --- a/ext/standard/filters.c +++ b/ext/standard/filters.c @@ -1090,7 +1090,7 @@ static php_conv_err_t php_conv_qprint_decode_convert(php_conv_qprint_decode *ins goto out; } - if (!isxdigit((int) *ps)) { + if (!isxdigit(*ps)) { err = PHP_CONV_ERR_INVALID_SEQ; goto out; } diff --git a/ext/standard/formatted_print.c b/ext/standard/formatted_print.c index 4ee68adefa5..50606278be2 100644 --- a/ext/standard/formatted_print.c +++ b/ext/standard/formatted_print.c @@ -440,13 +440,13 @@ php_formatted_print(zval *z_format, zval *args, int argc) PRINTF_DEBUG(("sprintf: first looking at '%c', inpos=%d\n", *format, format - Z_STRVAL_P(z_format))); - if (isalpha((int)*format)) { + if (isalpha((unsigned char)*format)) { width = precision = 0; argnum = currarg++; } else { /* first look for argnum */ temppos = format; - while (isdigit((int)*temppos)) temppos++; + while (isdigit((unsigned char)*temppos)) temppos++; if (*temppos == '$') { argnum = php_sprintf_getnumber(&format, &format_len); @@ -489,7 +489,7 @@ php_formatted_print(zval *z_format, zval *args, int argc) /* after modifiers comes width */ - if (isdigit((int)*format)) { + if (isdigit((unsigned char)*format)) { PRINTF_DEBUG(("sprintf: getting width\n")); if ((width = php_sprintf_getnumber(&format, &format_len)) < 0) { efree(result); @@ -507,7 +507,7 @@ php_formatted_print(zval *z_format, zval *args, int argc) format++; format_len--; PRINTF_DEBUG(("sprintf: getting precision\n")); - if (isdigit((int)*format)) { + if (isdigit((unsigned char)*format)) { if ((precision = php_sprintf_getnumber(&format, &format_len)) < 0) { efree(result); php_error_docref(NULL, E_WARNING, "Precision must be greater than zero and less than %d", INT_MAX); diff --git a/ext/standard/ftp_fopen_wrapper.c b/ext/standard/ftp_fopen_wrapper.c index 3a7dec4a3bc..f0467720e63 100644 --- a/ext/standard/ftp_fopen_wrapper.c +++ b/ext/standard/ftp_fopen_wrapper.c @@ -81,8 +81,8 @@ static inline int get_ftp_result(php_stream *stream, char *buffer, size_t buffer { buffer[0] = '\0'; /* in case read fails to read anything */ while (php_stream_gets(stream, buffer, buffer_size-1) && - !(isdigit((int) buffer[0]) && isdigit((int) buffer[1]) && - isdigit((int) buffer[2]) && buffer[3] == ' ')); + !(isdigit((unsigned char)buffer[0]) && isdigit((unsigned char)buffer[1]) && + isdigit((unsigned char)buffer[2]) && buffer[3] == ' ')); return strtol(buffer, NULL, 10); } /* }}} */ @@ -234,7 +234,7 @@ static php_stream *php_ftp_fopen_connect(php_stream_wrapper *wrapper, const char #define PHP_FTP_CNTRL_CHK(val, val_len, err_msg) { \ unsigned char *s = (unsigned char *) val, *e = (unsigned char *) s + val_len; \ while (s < e) { \ - if (iscntrl(*s)) { \ + if (iscntrl((unsigned char)*s)) { \ php_stream_wrapper_log_error(wrapper, options, err_msg, val); \ goto connect_errexit; \ } \ @@ -346,14 +346,14 @@ static unsigned short php_fopen_do_pasv(php_stream *stream, char *ip, size_t ip_ /* parse pasv command (129, 80, 95, 25, 13, 221) */ tpath = tmp_line; /* skip over the "227 Some message " part */ - for (tpath += 4; *tpath && !isdigit((int) *tpath); tpath++); + for (tpath += 4; *tpath && !isdigit((unsigned char)*tpath); tpath++); if (!*tpath) { return 0; } /* skip over the host ip, to get the port */ hoststart = tpath; for (i = 0; i < 4; i++) { - for (; isdigit((int) *tpath); tpath++); + for (; isdigit((unsigned char)*tpath); tpath++); if (*tpath != ',') { return 0; } @@ -838,7 +838,7 @@ static int php_stream_ftp_url_stat(php_stream_wrapper *wrapper, const char *url, struct tm tm, tmbuf, *gmt; time_t stamp; - while ((size_t)(p - tmp_line) < sizeof(tmp_line) && !isdigit(*p)) { + while ((size_t)(p - tmp_line) < sizeof(tmp_line) && !isdigit((unsigned char)*p)) { p++; } diff --git a/ext/standard/html.c b/ext/standard/html.c index e9c46ba0831..a2e39f7d5d9 100644 --- a/ext/standard/html.c +++ b/ext/standard/html.c @@ -753,8 +753,8 @@ static inline int process_numeric_entity(const char **buf, unsigned *code_point) /* strtol allows whitespace and other stuff in the beginning * we're not interested */ - if ((hexadecimal && !isxdigit(**buf)) || - (!hexadecimal && !isdigit(**buf))) { + if ((hexadecimal && !isxdigit((unsigned char)**buf)) || + (!hexadecimal && !isdigit((unsigned char)**buf))) { return FAILURE; } diff --git a/ext/standard/math.c b/ext/standard/math.c index ba7e3944aa5..d8675be9bcb 100644 --- a/ext/standard/math.c +++ b/ext/standard/math.c @@ -863,9 +863,9 @@ PHPAPI int _php_math_basetozval(zval *arg, int base, zval *ret) e = s + Z_STRLEN_P(arg); /* Skip leading whitespace */ - while (s < e && isspace(*s)) s++; + while (s < e && isspace((unsigned char)*s)) s++; /* Skip trailing whitespace */ - while (s < e && isspace(*(e-1))) e--; + while (s < e && isspace((unsigned char)e[-1])) e--; if (e - s >= 2) { if (base == 16 && s[0] == '0' && (s[1] == 'x' || s[1] == 'X')) s += 2; @@ -1160,7 +1160,7 @@ PHPAPI zend_string *_php_math_number_format_ex(double d, int dec, char *dec_poin tmpbuf = strpprintf(0, "%.*F", dec, d); if (tmpbuf == NULL) { return NULL; - } else if (!isdigit((int)ZSTR_VAL(tmpbuf)[0])) { + } else if (!isdigit((unsigned char)ZSTR_VAL(tmpbuf)[0])) { return tmpbuf; } diff --git a/ext/standard/metaphone.c b/ext/standard/metaphone.c index 448e9b75d37..5a967fe1bbe 100644 --- a/ext/standard/metaphone.c +++ b/ext/standard/metaphone.c @@ -83,7 +83,7 @@ static const char _codes[26] = }; -#define ENCODE(c) (isalpha(c) ? _codes[((toupper(c)) - 'A')] : 0) +#define ENCODE(c) (isalpha((unsigned char)(c)) ? _codes[((toupper((unsigned char)(c))) - 'A')] : 0) #define isvowel(c) (ENCODE(c) & 1) /* AEIOU */ @@ -107,17 +107,17 @@ static const char _codes[26] = * accesssing the array directly... */ /* Look at the next letter in the word */ -#define Next_Letter (toupper(word[w_idx+1])) +#define Next_Letter (toupper((unsigned char)word[w_idx+1])) /* Look at the current letter in the word */ -#define Curr_Letter (toupper(word[w_idx])) +#define Curr_Letter (toupper((unsigned char)word[w_idx])) /* Go N letters back. */ -#define Look_Back_Letter(n) (w_idx >= n ? toupper(word[w_idx-n]) : '\0') +#define Look_Back_Letter(n) (w_idx >= n ? toupper((unsigned char)word[w_idx-n]) : '\0') /* Previous letter. I dunno, should this return null on failure? */ #define Prev_Letter (Look_Back_Letter(1)) /* Look two letters down. It makes sure you don't walk off the string. */ -#define After_Next_Letter (Next_Letter != '\0' ? toupper(word[w_idx+2]) \ +#define After_Next_Letter (Next_Letter != '\0' ? toupper((unsigned char)word[w_idx+2]) \ : '\0') -#define Look_Ahead_Letter(n) (toupper(Lookahead((char *) word+w_idx, n))) +#define Look_Ahead_Letter(n) (toupper((unsigned char)Lookahead((char *) word+w_idx, n))) /* Allows us to safely look ahead an arbitrary # of letters */ @@ -161,7 +161,7 @@ static char Lookahead(char *word, size_t how_far) #define Phone_Len (p_idx) /* Note is a letter is a 'break' in the word */ -#define Isbreak(c) (!isalpha(c)) +#define Isbreak(c) (!isalpha((unsigned char)(c))) /* {{{ metaphone */ @@ -196,7 +196,7 @@ static int metaphone(unsigned char *word, size_t word_len, zend_long max_phoneme /*-- The first phoneme has to be processed specially. --*/ /* Find our first letter */ - for (; !isalpha(Curr_Letter); w_idx++) { + for (; !isalpha((unsigned char)Curr_Letter); w_idx++) { /* On the off chance we were given nothing but crap... */ if (Curr_Letter == '\0') { End_Phoned_Word @@ -280,7 +280,7 @@ static int metaphone(unsigned char *word, size_t word_len, zend_long max_phoneme */ /* Ignore non-alphas */ - if (!isalpha(Curr_Letter)) + if (!isalpha((unsigned char)Curr_Letter)) continue; /* Drop duplicates, except CC */ diff --git a/ext/standard/quot_print.c b/ext/standard/quot_print.c index 336a4cc0bb4..22e48fd702c 100644 --- a/ext/standard/quot_print.c +++ b/ext/standard/quot_print.c @@ -219,11 +219,11 @@ PHP_FUNCTION(quoted_printable_decode) switch (str_in[i]) { case '=': if (str_in[i + 1] && str_in[i + 2] && - isxdigit((int) str_in[i + 1]) && - isxdigit((int) str_in[i + 2])) + isxdigit((unsigned char)str_in[i + 1]) && + isxdigit((unsigned char)str_in[i + 2])) { - ZSTR_VAL(str_out)[j++] = (php_hex2int((int) str_in[i + 1]) << 4) - + php_hex2int((int) str_in[i + 2]); + ZSTR_VAL(str_out)[j++] = (php_hex2int((unsigned char)str_in[i + 1]) << 4) + + php_hex2int((unsigned char)str_in[i + 2]); i += 3; } else /* check for soft line break according to RFC 2045*/ { k = 1; diff --git a/ext/standard/scanf.c b/ext/standard/scanf.c index fc483159737..d62b910dbd9 100644 --- a/ext/standard/scanf.c +++ b/ext/standard/scanf.c @@ -345,7 +345,7 @@ PHPAPI int ValidateFormat(char *format, int numVars, int *totalSubs) goto xpgCheckDone; } - if ( isdigit( (int)*ch ) ) { + if ( isdigit( (unsigned char)*ch ) ) { /* * Check for an XPG3-style %n$ specification. Note: there * must not be a mixture of XPG3 specs and non-XPG3 specs @@ -664,9 +664,9 @@ PHPAPI int php_sscanf_internal( char *string, char *format, /* * If we see whitespace in the format, skip whitespace in the string. */ - if ( isspace( (int)*ch ) ) { + if ( isspace( (unsigned char)*ch ) ) { sch = *string; - while ( isspace( (int)sch ) ) { + while ( isspace( (unsigned char)sch ) ) { if (*string == '\0') { goto done; } @@ -817,7 +817,7 @@ literal: if (!(flags & SCAN_NOSKIP)) { while (*string != '\0') { sch = *string; - if (! isspace((int)sch) ) { + if (! isspace((unsigned char)sch) ) { break; } string++; @@ -843,7 +843,7 @@ literal: end = string; while (*end != '\0') { sch = *end; - if ( isspace( (int)sch ) ) { + if ( isspace( (unsigned char)sch ) ) { break; } end++; diff --git a/ext/standard/soundex.c b/ext/standard/soundex.c index 0f46fbfdfe8..7530e249ddf 100644 --- a/ext/standard/soundex.c +++ b/ext/standard/soundex.c @@ -74,7 +74,7 @@ PHP_FUNCTION(soundex) /* BUG: should also map here accented letters used in non */ /* English words or names (also found in English text!): */ /* esstsett, thorn, n-tilde, c-cedilla, s-caron, ... */ - code = toupper((int)(unsigned char)str[i]); + code = toupper((unsigned char)str[i]); if (code >= 'A' && code <= 'Z') { if (_small == 0) { /* remember first valid char */ diff --git a/ext/standard/string.c b/ext/standard/string.c index 825d1b7fe43..7d370450c67 100644 --- a/ext/standard/string.c +++ b/ext/standard/string.c @@ -3773,9 +3773,9 @@ PHPAPI void php_stripcslashes(zend_string *str) case 'f': *target++='\f'; nlen--; break; case '\\': *target++='\\'; nlen--; break; case 'x': - if (source+1 < end && isxdigit((int)(*(source+1)))) { + if (source+1 < end && isxdigit((unsigned char)source[1])) { numtmp[0] = *++source; - if (source+1 < end && isxdigit((int)(*(source+1)))) { + if (source+1 < end && isxdigit((unsigned char)source[1])) { numtmp[1] = *++source; numtmp[2] = '\0'; nlen-=3; @@ -4636,7 +4636,7 @@ static void php_hebrev(INTERNAL_FUNCTION_PARAMETERS, int convert_newlines) do { if (block_type == _HEB_BLOCK_TYPE_HEB) { - while ((isheb((int)*(tmp+1)) || _isblank((int)*(tmp+1)) || ispunct((int)*(tmp+1)) || (int)*(tmp+1)=='\n' ) && block_end block_start) { + while ((_isblank((int)*tmp) || ispunct((unsigned char)*tmp)) && *tmp!='/' && *tmp!='-' && block_end > block_start) { tmp--; block_end--; } @@ -5113,7 +5113,7 @@ int php_tag_find(char *tag, size_t len, const char *set) { done =1; break; default: - if (!isspace((int)c)) { + if (!isspace((unsigned char)c)) { if (state == 0) { state=1; } @@ -5215,7 +5215,7 @@ state_0: if (in_q) { break; } - if (isspace(*(p + 1)) && !allow_tag_spaces) { + if (isspace((unsigned char)p[1]) && !allow_tag_spaces) { *(rp++) = c; break; } @@ -5262,7 +5262,7 @@ state_1: if (in_q) { break; } - if (isspace(*(p + 1)) && !allow_tag_spaces) { + if (isspace((unsigned char)p[1]) && !allow_tag_spaces) { goto reg_char_1; } depth++; diff --git a/ext/standard/strnatcmp.c b/ext/standard/strnatcmp.c index 72ed5e142dd..dc091b4dad4 100644 --- a/ext/standard/strnatcmp.c +++ b/ext/standard/strnatcmp.c @@ -41,12 +41,12 @@ compare_right(char const **a, char const *aend, char const **b, char const *bend both numbers to know that they have the same magnitude, so we remember it in BIAS. */ for(;; (*a)++, (*b)++) { - if ((*a == aend || !isdigit((int)(unsigned char)**a)) && - (*b == bend || !isdigit((int)(unsigned char)**b))) + if ((*a == aend || !isdigit((unsigned char)**a)) && + (*b == bend || !isdigit((unsigned char)**b))) return bias; - else if (*a == aend || !isdigit((int)(unsigned char)**a)) + else if (*a == aend || !isdigit((unsigned char)**a)) return -1; - else if (*b == bend || !isdigit((int)(unsigned char)**b)) + else if (*b == bend || !isdigit((unsigned char)**b)) return +1; else if (**a < **b) { if (!bias) @@ -69,12 +69,12 @@ compare_left(char const **a, char const *aend, char const **b, char const *bend) /* Compare two left-aligned numbers: the first to have a different value wins. */ for(;; (*a)++, (*b)++) { - if ((*a == aend || !isdigit((int)(unsigned char)**a)) && - (*b == bend || !isdigit((int)(unsigned char)**b))) + if ((*a == aend || !isdigit((unsigned char)**a)) && + (*b == bend || !isdigit((unsigned char)**b))) return 0; - else if (*a == aend || !isdigit((int)(unsigned char)**a)) + else if (*a == aend || !isdigit((unsigned char)**a)) return -1; - else if (*b == bend || !isdigit((int)(unsigned char)**b)) + else if (*b == bend || !isdigit((unsigned char)**b)) return +1; else if (**a < **b) return -1; @@ -107,27 +107,27 @@ PHPAPI int strnatcmp_ex(char const *a, size_t a_len, char const *b, size_t b_len ca = *ap; cb = *bp; /* skip over leading zeros */ - while (leading && ca == '0' && (ap+1 < aend) && isdigit((int)(unsigned char)*(ap+1))) { + while (leading && ca == '0' && (ap+1 < aend) && isdigit((unsigned char)ap[1])) { ca = *++ap; } - while (leading && cb == '0' && (bp+1 < bend) && isdigit((int)(unsigned char)*(bp+1))) { + while (leading && cb == '0' && (bp+1 < bend) && isdigit((unsigned char)bp[1])) { cb = *++bp; } leading = 0; /* Skip consecutive whitespace */ - while (isspace((int)(unsigned char)ca)) { + while (isspace(ca)) { ca = *++ap; } - while (isspace((int)(unsigned char)cb)) { + while (isspace(cb)) { cb = *++bp; } /* process run of digits */ - if (isdigit((int)(unsigned char)ca) && isdigit((int)(unsigned char)cb)) { + if (isdigit(ca) && isdigit(cb)) { fractional = (ca == '0' || cb == '0'); if (fractional) @@ -151,8 +151,8 @@ PHPAPI int strnatcmp_ex(char const *a, size_t a_len, char const *b, size_t b_len } if (fold_case) { - ca = toupper((int)(unsigned char)ca); - cb = toupper((int)(unsigned char)cb); + ca = toupper(ca); + cb = toupper(cb); } if (ca < cb) diff --git a/ext/standard/type.c b/ext/standard/type.c index d2e267bb3f8..82d7a1bf27a 100644 --- a/ext/standard/type.c +++ b/ext/standard/type.c @@ -121,7 +121,7 @@ PHP_FUNCTION(intval) char *strval = Z_STRVAL_P(num); size_t strlen = Z_STRLEN_P(num); - while (isspace(*strval) && strlen) { + while (isspace((unsigned char)*strval) && strlen) { strval++; strlen--; } diff --git a/ext/standard/url.c b/ext/standard/url.c index eaad48a1ba4..900523e33d2 100644 --- a/ext/standard/url.c +++ b/ext/standard/url.c @@ -124,7 +124,7 @@ PHPAPI php_url *php_url_parse_ex2(char const *str, size_t length, zend_bool *has p = s; while (p < e) { /* scheme = 1*[ lowalpha | digit | "+" | "-" | "." ] */ - if (!isalpha(*p) && !isdigit(*p) && *p != '+' && *p != '.' && *p != '-') { + if (!isalpha((unsigned char)*p) && !isdigit((unsigned char)*p) && *p != '+' && *p != '.' && *p != '-') { if (e + 1 < ue && e < binary_strcspn(s, ue, "?#")) { goto parse_port; } else if (s + 1 < ue && *s == '/' && *(s + 1) == '/') { /* relative-scheme URL */ @@ -153,7 +153,7 @@ PHPAPI php_url *php_url_parse_ex2(char const *str, size_t length, zend_bool *has * correctly parse things like a.com:80 */ p = e + 1; - while (p < ue && isdigit(*p)) { + while (p < ue && isdigit((unsigned char)*p)) { p++; } @@ -193,7 +193,7 @@ PHPAPI php_url *php_url_parse_ex2(char const *str, size_t length, zend_bool *has p = e + 1; pp = p; - while (pp < ue && pp - p < 6 && isdigit(*pp)) { + while (pp < ue && pp - p < 6 && isdigit((unsigned char)*pp)) { pp++; } @@ -434,12 +434,12 @@ static int php_htoi(char *s) int value; int c; - c = ((unsigned char *)s)[0]; + c = (unsigned char)s[0]; if (isupper(c)) c = tolower(c); value = (c >= '0' && c <= '9' ? c - '0' : c - 'a' + 10) * 16; - c = ((unsigned char *)s)[1]; + c = (unsigned char)s[1]; if (isupper(c)) c = tolower(c); value += c >= '0' && c <= '9' ? c - '0' : c - 'a' + 10; @@ -553,8 +553,8 @@ PHPAPI size_t php_url_decode(char *str, size_t len) if (*data == '+') { *dest = ' '; } - else if (*data == '%' && len >= 2 && isxdigit((int) *(data + 1)) - && isxdigit((int) *(data + 2))) { + else if (*data == '%' && len >= 2 && isxdigit((unsigned char)data[1]) + && isxdigit((unsigned char)data[2])) { #ifndef CHARSET_EBCDIC *dest = (char) php_htoi(data + 1); #else @@ -649,8 +649,8 @@ PHPAPI size_t php_raw_url_decode(char *str, size_t len) char *data = str; while (len--) { - if (*data == '%' && len >= 2 && isxdigit((int) *(data + 1)) - && isxdigit((int) *(data + 2))) { + if (*data == '%' && len >= 2 && isxdigit((unsigned char)data[1]) + && isxdigit((unsigned char)data[2])) { #ifndef CHARSET_EBCDIC *dest = (char) php_htoi(data + 1); #else @@ -716,7 +716,7 @@ no_name_header: c = *p; *p = '\0'; s = p + 1; - while (isspace((int)*(unsigned char *)s)) { + while (isspace((unsigned char)*s)) { s++; } diff --git a/ext/standard/url_scanner_ex.re b/ext/standard/url_scanner_ex.re index 1877e689180..ec3caa6f36e 100644 --- a/ext/standard/url_scanner_ex.re +++ b/ext/standard/url_scanner_ex.re @@ -87,7 +87,7 @@ static int php_ini_on_update_tags(zend_ini_entry *entry, zend_string *new_value, *val++ = '\0'; for (q = key; *q; q++) { - *q = tolower(*q); + *q = tolower((unsigned char)*q); } keylen = q - key; str = zend_string_init(key, keylen, 1); @@ -136,7 +136,7 @@ static int php_ini_on_update_hosts(zend_ini_entry *entry, zend_string *new_value char *q; for (q = key; *q; q++) { - *q = tolower(*q); + *q = tolower((unsigned char)*q); } keylen = q - key; if (keylen > 0) { @@ -456,7 +456,7 @@ static inline void handle_tag(STD_PARA) } smart_str_appendl(&ctx->tag, start, YYCURSOR - start); for (i = 0; i < ZSTR_LEN(ctx->tag.s); i++) - ZSTR_VAL(ctx->tag.s)[i] = tolower((int)(unsigned char)ZSTR_VAL(ctx->tag.s)[i]); + ZSTR_VAL(ctx->tag.s)[i] = tolower((unsigned char)ZSTR_VAL(ctx->tag.s)[i]); /* intentionally using str_find here, in case the hash value is set, but the string val is changed later */ if ((ctx->lookup_data = zend_hash_str_find_ptr(ctx->tags, ZSTR_VAL(ctx->tag.s), ZSTR_LEN(ctx->tag.s))) != NULL) { ok = 1; diff --git a/ext/standard/versioning.c b/ext/standard/versioning.c index e4353130d63..fa361bb9b28 100644 --- a/ext/standard/versioning.c +++ b/ext/standard/versioning.c @@ -47,8 +47,8 @@ php_canonicalize_version(const char *version) * s/([^\d\.])([^\D\.])/$1.$2/g; * s/([^\D\.])([^\d\.])/$1.$2/g; */ -#define isdig(x) (isdigit(x)&&(x)!='.') -#define isndig(x) (!isdigit(x)&&(x)!='.') +#define isdig(x) (isdigit((unsigned char)(x))&&(x)!='.') +#define isndig(x) (!isdigit((unsigned char)(x))&&(x)!='.') #define isspecialver(x) ((x)=='-'||(x)=='_'||(x)=='+') lq = *(q - 1); @@ -61,7 +61,7 @@ php_canonicalize_version(const char *version) *q++ = '.'; } *q++ = *p; - } else if (!isalnum(*p)) { + } else if (!isalnum((unsigned char)*p)) { if (lq != '.') { *q++ = '.'; } @@ -154,17 +154,17 @@ php_version_compare(const char *orig_ver1, const char *orig_ver2) if ((n2 = strchr(p2, '.')) != NULL) { *n2 = '\0'; } - if (isdigit(*p1) && isdigit(*p2)) { + if (isdigit((unsigned char)*p1) && isdigit((unsigned char)*p2)) { /* compare element numerically */ l1 = strtol(p1, NULL, 10); l2 = strtol(p2, NULL, 10); compare = ZEND_NORMALIZE_BOOL(l1 - l2); - } else if (!isdigit(*p1) && !isdigit(*p2)) { + } else if (!isdigit((unsigned char)*p1) && !isdigit((unsigned char)*p2)) { /* compare element names */ compare = compare_special_version_forms(p1, p2); } else { /* mix of names and numbers */ - if (isdigit(*p1)) { + if (isdigit((unsigned char)*p1)) { compare = compare_special_version_forms("#N#", p2); } else { compare = compare_special_version_forms(p1, "#N#"); @@ -182,13 +182,13 @@ php_version_compare(const char *orig_ver1, const char *orig_ver2) } if (compare == 0) { if (n1 != NULL) { - if (isdigit(*p1)) { + if (isdigit((unsigned char)*p1)) { compare = 1; } else { compare = php_version_compare(p1, "#N#"); } } else if (n2 != NULL) { - if (isdigit(*p2)) { + if (isdigit((unsigned char)*p2)) { compare = -1; } else { compare = php_version_compare("#N#", p2); diff --git a/main/SAPI.c b/main/SAPI.c index a5a68f8c680..e4f8d49ce01 100644 --- a/main/SAPI.c +++ b/main/SAPI.c @@ -195,7 +195,7 @@ static void sapi_read_post_data(void) *p = 0; break; default: - *p = tolower(*p); + *p = tolower((unsigned char)*p); break; } } @@ -704,10 +704,10 @@ SAPI_API int sapi_header_op(sapi_header_op_enum op, void *arg) header_line = estrndup(header_line, header_line_len); /* cut off trailing spaces, linefeeds and carriage-returns */ - if (header_line_len && isspace(header_line[header_line_len-1])) { + if (header_line_len && isspace((unsigned char)header_line[header_line_len - 1])) { do { header_line_len--; - } while(header_line_len && isspace(header_line[header_line_len-1])); + } while(header_line_len && isspace((unsigned char)header_line[header_line_len - 1])); header_line[header_line_len]='\0'; } diff --git a/main/fopen_wrappers.c b/main/fopen_wrappers.c index 90de040a218..b7173df26a5 100644 --- a/main/fopen_wrappers.c +++ b/main/fopen_wrappers.c @@ -493,7 +493,7 @@ PHPAPI zend_string *php_resolve_path(const char *filename, size_t filename_lengt } /* Don't resolve paths which contain protocol (except of file://) */ - for (p = filename; isalnum((int)*p) || *p == '+' || *p == '-' || *p == '.'; p++); + for (p = filename; isalnum((unsigned char)*p) || *p == '+' || *p == '-' || *p == '.'; p++); if ((*p == ':') && (p - filename > 1) && (p[1] == '/') && (p[2] == '/')) { wrapper = php_stream_locate_url_wrapper(filename, &actual_path, STREAM_OPEN_FOR_INCLUDE); if (wrapper == &php_plain_files_wrapper) { @@ -529,7 +529,7 @@ PHPAPI zend_string *php_resolve_path(const char *filename, size_t filename_lengt /* Check for stream wrapper */ int is_stream_wrapper = 0; - for (p = ptr; isalnum((int)*p) || *p == '+' || *p == '-' || *p == '.'; p++); + for (p = ptr; isalnum((unsigned char)*p) || *p == '+' || *p == '-' || *p == '.'; p++); if ((*p == ':') && (p - ptr > 1) && (p[1] == '/') && (p[2] == '/')) { /* .:// or ..:// is not a stream wrapper */ if (p[-1] != '.' || p[-2] != '.' || p - 2 != ptr) { @@ -598,7 +598,7 @@ PHPAPI zend_string *php_resolve_path(const char *filename, size_t filename_lengt actual_path = trypath; /* Check for stream wrapper */ - for (p = trypath; isalnum((int)*p) || *p == '+' || *p == '-' || *p == '.'; p++); + for (p = trypath; isalnum((unsigned char)*p) || *p == '+' || *p == '-' || *p == '.'; p++); if ((*p == ':') && (p - trypath > 1) && (p[1] == '/') && (p[2] == '/')) { wrapper = php_stream_locate_url_wrapper(trypath, &actual_path, STREAM_OPEN_FOR_INCLUDE); if (!wrapper) { diff --git a/main/php_ini.c b/main/php_ini.c index cc2cf16cf8b..8d5b5811541 100644 --- a/main/php_ini.c +++ b/main/php_ini.c @@ -42,7 +42,7 @@ char *tmp = path; \ while (*tmp) { \ if (*tmp == '\\') *tmp = '/'; \ - else *tmp = tolower(*tmp); \ + else *tmp = tolower((unsigned char)*tmp); \ tmp++; \ } \ } diff --git a/main/php_variables.c b/main/php_variables.c index e971d497337..de2f7e83fc6 100644 --- a/main/php_variables.c +++ b/main/php_variables.c @@ -196,7 +196,7 @@ PHPAPI void php_register_variable_ex(char *var_name, zval *val, zval *track_vars ip++; index_s = ip; - if (isspace(*ip)) { + if (isspace((unsigned char)*ip)) { ip++; } if (*ip==']') { @@ -513,7 +513,7 @@ SAPI_API SAPI_TREAT_DATA_FUNC(php_default_treat_data) if (arg == PARSE_COOKIE) { /* Remove leading spaces from cookie names, needed for multi-cookie header where ; can be followed by a space */ - while (isspace(*var)) { + while (isspace((unsigned char)*var)) { var++; } if (var == val || *var == '\0') { diff --git a/main/rfc1867.c b/main/rfc1867.c index 43ccce120c3..704e1455dcb 100644 --- a/main/rfc1867.c +++ b/main/rfc1867.c @@ -421,7 +421,7 @@ static int multipart_buffer_headers(multipart_buffer *self, zend_llist *header) } /* space in the beginning means same header */ - if (!isspace(line[0])) { + if (!isspace((unsigned char)line[0])) { value = strchr(line, ':'); } @@ -437,7 +437,7 @@ static int multipart_buffer_headers(multipart_buffer *self, zend_llist *header) } *value = '\0'; - do { value++; } while (isspace(*value)); + do { value++; } while (isspace((unsigned char)*value)); key = estrdup(line); smart_string_appends(&buf_value, value); @@ -534,7 +534,7 @@ static char *substring_conf(char *start, int len, char quote) static char *php_ap_getword_conf(const zend_encoding *encoding, char *str) { - while (*str && isspace(*str)) { + while (*str && isspace((unsigned char)*str)) { ++str; } @@ -550,7 +550,7 @@ static char *php_ap_getword_conf(const zend_encoding *encoding, char *str) } else { char *strend = str; - while (*strend && !isspace(*strend)) { + while (*strend && !isspace((unsigned char)*strend)) { ++strend; } return substring_conf(str, strend - str, 0); @@ -817,7 +817,7 @@ SAPI_API SAPI_POST_HANDLER_FUNC(rfc1867_post_handler) /* {{{ */ goto fileupload_done; } - while (isspace(*cd)) { + while (isspace((unsigned char)*cd)) { ++cd; } @@ -825,7 +825,7 @@ SAPI_API SAPI_POST_HANDLER_FUNC(rfc1867_post_handler) /* {{{ */ { char *key = NULL, *word = pair; - while (isspace(*cd)) { + while (isspace((unsigned char)*cd)) { ++cd; } diff --git a/main/snprintf.c b/main/snprintf.c index 61a5dfffce4..01d605cc9d0 100644 --- a/main/snprintf.c +++ b/main/snprintf.c @@ -391,7 +391,7 @@ PHPAPI char * php_conv_fp(register char format, register double num, /* * Check for Infinity and NaN */ - if (isalpha((int)*p)) { + if (isalpha((unsigned char)*p)) { *len = strlen(p); memcpy(buf, p, *len + 1); *is_negative = FALSE; @@ -538,11 +538,11 @@ typedef struct buf_area buffy; #define NUM( c ) ( c - '0' ) #define STR_TO_DEC( str, num ) \ - num = NUM( *str++ ) ; \ - while ( isdigit((int)*str ) ) \ + num = NUM( *(str)++ ) ; \ + while ( isdigit((unsigned char)*(str) ) ) \ { \ num *= 10 ; \ - num += NUM( *str++ ) ; \ + num += NUM( *(str)++ ) ; \ } /* @@ -646,7 +646,7 @@ static int format_converter(register buffy * odp, const char *fmt, va_list ap) / /* * Try to avoid checking for flags, width or precision */ - if (isascii((int)*fmt) && !islower((int)*fmt)) { + if (isascii((unsigned char)*fmt) && !islower((unsigned char)*fmt)) { /* * Recognize flags: -, #, BLANK, + */ @@ -668,7 +668,7 @@ static int format_converter(register buffy * odp, const char *fmt, va_list ap) / /* * Check if a width was specified */ - if (isdigit((int)*fmt)) { + if (isdigit((unsigned char)*fmt)) { STR_TO_DEC(fmt, min_width); adjust_width = YES; } else if (*fmt == '*') { @@ -688,7 +688,7 @@ static int format_converter(register buffy * odp, const char *fmt, va_list ap) / if (*fmt == '.') { adjust_precision = YES; fmt++; - if (isdigit((int)*fmt)) { + if (isdigit((unsigned char)*fmt)) { STR_TO_DEC(fmt, precision); } else if (*fmt == '*') { precision = va_arg(ap, int); diff --git a/main/spprintf.c b/main/spprintf.c index a20705016a1..ef90f9b2d28 100644 --- a/main/spprintf.c +++ b/main/spprintf.c @@ -152,12 +152,12 @@ #define NUM(c) (c - '0') #define STR_TO_DEC(str, num) do { \ - num = NUM(*str++); \ - while (isdigit((int)*str)) { \ + num = NUM(*(str)++); \ + while (isdigit((unsigned char)*(str))) {\ num *= 10; \ - num += NUM(*str++); \ + num += NUM(*(str)++); \ if (num >= INT_MAX / 10) { \ - while (isdigit((int)*str++)); \ + while (isdigit((unsigned char)*(str)++)); \ break; \ } \ } \ @@ -246,7 +246,7 @@ static void xbuf_format_converter(void *xbuf, zend_bool is_char, const char *fmt /* * Try to avoid checking for flags, width or precision */ - if (isascii((int)*fmt) && !islower((int)*fmt)) { + if (isascii((unsigned char)*fmt) && !islower((unsigned char)*fmt)) { /* * Recognize flags: -, #, BLANK, + */ @@ -268,7 +268,7 @@ static void xbuf_format_converter(void *xbuf, zend_bool is_char, const char *fmt /* * Check if a width was specified */ - if (isdigit((int)*fmt)) { + if (isdigit((unsigned char)*fmt)) { STR_TO_DEC(fmt, min_width); adjust_width = YES; } else if (*fmt == '*') { @@ -288,7 +288,7 @@ static void xbuf_format_converter(void *xbuf, zend_bool is_char, const char *fmt if (*fmt == '.') { adjust_precision = YES; fmt++; - if (isdigit((int)*fmt)) { + if (isdigit((unsigned char)*fmt)) { STR_TO_DEC(fmt, precision); } else if (*fmt == '*') { precision = va_arg(ap, int); diff --git a/main/streams/streams.c b/main/streams/streams.c index a320a90b525..8f368d4accf 100644 --- a/main/streams/streams.c +++ b/main/streams/streams.c @@ -1750,7 +1750,7 @@ static inline int php_stream_wrapper_scheme_validate(const char *protocol, unsig unsigned int i; for(i = 0; i < protocol_len; i++) { - if (!isalnum((int)protocol[i]) && + if (!isalnum((unsigned char)protocol[i]) && protocol[i] != '+' && protocol[i] != '-' && protocol[i] != '.') { @@ -1830,7 +1830,7 @@ PHPAPI php_stream_wrapper *php_stream_locate_url_wrapper(const char *path, const return (php_stream_wrapper*)((options & STREAM_LOCATE_WRAPPERS_ONLY) ? NULL : &php_plain_files_wrapper); } - for (p = path; isalnum((int)*p) || *p == '+' || *p == '-' || *p == '.'; p++) { + for (p = path; isalnum((unsigned char)*p) || *p == '+' || *p == '-' || *p == '.'; p++) { n++; } diff --git a/main/streams/transports.c b/main/streams/transports.c index 74fbef58d84..51f0ab35ea4 100644 --- a/main/streams/transports.c +++ b/main/streams/transports.c @@ -95,7 +95,7 @@ PHPAPI php_stream *_php_stream_xport_create(const char *name, size_t namelen, in } } - for (p = name; isalnum((int)*p) || *p == '+' || *p == '-' || *p == '.'; p++) { + for (p = name; isalnum((unsigned char)*p) || *p == '+' || *p == '-' || *p == '.'; p++) { n++; } diff --git a/sapi/cli/php_cli_server.c b/sapi/cli/php_cli_server.c index 8717dc57418..2ea81763517 100644 --- a/sapi/cli/php_cli_server.c +++ b/sapi/cli/php_cli_server.c @@ -673,7 +673,7 @@ static int sapi_cli_server_register_entry_cb(char **entry, int num_args, va_list if (key[i] == '-') { key[i] = '_'; } else { - key[i] = toupper(key[i]); + key[i] = toupper((unsigned char)key[i]); } } spprintf(&real_key, 0, "%s_%s", "HTTP", key); diff --git a/sapi/fpm/fpm/fpm_conf.c b/sapi/fpm/fpm/fpm_conf.c index 7a052863091..d7af7bf0e69 100644 --- a/sapi/fpm/fpm/fpm_conf.c +++ b/sapi/fpm/fpm/fpm_conf.c @@ -875,7 +875,7 @@ static int fpm_conf_process_all_pools() /* {{{ */ } for (i = 0; i < strlen(status); i++) { - if (!isalnum(status[i]) && status[i] != '/' && status[i] != '-' && status[i] != '_' && status[i] != '.' && status[i] != '~') { + if (!isalnum((unsigned char)status[i]) && status[i] != '/' && status[i] != '-' && status[i] != '_' && status[i] != '.' && status[i] != '~') { zlog(ZLOG_ERROR, "[pool %s] the status path '%s' must contain only the following characters '[alphanum]/_-.~'", wp->config->name, status); return -1; } @@ -898,7 +898,7 @@ static int fpm_conf_process_all_pools() /* {{{ */ } for (i = 0; i < strlen(ping); i++) { - if (!isalnum(ping[i]) && ping[i] != '/' && ping[i] != '-' && ping[i] != '_' && ping[i] != '.' && ping[i] != '~') { + if (!isalnum((unsigned char)ping[i]) && ping[i] != '/' && ping[i] != '-' && ping[i] != '_' && ping[i] != '.' && ping[i] != '~') { zlog(ZLOG_ERROR, "[pool %s] the ping path '%s' must containt only the following characters '[alphanum]/_-.~'", wp->config->name, ping); return -1; } diff --git a/sapi/litespeed/lsapi_main.c b/sapi/litespeed/lsapi_main.c index 94138107e62..74894f000f3 100644 --- a/sapi/litespeed/lsapi_main.c +++ b/sapi/litespeed/lsapi_main.c @@ -1738,12 +1738,12 @@ PHP_FUNCTION(litespeed_response_headers) len = p - h->header; if (p && len > 0 && len < LSAPI_RESP_HTTP_HEADER_MAX) { memmove( headerBuf, h->header, len ); - while( len > 0 && (isspace( headerBuf[len-1])) ) { + while( len > 0 && (isspace((unsigned char)headerBuf[len - 1])) ) { --len; } headerBuf[len] = 0; if ( len ) { - while( isspace(*++p)); + while(isspace((unsigned char)*++p)); add_assoc_string_ex(return_value, headerBuf, len, p); } } diff --git a/sapi/litespeed/lsapilib.c b/sapi/litespeed/lsapilib.c index 3dbf8bc2fae..60c4c06a620 100644 --- a/sapi/litespeed/lsapilib.c +++ b/sapi/litespeed/lsapilib.c @@ -2199,7 +2199,7 @@ static char * GetHeaderVar( LSAPI_Request * pReq, const char * name ) while(( pKey < pKeyEnd )&&( *p )) { - char ch = toupper( *pKey ); + char ch = toupper( (unsigned char)*pKey ); if ((ch != *p )||(( *p == '_' )&&( ch != '-'))) break; ++p; ++pKey; @@ -2383,7 +2383,7 @@ int LSAPI_ForeachHeader_r( LSAPI_Request * pReq, if ( ch == '-' ) *p++ = '_'; else - *p++ = toupper( ch ); + *p++ = toupper( (unsigned char)ch ); } *p = 0; keyLen += 5; @@ -2628,7 +2628,7 @@ int LSAPI_ParseSockAddr( const char * pBind, struct sockaddr * pAddr ) if ( !pBind ) return -1; - while( isspace( *pBind ) ) + while(isspace( (unsigned char)*pBind ) ) ++pBind; strncpy(achAddr, pBind, 255); diff --git a/sapi/phpdbg/phpdbg_cmd.c b/sapi/phpdbg/phpdbg_cmd.c index 4845acca9a5..8c79707919a 100644 --- a/sapi/phpdbg/phpdbg_cmd.c +++ b/sapi/phpdbg/phpdbg_cmd.c @@ -785,9 +785,9 @@ PHPDBG_API char *phpdbg_read_input(char *buffered) /* {{{ */ #endif } - if (buffer && isspace(*buffer)) { + if (buffer && isspace((unsigned char)*buffer)) { char *trimmed = buffer; - while (isspace(*trimmed)) + while (isspace((unsigned char)*trimmed)) trimmed++; trimmed = estrdup(trimmed); diff --git a/sapi/phpdbg/phpdbg_prompt.c b/sapi/phpdbg/phpdbg_prompt.c index 6b0de5c0214..0d2b2babcb9 100644 --- a/sapi/phpdbg/phpdbg_prompt.c +++ b/sapi/phpdbg/phpdbg_prompt.c @@ -221,7 +221,7 @@ static void phpdbg_line_init(char *cmd, struct phpdbg_init_state *state) { state->line++; - while (cmd_len > 0L && isspace(cmd[cmd_len-1])) { + while (cmd_len > 0L && isspace((unsigned char)cmd[cmd_len-1])) { cmd_len--; } diff --git a/sapi/phpdbg/phpdbg_utils.c b/sapi/phpdbg/phpdbg_utils.c index d32f2fb7f86..6176819ac90 100644 --- a/sapi/phpdbg/phpdbg_utils.c +++ b/sapi/phpdbg/phpdbg_utils.c @@ -85,10 +85,10 @@ PHPDBG_API int phpdbg_is_numeric(const char *str) /* {{{ */ return 0; for (; *str; str++) { - if (isspace(*str) || *str == '-') { + if (isspace((unsigned char)*str) || *str == '-') { continue; } - return isdigit(*str); + return isdigit((unsigned char)*str); } return 0; } /* }}} */ @@ -99,7 +99,7 @@ PHPDBG_API int phpdbg_is_empty(const char *str) /* {{{ */ return 1; for (; *str; str++) { - if (isspace(*str)) { + if (isspace((unsigned char)*str)) { continue; } return 0; @@ -202,12 +202,12 @@ PHPDBG_API char *phpdbg_trim(const char *str, size_t len, size_t *new_len) /* {{ const char *p = str; char *new = NULL; - while (p && isspace(*p)) { + while (p && isspace((unsigned char)*p)) { ++p; --len; } - while (*p && isspace(*(p + len -1))) { + while (*p && isspace((unsigned char)p[len - 1])) { --len; } diff --git a/win32/sendmail.c b/win32/sendmail.c index ee017374f49..bd6e3a2d986 100644 --- a/win32/sendmail.c +++ b/win32/sendmail.c @@ -57,7 +57,7 @@ efree(response); \ } \ } -#define SMTP_SKIP_SPACE(str) { while (isspace(*str)) { str++; } } +#define SMTP_SKIP_SPACE(str) { while (isspace((unsigned char)*(str))) { (str)++; } } char seps[] = " ,\t\n"; @@ -724,7 +724,7 @@ static int PostHeader(char *RPath, char *Subject, char *mailTo, char *xheaders) headers_lc_len = strlen(headers_lc); for (i = 0; i < headers_lc_len; i++) { - headers_lc[i] = tolower(headers_lc[i]); + headers_lc[i] = tolower((unsigned char)headers_lc[i]); } } @@ -852,7 +852,7 @@ return 0; /* Resolve the servers IP */ /* - if (!isdigit(PW32G(mail_host)[0])||!gethostbyname(PW32G(mail_host))) + if (!isdigit((unsigned char)PW32G(mail_host)[0])||!gethostbyname(PW32G(mail_host))) { return (FAILED_TO_RESOLVE_HOST); } -- 2.54.0 From 6b9f5d1673522bb3cf5d77889919084024565c7f Mon Sep 17 00:00:00 2001 From: Remi Collet Date: Thu, 7 May 2026 09:01:35 +0200 Subject: [PATCH 9/9] NEWS from 8.2.31 (cherry picked from commit 7dff10e9a31d469fcd436e10b06f8b2bf2758a68) (cherry picked from commit 1cbf0c27044bd54fb77de8a6bf993a7ab53892a4) --- NEWS | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/NEWS b/NEWS index f212d40b2e9..d4d668b3afb 100644 --- a/NEWS +++ b/NEWS @@ -1,6 +1,26 @@ PHP NEWS ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| +Backported from 8.2.31 + +- FPM: + . Fixed GHSA-7qg2-v9fj-4mwv (XSS within status endpoint). (CVE-2026-6735) + (Jakub Zelenka) + +- SOAP: + . Fixed GHSA-85c2-q967-79q5 (Stale SOAP_GLOBAL(ref_map) pointer with Apache + Map). (CVE-2026-6722) (ilutov) + . Fixed GHSA-m33r-qmcv-p97q (Use-after-free after header parsing failure with + SOAP_PERSISTENCE_SESSION). (CVE-2026-7261) (ilutov) + . Fixed GHSA-hmxp-6pc4-f3vv (Broken Apache map value NULL check). + (CVE-2026-7262) (ilutov) + +- Standard: + . Fixed GHSA-96wq-48vp-hh57 (Signed integer overflow of char array offset). + (CVE-2026-7568) (TimWolla) + . Fixed GHSA-m8rr-4c36-8gq4 (Consistently pass unsigned char to ctype.h + functions). (CVE-2026-7258) (ilutov) + Backported from 8.1.34 - Standard: -- 2.54.0