This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
runops becomes a funtion pointer and sv_bless3 created
authorMalcolm Beattie <mbeattie@sable.ox.ac.uk>
Mon, 22 Sep 1997 16:01:48 +0000 (16:01 +0000)
committerMalcolm Beattie <mbeattie@sable.ox.ac.uk>
Mon, 22 Sep 1997 16:01:48 +0000 (16:01 +0000)
to avoid pointer forgery with '~'-magic.

p4raw-id: //depot/perl@68

global.sym
perl.h
pp.c
proto.h
run.c
sv.c

index f7d11f2..497e1c4 100644 (file)
@@ -200,6 +200,7 @@ rsfp
 rsfp_filters
 rshift_amg
 rshift_ass_amg
+runops
 savestack
 savestack_ix
 savestack_max
@@ -1015,7 +1016,6 @@ rsignal
 rsignal_save
 rsignal_state
 rsignal_restore
-runops
 rxres_free
 rxres_restore
 rxres_save
@@ -1096,6 +1096,7 @@ sv_2uv
 sv_add_arena
 sv_backoff
 sv_bless
+sv_bless3
 sv_catpvf
 sv_catpv
 sv_catpvn
diff --git a/perl.h b/perl.h
index 5ef7cd9..70d9a63 100644 (file)
--- a/perl.h
+++ b/perl.h
@@ -1314,8 +1314,10 @@ typedef Sighandler_t Sigsave_t;
 #  endif
 # endif
 # define PAD_SV(po) pad_sv(po)
+# define RUNOPS_DEFAULT runops_debug
 #else
 # define PAD_SV(po) curpad[po]
+# define RUNOPS_DEFAULT runops_standard
 #endif
 
 /****************/
@@ -1392,6 +1394,7 @@ EXT OP *  opsave;         /* save current op register across longjmps */
 #else
 EXT OP *       op;             /* current op--when not in a global register */
 #endif
+EXT int                (*runops) _((void)) INIT(RUNOPS_DEFAULT);
 EXT I32 *      scopestack;     /* blocks we've entered */
 EXT I32                scopestack_ix;
 EXT I32                scopestack_max;
diff --git a/pp.c b/pp.c
index 01c61c2..ff00688 100644 (file)
--- a/pp.c
+++ b/pp.c
@@ -426,7 +426,7 @@ PP(pp_bless)
     else
        stash = gv_stashsv(POPs, TRUE);
 
-    (void)sv_bless(TOPs, stash);
+    (void)sv_bless3(TOPs, stash, TRUE);
     RETURN;
 }
 
diff --git a/proto.h b/proto.h
index 4565ec4..4c51fdc 100644 (file)
--- a/proto.h
+++ b/proto.h
@@ -398,7 +398,10 @@ Sighandler_t rsignal _((int, Sighandler_t));
 int    rsignal_restore _((int, Sigsave_t*));
 int    rsignal_save _((int, Sighandler_t, Sigsave_t*));
 Sighandler_t rsignal_state _((int));
-int    runops _((void));
+int    runops_standard _((void));
+#ifdef DEBUGGING
+int    runops_debug _((void));
+#endif
 void   rxres_free _((void** rsp));
 void   rxres_restore _((void** rsp, REGEXP* rx));
 void   rxres_save _((void** rsp, REGEXP* rx));
@@ -465,6 +468,7 @@ UV  sv_2uv _((SV* sv));
 void   sv_add_arena _((char* ptr, U32 size, U32 flags));
 int    sv_backoff _((SV* sv));
 SV*    sv_bless _((SV* sv, HV* stash));
+SV*    sv_bless3 _((SV* sv, HV* stash, bool zaptilde));
 void   sv_catpvf _((SV* sv, const char* pat, ...));
 void   sv_catpv _((SV* sv, char* ptr));
 void   sv_catpvn _((SV* sv, char* ptr, STRLEN len));
diff --git a/run.c b/run.c
index 2f8d8fa..1e1001d 100644 (file)
--- a/run.c
+++ b/run.c
 dEXT char **watchaddr = 0;
 dEXT char *watchok;
 
-#ifndef DEBUGGING
-
 int
-runops() {
+runops_standard() {
     dTHR;
     SAVEI32(runlevel);
     runlevel++;
@@ -33,12 +31,11 @@ runops() {
     return 0;
 }
 
-#else
-
+#ifdef DEBUGGING
 static void debprof _((OP*o));
 
 int
-runops() {
+runops_debug() {
     dTHR;
     if (!op) {
        warn("NULL OP IN RUN");
diff --git a/sv.c b/sv.c
index cd55f81..1c58c46 100644 (file)
--- a/sv.c
+++ b/sv.c
@@ -4043,9 +4043,10 @@ I32 n;
 }
 
 SV*
-sv_bless(sv,stash)
+sv_bless3(sv,stash,zaptilde)
 SV* sv;
 HV* stash;
+bool zaptilde;
 {
     dTHR;
     SV *ref;
@@ -4058,6 +4059,8 @@ HV* stash;
        if (SvOBJECT(ref)) {
            if (SvTYPE(ref) != SVt_PVIO)
                --sv_objcount;
+           if (zaptilde && SvRMAGICAL(ref))
+               sv_unmagic(ref, '~');   /* stop cross-class pointer forgery */
            SvREFCNT_dec(SvSTASH(ref));
        }
     }
@@ -4077,6 +4080,14 @@ HV* stash;
     return sv;
 }
 
+SV*
+sv_bless(sv,stash)
+SV* sv;
+HV* stash;
+{
+    return sv_bless3(sv, stash, FALSE);
+}
+
 static void
 sv_unglob(sv)
 SV* sv;