1 /* Mednafen - Multi-system Emulator
2 *
3 * This program is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License as published by
5 * the Free Software Foundation; either version 2 of the License, or
6 * (at your option) any later version.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program; if not, write to the Free Software
15 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
16 */
17
18 #include "mednafen.h"
19
20 #include <string.h>
21 #include <stdarg.h>
22
23 #include <sys/types.h>
24
25 #include <string>
26
27 #include "general.h"
28 #include "state.h"
29
30 using namespace std;
31
IsAbsolutePath(const char * path)32 static bool IsAbsolutePath(const char *path)
33 {
34 if (
35 #ifdef _WIN32
36 path[0] == '\\' ||
37 #endif
38 path[0] == '/'
39 )
40 return(TRUE);
41
42 #if defined(WIN32) || defined(DOS)
43 if((path[0] >= 'a' && path[0] <= 'z') || (path[0] >= 'A' && path[0] <= 'Z'))
44 {
45 if(path[1] == ':')
46 return(TRUE);
47 }
48 #endif
49
50 return(FALSE);
51 }
52
IsAbsolutePath(const std::string & path)53 static bool IsAbsolutePath(const std::string &path)
54 {
55 return(IsAbsolutePath(path.c_str()));
56 }
57
MDFN_IsFIROPSafe(const std::string & path)58 bool MDFN_IsFIROPSafe(const std::string &path)
59 {
60 // We could make this more OS-specific, but it shouldn't hurt to try to weed out usage of characters that are path
61 // separators in one OS but not in another, and we'd also run more of a risk of missing a special path separator case
62 // in some OS.
63
64 if(!MDFN_GetSettingB("filesys.untrusted_fip_check"))
65 return(true);
66
67 if(path.find('\0') != string::npos)
68 return(false);
69
70 if(path.find(':') != string::npos)
71 return(false);
72
73 if(path.find('\\') != string::npos)
74 return(false);
75
76 if(path.find('/') != string::npos)
77 return(false);
78
79 return(true);
80 }
81
MDFN_GetFilePathComponents(const std::string & file_path,std::string * dir_path_out,std::string * file_base_out,std::string * file_ext_out)82 void MDFN_GetFilePathComponents(const std::string &file_path,
83 std::string *dir_path_out, std::string *file_base_out,
84 std::string *file_ext_out)
85 {
86 size_t final_ds; // in file_path
87 string file_name;
88 size_t fn_final_dot; // in local var file_name
89 string dir_path, file_base, file_ext; // Temporary output
90
91 #ifdef _WIN32
92 final_ds = file_path.find_last_of('\\');
93
94 size_t alt_final_ds = file_path.find_last_of('/');
95
96 if(final_ds == string::npos || (alt_final_ds != string::npos && alt_final_ds > final_ds))
97 final_ds = alt_final_ds;
98 #else
99 final_ds = file_path.find_last_of('/');
100 #endif
101
102 if(final_ds == string::npos)
103 {
104 dir_path = string(".");
105 file_name = file_path;
106 }
107 else
108 {
109 dir_path = file_path.substr(0, final_ds);
110 file_name = file_path.substr(final_ds + 1);
111 }
112
113 fn_final_dot = file_name.find_last_of('.');
114
115 if(fn_final_dot != string::npos)
116 {
117 file_base = file_name.substr(0, fn_final_dot);
118 file_ext = file_name.substr(fn_final_dot);
119 }
120 else
121 {
122 file_base = file_name;
123 file_ext = string("");
124 }
125
126 if(dir_path_out)
127 *dir_path_out = dir_path;
128
129 if(file_base_out)
130 *file_base_out = file_base;
131
132 if(file_ext_out)
133 *file_ext_out = file_ext;
134 }
135
MDFN_EvalFIP(const std::string & dir_path,const std::string & rel_path,bool skip_safety_check)136 std::string MDFN_EvalFIP(const std::string &dir_path, const std::string &rel_path, bool skip_safety_check)
137 {
138 char slash;
139 #ifdef _WIN32
140 slash = '\\';
141 #else
142 slash = '/';
143 #endif
144
145 if(!skip_safety_check && !MDFN_IsFIROPSafe(rel_path))
146 throw MDFN_Error(0, _("Referenced path \"%s\" is potentially unsafe. See \"filesys.untrusted_fip_check\" setting.\n"), rel_path.c_str());
147
148 if(IsAbsolutePath(rel_path.c_str()))
149 return(rel_path);
150 else
151 return(dir_path + slash + rel_path);
152 }
153
GetFNComponent(const char * str)154 const char * GetFNComponent(const char *str)
155 {
156 const char *tp1;
157
158 #ifdef _WIN32
159 tp1 = ((char *)strrchr(str,'\\'));
160
161 const char *tp3;
162
163 tp3 = ((char *)strrchr(str,'/'));
164
165 if (tp1<tp3)
166 tp1 = tp3;
167 #else
168 tp1 = ((char *)strrchr(str,'/'));
169 #endif
170
171 if (tp1)
172 return (tp1+1);
173 else
174 return (str);
175 }
176