Skip to content

Commit b8dad93

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 3f6f38b + dc9e21b commit b8dad93

57 files changed

Lines changed: 176 additions & 176 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
@@ -2182,7 +2182,7 @@ ZEND_API size_t zend_dirname(char *path, size_t len)
21822182
/* Note that on Win32 CWD is per drive (heritage from CP/M).
21832183
* This means dirname("c:foo") maps to "c:." or "c:" - which means CWD on C: drive.
21842184
*/
2185-
if ((2 <= len) && isalpha((int)((unsigned char *)path)[0]) && (':' == path[1])) {
2185+
if ((2 <= len) && isalpha((unsigned char)path[0]) && (':' == path[1])) {
21862186
/* Skip over the drive spec (if any) so as not to change */
21872187
path += 2;
21882188
len_adjust += 2;

Zend/zend_ini.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -585,7 +585,7 @@ static const char *zend_ini_consume_quantity_prefix(const char *const digits, co
585585
++digits_consumed;
586586
}
587587

588-
if (digits_consumed[0] == '0' && !isdigit(digits_consumed[1])) {
588+
if (digits_consumed[0] == '0' && !isdigit((unsigned char)digits_consumed[1])) {
589589
/* Value is just 0 */
590590
if ((digits_consumed+1) == str_end) {
591591
return digits_consumed;
@@ -643,7 +643,7 @@ static zend_ulong zend_ini_parse_quantity_internal(zend_string *value, zend_ini_
643643
}
644644

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

659659
int base = 0;
660-
if (digits[0] == '0' && !isdigit(digits[1])) {
660+
if (digits[0] == '0' && !isdigit((unsigned char)digits[1])) {
661661
/* Value is just 0 */
662662
if ((digits+1) == str_end) {
663663
*errstr = NULL;

Zend/zend_operators.c

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

33273327
len = MIN(len1, len2);
33283328
while (len--) {
3329-
c1 = zend_tolower((int)*(unsigned char *)s1++);
3330-
c2 = zend_tolower((int)*(unsigned char *)s2++);
3329+
c1 = zend_tolower((unsigned char)*(s1++));
3330+
c2 = zend_tolower((unsigned char)*(s2++));
33313331
if (c1 != c2) {
33323332
return c1 - c2;
33333333
}
@@ -3347,8 +3347,8 @@ ZEND_API int ZEND_FASTCALL zend_binary_strncasecmp_l(const char *s1, size_t len1
33473347
}
33483348
len = MIN(length, MIN(len1, len2));
33493349
while (len--) {
3350-
c1 = zend_tolower((int)*(unsigned char *)s1++);
3351-
c2 = zend_tolower((int)*(unsigned char *)s2++);
3350+
c1 = zend_tolower((unsigned char)*(s1++));
3351+
c2 = zend_tolower((unsigned char)*(s2++));
33523352
if (c1 != c2) {
33533353
return c1 - c2;
33543354
}

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)