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

fs: (+/-)Infinity and NaN invalid unixtimestamp #11919

Conversation

lucamaraschi
Copy link
Contributor

Infinity and NaN are currently considered valid input when generating a
unix time stamp but are defaulted arbitrarly to Date.now()/1000. This
PR removes this behaviour and throw an exception like all the other
invalid input types.

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][]
Affected core subsystem(s)

fs

@nodejs-github-bot nodejs-github-bot added the fs Issues and PRs related to the fs subsystem / file system. label Mar 18, 2017
@mscdex mscdex added the semver-major PRs that contain breaking changes and should be released in the next major version. label Mar 18, 2017
doc/api/fs.md Outdated
- If the value is `NaN` or `Infinity`, the value will get converted to
`Date.now() / 1000`.
- If the value is `NaN` or `Infinity` (either positive or negative), an Error is
going to be thrown.
Copy link
Contributor

Choose a reason for hiding this comment

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

Minor nit: I think 'an Error will be thrown' sounds better

Copy link
Contributor

Choose a reason for hiding this comment

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

Agreed. Might be better to list NaN, Infinity, or -Infinity too.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Thanks, gonna change it

@ChALkeR
Copy link
Member

ChALkeR commented Mar 18, 2017

Not sure about this. /cc @jasnell, do we want to put this through a deprecation cycle?
Note that this changes both documented behavior and existing tests expectations.

@lucamaraschi to me it is not clear why this change should be done — that's not mentioned in this PR.

lib/fs.js Outdated
@@ -1164,8 +1164,8 @@ function toUnixTimestamp(time) {
if (typeof time === 'string' && +time == time) {
return +time;
}
if (typeof time === 'number') {
if (!Number.isFinite(time) || time < 0) {
if (typeof time === 'number' && !isNaN(time) && isFinite(time)) {
Copy link
Contributor

Choose a reason for hiding this comment

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

isFinite() covers NaN, so I think the !isNaN(time) can be dropped.

'use strict';
const fs = require('fs');
const assert = require('assert');
require('../common');
Copy link
Contributor

Choose a reason for hiding this comment

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

Can you move this up before the other require()s.

doc/api/fs.md Outdated
- If the value is `NaN` or `Infinity`, the value will get converted to
`Date.now() / 1000`.
- If the value is `NaN` or `Infinity` (either positive or negative), an Error is
going to be thrown.
Copy link
Contributor

Choose a reason for hiding this comment

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

Agreed. Might be better to list NaN, Infinity, or -Infinity too.

lib/fs.js Outdated
@@ -1164,8 +1164,8 @@ function toUnixTimestamp(time) {
if (typeof time === 'string' && +time == time) {
return +time;
}
if (typeof time === 'number') {
if (!Number.isFinite(time) || time < 0) {
if (typeof time === 'number' && !isNaN(time) && isFinite(time)) {
Copy link
Contributor

Choose a reason for hiding this comment

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

I think this can be simplified to just typeof time === 'number' && Number.isFinite(time)

Copy link
Contributor

Choose a reason for hiding this comment

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

I think Number.isFinite(time) would cover typeof time === 'number' anyway, so this is equivalent to just Number.isFinite(time).

});

const okInputs = [1, -1, '1', '-1', Date.now()];
okInputs.forEach((input) => assert.doesNotThrow(() =>
Copy link
Contributor

@mscdex mscdex Mar 18, 2017

Choose a reason for hiding this comment

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

I think using braces and better indentation for the forEach() callback will make this look better (especially since assert methods do not return meaningful values). Example:

okInputs.forEach((input) => {
  assert.doesNotThrow(() => fs._toUnixTimestamp(input));
});

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Agreed @mscdex, I was trying to keep it as compact as possible tho.

Copy link
Contributor

Choose a reason for hiding this comment

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

IMHO compactness isn't as important in tests.

@addaleax
Copy link
Member

I think this makes sense, silently converting these values to the current time is not something I’d expect as a user (at least not for ±∞).

do we want to put this through a deprecation cycle?

Hm, is there any reason not to?

@jasnell
Copy link
Member

jasnell commented Mar 19, 2017

I'm not convinced this behavior was intentional. It could be viewed as a bug fix and it is in a _-prefixed method. Unless we can find direct uses that would be problematic, I don't think a deprecation cycle should be necessary.

const fs = require('fs');
const assert = require('assert');

[Number.POSITIVE_INFINITY, Number.NEGATIVE_INFINITY, NaN].forEach((input) => {
Copy link
Member

Choose a reason for hiding this comment

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

nit: any reasons the shorter form -Infinity and Infinity are not used?

Copy link
Contributor

@cjihrig cjihrig left a comment

Choose a reason for hiding this comment

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

LGTM once @not-an-aardvark's nit is addressed.

Copy link
Member

@mcollina mcollina left a comment

Choose a reason for hiding this comment

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

LGTM. I don't think it was intentional in the first place.

@cjihrig
Copy link
Contributor

cjihrig commented Mar 20, 2017

@lucamaraschi this needs a rebase. Could you squash the commits while you're at it.

@lucamaraschi lucamaraschi force-pushed the fs-fix-unixtimestamp-ctor-validation branch from e5718ba to 3588f6a Compare March 20, 2017 22:10
Infinity and NaN are currently considered valid input when generating a
unix time stamp but are defaulted arbitrarly to Date.now()/1000. This
PR removes this behaviour and throw an exception like all the other
invalid input types.
@lucamaraschi lucamaraschi force-pushed the fs-fix-unixtimestamp-ctor-validation branch from 3588f6a to 1716ef5 Compare March 20, 2017 22:10
@cjihrig
Copy link
Contributor

cjihrig commented Mar 21, 2017

jasnell pushed a commit that referenced this pull request Mar 22, 2017
Infinity and NaN are currently considered valid input when generating a
unix time stamp but are defaulted arbitrarly to Date.now()/1000. This
PR removes this behaviour and throw an exception like all the other
invalid input types.

PR-URL: #11919
Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
Reviewed-By: James M Snell <jasnell@gmail.com>
@jasnell
Copy link
Member

jasnell commented Mar 22, 2017

Landed in eed87b1

@jasnell jasnell closed this Mar 22, 2017
@jasnell jasnell mentioned this pull request Apr 4, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
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.

10 participants