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

Adopt IETF's test suite, fix spec and browser compliance errors #30

Merged
merged 23 commits into from
Apr 17, 2015
Merged

Adopt IETF's test suite, fix spec and browser compliance errors #30

merged 23 commits into from
Apr 17, 2015

Conversation

inikulin
Copy link
Contributor

Hello!

We've decided to adopt tough-cookie for the jsdom (jsdom/jsdom#1027). Therefore I've adopted IETF's test suite and fixed issues that arose.

1)Doubles quotes should be a part of the value (RFC6265 S4.1.1)
2)"Relaxed" mode should use \r \n\ and \0 as terminators according to Chromium source (https://chromium.googlesource.com/chromium/src.git/+/master/net/cookies/parsed_cookie.cc)
… correct way).

According to S5.2.4 we should fallback to the default-path only if the path attribute-value is empty or if the first character is not "/".
Meanwhile, then we are query cookies from the store we should use path-match algorithm from S5.1.4 instead of path permutation based algorithm.
… correct order for the cookies which are set synchronously. So we are using high-resolution time now where possible.
…values is '/' we should fallback to the default-path. Previously code doesn't considered the case then we have two path attributes. Now we always assign null explicitly if the path attribute is empty or '/' (Fixes PATH0030 IETF test)
… meanwhile previously used regexp doesn't allowed years that starts with zero (e.g. 07). Also, it allowed 3-digits year, which is incorrect
According to RFC6265:
 time            = hms-time ( non-digit *OCTET )
 hms-time        = time-field ":" time-field ":" time-field
 time-field      = 1*2DIGIT

Previous regexp doesn't allowed 1 digit minute/second time fields.
According to RFC6265  S5.1.1:
  month           = ( "jan" / "feb" / "mar" / "apr" /
                       "may" / "jun" / "jul" / "aug" /
                       "sep" / "oct" / "nov" / "dec" ) *OCTET

So, spec allows suffix for the month.
Use the exact grammar productions from the RFC for the time and day-of-month. Then perform correct validation (e.g. we should fail on "Sat, 15-Apr-17 91:22:33 21:01:22" because first met time token was incorrect. Previous approach just skipped first token, which is incorrect according to the RFC and doesn't matches browser's behavior (see: https://github.com/ChromiumWebApps/chromium/blob/b3d3b4da8bb94c1b2e061600df106d590fda3620/net/cookies/cookie_util.cc#L189)
@domenic
Copy link

domenic commented Mar 18, 2015

+1, would love to be able to have jsdom depend on something with a cute cookie-turtle logo.

@apsavin
Copy link
Contributor

apsavin commented Mar 23, 2015

Where is somebody who can merge it?)

@JSBizon
Copy link

JSBizon commented Mar 23, 2015

looks this important repository isn't supported anymore, maybe make sense create a fork? I did one for myself: https://github.com/JSBizon/tough-cookie

@inikulin
Copy link
Contributor Author

This is a plan B =)

@JSBizon
Copy link

JSBizon commented Mar 23, 2015

right, but owner of this repo is silent for a long time

@domenic
Copy link

domenic commented Mar 23, 2015

Someone should email https://www.npmjs.com/~goinstant and https://www.npmjs.com/~jstash to see if they'd be willing to transfer the npm package ownership at least

@stash
Copy link
Collaborator

stash commented Mar 30, 2015

Hey folks. I'm so, so sorry to have taken so long to respond. Long story short (I can explain if you want) is that I lost control of this repo for legal reasons, but now I can maintain it again!

I will look over the PR. Salesforce is currently requiring that contributors sign a CLA. If the PR looks good, I will need to get one from @inikulin and then I can publish to NPM.

@stash stash self-assigned this Mar 30, 2015
var STRICT_TIME = /^(0?[0-9]|1[0-9]|2[0-3]):([0-5][0-9]):([0-5][0-9])$/;
var DAY_OF_MONTH = /^(\d{1,2})[^\d]*$/;
var TIME = /^(\d{1,2})[^\d]*:(\d{1,2})[^\d]*:(\d{1,2})[^\d]*$/;
var MONTH = /^(Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)/i;
Copy link
Collaborator

Choose a reason for hiding this comment

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

Is the removal of the $ anchor here intentional?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

You mean in month regexp? If so, yes, according to RFC:

month = ( "jan" / "feb" / "mar" / "apr" /
"may" / "jun" / "jul" / "aug" /
"sep" / "oct" / "nov" / "dec" ) *OCTET

