rubygems-update 2.0.17 → 2.1.0.rc.1

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of rubygems-update might be problematic. Click here for more details.

Files changed (154) hide show
  1. checksums.yaml +4 -4
  2. checksums.yaml.gz.sig +0 -0
  3. data.tar.gz.sig +2 -0
  4. data/.autotest +1 -1
  5. data/History.txt +82 -153
  6. data/Manifest.txt +35 -9
  7. data/Rakefile +35 -36
  8. data/lib/rubygems.rb +106 -18
  9. data/lib/rubygems/available_set.rb +68 -0
  10. data/lib/rubygems/basic_specification.rb +139 -0
  11. data/lib/rubygems/command_manager.rb +37 -40
  12. data/lib/rubygems/commands/cert_command.rb +78 -29
  13. data/lib/rubygems/commands/cleanup_command.rb +2 -2
  14. data/lib/rubygems/commands/contents_command.rb +101 -58
  15. data/lib/rubygems/commands/dependency_command.rb +94 -53
  16. data/lib/rubygems/commands/environment_command.rb +70 -53
  17. data/lib/rubygems/commands/fetch_command.rb +1 -2
  18. data/lib/rubygems/commands/help_command.rb +85 -55
  19. data/lib/rubygems/commands/install_command.rb +84 -42
  20. data/lib/rubygems/commands/outdated_command.rb +2 -12
  21. data/lib/rubygems/commands/owner_command.rb +6 -0
  22. data/lib/rubygems/commands/pristine_command.rb +26 -16
  23. data/lib/rubygems/commands/sources_command.rb +85 -70
  24. data/lib/rubygems/commands/uninstall_command.rb +32 -2
  25. data/lib/rubygems/commands/update_command.rb +111 -75
  26. data/lib/rubygems/config_file.rb +15 -3
  27. data/lib/rubygems/core_ext/kernel_require.rb +9 -31
  28. data/lib/rubygems/defaults.rb +8 -0
  29. data/lib/rubygems/dependency.rb +4 -2
  30. data/lib/rubygems/dependency_installer.rb +180 -170
  31. data/lib/rubygems/dependency_resolver.rb +191 -526
  32. data/lib/rubygems/dependency_resolver/activation_request.rb +109 -0
  33. data/lib/rubygems/dependency_resolver/api_set.rb +65 -0
  34. data/lib/rubygems/dependency_resolver/api_specification.rb +36 -0
  35. data/lib/rubygems/dependency_resolver/composed_set.rb +18 -0
  36. data/lib/rubygems/dependency_resolver/current_set.rb +16 -0
  37. data/lib/rubygems/dependency_resolver/dependency_conflict.rb +85 -0
  38. data/lib/rubygems/dependency_resolver/dependency_request.rb +51 -0
  39. data/lib/rubygems/dependency_resolver/index_set.rb +59 -0
  40. data/lib/rubygems/dependency_resolver/index_specification.rb +53 -0
  41. data/lib/rubygems/dependency_resolver/installed_specification.rb +38 -0
  42. data/lib/rubygems/dependency_resolver/installer_set.rb +130 -0
  43. data/lib/rubygems/exceptions.rb +88 -1
  44. data/lib/rubygems/ext/builder.rb +1 -1
  45. data/lib/rubygems/gem_runner.rb +17 -9
  46. data/lib/rubygems/gemcutter_utilities.rb +72 -42
  47. data/lib/rubygems/install_default_message.rb +12 -0
  48. data/lib/rubygems/install_update_options.rb +3 -0
  49. data/lib/rubygems/installer.rb +55 -30
  50. data/lib/rubygems/name_tuple.rb +18 -7
  51. data/lib/rubygems/package.rb +50 -25
  52. data/lib/rubygems/package/tar_test_case.rb +9 -9
  53. data/lib/rubygems/package/tar_writer.rb +35 -12
  54. data/lib/rubygems/package_task.rb +2 -5
  55. data/lib/rubygems/path_support.rb +10 -0
  56. data/lib/rubygems/platform.rb +9 -3
  57. data/lib/rubygems/psych_additions.rb +1 -1
  58. data/lib/rubygems/remote_fetcher.rb +9 -276
  59. data/lib/rubygems/request.rb +267 -0
  60. data/lib/rubygems/request_set.rb +123 -125
  61. data/lib/rubygems/request_set/gem_dependency_api.rb +39 -0
  62. data/lib/rubygems/security.rb +32 -23
  63. data/lib/rubygems/security/policy.rb +35 -9
  64. data/lib/rubygems/security/signer.rb +2 -2
  65. data/lib/rubygems/server.rb +8 -16
  66. data/lib/rubygems/source.rb +25 -14
  67. data/lib/rubygems/source/installed.rb +28 -0
  68. data/lib/rubygems/source/local.rb +122 -0
  69. data/lib/rubygems/source/specific_file.rb +28 -0
  70. data/lib/rubygems/source_local.rb +2 -89
  71. data/lib/rubygems/source_specific_file.rb +2 -26
  72. data/lib/rubygems/spec_fetcher.rb +11 -11
  73. data/lib/rubygems/specification.rb +186 -198
  74. data/lib/rubygems/ssl_certs/AddTrustExternalCARoot.pem +88 -30
  75. data/lib/rubygems/ssl_certs/Entrust_net-Secure-Server-Certification-Authority.pem +90 -0
  76. data/lib/rubygems/ssl_certs/{GeoTrustGlobalCA.pem → GeoTrust_Global_CA.pem} +20 -20
  77. data/lib/rubygems/ssl_certs/VerisignClass3PublicPrimaryCertificationAuthority-G2.pem +57 -0
  78. data/lib/rubygems/stub_specification.rb +119 -0
  79. data/lib/rubygems/test_case.rb +117 -49
  80. data/lib/rubygems/uninstaller.rb +14 -9
  81. data/lib/rubygems/uri_formatter.rb +39 -0
  82. data/lib/rubygems/util/list.rb +44 -0
  83. data/lib/rubygems/version.rb +15 -5
  84. data/lib/rubygems/version_option.rb +8 -2
  85. data/test/rubygems/ca_cert.pem +23 -0
  86. data/test/rubygems/client.pem +49 -0
  87. data/test/rubygems/encrypted_private_key.pem +30 -0
  88. data/test/rubygems/invalid_client.pem +49 -0
  89. data/test/rubygems/specifications/bar-0.0.2.gemspec +9 -0
  90. data/test/rubygems/specifications/foo-0.0.1.gemspec +0 -0
  91. data/test/rubygems/test_gem.rb +76 -454
  92. data/test/rubygems/test_gem_command_manager.rb +23 -21
  93. data/test/rubygems/test_gem_commands_cert_command.rb +154 -14
  94. data/test/rubygems/test_gem_commands_cleanup_command.rb +15 -0
  95. data/test/rubygems/test_gem_commands_contents_command.rb +32 -4
  96. data/test/rubygems/test_gem_commands_environment_command.rb +9 -1
  97. data/test/rubygems/test_gem_commands_fetch_command.rb +2 -28
  98. data/test/rubygems/test_gem_commands_help_command.rb +6 -3
  99. data/test/rubygems/test_gem_commands_install_command.rb +2 -65
  100. data/test/rubygems/test_gem_commands_owner_command.rb +49 -0
  101. data/test/rubygems/test_gem_commands_pristine_command.rb +30 -0
  102. data/test/rubygems/test_gem_commands_sources_command.rb +1 -1
  103. data/test/rubygems/test_gem_commands_uninstall_command.rb +33 -0
  104. data/test/rubygems/test_gem_commands_update_command.rb +2 -1
  105. data/test/rubygems/test_gem_config_file.rb +12 -0
  106. data/test/rubygems/test_gem_dependency_installer.rb +58 -65
  107. data/test/rubygems/test_gem_dependency_resolver.rb +6 -3
  108. data/test/rubygems/test_gem_dependency_resolver_dependency_conflict.rb +36 -0
  109. data/test/rubygems/test_gem_ext_builder.rb +2 -4
  110. data/test/rubygems/test_gem_ext_ext_conf_builder.rb +7 -2
  111. data/test/rubygems/test_gem_gem_runner.rb +17 -13
  112. data/test/rubygems/test_gem_gemcutter_utilities.rb +6 -19
  113. data/test/rubygems/test_gem_impossible_dependencies_error.rb +41 -0
  114. data/test/rubygems/test_gem_install_update_options.rb +4 -1
  115. data/test/rubygems/test_gem_installer.rb +31 -2
  116. data/test/rubygems/test_gem_name_tuple.rb +22 -0
  117. data/test/rubygems/test_gem_package.rb +122 -11
  118. data/test/rubygems/test_gem_package_old.rb +8 -0
  119. data/test/rubygems/test_gem_package_tar_reader.rb +9 -8
  120. data/test/rubygems/test_gem_package_tar_reader_entry.rb +1 -1
  121. data/test/rubygems/test_gem_package_tar_writer.rb +78 -56
  122. data/test/rubygems/test_gem_package_task.rb +2 -23
  123. data/test/rubygems/test_gem_path_support.rb +17 -0
  124. data/test/rubygems/test_gem_platform.rb +18 -0
  125. data/test/rubygems/test_gem_remote_fetcher.rb +106 -385
  126. data/test/rubygems/test_gem_request.rb +239 -0
  127. data/test/rubygems/test_gem_requirement.rb +9 -11
  128. data/test/rubygems/test_gem_security.rb +58 -2
  129. data/test/rubygems/test_gem_security_policy.rb +42 -1
  130. data/test/rubygems/test_gem_security_signer.rb +13 -1
  131. data/test/rubygems/test_gem_security_trust_dir.rb +5 -1
  132. data/test/rubygems/test_gem_server.rb +1 -105
  133. data/test/rubygems/test_gem_source.rb +4 -14
  134. data/test/rubygems/test_gem_source_local.rb +4 -4
  135. data/test/rubygems/test_gem_source_specific_file.rb +1 -1
  136. data/test/rubygems/test_gem_spec_fetcher.rb +0 -12
  137. data/test/rubygems/test_gem_specification.rb +452 -28
  138. data/test/rubygems/test_gem_stub_specification.rb +30 -0
  139. data/test/rubygems/test_gem_uninstaller.rb +14 -0
  140. data/test/rubygems/test_gem_uri_formatter.rb +20 -0
  141. data/test/rubygems/test_gem_version.rb +23 -13
  142. data/test/rubygems/test_gem_version_option.rb +63 -1
  143. data/test/rubygems/test_require.rb +0 -12
  144. data/util/create_encrypted_key.rb +16 -0
  145. metadata +161 -23
  146. metadata.gz.sig +0 -0
  147. data/CVE-2013-4287.txt +0 -36
  148. data/CVE-2013-4363.txt +0 -45
  149. data/lib/rubygems/ssl_certs/AddTrustExternalCARoot-2048.pem +0 -25
  150. data/lib/rubygems/ssl_certs/Class3PublicPrimaryCertificationAuthority.pem +0 -14
  151. data/lib/rubygems/ssl_certs/DigiCertHighAssuranceEVRootCA.pem +0 -23
  152. data/lib/rubygems/ssl_certs/EntrustnetSecureServerCertificationAuthority.pem +0 -28
  153. data/test/rubygems/test_bundled_ca.rb +0 -59
  154. data/util/update_bundled_ca_certificates.rb +0 -103
@@ -0,0 +1,12 @@
1
+ require 'rubygems'
2
+ require 'rubygems/user_interaction'
3
+
4
+ ##
5
+ # A post-install hook that displays "Successfully installed
6
+ # some_gem-1.0 as a default gem"
7
+
8
+ Gem.post_install do |installer|
9
+ ui = Gem::DefaultUserInteraction.ui
10
+ ui.say "Successfully installed #{installer.spec.full_name} as a default gem"
11
+ end
12
+
@@ -26,6 +26,9 @@ module Gem::InstallUpdateOptions
26
26
  OptionParser.accept Gem::Security::Policy do |value|
27
27
  require 'rubygems/security'
28
28
 
29
+ raise OptionParser::InvalidArgument, 'OpenSSL not installed' unless
30
+ defined?(Gem::Security::HighSecurity)
31
+
29
32
  value = Gem::Security::Policies[value]
30
33
  valid = Gem::Security::Policies.keys.sort
31
34
  message = "#{value} (#{valid.join ', '} are valid)"
@@ -9,7 +9,6 @@ require 'rubygems/package'
9
9
  require 'rubygems/ext'
10
10
  require 'rubygems/user_interaction'
11
11
  require 'fileutils'
12
- require 'thread'
13
12
 
14
13
  ##
