Buffer的buf.fill(value)方法在value为一个长度为0的Buffer时会卡死,是bug吗?
发布于 7 年前 作者 dislido 2805 次浏览 来自 问答

Node版本8.1.2

const src = Buffer.alloc(0);
const dist = Buffer.alloc(10);
dist.fill(src);

这段代码会卡死,CPU满占用 API文档中没写value为长度为0的Buffer时的处理,感觉正常来说应该是等同于没有进行fill操作,是bug吗?

2 回复

看源码assertSize没有验证size为0的情况,正常情况下不会写出Buffer.alloc(0)这样的代码,可以说算bug也可以说不算bug

/**
 * Creates a new filled Buffer instance.
 * alloc(size[, fill[, encoding]])
 **/
Buffer.alloc = function(size, fill, encoding) {
  assertSize(size);
  if (size > 0 && fill !== undefined) {
    // Since we are filling anyway, don't zero fill initially.
    // Only pay attention to encoding if it's a string. This
    // prevents accidentally sending in a number that would
    // be interpreted as a start offset.
    if (typeof encoding !== 'string')
      encoding = undefined;
    return createUnsafeBuffer(size).fill(fill, encoding);
  }
  return new FastBuffer(size);
};


// The 'assertSize' method will remove itself from the callstack when an error
// occurs. This is done simply to keep the internal details of the
// implementation from bleeding out to users.
function assertSize(size) {
  let err = null;

  if (typeof size !== 'number') {
    err = new TypeError('"size" argument must be a number');
  } else if (size < 0) {
    err = new RangeError('"size" argument must not be negative');
  } else if (size > binding.kMaxLength) {
    err = new RangeError('"size" argument must not be larger ' +
                         'than ' + binding.kMaxLength);
  }

  if (err) {
    Error.captureStackTrace(err, assertSize);
    throw err;
  }
}

@godghdai 是的,我是在用buffer.slice的时候获得了空buffer导致的bug,看来还是要加上长度判断了

回到顶部