Skip to content

Commit

Permalink
Merge branch 'main' into alexb/check_before_force_encoding
Browse files Browse the repository at this point in the history
  • Loading branch information
sporkmonger committed Jul 30, 2022
2 parents ca5a303 + 99810af commit 781ee9a
Show file tree
Hide file tree
Showing 18 changed files with 138 additions and 73 deletions.
6 changes: 6 additions & 0 deletions .github/dependabot.yml
@@ -0,0 +1,6 @@
version: 2
updates:
- package-ecosystem: "github-actions"
directory: "/"
schedule:
interval: "weekly"
42 changes: 42 additions & 0 deletions .github/workflows/codeql-analysis.yml
@@ -0,0 +1,42 @@
name: "CodeQL"

on:
push:
branches: [ "main" ]
pull_request:
# The branches below must be a subset of the branches above
branches: [ "main" ]
schedule:
- cron: '41 19 * * 2'

jobs:
analyze:
name: Analyze
runs-on: ubuntu-latest
permissions:
actions: read
contents: read
security-events: write

strategy:
fail-fast: false
matrix:
language: [ 'ruby' ]

steps:
- name: Checkout repository
uses: actions/checkout@v3

# Initializes the CodeQL tools for scanning.
- name: Initialize CodeQL
uses: github/codeql-action/init@v2
with:
languages: ${{ matrix.language }}

# Autobuild attempts to build any compiled languages (C/C++, C#, or Java).
# If this step fails, then you should remove it and run the build manually (see below)
- name: Autobuild
uses: github/codeql-action/autobuild@v2

- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v2
56 changes: 27 additions & 29 deletions .github/workflows/test.yml
Expand Up @@ -14,11 +14,11 @@ jobs:
matrix:
ruby: [2.7]
idna_mode: [native, pure]
os: [ubuntu-18.04]
os: [ubuntu-20.04]
env:
IDNA_MODE: ${{ matrix.idna_mode }}
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v3

- name: Install libidn
run: sudo apt-get install libidn11-dev
Expand Down Expand Up @@ -46,15 +46,15 @@ jobs:
fail-fast: false
matrix:
ruby: [2.7]
os: [ubuntu-18.04]
os: [ubuntu-20.04]
env:
BUNDLE_WITHOUT: development
COVERALLS_SERVICE_NAME: github
COVERALLS_REPO_TOKEN: ${{ secrets.GITHUB_TOKEN }}
COVERALLS_DEBUG: true
CI_BUILD_NUMBER: ${{ github.run_id }}
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v3

