read-attribute-pair.js 2.0 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273
  1. 'use strict'
  2. const findNameStart = require('./find-name-start')
  3. const findNameEnd = require('./find-name-end')
  4. const isValidAttributeTypeName = require('./is-valid-attribute-type-name')
  5. const readAttributeValue = require('./read-attribute-value')
  6. /**
  7. * @typedef {object} AttributePair
  8. * @property {string | import('@ldapjs/asn1').BerReader} name Property name is
  9. * actually the property name of the attribute pair. The value will be a string,
  10. * or, in the case of the value being a hex encoded string, an instance of
  11. * `BerReader`.
  12. *
  13. * @example
  14. * const input = 'foo=bar'
  15. * const pair = { foo: 'bar' }
  16. */
  17. /**
  18. * @typedef {object} ReadAttributePairResult
  19. * @property {number} endPos The ending position in the input search buffer that
  20. * is the end of the read attribute pair.
  21. * @property {AttributePair} pair The parsed attribute pair.
  22. */
  23. /**
  24. * Read an RDN attribute type and attribute value pair from the provided
  25. * search buffer at the given starting position.
  26. *
  27. * @param {Buffer} searchBuffer
  28. * @param {number} startPos
  29. *
  30. * @returns {ReadAttributePairResult}
  31. *
  32. * @throws When there is some problem with the input string.
  33. */
  34. module.exports = function readAttributePair ({ searchBuffer, startPos }) {
  35. let pos = startPos
  36. const nameStartPos = findNameStart({
  37. searchBuffer,
  38. startPos: pos
  39. })
  40. if (nameStartPos < 0) {
  41. throw Error('invalid attribute name leading character encountered')
  42. }
  43. const nameEndPos = findNameEnd({
  44. searchBuffer,
  45. startPos: nameStartPos
  46. })
  47. if (nameStartPos < 0) {
  48. throw Error('invalid character in attribute name encountered')
  49. }
  50. const attributeName = searchBuffer.subarray(nameStartPos, nameEndPos).toString('utf8')
  51. if (isValidAttributeTypeName(attributeName) === false) {
  52. throw Error('invalid attribute type name: ' + attributeName)
  53. }
  54. const valueReadResult = readAttributeValue({
  55. searchBuffer,
  56. startPos: nameEndPos
  57. })
  58. pos = valueReadResult.endPos
  59. const attributeValue = valueReadResult.value
  60. return {
  61. endPos: pos,
  62. pair: { [attributeName]: attributeValue }
  63. }
  64. }