|
|
f70500 |
From d6f00c288f84523eec263455ff5bfc631bc27188 Mon Sep 17 00:00:00 2001
|
|
|
f70500 |
From: usa <usa@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>
|
|
|
f70500 |
Date: Fri, 16 Feb 2018 16:27:56 +0000
|
|
|
f70500 |
Subject: [PATCH] merge revision(s) 58471,58493,62436: [Backport #13505]
|
|
|
f70500 |
|
|
|
f70500 |
load.c: backtrace of circular require
|
|
|
f70500 |
|
|
|
f70500 |
* load.c (load_lock): print backtrace of circular require via
|
|
|
f70500 |
`Warning.warn` [ruby-core:80850] [Bug #13505]
|
|
|
f70500 |
|
|
|
f70500 |
Send the backtrace of the circular require warning as a single String to Warning.warn
|
|
|
f70500 |
|
|
|
f70500 |
* load.c: send as a single string.
|
|
|
f70500 |
* error.c: expose the string formatted by rb_warning as rb_warning_string().
|
|
|
f70500 |
* test/ruby/test_exception.rb: update tests.
|
|
|
f70500 |
[ruby-core:80850] [Bug #13505]
|
|
|
f70500 |
|
|
|
f70500 |
fix regexp literal warning.
|
|
|
f70500 |
|
|
|
f70500 |
* test/rubygems/test_gem_server.rb: eliminate duplicated character class warning.
|
|
|
f70500 |
[Bug #14481]
|
|
|
f70500 |
|
|
|
f70500 |
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/branches/ruby_2_2@62441 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
|
|
|
f70500 |
---
|
|
|
f70500 |
lib/rubygems/package.rb | 6 +-
|
|
|
f70500 |
lib/rubygems/package/tar_header.rb | 23 ++-
|
|
|
f70500 |
lib/rubygems/package/tar_writer.rb | 2 +
|
|
|
f70500 |
lib/rubygems/server.rb | 14 +-
|
|
|
f70500 |
lib/rubygems/specification.rb | 15 +-
|
|
|
f70500 |
test/rubygems/test_gem_package.rb | 49 +++++-
|
|
|
f70500 |
test/rubygems/test_gem_package_tar_header.rb | 21 +++
|
|
|
f70500 |
test/rubygems/test_gem_server.rb | 165 +++++++++++++++++++
|
|
|
f70500 |
test/rubygems/test_gem_specification.rb | 17 +-
|
|
|
f70500 |
9 files changed, 295 insertions(+), 17 deletions(-)
|
|
|
f70500 |
|
|
|
f70500 |
diff --git a/lib/rubygems/package.rb b/lib/rubygems/package.rb
|
|
|
f70500 |
index c2bbda9b05..9ed5b2c9ed 100644
|
|
|
f70500 |
--- a/lib/rubygems/package.rb
|
|
|
f70500 |
+++ b/lib/rubygems/package.rb
|
|
|
f70500 |
@@ -374,7 +374,7 @@ EOM
|
|
|
f70500 |
destination = File.expand_path destination
|
|
|
f70500 |
|
|
|
f70500 |
raise Gem::Package::PathError.new(destination, destination_dir) unless
|
|
|
f70500 |
- destination.start_with? destination_dir
|
|
|
f70500 |
+ destination.start_with? destination_dir + '/'
|
|
|
f70500 |
|
|
|
f70500 |
destination.untaint
|
|
|
f70500 |
destination
|
|
|
f70500 |
@@ -541,6 +541,10 @@ EOM
|
|
|
f70500 |
raise Gem::Package::FormatError.new \
|
|
|
f70500 |
'package content (data.tar.gz) is missing', @gem
|
|
|
f70500 |
end
|
|
|
f70500 |
+
|
|
|
f70500 |
+ if duplicates = @files.group_by {|f| f }.select {|k,v| v.size > 1 }.map(&:first) and duplicates.any?
|
|
|
f70500 |
+ raise Gem::Security::Exception, "duplicate files in the package: (#{duplicates.map(&:inspect).join(', ')})"
|
|
|
f70500 |
+ end
|
|
|
f70500 |
end
|
|
|
f70500 |
|
|
|
f70500 |
##
|
|
|
f70500 |
diff --git a/lib/rubygems/package/tar_header.rb b/lib/rubygems/package/tar_header.rb
|
|
|
f70500 |
index 28da1db0b5..7d75ff5d46 100644
|
|
|
f70500 |
--- a/lib/rubygems/package/tar_header.rb
|
|
|
f70500 |
+++ b/lib/rubygems/package/tar_header.rb
|
|
|
f70500 |
@@ -103,25 +103,30 @@ class Gem::Package::TarHeader
|
|
|
f70500 |
fields = header.unpack UNPACK_FORMAT
|
|
|
f70500 |
|
|
|
f70500 |
new :name => fields.shift,
|
|
|
f70500 |
- :mode => fields.shift.oct,
|
|
|
f70500 |
- :uid => fields.shift.oct,
|
|
|
f70500 |
- :gid => fields.shift.oct,
|
|
|
f70500 |
- :size => fields.shift.oct,
|
|
|
f70500 |
- :mtime => fields.shift.oct,
|
|
|
f70500 |
- :checksum => fields.shift.oct,
|
|
|
f70500 |
+ :mode => strict_oct(fields.shift),
|
|
|
f70500 |
+ :uid => strict_oct(fields.shift),
|
|
|
f70500 |
+ :gid => strict_oct(fields.shift),
|
|
|
f70500 |
+ :size => strict_oct(fields.shift),
|
|
|
f70500 |
+ :mtime => strict_oct(fields.shift),
|
|
|
f70500 |
+ :checksum => strict_oct(fields.shift),
|
|
|
f70500 |
:typeflag => fields.shift,
|
|
|
f70500 |
:linkname => fields.shift,
|
|
|
f70500 |
:magic => fields.shift,
|
|
|
f70500 |
- :version => fields.shift.oct,
|
|
|
f70500 |
+ :version => strict_oct(fields.shift),
|
|
|
f70500 |
:uname => fields.shift,
|
|
|
f70500 |
:gname => fields.shift,
|
|
|
f70500 |
- :devmajor => fields.shift.oct,
|
|
|
f70500 |
- :devminor => fields.shift.oct,
|
|
|
f70500 |
+ :devmajor => strict_oct(fields.shift),
|
|
|
f70500 |
+ :devminor => strict_oct(fields.shift),
|
|
|
f70500 |
:prefix => fields.shift,
|
|
|
f70500 |
|
|
|
f70500 |
:empty => empty
|
|
|
f70500 |
end
|
|
|
f70500 |
|
|
|
f70500 |
+ def self.strict_oct(str)
|
|
|
f70500 |
+ return str.oct if str =~ /\A[0-7]*\z/
|
|
|
f70500 |
+ raise ArgumentError, "#{str.inspect} is not an octal string"
|
|
|
f70500 |
+ end
|
|
|
f70500 |
+
|
|
|
f70500 |
##
|
|
|
f70500 |
# Creates a new TarHeader using +vals+
|
|
|
f70500 |
|
|
|
f70500 |
diff --git a/lib/rubygems/package/tar_writer.rb b/lib/rubygems/package/tar_writer.rb
|
|
|
f70500 |
index f2c11e3544..0fbc1770fb 100644
|
|
|
f70500 |
--- a/lib/rubygems/package/tar_writer.rb
|
|
|
f70500 |
+++ b/lib/rubygems/package/tar_writer.rb
|
|
|
f70500 |
@@ -176,6 +176,8 @@ class Gem::Package::TarWriter
|
|
|
f70500 |
digest.name == signer.digest_name
|
|
|
f70500 |
end
|
|
|
f70500 |
|
|
|
f70500 |
+ raise "no #{signer.digest_name} in #{digests.values.compact}" unless signature_digest
|
|
|
f70500 |
+
|
|
|
f70500 |
signature = signer.sign signature_digest.digest
|
|
|
f70500 |
|
|
|
f70500 |
add_file_simple "#{name}.sig", 0444, signature.length do |io|
|
|
|
f70500 |
diff --git a/lib/rubygems/server.rb b/lib/rubygems/server.rb
|
|
|
f70500 |
index f2d1428489..af1448e79c 100644
|
|
|
f70500 |
--- a/lib/rubygems/server.rb
|
|
|
f70500 |
+++ b/lib/rubygems/server.rb
|
|
|
f70500 |
@@ -595,6 +595,18 @@ div.method-source-code pre { color: #ffdead; overflow: hidden; }
|
|
|
f70500 |
executables = nil if executables.empty?
|
|
|
f70500 |
executables.last["is_last"] = true if executables
|
|
|
f70500 |
|
|
|
f70500 |
+ # Pre-process spec homepage for safety reasons
|
|
|
f70500 |
+ begin
|
|
|
f70500 |
+ homepage_uri = URI.parse(spec.homepage)
|
|
|
f70500 |
+ if [URI::HTTP, URI::HTTPS].member? homepage_uri.class
|
|
|
f70500 |
+ homepage_uri = spec.homepage
|
|
|
f70500 |
+ else
|
|
|
f70500 |
+ homepage_uri = "."
|
|
|
f70500 |
+ end
|
|
|
f70500 |
+ rescue URI::InvalidURIError
|
|
|
f70500 |
+ homepage_uri = "."
|
|
|
f70500 |
+ end
|
|
|
f70500 |
+
|
|
|
f70500 |
specs << {
|
|
|
f70500 |
"authors" => spec.authors.sort.join(", "),
|
|
|
f70500 |
"date" => spec.date.to_s,
|
|
|
f70500 |
@@ -604,7 +616,7 @@ div.method-source-code pre { color: #ffdead; overflow: hidden; }
|
|
|
f70500 |
"only_one_executable" => (executables && executables.size == 1),
|
|
|
f70500 |
"full_name" => spec.full_name,
|
|
|
f70500 |
"has_deps" => !deps.empty?,
|
|
|
f70500 |
- "homepage" => spec.homepage,
|
|
|
f70500 |
+ "homepage" => homepage_uri,
|
|
|
f70500 |
"name" => spec.name,
|
|
|
f70500 |
"rdoc_installed" => Gem::RDoc.new(spec).rdoc_installed?,
|
|
|
f70500 |
"ri_installed" => Gem::RDoc.new(spec).ri_installed?,
|
|
|
f70500 |
diff --git a/lib/rubygems/specification.rb b/lib/rubygems/specification.rb
|
|
|
f70500 |
index c3e39b4759..d04c08b828 100644
|
|
|
f70500 |
--- a/lib/rubygems/specification.rb
|
|
|
f70500 |
+++ b/lib/rubygems/specification.rb
|
|
|
f70500 |
@@ -9,6 +9,7 @@ require 'rubygems/version'
|
|
|
f70500 |
require 'rubygems/requirement'
|
|
|
f70500 |
require 'rubygems/platform'
|
|
|
f70500 |
require 'rubygems/deprecate'
|
|
|
f70500 |
+require 'uri'
|
|
|
f70500 |
|
|
|
f70500 |
# :stopdoc:
|
|
|
f70500 |
# date.rb can't be loaded for `make install` due to miniruby
|
|
|
f70500 |
@@ -2503,10 +2504,16 @@ class Gem::Specification
|
|
|
f70500 |
raise Gem::InvalidSpecificationException, "#{lazy} is not a summary"
|
|
|
f70500 |
end
|
|
|
f70500 |
|
|
|
f70500 |
- if homepage and not homepage.empty? and
|
|
|
f70500 |
- homepage !~ /\A[a-z][a-z\d+.-]*:/i then
|
|
|
f70500 |
- raise Gem::InvalidSpecificationException,
|
|
|
f70500 |
- "\"#{homepage}\" is not a URI"
|
|
|
f70500 |
+ # Make sure a homepage is valid HTTP/HTTPS URI
|
|
|
f70500 |
+ if homepage and not homepage.empty?
|
|
|
f70500 |
+ begin
|
|
|
f70500 |
+ homepage_uri = URI.parse(homepage)
|
|
|
f70500 |
+ unless [URI::HTTP, URI::HTTPS].member? homepage_uri.class
|
|
|
f70500 |
+ raise Gem::InvalidSpecificationException, "\"#{homepage}\" is not a valid HTTP URI"
|
|
|
f70500 |
+ end
|
|
|
f70500 |
+ rescue URI::InvalidURIError
|
|
|
f70500 |
+ raise Gem::InvalidSpecificationException, "\"#{homepage}\" is not a valid HTTP URI"
|
|
|
f70500 |
+ end
|
|
|
f70500 |
end
|
|
|
f70500 |
|
|
|
f70500 |
# Warnings
|
|
|
f70500 |
diff --git a/test/rubygems/test_gem_package.rb b/test/rubygems/test_gem_package.rb
|
|
|
f70500 |
index c77fc47ada..29e2ce86b1 100644
|
|
|
f70500 |
--- a/test/rubygems/test_gem_package.rb
|
|
|
f70500 |
+++ b/test/rubygems/test_gem_package.rb
|
|
|
f70500 |
@@ -360,6 +360,21 @@ class TestGemPackage < Gem::Package::TarTestCase
|
|
|
f70500 |
"#{@destination} is not allowed", e.message)
|
|
|
f70500 |
end
|
|
|
f70500 |
|
|
|
f70500 |
+ def test_install_location_suffix
|
|
|
f70500 |
+ package = Gem::Package.new @gem
|
|
|
f70500 |
+
|
|
|
f70500 |
+ filename = "../#{File.basename(@destination)}suffix.rb"
|
|
|
f70500 |
+
|
|
|
f70500 |
+ e = assert_raises Gem::Package::PathError do
|
|
|
f70500 |
+ package.install_location filename, @destination
|
|
|
f70500 |
+ end
|
|
|
f70500 |
+
|
|
|
f70500 |
+ parent = File.expand_path File.join @destination, filename
|
|
|
f70500 |
+
|
|
|
f70500 |
+ assert_equal("installing into parent path #{parent} of " +
|
|
|
f70500 |
+ "#{@destination} is not allowed", e.message)
|
|
|
f70500 |
+ end
|
|
|
f70500 |
+
|
|
|
f70500 |
def test_load_spec
|
|
|
f70500 |
entry = StringIO.new Gem.gzip @spec.to_yaml
|
|
|
f70500 |
def entry.full_name() 'metadata.gz' end
|
|
|
f70500 |
@@ -514,6 +529,32 @@ class TestGemPackage < Gem::Package::TarTestCase
|
|
|
f70500 |
assert_match %r%nonexistent.gem$%, e.message
|
|
|
f70500 |
end
|
|
|
f70500 |
|
|
|
f70500 |
+ def test_verify_duplicate_file
|
|
|
f70500 |
+ FileUtils.mkdir_p 'lib'
|
|
|
f70500 |
+ FileUtils.touch 'lib/code.rb'
|
|
|
f70500 |
+
|
|
|
f70500 |
+ build = Gem::Package.new @gem
|
|
|
f70500 |
+ build.spec = @spec
|
|
|
f70500 |
+ build.setup_signer
|
|
|
f70500 |
+ open @gem, 'wb' do |gem_io|
|
|
|
f70500 |
+ Gem::Package::TarWriter.new gem_io do |gem|
|
|
|
f70500 |
+ build.add_metadata gem
|
|
|
f70500 |
+ build.add_contents gem
|
|
|
f70500 |
+
|
|
|
f70500 |
+ gem.add_file_simple 'a.sig', 0444, 0
|
|
|
f70500 |
+ gem.add_file_simple 'a.sig', 0444, 0
|
|
|
f70500 |
+ end
|
|
|
f70500 |
+ end
|
|
|
f70500 |
+
|
|
|
f70500 |
+ package = Gem::Package.new @gem
|
|
|
f70500 |
+
|
|
|
f70500 |
+ e = assert_raises Gem::Security::Exception do
|
|
|
f70500 |
+ package.verify
|
|
|
f70500 |
+ end
|
|
|
f70500 |
+
|
|
|
f70500 |
+ assert_equal 'duplicate files in the package: ("a.sig")', e.message
|
|
|
f70500 |
+ end
|
|
|
f70500 |
+
|
|
|
f70500 |
def test_verify_security_policy
|
|
|
f70500 |
package = Gem::Package.new @gem
|
|
|
f70500 |
package.security_policy = Gem::Security::HighSecurity
|
|
|
f70500 |
@@ -565,7 +606,13 @@ class TestGemPackage < Gem::Package::TarTestCase
|
|
|
f70500 |
|
|
|
f70500 |
# write bogus data.tar.gz to foil signature
|
|
|
f70500 |
bogus_data = Gem.gzip 'hello'
|
|
|
f70500 |
- gem.add_file_simple 'data.tar.gz', 0444, bogus_data.length do |io|
|
|
|
f70500 |
+ fake_signer = Class.new do
|
|
|
f70500 |
+ def digest_name; 'SHA512'; end
|
|
|
f70500 |
+ def digest_algorithm; Digest(:SHA512); end
|
|
|
f70500 |
+ def key; 'key'; end
|
|
|
f70500 |
+ def sign(*); 'fake_sig'; end
|
|
|
f70500 |
+ end
|
|
|
f70500 |
+ gem.add_file_signed 'data2.tar.gz', 0444, fake_signer.new do |io|
|
|
|
f70500 |
io.write bogus_data
|
|
|
f70500 |
end
|
|
|
f70500 |
|
|
|
f70500 |
diff --git a/test/rubygems/test_gem_package_tar_header.rb b/test/rubygems/test_gem_package_tar_header.rb
|
|
|
f70500 |
index 5d855435ec..ee30d4afd6 100644
|
|
|
f70500 |
--- a/test/rubygems/test_gem_package_tar_header.rb
|
|
|
f70500 |
+++ b/test/rubygems/test_gem_package_tar_header.rb
|
|
|
f70500 |
@@ -126,5 +126,26 @@ group\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000
|
|
|
f70500 |
assert_equal '012467', @tar_header.checksum
|
|
|
f70500 |
end
|
|
|
f70500 |
|
|
|
f70500 |
+ def test_from_bad_octal
|
|
|
f70500 |
+ test_cases = [
|
|
|
f70500 |
+ "00000006,44\000", # bogus character
|
|
|
f70500 |
+ "00000006789\000", # non-octal digit
|
|
|
f70500 |
+ "+0000001234\000", # positive sign
|
|
|
f70500 |
+ "-0000001000\000", # negative sign
|
|
|
f70500 |
+ "0x000123abc\000", # radix prefix
|
|
|
f70500 |
+ ]
|
|
|
f70500 |
+
|
|
|
f70500 |
+ test_cases.each do |val|
|
|
|
f70500 |
+ header_s = @tar_header.to_s
|
|
|
f70500 |
+ # overwrite the size field
|
|
|
f70500 |
+ header_s[124, 12] = val
|
|
|
f70500 |
+ io = TempIO.new header_s
|
|
|
f70500 |
+ assert_raises ArgumentError do
|
|
|
f70500 |
+ new_header = Gem::Package::TarHeader.from io
|
|
|
f70500 |
+ end
|
|
|
f70500 |
+ io.close! if io.respond_to? :close!
|
|
|
f70500 |
+ end
|
|
|
f70500 |
+ end
|
|
|
f70500 |
+
|
|
|
f70500 |
end
|
|
|
f70500 |
|
|
|
f70500 |
diff --git a/test/rubygems/test_gem_server.rb b/test/rubygems/test_gem_server.rb
|
|
|
f70500 |
index bf30399db2..5344ebbe69 100644
|
|
|
f70500 |
--- a/test/rubygems/test_gem_server.rb
|
|
|
f70500 |
+++ b/test/rubygems/test_gem_server.rb
|
|
|
f70500 |
@@ -268,6 +268,171 @@ class TestGemServer < Gem::TestCase
|
|
|
f70500 |
assert_match 'z 9', @res.body
|
|
|
f70500 |
end
|
|
|
f70500 |
|
|
|
f70500 |
+
|
|
|
f70500 |
+ def test_xss_homepage_fix_289313
|
|
|
f70500 |
+ data = StringIO.new "GET / HTTP/1.0\r\n\r\n"
|
|
|
f70500 |
+ dir = "#{@gemhome}2"
|
|
|
f70500 |
+
|
|
|
f70500 |
+ spec = util_spec 'xsshomepagegem', 1
|
|
|
f70500 |
+ spec.homepage = "javascript:confirm(document.domain)"
|
|
|
f70500 |
+
|
|
|
f70500 |
+ specs_dir = File.join dir, 'specifications'
|
|
|
f70500 |
+ FileUtils.mkdir_p specs_dir
|
|
|
f70500 |
+
|
|
|
f70500 |
+ open File.join(specs_dir, spec.spec_name), 'w' do |io|
|
|
|
f70500 |
+ io.write spec.to_ruby
|
|
|
f70500 |
+ end
|
|
|
f70500 |
+
|
|
|
f70500 |
+ server = Gem::Server.new dir, process_based_port, false
|
|
|
f70500 |
+
|
|
|
f70500 |
+ @req.parse data
|
|
|
f70500 |
+
|
|
|
f70500 |
+ server.root @req, @res
|
|
|
f70500 |
+
|
|
|
f70500 |
+ assert_equal 200, @res.status
|
|
|
f70500 |
+ assert_match 'xsshomepagegem 1', @res.body
|
|
|
f70500 |
+
|
|
|
f70500 |
+ # This verifies that the homepage for this spec is not displayed and is set to ".", because it's not a
|
|
|
f70500 |
+ # valid HTTP/HTTPS URL and could be unsafe in an HTML context. We would prefer to throw an exception here,
|
|
|
f70500 |
+ # but spec.homepage is currently free form and not currently required to be a URL, this behavior may be
|
|
|
f70500 |
+ # validated in future versions of Gem::Specification.
|
|
|
f70500 |
+ #
|
|
|
f70500 |
+ # There are two variant we're checking here, one where rdoc is not present, and one where rdoc is present in the same regex:
|
|
|
f70500 |
+ #
|
|
|
f70500 |
+ # Variant #1 - rdoc not installed
|
|
|
f70500 |
+ #
|
|
|
f70500 |
+ # xsshomepagegem 1
|
|
|
f70500 |
+ #
|
|
|
f70500 |
+ #
|
|
|
f70500 |
+ # [rdoc]
|
|
|
f70500 |
+ #
|
|
|
f70500 |
+ #
|
|
|
f70500 |
+ #
|
|
|
f70500 |
+ # [www]
|
|
|
f70500 |
+ #
|
|
|
f70500 |
+ # Variant #2 - rdoc installed
|
|
|
f70500 |
+ #
|
|
|
f70500 |
+ # xsshomepagegem 1
|
|
|
f70500 |
+ #
|
|
|
f70500 |
+ #
|
|
|
f70500 |
+ # \[rdoc\]<\/a>
|
|
|
f70500 |
+ #
|
|
|
f70500 |
+ #
|
|
|
f70500 |
+ #
|
|
|
f70500 |
+ # [www]
|
|
|
f70500 |
+ regex_match = /xsshomepagegem 1<\/b>[\s]+(\[rdoc\]<\/span>|\[rdoc\]<\/a>)[\s]+\[www\]<\/a>/
|
|
|
f70500 |
+ assert_match regex_match, @res.body
|
|
|
f70500 |
+ end
|
|
|
f70500 |
+
|
|
|
f70500 |
+ def test_invalid_homepage
|
|
|
f70500 |
+ data = StringIO.new "GET / HTTP/1.0\r\n\r\n"
|
|
|
f70500 |
+ dir = "#{@gemhome}2"
|
|
|
f70500 |
+
|
|
|
f70500 |
+ spec = util_spec 'invalidhomepagegem', 1
|
|
|
f70500 |
+ spec.homepage = "notavalidhomepageurl"
|
|
|
f70500 |
+
|
|
|
f70500 |
+ specs_dir = File.join dir, 'specifications'
|
|
|
f70500 |
+ FileUtils.mkdir_p specs_dir
|
|
|
f70500 |
+
|
|
|
f70500 |
+ open File.join(specs_dir, spec.spec_name), 'w' do |io|
|
|
|
f70500 |
+ io.write spec.to_ruby
|
|
|
f70500 |
+ end
|
|
|
f70500 |
+
|
|
|
f70500 |
+ server = Gem::Server.new dir, process_based_port, false
|
|
|
f70500 |
+
|
|
|
f70500 |
+ @req.parse data
|
|
|
f70500 |
+
|
|
|
f70500 |
+ server.root @req, @res
|
|
|
f70500 |
+
|
|
|
f70500 |
+ assert_equal 200, @res.status
|
|
|
f70500 |
+ assert_match 'invalidhomepagegem 1', @res.body
|
|
|
f70500 |
+
|
|
|
f70500 |
+ # This verifies that the homepage for this spec is not displayed and is set to ".", because it's not a
|
|
|
f70500 |
+ # valid HTTP/HTTPS URL and could be unsafe in an HTML context. We would prefer to throw an exception here,
|
|
|
f70500 |
+ # but spec.homepage is currently free form and not currently required to be a URL, this behavior may be
|
|
|
f70500 |
+ # validated in future versions of Gem::Specification.
|
|
|
f70500 |
+ #
|
|
|
f70500 |
+ # There are two variant we're checking here, one where rdoc is not present, and one where rdoc is present in the same regex:
|
|
|
f70500 |
+ #
|
|
|
f70500 |
+ # Variant #1 - rdoc not installed
|
|
|
f70500 |
+ #
|
|
|
f70500 |
+ # invalidhomepagegem 1
|
|
|
f70500 |
+ #
|
|
|
f70500 |
+ #
|
|
|
f70500 |
+ # [rdoc]
|
|
|
f70500 |
+ #
|
|
|
f70500 |
+ #
|
|
|
f70500 |
+ #
|
|
|
f70500 |
+ # [www]
|
|
|
f70500 |
+ #
|
|
|
f70500 |
+ # Variant #2 - rdoc installed
|
|
|
f70500 |
+ #
|
|
|
f70500 |
+ # invalidhomepagegem 1
|
|
|
f70500 |
+ #
|
|
|
f70500 |
+ #
|
|
|
f70500 |
+ # \[rdoc\]<\/a>
|
|
|
f70500 |
+ #
|
|
|
f70500 |
+ #
|
|
|
f70500 |
+ #
|
|
|
f70500 |
+ # [www]
|
|
|
f70500 |
+ regex_match = /invalidhomepagegem 1<\/b>[\s]+(\[rdoc\]<\/span>|\[rdoc\]<\/a>)[\s]+\[www\]<\/a>/
|
|
|
f70500 |
+ assert_match regex_match, @res.body
|
|
|
f70500 |
+ end
|
|
|
f70500 |
+
|
|
|
f70500 |
+ def test_valid_homepage_http
|
|
|
f70500 |
+ data = StringIO.new "GET / HTTP/1.0\r\n\r\n"
|
|
|
f70500 |
+ dir = "#{@gemhome}2"
|
|
|
f70500 |
+
|
|
|
f70500 |
+ spec = util_spec 'validhomepagegemhttp', 1
|
|
|
f70500 |
+ spec.homepage = "http://rubygems.org"
|
|
|
f70500 |
+
|
|
|
f70500 |
+ specs_dir = File.join dir, 'specifications'
|
|
|
f70500 |
+ FileUtils.mkdir_p specs_dir
|
|
|
f70500 |
+
|
|
|
f70500 |
+ open File.join(specs_dir, spec.spec_name), 'w' do |io|
|
|
|
f70500 |
+ io.write spec.to_ruby
|
|
|
f70500 |
+ end
|
|
|
f70500 |
+
|
|
|
f70500 |
+ server = Gem::Server.new dir, process_based_port, false
|
|
|
f70500 |
+
|
|
|
f70500 |
+ @req.parse data
|
|
|
f70500 |
+
|
|
|
f70500 |
+ server.root @req, @res
|
|
|
f70500 |
+
|
|
|
f70500 |
+ assert_equal 200, @res.status
|
|
|
f70500 |
+ assert_match 'validhomepagegemhttp 1', @res.body
|
|
|
f70500 |
+
|
|
|
f70500 |
+ regex_match = /validhomepagegemhttp 1<\/b>[\s]+(\[rdoc\]<\/span>|\[rdoc\]<\/a>)[\s]+\[www\]<\/a>/
|
|
|
f70500 |
+ assert_match regex_match, @res.body
|
|
|
f70500 |
+ end
|
|
|
f70500 |
+
|
|
|
f70500 |
+ def test_valid_homepage_https
|
|
|
f70500 |
+ data = StringIO.new "GET / HTTP/1.0\r\n\r\n"
|
|
|
f70500 |
+ dir = "#{@gemhome}2"
|
|
|
f70500 |
+
|
|
|
f70500 |
+ spec = util_spec 'validhomepagegemhttps', 1
|
|
|
f70500 |
+ spec.homepage = "https://rubygems.org"
|
|
|
f70500 |
+
|
|
|
f70500 |
+ specs_dir = File.join dir, 'specifications'
|
|
|
f70500 |
+ FileUtils.mkdir_p specs_dir
|
|
|
f70500 |
+
|
|
|
f70500 |
+ open File.join(specs_dir, spec.spec_name), 'w' do |io|
|
|
|
f70500 |
+ io.write spec.to_ruby
|
|
|
f70500 |
+ end
|
|
|
f70500 |
+
|
|
|
f70500 |
+ server = Gem::Server.new dir, process_based_port, false
|
|
|
f70500 |
+
|
|
|
f70500 |
+ @req.parse data
|
|
|
f70500 |
+
|
|
|
f70500 |
+ server.root @req, @res
|
|
|
f70500 |
+
|
|
|
f70500 |
+ assert_equal 200, @res.status
|
|
|
f70500 |
+ assert_match 'validhomepagegemhttps 1', @res.body
|
|
|
f70500 |
+
|
|
|
f70500 |
+ regex_match = /validhomepagegemhttps 1<\/b>[\s]+(\[rdoc\]<\/span>|\[rdoc\]<\/a>)[\s]+\[www\]<\/a>/
|
|
|
f70500 |
+ assert_match regex_match, @res.body
|
|
|
f70500 |
+ end
|
|
|
f70500 |
+
|
|
|
f70500 |
def test_specs
|
|
|
f70500 |
data = StringIO.new "GET /specs.#{Gem.marshal_version} HTTP/1.0\r\n\r\n"
|
|
|
f70500 |
@req.parse data
|
|
|
f70500 |
diff --git a/test/rubygems/test_gem_specification.rb b/test/rubygems/test_gem_specification.rb
|
|
|
f70500 |
index 85db5356f2..65984675e1 100644
|
|
|
f70500 |
--- a/test/rubygems/test_gem_specification.rb
|
|
|
f70500 |
+++ b/test/rubygems/test_gem_specification.rb
|
|
|
f70500 |
@@ -1586,7 +1586,22 @@ end
|
|
|
f70500 |
@a1.validate
|
|
|
f70500 |
end
|
|
|
f70500 |
|
|
|
f70500 |
- assert_equal '"over at my cool site" is not a URI', e.message
|
|
|
f70500 |
+ assert_equal '"over at my cool site" is not a valid HTTP URI', e.message
|
|
|
f70500 |
+
|
|
|
f70500 |
+ @a1.homepage = 'ftp://rubygems.org'
|
|
|
f70500 |
+
|
|
|
f70500 |
+ e = assert_raises Gem::InvalidSpecificationException do
|
|
|
f70500 |
+ @a1.validate
|
|
|
f70500 |
+ end
|
|
|
f70500 |
+
|
|
|
f70500 |
+ assert_equal '"ftp://rubygems.org" is not a valid HTTP URI', e.message
|
|
|
f70500 |
+
|
|
|
f70500 |
+ @a1.homepage = 'http://rubygems.org'
|
|
|
f70500 |
+ assert_equal true, @a1.validate
|
|
|
f70500 |
+
|
|
|
f70500 |
+ @a1.homepage = 'https://rubygems.org'
|
|
|
f70500 |
+ assert_equal true, @a1.validate
|
|
|
f70500 |
+
|
|
|
f70500 |
end
|
|
|
f70500 |
end
|
|
|
f70500 |
|
|
|
f70500 |
--
|
|
|
f70500 |
2.17.1
|
|
|
f70500 |
|