mirror of
https://github.com/transmission/transmission
synced 2025-03-19 10:15:36 +00:00
#5802: Don't make assumptions of remote path validity in transmission-remote
Defer validity checks until path gets to the remote side, where they actually make sense. Add simple checks for download directory path to ensure it's not relative, since one cannot know what current working directory of the remote process is.
This commit is contained in:
parent
ca21c1f230
commit
650db1f46e
6 changed files with 95 additions and 48 deletions
|
@ -490,43 +490,6 @@ static char * netrc = NULL;
|
|||
static char * sessionId = NULL;
|
||||
static bool UseSSL = false;
|
||||
|
||||
static char*
|
||||
tr_getcwd (void)
|
||||
{
|
||||
char * result;
|
||||
tr_error * error = NULL;
|
||||
|
||||
result = tr_sys_dir_get_current (&error);
|
||||
|
||||
if (result == NULL)
|
||||
{
|
||||
fprintf (stderr, "getcwd error: \"%s\"", error->message);
|
||||
tr_error_free (error);
|
||||
result = tr_strdup ("");
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static char*
|
||||
absolutify (const char * path)
|
||||
{
|
||||
char * buf;
|
||||
|
||||
if (*path == '/')
|
||||
{
|
||||
buf = tr_strdup (path);
|
||||
}
|
||||
else
|
||||
{
|
||||
char * cwd = tr_getcwd ();
|
||||
buf = tr_buildPath (cwd, path, NULL);
|
||||
tr_free (cwd);
|
||||
}
|
||||
|
||||
return buf;
|
||||
}
|
||||
|
||||
static char*
|
||||
getEncodedMetainfo (const char * filename)
|
||||
{
|
||||
|
@ -2253,14 +2216,8 @@ processArgs (const char * rpcurl, int argc, const char ** argv)
|
|||
}
|
||||
case 'w':
|
||||
{
|
||||
char * path = absolutify (optarg);
|
||||
if (tadd)
|
||||
tr_variantDictAddStr (tr_variantDictFind (tadd, TR_KEY_arguments), TR_KEY_download_dir, path);
|
||||
else {
|
||||
tr_variant * args = ensure_sset (&sset);
|
||||
tr_variantDictAddStr (args, TR_KEY_download_dir, path);
|
||||
}
|
||||
tr_free (path);
|
||||
tr_variant * args = tadd ? tr_variantDictFind (tadd, TR_KEY_arguments) : ensure_sset (&sset);
|
||||
tr_variantDictAddStr (args, TR_KEY_download_dir, optarg);
|
||||
break;
|
||||
}
|
||||
case 850:
|
||||
|
|
|
@ -258,6 +258,14 @@ tr_sys_path_get_info (const char * path,
|
|||
return ret;
|
||||
}
|
||||
|
||||
bool
|
||||
tr_sys_path_is_relative (const char * path)
|
||||
{
|
||||
assert (path != NULL);
|
||||
|
||||
return path[0] != '/';
|
||||
}
|
||||
|
||||
bool
|
||||
tr_sys_path_is_same (const char * path1,
|
||||
const char * path2,
|
||||
|
|
|
@ -320,6 +320,49 @@ test_path_exists (void)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
test_path_is_relative (void)
|
||||
{
|
||||
check (tr_sys_path_is_relative (""));
|
||||
check (tr_sys_path_is_relative ("."));
|
||||
check (tr_sys_path_is_relative (".."));
|
||||
check (tr_sys_path_is_relative ("x"));
|
||||
check (tr_sys_path_is_relative ("\\"));
|
||||
check (tr_sys_path_is_relative (":"));
|
||||
|
||||
#ifdef _WIN32
|
||||
|
||||
check (tr_sys_path_is_relative ("/"));
|
||||
check (tr_sys_path_is_relative ("//x"));
|
||||
check (tr_sys_path_is_relative ("\\x"));
|
||||
check (tr_sys_path_is_relative ("\\x\\y"));
|
||||
check (tr_sys_path_is_relative ("C:x"));
|
||||
check (tr_sys_path_is_relative ("C:x\\y"));
|
||||
|
||||
check (!tr_sys_path_is_relative ("\\\\"));
|
||||
check (!tr_sys_path_is_relative ("\\\\x"));
|
||||
check (!tr_sys_path_is_relative ("\\\\x\\y"));
|
||||
check (!tr_sys_path_is_relative ("\\\\.\\x"));
|
||||
|
||||
check (!tr_sys_path_is_relative ("a:"));
|
||||
check (!tr_sys_path_is_relative ("a:\\"));
|
||||
check (!tr_sys_path_is_relative ("a:/"));
|
||||
check (!tr_sys_path_is_relative ("Z:"));
|
||||
check (!tr_sys_path_is_relative ("Z:\\"));
|
||||
check (!tr_sys_path_is_relative ("Z:/"));
|
||||
|
||||
#else /* _WIN32 */
|
||||
|
||||
check (!tr_sys_path_is_relative ("/"));
|
||||
check (!tr_sys_path_is_relative ("/x"));
|
||||
check (!tr_sys_path_is_relative ("/x/y"));
|
||||
check (!tr_sys_path_is_relative ("//x"));
|
||||
|
||||
#endif /* _WIN32 */
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
test_path_is_same (void)
|
||||
{
|
||||
|
@ -1401,6 +1444,7 @@ main (void)
|
|||
{
|
||||
test_get_info,
|
||||
test_path_exists,
|
||||
test_path_is_relative,
|
||||
test_path_is_same,
|
||||
test_path_resolve,
|
||||
test_path_basename_dirname,
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
*/
|
||||
|
||||
#include <assert.h>
|
||||
#include <ctype.h> /* isalpha () */
|
||||
#include <stdlib.h> /* _splitpath_s (), _makepath_s () */
|
||||
|
||||
#include <shlobj.h> /* SHCreateDirectoryEx () */
|
||||
|
@ -327,6 +328,22 @@ tr_sys_path_get_info (const char * path,
|
|||
return ret;
|
||||
}
|
||||
|
||||
bool
|
||||
tr_sys_path_is_relative (const char * path)
|
||||
{
|
||||
assert (path != NULL);
|
||||
|
||||
/* UNC path: `\\...`. */
|
||||
if (path[0] == '\\' && path[1] == '\\')
|
||||
return false;
|
||||
|
||||
/* Local path: `X:` or `X:\...`. */
|
||||
if (isalpha (path[0]) && path[1] == ':' && (path[2] == '\0' || path[2] == '\\' || path[2] == '/'))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
tr_sys_path_is_same (const char * path1,
|
||||
const char * path2,
|
||||
|
|
|
@ -156,6 +156,17 @@ bool tr_sys_path_get_info (const char * path,
|
|||
bool tr_sys_path_exists (const char * path,
|
||||
struct tr_error ** error);
|
||||
|
||||
/**
|
||||
* @brief Check whether path is relative.
|
||||
*
|
||||
* This function only analyzes the string, so no error reporting is needed.
|
||||
*
|
||||
* @param[in] path Path to file or directory.
|
||||
*
|
||||
* @return `True` if path is relative, `false` otherwise
|
||||
*/
|
||||
bool tr_sys_path_is_relative (const char * path);
|
||||
|
||||
/**
|
||||
* @brief Test to see if the two filenames point to the same file.
|
||||
*
|
||||
|
|
|
@ -1343,6 +1343,9 @@ torrentSetLocation (tr_session * session,
|
|||
if (!tr_variantDictFindStr (args_in, TR_KEY_location, &location, NULL))
|
||||
return "no location";
|
||||
|
||||
if (tr_sys_path_is_relative (location))
|
||||
return "new location path is not absolute";
|
||||
|
||||
bool move;
|
||||
int i, torrentCount;
|
||||
tr_torrent ** torrents = getTorrents (session, args_in, &torrentCount);
|
||||
|
@ -1711,10 +1714,17 @@ torrentAdd (tr_session * session,
|
|||
if (!filename && !metainfo_base64)
|
||||
return "no filename or metainfo specified";
|
||||
|
||||
const char * download_dir = NULL;
|
||||
|
||||
if (tr_variantDictFindStr (args_in, TR_KEY_download_dir, &download_dir, NULL))
|
||||
{
|
||||
if (tr_sys_path_is_relative (download_dir))
|
||||
return "download directory path is not absolute";
|
||||
}
|
||||
|
||||
int64_t i;
|
||||
bool boolVal;
|
||||
tr_variant * l;
|
||||
const char * str;
|
||||
const char * cookies = NULL;
|
||||
tr_ctor * ctor = tr_ctorNew (session);
|
||||
|
||||
|
@ -1722,8 +1732,8 @@ torrentAdd (tr_session * session,
|
|||
|
||||
tr_variantDictFindStr (args_in, TR_KEY_cookies, &cookies, NULL);
|
||||
|
||||
if (tr_variantDictFindStr (args_in, TR_KEY_download_dir, &str, NULL))
|
||||
tr_ctorSetDownloadDir (ctor, TR_FORCE, str);
|
||||
if (download_dir != NULL)
|
||||
tr_ctorSetDownloadDir (ctor, TR_FORCE, download_dir);
|
||||
|
||||
if (tr_variantDictFindBool (args_in, TR_KEY_paused, &boolVal))
|
||||
tr_ctorSetPaused (ctor, TR_FORCE, boolVal);
|
||||
|
|
Loading…
Add table
Reference in a new issue