15
14
  # The installer installs the files contained in the .gem into the Gem.home.
@@ -32,14 +31,6 @@ class Gem::Installer
32
31
 
33
32
  ENV_PATHS = %w[/usr/bin/env /bin/env]
34
33
 
35
- ##
36
- # The builder shells-out to run various commands after changing the
37
- # directory. This means multiple installations cannot be allowed to build
38
- # extensions in parallel as they may change each other's directories leading
39
- # to broken extensions or failed installations.
40
-
41
- CHDIR_MUTEX = Mutex.new # :nodoc:
42
-
43
34
  ##
44
35
  # Raised when there is an error while building extensions.
45
36
  #
@@ -93,8 +84,8 @@ class Gem::Installer
93
84
  # :env_shebang:: Use /usr/bin/env in bin wrappers.
94
85
  # :force:: Overrides all version checks and security policy checks, except
95
86
  # for a signed-gems-only policy.
96
- # :format_executable:: Format the executable the same as the ruby executable.
97
- # If your ruby is ruby18, foo_exec will be installed as
87
+ # :format_executable:: Format the executable the same as the Ruby executable.
88
+ # If your Ruby is ruby18, foo_exec will be installed as
98
89
  # foo_exec18.
99
90
  # :ignore_dependencies:: Don't raise if a dependency is missing.
