Changeset: 85e657dfa8af for MonetDB
URL: http://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=85e657dfa8af
Modified Files:
        
java/embedded/src/main/java/org/monetdb/embedded/result/EmbeddedQueryResult.java
        java/embedded/src/test/java/org/monetdb/embedded/test/EmbeddedTest.java
Branch: embedded-java
Log Message:

Avoid segfault when accessing cleaned-up resources

Simply check if it cleaned-up and do not allow access. Returns null on column 
get. Can produce NullPointerExceptions, but prevents segfaults and JVM crashes.
Add a unit test of that

While there - minor var cleanup


diffs (106 lines):

diff --git 
a/java/embedded/src/main/java/org/monetdb/embedded/result/EmbeddedQueryResult.java
 
b/java/embedded/src/main/java/org/monetdb/embedded/result/EmbeddedQueryResult.java
--- 
a/java/embedded/src/main/java/org/monetdb/embedded/result/EmbeddedQueryResult.java
+++ 
b/java/embedded/src/main/java/org/monetdb/embedded/result/EmbeddedQueryResult.java
@@ -75,6 +75,11 @@ public class EmbeddedQueryResult impleme
                if (index >= numberOfColumns || index < 0) {
                        return null;
                }
+               if (resultPointer == 0) {
+                       // The object was closed and result was cleaned-up
+                       // Calling the can produce a native Segfault (and crash 
the JVM) 
+                       return null;
+               }
                return getColumnWrapper(resultPointer, index);
        }
 
@@ -133,7 +138,10 @@ public class EmbeddedQueryResult impleme
 
        @Override
        public void close() throws IOException {
-               cleanupResult(resultPointer);
+               if (resultPointer > 0) {
+                       cleanupResult(resultPointer);
+                       resultPointer = 0;
+               }
        }
 
        /** 
diff --git 
a/java/embedded/src/test/java/org/monetdb/embedded/test/EmbeddedTest.java 
b/java/embedded/src/test/java/org/monetdb/embedded/test/EmbeddedTest.java
--- a/java/embedded/src/test/java/org/monetdb/embedded/test/EmbeddedTest.java
+++ b/java/embedded/src/test/java/org/monetdb/embedded/test/EmbeddedTest.java
@@ -16,8 +16,10 @@ import java.nio.file.Files;
 import java.nio.file.Path;
 import java.sql.SQLException;
 import java.util.Iterator;
+import java.util.concurrent.TimeUnit;
 
 import org.junit.BeforeClass;
+import org.junit.Ignore;
 import org.junit.Test;
 import org.monetdb.embedded.MonetDBEmbedded;
 import org.monetdb.embedded.result.EmbeddedQueryResult;
@@ -49,11 +51,12 @@ public class EmbeddedTest {
        };
 
        @BeforeClass
-       public static void createTestDB() throws IOException, SQLException {
+       public static void createTestDB() throws IOException, SQLException, 
InterruptedException {
                final Path directoryPath = 
Files.createTempDirectory("monetdbtest");
                datbaseDirectory = directoryPath.toFile();
 
                db = new MonetDBEmbedded(datbaseDirectory);
+//         TimeUnit.SECONDS.sleep(15);
                db.start();
 
                db.query("CREATE TABLE test (id integer, val integer);");
@@ -187,9 +190,6 @@ public class EmbeddedTest {
                assertEquals(2, result1.getColumn(1).columnSize());
                assertEquals(testValues[1][2], 
result1.getColumn(1).getValue(0));
                assertEquals(testValues[1][3], 
result1.getColumn(1).getValue(1));
-               
-               result1.close();
-               result2.close();
        }
        
        @Test
@@ -198,7 +198,6 @@ public class EmbeddedTest {
                assertEquals(2, result1.getColumn(1).columnSize());
                assertEquals(testValues[1][2], 
result1.getColumn(1).getValue(0));
                assertEquals(testValues[1][3], 
result1.getColumn(1).getValue(1));
-               result1.close();
 
                EmbeddedQueryResult result2 = db.query("SELECT * FROM test 
WHERE id < 1;");
                assertEquals(testValues[1][0], 
result2.getColumn(1).getValue(0));
@@ -221,6 +220,32 @@ public class EmbeddedTest {
 
                result.close();
        }
+       
+       @Test
+       public void dobuleManualCleanupTest() throws IOException, SQLException {
+               @SuppressWarnings("resource")
+               EmbeddedQueryResult result = db.query("SELECT * FROM test;");
+               assertEquals(4, result.getColumn(1).columnSize());
+               assertEquals(Integer.valueOf(20), 
result.getColumn(1).getValue(1));
+               assertEquals(null, result.getColumn(1).getValue(3));
+
+               result.close();
+               result.close();
+       }
+       
+       @Test
+       public void resultAccessAfterClose() throws IOException, SQLException {
+               @SuppressWarnings("resource")
+               EmbeddedQueryResult result = db.query("SELECT * FROM test;");
+               assertEquals(4, result.getColumn(1).columnSize());
+               assertEquals(Integer.valueOf(20), 
result.getColumn(1).getValue(1));
+               assertEquals(null, result.getColumn(1).getValue(3));
+
+               result.close();
+               
+               // The result of any column get should be null
+               assertEquals(null, result.getColumn(1));
+       }
 
        @Test(expected=SQLException.class)
        public void captureQueryErrorTest() throws SQLException {
_______________________________________________
checkin-list mailing list
checkin-list@monetdb.org
https://www.monetdb.org/mailman/listinfo/checkin-list

Reply via email to