b8876f
From 8fe3452cc6ac7af8c08c2044cd3757018a9c8887 Mon Sep 17 00:00:00 2001
b8876f
From: Zefram <zefram@fysh.org>
b8876f
Date: Fri, 22 Dec 2017 05:32:41 +0000
b8876f
Subject: [PATCH] preserve numericness of system() args on Win32
b8876f
MIME-Version: 1.0
b8876f
Content-Type: text/plain; charset=UTF-8
b8876f
Content-Transfer-Encoding: 8bit
b8876f
b8876f
On Windows there's a nasty variation in the meaning of arguments
b8876f
to Perl's system(), in which a numeric first argument isn't used as
b8876f
part of the command to run, but instead selects between two different
b8876f
operations to perform with the command (whether to wait for the command
b8876f
to complete or not).  Therefore the reduction of argument scalars to
b8876f
their operative values in the parent process, which was added in commit
b8876f
64def2aeaeb63f92dadc6dfa33486c1d7b311963, needs to preserve numericness
b8876f
of arguments on Windows.  Fixes [perl #132633].
b8876f
b8876f
Signed-off-by: Petr Písař <ppisar@redhat.com>
b8876f
---
b8876f
 pp_sys.c | 35 +++++++++++++++++++++++++++++++----
b8876f
 1 file changed, 31 insertions(+), 4 deletions(-)
b8876f
b8876f
diff --git a/pp_sys.c b/pp_sys.c
b8876f
index beb60da4c6..0649794104 100644
b8876f
--- a/pp_sys.c
b8876f
+++ b/pp_sys.c
b8876f
@@ -4393,12 +4393,39 @@ PP(pp_system)
b8876f
 # endif
b8876f
 
b8876f
     while (++MARK <= SP) {
b8876f
-	SV *origsv = *MARK;
b8876f
+	SV *origsv = *MARK, *copysv;
b8876f
 	STRLEN len;
b8876f
 	char *pv;
b8876f
-	pv = SvPV(origsv, len);
b8876f
-	*MARK = newSVpvn_flags(pv, len,
b8876f
-		    (SvFLAGS(origsv) & SVf_UTF8) | SVs_TEMP);
b8876f
+	SvGETMAGIC(origsv);
b8876f
+#ifdef WIN32
b8876f
+	/*
b8876f
+	 * Because of a nasty platform-specific variation on the meaning
b8876f
+	 * of arguments to this op, we must preserve numeric arguments
b8876f
+	 * as numeric, not just retain the string value.
b8876f
+	 */
b8876f
+	if (SvNIOK(origsv) || SvNIOKp(origsv)) {
b8876f
+	    copysv = newSV_type(SVt_PVNV);
b8876f
+	    sv_2mortal(copysv);
b8876f
+	    if (SvPOK(origsv) || SvPOKp(origsv)) {
b8876f
+		pv = SvPV_nomg(origsv, len);
b8876f
+		sv_setpvn(copysv, pv, len);
b8876f
+		SvPOK_off(copysv);
b8876f
+	    }
b8876f
+	    if (SvIOK(origsv) || SvIOKp(origsv))
b8876f
+		SvIV_set(copysv, SvIVX(origsv));
b8876f
+	    if (SvNOK(origsv) || SvNOKp(origsv))
b8876f
+		SvNV_set(copysv, SvNVX(origsv));
b8876f
+	    SvFLAGS(copysv) |= SvFLAGS(origsv) &
b8876f
+		(SVf_IOK|SVf_NOK|SVf_POK|SVp_IOK|SVp_NOK|SVp_POK|
b8876f
+		    SVf_UTF8|SVf_IVisUV);
b8876f
+	} else
b8876f
+#endif
b8876f
+	{
b8876f
+	    pv = SvPV_nomg(origsv, len);
b8876f
+	    copysv = newSVpvn_flags(pv, len,
b8876f
+			(SvFLAGS(origsv) & SVf_UTF8) | SVs_TEMP);
b8876f
+	}
b8876f
+	*MARK = copysv;
b8876f
     }
b8876f
     MARK = ORIGMARK;
b8876f
 
b8876f
-- 
b8876f
2.13.6
b8876f