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

fix: ftruncate for negative and maximum values #35645

Closed
wants to merge 6 commits into from

Conversation

IgorHalfeld
Copy link

@IgorHalfeld IgorHalfeld commented Oct 14, 2020

fix: fs.ftruncate and fd.ftruncateSync both silently ignore negative offsets

Fixes #35632

Checklist
  • make -j4 test (UNIX), or vcbuild test (Windows) passes
  • tests and/or benchmarks are included
  • documentation is changed or added
  • commit message follows commit guidelines

@nodejs-github-bot nodejs-github-bot added errors Issues and PRs related to JavaScript errors originated in Node.js core. fs Issues and PRs related to the fs subsystem / file system. labels Oct 14, 2020
@cjihrig cjihrig added the semver-major PRs that contain breaking changes and should be released in the next major version. label Oct 14, 2020
lib/fs.js Outdated
len = MathMax(0, len);

if (len < 0) {
throw new ERR_FS_FILE_TOO_SMALL(len);
Copy link
Member

Choose a reason for hiding this comment

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

I would use ERR_INVALID_ARG_VALUE here – it’s not the file that has a negative length, it is an invalid argument to the function here.

Likewise, using kIoMaxLength/ERR_FS_FILE_TOO_LARGE seems a bit odd here. The 2 GB limit is because that is the maximum buffer size supported, but Node.js generally does support way larger files than that (just not reading or writing to them in multi-GB chunks). We should not fail just because len exceeds this smaller limit, and only fail if it exceeds the actual limit after which the operation would fail or do the wrong thing.

Copy link
Author

@IgorHalfeld IgorHalfeld Oct 14, 2020

Choose a reason for hiding this comment

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

Makes sense!

So, that should solve

  if (len < 0) {
    throw new ERR_INVALID_ARG_VALUE('len', len);
  }

I'll update the PR

@addaleax addaleax added the request-ci Add this label to start a Jenkins CI on a PR. label Oct 14, 2020
@github-actions github-actions bot removed the request-ci Add this label to start a Jenkins CI on a PR. label Oct 14, 2020
@nodejs-github-bot
Copy link
Collaborator

lib/fs.js Outdated Show resolved Hide resolved
lib/fs.js Outdated Show resolved Hide resolved
lib/fs.js Show resolved Hide resolved
@Trott Trott added the request-ci Add this label to start a Jenkins CI on a PR. label Oct 15, 2020
@github-actions github-actions bot removed the request-ci Add this label to start a Jenkins CI on a PR. label Oct 15, 2020
@nodejs-github-bot
Copy link
Collaborator

@aduh95 aduh95 added the request-ci Add this label to start a Jenkins CI on a PR. label Nov 11, 2020
@github-actions github-actions bot removed the request-ci Add this label to start a Jenkins CI on a PR. label Nov 11, 2020
@nodejs-github-bot
Copy link
Collaborator

@aduh95
Copy link
Contributor

aduh95 commented Nov 12, 2020

@IgorHalfeld can you drop the merge commit and rebase please? Merge commits break our tooling.

@gireeshpunathil
Copy link
Member

@IgorHalfeld - this needs a rebase

@IgorHalfeld
Copy link
Author

Done 🎉

@aduh95
Copy link
Contributor

aduh95 commented Dec 11, 2020

@IgorHalfeld can you rebase rather than using merge commits please?

git fetch upstream master
git rebase upstream/master -i

Then you select the commits you want to keep (all of them except the merge commits), fix git conflicts, and force push to your fix-ftruncate branch.

The reason this is needed is because the CI downloads the patch from GitHub and tries to apply it on top of the master branch. This fails when trying to apply d9e745c.

@IgorHalfeld
Copy link
Author

any updates?

Comment on lines +227 to +234
assert.throws(
() => fs.ftruncate(fd, -1),
{
code: 'ERR_INVALID_ARG_VALUE',
name: /(TypeError|RangeError)/,
message: 'The argument \'len\' is invalid. Received -1'
}
);
Copy link
Contributor

Choose a reason for hiding this comment

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

@IgorHalfeld The fd you have used here is already closed by the time this is run but the test passes because ERR_INVALID_ARG_VALUE is thrown earlier:

fs.closeSync(fd);

Instead of replacing the previous test completely, consider replacing only this part with your test (you may take a look at the other tests for help):

fs.ftruncate(fd, -1, common.mustSucceed(() => {
assert(fs.readFileSync(file6).equals(Buffer.from('')));
}));

Also, fs.ftruncate needs to be called with a callback: https://nodejs.org/api/fs.html#fs_fs_ftruncate_fd_len_callback

Similarly, consider adding a corresponding test for fs.ftruncateSync too: https://nodejs.org/api/fs.html#fs_fs_ftruncatesync_fd_len

@RaisinTen RaisinTen dismissed their stale review January 20, 2021 15:34

My suggestion was very architecture specific.

Comment on lines 846 to +851
validateInteger(len, 'len');
len = MathMax(0, len);

if (len < 0) {
throw new ERR_INVALID_ARG_VALUE('len', len);
}

Copy link
Contributor

Choose a reason for hiding this comment

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

Shouldn't we throw a ERR_OUT_OF_RANGE instead?

Suggested change
validateInteger(len, 'len');
len = MathMax(0, len);
if (len < 0) {
throw new ERR_INVALID_ARG_VALUE('len', len);
}
validateInteger(len, 'len', 0);

Comment on lines 861 to +866
validateInteger(len, 'len');
len = MathMax(0, len);

if (len < 0) {
throw new ERR_INVALID_ARG_VALUE('len', len);
}

Copy link
Contributor

Choose a reason for hiding this comment

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

Shouldn't we throw a ERR_OUT_OF_RANGE instead?

Suggested change
validateInteger(len, 'len');
len = MathMax(0, len);
if (len < 0) {
throw new ERR_INVALID_ARG_VALUE('len', len);
}
validateInteger(len, 'len', 0);

assert.throws(
() => fs.ftruncate(fd, -1),
{
code: 'ERR_INVALID_ARG_VALUE',
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
code: 'ERR_INVALID_ARG_VALUE',
code: 'ERR_OUT_OF_RANGE',

@RaisinTen
Copy link
Contributor

Thank you very much for the contribution.
An alt solution for the related issue has already landed in #37483 so, I'm closing this PR.
Feel free to reopen if you still feel like continuing your work on this.

@RaisinTen RaisinTen closed this Feb 26, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
errors Issues and PRs related to JavaScript errors originated in Node.js core. fs Issues and PRs related to the fs subsystem / file system. 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.

fs.ftruncate silently accepts negative offsets rather than failing with ERR_INVALID
9 participants