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

Parser incorrectly parses years in some cases #162

Closed
except opened this issue Aug 11, 2020 · 5 comments
Closed

Parser incorrectly parses years in some cases #162

except opened this issue Aug 11, 2020 · 5 comments

Comments

@except
Copy link

except commented Aug 11, 2020

Consider the following Set-Cookie header -
foo=bar; expires=Thu, 10-Sep-20 20:00:00 GMT;

This should be parsed as 2020-09-10 20:00 +0 however expires returns 0020-09-10 20:00 +0

@jhpratt
Copy link

jhpratt commented Aug 11, 2020

After a quick discussion, this behavior is correct as intended on time's end — the century will not be assumed.

Apparently this originates from Cloudflare, which isn't actually following the spec (emphasis mine)

HTTP/1.1 clients and servers that parse the date value MUST accept
all three formats (for compatibility with HTTP/1.0), though they MUST
only generate the RFC 1123 format for representing HTTP-date values
in header fields.

The first part of that doesn't actually specify what should happen when encountering a two-digit year, though I can't find anything along those lines in any RFC. As such, I think it's best to follow browsers' behavior. Apparently Chrome uses the following code (@except can you provide a source?)

// Normalize the year to expand abbreviated years to the full year.
if (exploded.year >= 69 && exploded.year <= 99)
  exploded.year += 1900;
if (exploded.year >= 0 && exploded.year <= 68)
  exploded.year += 2000;

This essentially assumes the year is between 1969 and 2068 inclusive.

Unfortunately, the only way to adjust the year is to fully reconstruct a PrimitiveDateTime from its components. Having a better API for operations along these lines is tracked in time-rs/time#256.

@except
Copy link
Author

except commented Aug 11, 2020

Source to where Chromium corrects two-digit based years.

@jhpratt
Copy link

jhpratt commented Aug 11, 2020

For the record: I have just submitted a request to Cloudflare. Regardless, this crate's behavior is also not spec compliant.

@except
Copy link
Author

except commented Aug 11, 2020

Firefox uses PR_ParseTimeString (PR_ParseTimeStringToExplodedTime) which does something similar when parsing.

year = n1;
if (year < 70) {
    year += 2000;
}
else if (year < 100) {
    year += 1900;
}

WebKit using parseExpiresMS (WTF::parseDateFromNullTerminatedCharacter) also parses slightly differently.

if (year) {
    int yearValue = year.value();
    if (yearValue >= 0 && yearValue < 100) {
        if (yearValue < 50)
            yearValue += 2000;
        else
            yearValue += 1900;
    }
    year = yearValue;
}

@SergioBenitez
Copy link
Member

Thank you for the input, all!

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

No branches or pull requests

3 participants