Skip to content

Commit 63427c1

Browse files
committed
Make LDAP_ESCAPE_DN compliant with RFC 4514
1 parent c9a538c commit 63427c1

File tree

2 files changed

+25
-4
lines changed

2 files changed

+25
-4
lines changed

ext/ldap/ldap.c

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2823,7 +2823,7 @@ PHP_FUNCTION(ldap_set_rebind_proc)
28232823
/* }}} */
28242824
#endif
28252825

2826-
static zend_string* php_ldap_do_escape(const zend_bool *map, const char *value, size_t valuelen)
2826+
static zend_string* php_ldap_do_escape(const zend_bool *map, const char *value, size_t valuelen, zend_long flags)
28272827
{
28282828
char hex[] = "0123456789abcdef";
28292829
size_t i, p = 0;
@@ -2833,13 +2833,20 @@ static zend_string* php_ldap_do_escape(const zend_bool *map, const char *value,
28332833
for (i = 0; i < valuelen; i++) {
28342834
len += (map[(unsigned char) value[i]]) ? 3 : 1;
28352835
}
2836+
/* Per RFC 4514, a leading and trailing space must be escaped */
2837+
if (flags & PHP_LDAP_ESCAPE_DN && value[0] == ' ') {
2838+
len += 2;
2839+
}
2840+
if (flags & PHP_LDAP_ESCAPE_DN && valuelen && value[valuelen] == ' ') {
2841+
len += 2;
2842+
}
28362843

28372844
ret = zend_string_alloc(len, 0);
28382845

28392846
for (i = 0; i < valuelen; i++) {
28402847
unsigned char v = (unsigned char) value[i];
28412848

2842-
if (map[v]) {
2849+
if (map[v] || (flags & PHP_LDAP_ESCAPE_DN && (i == 0 || i + 1 == valuelen ) && v == ' ')) {
28432850
ZSTR_VAL(ret)[p++] = '\\';
28442851
ZSTR_VAL(ret)[p++] = hex[v >> 4];
28452852
ZSTR_VAL(ret)[p++] = hex[v & 0x0f];
@@ -2884,7 +2891,7 @@ PHP_FUNCTION(ldap_escape)
28842891

28852892
if (flags & PHP_LDAP_ESCAPE_DN) {
28862893
havecharlist = 1;
2887-
php_ldap_escape_map_set_chars(map, "\\,=+<>;\"#", sizeof("\\,=+<>;\"#") - 1, 1);
2894+
php_ldap_escape_map_set_chars(map, "\\,=+<>;\"#\r", sizeof("\\,=+<>;\"#\r") - 1, 1);
28882895
}
28892896

28902897
if (!havecharlist) {
@@ -2897,7 +2904,7 @@ PHP_FUNCTION(ldap_escape)
28972904
php_ldap_escape_map_set_chars(map, ignores, ignoreslen, 0);
28982905
}
28992906

2900-
RETURN_NEW_STR(php_ldap_do_escape(map, value, valuelen));
2907+
RETURN_NEW_STR(php_ldap_do_escape(map, value, valuelen, flags));
29012908
}
29022909

29032910
#ifdef STR_TRANSLATION

ext/ldap/tests/bug72021.phpt

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
--TEST--
2+
Bug #72021 (ldap_escape() with DN flag is not RFC compliant)
3+
--CREDITS--
4+
Chad Sikorra <[email protected]>
5+
--SKIPIF--
6+
<?php require_once('skipif.inc'); ?>
7+
--FILE--
8+
<?php
9+
$subject = " Joe,= \rSmith ";
10+
11+
var_dump(ldap_escape($subject, null, LDAP_ESCAPE_DN));
12+
?>
13+
--EXPECT--
14+
string(24) "\20Joe\2c\3d \0dSmith\20"

0 commit comments

Comments
 (0)