tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

buffer-util.js (2971B)


      1 'use strict';
      2 
      3 const { EMPTY_BUFFER } = require('./constants');
      4 
      5 /**
      6 * Merges an array of buffers into a new buffer.
      7 *
      8 * @param {Buffer[]} list The array of buffers to concat
      9 * @param {Number} totalLength The total length of buffers in the list
     10 * @return {Buffer} The resulting buffer
     11 * @public
     12 */
     13 function concat(list, totalLength) {
     14  if (list.length === 0) return EMPTY_BUFFER;
     15  if (list.length === 1) return list[0];
     16 
     17  const target = Buffer.allocUnsafe(totalLength);
     18  let offset = 0;
     19 
     20  for (let i = 0; i < list.length; i++) {
     21    const buf = list[i];
     22    target.set(buf, offset);
     23    offset += buf.length;
     24  }
     25 
     26  if (offset < totalLength) return target.slice(0, offset);
     27 
     28  return target;
     29 }
     30 
     31 /**
     32 * Masks a buffer using the given mask.
     33 *
     34 * @param {Buffer} source The buffer to mask
     35 * @param {Buffer} mask The mask to use
     36 * @param {Buffer} output The buffer where to store the result
     37 * @param {Number} offset The offset at which to start writing
     38 * @param {Number} length The number of bytes to mask.
     39 * @public
     40 */
     41 function _mask(source, mask, output, offset, length) {
     42  for (let i = 0; i < length; i++) {
     43    output[offset + i] = source[i] ^ mask[i & 3];
     44  }
     45 }
     46 
     47 /**
     48 * Unmasks a buffer using the given mask.
     49 *
     50 * @param {Buffer} buffer The buffer to unmask
     51 * @param {Buffer} mask The mask to use
     52 * @public
     53 */
     54 function _unmask(buffer, mask) {
     55  for (let i = 0; i < buffer.length; i++) {
     56    buffer[i] ^= mask[i & 3];
     57  }
     58 }
     59 
     60 /**
     61 * Converts a buffer to an `ArrayBuffer`.
     62 *
     63 * @param {Buffer} buf The buffer to convert
     64 * @return {ArrayBuffer} Converted buffer
     65 * @public
     66 */
     67 function toArrayBuffer(buf) {
     68  if (buf.byteLength === buf.buffer.byteLength) {
     69    return buf.buffer;
     70  }
     71 
     72  return buf.buffer.slice(buf.byteOffset, buf.byteOffset + buf.byteLength);
     73 }
     74 
     75 /**
     76 * Converts `data` to a `Buffer`.
     77 *
     78 * @param {*} data The data to convert
     79 * @return {Buffer} The buffer
     80 * @throws {TypeError}
     81 * @public
     82 */
     83 function toBuffer(data) {
     84  toBuffer.readOnly = true;
     85 
     86  if (Buffer.isBuffer(data)) return data;
     87 
     88  let buf;
     89 
     90  if (data instanceof ArrayBuffer) {
     91    buf = Buffer.from(data);
     92  } else if (ArrayBuffer.isView(data)) {
     93    buf = Buffer.from(data.buffer, data.byteOffset, data.byteLength);
     94  } else {
     95    buf = Buffer.from(data);
     96    toBuffer.readOnly = false;
     97  }
     98 
     99  return buf;
    100 }
    101 
    102 module.exports = {
    103  concat,
    104  mask: _mask,
    105  toArrayBuffer,
    106  toBuffer,
    107  unmask: _unmask
    108 };
    109 
    110 /* istanbul ignore else  */
    111 if (!process.env.WS_NO_BUFFER_UTIL) {
    112  try {
    113    const bufferUtil = require('bufferutil');
    114 
    115    module.exports.mask = function (source, mask, output, offset, length) {
    116      if (length < 48) _mask(source, mask, output, offset, length);
    117      else bufferUtil.mask(source, mask, output, offset, length);
    118    };
    119 
    120    module.exports.unmask = function (buffer, mask) {
    121      if (buffer.length < 32) _unmask(buffer, mask);
    122      else bufferUtil.unmask(buffer, mask);
    123    };
    124  } catch (e) {
    125    // Continue regardless of the error.
    126  }
    127 }