Fix JVM segv on null pointers
authorJakub Skoczen <jakub@indexdata.dk>
Tue, 1 Apr 2014 22:45:14 +0000 (00:45 +0200)
committerJakub Skoczen <jakub@indexdata.dk>
Tue, 1 Apr 2014 22:45:14 +0000 (00:45 +0200)
src/main/java/org/yaz4j/CQLQuery.java
src/main/java/org/yaz4j/Connection.java
src/main/java/org/yaz4j/Package.java
src/main/java/org/yaz4j/PrefixQuery.java
src/main/java/org/yaz4j/Query.java
src/main/java/org/yaz4j/Record.java
src/main/java/org/yaz4j/ResultSet.java
src/test/org/yaz4j/ConnectionTest.java
src/test/org/yaz4j/DinosaurTest.java
src/test/org/yaz4j/NullPointersTest.java [new file with mode: 0644]

index 58cc0ff..9bedb04 100644 (file)
@@ -14,7 +14,7 @@ import org.yaz4j.jni.yaz4jlib;
 public class CQLQuery extends Query {
 
   public CQLQuery(String cqlQuery) {
-    super();
+    super(cqlQuery);
     yaz4jlib.ZOOM_query_cql(query, cqlQuery);
   }
   
index ae99d7c..6a173f9 100644 (file)
@@ -37,9 +37,8 @@ import org.yaz4j.jni.yaz4jlib;
  * @author jakub
  */
 public class Connection implements Closeable {
-
-  private String host;
-  private int port;
+  private final String host;
+  private final int port;
   protected SWIGTYPE_p_ZOOM_connection_p zoomConnection;
   //connection is initially closed
   protected boolean closed = true;
@@ -64,6 +63,8 @@ public class Connection implements Closeable {
    * @param port port of the server
    */
   public Connection(String host, int port) {
+    if (host == null)
+      throw new NullPointerException("host cannot be null");
     this.host = host;
     this.port = port;
     zoomConnection = yaz4jlib.ZOOM_connection_create(null);
@@ -87,9 +88,12 @@ public class Connection implements Closeable {
   @Deprecated
   public ResultSet search(String query, QueryType queryType) throws
     ZoomException {
-    if (closed) {
+    if (query == null)
+      throw new NullPointerException("query cannot be null");
+    if (queryType == null)
+      throw new NullPointerException("queryType cannot be null");
+    if (closed)
       throw new IllegalStateException("Connection is closed.");
-    }
     SWIGTYPE_p_ZOOM_query_p yazQuery = null;
     if (queryType == QueryType.CQLQuery) {
       yazQuery = yaz4jlib.ZOOM_query_create();
@@ -120,9 +124,10 @@ public class Connection implements Closeable {
    * @throws ZoomException protocol or network-level error
    */
   public ResultSet search(Query query) throws ZoomException {
-    if (closed) {
+    if (query == null)
+      throw new NullPointerException("query cannot be null");
+    if (closed)
       throw new IllegalStateException("Connection is closed.");
-    }
     SWIGTYPE_p_ZOOM_resultset_p yazResultSet = yaz4jlib.ZOOM_connection_search(
       zoomConnection, query.query);
     ZoomException err = ExceptionUtil.getError(zoomConnection, host,
@@ -144,9 +149,10 @@ public class Connection implements Closeable {
    */
   @Deprecated
   public ScanSet scan(String query) throws ZoomException {
-    if (closed) {
+    if (query == null)
+      throw new NullPointerException("query cannot be null");
+    if (closed)
       throw new IllegalStateException("Connection is closed.");
-    }
     SWIGTYPE_p_ZOOM_scanset_p yazScanSet = yaz4jlib.ZOOM_connection_scan(
       zoomConnection, query);
     ZoomException err = ExceptionUtil.getError(zoomConnection, host, port);
@@ -167,9 +173,10 @@ public class Connection implements Closeable {
    * @throws ZoomException a protocol or network-level error
    */
   public ScanSet scan(Query query) throws ZoomException {
-    if (closed) {
+    if (query == null)
+      throw new NullPointerException("query cannot be null");
+    if (closed)
       throw new IllegalStateException("Connection is closed.");
-    }
     SWIGTYPE_p_ZOOM_scanset_p yazScanSet = yaz4jlib.ZOOM_connection_scan1(
       zoomConnection, query.query);
     ZoomException err = ExceptionUtil.getError(zoomConnection, host, port);
@@ -197,6 +204,7 @@ public class Connection implements Closeable {
   /**
    * Closes the connection.
    */
+  @Override
   public void close() {
     yaz4jlib.ZOOM_connection_close(zoomConnection);
     closed = true;
@@ -219,6 +227,8 @@ public class Connection implements Closeable {
    * @return connection (self) for chainability
    */
   public Connection option(String name, String value) {
+    if (name == null)
+      throw new NullPointerException("option name cannot be null");
     yaz4jlib.ZOOM_connection_option_set(zoomConnection, name, value);
     return this;
   }
@@ -229,6 +239,8 @@ public class Connection implements Closeable {
    * @return option value
    */
   public String option(String name) {
+    if (name == null)
+      throw new NullPointerException("option name cannot be null");
     return yaz4jlib.ZOOM_connection_option_get(zoomConnection, name);
   }
 
index bf7280a..93994f7 100644 (file)
@@ -1,5 +1,6 @@
 package org.yaz4j;
 
+import org.yaz4j.exception.ZoomException;
 import org.yaz4j.jni.SWIGTYPE_p_ZOOM_package_p;
 import org.yaz4j.jni.yaz4jlib;
 
@@ -14,16 +15,17 @@ import org.yaz4j.jni.yaz4jlib;
  * @author jakub
  */
 public class Package {
-
+  //for GC ref count
+  private ConnectionExtended conn;
   private SWIGTYPE_p_ZOOM_package_p pack;
-  private ConnectionExtended connection;
-  private String type;
+  private final String type;
 
-  Package(SWIGTYPE_p_ZOOM_package_p pack, ConnectionExtended connection,
-    String type) {
+  Package(SWIGTYPE_p_ZOOM_package_p pack, ConnectionExtended conn, String type) {
+    if (type == null)
+      throw new NullPointerException("type cannot be null");
     this.type = type;
-    this.connection = connection;
     this.pack = pack;
+    this.conn = conn;
   }
 
   public void finalize() {
@@ -37,6 +39,8 @@ public class Package {
    * @return package (self) for chainability
    */
   public Package option(String key, String value) {
+    if (key == null)
+      throw new NullPointerException("option name cannot be null");
     yaz4jlib.ZOOM_package_option_set(pack, key, value);
     return this;
   }
@@ -47,6 +51,8 @@ public class Package {
    * @return option value
    */
   public String option(String key) {
+    if (key == null)
+      throw new NullPointerException("option name cannot be null");
     return yaz4jlib.ZOOM_package_option_get(pack, key);
   }
 
@@ -60,8 +66,8 @@ public class Package {
   void _dispose() {
     if (pack != null) {
       yaz4jlib.ZOOM_package_destroy(pack);
-      connection = null;
       pack = null;
+      conn = null;
     }
   }
 }
index 80522e0..0770822 100644 (file)
@@ -14,7 +14,7 @@ import org.yaz4j.jni.yaz4jlib;
 public class PrefixQuery extends Query {
 
   public PrefixQuery(String prefixQuery) {
-    super();
+    super(prefixQuery);
     yaz4jlib.ZOOM_query_prefix(query, prefixQuery);
   }
   
index 03a5f09..cf66a9d 100644 (file)
@@ -18,7 +18,9 @@ public abstract class Query {
   SWIGTYPE_p_ZOOM_query_p query;
   private boolean disposed = false;
   
-  protected Query() {
+  protected Query(String queryString) {
+    if (queryString == null)
+      throw new NullPointerException("query string cannot be null");
     query = yaz4jlib.ZOOM_query_create();
   }
   
index 08fd679..2793ba9 100644 (file)
@@ -18,11 +18,14 @@ public class Record implements Cloneable {
     this.record = record;
   }
 
+  @Override
   public void finalize() {
     _dispose();
   }
 
   public byte[] get(String type) {
+    if (type == null)
+      throw new NullPointerException("type cannot be null");
     return yaz4jlib.ZOOM_record_get_bytes(record, type);
   }
 
@@ -42,6 +45,7 @@ public class Record implements Cloneable {
     return new String(get("database"));
   }
 
+  @Override
   public Object clone() {
     SWIGTYPE_p_ZOOM_record_p clone = yaz4jlib.ZOOM_record_clone(record);
     return new Record(clone);
index b2fd119..1bae33f 100644 (file)
@@ -64,6 +64,8 @@ public class ResultSet implements Iterable<Record> {
    * @return result set (self) for chainability
    */
   public ResultSet option(String name, String value) {
+    if (name == null)
+      throw new NullPointerException("option name cannot be null");
     yaz4jlib.ZOOM_resultset_option_set(resultSet, name, value);
     return this;
   }
@@ -77,7 +79,7 @@ public class ResultSet implements Iterable<Record> {
     }
     int errorCode = yaz4jlib.ZOOM_record_error(record, null, null, null);
     if (errorCode != 0) {
-      throw new ZoomException("Record excpetion, code " + errorCode);
+      throw new ZoomException("Record exception, code " + errorCode);
     }
     return new Record(record, this);
   }
@@ -106,7 +108,7 @@ public class ResultSet implements Iterable<Record> {
       }
       int errorCode = yaz4jlib.ZOOM_record_error(record, null, null, null);
       if (errorCode != 0) {
-        throw new ZoomException("Record excpetion, code " + errorCode);
+        throw new ZoomException("Record exception, code " + errorCode);
       }
       out.add(new Record(record, this));
     }
@@ -146,6 +148,10 @@ public class ResultSet implements Iterable<Record> {
    * @throws ZoomException 
    */
   public ResultSet sort(String type, String spec) throws ZoomException {
+    if (type == null)
+      throw new NullPointerException("sort type cannot be null");
+    if (spec == null)
+      throw new NullPointerException("sort spec cannot be null");
     int ret = yaz4jlib.ZOOM_resultset_sort1(resultSet, type, spec);
     if (ret != 0) throw new ZoomException("Sorting resultset failed");
     return this;
index 38a4f3e..56198f0 100644 (file)
@@ -5,6 +5,7 @@ import static org.junit.Assert.*;
 import org.yaz4j.exception.*;
 import java.util.List;
 
+@SuppressWarnings("deprecation")
 public class ConnectionTest {
   
   @Test
@@ -42,7 +43,6 @@ public class ConnectionTest {
       List<Record> all = s.getRecords(0, (int) s.getHitCount());
       for (Record r : all) {
         System.out.println("getRecords, rec '"+i+"'"+r.getSyntax());
-        System.out.println(r.render());
         i++;
       }
     } catch (ZoomException ze) {
@@ -147,22 +147,5 @@ public class ConnectionTest {
       con.close();
     }
   }
-
-  @Test
-  public void testScan() {
-    System.out.println("Open connection to z3950cat.bl.uk:9909/BLAC");
-    Connection con = new Connection("z3950cat.bl.uk:9909/BLAC", 0);
-    try {
-      con.connect();
-      con.option("number", "20");
-      ScanSet set = con.scan("@attr 1=21 \"development\"");
-      System.out.println("getSize(): " + set.getSize());
-      assertEquals(20, set.getSize());
-
-    } catch (ZoomException ex) {
-      fail(ex.getMessage());
-    } finally {
-      con.close();
-    }
-  }
+  
 }
index c530abf..dbded33 100644 (file)
@@ -7,6 +7,7 @@ import org.yaz4j.exception.ZoomException;
 /**
  * @author adam
  */
+@SuppressWarnings("deprecation")
 public class DinosaurTest {
 
   @Test
diff --git a/src/test/org/yaz4j/NullPointersTest.java b/src/test/org/yaz4j/NullPointersTest.java
new file mode 100644 (file)
index 0000000..9369679
--- /dev/null
@@ -0,0 +1,351 @@
+package org.yaz4j;
+
+import org.junit.*;
+import static org.junit.Assert.*;
+import org.yaz4j.exception.*;
+
+@SuppressWarnings("deprecation")
+public class NullPointersTest {
+   
+  @Test
+  public void testNullPointers1() {
+    try {
+      Connection conn = new Connection(null, 0);
+      conn.connect();
+    } catch (ZoomException ze) {
+      fail(ze.getMessage());
+    } catch (NullPointerException npe) {
+      System.out.println("Caught expected NPE: " +npe.getMessage()); 
+    }
+  }
+  
+  @Test
+  public void testNullPointers2() {
+    try {
+      Connection conn = new Connection("z3950.indexdata.dk:210/gils", 0);
+      conn.setSyntax("sutrs");
+      conn.connect();
+      ResultSet s = conn.search(null);
+    } catch (ZoomException ze) {
+      fail(ze.getMessage());
+    } catch (NullPointerException npe) {
+      System.out.println("Caught expected NPE: " +npe.getMessage());
+      
+    }
+  }
+  
+  @Test
+  public void testNullPointers3() {
+    try {
+      Connection conn = new Connection("z3950.indexdata.dk:210/gils", 0);
+      conn.setSyntax("sutrs");
+      conn.connect();
+      ResultSet s = conn.search(null, null);
+    } catch (ZoomException ze) {
+      fail(ze.getMessage());
+    } catch (NullPointerException npe) {
+      System.out.println("Caught expected NPE: " +npe.getMessage());
+      
+    }
+  }
+  
+  @Test
+  public void testNullPointers4() {
+    try {
+      Connection conn = new Connection("z3950.indexdata.dk:210/gils", 0);
+      conn.setSyntax("sutrs");
+      conn.connect();
+      ResultSet s = conn.search(new CQLQuery(null));
+    } catch (ZoomException ze) {
+      fail(ze.getMessage());
+    } catch (NullPointerException npe) {
+      System.out.println("Caught expected NPE: " +npe.getMessage());
+      
+    }
+  }
+  
+  @Test
+  public void testNullPointers5() {
+    try {
+      Connection conn = new Connection("z3950.indexdata.dk:210/gils", 0);
+      conn.setSyntax("sutrs");
+      conn.connect();
+      ResultSet s = conn.search(new PrefixQuery(null));
+    } catch (ZoomException ze) {
+      fail(ze.getMessage());
+    } catch (NullPointerException npe) {
+      System.out.println("Caught expected NPE: " +npe.getMessage());
+      
+    }
+  }
+  
+  @Test
+  public void testNullPointers6() {
+    try {
+      Connection conn = new Connection("z3950.indexdata.dk:210/gils", 0);
+      conn.setSyntax("sutrs");
+      conn.connect();
+      ResultSet s = conn.search(null, Connection.QueryType.CQLQuery);
+    } catch (ZoomException ze) {
+      fail(ze.getMessage());
+    } catch (NullPointerException npe) {
+      System.out.println("Caught expected NPE: " +npe.getMessage());
+      
+    }
+  }
+  
+  @Test
+  public void testNullPointers7() {
+    try {
+      Connection conn = new Connection("z3950.indexdata.dk:210/gils", 0);
+      conn.setSyntax("sutrs");
+      conn.connect();
+      ResultSet s = conn.search(null, Connection.QueryType.PrefixQuery);
+    } catch (ZoomException ze) {
+      fail(ze.getMessage());
+    } catch (NullPointerException npe) {
+      System.out.println("Caught expected NPE: " +npe.getMessage());
+      
+    }
+  }
+  
+   @Test
+  public void testNullPointers8() {
+    try {
+      Connection conn = new Connection("z3950.indexdata.dk:210/gils", 0);
+      conn.setSyntax("sutrs");
+      conn.connect();
+      ScanSet s = conn.scan((String) null);
+    } catch (ZoomException ze) {
+      fail(ze.getMessage());
+    } catch (NullPointerException npe) {
+      System.out.println("Caught expected NPE: " +npe.getMessage());
+      
+    }
+  }
+  
+   @Test
+  public void testNullPointers9() {
+    try {
+      Connection conn = new Connection("z3950.indexdata.dk:210/gils", 0);
+      conn.setSyntax("sutrs");
+      conn.connect();
+      ScanSet s = conn.scan((Query) null);
+    } catch (ZoomException ze) {
+      fail(ze.getMessage());
+    } catch (NullPointerException npe) {
+      System.out.println("Caught expected NPE: " +npe.getMessage());
+      
+    }
+  }
+  
+  @Test
+  public void testNullPointers10() {
+    try {
+      Connection conn = new Connection("z3950.indexdata.dk:210/gils", 0);
+      conn.setSyntax("sutrs");
+      conn.connect();
+      ScanSet s = conn.scan(new PrefixQuery(null));
+    } catch (ZoomException ze) {
+      fail(ze.getMessage());
+    } catch (NullPointerException npe) {
+      System.out.println("Caught expected NPE: " +npe.getMessage());
+      
+    }
+  }
+  
+  @Test
+  public void testNullPointers11() {
+    try {
+      Connection conn = new Connection("z3950.indexdata.dk:210/gils", 0);
+      conn.setSyntax("sutrs");
+      conn.connect();
+      ScanSet s = conn.scan(new CQLQuery(null));
+    } catch (ZoomException ze) {
+      fail(ze.getMessage());
+    } catch (NullPointerException npe) {
+      System.out.println("Caught expected NPE: " +npe.getMessage());
+      
+    }
+  }
+  
+  @Test
+  public void testNullPointers12() {
+    try {
+      Connection conn = new Connection("z3950.indexdata.dk:210/gils", 0);
+      conn.setSyntax("sutrs");
+      conn.connect();
+      conn.option(null, null);
+    } catch (ZoomException ze) {
+      fail(ze.getMessage());
+    } catch (NullPointerException npe) {
+      System.out.println("Caught expected NPE: " +npe.getMessage());
+      
+    }
+  }
+  
+  @Test
+  public void testNullPointers13() {
+    try {
+      Connection conn = new Connection("z3950.indexdata.dk:210/gils", 0);
+      conn.setSyntax("sutrs");
+      conn.connect();
+      String opt = conn.option(null);
+    } catch (ZoomException ze) {
+      fail(ze.getMessage());
+    } catch (NullPointerException npe) {
+      System.out.println("Caught expected NPE: " +npe.getMessage());
+      
+    }
+  }
+  
+  @Test
+  public void testNullPointers14() {
+    try {
+      Connection conn = new Connection("z3950.indexdata.dk:210/gils", 0);
+      conn.setSyntax("sutrs");
+      conn.connect();
+      conn.option("some", null);
+    } catch (ZoomException ze) {
+      fail(ze.getMessage());
+    } catch (NullPointerException npe) {
+      System.out.println("Caught expected NPE: " +npe.getMessage());
+      
+    }
+  }
+  
+  @Test
+  public void testNullPointers15() {
+    try {
+      Connection conn = new Connection("z3950.indexdata.dk:210/gils", 0);
+      conn.setSyntax("sutrs");
+      conn.connect();
+      ResultSet s = conn.search(new PrefixQuery("@attr 1=4 water"));
+      s.sort(null, null);
+    } catch (ZoomException ze) {
+      fail(ze.getMessage());
+    } catch (NullPointerException npe) {
+      System.out.println("Caught expected NPE: " +npe.getMessage());
+      
+    }
+  }
+  
+  @Test
+  public void testNullPointers16() {
+    try {
+      Connection conn = new Connection("z3950.indexdata.dk:210/gils", 0);
+      conn.setSyntax("sutrs");
+      conn.connect();
+      ResultSet s = conn.search(new PrefixQuery("@attr 1=4 water"));
+      s.sort("some", null);
+    } catch (ZoomException ze) {
+      fail(ze.getMessage());
+    } catch (NullPointerException npe) {
+      System.out.println("Caught expected NPE: " +npe.getMessage());
+      
+    }
+  }
+  
+  @Test
+  public void testNullPointers17() {
+    try {
+      Connection conn = new Connection("z3950.indexdata.dk:210/gils", 0);
+      conn.setSyntax("sutrs");
+      conn.connect();
+      ResultSet s = conn.search(new PrefixQuery("@attr 1=4 water"));
+      Record r = s.getRecord(0);
+      r.get(null);
+    } catch (ZoomException ze) {
+      fail(ze.getMessage());
+    } catch (NullPointerException npe) {
+      System.out.println("Caught expected NPE: " +npe.getMessage());
+      
+    }
+  }
+  
+  @Test
+  public void testNullPointers18() {
+    try {
+      Connection conn = new Connection("z3950.indexdata.dk:210/gils", 0);
+      conn.setSyntax("sutrs");
+      conn.connect();
+      ResultSet s = conn.search(new PrefixQuery("@attr 1=4 water"));
+      Record r = s.getRecord(0);
+      byte[] b = r.get("unknownType");
+      String str = new String(b);
+    } catch (ZoomException ze) {
+      fail(ze.getMessage());
+    } catch (NullPointerException npe) {
+      System.out.println("Caught expected NPE: " +npe.getMessage());
+      
+    }
+  }
+  
+  @Test
+  public void testNullPointers19() {
+    try {
+      ConnectionExtended conn = new ConnectionExtended("z3950.indexdata.dk:210/gils", 0);
+      conn.setSyntax("sutrs");
+      conn.connect();
+      Package p = conn.getPackage(null);
+    } catch (ZoomException ze) {
+      fail(ze.getMessage());
+    } catch (NullPointerException npe) {
+      System.out.println("Caught expected NPE: " +npe.getMessage());
+      
+    }
+  }
+  
+  @Test
+  public void testNullPointer20() {
+    try {
+      ConnectionExtended conn = new ConnectionExtended("z3950.indexdata.dk:210/gils", 0);
+      conn.setSyntax("sutrs");
+      conn.connect();
+      Package p = conn.getPackage("some");
+      p.option("some", null);
+    } catch (ZoomException ze) {
+      fail(ze.getMessage());
+    } catch (NullPointerException npe) {
+      System.out.println("Caught expected NPE: " +npe.getMessage());
+      
+    }
+  }
+  
+  @Test
+  public void testNullPointer21() {
+    try {
+      ConnectionExtended conn = new ConnectionExtended("z3950.indexdata.dk:210/gils", 0);
+      conn.setSyntax("sutrs");
+      conn.connect();
+      Package p = conn.getPackage("some");
+      p.option(null);
+    } catch (ZoomException ze) {
+      fail(ze.getMessage());
+    } catch (NullPointerException npe) {
+      System.out.println("Caught expected NPE: " +npe.getMessage());
+      
+    }
+  }
+  
+  @Test
+  public void testNullPointer22() {
+    try {
+      ConnectionExtended conn = new ConnectionExtended("z3950.indexdata.dk:210/gils", 0);
+      conn.setSyntax("sutrs");
+      conn.connect();
+      Package create = conn.getPackage("create"); //db create
+      create.option("databaseName", "yaz4j");
+      create.send();
+      Package drop = conn.getPackage("drop");
+      drop.send();
+    } catch (ZoomException ze) {
+      fail(ze.getMessage());
+    } catch (NullPointerException npe) {
+      System.out.println("Caught expected NPE: " +npe.getMessage());  
+    }
+  }
+  
+
+
+}