diff --git a/src/Symfony/Component/Ldap/LdapClient.php b/src/Symfony/Component/Ldap/LdapClient.php index 0a8fa22c16..3fc0cb5454 100644 --- a/src/Symfony/Component/Ldap/LdapClient.php +++ b/src/Symfony/Component/Ldap/LdapClient.php @@ -99,7 +99,20 @@ class LdapClient implements LdapClientInterface */ public function escape($subject, $ignore = '', $flags = 0) { - return ldap_escape($subject, $ignore, $flags); + $value = ldap_escape($subject, $ignore, $flags); + + // Per RFC 4514, leading/trailing spaces should be encoded in DNs, as well as carriage returns. + if ((int) $flags & LDAP_ESCAPE_DN) { + if (!empty($value) && $value[0] === ' ') { + $value = '\\20'.substr($value, 1); + } + if (!empty($value) && $value[strlen($value) - 1] === ' ') { + $value = substr($value, 0, -1).'\\20'; + } + $value = str_replace("\r", '\0d', $value); + } + + return $value; } private function connect() diff --git a/src/Symfony/Component/Ldap/Tests/LdapClientTest.php b/src/Symfony/Component/Ldap/Tests/LdapClientTest.php new file mode 100644 index 0000000000..acf15b06d6 --- /dev/null +++ b/src/Symfony/Component/Ldap/Tests/LdapClientTest.php @@ -0,0 +1,28 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Ldap\Tests; + +use Symfony\Component\Ldap\LdapClient; +use Symfony\Polyfill\Php56\Php56 as p; + +/** + * @requires extension ldap + */ +class LdapClientTest extends \PHPUnit_Framework_TestCase +{ + public function testLdapEscape() + { + $ldap = new LdapClient(); + + $this->assertEquals('\20foo\3dbar\0d(baz)*\20', $ldap->escape(" foo=bar\r(baz)* ", null, p::LDAP_ESCAPE_DN)); + } +}