rubygems-update 3.0.0 → 3.0.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.rubocop.yml +1 -0
- data/.travis.yml +2 -0
- data/CODE_OF_CONDUCT.md +10 -8
- data/CONTRIBUTING.md +7 -0
- data/History.txt +180 -0
- data/Manifest.txt +5 -3
- data/README.md +6 -0
- data/Rakefile +33 -7
- data/bundler/CHANGELOG.md +11 -0
- data/bundler/lib/bundler/build_metadata.rb +2 -2
- data/bundler/lib/bundler/rubygems_gem_installer.rb +7 -0
- data/bundler/lib/bundler/source/metadata.rb +2 -3
- data/bundler/lib/bundler/version.rb +1 -1
- data/bundler/man/bundle.ronn +3 -0
- data/lib/rubygems/command_manager.rb +12 -4
- data/lib/rubygems/commands/build_command.rb +28 -13
- data/lib/rubygems/commands/owner_command.rb +6 -1
- data/lib/rubygems/commands/push_command.rb +2 -0
- data/lib/rubygems/commands/setup_command.rb +14 -16
- data/lib/rubygems/commands/uninstall_command.rb +16 -6
- data/lib/rubygems/commands/which_command.rb +1 -3
- data/lib/rubygems/defaults.rb +1 -8
- data/lib/rubygems/dependency.rb +1 -1
- data/lib/rubygems/dependency_installer.rb +1 -2
- data/lib/rubygems/dependency_list.rb +1 -1
- data/lib/rubygems/exceptions.rb +0 -4
- data/lib/rubygems/gemcutter_utilities.rb +14 -7
- data/lib/rubygems/install_update_options.rb +1 -1
- data/lib/rubygems/installer.rb +37 -15
- data/lib/rubygems/installer_test_case.rb +2 -2
- data/lib/rubygems/package/old.rb +1 -1
- data/lib/rubygems/package/tar_header.rb +11 -2
- data/lib/rubygems/package.rb +12 -2
- data/lib/rubygems/rdoc.rb +2 -2
- data/lib/rubygems/remote_fetcher.rb +15 -54
- data/lib/rubygems/request.rb +1 -1
- data/lib/rubygems/request_set/gem_dependency_api.rb +11 -10
- data/lib/rubygems/requirement.rb +16 -5
- data/lib/rubygems/resolver.rb +4 -1
- data/lib/rubygems/s3_uri_signer.rb +183 -0
- data/lib/rubygems/security_option.rb +0 -1
- data/lib/rubygems/specification.rb +21 -23
- data/lib/rubygems/ssl_certs/rubygems.org/GlobalSignRootCA_R3.pem +21 -0
- data/lib/rubygems/stub_specification.rb +1 -2
- data/lib/rubygems/test_case.rb +23 -12
- data/lib/rubygems/uninstaller.rb +1 -1
- data/lib/rubygems/user_interaction.rb +4 -1
- data/lib/rubygems/util.rb +13 -1
- data/lib/rubygems.rb +8 -13
- data/rubygems-update.gemspec +1 -1
- data/test/rubygems/ca_cert.pem +74 -65
- data/test/rubygems/client.pem +103 -45
- data/test/rubygems/ssl_cert.pem +78 -17
- data/test/rubygems/ssl_key.pem +25 -13
- data/test/rubygems/test_bundled_ca.rb +8 -5
- data/test/rubygems/test_gem.rb +55 -13
- data/test/rubygems/test_gem_bundler_version_finder.rb +4 -0
- data/test/rubygems/test_gem_command_manager.rb +10 -0
- data/test/rubygems/test_gem_commands_build_command.rb +1 -0
- data/test/rubygems/test_gem_commands_push_command.rb +15 -0
- data/test/rubygems/test_gem_commands_setup_command.rb +11 -7
- data/test/rubygems/test_gem_commands_uninstall_command.rb +80 -1
- data/test/rubygems/test_gem_ext_cmake_builder.rb +1 -1
- data/test/rubygems/test_gem_indexer.rb +15 -8
- data/test/rubygems/test_gem_installer.rb +191 -22
- data/test/rubygems/test_gem_package.rb +37 -0
- data/test/rubygems/test_gem_package_tar_header.rb +41 -0
- data/test/rubygems/test_gem_package_tar_writer.rb +3 -0
- data/test/rubygems/test_gem_rdoc.rb +1 -135
- data/test/rubygems/test_gem_remote_fetcher.rb +133 -14
- data/test/rubygems/test_gem_request.rb +4 -4
- data/test/rubygems/test_gem_request_set_gem_dependency_api.rb +80 -57
- data/test/rubygems/test_gem_requirement.rb +6 -0
- data/test/rubygems/test_gem_security_policy.rb +1 -1
- data/test/rubygems/test_gem_specification.rb +32 -0
- data/test/rubygems/test_gem_stream_ui.rb +2 -2
- data/test/rubygems/test_gem_text.rb +5 -0
- data/test/rubygems/test_gem_uninstaller.rb +21 -2
- data/test/rubygems/test_gem_util.rb +25 -0
- data/util/ci +6 -1
- data/util/cops/deprecations.rb +52 -0
- data/util/create_certs.sh +27 -0
- data/util/create_encrypted_key.rb +4 -4
- data/util/update_bundled_ca_certificates.rb +1 -3
- metadata +12 -10
- data/lib/rubygems/ssl_certs/rubygems.global.ssl.fastly.net/DigiCertHighAssuranceEVRootCA.pem +0 -23
- data/lib/rubygems/ssl_certs/rubygems.org/AddTrustExternalCARoot.pem +0 -25
- /data/lib/rubygems/ssl_certs/{index.rubygems.org → rubygems.org}/GlobalSignRootCA.pem +0 -0
@@ -199,6 +199,21 @@ class TestGemCommandsPushCommand < Gem::TestCase
|
|
199
199
|
send_battery
|
200
200
|
end
|
201
201
|
|
202
|
+
def test_sending_gem_with_env_var_api_key
|
203
|
+
@host = "http://privategemserver.example"
|
204
|
+
|
205
|
+
@spec, @path = util_gem "freebird", "1.0.1" do |spec|
|
206
|
+
spec.metadata['allowed_push_host'] = @host
|
207
|
+
end
|
208
|
+
|
209
|
+
@api_key = "PRIVKEY"
|
210
|
+
ENV["GEM_HOST_API_KEY"] = "PRIVKEY"
|
211
|
+
|
212
|
+
@response = "Successfully registered gem: freebird (1.0.1)"
|
213
|
+
@fetcher.data["#{@host}/api/v1/gems"] = [@response, 200, 'OK']
|
214
|
+
send_battery
|
215
|
+
end
|
216
|
+
|
202
217
|
def test_sending_gem_to_allowed_push_host_with_basic_credentials
|
203
218
|
@sanitized_host = "http://privategemserver.example"
|
204
219
|
@host = "http://user:password@privategemserver.example"
|
@@ -38,6 +38,7 @@ class TestGemCommandsSetupCommand < Gem::TestCase
|
|
38
38
|
FileUtils.mkdir_p 'default/gems'
|
39
39
|
|
40
40
|
gemspec = Gem::Specification.new
|
41
|
+
gemspec.author = "Us"
|
41
42
|
gemspec.name = "bundler"
|
42
43
|
gemspec.version = BUNDLER_VERS
|
43
44
|
gemspec.bindir = "exe"
|
@@ -166,16 +167,19 @@ class TestGemCommandsSetupCommand < Gem::TestCase
|
|
166
167
|
def test_install_default_bundler_gem
|
167
168
|
@cmd.extend FileUtils
|
168
169
|
|
169
|
-
@
|
170
|
+
bin_dir = File.join(@gemhome, 'bin')
|
171
|
+
@cmd.install_default_bundler_gem bin_dir
|
170
172
|
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
spec = Gem::Specification.load(default_spec_path)
|
173
|
+
bundler_spec = Gem::Specification.load("bundler/bundler.gemspec")
|
174
|
+
default_spec_path = File.join(Gem::Specification.default_specifications_dir, "#{bundler_spec.full_name}.gemspec")
|
175
|
+
spec = Gem::Specification.load(default_spec_path)
|
175
176
|
|
176
|
-
|
177
|
-
|
177
|
+
spec.executables.each do |e|
|
178
|
+
if Gem.win_platform?
|
179
|
+
assert_path_exists File.join(bin_dir, "#{e}.bat")
|
178
180
|
end
|
181
|
+
|
182
|
+
assert_path_exists File.join bin_dir, e
|
179
183
|
end
|
180
184
|
|
181
185
|
default_dir = Gem::Specification.default_specifications_dir
|
@@ -192,6 +192,62 @@ class TestGemCommandsUninstallCommand < Gem::InstallerTestCase
|
|
192
192
|
assert File.exist? File.join(@gemhome, 'bin', 'executable')
|
193
193
|
end
|
194
194
|
|
195
|
+
def test_uninstall_selection
|
196
|
+
ui = Gem::MockGemUi.new "1\n"
|
197
|
+
|
198
|
+
util_make_gems
|
199
|
+
|
200
|
+
list = Gem::Specification.find_all_by_name 'a'
|
201
|
+
|
202
|
+
@cmd.options[:args] = ['a']
|
203
|
+
|
204
|
+
use_ui ui do
|
205
|
+
@cmd.execute
|
206
|
+
end
|
207
|
+
|
208
|
+
updated_list = Gem::Specification.find_all_by_name('a')
|
209
|
+
assert_equal list.length - 1, updated_list.length
|
210
|
+
|
211
|
+
assert_match ' 1. a-1', ui.output
|
212
|
+
assert_match ' 2. a-2', ui.output
|
213
|
+
assert_match ' 3. a-3.a', ui.output
|
214
|
+
assert_match ' 4. All versions', ui.output
|
215
|
+
assert_match 'uninstalled a-1', ui.output
|
216
|
+
end
|
217
|
+
|
218
|
+
def test_uninstall_selection_multiple_gems
|
219
|
+
ui = Gem::MockGemUi.new "1\n"
|
220
|
+
|
221
|
+
util_make_gems
|
222
|
+
|
223
|
+
a_list = Gem::Specification.find_all_by_name('a')
|
224
|
+
b_list = Gem::Specification.find_all_by_name('b')
|
225
|
+
list = a_list + b_list
|
226
|
+
|
227
|
+
@cmd.options[:args] = ['a', 'b']
|
228
|
+
|
229
|
+
use_ui ui do
|
230
|
+
@cmd.execute
|
231
|
+
end
|
232
|
+
|
233
|
+
updated_a_list = Gem::Specification.find_all_by_name('a')
|
234
|
+
updated_b_list = Gem::Specification.find_all_by_name('b')
|
235
|
+
updated_list = updated_a_list + updated_b_list
|
236
|
+
|
237
|
+
assert_equal list.length - 2, updated_list.length
|
238
|
+
|
239
|
+
out = ui.output.split("\n")
|
240
|
+
assert_match 'uninstalled b-2', out.shift
|
241
|
+
assert_match '', out.shift
|
242
|
+
assert_match 'Select gem to uninstall:', out.shift
|
243
|
+
assert_match ' 1. a-1', out.shift
|
244
|
+
assert_match ' 2. a-2', out.shift
|
245
|
+
assert_match ' 3. a-3.a', out.shift
|
246
|
+
assert_match ' 4. All versions', out.shift
|
247
|
+
assert_match 'uninstalled a-1', out.shift
|
248
|
+
assert_empty out
|
249
|
+
end
|
250
|
+
|
195
251
|
def test_execute_with_force_and_without_version_uninstalls_everything
|
196
252
|
ui = Gem::MockGemUi.new "y\n"
|
197
253
|
|
@@ -246,7 +302,7 @@ class TestGemCommandsUninstallCommand < Gem::InstallerTestCase
|
|
246
302
|
gemhome2 = "#{@gemhome}2"
|
247
303
|
|
248
304
|
a_4, = util_gem 'a', 4
|
249
|
-
install_gem a_4
|
305
|
+
install_gem a_4
|
250
306
|
|
251
307
|
Gem::Specification.dirs = [@gemhome, gemhome2]
|
252
308
|
|
@@ -264,6 +320,29 @@ class TestGemCommandsUninstallCommand < Gem::InstallerTestCase
|
|
264
320
|
assert_equal %w[default-1], Gem::Specification.all_names.sort
|
265
321
|
end
|
266
322
|
|
323
|
+
def test_execute_outside_gem_home
|
324
|
+
ui = Gem::MockGemUi.new "y\n"
|
325
|
+
|
326
|
+
gemhome2 = "#{@gemhome}2"
|
327
|
+
|
328
|
+
a_4, = util_gem 'a', 4
|
329
|
+
install_gem a_4 , :install_dir => gemhome2
|
330
|
+
|
331
|
+
Gem::Specification.dirs = [@gemhome, gemhome2]
|
332
|
+
|
333
|
+
assert_includes Gem::Specification.all_names, 'a-4'
|
334
|
+
|
335
|
+
@cmd.options[:args] = ['a:4']
|
336
|
+
|
337
|
+
e = assert_raises Gem::InstallError do
|
338
|
+
use_ui ui do
|
339
|
+
@cmd.execute
|
340
|
+
end
|
341
|
+
end
|
342
|
+
|
343
|
+
assert_includes e.message, "a is not installed in GEM_HOME"
|
344
|
+
end
|
345
|
+
|
267
346
|
def test_handle_options
|
268
347
|
@cmd.handle_options %w[]
|
269
348
|
|
@@ -25,7 +25,7 @@ class TestGemExtCmakeBuilder < Gem::TestCase
|
|
25
25
|
File.open File.join(@ext, 'CMakeLists.txt'), 'w' do |cmakelists|
|
26
26
|
cmakelists.write <<-eo_cmake
|
27
27
|
cmake_minimum_required(VERSION 2.6)
|
28
|
-
project(self_build
|
28
|
+
project(self_build NONE)
|
29
29
|
install (FILES test.txt DESTINATION bin)
|
30
30
|
eo_cmake
|
31
31
|
end
|
@@ -37,6 +37,13 @@ class TestGemIndexer < Gem::TestCase
|
|
37
37
|
@indexer = Gem::Indexer.new(@tempdir)
|
38
38
|
end
|
39
39
|
|
40
|
+
def teardown
|
41
|
+
super
|
42
|
+
|
43
|
+
util_clear_gems
|
44
|
+
util_clear_default_gems
|
45
|
+
end
|
46
|
+
|
40
47
|
def test_initialize
|
41
48
|
assert_equal @tempdir, @indexer.dest_directory
|
42
49
|
assert_match %r{#{Dir.mktmpdir('gem_generate_index').match(/.*-/)}}, @indexer.directory
|
@@ -96,8 +103,8 @@ class TestGemIndexer < Gem::TestCase
|
|
96
103
|
quickdir = File.join @tempdir, 'quick'
|
97
104
|
marshal_quickdir = File.join quickdir, "Marshal.#{@marshal_version}"
|
98
105
|
|
99
|
-
|
100
|
-
|
106
|
+
assert_directory_exists quickdir
|
107
|
+
assert_directory_exists marshal_quickdir
|
101
108
|
|
102
109
|
assert_indexed marshal_quickdir, "#{File.basename(@a1.spec_file)}.rz"
|
103
110
|
assert_indexed marshal_quickdir, "#{File.basename(@a2.spec_file)}.rz"
|
@@ -126,8 +133,8 @@ class TestGemIndexer < Gem::TestCase
|
|
126
133
|
quickdir = File.join @tempdir, 'quick'
|
127
134
|
marshal_quickdir = File.join quickdir, "Marshal.#{@marshal_version}"
|
128
135
|
|
129
|
-
|
130
|
-
|
136
|
+
assert_directory_exists quickdir, 'quickdir should be directory'
|
137
|
+
assert_directory_exists marshal_quickdir
|
131
138
|
|
132
139
|
refute_indexed quickdir, "index"
|
133
140
|
refute_indexed quickdir, "index.rz"
|
@@ -172,8 +179,8 @@ class TestGemIndexer < Gem::TestCase
|
|
172
179
|
quickdir = File.join @tempdir, 'quick'
|
173
180
|
marshal_quickdir = File.join quickdir, "Marshal.#{@marshal_version}"
|
174
181
|
|
175
|
-
|
176
|
-
|
182
|
+
assert_directory_exists quickdir
|
183
|
+
assert_directory_exists marshal_quickdir
|
177
184
|
|
178
185
|
assert_indexed marshal_quickdir, "#{File.basename(@a1.spec_file)}.rz"
|
179
186
|
assert_indexed marshal_quickdir, "#{File.basename(@a2.spec_file)}.rz"
|
@@ -308,8 +315,8 @@ class TestGemIndexer < Gem::TestCase
|
|
308
315
|
quickdir = File.join @tempdir, 'quick'
|
309
316
|
marshal_quickdir = File.join quickdir, "Marshal.#{@marshal_version}"
|
310
317
|
|
311
|
-
|
312
|
-
|
318
|
+
assert_directory_exists quickdir
|
319
|
+
assert_directory_exists marshal_quickdir
|
313
320
|
|
314
321
|
@d2_1 = util_spec 'd', '2.1'
|
315
322
|
util_build_gem @d2_1
|
@@ -163,6 +163,8 @@ gem 'other', version
|
|
163
163
|
|
164
164
|
wrapper = File.read installed_exec
|
165
165
|
assert_match %r|generated by RubyGems|, wrapper
|
166
|
+
ensure
|
167
|
+
Gem::Installer.exec_format = nil
|
166
168
|
end
|
167
169
|
|
168
170
|
def test_check_executable_overwrite_other_gem
|
@@ -311,7 +313,7 @@ gem 'other', version
|
|
311
313
|
@installer.wrappers = true
|
312
314
|
|
313
315
|
@spec.executables = %w[executable]
|
314
|
-
@spec.bindir = '
|
316
|
+
@spec.bindir = 'bin'
|
315
317
|
|
316
318
|
exec_file = @installer.formatted_program_filename 'executable'
|
317
319
|
exec_path = File.join @spec.gem_dir, exec_file
|
@@ -323,7 +325,7 @@ gem 'other', version
|
|
323
325
|
|
324
326
|
@installer.generate_bin
|
325
327
|
|
326
|
-
|
328
|
+
assert_directory_exists (util_inst_bindir)
|
327
329
|
installed_exec = File.join(util_inst_bindir, 'executable')
|
328
330
|
assert_path_exists installed_exec
|
329
331
|
assert_equal mask, File.stat(installed_exec).mode unless win_platform?
|
@@ -364,7 +366,7 @@ gem 'other', version
|
|
364
366
|
@installer.gem_dir = @spec.gem_dir
|
365
367
|
|
366
368
|
@installer.generate_bin
|
367
|
-
|
369
|
+
assert_directory_exists util_inst_bindir
|
368
370
|
installed_exec = File.join util_inst_bindir, 'executable'
|
369
371
|
assert_path_exists installed_exec
|
370
372
|
assert_equal mask, File.stat(installed_exec).mode unless win_platform?
|
@@ -381,7 +383,7 @@ gem 'other', version
|
|
381
383
|
|
382
384
|
Gem::Installer.exec_format = 'foo-%s-bar'
|
383
385
|
@installer.generate_bin
|
384
|
-
|
386
|
+
assert_directory_exists util_inst_bindir
|
385
387
|
installed_exec = File.join util_inst_bindir, 'foo-executable-bar'
|
386
388
|
assert_path_exists installed_exec
|
387
389
|
ensure
|
@@ -395,7 +397,7 @@ gem 'other', version
|
|
395
397
|
|
396
398
|
Gem::Installer.exec_format = 'foo-%s-bar'
|
397
399
|
@installer.generate_bin
|
398
|
-
|
400
|
+
assert_directory_exists util_inst_bindir
|
399
401
|
installed_exec = File.join util_inst_bindir, 'executable'
|
400
402
|
assert_path_exists installed_exec
|
401
403
|
ensure
|
@@ -494,7 +496,7 @@ gem 'other', version
|
|
494
496
|
end
|
495
497
|
|
496
498
|
@installer.generate_bin
|
497
|
-
|
499
|
+
assert_directory_exists util_inst_bindir
|
498
500
|
assert_path_exists installed_exec
|
499
501
|
assert_equal mask, File.stat(installed_exec).mode unless win_platform?
|
500
502
|
|
@@ -512,7 +514,7 @@ gem 'other', version
|
|
512
514
|
@installer.gem_dir = @spec.gem_dir
|
513
515
|
|
514
516
|
@installer.generate_bin
|
515
|
-
|
517
|
+
assert_directory_exists util_inst_bindir
|
516
518
|
installed_exec = File.join util_inst_bindir, 'executable'
|
517
519
|
assert_equal true, File.symlink?(installed_exec)
|
518
520
|
assert_equal(File.join(@spec.gem_dir, 'bin', 'executable'),
|
@@ -664,7 +666,7 @@ gem 'other', version
|
|
664
666
|
@installer.generate_bin
|
665
667
|
end
|
666
668
|
|
667
|
-
|
669
|
+
assert_directory_exists util_inst_bindir
|
668
670
|
installed_exec = File.join(util_inst_bindir, 'executable')
|
669
671
|
assert_path_exists installed_exec
|
670
672
|
|
@@ -740,13 +742,13 @@ gem 'other', version
|
|
740
742
|
rakefile = File.join gemdir, 'ext', 'a', 'Rakefile'
|
741
743
|
spec_file = File.join @gemhome, 'specifications', @spec.spec_name
|
742
744
|
|
743
|
-
Gem.pre_install do
|
745
|
+
Gem.pre_install do
|
744
746
|
refute_path_exists cache_file, 'cache file must not exist yet'
|
745
747
|
refute_path_exists spec_file, 'spec file must not exist yet'
|
746
748
|
true
|
747
749
|
end
|
748
750
|
|
749
|
-
Gem.post_build do
|
751
|
+
Gem.post_build do
|
750
752
|
assert_path_exists gemdir, 'gem install dir must exist'
|
751
753
|
assert_path_exists rakefile, 'gem executable must exist'
|
752
754
|
refute_path_exists stub_exe, 'gem executable must not exist'
|
@@ -754,7 +756,7 @@ gem 'other', version
|
|
754
756
|
true
|
755
757
|
end
|
756
758
|
|
757
|
-
Gem.post_install do
|
759
|
+
Gem.post_install do
|
758
760
|
assert_path_exists cache_file, 'cache file must exist'
|
759
761
|
assert_path_exists spec_file, 'spec file must exist'
|
760
762
|
end
|
@@ -975,16 +977,16 @@ gem 'other', version
|
|
975
977
|
|
976
978
|
def test_install_missing_dirs
|
977
979
|
FileUtils.rm_f File.join(Gem.dir, 'cache')
|
978
|
-
FileUtils.rm_f File.join(Gem.dir, '
|
980
|
+
FileUtils.rm_f File.join(Gem.dir, 'doc')
|
979
981
|
FileUtils.rm_f File.join(Gem.dir, 'specifications')
|
980
982
|
|
981
983
|
use_ui @ui do
|
982
984
|
@installer.install
|
983
985
|
end
|
984
986
|
|
985
|
-
|
986
|
-
|
987
|
-
|
987
|
+
assert_directory_exists File.join(Gem.dir, 'cache')
|
988
|
+
assert_directory_exists File.join(Gem.dir, 'doc')
|
989
|
+
assert_directory_exists File.join(Gem.dir, 'specifications')
|
988
990
|
|
989
991
|
assert_path_exists File.join @gemhome, 'cache', @spec.file_name
|
990
992
|
assert_path_exists File.join @gemhome, 'specifications', @spec.spec_name
|
@@ -1446,6 +1448,114 @@ gem 'other', version
|
|
1446
1448
|
end
|
1447
1449
|
end
|
1448
1450
|
|
1451
|
+
def test_pre_install_checks_malicious_name_before_eval
|
1452
|
+
spec = util_spec "malicious\n::Object.const_set(:FROM_EVAL, true)#", '1'
|
1453
|
+
def spec.full_name # so the spec is buildable
|
1454
|
+
"malicious-1"
|
1455
|
+
end
|
1456
|
+
def spec.validate(*args); end
|
1457
|
+
|
1458
|
+
util_build_gem spec
|
1459
|
+
|
1460
|
+
gem = File.join(@gemhome, 'cache', spec.file_name)
|
1461
|
+
|
1462
|
+
use_ui @ui do
|
1463
|
+
@installer = Gem::Installer.at gem
|
1464
|
+
e = assert_raises Gem::InstallError do
|
1465
|
+
@installer.pre_install_checks
|
1466
|
+
end
|
1467
|
+
assert_equal "#<Gem::Specification name=malicious\n::Object.const_set(:FROM_EVAL, true)# version=1> has an invalid name", e.message
|
1468
|
+
end
|
1469
|
+
refute defined?(::Object::FROM_EVAL)
|
1470
|
+
end
|
1471
|
+
|
1472
|
+
def test_pre_install_checks_malicious_require_paths_before_eval
|
1473
|
+
spec = util_spec "malicious", '1'
|
1474
|
+
def spec.full_name # so the spec is buildable
|
1475
|
+
"malicious-1"
|
1476
|
+
end
|
1477
|
+
def spec.validate(*args); end
|
1478
|
+
spec.require_paths = ["malicious\n``"]
|
1479
|
+
|
1480
|
+
util_build_gem spec
|
1481
|
+
|
1482
|
+
gem = File.join(@gemhome, 'cache', spec.file_name)
|
1483
|
+
|
1484
|
+
use_ui @ui do
|
1485
|
+
@installer = Gem::Installer.at gem
|
1486
|
+
e = assert_raises Gem::InstallError do
|
1487
|
+
@installer.pre_install_checks
|
1488
|
+
end
|
1489
|
+
assert_equal "#<Gem::Specification name=malicious version=1> has an invalid require_paths", e.message
|
1490
|
+
end
|
1491
|
+
end
|
1492
|
+
|
1493
|
+
def test_pre_install_checks_malicious_extensions_before_eval
|
1494
|
+
skip "mswin environment disallow to create file contained the carriage return code." if Gem.win_platform?
|
1495
|
+
|
1496
|
+
spec = util_spec "malicious", '1'
|
1497
|
+
def spec.full_name # so the spec is buildable
|
1498
|
+
"malicious-1"
|
1499
|
+
end
|
1500
|
+
def spec.validate(*args); end
|
1501
|
+
spec.extensions = ["malicious\n``"]
|
1502
|
+
|
1503
|
+
util_build_gem spec
|
1504
|
+
|
1505
|
+
gem = File.join(@gemhome, 'cache', spec.file_name)
|
1506
|
+
|
1507
|
+
use_ui @ui do
|
1508
|
+
@installer = Gem::Installer.at gem
|
1509
|
+
e = assert_raises Gem::InstallError do
|
1510
|
+
@installer.pre_install_checks
|
1511
|
+
end
|
1512
|
+
assert_equal "#<Gem::Specification name=malicious version=1> has an invalid extensions", e.message
|
1513
|
+
end
|
1514
|
+
end
|
1515
|
+
|
1516
|
+
def test_pre_install_checks_malicious_specification_version_before_eval
|
1517
|
+
spec = util_spec "malicious", '1'
|
1518
|
+
def spec.full_name # so the spec is buildable
|
1519
|
+
"malicious-1"
|
1520
|
+
end
|
1521
|
+
def spec.validate(*args); end
|
1522
|
+
spec.specification_version = "malicious\n``"
|
1523
|
+
|
1524
|
+
util_build_gem spec
|
1525
|
+
|
1526
|
+
gem = File.join(@gemhome, 'cache', spec.file_name)
|
1527
|
+
|
1528
|
+
use_ui @ui do
|
1529
|
+
@installer = Gem::Installer.at gem
|
1530
|
+
e = assert_raises Gem::InstallError do
|
1531
|
+
@installer.pre_install_checks
|
1532
|
+
end
|
1533
|
+
assert_equal "#<Gem::Specification name=malicious version=1> has an invalid specification_version", e.message
|
1534
|
+
end
|
1535
|
+
end
|
1536
|
+
|
1537
|
+
def test_pre_install_checks_malicious_dependencies_before_eval
|
1538
|
+
spec = util_spec "malicious", '1'
|
1539
|
+
def spec.full_name # so the spec is buildable
|
1540
|
+
"malicious-1"
|
1541
|
+
end
|
1542
|
+
def spec.validate(*args); end
|
1543
|
+
spec.add_dependency "b\nfoo", '> 5'
|
1544
|
+
|
1545
|
+
util_build_gem spec
|
1546
|
+
|
1547
|
+
gem = File.join(@gemhome, 'cache', spec.file_name)
|
1548
|
+
|
1549
|
+
use_ui @ui do
|
1550
|
+
@installer = Gem::Installer.at gem
|
1551
|
+
@installer.ignore_dependencies = true
|
1552
|
+
e = assert_raises Gem::InstallError do
|
1553
|
+
@installer.pre_install_checks
|
1554
|
+
end
|
1555
|
+
assert_equal "#<Gem::Specification name=malicious version=1> has an invalid dependencies", e.message
|
1556
|
+
end
|
1557
|
+
end
|
1558
|
+
|
1449
1559
|
def test_shebang
|
1450
1560
|
util_make_exec @spec, "#!/usr/bin/ruby"
|
1451
1561
|
|
@@ -1712,28 +1822,87 @@ gem 'other', version
|
|
1712
1822
|
assert_predicate spec, :default_gem?
|
1713
1823
|
end
|
1714
1824
|
|
1715
|
-
def
|
1825
|
+
def test_default_gem_without_wrappers
|
1716
1826
|
FileUtils.rm_f File.join(Gem.dir, 'specifications')
|
1717
1827
|
|
1718
|
-
@installer.wrappers =
|
1828
|
+
@installer.wrappers = false
|
1719
1829
|
@installer.options[:install_as_default] = true
|
1720
1830
|
@installer.gem_dir = @spec.gem_dir
|
1721
|
-
@installer.generate_bin
|
1722
1831
|
|
1723
1832
|
use_ui @ui do
|
1724
1833
|
@installer.install
|
1725
1834
|
end
|
1726
1835
|
|
1727
|
-
|
1728
|
-
installed_exec = File.join
|
1836
|
+
assert_directory_exists File.join(@spec.gem_dir, 'bin')
|
1837
|
+
installed_exec = File.join @spec.gem_dir, 'bin', 'executable'
|
1729
1838
|
assert_path_exists installed_exec
|
1730
1839
|
|
1731
|
-
|
1732
|
-
|
1840
|
+
assert_directory_exists File.join(Gem.default_dir, 'specifications')
|
1841
|
+
assert_directory_exists File.join(Gem.default_dir, 'specifications', 'default')
|
1733
1842
|
|
1734
1843
|
default_spec = eval File.read File.join(Gem.default_dir, 'specifications', 'default', 'a-2.gemspec')
|
1735
1844
|
assert_equal Gem::Version.new("2"), default_spec.version
|
1736
1845
|
assert_equal ['bin/executable'], default_spec.files
|
1846
|
+
|
1847
|
+
assert_directory_exists util_inst_bindir
|
1848
|
+
|
1849
|
+
installed_exec = File.join util_inst_bindir, 'executable'
|
1850
|
+
assert_path_exists installed_exec
|
1851
|
+
|
1852
|
+
wrapper = File.read installed_exec
|
1853
|
+
refute_match %r|generated by RubyGems|, wrapper
|
1854
|
+
end
|
1855
|
+
|
1856
|
+
def test_default_gem_with_wrappers
|
1857
|
+
FileUtils.rm_f File.join(Gem.dir, 'specifications')
|
1858
|
+
|
1859
|
+
@installer.wrappers = true
|
1860
|
+
@installer.options[:install_as_default] = true
|
1861
|
+
@installer.gem_dir = @spec.gem_dir
|
1862
|
+
|
1863
|
+
use_ui @ui do
|
1864
|
+
@installer.install
|
1865
|
+
end
|
1866
|
+
|
1867
|
+
assert_directory_exists util_inst_bindir
|
1868
|
+
|
1869
|
+
installed_exec = File.join util_inst_bindir, 'executable'
|
1870
|
+
assert_path_exists installed_exec
|
1871
|
+
|
1872
|
+
wrapper = File.read installed_exec
|
1873
|
+
assert_match %r|generated by RubyGems|, wrapper
|
1874
|
+
end
|
1875
|
+
|
1876
|
+
def test_default_gem_with_exe_as_bindir
|
1877
|
+
FileUtils.rm_f File.join(Gem.dir, 'specifications')
|
1878
|
+
|
1879
|
+
@spec = quick_gem 'c' do |spec|
|
1880
|
+
util_make_exec spec, '#!/usr/bin/ruby', 'exe'
|
1881
|
+
end
|
1882
|
+
|
1883
|
+
util_build_gem @spec
|
1884
|
+
|
1885
|
+
@spec.cache_file
|
1886
|
+
|
1887
|
+
installer = util_installer @spec, @gemhome
|
1888
|
+
|
1889
|
+
installer.options[:install_as_default] = true
|
1890
|
+
installer.gem_dir = @spec.gem_dir
|
1891
|
+
|
1892
|
+
use_ui @ui do
|
1893
|
+
installer.install
|
1894
|
+
end
|
1895
|
+
|
1896
|
+
assert_directory_exists File.join(@spec.gem_dir, 'exe')
|
1897
|
+
installed_exec = File.join @spec.gem_dir, 'exe', 'executable'
|
1898
|
+
assert_path_exists installed_exec
|
1899
|
+
|
1900
|
+
assert_directory_exists File.join(Gem.default_dir, 'specifications')
|
1901
|
+
assert_directory_exists File.join(Gem.default_dir, 'specifications', 'default')
|
1902
|
+
|
1903
|
+
default_spec = eval File.read File.join(Gem.default_dir, 'specifications', 'default', 'c-2.gemspec')
|
1904
|
+
assert_equal Gem::Version.new("2"), default_spec.version
|
1905
|
+
assert_equal ['exe/executable'], default_spec.files
|
1737
1906
|
end
|
1738
1907
|
|
1739
1908
|
def old_ruby_required(requirement)
|
@@ -105,6 +105,7 @@ class TestGemPackage < Gem::Package::TarTestCase
|
|
105
105
|
end
|
106
106
|
|
107
107
|
def test_build_time_source_date_epoch
|
108
|
+
epoch = ENV["SOURCE_DATE_EPOCH"]
|
108
109
|
ENV["SOURCE_DATE_EPOCH"] = "123456789"
|
109
110
|
|
110
111
|
spec = Gem::Specification.new 'build', '1'
|
@@ -118,6 +119,8 @@ class TestGemPackage < Gem::Package::TarTestCase
|
|
118
119
|
package = Gem::Package.new spec.file_name
|
119
120
|
|
120
121
|
assert_equal Time.at(ENV["SOURCE_DATE_EPOCH"].to_i).utc, package.build_time
|
122
|
+
ensure
|
123
|
+
ENV["SOURCE_DATE_EPOCH"] = epoch
|
121
124
|
end
|
122
125
|
|
123
126
|
def test_add_files
|
@@ -526,6 +529,40 @@ class TestGemPackage < Gem::Package::TarTestCase
|
|
526
529
|
end
|
527
530
|
end
|
528
531
|
|
532
|
+
def test_extract_symlink_parent_doesnt_delete_user_dir
|
533
|
+
package = Gem::Package.new @gem
|
534
|
+
|
535
|
+
# Extract into a subdirectory of @destination; if this test fails it writes
|
536
|
+
# a file outside destination_subdir, but we want the file to remain inside
|
537
|
+
# @destination so it will be cleaned up.
|
538
|
+
destination_subdir = File.join @destination, 'subdir'
|
539
|
+
FileUtils.mkdir_p destination_subdir
|
540
|
+
|
541
|
+
destination_user_dir = File.join @destination, 'user'
|
542
|
+
destination_user_subdir = File.join destination_user_dir, 'dir'
|
543
|
+
FileUtils.mkdir_p destination_user_subdir
|
544
|
+
|
545
|
+
tgz_io = util_tar_gz do |tar|
|
546
|
+
tar.add_symlink 'link', destination_user_dir, 16877
|
547
|
+
tar.add_symlink 'link/dir', '.', 16877
|
548
|
+
end
|
549
|
+
|
550
|
+
e = assert_raises(Gem::Package::PathError, Errno::EACCES) do
|
551
|
+
package.extract_tar_gz tgz_io, destination_subdir
|
552
|
+
end
|
553
|
+
|
554
|
+
assert_path_exists destination_user_subdir
|
555
|
+
|
556
|
+
if Gem::Package::PathError === e
|
557
|
+
assert_equal("installing into parent path #{destination_user_subdir} of " +
|
558
|
+
"#{destination_subdir} is not allowed", e.message)
|
559
|
+
elsif win_platform?
|
560
|
+
skip "symlink - must be admin with no UAC on Windows"
|
561
|
+
else
|
562
|
+
raise e
|
563
|
+
end
|
564
|
+
end
|
565
|
+
|
529
566
|
def test_extract_tar_gz_directory
|
530
567
|
package = Gem::Package.new @gem
|
531
568
|
|
@@ -164,4 +164,45 @@ group\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000
|
|
164
164
|
end
|
165
165
|
end
|
166
166
|
|
167
|
+
def test_big_uid_gid
|
168
|
+
stream = StringIO.new(
|
169
|
+
<<-EOF.dup.force_encoding('binary').split("\n").join
|
170
|
+
GeoIP2-City_20190528/
|
171
|
+
\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00
|
172
|
+
\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00
|
173
|
+
\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00
|
174
|
+
\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x000000755\x00\x80\x00
|
175
|
+
\x00\x00v\xB2Z\x9E\x80\x00\x00\x00v\xB2Z\x9E00000000000\x0013473270100\x00015424
|
176
|
+
\x00 5\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00
|
177
|
+
\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00
|
178
|
+
\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00
|
179
|
+
\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00
|
180
|
+
\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00ustar \x00
|
181
|
+
tjmather\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00
|
182
|
+
\x00\x00\x00\x00\x00tjmather\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00
|
183
|
+
\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00
|
184
|
+
\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00
|
185
|
+
\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00
|
186
|
+
\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00
|
187
|
+
\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00
|
188
|
+
\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00
|
189
|
+
\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00
|
190
|
+
\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00
|
191
|
+
\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00
|
192
|
+
\x00\x00\x00\x00
|
193
|
+
EOF
|
194
|
+
)
|
195
|
+
|
196
|
+
tar_header = Gem::Package::TarHeader.from stream
|
197
|
+
|
198
|
+
assert_equal 1991400094, tar_header.uid
|
199
|
+
assert_equal 1991400094, tar_header.gid
|
200
|
+
|
201
|
+
assert_equal 'GeoIP2-City_20190528/', tar_header.name
|
202
|
+
assert_equal 0755, tar_header.mode
|
203
|
+
assert_equal 0, tar_header.size
|
204
|
+
assert_equal 1559064640, tar_header.mtime
|
205
|
+
assert_equal 6932, tar_header.checksum
|
206
|
+
end
|
207
|
+
|
167
208
|
end
|
@@ -11,9 +11,12 @@ class TestGemPackageTarWriter < Gem::Package::TarTestCase
|
|
11
11
|
@data = 'abcde12345'
|
12
12
|
@io = TempIO.new
|
13
13
|
@tar_writer = Gem::Package::TarWriter.new @io
|
14
|
+
@epoch = ENV["SOURCE_DATE_EPOCH"]
|
15
|
+
ENV["SOURCE_DATE_EPOCH"] = nil
|
14
16
|
end
|
15
17
|
|
16
18
|
def teardown
|
19
|
+
ENV["SOURCE_DATE_EPOCH"] = @epoch
|
17
20
|
@tar_writer.close unless @tar_writer.closed?
|
18
21
|
@io.close!
|
19
22
|
|