Skip to content

Commit

Permalink
Only treate -1 ret from lseek as error. Fixes #3435.
Browse files Browse the repository at this point in the history
There's a larger bug here, in that our native lseek does not
return a 64-bit value. This results in seeks past the range of a
32-bit int overflowing to negative, which triggered the errors in

See #3817 for remaining work.
headius committed Apr 20, 2016
1 parent 67804b0 commit 623bc59
Showing 3 changed files with 10 additions and 10 deletions.
8 changes: 4 additions & 4 deletions core/src/main/java/org/jruby/RubyIO.java
Original file line number Diff line number Diff line change
@@ -1530,7 +1530,7 @@ public RubyFixnum pos(ThreadContext context) {
boolean locked = fptr.lock();
try {
long pos = fptr.tell(context);
if (pos < 0 && fptr.errno() != null) throw context.runtime.newErrnoFromErrno(fptr.errno(), fptr.getPath());
if (pos == -1 && fptr.errno() != null) throw context.runtime.newErrnoFromErrno(fptr.errno(), fptr.getPath());
pos -= fptr.rbuf.len;
return context.runtime.newFixnum(pos);
} finally {
@@ -1550,7 +1550,7 @@ public RubyFixnum pos_set(ThreadContext context, IRubyObject offset) {
boolean locked = fptr.lock();
try {
pos = fptr.seek(context, pos, PosixShim.SEEK_SET);
if (pos < 0 && fptr.errno() != null) throw context.runtime.newErrnoFromErrno(fptr.errno(), fptr.getPath());
if (pos == -1 && fptr.errno() != null) throw context.runtime.newErrnoFromErrno(fptr.errno(), fptr.getPath());
} finally {
if (locked) fptr.unlock();
}
@@ -1733,7 +1733,7 @@ public RubyFixnum rewind(ThreadContext context) {
fptr = getOpenFileChecked();
boolean locked = fptr.lock();
try {
if (fptr.seek(context, 0L, 0) < 0 && fptr.errno() != null)
if (fptr.seek(context, 0L, 0) == -1 && fptr.errno() != null)
throw context.runtime.newErrnoFromErrno(fptr.errno(), fptr.getPath());
RubyArgsFile.ArgsFileData data = RubyArgsFile.ArgsFileData.getDataFrom(runtime.getArgsFile());
if (this == data.currentFile) {
@@ -1887,7 +1887,7 @@ public IRubyObject initialize_copy(IRubyObject _io){
fd = orig.fd().dup();
fptr.setFD(fd);
pos = orig.tell(context);
if (0 <= pos)
if (pos == -1)
fptr.seek(context, pos, PosixShim.SEEK_SET);
} finally {
if (locked2) fptr.unlock();
10 changes: 5 additions & 5 deletions core/src/main/java/org/jruby/util/io/OpenFile.java
Original file line number Diff line number Diff line change
@@ -99,7 +99,7 @@ public void ascii8bitBinmode(Ruby runtime) {
}

public void checkReopenSeek(ThreadContext context, Ruby runtime, long pos) {
if (seek(context, pos, PosixShim.SEEK_SET) < 0 && errno() != null) {
if (seek(context, pos, PosixShim.SEEK_SET) == -1 && errno() != null) {
throw runtime.newErrnoFromErrno(errno(), getPath());
}
}
@@ -1929,7 +1929,7 @@ private synchronized void unreadUnix(ThreadContext context) {
/* xxx: target position may be negative if buffer is filled by ungetc */
posix.errno = null;
r = posix.lseek(fd, -rbuf.len, PosixShim.SEEK_CUR);
if (r < 0 && posix.errno != null) {
if (r == -1 && posix.errno != null) {
if (posix.errno == Errno.ESPIPE)
mode |= DUPLEX;
return;
@@ -1977,7 +1977,7 @@ private void unreadWindows(ThreadContext context) {
// }

pos = posix.lseek(fd, 0, PosixShim.SEEK_CUR);
if (pos < 0 && posix.errno != null) {
if (pos == -1 && posix.errno != null) {
if (posix.errno == Errno.ESPIPE)
mode |= DUPLEX;
return;
@@ -2003,7 +2003,7 @@ private void unreadWindows(ThreadContext context) {
while (newlines >= 0) {
r = posix.lseek(fd, pos - rbuf.len - newlines, PosixShim.SEEK_SET);
if (newlines == 0) break;
if (r < 0) {
if (r == -1) {
newlines--;
continue;
}
@@ -2632,7 +2632,7 @@ public int remainSize() {
long pos;

if ((size = posix.size(fd)) >= 0 &&
(pos = posix.lseek(fd, 0, PosixShim.SEEK_CUR)) >= 0 &&
(pos = posix.lseek(fd, 0, PosixShim.SEEK_CUR)) != -1 &&
size > pos) {
if (siz + (size - pos) > Integer.MAX_VALUE) {
throw runtime.newIOError("file too big for single read");
2 changes: 1 addition & 1 deletion core/src/main/java/org/jruby/util/io/PosixShim.java
Original file line number Diff line number Diff line change
@@ -67,7 +67,7 @@ public long lseek(ChannelFD fd, long offset, int type) {
} else if (fd.chNative != null) {
// native channel, use native lseek
int ret = posix.lseek(fd.chNative.getFD(), offset, type);
if (ret < 0) errno = Errno.valueOf(posix.errno());
if (ret == -1) errno = Errno.valueOf(posix.errno());
return ret;
}

0 comments on commit 623bc59

Please sign in to comment.