100
91
  # :install_dir:: The directory to install the gem into.
@@ -153,7 +144,7 @@ class Gem::Installer
153
144
  io.gets # blankline
154
145
 
155
146
  # TODO detect a specially formatted comment instead of trying
156
- # to run a regexp against ruby code.
147
+ # to run a regexp against Ruby code.
157
148
  next unless io.gets =~ /This file was generated by RubyGems/
158
149
 
159
150
  ruby_executable = true
@@ -222,15 +213,20 @@ class Gem::Installer
222
213
 
223
214
  FileUtils.mkdir_p gem_dir
224
215
 
225
- extract_files
216
+ if @options[:install_as_default]
217
+ extract_bin
218
+ write_default_spec
219
+ else
220
+ extract_files
226
221
 
227
- build_extensions
228
- write_build_info_file
229
- run_post_build_hooks
222
+ build_extensions
223
+ write_build_info_file
224
+ run_post_build_hooks
230
225
 
231
- generate_bin
232
- write_spec
233
- write_cache_file
226
+ generate_bin
227
+ write_spec
228
+ write_cache_file
229
+ end
234
230
 
235
231
  say spec.post_install_message unless spec.post_install_message.nil?
236
232
 
@@ -335,6 +331,14 @@ class Gem::Installer
335
331
  File.join gem_home, "specifications", "#{spec.full_name}.gemspec"
336
332
  end
337
333
 
334
+ ##
335
+ # The location of of the default spec file for default gems.
336
+ #
337
+
338
+ def default_spec_file
339
+ File.join gem_home, "specifications/default", "#{spec.full_name}.gemspec"
340
+ end
341
+
338
342
  ##
339
343
  # Writes the .gemspec specification (in Ruby) to the gem home's
340
344
  # specifications directory.
@@ -346,6 +350,16 @@ class Gem::Installer
346
350
  end
347
351
  end
348
352
 
353
+ ##
354
+ # Writes the full .gemspec specification (in Ruby) to the gem home's
355
+ # specifications/default directory.
356
+
357
+ def write_default_spec
358
+ File.open(default_spec_file, "w") do |file|
359
+ file.puts spec.to_ruby
360
+ end
361
+ end
362
+
349
363
  ##
350
364
  # Creates windows .bat files for easy running of commands
351
365
 
