Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
96 changes: 27 additions & 69 deletions src/crypto/crypto_bio.cc
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,9 @@
// USE OR OTHER DEALINGS IN THE SOFTWARE.

#include "crypto/crypto_bio.h"
#include "allocated_buffer-inl.h"
#include "base_object-inl.h"
#include "memory_tracker-inl.h"
#include "allocated_buffer-inl.h"
#include "util-inl.h"

#include <openssl/bio.h>
Expand All @@ -35,17 +35,14 @@ namespace crypto {

BIOPointer NodeBIO::New(Environment* env) {
BIOPointer bio(BIO_new(GetMethod()));
if (bio && env != nullptr)
NodeBIO::FromBIO(bio.get())->env_ = env;
if (bio && env != nullptr) NodeBIO::FromBIO(bio.get())->env_ = env;
return bio;
}


BIOPointer NodeBIO::NewFixed(const char* data, size_t len, Environment* env) {
BIOPointer bio = New(env);

if (!bio ||
len > INT_MAX ||
if (!bio || len > INT_MAX ||
BIO_write(bio.get(), data, len) != static_cast<int>(len) ||
BIO_set_mem_eof_return(bio.get(), 0) != 1) {
return BIOPointer();
Expand All @@ -54,18 +51,15 @@ BIOPointer NodeBIO::NewFixed(const char* data, size_t len, Environment* env) {
return bio;
}


int NodeBIO::New(BIO* bio) {
BIO_set_data(bio, new NodeBIO());
BIO_set_init(bio, 1);

return 1;
}


int NodeBIO::Free(BIO* bio) {
if (bio == nullptr)
return 0;
if (bio == nullptr) return 0;

if (BIO_get_shutdown(bio)) {
if (BIO_get_init(bio) && BIO_get_data(bio) != nullptr) {
Expand All @@ -77,7 +71,6 @@ int NodeBIO::Free(BIO* bio) {
return 1;
}


int NodeBIO::Read(BIO* bio, char* out, int len) {
BIO_clear_retry_flags(bio);

Expand All @@ -94,13 +87,11 @@ int NodeBIO::Read(BIO* bio, char* out, int len) {
return bytes;
}


char* NodeBIO::Peek(size_t* size) {
*size = read_head_->write_pos_ - read_head_->read_pos_;
return read_head_->data_ + read_head_->read_pos_;
}


size_t NodeBIO::PeekMultiple(char** out, size_t* size, size_t* count) {
Buffer* pos = read_head_;
size_t max = *count;
Expand All @@ -127,7 +118,6 @@ size_t NodeBIO::PeekMultiple(char** out, size_t* size, size_t* count) {
return total;
}


int NodeBIO::Write(BIO* bio, const char* data, int len) {
BIO_clear_retry_flags(bio);

Expand All @@ -136,27 +126,22 @@ int NodeBIO::Write(BIO* bio, const char* data, int len) {
return len;
}


int NodeBIO::Puts(BIO* bio, const char* str) {
return Write(bio, str, strlen(str));
}


int NodeBIO::Gets(BIO* bio, char* out, int size) {
NodeBIO* nbio = FromBIO(bio);

if (nbio->Length() == 0)
return 0;
if (nbio->Length() == 0) return 0;

int i = nbio->IndexOf('\n', size);

// Include '\n', if it's there. If not, don't read off the end.
if (i < size && i >= 0 && static_cast<size_t>(i) < nbio->Length())
i++;
if (i < size && i >= 0 && static_cast<size_t>(i) < nbio->Length()) i++;

// Shift `i` a bit to nullptr-terminate string later
if (size == i)
i--;
if (size == i) i--;

// Flush read data
nbio->Read(out, i);
Expand All @@ -166,8 +151,9 @@ int NodeBIO::Gets(BIO* bio, char* out, int size) {
return i;
}


long NodeBIO::Ctrl(BIO* bio, int cmd, long num, // NOLINT(runtime/int)
long NodeBIO::Ctrl(BIO* bio, // NOLINT(runtime/int)
int cmd,
long num, // NOLINT(runtime/int)
void* ptr) {
NodeBIO* nbio;
long ret; // NOLINT(runtime/int)
Expand All @@ -187,8 +173,7 @@ long NodeBIO::Ctrl(BIO* bio, int cmd, long num, // NOLINT(runtime/int)
break;
case BIO_CTRL_INFO:
ret = nbio->Length();
if (ptr != nullptr)
*reinterpret_cast<void**>(ptr) = nullptr;
if (ptr != nullptr) *reinterpret_cast<void**>(ptr) = nullptr;
break;
case BIO_C_SET_BUF_MEM:
CHECK(0 && "Can't use SET_BUF_MEM_PTR with NodeBIO");
Expand Down Expand Up @@ -222,7 +207,6 @@ long NodeBIO::Ctrl(BIO* bio, int cmd, long num, // NOLINT(runtime/int)
return ret;
}


const BIO_METHOD* NodeBIO::GetMethod() {
// This is called from InitCryptoOnce() to avoid race conditions during
// initialization.
Expand All @@ -242,7 +226,6 @@ const BIO_METHOD* NodeBIO::GetMethod() {
return method;
}


void NodeBIO::TryMoveReadHead() {
// `read_pos_` and `write_pos_` means the position of the reader and writer
// inside the buffer, respectively. When they're equal - its safe to reset
Expand All @@ -256,12 +239,10 @@ void NodeBIO::TryMoveReadHead() {

// Move read_head_ forward, just in case if there're still some data to
// read in the next buffer.
if (read_head_ != write_head_)
read_head_ = read_head_->next_;
if (read_head_ != write_head_) read_head_ = read_head_->next_;
}
}


size_t NodeBIO::Read(char* out, size_t size) {
size_t bytes_read = 0;
size_t expected = Length() > size ? size : Length();
Expand All @@ -271,8 +252,7 @@ size_t NodeBIO::Read(char* out, size_t size) {
while (bytes_read < expected) {
CHECK_LE(read_head_->read_pos_, read_head_->write_pos_);
size_t avail = read_head_->write_pos_ - read_head_->read_pos_;
if (avail > left)
avail = left;
if (avail > left) avail = left;
Comment on lines -274 to +255
Copy link
Member Author

@Trott Trott Apr 9, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I find changes like this less readable and I'm guessing I'm not alone. (It further suggests to me that we don't actually use clang-format.) I imagine there's a configuration that could be changed in .clang-format if this is a highly-undesriable change (or we could add { and } which would presumably cause clang-format to leave the block on it's own line, although I haven't tested that).


// Copy data
if (out != nullptr)
Expand All @@ -295,16 +275,12 @@ size_t NodeBIO::Read(char* out, size_t size) {
return bytes_read;
}


void NodeBIO::FreeEmpty() {
if (write_head_ == nullptr)
return;
if (write_head_ == nullptr) return;
Buffer* child = write_head_->next_;
if (child == write_head_ || child == read_head_)
return;
if (child == write_head_ || child == read_head_) return;
Buffer* cur = child->next_;
if (cur == write_head_ || cur == read_head_)
return;
if (cur == write_head_ || cur == read_head_) return;

Buffer* prev = child;
while (cur != read_head_) {
Expand All @@ -318,7 +294,6 @@ void NodeBIO::FreeEmpty() {
prev->next_ = cur;
}


size_t NodeBIO::IndexOf(char delim, size_t limit) {
size_t bytes_read = 0;
size_t max = Length() > limit ? limit : Length();
Expand All @@ -328,8 +303,7 @@ size_t NodeBIO::IndexOf(char delim, size_t limit) {
while (bytes_read < max) {
CHECK_LE(current->read_pos_, current->write_pos_);
size_t avail = current->write_pos_ - current->read_pos_;
if (avail > left)
avail = left;
if (avail > left) avail = left;

// Walk through data
char* tmp = current->data_ + current->read_pos_;
Expand Down Expand Up @@ -358,7 +332,6 @@ size_t NodeBIO::IndexOf(char delim, size_t limit) {
return max;
}


void NodeBIO::Write(const char* data, size_t size) {
size_t offset = 0;
size_t left = size;
Expand All @@ -371,13 +344,11 @@ void NodeBIO::Write(const char* data, size_t size) {
CHECK_LE(write_head_->write_pos_, write_head_->len_);
size_t avail = write_head_->len_ - write_head_->write_pos_;

if (to_write > avail)
to_write = avail;
if (to_write > avail) to_write = avail;

// Copy data
memcpy(write_head_->data_ + write_head_->write_pos_,
data + offset,
to_write);
memcpy(
write_head_->data_ + write_head_->write_pos_, data + offset, to_write);

// Move pointers
left -= to_write;
Expand All @@ -400,18 +371,15 @@ void NodeBIO::Write(const char* data, size_t size) {
CHECK_EQ(left, 0);
}


char* NodeBIO::PeekWritable(size_t* size) {
TryAllocateForWrite(*size);

size_t available = write_head_->len_ - write_head_->write_pos_;
if (*size == 0 || available <= *size)
*size = available;
if (*size == 0 || available <= *size) *size = available;

return write_head_->data_ + write_head_->write_pos_;
}


void NodeBIO::Commit(size_t size) {
write_head_->write_pos_ += size;
length_ += size;
Expand All @@ -429,18 +397,14 @@ void NodeBIO::Commit(size_t size) {
}
}


void NodeBIO::TryAllocateForWrite(size_t hint) {
Buffer* w = write_head_;
Buffer* r = read_head_;
// If write head is full, next buffer is either read head or not empty.
if (w == nullptr ||
(w->write_pos_ == w->len_ &&
(w->next_ == r || w->next_->write_pos_ != 0))) {
size_t len = w == nullptr ? initial_ :
kThroughputBufferLength;
if (len < hint)
len = hint;
if (w == nullptr || (w->write_pos_ == w->len_ &&
(w->next_ == r || w->next_->write_pos_ != 0))) {
size_t len = w == nullptr ? initial_ : kThroughputBufferLength;
if (len < hint) len = hint;

// If there is a one time allocation size hint, use it.
if (allocate_hint_ > len) {
Expand All @@ -461,10 +425,8 @@ void NodeBIO::TryAllocateForWrite(size_t hint) {
}
}


void NodeBIO::Reset() {
if (read_head_ == nullptr)
return;
if (read_head_ == nullptr) return;

while (read_head_->read_pos_ != read_head_->write_pos_) {
CHECK(read_head_->write_pos_ > read_head_->read_pos_);
Expand All @@ -479,10 +441,8 @@ void NodeBIO::Reset() {
CHECK_EQ(length_, 0);
}


NodeBIO::~NodeBIO() {
if (read_head_ == nullptr)
return;
if (read_head_ == nullptr) return;

Buffer* current = read_head_;
do {
Expand All @@ -495,12 +455,10 @@ NodeBIO::~NodeBIO() {
write_head_ = nullptr;
}


NodeBIO* NodeBIO::FromBIO(BIO* bio) {
CHECK_NOT_NULL(BIO_get_data(bio));
return static_cast<NodeBIO*>(BIO_get_data(bio));
}


} // namespace crypto
} // namespace node
31 changes: 11 additions & 20 deletions src/crypto/crypto_bio.h
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,8 @@ class NodeBIO : public MemoryRetainer {

// NewFixed takes a copy of `len` bytes from `data` and returns a BIO that,
// when read from, returns those bytes followed by EOF.
static BIOPointer NewFixed(const char* data, size_t len,
static BIOPointer NewFixed(const char* data,
size_t len,
Environment* env = nullptr);

// Move read head to next buffer if needed
Expand Down Expand Up @@ -89,11 +90,8 @@ class NodeBIO : public MemoryRetainer {
// PeekWritable().
void Commit(size_t size);


// Return size of buffer in bytes
inline size_t Length() const {
return length_;
}
inline size_t Length() const { return length_; }

// Provide a hint about the size of the next pending set of writes. TLS
// writes records of a maximum length of 16k of data plus a 5-byte header,
Expand All @@ -110,17 +108,11 @@ class NodeBIO : public MemoryRetainer {
}
}

inline void set_eof_return(int num) {
eof_return_ = num;
}
inline void set_eof_return(int num) { eof_return_ = num; }

inline int eof_return() {
return eof_return_;
}
inline int eof_return() { return eof_return_; }

inline void set_initial(size_t initial) {
initial_ = initial;
}
inline void set_initial(size_t initial) { initial_ = initial; }

static NodeBIO* FromBIO(BIO* bio);

Expand All @@ -138,7 +130,9 @@ class NodeBIO : public MemoryRetainer {
static int Write(BIO* bio, const char* data, int len);
static int Puts(BIO* bio, const char* str);
static int Gets(BIO* bio, char* out, int size);
static long Ctrl(BIO* bio, int cmd, long num, // NOLINT(runtime/int)
static long Ctrl(BIO* bio, // NOLINT(runtime/int)
int cmd,
long num, // NOLINT(runtime/int)
void* ptr);

static const BIO_METHOD* GetMethod();
Expand All @@ -149,11 +143,8 @@ class NodeBIO : public MemoryRetainer {

class Buffer {
public:
Buffer(Environment* env, size_t len) : env_(env),
read_pos_(0),
write_pos_(0),
len_(len),
next_(nullptr) {
Buffer(Environment* env, size_t len)
: env_(env), read_pos_(0), write_pos_(0), len_(len), next_(nullptr) {
data_ = new char[len];
if (env_ != nullptr)
env_->isolate()->AdjustAmountOfExternalAllocatedMemory(len);
Expand Down