Skip to content

Commit 47c2b67

Browse files
bnoordhuisaddaleax
authored andcommitted
src: DRY crypto Update() methods
Factor out the common logic into a template function. Removes approximately six instances of copy/pasted code. PR-URL: #31767 Reviewed-By: Santiago Gimeno <santiago.gimeno@gmail.com> Reviewed-By: Anna Henningsen <anna@addaleax.net> Reviewed-By: Colin Ihrig <cjihrig@gmail.com> Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: David Carlier <devnexen@gmail.com> Reviewed-By: Tobias Nießen <tniessen@tnie.de>
1 parent 3b9a403 commit 47c2b67

File tree

1 file changed

+56
-113
lines changed

1 file changed

+56
-113
lines changed

src/node_crypto.cc

+56-113
Original file line numberDiff line numberDiff line change
@@ -145,6 +145,26 @@ template int SSLWrap<TLSWrap>::SelectALPNCallback(
145145
unsigned int inlen,
146146
void* arg);
147147

148+
template <typename T>
149+
void Decode(const FunctionCallbackInfo<Value>& args,
150+
void (*callback)(T*, const FunctionCallbackInfo<Value>&,
151+
const char*, size_t)) {
152+
T* ctx;
153+
ASSIGN_OR_RETURN_UNWRAP(&ctx, args.Holder());
154+
155+
if (args[0]->IsString()) {
156+
StringBytes::InlineDecoder decoder;
157+
Environment* env = Environment::GetCurrent(args);
158+
enum encoding enc = ParseEncoding(env->isolate(), args[1], UTF8);
159+
if (decoder.Decode(env, args[0].As<String>(), enc).IsNothing())
160+
return;
161+
callback(ctx, args, decoder.out(), decoder.size());
162+
} else {
163+
ArrayBufferViewContents<char> buf(args[0]);
164+
callback(ctx, args, buf.data(), buf.length());
165+
}
166+
}
167+
148168
static int PasswordCallback(char* buf, int size, int rwflag, void* u) {
149169
const char* passphrase = static_cast<char*>(u);
150170
if (passphrase != nullptr) {
@@ -3946,38 +3966,24 @@ CipherBase::UpdateResult CipherBase::Update(const char* data,
39463966

39473967

39483968
void CipherBase::Update(const FunctionCallbackInfo<Value>& args) {
3949-
Environment* env = Environment::GetCurrent(args);
3950-
3951-
CipherBase* cipher;
3952-
ASSIGN_OR_RETURN_UNWRAP(&cipher, args.Holder());
3953-
3954-
AllocatedBuffer out;
3955-
UpdateResult r;
3956-
3957-
// Only copy the data if we have to, because it's a string
3958-
if (args[0]->IsString()) {
3959-
StringBytes::InlineDecoder decoder;
3960-
enum encoding enc = ParseEncoding(env->isolate(), args[1], UTF8);
3961-
3962-
if (decoder.Decode(env, args[0].As<String>(), enc).IsNothing())
3969+
Decode<CipherBase>(args, [](CipherBase* cipher,
3970+
const FunctionCallbackInfo<Value>& args,
3971+
const char* data, size_t size) {
3972+
AllocatedBuffer out;
3973+
UpdateResult r = cipher->Update(data, size, &out);
3974+
3975+
if (r != kSuccess) {
3976+
if (r == kErrorState) {
3977+
Environment* env = Environment::GetCurrent(args);
3978+
ThrowCryptoError(env, ERR_get_error(),
3979+
"Trying to add data in unsupported state");
3980+
}
39633981
return;
3964-
r = cipher->Update(decoder.out(), decoder.size(), &out);
3965-
} else {
3966-
ArrayBufferViewContents<char> buf(args[0]);
3967-
r = cipher->Update(buf.data(), buf.length(), &out);
3968-
}
3969-
3970-
if (r != kSuccess) {
3971-
if (r == kErrorState) {
3972-
ThrowCryptoError(env, ERR_get_error(),
3973-
"Trying to add data in unsupported state");
39743982
}
3975-
return;
3976-
}
3977-
3978-
CHECK(out.data() != nullptr || out.size() == 0);
39793983

3980-
args.GetReturnValue().Set(out.ToBuffer().ToLocalChecked());
3984+
CHECK(out.data() != nullptr || out.size() == 0);
3985+
args.GetReturnValue().Set(out.ToBuffer().ToLocalChecked());
3986+
});
39813987
}
39823988

39833989

@@ -4139,26 +4145,11 @@ bool Hmac::HmacUpdate(const char* data, int len) {
41394145

41404146

41414147
void Hmac::HmacUpdate(const FunctionCallbackInfo<Value>& args) {
4142-
Environment* env = Environment::GetCurrent(args);
4143-
4144-
Hmac* hmac;
4145-
ASSIGN_OR_RETURN_UNWRAP(&hmac, args.Holder());
4146-
4147-
// Only copy the data if we have to, because it's a string
4148-
bool r = false;
4149-
if (args[0]->IsString()) {
4150-
StringBytes::InlineDecoder decoder;
4151-
enum encoding enc = ParseEncoding(env->isolate(), args[1], UTF8);
4152-
4153-
if (!decoder.Decode(env, args[0].As<String>(), enc).IsNothing()) {
4154-
r = hmac->HmacUpdate(decoder.out(), decoder.size());
4155-
}
4156-
} else {
4157-
ArrayBufferViewContents<char> buf(args[0]);
4158-
r = hmac->HmacUpdate(buf.data(), buf.length());
4159-
}
4160-
4161-
args.GetReturnValue().Set(r);
4148+
Decode<Hmac>(args, [](Hmac* hmac, const FunctionCallbackInfo<Value>& args,
4149+
const char* data, size_t size) {
4150+
bool r = hmac->HmacUpdate(data, size);
4151+
args.GetReturnValue().Set(r);
4152+
});
41624153
}
41634154

41644155

@@ -4287,28 +4278,11 @@ bool Hash::HashUpdate(const char* data, int len) {
42874278

42884279

42894280
void Hash::HashUpdate(const FunctionCallbackInfo<Value>& args) {
4290-
Environment* env = Environment::GetCurrent(args);
4291-
4292-
Hash* hash;
4293-
ASSIGN_OR_RETURN_UNWRAP(&hash, args.Holder());
4294-
4295-
// Only copy the data if we have to, because it's a string
4296-
bool r = true;
4297-
if (args[0]->IsString()) {
4298-
StringBytes::InlineDecoder decoder;
4299-
enum encoding enc = ParseEncoding(env->isolate(), args[1], UTF8);
4300-
4301-
if (decoder.Decode(env, args[0].As<String>(), enc).IsNothing()) {
4302-
args.GetReturnValue().Set(false);
4303-
return;
4304-
}
4305-
r = hash->HashUpdate(decoder.out(), decoder.size());
4306-
} else if (args[0]->IsArrayBufferView()) {
4307-
ArrayBufferViewContents<char> buf(args[0].As<ArrayBufferView>());
4308-
r = hash->HashUpdate(buf.data(), buf.length());
4309-
}
4310-
4311-
args.GetReturnValue().Set(r);
4281+
Decode<Hash>(args, [](Hash* hash, const FunctionCallbackInfo<Value>& args,
4282+
const char* data, size_t size) {
4283+
bool r = hash->HashUpdate(data, size);
4284+
args.GetReturnValue().Set(r);
4285+
});
43124286
}
43134287

43144288

@@ -4509,27 +4483,11 @@ void Sign::SignInit(const FunctionCallbackInfo<Value>& args) {
45094483

45104484

45114485
void Sign::SignUpdate(const FunctionCallbackInfo<Value>& args) {
4512-
Environment* env = Environment::GetCurrent(args);
4513-
4514-
Sign* sign;
4515-
ASSIGN_OR_RETURN_UNWRAP(&sign, args.Holder());
4516-
4517-
Error err;
4518-
4519-
// Only copy the data if we have to, because it's a string
4520-
if (args[0]->IsString()) {
4521-
StringBytes::InlineDecoder decoder;
4522-
enum encoding enc = ParseEncoding(env->isolate(), args[1], UTF8);
4523-
4524-
if (decoder.Decode(env, args[0].As<String>(), enc).IsNothing())
4525-
return;
4526-
err = sign->Update(decoder.out(), decoder.size());
4527-
} else {
4528-
ArrayBufferViewContents<char> buf(args[0]);
4529-
err = sign->Update(buf.data(), buf.length());
4530-
}
4531-
4532-
sign->CheckThrow(err);
4486+
Decode<Sign>(args, [](Sign* sign, const FunctionCallbackInfo<Value>& args,
4487+
const char* data, size_t size) {
4488+
Error err = sign->Update(data, size);
4489+
sign->CheckThrow(err);
4490+
});
45334491
}
45344492

45354493
static int GetDefaultSignPadding(const ManagedEVPPKey& key) {
@@ -4847,27 +4805,12 @@ void Verify::VerifyInit(const FunctionCallbackInfo<Value>& args) {
48474805

48484806

48494807
void Verify::VerifyUpdate(const FunctionCallbackInfo<Value>& args) {
4850-
Environment* env = Environment::GetCurrent(args);
4851-
4852-
Verify* verify;
4853-
ASSIGN_OR_RETURN_UNWRAP(&verify, args.Holder());
4854-
4855-
Error err;
4856-
4857-
// Only copy the data if we have to, because it's a string
4858-
if (args[0]->IsString()) {
4859-
StringBytes::InlineDecoder decoder;
4860-
enum encoding enc = ParseEncoding(env->isolate(), args[1], UTF8);
4861-
4862-
if (decoder.Decode(env, args[0].As<String>(), enc).IsNothing())
4863-
return;
4864-
err = verify->Update(decoder.out(), decoder.size());
4865-
} else {
4866-
ArrayBufferViewContents<char> buf(args[0]);
4867-
err = verify->Update(buf.data(), buf.length());
4868-
}
4869-
4870-
verify->CheckThrow(err);
4808+
Decode<Verify>(args, [](Verify* verify,
4809+
const FunctionCallbackInfo<Value>& args,
4810+
const char* data, size_t size) {
4811+
Error err = verify->Update(data, size);
4812+
verify->CheckThrow(err);
4813+
});
48714814
}
48724815

48734816

0 commit comments

Comments
 (0)