Skip to content

Commit 4b211a7

Browse files
committed
Merge branch 'PHP-8.4'
2 parents f2f9831 + 7c96af4 commit 4b211a7

30 files changed

+2028
-37
lines changed

ext/ldap/ldap.c

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3759,13 +3759,23 @@ static zend_string* php_ldap_do_escape(const bool *map, const char *value, size_
37593759
zend_string *ret;
37603760

37613761
for (i = 0; i < valuelen; i++) {
3762-
len += (map[(unsigned char) value[i]]) ? 3 : 1;
3762+
size_t addend = (map[(unsigned char) value[i]]) ? 3 : 1;
3763+
if (len > ZSTR_MAX_LEN - addend) {
3764+
return NULL;
3765+
}
3766+
len += addend;
37633767
}
37643768
/* Per RFC 4514, a leading and trailing space must be escaped */
37653769
if ((flags & PHP_LDAP_ESCAPE_DN) && (value[0] == ' ')) {
3770+
if (len > ZSTR_MAX_LEN - 2) {
3771+
return NULL;
3772+
}
37663773
len += 2;
37673774
}
37683775
if ((flags & PHP_LDAP_ESCAPE_DN) && ((valuelen > 1) && (value[valuelen - 1] == ' '))) {
3776+
if (len > ZSTR_MAX_LEN - 2) {
3777+
return NULL;
3778+
}
37693779
len += 2;
37703780
}
37713781

@@ -3832,7 +3842,13 @@ PHP_FUNCTION(ldap_escape)
38323842
php_ldap_escape_map_set_chars(map, ignores, ignoreslen, 0);
38333843
}
38343844

3835-
RETURN_NEW_STR(php_ldap_do_escape(map, value, valuelen, flags));
3845+
zend_string *result = php_ldap_do_escape(map, value, valuelen, flags);
3846+
if (UNEXPECTED(!result)) {
3847+
zend_argument_value_error(1, "is too long");
3848+
RETURN_THROWS();
3849+
}
3850+
3851+
RETURN_NEW_STR(result);
38363852
}
38373853

38383854
#ifdef STR_TRANSLATION
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
--TEST--
2+
GHSA-g665-fm4p-vhff (OOB access in ldap_escape)
3+
--EXTENSIONS--
4+
ldap
5+
--INI--
6+
memory_limit=-1
7+
--SKIPIF--
8+
<?php
9+
if (PHP_INT_SIZE !== 4) die("skip only for 32-bit");
10+
if (getenv("SKIP_SLOW_TESTS")) die("skip slow test");
11+
?>
12+
--FILE--
13+
<?php
14+
try {
15+
ldap_escape(' '.str_repeat("#", 1431655758), "", LDAP_ESCAPE_DN);
16+
} catch (ValueError $e) {
17+
echo $e->getMessage(), "\n";
18+
}
19+
20+
try {
21+
ldap_escape(str_repeat("#", 1431655758).' ', "", LDAP_ESCAPE_DN);
22+
} catch (ValueError $e) {
23+
echo $e->getMessage(), "\n";
24+
}
25+
?>
26+
--EXPECT--
27+
ldap_escape(): Argument #1 ($value) is too long
28+
ldap_escape(): Argument #1 ($value) is too long
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
--TEST--
2+
GHSA-g665-fm4p-vhff (OOB access in ldap_escape)
3+
--EXTENSIONS--
4+
ldap
5+
--INI--
6+
memory_limit=-1
7+
--SKIPIF--
8+
<?php
9+
if (PHP_INT_SIZE !== 4) die("skip only for 32-bit");
10+
if (getenv("SKIP_SLOW_TESTS")) die("skip slow test");
11+
?>
12+
--FILE--
13+
<?php
14+
try {
15+
ldap_escape(str_repeat("*", 1431655759), "", LDAP_ESCAPE_FILTER);
16+
} catch (ValueError $e) {
17+
echo $e->getMessage(), "\n";
18+
}
19+
20+
// would allocate a string of length 2
21+
try {
22+
ldap_escape(str_repeat("*", 1431655766), "", LDAP_ESCAPE_FILTER);
23+
} catch (ValueError $e) {
24+
echo $e->getMessage(), "\n";
25+
}
26+
?>
27+
--EXPECT--
28+
ldap_escape(): Argument #1 ($value) is too long
29+
ldap_escape(): Argument #1 ($value) is too long

0 commit comments

Comments
 (0)