提交 0416d329 authored 作者: Evgenij Ryazanov's avatar Evgenij Ryazanov

Pre-read skipped part of LOBs to throw SQL exception with invalid pos value

上级 24bdf676
package org.h2.store;
import java.io.EOFException;
import java.io.FilterInputStream;
import java.io.IOException;
import java.io.InputStream;
public final class RangeInputStream extends FilterInputStream {
private long offset, limit;
private long limit;
public RangeInputStream(InputStream in, long offset, long limit) {
public RangeInputStream(InputStream in, long offset, long limit) throws IOException {
super(in);
this.offset = offset;
this.limit = limit;
}
private void before() throws IOException {
while (offset > 0) {
offset -= in.skip(offset);
long skip = in.skip(offset);
if (skip <= 0) {
int b = read();
if (b < 0)
throw new EOFException();
offset--;
} else {
offset -= skip;
}
}
}
@Override
public int read() throws IOException {
before();
if (limit < 1) {
return -1;
}
......@@ -34,7 +38,6 @@ public final class RangeInputStream extends FilterInputStream {
@Override
public int read(byte b[], int off, int len) throws IOException {
before();
if (len > limit) {
len = (int) limit;
}
......@@ -47,7 +50,6 @@ public final class RangeInputStream extends FilterInputStream {
@Override
public long skip(long n) throws IOException {
before();
if (n > limit) {
n = (int) limit;
}
......@@ -58,7 +60,6 @@ public final class RangeInputStream extends FilterInputStream {
@Override
public int available() throws IOException {
before();
int cnt = in.available();
if (cnt > limit) {
return (int) limit;
......
package org.h2.store;
import java.io.EOFException;
import java.io.IOException;
import java.io.Reader;
public final class RangeReader extends Reader {
private final Reader r;
private long offset, limit;
private long limit;
public RangeReader(Reader r, long offset, long limit) {
public RangeReader(Reader r, long offset, long limit) throws IOException {
this.r = r;
this.offset = offset;
this.limit = limit;
}
private void before() throws IOException {
while (offset > 0) {
offset -= r.skip(offset);
long skip = r.skip(offset);
if (skip <= 0) {
int ch = read();
if (ch < 0)
throw new EOFException();
offset--;
} else {
offset -= skip;
}
}
}
@Override
public int read() throws IOException {
before();
if (limit < 1) {
return -1;
}
......@@ -35,7 +39,6 @@ public final class RangeReader extends Reader {
@Override
public int read(char cbuf[], int off, int len) throws IOException {
before();
if (len > limit) {
len = (int) limit;
}
......@@ -48,7 +51,6 @@ public final class RangeReader extends Reader {
@Override
public long skip(long n) throws IOException {
before();
if (n > limit) {
n = (int) limit;
}
......@@ -59,7 +61,6 @@ public final class RangeReader extends Reader {
@Override
public boolean ready() throws IOException {
before();
if (limit > 0) {
return r.ready();
}
......
......@@ -60,13 +60,21 @@ public class ValueLob extends Value {
}
static InputStream rangeInputStream(InputStream inputStream, long oneBasedOffset, long length) {
rangeCheckUnknown(--oneBasedOffset, length);
return new RangeInputStream(inputStream, /* 0-based */ oneBasedOffset, length);
rangeCheckUnknown(oneBasedOffset, length);
try {
return new RangeInputStream(inputStream, oneBasedOffset - 1, length);
} catch (IOException e) {
throw DbException.getInvalidValueException("offset", oneBasedOffset);
}
}
static Reader rangeReader(Reader reader, long oneBasedOffset, long length) {
rangeCheckUnknown(--oneBasedOffset, length);
return new RangeReader(reader, /* 0-based */ oneBasedOffset, length);
rangeCheckUnknown(oneBasedOffset, length);
try {
return new RangeReader(reader, oneBasedOffset - 1, length);
} catch (IOException e) {
throw DbException.getInvalidValueException("offset", oneBasedOffset);
}
}
/**
......
......@@ -29,6 +29,7 @@ import java.util.concurrent.TimeUnit;
import org.h2.api.ErrorCode;
import org.h2.engine.SysProperties;
import org.h2.jdbc.JdbcConnection;
import org.h2.jdbc.JdbcSQLException;
import org.h2.message.DbException;
import org.h2.store.fs.FileUtils;
import org.h2.test.TestBase;
......@@ -1102,6 +1103,8 @@ public class TestLob extends TestBase {
fail("expected -1 got: " + ch);
}
r.close();
// TODO assertThrows(ErrorCode.INVALID_VALUE_2, clob0).getCharacterStream(10001, 1);
assertThrows(ErrorCode.INVALID_VALUE_2, clob0).getCharacterStream(10002, 0);
conn0.close();
}
......
......@@ -1615,6 +1615,7 @@ public class TestResultSet extends TestBase {
assertEqualsWithNull(new byte[] { (byte) 0x03,
(byte) 0x03 }, readAllBytes(blob.getBinaryStream(2, 2)));
assertTrue(!rs.wasNull());
assertThrows(ErrorCode.INVALID_VALUE_2, blob).getBinaryStream(5, 1);
} finally {
blob.free();
}
......@@ -1632,6 +1633,8 @@ public class TestResultSet extends TestBase {
byte[] got = readAllBytes(blob.getBinaryStream(101, 50002));
assertEqualsWithNull(expected, got);
assertTrue(!rs.wasNull());
// TODO assertThrows(ErrorCode.INVALID_VALUE_2, blob).getBinaryStream(0x10001, 1);
assertThrows(ErrorCode.INVALID_VALUE_2, blob).getBinaryStream(0x10002, 0);
} finally {
blob.free();
}
......@@ -1695,6 +1698,8 @@ public class TestResultSet extends TestBase {
Clob clob = rs.getClob(2);
try {
assertEquals("all", readString(clob.getCharacterStream(2, 3)));
// TODO assertThrows(ErrorCode.INVALID_VALUE_2, clob).getCharacterStream(6, 1);
assertThrows(ErrorCode.INVALID_VALUE_2, clob).getCharacterStream(7, 0);
} finally {
clob.free();
}
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论