Fix bugs and limitations in NTFS utilities encountered with deep paths (over 20 levels)
This affects ntfscluster and ntfsmove. * Don't output the path if utils_inode_get_name() returns an error, which previously would output an uninitialized string for deep paths, producing random garbage. * If the path depth limit is encountered, utils_inode_get_name() now returns a partial path beginning with ".../" instead of an error code. * Increase utils_inode_get_name()'s path depth limit from 20 to 40. * Always free temporary memory, previously lost for deep paths.pull/9/head
parent
92b9fbc6fe
commit
00a4329bc0
|
@ -392,9 +392,8 @@ static int dump_file(ntfs_volume *vol, ntfs_inode *ino)
|
|||
int i;
|
||||
runlist *runs;
|
||||
|
||||
utils_inode_get_name(ino, buffer, sizeof(buffer));
|
||||
|
||||
ntfs_log_info("Dump: %s\n", buffer);
|
||||
if (utils_inode_get_name(ino, buffer, sizeof(buffer)))
|
||||
ntfs_log_info("Dump: %s\n", buffer);
|
||||
|
||||
ctx = ntfs_attr_get_search_ctx(ino, NULL);
|
||||
|
||||
|
@ -440,8 +439,8 @@ static int print_match(ntfs_inode *ino, ATTR_RECORD *attr,
|
|||
return 1;
|
||||
}
|
||||
|
||||
utils_inode_get_name(ino, buffer, MAX_PATH);
|
||||
ntfs_log_info("Inode %llu %s", (unsigned long long)ino->mft_no, buffer);
|
||||
if (utils_inode_get_name(ino, buffer, MAX_PATH))
|
||||
ntfs_log_info("Inode %llu %s", (unsigned long long)ino->mft_no, buffer);
|
||||
|
||||
utils_attr_get_name(ino->vol, attr, buffer, MAX_PATH);
|
||||
ntfs_log_info("/%s\n", buffer);
|
||||
|
|
|
@ -816,7 +816,8 @@ static s64 move_file(ntfs_volume *vol, ntfs_inode *ino, u64 loc, int flags)
|
|||
return -1;
|
||||
}
|
||||
|
||||
utils_inode_get_name(ino, buffer, MAX_PATH);
|
||||
if (!utils_inode_get_name(ino, buffer, MAX_PATH))
|
||||
return -1;
|
||||
|
||||
if (dont_move(ino)) {
|
||||
ntfs_log_error("can't move\n");
|
||||
|
|
|
@ -521,7 +521,7 @@ ATTR_RECORD * find_first_attribute(const ATTR_TYPES type, MFT_RECORD *mft)
|
|||
* if parent is 5 (/) stop
|
||||
* get inode of parent
|
||||
*/
|
||||
#define max_path 20
|
||||
#define max_path 40
|
||||
int utils_inode_get_name(ntfs_inode *inode, char *buffer, int bufsize)
|
||||
{
|
||||
// XXX option: names = posix/win32 or dos
|
||||
|
@ -535,7 +535,7 @@ int utils_inode_get_name(ntfs_inode *inode, char *buffer, int bufsize)
|
|||
int name_space;
|
||||
MFT_REF parent = FILE_root;
|
||||
char *names[max_path + 1];// XXX ntfs_malloc? and make max bigger?
|
||||
int i, len, offset = 0;
|
||||
int i, ir, len, offset = 0;
|
||||
|
||||
if (!inode || !buffer) {
|
||||
errno = EINVAL;
|
||||
|
@ -611,26 +611,28 @@ int utils_inode_get_name(ntfs_inode *inode, char *buffer, int bufsize)
|
|||
if (i >= max_path) {
|
||||
/* If we get into an infinite loop, we'll end up here. */
|
||||
ntfs_log_error("The directory structure is too deep (over %d) nested directories.\n", max_path);
|
||||
return 0;
|
||||
offset = snprintf(buffer, bufsize, "...");
|
||||
}
|
||||
|
||||
/* Assemble the names in the correct order. */
|
||||
for (i = max_path; i >= 0; i--) {
|
||||
if (!names[i])
|
||||
continue;
|
||||
if (bufsize > offset) {
|
||||
/* Assemble the names in the correct order. */
|
||||
for (ir = max_path; ir >= 0; ir--) {
|
||||
if (!names[ir])
|
||||
continue;
|
||||
|
||||
len = snprintf(buffer + offset, bufsize - offset, "%c%s", PATH_SEP, names[i]);
|
||||
if (len >= (bufsize - offset)) {
|
||||
ntfs_log_error("Pathname was truncated.\n");
|
||||
break;
|
||||
}
|
||||
len = snprintf(buffer + offset, bufsize - offset, "%c%s", PATH_SEP, names[ir]);
|
||||
if (len >= (bufsize - offset)) {
|
||||
ntfs_log_error("Pathname was truncated.\n");
|
||||
break;
|
||||
}
|
||||
|
||||
offset += len;
|
||||
}
|
||||
offset += len;
|
||||
}
|
||||
}
|
||||
|
||||
/* Free all the allocated memory */
|
||||
for (i = 0; i < max_path; i++)
|
||||
free(names[i]);
|
||||
for (ir = 0; ir <= i; ir++)
|
||||
free(names[ir]);
|
||||
|
||||
ntfs_log_debug("Pathname: %s\n", buffer);
|
||||
|
||||
|
|
Loading…
Reference in New Issue