Skip to content
This repository has been archived by the owner on May 14, 2024. It is now read-only.

The search fails if the filter contains non-ascii characters and "*" #8

Open
PositroniumJS opened this issue Nov 12, 2023 · 5 comments

Comments

@PositroniumJS
Copy link

This issue is the sequel of ldapjs/node-ldapjs#860. After upgrading to v3, my search request fails when combining wildcard (*) and non-ascii characters. Using Apache directory studio or ldapsearch my search request succeeds but not when using ldapjs.
I have read the logs on my OpenLDAP server and we clearly see a problem on how the filter is processed:

ldapjs for (&(description=*réseau*))
In the logs: filter="(&(description=*r\5Cc3\5Ca9seau*))"
❌ Not working

Apache Directory Studio for (description=*réseau*)
In the logs: filter="(description=*r\C3\A9seau*)"
🆗 Working

ldapjs for (&(description=réseau))
In the logs: filter="(&(description=r\C3\A9seau))"
🆗 Working thanks to ldapjs/node-ldapjs#860 and no wildcard

ldapjs for new EqualityFilter({ attribute: "description", value: "*réseau*"})
In the logs: filter="(description=\2Ar\C3\A9seau\2A)"
❌ Not working

ldapsearch for (description=*réseau*)
In the logs: filter="(description=*r\C3\A9seau*)"
🆗 Working

Thank you in advance for your help!

@PositroniumJS
Copy link
Author

I think that a fix would be to remove the call of escapeFilterValue here

@PositroniumJS
Copy link
Author

I think that a fix would be to remove the call of escapeFilterValue here

I have tried localy this change and I have added the following integration test: with the change all the tests pass whereas without the change this test fails.

tap.test('can search with non-ascii chars and wildcard in filter', t => {
  t.plan(3)

  const opts = {
    filter: '(&(sn=*í*))',
    scope: 'sub',
    attributes: ['dn', 'sn', 'cn'],
    type: 'user'
  }

  let searchEntryCount = 0
  client.search('dc=planetexpress,dc=com', opts, (err, res) => {
    t.error(err, 'search error')
    res.on('searchEntry', (entry) => {
      searchEntryCount += 1
      t.match(entry.pojo, {
        type: 'SearchResultEntry',
        objectName: 'cn=Bender Bending Rodr\\c3\\adguez,ou=people,dc=planetexpress,dc=com',
        attributes: [{
          type: 'cn',
          values: ['Bender Bending Rodríguez']
        }]
      })
    })
    res.on('error', (err) => {
      t.error(err, 'search entry error')
    })
    res.on('end', () => {
      t.equal(searchEntryCount, 1, 'should have found 1 entry')
      t.end()
    })
  })
})

@jsumners jsumners transferred this issue from ldapjs/node-ldapjs Nov 15, 2023
@jsumners
Copy link
Member

Good find. The out.final is likely also incorrect. See the findings in #6. Are you willing to contribute a PR to resolve this issue?

PositroniumJS pushed a commit to PositroniumJS/ldapjs-filter that referenced this issue Nov 16, 2023
PositroniumJS added a commit to PositroniumJS/ldapjs-filter that referenced this issue Nov 16, 2023
@PositroniumJS
Copy link
Author

Good find. The out.final is likely also incorrect. See the findings in #6. Are you willing to contribute a PR to resolve this issue?

I have opened a PR, please tell me if something is missing!

PositroniumJS added a commit to PositroniumJS/ldapjs-filter that referenced this issue Nov 22, 2023
@PositroniumJS
Copy link
Author

In the meantime, to solve this problem in my project I have added the following script as a postinstallation script in package.json:

const colors = require('colors');
const fs = require('fs');
const path = require('path');

const nodeModulesPath = path.resolve(process.cwd(), 'node_modules');
const packageName = '@ldapjs';

console.log(path.resolve(nodeModulesPath, packageName));
if (!fs.existsSync(path.resolve(nodeModulesPath, packageName))) {
    console.log(colors.red(`@ldapjs was not found.`));
    return;
}

console.log(colors.yellow(`Detected "${packageName}" package...`));
console.log(colors.yellow(`Applying ldapsjs@3 patch`));

const fileToPatchPath = path.resolve(
    nodeModulesPath,
    packageName,
    'filter',
    'lib',
    'string-parsing',
    'escape-substring.js'
);

const fileContent = fs.readFileSync(fileToPatchPath, { encoding: 'utf8' });
if (!fileContent.match('escapeFilterValue')) {
    colors.red(
        `Nothing to patch found in @ldapjs/filter.`
    );
}

fs.writeFileSync(
    fileToPatchPath,
    fileContent
        .replace(`const escapeFilterValue = require('../utils/escape-filter-value')`, ``)
        .replace(`escapeFilterValue(fields.shift())`, `fields.shift()`)
        .replace(`escapeFilterValue(fields.pop())`, `fields.pop()`)
        .replace(`fields.map(escapeFilterValue)`, `fields`)
);

console.log(colors.yellow(`ldapjs@3 patch was successfully applied`));

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants