summaryrefslogtreecommitdiff
path: root/vms/vms.c
diff options
context:
space:
mode:
authorCraig A. Berry <craigberry@mac.com>2013-02-05 19:04:23 -0600
committerCraig A. Berry <craigberry@mac.com>2013-02-05 19:04:23 -0600
commit59247333b91dc05c865ef5c89f217a9695709cb8 (patch)
tree999df3fb054a43aef71d65fe21a523fa7b9513f4 /vms/vms.c
parent0c50187808c90649d93897951eb5d95c20c23588 (diff)
downloadperl-59247333b91dc05c865ef5c89f217a9695709cb8.tar.gz
Make vmsify support files with no directory component.
We've been assuming there is always a directory portion to a path being converted to VMS format, and it's true that translating directory delimiters and such is the most noticeable aspect of such conversions. But we also depend on the conversion to add caret escapes to characters in the path that are only valid when using Extended Filename Syntax (EFS), but weren't doing that for paths with no directory component. I.e., this was working: /disk/dir/foo%bar --> disk:[dir]foo^%bar but this was not (until now): foo%bar --> foo^%bar Since we're now working on a pointer that has not necessarily been incremented while adding directory syntax, we also add a number of guards to make sure we don't peek beyond the beginning of the result string. N.B. There will be a separate commit following shortly that prevents paths with no directory component from being passed through as-is -- here we just provide the infrastructure to make that possible.
Diffstat (limited to 'vms/vms.c')
-rw-r--r--vms/vms.c21
1 files changed, 12 insertions, 9 deletions
diff --git a/vms/vms.c b/vms/vms.c
index b92b7dab48..c5ad229ed8 100644
--- a/vms/vms.c
+++ b/vms/vms.c
@@ -8499,7 +8499,7 @@ static char *int_tovmsspec
}
PerlMem_free(trndev);
}
- else {
+ else if (hasdir) {
*(cp1++) = '[';
if (*cp2 == '.') {
if (*(cp2+1) == '/' || *(cp2+1) == '\0') {
@@ -8524,18 +8524,21 @@ static char *int_tovmsspec
}
else *(cp1++) = '.';
}
+ else {
+ *(cp1++) = *cp2;
+ }
for (; cp2 < dirend; cp2++) {
if (*cp2 == '/') {
if (*(cp2-1) == '/') continue;
- if (*(cp1-1) != '.') *(cp1++) = '.';
+ if (cp1 > rslt && *(cp1-1) != '.') *(cp1++) = '.';
infront = 0;
}
else if (!infront && *cp2 == '.') {
if (cp2+1 == dirend || *(cp2+1) == '\0') { cp2++; break; }
else if (*(cp2+1) == '/') cp2++; /* skip over "./" - it's redundant */
else if (*(cp2+1) == '.' && (*(cp2+2) == '/' || *(cp2+2) == '\0')) {
- if (*(cp1-1) == '-' || *(cp1-1) == '[') *(cp1++) = '-'; /* handle "../" */
- else if (*(cp1-2) == '[') *(cp1-1) = '-';
+ if (cp1 > rslt && (*(cp1-1) == '-' || *(cp1-1) == '[')) *(cp1++) = '-'; /* handle "../" */
+ else if (cp1 > rslt + 1 && *(cp1-2) == '[') *(cp1-1) = '-';
else {
*(cp1++) = '-';
}
@@ -8544,7 +8547,7 @@ static char *int_tovmsspec
}
else if ( *(cp2+1) == '.' && *(cp2+2) == '.' &&
(*(cp2+3) == '/' || *(cp2+3) == '\0') ) {
- if (*(cp1-1) != '.') *(cp1++) = '.'; /* May already have 1 from '/' */
+ if (cp1 > rslt && *(cp1-1) != '.') *(cp1++) = '.'; /* May already have 1 from '/' */
*(cp1++) = '.'; *(cp1++) = '.'; /* ".../" --> "..." */
if (!*(cp2+3)) {
*(cp1++) = '.'; /* Simulate trailing '/' */
@@ -8554,7 +8557,7 @@ static char *int_tovmsspec
}
else {
if (decc_efs_charset == 0) {
- if (*(cp1-1) == '^')
+ if (cp1 > rslt && *(cp1-1) == '^')
cp1--; /* remove the escape, if any */
*(cp1++) = '_'; /* fix up syntax - '.' in name not allowed */
}
@@ -8564,10 +8567,10 @@ static char *int_tovmsspec
}
}
else {
- if (!infront && *(cp1-1) == '-') *(cp1++) = '.';
+ if (!infront && cp1 > rslt && *(cp1-1) == '-') *(cp1++) = '.';
if (*cp2 == '.') {
if (decc_efs_charset == 0) {
- if (*(cp1-1) == '^')
+ if (cp1 > rslt && *(cp1-1) == '^')
cp1--; /* remove the escape, if any */
*(cp1++) = '_';
}
@@ -8579,7 +8582,7 @@ static char *int_tovmsspec
infront = 1;
}
}
- if (*(cp1-1) == '.') cp1--; /* Unix spec ending in '/' ==> trailing '.' */
+ if (cp1 > rslt && *(cp1-1) == '.') cp1--; /* Unix spec ending in '/' ==> trailing '.' */
if (hasdir) *(cp1++) = ']';
if (*cp2) cp2++; /* check in case we ended with trailing '..' */
/* fixme for ODS5 */