db-derby-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From krist...@apache.org
Subject svn commit: r677172 - in /db/derby/code/trunk/java: engine/org/apache/derby/impl/jdbc/PositionedStoreStream.java testing/org/apache/derbyTesting/functionTests/tests/store/PositionedStoreStreamTest.java
Date Wed, 16 Jul 2008 06:44:54 GMT
Author: kristwaa
Date: Tue Jul 15 23:44:54 2008
New Revision: 677172

URL: http://svn.apache.org/viewvc?rev=677172&view=rev
Log:
DERBY-3781: PositionedStoreStream.reposition(pos) with pos greater than length leaves the
stream object in an inconsistent state.
Reset the underlying stream and the position to zero after an unsuccessful positioning attempt
(requestedPos > length).
Patch file: derby-3781-1a-fix_and_test.diff

Modified:
    db/derby/code/trunk/java/engine/org/apache/derby/impl/jdbc/PositionedStoreStream.java
    db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/store/PositionedStoreStreamTest.java

Modified: db/derby/code/trunk/java/engine/org/apache/derby/impl/jdbc/PositionedStoreStream.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/impl/jdbc/PositionedStoreStream.java?rev=677172&r1=677171&r2=677172&view=diff
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/impl/jdbc/PositionedStoreStream.java
(original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/impl/jdbc/PositionedStoreStream.java
Tue Jul 15 23:44:54 2008
@@ -185,22 +185,34 @@
      * stream, which changes the position of it. If a class is dependent on the
      * underlying stream not changing its position, it must call reposition with
      * the position it expects before using the stream again.
+     * <p>
+     * If the repositioning fails because the stream is exhausted, most likely
+     * because of an invalid position specified by the user, the stream is
+     * reset to position zero and the {@code EOFException} is rethrown.
      *
+     * @throws EOFException if the stream is exhausted before the requested
+     *      position is reached
      * @throws IOException if reading from the store stream fails
      * @throws StandardException if resetting the store in stream fails, or
      *      some other exception happens in store
      * @see #getPosition
      */
-    public void reposition(long requestedPos)
+    public void reposition(final long requestedPos)
             throws IOException, StandardException {
+        if (this.pos > requestedPos) {
+            // Reset stream to reposition from start.
+            resetStream();
+        }
         if (this.pos < requestedPos) {
-            // Reposition from current position.
-            skipFully(requestedPos - this.pos);
-            this.pos = requestedPos;
-        } else if (this.pos > requestedPos) {
-            // Reposition from start.
-            this.resettable.resetStream();
-            skipFully(requestedPos);
+            try {
+                skipFully(requestedPos - this.pos);
+            } catch (EOFException eofe) {
+                // A position after the end of the stream was requested.
+                // To recover, and for consistency, reset to position zero.
+                resetStream();
+                throw eofe;
+            }
+            // Operation successful, update position.
             this.pos = requestedPos;
         }
     }

Modified: db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/store/PositionedStoreStreamTest.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/store/PositionedStoreStreamTest.java?rev=677172&r1=677171&r2=677172&view=diff
==============================================================================
--- db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/store/PositionedStoreStreamTest.java
(original)
+++ db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/store/PositionedStoreStreamTest.java
Tue Jul 15 23:44:54 2008
@@ -22,6 +22,7 @@
  */
 package org.apache.derbyTesting.functionTests.tests.store;
 
+import java.io.EOFException;
 import java.io.IOException;
 import java.io.InputStream;
 
@@ -199,6 +200,45 @@
         pss.reposition(0);
     }
 
+    /**
+     * Tests that trying to move past the end of the stream leaves the stream
+     * object in a consistent state, and can be repositioned again after the
+     * failed reposition attempt.
+     * <p>
+     * Issue logged in Jira as DERBY-3781
+     *
+     * @throws IOException if reading the stream fails unexpectedly
+     * @throws StandardException will never happen
+     */
+    public void testDerby3781()
+            throws IOException, StandardException {
+        final long size = 10;
+        InputStream in = new LoopingAlphabetStream(size);
+        PositionedStoreStream pss = new PositionedStoreStream(in);
+        assertEquals("Invalid initial position", 0L, pss.getPosition());
+        pss.reposition(size -1); // Goto end.
+        assertEquals(size -1, pss.getPosition());
+        assertEquals('j', pss.read());
+        assertEquals(size, pss.getPosition());
+        assertEquals(-1, pss.read());
+        // This step is crucial, position must be different than zero when the
+        // first exception below is thrown.
+        pss.reposition(size / 2); // Goto middle.
+        assertEquals(size / 2, pss.getPosition());
+        try {
+            pss.reposition(size *2); // Try to go past end.
+            fail("Should have failed with EOFException");
+        } catch (EOFException eofe) {
+            // Ignore this exception
+        }
+        // Failed here before, because internal state was inconsistent.
+        // Assumed: pos = 5, underlying stream at pos 5, skipped (size -1 - pos)
+        // Actual: pos = 5, underlying stream at pos (size -1)
+        pss.reposition(size -1); // Goto end.
+        assertEquals(size -1, pss.getPosition());
+        assertEquals('j', pss.read());
+    }
+
     public static Test suite() {
         return new TestSuite(
                 PositionedStoreStreamTest.class, "PositionedStoreStreamTest");



Mime
View raw message