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