summaryrefslogtreecommitdiff
path: root/mg.c
diff options
context:
space:
mode:
Diffstat (limited to 'mg.c')
-rw-r--r--mg.c53
1 files changed, 46 insertions, 7 deletions
diff --git a/mg.c b/mg.c
index 318b7fef2d..04fccaf38e 100644
--- a/mg.c
+++ b/mg.c
@@ -585,37 +585,76 @@ MAGIC* mg;
char *ptr;
STRLEN len;
I32 i;
+
s = SvPV(sv,len);
ptr = MgPV(mg);
my_setenv(ptr, s);
+
#ifdef DYNAMIC_ENV_FETCH
/* We just undefd an environment var. Is a replacement */
/* waiting in the wings? */
if (!len) {
HE *envhe;
SV *keysv;
- if (mg->mg_len == HEf_SVKEY) keysv = (SV *)mg->mg_ptr;
- else keysv = newSVpv(mg->mg_ptr,mg->mg_len);
- if (envhe = hv_fetch_ent(GvHVn(envgv),keysv,FALSE,0))
- s = SvPV(HeVAL(envhe),len);
- if (mg->mg_len != HEf_SVKEY) SvREFCNT_dec(keysv);
+ if (mg->mg_len == HEf_SVKEY)
+ keysv = (SV *)mg->mg_ptr;
+ else
+ keysv = newSVpv(mg->mg_ptr, mg->mg_len);
+ if ((envhe = hv_fetch_ent(GvHVn(envgv), keysv, FALSE, 0)))
+ s = SvPV(HeVAL(envhe), len);
+ if (mg->mg_len != HEf_SVKEY)
+ SvREFCNT_dec(keysv);
}
#endif
+
+#if !defined(OS2) && !defined(AMIGAOS)
/* And you'll never guess what the dog had */
/* in its mouth... */
if (tainting) {
+ MgTAINTEDDIR_off(mg);
+#ifdef VMS
+ if (s && strnEQ(ptr, "DCL$PATH", 8)) {
+ char pathbuf[256], eltbuf[256], *cp, *elt = s;
+ struct stat sbuf;
+ int i = 0, j = 0;
+
+ do { /* DCL$PATH may be a search list */
+ while (1) { /* as may dev portion of any element */
+ if ( ((cp = strchr(elt,'[')) || (cp = strchr(elt,'<'))) ) {
+ if ( *(cp+1) == '.' || *(cp+1) == '-' ||
+ cando_by_name(S_IWUSR,0,elt) ) {
+ MgTAINTEDDIR_on(mg);
+ return 0;
+ }
+ }
+ if ((cp = strchr(elt, ':')) != Nullch)
+ *cp = '\0';
+ if (my_trnlnm(elt, eltbuf, j++))
+ elt = eltbuf;
+ else
+ break;
+ }
+ j = 0;
+ } while (my_trnlnm(s, pathbuf, i++) && (elt = pathbuf));
+ }
+#endif /* VMS */
if (s && strEQ(ptr,"PATH")) {
char *strend = s + len;
while (s < strend) {
- s = cpytill(tokenbuf,s,strend,':',&i);
+ struct stat st;
+ s = cpytill(tokenbuf, s, strend, ':', &i);
s++;
if (*tokenbuf != '/'
- || (Stat(tokenbuf,&statbuf) && (statbuf.st_mode & 2)) )
+ || (Stat(tokenbuf, &st) == 0 && (st.st_mode & 2)) ) {
MgTAINTEDDIR_on(mg);
+ return 0;
+ }
}
}
}
+#endif /* neither OS2 nor AMIGAOS */
+
return 0;
}