-
Notifications
You must be signed in to change notification settings - Fork 29.8k
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
lib: mask mode_t type of arguments with 0o777 #20636
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -2,6 +2,7 @@ | |
|
||
const { | ||
ERR_INVALID_ARG_TYPE, | ||
ERR_INVALID_ARG_VALUE, | ||
ERR_OUT_OF_RANGE | ||
} = require('internal/errors').codes; | ||
|
||
|
@@ -13,6 +14,40 @@ function isUint32(value) { | |
return value === (value >>> 0); | ||
} | ||
|
||
const octalReg = /^[0-7]+$/; | ||
const modeDesc = 'must be a 32-bit unsigned integer or an octal string'; | ||
// Validator for mode_t (the S_* constants). Valid numbers or octal strings | ||
// will be masked with 0o777 to be consistent with the behavior in POSIX APIs. | ||
function validateAndMaskMode(value, name, def) { | ||
if (isUint32(value)) { | ||
return value & 0o777; | ||
} | ||
|
||
if (typeof value === 'number') { | ||
if (!Number.isInteger(value)) { | ||
throw new ERR_OUT_OF_RANGE(name, 'an integer', value); | ||
} else { | ||
// 2 ** 32 === 4294967296 | ||
throw new ERR_OUT_OF_RANGE(name, '>= 0 && < 4294967296', value); | ||
} | ||
} | ||
|
||
if (typeof value === 'string') { | ||
if (!octalReg.test(value)) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why do we need this? If the number is not a parseable octal value, There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. By the way, https://github.com/tc39/proposal-number-fromstring (currently in Stage 1) is designed for this situation There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @joyeecheung what I meant is that the |
||
throw new ERR_INVALID_ARG_VALUE(name, value, modeDesc); | ||
} | ||
const parsed = parseInt(value, 8); | ||
return parsed & 0o777; | ||
} | ||
|
||
// TODO(BridgeAR): Only return `def` in case `value == null` | ||
if (def !== undefined) { | ||
return def; | ||
} | ||
|
||
throw new ERR_INVALID_ARG_VALUE(name, value, modeDesc); | ||
} | ||
|
||
function validateInt32(value, name) { | ||
if (!isInt32(value)) { | ||
let err; | ||
|
@@ -53,6 +88,7 @@ function validateUint32(value, name, positive) { | |
module.exports = { | ||
isInt32, | ||
isUint32, | ||
validateAndMaskMode, | ||
validateInt32, | ||
validateUint32 | ||
}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should we really be using an out of range error type when it's a value type issue?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@mscdex JavaScript only has one number type (at least for now) so it could be seen both ways. I went with
ERR_OUT_OF_RANGE
so this can still be semver-patch.