Skip to content

Add ldap_escape() #458

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Oct 18, 2013
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
89 changes: 89 additions & 0 deletions ext/ldap/ldap.c
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,9 @@
#include <sasl/sasl.h>
#endif

#define PHP_LDAP_ESCAPE_FILTER 0x01
#define PHP_LDAP_ESCAPE_DN 0x02

typedef struct {
LDAP *link;
#if defined(LDAP_API_FEATURE_X_OPENLDAP) && defined(HAVE_3ARG_SETREBINDPROC)
Expand Down Expand Up @@ -195,6 +198,9 @@ PHP_MINIT_FUNCTION(ldap)
REGISTER_LONG_CONSTANT("GSLC_SSL_TWOWAY_AUTH", GSLC_SSL_TWOWAY_AUTH, CONST_PERSISTENT | CONST_CS);
#endif

REGISTER_LONG_CONSTANT("LDAP_ESCAPE_FILTER", PHP_LDAP_ESCAPE_FILTER, CONST_PERSISTENT | CONST_CS);
REGISTER_LONG_CONSTANT("LDAP_ESCAPE_DN", PHP_LDAP_ESCAPE_DN, CONST_PERSISTENT | CONST_CS);

le_link = zend_register_list_destructors_ex(_close_ldap_link, NULL, "ldap link", module_number);
le_result = zend_register_list_destructors_ex(_free_ldap_result, NULL, "ldap result", module_number);
le_result_entry = zend_register_list_destructors_ex(_free_ldap_result_entry, NULL, "ldap result entry", module_number);
Expand Down Expand Up @@ -2136,6 +2142,81 @@ PHP_FUNCTION(ldap_set_rebind_proc)
/* }}} */
#endif

static void php_ldap_do_escape(const zend_bool *map, const unsigned char *value, const int valuelen, unsigned char **result, int *resultlen)
{
char hex[] = "0123456789abcdef";
int i, p = 0;
size_t len = 0;

for (i = 0; i < valuelen; i++) {
len += (map[value[i]]) ? 3 : 1;
}
len += 1;

(*result) = (unsigned char *)emalloc(len);
(*resultlen) = (int)len;

for (i = 0; i < valuelen; i++) {
if (map[value[i]]) {
(*result)[p++] = '\\';
(*result)[p++] = hex[value[i] >> 4];
(*result)[p++] = hex[value[i] & 0x0f];
} else {
(*result)[p++] = value[i];
}
}

(*result)[p++] = '\0';
}

static void php_ldap_escape_map_set_chars(zend_bool *map, const unsigned char *chars, const int charslen, char escape)
{
int i = 0;
while (i < charslen) {
map[chars[i++]] = escape;
}
}

PHP_FUNCTION(ldap_escape)
{
unsigned char *value, *ignores, *result;
int valuelen = 0, ignoreslen = 0, resultlen = 0, i;
long flags = 0;
zend_bool map[256] = {0}, havecharlist = 0;

if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|sl", &value, &valuelen, &ignores, &ignoreslen, &flags) != SUCCESS) {
return;
}

if (!valuelen) {
RETURN_EMPTY_STRING();
}

if (flags & PHP_LDAP_ESCAPE_FILTER) {
havecharlist = 1;
php_ldap_escape_map_set_chars(map, "\\*()\0", sizeof("\\*()\0") - 1, 1);
}

if (flags & PHP_LDAP_ESCAPE_DN) {
havecharlist = 1;
php_ldap_escape_map_set_chars(map, "\\,=+<>;\"#", sizeof("\\,=+<>;\"#") - 1, 1);
}

if (!havecharlist) {
for (i = 0; i < 256; i++) {
map[i] = 1;
}
}

if (ignoreslen) {
php_ldap_escape_map_set_chars(map, ignores, ignoreslen, 0);
}

php_ldap_do_escape(map, value, valuelen, &result, &resultlen);

RETURN_STRINGL(result, resultlen - 1, 0);
}

#ifdef STR_TRANSLATION
/* {{{ php_ldap_do_translate
*/
Expand Down Expand Up @@ -2625,6 +2706,12 @@ ZEND_BEGIN_ARG_INFO_EX(arginfo_ldap_set_rebind_proc, 0, 0, 2)
ZEND_END_ARG_INFO()
#endif

ZEND_BEGIN_ARG_INFO_EX(arginfo_ldap_escape, 0, 0, 1)
ZEND_ARG_INFO(0, value)
ZEND_ARG_INFO(0, ignore)
ZEND_ARG_INFO(0, flags)
ZEND_END_ARG_INFO()

#ifdef STR_TRANSLATION
ZEND_BEGIN_ARG_INFO_EX(arginfo_ldap_t61_to_8859, 0, 0, 1)
ZEND_ARG_INFO(0, value)
Expand Down Expand Up @@ -2703,6 +2790,8 @@ const zend_function_entry ldap_functions[] = {
PHP_FE(ldap_set_rebind_proc, arginfo_ldap_set_rebind_proc)
#endif

PHP_FE(ldap_escape, arginfo_ldap_escape)

#ifdef STR_TRANSLATION
PHP_FE(ldap_t61_to_8859, arginfo_ldap_t61_to_8859)
PHP_FE(ldap_8859_to_t61, arginfo_ldap_8859_to_t61)
Expand Down
14 changes: 14 additions & 0 deletions ext/ldap/tests/ldap_escape_all.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
--TEST--
ldap_escape() test all
--SKIPIF--
<?php require_once('skipif.inc'); ?>
--FILE--
<?php

$subject = 'foo=bar(baz)*';

var_dump(ldap_escape($subject));

?>
--EXPECT--
string(39) "\66\6f\6f\3d\62\61\72\28\62\61\7a\29\2a"
14 changes: 14 additions & 0 deletions ext/ldap/tests/ldap_escape_both.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
--TEST--
ldap_escape() test filter and DN
--SKIPIF--
<?php require_once('skipif.inc'); ?>
--FILE--
<?php

$subject = 'foo=bar(baz)*';

var_dump(ldap_escape($subject, null, LDAP_ESCAPE_DN | LDAP_ESCAPE_FILTER));

?>
--EXPECT--
string(21) "foo\3dbar\28baz\29\2a"
14 changes: 14 additions & 0 deletions ext/ldap/tests/ldap_escape_dn.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
--TEST--
ldap_escape() test DN
--SKIPIF--
<?php require_once('skipif.inc'); ?>
--FILE--
<?php

$subject = 'foo=bar(baz)*';

var_dump(ldap_escape($subject, null, LDAP_ESCAPE_DN));

?>
--EXPECT--
string(15) "foo\3dbar(baz)*"
14 changes: 14 additions & 0 deletions ext/ldap/tests/ldap_escape_filter.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
--TEST--
ldap_escape() test filter
--SKIPIF--
<?php require_once('skipif.inc'); ?>
--FILE--
<?php

$subject = 'foo=bar(baz)*';

var_dump(ldap_escape($subject, null, LDAP_ESCAPE_FILTER));

?>
--EXPECT--
string(19) "foo=bar\28baz\29\2a"
15 changes: 15 additions & 0 deletions ext/ldap/tests/ldap_escape_ignore.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
--TEST--
ldap_escape() test ignore
--SKIPIF--
<?php require_once('skipif.inc'); ?>
--FILE--
<?php

$subject = 'foo=bar(baz)*';
$ignore = 'ao';

var_dump(ldap_escape($subject, $ignore));

?>
--EXPECT--
string(31) "\66oo\3d\62a\72\28\62a\7a\29\2a"