@@ -547,13 +561,13 @@ class Gem::Installer
547
561
  :bin_dir => nil,
548
562
  :env_shebang => false,
549
563
  :force => false,
550
- :install_dir => Gem.dir,
551
564
  :only_install_dir => false
552
565
  }.merge options
553
566
 
554
567
  @env_shebang = options[:env_shebang]
555
568
  @force = options[:force]
556
- @gem_home = options[:install_dir]
569
+ @install_dir = options[:install_dir]
570
+ @gem_home = options[:install_dir] || Gem.dir
557
571
  @ignore_dependencies = options[:ignore_dependencies]
558
572
  @format_executable = options[:format_executable]
559
573
  @security_policy = options[:security_policy]
@@ -628,7 +642,7 @@ TEXT
628
642
  end
629
643
 
630
644
  ##
631
- # return the stub script text used to launch the true ruby script
645
+ # return the stub script text used to launch the true Ruby script
632
646
 
633
647
  def windows_stub_script(bindir, bin_file_name)
634
648
  ruby = File.basename(Gem.ruby).chomp('"')
@@ -684,13 +698,11 @@ TEXT
684
698
  begin
685
699
  FileUtils.mkdir_p dest_path
686
700
 
687
- CHDIR_MUTEX.synchronize do
688
- Dir.chdir extension_dir do
689
- results = builder.build(extension, gem_dir, dest_path,
690
- results, @build_args)
701
+ Dir.chdir extension_dir do
702
+ results = builder.build(extension, gem_dir, dest_path,
703
+ results, @build_args)
691
704
 
692
- say results.join("\n") if Gem.configuration.really_verbose
693
- end
705
+ say results.join("\n") if Gem.configuration.really_verbose
694
706
  end
695
707
  rescue
696
708
  extension_build_error(extension_dir, results.join("\n"), $@)
@@ -727,6 +739,15 @@ EOF
727
739
  @package.extract_files gem_dir
728
740
  end
729
741
 
742
+ ##
743
+ # Extracts only the bin/ files from the gem into the gem directory.
744
+ # This is used by default gems to allow a gem-aware stub to function
745
+ # without the full gem installed.
746
+
747
+ def extract_bin
748
+ @package.extract_files gem_dir, "bin/*"
749
+ end
750
+
730
751
  ##
731
752
  # Prefix and suffix the program filename the same as ruby.
732
753
 
@@ -750,7 +771,7 @@ EOF
750
771
 
751
772
  ##
752
773
  # Performs various checks before installing the gem such as the install
753
- # repository is writable and its directories exist, required ruby and
774
+ # repository is writable and its directories exist, required Ruby and
754
775
  # rubygems versions are met and that dependencies are installed.
755
776
  #
756
777
  # Version and dependency checks are skipped if this install is forced.
@@ -767,7 +788,11 @@ EOF
767
788
 
768
789
  ensure_loadable_spec
769
790
 
770
- Gem.ensure_gem_subdirectories gem_home
791
+ if options[:install_as_default]
792
+ Gem.ensure_default_gem_subdirectories gem_home
793
+ else
794
+ Gem.ensure_gem_subdirectories gem_home
795
+ end
771
796
 
772
797
  return true if @force
773
798
 
@@ -42,6 +42,20 @@ class Gem::NameTuple
42
42
  new nil, Gem::Version.new(0), nil
43
43
  end
44
44
 
45
+ ##
46
+ # Returns the full name (name-version) of this Gem. Platform information is
47
+ # included if it is not the default Ruby platform. This mimics the behavior
48
+ # of Gem::Specification#full_name.
49
+
50
+ def full_name
51
+ case @platform
52
+ when nil, 'ruby', ''
53
+ "#{@name}-#{@version}"
54
+ else
55
+ "#{@name}-#{@version}-#{@platform}"
56
+ end
57
+ end
58
+
45
59
  ##
46
60
  # Indicate if this NameTuple matches the current platform.
47
61
 
@@ -59,12 +73,7 @@ class Gem::NameTuple
59
73
  # Return the name that the gemspec file would be
60
74
 
61
75
  def spec_name
62
- case @platform
63
- when nil, 'ruby', ''
64
- "#{@name}-#{@version}.gemspec"
65
- else
66
- "#{@name}-#{@version}-#{@platform}.gemspec"
67
- end
76
+ "#{full_name}.gemspec"
68
77
  end
69
78
 
70
79
  ##
@@ -74,10 +83,12 @@ class Gem::NameTuple
74
83
  [@name, @version, @platform]
75
84
  end
76
85
 
77
- def to_s
86
+ def inspect # :nodoc:
78
87
  "#<Gem::NameTuple #{@name}, #{@version}, #{@platform}>"
79
88
  end
80
89
 
90
+ alias to_s inspect # :nodoc:
91
+
81
92
  def <=> other
82
93
  to_a <=> other.to_a
83
94
  end
@@ -37,7 +37,7 @@
37
37
  # the_gem.spec # get the spec out of the gem
38
38
  # the_gem.verify # check the gem is OK (contains valid gem specification, contains a not corrupt contents archive)
39
39
  #
40
- # #files are the files in the .gem tar file, not the ruby files in the gem
40
+ # #files are the files in the .gem tar file, not the Ruby files in the gem
41
41
  # #extract_files and #contents automatically call #verify
42
42
 
43
43
  require 'rubygems/security'
@@ -280,11 +280,16 @@ EOM
280
280
  algorithms = if @checksums then
281
281
  @checksums.keys
282
282
  else
283
- [Gem::Security::DIGEST_NAME]
283
+ [Gem::Security::DIGEST_NAME].compact
284
284
  end
285
285
 
286
286
  algorithms.each do |algorithm|
287
- digester = OpenSSL::Digest.new algorithm
287
+ digester =
288
+ if defined?(OpenSSL::Digest) then
289
+ OpenSSL::Digest.new algorithm
290
+ else
291
+ Digest.const_get(algorithm).new
292
+ end
288
293
 
289
294
  digester << entry.read(16384) until entry.eof?
290
295
 
@@ -298,8 +303,11 @@ EOM
298
303
 
299
304
  ##
300
305
  # Extracts the files in this package into +destination_dir+
306
+ #
307
+ # If +pattern+ is specified, only entries matching that glob will be
308
+ # extracted.
301
309
 
302
- def extract_files destination_dir
310
+ def extract_files destination_dir, pattern = "*"
303
311
  verify unless @spec
304
312
 
305
313
  FileUtils.mkdir_p destination_dir
@@ -310,7 +318,7 @@ EOM
310
318
  reader.each do |entry|
311
319
  next unless entry.full_name == 'data.tar.gz'
312
320
 
313
- extract_tar_gz entry, destination_dir
321
+ extract_tar_gz entry, destination_dir, pattern
314
322
 
315
323
  return # ignore further entries
316
324
  end
@@ -324,10 +332,15 @@ EOM
324
332
  # If an entry in the archive contains a relative path above
325
333
  # +destination_dir+ or an absolute path is encountered an exception is
326
334
  # raised.
335
+ #
336
+ # If +pattern+ is specified, only entries matching that glob will be
337
+ # extracted.
327
338
 
328
- def extract_tar_gz io, destination_dir # :nodoc:
339
+ def extract_tar_gz io, destination_dir, pattern = "*" # :nodoc:
329
340
  open_tar_gz io do |tar|
330
341
  tar.each do |entry|
342
+ next unless File.fnmatch pattern, entry.full_name
343
+
331
344
  destination = install_location entry.full_name, destination_dir
332
345
 
333
346
  FileUtils.rm_rf destination
@@ -428,12 +441,13 @@ EOM
428
441
  # certificate and key are not present only checksum generation is set up.
429
442
 
430
443
  def setup_signer
444
+ passphrase = ENV['GEM_PRIVATE_KEY_PASSPHRASE']
431
445
  if @spec.signing_key then
432
- @signer = Gem::Security::Signer.new @spec.signing_key, @spec.cert_chain
446
+ @signer = Gem::Security::Signer.new @spec.signing_key, @spec.cert_chain, passphrase
433
447
  @spec.signing_key = nil
