Fix CRLF -> LF conversion on read for rb_io_fdopen & rb_file_open

When opening a file with `File.open`, and then setting the encoding with
`IO#set_encoding`, it still correctly performs CRLF -> LF conversion on
Windows when reading files with a CRLF line ending in them (in text
mode).

However, the file is opened instead with either the `rb_io_fdopen` or
`rb_file_open` APIs from C, the CRLF conversion is _NOT_ set up
correctly; it works if the encoding is not specified, but if
`IO#set_encoding` is called, the conversion stops happening. This seems
to be because the encflags never get ECONV_DEFAULT_NEWLINE_DECORATOR
set in these codepaths.

Concretely, this means that the conversion doesn't happen in the
following circumstances:
  * When loading ruby files with require (that calls rb_io_fdopen)
  * When parsing ruuby files with RubyVM::AbstractSyntaxTree (that calls
    rb_file_open).
This then causes the ErrorHighlight tests to fail on windows if git has
checked them out with CRLF line endings - the error messages it's
testing wind up with literal \r\n sequences in them because the iseq
text from the parser contains un-newline-converted strings.

This commit fixes the problem by copy-pasting the relevant snippet which
sets this up in `rb_io_extract_modeenc` (for the File.open path) into
the relevant codepaths for `rb_io_fdopen` and `rb_file_open`.

