From a2a53e742c9f927aad2a45a19e4796ef26e8ad0b Mon Sep 17 00:00:00 2001 From: Jakub Skoczen Date: Wed, 2 Apr 2014 00:45:14 +0200 Subject: [PATCH] Fix JVM segv on null pointers --- src/main/java/org/yaz4j/CQLQuery.java | 2 +- src/main/java/org/yaz4j/Connection.java | 34 ++- src/main/java/org/yaz4j/Package.java | 20 +- src/main/java/org/yaz4j/PrefixQuery.java | 2 +- src/main/java/org/yaz4j/Query.java | 4 +- src/main/java/org/yaz4j/Record.java | 4 + src/main/java/org/yaz4j/ResultSet.java | 10 +- src/test/org/yaz4j/ConnectionTest.java | 21 +- src/test/org/yaz4j/DinosaurTest.java | 1 + src/test/org/yaz4j/NullPointersTest.java | 351 ++++++++++++++++++++++++++++++ 10 files changed, 407 insertions(+), 42 deletions(-) create mode 100644 src/test/org/yaz4j/NullPointersTest.java diff --git a/src/main/java/org/yaz4j/CQLQuery.java b/src/main/java/org/yaz4j/CQLQuery.java index 58cc0ff..9bedb04 100644 --- a/src/main/java/org/yaz4j/CQLQuery.java +++ b/src/main/java/org/yaz4j/CQLQuery.java @@ -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); } diff --git a/src/main/java/org/yaz4j/Connection.java b/src/main/java/org/yaz4j/Connection.java index ae99d7c..6a173f9 100644 --- a/src/main/java/org/yaz4j/Connection.java +++ b/src/main/java/org/yaz4j/Connection.java @@ -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); } diff --git a/src/main/java/org/yaz4j/Package.java b/src/main/java/org/yaz4j/Package.java index bf7280a..93994f7 100644 --- a/src/main/java/org/yaz4j/Package.java +++ b/src/main/java/org/yaz4j/Package.java @@ -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; } } } diff --git a/src/main/java/org/yaz4j/PrefixQuery.java b/src/main/java/org/yaz4j/PrefixQuery.java index 80522e0..0770822 100644 --- a/src/main/java/org/yaz4j/PrefixQuery.java +++ b/src/main/java/org/yaz4j/PrefixQuery.java @@ -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); } diff --git a/src/main/java/org/yaz4j/Query.java b/src/main/java/org/yaz4j/Query.java index 03a5f09..cf66a9d 100644 --- a/src/main/java/org/yaz4j/Query.java +++ b/src/main/java/org/yaz4j/Query.java @@ -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(); } diff --git a/src/main/java/org/yaz4j/Record.java b/src/main/java/org/yaz4j/Record.java index 08fd679..2793ba9 100644 --- a/src/main/java/org/yaz4j/Record.java +++ b/src/main/java/org/yaz4j/Record.java @@ -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); diff --git a/src/main/java/org/yaz4j/ResultSet.java b/src/main/java/org/yaz4j/ResultSet.java index b2fd119..1bae33f 100644 --- a/src/main/java/org/yaz4j/ResultSet.java +++ b/src/main/java/org/yaz4j/ResultSet.java @@ -64,6 +64,8 @@ public class ResultSet implements Iterable { * @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 { } 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 { } 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 { * @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; diff --git a/src/test/org/yaz4j/ConnectionTest.java b/src/test/org/yaz4j/ConnectionTest.java index 38a4f3e..56198f0 100644 --- a/src/test/org/yaz4j/ConnectionTest.java +++ b/src/test/org/yaz4j/ConnectionTest.java @@ -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 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(); - } - } + } diff --git a/src/test/org/yaz4j/DinosaurTest.java b/src/test/org/yaz4j/DinosaurTest.java index c530abf..dbded33 100644 --- a/src/test/org/yaz4j/DinosaurTest.java +++ b/src/test/org/yaz4j/DinosaurTest.java @@ -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 index 0000000..9369679 --- /dev/null +++ b/src/test/org/yaz4j/NullPointersTest.java @@ -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()); + } + } + + + +} -- 1.7.10.4