Skip to content

Commit 0d534d7

Browse files
committed
Add ldap_escape()
1 parent 4a85b5e commit 0d534d7

File tree

6 files changed

+160
-0
lines changed

6 files changed

+160
-0
lines changed

ext/ldap/ldap.c

Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,9 @@
6767
#include <sasl/sasl.h>
6868
#endif
6969

70+
#define PHP_LDAP_ESCAPE_FILTER 0x01
71+
#define PHP_LDAP_ESCAPE_DN 0x02
72+
7073
typedef struct {
7174
LDAP *link;
7275
#if defined(LDAP_API_FEATURE_X_OPENLDAP) && defined(HAVE_3ARG_SETREBINDPROC)
@@ -195,6 +198,9 @@ PHP_MINIT_FUNCTION(ldap)
195198
REGISTER_LONG_CONSTANT("GSLC_SSL_TWOWAY_AUTH", GSLC_SSL_TWOWAY_AUTH, CONST_PERSISTENT | CONST_CS);
196199
#endif
197200

201+
REGISTER_LONG_CONSTANT("LDAP_ESCAPE_FILTER", PHP_LDAP_ESCAPE_FILTER, CONST_PERSISTENT | CONST_CS);
202+
REGISTER_LONG_CONSTANT("LDAP_ESCAPE_DN", PHP_LDAP_ESCAPE_DN, CONST_PERSISTENT | CONST_CS);
203+
198204
le_link = zend_register_list_destructors_ex(_close_ldap_link, NULL, "ldap link", module_number);
199205
le_result = zend_register_list_destructors_ex(_free_ldap_result, NULL, "ldap result", module_number);
200206
le_result_entry = zend_register_list_destructors_ex(_free_ldap_result_entry, NULL, "ldap result entry", module_number);
@@ -2136,6 +2142,81 @@ PHP_FUNCTION(ldap_set_rebind_proc)
21362142
/* }}} */
21372143
#endif
21382144

2145+
static void php_ldap_do_escape(const zend_bool *map, const unsigned char *value, const int valuelen, unsigned char **result, int *resultlen)
2146+
{
2147+
char hex[] = "0123456789abcdef";
2148+
int i, p = 0;
2149+
size_t len = 0;
2150+
2151+
for (i = 0; i < valuelen; i++) {
2152+
len += (map[value[i]]) ? 3 : 1;
2153+
}
2154+
len += 1;
2155+
2156+
(*result) = (unsigned char *)emalloc(len);
2157+
(*resultlen) = (int)len;
2158+
2159+
for (i = 0; i < valuelen; i++) {
2160+
if (map[value[i]]) {
2161+
(*result)[p++] = '\\';
2162+
(*result)[p++] = hex[value[i] >> 4];
2163+
(*result)[p++] = hex[value[i] & 0x0f];
2164+
} else {
2165+
(*result)[p++] = value[i];
2166+
}
2167+
}
2168+
2169+
(*result)[p++] = '\0';
2170+
}
2171+
2172+
static void php_ldap_escape_map_set_chars(zend_bool *map, const unsigned char *chars, const int charslen, char escape)
2173+
{
2174+
int i = 0;
2175+
while (i < charslen) {
2176+
map[chars[i++]] = escape;
2177+
}
2178+
}
2179+
2180+
PHP_FUNCTION(ldap_escape)
2181+
{
2182+
unsigned char *value, *ignores, *result;
2183+
int valuelen = 0, ignoreslen = 0, resultlen = 0, i;
2184+
long flags = 0;
2185+
zend_bool map[256] = {0}, havecharlist = 0;
2186+
2187+
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|sl", &value, &valuelen, &ignores, &ignoreslen, &flags) != SUCCESS) {
2188+
return;
2189+
}
2190+
2191+
if (!valuelen) {
2192+
RETURN_EMPTY_STRING();
2193+
}
2194+
2195+
if (flags & PHP_LDAP_ESCAPE_FILTER) {
2196+
havecharlist = 1;
2197+
php_ldap_escape_map_set_chars(map, "\\*()\0", sizeof("\\*()\0") - 1, 1);
2198+
}
2199+
2200+
if (flags & PHP_LDAP_ESCAPE_DN) {
2201+
havecharlist = 1;
2202+
php_ldap_escape_map_set_chars(map, "\\,=+<>;\"#", sizeof("\\,=+<>;\"#") - 1, 1);
2203+
}
2204+
2205+
if (!havecharlist) {
2206+
for (i = 0; i < 256; i++) {
2207+
map[i] = 1;
2208+
}
2209+
}
2210+
2211+
if (ignoreslen) {
2212+
php_ldap_escape_map_set_chars(map, ignores, ignoreslen, 0);
2213+
}
2214+
2215+
php_ldap_do_escape(map, value, valuelen, &result, &resultlen);
2216+
2217+
RETURN_STRINGL(result, resultlen - 1, 0);
2218+
}
2219+
21392220
#ifdef STR_TRANSLATION
21402221
/* {{{ php_ldap_do_translate
21412222
*/
@@ -2625,6 +2706,12 @@ ZEND_BEGIN_ARG_INFO_EX(arginfo_ldap_set_rebind_proc, 0, 0, 2)
26252706
ZEND_END_ARG_INFO()
26262707
#endif
26272708

