You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
cvm/src/parse/octal-mode.js

80 lines
2.2 KiB
JavaScript

"use strict";
function parseModeDigit(modeDigit) {
let integer = parseInt(modeDigit);
return {
read: Boolean(integer & 4),
write: Boolean(integer & 2),
execute: Boolean(integer & 1)
};
}
function parseSpecialDigit(modeDigit) {
let integer = parseInt(modeDigit);
return {
setUID: Boolean(integer & 4),
setGID: Boolean(integer & 2),
sticky: Boolean(integer & 1)
};
}
function mapModeDigits(digits, hasSpecialBits) {
/* NOTE: The hasSpecialBits setting indicates whether the zeroeth digit was user-supplied (as opposed to being a default 0). This ensures that the index of the other bits is always stable, but we still don't return any special-bit information if the user didn't ask for it. This is important because the behaviour of an omitted special-bits digit may differ from environment to environment, so it should be left up to the calling code to deal with how to interpret that, and we cannot assume here that it's correct to interpret it as "none of the special bits are set". */
let normalModes = {
owner: parseModeDigit(digits[1]),
group: parseModeDigit(digits[2]),
everybody: parseModeDigit(digits[3]),
};
if (!hasSpecialBits) {
return normalModes;
} else {
return Object.assign(normalModes, parseSpecialDigit(digits[0]));
}
}
function applyMask(target, mask) {
return (target & (~mask));
}
module.exports = function parseModeString(modeString, { mask } = {}) {
let hasSpecialBits = (modeString.length === 4);
let modeDigits = intoDigits(modeString);
let maskDigits;
if (mask != null) {
maskDigits = intoDigits(mask);
} else {
maskDigits = [0, 0, 0, 0];
}
let maskedModeDigits = modeDigits.map((digit, i) => {
return applyMask(digit, maskDigits[i])
});
return mapModeDigits(maskedModeDigits, hasSpecialBits);
};
function intoDigits(modeString) {
let parsedDigits = modeString
.split("")
.map((digit) => {
let parsedDigit = parseInt(digit);
if (parsedDigit < 8) {
return parsedDigit;
} else {
throw new Error(`Mode string digit can only be 0-7, but encountered: ${digit}`);
}
});
if (parsedDigits.length === 3) {
return [0].concat(parsedDigits);
} else if (parsedDigits.length === 4) {
return parsedDigits;
} else {
throw new Error(`Unrecognized mode string length: ${modeString}`);
}
}