Skip to content

Commit 5f3fb1d

Browse files
committed
Fix resource leaks and NPEs.
Detected using Facebook's static analysis tools via a build using Buck.
1 parent b914c61 commit 5f3fb1d

File tree

14 files changed

+187
-112
lines changed

14 files changed

+187
-112
lines changed

java/client/src/com/thoughtworks/selenium/webdriven/commands/AttachFile.java

+12
Original file line numberDiff line numberDiff line change
@@ -32,8 +32,11 @@
3232
import java.io.IOException;
3333
import java.net.MalformedURLException;
3434
import java.net.URL;
35+
import java.util.logging.Level;
36+
import java.util.logging.Logger;
3537

3638
public class AttachFile extends SeleneseCommand<Void> {
39+
private final static Logger LOGGER = Logger.getLogger(AttachFile.class.getName());
3740
private final ElementFinder finder;
3841

3942
public AttachFile(ElementFinder finder) {
@@ -63,6 +66,15 @@ private File downloadFile(String name) {
6366
Resources.copy(url, fos);
6467
} catch (IOException e) {
6568
throw new SeleniumException("Can't access file to upload: " + url, e);
69+
} finally {
70+
try {
71+
if (fos != null) {
72+
fos.close();
73+
}
74+
} catch (IOException e) {
75+
// Nothing sane to do. Log and continue.
76+
LOGGER.log(Level.WARNING, "Unable to close stream used for reading file: " + name, e);
77+
}
6678
}
6779

6880
return outputTo;

java/client/test/org/openqa/selenium/environment/webserver/UploadServlet.java

+11-4
Original file line numberDiff line numberDiff line change
@@ -46,10 +46,17 @@ protected void doPost(HttpServletRequest request,
4646

4747
int length = (int) file.length();
4848
byte[] buffer = new byte[length];
49-
InputStream in = new FileInputStream(file);
50-
in.read(buffer, 0, length);
51-
String content = new String(buffer, "UTF-8");
52-
in.close();
49+
InputStream in = null;
50+
String content;
51+
try {
52+
in = new FileInputStream(file);
53+
in.read(buffer, 0, length);
54+
content = new String(buffer, "UTF-8");
55+
} finally {
56+
if (in != null) {
57+
in.close();
58+
}
59+
}
5360

5461
// Slow down the upload so we can verify WebDriver waits.
5562
try {

java/server/src/cybervillains/ca/Generator.java

+6-3
Original file line numberDiff line numberDiff line change
@@ -38,12 +38,12 @@
3838
* $> rm -r new_certs
3939
* $> COMMIT TO SELENIUM REPO
4040
* </pre>
41-
*
41+
*
4242
* *************************************************************************************** Copyright
4343
* (c) 2012, NeuStar, Inc. All Rights Reserved.
44-
*
44+
*
4545
* In a special exception, Selenium/OpenQA is allowed to use this code under the Apache License 2.0.
46-
*
46+
*
4747
* @author Mark Watson <[email protected]>, Ivan De Marino <[email protected]>
4848
*/
4949
public class Generator {
@@ -62,6 +62,9 @@ public static void main(String[] args) {
6262
X509Certificate caCrlCert = null;
6363
try {
6464
caCrlCert = mgr.getSigningCert();
65+
if (caCrlCert == null) {
66+
throw new IllegalStateException("Unable to obtain signing certificate");
67+
}
6568
PrivateKey caCrlPrivateKey = mgr.getSigningPrivateKey();
6669

6770
crlGen.setIssuerDN(mgr.getSigningCert().getSubjectX500Principal());

java/server/src/cybervillains/ca/KeyStoreManager.java

+46-65
Original file line numberDiff line numberDiff line change
@@ -39,28 +39,29 @@
3939
import java.security.cert.X509Certificate;
4040
import java.security.spec.DSAParameterSpec;
4141
import java.util.HashMap;
42+
import java.util.Map;
4243
import java.util.logging.Level;
4344
import java.util.logging.Logger;
4445

4546
import javax.crypto.spec.DHParameterSpec;
4647

4748
/**
4849
* This is the main entry point into the Cybervillains CA.
49-
*
50+
*
5051
* This class handles generation, storage and the persistent mapping of input to duplicated
5152
* certificates and mapped public keys.
52-
*
53+
*
5354
* Default setting is to immediately persist changes to the store by writing out the keystore and
5455
* mapping file every time a new certificate is added. This behavior can be disabled if desired, to
5556
* enhance performance or allow temporary testing without modifying the certificate store.
56-
*
57-
***************************************************************************************
57+
*
58+
***************************************************************************************
5859
* Copyright (c) 2007, Information Security Partners, LLC All rights reserved.
59-
*
60+
*
6061
* In a special exception, Selenium/OpenQA is allowed to use this code under the Apache License 2.0.
61-
*
62+
*
6263
* @author Brad Hill
63-
*
64+
*
6465
*/
6566
public class KeyStoreManager {
6667

@@ -384,7 +385,7 @@ protected void createKeystore() {
384385

385386
/**
386387
* Stores a new certificate and its associated private key in the keystore.
387-
*
388+
*
388389
* @throws KeyStoreException
389390
* @throws CertificateException
390391
* @throws NoSuchAlgorithmException
@@ -409,32 +410,39 @@ public synchronized void addCertAndPrivateKey(String hostname, final X509Certifi
409410

410411
/**
411412
* Writes the keystore and certificate/keypair mappings to disk.
412-
*
413+
*
413414
* @throws KeyStoreException
414415
* @throws NoSuchAlgorithmException
415416
* @throws CertificateException
416417
*/
417418
public synchronized void persist() throws KeyStoreException, NoSuchAlgorithmException,
418419
CertificateException {
419-
try
420-
{
421-
FileOutputStream kso = new FileOutputStream(new File(root, _caPrivateKeystore));
420+
FileOutputStream kso = null;
421+
try {
422+
kso = new FileOutputStream(new File(root, _caPrivateKeystore));
422423
_ks.store(kso, _keystorepass);
423424
kso.flush();
424425
kso.close();
425426
persistCertMap();
426427
persistSubjectMap();
427428
persistKeyPairMap();
428429
persistPublicKeyMap();
429-
} catch (IOException ioe)
430-
{
430+
} catch (IOException ioe) {
431431
ioe.printStackTrace();
432+
} finally {
433+
if (kso != null) {
434+
try {
435+
kso.close();
436+
} catch (IOException e) {
437+
log.log(Level.WARNING, "Unable to close " + _caPrivateKeystore, e);
438+
}
439+
}
432440
}
433441
}
434442

435443
/**
436444
* Returns the aliased certificate. Certificates are aliased by their SHA1 digest.
437-
*
445+
*
438446
* @see ThumbprintUtil
439447
* @throws KeyStoreException
440448
*/
@@ -445,7 +453,7 @@ public synchronized X509Certificate getCertificateByAlias(final String alias)
445453

446454
/**
447455
* Returns the aliased certificate. Certificates are aliased by their hostname.
448-
*
456+
*
449457
* @see ThumbprintUtil
450458
* @throws KeyStoreException
451459
* @throws UnrecoverableKeyException
@@ -472,7 +480,7 @@ public synchronized X509Certificate getCertificateByHostname(final String hostna
472480

473481
/**
474482
* Gets the authority root signing cert.
475-
*
483+
*
476484
* @throws KeyStoreException
477485
*/
478486
public synchronized X509Certificate getSigningCert() throws KeyStoreException {
@@ -481,7 +489,7 @@ public synchronized X509Certificate getSigningCert() throws KeyStoreException {
481489

482490
/**
483491
* Gets the authority private signing key.
484-
*
492+
*
485493
* @throws KeyStoreException
486494
* @throws NoSuchAlgorithmException
487495
* @throws UnrecoverableKeyException
@@ -495,7 +503,7 @@ public synchronized PrivateKey getSigningPrivateKey() throws KeyStoreException,
495503
* This method returns the mapped certificate for a hostname, or generates a "standard" SSL server
496504
* certificate issued by the CA to the supplied subject if no mapping has been created. This is
497505
* not a true duplication, just a shortcut method that is adequate for web browsers.
498-
*
506+
*
499507
* @throws CertificateParsingException
500508
* @throws InvalidKeyException
501509
* @throws CertificateExpiredException
@@ -544,39 +552,13 @@ private String getSubjectForHostname(String hostname) {
544552
}
545553

546554
private synchronized void persistCertMap() {
547-
try {
548-
ObjectOutput out =
549-
new ObjectOutputStream(new FileOutputStream(new File(root, CERTMAP_SER_FILE)));
550-
out.writeObject(_certMap);
551-
out.flush();
552-
out.close();
553-
} catch (FileNotFoundException e) {
554-
// writing, this shouldn't happen...
555-
e.printStackTrace();
556-
} catch (IOException e) {
557-
// big problem!
558-
e.printStackTrace();
559-
throw new Error(e);
560-
}
555+
persistMap(new File(root, CERTMAP_SER_FILE), _certMap);
561556
}
562557

563558

564559

565560
private synchronized void persistSubjectMap() {
566-
try {
567-
ObjectOutput out =
568-
new ObjectOutputStream(new FileOutputStream(new File(root, SUBJMAP_SER_FILE)));
569-
out.writeObject(_subjectMap);
570-
out.flush();
571-
out.close();
572-
} catch (FileNotFoundException e) {
573-
// writing, this shouldn't happen...
574-
e.printStackTrace();
575-
} catch (IOException e) {
576-
// big problem!
577-
e.printStackTrace();
578-
throw new Error(e);
579-
}
561+
persistMap(new File(root, SUBJMAP_SER_FILE), _subjectMap);
580562
}
581563

582564
/**
@@ -591,36 +573,35 @@ public KeyPair getRSAKeyPair()
591573
}
592574

593575
private synchronized void persistPublicKeyMap() {
594-
try {
595-
ObjectOutput out =
596-
new ObjectOutputStream(new FileOutputStream(new File(root, PUB_KEYMAP_SER_FILE)));
597-
out.writeObject(_mappedPublicKeys);
598-
out.flush();
599-
out.close();
600-
} catch (FileNotFoundException e) {
601-
// writing, won't happen
602-
e.printStackTrace();
603-
} catch (IOException e) {
604-
// very bad
605-
e.printStackTrace();
606-
throw new Error(e);
607-
}
576+
persistMap(new File(root, PUB_KEYMAP_SER_FILE), _mappedPublicKeys);
608577
}
609578

610579
private synchronized void persistKeyPairMap() {
580+
persistMap(new File(root, KEYMAP_SER_FILE), _rememberedPrivateKeys);
581+
}
582+
583+
private void persistMap(File outputFile, Map<?, ?> toPersist) {
584+
ObjectOutput out = null;
611585
try {
612-
ObjectOutput out =
613-
new ObjectOutputStream(new FileOutputStream(new File(root, KEYMAP_SER_FILE)));
614-
out.writeObject(_rememberedPrivateKeys);
586+
out = new ObjectOutputStream(new FileOutputStream(outputFile));
587+
out.writeObject(toPersist);
615588
out.flush();
616-
out.close();
617589
} catch (FileNotFoundException e) {
618590
// writing, won't happen.
619591
e.printStackTrace();
620592
} catch (IOException e) {
621593
// very bad
622594
e.printStackTrace();
623595
throw new Error(e);
596+
} finally {
597+
if (out != null) {
598+
try {
599+
out.close();
600+
} catch (IOException e) {
601+
// Nothing sane to do.
602+
log.log(Level.WARNING, "Unable to close " + outputFile.getName(), e);
603+
}
604+
}
624605
}
625606
}
626607

java/server/src/org/openqa/grid/web/servlet/handler/WebDriverRequest.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ public RequestType extractRequestType() {
4646
return RequestType.START_SESSION;
4747
} else if (getMethod().equalsIgnoreCase("DELETE")) {
4848
ExternalSessionKey externalKey = ExternalSessionKey.fromWebDriverRequest(getPathInfo());
49-
if (getPathInfo().endsWith("/session/" + externalKey.getKey())) {
49+
if (externalKey != null && getPathInfo().endsWith("/session/" + externalKey.getKey())) {
5050
return RequestType.STOP_SESSION;
5151
}
5252
}

java/server/src/org/openqa/selenium/remote/server/handler/WebDriverHandler.java

+3-1
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@
1717

1818
package org.openqa.selenium.remote.server.handler;
1919

20+
import com.google.common.base.Preconditions;
21+
2022
import org.openqa.selenium.WebDriver;
2123
import org.openqa.selenium.internal.WrapsDriver;
2224
import org.openqa.selenium.remote.SessionId;
@@ -84,6 +86,6 @@ protected WebDriver getUnwrappedDriver() {
8486
while (toReturn instanceof WrapsDriver) {
8587
toReturn = ((WrapsDriver) toReturn).getWrappedDriver();
8688
}
87-
return toReturn;
89+
return Preconditions.checkNotNull(toReturn);
8890
}
8991
}

java/server/src/org/openqa/selenium/remote/server/log/SessionLogsToFileRepository.java

+3-2
Original file line numberDiff line numberDiff line change
@@ -94,10 +94,11 @@ public List<LogRecord> getLogRecords(SessionId sessionId) throws IOException {
9494
if (logFile == null) {
9595
return new ArrayList<LogRecord>();
9696
}
97-
logFile.openLogReader();
98-
ObjectInputStream logObjInStream = logFile.getLogReader();
97+
9998
List<LogRecord> logRecords = new ArrayList<LogRecord>();
10099
try {
100+
logFile.openLogReader();
101+
ObjectInputStream logObjInStream = logFile.getLogReader();
101102
LogRecord tmpLogRecord;
102103
while (null != (tmpLogRecord = (LogRecord) logObjInStream
103104
.readObject())) {

java/server/src/org/openqa/selenium/server/ProxyHandler.java

+7-5
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@
1616

1717
package org.openqa.selenium.server;
1818

19+
import com.google.common.base.Preconditions;
20+
1921
import cybervillains.ca.KeyStoreManager;
2022

2123
import org.openqa.jetty.http.HttpConnection;
@@ -67,7 +69,7 @@
6769
* make proxy requests.
6870
* <p/>
6971
* The HttpTunnel mechanism is also used to implement the CONNECT method.
70-
*
72+
*
7173
* @author Greg Wilkins (gregw)
7274
* @author [email protected] (chained proxy)
7375
* @version $Id: ProxyHandler.java,v 1.34 2005/10/05 13:32:59 gregwilkins Exp $
@@ -641,7 +643,7 @@ protected void wireUpSslWithCyberVilliansCA(String host, SslRelay listener) {
641643
new KeyStoreManager(root, "http://127.0.0.1:" + port +
642644
"/selenium-server/sslSupport/blank_crl.pem");
643645
mgr.getCertificateByHostname(host);
644-
mgr.getKeyStore().deleteEntry(KeyStoreManager._caPrivKeyAlias);
646+
Preconditions.checkNotNull(mgr.getKeyStore()).deleteEntry(KeyStoreManager._caPrivKeyAlias);
645647
mgr.persist();
646648

647649
listener.setKeystore(new File(root, "cybervillainsCA.jks").getAbsolutePath());
@@ -670,7 +672,7 @@ protected HttpTunnel newHttpTunnel(HttpResponse response, InetAddress iaddr,
670672

671673
/**
672674
* Is URL Proxied. Method to allow derived handlers to select which URIs are proxied and to where.
673-
*
675+
*
674676
* @param uri The requested URI, which should include a scheme, host and port.
675677
* @return The URL to proxy to, or null if the passed URI should not be proxied. The default
676678
* implementation returns the passed uri if isForbidden() returns true.
@@ -688,7 +690,7 @@ protected URL isProxied(URI uri) throws MalformedURLException {
688690

689691
/**
690692
* Is URL Forbidden.
691-
*
693+
*
692694
* @return True if the URL is not forbidden. Calls isForbidden(scheme,host,port,true);
693695
*/
694696
protected boolean isForbidden(URI uri) {
@@ -702,7 +704,7 @@ protected boolean isForbidden(URI uri) {
702704

703705
/**
704706
* Is scheme,host & port Forbidden.
705-
*
707+
*
706708
* @param scheme A scheme that mast be in the proxySchemes StringMap.
707709
* @param host A host that must pass the white and black lists
708710
* @return True if the request to the scheme,host and port is not forbidden.

0 commit comments

Comments
 (0)