434
448
  @spec.cert_chain = @signer.cert_chain.map { |cert| cert.to_s }
435
449
  else
436
- @signer = Gem::Security::Signer.new nil, nil
450
+ @signer = Gem::Security::Signer.new nil, nil, passphrase
437
451
  @spec.cert_chain = @signer.cert_chain.map { |cert| cert.to_pem } if
438
452
  @signer.cert_chain
439
453
  end
@@ -509,28 +523,39 @@ EOM
509
523
  end
510
524
  end
511
525
 
526
+ ##
527
+ # Verifies +entry+ in a .gem file.
528
+
529
+ def verify_entry entry
530
+ file_name = entry.full_name
531
+ @files << file_name
532
+
533
+ case file_name
534
+ when /\.sig$/ then
535
+ @signatures[$`] = entry.read if @security_policy
536
+ return
537
+ else
538
+ digest entry
539
+ end
540
+
541
+ case file_name
542
+ when /^metadata(.gz)?$/ then
543
+ load_spec entry
544
+ when 'data.tar.gz' then
545
+ verify_gz entry
546
+ end
547
+ rescue => e
548
+ message = "package is corrupt, exception while verifying: " +
549
+ "#{e.message} (#{e.class})"
550
+ raise Gem::Package::FormatError.new message, @gem
551
+ end
552
+
512
553
  ##
513
554
  # Verifies the files of the +gem+
514
555
 
515
556
  def verify_files gem
516
557
  gem.each do |entry|
517
- file_name = entry.full_name
518
- @files << file_name
519
-
520
- case file_name
521
- when /\.sig$/ then
522
- @signatures[$`] = entry.read if @security_policy
523
- next
524
- else
525
- digest entry
526
- end
527
-
528
- case file_name
529
- when /^metadata(.gz)?$/ then
530
- load_spec entry
531
- when 'data.tar.gz' then
532
- verify_gz entry
533
- end
558
+ verify_entry entry
534
559
  end
535
560
 
536
561
  unless @spec then
@@ -71,7 +71,7 @@ class Gem::Package::TarTestCase < Gem::TestCase
71
71
  SP(Z(to_oct(sum, 6)))
72
72
  end
73
73
 
74
- def header(type, fname, dname, length, mode, checksum = nil)
74
+ def header(type, fname, dname, length, mode, mtime, checksum = nil)
75
75
  checksum ||= " " * 8
76
76
 
