Skip to content
Closed
Show file tree
Hide file tree
Changes from 6 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
4 changes: 2 additions & 2 deletions lib/buffer.js
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ const {

const {
byteLengthUtf8,
bufferToString,
compare: _compare,
compareOffset,
createFromString,
Expand Down Expand Up @@ -1237,8 +1238,7 @@ function btoa(input) {
if (input[n].charCodeAt(0) > 0xff)
throw lazyDOMException('Invalid character', 'InvalidCharacterError');
}
const buf = Buffer.from(input, 'latin1');
return buf.toString('base64');
return bufferToString(input, 'latin1', 'base64');
}

// Refs: https://infra.spec.whatwg.org/#forgiving-base64-decode
Expand Down
45 changes: 45 additions & 0 deletions src/node_buffer.cc
Original file line number Diff line number Diff line change
Expand Up @@ -520,6 +520,49 @@ MaybeLocal<Object> New(Environment* env,

namespace {

// TODO: Buffer.from(buf, fromEnc).toString(buf, toEnc)
void BufferToString(const FunctionCallbackInfo<Value>& args) {
CHECK_GE(args.Length(), 3);

// TODO: btoa('a') is throwing error: assertion failed
CHECK(args[0]->IsArrayBuffer() || args[0]->IsSharedArrayBuffer() ||
Comment thread
anonrig marked this conversation as resolved.
Outdated
args[0]->IsArrayBufferView());
CHECK(args[1]->IsString());
CHECK(args[2]->IsString());

Environment* env = Environment::GetCurrent(args);
Isolate* isolate = env->isolate();

enum encoding from_encoding = ParseEncoding(isolate, args[1], UTF8);
enum encoding to_encoding = ParseEncoding(isolate, args[2], UTF8);

Local<Value> error;
MaybeLocal<Value> maybe_ret;

if (args[0]->IsArrayBuffer() || args[0]->IsSharedArrayBuffer() ||
args[0]->IsArrayBufferView()) {
ArrayBufferViewContents<char> buffer(args[0]);
if (buffer.length() == 0) {
return args.GetReturnValue().SetEmptyString();
}
maybe_ret = StringBytes::Encode(
isolate, buffer.data(), buffer.length(), from_encoding, &error);
} else if (args[0]->IsString()) {
ArrayBufferViewContents<char> buffer(args[0]);
size_t length = buffer.length();
const char* data = buffer.data();
maybe_ret = StringBytes::Encode(
isolate, data, length, to_encoding, &error);
}
Local<Value> ret;
if (!maybe_ret.ToLocal(&ret)) {
CHECK(!error.IsEmpty());
isolate->ThrowException(error);
return;
}
args.GetReturnValue().Set(ret);
}

void CreateFromString(const FunctionCallbackInfo<Value>& args) {
CHECK(args[0]->IsString());
CHECK(args[1]->IsInt32());
Expand Down Expand Up @@ -1325,6 +1368,7 @@ void Initialize(Local<Object> target,

SetMethod(context, target, "setBufferPrototype", SetBufferPrototype);
SetMethodNoSideEffect(context, target, "createFromString", CreateFromString);
SetMethodNoSideEffect(context, target, "bufferToString", BufferToString);
SetMethodNoSideEffect(context, target, "decodeUTF8", DecodeUTF8);

SetMethodNoSideEffect(context, target, "byteLengthUtf8", ByteLengthUtf8);
Expand Down Expand Up @@ -1382,6 +1426,7 @@ void Initialize(Local<Object> target,

void RegisterExternalReferences(ExternalReferenceRegistry* registry) {
registry->Register(SetBufferPrototype);
registry->Register(BufferToString);
registry->Register(CreateFromString);
registry->Register(DecodeUTF8);

Expand Down