Project

General

Profile

Actions

Bug #12989

closed

Passing `binmode: true` to `IO.pipe` makes `binmode?` return `true` but encoding is not binary

Added by tenderlovemaking (Aaron Patterson) over 7 years ago. Updated over 4 years ago.

Status:
Closed
Target version:
-
ruby -v:
ruby 2.4.0dev (2016-11-16 gc-compact 56805) [x86_64-darwin16]
[ruby-core:78404]

Description

Here is a sample program:

Encoding.default_external = Encoding::UTF_8
Encoding.default_internal = Encoding::UTF_8

reader, writer = IO.pipe(binmode: true)
reader.binmode?           # => true
reader.external_encoding  # => #<Encoding:UTF-8>
writer.binmode?           # => true
writer.external_encoding  # => #<Encoding:UTF-8>

reader, writer = IO.pipe
reader.binmode
writer.binmode

reader.binmode?           # => true
reader.external_encoding  # => #<Encoding:ASCII-8BIT>
writer.binmode?           # => true
writer.external_encoding  # => #<Encoding:ASCII-8BIT>

I think that passing binmode: true to IO.pipe should behave the same way as calling binmode on each file. Today, passing binmode: true to IO.pipe puts the files in a strange state: they are binary and not binary.

I've attached a patch to fix the problem.


Files

0001-Passing-binmode-true-to-IO.pipe-should-behave-like-b.patch (2.5 KB) 0001-Passing-binmode-true-to-IO.pipe-should-behave-like-b.patch tenderlovemaking (Aaron Patterson), 11/28/2016 10:31 PM
io-pipe-binmode.patch (2.87 KB) io-pipe-binmode.patch jeremyevans0 (Jeremy Evans), 07/25/2019 08:50 PM

Updated by nobu (Nobuyoshi Nakada) over 7 years ago

  • Description updated (diff)

Encoding argument should be prior to binmode option.

open(IO::NULL, "r", binmode: true){|f| p [f.binmode?, f.external_encoding]} #=> [true, #<Encoding:ASCII-8BIT>]
open(IO::NULL, "r:utf-8", binmode: true){|f| p [f.binmode?, f.external_encoding]} #=> [true, #<Encoding:UTF-8>]

Your patch always makes external_encoding ASCII-8BIT when binmode is set, even if an encoding is given.

Updated by jeremyevans0 (Jeremy Evans) over 4 years ago

nobu (Nobuyoshi Nakada) wrote:

Encoding argument should be prior to binmode option.

open(IO::NULL, "r", binmode: true){|f| p [f.binmode?, f.external_encoding]} #=> [true, #<Encoding:ASCII-8BIT>]
open(IO::NULL, "r:utf-8", binmode: true){|f| p [f.binmode?, f.external_encoding]} #=> [true, #<Encoding:UTF-8>]

Your patch always makes external_encoding ASCII-8BIT when binmode is set, even if an encoding is given.

Here's an updated patch based on tenderlove's original patch that does not change the encoding of the returned IO objects if encoding arguments are given in addition to the binmode option. Is this acceptable?

Updated by ko1 (Koichi Sasada) over 4 years ago

  • Status changed from Open to Assigned
  • Assignee set to nobu (Nobuyoshi Nakada)

Updated by nobu (Nobuyoshi Nakada) over 4 years ago

jeremyevans0 (Jeremy Evans) wrote:

Here's an updated patch based on tenderlove's original patch that does not change the encoding of the returned IO objects if encoding arguments are given in addition to the binmode option. Is this acceptable?

I think so.
In general, dedicated assertion methods e.g.,assert_predicate would be preferable to mere assert, I think.

Actions #5

Updated by jeremyevans (Jeremy Evans) over 4 years ago

  • Status changed from Assigned to Closed

Applied in changeset git|ebc99e026d0ae770b297a93d1f1c1ceeffd13bfc.


Do not change IO.pipe encodings if encodings explicitly given

This commit makes it so that if the binmode option is given with
any encoding arguments, the reader and writer IO objects are
not set to binary encoding.

Fixes [Bug #12989]

Actions

Also available in: Atom PDF

Like0
Like0Like0Like0Like0Like0