summaryrefslogtreecommitdiff
path: root/pp_sys.c
diff options
context:
space:
mode:
authorJan Dubois <jand@activestate.com>2010-08-19 18:43:59 -0700
committerJan Dubois <jand@activestate.com>2010-08-19 18:45:57 -0700
commit1b0124a7c19a5499714e57a00a3d30b2f2647b1f (patch)
tree42654f31b7c7f8348f69243c8e071188eb64dd2d /pp_sys.c
parent63cf24924effea6eabe5e1216348eea653365fda (diff)
downloadperl-1b0124a7c19a5499714e57a00a3d30b2f2647b1f.tar.gz
Fix stack corruption by unsupported filetests
Commit c410dd6ad7 indiscriminately pops elements from the stack even when nothing has been pushed: file tests without arguments (testing $_) and stacked filetests don't have anything on the stack that needs to be removed. The general idea is that we need to have the same side effects as if we had called my_stat_flags(), so we shall only call POPs under the same conditions as the code in my_stat_flags().
Diffstat (limited to 'pp_sys.c')
-rw-r--r--pp_sys.c13
1 files changed, 8 insertions, 5 deletions
diff --git a/pp_sys.c b/pp_sys.c
index ec826108ba..0f5a3fd737 100644
--- a/pp_sys.c
+++ b/pp_sys.c
@@ -3216,29 +3216,32 @@ PP(pp_ftrowned)
}
tryAMAGICftest_MG(opchar);
+ STACKED_FTEST_CHECK;
+
/* I believe that all these three are likely to be defined on most every
system these days. */
#ifndef S_ISUID
if(PL_op->op_type == OP_FTSUID) {
- (void) POPs;
+ if ((PL_op->op_flags & OPf_REF) == 0 && (PL_op->op_private & OPpFT_STACKED) == 0)
+ (void) POPs;
RETPUSHNO;
}
#endif
#ifndef S_ISGID
if(PL_op->op_type == OP_FTSGID) {
- (void) POPs;
+ if ((PL_op->op_flags & OPf_REF) == 0 && (PL_op->op_private & OPpFT_STACKED) == 0)
+ (void) POPs;
RETPUSHNO;
}
#endif
#ifndef S_ISVTX
if(PL_op->op_type == OP_FTSVTX) {
- (void) POPs;
+ if ((PL_op->op_flags & OPf_REF) == 0 && (PL_op->op_private & OPpFT_STACKED) == 0)
+ (void) POPs;
RETPUSHNO;
}
#endif
- STACKED_FTEST_CHECK;
-
result = my_stat_flags(0);
SPAGAIN;
if (result < 0)