- name: Install libidn
run: sudo apt-get install libidn11-dev
Expand Down Expand Up @@ -86,45 +86,43 @@ jobs:
- 2.7
# quotes because of YAML gotcha: https://github.com/actions/runner/issues/849
- '3.0'
- 3.1
- head
- jruby-9.1
- jruby-9.2
- jruby-head
# truffleruby-21.2 fails due to https://github.com/oracle/truffleruby/issues/2408
- truffleruby-21.1
- truffleruby-head
- jruby-9.3
- truffleruby-21.3
- truffleruby-22.1
os:
- ubuntu-18.04
- ubuntu-20.04
gemfile:
- Gemfile
include:
- { os: ubuntu-18.04, ruby: 2.7, gemfile: gemfiles/public_suffix_2.rb }
- { os: ubuntu-18.04, ruby: 2.7, gemfile: gemfiles/public_suffix_3.rb }
# Ubuntu 20.04
- { os: ubuntu-20.04, ruby: 2.7 }
- { os: ubuntu-20.04, ruby: '3.0' }
- { os: ubuntu-20.04, ruby: 2.7, gemfile: gemfiles/public_suffix_2.rb }
- { os: ubuntu-20.04, ruby: 2.7, gemfile: gemfiles/public_suffix_3.rb }
- { os: ubuntu-20.04, ruby: 2.7, gemfile: gemfiles/public_suffix_4.rb }
# Ubuntu
- { os: ubuntu-18.04, ruby: 2.7 }
- { os: ubuntu-22.04, ruby: 3.1 }
# macOS
- { os: macos-10.15, ruby: 2.7 }
- { os: macos-10.15, ruby: '3.0' }
- { os: macos-10.15, ruby: jruby }
- { os: macos-10.15, ruby: truffleruby-21.1 }
- { os: macos-11, ruby: 2.7 }
- { os: macos-11, ruby: '3.0' }
- { os: macos-11, ruby: jruby }
- { os: macos-11, ruby: truffleruby-21.1 }
- { os: macos-11, ruby: 3.1 }
- { os: macos-12, ruby: 3.1 }
# Windows
- { os: windows-2019, ruby: 2.7 }
- { os: windows-2019, ruby: '3.0' }
- { os: windows-2019, ruby: jruby-9.1 }
- { os: windows-2019, ruby: jruby-9.2 }
- { os: windows-2019, ruby: 3.1 }
- { os: windows-2022, ruby: 3.1 }
- { os: windows-2022, ruby: jruby-9.3 }
# allowed to fail
- { os: ubuntu-18.04, ruby: jruby-head, allow-failure: true }
- { os: ubuntu-18.04, ruby: truffleruby-head, allow-failure: true }
- { os: ubuntu-20.04, ruby: jruby-head, gemfile: Gemfile, allow-failure: true }
- { os: ubuntu-20.04, ruby: truffleruby-head, gemfile: Gemfile, allow-failure: true }
env:
BUNDLE_GEMFILE: ${{ matrix.gemfile }}
BUNDLE_WITHOUT: development:coverage
# Workaround for Windows JRuby JDK issue
# https://github.com/ruby/setup-ruby/issues/339
# https://github.com/jruby/jruby/issues/7182#issuecomment-1112953015
JAVA_OPTS: -Djdk.io.File.enableADS=true
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v3

- name: Install libidn (Ubuntu)
if: startsWith(matrix.os, 'ubuntu')
Expand Down
4 changes: 3 additions & 1 deletion Gemfile
Expand Up @@ -25,4 +25,6 @@ group :test, :development do
gem "rake", ">= 12.3.3"
end

gem "idn-ruby", platform: :mri
unless ENV["IDNA_MODE"] == "pure"
gem "idn-ruby", platform: :mri
end
20 changes: 9 additions & 11 deletions addressable.gemspec
Expand Up @@ -6,32 +6,30 @@ Gem::Specification.new do |s|
s.version = "2.8.0"

