| | @@ -703,11 +703,11 @@ |
| 703 | 703 | } |
| 704 | 704 | } |
| 705 | 705 | if( j>=0 ) z[j] = z[i]; |
| 706 | 706 | j++; |
| 707 | 707 | } |
| 708 | | - if( j==0 ) z[j++] = '.'; |
| 708 | + if( j==0 ) z[j++] = '/'; |
| 709 | 709 | z[j] = 0; |
| 710 | 710 | return j; |
| 711 | 711 | } |
| 712 | 712 | |
| 713 | 713 | /* |
| | @@ -777,39 +777,40 @@ |
| 777 | 777 | ** Convert /A/../ to just / |
| 778 | 778 | ** If the slash parameter is non-zero, the trailing slash, if any, |
| 779 | 779 | ** is retained. |
| 780 | 780 | */ |
| 781 | 781 | void file_canonical_name(const char *zOrigName, Blob *pOut, int slash){ |
| 782 | + blob_zero(pOut); |
| 782 | 783 | if( file_is_absolute_path(zOrigName) ){ |
| 783 | | -#if defined(_WIN32) || defined(__CYGWIN__) |
| 784 | | - char *zOut; |
| 785 | | -#endif |
| 786 | | - blob_set(pOut, zOrigName); |
| 787 | | - blob_materialize(pOut); |
| 784 | + blob_appendf(pOut, "%/", zOrigName); |
| 785 | + }else{ |
| 786 | + char zPwd[2000]; |
| 787 | + file_getcwd(zPwd, sizeof(zPwd)-strlen(zOrigName)); |
| 788 | + if( zPwd[0]=='/' && strlen(zPwd)==1 ){ |
| 789 | + // when on '/', don't add an extra '/' |
| 790 | + if( zOrigName[0]=='.' && strlen(zOrigName)==1 ){ |
| 791 | + // '.' when on '/' mean '/' |
| 792 | + blob_appendf(pOut, "%/", zPwd); |
| 793 | + }else{ |
| 794 | + blob_appendf(pOut, "%/%/", zPwd, zOrigName); |
| 795 | + } |
| 796 | + }else{ |
| 797 | + blob_appendf(pOut, "%//%/", zPwd, zOrigName); |
| 798 | + } |
| 799 | + } |
| 788 | 800 | #if defined(_WIN32) || defined(__CYGWIN__) |
| 801 | + { |
| 802 | + char *zOut; |
| 789 | 803 | /* |
| 790 | 804 | ** On Windows/cygwin, normalize the drive letter to upper case. |
| 791 | 805 | */ |
| 792 | 806 | zOut = blob_str(pOut); |
| 793 | | - if( fossil_islower(zOut[0]) && zOut[1]==':' ){ |
| 807 | + if( fossil_islower(zOut[0]) && zOut[1]==':' && zOut[2]=='/' ){ |
| 794 | 808 | zOut[0] = fossil_toupper(zOut[0]); |
| 795 | 809 | } |
| 796 | | -#endif |
| 797 | | - }else{ |
| 798 | | - char zPwd[2000]; |
| 799 | | - file_getcwd(zPwd, sizeof(zPwd)-strlen(zOrigName)); |
| 800 | | -#if defined(_WIN32) |
| 801 | | - /* |
| 802 | | - ** On Windows, normalize the drive letter to upper case. |
| 803 | | - */ |
| 804 | | - if( fossil_islower(zPwd[0]) && zPwd[1]==':' ){ |
| 805 | | - zPwd[0] = fossil_toupper(zPwd[0]); |
| 806 | | - } |
| 807 | | -#endif |
| 808 | | - blob_zero(pOut); |
| 809 | | - blob_appendf(pOut, "%//%/", zPwd, zOrigName); |
| 810 | | - } |
| 810 | + } |
| 811 | +#endif |
| 811 | 812 | blob_resize(pOut, file_simplify_name(blob_buffer(pOut), |
| 812 | 813 | blob_size(pOut), slash)); |
| 813 | 814 | } |
| 814 | 815 | |
| 815 | 816 | /* |
| | @@ -928,11 +929,16 @@ |
| 928 | 929 | blob_append(pOut, &zPath[i+1], -1); |
| 929 | 930 | blob_reset(&tmp); |
| 930 | 931 | return; |
| 931 | 932 | } |
| 932 | 933 | while( zPath[i-1]!='/' ){ i--; } |
| 933 | | - blob_set(&tmp, "../"); |
| 934 | + if( zPwd[0]=='/' && strlen(zPwd)==1 ){ |
| 935 | + // If on '/', don't go to higher level |
| 936 | + blob_zero(&tmp); |
| 937 | + }else{ |
| 938 | + blob_set(&tmp, "../"); |
| 939 | + } |
| 934 | 940 | for(j=i; zPwd[j]; j++){ |
| 935 | 941 | if( zPwd[j]=='/' ){ |
| 936 | 942 | blob_append(&tmp, "../", 3); |
| 937 | 943 | } |
| 938 | 944 | } |
| | @@ -990,11 +996,12 @@ |
| 990 | 996 | }else{ |
| 991 | 997 | xCmp = fossil_strnicmp; |
| 992 | 998 | } |
| 993 | 999 | |
| 994 | 1000 | /* Special case. zOrigName refers to g.zLocalRoot directory. */ |
| 995 | | - if( nFull==nLocalRoot-1 && xCmp(zLocalRoot, zFull, nFull)==0 ){ |
| 1001 | + if( (nFull==nLocalRoot-1 && xCmp(zLocalRoot, zFull, nFull)==0) |
| 1002 | + || (nFull==1 && zFull[0]=='/' && nLocalRoot==1 && zLocalRoot[0]=='/') ){ |
| 996 | 1003 | blob_append(pOut, ".", 1); |
| 997 | 1004 | blob_reset(&localRoot); |
| 998 | 1005 | blob_reset(&full); |
| 999 | 1006 | return 1; |
| 1000 | 1007 | } |
| 1001 | 1008 | |