From adc11f0b907360e0200070e6c61df037613107d4 Mon Sep 17 00:00:00 2001 From: "Craig A. Berry" Date: Tue, 19 Jun 2007 12:29:32 +0000 Subject: [PATCH] Better handling of escapes in filenames when converting between VMS and Unix syntax. p4raw-id: //depot/perl@31421 --- vms/vms.c | 35 +++++++++++++++++++++++++++++++---- 1 file changed, 31 insertions(+), 4 deletions(-) diff --git a/vms/vms.c b/vms/vms.c index aaaa869..f361595 100644 --- a/vms/vms.c +++ b/vms/vms.c @@ -521,6 +521,16 @@ int utf8_flag; case ']': case '%': case '^': + /* Don't escape again if following character is + * already something we escape. + */ + if (strchr(".~!#&\'`()+@{},;[]%^=_", *(inspec+1))) { + *outspec = *inspec; + *output_cnt = 1; + return 1; + break; + } + /* But otherwise fall through and escape it. */ case '=': /* Assume that this is to be escaped */ outspec[0] = '^'; @@ -564,17 +574,26 @@ int scnt; if (*inspec == '^') { inspec++; switch (*inspec) { + /* Spaces and non-trailing dots should just be passed through, + * but eat the escape character. + */ case '.': - /* Non trailing dots should just be passed through, but eat the escape */ *outspec = *inspec; - count++; + count += 2; + (*output_cnt)++; break; case '_': /* space */ *outspec = ' '; - inspec++; - count++; + count += 2; (*output_cnt)++; break; + case '^': + /* Hmm. Better leave the escape escaped. */ + outspec[0] = '^'; + outspec[1] = '^'; + count += 2; + (*output_cnt) += 2; + break; case 'U': /* Unicode - FIX-ME this is wrong. */ inspec++; count++; @@ -7559,6 +7578,14 @@ static char *mp_do_tovmsspec case '#': case '%': case '^': + /* Don't escape again if following character is + * already something we escape. + */ + if (strchr("\"~`!#%^&()=+\'@[]{}:\\|<>_.", *(cp2+1))) { + *(cp1++) = *(cp2++); + break; + } + /* But otherwise fall through and escape it. */ case '&': case '(': case ')': -- 2.7.4