Skip to content

Commit dc9e21b

Browse files
committed
GHSA-m8rr-4c36-8gq4: Consistently pass unsigned char to ctype.h functions
Fixes GHSA-m8rr-4c36-8gq4 Fixes CVE-2026-7258
2 parents f5d445e + 398b7da commit dc9e21b

58 files changed

Lines changed: 179 additions & 179 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

Zend/zend_compile.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2188,7 +2188,7 @@ ZEND_API size_t zend_dirname(char *path, size_t len)
21882188
/* Note that on Win32 CWD is per drive (heritage from CP/M).
21892189
* This means dirname("c:foo") maps to "c:." or "c:" - which means CWD on C: drive.
21902190
*/
2191-
if ((2 <= len) && isalpha((int)((unsigned char *)path)[0]) && (':' == path[1])) {
2191+
if ((2 <= len) && isalpha((unsigned char)path[0]) && (':' == path[1])) {
21922192
/* Skip over the drive spec (if any) so as not to change */
21932193
path += 2;
21942194
len_adjust += 2;

Zend/zend_ini.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -595,7 +595,7 @@ static const char *zend_ini_consume_quantity_prefix(const char *const digits, co
595595
++digits_consumed;
596596
}
597597

598-
if (digits_consumed[0] == '0' && !isdigit(digits_consumed[1])) {
598+
if (digits_consumed[0] == '0' && !isdigit((unsigned char)digits_consumed[1])) {
599599
/* Value is just 0 */
600600
if ((digits_consumed+1) == str_end) {
601601
return digits_consumed;
@@ -653,7 +653,7 @@ static zend_ulong zend_ini_parse_quantity_internal(zend_string *value, zend_ini_
653653
}
654654

655655
/* if there is no digit after +/- */
656-
if (!isdigit(digits[0])) {
656+
if (!isdigit((unsigned char)digits[0])) {
657657
/* Escape the string to avoid null bytes and to make non-printable chars
658658
* visible */
659659
smart_str_append_escaped(&invalid, ZSTR_VAL(value), ZSTR_LEN(value));
@@ -667,7 +667,7 @@ static zend_ulong zend_ini_parse_quantity_internal(zend_string *value, zend_ini_
667667
}
668668

669669
int base = 0;
670-
if (digits[0] == '0' && !isdigit(digits[1])) {
670+
if (digits[0] == '0' && !isdigit((unsigned char)digits[1])) {
671671
/* Value is just 0 */
672672
if ((digits+1) == str_end) {
673673
*errstr = NULL;

Zend/zend_operators.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3254,8 +3254,8 @@ ZEND_API int ZEND_FASTCALL zend_binary_strcasecmp_l(const char *s1, size_t len1,
32543254

32553255
len = MIN(len1, len2);
32563256
while (len--) {
3257-
c1 = zend_tolower((int)*(unsigned char *)s1++);
3258-
c2 = zend_tolower((int)*(unsigned char *)s2++);
3257+
c1 = zend_tolower((unsigned char)*(s1++));
3258+
c2 = zend_tolower((unsigned char)*(s2++));
32593259
if (c1 != c2) {
32603260
return c1 - c2;
32613261
}
@@ -3275,8 +3275,8 @@ ZEND_API int ZEND_FASTCALL zend_binary_strncasecmp_l(const char *s1, size_t len1
32753275
}
32763276
len = MIN(length, MIN(len1, len2));
32773277
while (len--) {
3278-
c1 = zend_tolower((int)*(unsigned char *)s1++);
3279-
c2 = zend_tolower((int)*(unsigned char *)s2++);
3278+
c1 = zend_tolower((unsigned char)*(s1++));
3279+
c2 = zend_tolower((unsigned char)*(s2++));
32803280
if (c1 != c2) {
32813281
return c1 - c2;
32823282
}

Zend/zend_virtual_cwd.c

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -195,7 +195,7 @@ void virtual_cwd_main_cwd_init(uint8_t reinit) /* {{{ */
195195
main_cwd_state.cwd_length = strlen(cwd);
196196
#ifdef ZEND_WIN32
197197
if (main_cwd_state.cwd_length >= 2 && cwd[1] == ':') {
198-
cwd[0] = toupper(cwd[0]);
198+
cwd[0] = toupper((unsigned char)cwd[0]);
199199
}
200200
#endif
201201
main_cwd_state.cwd = strdup(cwd);
@@ -271,7 +271,7 @@ CWD_API char *virtual_getcwd_ex(size_t *length) /* {{{ */
271271
*length = state->cwd_length+1;
272272
retval = (char *) emalloc(*length+1);
273273
memcpy(retval, state->cwd, *length);
274-
retval[0] = toupper(retval[0]);
274+
retval[0] = toupper((unsigned char)retval[0]);
275275
retval[*length-1] = DEFAULT_SLASH;
276276
retval[*length] = '\0';
277277
return retval;
@@ -1113,21 +1113,21 @@ CWD_API int virtual_file_ex(cwd_state *state, const char *path, verify_path_func
11131113
if (resolved_path[start] == 0) {
11141114
goto verify;
11151115
}
1116-
resolved_path[start] = toupper(resolved_path[start]);
1116+
resolved_path[start] = toupper((unsigned char)resolved_path[start]);
11171117
start++;
11181118
}
11191119
resolved_path[start++] = DEFAULT_SLASH;
11201120
while (!IS_SLASH(resolved_path[start])) {
11211121
if (resolved_path[start] == 0) {
11221122
goto verify;
11231123
}
1124-
resolved_path[start] = toupper(resolved_path[start]);
1124+
resolved_path[start] = toupper((unsigned char)resolved_path[start]);
11251125
start++;
11261126
}
11271127
resolved_path[start++] = DEFAULT_SLASH;
11281128
} else if (IS_ABSOLUTE_PATH(resolved_path, path_length)) {
11291129
/* skip DRIVE name */
1130-
resolved_path[0] = toupper(resolved_path[0]);
1130+
resolved_path[0] = toupper((unsigned char)resolved_path[0]);
11311131
resolved_path[2] = DEFAULT_SLASH;
11321132
if (path_length == 2) {
11331133
resolved_path[3] = '\0';

Zend/zend_virtual_cwd.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,7 @@ typedef unsigned short mode_t;
8787
#define IS_UNC_PATH(path, len) \
8888
(len >= 2 && IS_SLASH(path[0]) && IS_SLASH(path[1]))
8989
#define IS_ABSOLUTE_PATH(path, len) \
90-
(len >= 2 && (/* is local */isalpha(path[0]) && path[1] == ':' || /* is UNC */IS_SLASH(path[0]) && IS_SLASH(path[1])))
90+
(len >= 2 && (/* is local */isalpha((unsigned char)(path)[0]) && path[1] == ':' || /* is UNC */IS_SLASH(path[0]) && IS_SLASH(path[1])))
9191

9292
#else
9393
#ifdef HAVE_DIRENT_H

ext/com_dotnet/com_extension.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -118,11 +118,11 @@ static PHP_INI_MH(OnTypeLibFileUpdate)
118118
}
119119

120120
/* Remove leading/training white spaces on search_string */
121-
while (isspace(*typelib_name)) {/* Ends on '\0' in worst case */
121+
while (isspace((unsigned char)*typelib_name)) {/* Ends on '\0' in worst case */
122122
typelib_name ++;
123123
}
124124
ptr = typelib_name + strlen(typelib_name) - 1;
125-
while ((ptr != typelib_name) && isspace(*ptr)) {
125+
while ((ptr != typelib_name) && isspace((unsigned char)*ptr)) {
126126
*ptr = '\0';
127127
ptr--;
128128
}

ext/date/lib/parse_date.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -518,7 +518,7 @@ static timelib_sll timelib_get_nr(const char **ptr, int max_length)
518518

519519
static void timelib_skip_day_suffix(const char **ptr)
520520
{
521-
if (isspace(**ptr)) {
521+
if (isspace((unsigned char)**ptr)) {
522522
return;
523523
}
524524
if (!timelib_strncasecmp(*ptr, "nd", 2) || !timelib_strncasecmp(*ptr, "rd", 2) ||!timelib_strncasecmp(*ptr, "st", 2) || !timelib_strncasecmp(*ptr, "th", 2)) {
@@ -859,7 +859,7 @@ static timelib_long timelib_parse_tz_cor(const char **ptr, int *tz_not_found)
859859

860860
*tz_not_found = 1;
861861

862-
while (isdigit(**ptr) || **ptr == ':') {
862+
while (isdigit((unsigned char)**ptr) || **ptr == ':') {
863863
++*ptr;
864864
}
865865
end = *ptr;
@@ -924,7 +924,7 @@ static timelib_long timelib_parse_tz_minutes(const char **ptr, timelib_time *t)
924924
}
925925

926926
++*ptr;
927-
while (isdigit(**ptr)) {
927+
while (isdigit((unsigned char)**ptr)) {
928928
++*ptr;
929929
}
930930

ext/date/lib/parse_date.re

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -516,7 +516,7 @@ static timelib_sll timelib_get_nr(const char **ptr, int max_length)
516516

517517
static void timelib_skip_day_suffix(const char **ptr)
518518
{
519-
if (isspace(**ptr)) {
519+
if (isspace((unsigned char)**ptr)) {
520520
return;
521521
}
522522
if (!timelib_strncasecmp(*ptr, "nd", 2) || !timelib_strncasecmp(*ptr, "rd", 2) ||!timelib_strncasecmp(*ptr, "st", 2) || !timelib_strncasecmp(*ptr, "th", 2)) {
@@ -857,7 +857,7 @@ static timelib_long timelib_parse_tz_cor(const char **ptr, int *tz_not_found)
857857

858858
*tz_not_found = 1;
859859

860-
while (isdigit(**ptr) || **ptr == ':') {
860+
while (isdigit((unsigned char)**ptr) || **ptr == ':') {
861861
++*ptr;
862862
}
863863
end = *ptr;
@@ -922,7 +922,7 @@ static timelib_long timelib_parse_tz_minutes(const char **ptr, timelib_time *t)
922922
}
923923

924924
++*ptr;
925-
while (isdigit(**ptr)) {
925+
while (isdigit((unsigned char)**ptr)) {
926926
++*ptr;
927927
}
928928

ext/date/lib/parse_iso_intervals.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -985,10 +985,10 @@ void timelib_strtointerval(const char *s, size_t len,
985985
in.errors->error_messages = NULL;
986986

987987
if (len > 0) {
988-
while (isspace(*s) && s < e) {
988+
while (isspace((unsigned char)*s) && s < e) {
989989
s++;
990990
}
991-
while (isspace(*e) && e > s) {
991+
while (isspace((unsigned char)*e) && e > s) {
992992
e--;
993993
}
994994
}

ext/date/lib/parse_iso_intervals.re

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -343,10 +343,10 @@ void timelib_strtointerval(const char *s, size_t len,
343343
in.errors->error_messages = NULL;
344344

345345
if (len > 0) {
346-
while (isspace(*s) && s < e) {
346+
while (isspace((unsigned char)*s) && s < e) {
347347
s++;
348348
}
349-
while (isspace(*e) && e > s) {
349+
while (isspace((unsigned char)*e) && e > s) {
350350
e--;
351351
}
352352
}

0 commit comments

Comments
 (0)