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(http/cookies): allow spaces to be present in the cookie value #14455

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

anton7c3
Copy link

@anton7c3 anton7c3 commented Apr 8, 2024

Fixes #14435.

Move parse_set_cookie example to the correct location.

src/http/cookie.cr Outdated Show resolved Hide resolved
@bararchy
Copy link
Contributor

bararchy commented Apr 8, 2024

Looks good to me and fixes the current issue I'm seeing (#14435)

it "with space" do
cookie = parse_set_cookie("key=value; path=/test")
parse_set_cookie("key=value;path=/test").should eq cookie
parse_set_cookie("key=value; \t\npath=/test").should eq cookie
Copy link
Contributor

@hovsater hovsater Apr 8, 2024

Choose a reason for hiding this comment

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

If I'm not mistaken, there's a test case missing here. A value with leading and trailing whitespace. From RFC 6265:

  1. Remove any leading or trailing WSP characters from the name
    string and the value string.
parse_set_cookie("key= \tvalue \t;  \t\npath=/test").should eq cookie

Note that the test case is not currently passing.

Copy link
Author

Choose a reason for hiding this comment

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

The solution I can propose is to add \s* around CookieName and CookieValue regexes in the CookiePair regex and then strip the name and the value before passing it to the Cookie constructor.

The changes are uploaded with your example added to the spec.

Copy link
Author

Choose a reason for hiding this comment

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

Changed logic a little based on @straight-shoota's comment. Now only unquoted values are stripped.

@anton7c3 anton7c3 force-pushed the master branch 3 times, most recently from c748b0d to 912f1c1 Compare April 15, 2024 14:53
@anton7c3 anton7c3 requested a review from hovsater April 15, 2024 14:54
# Unwrap quoted cookie value
value = value.byte_slice(1, value.bytesize - 2)
end
yield Cookie.new(pair["name"], value)
yield Cookie.new(pair["name"].strip, value.strip)
Copy link
Contributor

@Sija Sija Apr 15, 2024

Choose a reason for hiding this comment

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

Stripping leading and trailing spaces should be done only for unquoted names/values.

ditto below

Copy link
Author

Choose a reason for hiding this comment

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

The RFC 6265 mentioned above doesn't mention quotes, It states that the name and the value should be stripped, that's it.

I don't mind any solution, but let's come to a single decision.

Copy link
Contributor

Choose a reason for hiding this comment

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

I wonder how other languages/frameworks do it.

Copy link
Member

Choose a reason for hiding this comment

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

IIUC, leading or trailing whitespace can only exist when the value is quoted. On unquoted values, as well as name (which is never quoted) all extra whitespace should be matched by \s* and thus is not part of the capture group.

So I don't think stripping makes any sense here.
If the value is quote, it's probably intended to have leading or trailing whitespace (for whatever reason 🤷).

Copy link
Member

Choose a reason for hiding this comment

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

Reverting the change in this line doesn't break any specs. So if it was preserved, we'd need to add some test for it.
But I think it should be removed.

Copy link
Member

Choose a reason for hiding this comment

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

I suppose \s* can miss some whitespace on unquoted values because a blank also matches CookieOctet and the quantifiers are both greedy. So we might need to strip trailing whitespace off of an unquoted value, unless we can fix the quantifier greediness in regex.

Copy link
Author

Choose a reason for hiding this comment

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

I've changed the logic to strip only unquoted values.This way the following works:

  • key= value ; path=/test should be parsed as <HTTP::Cookie @name="key" @value="value">
  • key=" value "; path=/test should be parsed as <HTTP::Cookie @name="key" @value=" value ">

The specs for this case are also added.

Fixes crystal-lang#14435.

Move parse_set_cookie example to the correct location.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Allow space in cookie value for Set-Cookie header
6 participants