s.required_rubygems_version = Gem::Requirement.new(">= 0".freeze) if s.respond_to? :required_rubygems_version=
s.metadata = { "changelog_uri" => "https://github.com/sporkmonger/addressable/blob/main/CHANGELOG.md" } if s.respond_to? :metadata=
s.require_paths = ["lib".freeze]
s.authors = ["Bob Aman".freeze]
s.date = "2021-07-03"
s.description = "Addressable is an alternative implementation to the URI implementation that is\npart of Ruby's standard library. It is flexible, offers heuristic parsing, and\nadditionally provides extensive support for IRIs and URI templates.\n".freeze
s.email = "bob@sporkmonger.com".freeze
s.extra_rdoc_files = ["README.md".freeze]
s.files = ["CHANGELOG.md".freeze, "Gemfile".freeze, "LICENSE.txt".freeze, "README.md".freeze, "Rakefile".freeze, "addressable.gemspec".freeze, "benchmark".freeze, "coverage".freeze, "data".freeze, "data/unicode.data".freeze, "documentation".freeze, "gemfiles".freeze, "lib".freeze, "lib/addressable".freeze, "lib/addressable.rb".freeze, "lib/addressable/idna".freeze, "lib/addressable/idna.rb".freeze, "lib/addressable/idna/native.rb".freeze, "lib/addressable/idna/pure.rb".freeze, "lib/addressable/template.rb".freeze, "lib/addressable/uri.rb".freeze, "lib/addressable/version.rb".freeze, "spec".freeze, "spec/addressable".freeze, "spec/addressable/idna_spec.rb".freeze, "spec/addressable/net_http_compat_spec.rb".freeze, "spec/addressable/security_spec.rb".freeze, "spec/addressable/template_spec.rb".freeze, "spec/addressable/uri_spec.rb".freeze, "spec/spec_helper.rb".freeze, "specdoc".freeze, "tasks".freeze, "tasks/clobber.rake".freeze, "tasks/gem.rake".freeze, "tasks/git.rake".freeze, "tasks/metrics.rake".freeze, "tasks/profile.rake".freeze, "tasks/rspec.rake".freeze, "tasks/yard.rake".freeze, "tmp".freeze]
s.files = ["CHANGELOG.md".freeze, "Gemfile".freeze, "LICENSE.txt".freeze, "README.md".freeze, "Rakefile".freeze, "data/unicode.data".freeze, "lib/addressable".freeze, "lib/addressable.rb".freeze, "lib/addressable/idna".freeze, "lib/addressable/idna.rb".freeze, "lib/addressable/idna/native.rb".freeze, "lib/addressable/idna/pure.rb".freeze, "lib/addressable/template.rb".freeze, "lib/addressable/uri.rb".freeze, "lib/addressable/version.rb".freeze, "spec/addressable".freeze, "spec/addressable/idna_spec.rb".freeze, "spec/addressable/net_http_compat_spec.rb".freeze, "spec/addressable/security_spec.rb".freeze, "spec/addressable/template_spec.rb".freeze, "spec/addressable/uri_spec.rb".freeze, "spec/spec_helper.rb".freeze, "tasks/clobber.rake".freeze, "tasks/gem.rake".freeze, "tasks/git.rake".freeze, "tasks/metrics.rake".freeze, "tasks/profile.rake".freeze, "tasks/rspec.rake".freeze, "tasks/yard.rake".freeze]
s.homepage = "https://github.com/sporkmonger/addressable".freeze
s.licenses = ["Apache-2.0".freeze]
s.rdoc_options = ["--main".freeze, "README.md".freeze]
s.required_ruby_version = Gem::Requirement.new(">= 2.0".freeze)
s.rubygems_version = "3.0.3".freeze
s.required_ruby_version = Gem::Requirement.new(">= 2.2".freeze)
s.rubygems_version = "3.3.7".freeze
s.summary = "URI Implementation".freeze

if s.respond_to? :specification_version then
s.specification_version = 4
end

if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
s.add_runtime_dependency(%q<public_suffix>.freeze, [">= 2.0.2", "< 5.0"])
s.add_development_dependency(%q<bundler>.freeze, [">= 1.0", "< 3.0"])
else
s.add_dependency(%q<public_suffix>.freeze, [">= 2.0.2", "< 5.0"])
s.add_dependency(%q<bundler>.freeze, [">= 1.0", "< 3.0"])
end
if s.respond_to? :add_runtime_dependency then
s.add_runtime_dependency(%q<public_suffix>.freeze, [">= 2.0.2", "< 6.0"])
s.add_development_dependency(%q<bundler>.freeze, [">= 1.0", "< 3.0"])
else
s.add_dependency(%q<public_suffix>.freeze, [">= 2.0.2", "< 5.0"])
s.add_dependency(%q<public_suffix>.freeze, [">= 2.0.2", "< 6.0"])
s.add_dependency(%q<bundler>.freeze, [">= 1.0", "< 3.0"])
end
end
6 changes: 6 additions & 0 deletions gemfiles/public_suffix_4.rb
@@ -0,0 +1,6 @@
# frozen_string_literal: true

# Assumes this gemfile is used from the project root
eval_gemfile "../Gemfile"

