You are viewing a plain text version of this content. The canonical link for it is here.
Posted to derby-commits@db.apache.org by my...@apache.org on 2010/08/11 18:59:48 UTC
svn commit: r984472 - in /db/derby/code/trunk/java:
client/org/apache/derby/client/am/ engine/org/apache/derby/impl/jdbc/
testing/org/apache/derbyTesting/functionTests/tests/jdbcapi/
Author: myrnavl
Date: Wed Aug 11 16:59:47 2010
New Revision: 984472
URL: http://svn.apache.org/viewvc?rev=984472&view=rev
Log:
DERBY-3898; Blob.setBytes differs between embedded and client driver when the specified length is invalid;
patch contributed by Yun Lee (yun dot lee dot bj at gmail dot com)
Added:
db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/jdbcapi/BlobSetBytesBoundaryTest.java (with props)
Modified:
db/derby/code/trunk/java/client/org/apache/derby/client/am/Blob.java
db/derby/code/trunk/java/engine/org/apache/derby/impl/jdbc/EmbedBlob.java
db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/jdbcapi/_Suite.java
Modified: db/derby/code/trunk/java/client/org/apache/derby/client/am/Blob.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/client/org/apache/derby/client/am/Blob.java?rev=984472&r1=984471&r2=984472&view=diff
==============================================================================
--- db/derby/code/trunk/java/client/org/apache/derby/client/am/Blob.java (original)
+++ db/derby/code/trunk/java/client/org/apache/derby/client/am/Blob.java Wed Aug 11 16:59:47 2010
@@ -469,6 +469,11 @@ public class Blob extends Lob implements
if (len == 0) {
return 0;
}
+ if (len + offset > bytes.length) {
+ throw new SqlException(agent_.logWriter_,
+ new ClientMessageId(SQLState.BLOB_LENGTH_TOO_LONG),
+ new Integer(len));
+ }
final int length = Math.min((bytes.length - offset), len);
Modified: db/derby/code/trunk/java/engine/org/apache/derby/impl/jdbc/EmbedBlob.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/impl/jdbc/EmbedBlob.java?rev=984472&r1=984471&r2=984472&view=diff
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/impl/jdbc/EmbedBlob.java (original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/impl/jdbc/EmbedBlob.java Wed Aug 11 16:59:47 2010
@@ -879,31 +879,46 @@ final class EmbedBlob extends Connection
int offset,
int len) throws SQLException {
checkValidity();
+
+ if (pos - 1 > length())
+ throw Util.generateCsSQLException(SQLState.BLOB_POSITION_TOO_LARGE,
+ new Long(pos));
+ if (pos < 1)
+ throw Util.generateCsSQLException(SQLState.BLOB_BAD_POSITION,
+ new Long(pos));
+
+ if ((offset < 0) || offset > bytes.length) {
+ throw Util.generateCsSQLException(SQLState.BLOB_INVALID_OFFSET,
+ new Long(offset));
+ }
+ if (len < 0) {
+ throw Util.generateCsSQLException(SQLState.BLOB_NONPOSITIVE_LENGTH,
+ new Long(len));
+ }
+ if (len == 0) {
+ return 0;
+ }
+ if (len + offset > bytes.length) {
+ throw Util.generateCsSQLException(SQLState.BLOB_LENGTH_TOO_LONG,
+ new Long(len));
+ }
+
try {
if (materialized) {
- if (pos - 1 > length())
- throw Util.generateCsSQLException(
- SQLState.BLOB_POSITION_TOO_LARGE, new Long(pos));
- if (pos < 1)
- throw Util.generateCsSQLException(
- SQLState.BLOB_BAD_POSITION, new Long(pos));
- control.write (bytes, offset, len, pos - 1);
- }
- else {
- control = new LOBStreamControl (getEmbedConnection());
- control.copyData (myStream, length());
+ control.write(bytes, offset, len, pos - 1);
+ } else {
+ control = new LOBStreamControl(getEmbedConnection());
+ control.copyData(myStream, length());
control.write(bytes, offset, len, pos - 1);
myStream.close();
streamLength = -1;
materialized = true;
}
return len;
- }
- catch (IOException e) {
- throw Util.setStreamFailure (e);
- }
- catch (StandardException se) {
- throw Util.generateCsSQLException (se);
+ } catch (IOException e) {
+ throw Util.setStreamFailure(e);
+ } catch (StandardException se) {
+ throw Util.generateCsSQLException(se);
}
}
Added: db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/jdbcapi/BlobSetBytesBoundaryTest.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/jdbcapi/BlobSetBytesBoundaryTest.java?rev=984472&view=auto
==============================================================================
--- db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/jdbcapi/BlobSetBytesBoundaryTest.java (added)
+++ db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/jdbcapi/BlobSetBytesBoundaryTest.java Wed Aug 11 16:59:47 2010
@@ -0,0 +1,244 @@
+/*
+
+ Derby - Class BlobSetBytesBoundaryTest
+
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to you under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+
+ */
+
+package org.apache.derbyTesting.functionTests.tests.jdbcapi;
+
+import java.sql.Blob;
+import java.sql.Connection;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.sql.Statement;
+
+import junit.framework.Test;
+
+import org.apache.derbyTesting.junit.BaseJDBCTestCase;
+import org.apache.derbyTesting.junit.CleanDatabaseTestSetup;
+import org.apache.derbyTesting.junit.TestConfiguration;
+
+
+/**
+ * Boundary tests for Blob.setBytes(). see DERBY-3898.
+ *
+ */
+public class BlobSetBytesBoundaryTest extends BaseJDBCTestCase {
+
+ private static final byte[] BOLB_CONTENT = "test".getBytes();;
+
+ public BlobSetBytesBoundaryTest(String name) {
+ super(name);
+ }
+
+ public static Test suite() {
+ Test suite = TestConfiguration.defaultSuite(
+ BlobSetBytesBoundaryTest.class, false);
+
+ return new CleanDatabaseTestSetup(suite) {
+ protected void decorateSQL(Statement stmt)
+ throws SQLException {
+ initializeBlobData(stmt);
+ }
+ };
+ }
+
+ public void testSetBytesWithTooLongLength() throws SQLException {
+ Statement stmt = getConnection().createStatement();
+ ResultSet rs = stmt.executeQuery(
+ "select dBlob, length from BlobTable");
+ rs.next();
+ Blob blob = rs.getBlob(1);
+
+ try {
+ blob.setBytes(1, new byte[] {0x69}, 0, 2);
+ fail("Wrong long length is not accepted!");
+ } catch (SQLException sqle) {
+ assertSQLState("XJ079", sqle);
+ }
+
+ stmt.close();
+ }
+
+ public void testSetBytesByBadLengthAndOffset() throws SQLException {
+ Statement stmt = getConnection().createStatement();
+ ResultSet rs = stmt.executeQuery(
+ "select dBlob, length from BlobTable");
+ rs.next();
+ Blob blob = rs.getBlob(1);
+
+ try {
+ //length adding offset will be bigger than the length of the byte array.
+ blob.setBytes(1, new byte[] {0x69, 0x4e, 0x47, 0x55}, 1, 4);
+ fail("Wrong offset and length is not accepted!");
+ } catch (SQLException sqle) {
+ assertSQLState("XJ079", sqle);
+ }
+
+ stmt.close();
+ }
+
+ public void testSetBytesWithZeroLength() throws SQLException {
+ Statement stmt = getConnection().createStatement();
+ ResultSet rs = stmt.executeQuery(
+ "select dBlob, length from BlobTable");
+ rs.next();
+ Blob blob = rs.getBlob(1);
+
+ int actualLength = blob.setBytes(1, new byte[] {0x69}, 0, 0);
+ assertEquals("return zero for zero length", 0, actualLength);
+
+ stmt.close();
+ }
+
+ public void testSetBytesWithNonPositiveLength() throws SQLException {
+ Statement stmt = getConnection().createStatement();
+ ResultSet rs = stmt.executeQuery(
+ "select dBlob, length from BlobTable");
+ rs.next();
+ Blob blob = rs.getBlob(1);
+
+ try{
+ blob.setBytes(1, new byte[] {0x69}, 0, -1);
+ fail("Nonpositive Length is not sccepted!");
+ } catch (SQLException sqle) {
+ assertSQLState("XJ071", sqle);
+ }
+
+ stmt.close();
+ }
+
+ public void testSetBytesWithInvalidOffset() throws SQLException {
+ Statement stmt = getConnection().createStatement();
+ ResultSet rs = stmt.executeQuery(
+ "select dBlob, length from BlobTable");
+ rs.next();
+ Blob blob = rs.getBlob(1);
+
+ try {
+ blob.setBytes(1, new byte[] {0xb}, -1, 1);
+ fail("Invalid offset Length is not sccepted!");
+ } catch (SQLException sqle) {
+ assertSQLState("XJ078", sqle);
+ }
+
+ try {
+ blob.setBytes(1, new byte[] {0xb}, 2, 1);
+ fail("Invalid offset Length is not sccepted!");
+ } catch (SQLException sqle) {
+ assertSQLState("XJ078", sqle);
+ }
+
+ try {
+ blob.setBytes(1, new byte[] {0xb, 0xe}, Integer.MAX_VALUE, 1);
+ fail("Invalid offset Length is not sccepted!");
+ } catch (SQLException sqle) {
+ assertSQLState("XJ078", sqle);
+ }
+
+ stmt.close();
+ }
+
+ public void testSetBytesWithEmptyBytes() throws SQLException {
+ Statement stmt = getConnection().createStatement();
+ ResultSet rs = stmt.executeQuery(
+ "select dBlob, length from BlobTable");
+ rs.next();
+ Blob blob = rs.getBlob(1);
+
+ assertEquals(0, blob.setBytes(1, new byte[0]));
+
+ stmt.close();
+ }
+
+ public void testSetBytesWithTooBigPos() throws SQLException {
+ Statement stmt = getConnection().createStatement();
+ ResultSet rs = stmt.executeQuery(
+ "select dBlob, length from BlobTable");
+ rs.next();
+ Blob blob = rs.getBlob(1);
+
+ try {
+ blob.setBytes(Integer.MAX_VALUE, new byte[] {0xf});
+ fail("Too big position is not sccepted!");
+ } catch (SQLException sqle) {
+ assertSQLState("XJ076", sqle);
+ }
+
+ try {
+ blob.setBytes(BOLB_CONTENT.length + 2, new byte[] {0xf});
+ fail("Too big position is not sccepted!");
+ } catch (SQLException sqle) {
+ assertSQLState("XJ076", sqle);
+ }
+
+ stmt.close();
+ }
+
+ public void testSetBytesWithNonpositivePos() throws SQLException {
+ Statement stmt = getConnection().createStatement();
+ ResultSet rs = stmt.executeQuery(
+ "select dBlob, length from BlobTable");
+ rs.next();
+ Blob blob = rs.getBlob(1);
+
+ try {
+ blob.setBytes(0, new byte[] {0xf});
+ fail("Nonpositive position is not sccepted!");
+ } catch (SQLException sqle) {
+ assertSQLState("XJ070", sqle);
+ }
+
+ try {
+ blob.setBytes(-1, new byte[] {0xf});
+ fail("Nonpositive position is not sccepted!");
+ } catch (SQLException sqle) {
+ assertSQLState("XJ070", sqle);
+ }
+
+ stmt.close();
+ }
+
+ /**
+ * Generates test data.
+ */
+ private static void initializeBlobData(Statement stmt)
+ throws SQLException {
+ Connection con = stmt.getConnection();
+ con.setAutoCommit(false);
+
+ try {
+ stmt.executeUpdate("drop table BlobTable");
+ } catch (SQLException sqle) {
+ assertSQLState("42Y55", sqle);
+ }
+
+ stmt.executeUpdate("create table BlobTable (dBlob Blob, length int)");
+
+ PreparedStatement smallBlobInsert = con
+ .prepareStatement("insert into BlobTable values (?,?)");
+ // Insert just one record.
+
+ smallBlobInsert.setBytes(1, BOLB_CONTENT );
+ smallBlobInsert.setInt(2, BOLB_CONTENT.length);
+ smallBlobInsert.executeUpdate();
+
+ con.commit();
+ }
+}
Propchange: db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/jdbcapi/BlobSetBytesBoundaryTest.java
------------------------------------------------------------------------------
svn:eol-style = native
Modified: db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/jdbcapi/_Suite.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/jdbcapi/_Suite.java?rev=984472&r1=984471&r2=984472&view=diff
==============================================================================
--- db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/jdbcapi/_Suite.java (original)
+++ db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/jdbcapi/_Suite.java Wed Aug 11 16:59:47 2010
@@ -163,6 +163,7 @@ public class _Suite extends BaseTestCase
// XA and ConnectionPool Datasource are not available with
// JSR169 so can't run InternationalConnectTest.
suite.addTest(InternationalConnectTest.suite());
+ suite.addTest(BlobSetBytesBoundaryTest.suite());
}
return suite;