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:
parent
c4051d5f43
commit
31371b2e24
@ -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
|
||||
|
73
ext/-test-/file/newline_conv.c
Normal file
73
ext/-test-/file/newline_conv.c
Normal 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
33
io.c
@ -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)) {
|
||||
|
@ -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
|
||||
|
Loading…
x
Reference in New Issue
Block a user