First commit
This commit is contained in:
137
node_modules/@ldapjs/dn/lib/utils/parse-string/read-escape-sequence.js
generated
vendored
Normal file
137
node_modules/@ldapjs/dn/lib/utils/parse-string/read-escape-sequence.js
generated
vendored
Normal file
@ -0,0 +1,137 @@
|
||||
'use strict'
|
||||
|
||||
/**
|
||||
* @typedef ReadEscapeSequenceResult
|
||||
* @property {number} endPos The position in the buffer that marks the end of
|
||||
* the escape sequence.
|
||||
* @property {Buffer} parsed The parsed escape sequence as a buffer of bytes.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Read an escape sequence from a buffer. It reads until no escape sequences
|
||||
* are found. Thus, a sequence of escape sequences will all be parsed at once
|
||||
* and returned as a single result.
|
||||
*
|
||||
* @example A Single ASCII Sequence
|
||||
* const toParse = Buffer.from('foo\\#bar', 'utf8')
|
||||
* const {parsed, endPos} = readEscapeSequence({
|
||||
* searchBuffer: toParse,
|
||||
* startPos: 3
|
||||
* })
|
||||
* // => parsed = '#', endPos = 5
|
||||
*
|
||||
* @example Multiple ASCII Sequences In Succession
|
||||
* const toParse = Buffer.from('foo\\#\\!bar', 'utf8')
|
||||
* const {parsed, endPos} = readEscapeSequence({
|
||||
* searchBuffer: toParse,
|
||||
* startPos: 3
|
||||
* })
|
||||
* // => parsed = '#!', endPos = 7
|
||||
*
|
||||
* @param searchBuffer
|
||||
* @param startPos
|
||||
*
|
||||
* @returns {ReadEscapeSequenceResult}
|
||||
*
|
||||
* @throws When an escaped sequence is not a valid hexadecimal value.
|
||||
*/
|
||||
module.exports = function readEscapeSequence ({ searchBuffer, startPos }) {
|
||||
// This is very similar to the `readEscapedCharacters` algorithm in
|
||||
// the `utils/escape-filter-value` in `@ldapjs/filter`. The difference being
|
||||
// that here we want to interpret the escape sequence instead of return it
|
||||
// as a string to be embedded in an "escaped" string.
|
||||
// https://github.com/ldapjs/filter/blob/1423612/lib/utils/escape-filter-value.js
|
||||
|
||||
let pos = startPos
|
||||
const buf = []
|
||||
|
||||
while (pos < searchBuffer.byteLength) {
|
||||
const char = searchBuffer[pos]
|
||||
const nextChar = searchBuffer[pos + 1]
|
||||
|
||||
if (char !== 0x5c) {
|
||||
// End of sequence reached.
|
||||
break
|
||||
}
|
||||
|
||||
const strHexCode = String.fromCharCode(nextChar) +
|
||||
String.fromCharCode(searchBuffer[pos + 2])
|
||||
const hexCode = parseInt(strHexCode, 16)
|
||||
if (Number.isNaN(hexCode) === true) {
|
||||
if (nextChar >= 0x00 && nextChar <= 0x7f) {
|
||||
// Sequence is a single escaped ASCII character
|
||||
buf.push(nextChar)
|
||||
pos += 2
|
||||
continue
|
||||
} else {
|
||||
throw Error('invalid hex code in escape sequence')
|
||||
}
|
||||
}
|
||||
|
||||
if (hexCode >= 0xc0 && hexCode <= 0xdf) {
|
||||
// Sequence is a 2-byte utf-8 character.
|
||||
const secondByte = parseInt(
|
||||
String.fromCharCode(searchBuffer[pos + 4]) +
|
||||
String.fromCharCode(searchBuffer[pos + 5]),
|
||||
16
|
||||
)
|
||||
buf.push(hexCode)
|
||||
buf.push(secondByte)
|
||||
pos += 6
|
||||
continue
|
||||
}
|
||||
|
||||
if (hexCode >= 0xe0 && hexCode <= 0xef) {
|
||||
// Sequence is a 3-byte utf-8 character.
|
||||
const secondByte = parseInt(
|
||||
String.fromCharCode(searchBuffer[pos + 4]) +
|
||||
String.fromCharCode(searchBuffer[pos + 5]),
|
||||
16
|
||||
)
|
||||
const thirdByte = parseInt(
|
||||
String.fromCharCode(searchBuffer[pos + 7]) +
|
||||
String.fromCharCode(searchBuffer[pos + 8]),
|
||||
16
|
||||
)
|
||||
buf.push(hexCode)
|
||||
buf.push(secondByte)
|
||||
buf.push(thirdByte)
|
||||
pos += 9
|
||||
continue
|
||||
}
|
||||
|
||||
if (hexCode >= 0xf0 && hexCode <= 0xf7) {
|
||||
// Sequence is a 4-byte utf-8 character.
|
||||
const secondByte = parseInt(
|
||||
String.fromCharCode(searchBuffer[pos + 4]) +
|
||||
String.fromCharCode(searchBuffer[pos + 5]),
|
||||
16
|
||||
)
|
||||
const thirdByte = parseInt(
|
||||
String.fromCharCode(searchBuffer[pos + 7]) +
|
||||
String.fromCharCode(searchBuffer[pos + 8]),
|
||||
16
|
||||
)
|
||||
const fourthByte = parseInt(
|
||||
String.fromCharCode(searchBuffer[pos + 10]) +
|
||||
String.fromCharCode(searchBuffer[pos + 11]),
|
||||
16
|
||||
)
|
||||
buf.push(hexCode)
|
||||
buf.push(secondByte)
|
||||
buf.push(thirdByte)
|
||||
buf.push(fourthByte)
|
||||
pos += 12
|
||||
continue
|
||||
}
|
||||
|
||||
// The escaped character should be a single hex value.
|
||||
buf.push(hexCode)
|
||||
pos += 3
|
||||
}
|
||||
|
||||
return {
|
||||
endPos: pos,
|
||||
parsed: Buffer.from(buf)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user