gem "public_suffix", "~> 4.0"
1 change: 0 additions & 1 deletion lib/addressable/idna.rb
@@ -1,6 +1,5 @@
# frozen_string_literal: true

# encoding:utf-8
#--
# Copyright (C) Bob Aman
#
Expand Down
1 change: 0 additions & 1 deletion lib/addressable/idna/native.rb
@@ -1,6 +1,5 @@
# frozen_string_literal: true

# encoding:utf-8
#--
# Copyright (C) Bob Aman
#
Expand Down
1 change: 0 additions & 1 deletion lib/addressable/idna/pure.rb
@@ -1,6 +1,5 @@
# frozen_string_literal: true

# encoding:utf-8
#--
# Copyright (C) Bob Aman
#
Expand Down
3 changes: 1 addition & 2 deletions lib/addressable/template.rb
@@ -1,6 +1,5 @@
# frozen_string_literal: true

# encoding:utf-8
#--
# Copyright (C) Bob Aman
#
Expand Down Expand Up @@ -1023,7 +1022,7 @@ def parse_new_template_pattern(pattern, processor = nil)
end

# Ensure that the regular expression matches the whole URI.
regexp_string = "^#{regexp_string}$"
regexp_string = "\\A#{regexp_string}\\z"
return expansions, Regexp.new(regexp_string)
end

Expand Down
37 changes: 18 additions & 19 deletions lib/addressable/uri.rb
@@ -1,6 +1,5 @@
# frozen_string_literal: true

# encoding:utf-8
#--
# Copyright (C) Bob Aman
#
Expand Down Expand Up @@ -38,20 +37,26 @@ class InvalidURIError < StandardError
##
# Container for the character classes specified in
# <a href="http://www.ietf.org/rfc/rfc3986.txt">RFC 3986</a>.
#
# Note: Concatenated and interpolated `String`s are not affected by the
# `frozen_string_literal` directive and must be frozen explicitly.
#
# Interpolated `String`s *were* frozen this way before Ruby 3.0:
# https://bugs.ruby-lang.org/issues/17104
module CharacterClasses
ALPHA = "a-zA-Z"
DIGIT = "0-9"
GEN_DELIMS = "\\:\\/\\?\\#\\[\\]\\@"
SUB_DELIMS = "\\!\\$\\&\\'\\(\\)\\*\\+\\,\\;\\="
RESERVED = GEN_DELIMS + SUB_DELIMS
UNRESERVED = ALPHA + DIGIT + "\\-\\.\\_\\~"
PCHAR = UNRESERVED + SUB_DELIMS + "\\:\\@"
SCHEME = ALPHA + DIGIT + "\\-\\+\\."
HOST = UNRESERVED + SUB_DELIMS + "\\[\\:\\]"
AUTHORITY = PCHAR + "\\[\\:\\]"
PATH = PCHAR + "\\/"
QUERY = PCHAR + "\\/\\?"
FRAGMENT = PCHAR + "\\/\\?"
RESERVED = (GEN_DELIMS + SUB_DELIMS).freeze
UNRESERVED = (ALPHA + DIGIT + "\\-\\.\\_\\~").freeze
PCHAR = (UNRESERVED + SUB_DELIMS + "\\:\\@").freeze
SCHEME = (ALPHA + DIGIT + "\\-\\+\\.").freeze
HOST = (UNRESERVED + SUB_DELIMS + "\\[\\:\\]").freeze
AUTHORITY = (PCHAR + "\\[\\:\\]").freeze
PATH = (PCHAR + "\\/").freeze
QUERY = (PCHAR + "\\/\\?").freeze
FRAGMENT = (PCHAR + "\\/\\?").freeze
end

module NormalizeCharacterClasses
Expand Down Expand Up @@ -469,19 +474,13 @@ def self.unencode(uri, return_type=String, leave_encoded='')
"Expected Class (String or Addressable::URI), " +
"got #{return_type.inspect}"
end
uri = uri.dup
# Seriously, only use UTF-8. I'm really not kidding!
uri.force_encoding("utf-8")

