Skip to content

Commit

Permalink
try with option 2: wrap errors in URI
Browse files Browse the repository at this point in the history
  • Loading branch information
jarthod committed Apr 18, 2023
1 parent ccbcb9e commit 2fb0316
Show file tree
Hide file tree
Showing 4 changed files with 123 additions and 15 deletions.
7 changes: 1 addition & 6 deletions lib/addressable/idna.rb
Expand Up @@ -17,14 +17,9 @@
#++

module Addressable
# moved from uri.rb here so we can inherit it
class URI
class InvalidURIError < StandardError; end
end

module IDNA
# All IDNA conversion related errors
class Error < Addressable::URI::InvalidURIError; end
class Error < StandardError; end
# Input is invalid.
class PunycodeBadInput < Error; end
# Output would exceed the space provided.
Expand Down
9 changes: 9 additions & 0 deletions lib/addressable/uri.rb
Expand Up @@ -29,6 +29,11 @@ module Addressable
# <a href="http://www.ietf.org/rfc/rfc3986.txt">RFC 3986</a>,
# <a href="http://www.ietf.org/rfc/rfc3987.txt">RFC 3987</a>.
class URI
##
# Raised if something other than a uri is supplied.
class InvalidURIError < StandardError
end

##
# Container for the character classes specified in
# <a href="http://www.ietf.org/rfc/rfc3986.txt">RFC 3986</a>.
Expand Down Expand Up @@ -1135,6 +1140,8 @@ def normalized_host
# All normalized values should be UTF-8
force_utf8_encoding_if_needed(@normalized_host)
@normalized_host
rescue IDNA::Error => e
raise InvalidURIError.new(e)
end

##
Expand Down Expand Up @@ -2190,6 +2197,8 @@ def display_uri
display_uri = self.normalize
display_uri.host = ::Addressable::IDNA.to_unicode(display_uri.host)
return display_uri
rescue IDNA::Error => e
raise InvalidURIError.new(e)
end

##
Expand Down
10 changes: 1 addition & 9 deletions spec/addressable/idna_spec.rb
Expand Up @@ -271,14 +271,6 @@
expect(Addressable::IDNA.to_ascii("faß.de")).to eq("xn--fa-hia.de")
end

it "throws exceptions which inherits Addressable::URI::InvalidURIError" do
# this way IDNA exceptions are also caught by existing rescue on InvalidURIError
expect(Addressable::IDNA::Error).to be < Addressable::URI::InvalidURIError
expect(Addressable::IDNA::PunycodeBadInput).to be < Addressable::IDNA::Error
expect(Addressable::IDNA::PunycodeBigOutput).to be < Addressable::IDNA::Error
expect(Addressable::IDNA::PunycodeOverflow).to be < Addressable::IDNA::Error
end

begin
require "fiber"

Expand Down Expand Up @@ -344,7 +336,7 @@
}.to raise_error(Addressable::IDNA::Error, /longer than 63 char/)
expect {
Addressable::IDNA.to_ascii(long)
}.to raise_error(Addressable::URI::InvalidURIError, /longer than 63 char/)
}.to raise_error(Addressable::IDNA::Error, /longer than 63 char/)
end

it "should raise when punycode decode fails" do
Expand Down
112 changes: 112 additions & 0 deletions spec/addressable/uri_spec.rb
Expand Up @@ -5234,6 +5234,118 @@ def to_s
end
end

describe Addressable::URI, "when parsed from invalid IDNA hostname " +
"'http://xn---3a.com/'" do
before do
@uri = Addressable::URI.parse("http://xn---3a.com/")
end

begin
require "addressable/idna/libidn2"
context "with libidn2" do
before { Addressable::IDNA.backend = Addressable::IDNA::Libidn2 }

context "when strict_mode is true" do
before { Addressable::IDNA.strict_mode = true }
after { Addressable::IDNA.strict_mode = false }

it "display_uri should raise a wrapped InvalidURL error" do
expect { @uri.display_uri.to_s
}.to raise_error(Addressable::URI::InvalidURIError, /invalid punycode/) { |e|
expect(e.cause).to be_a(Addressable::IDNA::Error)
}
end

it "normalized_host should raise a wrapped InvalidURL error" do
expect { @uri.normalized_host
}.to raise_error(Addressable::URI::InvalidURIError, /invalid punycode/) { |e|
expect(e.cause).to be_a(Addressable::IDNA::Error)
}
end
end

it "display_uri should be kept as http://xn---3a.com/" do
expect(@uri.display_uri.to_s).to eq("http://xn---3a.com/")
end

it "normalized_host should be kept as http://xn---3a.com/" do
expect(@uri.normalized_host).to eq("xn---3a.com")
end
end
rescue LoadError => error
raise error if ENV["CI"] && TestHelper.native_supported?
warn('Could not load native libidn2 implementation.')
end

begin
require "addressable/idna/libidn1"
context "with libidn1" do
before { Addressable::IDNA.backend = Addressable::IDNA::Libidn1 }

context "when strict_mode is true" do
before { Addressable::IDNA.strict_mode = true }
after { Addressable::IDNA.strict_mode = false }

# libidn1 silently falls back in this case
it "display_uri should be kept as http://xn---3a.com/" do
expect(@uri.display_uri.to_s).to eq("http://xn---3a.com/")
end

it "normalized_host should be kept as http://xn---3a.com/" do
expect(@uri.normalized_host).to eq("xn---3a.com")
end
end

it "display_uri should be kept as http://xn---3a.com/" do
expect(@uri.display_uri.to_s).to eq("http://xn---3a.com/")
end

it "normalized_host should be kept as http://xn---3a.com/" do
expect(@uri.normalized_host).to eq("xn---3a.com")
end
end
rescue LoadError => error
raise error if ENV["CI"] && TestHelper.native_supported?
warn('Could not load native libidn2 implementation.')
end

require "addressable/idna/pure"
context "with pure-ruby IDNA implementation" do
before { Addressable::IDNA.backend = Addressable::IDNA::Pure }

context "when strict_mode is true" do
before { Addressable::IDNA.strict_mode = true }
after { Addressable::IDNA.strict_mode = false }

# libidn1 silently falls back in this case
it "display_uri should be kept as http://xn---3a.com/" do
pending "incorrect result"
expect { @uri.display_uri.to_s
}.to raise_error(Addressable::URI::InvalidURIError, /invalid punycode/) { |e|
expect(e.cause).to be_a(Addressable::IDNA::Error)
}
end

it "normalized_host should be kept as http://xn---3a.com/" do
pending "incorrect result"
expect { @uri.normalized_host
}.to raise_error(Addressable::URI::InvalidURIError, /invalid punycode/) { |e|
expect(e.cause).to be_a(Addressable::IDNA::Error)
}
end
end

it "display_uri should be kept as http://xn---3a.com/" do
pending "incorrect result"
expect(@uri.display_uri.to_s).to eq("http://xn---3a.com/")
end

it "normalized_host should be kept as http://xn---3a.com/" do
expect(@uri.normalized_host).to eq("xn---3a.com")
end
end
end

describe Addressable::URI, "when parsed from " +
"'http://www.詹姆斯.com/atomtests/iri/詹.html'" do
before do
Expand Down

0 comments on commit 2fb0316

Please sign in to comment.