Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

crypto: accept decimal Number in randomBytes #15130

Closed
wants to merge 1 commit into from

Conversation

benjamingr
Copy link
Member

@benjamingr benjamingr commented Sep 1, 2017

This change adds the ability to pass a double into randomBytes based on feedback from #15118 which aligns the behavior with other core methods like setTimeout

Marking as semver-major out of caution but generally I think this is patch.

No docs were changed because this actually aligns with the documented behavior better.

  • make -j4 test (UNIX), or vcbuild test (Windows) passes
  • tests and/or benchmarks are included
  • commit message follows commit guidelines
Affected core subsystem(s)

crypto

@nodejs-github-bot nodejs-github-bot added c++ Issues and PRs that require attention from people who are familiar with C++. crypto Issues and PRs related to the crypto subsystem. labels Sep 1, 2017
@benjamingr benjamingr added the semver-major PRs that contain breaking changes and should be released in the next major version. label Sep 1, 2017
@benjamingr benjamingr changed the title crypto: accept Number with decimal point in randomBytes crypto: accept decimal Number in randomBytes Sep 1, 2017
@@ -5616,13 +5616,13 @@ void RandomBytesProcessSync(Environment* env,
void RandomBytes(const FunctionCallbackInfo<Value>& args) {
Environment* env = Environment::GetCurrent(args);

if (!args[0]->IsUint32()) {
if (!args[0]->IsNumber() || args[0]->NumberValue() < 0) {
Copy link
Contributor

Choose a reason for hiding this comment

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

I wonder if the args[0]->NumberValue() has a performance impact here? Could you not use args[0].As<Number>?

Copy link
Member Author

Choose a reason for hiding this comment

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

@evanlucas did you accidentally add a not in? Would you like me to change it to as<Number>?

for the record NumberValue does if (obj->IsNumber()) return Just(obj->Number());

Copy link
Contributor

Choose a reason for hiding this comment

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

No, I thought it had come up a few times that .As() is faster than *Value(), but could be wrong. I haven't done any performance testing on the difference though. Being that this is used for things like uuid generation, checking which is faster would probably be a good thing though.

Copy link
Member

@addaleax addaleax Sep 1, 2017

Choose a reason for hiding this comment

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

NumberValue() has a fast path for things that are already numbers, so it won’t be a huge difference. In any case, not compared to the work of actually creating these numbers.

The overload of NumberValue() that doesn’t take a context argument is deprecated, by the way; you should use the one that does. (The reason being that NumberValue can actually execute arbitrary code via @@toPromitive if the input isn’t already a number, but in this case that won’t happen).

I personally would really prefer args[0].As<Number> since you’re already checking that args[0] is a Number instance.

if (size < 0 || size > Buffer::kMaxLength)
return env->ThrowRangeError("size is not a valid Smi");
if (size > Buffer::kMaxLength)
return env->ThrowTypeError("size must be a uint32");
Copy link
Contributor

Choose a reason for hiding this comment

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

I'm +1 on this change, but wouldn't feel comfortable with it not being semver-major since it changes an error message

Copy link
Member

Choose a reason for hiding this comment

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

Wait, why is the RangeError changed to a TypeError?

Copy link
Member Author

Choose a reason for hiding this comment

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

Good question: A range error made no sense there - and the code path emitting it didn't happen in reasonable cases anyway. For example if you passed -1.1 you'd get the TypeError in the path above - so not changing this to a TypeError would break a lot more.

Copy link
Member

Choose a reason for hiding this comment

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

Hmm, I am not sure I totally buy the argument of breaking less code here. Since we are changing the error messages here, why not make everything Semantically Correct(r)?

  • -1.1: RangeError: size must be a uint32
  • 240: RangeError: size must be a uint32
  • 'hello': TypeError: size must be a number

Copy link
Member Author

@benjamingr benjamingr Sep 2, 2017

Choose a reason for hiding this comment

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

I'm not saying that a TypeError is more correct here, I'll try to explain what I mean by breakage:

Before both -1.1 and 240 were TypeErrors since ->IsUint32 returns false and this change would make them both RangeErrors.

A RangeError would only happen if the number was a Uint32 and it's smaller than Buffer::kMaxLength which would only happen if the number was bigger than 2147483647 which is never. Only on 32 bit architecture buffers are max sized at 1073741823 which means RangeErrors would only happen on 32 bit and only when the number passed was between 1073741823 and 2147483647 - which I guess is very rare.

I'm fine with breaking this in a semver-major, but I'd rather do that in a different PR titled "make invalid numbers throw RangeError in randomBytes so it can be specifically examined for that change.

Copy link
Member

Choose a reason for hiding this comment

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

That's fair 👍

This change adds the ability to pass a double into randomBytes.

PR-URL: nodejs#15130
Fixes: nodejs#15118
Reviewed-By: Sam Roberts <vieuxtech@gmail.com>
Copy link
Member

@jasnell jasnell left a comment

Choose a reason for hiding this comment

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

LGTM with green CI

@benjamingr
Copy link
Member Author

benjamingr commented Sep 1, 2017

CI: https://ci.nodejs.org/job/node-test-pull-request/9920/

macOS failures unrelated, tests pass on a macOS vm locally.

@benjamingr
Copy link
Member Author

Landed in 484bfa2 - thanks for all the reviews

@benjamingr benjamingr closed this Sep 4, 2017
benjamingr pushed a commit that referenced this pull request Sep 4, 2017
This change adds the ability to pass a double into randomBytes.

PR-URL: #15130
Fixes: #15118
Reviewed-By: Sam Roberts <vieuxtech@gmail.com>
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Evan Lucas <evanlucas@me.com>
Reviewed-By: Anna Henningsen <anna@addaleax.net>
Reviewed-By: Luigi Pinca <luigipinca@gmail.com>
Reviewed-By: Timothy Gu <timothygu99@gmail.com>
Reviewed-By: Tobias Nießen <tniessen@tnie.de>
Reviewed-By: Joyee Cheung <joyeec9h3@gmail.com>
Reviewed-By: Ruben Bridgewater <ruben@bridgewater.de>
addaleax pushed a commit to addaleax/ayo that referenced this pull request Sep 5, 2017
This change adds the ability to pass a double into randomBytes.

PR-URL: nodejs/node#15130
Fixes: nodejs/node#15118
Reviewed-By: Sam Roberts <vieuxtech@gmail.com>
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Evan Lucas <evanlucas@me.com>
Reviewed-By: Anna Henningsen <anna@addaleax.net>
Reviewed-By: Luigi Pinca <luigipinca@gmail.com>
Reviewed-By: Timothy Gu <timothygu99@gmail.com>
Reviewed-By: Tobias Nießen <tniessen@tnie.de>
Reviewed-By: Joyee Cheung <joyeec9h3@gmail.com>
Reviewed-By: Ruben Bridgewater <ruben@bridgewater.de>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
c++ Issues and PRs that require attention from people who are familiar with C++. crypto Issues and PRs related to the crypto subsystem. semver-major PRs that contain breaking changes and should be released in the next major version.
Projects
None yet
Development

Successfully merging this pull request may close these issues.