[Bug #20101]
This commit is contained in:
KJ Tsanaktsidis 2023-12-28 16:08:54 +11:00
parent c4051d5f43
commit 31371b2e24
4 changed files with 518 additions and 5 deletions

View File

@ -329,6 +329,177 @@ init.o: $(hdrdir)/ruby/ruby.h
init.o: $(hdrdir)/ruby/st.h
init.o: $(hdrdir)/ruby/subst.h
init.o: init.c
newline_conv.o: $(RUBY_EXTCONF_H)
newline_conv.o: $(arch_hdrdir)/ruby/config.h
newline_conv.o: $(hdrdir)/ruby/assert.h
newline_conv.o: $(hdrdir)/ruby/backward.h
newline_conv.o: $(hdrdir)/ruby/backward/2/assume.h
newline_conv.o: $(hdrdir)/ruby/backward/2/attributes.h
newline_conv.o: $(hdrdir)/ruby/backward/2/bool.h
newline_conv.o: $(hdrdir)/ruby/backward/2/inttypes.h
newline_conv.o: $(hdrdir)/ruby/backward/2/limits.h
newline_conv.o: $(hdrdir)/ruby/backward/2/long_long.h
newline_conv.o: $(hdrdir)/ruby/backward/2/stdalign.h
newline_conv.o: $(hdrdir)/ruby/backward/2/stdarg.h
newline_conv.o: $(hdrdir)/ruby/defines.h
newline_conv.o: $(hdrdir)/ruby/encoding.h
newline_conv.o: $(hdrdir)/ruby/intern.h
newline_conv.o: $(hdrdir)/ruby/internal/abi.h
newline_conv.o: $(hdrdir)/ruby/internal/anyargs.h
newline_conv.o: $(hdrdir)/ruby/internal/arithmetic.h
newline_conv.o: $(hdrdir)/ruby/internal/arithmetic/char.h
newline_conv.o: $(hdrdir)/ruby/internal/arithmetic/double.h
newline_conv.o: $(hdrdir)/ruby/internal/arithmetic/fixnum.h
newline_conv.o: $(hdrdir)/ruby/internal/arithmetic/gid_t.h
newline_conv.o: $(hdrdir)/ruby/internal/arithmetic/int.h
newline_conv.o: $(hdrdir)/ruby/internal/arithmetic/intptr_t.h
newline_conv.o: $(hdrdir)/ruby/internal/arithmetic/long.h
newline_conv.o: $(hdrdir)/ruby/internal/arithmetic/long_long.h
newline_conv.o: $(hdrdir)/ruby/internal/arithmetic/mode_t.h
newline_conv.o: $(hdrdir)/ruby/internal/arithmetic/off_t.h
newline_conv.o: $(hdrdir)/ruby/internal/arithmetic/pid_t.h
newline_conv.o: $(hdrdir)/ruby/internal/arithmetic/short.h
newline_conv.o: $(hdrdir)/ruby/internal/arithmetic/size_t.h
newline_conv.o: $(hdrdir)/ruby/internal/arithmetic/st_data_t.h
newline_conv.o: $(hdrdir)/ruby/internal/arithmetic/uid_t.h
newline_conv.o: $(hdrdir)/ruby/internal/assume.h
newline_conv.o: $(hdrdir)/ruby/internal/attr/alloc_size.h
newline_conv.o: $(hdrdir)/ruby/internal/attr/artificial.h
newline_conv.o: $(hdrdir)/ruby/internal/attr/cold.h
newline_conv.o: $(hdrdir)/ruby/internal/attr/const.h
newline_conv.o: $(hdrdir)/ruby/internal/attr/constexpr.h
newline_conv.o: $(hdrdir)/ruby/internal/attr/deprecated.h
newline_conv.o: $(hdrdir)/ruby/internal/attr/diagnose_if.h
newline_conv.o: $(hdrdir)/ruby/internal/attr/enum_extensibility.h
newline_conv.o: $(hdrdir)/ruby/internal/attr/error.h
newline_conv.o: $(hdrdir)/ruby/internal/attr/flag_enum.h
newline_conv.o: $(hdrdir)/ruby/internal/attr/forceinline.h
newline_conv.o: $(hdrdir)/ruby/internal/attr/format.h
newline_conv.o: $(hdrdir)/ruby/internal/attr/maybe_unused.h
newline_conv.o: $(hdrdir)/ruby/internal/attr/noalias.h
newline_conv.o: $(hdrdir)/ruby/internal/attr/nodiscard.h
newline_conv.o: $(hdrdir)/ruby/internal/attr/noexcept.h
newline_conv.o: $(hdrdir)/ruby/internal/attr/noinline.h
newline_conv.o: $(hdrdir)/ruby/internal/attr/nonnull.h
newline_conv.o: $(hdrdir)/ruby/internal/attr/noreturn.h
newline_conv.o: $(hdrdir)/ruby/internal/attr/packed_struct.h
newline_conv.o: $(hdrdir)/ruby/internal/attr/pure.h
newline_conv.o: $(hdrdir)/ruby/internal/attr/restrict.h
newline_conv.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
newline_conv.o: $(hdrdir)/ruby/internal/attr/warning.h
newline_conv.o: $(hdrdir)/ruby/internal/attr/weakref.h
newline_conv.o: $(hdrdir)/ruby/internal/cast.h
newline_conv.o: $(hdrdir)/ruby/internal/compiler_is.h
newline_conv.o: $(hdrdir)/ruby/internal/compiler_is/apple.h
newline_conv.o: $(hdrdir)/ruby/internal/compiler_is/clang.h
newline_conv.o: $(hdrdir)/ruby/internal/compiler_is/gcc.h
newline_conv.o: $(hdrdir)/ruby/internal/compiler_is/intel.h
newline_conv.o: $(hdrdir)/ruby/internal/compiler_is/msvc.h
newline_conv.o: $(hdrdir)/ruby/internal/compiler_is/sunpro.h
newline_conv.o: $(hdrdir)/ruby/internal/compiler_since.h
newline_conv.o: $(hdrdir)/ruby/internal/config.h
newline_conv.o: $(hdrdir)/ruby/internal/constant_p.h
newline_conv.o: $(hdrdir)/ruby/internal/core.h
newline_conv.o: $(hdrdir)/ruby/internal/core/rarray.h
newline_conv.o: $(hdrdir)/ruby/internal/core/rbasic.h
newline_conv.o: $(hdrdir)/ruby/internal/core/rbignum.h
newline_conv.o: $(hdrdir)/ruby/internal/core/rclass.h
newline_conv.o: $(hdrdir)/ruby/internal/core/rdata.h
newline_conv.o: $(hdrdir)/ruby/internal/core/rfile.h
newline_conv.o: $(hdrdir)/ruby/internal/core/rhash.h
newline_conv.o: $(hdrdir)/ruby/internal/core/robject.h
newline_conv.o: $(hdrdir)/ruby/internal/core/rregexp.h
newline_conv.o: $(hdrdir)/ruby/internal/core/rstring.h
newline_conv.o: $(hdrdir)/ruby/internal/core/rstruct.h
newline_conv.o: $(hdrdir)/ruby/internal/core/rtypeddata.h
newline_conv.o: $(hdrdir)/ruby/internal/ctype.h
newline_conv.o: $(hdrdir)/ruby/internal/dllexport.h
newline_conv.o: $(hdrdir)/ruby/internal/dosish.h
newline_conv.o: $(hdrdir)/ruby/internal/encoding/coderange.h
newline_conv.o: $(hdrdir)/ruby/internal/encoding/ctype.h
newline_conv.o: $(hdrdir)/ruby/internal/encoding/encoding.h
newline_conv.o: $(hdrdir)/ruby/internal/encoding/pathname.h
newline_conv.o: $(hdrdir)/ruby/internal/encoding/re.h
newline_conv.o: $(hdrdir)/ruby/internal/encoding/sprintf.h
newline_conv.o: $(hdrdir)/ruby/internal/encoding/string.h
newline_conv.o: $(hdrdir)/ruby/internal/encoding/symbol.h
newline_conv.o: $(hdrdir)/ruby/internal/encoding/transcode.h
newline_conv.o: $(hdrdir)/ruby/internal/error.h
newline_conv.o: $(hdrdir)/ruby/internal/eval.h
newline_conv.o: $(hdrdir)/ruby/internal/event.h
newline_conv.o: $(hdrdir)/ruby/internal/fl_type.h
newline_conv.o: $(hdrdir)/ruby/internal/gc.h
newline_conv.o: $(hdrdir)/ruby/internal/glob.h
newline_conv.o: $(hdrdir)/ruby/internal/globals.h
newline_conv.o: $(hdrdir)/ruby/internal/has/attribute.h
newline_conv.o: $(hdrdir)/ruby/internal/has/builtin.h
newline_conv.o: $(hdrdir)/ruby/internal/has/c_attribute.h
newline_conv.o: $(hdrdir)/ruby/internal/has/cpp_attribute.h
newline_conv.o: $(hdrdir)/ruby/internal/has/declspec_attribute.h
newline_conv.o: $(hdrdir)/ruby/internal/has/extension.h
newline_conv.o: $(hdrdir)/ruby/internal/has/feature.h
newline_conv.o: $(hdrdir)/ruby/internal/has/warning.h
newline_conv.o: $(hdrdir)/ruby/internal/intern/array.h
newline_conv.o: $(hdrdir)/ruby/internal/intern/bignum.h
newline_conv.o: $(hdrdir)/ruby/internal/intern/class.h
newline_conv.o: $(hdrdir)/ruby/internal/intern/compar.h
newline_conv.o: $(hdrdir)/ruby/internal/intern/complex.h
newline_conv.o: $(hdrdir)/ruby/internal/intern/cont.h
newline_conv.o: $(hdrdir)/ruby/internal/intern/dir.h
newline_conv.o: $(hdrdir)/ruby/internal/intern/enum.h
newline_conv.o: $(hdrdir)/ruby/internal/intern/enumerator.h
newline_conv.o: $(hdrdir)/ruby/internal/intern/error.h
newline_conv.o: $(hdrdir)/ruby/internal/intern/eval.h
newline_conv.o: $(hdrdir)/ruby/internal/intern/file.h
newline_conv.o: $(hdrdir)/ruby/internal/intern/hash.h
newline_conv.o: $(hdrdir)/ruby/internal/intern/io.h
newline_conv.o: $(hdrdir)/ruby/internal/intern/load.h
newline_conv.o: $(hdrdir)/ruby/internal/intern/marshal.h
newline_conv.o: $(hdrdir)/ruby/internal/intern/numeric.h
newline_conv.o: $(hdrdir)/ruby/internal/intern/object.h
newline_conv.o: $(hdrdir)/ruby/internal/intern/parse.h
newline_conv.o: $(hdrdir)/ruby/internal/intern/proc.h
newline_conv.o: $(hdrdir)/ruby/internal/intern/process.h
newline_conv.o: $(hdrdir)/ruby/internal/intern/random.h
newline_conv.o: $(hdrdir)/ruby/internal/intern/range.h
newline_conv.o: $(hdrdir)/ruby/internal/intern/rational.h
newline_conv.o: $(hdrdir)/ruby/internal/intern/re.h
newline_conv.o: $(hdrdir)/ruby/internal/intern/ruby.h
newline_conv.o: $(hdrdir)/ruby/internal/intern/select.h
newline_conv.o: $(hdrdir)/ruby/internal/intern/select/largesize.h
newline_conv.o: $(hdrdir)/ruby/internal/intern/signal.h
newline_conv.o: $(hdrdir)/ruby/internal/intern/sprintf.h
newline_conv.o: $(hdrdir)/ruby/internal/intern/string.h
newline_conv.o: $(hdrdir)/ruby/internal/intern/struct.h
newline_conv.o: $(hdrdir)/ruby/internal/intern/thread.h
newline_conv.o: $(hdrdir)/ruby/internal/intern/time.h
newline_conv.o: $(hdrdir)/ruby/internal/intern/variable.h
newline_conv.o: $(hdrdir)/ruby/internal/intern/vm.h
newline_conv.o: $(hdrdir)/ruby/internal/interpreter.h
newline_conv.o: $(hdrdir)/ruby/internal/iterator.h
newline_conv.o: $(hdrdir)/ruby/internal/memory.h
newline_conv.o: $(hdrdir)/ruby/internal/method.h
newline_conv.o: $(hdrdir)/ruby/internal/module.h
newline_conv.o: $(hdrdir)/ruby/internal/newobj.h
newline_conv.o: $(hdrdir)/ruby/internal/scan_args.h
newline_conv.o: $(hdrdir)/ruby/internal/special_consts.h
newline_conv.o: $(hdrdir)/ruby/internal/static_assert.h
newline_conv.o: $(hdrdir)/ruby/internal/stdalign.h
newline_conv.o: $(hdrdir)/ruby/internal/stdbool.h
newline_conv.o: $(hdrdir)/ruby/internal/symbol.h
newline_conv.o: $(hdrdir)/ruby/internal/value.h
newline_conv.o: $(hdrdir)/ruby/internal/value_type.h
newline_conv.o: $(hdrdir)/ruby/internal/variable.h
newline_conv.o: $(hdrdir)/ruby/internal/warning_push.h
newline_conv.o: $(hdrdir)/ruby/internal/xmalloc.h
newline_conv.o: $(hdrdir)/ruby/io.h
newline_conv.o: $(hdrdir)/ruby/missing.h
newline_conv.o: $(hdrdir)/ruby/onigmo.h
newline_conv.o: $(hdrdir)/ruby/oniguruma.h
newline_conv.o: $(hdrdir)/ruby/ruby.h
newline_conv.o: $(hdrdir)/ruby/st.h
newline_conv.o: $(hdrdir)/ruby/subst.h
newline_conv.o: newline_conv.c
stat.o: $(RUBY_EXTCONF_H)
stat.o: $(arch_hdrdir)/ruby/config.h
stat.o: $(hdrdir)/ruby/assert.h

View File

@ -0,0 +1,73 @@
#include "ruby/ruby.h"
#include "ruby/io.h"
#include <fcntl.h>
static VALUE
open_with_rb_file_open(VALUE self, VALUE filename, VALUE read_or_write, VALUE binary_or_text)
{
char fmode[3] = { 0 };
if (rb_sym2id(read_or_write) == rb_intern("read")) {
fmode[0] = 'r';
}
else if (rb_sym2id(read_or_write) == rb_intern("write")) {
fmode[0] = 'w';
}
else {
rb_raise(rb_eArgError, "read_or_write param must be :read or :write");
}
if (rb_sym2id(binary_or_text) == rb_intern("binary")) {
fmode[1] = 'b';
}
else if (rb_sym2id(binary_or_text) == rb_intern("text")) {
}
else {
rb_raise(rb_eArgError, "binary_or_text param must be :binary or :text");
}
return rb_file_open(StringValueCStr(filename), fmode);
}
static VALUE
open_with_rb_io_fdopen(VALUE self, VALUE filename, VALUE read_or_write, VALUE binary_or_text)
{
int omode = 0;
if (rb_sym2id(read_or_write) == rb_intern("read")) {
omode |= O_RDONLY;
}
else if (rb_sym2id(read_or_write) == rb_intern("write")) {
omode |= O_WRONLY;
}
else {
rb_raise(rb_eArgError, "read_or_write param must be :read or :write");
}
if (rb_sym2id(binary_or_text) == rb_intern("binary")) {
#ifdef O_BINARY
omode |= O_BINARY;
#endif
}
else if (rb_sym2id(binary_or_text) == rb_intern("text")) {
}
else {
rb_raise(rb_eArgError, "binary_or_text param must be :binary or :text");
}
int fd = rb_cloexec_open(StringValueCStr(filename), omode, 0);
if (fd < 0) {
rb_raise(rb_eIOError, "failed to open the file");
}
rb_update_max_fd(fd);
return rb_io_fdopen(fd, omode, StringValueCStr(filename));
}
void
Init_newline_conv(VALUE module)
{
VALUE newline_conv = rb_define_module_under(module, "NewlineConv");
rb_define_module_function(newline_conv, "rb_file_open", open_with_rb_file_open, 3);
rb_define_module_function(newline_conv, "rb_io_fdopen", open_with_rb_io_fdopen, 3);
}

33
io.c
View File

@ -7166,8 +7166,6 @@ rb_file_open_internal(VALUE io, VALUE filename, const char *modestr)
if (p) {
parse_mode_enc(p+1, rb_usascii_encoding(),
&convconfig.enc, &convconfig.enc2, &fmode);
convconfig.ecflags = 0;
convconfig.ecopts = Qnil;
}
else {
rb_encoding *e;
@ -7175,10 +7173,19 @@ rb_file_open_internal(VALUE io, VALUE filename, const char *modestr)
e = (fmode & FMODE_BINMODE) ? rb_ascii8bit_encoding() : NULL;
rb_io_ext_int_to_encs(e, NULL, &convconfig.enc, &convconfig.enc2, fmode);
convconfig.ecflags = 0;
convconfig.ecopts = Qnil;
}
convconfig.ecflags = (fmode & FMODE_READABLE) ?
MODE_BTMODE(ECONV_DEFAULT_NEWLINE_DECORATOR,
0, ECONV_UNIVERSAL_NEWLINE_DECORATOR) : 0;
#ifdef TEXTMODE_NEWLINE_DECORATOR_ON_WRITE
convconfig.ecflags |= (fmode & FMODE_WRITABLE) ?
MODE_BTMODE(TEXTMODE_NEWLINE_DECORATOR_ON_WRITE,
0, TEXTMODE_NEWLINE_DECORATOR_ON_WRITE) : 0;
#endif
SET_UNIVERSAL_NEWLINE_DECORATOR_IF_ENC2(convconfig.enc2, convconfig.ecflags);
convconfig.ecopts = Qnil;
return rb_file_open_generic(io, filename,
rb_io_fmode_oflags(fmode),
fmode,
@ -9241,11 +9248,27 @@ static VALUE
prep_io(int fd, int fmode, VALUE klass, const char *path)
{
VALUE path_value = Qnil;
rb_encoding *e;
struct rb_io_encoding convconfig;
if (path) {
path_value = rb_obj_freeze(rb_str_new_cstr(path));
}
VALUE self = rb_io_open_descriptor(klass, fd, fmode, path_value, Qnil, NULL);
e = (fmode & FMODE_BINMODE) ? rb_ascii8bit_encoding() : NULL;
rb_io_ext_int_to_encs(e, NULL, &convconfig.enc, &convconfig.enc2, fmode);
convconfig.ecflags = (fmode & FMODE_READABLE) ?
MODE_BTMODE(ECONV_DEFAULT_NEWLINE_DECORATOR,
0, ECONV_UNIVERSAL_NEWLINE_DECORATOR) : 0;
#ifdef TEXTMODE_NEWLINE_DECORATOR_ON_WRITE
convconfig.ecflags |= (fmode & FMODE_WRITABLE) ?
MODE_BTMODE(TEXTMODE_NEWLINE_DECORATOR_ON_WRITE,
0, TEXTMODE_NEWLINE_DECORATOR_ON_WRITE) : 0;
#endif
SET_UNIVERSAL_NEWLINE_DECORATOR_IF_ENC2(convconfig.enc2, convconfig.ecflags);
convconfig.ecopts = Qnil;
VALUE self = rb_io_open_descriptor(klass, fd, fmode, path_value, Qnil, &convconfig);
rb_io_t*io = RFILE(self)->fptr;
if (!io_check_tty(io)) {

View File

@ -554,4 +554,250 @@ class TestFile < Test::Unit::TestCase
assert_file.absolute_path?("/foo/bar\\baz")
end
end
class NewlineConvTests < Test::Unit::TestCase
TEST_STRING_WITH_CRLF = "line1\r\nline2\r\n".freeze
TEST_STRING_WITH_LF = "line1\nline2\n".freeze
def setup
@tmpdir = Dir.mktmpdir(self.class.name)
@read_path_with_crlf = File.join(@tmpdir, "read_path_with_crlf")
File.binwrite(@read_path_with_crlf, TEST_STRING_WITH_CRLF)
@read_path_with_lf = File.join(@tmpdir, "read_path_with_lf")
File.binwrite(@read_path_with_lf, TEST_STRING_WITH_LF)
@write_path = File.join(@tmpdir, "write_path")
File.binwrite(@write_path, '')
end
def teardown
FileUtils.rm_rf @tmpdir
end
def windows?
/cygwin|mswin|mingw/ =~ RUBY_PLATFORM
end
def open_file_with(method, filename, mode)
read_or_write = mode.include?('w') ? :write : :read
binary_or_text = mode.include?('b') ? :binary : :text
f = case method
when :ruby_file_open
File.open(filename, mode)
when :c_rb_file_open
Bug::File::NewlineConv.rb_file_open(filename, read_or_write, binary_or_text)
when :c_rb_io_fdopen
Bug::File::NewlineConv.rb_io_fdopen(filename, read_or_write, binary_or_text)
else
raise "Don't know how to open with #{method}"
end
begin
yield f
ensure
f.close
end
end
def assert_file_contents_has_lf(f)
assert_equal TEST_STRING_WITH_LF, f.read
end
def assert_file_contents_has_crlf(f)
assert_equal TEST_STRING_WITH_CRLF, f.read
end
def assert_file_contents_has_lf_on_windows(f)
if windows?
assert_file_contents_has_lf(f)
else
assert_file_contents_has_crlf(f)
end
end
def assert_file_contents_has_crlf_on_windows(f)
if windows?
assert_file_contents_has_crlf(f)
else
assert_file_contents_has_lf(f)
end
end
def test_ruby_file_open_text_mode_read_crlf
open_file_with(:ruby_file_open, @read_path_with_crlf, 'r') { |f| assert_file_contents_has_lf_on_windows(f) }
end
def test_ruby_file_open_bin_mode_read_crlf
open_file_with(:ruby_file_open, @read_path_with_crlf, 'rb') { |f| assert_file_contents_has_crlf(f) }
end
def test_ruby_file_open_text_mode_read_lf
open_file_with(:ruby_file_open, @read_path_with_lf, 'r') { |f| assert_file_contents_has_lf(f) }
end
def test_ruby_file_open_bin_mode_read_lf
open_file_with(:ruby_file_open, @read_path_with_lf, 'rb') { |f| assert_file_contents_has_lf(f) }
end
def test_ruby_file_open_text_mode_read_crlf_with_utf8_encoding
open_file_with(:ruby_file_open, @read_path_with_crlf, 'r') do |f|
f.set_encoding Encoding::UTF_8, '-'
assert_file_contents_has_lf_on_windows(f)
end
end
def test_ruby_file_open_bin_mode_read_crlf_with_utf8_encoding
open_file_with(:ruby_file_open, @read_path_with_crlf, 'rb') do |f|
f.set_encoding Encoding::UTF_8, '-'
assert_file_contents_has_crlf(f)
end
end
def test_ruby_file_open_text_mode_read_lf_with_utf8_encoding
open_file_with(:ruby_file_open, @read_path_with_lf, 'r') do |f|
f.set_encoding Encoding::UTF_8, '-'
assert_file_contents_has_lf(f)
end
end
def test_ruby_file_open_bin_mode_read_lf_with_utf8_encoding
open_file_with(:ruby_file_open, @read_path_with_lf, 'rb') do |f|
f.set_encoding Encoding::UTF_8, '-'
assert_file_contents_has_lf(f)
end
end
def test_ruby_file_open_text_mode_write_lf
open_file_with(:ruby_file_open, @write_path, 'w') { |f| f.write TEST_STRING_WITH_LF }
File.open(@write_path, 'rb') { |f| assert_file_contents_has_crlf_on_windows(f) }
end
def test_ruby_file_open_bin_mode_write_lf
open_file_with(:ruby_file_open, @write_path, 'wb') { |f| f.write TEST_STRING_WITH_LF }
File.open(@write_path, 'rb') { |f| assert_file_contents_has_lf(f) }
end
def test_ruby_file_open_bin_mode_write_crlf
open_file_with(:ruby_file_open, @write_path, 'wb') { |f| f.write TEST_STRING_WITH_CRLF }
File.open(@write_path, 'rb') { |f| assert_file_contents_has_crlf(f) }
end
def test_c_rb_file_open_text_mode_read_crlf
open_file_with(:c_rb_file_open, @read_path_with_crlf, 'r') { |f| assert_file_contents_has_lf_on_windows(f) }
end
def test_c_rb_file_open_bin_mode_read_crlf
open_file_with(:c_rb_file_open, @read_path_with_crlf, 'rb') { |f| assert_file_contents_has_crlf(f) }
end
def test_c_rb_file_open_text_mode_read_lf
open_file_with(:c_rb_file_open, @read_path_with_lf, 'r') { |f| assert_file_contents_has_lf(f) }
end
def test_c_rb_file_open_bin_mode_read_lf
open_file_with(:c_rb_file_open, @read_path_with_lf, 'rb') { |f| assert_file_contents_has_lf(f) }
end
def test_c_rb_file_open_text_mode_write_lf
open_file_with(:c_rb_file_open, @write_path, 'w') { |f| f.write TEST_STRING_WITH_LF }
File.open(@write_path, 'rb') { |f| assert_file_contents_has_crlf_on_windows(f) }
end
def test_c_rb_file_open_bin_mode_write_lf
open_file_with(:c_rb_file_open, @write_path, 'wb') { |f| f.write TEST_STRING_WITH_LF }
File.open(@write_path, 'rb') { |f| assert_file_contents_has_lf(f) }
end
def test_c_rb_file_open_bin_mode_write_crlf
open_file_with(:c_rb_file_open, @write_path, 'wb') { |f| f.write TEST_STRING_WITH_CRLF }
File.open(@write_path, 'rb') { |f| assert_file_contents_has_crlf(f) }
end
def test_c_rb_file_open_text_mode_read_crlf_with_utf8_encoding
open_file_with(:c_rb_file_open, @read_path_with_crlf, 'r') do |f|
f.set_encoding Encoding::UTF_8, '-'
assert_file_contents_has_lf_on_windows(f)
end
end
def test_c_rb_file_open_bin_mode_read_crlf_with_utf8_encoding
open_file_with(:c_rb_file_open, @read_path_with_crlf, 'rb') do |f|
f.set_encoding Encoding::UTF_8, '-'
assert_file_contents_has_crlf(f)
end
end
def test_c_rb_file_open_text_mode_read_lf_with_utf8_encoding
open_file_with(:c_rb_file_open, @read_path_with_lf, 'r') do |f|
f.set_encoding Encoding::UTF_8, '-'
assert_file_contents_has_lf(f)
end
end
def test_c_rb_file_open_bin_mode_read_lf_with_utf8_encoding
open_file_with(:c_rb_file_open, @read_path_with_lf, 'rb') do |f|
f.set_encoding Encoding::UTF_8, '-'
assert_file_contents_has_lf(f)
end
end
def test_c_rb_io_fdopen_text_mode_read_crlf
open_file_with(:c_rb_io_fdopen, @read_path_with_crlf, 'r') { |f| assert_file_contents_has_lf_on_windows(f) }
end
def test_c_rb_io_fdopen_bin_mode_read_crlf
open_file_with(:c_rb_io_fdopen, @read_path_with_crlf, 'rb') { |f| assert_file_contents_has_crlf(f) }
end
def test_c_rb_io_fdopen_text_mode_read_lf
open_file_with(:c_rb_io_fdopen, @read_path_with_lf, 'r') { |f| assert_file_contents_has_lf(f) }
end
def test_c_rb_io_fdopen_bin_mode_read_lf
open_file_with(:c_rb_io_fdopen, @read_path_with_lf, 'rb') { |f| assert_file_contents_has_lf(f) }
end
def test_c_rb_io_fdopen_text_mode_write_lf
open_file_with(:c_rb_io_fdopen, @write_path, 'w') { |f| f.write TEST_STRING_WITH_LF }
File.open(@write_path, 'rb') { |f| assert_file_contents_has_crlf_on_windows(f) }
end
def test_c_rb_io_fdopen_bin_mode_write_lf
open_file_with(:c_rb_io_fdopen, @write_path, 'wb') { |f| f.write TEST_STRING_WITH_LF }
File.open(@write_path, 'rb') { |f| assert_file_contents_has_lf(f) }
end
def test_c_rb_io_fdopen_bin_mode_write_crlf
open_file_with(:c_rb_io_fdopen, @write_path, 'wb') { |f| f.write TEST_STRING_WITH_CRLF }
File.open(@write_path, 'rb') { |f| assert_file_contents_has_crlf(f) }
end
def test_c_rb_io_fdopen_text_mode_read_crlf_with_utf8_encoding
open_file_with(:c_rb_io_fdopen, @read_path_with_crlf, 'r') do |f|
f.set_encoding Encoding::UTF_8, '-'
assert_file_contents_has_lf_on_windows(f)
end
end
def test_c_rb_io_fdopen_bin_mode_read_crlf_with_utf8_encoding
open_file_with(:c_rb_io_fdopen, @read_path_with_crlf, 'rb') do |f|
f.set_encoding Encoding::UTF_8, '-'
assert_file_contents_has_crlf(f)
end
end
def test_c_rb_io_fdopen_text_mode_read_lf_with_utf8_encoding
open_file_with(:c_rb_io_fdopen, @read_path_with_lf, 'r') do |f|
f.set_encoding Encoding::UTF_8, '-'
assert_file_contents_has_lf(f)
end
end
def test_c_rb_io_fdopen_bin_mode_read_lf_with_utf8_encoding
open_file_with(:c_rb_io_fdopen, @read_path_with_lf, 'rb') do |f|
f.set_encoding Encoding::UTF_8, '-'
assert_file_contents_has_lf(f)
end
end
end
end