-
Notifications
You must be signed in to change notification settings - Fork 29.9k
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
test: add test for loading read-only modules #20138
Conversation
Adds a test-case to cover loading modules the user does not have permission to write to. Covers issue logged in #20112
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.
LGTM if CI passes once the necessary libuv patch lands on master. (Will label this "blocked" until that happens.)
Let's start a CI anyway and check that it passes the linter, actually fails on Windows as expected (prior to the libuv fix) and is skipped everywhere else: https://ci.nodejs.org/job/node-test-pull-request/14368/ We'll obviously need to rerun the CI when the libuv fix lands and verify that the test then passes. |
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.
LGTM with some ignorable nits)
const tmpdir = require('../common/tmpdir'); | ||
tmpdir.refresh(); | ||
|
||
if (common.isWindows) { |
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.
Maybe it would be more optimal to add this check at the beginning, something like:
const common = require('../common');
// TODO: Similar checks on *nix-like systems (e.g using chmod or the like)
if (!common.isWindows)
common.skip('test only runs on Windows');
const assert = require('assert');
// ...
This way the test will not waste the time and resources loading all the other modules. common.skip()
makes the script exit, so no else
is required after it and we can save one indentation level as well.
// Create readOnlyMod.js and set to read only | ||
const readOnlyMod = path.join(tmpdir.path, 'readOnlyMod'); | ||
const readOnlyModRelative = path.relative(__dirname, readOnlyMod); | ||
const readOnlyModFullPath = readOnlyMod + '.js'; |
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.
We usually prefer template literals in such cases, so maybe:
const readOnlyModFullPath = `${readOnlyMod}.js`;
but feel free to ignore this and next stylistic notes)
fs.writeFileSync(readOnlyModFullPath, 'module.exports = 42;'); | ||
// Removed any inherited ACEs, and any explicitly granted ACEs for the | ||
// current user | ||
cp.execSync('icacls.exe "' + readOnlyModFullPath + |
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.
Maybe:
cp.execSync(
`icacls.exe "${readOnlyModFullPath}" /inheritance:r /remove "%USERNAME%"`);
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.
I did originally have template literals, but a) I wasn't sure they were supported all the way back to all LTS releases (I see now they are), and b) One long string was exceeded the lint line limit (but I could wrap it as shown above). I can add them back if desired.
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.
Personally, I find template literals in these cases more clear, they have less syntactic noise (operators, quotes), but this can be my personal taste, so you can decide freely) We did not set strict linting rule for this, but we had many PRs that have replaced concatenations with templates, so templates may be prevalent style in tests now.
'" /inheritance:r /remove "%USERNAME%"'); | ||
|
||
// Grant the current user read & execute only | ||
cp.execSync('icacls.exe "' + readOnlyModFullPath + |
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.
Maybe:
cp.execSync(`icacls.exe "${readOnlyModFullPath}" /grant "%USERNAME%":RX`);
} | ||
|
||
// Remove the expliclty granted rights, and reenable inheritance | ||
cp.execSync('icacls.exe "' + readOnlyModFullPath + |
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.
Maybe:
cp.execSync(
`icacls.exe "${readOnlyModFullPath}" /remove "%USERNAME%" /inheritance:e`);
CI seems to have come back exactly as expected. 🎉 (Everything is green except Windows because we haven't yet fixed the bug that this test is written for.) |
It seems only Windows job failed in previous CI, so we can wait till #20129 is landed and run this variant then. |
|
||
// Grant the current user read & execute only | ||
cp.execSync(`icacls.exe "${readOnlyModFullPath}" /grant "%USERNAME%":RX`); | ||
|
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.
Can't we simply end the test here with require(readOnlyModRelative);
? Is the cleanup required?
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.
Seeing as the test must explicitly remove any write access to the file, I figure clean up could potentially hit issues if I don't restore the default permissions afterwards (per line 42). Once that is done, removing the file isn't strictly necessary (line 46), but I see no harm in it (per the comment note above it).
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.
Yes, nothing wrong with the tear down, I just think it's not needed as tmpdir.refresh()
purges everything.
#20129 is landed. |
CI is green. Landing... |
Adds a test-case to cover loading modules the user does not have permission to write to. Covers issue logged in #20112 PR-URL: #20138 Refs: #20112 Reviewed-By: Rich Trott <rtrott@gmail.com> Reviewed-By: Richard Lau <riclau@uk.ibm.com> Reviewed-By: Vse Mozhet Byt <vsemozhetbyt@gmail.com> Reviewed-By: Bartosz Sosnowski <bartosz@janeasystems.com> Reviewed-By: Luigi Pinca <luigipinca@gmail.com> Reviewed-By: James M Snell <jasnell@gmail.com>
Adds a test-case to cover loading modules the user does not have permission to write to. Covers issue logged in #20112 PR-URL: #20138 Refs: #20112 Reviewed-By: Rich Trott <rtrott@gmail.com> Reviewed-By: Richard Lau <riclau@uk.ibm.com> Reviewed-By: Vse Mozhet Byt <vsemozhetbyt@gmail.com> Reviewed-By: Bartosz Sosnowski <bartosz@janeasystems.com> Reviewed-By: Luigi Pinca <luigipinca@gmail.com> Reviewed-By: James M Snell <jasnell@gmail.com>
Port test from nodejs/node#20138 to libuv. Refs: nodejs/node#20112 Refs: nodejs/node#20138
Adds a test-case to cover loading modules the user does not have permission
to write to.
Covers issue logged in #20112
Checklist
make -j4 test
(UNIX), orvcbuild test
(Windows) passesCC @Trott @cjihrig @richardlau