diff options
author | Craig A. Berry <craigberry@mac.com> | 2012-12-14 08:29:55 -0600 |
---|---|---|
committer | Craig A. Berry <craigberry@mac.com> | 2012-12-14 08:50:11 -0600 |
commit | b7bc7afbe074add30fdf01d619e7cfef04b07403 (patch) | |
tree | fe3fdb1a20c9f0bceee06416419cee40215ddd94 /vms/vms.c | |
parent | 35c9969e6e0005027f32d516744606751dcaab67 (diff) | |
download | perl-b7bc7afbe074add30fdf01d619e7cfef04b07403.tar.gz |
More fun escaping dots in tovmsspec.
c1abd561a0a322 avoided the double escaping of dots in filenames,
but failed to copy the dot itself in cases where it was already
escaped. Plus, when not using extended file specifications and
thus converting the dot to an underscore, we need to make sure
the underscore is not escaped.
And add a test that covers most of these scenarios. Probably
more tests are needed.
Diffstat (limited to 'vms/vms.c')
-rw-r--r-- | vms/vms.c | 31 |
1 files changed, 19 insertions, 12 deletions
@@ -8248,19 +8248,20 @@ int utf8_flag; return result; } -/* A convenience macro for escaping dots that haven't already been - * escaped, with guards to avoid checking before the start of the - * buffer or advancing beyond the end of it (allowing room for the - * NUL terminator). +/* A convenience macro for copying dots in filenames and escaping + * them when they haven't already been escaped, with guards to + * avoid checking before the start of the buffer or advancing + * beyond the end of it (allowing room for the NUL terminator). */ -#define VMSEFS_ESCAPE_DOT(vmsefsdot,vmsefsbuf,vmsefsbufsiz) STMT_START { \ +#define VMSEFS_DOT_WITH_ESCAPE(vmsefsdot,vmsefsbuf,vmsefsbufsiz) STMT_START { \ if ( ((vmsefsdot) > (vmsefsbuf) && *((vmsefsdot) - 1) != '^' \ || ((vmsefsdot) == (vmsefsbuf))) \ - && (vmsefsdot) < (vmsefsbuf) + (vmsefsbufsiz) - 2 \ + && (vmsefsdot) < (vmsefsbuf) + (vmsefsbufsiz) - 3 \ ) { \ *((vmsefsdot)++) = '^'; \ - *((vmsefsdot)++) = '.'; \ } \ + if ((vmsefsdot) < (vmsefsbuf) + (vmsefsbufsiz) - 2) \ + *((vmsefsdot)++) = '.'; \ } STMT_END /*{{{ char *tovmsspec[_ts](char *path, char *buf, int * utf8_flag)*/ @@ -8546,20 +8547,26 @@ static char *int_tovmsspec else cp2 += 3; /* Trailing '/' was there, so skip it, too */ } else { - if (decc_efs_charset == 0) + if (decc_efs_charset == 0) { + if (*(cp1-1) == '^') + cp1--; /* remove the escape, if any */ *(cp1++) = '_'; /* fix up syntax - '.' in name not allowed */ + } else { - VMSEFS_ESCAPE_DOT(cp1, rslt, VMS_MAXRSS); + VMSEFS_DOT_WITH_ESCAPE(cp1, rslt, VMS_MAXRSS); } } } else { if (!infront && *(cp1-1) == '-') *(cp1++) = '.'; if (*cp2 == '.') { - if (decc_efs_charset == 0) + if (decc_efs_charset == 0) { + if (*(cp1-1) == '^') + cp1--; /* remove the escape, if any */ *(cp1++) = '_'; + } else { - VMSEFS_ESCAPE_DOT(cp1, rslt, VMS_MAXRSS); + VMSEFS_DOT_WITH_ESCAPE(cp1, rslt, VMS_MAXRSS); } } else *(cp1++) = *cp2; @@ -8590,7 +8597,7 @@ static char *int_tovmsspec case '.': if (((cp2 < lastdot) || (cp2[1] == '\0')) && decc_readdir_dropdotnotype) { - VMSEFS_ESCAPE_DOT(cp1, rslt, VMS_MAXRSS); + VMSEFS_DOT_WITH_ESCAPE(cp1, rslt, VMS_MAXRSS); cp2++; /* trailing dot ==> '^..' on VMS */ |