First commit
This commit is contained in:
105
node_modules/@ldapjs/dn/lib/utils/parse-string/index.js
generated
vendored
Normal file
105
node_modules/@ldapjs/dn/lib/utils/parse-string/index.js
generated
vendored
Normal file
@ -0,0 +1,105 @@
|
||||
'use strict'
|
||||
|
||||
const readAttributePair = require('./read-attribute-pair')
|
||||
|
||||
/**
|
||||
* @typedef {object} ParsedPojoRdn
|
||||
* @property {string} name Either the name of an RDN attribute, or the
|
||||
* equivalent numeric OID.
|
||||
* @property {string | import('@ldapjs/asn1').BerReader} value The attribute
|
||||
* value as a plain string, or a `BerReader` if the string value was an encoded
|
||||
* hex string.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Parse a string into a set of plain JavaScript object representations of
|
||||
* RDNs.
|
||||
*
|
||||
* @example A plain string with multiple RDNs and multiple attribute assertions.
|
||||
* const input = 'cn=foo+sn=bar,dc=example,dc=com
|
||||
* const result = parseString(input)
|
||||
* // [
|
||||
* // { cn: 'foo', sn: 'bar' },
|
||||
* // { dc: 'example' }
|
||||
* // { dc: 'com' }
|
||||
* // ]
|
||||
*
|
||||
* @param {string} input The RDN string to parse.
|
||||
*
|
||||
* @returns {ParsedPojoRdn[]}
|
||||
*
|
||||
* @throws When there is some problem parsing the RDN string.
|
||||
*/
|
||||
module.exports = function parseString (input) {
|
||||
if (typeof input !== 'string') {
|
||||
throw Error('input must be a string')
|
||||
}
|
||||
if (input.length === 0) {
|
||||
// Short circuit because the input is an empty DN (i.e. "root DSE").
|
||||
return []
|
||||
}
|
||||
|
||||
const searchBuffer = Buffer.from(input, 'utf8')
|
||||
const length = searchBuffer.byteLength
|
||||
const rdns = []
|
||||
|
||||
let pos = 0
|
||||
let rdn = {}
|
||||
|
||||
readRdnLoop:
|
||||
while (pos <= length) {
|
||||
if (pos === length) {
|
||||
const char = searchBuffer[pos - 1]
|
||||
|
||||
/* istanbul ignore else */
|
||||
if (char === 0x2b || char === 0x2c || char === 0x3b) {
|
||||
throw Error('rdn string ends abruptly with character: ' + String.fromCharCode(char))
|
||||
}
|
||||
}
|
||||
|
||||
// Find the start of significant characters by skipping over any leading
|
||||
// whitespace.
|
||||
while (pos < length && searchBuffer[pos] === 0x20) {
|
||||
pos += 1
|
||||
}
|
||||
|
||||
const readAttrPairResult = readAttributePair({ searchBuffer, startPos: pos })
|
||||
pos = readAttrPairResult.endPos
|
||||
rdn = { ...rdn, ...readAttrPairResult.pair }
|
||||
|
||||
if (pos >= length) {
|
||||
// We've reached the end of the string. So push the current RDN and stop.
|
||||
rdns.push(rdn)
|
||||
break
|
||||
}
|
||||
|
||||
// Next, we need to determine if the next set of significant characters
|
||||
// denotes another attribute pair for the current RDN, or is the indication
|
||||
// of another RDN.
|
||||
while (pos < length) {
|
||||
const char = searchBuffer[pos]
|
||||
|
||||
// We don't need to skip whitespace before the separator because the
|
||||
// attribute pair function has already advanced us past any such
|
||||
// whitespace.
|
||||
|
||||
if (char === 0x2b) { // +
|
||||
// We need to continue adding attribute pairs to the current RDN.
|
||||
pos += 1
|
||||
continue readRdnLoop
|
||||
}
|
||||
|
||||
/* istanbul ignore else */
|
||||
if (char === 0x2c || char === 0x3b) { // , or ;
|
||||
// The current RDN has been fully parsed, so push it to the list,
|
||||
// reset the collector, and start parsing the next RDN.
|
||||
rdns.push(rdn)
|
||||
rdn = {}
|
||||
pos += 1
|
||||
continue readRdnLoop
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return rdns
|
||||
}
|
||||
Reference in New Issue
Block a user