Bug #18955

Updated by andrykonchin (Andrew Konchin) 4 months ago

I haven't found any similar existing issue so decided to create a new one. 

 I noticed that `sprintf("%c", string)` doesn't handle (in an expected way) a case when encodings of format sequence and string argument aren't the same and the string argument contains non-ASCII character. 

 In this case it seems to me that `sprintf` just uses binary representation of a character and assigns (or interprets with) encoding of the format sequence string. 

 I would expect that `sprintf` negotiates encoding and converts everything (the character and the format string) to the chosen one. And raises error when negotiation fails. 

 Examples to illustrate this behavior: 

 format = "%c".encode("Windows-1251") 
 string = "Й".encode(Encoding::KOI8_U) 
 r = sprintf(format, string) 
 # => #<Encoding:Windows-1251> 

 r == "Й".encode("Windows-1251") 
 # => false 

 # => [234] 
 # => [234] 

 In this example the result's encoding is a format's encoding. But codepoint isn't changed and equals a codepoint of the character in the original string's encoding. But it should be different: 

 # => [201] 

 Another example: 

 string = "À".encode(Encoding::CP1252) 
 sprintf("%c", string) 
 # => in `sprintf': invalid byte sequence in UTF-8 (ArgumentError) 

 In this example the error means that `sprintf` doesn't encode properly a codepoint (of string's encoding) in UTF-8. It uses just raw bytes.