Skip to content

Commit 28b425f

Browse files
committed
fix #39351 (relative include fails on Solaris)
1 parent c1104b0 commit 28b425f

File tree

1 file changed

+59
-39
lines changed

1 file changed

+59
-39
lines changed

TSRM/tsrm_virtual_cwd.c

+59-39
Original file line numberDiff line numberDiff line change
@@ -473,8 +473,12 @@ CWD_API int virtual_file_ex(cwd_state *state, const char *path, verify_path_func
473473
realpath_cache_bucket *bucket;
474474
time_t t = 0;
475475
int ret;
476+
int use_cache;
477+
int use_relative_path = 0;
476478
TSRMLS_FETCH();
477479

480+
use_cache = ((use_realpath != CWD_EXPAND) && CWDG(realpath_cache_size_limit));
481+
478482
if (path_length == 0)
479483
return (0);
480484
if (path_length >= MAXPATHLEN)
@@ -487,27 +491,32 @@ CWD_API int virtual_file_ex(cwd_state *state, const char *path, verify_path_func
487491
/* cwd_length can be 0 when getcwd() fails.
488492
* This can happen under solaris when a dir does not have read permissions
489493
* but *does* have execute permissions */
490-
if (!IS_ABSOLUTE_PATH(path, path_length) && (state->cwd_length > 0)) {
491-
int orig_path_len;
492-
int state_cwd_length = state->cwd_length;
494+
if (!IS_ABSOLUTE_PATH(path, path_length)) {
495+
if (state->cwd_length == 0) {
496+
use_cache = 0;
497+
use_relative_path = 1;
498+
} else {
499+
int orig_path_len;
500+
int state_cwd_length = state->cwd_length;
493501

494502
#ifdef TSRM_WIN32
495-
if (IS_SLASH(path[0])) {
496-
state_cwd_length = 2;
497-
}
503+
if (IS_SLASH(path[0])) {
504+
state_cwd_length = 2;
505+
}
498506
#endif
499-
orig_path_len = path_length + state_cwd_length + 1;
500-
if (orig_path_len >= MAXPATHLEN) {
501-
return 1;
507+
orig_path_len = path_length + state_cwd_length + 1;
508+
if (orig_path_len >= MAXPATHLEN) {
509+
return 1;
510+
}
511+
memcpy(orig_path, state->cwd, state_cwd_length);
512+
orig_path[state_cwd_length] = DEFAULT_SLASH;
513+
memcpy(orig_path + state_cwd_length + 1, path, path_length + 1);
514+
path = orig_path;
515+
path_length = orig_path_len;
502516
}
503-
memcpy(orig_path, state->cwd, state_cwd_length);
504-
orig_path[state_cwd_length] = DEFAULT_SLASH;
505-
memcpy(orig_path + state_cwd_length + 1, path, path_length + 1);
506-
path = orig_path;
507-
path_length = orig_path_len;
508517
}
509518

510-
if (use_realpath != CWD_EXPAND && CWDG(realpath_cache_size_limit)) {
519+
if (use_cache) {
511520
t = CWDG(realpath_cache_ttl)?time(NULL):0;
512521
if ((bucket = realpath_cache_find(path, path_length, t TSRMLS_CC)) != NULL) {
513522
int len = bucket->realpath_len;
@@ -590,6 +599,12 @@ CWD_API int virtual_file_ex(cwd_state *state, const char *path, verify_path_func
590599
if (IS_DIRECTORY_UP(ptr, ptr_length)) {
591600
char save;
592601

602+
if (use_relative_path) {
603+
CWD_STATE_FREE(state);
604+
*state = old_state;
605+
return 1;
606+
}
607+
593608
save = DEFAULT_SLASH;
594609

595610
#define PREVIOUS state->cwd[state->cwd_length - 1]
@@ -609,33 +624,38 @@ CWD_API int virtual_file_ex(cwd_state *state, const char *path, verify_path_func
609624
state->cwd_length--;
610625
}
611626
} else if (!IS_DIRECTORY_CURRENT(ptr, ptr_length)) {
612-
state->cwd = (char *) realloc(state->cwd, state->cwd_length+ptr_length+1+1);
627+
if (use_relative_path) {
628+
state->cwd = (char *) realloc(state->cwd, state->cwd_length+ptr_length+1);
629+
use_relative_path = 0;
630+
} else {
631+
state->cwd = (char *) realloc(state->cwd, state->cwd_length+ptr_length+1+1);
613632
#ifdef TSRM_WIN32
614-
/* Windows 9x will consider C:\\Foo as a network path. Avoid it. */
615-
if (state->cwd_length < 2 ||
616-
(state->cwd[state->cwd_length-1]!='\\' && state->cwd[state->cwd_length-1]!='/') ||
617-
IsDBCSLeadByte(state->cwd[state->cwd_length-2])) {
618-
state->cwd[state->cwd_length++] = DEFAULT_SLASH;
619-
}
633+
/* Windows 9x will consider C:\\Foo as a network path. Avoid it. */
634+
if (state->cwd_length < 2 ||
635+
(state->cwd[state->cwd_length-1]!='\\' && state->cwd[state->cwd_length-1]!='/') ||
636+
IsDBCSLeadByte(state->cwd[state->cwd_length-2])) {
637+
state->cwd[state->cwd_length++] = DEFAULT_SLASH;
638+
}
620639
#elif defined(NETWARE)
621-
/*
622-
Below code keeps appending to state->cwd a File system seperator
623-
cases where this appending should not happen is given below,
624-
a) sys: should just be left as it is
625-
b) sys:system should just be left as it is,
626-
Colon is allowed only in the first token as volume names alone can have the : in their names.
627-
Files and Directories cannot have : in their names
628-
So the check goes like this,
629-
For second token and above simply append the DEFAULT_SLASH to the state->cwd.
630-
For first token check for the existence of :
631-
if it exists don't append the DEFAULT_SLASH to the state->cwd.
632-
*/
633-
if(((state->cwd_length == 0) && (strchr(ptr, ':') == NULL)) || (state->cwd_length > 0)) {
634-
state->cwd[state->cwd_length++] = DEFAULT_SLASH;
635-
}
640+
/*
641+
Below code keeps appending to state->cwd a File system seperator
642+
cases where this appending should not happen is given below,
643+
a) sys: should just be left as it is
644+
b) sys:system should just be left as it is,
645+
Colon is allowed only in the first token as volume names alone can have the : in their names.
646+
Files and Directories cannot have : in their names
647+
So the check goes like this,
648+
For second token and above simply append the DEFAULT_SLASH to the state->cwd.
649+
For first token check for the existence of :
650+
if it exists don't append the DEFAULT_SLASH to the state->cwd.
651+
*/
652+
if(((state->cwd_length == 0) && (strchr(ptr, ':') == NULL)) || (state->cwd_length > 0)) {
653+
state->cwd[state->cwd_length++] = DEFAULT_SLASH;
654+
}
636655
#else
637-
state->cwd[state->cwd_length++] = DEFAULT_SLASH;
656+
state->cwd[state->cwd_length++] = DEFAULT_SLASH;
638657
#endif
658+
}
639659
memcpy(&state->cwd[state->cwd_length], ptr, ptr_length+1);
640660

641661
#ifdef TSRM_WIN32
@@ -686,7 +706,7 @@ CWD_API int virtual_file_ex(cwd_state *state, const char *path, verify_path_func
686706
}
687707
}
688708

689-
if (use_realpath != CWD_EXPAND && CWDG(realpath_cache_size_limit)) {
709+
if (use_cache) {
690710
realpath_cache_add(path, path_length, state->cwd, state->cwd_length, t TSRMLS_CC);
691711
}
692712

0 commit comments

Comments
 (0)