2709+
ZEND_BEGIN_ARG_INFO_EX(arginfo_ldap_escape, 0, 0, 1)
2710+
ZEND_ARG_INFO(0, value)
2711+
ZEND_ARG_INFO(0, ignore)
2712+
ZEND_ARG_INFO(0, flags)
2713+
ZEND_END_ARG_INFO()
2714+
26282715
#ifdef STR_TRANSLATION
26292716
ZEND_BEGIN_ARG_INFO_EX(arginfo_ldap_t61_to_8859, 0, 0, 1)
26302717
ZEND_ARG_INFO(0, value)
@@ -2703,6 +2790,8 @@ const zend_function_entry ldap_functions[] = {
27032790
PHP_FE(ldap_set_rebind_proc, arginfo_ldap_set_rebind_proc)
27042791
#endif
27052792

2793+
PHP_FE(ldap_escape, arginfo_ldap_escape)
2794+
27062795
#ifdef STR_TRANSLATION
27072796
PHP_FE(ldap_t61_to_8859, arginfo_ldap_t61_to_8859)
27082797
PHP_FE(ldap_8859_to_t61, arginfo_ldap_8859_to_t61)

ext/ldap/tests/ldap_escape_all.phpt

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
--TEST--
2+
ldap_escape() test all
3+
--SKIPIF--
4+
<?php require_once('skipif.inc'); ?>
5+
--FILE--
6+
<?php
7+
8+
$subject = 'foo=bar(baz)*';
9+
10+
var_dump(ldap_escape($subject));
11+
12+
?>
13+
--EXPECT--
14+
string(39) "\66\6f\6f\3d\62\61\72\28\62\61\7a\29\2a"

ext/ldap/tests/ldap_escape_both.phpt

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
--TEST--
2+
ldap_escape() test filter and DN
3+
--SKIPIF--
4+
<?php require_once('skipif.inc'); ?>
5+
--FILE--
6+
<?php
7+
8+
$subject = 'foo=bar(baz)*';
9+
10+
var_dump(ldap_escape($subject, null, LDAP_ESCAPE_DN | LDAP_ESCAPE_FILTER));
11+
12+
?>
13+
--EXPECT--
14+
string(21) "foo\3dbar\28baz\29\2a"

ext/ldap/tests/ldap_escape_dn.phpt

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
--TEST--
2+
ldap_escape() test DN
3+
--SKIPIF--
4+
<?php require_once('skipif.inc'); ?>
5+
--FILE--
6+
<?php
7+
8+
$subject = 'foo=bar(baz)*';
9+
10+
var_dump(ldap_escape($subject, null, LDAP_ESCAPE_DN));
11+
12+
?>
13+
--EXPECT--
14+
string(15) "foo\3dbar(baz)*"
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
--TEST--
2+
ldap_escape() test filter
3+
--SKIPIF--
4+
<?php require_once('skipif.inc'); ?>
5+
--FILE--
6+
<?php
7+
8+
$subject = 'foo=bar(baz)*';
9+
10+
var_dump(ldap_escape($subject, null, LDAP_ESCAPE_FILTER));
11+
12+
?>
13+
--EXPECT--
14+
string(19) "foo=bar\28baz\29\2a"
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
--TEST--
2+
ldap_escape() test ignore
3+
--SKIPIF--
4+
<?php require_once('skipif.inc'); ?>
5+
--FILE--
6+
<?php
7+
8+
$subject = 'foo=bar(baz)*';
9+
$ignore = 'ao';
10+
11+
var_dump(ldap_escape($subject, $ignore));
12+
13+
?>
14+
--EXPECT--
15+
string(31) "\66oo\3d\62a\72\28\62a\7a\29\2a"

0 commit comments

Comments
 (0)