From: josh.nw@... Date: 2018-01-23T02:50:06+00:00 Subject: [ruby-core:84972] [Ruby trunk Bug#14384] CompatibilityError is thrown when formatting a non-ASCII string with a binary string argument 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
' from tcp.rb:4:in `
' ~~~ 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: �������������������z���X���g�����s�����������������B ~~~ 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: