Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit e296ced

Browse files
committed
Be more rigorous about making pathnames absolute, to address SF bug
#424002. Refactor init_path_from_argv0() and rename to copy_absolute(); add absolutize() which does the same in-place. Clean up whitespace (leading tabs -> spaces, delete trailing spaces/tabs).
1 parent 746fe0f commit e296ced

1 file changed

Lines changed: 58 additions & 53 deletions

File tree

Modules/getpath.c

Lines changed: 58 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -113,13 +113,13 @@
113113

114114
#ifndef PYTHONPATH
115115
#define PYTHONPATH PREFIX "/lib/python" VERSION ":" \
116-
EXEC_PREFIX "/lib/python" VERSION "/lib-dynload"
116+
EXEC_PREFIX "/lib/python" VERSION "/lib-dynload"
117117
#endif
118118

119119
#ifndef LANDMARK
120120
#define LANDMARK "os.py"
121121
#endif
122-
122+
123123
static char prefix[MAXPATHLEN+1];
124124
static char exec_prefix[MAXPATHLEN+1];
125125
static char progpath[MAXPATHLEN+1];
@@ -137,7 +137,7 @@ reduce(char *dir)
137137

138138

139139
static int
140-
isfile(char *filename) /* Is file, not directory */
140+
isfile(char *filename) /* Is file, not directory */
141141
{
142142
struct stat buf;
143143
if (stat(filename, &buf) != 0)
@@ -149,7 +149,7 @@ isfile(char *filename) /* Is file, not directory */
149149

150150

151151
static int
152-
ismodule(char *filename) /* Is module -- check for .pyc/.pyo too */
152+
ismodule(char *filename) /* Is module -- check for .pyc/.pyo too */
153153
{
154154
if (isfile(filename))
155155
return 1;
@@ -165,7 +165,7 @@ ismodule(char *filename) /* Is module -- check for .pyc/.pyo too */
165165

166166

167167
static int
168-
isxfile(char *filename) /* Is executable file */
168+
isxfile(char *filename) /* Is executable file */
169169
{
170170
struct stat buf;
171171
if (stat(filename, &buf) != 0)
@@ -179,7 +179,7 @@ isxfile(char *filename) /* Is executable file */
179179

180180

181181
static int
182-
isdir(char *filename) /* Is directory */
182+
isdir(char *filename) /* Is directory */
183183
{
184184
struct stat buf;
185185
if (stat(filename, &buf) != 0)
@@ -213,29 +213,34 @@ joinpath(char *buffer, char *stuff)
213213
buffer[n+k] = '\0';
214214
}
215215

216-
/* init_path_from_argv0 requires that path be allocated at least
217-
MAXPATHLEN + 1 bytes and that argv0_path be no more than MAXPATHLEN
218-
bytes.
219-
*/
216+
/* copy_absolute requires that path be allocated at least
217+
MAXPATHLEN + 1 bytes and that p be no more than MAXPATHLEN bytes. */
220218
static void
221-
init_path_from_argv0(char *path, char *argv0_path)
219+
copy_absolute(char *path, char *p)
222220
{
223-
if (argv0_path[0] == '/')
224-
strcpy(path, argv0_path);
225-
else if (argv0_path[0] == '.') {
226-
getcwd(path, MAXPATHLEN);
227-
if (argv0_path[1] == '/')
228-
joinpath(path, argv0_path + 2);
229-
else
230-
joinpath(path, argv0_path);
231-
}
221+
if (p[0] == SEP)
222+
strcpy(path, p);
232223
else {
233-
getcwd(path, MAXPATHLEN);
234-
joinpath(path, argv0_path);
224+
getcwd(path, MAXPATHLEN);
225+
if (p[0] == '.' && p[1] == SEP)
226+
p += 2;
227+
joinpath(path, p);
235228
}
236229
}
237230

238-
/* search_for_prefix requires that argv0_path be no more than MAXPATHLEN
231+
/* absolutize() requires that path be allocated at least MAXPATHLEN+1 bytes. */
232+
static void
233+
absolutize(char *path)
234+
{
235+
char buffer[MAXPATHLEN + 1];
236+
237+
if (path[0] == SEP)
238+
return;
239+
copy_absolute(buffer, path);
240+
strcpy(path, buffer);
241+
}
242+
243+
/* search_for_prefix requires that argv0_path be no more than MAXPATHLEN
239244
bytes long.
240245
*/
241246
static int
@@ -271,7 +276,7 @@ search_for_prefix(char *argv0_path, char *home)
271276
}
272277

273278
/* Search from argv0_path, until root is found */
274-
init_path_from_argv0(prefix, argv0_path);
279+
copy_absolute(prefix, argv0_path);
275280
do {
276281
n = strlen(prefix);
277282
joinpath(prefix, lib_python);
@@ -295,7 +300,7 @@ search_for_prefix(char *argv0_path, char *home)
295300

296301

297302
/* search_for_exec_prefix requires that argv0_path be no more than
298-
MAXPATHLEN bytes long.
303+
MAXPATHLEN bytes long.
299304
*/
300305
static int
301306
search_for_exec_prefix(char *argv0_path, char *home)
@@ -324,7 +329,7 @@ search_for_exec_prefix(char *argv0_path, char *home)
324329
}
325330

326331
/* Search from argv0_path, until root is found */
327-
init_path_from_argv0(exec_prefix, argv0_path);
332+
copy_absolute(exec_prefix, argv0_path);
328333
do {
329334
n = strlen(exec_prefix);
330335
joinpath(exec_prefix, lib_python);
@@ -368,7 +373,7 @@ calculate_path(void)
368373
#ifdef WITH_NEXT_FRAMEWORK
369374
NSModule pythonModule;
370375
#endif
371-
376+
372377
#ifdef WITH_NEXT_FRAMEWORK
373378
pythonModule = NSModuleForSymbol(NSLookupAndBindSymbol("_Py_Initialize"));
374379
/* Use dylib functions to find out where the framework was loaded from */
@@ -387,42 +392,40 @@ calculate_path(void)
387392
joinpath(argv0_path, lib_python);
388393
joinpath(argv0_path, LANDMARK);
389394
if (!ismodule(argv0_path)) {
390-
/* We are in the build directory so use the name of the
391-
executable - we know that the absolute path is passed */
392-
strncpy(progpath, prog, MAXPATHLEN);
395+
/* We are in the build directory so use the name of the
396+
executable - we know that the absolute path is passed */
397+
strncpy(progpath, prog, MAXPATHLEN);
393398
}
394399
else {
395-
/* Use the location of the library as the progpath */
396-
strncpy(progpath, buf, MAXPATHLEN);
400+
/* Use the location of the library as the progpath */
401+
strncpy(progpath, buf, MAXPATHLEN);
397402
}
398403
}
399404
else {
400405
/* If we're not in a framework, fall back to the old way
401406
(even though NSNameOfModule() probably does the same thing.) */
402407
#endif
403-
404-
/* If there is no slash in the argv0 path, then we have to
405-
* assume python is on the user's $PATH, since there's no
406-
* other way to find a directory to start the search from. If
407-
* $PATH isn't exported, you lose.
408-
*/
409-
if (strchr(prog, SEP))
408+
409+
/* If there is no slash in the argv0 path, then we have to
410+
* assume python is on the user's $PATH, since there's no
411+
* other way to find a directory to start the search from. If
412+
* $PATH isn't exported, you lose.
413+
*/
414+
if (strchr(prog, SEP))
410415
strncpy(progpath, prog, MAXPATHLEN);
411-
else if (path) {
412-
int bufspace = MAXPATHLEN;
416+
else if (path) {
413417
while (1) {
414418
char *delim = strchr(path, DELIM);
415419

416420
if (delim) {
417421
size_t len = delim - path;
418-
if (len > bufspace)
419-
len = bufspace;
422+
if (len > MAXPATHLEN)
423+
len = MAXPATHLEN;
420424
strncpy(progpath, path, len);
421425
*(progpath + len) = '\0';
422-
bufspace -= len;
423426
}
424427
else
425-
strncpy(progpath, path, bufspace);
428+
strncpy(progpath, path, MAXPATHLEN);
426429

427430
joinpath(progpath, prog);
428431
if (isxfile(progpath))
@@ -434,15 +437,17 @@ calculate_path(void)
434437
}
435438
path = delim + 1;
436439
}
437-
}
438-
else
440+
}
441+
else
439442
progpath[0] = '\0';
443+
if (progpath[0] != SEP)
444+
absolutize(progpath);
440445
#ifdef WITH_NEXT_FRAMEWORK
441446
}
442447
#endif
443448

444449
strncpy(argv0_path, progpath, MAXPATHLEN);
445-
450+
446451
#if HAVE_READLINK
447452
{
448453
char tmpbuffer[MAXPATHLEN+1];
@@ -451,8 +456,8 @@ calculate_path(void)
451456
/* It's not null terminated! */
452457
tmpbuffer[linklen] = '\0';
453458
if (tmpbuffer[0] == SEP)
454-
/* tmpbuffer should never be longer than MAXPATHLEN,
455-
but extra check does not hurt */
459+
/* tmpbuffer should never be longer than MAXPATHLEN,
460+
but extra check does not hurt */
456461
strncpy(argv0_path, tmpbuffer, MAXPATHLEN);
457462
else {
458463
/* Interpret relative to progpath */
@@ -472,17 +477,17 @@ calculate_path(void)
472477
if (!(pfound = search_for_prefix(argv0_path, home))) {
473478
if (!Py_FrozenFlag)
474479
fprintf(stderr,
475-
"Could not find platform independent libraries <prefix>\n");
480+
"Could not find platform independent libraries <prefix>\n");
476481
strncpy(prefix, PREFIX, MAXPATHLEN);
477482
joinpath(prefix, lib_python);
478483
}
479484
else
480485
reduce(prefix);
481-
486+
482487
if (!(efound = search_for_exec_prefix(argv0_path, home))) {
483488
if (!Py_FrozenFlag)
484489
fprintf(stderr,
485-
"Could not find platform dependent libraries <exec_prefix>\n");
490+
"Could not find platform dependent libraries <exec_prefix>\n");
486491
strncpy(exec_prefix, EXEC_PREFIX, MAXPATHLEN);
487492
joinpath(exec_prefix, "lib/lib-dynload");
488493
}

0 commit comments

Comments
 (0)