[jcifs] NullPointerException in SmbFile.resolveDfs()
Brett Johnson
brett.michael.johnson at gmail.com
Mon Oct 15 16:09:20 MDT 2012
One of our customers have encountered a NullPointerException
thrown from deep within jCIFS while closing an input stream:
From a customer log:
Exception in thread "..." java.lang.NullPointerException
at jcifs.smb.SmbFile.resolveDfs(SmbFile.java:668)
at jcifs.smb.SmbFile.send(SmbFile.java:770)
at jcifs.smb.SmbFile.close(SmbFile.java:1018)
at jcifs.smb.SmbFile.close(SmbFile.java:1024)
at jcifs.smb.SmbFile.close(SmbFile.java:1028)
at jcifs.smb.SmbFileInputStream.close(SmbFileInputStream.java:104)
at java.io.BufferedInputStream.close(Unknown Source)
at com.google.enterprise.connector.filesystem.SmbInputStream.close(SmbInputStream.java:64)
at com.google.enterprise.connector.util.BasicChecksumGenerator.getDigest(BasicChecksumGenerator.java:117)
at com.google.enterprise.connector.util.BasicChecksumGenerator.getChecksum(BasicChecksumGenerator.java:131)
at com.google.enterprise.connector.filesystem.FileInfoCache.getChecksum(FileInfoCache.java:59)
at com.google.enterprise.connector.filesystem.FileDocumentSnapshot$GetUpdateSupport.getUpdate(FileDocumentSnapshot.java:384)
at com.google.enterprise.connector.filesystem.FileDocumentSnapshot.getUpdate(FileDocumentSnapshot.java:141)
at com.google.enterprise.connector.filesystem.FileDocumentSnapshot.getUpdate(FileDocumentSnapshot.java:35)
Looking more closely at SmbFile, the NPE is thrown from this statement:
DfsReferral dr = dfs.resolve(
tree.session.transport.tconHostName,
tree.share,
unc,
auth);
I know dfs itself is not null, since it is statically initialized.
So the suspects are tree, tree.session, tree.session.transport.
Immediately before this statement is a call to connect0. Examining
that code, tree starts out null but I don't think tree can be null after
a successful call to connect().
So that leaves tree.session and tree.session.transport. Since
session is a constructor arg for SmbTree, that probably is not
null. That leaves only SmbSession.transport. When I read SmbSession,
transport is initialized lazily and is always fetched via the
SmbSession.transport() method. I think that is the problem here.
I think JCIFS could be patched as follows (note transport() method call):
DfsReferral dr = dfs.resolve(
tree.session.transport().tconHostName,
tree.share,
unc,
auth);
However, even after this, tconHostName is very likely to be null in the
current failure case, since it is populated by a call to transport.doConnect().
If domain is null, dfs.resolve() will throw NPE when it dereferences
domain (which it does several times). At this point, I don't know
enough about DFS and JCIFS to know how to fix the bug, so I modified
com.google.enterprise.connector.filesystem.SmbInputStream.close() to
catch NullPointerException and rethrow as IOException.
--
Brett M. Johnson
More information about the jCIFS
mailing list