diff --git a/.github/workflows/push_gem.yml b/.github/workflows/push_gem.yml
new file mode 100644
index 0000000..a87f329
--- /dev/null
+++ b/.github/workflows/push_gem.yml
@@ -0,0 +1,62 @@
+name: Publish gem to rubygems.org
+
+on:
+ push:
+ tags:
+ - 'v*'
+
+permissions:
+ contents: read
+
+jobs:
+ push:
+ if: github.repository == 'ruby/cgi'
+ runs-on: ubuntu-latest
+
+ environment:
+ name: rubygems.org
+ url: https://rubygems.org/gems/cgi
+
+ permissions:
+ contents: write
+ id-token: write
+
+ strategy:
+ matrix:
+ ruby: ["3.3", "jruby"]
+
+ steps:
+ - name: Harden Runner
+ uses: step-security/harden-runner@4d991eb9b905ef189e4c376166672c3f2f230481 # v2.11.0
+ with:
+ egress-policy: audit
+
+ - uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4
+
+ - name: Set up Ruby
+ uses: ruby/setup-ruby@a6e6f86333f0a2523ece813039b8b4be04560854 # v1.190.0
+ with:
+ ruby-version: ${{ matrix.ruby }}
+
+ # https://github.com/rubygems/rubygems/issues/5882
+ - name: Install dependencies and build for JRuby
+ run: |
+ sudo apt install default-jdk maven
+ gem update --system
+ gem install ruby-maven rake-compiler --no-document
+ rake compile
+ if: matrix.ruby == 'jruby'
+
+ - name: Install dependencies
+ run: bundle install --jobs 4 --retry 3
+
+ - name: Publish to RubyGems
+ uses: rubygems/release-gem@a25424ba2ba8b387abc8ef40807c2c85b96cbe32 # v1.1.1
+
+ - name: Create GitHub release
+ run: |
+ tag_name="$(git describe --tags --abbrev=0)"
+ gh release create "${tag_name}" --verify-tag --generate-notes
+ env:
+ GITHUB_TOKEN: ${{ secrets.MATZBOT_GITHUB_WORKFLOW_TOKEN }}
+ if: matrix.ruby != 'jruby'
diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml
index 284daa2..df8824a 100644
--- a/.github/workflows/test.yml
+++ b/.github/workflows/test.yml
@@ -4,16 +4,9 @@ on: [push, pull_request]
jobs:
ruby-versions:
- runs-on: ubuntu-latest
- strategy:
- fail-fast: false
- outputs:
- versions: ${{ steps.versions.outputs.value }}
- steps:
- - id: versions
- run: |
- versions=$(curl -s 'https://cache.ruby-lang.org/pub/misc/ci_versions/cruby.json' | jq -c '. + ["2.5", "jruby"]')
- echo "::set-output name=value::${versions}"
+ uses: ruby/actions/.github/workflows/ruby_versions.yml@master
+ with:
+ min_version: 2.5
test:
needs: ruby-versions
name: build (${{ matrix.ruby }} / ${{ matrix.os }})
@@ -23,15 +16,20 @@ jobs:
ruby: ${{ fromJson(needs.ruby-versions.outputs.versions) }}
os: [ ubuntu-latest, macos-latest, windows-latest ]
exclude:
+ - { os: macos-latest, ruby: 2.5 }
- { os: windows-latest, ruby: head }
- { os: macos-latest, ruby: jruby }
- { os: windows-latest, ruby: jruby }
+ - { os: macos-latest, ruby: jruby-head }
+ - { os: windows-latest, ruby: jruby-head }
+ - { os: windows-latest, ruby: truffleruby }
+ - { os: windows-latest, ruby: truffleruby-head }
include:
- { os: windows-latest, ruby: mingw }
- { os: windows-latest, ruby: mswin }
runs-on: ${{ matrix.os }}
steps:
- - uses: actions/checkout@v3
+ - uses: actions/checkout@v4
- name: Set up Ruby
uses: ruby/setup-ruby@v1
with:
@@ -41,4 +39,4 @@ jobs:
- name: Build
run: rake compile
- name: Run test
- run: rake test
+ run: bundle exec rake test
diff --git a/lib/cgi.rb b/lib/cgi.rb
index 4cd6b3b..7dc3a64 100644
--- a/lib/cgi.rb
+++ b/lib/cgi.rb
@@ -288,7 +288,7 @@
#
class CGI
- VERSION = "0.3.6"
+ VERSION = "0.3.7"
end
require 'cgi/core'
diff --git a/lib/cgi/cookie.rb b/lib/cgi/cookie.rb
index 9498e2f..1c4ef6a 100644
--- a/lib/cgi/cookie.rb
+++ b/lib/cgi/cookie.rb
@@ -190,9 +190,10 @@ def self.parse(raw_cookie)
values ||= ""
values = values.split('&').collect{|v| CGI.unescape(v,@@accept_charset) }
if cookies.has_key?(name)
- values = cookies[name].value + values
+ cookies[name].concat(values)
+ else
+ cookies[name] = Cookie.new(name, *values)
end
- cookies[name] = Cookie.new(name, *values)
end
cookies
diff --git a/lib/cgi/util.rb b/lib/cgi/util.rb
index 5a5c77a..ce77a0c 100644
--- a/lib/cgi/util.rb
+++ b/lib/cgi/util.rb
@@ -178,7 +178,7 @@ def unescapeHTML(string)
def escapeElement(string, *elements)
elements = elements[0] if elements[0].kind_of?(Array)
unless elements.empty?
- string.gsub(/<\/?(?:#{elements.join("|")})(?!\w)(?:.|\n)*?>/i) do
+ string.gsub(/<\/?(?:#{elements.join("|")})\b[^<>]*+>?/im) do
CGI.escapeHTML($&)
end
else
@@ -198,7 +198,7 @@ def escapeElement(string, *elements)
def unescapeElement(string, *elements)
elements = elements[0] if elements[0].kind_of?(Array)
unless elements.empty?
- string.gsub(/<\/?(?:#{elements.join("|")})(?!\w)(?:.|\n)*?>/i) do
+ string.gsub(/<\/?(?:#{elements.join("|")})\b(?>[^&]+|&(?![gl]t;)\w+;)*(?:>)?/im) do
unescapeHTML($&)
end
else
diff --git a/test/cgi/test_cgi_util.rb b/test/cgi/test_cgi_util.rb
index a3be193..d058ccc 100644
--- a/test/cgi/test_cgi_util.rb
+++ b/test/cgi/test_cgi_util.rb
@@ -244,6 +244,14 @@ def test_cgi_escapeElement
assert_equal("
<A HREF="url"></A>", escapeElement('
', ["A", "IMG"]))
assert_equal("
<A HREF="url"></A>", escape_element('
', "A", "IMG"))
assert_equal("
<A HREF="url"></A>", escape_element('
', ["A", "IMG"]))
+
+ assert_equal("<A <A HREF="url"></A>", escapeElement('', "A", "IMG"))
+ assert_equal("<A <A HREF="url"></A>", escapeElement('', ["A", "IMG"]))
+ assert_equal("<A <A HREF="url"></A>", escape_element('', "A", "IMG"))
+ assert_equal("<A <A HREF="url"></A>", escape_element('', ["A", "IMG"]))
+
+ assert_equal("<A <A ", escapeElement('', unescapeElement(escapeHTML('
'), ["A", "IMG"]))
assert_equal('<BR>', unescape_element(escapeHTML('
'), "A", "IMG"))
assert_equal('<BR>', unescape_element(escapeHTML('
'), ["A", "IMG"]))
+
+ assert_equal('', unescapeElement(escapeHTML(''), "A", "IMG"))
+ assert_equal('', unescapeElement(escapeHTML(''), ["A", "IMG"]))
+ assert_equal('', unescape_element(escapeHTML(''), "A", "IMG"))
+ assert_equal('', unescape_element(escapeHTML(''), ["A", "IMG"]))
+
+ assert_equal('