Directly run the following code snippet using node:
require('process').setuid(-0)
No. This potential bug can always be reproduced.
The argument to 'process.setuid' should be a Uint32 or string value, but we passed a -0 into it. The function should throw an exception or other similar error-reporting stuff rather than crash the whole nodejs process.
This is the stack dump produced during abort:
./node[37487]: ../src/node_credentials.cc:247:void node::credentials::SetUid(const FunctionCallbackInfo<v8::Value> &): Assertion `args[0]->IsUint32() || args[0]->IsString()' failed.
1: 0x13f9b30 node::Abort() [./node]
2: 0x13f9709 [./node]
3: 0x13ea56b [./node]
4: 0x17b379c v8::internal::FunctionCallbackArguments::Call(v8::internal::CallHandlerInfo) [./node]
5: 0x17b23d5 [./node]
6: 0x17b1092 [./node]
7: 0x2717a59 [./node]
[2] 37487 abort ./node
I can recreate this on master, v10.x prints a proper error message, so looks like a regression to me
definition of unsigned int seem to have diverged between JS and C++? looks like the check passed in the former, but failed later?
failed later -> failed * in * later
node --expose-internals -e 'require("internal/validators").validateInt32(-0)'
does not throw, implies this method (validateInt32) does not consider IsMinusZero which IsUint32 of v8 does.
validateInt32 hasn't changed between (passing and failing) versions:
https://github.com/nodejs/node/blob/b023d61716ddc9cd97cc148bb8d237ec8d894d2b/lib/internal/validators.js#L83
does this imply IsUint32 has changed its meaning in V8? that doesn't sound logical!
My team is trying to find bugs and vulnerabilities at the interface between js and c++, and we think this problem of inconsistency is an interesting study case for us. Can you give us a confirmation for this bug? As proof for us to make a discussion in our work.
@zyscoder - that is an interesting area to research, good luck! I tagged it as bug
/cc @nodejs/v8 in case if there is an obvious explanation.

¯_(ツ)_/¯
bisecting now.
bisect is pointing to the commit(s) in https://github.com/nodejs/node/pull/19973 /cc @targos
Interesting! That problem is not only present in process.setuid. The following also fails on Node.js 10:
> node -e "require('fs').chownSync('test', -0, -0)"
src\node_file.cc:2029: Assertion `args[1]->IsUint32()' failed.
V8 always returns false (and it's not new) for IsInt32 and IsUint32 methods.
I see two things that we can do:
Thoughts?
technically -0 is signed, so throwing from uint32 validator makes sense to me!
The counterargument is that 0 and -0 are indistinguishable (i.e., 0 === -0) except when checking with Object.is(). Coercion to positive 0 seems like the principle of least surprise to me.
Most helpful comment
The counterargument is that
0and-0are indistinguishable (i.e.,0 === -0) except when checking withObject.is(). Coercion to positive 0 seems like the principle of least surprise to me.