[tor-commits] [exonerator/master] Prevent NPE and unclosed connections.

karsten at torproject.org karsten at torproject.org
Tue Nov 14 20:28:23 UTC 2017


commit 7817a7cc2a88671882fafabff162f262adc650fa
Author: iwakeh <iwakeh at torproject.org>
Date:   Thu Nov 2 12:48:00 2017 +0000

    Prevent NPE and unclosed connections.
---
 .../org/torproject/exonerator/QueryServlet.java    | 133 +++++++++++----------
 1 file changed, 69 insertions(+), 64 deletions(-)

diff --git a/src/main/java/org/torproject/exonerator/QueryServlet.java b/src/main/java/org/torproject/exonerator/QueryServlet.java
index 893a7b9..3005302 100644
--- a/src/main/java/org/torproject/exonerator/QueryServlet.java
+++ b/src/main/java/org/torproject/exonerator/QueryServlet.java
@@ -13,6 +13,7 @@ import java.sql.CallableStatement;
 import java.sql.Connection;
 import java.sql.ResultSet;
 import java.sql.SQLException;
+import java.sql.Timestamp;
 import java.text.ParseException;
 import java.text.SimpleDateFormat;
 import java.util.ArrayList;
@@ -245,77 +246,82 @@ public class QueryServlet extends HttpServlet {
     SortedSet<Long> allValidAfters = new TreeSet<>();
     List<QueryResponse.Match> matches = new ArrayList<>();
     SortedSet<String> allAddresses = new TreeSet<>();
-    try {
-      final long requestedConnection = System.currentTimeMillis();
-      Connection conn = this.ds.getConnection();
-      CallableStatement cs = conn.prepareCall(String.format(
+    final long requestedConnection = System.currentTimeMillis();
+    Calendar utcCalendar = Calendar.getInstance(TimeZone.getTimeZone("UTC"));
+    try (Connection conn = this.ds.getConnection()) {
+      try (CallableStatement cs = conn.prepareCall(String.format(
           "{call search_by_address%s_date(?, ?)}",
-          relayIp.contains(":") ? 48 : 24));
-      cs.setString(1, address24Or48Hex);
-      Calendar utcCalendar = Calendar.getInstance(
-          TimeZone.getTimeZone("UTC"));
-      cs.setDate(2, new java.sql.Date(timestamp), utcCalendar);
-      ResultSet rs = cs.executeQuery();
-      while (rs.next()) {
-        long validafter = rs.getTimestamp(2, utcCalendar).getTime();
-        allValidAfters.add(validafter);
-        byte[] rawstatusentry = rs.getBytes(1);
-        if (null == rawstatusentry) {
-          continue;
-        }
-        SortedSet<String> addresses = new TreeSet<>();
-        SortedSet<String> addressesHex = new TreeSet<>();
-        String nickname = null;
-        Boolean exit = null;
-        for (String line : new String(rawstatusentry).split("\n")) {
-          if (line.startsWith("r ")) {
-            String[] parts = line.split(" ");
-            nickname = parts[1];
-            addresses.add(parts[6]);
-            addressesHex.add(this.convertIpV4ToHex(parts[6]));
-          } else if (line.startsWith("a ")) {
-            String address = line.substring("a ".length(),
-                line.lastIndexOf(":"));
-            addresses.add(address);
-            String orAddressHex = !address.contains(":")
-                ? this.convertIpV4ToHex(address)
-                : this.convertIpV6ToHex(address);
-            addressesHex.add(orAddressHex);
-          } else if (line.startsWith("p ")) {
-            exit = !line.equals("p reject 1-65535");
+          relayIp.contains(":") ? 48 : 24))) {
+        cs.setString(1, address24Or48Hex);
+        cs.setDate(2, new java.sql.Date(timestamp), utcCalendar);
+        try (ResultSet rs = cs.executeQuery()) {
+          while (rs.next()) {
+            Timestamp ts = rs.getTimestamp(2, utcCalendar);
+            if (null == ts) {
+              continue;
+            }
+            long validafter = ts.getTime();
+            allValidAfters.add(validafter);
+            byte[] rawstatusentry = rs.getBytes(1);
+            if (null == rawstatusentry) {
+              continue;
+            }
+            SortedSet<String> addresses = new TreeSet<>();
+            SortedSet<String> addressesHex = new TreeSet<>();
+            String nickname = null;
+            Boolean exit = null;
+            for (String line : new String(rawstatusentry).split("\n")) {
+              if (line.startsWith("r ")) {
+                String[] parts = line.split(" ");
+                nickname = parts[1];
+                addresses.add(parts[6]);
+                addressesHex.add(this.convertIpV4ToHex(parts[6]));
+              } else if (line.startsWith("a ")) {
+                String address = line.substring("a ".length(),
+                    line.lastIndexOf(":"));
+                addresses.add(address);
+                String orAddressHex = !address.contains(":")
+                    ? this.convertIpV4ToHex(address)
+                    : this.convertIpV6ToHex(address);
+                addressesHex.add(orAddressHex);
+              } else if (line.startsWith("p ")) {
+                exit = !line.equals("p reject 1-65535");
+              }
+            }
+            String exitaddress = rs.getString(4);
+            if (exitaddress != null && exitaddress.length() > 0) {
+              addresses.add(exitaddress);
+              addressesHex.add(this.convertIpV4ToHex(exitaddress));
+            }
+            allAddresses.addAll(addresses);
+            if (!addressesHex.contains(addressHex)) {
+              continue;
+            }
+            String validAfterString = validAfterTimeFormat.format(validafter);
+            String fingerprint = rs.getString(3).toUpperCase();
+            QueryResponse.Match match = new QueryResponse.Match();
+            match.timestamp = validAfterString;
+            match.addresses = addresses.toArray(new String[0]);
+            match.fingerprint = fingerprint;
+            match.nickname = nickname;
+            match.exit = exit;
+            matches.add(match);
           }
+        } catch (SQLException e) {
+          this.logger.warn("Result set error.  Returning 'null'.", e);
+          return null;
         }
-        String exitaddress = rs.getString(4);
-        if (exitaddress != null && exitaddress.length() > 0) {
-          addresses.add(exitaddress);
-          addressesHex.add(this.convertIpV4ToHex(exitaddress));
-        }
-        allAddresses.addAll(addresses);
-        if (!addressesHex.contains(addressHex)) {
-          continue;
-        }
-        String validAfterString = validAfterTimeFormat.format(validafter);
-        String fingerprint = rs.getString(3).toUpperCase();
-        QueryResponse.Match match = new QueryResponse.Match();
-        match.timestamp = validAfterString;
-        match.addresses = addresses.toArray(new String[0]);
-        match.fingerprint = fingerprint;
-        match.nickname = nickname;
-        match.exit = exit;
-        matches.add(match);
+        this.logger.info("Returned a database connection to the pool after {}"
+            + " millis.", System.currentTimeMillis() - requestedConnection);
+      } catch (SQLException e) {
+        this.logger.warn("Callable statement error.  Returning 'null'.", e);
+        return null;
       }
-      rs.close();
-      cs.close();
-      conn.close();
-      this.logger.info("Returned a database connection to the pool after {}"
-          + " millis.", System.currentTimeMillis() - requestedConnection);
-    } catch (SQLException e) {
-      /* Nothing found. */
+    } catch (Throwable e) { // Catch all problems left.
       this.logger.warn("Database error.  Returning 'null'.", e);
       return null;
     }
 
-    /* Create a query response object. */
     QueryResponse response = new QueryResponse();
     response.queryAddress = relayIp;
     response.queryDate = dateFormat.format(timestamp);
@@ -352,7 +358,6 @@ public class QueryServlet extends HttpServlet {
       }
     }
 
-    /* Return the query response. */
     return response;
   }
 }





More information about the tor-commits mailing list