Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 10 additions & 6 deletions ext/java/org/jruby/ext/stringio/StringIO.java
Original file line number Diff line number Diff line change
Expand Up @@ -650,13 +650,17 @@ public IRubyObject each_char(final ThreadContext context, final Block block) {
public IRubyObject eof(ThreadContext context) {
checkReadable();
StringIOData ptr = getPtr();
if (ptr.pos < ptr.string.size()) return context.fals;
if (!isEndOfString()) return context.fals;
return context.tru;
}

private boolean isEndOfString() {
return isOutside(ptr.pos);
}

private boolean isOutside(int pos) {
StringIOData ptr = getPtr();
return ptr.string == null || ptr.pos >= ptr.string.size();
return ptr.string == null || pos >= ptr.string.size();
}

@JRubyMethod(name = "getc")
Expand Down Expand Up @@ -1107,9 +1111,9 @@ private IRubyObject readCommon(ThreadContext context, int argc, IRubyObject arg0
if (len < 0) {
throw runtime.newArgumentError("negative length " + len + " given");
}
if (len > 0 && isEndOfString()) {
if (isEndOfString()) {
if (!str.isNil()) ((RubyString) str).resize(0);
return context.nil;
return len > 0 ? context.nil : runtime.newString();
}
binary = true;
break;
Expand Down Expand Up @@ -1224,8 +1228,7 @@ private RubyString preadCommon(ThreadContext context, int argc, IRubyObject arg0
throw runtime.newErrnoEINVALError("pread: Invalid offset argument");
}

RubyString myString = ptr.string;
if (offset >= myString.size()) {
if (isOutside(offset)) {
throw context.runtime.newEOFError();
}

Expand All @@ -1234,6 +1237,7 @@ private RubyString preadCommon(ThreadContext context, int argc, IRubyObject arg0
}

string = (RubyString) str;
RubyString myString = ptr.string;
int rest = myString.size() - offset;
if (len > rest) len = rest;
string.resize(len);
Expand Down
28 changes: 19 additions & 9 deletions ext/stringio/stringio.c
Original file line number Diff line number Diff line change
Expand Up @@ -203,6 +203,18 @@ check_modifiable(struct StringIO *ptr)
}
}

static inline bool
outside_p(struct StringIO *ptr, long pos)
{
return NIL_P(ptr->string) || pos >= RSTRING_LEN(ptr->string);
}

static inline bool
eos_p(struct StringIO *ptr)
{
return outside_p(ptr, ptr->pos);
}

static VALUE
strio_s_allocate(VALUE klass)
{
Expand Down Expand Up @@ -628,9 +640,8 @@ static struct StringIO *
strio_to_read(VALUE self)
{
struct StringIO *ptr = readable(self);
if (NIL_P(ptr->string)) return NULL;
if (ptr->pos < RSTRING_LEN(ptr->string)) return ptr;
return NULL;
if (eos_p(ptr)) return NULL;
return ptr;
}

/*
Expand Down Expand Up @@ -910,7 +921,7 @@ strio_getc(VALUE self)
int len;
char *p;

if (NIL_P(str) || pos >= RSTRING_LEN(str)) {
if (eos_p(ptr)) {
return Qnil;
}
p = RSTRING_PTR(str)+pos;
Expand All @@ -931,7 +942,7 @@ strio_getbyte(VALUE self)
{
struct StringIO *ptr = readable(self);
int c;
if (NIL_P(ptr->string) || ptr->pos >= RSTRING_LEN(ptr->string)) {
if (eos_p(ptr)) {
return Qnil;
}
c = RSTRING_PTR(ptr->string)[ptr->pos++];
Expand Down Expand Up @@ -1609,10 +1620,9 @@ strio_read(int argc, VALUE *argv, VALUE self)
if (len < 0) {
rb_raise(rb_eArgError, "negative length %ld given", len);
}
if (len > 0 &&
(NIL_P(ptr->string) || ptr->pos >= RSTRING_LEN(ptr->string))) {
if (eos_p(ptr)) {
if (!NIL_P(str)) rb_str_resize(str, 0);
return Qnil;
return len > 0 ? Qnil : rb_str_new(0, 0);
}
binary = 1;
break;
Expand Down Expand Up @@ -1688,7 +1698,7 @@ strio_pread(int argc, VALUE *argv, VALUE self)

struct StringIO *ptr = readable(self);

if (offset >= RSTRING_LEN(ptr->string)) {
if (outside_p(ptr, offset)) {
rb_eof_error();
}

Expand Down
15 changes: 15 additions & 0 deletions test/stringio/test_stringio.rb
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,21 @@ def test_null
assert_nil io.getc
end

def test_pread_eof
io = StringIO.new(nil)
assert_predicate io, :eof?
end

def test_pread_null
io = StringIO.new(nil)
assert_raise(EOFError) { io.pread(1, 0) }
end

def test_read_null
io = StringIO.new(nil)
assert_equal "", io.read(0)
end

def test_seek_null
io = StringIO.new(nil)
assert_equal(0, io.seek(0, IO::SEEK_SET))
Expand Down
Loading