unless leave_encoded.empty?
leave_encoded = leave_encoded.dup.force_encoding("utf-8")
end

result = uri.gsub(/%[0-9a-f]{2}/iu) do |sequence|
result = uri.gsub(/%[0-9a-f]{2}/i) do |sequence|
c = sequence[1..3].to_i(16).chr
c.force_encoding("utf-8")
c.force_encoding(sequence.encoding)
leave_encoded.include?(c) ? sequence : c
end

result.force_encoding("utf-8")
if return_type == String
return result
Expand Down
1 change: 0 additions & 1 deletion lib/addressable/version.rb
@@ -1,6 +1,5 @@
# frozen_string_literal: true

# encoding:utf-8
#--
# Copyright (C) Bob Aman
#
Expand Down
1 change: 0 additions & 1 deletion spec/addressable/idna_spec.rb
@@ -1,6 +1,5 @@
# frozen_string_literal: true

# coding: utf-8
# Copyright (C) Bob Aman
#
# Licensed under the Apache License, Version 2.0 (the "License");
Expand Down
1 change: 0 additions & 1 deletion spec/addressable/net_http_compat_spec.rb
@@ -1,6 +1,5 @@
# frozen_string_literal: true

# coding: utf-8
# Copyright (C) Bob Aman
#
# Licensed under the Apache License, Version 2.0 (the "License");
Expand Down
1 change: 0 additions & 1 deletion spec/addressable/security_spec.rb
@@ -1,6 +1,5 @@
# frozen_string_literal: true

# coding: utf-8
# Copyright (C) Bob Aman
#
# Licensed under the Apache License, Version 2.0 (the "License");
Expand Down
10 changes: 9 additions & 1 deletion spec/addressable/template_spec.rb
@@ -1,6 +1,5 @@
# frozen_string_literal: true

# coding: utf-8
# Copyright (C) Bob Aman
#
# Licensed under the Apache License, Version 2.0 (the "License");
Expand Down Expand Up @@ -78,6 +77,15 @@
end
end

describe "#to_regexp" do
it "does not match the first line of multiline strings" do
uri = "https://www.example.com/bar"
template = Addressable::Template.new(uri)
expect(template.match(uri)).not_to be_nil
expect(template.match("#{uri}\ngarbage")).to be_nil
end
end

describe "Type conversion" do
subject {
{
Expand Down
16 changes: 15 additions & 1 deletion spec/addressable/uri_spec.rb
@@ -1,6 +1,5 @@
# frozen_string_literal: true

# coding: utf-8
# Copyright (C) Bob Aman
#
# Licensed under the Apache License, Version 2.0 (the "License");
Expand Down Expand Up @@ -6061,6 +6060,11 @@ def to_str
expect(Addressable::URI.unencode_component("ski=%BA%DAɫ")).to eq("ski=\xBA\xDAɫ")
end

it "should not fail with UTF-8 incompatible string" do
url = "/M%E9/\xE9?p=\xFC".b
expect(Addressable::URI.unencode_component(url)).to eq("/M\xE9/\xE9?p=\xFC")
end

it "should result in correct percent encoded sequence as a URI" do
expect(Addressable::URI.unencode(
"/path?g%C3%BCnther", ::Addressable::URI
Expand Down Expand Up @@ -6731,3 +6735,13 @@ def to_str
expect(@uri.class).to eq(@uri.join('path').class)
end
end

describe Addressable::URI, "when initialized in a non-main `Ractor`" do
it "should have the same value as if used in the main `Ractor`" do
pending("Ruby 3.0+ for `Ractor` support") unless defined?(Ractor)
main = Addressable::URI.parse("http://example.com")
expect(
Ractor.new { Addressable::URI.parse("http://example.com") }.take
).to eq(main)
end
end

0 comments on commit 781ee9a

Please sign in to comment.