Patch: Untaint FH flag and clean DATA handles
Randy J. Ray [Thu, 19 Sep 1996 15:58:22 +0000 (11:58 -0400)]
Restore the 5.003 gv_fullname() and gv_efullname() functions.
Provide new 3-arg forms gv_fullname3() and gv_efullname3().

This patch adds a IOf_UNTAINT flag in sv.h, as one of the possibles
on an xpvio->xio_flags struct member. It is used to mark the given
file handle as a clean source, even when tainting is turned on.
There are also patches to pp_sys.c in pp_sysread to check this flag
before tainting data, and in pp_hot.c in do_readline for the same
reason. Lastly, it patches toke.c to automatically set this flag on
on a __DATA__ filehandle. The creation of the $pack::DATA
pseudo-filehandle is already checked against running under eval, so
this should not introduce any insecurity.

This patch *does not*:

* Add the "untaint" keyword.

pp_hot.c

index bf33ab8..150afe2 100644 (file)
--- a/pp_hot.c
+++ b/pp_hot.c
@@ -344,7 +344,7 @@ PP(pp_print)
     if (!(io = GvIO(gv))) {
        if (dowarn) {
            SV* sv = sv_newmortal();
-            gv_fullname(sv, gv, Nullch);
+            gv_fullname3(sv, gv, Nullch);
             warn("Filehandle %s never opened", SvPV(sv,na));
         }
 
@@ -354,7 +354,7 @@ PP(pp_print)
     else if (!(fp = IoOFP(io))) {
        if (dowarn)  {
            SV* sv = sv_newmortal();
-            gv_fullname(sv, gv, Nullch);
+            gv_fullname3(sv, gv, Nullch);
            if (IoIFP(io))
                warn("Filehandle %s opened only for input", SvPV(sv,na));
            else
@@ -1166,7 +1166,9 @@ do_readline()
        IoLINES(io)++;
        XPUSHs(sv);
        if (tainting) {
-           tainted = TRUE;
+           /* This should not be marked tainted if the fp is marked clean */
+           if (!(IoFLAGS(io) & IOf_UNTAINT))
+               tainted = TRUE;
            SvTAINT(sv); /* Anything from the outside world...*/
        }
        if (type == OP_GLOB) {
@@ -1746,7 +1748,7 @@ PP(pp_entersub)
                goto retry;
            }
            tmpstr = sv_newmortal();
-           gv_efullname(tmpstr, gv, Nullch);
+           gv_efullname3(tmpstr, gv, Nullch);
            ngv = gv_fetchmethod(GvESTASH(gv), "AUTOLOAD");
            if (ngv && ngv != gv && (cv = GvCV(ngv))) { /* One more chance... */
                gv = ngv;
@@ -1772,7 +1774,7 @@ PP(pp_entersub)
            sv_setsv(sv, newRV((SV*)cv));
        }
        else {
-           gv_efullname(sv, gv, Nullch);
+           gv_efullname3(sv, gv, Nullch);
        }
        cv = GvCV(DBsub);
        if (CvXSUB(cv)) curcopdb = curcop;