read-hex-string.js 1.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061
  1. 'use strict'
  2. const { BerReader } = require('@ldapjs/asn1')
  3. const isValidHexCode = code => /[0-9a-fA-F]{2}/.test(code) === true
  4. /**
  5. * @typedef {object} ReadHexStringResult
  6. * @property {number} endPos The position in the buffer where the end of the
  7. * hex string was encountered.
  8. * @property {import('@ldapjs/asn1').BerReader} berReader The parsed hex string
  9. * as an BER object.
  10. */
  11. /**
  12. * Read a sequence of bytes as a hex encoded octet string. The sequence is
  13. * assumed to be a spec compliant encoded BER object.
  14. *
  15. * @param {Buffer} searchBuffer The buffer to read.
  16. * @param {number} startPos The position in the buffer to start reading from.
  17. *
  18. * @returns {ReadHexStringResult}
  19. *
  20. * @throws When an invalid hex pair has been encountered.
  21. */
  22. module.exports = function readHexString ({ searchBuffer, startPos }) {
  23. const bytes = []
  24. let pos = startPos
  25. while (pos < searchBuffer.byteLength) {
  26. if (isEndChar(searchBuffer[pos])) {
  27. break
  28. }
  29. const hexPair = String.fromCharCode(searchBuffer[pos]) +
  30. String.fromCharCode(searchBuffer[pos + 1])
  31. if (isValidHexCode(hexPair) === false) {
  32. throw Error('invalid hex pair encountered: 0x' + hexPair)
  33. }
  34. bytes.push(parseInt(hexPair, 16))
  35. pos += 2
  36. }
  37. return {
  38. endPos: pos,
  39. berReader: new BerReader(Buffer.from(bytes))
  40. }
  41. }
  42. function isEndChar (c) {
  43. switch (c) {
  44. case 0x20: // space
  45. case 0x2b: // +
  46. case 0x2c: // ,
  47. case 0x3b: // ;
  48. return true
  49. default:
  50. return false
  51. }
  52. }