diff options
author | Craig A. Berry <craigberry@mac.com> | 2012-12-02 15:17:55 -0600 |
---|---|---|
committer | Craig A. Berry <craigberry@mac.com> | 2012-12-02 15:17:55 -0600 |
commit | c1abd561a0a322ca22ba5ef8301a708c37336afb (patch) | |
tree | 00daa9b60c3aefb13ec0143b1ed50175141bd49f /vms | |
parent | a84b1d1f981773674baedc3f054c82b3243c6136 (diff) | |
download | perl-c1abd561a0a322ca22ba5ef8301a708c37336afb.tar.gz |
Better escaping of dots in tovmsspec.
When converting a filename with multiple dots to native VMS syntax,
it's necessary to escape all but the last dot with a caret ('^').
We've been doing this for some time, but have been doing it blindly
such that multiple trips through the converter resulted in a
stuttering caret problem (e.g., foo^^^.bar.pl when foo^.bar.pl was
intended).
So create a convenience macro that does the escaping and make it
only escape unescaped instances and also make it check that the
escape doesn't push us off the end of the buffer we are working
on.
Use the new macro in the three most obvious places that it's
applicable. There may be other places that also should use it.
Diffstat (limited to 'vms')
-rw-r--r-- | vms/vms.c | 24 |
1 files changed, 17 insertions, 7 deletions
@@ -8248,7 +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). + */ +#define VMSEFS_ESCAPE_DOT(vmsefsdot,vmsefsbuf,vmsefsbufsiz) STMT_START { \ + if ( ((vmsefsdot) > (vmsefsbuf) && *((vmsefsdot) - 1) != '^' \ + || ((vmsefsdot) == (vmsefsbuf))) \ + && (vmsefsdot) < (vmsefsbuf) + (vmsefsbufsiz) - 2 \ + ) { \ + *((vmsefsdot)++) = '^'; \ + *((vmsefsdot)++) = '.'; \ + } \ +} STMT_END /*{{{ char *tovmsspec[_ts](char *path, char *buf, int * utf8_flag)*/ static char *int_tovmsspec @@ -8536,8 +8549,7 @@ static char *int_tovmsspec if (decc_efs_charset == 0) *(cp1++) = '_'; /* fix up syntax - '.' in name not allowed */ else { - *(cp1++) = '^'; /* fix up syntax - '.' in name is allowed */ - *(cp1++) = '.'; + VMSEFS_ESCAPE_DOT(cp1, rslt, VMS_MAXRSS); } } } @@ -8547,8 +8559,7 @@ static char *int_tovmsspec if (decc_efs_charset == 0) *(cp1++) = '_'; else { - *(cp1++) = '^'; - *(cp1++) = '.'; + VMSEFS_ESCAPE_DOT(cp1, rslt, VMS_MAXRSS); } } else *(cp1++) = *cp2; @@ -8578,8 +8589,7 @@ static char *int_tovmsspec case '.': if (((cp2 < lastdot) || (cp2[1] == '\0')) && decc_readdir_dropdotnotype) { - *(cp1)++ = '^'; - *(cp1)++ = '.'; + VMSEFS_ESCAPE_DOT(cp1, rslt, VMS_MAXRSS); cp2++; /* trailing dot ==> '^..' on VMS */ |