Bug #15637 ยป ruby-2.4.5-rubygems-v2.patch
lib/rubygems.rb | ||
---|---|---|
10 | 10 |
require 'thread' |
11 | 11 | |
12 | 12 |
module Gem |
13 |
VERSION = "2.6.14.3"
|
|
13 |
VERSION = "2.6.14.4"
|
|
14 | 14 |
end |
15 | 15 | |
16 | 16 |
# Must be first since it unloads the prelude from 1.9.2 |
lib/rubygems/command_manager.rb | ||
---|---|---|
7 | 7 | |
8 | 8 |
require 'rubygems/command' |
9 | 9 |
require 'rubygems/user_interaction' |
10 |
require 'rubygems/text' |
|
10 | 11 | |
11 | 12 |
## |
12 | 13 |
# The command manager registers and installs all the individual sub-commands |
... | ... | |
32 | 33 | |
33 | 34 |
class Gem::CommandManager |
34 | 35 | |
36 |
include Gem::Text |
|
35 | 37 |
include Gem::UserInteraction |
36 | 38 | |
37 | 39 |
BUILTIN_COMMANDS = [ # :nodoc: |
... | ... | |
138 | 140 |
def run(args, build_args=nil) |
139 | 141 |
process_args(args, build_args) |
140 | 142 |
rescue StandardError, Timeout::Error => ex |
141 |
alert_error "While executing gem ... (#{ex.class})\n #{ex}"
|
|
143 |
alert_error clean_text("While executing gem ... (#{ex.class})\n #{ex}")
|
|
142 | 144 |
ui.backtrace ex |
143 | 145 | |
144 | 146 |
terminate_interaction(1) |
145 | 147 |
rescue Interrupt |
146 |
alert_error "Interrupted"
|
|
148 |
alert_error clean_text("Interrupted")
|
|
147 | 149 |
terminate_interaction(1) |
148 | 150 |
end |
149 | 151 | |
... | ... | |
161 | 163 |
say Gem::VERSION |
162 | 164 |
terminate_interaction 0 |
163 | 165 |
when /^-/ then |
164 |
alert_error "Invalid option: #{args.first}. See 'gem --help'."
|
|
166 |
alert_error clean_text("Invalid option: #{args.first}. See 'gem --help'.")
|
|
165 | 167 |
terminate_interaction 1 |
166 | 168 |
else |
167 | 169 |
cmd_name = args.shift.downcase |
... | ... | |
210 | 212 |
rescue Exception => e |
211 | 213 |
e = load_error if load_error |
212 | 214 | |
213 |
alert_error "Loading command: #{command_name} (#{e.class})\n\t#{e}"
|
|
215 |
alert_error clean_text("Loading command: #{command_name} (#{e.class})\n\t#{e}")
|
|
214 | 216 |
ui.backtrace e |
215 | 217 |
end |
216 | 218 |
end |
lib/rubygems/commands/owner_command.rb | ||
---|---|---|
2 | 2 |
require 'rubygems/command' |
3 | 3 |
require 'rubygems/local_remote_options' |
4 | 4 |
require 'rubygems/gemcutter_utilities' |
5 |
require 'rubygems/text' |
|
5 | 6 | |
6 | 7 |
class Gem::Commands::OwnerCommand < Gem::Command |
8 | ||
9 |
include Gem::Text |
|
7 | 10 |
include Gem::LocalRemoteOptions |
8 | 11 |
include Gem::GemcutterUtilities |
9 | 12 | |
... | ... | |
62 | 65 |
end |
63 | 66 | |
64 | 67 |
with_response response do |resp| |
65 |
owners = Gem::SafeYAML.load resp.body
|
|
68 |
owners = Gem::SafeYAML.load clean_text(resp.body)
|
|
66 | 69 | |
67 | 70 |
say "Owners for gem: #{name}" |
68 | 71 |
owners.each do |owner| |
lib/rubygems/gemcutter_utilities.rb | ||
---|---|---|
1 | 1 |
# frozen_string_literal: true |
2 | 2 |
require 'rubygems/remote_fetcher' |
3 |
require 'rubygems/text' |
|
3 | 4 | |
4 | 5 |
## |
5 | 6 |
# Utility methods for using the RubyGems API. |
6 | 7 | |
7 | 8 |
module Gem::GemcutterUtilities |
8 | 9 | |
10 |
include Gem::Text |
|
11 | ||
9 | 12 |
# TODO: move to Gem::Command |
10 | 13 |
OptionParser.accept Symbol do |value| |
11 | 14 |
value.to_sym |
... | ... | |
145 | 148 |
if block_given? then |
146 | 149 |
yield response |
147 | 150 |
else |
148 |
say response.body
|
|
151 |
say clean_text(response.body)
|
|
149 | 152 |
end |
150 | 153 |
else |
151 | 154 |
message = response.body |
152 | 155 |
message = "#{error_prefix}: #{message}" if error_prefix |
153 | 156 | |
154 |
say message
|
|
157 |
say clean_text(message)
|
|
155 | 158 |
terminate_interaction 1 # TODO: question this |
156 | 159 |
end |
157 | 160 |
end |
lib/rubygems/installer.rb | ||
---|---|---|
697 | 697 |
unpack or File.writable?(gem_home) |
698 | 698 |
end |
699 | 699 | |
700 |
def verify_spec_name |
|
701 |
return if spec.name =~ Gem::Specification::VALID_NAME_PATTERN |
|
702 |
raise Gem::InstallError, "#{spec} has an invalid name" |
|
700 |
def verify_spec |
|
701 |
unless spec.name =~ Gem::Specification::VALID_NAME_PATTERN |
|
702 |
raise Gem::InstallError, "#{spec} has an invalid name" |
|
703 |
end |
|
704 | ||
705 |
if spec.raw_require_paths.any?{|path| path =~ /\r\n|\r|\n/ } |
|
706 |
raise Gem::InstallError, "#{spec} has an invalid require_paths" |
|
707 |
end |
|
708 | ||
709 |
if spec.extensions.any?{|ext| ext =~ /\r\n|\r|\n/ } |
|
710 |
raise Gem::InstallError, "#{spec} has an invalid extensions" |
|
711 |
end |
|
712 | ||
713 |
unless spec.specification_version.to_s =~ /\A\d+\z/ |
|
714 |
raise Gem::InstallError, "#{spec} has an invalid specification_version" |
|
715 |
end |
|
716 | ||
717 |
if spec.dependencies.any? {|dep| dep.type =~ /\r\n|\r|\n/ || dep.name =~ /\r\n|\r|\n/ } |
|
718 |
raise Gem::InstallError, "#{spec} has an invalid dependencies" |
|
719 |
end |
|
703 | 720 |
end |
704 | 721 | |
705 | 722 |
## |
... | ... | |
826 | 843 |
def pre_install_checks |
827 | 844 |
verify_gem_home options[:unpack] |
828 | 845 | |
846 |
# The name and require_paths must be verified first, since it could contain |
|
847 |
# ruby code that would be eval'ed in #ensure_loadable_spec |
|
848 |
verify_spec |
|
849 | ||
829 | 850 |
ensure_loadable_spec |
830 | 851 | |
831 |
verify_spec_name |
|
832 | ||
833 | 852 |
if options[:install_as_default] |
834 | 853 |
Gem.ensure_default_gem_subdirectories gem_home |
835 | 854 |
else |
lib/rubygems/package.rb | ||
---|---|---|
425 | 425 |
raise Gem::Package::PathError.new(destination, destination_dir) unless |
426 | 426 |
destination.start_with? destination_dir + '/' |
427 | 427 | |
428 |
begin |
|
429 |
real_destination = File.expand_path(File.realpath(destination)) |
|
430 |
rescue |
|
431 |
# it's fine if the destination doesn't exist, because rm -rf'ing it can't cause any damage |
|
432 |
nil |
|
433 |
else |
|
434 |
raise Gem::Package::PathError.new(real_destination, destination_dir) unless |
|
435 |
real_destination.start_with? destination_dir + '/' |
|
436 |
end |
|
437 | ||
428 | 438 |
destination.untaint |
429 | 439 |
destination |
430 | 440 |
end |
lib/rubygems/user_interaction.rb | ||
---|---|---|
6 | 6 |
#++ |
7 | 7 | |
8 | 8 |
require 'rubygems/util' |
9 |
require 'rubygems/text' |
|
9 | 10 | |
10 | 11 |
begin |
11 | 12 |
require 'io/console' |
... | ... | |
18 | 19 | |
19 | 20 |
module Gem::DefaultUserInteraction |
20 | 21 | |
22 |
include Gem::Text |
|
23 | ||
21 | 24 |
## |
22 | 25 |
# The default UI is a class variable of the singleton class for this |
23 | 26 |
# module. |
... | ... | |
165 | 168 |
# Calls +say+ with +msg+ or the results of the block if really_verbose |
166 | 169 |
# is true. |
167 | 170 | |
168 |
def verbose msg = nil
|
|
169 |
say(msg || yield) if Gem.configuration.really_verbose
|
|
171 |
def verbose(msg = nil)
|
|
172 |
say(clean_text(msg || yield)) if Gem.configuration.really_verbose
|
|
170 | 173 |
end |
171 | 174 |
end |
172 | 175 |
test/rubygems/test_gem_installer.rb | ||
---|---|---|
1468 | 1468 |
end |
1469 | 1469 |
end |
1470 | 1470 | |
1471 |
def test_pre_install_checks_malicious_name_before_eval |
|
1472 |
spec = util_spec "malicious\n::Object.const_set(:FROM_EVAL, true)#", '1' |
|
1473 |
def spec.full_name # so the spec is buildable |
|
1474 |
"malicious-1" |
|
1475 |
end |
|
1476 |
def spec.validate(*args); end |
|
1477 | ||
1478 |
util_build_gem spec |
|
1479 | ||
1480 |
gem = File.join(@gemhome, 'cache', spec.file_name) |
|
1481 | ||
1482 |
use_ui @ui do |
|
1483 |
@installer = Gem::Installer.at gem |
|
1484 |
e = assert_raises Gem::InstallError do |
|
1485 |
@installer.pre_install_checks |
|
1486 |
end |
|
1487 |
assert_equal "#<Gem::Specification name=malicious\n::Object.const_set(:FROM_EVAL, true)# version=1> has an invalid name", e.message |
|
1488 |
end |
|
1489 |
refute defined?(::Object::FROM_EVAL) |
|
1490 |
end |
|
1491 | ||
1492 |
def test_pre_install_checks_malicious_require_paths_before_eval |
|
1493 |
spec = util_spec "malicious", '1' |
|
1494 |
def spec.full_name # so the spec is buildable |
|
1495 |
"malicious-1" |
|
1496 |
end |
|
1497 |
def spec.validate(*args); end |
|
1498 |
spec.require_paths = ["malicious\n``"] |
|
1499 | ||
1500 |
util_build_gem spec |
|
1501 | ||
1502 |
gem = File.join(@gemhome, 'cache', spec.file_name) |
|
1503 | ||
1504 |
use_ui @ui do |
|
1505 |
@installer = Gem::Installer.at gem |
|
1506 |
e = assert_raises Gem::InstallError do |
|
1507 |
@installer.pre_install_checks |
|
1508 |
end |
|
1509 |
assert_equal "#<Gem::Specification name=malicious version=1> has an invalid require_paths", e.message |
|
1510 |
end |
|
1511 |
end |
|
1512 | ||
1513 |
def test_pre_install_checks_malicious_extensions_before_eval |
|
1514 |
skip "mswin environment disallow to create file contained the carriage return code." if Gem.win_platform? |
|
1515 | ||
1516 |
spec = util_spec "malicious", '1' |
|
1517 |
def spec.full_name # so the spec is buildable |
|
1518 |
"malicious-1" |
|
1519 |
end |
|
1520 |
def spec.validate(*args); end |
|
1521 |
spec.extensions = ["malicious\n``"] |
|
1522 | ||
1523 |
util_build_gem spec |
|
1524 | ||
1525 |
gem = File.join(@gemhome, 'cache', spec.file_name) |
|
1526 | ||
1527 |
use_ui @ui do |
|
1528 |
@installer = Gem::Installer.at gem |
|
1529 |
e = assert_raises Gem::InstallError do |
|
1530 |
@installer.pre_install_checks |
|
1531 |
end |
|
1532 |
assert_equal "#<Gem::Specification name=malicious version=1> has an invalid extensions", e.message |
|
1533 |
end |
|
1534 |
end |
|
1535 | ||
1536 |
def test_pre_install_checks_malicious_specification_version_before_eval |
|
1537 |
spec = util_spec "malicious", '1' |
|
1538 |
def spec.full_name # so the spec is buildable |
|
1539 |
"malicious-1" |
|
1540 |
end |
|
1541 |
def spec.validate(*args); end |
|
1542 |
spec.specification_version = "malicious\n``" |
|
1543 | ||
1544 |
util_build_gem spec |
|
1545 | ||
1546 |
gem = File.join(@gemhome, 'cache', spec.file_name) |
|
1547 | ||
1548 |
use_ui @ui do |
|
1549 |
@installer = Gem::Installer.at gem |
|
1550 |
e = assert_raises Gem::InstallError do |
|
1551 |
@installer.pre_install_checks |
|
1552 |
end |
|
1553 |
assert_equal "#<Gem::Specification name=malicious version=1> has an invalid specification_version", e.message |
|
1554 |
end |
|
1555 |
end |
|
1556 | ||
1557 |
def test_pre_install_checks_malicious_dependencies_before_eval |
|
1558 |
spec = util_spec "malicious", '1' |
|
1559 |
def spec.full_name # so the spec is buildable |
|
1560 |
"malicious-1" |
|
1561 |
end |
|
1562 |
def spec.validate(*args); end |
|
1563 |
spec.add_dependency "b\nfoo", '> 5' |
|
1564 | ||
1565 |
util_build_gem spec |
|
1566 | ||
1567 |
gem = File.join(@gemhome, 'cache', spec.file_name) |
|
1568 | ||
1569 |
use_ui @ui do |
|
1570 |
@installer = Gem::Installer.at gem |
|
1571 |
@installer.ignore_dependencies = true |
|
1572 |
e = assert_raises Gem::InstallError do |
|
1573 |
@installer.pre_install_checks |
|
1574 |
end |
|
1575 |
assert_equal "#<Gem::Specification name=malicious version=1> has an invalid dependencies", e.message |
|
1576 |
end |
|
1577 |
end |
|
1578 | ||
1471 | 1579 |
def test_shebang |
1472 | 1580 |
util_make_exec @spec, "#!/usr/bin/ruby" |
1473 | 1581 |
test/rubygems/test_gem_package.rb | ||
---|---|---|
480 | 480 |
"#{destination_subdir} is not allowed", e.message) |
481 | 481 |
end |
482 | 482 | |
483 |
def test_extract_symlink_parent_doesnt_delete_user_dir |
|
484 |
skip if RUBY_VERSION <= "1.8.7" |
|
485 | ||
486 |
package = Gem::Package.new @gem |
|
487 | ||
488 |
# Extract into a subdirectory of @destination; if this test fails it writes |
|
489 |
# a file outside destination_subdir, but we want the file to remain inside |
|
490 |
# @destination so it will be cleaned up. |
|
491 |
destination_subdir = File.join @destination, 'subdir' |
|
492 |
FileUtils.mkdir_p destination_subdir |
|
493 | ||
494 |
destination_user_dir = File.join @destination, 'user' |
|
495 |
destination_user_subdir = File.join destination_user_dir, 'dir' |
|
496 |
FileUtils.mkdir_p destination_user_subdir |
|
497 | ||
498 |
tgz_io = util_tar_gz do |tar| |
|
499 |
tar.add_symlink 'link', destination_user_dir, 16877 |
|
500 |
tar.add_symlink 'link/dir', '.', 16877 |
|
501 |
end |
|
502 | ||
503 |
e = assert_raises(Gem::Package::PathError, Errno::EACCES) do |
|
504 |
package.extract_tar_gz tgz_io, destination_subdir |
|
505 |
end |
|
506 | ||
507 |
assert_path_exists destination_user_subdir |
|
508 | ||
509 |
if Gem::Package::PathError === e |
|
510 |
assert_equal("installing into parent path #{destination_user_subdir} of " + |
|
511 |
"#{destination_subdir} is not allowed", e.message) |
|
512 |
elsif win_platform? |
|
513 |
skip "symlink - must be admin with no UAC on Windows" |
|
514 |
else |
|
515 |
raise e |
|
516 |
end |
|
517 |
end |
|
518 | ||
483 | 519 |
def test_extract_tar_gz_directory |
484 | 520 |
package = Gem::Package.new @gem |
485 | 521 |
test/rubygems/test_gem_text.rb | ||
---|---|---|
85 | 85 |
s = "ab" * 500_001 |
86 | 86 |
assert_equal "Truncating desc to 1,000,000 characters:\n#{s[0, 1_000_000]}", truncate_text(s, "desc", 1_000_000) |
87 | 87 |
end |
88 | ||
89 |
def test_clean_text |
|
90 |
assert_equal ".]2;nyan.", clean_text("\e]2;nyan\a") |
|
91 |
end |
|
92 | ||
88 | 93 |
end |