*OCTET - means that we can have any suffix. So, thing like January and even JanWhatever are acceptable. In Chromium source: https://github.com/ChromiumWebApps/chromium/blob/b3d3b4da8bb94c1b2e061600df106d590fda3620/net/cookies/cookie_util.cc#L125

});
};
//NOTE: we should use path-match algorithm from S5.1.4 here
//(see : https://github.com/ChromiumWebApps/chromium/blob/b3d3b4da8bb94c1b2e061600df106d590fda3620/net/cookies/canonical_cookie.cc#L299)
Copy link
Collaborator

Choose a reason for hiding this comment

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

Could you please explain here why we should use that path-match implementation?

Tactical: if this is a TODO, then maybe that goes as a comment on pathMatch? Or are you saying that matchRFC doesn't sync up with how Chromium does it?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

This is according to the S5.4.1:

The user agent MUST use an algorithm equivalent to the following
algorithm to compute the "cookie-string" from a cookie store and a
request-uri:
....

  • The request-uri's path path-matches the cookie's path.

BTW, seems like we can remove other matcher. I'll try it and will add another commit in case if it works.

Copy link
Collaborator

Choose a reason for hiding this comment

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

OK. A separate PR sounds good just to keep this big one reasonable.

@stash
Copy link
Collaborator

stash commented Mar 30, 2015

@inikulin I'm in the middle of looking at the changes and, overall, I'm impressed. I'm confident we can work through the minor issues. Most importantly: THANK YOU for all of the hard work! This is great!

// some may have been created at now + 1ms.
var i = cookies.length;
cookies.forEach(function (cookie) {
cookie.creation = new Date(now - 100 * (i--));
Copy link
Collaborator

Choose a reason for hiding this comment

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

If .hrCreation gets left in, then this doesn't do anything since .hrCreation takes precedence over .creation. The end result is coincidentally the same, making this forEach loop redundant.

Copy link
Collaborator

Choose a reason for hiding this comment

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

Not saying it should be left in; we should still discuss it (and probably have some unit tests that cover it).

Previous algorithm failed at the last day of the current month. This was caused by the fact that setUTCMonth method was used. According to MDN(https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/setUTCMonth) it accepts two parameters. If second parameter (dayValue) is not specified then V8 uses current day value. So if you are setting April as month, and current system date is March 31 then if will be resolved as May 1 which doesn't works for us. Therefore, we will parse tokens separately and then create new Date() object using Date.UTC()
@inikulin
Copy link
Contributor Author

Weird, BSD date tests starts to fail after March 30th (https://travis-ci.org/inikulin/tough-cookie/jobs/56567365). Need to take a look at it. (Upd: Fixed via inikulin/tough-cookie@553d20b)

@inikulin inikulin closed this Mar 31, 2015
@inikulin inikulin reopened this Mar 31, 2015
Previous algorithm failed at the last day of the current month. This was caused by the fact that setUTCMonth method was used. According to MDN(https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/setUTCMonth) it accepts two parameters. If second parameter (dayValue) is not specified then V8 uses current day value. So if you are setting April as month, and current system date is March 31 then if will be resolved as May 1 which doesn't works for us. Therefore, we will parse tokens separately and then create new Date() object using Date.UTC()
@inikulin
Copy link
Contributor Author

Ok, now we need to decide what to do with the hrCreation

Use runtime creation index instead of hrTime. Track cookie.creation modifications by
storing original UTC timestamp and comparing it with the actual cookie.creation.getTime().
If creation date was modified we fallback to the plane dates comparison.
@inikulin
Copy link
Contributor Author

Ok, I think some tests required for the latest commit to be sure that we are not breaking cookieCompare if cookie.creation was modified by the user. But, I need to go now, so I'll add them tomorrow.

@stash
Copy link
Collaborator

stash commented Apr 1, 2015

There's another issue open for the date thing. I have a fix waiting in the wings that I'll merge in after this one.

@stash
Copy link
Collaborator

stash commented Apr 1, 2015

re-reviewed; looking great still.

@domenic
Copy link

domenic commented Apr 15, 2015

Anything left before this can be merged?

stash added a commit that referenced this pull request Apr 17, 2015
Adopt IETF's test suite, fix spec and browser compliance errors

Amazing thanks to @inikulin !
@stash stash merged commit 16625cb into salesforce:master Apr 17, 2015
@stash
Copy link
Collaborator

stash commented Apr 17, 2015

I will cut a release for this tomorrow. I'm still sorting out NPM ownership so please bear with me.

@stash
Copy link
Collaborator

stash commented Apr 20, 2015

Still working on this, stay tuned.

@stash
Copy link
Collaborator

stash commented Apr 22, 2015

Published as v0.13.0

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants