Issue #14384 has been reported by joshc (Josh C).

----------------------------------------
Bug #14384: CompatibilityError is thrown when formatting a non-ASCII string with a binary string argument
https://bugs.ruby-lang.org/issues/14384

* Author: joshc (Josh C)
* Status: Open
* Priority: Normal
* Assignee: 
* Target version: 
* ruby -v: ruby 2.3.3p222 (2016-11-21 revision 56859) [x64-mingw32]
* Backport: 2.3: UNKNOWN, 2.4: UNKNOWN, 2.5: UNKNOWN
----------------------------------------
The following script:

~~~
# coding: utf-8
require 'socket'
begin
  TCPSocket.open('nowhere', 80)
rescue => e
  puts "証明書をリクエストできませんでした: %s" % e.message
end
~~~

Produces an error on Windows instead of printing message:

~~~
PS C:\work\puppet> ruby tcp.rb
tcp.rb:7:in `%': incompatible character encodings: UTF-8 and ASCII-8BIT (Encoding::CompatibilityError)
        from tcp.rb:7:in `rescue in <main>'
        from tcp.rb:4:in `<main>'
~~~

The SocketError's exception message is a binary string (ASCII_8BIT). The exception message comes from the `rb_w32_strerror` method which uses `FormatMessage` instead of `FormatMessageW`.

The following works around the issue:

~~~
puts "証明書をリクエストできませんでした: %s".encode(Encoding.default_external) % e.message.force_encoding(Encoding.default_external)
~~~

The exception is not raised if the format string consists of ASCII only, e.g. `puts "Connection failed: %s" % e.message`, however, the output is not formatted correctly:

~~~
PS C:\work\puppet> ruby tcp.rb
Connection failed: getaddrinfo: zXgsB
~~~

Changing that to:

~~~
puts "Connection failed: %s" % e.message.force_encoding(Encoding.default_external)
~~~

Does correctly output the message:

~~~
PS C:\work\puppet> ruby tcp.rb
Connection failed: getaddrinfo: そのようなホストは不明です。
~~~

So the issue is a combination of the encoding of the format and argument strings.

My environment:

~~~
PS C:\work\puppet> gem env
RubyGems Environment:
  - RUBYGEMS VERSION: 2.5.2
  - RUBY VERSION: 2.3.3 (2016-11-21 patchlevel 222) [x64-mingw32]
  - INSTALLATION DIRECTORY: C:/Ruby23-x64/lib/ruby/gems/2.3.0
  - USER INSTALLATION DIRECTORY: C:/Users/Administrator/.gem/ruby/2.3.0
  - RUBY EXECUTABLE: C:/Ruby23-x64/bin/ruby.exe
  - EXECUTABLE DIRECTORY: C:/Ruby23-x64/bin
  - SPEC CACHE DIRECTORY: C:/Users/Administrator/.gem/specs
  - SYSTEM CONFIGURATION DIRECTORY: C:/ProgramData
  - RUBYGEMS PLATFORMS:
    - ruby
    - x64-mingw32
  - GEM PATHS:
     - C:/Ruby23-x64/lib/ruby/gems/2.3.0
     - C:/Users/Administrator/.gem/ruby/2.3.0
  - GEM CONFIGURATION:
     - :update_sources => true
     - :verbose => true
     - :backtrace => false
     - :bulk_threshold => 1000
  - REMOTE SOURCES:
     - https://rubygems.org/
  - SHELL PATH:
     - C:\Ruby23-x64\bin
     - C:\Windows\system32
     - C:\Windows
     - C:\Windows\System32\Wbem
     - C:\Windows\System32\WindowsPowerShell\v1.0\
     - C:\Program Files\Git\cmd
     - C:\Packer\SysInternals
PS C:\work\puppet>
PS C:\work\puppet> ruby --version
ruby 2.3.3p222 (2016-11-21 revision 56859) [x64-mingw32]
PS C:\work\puppet> gem --version
2.5.2
~~~



-- 
https://bugs.ruby-lang.org/

Unsubscribe: <mailto:ruby-core-request / ruby-lang.org?subject=unsubscribe>
<http://lists.ruby-lang.org/cgi-bin/mailman/options/ruby-core>