77
77
  arr = [ # struct tarfile_entry_posix
@@ -80,7 +80,7 @@ class Gem::Package::TarTestCase < Gem::TestCase
80
80
  Z(to_oct(0, 7)), # char uid[8]; ditto
81
81
  Z(to_oct(0, 7)), # char gid[8]; ditto
82
82
  Z(to_oct(length, 11)), # char size[12]; 0 padded, octal, null
83
- Z(to_oct(0, 11)), # char mtime[12]; 0 padded, octal, null
83
+ Z(to_oct(mtime, 11)), # char mtime[12]; 0 padded, octal, null
84
84
  checksum, # char checksum[8]; 0 padded, octal, null, space
85
85
  type, # char typeflag[1]; file: "0" dir: "5"
86
86
  "\0" * 100, # char linkname[100]; ASCII + (Z unless filled)
@@ -105,16 +105,16 @@ class Gem::Package::TarTestCase < Gem::TestCase
105
105
  ret
106
106
  end
107
107
 
108
- def tar_dir_header(name, prefix, mode)
109
- h = header("5", name, prefix, 0, mode)
108
+ def tar_dir_header(name, prefix, mode, mtime)
109
+ h = header("5", name, prefix, 0, mode, mtime)
110
110
  checksum = calc_checksum(h)
111
- header("5", name, prefix, 0, mode, checksum)
111
+ header("5", name, prefix, 0, mode, mtime, checksum)
112
112
  end
113
113
 
114
- def tar_file_header(fname, dname, mode, length)
115
- h = header("0", fname, dname, length, mode)
114
+ def tar_file_header(fname, dname, mode, length, mtime)
115
+ h = header("0", fname, dname, length, mode, mtime)
116
116
  checksum = calc_checksum(h)
117
- header("0", fname, dname, length, mode, checksum)
117
+ header("0", fname, dname, length, mode, mtime, checksum)
118
118
  end
119
119
 
120
120
  def to_oct(n, pad_size)
@@ -130,7 +130,7 @@ class Gem::Package::TarTestCase < Gem::TestCase
130
130
  end
131
131
 
132
132
  def util_dir_entry
133
- util_entry tar_dir_header("foo", "bar", 0)
133
+ util_entry tar_dir_header("foo", "bar", 0, Time.now)
134
134
  end
135
135
 
136
136
  end
@@ -4,6 +4,8 @@
4
4
  # See LICENSE.txt for additional licensing information.
5
5
  #++
6
6
 
7
+ require 'digest'
8
+
7
9
  ##
8
10
  # Allows writing of tar files
9
11
 
@@ -121,7 +123,8 @@ class Gem::Package::TarWriter
121
123
  @io.pos = init_pos
122
124
 
123
125
  header = Gem::Package::TarHeader.new :name => name, :mode => mode,
124
- :size => size, :prefix => prefix
126
+ :size => size, :prefix => prefix,
127
+ :mtime => Time.now
125
128
 
126
129
  @io.write header
127
130
  @io.pos = final_pos
@@ -140,7 +143,15 @@ class Gem::Package::TarWriter
140
143
  def add_file_digest name, mode, digest_algorithms # :yields: io
141
144
  digests = digest_algorithms.map do |digest_algorithm|
142
145
  digest = digest_algorithm.new
143
- [digest.name, digest]
146
+ digest_name =
147
+ if digest.respond_to? :name then
148
+ digest.name
149
+ else
150
+ /::([^:]+)$/ =~ digest_algorithm.name
151
+ $1
152
+ end
153
+
154
+ [digest_name, digest]
144
155
  end
145
156
 
146
157
  digests = Hash[*digests.flatten]
@@ -165,22 +176,32 @@ class Gem::Package::TarWriter
165
176
  def add_file_signed name, mode, signer
166
177
  digest_algorithms = [
167
178
  signer.digest_algorithm,
168
- OpenSSL::Digest::SHA512,
169
- ].uniq
179
+ Digest::SHA512,
180
+ ].compact.uniq
170
181
 
171
182
  digests = add_file_digest name, mode, digest_algorithms do |io|
172
183
  yield io
173
184
  end
174
185
 
175
- signature_digest = digests.values.find do |digest|
176
- digest.name == signer.digest_name
186
+ signature_digest = digests.values.compact.find do |digest|
187
+ digest_name =
188
+ if digest.respond_to? :name then
189
+ digest.name
190
+ else
191
+ /::([^:]+)$/ =~ digest.class.name
192
+ $1
193
+ end
194
+
195
+ digest_name == signer.digest_name
177
196
  end
178
197
 
179
- signature = signer.sign signature_digest.digest
198
+ if signer.key then
199
+ signature = signer.sign signature_digest.digest
180
200
 
181
- add_file_simple "#{name}.sig", 0444, signature.length do |io|
182
- io.write signature
183
- end if signature
201
+ add_file_simple "#{name}.sig", 0444, signature.length do |io|
202
+ io.write signature
203
+ end
204
+ end
184
205
 
185
206
  digests
186
207
  end
@@ -195,7 +216,8 @@ class Gem::Package::TarWriter
195
216
  name, prefix = split_name name
196
217
 
197
218
  header = Gem::Package::TarHeader.new(:name => name, :mode => mode,
198
- :size => size, :prefix => prefix).to_s
219
+ :size => size, :prefix => prefix,
220
+ :mtime => Time.now).to_s
199
221
 
200
222
  @io.write header
201
223
  os = BoundedStream.new @io, size
@@ -256,7 +278,8 @@ class Gem::Package::TarWriter
256
278
 
257
279
  header = Gem::Package::TarHeader.new :name => name, :mode => mode,
258
280
  :typeflag => "5", :size => 0,
259
- :prefix => prefix
281
+ :prefix => prefix,
282
+ :mtime => Time.now
260
283
 
261
284
  @io.write header
262
285