diff --git a/src/node_buffer.cc b/src/node_buffer.cc index eb8e541c68635d..b96b39a8c31d72 100644 --- a/src/node_buffer.cc +++ b/src/node_buffer.cc @@ -244,7 +244,18 @@ bool HasInstance(Local obj) { char* Data(Local val) { CHECK(val->IsArrayBufferView()); Local ui = val.As(); - return static_cast(ui->Buffer()->Data()) + ui->ByteOffset(); + // GetBackingStore() is slow, and this would be faster if we just did + // ui->Buffer()->Data(). However these two are not equivalent in the case of + // zero-length buffers: the former returns a "valid" address, while the + // latter returns `NULL`. At least one library in the ecosystem (see the + // referenced issue) abuses zero-length buffers to wrap arbitrary pointers, + // which is broken by this difference. It is unfortunate that every library + // needs to take a performance hit because of this edge-case, so this change + // is only being backported to older Node.js releases. + // + // See: https://github.com/nodejs/node/issues/44554 + return static_cast(ui->Buffer()->GetBackingStore()->Data()) + + ui->ByteOffset(); }