diff --git a/bindings/java/jni/auto_db_java.cpp b/bindings/java/jni/auto_db_java.cpp index 033f28e07fa6b1f42f49a3ba2735ed53d5f631b6..e0e9afb5c461628fb1215d11a3bb40305b611cd6 100644 --- a/bindings/java/jni/auto_db_java.cpp +++ b/bindings/java/jni/auto_db_java.cpp @@ -482,7 +482,9 @@ TSK_RETVAL_ENUM TskAutoDbJava::createJString(const char * input, jstring & newJS if (tsk_UTF8toUTF16((const UTF8 **)&source, (const UTF8 *)&source[input_len], &target, &target[input_len], TSKlenientConversion) != TSKconversionOK) { free(utf16_input); - return TSK_ERR; + // use default JNI method as fallback, fixes https://github.com/sleuthkit/sleuthkit/issues/2723 + newJString = m_jniEnv->NewStringUTF(input); + return TSK_OK; } /* diff --git a/bindings/java/src/org/sleuthkit/datamodel/AbstractFile.java b/bindings/java/src/org/sleuthkit/datamodel/AbstractFile.java index 50f0cc17e2f1ee67d2c8ded378dcd7e24b97e831..db07ed5d4d6a8188fd687f8ff55f33dbbba5f76a 100644 --- a/bindings/java/src/org/sleuthkit/datamodel/AbstractFile.java +++ b/bindings/java/src/org/sleuthkit/datamodel/AbstractFile.java @@ -21,6 +21,7 @@ import java.io.FileNotFoundException; import java.io.IOException; import java.io.RandomAccessFile; +import java.lang.ref.SoftReference; import java.sql.SQLException; import java.sql.Statement; import java.text.MessageFormat; @@ -118,8 +119,9 @@ public abstract class AbstractFile extends AbstractContent { private volatile String uniquePath; private volatile FileSystem parentFileSystem; - private ContentStream contentStream; private boolean tryContentStream; + private Object contentStreamLock = new Object(); + private SoftReference<ContentStream> contentStreamRef = null; /** * Initializes common fields used by AbstactFile implementations (objects in @@ -1070,44 +1072,54 @@ short getMetaFlagsAsInt() { return TSK_FS_META_FLAG_ENUM.toInt(metaFlags); } - /** - * Attempts to load the content stream for this file. If none exists, returns false. - * @return False if no content stream exists for this file. - * @throws TskCoreException - */ - private boolean loadContentStream() throws TskCoreException { - if (contentStream != null) { - return true; - } else if (tryContentStream) { - // only attempt to load if the flag indicates it should be tried - contentStream = getSleuthkitCase().getContentProvider().getContentStream(this).orElse(null); - - if (contentStream == null) { - // if no content stream could be loaded, mark tryContentStream as false so load - // isn't attempted again - tryContentStream = false; - return false; - } else { - return true; - } - } else { - return false; + + + private boolean hasContentStream() { + ContentStream contentStream = null; + try { + contentStream = getContentStream(); + } catch (TskCoreException ex) { + LOGGER.log(Level.WARNING, "An error occurred while loading content stream for file with id: " + getId(), ex); } + return contentStream != null; } /** - * @return True if the custom content provider for the case should be used to fetch content bytes. + * Attempts to load the content stream for this file. If none exists, returns null. + * @return The content stream for this file or null if none exists. + * @throws TskCoreException */ - private boolean useContentProvider() { - return this.getCollected() == CollectedStatus.YES_REPO && getSleuthkitCase().getContentProvider() != null; + private ContentStream getContentStream() throws TskCoreException { + ContentStream contentStream = null; + if (tryContentStream) { + try { + synchronized (contentStreamLock) { + // try to get soft reference content stream + contentStream = contentStreamRef == null ? null : contentStreamRef.get(); + // load if not cached and then cache if present + if (contentStream == null) { + contentStream = getSleuthkitCase().getContentProvider().getContentStream(this).orElse(null); + if (contentStream != null) { + this.contentStreamRef = new SoftReference<>(contentStream); + } + } + } + } finally { + if (contentStream == null) { + // don't try to load the content stream again if it fails to load (either through exception or not existing) + tryContentStream = false; + } + } + } + return contentStream; } - @Override public final int read(byte[] buf, long offset, long len) throws TskCoreException { - //template method - if (useContentProvider() && loadContentStream()) { - return this.contentStream.read(buf, offset, len); + // try to use content stream if present + ContentStream contentStream = getContentStream(); + if (contentStream != null) { + return contentStream.read(buf, offset, len); } //if localPath is set, use local, otherwise, use readCustom() supplied by derived class @@ -1283,13 +1295,8 @@ final void setEncodingType(TskData.EncodingType encodingType) { * @return true if the file exists, false otherwise */ public boolean exists() { - if (useContentProvider()) { - try { - return loadContentStream(); - } catch (TskCoreException ex) { - LOGGER.log(Level.SEVERE, ex.getMessage()); - return false; - } + if (hasContentStream()) { + return true; } if (!localPathSet) { @@ -1313,13 +1320,8 @@ public boolean exists() { * @return true if the file is readable */ public boolean canRead() { - if (useContentProvider()) { - try { - return loadContentStream(); - } catch (TskCoreException ex) { - LOGGER.log(Level.SEVERE, ex.getMessage()); - return false; - } + if (hasContentStream()) { + return true; } if (!localPathSet) { diff --git a/bindings/java/src/org/sleuthkit/datamodel/ContentStream.java b/bindings/java/src/org/sleuthkit/datamodel/ContentStream.java index 8037219c322d936593574874536f4f9f93ba2cac..00055d0a78188f1dada7745736c29747fdeecccb 100644 --- a/bindings/java/src/org/sleuthkit/datamodel/ContentStream.java +++ b/bindings/java/src/org/sleuthkit/datamodel/ContentStream.java @@ -23,7 +23,7 @@ /** * Custom provider for content bytes. */ -public interface ContentStream { +public interface ContentStream extends AutoCloseable { /** * Reads data that this content object is associated with (file contents, diff --git a/bindings/java/src/org/sleuthkit/datamodel/Pool.java b/bindings/java/src/org/sleuthkit/datamodel/Pool.java index 417bf0c7f1ed6647eec15caa6b26cd9f78f2f1f2..98681759fd86791e7152ca2de1a0247113d7b737 100644 --- a/bindings/java/src/org/sleuthkit/datamodel/Pool.java +++ b/bindings/java/src/org/sleuthkit/datamodel/Pool.java @@ -114,7 +114,13 @@ private long getPoolOffset(Image image) throws TskCoreException { } else if (this.getParent() instanceof Volume) { // If the parent is a volume, then the pool starts at the volume offset Volume parent = (Volume)this.getParent(); - return parent.getStart() * image.getSsize(); // Offset needs to be in bytes + if (parent.getParent() instanceof VolumeSystem) { + // uses block size from parent volume system + return parent.getStart() * ((VolumeSystem) parent.getParent()).getBlockSize(); // Offset needs to be in bytes + } else { + // uses sector size from parent image (old behavior fallback) + return parent.getStart() * image.getSsize(); // Offset needs to be in bytes + } } throw new TskCoreException("Pool with object ID " + this.getId() + " does not have Image or Volume parent"); } diff --git a/bindings/java/src/org/sleuthkit/datamodel/TskCaseDbBridge.java b/bindings/java/src/org/sleuthkit/datamodel/TskCaseDbBridge.java index a161ecc40a0ee244f9de92528f82b7e5bec37a7a..0da8c2a846cca449749b58250e49aa0482d6315d 100644 --- a/bindings/java/src/org/sleuthkit/datamodel/TskCaseDbBridge.java +++ b/bindings/java/src/org/sleuthkit/datamodel/TskCaseDbBridge.java @@ -396,6 +396,10 @@ private long addBatchedFilesToDb() { } catch (NotUserSIDException ex) { // if the owner SID is not a user SID, set the owner account to null ownerIdToAccountMap.put(ownerUid, null); + } catch (Exception ex) { + // catch other exceptions to avoid skiping add batched files loop below + logger.log(Level.WARNING, "Error mapping ownerId " + ownerUid + " to account", ex); + ownerIdToAccountMap.put(ownerUid, null); } } } @@ -484,7 +488,7 @@ private long addBatchedFilesToDb() { // Exception firewall to prevent unexpected return to the native code logger.log(Level.SEVERE, "Unexpected error from files added callback", ex); } - } catch (TskCoreException ex) { + } catch (Throwable ex) { logger.log(Level.SEVERE, "Error adding batched files to database", ex); revertTransaction(); return -1; diff --git a/bindings/java/src/org/sleuthkit/datamodel/WindowsAccountUtils.java b/bindings/java/src/org/sleuthkit/datamodel/WindowsAccountUtils.java index ee4e8ff9e2dc4c4c4205a591c649952237ef481f..28a92ca920e1754e4cf89281ac607c6a79d30e55 100644 --- a/bindings/java/src/org/sleuthkit/datamodel/WindowsAccountUtils.java +++ b/bindings/java/src/org/sleuthkit/datamodel/WindowsAccountUtils.java @@ -170,6 +170,7 @@ public String getDescription() { // - We can assume and fill in SID from given account name, and vice versa. // - We map account names in foreign languages (some known set) to english names, for these well known accounts. private static final Map<String, WellKnownSidInfo> SPECIAL_SIDS_MAP = ImmutableMap.<String, WellKnownSidInfo>builder() + .put("S-1-5-17", new WellKnownSidInfo(true, "S-1-5", NTAUTHORITY_REALM_NAME, "IUSR", "IIS Default Account")) .put("S-1-5-18", new WellKnownSidInfo(true, "S-1-5", NTAUTHORITY_REALM_NAME, "SYSTEM", "Local System Account")) .put("S-1-5-19", new WellKnownSidInfo(true, "S-1-5", NTAUTHORITY_REALM_NAME, "LOCAL SERVICE", "Local Service Account")) .put("S-1-5-20", new WellKnownSidInfo(true, "S-1-5", NTAUTHORITY_REALM_NAME, "NETWORK SERVICE", "Network Service Account")) diff --git a/tsk/auto/auto.cpp b/tsk/auto/auto.cpp index b2438376b99f2588cf2566a9f71f4a00f20a725b..89243df85f7cc293b9947b907d65de4016b3c9ae 100755 --- a/tsk/auto/auto.cpp +++ b/tsk/auto/auto.cpp @@ -507,10 +507,6 @@ TskAuto::findFilesInPool(TSK_OFF_T start, TSK_POOL_TYPE_ENUM ptype) "findFilesInPool: Error opening APFS file system"); registerError(); } - - tsk_img_close(pool_img); - tsk_pool_close(pool); - return TSK_ERR; } tsk_img_close(pool_img);