@@ -473,8 +473,12 @@ CWD_API int virtual_file_ex(cwd_state *state, const char *path, verify_path_func
473
473
realpath_cache_bucket * bucket ;
474
474
time_t t = 0 ;
475
475
int ret ;
476
+ int use_cache ;
477
+ int use_relative_path = 0 ;
476
478
TSRMLS_FETCH ();
477
479
480
+ use_cache = ((use_realpath != CWD_EXPAND ) && CWDG (realpath_cache_size_limit ));
481
+
478
482
if (path_length == 0 )
479
483
return (0 );
480
484
if (path_length >= MAXPATHLEN )
@@ -487,27 +491,32 @@ CWD_API int virtual_file_ex(cwd_state *state, const char *path, verify_path_func
487
491
/* cwd_length can be 0 when getcwd() fails.
488
492
* This can happen under solaris when a dir does not have read permissions
489
493
* 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 ;
493
501
494
502
#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
+ }
498
506
#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 ;
502
516
}
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 ;
508
517
}
509
518
510
- if (use_realpath != CWD_EXPAND && CWDG ( realpath_cache_size_limit ) ) {
519
+ if (use_cache ) {
511
520
t = CWDG (realpath_cache_ttl )?time (NULL ):0 ;
512
521
if ((bucket = realpath_cache_find (path , path_length , t TSRMLS_CC )) != NULL ) {
513
522
int len = bucket -> realpath_len ;
@@ -590,6 +599,12 @@ CWD_API int virtual_file_ex(cwd_state *state, const char *path, verify_path_func
590
599
if (IS_DIRECTORY_UP (ptr , ptr_length )) {
591
600
char save ;
592
601
602
+ if (use_relative_path ) {
603
+ CWD_STATE_FREE (state );
604
+ * state = old_state ;
605
+ return 1 ;
606
+ }
607
+
593
608
save = DEFAULT_SLASH ;
594
609
595
610
#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
609
624
state -> cwd_length -- ;
610
625
}
611
626
} 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 );
613
632
#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
+ }
620
639
#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
+ }
636
655
#else
637
- state -> cwd [state -> cwd_length ++ ] = DEFAULT_SLASH ;
656
+ state -> cwd [state -> cwd_length ++ ] = DEFAULT_SLASH ;
638
657
#endif
658
+ }
639
659
memcpy (& state -> cwd [state -> cwd_length ], ptr , ptr_length + 1 );
640
660
641
661
#ifdef TSRM_WIN32
@@ -686,7 +706,7 @@ CWD_API int virtual_file_ex(cwd_state *state, const char *path, verify_path_func
686
706
}
687
707
}
688
708
689
- if (use_realpath != CWD_EXPAND && CWDG ( realpath_cache_size_limit ) ) {
709
+ if (use_cache ) {
690
710
realpath_cache_add (path , path_length , state -> cwd , state -> cwd_length , t TSRMLS_CC );
691
711
}
692
712
0 commit comments