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