Permalink
Browse files

Unbreak gem specification loading if specification file encoding is n…

…ot compatible with Encoding.default_internal

The :encoding option only specifies the external encoding.  If
Encoding.default_internal is set, it will automatically convert
it to the internal encoding.  If it cannot be converted (e.g.
internal encoding is US-ASCII and specification file contains
8-bit characters), an error is raised.

Instead, the :mode option should be given specifying that the
file should be left in its external encoding without converting
it to the default internal encoding.  This allows you to load
gem specification files with 8-bit characters and a default
internal encoding of US-ASCII.
  • Loading branch information...
1 parent 69416b7 commit 930aaf4c21eb85e7de0866c95238535d47864a4e @jeremyevans jeremyevans committed Aug 2, 2011
Showing with 24 additions and 1 deletion.
  1. +1 −1 lib/rubygems/specification.rb
  2. +23 −0 test/rubygems/test_gem_specification.rb
@@ -900,7 +900,7 @@ def self.load file
return unless File.file?(file)
code = if defined? Encoding
- File.read file, :encoding => "UTF-8"
+ File.read file, :mode => 'r:UTF-8:-'
else
File.read file
end
@@ -308,6 +308,29 @@ def test_self_load_escape_quote
assert_equal @a2, spec
end
+ if defined?(Encoding)
+ def test_self_load_utf8_with_ascii_encoding
+ int_enc = Encoding.default_internal
+ Encoding.default_internal = 'US-ASCII'
+
+ spec2 = @a2.dup
+ bin = "\u5678"
+ spec2.authors = [bin]
+ full_path = spec2.spec_file
+ write_file full_path do |io|
+ io.write spec2.to_ruby_for_cache.force_encoding('BINARY').sub("\\u{5678}", bin.force_encoding('BINARY'))
+ end
+
+ spec = Gem::Specification.load full_path
+
+ spec2.files.clear
+
+ assert_equal spec2, spec
+ ensure
+ Encoding.default_internal = int_enc
+ end
+ end
+
def test_self_load_legacy_ruby
spec = Gem::Deprecate.skip_during do
eval LEGACY_RUBY_SPEC

0 comments on commit 930aaf4

Please sign in to comment.