diff --git a/bindings/java/jni/auto_db_java.cpp b/bindings/java/jni/auto_db_java.cpp index 969d87ba117d3a9b4959ad27feb27c116d42b62f..8b8fa9d2346b9b3fbb6043efc7d29ab79404b2bf 100644 --- a/bindings/java/jni/auto_db_java.cpp +++ b/bindings/java/jni/auto_db_java.cpp @@ -459,9 +459,43 @@ void extractExtension(char *name, char *extension) { } } +/** +* Convert a sequence of characters to a jstring object. +* We first convert the character sequence to UTF16 and then +* use the JNI NewString() method to create the jstring. +* We do it this way because we encountered data that contained +* 4 byte (or more) UTF8 encoded characters and the JNI NewStringUTF() +* method does not handle 4 byte UTF8 encoding. +* +* @param input The sequence of characters to be turned into a jstring. +* @param input_len The number of chars in the input. +* @param newJString The new jstring object created from the input. +* @returns TSK_ERR on error, TSK_OK on success +*/ +TSK_RETVAL_ENUM TskAutoDbJava::createJString(const char * input, size_t input_len, jstring & newJString) { + UTF16 * utf16_input; + + if ((utf16_input = (UTF16 *)tsk_malloc(input_len * sizeof(wchar_t))) == NULL) { + return TSK_ERR; + } + + UTF8 * source = (UTF8 *)input; + UTF16 * target = utf16_input; + + if (tsk_UTF8toUTF16((const UTF8 **)&source, (const UTF8 *)&source[input_len], &target, &target[input_len], TSKlenientConversion) != TSKconversionOK) { + free(utf16_input); + return TSK_ERR; + } + + newJString = m_jniEnv->NewString(utf16_input, wcslen((const wchar_t *)utf16_input)); + + free(utf16_input); + return TSK_OK; +} + /** * Adds a file and its associated slack file to database. -* Does not learn object ID for new files, and files may +* Does not learn object ID for new files, and files may * not be added to the database immediately. * * @param fs_file @@ -547,6 +581,12 @@ TskAutoDbJava::addFile(TSK_FS_FILE* fs_file, } } + jstring namej; + if (createJString(name, nlen, namej) != TSK_OK) { + free(name); + return TSK_ERR; + } + // clean up path // +2 = space for leading slash and terminating null size_t path_len = strlen(path) + 2; @@ -558,9 +598,21 @@ TskAutoDbJava::addFile(TSK_FS_FILE* fs_file, strncpy(escaped_path, "/", path_len); strncat(escaped_path, path, path_len - strlen(escaped_path)); - jstring namej = m_jniEnv->NewStringUTF(name); - jstring pathj = m_jniEnv->NewStringUTF(escaped_path); - jstring extj = m_jniEnv->NewStringUTF(extension); + jstring pathj; + if (createJString(escaped_path, path_len, pathj) != TSK_OK) { + free(name); + free(escaped_path); + return TSK_ERR; + } + + // Escaped path is not needed beyond this point so free it. + free(escaped_path); + + jstring extj; + if (createJString(extension, 24, extj) != TSK_OK) { + free(name); + return TSK_ERR; + } /* NTFS uses sequence, otherwise we hash the path. We do this to map to the * correct parent folder if there are two from the root dir that eventually point to @@ -590,6 +642,7 @@ TskAutoDbJava::addFile(TSK_FS_FILE* fs_file, (uint64_t)meta_seq, par_meta_addr, par_seqj); if (ret_val < 0) { + free(name); return TSK_ERR; } @@ -609,8 +662,16 @@ TskAutoDbJava::addFile(TSK_FS_FILE* fs_file, if (strlen(extension) > 0) { strncat(extension, "-slack", 6); } - jstring slackNamej = m_jniEnv->NewStringUTF(name); - jstring slackExtj = m_jniEnv->NewStringUTF(extension); + jstring slackNamej; + if (createJString(name, nlen, slackNamej) != TSK_OK) { + free(name); + return TSK_ERR; + } + jstring slackExtj; + if (createJString(extension, 24, slackExtj) != TSK_OK) { + free(name); + return TSK_ERR; + } TSK_OFF_T slackSize = fs_attr->nrd.allocsize - fs_attr->nrd.initsize; // Add slack file to database @@ -628,12 +689,12 @@ TskAutoDbJava::addFile(TSK_FS_FILE* fs_file, (uint64_t)meta_seq, par_meta_addr, par_seqj); if (ret_val < 0) { + free(name); return TSK_ERR; } } free(name); - free(escaped_path); return TSK_OK; } diff --git a/bindings/java/jni/auto_db_java.h b/bindings/java/jni/auto_db_java.h index e6c5e68dd7217d784695749cf53c24df090db75d..c3e8d6c1f67b753b2dae2eb40b90240db70a455d 100644 --- a/bindings/java/jni/auto_db_java.h +++ b/bindings/java/jni/auto_db_java.h @@ -167,6 +167,8 @@ class TskAutoDbJava :public TskAuto { void saveObjectInfo(uint64_t objId, uint64_t parObjId, TSK_DB_OBJECT_TYPE_ENUM type); TSK_RETVAL_ENUM getObjectInfo(uint64_t objId, TSK_DB_OBJECT** obj_info); + TSK_RETVAL_ENUM createJString(const char * inputString, size_t input_len, jstring & newJString); + // prevent copying until we add proper logic to handle it TskAutoDbJava(const TskAutoDbJava&); TskAutoDbJava & operator=(const TskAutoDbJava&);