[ruby-core:118894] [Ruby master Bug#20686] URI::HTTPS can build URI with blank, invalid host

Issue #20686 has been reported by ronricardo (Roniece Ricardo). ---------------------------------------- Bug #20686: URI::HTTPS can build URI with blank, invalid host https://bugs.ruby-lang.org/issues/20686 * Author: ronricardo (Roniece Ricardo) * Status: Open * ruby -v: 3.4.0+ * Backport: 3.1: UNKNOWN, 3.2: UNKNOWN, 3.3: UNKNOWN ---------------------------------------- In Ruby 3.4.0+, calling `URI::HTTPS.build(host: "")` does not raise `URI::InvalidComponentError` as expected. Instead, it returns `#<URI::HTTPS https://>` I think this was introduced in [this PR](https://github.com/ruby/uri/pull/90). ## Steps to Reproduce ### 1. Environment: - **Ruby Version:** 3.4.0+ ### 2. Steps: - Open an IRB session. - Run: ```ruby URI::HTTPS.build(host: "") ``` ### 3. Expected Behavior: - `URI::InvalidComponentError` should be raised due to the invalid empty `host` component. ### 4. Actual Behavior: - Returns `#<URI::HTTPS https://>` without raising an error. ### Ruby 3.1.4: ```ruby irb(main):008:0> RUBY_VERSION => "3.1.4" irb(main):009:0> URI::HTTPS.build(host:"") /home/vscode/.rbenv/versions/3.1.4/lib/ruby/3.1.0/uri/generic.rb:601:in `check_host': bad component(expected host component): (URI::InvalidComponentError) ``` ### Ruby 3.4.0: ```ruby irb(…):015> RUBY_VERSION => "3.4.0" irb(...):016> URI::HTTPS.build(host:"") => #<URI::HTTPS https://> ``` -- https://bugs.ruby-lang.org/

Issue #20686 has been updated by jeremyevans0 (Jeremy Evans). ronricardo (Roniece Ricardo) wrote:
In Ruby 3.4.0+, calling `URI::HTTPS.build(host: "")` does not raise `URI::InvalidComponentError` as expected. Instead, it returns `#<URI::HTTPS https://>`
I think this was introduced in [this PR](https://github.com/ruby/uri/pull/90).
That PR only affects `#to_s`, not `.build`, and is unrelated. This was caused by the RFC 2396 -> RFC 3986 parser change: ```ruby URI::HTTPS.new(nil, nil, "", nil, nil, nil, nil, nil, nil, URI::RFC3986_PARSER, true) # => #<URI::HTTPS //> URI::HTTPS.new(nil, nil, "", nil, nil, nil, nil, nil, nil, URI::RFC2396_PARSER, true) # /home/jeremy/tmp/uri/lib/uri/generic.rb:601:in `check_host': bad component(expected host component): (URI::InvalidComponentError) ``` It appears RFC 3986 allows empty hosts (https://datatracker.ietf.org/doc/html/rfc3986#section-3.2.2: `reg-name = *( unreserved / pct-encoded / sub-delims )`), so I think this is not a bug, but an expected behavior change. ---------------------------------------- Bug #20686: URI::HTTPS can build URI with blank, invalid host https://bugs.ruby-lang.org/issues/20686#change-109464 * Author: ronricardo (Roniece Ricardo) * Status: Open * ruby -v: 3.4.0+ * Backport: 3.1: UNKNOWN, 3.2: UNKNOWN, 3.3: UNKNOWN ---------------------------------------- In Ruby 3.4.0+, calling `URI::HTTPS.build(host: "")` does not raise `URI::InvalidComponentError` as expected. Instead, it returns `#<URI::HTTPS https://>` I think this was introduced in [this PR](https://github.com/ruby/uri/pull/90). ## Steps to Reproduce ### 1. Environment: - **Ruby Version:** 3.4.0+ ### 2. Steps: - Open an IRB session. - Run: ```ruby URI::HTTPS.build(host: "") ``` ### 3. Expected Behavior: - `URI::InvalidComponentError` should be raised due to the invalid empty `host` component. ### 4. Actual Behavior: - Returns `#<URI::HTTPS https://>` without raising an error. ### Ruby 3.1.4: ```ruby irb(main):008:0> RUBY_VERSION => "3.1.4" irb(main):009:0> URI::HTTPS.build(host:"") /home/vscode/.rbenv/versions/3.1.4/lib/ruby/3.1.0/uri/generic.rb:601:in `check_host': bad component(expected host component): (URI::InvalidComponentError) ``` ### Ruby 3.4.0: ```ruby irb(…):015> RUBY_VERSION => "3.4.0" irb(...):016> URI::HTTPS.build(host:"") => #<URI::HTTPS https://> ``` -- https://bugs.ruby-lang.org/

Issue #20686 has been updated by jhawthorn (John Hawthorn). jeremyevans0 (Jeremy Evans) wrote in #note-1:
It appears RFC 3986 allows empty hosts (https://datatracker.ietf.org/doc/html/rfc3986#section-3.2.2: `reg-name = *( unreserved / pct-encoded / sub-delims )`), so I think this is not a bug, but an expected behavior change.
It's allowed by the ABNF, but the next paragraph states that it isn't valid for HTTP/HTTPS URIs
If the URI scheme defines a default for host, then that default applies when the host subcomponent is undefined or when the registered name is empty (zero length). For example, the "file" URI scheme is defined so that no authority, an empty host, and "localhost" all mean the end-user's machine, **whereas the "http"** **scheme considers a missing authority or empty host invalid.**
---------------------------------------- Bug #20686: URI::HTTPS can build URI with blank, invalid host https://bugs.ruby-lang.org/issues/20686#change-109468 * Author: ronricardo (Roniece Ricardo) * Status: Open * ruby -v: 3.4.0+ * Backport: 3.1: UNKNOWN, 3.2: UNKNOWN, 3.3: UNKNOWN ---------------------------------------- In Ruby 3.4.0+, calling `URI::HTTPS.build(host: "")` does not raise `URI::InvalidComponentError` as expected. Instead, it returns `#<URI::HTTPS https://>` I think this was introduced in [this PR](https://github.com/ruby/uri/pull/90). ## Steps to Reproduce ### 1. Environment: - **Ruby Version:** 3.4.0+ ### 2. Steps: - Open an IRB session. - Run: ```ruby URI::HTTPS.build(host: "") ``` ### 3. Expected Behavior: - `URI::InvalidComponentError` should be raised due to the invalid empty `host` component. ### 4. Actual Behavior: - Returns `#<URI::HTTPS https://>` without raising an error. ### Ruby 3.1.4: ```ruby irb(main):008:0> RUBY_VERSION => "3.1.4" irb(main):009:0> URI::HTTPS.build(host:"") /home/vscode/.rbenv/versions/3.1.4/lib/ruby/3.1.0/uri/generic.rb:601:in `check_host': bad component(expected host component): (URI::InvalidComponentError) ``` ### Ruby 3.4.0: ```ruby irb(…):015> RUBY_VERSION => "3.4.0" irb(...):016> URI::HTTPS.build(host:"") => #<URI::HTTPS https://> ``` -- https://bugs.ruby-lang.org/

Issue #20686 has been updated by jhawthorn (John Hawthorn). Interestingly RFC2396_PARSER seems to allow nil for a host but not empty string, so the newer behaviour is at least more consistent. It does seem like we are missing some expected validation here though. ```
URI::HTTPS.new(nil, nil, "", nil, nil, nil, nil, nil, nil, URI::RFC2396_Parser.new, true) /Users/jhawthorn/.rubies/ruby-3.3.2/lib/ruby/3.3.0/uri/generic.rb:601:in `check_host': bad component(expected host component): (URI::InvalidComponentError) from /Users/jhawthorn/.rubies/ruby-3.3.2/lib/ruby/3.3.0/uri/generic.rb:640:in `host=' ...
URI::HTTPS.new(nil, nil, nil, nil, nil, nil, nil, nil, nil, URI::RFC2396_Parser.new, true) => #<URI::HTTPS >
----------------------------------------
Bug #20686: URI::HTTPS can build URI with blank, invalid host
https://bugs.ruby-lang.org/issues/20686#change-109469
* Author: ronricardo (Roniece Ricardo)
* Status: Open
* ruby -v: 3.4.0+
* Backport: 3.1: UNKNOWN, 3.2: UNKNOWN, 3.3: UNKNOWN
----------------------------------------
In Ruby 3.4.0+, calling `URI::HTTPS.build(host: "")` does not raise `URI::InvalidComponentError` as expected. Instead, it returns `#<URI::HTTPS https://>`
I think this was introduced in [this PR](https://github.com/ruby/uri/pull/90).
## Steps to Reproduce
### 1. Environment:
- **Ruby Version:** 3.4.0+
### 2. Steps:
- Open an IRB session.
- Run:
```ruby
URI::HTTPS.build(host: "")
### 3. Expected Behavior: - `URI::InvalidComponentError` should be raised due to the invalid empty `host` component. ### 4. Actual Behavior: - Returns `#<URI::HTTPS https://>` without raising an error. ### Ruby 3.1.4: ```ruby irb(main):008:0> RUBY_VERSION => "3.1.4" irb(main):009:0> URI::HTTPS.build(host:"") /home/vscode/.rbenv/versions/3.1.4/lib/ruby/3.1.0/uri/generic.rb:601:in `check_host': bad component(expected host component): (URI::InvalidComponentError) ``` ### Ruby 3.4.0: ```ruby irb(…):015> RUBY_VERSION => "3.4.0" irb(...):016> URI::HTTPS.build(host:"") => #<URI::HTTPS https://> ``` -- https://bugs.ruby-lang.org/

Issue #20686 has been updated by jeremyevans0 (Jeremy Evans). jhawthorn (John Hawthorn) wrote in #note-2:
jeremyevans0 (Jeremy Evans) wrote in #note-1:
It appears RFC 3986 allows empty hosts (https://datatracker.ietf.org/doc/html/rfc3986#section-3.2.2: `reg-name = *( unreserved / pct-encoded / sub-delims )`), so I think this is not a bug, but an expected behavior change.
It's allowed by the ABNF, but the next paragraph states that it isn't valid for HTTP/HTTPS URIs
If the URI scheme defines a default for host, then that default applies when the host subcomponent is undefined or when the registered name is empty (zero length). For example, the "file" URI scheme is defined so that no authority, an empty host, and "localhost" all mean the end-user's machine, **whereas the "http"** **scheme considers a missing authority or empty host invalid.**
Thank you for pointing that out. I obviously should have read a little further. I submitted a pull request to reject empty host for `URI::HTTP{,S}`: https://github.com/ruby/uri/pull/116 ---------------------------------------- Bug #20686: URI::HTTPS can build URI with blank, invalid host https://bugs.ruby-lang.org/issues/20686#change-109470 * Author: ronricardo (Roniece Ricardo) * Status: Open * ruby -v: 3.4.0+ * Backport: 3.1: UNKNOWN, 3.2: UNKNOWN, 3.3: UNKNOWN ---------------------------------------- In Ruby 3.4.0+, calling `URI::HTTPS.build(host: "")` does not raise `URI::InvalidComponentError` as expected. Instead, it returns `#<URI::HTTPS https://>` I think this was introduced in [this PR](https://github.com/ruby/uri/pull/90). ## Steps to Reproduce ### 1. Environment: - **Ruby Version:** 3.4.0+ ### 2. Steps: - Open an IRB session. - Run: ```ruby URI::HTTPS.build(host: "") ``` ### 3. Expected Behavior: - `URI::InvalidComponentError` should be raised due to the invalid empty `host` component. ### 4. Actual Behavior: - Returns `#<URI::HTTPS https://>` without raising an error. ### Ruby 3.1.4: ```ruby irb(main):008:0> RUBY_VERSION => "3.1.4" irb(main):009:0> URI::HTTPS.build(host:"") /home/vscode/.rbenv/versions/3.1.4/lib/ruby/3.1.0/uri/generic.rb:601:in `check_host': bad component(expected host component): (URI::InvalidComponentError) ``` ### Ruby 3.4.0: ```ruby irb(…):015> RUBY_VERSION => "3.4.0" irb(...):016> URI::HTTPS.build(host:"") => #<URI::HTTPS https://> ``` -- https://bugs.ruby-lang.org/
participants (3)
-
jeremyevans0 (Jeremy Evans)
-
jhawthorn (John Hawthorn)
-
ronricardo (Roniece Ricardo)