Changeset 14264
- Timestamp:
- Apr 27, 2014, 8:17:16 PM (9 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/libtransmission/metainfo.c
r14241 r14264 31 31 ***/ 32 32 33 34 #ifdef WIN32 35 #define PATH_DELIMITER_CHARS "/\\" 36 #else 37 #define PATH_DELIMITER_CHARS "/" 38 #endif 39 40 static inline bool 41 char_is_path_separator (char c) 42 { 43 return strchr(PATH_DELIMITER_CHARS, c) != NULL; 44 } 45 33 46 char* 34 47 tr_metainfoGetBasename (const tr_info * inf) … … 40 53 41 54 for (i=0; i<name_len; ++i) 42 if ( ret[i] == '/')55 if (char_is_path_separator (ret[i])) 43 56 ret[i] = '_'; 44 57 … … 61 74 62 75 static bool 63 path_is_suspicious (const char * path) 64 { 65 return (path == NULL) 66 || (!strncmp (path, "../", 3)) 67 || (strstr (path, "/../") != NULL); 76 path_component_is_suspicious (const char * component) 77 { 78 return (component == NULL) 79 || (*component == '\0') 80 || (strpbrk (component, PATH_DELIMITER_CHARS) != NULL) 81 || (strcmp (component, ".") == 0) 82 || (strcmp (component, "..") == 0); 68 83 } 69 84 … … 73 88 bool success = false; 74 89 90 *setme = NULL; 91 92 /* root's already been checked by caller */ 93 assert (!path_component_is_suspicious (root)); 94 75 95 if (tr_variantIsList (path)) 76 96 { … … 78 98 const int n = tr_variantListSize (path); 79 99 100 success = true; 80 101 evbuffer_drain (buf, evbuffer_get_length (buf)); 81 102 evbuffer_add (buf, root, strlen (root)); 103 82 104 for (i=0; i<n; i++) 83 105 { … … 85 107 const char * str; 86 108 87 if (tr_variantGetStr (tr_variantListChild (path, i), &str, &len)) 109 if (!tr_variantGetStr (tr_variantListChild (path, i), &str, &len) || 110 path_component_is_suspicious (str)) 88 111 { 89 evbuffer_add (buf, TR_PATH_DELIMITER_STR, 1);90 evbuffer_add (buf, str, len);112 success = false; 113 break; 91 114 } 92 } 93 115 116 evbuffer_add (buf, TR_PATH_DELIMITER_STR, 1); 117 evbuffer_add (buf, str, len); 118 } 119 } 120 121 if (success) 122 { 94 123 *setme = tr_utf8clean ((char*)evbuffer_pullup (buf, -1), evbuffer_get_length (buf)); 95 /* fprintf (stderr, "[%s]\n", *setme); */ 96 success = true; 97 } 98 99 if ((*setme != NULL) && path_is_suspicious (*setme)) 100 { 101 tr_free (*setme); 102 *setme = NULL; 103 success = false; 124 /*fprintf (stderr, "[%s]\n", *setme);*/ 104 125 } 105 126 … … 117 138 { 118 139 tr_file_index_t i; 119 struct evbuffer * buf = evbuffer_new (); 140 struct evbuffer * buf; 141 const char * result; 142 143 if (path_component_is_suspicious (inf->name)) 144 return "path"; 145 146 buf = evbuffer_new (); 147 result = NULL; 120 148 121 149 inf->isMultifile = 1; … … 130 158 file = tr_variantListChild (files, i); 131 159 if (!tr_variantIsDict (file)) 132 return "files"; 160 { 161 result = "files"; 162 break; 163 } 133 164 134 165 if (!tr_variantDictFindList (file, TR_KEY_path_utf_8, &path)) 135 166 if (!tr_variantDictFindList (file, TR_KEY_path, &path)) 136 return "path"; 167 { 168 result = "path"; 169 break; 170 } 137 171 138 172 if (!getfile (&inf->files[i].name, inf->name, path, buf)) 139 return "path"; 173 { 174 result = "path"; 175 break; 176 } 140 177 141 178 if (!tr_variantDictFindInt (file, TR_KEY_length, &len)) 142 return "length"; 179 { 180 result = "length"; 181 break; 182 } 143 183 144 184 inf->files[i].length = len; … … 147 187 148 188 evbuffer_free (buf); 189 return result; 149 190 } 150 191 else if (tr_variantGetInt (length, &len)) /* single-file mode */ 151 192 { 152 if (path_ is_suspicious (inf->name))193 if (path_component_is_suspicious (inf->name)) 153 194 return "path"; 154 195
Note: See TracChangeset
for help on using the changeset viewer.