Compare commits

...

No commits in common. "c8" and "c8-beta-stream-5.24" have entirely different histories.

117 changed files with 12707 additions and 5919 deletions

2
.gitignore vendored
View File

@ -1 +1 @@
SOURCES/perl-5.26.3.tar.bz2 SOURCES/perl-5.24.4.tar.bz2

View File

@ -1 +1 @@
4c61872bab631427cbb5b519ef8809d3a4c7f921 SOURCES/perl-5.26.3.tar.bz2 0606bb25bfe3e00e3e54fe858bd7247a104c3772 SOURCES/perl-5.24.4.tar.bz2

View File

@ -0,0 +1,367 @@
From 0c7af9e6cb05b436505e7f46ef49dcb6f791f30a Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Petr=20P=C3=ADsa=C5=99?= <ppisar@redhat.com>
Date: Fri, 17 Feb 2017 11:00:21 +0100
Subject: [PATCH] Adapt to zlib-1.2.11
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
This is a fix ported from Compress-Raw-Zlib-2.072 that restores
compatibility with zlib-1.2.11.
CPAN RT#119762
Signed-off-by: Petr Písař <ppisar@redhat.com>
---
Zlib.xs | 220 +++++++++++++++++++++++++++++++++++++++++++++++--------------
t/02zlib.t | 11 +++-
2 files changed, 178 insertions(+), 53 deletions(-)
diff --git a/Zlib.xs b/Zlib.xs
index d379f78..83d1423 100644
--- a/Zlib.xs
+++ b/Zlib.xs
@@ -74,6 +74,10 @@
# define AT_LEAST_ZLIB_1_2_8
#endif
+#if defined(ZLIB_VERNUM) && ZLIB_VERNUM >= 0x1290
+# define AT_LEAST_ZLIB_1_2_9
+#endif
+
#ifdef USE_PPPORT_H
# define NEED_sv_2pvbyte
# define NEED_sv_2pv_nolen
@@ -134,12 +138,13 @@ typedef struct di_stream {
uLong dict_adler ;
int last_error ;
bool zip_mode ;
-#define SETP_BYTE
+/* #define SETP_BYTE */
#ifdef SETP_BYTE
+ /* SETP_BYTE only works with zlib up to 1.2.8 */
bool deflateParams_out_valid ;
Bytef deflateParams_out_byte;
#else
-#define deflateParams_BUFFER_SIZE 0x4000
+#define deflateParams_BUFFER_SIZE 0x40000
uLong deflateParams_out_length;
Bytef* deflateParams_out_buffer;
#endif
@@ -636,6 +641,103 @@ char * string ;
return sv ;
}
+#if 0
+int
+flushToBuffer(di_stream* s, int flush)
+{
+ dTHX;
+ int ret ;
+ z_stream * strm = &s->stream;
+
+ Bytef* output = s->deflateParams_out_buffer ;
+
+ strm->next_in = NULL;
+ strm->avail_in = 0;
+
+ uLong total_output = 0;
+ uLong have = 0;
+
+ do
+ {
+ if (output)
+ output = (unsigned char *)saferealloc(output, total_output + s->bufsize);
+ else
+ output = (unsigned char *)safemalloc(s->bufsize);
+
+ strm->next_out = output + total_output;
+ strm->avail_out = s->bufsize;
+
+ ret = deflate(strm, flush); /* no bad return value */
+ //assert(ret != Z_STREAM_ERROR); /* state not clobbered */
+ if(ret == Z_STREAM_ERROR)
+ {
+ safefree(output);
+ return ret;
+ }
+ have = s->bufsize - strm->avail_out;
+ total_output += have;
+
+ //fprintf(stderr, "FLUSH %s %d, return %d\n", flush_flags[flush], have, ret);
+
+ } while (strm->avail_out == 0);
+
+ s->deflateParams_out_buffer = output;
+ s->deflateParams_out_length = total_output;
+
+ return Z_OK;
+}
+#endif
+
+#ifndef SETP_BYTE
+int
+flushParams(di_stream* s)
+{
+ dTHX;
+ int ret ;
+ z_stream * strm = &s->stream;
+
+ strm->next_in = NULL;
+ strm->avail_in = 0;
+
+ Bytef* output = s->deflateParams_out_buffer ;
+ uLong total_output = s->deflateParams_out_length;
+
+ uLong have = 0;
+
+ do
+ {
+ if (output)
+ output = (unsigned char *)saferealloc(output, total_output + s->bufsize);
+ else
+ output = (unsigned char *)safemalloc(s->bufsize);
+
+ strm->next_out = output + total_output;
+ strm->avail_out = s->bufsize;
+
+ ret = deflateParams(&(s->stream), s->Level, s->Strategy);
+ /* fprintf(stderr, "deflateParams %d %s %lu\n", ret,
+ GetErrorString(ret), s->bufsize - strm->avail_out); */
+
+ if (ret == Z_STREAM_ERROR)
+ break;
+
+ have = s->bufsize - strm->avail_out;
+ total_output += have;
+
+
+ } while (ret == Z_BUF_ERROR) ;
+
+ if(ret == Z_STREAM_ERROR)
+ safefree(output);
+ else
+ {
+ s->deflateParams_out_buffer = output;
+ s->deflateParams_out_length = total_output;
+ }
+
+ return ret;
+}
+#endif /* ! SETP_BYTE */
#include "constants.h"
@@ -991,20 +1093,24 @@ deflate (s, buf, output)
/* Check for saved output from deflateParams */
if (s->deflateParams_out_length) {
uLong plen = s->deflateParams_out_length ;
- /* printf("Copy %d bytes saved data\n", plen);*/
+ /* printf("Copy %lu bytes saved data\n", plen); */
if (s->stream.avail_out < plen) {
- /*printf("GROW from %d to %d\n", s->stream.avail_out,
- SvLEN(output) + plen - s->stream.avail_out); */
- Sv_Grow(output, SvLEN(output) + plen - s->stream.avail_out) ;
+ /* printf("GROW from %d to %lu\n", s->stream.avail_out,
+ SvLEN(output) + plen - s->stream.avail_out); */
+ s->stream.next_out = (Bytef*) Sv_Grow(output, SvLEN(output) + plen - s->stream.avail_out) ;
+ s->stream.next_out += cur_length;
}
- Copy(s->stream.next_out, s->deflateParams_out_buffer, plen, Bytef) ;
- cur_length = cur_length + plen;
+ Copy(s->deflateParams_out_buffer, s->stream.next_out, plen, Bytef) ;
+ cur_length += plen;
SvCUR_set(output, cur_length);
- s->stream.next_out += plen ;
- s->stream.avail_out = SvLEN(output) - cur_length ;
- increment = s->stream.avail_out;
- s->deflateParams_out_length = 0;
+ s->stream.next_out += plen ;
+ s->stream.avail_out = SvLEN(output) - cur_length ;
+ increment = s->stream.avail_out;
+
+ s->deflateParams_out_length = 0;
+ Safefree(s->deflateParams_out_buffer);
+ s->deflateParams_out_buffer = NULL;
}
#endif
RETVAL = Z_OK ;
@@ -1027,6 +1133,12 @@ deflate (s, buf, output)
}
RETVAL = deflate(&(s->stream), Z_NO_FLUSH);
+ if (RETVAL != Z_STREAM_ERROR) {
+ int done = increment - s->stream.avail_out ;
+ /* printf("std DEFLATEr returned %d '%s' avail in %d, out %d wrote %d\n", RETVAL,
+ GetErrorString(RETVAL), s->stream.avail_in,
+s->stream.avail_out, done); */
+ }
if (trace) {
printf("DEFLATE returned %d %s, avail in %d, out %d\n", RETVAL,
@@ -1080,7 +1192,6 @@ flush(s, output, f=Z_FINISH)
CODE:
bufinc = s->bufsize;
- s->stream.avail_in = 0; /* should be zero already anyway */
/* retrieve the output buffer */
output = deRef_l(output, "flush") ;
@@ -1108,20 +1219,24 @@ flush(s, output, f=Z_FINISH)
/* Check for saved output from deflateParams */
if (s->deflateParams_out_length) {
uLong plen = s->deflateParams_out_length ;
- /* printf("Copy %d bytes saved data\n", plen); */
+ /* printf("Copy %lu bytes saved data\n", plen); */
if (s->stream.avail_out < plen) {
- /* printf("GROW from %d to %d\n", s->stream.avail_out,
+ /* printf("GROW from %d to %lu\n", s->stream.avail_out,
SvLEN(output) + plen - s->stream.avail_out); */
- Sv_Grow(output, SvLEN(output) + plen - s->stream.avail_out) ;
+ s->stream.next_out = (Bytef*) Sv_Grow(output, SvLEN(output) + plen - s->stream.avail_out) ;
+ s->stream.next_out += cur_length;
}
- Copy(s->stream.next_out, s->deflateParams_out_buffer, plen, Bytef) ;
- cur_length = cur_length + plen;
+ Copy(s->deflateParams_out_buffer, s->stream.next_out, plen, Bytef) ;
+ cur_length += plen;
SvCUR_set(output, cur_length);
- s->stream.next_out += plen ;
- s->stream.avail_out = SvLEN(output) - cur_length ;
- increment = s->stream.avail_out;
- s->deflateParams_out_length = 0;
+ s->stream.next_out += plen ;
+ s->stream.avail_out = SvLEN(output) - cur_length ;
+ increment = s->stream.avail_out;
+
+ s->deflateParams_out_length = 0;
+ Safefree(s->deflateParams_out_buffer);
+ s->deflateParams_out_buffer = NULL;
}
#endif
@@ -1145,9 +1260,15 @@ flush(s, output, f=Z_FINISH)
}
RETVAL = deflate(&(s->stream), f);
+ if (RETVAL != Z_STREAM_ERROR) {
+ int done = availableout - s->stream.avail_out ;
+ /* printf("flush DEFLATEr returned %d '%s' avail in %d, out %d wrote %d\n", RETVAL,
+ GetErrorString(RETVAL), s->stream.avail_in,
+s->stream.avail_out, done); */
+ }
if (trace) {
- printf("flush DEFLATE returned %d %s, avail in %d, out %d\n", RETVAL,
+ printf("flush DEFLATE returned %d '%s', avail in %d, out %d\n", RETVAL,
GetErrorString(RETVAL), s->stream.avail_in, s->stream.avail_out);
DispStream(s, "AFTER");
}
@@ -1184,41 +1305,38 @@ _deflateParams(s, flags, level, strategy, bufsize)
int level
int strategy
uLong bufsize
+ bool changed = FALSE;
CODE:
- /* printf("_deflateParams(Flags %d Level %d Strategy %d Bufsize %d)\n", flags, level, strategy, bufsize);
- printf("Before -- Level %d, Strategy %d, Bufsize %d\n", s->Level, s->Strategy, s->bufsize); */
- if (flags & 1)
- s->Level = level ;
- if (flags & 2)
- s->Strategy = strategy ;
- if (flags & 4) {
+ /* printf("_deflateParams(Flags %d Level %d Strategy %d Bufsize %d)\n", flags, level, strategy, bufsize);
+ printf("Before -- Level %d, Strategy %d, Bufsize %d\n", s->Level, s->Strategy, s->bufsize); */
+ if (flags & 1 && level != s->Level) {
+ s->Level = level ;
+ changed = TRUE;
+ }
+ if (flags & 2 && strategy != s->Strategy) {
+ s->Strategy = strategy ;
+ changed = TRUE;
+ }
+ if (flags & 4)
s->bufsize = bufsize;
- }
- /* printf("After -- Level %d, Strategy %d, Bufsize %d\n", s->Level, s->Strategy, s->bufsize);*/
+ if (changed) {
#ifdef SETP_BYTE
- s->stream.avail_in = 0;
- s->stream.next_out = &(s->deflateParams_out_byte) ;
- s->stream.avail_out = 1;
- RETVAL = deflateParams(&(s->stream), s->Level, s->Strategy);
- s->deflateParams_out_valid =
- (RETVAL == Z_OK && s->stream.avail_out == 0) ;
- /* printf("RETVAL %d, avail out %d, byte %c\n", RETVAL, s->stream.avail_out, s->deflateParams_out_byte); */
+ s->stream.avail_in = 0;
+ s->stream.next_out = &(s->deflateParams_out_byte) ;
+ s->stream.avail_out = 1;
+ RETVAL = deflateParams(&(s->stream), s->Level, s->Strategy);
+ s->deflateParams_out_valid =
+ (RETVAL == Z_OK && s->stream.avail_out == 0) ;
#else
- /* printf("Level %d Strategy %d, Prev Len %d\n",
+ /* printf("Level %d Strategy %d, Prev Len %d\n",
s->Level, s->Strategy, s->deflateParams_out_length); */
- s->stream.avail_in = 0;
- if (s->deflateParams_out_buffer == NULL)
- s->deflateParams_out_buffer = safemalloc(deflateParams_BUFFER_SIZE);
- s->stream.next_out = s->deflateParams_out_buffer ;
- s->stream.avail_out = deflateParams_BUFFER_SIZE;
-
- RETVAL = deflateParams(&(s->stream), s->Level, s->Strategy);
- s->deflateParams_out_length = deflateParams_BUFFER_SIZE - s->stream.avail_out;
- /* printf("RETVAL %d, length out %d, avail %d\n",
- RETVAL, s->deflateParams_out_length, s->stream.avail_out ); */
+ RETVAL = flushParams(s);
#endif
+ }
+ else
+ RETVAL = Z_OK;
OUTPUT:
- RETVAL
+ RETVAL
int
diff --git a/t/02zlib.t b/t/02zlib.t
index 2c9aad6..5d024a9 100644
--- a/t/02zlib.t
+++ b/t/02zlib.t
@@ -27,7 +27,7 @@ BEGIN
$count = 232 ;
}
elsif ($] >= 5.006) {
- $count = 317 ;
+ $count = 320 ;
}
else {
$count = 275 ;
@@ -559,6 +559,13 @@ SKIP:
is $x->get_Level(), Z_BEST_SPEED;
is $x->get_Strategy(), Z_HUFFMAN_ONLY;
+ # change both Level & Strategy again without any calls to deflate
+ $status = $x->deflateParams(-Level => Z_DEFAULT_COMPRESSION, -Strategy => Z_DEFAULT_STRATEGY, -Bufsize => 1234) ;
+ cmp_ok $status, '==', Z_OK ;
+
+ is $x->get_Level(), Z_DEFAULT_COMPRESSION;
+ is $x->get_Strategy(), Z_DEFAULT_STRATEGY;
+
$status = $x->deflate($goodbye, $Answer) ;
cmp_ok $status, '==', Z_OK ;
$input .= $goodbye;
@@ -568,7 +575,7 @@ SKIP:
cmp_ok $status, '==', Z_OK ;
is $x->get_Level(), Z_NO_COMPRESSION;
- is $x->get_Strategy(), Z_HUFFMAN_ONLY;
+ is $x->get_Strategy(), Z_DEFAULT_STRATEGY;
$status = $x->deflate($goodbye, $Answer) ;
cmp_ok $status, '==', Z_OK ;
--
2.7.4

View File

@ -0,0 +1,82 @@
From 1f3ac68dac93b7b85f09427d188386aaff0d3f80 Mon Sep 17 00:00:00 2001
From: Reini Urban <reini.urban@gmail.com>
Date: Fri, 17 Feb 2017 12:06:27 +0100
Subject: [PATCH] Conform to C90
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
The code failed to compile when building perl because perl adds -Werror=declaration-after-statement:
gcc -c -I/usr/include -D_REENTRANT -D_GNU_SOURCE -O2 -g -pipe -Wall -Werror=format-security -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector-strong --param=ssp-buffer-size=4 -grecord-gcc-switches -m64 -mtune=generic -fwrapv -fno-strict-aliasing -I/usr/local/include -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 -Werror=declaration-after-statement -Wextra -Wc++-compat -Wwrite-strings -g -DVERSION=\"2.069\" -DXS_VERSION=\"2.069\" -fPIC "-I../.." -DNO_VIZ -DZ_SOLO -DGZIP_OS_CODE=3 Zlib.c
Zlib.xs: In function 'flushParams':
Zlib.xs:702:5: error: ISO C90 forbids mixed declarations and code [-Werror=declaration-after-statement]
Bytef* output = s->deflateParams_out_buffer ;
^~~~~
CPAN RT#120272
Signed-off-by: Petr Písař <ppisar@redhat.com>
---
Zlib.xs | 22 +++++++++++-----------
1 file changed, 11 insertions(+), 11 deletions(-)
diff --git a/Zlib.xs b/Zlib.xs
index 83d1423..7f4396a 100644
--- a/Zlib.xs
+++ b/Zlib.xs
@@ -696,14 +696,14 @@ flushParams(di_stream* s)
int ret ;
z_stream * strm = &s->stream;
- strm->next_in = NULL;
- strm->avail_in = 0;
-
Bytef* output = s->deflateParams_out_buffer ;
uLong total_output = s->deflateParams_out_length;
uLong have = 0;
+ strm->next_in = NULL;
+ strm->avail_in = 0;
+
do
{
if (output)
@@ -1133,12 +1133,12 @@ deflate (s, buf, output)
}
RETVAL = deflate(&(s->stream), Z_NO_FLUSH);
- if (RETVAL != Z_STREAM_ERROR) {
+ /* if (RETVAL != Z_STREAM_ERROR) {
int done = increment - s->stream.avail_out ;
- /* printf("std DEFLATEr returned %d '%s' avail in %d, out %d wrote %d\n", RETVAL,
+ printf("std DEFLATEr returned %d '%s' avail in %d, out %d wrote %d\n", RETVAL,
GetErrorString(RETVAL), s->stream.avail_in,
-s->stream.avail_out, done); */
- }
+s->stream.avail_out, done);
+ } */
if (trace) {
printf("DEFLATE returned %d %s, avail in %d, out %d\n", RETVAL,
@@ -1260,12 +1260,12 @@ flush(s, output, f=Z_FINISH)
}
RETVAL = deflate(&(s->stream), f);
- if (RETVAL != Z_STREAM_ERROR) {
+ /* if (RETVAL != Z_STREAM_ERROR) {
int done = availableout - s->stream.avail_out ;
- /* printf("flush DEFLATEr returned %d '%s' avail in %d, out %d wrote %d\n", RETVAL,
+ printf("flush DEFLATEr returned %d '%s' avail in %d, out %d wrote %d\n", RETVAL,
GetErrorString(RETVAL), s->stream.avail_in,
-s->stream.avail_out, done); */
- }
+s->stream.avail_out, done);
+ } */
if (trace) {
printf("flush DEFLATE returned %d '%s', avail in %d, out %d\n", RETVAL,
--
2.7.4

File diff suppressed because it is too large Load Diff

View File

@ -27,9 +27,9 @@ index a8b172f..a3fbce2 100644
$Is{Solaris} = $^O eq 'solaris'; $Is{Solaris} = $^O eq 'solaris';
$Is{SunOS} = $Is{SunOS4} || $Is{Solaris}; $Is{SunOS} = $Is{SunOS4} || $Is{Solaris};
@@ -932,7 +933,7 @@ $(INST_DYNAMIC): $(OBJECT) $(MYEXTLIB) $(BOOTSTRAP) $(INST_ARCHAUTODIR)$(DFSEP). @@ -932,7 +933,7 @@ $(INST_DYNAMIC): $(OBJECT) $(MYEXTLIB) $(BOOTSTRAP) $(INST_ARCHAUTODIR)$(DFSEP).
push(@m," \$(RM_F) \$\@\n");
my $libs = '$(LDLOADLIBS)'; my $libs = '$(LDLOADLIBS)';
- if (($Is{NetBSD} || $Is{Interix} || $Is{Android}) && $Config{'useshrplib'} eq 'true') { - if (($Is{NetBSD} || $Is{Interix} || $Is{Android}) && $Config{'useshrplib'} eq 'true') {
+ if (($Is{Linux} || $Is{NetBSD} || $Is{Interix} || $Is{Android}) && $Config{'useshrplib'} eq 'true') { + if (($Is{Linux} || $Is{NetBSD} || $Is{Interix} || $Is{Android}) && $Config{'useshrplib'} eq 'true') {
# Use nothing on static perl platforms, and to the flags needed # Use nothing on static perl platforms, and to the flags needed

View File

@ -0,0 +1,44 @@
From 4ccd57ed119eae3847df1ec241daa509f3b86ef3 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Petr=20P=C3=ADsa=C5=99?= <ppisar@redhat.com>
Date: Thu, 18 Jun 2015 13:19:49 +0200
Subject: [PATCH] Revert "const the core magic vtables"
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
This reverts commit c910fead7893fe9700031ee59de6b904260b5d69.
It's necessary for Coro-6.43. This patch will be removed once Coro
will be fixed or in a reasonable time if Coro become unamaintained.
<http://www.nntp.perl.org/group/perl.perl5.porters/2015/06/msg228530.html>
<https://bugzilla.redhat.com/show_bug.cgi?id=1231165>
Signed-off-by: Petr Písař <ppisar@redhat.com>
---
perl.h | 9 ++++++++-
1 file changed, 8 insertions(+), 1 deletion(-)
diff --git a/perl.h b/perl.h
index dcb184b..9bce052 100644
--- a/perl.h
+++ b/perl.h
@@ -5583,7 +5583,14 @@ EXTCONST runops_proc_t PL_runops_std
EXTCONST runops_proc_t PL_runops_dbg
INIT(Perl_runops_debug);
-#define EXT_MGVTBL EXTCONST MGVTBL
+/* PERL_GLOBAL_STRUCT_PRIVATE wants to keep global data like the
+ * magic vtables const, but this is incompatible with SWIG which
+ * does want to modify the vtables. */
+#ifdef PERL_GLOBAL_STRUCT_PRIVATE
+# define EXT_MGVTBL EXTCONST MGVTBL
+#else
+# define EXT_MGVTBL EXT MGVTBL
+#endif
#define PERL_MAGIC_READONLY_ACCEPTABLE 0x40
#define PERL_MAGIC_VALUE_MAGIC 0x80
--
2.1.0

View File

@ -24,7 +24,7 @@ index 6af238c..d4f0c56 100644
--- a/MANIFEST --- a/MANIFEST
+++ b/MANIFEST +++ b/MANIFEST
@@ -1045,6 +1045,7 @@ cpan/ExtUtils-MakeMaker/lib/ExtUtils/MM_OS2.pm MakeMaker methods for OS/2 @@ -1045,6 +1045,7 @@ cpan/ExtUtils-MakeMaker/lib/ExtUtils/MM_OS2.pm MakeMaker methods for OS/2
cpan/ExtUtils-MakeMaker/lib/ExtUtils/MM_OS2.pm MakeMaker methods for OS/2 cpan/ExtUtils-MakeMaker/lib/ExtUtils/MM.pm MakeMaker adaptor class
cpan/ExtUtils-MakeMaker/lib/ExtUtils/MM_QNX.pm MakeMaker methods for QNX cpan/ExtUtils-MakeMaker/lib/ExtUtils/MM_QNX.pm MakeMaker methods for QNX
cpan/ExtUtils-MakeMaker/lib/ExtUtils/MM_Unix.pm MakeMaker methods for Unix cpan/ExtUtils-MakeMaker/lib/ExtUtils/MM_Unix.pm MakeMaker methods for Unix
+cpan/ExtUtils-MakeMaker/lib/ExtUtils/MM/Utils.pm Independed MM methods +cpan/ExtUtils-MakeMaker/lib/ExtUtils/MM/Utils.pm Independed MM methods

View File

@ -0,0 +1,73 @@
From 702cf95bcb627f2b3b44fad409df7f0fd517af60 Mon Sep 17 00:00:00 2001
From: David Mitchell <davem@iabyn.com>
Date: Mon, 5 Dec 2016 14:54:44 +0000
Subject: [PATCH] assertion failure in ... or ((0) x 0))
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Petr Pisar: Ported to 5.24.0:
commit 5aa240eab7dbaa91f98c2fee1f04b6c0b5a9b9e3
Author: David Mitchell <davem@iabyn.com>
Date: Mon Dec 5 14:54:44 2016 +0000
assertion failure in ... or ((0) x 0))
[perl #130247] Perl_rpeep(OP *): Assertion `oldop' failed
the 'x 0' optimising code in rpeep didn't expect the repeat expression
to occur on the op_other side of an op_next chain.
Signed-off-by: Petr Písař <ppisar@redhat.com>
---
op.c | 4 ++--
t/op/repeat.t | 11 ++++++++++-
2 files changed, 12 insertions(+), 3 deletions(-)
diff --git a/op.c b/op.c
index d7b900e..018d90c 100644
--- a/op.c
+++ b/op.c
@@ -13573,10 +13573,10 @@ Perl_rpeep(pTHX_ OP *o)
&& kid->op_next->op_type == OP_REPEAT
&& kid->op_next->op_private & OPpREPEAT_DOLIST
&& (kid->op_next->op_flags & OPf_WANT) == OPf_WANT_LIST
- && SvIOK(kSVOP_sv) && SvIVX(kSVOP_sv) == 0)
+ && SvIOK(kSVOP_sv) && SvIVX(kSVOP_sv) == 0
+ && oldop)
{
o = kid->op_next; /* repeat */
- assert(oldop);
oldop->op_next = o;
op_free(cBINOPo->op_first);
op_free(cBINOPo->op_last );
diff --git a/t/op/repeat.t b/t/op/repeat.t
index bee7dac..c933475 100644
--- a/t/op/repeat.t
+++ b/t/op/repeat.t
@@ -6,7 +6,7 @@ BEGIN {
}
require './test.pl';
-plan(tests => 48);
+plan(tests => 49);
# compile time
@@ -183,3 +183,12 @@ fresh_perl_like(
{ },
'(1) x ~1',
);
+
+# [perl #130247] Perl_rpeep(OP *): Assertion `oldop' failed
+#
+# the 'x 0' optimising code in rpeep didn't expect the repeat expression
+# to occur on the op_other side of an op_next chain.
+# This used to give an assertion failure
+
+eval q{() = (() or ((0) x 0)); 1};
+is($@, "", "RT #130247");
--
2.7.4

View File

@ -0,0 +1,94 @@
From af04cb4d2503c5c75d2229e232b8a0bd5c210084 Mon Sep 17 00:00:00 2001
From: Yves Orton <demerphq@gmail.com>
Date: Tue, 13 Sep 2016 23:06:07 +0200
Subject: [PATCH] clean up gv_fetchmethod_pvn_flags: introduce name_end
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Ported to 5.24.0:
commit 65308f87d02a1900e59f0002fa94c855d4d4c5df
Author: Yves Orton <demerphq@gmail.com>
Date: Tue Sep 13 23:06:07 2016 +0200
clean up gv_fetchmethod_pvn_flags: introduce name_end
nend is used for too many things, this replaces various
uses of nend with name_end, which is constant.
this is a first step to fixing [perl #129267], which shouldnt
change any behavior
Signed-off-by: Petr Písař <ppisar@redhat.com>
---
gv.c | 14 ++++++++------
1 file changed, 8 insertions(+), 6 deletions(-)
diff --git a/gv.c b/gv.c
index 28396de..d738bf0 100644
--- a/gv.c
+++ b/gv.c
@@ -1014,6 +1014,8 @@ Perl_gv_fetchmethod_pv_flags(pTHX_ HV *stash, const char *name, U32 flags)
GV *
Perl_gv_fetchmethod_pvn_flags(pTHX_ HV *stash, const char *name, const STRLEN len, U32 flags)
{
+ const char * const origname = name;
+ const char * const name_end = name + len;
const char *nend;
const char *nsplit = NULL;
GV* gv;
@@ -1034,7 +1036,7 @@ Perl_gv_fetchmethod_pvn_flags(pTHX_ HV *stash, const char *name, const STRLEN le
the error reporting code. */
}
- for (nend = name; *nend || nend != (origname + len); nend++) {
+ for (nend = name; *nend || nend != name_end; nend++) {
if (*nend == '\'') {
nsplit = nend;
name = nend + 1;
@@ -1065,13 +1067,13 @@ Perl_gv_fetchmethod_pvn_flags(pTHX_ HV *stash, const char *name, const STRLEN le
ostash = stash;
}
- gv = gv_fetchmeth_pvn(stash, name, nend - name, 0, flags);
+ gv = gv_fetchmeth_pvn(stash, name, name_end - name, 0, flags);
if (!gv) {
if (strEQ(name,"import") || strEQ(name,"unimport"))
gv = MUTABLE_GV(&PL_sv_yes);
else if (autoload)
gv = gv_autoload_pvn(
- ostash, name, nend - name, GV_AUTOLOAD_ISMETHOD|flags
+ ostash, name, name_end - name, GV_AUTOLOAD_ISMETHOD|flags
);
if (!gv && do_croak) {
/* Right now this is exclusively for the benefit of S_method_common
@@ -1087,14 +1089,14 @@ Perl_gv_fetchmethod_pvn_flags(pTHX_ HV *stash, const char *name, const STRLEN le
HV_FETCH_ISEXISTS, NULL, 0)
) {
require_pv("IO/File.pm");
- gv = gv_fetchmeth_pvn(stash, name, nend - name, 0, flags);
+ gv = gv_fetchmeth_pvn(stash, name, name_end - name, 0, flags);
if (gv)
return gv;
}
Perl_croak(aTHX_
"Can't locate object method \"%"UTF8f
"\" via package \"%"HEKf"\"",
- UTF8fARG(is_utf8, nend - name, name),
+ UTF8fARG(is_utf8, name_end - name, name),
HEKfARG(HvNAME_HEK(stash)));
}
else {
@@ -1111,7 +1113,7 @@ Perl_gv_fetchmethod_pvn_flags(pTHX_ HV *stash, const char *name, const STRLEN le
"Can't locate object method \"%"UTF8f
"\" via package \"%"SVf"\""
" (perhaps you forgot to load \"%"SVf"\"?)",
- UTF8fARG(is_utf8, nend - name, name),
+ UTF8fARG(is_utf8, name_end - name, name),
SVfARG(packnamesv), SVfARG(packnamesv));
}
}
--
2.7.4

View File

@ -0,0 +1,94 @@
From 2c639acf40b4abc2783352f8e20dbfb68389e633 Mon Sep 17 00:00:00 2001
From: David Mitchell <davem@iabyn.com>
Date: Mon, 28 Nov 2016 08:03:49 +0000
Subject: [PATCH] crash on explicit return from s///e
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Petr Pisar: Ported to 5.24.0:
commit 7332835e5da7b7a793ef814a84e53003be1d0138
Author: David Mitchell <davem@iabyn.com>
Date: Mon Nov 28 08:03:49 2016 +0000
crash on explicit return from s///e
RT #130188
In
sub f {
my $x = 'a';
$x =~ s/./return;/e;
}
the 'return' triggers popping any contexts above the subroutine context:
in this case, a CXt_SUBST context. In this case, Perl_dounwind() calls
cx_popblock() for the bottom-most popped context, to restore any saved
vars. However, CXt_SUBST is the one context type which *doesn't* use
'struct block' as part of its context struct union, so you can't
cx_popblock() a CXt_SUBST context.
This commit makes it skip the cx_popblock() in this case.
Bug was introduced by me with v5.23.7-235-gfc6e609.
Signed-off-by: Petr Písař <ppisar@redhat.com>
---
pp_ctl.c | 6 ++++++
t/re/subst.t | 17 ++++++++++++++++-
2 files changed, 22 insertions(+), 1 deletion(-)
diff --git a/pp_ctl.c b/pp_ctl.c
index 99ff59a..b94c09a 100644
--- a/pp_ctl.c
+++ b/pp_ctl.c
@@ -1529,6 +1529,12 @@ Perl_dounwind(pTHX_ I32 cxix)
switch (CxTYPE(cx)) {
case CXt_SUBST:
CX_POPSUBST(cx);
+ /* CXt_SUBST is not a block context type, so skip the
+ * cx_popblock(cx) below */
+ if (cxstack_ix == cxix + 1) {
+ cxstack_ix--;
+ return;
+ }
break;
case CXt_SUB:
cx_popsub(cx);
diff --git a/t/re/subst.t b/t/re/subst.t
index 26a78c7..c039cc4 100644
--- a/t/re/subst.t
+++ b/t/re/subst.t
@@ -11,7 +11,7 @@ BEGIN {
require './loc_tools.pl';
}
-plan( tests => 271 );
+plan( tests => 272 );
$_ = 'david';
$a = s/david/rules/r;
@@ -1119,3 +1119,15 @@ SKIP: {
{stderr => 1 },
'[perl #129038 ] s/\xff//l no longer crashes');
}
+
+# [perl #130188] crash on return from substitution in subroutine
+# make sure returning from s///e doesn't SEGV
+{
+ my $f = sub {
+ my $x = 'a';
+ $x =~ s/./return;/e;
+ };
+ my $x = $f->();
+ pass("RT #130188");
+}
+
+
+
+
--
2.7.4

View File

@ -0,0 +1,66 @@
From d47812b974b515e952dc093e692bf15f0a9afbc4 Mon Sep 17 00:00:00 2001
From: Tony Cook <tony@develop-help.com>
Date: Mon, 5 Sep 2016 15:40:11 +1000
Subject: [PATCH] (perl #129130) make chdir allocate the stack it needs
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Ported to 5.24.0:
commit 92c843fb4b4e1a1e0ac7ec0fe198dc77266838da
Author: Tony Cook <tony@develop-help.com>
Date: Mon Sep 5 15:40:11 2016 +1000
(perl #129130) make chdir allocate the stack it needs
chdir with no argument didn't ensure there was stack space available
for its result.
Signed-off-by: Petr Písař <ppisar@redhat.com>
---
pp_sys.c | 1 +
t/op/chdir.t | 8 +++++++-
2 files changed, 8 insertions(+), 1 deletion(-)
diff --git a/pp_sys.c b/pp_sys.c
index 3bf2673..d2cf872 100644
--- a/pp_sys.c
+++ b/pp_sys.c
@@ -3639,6 +3639,7 @@ PP(pp_chdir)
HV * const table = GvHVn(PL_envgv);
SV **svp;
+ EXTEND(SP, 1);
if ( (svp = hv_fetchs(table, "HOME", FALSE))
|| (svp = hv_fetchs(table, "LOGDIR", FALSE))
#ifdef VMS
diff --git a/t/op/chdir.t b/t/op/chdir.t
index a5ea76a..685e556 100644
--- a/t/op/chdir.t
+++ b/t/op/chdir.t
@@ -10,7 +10,7 @@ BEGIN {
# possibilities into @INC.
unshift @INC, qw(t . lib ../lib);
require "test.pl";
- plan(tests => 47);
+ plan(tests => 48);
}
use Config;
@@ -161,6 +161,12 @@ sub check_env {
}
}
+fresh_perl_is(<<'EOP', '', { stderr => 1 }, "check stack handling");
+for $x (map $_+1, 1 .. 100) {
+ map chdir, 1 .. $x;
+}
+EOP
+
my %Saved_Env = ();
sub clean_env {
foreach my $env (@magic_envs) {
--
2.7.4

View File

@ -0,0 +1,79 @@
From 54550573a613ad20f00521880f345644a1db85cc Mon Sep 17 00:00:00 2001
From: Father Chrysostomos <sprout@cpan.org>
Date: Sun, 11 Sep 2016 21:29:56 -0700
Subject: [PATCH] Crash with splice
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Ported to 5.24.0:
commit 92b69f6501b4d7351e09c8b1ddd386aa7e1c9cd1
Author: Father Chrysostomos <sprout@cpan.org>
Date: Sun Sep 11 21:29:56 2016 -0700
[perl #129164] Crash with splice
This fixes #129166 and #129167 as well.
splice needs to take into account that arrays can hold NULLs and
return &PL_sv_undef in those cases where it would have returned a
NULL element.
Signed-off-by: Petr Písař <ppisar@redhat.com>
---
pp.c | 4 ++++
t/op/array.t | 17 +++++++++++++++++
2 files changed, 21 insertions(+)
diff --git a/pp.c b/pp.c
index 4a2cde0..4153482 100644
--- a/pp.c
+++ b/pp.c
@@ -5488,6 +5488,8 @@ PP(pp_splice)
for (i = length - 1, dst = &AvARRAY(ary)[offset]; i > 0; i--)
SvREFCNT_dec(*dst++); /* free them now */
}
+ if (!*MARK)
+ *MARK = &PL_sv_undef;
}
AvFILLp(ary) += diff;
@@ -5584,6 +5586,8 @@ PP(pp_splice)
while (length-- > 0)
SvREFCNT_dec(tmparyval[length]);
}
+ if (!*MARK)
+ *MARK = &PL_sv_undef;
}
else
*MARK = &PL_sv_undef;
diff --git a/t/op/array.t b/t/op/array.t
index 4f0a772..fb4e8c6 100644
--- a/t/op/array.t
+++ b/t/op/array.t
@@ -555,4 +555,21 @@ is $#foo, 3, 'assigning to arylen aliased in foreach(scalar $#arylen)';
is "@a", 'a b c', 'assigning to itself';
}
+# [perl #129164], [perl #129166], [perl #129167]
+# splice() with null array entries
+# These used to crash.
+$#a = -1; $#a++;
+() = 0-splice @a; # subtract
+$#a = -1; $#a++;
+() = -splice @a; # negate
+$#a = -1; $#a++;
+() = 0+splice @a; # add
+# And with array expansion, too
+$#a = -1; $#a++;
+() = 0-splice @a, 0, 1, 1, 1;
+$#a = -1; $#a++;
+() = -splice @a, 0, 1, 1, 1;
+$#a = -1; $#a++;
+() = 0+splice @a, 0, 1, 1, 1;
+
"We're included by lib/Tie/Array/std.t so we need to return something true";
--
2.7.4

View File

@ -0,0 +1,134 @@
From 478d23ef9e7700e20a75907648dd4c53b1b4f544 Mon Sep 17 00:00:00 2001
From: Tony Cook <tony@develop-help.com>
Date: Tue, 25 Oct 2016 16:17:18 +1100
Subject: [PATCH] (perl #129788) IO::Poll: fix memory leak
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Petr Pisar: Ported to 5.24.0:
commit 6de2dd46140d0d3ab6813e26940d7b74418b0260
Author: Tony Cook <tony@develop-help.com>
Date: Tue Oct 25 16:17:18 2016 +1100
(perl #129788) IO::Poll: fix memory leak
Whenever a magical/tied scalar which dies upon read was passed to _poll()
temporary buffer for events was not freed.
Adapted from a patch by Sergey Aleynikov <sergey.aleynikov@gmail.com>
Signed-off-by: Petr Písař <ppisar@redhat.com>
---
MANIFEST | 1 +
META.json | 1 +
META.yml | 1 +
dist/IO/IO.xs | 3 +--
dist/IO/t/io_leak.t | 37 +++++++++++++++++++++++++++++++++++++
5 files changed, 41 insertions(+), 2 deletions(-)
create mode 100644 dist/IO/t/io_leak.t
diff --git a/MANIFEST b/MANIFEST
index 2cdf616..3b5f8fb 100644
--- a/MANIFEST
+++ b/MANIFEST
@@ -3228,6 +3228,7 @@ dist/IO/t/io_dir.t See if directory-related methods from IO work
dist/IO/t/io_dup.t See if dup()-related methods from IO work
dist/IO/t/io_file_export.t Test IO::File exports
dist/IO/t/io_file.t See if binmode()-related methods on IO::File work
+dist/IO/t/io_leak.t See if IO leaks SVs (only run in core)
dist/IO/t/io_linenum.t See if I/O line numbers are tracked correctly
dist/IO/t/io_multihomed.t See if INET sockets work with multi-homed hosts
dist/IO/t/io_pipe.t See if pipe()-related methods from IO work
diff --git a/META.json b/META.json
index 4cb21a9..2809b58 100644
--- a/META.json
+++ b/META.json
@@ -84,6 +84,7 @@
"dist/IO/t/io_dup.t",
"dist/IO/t/io_file.t",
"dist/IO/t/io_file_export.t",
+ "dist/IO/t/io_leak.t",
"dist/IO/t/io_linenum.t",
"dist/IO/t/io_multihomed.t",
"dist/IO/t/io_pipe.t",
diff --git a/META.yml b/META.yml
index 13a2bb3..7494d2a 100644
--- a/META.yml
+++ b/META.yml
@@ -81,6 +81,7 @@ no_index:
- dist/IO/t/io_dup.t
- dist/IO/t/io_file.t
- dist/IO/t/io_file_export.t
+ - dist/IO/t/io_leak.t
- dist/IO/t/io_linenum.t
- dist/IO/t/io_multihomed.t
- dist/IO/t/io_pipe.t
diff --git a/dist/IO/IO.xs b/dist/IO/IO.xs
index fe749a6..15ef9b2 100644
--- a/dist/IO/IO.xs
+++ b/dist/IO/IO.xs
@@ -318,7 +318,7 @@ PPCODE:
{
#ifdef HAS_POLL
const int nfd = (items - 1) / 2;
- SV *tmpsv = NEWSV(999,nfd * sizeof(struct pollfd));
+ SV *tmpsv = sv_2mortal(NEWSV(999,nfd * sizeof(struct pollfd)));
/* We should pass _some_ valid pointer even if nfd is zero, but it
* doesn't matter what it is, since we're telling it to not check any fds.
*/
@@ -337,7 +337,6 @@ PPCODE:
sv_setiv(ST(i), fds[j].revents); i++;
}
}
- SvREFCNT_dec(tmpsv);
XSRETURN_IV(ret);
#else
not_here("IO::Poll::poll");
diff --git a/dist/IO/t/io_leak.t b/dist/IO/t/io_leak.t
new file mode 100644
index 0000000..08cbe2b
--- /dev/null
+++ b/dist/IO/t/io_leak.t
@@ -0,0 +1,37 @@
+#!/usr/bin/perl
+
+use warnings;
+use strict;
+
+use Test::More;
+
+eval { require XS::APItest; XS::APItest->import('sv_count'); 1 }
+ or plan skip_all => "No XS::APItest::sv_count() available";
+
+plan tests => 1;
+
+sub leak {
+ my ($n, $delta, $code, $name) = @_;
+ my $sv0 = 0;
+ my $sv1 = 0;
+ for my $i (1..$n) {
+ &$code();
+ $sv1 = sv_count();
+ $sv0 = $sv1 if $i == 1;
+ }
+ cmp_ok($sv1-$sv0, '<=', ($n-1)*$delta, $name);
+}
+
+# [perl #129788] IO::Poll shouldn't leak on errors
+{
+ package io_poll_leak;
+ use IO::Poll;
+
+ sub TIESCALAR { bless {} }
+ sub FETCH { die }
+
+ tie(my $a, __PACKAGE__);
+ sub f {eval { IO::Poll::_poll(0, $a, 1) }}
+
+ ::leak(5, 0, \&f, q{IO::Poll::_poll shouldn't leak});
+}
--
2.7.4

View File

@ -0,0 +1,97 @@
From 1b90dad20879f0e7a3eced5da0e0aacda93708ed Mon Sep 17 00:00:00 2001
From: Yves Orton <demerphq@gmail.com>
Date: Thu, 27 Oct 2016 13:52:24 +0200
Subject: [PATCH] regcomp.c: fix perl #129950 - fix firstchar bitmap under utf8
with prefix optimisation
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Ported to 5.24.0:
commit da42332b10691ba7af7550035ffc7f46c87e4e66
Author: Yves Orton <demerphq@gmail.com>
Date: Thu Oct 27 13:52:24 2016 +0200
regcomp.c: fix perl #129950 - fix firstchar bitmap under utf8 with prefix optimisation
The trie code contains a number of sub optimisations, one of which
extracts common prefixes from alternations, and another which isa
bitmap of the possible matching first chars.
The bitmap needs to contain the possible first octets of the string
which the trie can match, and for codepoints which might have a different
first octet under utf8 or non-utf8 need to register BOTH codepoints.
So for instance in the pattern (?:a|a\x{E4}) we should restructure this
as a(|\x{E4), and the bitmap for the trie should contain both \x{E4} AND
\x{C3} as \x{C3} is the first byte of \x{EF} expressed as utf8.
Signed-off-by: Petr Písař <ppisar@redhat.com>
---
regcomp.c | 14 ++++++++++++++
t/re/pat.t | 9 ++++++++-
2 files changed, 22 insertions(+), 1 deletion(-)
diff --git a/regcomp.c b/regcomp.c
index 7462885..bcb8db5 100644
--- a/regcomp.c
+++ b/regcomp.c
@@ -3272,6 +3272,13 @@ S_make_trie(pTHX_ RExC_state_t *pRExC_state, regnode *startbranch,
TRIE_BITMAP_SET(trie,*ch);
if ( folder )
TRIE_BITMAP_SET(trie, folder[ *ch ]);
+ if ( !UTF ) {
+ /* store first byte of utf8 representation of
+ variant codepoints */
+ if (! UVCHR_IS_INVARIANT(*ch)) {
+ TRIE_BITMAP_SET(trie, UTF8_TWO_BYTE_HI(*ch));
+ }
+ }
DEBUG_OPTIMISE_r(
Perl_re_printf( aTHX_ "%s", (char*)ch)
);
@@ -3280,6 +3287,13 @@ S_make_trie(pTHX_ RExC_state_t *pRExC_state, regnode *startbranch,
TRIE_BITMAP_SET(trie,*ch);
if ( folder )
TRIE_BITMAP_SET(trie,folder[ *ch ]);
+ if ( !UTF ) {
+ /* store first byte of utf8 representation of
+ variant codepoints */
+ if (! UVCHR_IS_INVARIANT(*ch)) {
+ TRIE_BITMAP_SET(trie, UTF8_TWO_BYTE_HI(*ch));
+ }
+ }
DEBUG_OPTIMISE_r(Perl_re_printf( aTHX_ "%s", ch));
}
idx = ofs;
diff --git a/t/re/pat.t b/t/re/pat.t
index 295a9f7..4aa77cf 100644
--- a/t/re/pat.t
+++ b/t/re/pat.t
@@ -23,7 +23,7 @@ BEGIN {
skip_all_without_unicode_tables();
}
-plan tests => 789; # Update this when adding/deleting tests.
+plan tests => 791; # Update this when adding/deleting tests.
run_tests() unless caller;
@@ -1758,6 +1758,13 @@ EOP
fresh_perl_is($code, $expect, {}, "$bug - $test_name" );
}
}
+
+ {
+ my $str = "a\xE4";
+ ok( $str =~ m{^(a|a\x{e4})$}, "fix [perl #129950] - latin1 case" );
+ utf8::upgrade($str);
+ ok( $str =~ m{^(a|a\x{e4})$}, "fix [perl #129950] - utf8 case" );
+ }
} # End of sub run_tests
1;
--
2.7.4

View File

@ -0,0 +1,92 @@
From 03fcc0c44bc7972f2c92736daae5b63d601b7c49 Mon Sep 17 00:00:00 2001
From: Dan Collins <dcollinsn@gmail.com>
Date: Fri, 23 Sep 2016 01:21:20 -0400
Subject: [PATCH] [rt #129336] #!perl -i u erroneously interpreted as -u
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Ported to 5.24.0:
commit f54cfdacff1f3744ef08fc70f1f3bc6c7d862e83
Author: Dan Collins <dcollinsn@gmail.com>
Date: Fri Sep 23 01:21:20 2016 -0400
[rt #129336] #!perl -i u erroneously interpreted as -u
Perl_moreswitches processes a single switch, and returns a pointer
to the start of the next switch. It can return either
the a pointer to the next flag itself:
#!perl -n -p
^ Can point here
Or, to the space before the next "arg":
#!perl -n -p
^ Can point here
(Where the next call to Perl_moreswitches will consume " -".)
In the case of -i[extension], the pointer is by default pointing at
the space after the end of the argument. The current code tries to
do the former, by unconditionally advancing the pointer, and then
advancing it again if it is on a '-'. But that is incorrect:
#!perl -i p
^ Will point here, but that isn't a flag
I could fix this by removing the unconditional s++, and having it
increment by 2 if *(s+1)=='-', but this work isn't actually
necessary - it's better to just leave it pointing at the space after
the argument.
Signed-off-by: Petr Písař <ppisar@redhat.com>
---
perl.c | 5 -----
t/op/lex.t | 9 ++++++++-
2 files changed, 8 insertions(+), 6 deletions(-)
diff --git a/perl.c b/perl.c
index 228a0d8..5cc7d0b 100644
--- a/perl.c
+++ b/perl.c
@@ -3306,11 +3306,6 @@ Perl_moreswitches(pTHX_ const char *s)
PL_inplace = savepvn(start, s - start);
}
- if (*s) {
- ++s;
- if (*s == '-') /* Additional switches on #! line. */
- s++;
- }
return s;
case 'I': /* -I handled both here and in parse_body() */
forbid_setid('I', FALSE);
diff --git a/t/op/lex.t b/t/op/lex.t
index c515449..9ada592 100644
--- a/t/op/lex.t
+++ b/t/op/lex.t
@@ -7,7 +7,7 @@ use warnings;
BEGIN { chdir 't' if -d 't'; require './test.pl'; }
-plan(tests => 26);
+plan(tests => 27);
{
no warnings 'deprecated';
@@ -209,3 +209,10 @@ fresh_perl_is(
{ stderr => 1 },
's;@{<<a; [perl #123995]'
);
+
+fresh_perl_like(
+ "#!perl -i u\nprint 'OK'",
+ qr/OK/,
+ {},
+ '[perl #129336] - #!perl -i argument handling'
+);
--
2.7.4

View File

@ -0,0 +1,94 @@
From 27a8a9e2a55ccc148582006396a9c35bafa5f0b3 Mon Sep 17 00:00:00 2001
From: David Mitchell <davem@iabyn.com>
Date: Wed, 30 Nov 2016 08:59:01 +0000
Subject: [PATCH] split was leaving PL_sv_undef in unused ary slots
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Petr Pisar: Ported to 5.24.0:
commit 71ca73e5fa9639ac33e9f2e74cd0c32288a5040d
Author: David Mitchell <davem@iabyn.com>
Date: Wed Nov 30 08:59:01 2016 +0000
split was leaving PL_sv_undef in unused ary slots
This:
@a = split(/-/,"-");
$a[1] = undef;
$a[0] = 0;
was giving
Modification of a read-only value attempted at foo line 3.
This is because:
1) unused slots in AvARRAY between AvFILL and AvMAX should always be
null; av_clear(), av_extend() etc do this; while av_store(), if storing
to a slot N somewhere between AvFILL and AvMAX, doesn't bother to clear
between (AvFILL+1)..(N-1) on the assumption that everyone else plays
nicely.
2) pp_split() when splitting directly to an array, sometimes over-splits
and has to null out the excess elements;
3) Since perl 5.19.4, unused AV slots are now marked with NULL rather than
&PL_sv_undef;
4) pp_split was still using &PL_sv_undef;
The fault was with (4), and is easily fixed.
Signed-off-by: Petr Písař <ppisar@redhat.com>
---
pp.c | 2 +-
t/op/split.t | 13 ++++++++++++-
2 files changed, 13 insertions(+), 2 deletions(-)
diff --git a/pp.c b/pp.c
index 4153482..70345ce 100644
--- a/pp.c
+++ b/pp.c
@@ -6212,7 +6212,7 @@ PP(pp_split)
while (iters > 0 && (!TOPs || !SvANY(TOPs) || SvCUR(TOPs) == 0)) {
if (TOPs && !make_mortal)
sv_2mortal(TOPs);
- *SP-- = &PL_sv_undef;
+ *SP-- = NULL;
iters--;
}
}
diff --git a/t/op/split.t b/t/op/split.t
index fb73271..b7846a1 100644
--- a/t/op/split.t
+++ b/t/op/split.t
@@ -7,7 +7,7 @@ BEGIN {
set_up_inc('../lib');
}
-plan tests => 131;
+plan tests => 133;
$FS = ':';
@@ -523,3 +523,14 @@ is "@a", '1 2 3', 'assignment to split-to-array (pmtarget/package array)';
}
(@{\@a} = split //, "abc") = 1..10;
is "@a", '1 2 3', 'assignment to split-to-array (stacked)';
+
+# splitting directly to an array wasn't filling unused AvARRAY slots with
+# NULL
+
+{
+ my @a;
+ @a = split(/-/,"-");
+ $a[1] = 'b';
+ ok eval { $a[0] = 'a'; 1; }, "array split filling AvARRAY: assign 0";
+ is "@a", "a b", "array split filling AvARRAY: result";
+}
--
2.7.4

View File

@ -0,0 +1,65 @@
From 3c38abae50c05c6f3c9f7eca561ec08c62fba1ba Mon Sep 17 00:00:00 2001
From: Sergey Aleynikov <sergey.aleynikov@gmail.com>
Date: Thu, 5 Jan 2017 01:33:32 +0300
Subject: [PATCH] Fix memory leak in B::RHE->HASH method.
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Petr Písař: Ported to 5.24.1:
commit 4b6e9aa6aa2256da1ec7ed08f819cbf5d1463741
Author: Sergey Aleynikov <sergey.aleynikov@gmail.com>
Date: Thu Jan 5 01:33:32 2017 +0300
Fix memory leak in B::RHE->HASH method.
Signed-off-by: Petr Písař <ppisar@redhat.com>
---
ext/B/B.xs | 2 +-
t/op/svleak.t | 12 +++++++++++-
2 files changed, 12 insertions(+), 2 deletions(-)
diff --git a/ext/B/B.xs b/ext/B/B.xs
index b4b6a40..e859d7d 100644
--- a/ext/B/B.xs
+++ b/ext/B/B.xs
@@ -2179,7 +2179,7 @@ SV*
HASH(h)
B::RHE h
CODE:
- RETVAL = newRV( (SV*)cophh_2hv(h, 0) );
+ RETVAL = newRV_noinc( (SV*)cophh_2hv(h, 0) );
OUTPUT:
RETVAL
diff --git a/t/op/svleak.t b/t/op/svleak.t
index c18f498..b0692ff 100644
--- a/t/op/svleak.t
+++ b/t/op/svleak.t
@@ -15,7 +15,7 @@ BEGIN {
use Config;
-plan tests => 132;
+plan tests => 133;
# run some code N times. If the number of SVs at the end of loop N is
# greater than (N-1)*delta at the end of loop 1, we've got a leak
@@ -547,3 +547,13 @@ EOF
sub f { $a =~ /[^.]+$b/; }
::leak(2, 0, \&f, q{use re 'strict' shouldn't leak warning strings});
}
+
+# check that B::RHE->HASH does not leak
+{
+ package BHINT;
+ sub foo {}
+ require B;
+ my $op = B::svref_2object(\&foo)->ROOT->first;
+ sub lk { { my $d = $op->hints_hash->HASH } }
+ ::leak(3, 0, \&lk, q!B::RHE->HASH shoudln't leak!);
+}
--
2.7.4

View File

@ -0,0 +1,70 @@
From 4e0fb37303b72ed9d38949139c304abdb73e223e Mon Sep 17 00:00:00 2001
From: Aaron Crane <arc@cpan.org>
Date: Tue, 24 Jan 2017 23:39:40 +0000
Subject: [PATCH] RT#130624: heap-use-after-free in 4-arg substr
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Ported to 5.24.1:
commit 41b1e858a075694f88057b9514f5fc78c80b5355
Author: Aaron Crane <arc@cpan.org>
Date: Tue Jan 24 23:39:40 2017 +0000
RT#130624: heap-use-after-free in 4-arg substr
Signed-off-by: Petr Písař <ppisar@redhat.com>
---
pp.c | 4 +++-
t/op/substr.t | 14 +++++++++++++-
2 files changed, 16 insertions(+), 2 deletions(-)
diff --git a/pp.c b/pp.c
index 334b353..aa6cff0 100644
--- a/pp.c
+++ b/pp.c
@@ -3462,8 +3462,10 @@ PP(pp_substr)
tmps = SvPV_force_nomg(sv, curlen);
if (DO_UTF8(repl_sv) && repl_len) {
if (!DO_UTF8(sv)) {
+ /* Upgrade the dest, and recalculate tmps in case the buffer
+ * got reallocated; curlen may also have been changed */
sv_utf8_upgrade_nomg(sv);
- curlen = SvCUR(sv);
+ tmps = SvPV_nomg(sv, curlen);
}
}
else if (DO_UTF8(sv))
diff --git a/t/op/substr.t b/t/op/substr.t
index 01c36a9..f9fee48 100644
--- a/t/op/substr.t
+++ b/t/op/substr.t
@@ -22,7 +22,7 @@ $SIG{__WARN__} = sub {
}
};
-plan(389);
+plan(391);
run_tests() unless caller;
@@ -872,3 +872,15 @@ is($destroyed, 1, 'Timely scalar destruction with lvalue substr');
# failed with ASAN
fresh_perl_is('$0 = "/usr/bin/perl"; substr($0, 0, 0, $0)', '', {}, "(perl #129340) substr() with source in target");
+
+
+# [perl #130624] - heap-use-after-free, observable under asan
+{
+ my $x = "\xE9zzzz";
+ my $y = "\x{100}";
+ my $z = substr $x, 0, 1, $y;
+ is $z, "\xE9", "RT#130624: heap-use-after-free in 4-arg substr (ret)";
+ is $x, "\x{100}zzzz", "RT#130624: heap-use-after-free in 4-arg substr (targ)";
+}
+
+
--
2.7.4

View File

@ -0,0 +1,93 @@
From fd25d49cae6409a4ce901fd4d899a197541604b3 Mon Sep 17 00:00:00 2001
From: David Mitchell <davem@iabyn.com>
Date: Sat, 4 Feb 2017 15:10:49 +0000
Subject: [PATCH] buffer overrun with format and 'use bytes'
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Ported to 5.24.1:
commit e452bf1c9e9f30813b1f289188a6e8b0894575ba
Author: David Mitchell <davem@iabyn.com>
Date: Sat Feb 4 15:10:49 2017 +0000
buffer overrun with format and 'use bytes'
RT #130703
In the scope of 'use bytes', appending a string to a format where the
format is utf8 and the string is non-utf8 but contains lots of chars
with ords >= 128, the buffer could be overrun. This is due to all the
\x80-type chars going from being stored as 1 bytes to 2 bytes, without
growing PL_formtarget accordingly.
This commit contains a minimal fix; the next commit will more generally
tidy up the grow code in pp_formline.
Signed-off-by: Petr Písař <ppisar@redhat.com>
---
pp_ctl.c | 3 +++
t/op/write.t | 18 +++++++++++++++++-
2 files changed, 20 insertions(+), 1 deletion(-)
diff --git a/pp_ctl.c b/pp_ctl.c
index a1fc2f4..4d5ef2e 100644
--- a/pp_ctl.c
+++ b/pp_ctl.c
@@ -505,6 +505,8 @@ PP(pp_formline)
SvTAINTED_on(PL_formtarget);
if (DO_UTF8(PL_formtarget))
targ_is_utf8 = TRUE;
+ /* this is an initial estimate of how much output buffer space
+ * to allocate. It may be exceeded later */
linemax = (SvCUR(formsv) * (IN_BYTES ? 1 : 3) + 1);
t = SvGROW(PL_formtarget, len + linemax + 1);
/* XXX from now onwards, SvCUR(PL_formtarget) is invalid */
@@ -766,6 +768,7 @@ PP(pp_formline)
if (targ_is_utf8 && !item_is_utf8) {
source = tmp = bytes_to_utf8(source, &to_copy);
+ grow = to_copy;
} else {
if (item_is_utf8 && !targ_is_utf8) {
U8 *s;
diff --git a/t/op/write.t b/t/op/write.t
index ab2733f..ae4ddb5 100644
--- a/t/op/write.t
+++ b/t/op/write.t
@@ -98,7 +98,7 @@ for my $tref ( @NumTests ){
my $bas_tests = 21;
# number of tests in section 3
-my $bug_tests = 66 + 3 * 3 * 5 * 2 * 3 + 2 + 66 + 6 + 2 + 3 + 96 + 11 + 3;
+my $bug_tests = 66 + 3 * 3 * 5 * 2 * 3 + 2 + 66 + 6 + 2 + 3 + 96 + 11 + 4;
# number of tests in section 4
my $hmb_tests = 37;
@@ -1562,6 +1562,22 @@ ok defined *{$::{CmT}}{FORMAT}, "glob assign";
formline $format, $orig, 12345;
is $^A, ("x" x 100) . " 12345\n", "\@* doesn't overflow";
+ # ...nor this (RT #130703).
+ # Under 'use bytes', the two bytes (c2, 80) making up each \x80 char
+ # each get expanded to two bytes (so four in total per \x80 char); the
+ # buffer growth wasn't accounting for this doubling in size
+
+ {
+ local $^A = '';
+ my $format = "X\n\x{100}" . ("\x80" x 200);
+ my $expected = $format;
+ utf8::encode($expected);
+ use bytes;
+ formline($format);
+ is $^A, $expected, "RT #130703";
+ }
+
+
# make sure it can cope with formats > 64k
$format = 'x' x 65537;
--
2.7.4

View File

@ -0,0 +1,116 @@
From b0254cedee2517d2705070839549189cf9f72db4 Mon Sep 17 00:00:00 2001
From: David Mitchell <davem@iabyn.com>
Date: Fri, 16 Jun 2017 15:46:19 +0100
Subject: [PATCH] don't call Perl_fbm_instr() with negative length
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Ported to 5.24.1:
commit bb152a4b442f7718fd37d32cc558be675e8ae1ae
Author: David Mitchell <davem@iabyn.com>
Date: Fri Jun 16 15:46:19 2017 +0100
don't call Perl_fbm_instr() with negative length
RT #131575
re_intuit_start() could calculate a maximum end position less than the
current start position. This used to get rejected by fbm_intr(), until
v5.23.3-110-g147f21b, which made fbm_intr() faster and removed unnecessary
checks.
This commits fixes re_intuit_start(), and adds an assert to fbm_intr().
Signed-off-by: Petr Písař <ppisar@redhat.com>
---
regexec.c | 17 +++++++++++------
t/re/pat.t | 13 ++++++++++++-
util.c | 2 ++
3 files changed, 25 insertions(+), 7 deletions(-)
diff --git a/regexec.c b/regexec.c
index f1a52ab..3080880 100644
--- a/regexec.c
+++ b/regexec.c
@@ -127,13 +127,16 @@ static const char* const non_utf8_target_but_utf8_required
(U8*)(off >= 0 ? reginfo->strend : reginfo->strbeg)) \
: (U8*)(pos + off))
-#define HOPBACKc(pos, off) \
- (char*)(reginfo->is_utf8_target \
- ? reghopmaybe3((U8*)pos, (SSize_t)0-off, (U8*)(reginfo->strbeg)) \
- : (pos - off >= reginfo->strbeg) \
- ? (U8*)pos - off \
+/* like HOPMAYBE3 but backwards. lim must be +ve. Returns NULL on overshoot */
+#define HOPBACK3(pos, off, lim) \
+ (reginfo->is_utf8_target \
+ ? reghopmaybe3((U8*)pos, (SSize_t)0-off, (U8*)(lim)) \
+ : (pos - off >= lim) \
+ ? (U8*)pos - off \
: NULL)
+#define HOPBACKc(pos, off) ((char*)HOPBACK3(pos, off, reginfo->strbeg))
+
#define HOP3(pos,off,lim) (reginfo->is_utf8_target ? reghop3((U8*)(pos), off, (U8*)(lim)) : (U8*)(pos + off))
#define HOP3c(pos,off,lim) ((char*)HOP3(pos,off,lim))
@@ -871,7 +874,9 @@ Perl_re_intuit_start(pTHX_
(IV)prog->check_end_shift);
});
- end_point = HOP3(strend, -end_shift, strbeg);
+ end_point = HOPBACK3(strend, end_shift, rx_origin);
+ if (!end_point)
+ goto fail_finish;
start_point = HOPMAYBE3(rx_origin, start_shift, end_point);
if (!start_point)
goto fail_finish;
diff --git a/t/re/pat.t b/t/re/pat.t
index 50529b8..007f11d 100644
--- a/t/re/pat.t
+++ b/t/re/pat.t
@@ -23,7 +23,7 @@ BEGIN {
skip_all_without_unicode_tables();
}
-plan tests => 793; # Update this when adding/deleting tests.
+plan tests => 794; # Update this when adding/deleting tests.
run_tests() unless caller;
@@ -1783,6 +1783,17 @@ EOP
# [perl #129281] buffer write overflow, detected by ASAN, valgrind
fresh_perl_is('/0(?0)|^*0(?0)|^*(^*())0|/', '', {}, "don't bump whilem_c too much");
}
+
+ {
+ # RT #131575 intuit skipping back from the end to find the highest
+ # possible start point, was potentially hopping back beyond pos()
+ # and crashing by calling fbm_instr with a negative length
+
+ my $text = "=t=\x{5000}";
+ pos($text) = 3;
+ ok(scalar($text !~ m{(~*=[a-z]=)}g), "RT #131575");
+ }
+
} # End of sub run_tests
1;
diff --git a/util.c b/util.c
index df75db0..bc265f5 100644
--- a/util.c
+++ b/util.c
@@ -806,6 +806,8 @@ Perl_fbm_instr(pTHX_ unsigned char *big, unsigned char *bigend, SV *littlestr, U
PERL_ARGS_ASSERT_FBM_INSTR;
+ assert(bigend >= big);
+
if ((STRLEN)(bigend - big) < littlelen) {
if ( SvTAIL(littlestr)
&& ((STRLEN)(bigend - big) == littlelen - 1)
--
2.9.4

View File

@ -0,0 +1,93 @@
From fbb9dc823a06b4815ee8fd8632fc475b8034e379 Mon Sep 17 00:00:00 2001
From: Yves Orton <demerphq@gmail.com>
Date: Fri, 27 Jan 2017 10:18:51 +0100
Subject: [PATCH] fix RT #130561 - recursion and optimising away impossible
quantifiers are not friends
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Ported to 5.24.1:
commit 31fc93954d1f379c7a49889d91436ce99818e1f6
Author: Yves Orton <demerphq@gmail.com>
Date: Fri Jan 27 10:18:51 2017 +0100
fix RT #130561 - recursion and optimising away impossible quantifiers are not friends
Instead of optimising away impossible quantifiers like (foo){1,0} treat them
as unquantified, and guard them with an OPFAIL. Thus /(foo){1,0}/ is treated
the same as /(*FAIL)(foo)/ this is important in patterns like /(foo){1,0}|(?1)/
where the (?1) needs to be able to recurse into the (foo) even though the
(foo){1,0} can never match. It also resolves various issues (SEGVs) with patterns
like /((?1)){1,0}/.
This patch would have been easier if S_reginsert() documented that it is
the callers responsibility to properly set up the NEXT_OFF() of the inserted
node (if the node has a NEXT_OFF())
Signed-off-by: Petr Písař <ppisar@redhat.com>
---
regcomp.c | 14 +++-----------
t/re/pat_rt_report.t | 11 ++++++++++-
2 files changed, 13 insertions(+), 12 deletions(-)
diff --git a/regcomp.c b/regcomp.c
index bcb8db5..9f343d3 100644
--- a/regcomp.c
+++ b/regcomp.c
@@ -11497,19 +11497,11 @@ S_regpiece(pTHX_ RExC_state_t *pRExC_state, I32 *flagp, U32 depth)
nextchar(pRExC_state);
if (max < min) { /* If can't match, warn and optimize to fail
unconditionally */
- if (SIZE_ONLY) {
-
- /* We can't back off the size because we have to reserve
- * enough space for all the things we are about to throw
- * away, but we can shrink it by the amount we are about
- * to re-use here */
- RExC_size += PREVOPER(RExC_size) - regarglen[(U8)OPFAIL];
- }
- else {
+ if (PASS2) {
ckWARNreg(RExC_parse, "Quantifier {n,m} with n > m can't match");
- RExC_emit = orig_emit;
}
- ret = reganode(pRExC_state, OPFAIL, 0);
+ reginsert(pRExC_state, OPFAIL, orig_emit, depth+1);
+ NEXT_OFF(orig_emit)= regarglen[OPFAIL] + NODE_STEP_REGNODE;
return ret;
}
else if (min == max && *RExC_parse == '?')
diff --git a/t/re/pat_rt_report.t b/t/re/pat_rt_report.t
index cb02ad2..2c1dbc4 100644
--- a/t/re/pat_rt_report.t
+++ b/t/re/pat_rt_report.t
@@ -20,7 +20,7 @@ use warnings;
use 5.010;
use Config;
-plan tests => 2500; # Update this when adding/deleting tests.
+plan tests => 2502; # Update this when adding/deleting tests.
run_tests() unless caller;
@@ -1113,6 +1113,15 @@ EOP
my $s = "\x{1ff}" . "f" x 32;
ok($s =~ /\x{1ff}[[:alpha:]]+/gca, "POSIXA pointer wrap");
}
+ {
+ # rt
+ fresh_perl_is(
+ '"foo"=~/((?1)){8,0}/; print "ok"',
+ "ok", {}, 'RT #130561 - allowing impossible quantifier should not cause SEGVs');
+ my $s= "foo";
+ ok($s=~/(foo){1,0}|(?1)/,
+ "RT #130561 - allowing impossible quantifier should not break recursion");
+ }
} # End of sub run_tests
1;
--
2.7.4

View File

@ -0,0 +1,198 @@
From f3704e62341b10824f503aa0c8029670d101a434 Mon Sep 17 00:00:00 2001
From: David Mitchell <davem@iabyn.com>
Date: Sat, 11 Feb 2017 11:53:41 +0000
Subject: [PATCH] fix pad/scope issue in re_evals
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Ported to 5.24.1:
commit 4b9c7caeaecf4e9df0be3a2e296644f763f775d6
Author: David Mitchell <davem@iabyn.com>
Date: Sat Feb 11 11:53:41 2017 +0000
fix pad/scope issue in re_evals
RT #129881 heap-buffer-overflow Perl_pad_sv
In some circumstances involving a pattern which has embedded code blocks
from more than one source, e.g.
my $r = qr{(?{1;}){2}X};
"" =~ /$r|(?{1;})/;
the wrong PL_comppad could be active while doing a LEAVE_SCOPE() or on
exit from the pattern.
This was mainly due to the big context stack changes in 5.24.0 - in
particular, since POP_MULTICALL() now does CX_LEAVE_SCOPE(cx) *before*
restoring PL_comppad, the (correct) unwinding of any SAVECOMPPAD's was
being followed by C<PL_comppad = cx->blk_sub.prevcomppad>, which wasn't
necessarily a sensible value.
To fix this, record the value of PL_savestack_ix at entry to S_regmatch(),
and set the cx->blk_oldsaveix of the MULTICALL to this value when pushed.
On exit from S_regmatch, we either POP_MULTICALL which will do a
LEAVE_SCOPE(cx->blk_oldsaveix), or in the absense of any EVAL, do the
explicit but equivalent LEAVE_SCOPE(orig_savestack_ix).
Note that this is a change in behaviour to S_regmatch() - formerly it
wouldn't necessarily clear the savestack completely back the point of
entry - that would get left to do by its caller, S_regtry(), or indirectly
by Perl_regexec_flags(). This shouldn't make any practical difference, but
is tidier and less likely to introduce bugs later.
Signed-off-by: Petr Písař <ppisar@redhat.com>
---
regexec.c | 69 +++++++++++++++++++++++++++++++++++++++++++-----------
t/re/pat_re_eval.t | 20 +++++++++++++++-
2 files changed, 74 insertions(+), 15 deletions(-)
diff --git a/regexec.c b/regexec.c
index a7bc0c3..5656cdd 100644
--- a/regexec.c
+++ b/regexec.c
@@ -5233,6 +5233,7 @@ S_regmatch(pTHX_ regmatch_info *reginfo, char *startpos, regnode *prog)
_char_class_number classnum;
bool is_utf8_pat = reginfo->is_utf8_pat;
bool match = FALSE;
+ I32 orig_savestack_ix = PL_savestack_ix;
/* Solaris Studio 12.3 messes up fetching PL_charclass['\n'] */
#if (defined(__SUNPRO_C) && (__SUNPRO_C == 0x5120) && defined(__x86_64) && defined(USE_64_BIT_ALL))
@@ -6646,30 +6647,67 @@ S_regmatch(pTHX_ regmatch_info *reginfo, char *startpos, regnode *prog)
nop = (OP*)rexi->data->data[n];
}
- /* normally if we're about to execute code from the same
- * CV that we used previously, we just use the existing
- * CX stack entry. However, its possible that in the
- * meantime we may have backtracked, popped from the save
- * stack, and undone the SAVECOMPPAD(s) associated with
- * PUSH_MULTICALL; in which case PL_comppad no longer
- * points to newcv's pad. */
+ /* Some notes about MULTICALL and the context and save stacks.
+ *
+ * In something like
+ * /...(?{ my $x)}...(?{ my $z)}...(?{ my $z)}.../
+ * since codeblocks don't introduce a new scope (so that
+ * local() etc accumulate), at the end of a successful
+ * match there will be a SAVEt_CLEARSV on the savestack
+ * for each of $x, $y, $z. If the three code blocks above
+ * happen to have come from different CVs (e.g. via
+ * embedded qr//s), then we must ensure that during any
+ * savestack unwinding, PL_comppad always points to the
+ * right pad at each moment. We achieve this by
+ * interleaving SAVEt_COMPPAD's on the savestack whenever
+ * there is a change of pad.
+ * In theory whenever we call a code block, we should
+ * push a CXt_SUB context, then pop it on return from
+ * that code block. This causes a bit of an issue in that
+ * normally popping a context also clears the savestack
+ * back to cx->blk_oldsaveix, but here we specifically
+ * don't want to clear the save stack on exit from the
+ * code block.
+ * Also for efficiency we don't want to keep pushing and
+ * popping the single SUB context as we backtrack etc.
+ * So instead, we push a single context the first time
+ * we need, it, then hang onto it until the end of this
+ * function. Whenever we encounter a new code block, we
+ * update the CV etc if that's changed. During the times
+ * in this function where we're not executing a code
+ * block, having the SUB context still there is a bit
+ * naughty - but we hope that no-one notices.
+ * When the SUB context is initially pushed, we fake up
+ * cx->blk_oldsaveix to be as if we'd pushed this context
+ * on first entry to S_regmatch rather than at some random
+ * point during the regexe execution. That way if we
+ * croak, popping the context stack will ensure that
+ * *everything* SAVEd by this function is undone and then
+ * the context popped, rather than e.g., popping the
+ * context (and restoring the original PL_comppad) then
+ * popping more of the savestack and restoiring a bad
+ * PL_comppad.
+ */
+
+ /* If this is the first EVAL, push a MULTICALL. On
+ * subsequent calls, if we're executing a different CV, or
+ * if PL_comppad has got messed up from backtracking
+ * through SAVECOMPPADs, then refresh the context.
+ */
if (newcv != last_pushed_cv || PL_comppad != last_pad)
{
U8 flags = (CXp_SUB_RE |
((newcv == caller_cv) ? CXp_SUB_RE_FAKE : 0));
+ SAVECOMPPAD();
if (last_pushed_cv) {
- /* PUSH/POP_MULTICALL save and restore the
- * caller's PL_comppad; if we call multiple subs
- * using the same CX block, we have to save and
- * unwind the varying PL_comppad's ourselves,
- * especially restoring the right PL_comppad on
- * backtrack - so save it on the save stack */
- SAVECOMPPAD();
CHANGE_MULTICALL_FLAGS(newcv, flags);
}
else {
PUSH_MULTICALL_FLAGS(newcv, flags);
}
+ /* see notes above */
+ CX_CUR()->blk_oldsaveix = orig_savestack_ix;
+
last_pushed_cv = newcv;
}
else {
@@ -8456,9 +8494,12 @@ NULL
if (last_pushed_cv) {
dSP;
+ /* see "Some notes about MULTICALL" above */
POP_MULTICALL;
PERL_UNUSED_VAR(SP);
}
+ else
+ LEAVE_SCOPE(orig_savestack_ix);
assert(!result || locinput - reginfo->strbeg >= 0);
return result ? locinput - reginfo->strbeg : -1;
diff --git a/t/re/pat_re_eval.t b/t/re/pat_re_eval.t
index e59b059..1a0b228 100644
--- a/t/re/pat_re_eval.t
+++ b/t/re/pat_re_eval.t
@@ -22,7 +22,7 @@ BEGIN {
}
-plan tests => 527; # Update this when adding/deleting tests.
+plan tests => 530; # Update this when adding/deleting tests.
run_tests() unless caller;
@@ -1232,6 +1232,24 @@ sub run_tests {
'padtmp swiping does not affect "$a$b" =~ /(??{})/'
}
+ # RT #129881
+ # on exit from a pattern with multiple code blocks from different
+ # CVs, PL_comppad wasn't being restored correctly
+
+ sub {
+ # give first few pad slots known values
+ my ($x1, $x2, $x3, $x4, $x5) = 101..105;
+ # these vars are in a separate pad
+ my $r = qr/((?{my ($y1, $y2) = 201..202; 1;})A){2}X/;
+ # the first alt fails, causing a switch to this anon
+ # sub's pad
+ "AAA" =~ /$r|(?{my ($z1, $z2) = 301..302; 1;})A/;
+ is $x1, 101, "RT #129881: x1";
+ is $x2, 102, "RT #129881: x2";
+ is $x3, 103, "RT #129881: x3";
+ }->();
+
+
} # End of sub run_tests
1;
--
2.7.4

View File

@ -0,0 +1,79 @@
From 59ef97c7af81ab6faba749d88b558a55da41c249 Mon Sep 17 00:00:00 2001
From: Zefram <zefram@fysh.org>
Date: Sun, 22 Jan 2017 07:26:34 +0000
Subject: [PATCH] fix special-case recreation of *::
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Ported to 5.24.1:
commit 120921acd4cf27bb932a725a8cf5c957652b22eb
Author: Zefram <zefram@fysh.org>
Date: Sun Jan 22 07:26:34 2017 +0000
fix special-case recreation of *::
If *:: is called for then as a special case it is looked up as
$::{"main::"}. If $::{"main::"} has been deleted, then that hash entry
is recreated. But formerly it was only recreated as an undef scalar,
which broke things relying on glob lookup returning a glob. Now in
that special case the recreated hash entry is initialised as a glob,
and populated with the customary recursive reference to the main stash.
Fixes [perl #129869].
Signed-off-by: Petr Písař <ppisar@redhat.com>
---
gv.c | 11 +++++++++--
t/op/stash.t | 9 ++++++++-
2 files changed, 17 insertions(+), 3 deletions(-)
diff --git a/gv.c b/gv.c
index c89a3e7..3fda9b9 100644
--- a/gv.c
+++ b/gv.c
@@ -1642,8 +1642,15 @@ S_parse_gv_stash_name(pTHX_ HV **stash, GV **gv, const char **name,
name_cursor++;
*name = name_cursor+1;
if (*name == name_end) {
- if (!*gv)
- *gv = MUTABLE_GV(*hv_fetchs(PL_defstash, "main::", TRUE));
+ if (!*gv) {
+ *gv = MUTABLE_GV(*hv_fetchs(PL_defstash, "main::", TRUE));
+ if (SvTYPE(*gv) != SVt_PVGV) {
+ gv_init_pvn(*gv, PL_defstash, "main::", 6,
+ GV_ADDMULTI);
+ GvHV(*gv) =
+ MUTABLE_HV(SvREFCNT_inc_simple(PL_defstash));
+ }
+ }
return TRUE;
}
}
diff --git a/t/op/stash.t b/t/op/stash.t
index 7ac379b..d6fded4 100644
--- a/t/op/stash.t
+++ b/t/op/stash.t
@@ -7,7 +7,7 @@ BEGIN {
BEGIN { require "./test.pl"; }
-plan( tests => 54 );
+plan( tests => 55 );
# Used to segfault (bug #15479)
fresh_perl_like(
@@ -355,3 +355,10 @@ is runperl(
),
"ok\n",
"[perl #128238] non-stashes in stashes";
+
+is runperl(
+ prog => '%:: = (); print *{q|::|}, qq|\n|',
+ stderr => 1,
+ ),
+ "*main::main::\n",
+ "[perl #129869] lookup %:: by name after clearing %::";
--
2.7.4

View File

@ -0,0 +1,107 @@
From 0c43d46cd570d2a19edfa54b9c637dea5c0a3514 Mon Sep 17 00:00:00 2001
From: Tony Cook <tony@develop-help.com>
Date: Thu, 19 Jan 2017 16:28:03 +1100
Subject: [PATCH] (perl #129125) copy form data if it might be freed
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Ported to 5.24.1:
commit 86191aed6f092273950ebdd48f886d4ec0c5e85e
Author: Tony Cook <tony@develop-help.com>
Date: Thu Jan 19 16:28:03 2017 +1100
(perl #129125) copy form data if it might be freed
If the format SV also appeared as an argument, and the FF_CHOP
operator modified that argument, the magic and hence the compiled
format would be freed, and the next iteration of the processing
the compiled format would read freed memory.
Unlike my original patch this copies the formsv too, since
that is also stored in the magic, and is needed for presenting
literal text from the format.
Signed-off-by: Petr Písař <ppisar@redhat.com>
---
pp_ctl.c | 18 ++++++++++++++++++
t/op/write.t | 19 ++++++++++++++++++-
2 files changed, 36 insertions(+), 1 deletion(-)
diff --git a/pp_ctl.c b/pp_ctl.c
index b94c09a..e859e01 100644
--- a/pp_ctl.c
+++ b/pp_ctl.c
@@ -490,6 +490,7 @@ PP(pp_formline)
U8 *source; /* source of bytes to append */
STRLEN to_copy; /* how may bytes to append */
char trans; /* what chars to translate */
+ bool copied_form = false; /* have we duplicated the form? */
mg = doparseform(tmpForm);
@@ -687,6 +688,23 @@ PP(pp_formline)
case FF_CHOP: /* (for ^*) chop the current item */
if (sv != &PL_sv_no) {
const char *s = chophere;
+ if (!copied_form &&
+ ((sv == tmpForm || SvSMAGICAL(sv))
+ || (SvGMAGICAL(tmpForm) && !sv_only_taint_gmagic(tmpForm))) ) {
+ /* sv and tmpForm are either the same SV, or magic might allow modification
+ of tmpForm when sv is modified, so copy */
+ SV *newformsv = sv_mortalcopy(formsv);
+ U32 *new_compiled;
+
+ f = SvPV_nolen(newformsv) + (f - SvPV_nolen(formsv));
+ Newx(new_compiled, mg->mg_len / sizeof(U32), U32);
+ memcpy(new_compiled, mg->mg_ptr, mg->mg_len);
+ SAVEFREEPV(new_compiled);
+ fpc = new_compiled + (fpc - (U32*)mg->mg_ptr);
+ formsv = newformsv;
+
+ copied_form = true;
+ }
if (chopspace) {
while (isSPACE(*s))
s++;
diff --git a/t/op/write.t b/t/op/write.t
index 590d658..ab2733f 100644
--- a/t/op/write.t
+++ b/t/op/write.t
@@ -98,7 +98,7 @@ for my $tref ( @NumTests ){
my $bas_tests = 21;
# number of tests in section 3
-my $bug_tests = 66 + 3 * 3 * 5 * 2 * 3 + 2 + 66 + 4 + 2 + 3 + 96 + 11 + 3;
+my $bug_tests = 66 + 3 * 3 * 5 * 2 * 3 + 2 + 66 + 6 + 2 + 3 + 96 + 11 + 3;
# number of tests in section 4
my $hmb_tests = 37;
@@ -1637,6 +1637,23 @@ printf ">%s<\n", ref $zamm;
print "$zamm->[0]\n";
EOP
+# [perl #129125] - detected by -fsanitize=address or valgrind
+# the compiled format would be freed when the format string was modified
+# by the chop operator
+fresh_perl_is(<<'EOP', "^", { stderr => 1 }, '#129125 - chop on format');
+my $x = '^@';
+formline$x=>$x;
+print $^A;
+EOP
+
+fresh_perl_is(<<'EOP', '<^< xx AA><xx ^<><>', { stderr => 1 }, '#129125 - chop on format, later values');
+my $x = '^< xx ^<';
+my $y = 'AA';
+formline $x => $x, $y;
+print "<$^A><$x><$y>";
+EOP
+
+
# [perl #73690]
select +(select(RT73690), do {
--
2.7.4

View File

@ -0,0 +1,70 @@
From 2f221fc2333bd87615c03354b591b390e8b06715 Mon Sep 17 00:00:00 2001
From: Tony Cook <tony@develop-help.com>
Date: Tue, 24 Jan 2017 11:14:28 +1100
Subject: [PATCH] (perl #129274) avoid treating the # in $# as a comment intro
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Petr Písař: Ported to 5.24.1:
commit 71776ae4fad9a7659deefe0c2376d45b873ffd6a
Author: Tony Cook <tony@develop-help.com>
Date: Tue Jan 24 11:14:28 2017 +1100
(perl #129274) avoid treating the # in $# as a comment intro
Signed-off-by: Petr Písař <ppisar@redhat.com>
---
t/op/lex.t | 15 ++++++++++++++-
toke.c | 4 +++-
2 files changed, 17 insertions(+), 2 deletions(-)
diff --git a/t/op/lex.t b/t/op/lex.t
index 9ada592..d679d7c 100644
--- a/t/op/lex.t
+++ b/t/op/lex.t
@@ -7,7 +7,7 @@ use warnings;
BEGIN { chdir 't' if -d 't'; require './test.pl'; }
-plan(tests => 27);
+plan(tests => 28);
{
no warnings 'deprecated';
@@ -223,3 +223,16 @@ fresh_perl_like(
{},
'[perl #129336] - #!perl -i argument handling'
);
+
+# probably only failed under ASAN
+fresh_perl_is(
+ "stat\tt\$#0",
+ <<'EOM',
+$# is no longer supported at - line 1.
+Number found where operator expected at - line 1, near "$#0"
+ (Missing operator before 0?)
+Can't call method "t" on an undefined value at - line 1.
+EOM
+ {},
+ "[perl #129273] heap use after free or overflow"
+);
diff --git a/toke.c b/toke.c
index 576ce72..630fc59 100644
--- a/toke.c
+++ b/toke.c
@@ -4090,7 +4090,9 @@ S_intuit_method(pTHX_ char *start, SV *ioname, CV *cv)
if (cv || PL_last_lop_op == OP_PRINT || PL_last_lop_op == OP_SAY
|| isUPPER(*PL_tokenbuf))
return 0;
- s = skipspace(s);
+ /* this could be $# */
+ if (isSPACE(*s))
+ s = skipspace(s);
PL_bufptr = start;
PL_expect = XREF;
return *s == '(' ? FUNCMETH : METHOD;
--
2.7.4

View File

@ -0,0 +1,49 @@
From 92f8cd4e7b0ff3d09162139e3c99b1d9310bca81 Mon Sep 17 00:00:00 2001
From: Tony Cook <tony@develop-help.com>
Date: Mon, 10 Oct 2016 10:46:46 +1100
Subject: [PATCH] (perl #129281) test for buffer overflow issue
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Ported to 5.24.1:
commit d2ba660af00f1bf2e7012741615eff7c19f29707
Author: Tony Cook <tony@develop-help.com>
Date: Mon Oct 10 10:46:46 2016 +1100
(perl #129281) test for buffer overflow issue
Signed-off-by: Petr Písař <ppisar@redhat.com>
---
t/re/pat.t | 7 ++++++-
1 file changed, 6 insertions(+), 1 deletion(-)
diff --git a/t/re/pat.t b/t/re/pat.t
index 749edd0..7b8e6f7 100644
--- a/t/re/pat.t
+++ b/t/re/pat.t
@@ -23,7 +23,7 @@ BEGIN {
skip_all_without_unicode_tables();
}
-plan tests => 792; # Update this when adding/deleting tests.
+plan tests => 793; # Update this when adding/deleting tests.
run_tests() unless caller;
@@ -1779,6 +1779,11 @@ EOP
}msx, { stderr => 1 }, "Offsets in debug output are not negative");
}
}
+ {
+ # [perl #129281] buffer write overflow, detected by ASAN, valgrind
+ local $::TODO = "whilem_c bumped too much";
+ fresh_perl_is('/0(?0)|^*0(?0)|^*(^*())0|/', '', {}, "don't bump whilem_c too much");
+ }
} # End of sub run_tests
1;
--
2.7.4

View File

@ -0,0 +1,104 @@
From 4fe0e2d067ac5639d94f35f8c7e8ac4e0e3ab336 Mon Sep 17 00:00:00 2001
From: Tony Cook <tony@develop-help.com>
Date: Mon, 20 Feb 2017 11:02:21 +1100
Subject: [PATCH] (perl #129340) copy the source when inside the dest in
sv_insert_flags()
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Ported to 5.24.1:
commit e7a8a8aac45d42d72d1586227ca51771f193f5dc
Author: Tony Cook <tony@develop-help.com>
Date: Mon Feb 20 11:02:21 2017 +1100
(perl #129340) copy the source when inside the dest in sv_insert_flags()
Signed-off-by: Petr Písař <ppisar@redhat.com>
---
embed.fnc | 2 +-
proto.h | 2 +-
sv.c | 12 +++++++++++-
t/op/substr.t | 5 ++++-
4 files changed, 17 insertions(+), 4 deletions(-)
diff --git a/embed.fnc b/embed.fnc
index a64ffba..2395efb 100644
--- a/embed.fnc
+++ b/embed.fnc
@@ -1437,7 +1437,7 @@ Amdb |void |sv_insert |NN SV *const bigstr|const STRLEN offset \
|const STRLEN len|NN const char *const little \
|const STRLEN littlelen
Apd |void |sv_insert_flags|NN SV *const bigstr|const STRLEN offset|const STRLEN len \
- |NN const char *const little|const STRLEN littlelen|const U32 flags
+ |NN const char *little|const STRLEN littlelen|const U32 flags
Apd |int |sv_isa |NULLOK SV* sv|NN const char *const name
Apd |int |sv_isobject |NULLOK SV* sv
Apd |STRLEN |sv_len |NULLOK SV *const sv
diff --git a/proto.h b/proto.h
index fb4ee29..2b2004a 100644
--- a/proto.h
+++ b/proto.h
@@ -3015,7 +3015,7 @@ PERL_CALLCONV void Perl_sv_inc_nomg(pTHX_ SV *const sv);
/* PERL_CALLCONV void Perl_sv_insert(pTHX_ SV *const bigstr, const STRLEN offset, const STRLEN len, const char *const little, const STRLEN littlelen); */
#define PERL_ARGS_ASSERT_SV_INSERT \
assert(bigstr); assert(little)
-PERL_CALLCONV void Perl_sv_insert_flags(pTHX_ SV *const bigstr, const STRLEN offset, const STRLEN len, const char *const little, const STRLEN littlelen, const U32 flags);
+PERL_CALLCONV void Perl_sv_insert_flags(pTHX_ SV *const bigstr, const STRLEN offset, const STRLEN len, const char *little, const STRLEN littlelen, const U32 flags);
#define PERL_ARGS_ASSERT_SV_INSERT_FLAGS \
assert(bigstr); assert(little)
PERL_CALLCONV int Perl_sv_isa(pTHX_ SV* sv, const char *const name);
diff --git a/sv.c b/sv.c
index d1e84f0..697db41 100644
--- a/sv.c
+++ b/sv.c
@@ -6223,7 +6223,7 @@ C<SvPV_force_flags> that applies to C<bigstr>.
*/
void
-Perl_sv_insert_flags(pTHX_ SV *const bigstr, const STRLEN offset, const STRLEN len, const char *const little, const STRLEN littlelen, const U32 flags)
+Perl_sv_insert_flags(pTHX_ SV *const bigstr, const STRLEN offset, const STRLEN len, const char *little, const STRLEN littlelen, const U32 flags)
{
char *big;
char *mid;
@@ -6236,6 +6236,16 @@ Perl_sv_insert_flags(pTHX_ SV *const bigstr, const STRLEN offset, const STRLEN l
SvPV_force_flags(bigstr, curlen, flags);
(void)SvPOK_only_UTF8(bigstr);
+
+ if (little >= SvPVX(bigstr) &&
+ little < SvPVX(bigstr) + (SvLEN(bigstr) ? SvLEN(bigstr) : SvCUR(bigstr))) {
+ /* little is a pointer to within bigstr, since we can reallocate bigstr,
+ or little...little+littlelen might overlap offset...offset+len we make a copy
+ */
+ little = savepvn(little, littlelen);
+ SAVEFREEPV(little);
+ }
+
if (offset + len > curlen) {
SvGROW(bigstr, offset+len+1);
Zero(SvPVX(bigstr)+curlen, offset+len-curlen, char);
diff --git a/t/op/substr.t b/t/op/substr.t
index eae2403..01c36a9 100644
--- a/t/op/substr.t
+++ b/t/op/substr.t
@@ -22,7 +22,7 @@ $SIG{__WARN__} = sub {
}
};
-plan(388);
+plan(389);
run_tests() unless caller;
@@ -869,3 +869,6 @@ is($destroyed, 1, 'Timely scalar destruction with lvalue substr');
is($result_3363, "best", "ref-to-substr retains lvalue-ness under recursion [perl #3363]");
}
+
+# failed with ASAN
+fresh_perl_is('$0 = "/usr/bin/perl"; substr($0, 0, 0, $0)', '', {}, "(perl #129340) substr() with source in target");
--
2.7.4

View File

@ -0,0 +1,73 @@
From a26907949ed561dccd661fc8600889eddc6664ea Mon Sep 17 00:00:00 2001
From: Hugo van der Sanden <hv@crypt.org>
Date: Wed, 5 Oct 2016 14:53:27 +0100
Subject: [PATCH] [perl #129342] ensure range-start is set after error in tr///
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Ported to 5.24.1:
t 59143e29a717d67a61b869a6c5bb49574f1ef43f
Author: Tony Cook <tony@develop-help.com>
Date: Tue Jan 17 11:52:53 2017 +1100
(perl #129342) test for buffer overflow
commit 3dd4eaeb8ac39e08179145b86aedda36584a3509
Author: Hugo van der Sanden <hv@crypt.org>
Date: Wed Oct 5 14:53:27 2016 +0100
[perl #129342] ensure range-start is set after error in tr///
A parse error due to invalid octal or hex escape in the range of a
transliteration must still ensure some kind of start and end values
are captured, since we don't stop on the first such error. Failure
to do so can cause invalid reads after "Here we have parsed a range".
Signed-off-by: Petr Písař <ppisar@redhat.com>
---
t/lib/croak/toke | 7 +++++++
toke.c | 4 ++--
2 files changed, 9 insertions(+), 2 deletions(-)
diff --git a/t/lib/croak/toke b/t/lib/croak/toke
index 18dfa24..578a6da 100644
--- a/t/lib/croak/toke
+++ b/t/lib/croak/toke
@@ -302,3 +302,10 @@ Execution of - aborted due to compilation errors.
BEGIN <>
EXPECT
Illegal declaration of subroutine BEGIN at - line 1.
+########
+# NAME tr/// handling of mis-formatted \o characters
+# may only fail with ASAN
+tr/\o-0//;
+EXPECT
+Missing braces on \o{} at - line 2, within string
+Execution of - aborted due to compilation errors.
diff --git a/toke.c b/toke.c
index 288f372..576ce72 100644
--- a/toke.c
+++ b/toke.c
@@ -3338,7 +3338,7 @@ S_scan_const(pTHX_ char *start)
UTF);
if (! valid) {
yyerror(error);
- continue;
+ uv = 0; /* drop through to ensure range ends are set */
}
goto NUM_ESCAPE_INSERT;
}
@@ -3356,7 +3356,7 @@ S_scan_const(pTHX_ char *start)
UTF);
if (! valid) {
yyerror(error);
- continue;
+ uv = 0; /* drop through to ensure range ends are set */
}
}
--
2.7.4

View File

@ -0,0 +1,107 @@
From a08fa6fd157fd0d61da7f20f07b939fbc302c2c6 Mon Sep 17 00:00:00 2001
From: Hugo van der Sanden <hv@crypt.org>
Date: Wed, 5 Oct 2016 12:56:05 +0100
Subject: [PATCH] [perl #129377] don't read past start of string for unmatched
backref
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Ported to 5.24.1:
commit 2dfc11ec3af312f4fa3eb244077c79dbb5fc2d85
Author: Hugo van der Sanden <hv@crypt.org>
Date: Wed Oct 5 12:56:05 2016 +0100
[perl #129377] don't read past start of string for unmatched backref
We can have (start, end) == (0, -1) for an unmatched backref, we must
check for that.
Signed-off-by: Petr Písař <ppisar@redhat.com>
---
regexec.c | 10 ++++++----
t/re/pat.t | 16 +++++++++++++++-
2 files changed, 21 insertions(+), 5 deletions(-)
diff --git a/regexec.c b/regexec.c
index a5d5db4..a7bc0c3 100644
--- a/regexec.c
+++ b/regexec.c
@@ -5179,6 +5179,7 @@ S_regmatch(pTHX_ regmatch_info *reginfo, char *startpos, regnode *prog)
regnode *next;
U32 n = 0; /* general value; init to avoid compiler warning */
SSize_t ln = 0; /* len or last; init to avoid compiler warning */
+ SSize_t endref = 0; /* offset of end of backref when ln is start */
char *locinput = startpos;
char *pushinput; /* where to continue after a PUSH */
I32 nextchr; /* is always set to UCHARAT(locinput), or -1 at EOS */
@@ -6489,10 +6490,11 @@ S_regmatch(pTHX_ regmatch_info *reginfo, char *startpos, regnode *prog)
do_nref_ref_common:
ln = rex->offs[n].start;
+ endref = rex->offs[n].end;
reginfo->poscache_iter = reginfo->poscache_maxiter; /* Void cache */
- if (rex->lastparen < n || ln == -1)
+ if (rex->lastparen < n || ln == -1 || endref == -1)
sayNO; /* Do not match unless seen CLOSEn. */
- if (ln == rex->offs[n].end)
+ if (ln == endref)
break;
s = reginfo->strbeg + ln;
@@ -6506,7 +6508,7 @@ S_regmatch(pTHX_ regmatch_info *reginfo, char *startpos, regnode *prog)
* not going off the end given by reginfo->strend, and
* returns in <limit> upon success, how much of the
* current input was matched */
- if (! foldEQ_utf8_flags(s, NULL, rex->offs[n].end - ln, utf8_target,
+ if (! foldEQ_utf8_flags(s, NULL, endref - ln, utf8_target,
locinput, &limit, 0, utf8_target, utf8_fold_flags))
{
sayNO;
@@ -6521,7 +6523,7 @@ S_regmatch(pTHX_ regmatch_info *reginfo, char *startpos, regnode *prog)
(type == REF ||
UCHARAT(s) != fold_array[nextchr]))
sayNO;
- ln = rex->offs[n].end - ln;
+ ln = endref - ln;
if (locinput + ln > reginfo->strend)
sayNO;
if (ln > 1 && (type == REF
diff --git a/t/re/pat.t b/t/re/pat.t
index 4aa77cf..749edd0 100644
--- a/t/re/pat.t
+++ b/t/re/pat.t
@@ -23,7 +23,7 @@ BEGIN {
skip_all_without_unicode_tables();
}
-plan tests => 791; # Update this when adding/deleting tests.
+plan tests => 792; # Update this when adding/deleting tests.
run_tests() unless caller;
@@ -1765,6 +1765,20 @@ EOP
utf8::upgrade($str);
ok( $str =~ m{^(a|a\x{e4})$}, "fix [perl #129950] - utf8 case" );
}
+ {
+ # [perl #129377] backref to an unmatched capture should not cause
+ # reading before start of string.
+ SKIP: {
+ skip "no re-debug under miniperl" if is_miniperl;
+ my $prog = <<'EOP';
+use re qw(Debug EXECUTE);
+"x" =~ m{ () y | () \1 }x;
+EOP
+ fresh_perl_like($prog, qr{
+ \A (?! .* ^ \s+ - )
+ }msx, { stderr => 1 }, "Offsets in debug output are not negative");
+ }
+ }
} # End of sub run_tests
1;
--
2.7.4

View File

@ -0,0 +1,62 @@
From 2bcb4a5888b1c26ee11bc447cc02b42290c707af Mon Sep 17 00:00:00 2001
From: Tony Cook <tony@develop-help.com>
Date: Mon, 5 Dec 2016 11:48:14 +1100
Subject: [PATCH] (perl #130262) split scalar context stack overflow fix
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Ported to 5.14.1:
commit 02c161ef974f8f1efbb5632f741c1164adb6ca75
Author: Tony Cook <tony@develop-help.com>
Date: Mon Dec 5 11:48:14 2016 +1100
(perl #130262) split scalar context stack overflow fix
pp_split didn't ensure there was space for its return value
in scalar context.
Signed-off-by: Petr Písař <ppisar@redhat.com>
---
pp.c | 2 +-
t/op/split.t | 6 +++++-
2 files changed, 6 insertions(+), 2 deletions(-)
diff --git a/pp.c b/pp.c
index 70345ce..334b353 100644
--- a/pp.c
+++ b/pp.c
@@ -6259,7 +6259,7 @@ PP(pp_split)
}
GETTARGET;
- PUSHi(iters);
+ XPUSHi(iters);
RETURN;
}
diff --git a/t/op/split.t b/t/op/split.t
index b7846a1..3e08841 100644
--- a/t/op/split.t
+++ b/t/op/split.t
@@ -7,7 +7,7 @@ BEGIN {
set_up_inc('../lib');
}
-plan tests => 133;
+plan tests => 134;
$FS = ':';
@@ -534,3 +534,7 @@ is "@a", '1 2 3', 'assignment to split-to-array (stacked)';
ok eval { $a[0] = 'a'; 1; }, "array split filling AvARRAY: assign 0";
is "@a", "a b", "array split filling AvARRAY: result";
}
+
+fresh_perl_is(<<'CODE', '', {}, "scalar split stack overflow");
+map{int"";split//.0>60for"0000000000000000"}split// for"00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"
+CODE
--
2.7.4

View File

@ -0,0 +1,50 @@
From 9df34f9c4701104a366e768237ca694411136d2a Mon Sep 17 00:00:00 2001
From: Hugo van der Sanden <hv@crypt.org>
Date: Sun, 19 Feb 2017 10:46:09 +0000
Subject: [PATCH] update pointer into PL_linestr after lookahead
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Ported to: 5.24.1:
commit 90f2cc9a600117a49f8ee3e30cc681f062350c24
Author: Hugo van der Sanden <hv@crypt.org>
Date: Sun Feb 19 10:46:09 2017 +0000
[perl #130814] update pointer into PL_linestr after lookahead
Looking ahead for the "Missing $ on loop variable" diagnostic can reallocate
PL_linestr, invalidating our pointer. Save the offset so we can update it
in that case.
Signed-off-by: Petr Písař <ppisar@redhat.com>
---
toke.c | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/toke.c b/toke.c
index 630fc59..029d2ea 100644
--- a/toke.c
+++ b/toke.c
@@ -7565,6 +7565,7 @@ Perl_yylex(pTHX)
s = skipspace(s);
if (PL_expect == XSTATE && isIDFIRST_lazy_if(s,UTF)) {
char *p = s;
+ SSize_t s_off = s - SvPVX(PL_linestr);
if ((PL_bufend - p) >= 3
&& strnEQ(p, "my", 2) && isSPACE(*(p + 2)))
@@ -7582,6 +7583,9 @@ Perl_yylex(pTHX)
}
if (*p != '$')
Perl_croak(aTHX_ "Missing $ on loop variable");
+
+ /* The buffer may have been reallocated, update s */
+ s = SvPVX(PL_linestr) + s_off;
}
OPERATOR(FOR);
--
2.7.4

View File

@ -0,0 +1,72 @@
From be05b2f7a801ae1721641fd240e0d7d6fc018136 Mon Sep 17 00:00:00 2001
From: Aaron Crane <arc@cpan.org>
Date: Sun, 19 Feb 2017 12:26:54 +0000
Subject: [PATCH] fix ck_return null-pointer deref on malformed code
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Ported to 5.24.1:
commit e5c165a0b7551ffb94661aa7f18aabadba257782
Author: Aaron Crane <arc@cpan.org>
Date: Sun Feb 19 12:26:54 2017 +0000
[perl #130815] fix ck_return null-pointer deref on malformed code
commit 9de2a80ffc0eefb4d60e13766baf4bad129e0a92
Author: David Mitchell <davem@iabyn.com>
Date: Sun Feb 19 12:36:58 2017 +0000
bump test count in t/comp/parser.t
(the previous commit forgot to)
Signed-off-by: Petr Písař <ppisar@redhat.com>
---
op.c | 2 +-
t/comp/parser.t | 8 +++++++-
2 files changed, 8 insertions(+), 2 deletions(-)
diff --git a/op.c b/op.c
index 018d90c..9a61ea7 100644
--- a/op.c
+++ b/op.c
@@ -10695,7 +10695,7 @@ Perl_ck_return(pTHX_ OP *o)
PERL_ARGS_ASSERT_CK_RETURN;
kid = OpSIBLING(cLISTOPo->op_first);
- if (CvLVALUE(PL_compcv)) {
+ if (PL_compcv && CvLVALUE(PL_compcv)) {
for (; kid; kid = OpSIBLING(kid))
op_lvalue(kid, OP_LEAVESUBLV);
}
diff --git a/t/comp/parser.t b/t/comp/parser.t
index 50f601c..5016509 100644
--- a/t/comp/parser.t
+++ b/t/comp/parser.t
@@ -8,7 +8,7 @@ BEGIN {
chdir 't' if -d 't';
}
-print "1..173\n";
+print "1..174\n";
sub failed {
my ($got, $expected, $name) = @_;
@@ -546,6 +546,12 @@ eval "grep+grep";
eval 'qq{@{0]}${}},{})';
is(1, 1, "RT #124207");
+# RT #130815: crash in ck_return for malformed code
+{
+ eval 'm(@{if(0){sub d{]]])}return';
+ like $@, qr/^syntax error at \(eval \d+\) line 1, near "\{\]"/,
+ 'RT #130815: null pointer deref';
+}
# Add new tests HERE (above this line)
--
2.7.4

View File

@ -0,0 +1,81 @@
From 0cefeca1fd2405ad1b5544a3919e0000377fde5e Mon Sep 17 00:00:00 2001
From: Tony Cook <tony@develop-help.com>
Date: Tue, 21 Feb 2017 16:38:36 +1100
Subject: [PATCH] (perl #130822) fix an AV leak in Perl_reg_named_buff_fetch
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Ported to 5.24.1:
commit 853eb961c1a3b014b5a9510740abc15ccd4383b6
Author: Tony Cook <tony@develop-help.com>
Date: Tue Feb 21 16:38:36 2017 +1100
(perl #130822) fix an AV leak in Perl_reg_named_buff_fetch
Originally noted as a scoping issue by Andy Lester.
Signed-off-by: Petr Písař <ppisar@redhat.com>
---
regcomp.c | 5 +----
t/op/svleak.t | 12 +++++++++++-
2 files changed, 12 insertions(+), 5 deletions(-)
diff --git a/regcomp.c b/regcomp.c
index 6329f6c..989c528 100644
--- a/regcomp.c
+++ b/regcomp.c
@@ -7849,21 +7849,18 @@ SV*
Perl_reg_named_buff_fetch(pTHX_ REGEXP * const r, SV * const namesv,
const U32 flags)
{
- AV *retarray = NULL;
SV *ret;
struct regexp *const rx = ReANY(r);
PERL_ARGS_ASSERT_REG_NAMED_BUFF_FETCH;
- if (flags & RXapif_ALL)
- retarray=newAV();
-
if (rx && RXp_PAREN_NAMES(rx)) {
HE *he_str = hv_fetch_ent( RXp_PAREN_NAMES(rx), namesv, 0, 0 );
if (he_str) {
IV i;
SV* sv_dat=HeVAL(he_str);
I32 *nums=(I32*)SvPVX(sv_dat);
+ AV * const retarray = (flags & RXapif_ALL) ? newAV() : NULL;
for ( i=0; i<SvIVX(sv_dat); i++ ) {
if ((I32)(rx->nparens) >= nums[i]
&& rx->offs[nums[i]].start != -1
diff --git a/t/op/svleak.t b/t/op/svleak.t
index b0692ff..eeea7c1 100644
--- a/t/op/svleak.t
+++ b/t/op/svleak.t
@@ -15,7 +15,7 @@ BEGIN {
use Config;
-plan tests => 133;
+plan tests => 134;
# run some code N times. If the number of SVs at the end of loop N is
# greater than (N-1)*delta at the end of loop 1, we've got a leak
@@ -557,3 +557,13 @@ EOF
sub lk { { my $d = $op->hints_hash->HASH } }
::leak(3, 0, \&lk, q!B::RHE->HASH shoudln't leak!);
}
+
+{
+ # Perl_reg_named_buff_fetch() leaks an AV when called with an RE
+ # with no named captures
+ sub named {
+ "x" =~ /x/;
+ re::regname("foo", 1);
+ }
+ ::leak(2, 0, \&named, "Perl_reg_named_buff_fetch() on no-name RE");
+}
--
2.7.4

View File

@ -0,0 +1,61 @@
From cba9aa759f7ce8a4a80e748eb451f679042cd74b Mon Sep 17 00:00:00 2001
From: Father Chrysostomos <sprout@cpan.org>
Date: Fri, 7 Apr 2017 14:08:02 -0700
Subject: [PATCH] Crash with sub-in-stash
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Ported to 5.24.1:
commit 790acddeaa0d2c73524596048b129561225cf100
Author: Father Chrysostomos <sprout@cpan.org>
Date: Fri Apr 7 14:08:02 2017 -0700
[perl #131085] Crash with sub-in-stash
$ perl -e '$::{"A"} = sub {}; \&{"A"}'
Segmentation fault (core dumped)
The code that vivifies a typeglob out of a code ref assumed that the
CV had a name hek, which is always the case when perl itself puts the
code ref there (via sub A{}), but is not necessarily the case if
someone is insinuating other stuff into the stash.
Signed-off-by: Petr Písař <ppisar@redhat.com>
---
gv.c | 2 +-
t/op/gv.t | 4 ++++
2 files changed, 5 insertions(+), 1 deletion(-)
diff --git a/gv.c b/gv.c
index 3fda9b9..6690b64 100644
--- a/gv.c
+++ b/gv.c
@@ -421,7 +421,7 @@ Perl_gv_init_pvn(pTHX_ GV *gv, HV *stash, const char *name, STRLEN len, U32 flag
/* Not actually a constant. Just a regular sub. */
CV * const cv = (CV *)has_constant;
GvCV_set(gv,cv);
- if (CvSTASH(cv) == stash && (
+ if (CvNAMED(cv) && CvSTASH(cv) == stash && (
CvNAME_HEK(cv) == GvNAME_HEK(gv)
|| ( HEK_LEN(CvNAME_HEK(cv)) == HEK_LEN(GvNAME_HEK(gv))
&& HEK_FLAGS(CvNAME_HEK(cv)) != HEK_FLAGS(GvNAME_HEK(gv))
diff --git a/t/op/gv.t b/t/op/gv.t
index 03ae46e..cdaaef5 100644
--- a/t/op/gv.t
+++ b/t/op/gv.t
@@ -1170,6 +1170,10 @@ SKIP: {
is ($? & 127, 0,"[perl #128597] No crash when gp_free calls ckWARN_d");
}
+# [perl #131085] This used to crash; no ok() necessary.
+$::{"A131085"} = sub {}; \&{"A131085"};
+
+
__END__
Perl
Rules
--
2.9.4

View File

@ -1,11 +1,19 @@
From 0db967b2e6a4093a6a5f649190159767e5d005e0 Mon Sep 17 00:00:00 2001 From 30cba075ecbb662b392b2c6e896dec287ea49aa8 Mon Sep 17 00:00:00 2001
From: Yves Orton <demerphq@gmail.com> From: Yves Orton <demerphq@gmail.com>
Date: Tue, 25 Apr 2017 15:17:06 +0200 Date: Tue, 25 Apr 2017 15:17:06 +0200
Subject: [PATCH] [perl #131211] fixup File::Glob degenerate matching Subject: [PATCH] fixup File::Glob degenerate matching
MIME-Version: 1.0 MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8 Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit Content-Transfer-Encoding: 8bit
Ported to 5.24.1:
commit 0db967b2e6a4093a6a5f649190159767e5d005e0
Author: Yves Orton <demerphq@gmail.com>
Date: Tue Apr 25 15:17:06 2017 +0200
[perl #131211] fixup File::Glob degenerate matching
The old code would go quadratic with recursion and backtracking The old code would go quadratic with recursion and backtracking
when doing patterns like "a*a*a*a*a*a*a*x" on a file like when doing patterns like "a*a*a*a*a*a*a*x" on a file like
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa". "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa".
@ -27,17 +35,17 @@ Signed-off-by: Petr Písař <ppisar@redhat.com>
create mode 100644 ext/File-Glob/t/rt131211.t create mode 100644 ext/File-Glob/t/rt131211.t
diff --git a/MANIFEST b/MANIFEST diff --git a/MANIFEST b/MANIFEST
index b7b6e74..af0da6c 100644 index fe045a7..be2a44f 100644
--- a/MANIFEST --- a/MANIFEST
+++ b/MANIFEST +++ b/MANIFEST
@@ -3948,6 +3948,7 @@ ext/File-Glob/t/basic.t See if File::Glob works @@ -3678,6 +3678,7 @@ ext/File-Glob/t/case.t See if File::Glob works
ext/File-Glob/t/case.t See if File::Glob works
ext/File-Glob/t/global.t See if File::Glob works ext/File-Glob/t/global.t See if File::Glob works
ext/File-Glob/TODO File::Glob extension todo list
ext/File-Glob/t/rt114984.t See if File::Glob works ext/File-Glob/t/rt114984.t See if File::Glob works
+ext/File-Glob/t/rt131211.t See if File::Glob works +ext/File-Glob/t/rt131211.t See if File::Glob works
ext/File-Glob/t/taint.t See if File::Glob works ext/File-Glob/t/taint.t See if File::Glob works
ext/File-Glob/t/threads.t See if File::Glob + threads works ext/File-Glob/t/threads.t See if File::Glob + threads works
ext/File-Glob/TODO File::Glob extension todo list ext/GDBM_File/GDBM_File.pm GDBM extension Perl module
diff --git a/ext/File-Glob/bsd_glob.c b/ext/File-Glob/bsd_glob.c diff --git a/ext/File-Glob/bsd_glob.c b/ext/File-Glob/bsd_glob.c
index 821ef20..e96fb73 100644 index 821ef20..e96fb73 100644
--- a/ext/File-Glob/bsd_glob.c --- a/ext/File-Glob/bsd_glob.c

View File

@ -1,4 +1,4 @@
From 7b3e03bd309fcc48a135123a60678ae2596b1c38 Mon Sep 17 00:00:00 2001 From 064604f904546ae4ddada5a2aa30256faccee39c Mon Sep 17 00:00:00 2001
From: Tony Cook <tony@develop-help.com> From: Tony Cook <tony@develop-help.com>
Date: Wed, 7 Jun 2017 15:00:26 +1000 Date: Wed, 7 Jun 2017 15:00:26 +1000
Subject: [PATCH] clear the UTF8 flag on a glob if it isn't UTF8 Subject: [PATCH] clear the UTF8 flag on a glob if it isn't UTF8
@ -6,7 +6,7 @@ MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8 Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit Content-Transfer-Encoding: 8bit
Ported to 5.26.0: Ported to 5.24.1:
commit 1097da16b21fe0a2257dba9937e55c0cca18f7e1 commit 1097da16b21fe0a2257dba9937e55c0cca18f7e1
Author: Tony Cook <tony@develop-help.com> Author: Tony Cook <tony@develop-help.com>
@ -27,10 +27,10 @@ Signed-off-by: Petr Písař <ppisar@redhat.com>
2 files changed, 11 insertions(+), 1 deletion(-) 2 files changed, 11 insertions(+), 1 deletion(-)
diff --git a/sv.c b/sv.c diff --git a/sv.c b/sv.c
index 9f3e28e..ae3dc95 100644 index 12cbb5f..05584a2 100644
--- a/sv.c --- a/sv.c
+++ b/sv.c +++ b/sv.c
@@ -3179,6 +3179,8 @@ Perl_sv_2pv_flags(pTHX_ SV *const sv, STRLEN *const lp, const I32 flags) @@ -3162,6 +3162,8 @@ Perl_sv_2pv_flags(pTHX_ SV *const sv, STRLEN *const lp, const I32 flags)
assert(SvPOK(buffer)); assert(SvPOK(buffer));
if (SvUTF8(buffer)) if (SvUTF8(buffer))
SvUTF8_on(sv); SvUTF8_on(sv);
@ -40,21 +40,21 @@ index 9f3e28e..ae3dc95 100644
*lp = SvCUR(buffer); *lp = SvCUR(buffer);
return SvPVX(buffer); return SvPVX(buffer);
diff --git a/t/op/gv.t b/t/op/gv.t diff --git a/t/op/gv.t b/t/op/gv.t
index 4fe6b00..670ccf6 100644 index cdaaef5..ea79e51 100644
--- a/t/op/gv.t --- a/t/op/gv.t
+++ b/t/op/gv.t +++ b/t/op/gv.t
@@ -12,7 +12,7 @@ BEGIN { @@ -12,7 +12,7 @@ BEGIN {
use warnings; use warnings;
-plan(tests => 280); -plan(tests => 277 );
+plan(tests => 282); +plan(tests => 279 );
# type coercion on assignment # type coercion on assignment
$foo = 'foo'; $foo = 'foo';
@@ -1170,6 +1170,14 @@ SKIP: { @@ -1173,6 +1173,14 @@ SKIP: {
is ($? & 127, 0,"[perl #128597] No crash when gp_free calls ckWARN_d"); # [perl #131085] This used to crash; no ok() necessary.
} $::{"A131085"} = sub {}; \&{"A131085"};
+{ +{
+ # [perl #131263] + # [perl #131263]
@ -64,9 +64,9 @@ index 4fe6b00..670ccf6 100644
+ ok(*sym eq "*main::\xC3\x80", "utf8 flag properly cleared"); + ok(*sym eq "*main::\xC3\x80", "utf8 flag properly cleared");
+} +}
+ +
# test gv_try_downgrade()
# If a GV can be stored in a stash in a compact, non-GV form, then __END__
# whenever ops are freed which reference the GV, an attempt is made to Perl
-- --
2.9.4 2.9.4

View File

@ -0,0 +1,94 @@
From 0a1ddbeaeeea3c690c2408bd4c3a61c05cb9695f Mon Sep 17 00:00:00 2001
From: Zefram <zefram@fysh.org>
Date: Mon, 23 Jan 2017 02:25:50 +0000
Subject: [PATCH] permit goto at top level of multicalled sub
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Petr Písař: Ported to 5.24.1:
commit 3c157b3cf0631c69ffa5aa2d55b9199bf93b22a9
Author: Zefram <zefram@fysh.org>
Date: Mon Jan 23 02:25:50 2017 +0000
permit goto at top level of multicalled sub
A multicalled sub is reckoned to be a pseudo block, out of which it is
not permissible to goto. However, the test for a pseudo block was being
applied too early, preventing not just escape from a multicalled sub but
also a goto at the top level within the sub. This is a bug similar, but
not identical, to [perl #113938]. Now the test is deferred, permitting
goto at the sub's top level but still forbidding goto out of it.
Signed-off-by: Petr Písař <ppisar@redhat.com>
---
pp_ctl.c | 11 ++++++-----
t/op/goto.t | 11 ++++++++++-
2 files changed, 16 insertions(+), 6 deletions(-)
diff --git a/pp_ctl.c b/pp_ctl.c
index e859e01..a1fc2f4 100644
--- a/pp_ctl.c
+++ b/pp_ctl.c
@@ -2921,6 +2921,7 @@ PP(pp_goto)
OP *gotoprobe = NULL;
bool leaving_eval = FALSE;
bool in_block = FALSE;
+ bool pseudo_block = FALSE;
PERL_CONTEXT *last_eval_cx = NULL;
/* find label */
@@ -2959,11 +2960,9 @@ PP(pp_goto)
gotoprobe = PL_main_root;
break;
case CXt_SUB:
- if (CvDEPTH(cx->blk_sub.cv) && !CxMULTICALL(cx)) {
- gotoprobe = CvROOT(cx->blk_sub.cv);
- break;
- }
- /* FALLTHROUGH */
+ gotoprobe = CvROOT(cx->blk_sub.cv);
+ pseudo_block = cBOOL(CxMULTICALL(cx));
+ break;
case CXt_FORMAT:
case CXt_NULL:
DIE(aTHX_ "Can't \"goto\" out of a pseudo block");
@@ -2992,6 +2991,8 @@ PP(pp_goto)
break;
}
}
+ if (pseudo_block)
+ DIE(aTHX_ "Can't \"goto\" out of a pseudo block");
PL_lastgotoprobe = gotoprobe;
}
if (!retop)
diff --git a/t/op/goto.t b/t/op/goto.t
index aa2f24f..07bd6fb 100644
--- a/t/op/goto.t
+++ b/t/op/goto.t
@@ -10,7 +10,7 @@ BEGIN {
use warnings;
use strict;
-plan tests => 98;
+plan tests => 99;
our $TODO;
my $deprecated = 0;
@@ -774,3 +774,12 @@ sub FETCH { $_[0][0] }
tie my $t, "", sub { "cluck up porridge" };
is eval { sub { goto $t }->() }//$@, 'cluck up porridge',
'tied arg returning sub ref';
+
+sub revnumcmp ($$) {
+ goto FOO;
+ die;
+ FOO:
+ return $_[1] <=> $_[0];
+}
+is eval { join(":", sort revnumcmp (9,5,1,3,7)) }, "9:7:5:3:1",
+ "can goto at top level of multicalled sub";
--
2.7.4

View File

@ -0,0 +1,68 @@
From 08bc282a248b21c92ff45e49490fb95e24358213 Mon Sep 17 00:00:00 2001
From: David Mitchell <davem@iabyn.com>
Date: Tue, 9 May 2017 14:29:11 +0100
Subject: [PATCH] sprintf(): add memory wrap tests
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Ported to 5.24.1:
commit d729f63cc94318c248eab95844cfbed5298a7ecd
Author: David Mitchell <davem@iabyn.com>
Date: Tue May 9 14:29:11 2017 +0100
sprintf(): add memory wrap tests
In various places Perl_sv_vcatpvfn_flags() does croak_memory_wrap()
(including a couple added by the previous commit to fix RT #131260),
but there don't appear to be any tests for them.
So this commit adds some tests.
Signed-off-by: Petr Písař <ppisar@redhat.com>
---
t/op/sprintf2.t | 29 ++++++++++++++++++++++++++++-
1 file changed, 28 insertions(+), 1 deletion(-)
diff --git a/t/op/sprintf2.t b/t/op/sprintf2.t
index 43ed919..ef8a743 100644
--- a/t/op/sprintf2.t
+++ b/t/op/sprintf2.t
@@ -749,6 +749,33 @@ SKIP: {
"non-canonical form");
}
}
+
+# check all calls to croak_memory_wrap()
+# RT #131260
+
+{
+ my $s = 8 * $Config{sizesize};
+ my $i = 1;
+ my $max;
+ while ($s--) { $max |= $i; $i <<= 1; }
+ my $max40 = $max - 40; # see the magic fudge factor in sv_vcatpvfn_flags()
+
+ my @tests = (
+ # format, arg
+ ["%.${max}a", 1.1 ],
+ ["%.${max40}a", 1.1 ],
+ ["%.${max}i", 1 ],
+ ["%.${max}i", -1 ],
+ );
+
+ for my $test (@tests) {
+ my ($fmt, $arg) = @$test;
+ eval { my $s = sprintf $fmt, $arg; };
+ like("$@", qr/panic: memory wrap/, qq{memory wrap: "$fmt", "$arg"});
+ }
+}
+
+
# These are IEEE 754 64-bit subnormals (formerly known as denormals).
# Keep these as strings so that non-IEEE-754 don't trip over them.
--
2.9.4

View File

@ -1,4 +1,4 @@
From b3937e202aaf10c2f8996e2993c880bb38a7a268 Mon Sep 17 00:00:00 2001 From ab3bb20383d6dbf9baa811d06414ee474bb8f91e Mon Sep 17 00:00:00 2001
From: Father Chrysostomos <sprout@cpan.org> From: Father Chrysostomos <sprout@cpan.org>
Date: Wed, 1 Nov 2017 13:11:27 -0700 Date: Wed, 1 Nov 2017 13:11:27 -0700
Subject: [PATCH] =?UTF-8?q?Carp:=20Don=E2=80=99t=20choke=20on=20ISA=20cons?= Subject: [PATCH] =?UTF-8?q?Carp:=20Don=E2=80=99t=20choke=20on=20ISA=20cons?=
@ -17,6 +17,8 @@ and still persisted in bleadperl (Carp 1.43) until this commit.
The code that goes poking through the symbol table needs to take into The code that goes poking through the symbol table needs to take into
account that not all stash elements are globs. account that not all stash elements are globs.
Petr Písař: Ported to 5.24.3.
Signed-off-by: Petr Písař <ppisar@redhat.com> Signed-off-by: Petr Písař <ppisar@redhat.com>
--- ---
dist/Carp/lib/Carp.pm | 3 ++- dist/Carp/lib/Carp.pm | 3 ++-
@ -24,10 +26,10 @@ Signed-off-by: Petr Písař <ppisar@redhat.com>
2 files changed, 14 insertions(+), 2 deletions(-) 2 files changed, 14 insertions(+), 2 deletions(-)
diff --git a/dist/Carp/lib/Carp.pm b/dist/Carp/lib/Carp.pm diff --git a/dist/Carp/lib/Carp.pm b/dist/Carp/lib/Carp.pm
index 6127b26f54..ef11a0c046 100644 index 92f8866..f94b9d4 100644
--- a/dist/Carp/lib/Carp.pm --- a/dist/Carp/lib/Carp.pm
+++ b/dist/Carp/lib/Carp.pm +++ b/dist/Carp/lib/Carp.pm
@@ -593,7 +593,8 @@ sub trusts_directly { @@ -594,7 +594,8 @@ sub trusts_directly {
for my $var (qw/ CARP_NOT ISA /) { for my $var (qw/ CARP_NOT ISA /) {
# Don't try using the variable until we know it exists, # Don't try using the variable until we know it exists,
# to avoid polluting the caller's namespace. # to avoid polluting the caller's namespace.
@ -38,19 +40,19 @@ index 6127b26f54..ef11a0c046 100644
} }
} }
diff --git a/dist/Carp/t/Carp.t b/dist/Carp/t/Carp.t diff --git a/dist/Carp/t/Carp.t b/dist/Carp/t/Carp.t
index 65daed7c6c..b1e399d143 100644 index 9ecdf88..f981005 100644
--- a/dist/Carp/t/Carp.t --- a/dist/Carp/t/Carp.t
+++ b/dist/Carp/t/Carp.t +++ b/dist/Carp/t/Carp.t
@@ -3,7 +3,7 @@ no warnings "once"; @@ -3,7 +3,7 @@ no warnings "once";
use Config; use Config;
use IPC::Open3 1.0103 qw(open3); use IPC::Open3 1.0103 qw(open3);
-use Test::More tests => 67; -use Test::More tests => 66;
+use Test::More tests => 68; +use Test::More tests => 67;
sub runperl { sub runperl {
my(%args) = @_; my(%args) = @_;
@@ -488,6 +488,17 @@ SKIP: @@ -478,6 +478,17 @@ SKIP:
); );
} }

View File

@ -1,4 +1,4 @@
From abd17348111a99642da217c45d836f2df5713594 Mon Sep 17 00:00:00 2001 From 2657358b67ba3eadd1be99bd7e732a8d68f1f95d Mon Sep 17 00:00:00 2001
From: John Lightsey <lightsey@debian.org> From: John Lightsey <lightsey@debian.org>
Date: Tue, 31 Oct 2017 18:12:26 -0500 Date: Tue, 31 Oct 2017 18:12:26 -0500
Subject: [PATCH] Fix deparsing of transliterations with unprintable Subject: [PATCH] Fix deparsing of transliterations with unprintable
@ -10,7 +10,7 @@ Content-Transfer-Encoding: 8bit
RT #132405 RT #132405
Signed-off-by: Nicolas R <atoomic@cpan.org> Signed-off-by: Nicolas R <atoomic@cpan.org>
Petr Písař: Port to 5.26.1. Petr Písař: Port to 5.24.3.
Signed-off-by: Petr Písař <ppisar@redhat.com> Signed-off-by: Petr Písař <ppisar@redhat.com>
--- ---
lib/B/Deparse.pm | 2 +- lib/B/Deparse.pm | 2 +-
@ -18,10 +18,10 @@ Signed-off-by: Petr Písař <ppisar@redhat.com>
2 files changed, 6 insertions(+), 1 deletion(-) 2 files changed, 6 insertions(+), 1 deletion(-)
diff --git a/lib/B/Deparse.pm b/lib/B/Deparse.pm diff --git a/lib/B/Deparse.pm b/lib/B/Deparse.pm
index 3166415..cc74552 100644 index 9879d67..f5f7d82 100644
--- a/lib/B/Deparse.pm --- a/lib/B/Deparse.pm
+++ b/lib/B/Deparse.pm +++ b/lib/B/Deparse.pm
@@ -5200,7 +5200,7 @@ sub pchr { # ASCII @@ -5047,7 +5047,7 @@ sub pchr { # ASCII
} elsif ($n == ord "\r") { } elsif ($n == ord "\r") {
return '\\r'; return '\\r';
} elsif ($n >= ord("\cA") and $n <= ord("\cZ")) { } elsif ($n >= ord("\cA") and $n <= ord("\cZ")) {
@ -31,13 +31,13 @@ index 3166415..cc74552 100644
# return '\x' . sprintf("%02x", $n); # return '\x' . sprintf("%02x", $n);
return '\\' . sprintf("%03o", $n); return '\\' . sprintf("%03o", $n);
diff --git a/lib/B/Deparse.t b/lib/B/Deparse.t diff --git a/lib/B/Deparse.t b/lib/B/Deparse.t
index 7eeb4f8..eae9c49 100644 index 19db404..45b1ff3 100644
--- a/lib/B/Deparse.t --- a/lib/B/Deparse.t
+++ b/lib/B/Deparse.t +++ b/lib/B/Deparse.t
@@ -2610,3 +2610,8 @@ sub ($a, $=) { @@ -2488,3 +2488,8 @@ $_ ^= $_;
$a; $_ |.= $_;
} $_ &.= $_;
; $_ ^.= $_;
+#### +####
+# tr with unprintable characters +# tr with unprintable characters
+my $str; +my $str;

View File

@ -0,0 +1,69 @@
From 86ecc4da0ec0cea8f9b6af4191b87e4c454aa17c Mon Sep 17 00:00:00 2001
From: Yves Orton <demerphq@gmail.com>
Date: Sun, 10 Sep 2017 10:59:05 +0200
Subject: [PATCH] fix #132017 - OPFAIL insert needs to set flags to 0
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
why reginsert doesnt do this stuff I dont know.
Petr Písař: Ported to 5.24.3.
Signed-off-by: Petr Písař <ppisar@redhat.com>
---
regcomp.c | 6 +++++-
t/re/pat.t | 5 ++++-
2 files changed, 9 insertions(+), 2 deletions(-)
diff --git a/regcomp.c b/regcomp.c
index 6dcc58a..374032c 100644
--- a/regcomp.c
+++ b/regcomp.c
@@ -11498,6 +11498,7 @@ S_regpiece(pTHX_ RExC_state_t *pRExC_state, I32 *flagp, U32 depth)
if (max < min) { /* If can't match, warn and optimize to fail
unconditionally */
reginsert(pRExC_state, OPFAIL, orig_emit, depth+1);
+ orig_emit->flags = 0;
if (PASS2) {
ckWARNreg(RExC_parse, "Quantifier {n,m} with n > m can't match");
NEXT_OFF(orig_emit)= regarglen[OPFAIL] + NODE_STEP_REGNODE;
@@ -19046,8 +19047,11 @@ Perl_regprop(pTHX_ const regexp *prog, SV *sv, const regnode *o, const regmatch_
/* add on the verb argument if there is one */
if ( ( k == VERB || OP(o) == ACCEPT || OP(o) == OPFAIL ) && o->flags) {
- Perl_sv_catpvf(aTHX_ sv, ":%"SVf,
+ if ( ARG(o) )
+ Perl_sv_catpvf(aTHX_ sv, ":%" SVf,
SVfARG((MUTABLE_SV(progi->data->data[ ARG( o ) ]))));
+ else
+ sv_catpvs(sv, ":NULL");
}
#else
PERL_UNUSED_CONTEXT;
diff --git a/t/re/pat.t b/t/re/pat.t
index 007f11d..6ff8b0b 100644
--- a/t/re/pat.t
+++ b/t/re/pat.t
@@ -23,7 +23,7 @@ BEGIN {
skip_all_without_unicode_tables();
}
-plan tests => 794; # Update this when adding/deleting tests.
+plan tests => 795; # Update this when adding/deleting tests.
run_tests() unless caller;
@@ -1793,6 +1793,9 @@ EOP
pos($text) = 3;
ok(scalar($text !~ m{(~*=[a-z]=)}g), "RT #131575");
}
+ {
+ fresh_perl_is('"AA" =~ m/AA{1,0}/','',{},"handle OPFAIL insert properly");
+ }
} # End of sub run_tests
--
2.13.6

File diff suppressed because it is too large Load Diff

View File

@ -1,4 +1,4 @@
From 3f8a98327dfdb171bd6e447fec23721b0e74c7a6 Mon Sep 17 00:00:00 2001 From a56b6643ac9d2bae70dc93d49a08ba1eafa62c30 Mon Sep 17 00:00:00 2001
From: Zefram <zefram@fysh.org> From: Zefram <zefram@fysh.org>
Date: Sun, 19 Nov 2017 09:15:53 +0000 Date: Sun, 19 Nov 2017 09:15:53 +0000
Subject: [PATCH] fix tainting of s/// with overloaded replacement Subject: [PATCH] fix tainting of s/// with overloaded replacement
@ -18,20 +18,20 @@ there's no visible behaviour that distinguishes taint specifically from
the replacement. Also remove a related taint check that seems to be the replacement. Also remove a related taint check that seems to be
not needed at all. Fixes [perl #115266]. not needed at all. Fixes [perl #115266].
Petr Písař: Ported to 5.26.1. Petr Písař: Ported to 5.24.3.
Signed-off-by: Petr Písař <ppisar@redhat.com> Signed-off-by: Petr Písař <ppisar@redhat.com>
--- ---
pp_ctl.c | 4 +- pp_ctl.c | 4 +-
pp_hot.c | 4 +- pp_hot.c | 4 +-
t/op/taint.t | 428 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++-- t/op/taint.t | 429 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++--
3 files changed, 422 insertions(+), 14 deletions(-) 3 files changed, 423 insertions(+), 14 deletions(-)
diff --git a/pp_ctl.c b/pp_ctl.c diff --git a/pp_ctl.c b/pp_ctl.c
index f136f91..15c193b 100644 index 9150142..97a4607 100644
--- a/pp_ctl.c --- a/pp_ctl.c
+++ b/pp_ctl.c +++ b/pp_ctl.c
@@ -219,9 +219,9 @@ PP(pp_substcont) @@ -218,9 +218,9 @@ PP(pp_substcont)
SvGETMAGIC(TOPs); /* possibly clear taint on $1 etc: #67962 */ SvGETMAGIC(TOPs); /* possibly clear taint on $1 etc: #67962 */
/* See "how taint works" above pp_subst() */ /* See "how taint works" above pp_subst() */
@ -44,10 +44,10 @@ index f136f91..15c193b 100644
!CALLREGEXEC(rx, s, cx->sb_strend, orig, !CALLREGEXEC(rx, s, cx->sb_strend, orig,
(s == m), cx->sb_targ, NULL, (s == m), cx->sb_targ, NULL,
diff --git a/pp_hot.c b/pp_hot.c diff --git a/pp_hot.c b/pp_hot.c
index f445fd9..5899413 100644 index 243f43a..e80d991 100644
--- a/pp_hot.c --- a/pp_hot.c
+++ b/pp_hot.c +++ b/pp_hot.c
@@ -3250,7 +3250,7 @@ PP(pp_subst) @@ -3004,7 +3004,7 @@ PP(pp_subst)
doutf8 = DO_UTF8(dstr); doutf8 = DO_UTF8(dstr);
} }
@ -56,25 +56,25 @@ index f445fd9..5899413 100644
rxtainted |= SUBST_TAINT_REPL; rxtainted |= SUBST_TAINT_REPL;
} }
else { else {
@@ -3421,8 +3421,6 @@ PP(pp_subst) @@ -3181,8 +3181,6 @@ PP(pp_subst)
sv_catsv(dstr, nsv);
} }
else { else sv_catsv(dstr, repl);
sv_catsv(dstr, repl);
- if (UNLIKELY(SvTAINTED(repl))) - if (UNLIKELY(SvTAINTED(repl)))
- rxtainted |= SUBST_TAINT_REPL; - rxtainted |= SUBST_TAINT_REPL;
} }
if (once) if (once)
break; break;
diff --git a/t/op/taint.t b/t/op/taint.t diff --git a/t/op/taint.t b/t/op/taint.t
index c13eaf6..be5eaa8 100644 index 846ac23..dbcc418 100644
--- a/t/op/taint.t --- a/t/op/taint.t
+++ b/t/op/taint.t +++ b/t/op/taint.t
@@ -17,7 +17,7 @@ BEGIN { @@ -17,7 +17,7 @@ BEGIN {
use strict; use strict;
use Config; use Config;
-plan tests => 828; -plan tests => 812;
+plan tests => 1040; +plan tests => 1024;
$| = 1; $| = 1;
@ -303,10 +303,10 @@ index c13eaf6..be5eaa8 100644
# [perl #121854] match taintedness became sticky # [perl #121854] match taintedness became sticky
# when one match has a taintess result, subseqent matches # when one match has a taintess result, subseqent matches
# using the same pattern shouldn't necessarily be tainted # using the same pattern shouldn't necessarily be tainted
@@ -2448,6 +2580,284 @@ is eval { eval $::x.1 }, 1, 'reset does not taint undef'; @@ -2408,6 +2540,285 @@ is eval { eval $::x.1 }, 1, 'reset does not taint undef';
isnt_tainted $b, "list assign post tainted expression b";
} }
+# taint passing through overloading +# taint passing through overloading
+package OvTaint { +package OvTaint {
+ sub new { bless({ t => $_[1] }, $_[0]) } + sub new { bless({ t => $_[1] }, $_[0]) }
@ -585,9 +585,10 @@ index c13eaf6..be5eaa8 100644
+ is($res, 4, "$desc: res value"); + is($res, 4, "$desc: res value");
+ is($one, 'd', "$desc: \$1 value"); + is($one, 'd', "$desc: \$1 value");
+} +}
+
# This may bomb out with the alarm signal so keep it last # This may bomb out with the alarm signal so keep it last
SKIP: { SKIP: {
skip "No alarm()" unless $Config{d_alarm};
-- --
2.13.6 2.13.6

View File

@ -0,0 +1,64 @@
From b890486ff0c482cbdec59a0f9beb28275aeee19b Mon Sep 17 00:00:00 2001
From: Tony Cook <tony@develop-help.com>
Date: Mon, 19 Jun 2017 14:59:53 +1000
Subject: [PATCH] (perl #131597) ensure the GV slot is filled for our [%$@]foo:
attr
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Petr Písař: Ported to 5.24.3.
Signed-off-by: Petr Písař <ppisar@redhat.com>
---
op.c | 6 +++---
t/op/attrs.t | 18 ++++++++++++++++++
2 files changed, 21 insertions(+), 3 deletions(-)
diff --git a/op.c b/op.c
index 2960dd5..8a5fc3f 100644
--- a/op.c
+++ b/op.c
@@ -3671,9 +3671,9 @@ S_my_kid(pTHX_ OP *o, OP *attrs, OP **imopsp)
PL_parser->in_my = FALSE;
PL_parser->in_my_stash = NULL;
apply_attrs(GvSTASH(gv),
- (type == OP_RV2SV ? GvSV(gv) :
- type == OP_RV2AV ? MUTABLE_SV(GvAV(gv)) :
- type == OP_RV2HV ? MUTABLE_SV(GvHV(gv)) : MUTABLE_SV(gv)),
+ (type == OP_RV2SV ? GvSVn(gv) :
+ type == OP_RV2AV ? MUTABLE_SV(GvAVn(gv)) :
+ type == OP_RV2HV ? MUTABLE_SV(GvHVn(gv)) : MUTABLE_SV(gv)),
attrs);
}
o->op_private |= OPpOUR_INTRO;
diff --git a/t/op/attrs.t b/t/op/attrs.t
index 219db03..b038c87 100644
--- a/t/op/attrs.t
+++ b/t/op/attrs.t
@@ -447,4 +447,22 @@ package P126257 {
::is $@, "", "RT 126257 sub";
}
+fresh_perl_is('sub dummy {} our $dummy : Dummy', <<EOS, {},
+Invalid SCALAR attribute: Dummy at - line 1.
+BEGIN failed--compilation aborted at - line 1.
+EOS
+ "attribute on our scalar with sub of same name");
+
+fresh_perl_is('sub dummy {} our @dummy : Dummy', <<EOS, {},
+Invalid ARRAY attribute: Dummy at - line 1.
+BEGIN failed--compilation aborted at - line 1.
+EOS
+ "attribute on our array with sub of same name");
+
+fresh_perl_is('sub dummy {} our %dummy : Dummy', <<EOS, {},
+Invalid HASH attribute: Dummy at - line 1.
+BEGIN failed--compilation aborted at - line 1.
+EOS
+ "attribute on our hash with sub of same name");
+
done_testing();
--
2.13.6

View File

@ -1,4 +1,4 @@
From 4ac7295514f35016a79dbcc07500f6c9ca4729b7 Mon Sep 17 00:00:00 2001 From 9a4826e0881f8c5498a0fd5f24ed2a0fefb771b7 Mon Sep 17 00:00:00 2001
From: Tony Cook <tony@develop-help.com> From: Tony Cook <tony@develop-help.com>
Date: Thu, 2 Nov 2017 20:18:56 +0000 Date: Thu, 2 Nov 2017 20:18:56 +0000
Subject: [PATCH] (perl #131895) fail stat on names with \0 embedded Subject: [PATCH] (perl #131895) fail stat on names with \0 embedded
@ -8,7 +8,7 @@ Content-Transfer-Encoding: 8bit
Also lstat() and the file test ops. Also lstat() and the file test ops.
Petr Písař: Port to 5.26.1. Petr Písař: Port to 5.24.3.
Signed-off-by: Petr Písař <ppisar@redhat.com> Signed-off-by: Petr Písař <ppisar@redhat.com>
--- ---
@ -20,10 +20,10 @@ Signed-off-by: Petr Písař <ppisar@redhat.com>
5 files changed, 73 insertions(+), 13 deletions(-) 5 files changed, 73 insertions(+), 13 deletions(-)
diff --git a/doio.c b/doio.c diff --git a/doio.c b/doio.c
index becb19b..70d7747 100644 index 6704862..2792c66 100644
--- a/doio.c --- a/doio.c
+++ b/doio.c +++ b/doio.c
@@ -1466,7 +1466,7 @@ Perl_my_stat_flags(pTHX_ const U32 flags) @@ -1458,7 +1458,7 @@ Perl_my_stat_flags(pTHX_ const U32 flags)
return PL_laststatval; return PL_laststatval;
else { else {
SV* const sv = TOPs; SV* const sv = TOPs;
@ -32,7 +32,7 @@ index becb19b..70d7747 100644
STRLEN len; STRLEN len;
if ((gv = MAYBE_DEREF_GV_flags(sv,flags))) { if ((gv = MAYBE_DEREF_GV_flags(sv,flags))) {
goto do_fstat; goto do_fstat;
@@ -1480,9 +1480,14 @@ Perl_my_stat_flags(pTHX_ const U32 flags) @@ -1472,9 +1472,14 @@ Perl_my_stat_flags(pTHX_ const U32 flags)
s = SvPV_flags_const(sv, len, flags); s = SvPV_flags_const(sv, len, flags);
PL_statgv = NULL; PL_statgv = NULL;
sv_setpvn(PL_statname, s, len); sv_setpvn(PL_statname, s, len);
@ -49,7 +49,7 @@ index becb19b..70d7747 100644
if (PL_laststatval < 0 && ckWARN(WARN_NEWLINE) && should_warn_nl(s)) { if (PL_laststatval < 0 && ckWARN(WARN_NEWLINE) && should_warn_nl(s)) {
GCC_DIAG_IGNORE(-Wformat-nonliteral); /* PL_warn_nl is constant */ GCC_DIAG_IGNORE(-Wformat-nonliteral); /* PL_warn_nl is constant */
Perl_warner(aTHX_ packWARN(WARN_NEWLINE), PL_warn_nl, "stat"); Perl_warner(aTHX_ packWARN(WARN_NEWLINE), PL_warn_nl, "stat");
@@ -1499,6 +1504,7 @@ Perl_my_lstat_flags(pTHX_ const U32 flags) @@ -1491,6 +1496,7 @@ Perl_my_lstat_flags(pTHX_ const U32 flags)
static const char* const no_prev_lstat = "The stat preceding -l _ wasn't an lstat"; static const char* const no_prev_lstat = "The stat preceding -l _ wasn't an lstat";
dSP; dSP;
const char *file; const char *file;
@ -57,7 +57,7 @@ index becb19b..70d7747 100644
SV* const sv = TOPs; SV* const sv = TOPs;
bool isio = FALSE; bool isio = FALSE;
if (PL_op->op_flags & OPf_REF) { if (PL_op->op_flags & OPf_REF) {
@@ -1542,9 +1548,14 @@ Perl_my_lstat_flags(pTHX_ const U32 flags) @@ -1534,9 +1540,14 @@ Perl_my_lstat_flags(pTHX_ const U32 flags)
HEKfARG(GvENAME_HEK((const GV *) HEKfARG(GvENAME_HEK((const GV *)
(SvROK(sv) ? SvRV(sv) : sv)))); (SvROK(sv) ? SvRV(sv) : sv))));
} }
@ -75,10 +75,10 @@ index becb19b..70d7747 100644
GCC_DIAG_IGNORE(-Wformat-nonliteral); /* PL_warn_nl is constant */ GCC_DIAG_IGNORE(-Wformat-nonliteral); /* PL_warn_nl is constant */
Perl_warner(aTHX_ packWARN(WARN_NEWLINE), PL_warn_nl, "lstat"); Perl_warner(aTHX_ packWARN(WARN_NEWLINE), PL_warn_nl, "lstat");
diff --git a/pp_sys.c b/pp_sys.c diff --git a/pp_sys.c b/pp_sys.c
index 0b60584..1b81fda 100644 index bd55043..1a72e60 100644
--- a/pp_sys.c --- a/pp_sys.c
+++ b/pp_sys.c +++ b/pp_sys.c
@@ -2963,19 +2963,24 @@ PP(pp_stat) @@ -2927,19 +2927,24 @@ PP(pp_stat)
} }
else { else {
const char *file; const char *file;
@ -106,7 +106,7 @@ index 0b60584..1b81fda 100644
PL_laststatval = PerlLIO_lstat(file, &PL_statcache); PL_laststatval = PerlLIO_lstat(file, &PL_statcache);
else else
PL_laststatval = PerlLIO_stat(file, &PL_statcache); PL_laststatval = PerlLIO_stat(file, &PL_statcache);
@@ -3211,8 +3216,12 @@ PP(pp_ftrread) @@ -3175,8 +3180,12 @@ PP(pp_ftrread)
if (use_access) { if (use_access) {
#if defined(HAS_ACCESS) || defined (PERL_EFF_ACCESS) #if defined(HAS_ACCESS) || defined (PERL_EFF_ACCESS)
@ -121,7 +121,7 @@ index 0b60584..1b81fda 100644
# ifdef PERL_EFF_ACCESS # ifdef PERL_EFF_ACCESS
result = PERL_EFF_ACCESS(name, access_mode); result = PERL_EFF_ACCESS(name, access_mode);
# else # else
@@ -3537,10 +3546,18 @@ PP(pp_fttext) @@ -3501,10 +3510,18 @@ PP(pp_fttext)
} }
else { else {
const char *file; const char *file;
@ -142,13 +142,13 @@ index 0b60584..1b81fda 100644
file = SvPVX_const(PL_statname); file = SvPVX_const(PL_statname);
PL_statgv = NULL; PL_statgv = NULL;
diff --git a/t/lib/warnings/pp_sys b/t/lib/warnings/pp_sys diff --git a/t/lib/warnings/pp_sys b/t/lib/warnings/pp_sys
index 9c544e0..c599aa3 100644 index 6338964..ded5d7d 100644
--- a/t/lib/warnings/pp_sys --- a/t/lib/warnings/pp_sys
+++ b/t/lib/warnings/pp_sys +++ b/t/lib/warnings/pp_sys
@@ -972,3 +972,17 @@ close $fh; @@ -962,3 +962,17 @@ close $fh;
unlink $file; unlink $file;
EXPECT EXPECT
syswrite() is deprecated on :utf8 handles. This will be a fatal error in Perl 5.30 at - line 5. syswrite() is deprecated on :utf8 handles at - line 6.
+######## +########
+# NAME stat on name with \0 +# NAME stat on name with \0
+use warnings; +use warnings;
@ -189,7 +189,7 @@ index 8883381..bd1d08c 100644
+ ok(!-r "TEST\0-", '-r on name with \0'); + ok(!-r "TEST\0-", '-r on name with \0');
+} +}
diff --git a/t/op/stat.t b/t/op/stat.t diff --git a/t/op/stat.t b/t/op/stat.t
index 323c498..dbbe6ec 100644 index 637a902..71193ad 100644
--- a/t/op/stat.t --- a/t/op/stat.t
+++ b/t/op/stat.t +++ b/t/op/stat.t
@@ -25,7 +25,7 @@ if ($^O eq 'MSWin32') { @@ -25,7 +25,7 @@ if ($^O eq 'MSWin32') {
@ -201,7 +201,7 @@ index 323c498..dbbe6ec 100644
my $Perl = which_perl(); my $Perl = which_perl();
@@ -653,6 +653,16 @@ SKIP: @@ -651,6 +651,16 @@ SKIP:
'stat on an array of valid paths should return ENOENT'; 'stat on an array of valid paths should return ENOENT';
} }

View File

@ -1,4 +1,4 @@
From dc5c68130b7c8b727e9e792506183c255fc2bc70 Mon Sep 17 00:00:00 2001 From 86a48d83a7caf38c553000a250ed1359c235f55e Mon Sep 17 00:00:00 2001
From: Tony Cook <tony@develop-help.com> From: Tony Cook <tony@develop-help.com>
Date: Thu, 19 Oct 2017 10:46:04 +1100 Date: Thu, 19 Oct 2017 10:46:04 +1100
Subject: [PATCH] (perl #132245) don't try to process a char range with no Subject: [PATCH] (perl #132245) don't try to process a char range with no
@ -11,40 +11,38 @@ A range like \N{}-0 eventually results in compilation failing, but
before that, get_and_check_backslash_N_name() attempts to treat before that, get_and_check_backslash_N_name() attempts to treat
the memory before the empty output of \N{} as a character. the memory before the empty output of \N{} as a character.
Petr Písař: Ported to 5.26.1. Petr Písař: Ported to 5.24.3.
Signed-off-by: Petr Písař <ppisar@redhat.com> Signed-off-by: Petr Písař <ppisar@redhat.com>
--- ---
t/lib/warnings/toke | 5 +++++ t/lib/warnings/toke | 5 +++++
toke.c | 6 +++--- toke.c | 4 ++--
2 files changed, 8 insertions(+), 3 deletions(-) 2 files changed, 7 insertions(+), 2 deletions(-)
diff --git a/t/lib/warnings/toke b/t/lib/warnings/toke diff --git a/t/lib/warnings/toke b/t/lib/warnings/toke
index fc51d9f..398ee22 100644 index 493c8a2..4a521e0 100644
--- a/t/lib/warnings/toke --- a/t/lib/warnings/toke
+++ b/t/lib/warnings/toke +++ b/t/lib/warnings/toke
@@ -1651,3 +1651,8 @@ Execution of - aborted due to compilation errors. @@ -1509,3 +1509,8 @@ my $v = 𝛃 - 5;
use utf8;
qw∘foo ∞ ♥ bar∘
EXPECT EXPECT
OPTION regex
(Wide character.*\n)?Warning: Use of "𝛃" without parentheses is ambiguous
+######## +########
+# NAME tr/// range with empty \N{} at the start +# NAME tr/// range with empty \N{} at the start
+tr//\N{}-0/; +tr//\N{}-0/;
+EXPECT +EXPECT
+Unknown charname '' is deprecated. Its use will be fatal in Perl 5.28 at - line 1. +Unknown charname '' is deprecated at - line 1.
diff --git a/toke.c b/toke.c diff --git a/toke.c b/toke.c
index 6f84d2d..6ee7a68 100644 index f2310cc..3d93fac 100644
--- a/toke.c --- a/toke.c
+++ b/toke.c +++ b/toke.c
@@ -2958,9 +2958,9 @@ S_scan_const(pTHX_ char *start) @@ -2906,8 +2906,8 @@ S_scan_const(pTHX_ char *start)
* at least one character, then see if this next one is a '-',
/* Here, we don't think we're in a range. If the new character * indicating the previous one was the start of a range. But
* is not a hyphen; or if it is a hyphen, but it's too close to * don't bother if we're too close to the end for the minus to
- * either edge to indicate a range, then it's a regular - * mean that. */
- * character. */
- if (*s != '-' || s >= send - 1 || s == start) { - if (*s != '-' || s >= send - 1 || s == start) {
+ * either edge to indicate a range, or if we haven't output any + * mean that, or if we haven't output any characters yet. */
+ * characters yet then it's a regular character. */
+ if (*s != '-' || s >= send - 1 || s == start || d == SvPVX(sv)) { + if (*s != '-' || s >= send - 1 || s == start || d == SvPVX(sv)) {
/* A regular character. Process like any other, but first /* A regular character. Process like any other, but first

View File

@ -1,7 +1,7 @@
From 695d6585affc8f13711f013329fb4810ab89d833 Mon Sep 17 00:00:00 2001 From 264472b6e83dd1a9d0e0e58d75f7162471a5b29b Mon Sep 17 00:00:00 2001
From: Father Chrysostomos <sprout@cpan.org> From: Father Chrysostomos <sprout@cpan.org>
Date: Tue, 14 Nov 2017 18:55:55 -0800 Date: Tue, 14 Nov 2017 18:55:55 -0800
Subject: [PATCH] [perl #132442] Fix stack with do {my sub l; 1} Subject: [PATCH] Fix stack with do {my sub l; 1}
MIME-Version: 1.0 MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8 Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit Content-Transfer-Encoding: 8bit
@ -61,6 +61,8 @@ setting the HINT_BLOCK_SCOPE flag when a lexical sub is declared.
Thus, we end up with an enter/leave pair, which creates a Thus, we end up with an enter/leave pair, which creates a
proper scope. proper scope.
Petr Písař: Ported to 5.24.3.
Signed-off-by: Petr Písař <ppisar@redhat.com> Signed-off-by: Petr Písař <ppisar@redhat.com>
--- ---
op.c | 2 ++ op.c | 2 ++
@ -68,10 +70,10 @@ Signed-off-by: Petr Písař <ppisar@redhat.com>
2 files changed, 6 insertions(+), 1 deletion(-) 2 files changed, 6 insertions(+), 1 deletion(-)
diff --git a/op.c b/op.c diff --git a/op.c b/op.c
index 8fa5aad876..c617ad2a00 100644 index 8a5fc3f..695bfa4 100644
--- a/op.c --- a/op.c
+++ b/op.c +++ b/op.c
@@ -9243,6 +9243,8 @@ Perl_newMYSUB(pTHX_ I32 floor, OP *o, OP *proto, OP *attrs, OP *block) @@ -7936,6 +7936,8 @@ Perl_newMYSUB(pTHX_ I32 floor, OP *o, OP *proto, OP *attrs, OP *block)
PERL_ARGS_ASSERT_NEWMYSUB; PERL_ARGS_ASSERT_NEWMYSUB;
@ -81,19 +83,19 @@ index 8fa5aad876..c617ad2a00 100644
We cannot use PL_comppad, as it is the pad owned by the new sub. We We cannot use PL_comppad, as it is the pad owned by the new sub. We
need to look in CvOUTSIDE and find the pad belonging to the enclos- need to look in CvOUTSIDE and find the pad belonging to the enclos-
diff --git a/t/op/lexsub.t b/t/op/lexsub.t diff --git a/t/op/lexsub.t b/t/op/lexsub.t
index 3fa17acdda..f085cd97e8 100644 index adccf4c..cf90a76 100644
--- a/t/op/lexsub.t --- a/t/op/lexsub.t
+++ b/t/op/lexsub.t +++ b/t/op/lexsub.t
@@ -7,7 +7,7 @@ BEGIN { @@ -7,7 +7,7 @@ BEGIN {
*bar::is = *is; *bar::is = *is;
*bar::like = *like; *bar::like = *like;
} }
-plan 149; -plan 151;
+plan 150; +plan 152;
# -------------------- our -------------------- # # -------------------- Errors with feature disabled -------------------- #
@@ -957,3 +957,6 @@ like runperl( @@ -967,3 +967,6 @@ like runperl(
{ {
my sub h; sub{my $x; sub{h}} my sub h; sub{my $x; sub{h}}
} }

View File

@ -1,4 +1,4 @@
From 8c7182b26a43f14cd8afbfbe4448cbbd691c3609 Mon Sep 17 00:00:00 2001 From 0a41ca5a68626a0f44e0d552e460e86567e47140 Mon Sep 17 00:00:00 2001
From: Zefram <zefram@fysh.org> From: Zefram <zefram@fysh.org>
Date: Wed, 15 Nov 2017 08:11:37 +0000 Date: Wed, 15 Nov 2017 08:11:37 +0000
Subject: [PATCH] set $! when statting a closed filehandle Subject: [PATCH] set $! when statting a closed filehandle
@ -11,7 +11,7 @@ filehandle, $! was often not being set, depending on the operation
and the nature of the invalidity. Consistently set it to EBADF. and the nature of the invalidity. Consistently set it to EBADF.
Fixes [perl #108288]. Fixes [perl #108288].
Petr Písař: Ported to 5.26.1. Petr Písař: Ported to 5.24.3.
Signed-off-by: Petr Písař <ppisar@redhat.com> Signed-off-by: Petr Písař <ppisar@redhat.com>
--- ---
@ -23,22 +23,22 @@ Signed-off-by: Petr Písař <ppisar@redhat.com>
create mode 100644 t/op/stat_errors.t create mode 100644 t/op/stat_errors.t
diff --git a/MANIFEST b/MANIFEST diff --git a/MANIFEST b/MANIFEST
index fcbf5cc..996759e 100644 index fcf7eae..3077142 100644
--- a/MANIFEST --- a/MANIFEST
+++ b/MANIFEST +++ b/MANIFEST
@@ -5670,6 +5670,7 @@ t/op/srand.t See if srand works @@ -5394,6 +5394,7 @@ t/op/sselect.t See if 4 argument select works
t/op/sselect.t See if 4 argument select works
t/op/stash.t See if %:: stashes work t/op/stash.t See if %:: stashes work
t/op/state.t See if state variables work
t/op/stat.t See if stat works t/op/stat.t See if stat works
+t/op/stat_errors.t See if stat and file tests handle threshold errors +t/op/stat_errors.t See if stat and file tests handle threshold errors
t/op/state.t See if state variables work
t/op/study.t See if study works t/op/study.t See if study works
t/op/studytied.t See if study works with tied scalars t/op/studytied.t See if study works with tied scalars
t/op/sub_lval.t See if lvalue subroutines work
diff --git a/doio.c b/doio.c diff --git a/doio.c b/doio.c
index 70d7747..71dc6e4 100644 index 2792c66..f2934c5 100644
--- a/doio.c --- a/doio.c
+++ b/doio.c +++ b/doio.c
@@ -1437,8 +1437,11 @@ Perl_my_stat_flags(pTHX_ const U32 flags) @@ -1429,8 +1429,11 @@ Perl_my_stat_flags(pTHX_ const U32 flags)
if (PL_op->op_flags & OPf_REF) { if (PL_op->op_flags & OPf_REF) {
gv = cGVOP_gv; gv = cGVOP_gv;
do_fstat: do_fstat:
@ -51,7 +51,7 @@ index 70d7747..71dc6e4 100644
io = GvIO(gv); io = GvIO(gv);
do_fstat_have_io: do_fstat_have_io:
PL_laststype = OP_STAT; PL_laststype = OP_STAT;
@@ -1449,6 +1452,7 @@ Perl_my_stat_flags(pTHX_ const U32 flags) @@ -1441,6 +1444,7 @@ Perl_my_stat_flags(pTHX_ const U32 flags)
int fd = PerlIO_fileno(IoIFP(io)); int fd = PerlIO_fileno(IoIFP(io));
if (fd < 0) { if (fd < 0) {
/* E.g. PerlIO::scalar has no real fd. */ /* E.g. PerlIO::scalar has no real fd. */
@ -59,7 +59,7 @@ index 70d7747..71dc6e4 100644
return (PL_laststatval = -1); return (PL_laststatval = -1);
} else { } else {
return (PL_laststatval = PerlLIO_fstat(fd, &PL_statcache)); return (PL_laststatval = PerlLIO_fstat(fd, &PL_statcache));
@@ -1459,6 +1463,7 @@ Perl_my_stat_flags(pTHX_ const U32 flags) @@ -1451,6 +1455,7 @@ Perl_my_stat_flags(pTHX_ const U32 flags)
} }
PL_laststatval = -1; PL_laststatval = -1;
report_evil_fh(gv); report_evil_fh(gv);
@ -67,7 +67,7 @@ index 70d7747..71dc6e4 100644
return -1; return -1;
} }
else if ((PL_op->op_private & (OPpFT_STACKED|OPpFT_AFTER_t)) else if ((PL_op->op_private & (OPpFT_STACKED|OPpFT_AFTER_t))
@@ -1511,6 +1516,8 @@ Perl_my_lstat_flags(pTHX_ const U32 flags) @@ -1503,6 +1508,8 @@ Perl_my_lstat_flags(pTHX_ const U32 flags)
if (cGVOP_gv == PL_defgv) { if (cGVOP_gv == PL_defgv) {
if (PL_laststype != OP_LSTAT) if (PL_laststype != OP_LSTAT)
Perl_croak(aTHX_ "%s", no_prev_lstat); Perl_croak(aTHX_ "%s", no_prev_lstat);
@ -76,7 +76,7 @@ index 70d7747..71dc6e4 100644
return PL_laststatval; return PL_laststatval;
} }
PL_laststatval = -1; PL_laststatval = -1;
@@ -1520,6 +1527,7 @@ Perl_my_lstat_flags(pTHX_ const U32 flags) @@ -1512,6 +1519,7 @@ Perl_my_lstat_flags(pTHX_ const U32 flags)
"Use of -l on filehandle %"HEKf, "Use of -l on filehandle %"HEKf,
HEKfARG(GvENAME_HEK(cGVOP_gv))); HEKfARG(GvENAME_HEK(cGVOP_gv)));
} }
@ -85,10 +85,10 @@ index 70d7747..71dc6e4 100644
} }
if ((PL_op->op_private & (OPpFT_STACKED|OPpFT_AFTER_t)) if ((PL_op->op_private & (OPpFT_STACKED|OPpFT_AFTER_t))
diff --git a/pp_sys.c b/pp_sys.c diff --git a/pp_sys.c b/pp_sys.c
index fefbea3..87961f1 100644 index 5e0993d..2fcc219 100644
--- a/pp_sys.c --- a/pp_sys.c
+++ b/pp_sys.c +++ b/pp_sys.c
@@ -2925,10 +2925,11 @@ PP(pp_stat) @@ -2889,10 +2889,11 @@ PP(pp_stat)
Perl_croak(aTHX_ "The stat preceding lstat() wasn't an lstat"); Perl_croak(aTHX_ "The stat preceding lstat() wasn't an lstat");
} }
@ -102,8 +102,8 @@ index fefbea3..87961f1 100644
- havefp = FALSE; - havefp = FALSE;
PL_laststype = OP_STAT; PL_laststype = OP_STAT;
PL_statgv = gv ? gv : (GV *)io; PL_statgv = gv ? gv : (GV *)io;
SvPVCLEAR(PL_statname); sv_setpvs(PL_statname, "");
@@ -2939,22 +2940,25 @@ PP(pp_stat) @@ -2903,22 +2904,25 @@ PP(pp_stat)
if (IoIFP(io)) { if (IoIFP(io)) {
int fd = PerlIO_fileno(IoIFP(io)); int fd = PerlIO_fileno(IoIFP(io));
if (fd < 0) { if (fd < 0) {
@ -134,7 +134,7 @@ index fefbea3..87961f1 100644
} }
if (PL_laststatval < 0) { if (PL_laststatval < 0) {
@@ -3451,7 +3455,7 @@ PP(pp_fttty) @@ -3415,7 +3419,7 @@ PP(pp_fttty)
else if (name && isDIGIT(*name) && grok_atoUV(name, &uv, NULL) && uv <= PERL_INT_MAX) else if (name && isDIGIT(*name) && grok_atoUV(name, &uv, NULL) && uv <= PERL_INT_MAX)
fd = (int)uv; fd = (int)uv;
else else

View File

@ -0,0 +1,270 @@
From 10ce49389ea9ee26a3b02b6494b0a3849d56c6fa Mon Sep 17 00:00:00 2001
From: Yves Orton <demerphq@gmail.com>
Date: Mon, 26 Jun 2017 13:19:55 +0200
Subject: [PATCH] fix #131649 - extended charclass can trigger assert
The extended charclass parser makes some assumptions during the
first pass which are only true on well structured input, and it
does not properly catch various errors. later on the code assumes
that things the first pass will let through are valid, when in
fact they should trigger errors.
(cherry picked from commit 19a498a461d7c81ae3507c450953d1148efecf4f)
---
pod/perldiag.pod | 27 ++++++++++++++++++++++++++-
pod/perlrecharclass.pod | 4 ++--
regcomp.c | 28 ++++++++++++++++++----------
t/lib/warnings/regcomp | 6 +++---
t/re/reg_mesg.t | 29 ++++++++++++++++-------------
t/re/regex_sets.t | 6 +++---
6 files changed, 68 insertions(+), 32 deletions(-)
diff --git a/pod/perldiag.pod b/pod/perldiag.pod
index 106fe41121..c29925a2a4 100644
--- a/pod/perldiag.pod
+++ b/pod/perldiag.pod
@@ -5904,7 +5904,7 @@ yourself.
a perl4 interpreter, especially if the next 2 tokens are "use strict"
or "my $var" or "our $var".
-=item Syntax error in (?[...]) in regex m/%s/
+=item Syntax error in (?[...]) in regex; marked by <-- HERE in m/%s/
(F) Perl could not figure out what you meant inside this construct; this
notifies you that it is giving up trying.
@@ -6402,6 +6402,31 @@ to find out why that isn't happening.
(F) The unexec() routine failed for some reason. See your local FSF
representative, who probably put it there in the first place.
+=item Unexpected ']' with no following ')' in (?[... in regex; marked by <-- HERE in m/%s/
+
+(F) While parsing an extended character class a ']' character was encountered
+at a point in the definition where the only legal use of ']' is to close the
+character class definition as part of a '])', you may have forgotten the close
+paren, or otherwise confused the parser.
+
+=item Expecting close paren for nested extended charclass in regex; marked by <-- HERE in m/%s/
+
+(F) While parsing a nested extended character class like:
+
+ (?[ ... (?flags:(?[ ... ])) ... ])
+ ^
+
+we expected to see a close paren ')' (marked by ^) but did not.
+
+=item Expecting close paren for wrapper for nested extended charclass in regex; marked by <-- HERE in m/%s/
+
+(F) While parsing a nested extended character class like:
+
+ (?[ ... (?flags:(?[ ... ])) ... ])
+ ^
+
+we expected to see a close paren ')' (marked by ^) but did not.
+
=item Unexpected binary operator '%c' with no preceding operand in regex;
marked by S<<-- HERE> in m/%s/
diff --git a/pod/perlrecharclass.pod b/pod/perlrecharclass.pod
index 79480e4131..8c008507d1 100644
--- a/pod/perlrecharclass.pod
+++ b/pod/perlrecharclass.pod
@@ -1128,8 +1128,8 @@ hence both of the following work:
Any contained POSIX character classes, including things like C<\w> and C<\D>
respect the C<E<sol>a> (and C<E<sol>aa>) modifiers.
-C<< (?[ ]) >> is a regex-compile-time construct. Any attempt to use
-something which isn't knowable at the time the containing regular
+Note that C<< (?[ ]) >> is a regex-compile-time construct. Any attempt
+to use something which isn't knowable at the time the containing regular
expression is compiled is a fatal error. In practice, this means
just three limitations:
diff --git a/regcomp.c b/regcomp.c
index 4ee48ede42..ddac290d2b 100644
--- a/regcomp.c
+++ b/regcomp.c
@@ -14840,8 +14840,9 @@ S_handle_regex_sets(pTHX_ RExC_state_t *pRExC_state, SV** return_invlist,
TRUE /* Force /x */ );
switch (*RExC_parse) {
- case '?':
- if (RExC_parse[1] == '[') depth++, RExC_parse++;
+ case '(':
+ if (RExC_parse[1] == '?' && RExC_parse[2] == '[')
+ depth++, RExC_parse+=2;
/* FALLTHROUGH */
default:
break;
@@ -14898,9 +14899,9 @@ S_handle_regex_sets(pTHX_ RExC_state_t *pRExC_state, SV** return_invlist,
}
case ']':
- if (depth--) break;
- RExC_parse++;
- if (*RExC_parse == ')') {
+ if (RExC_parse[1] == ')') {
+ RExC_parse++;
+ if (depth--) break;
node = reganode(pRExC_state, ANYOF, 0);
RExC_size += ANYOF_SKIP;
nextchar(pRExC_state);
@@ -14912,20 +14913,25 @@ S_handle_regex_sets(pTHX_ RExC_state_t *pRExC_state, SV** return_invlist,
return node;
}
- goto no_close;
+ /* We output the messages even if warnings are off, because we'll fail
+ * the very next thing, and these give a likely diagnosis for that */
+ if (posix_warnings && av_tindex_nomg(posix_warnings) >= 0) {
+ output_or_return_posix_warnings(pRExC_state, posix_warnings, NULL);
+ }
+ RExC_parse++;
+ vFAIL("Unexpected ']' with no following ')' in (?[...");
}
RExC_parse += UTF ? UTF8SKIP(RExC_parse) : 1;
}
- no_close:
/* We output the messages even if warnings are off, because we'll fail
* the very next thing, and these give a likely diagnosis for that */
if (posix_warnings && av_tindex_nomg(posix_warnings) >= 0) {
output_or_return_posix_warnings(pRExC_state, posix_warnings, NULL);
}
- FAIL("Syntax error in (?[...])");
+ vFAIL("Syntax error in (?[...])");
}
/* Pass 2 only after this. */
@@ -15105,12 +15111,14 @@ redo_curchar:
* inversion list, and RExC_parse points to the trailing
* ']'; the next character should be the ')' */
RExC_parse++;
- assert(UCHARAT(RExC_parse) == ')');
+ if (UCHARAT(RExC_parse) != ')')
+ vFAIL("Expecting close paren for nested extended charclass");
/* Then the ')' matching the original '(' handled by this
* case: statement */
RExC_parse++;
- assert(UCHARAT(RExC_parse) == ')');
+ if (UCHARAT(RExC_parse) != ')')
+ vFAIL("Expecting close paren for wrapper for nested extended charclass");
RExC_parse++;
RExC_flags = save_flags;
diff --git a/t/lib/warnings/regcomp b/t/lib/warnings/regcomp
index 2b084c59b0..51ad57ccbe 100644
--- a/t/lib/warnings/regcomp
+++ b/t/lib/warnings/regcomp
@@ -59,21 +59,21 @@ Unmatched [ in regex; marked by <-- HERE in m/abc[ <-- HERE fi[.00./ at - line
qr/(?[[[:word]]])/;
EXPECT
Assuming NOT a POSIX class since there is no terminating ':' in regex; marked by <-- HERE in m/(?[[[:word <-- HERE ]]])/ at - line 2.
-syntax error in (?[...]) in regex m/(?[[[:word]]])/ at - line 2.
+Unexpected ']' with no following ')' in (?[... in regex; marked by <-- HERE in m/(?[[[:word]] <-- HERE ])/ at - line 2.
########
# NAME qr/(?[ [[:digit: ])/
# OPTION fatal
qr/(?[[[:digit: ])/;
EXPECT
Assuming NOT a POSIX class since no blanks are allowed in one in regex; marked by <-- HERE in m/(?[[[:digit: ] <-- HERE )/ at - line 2.
-syntax error in (?[...]) in regex m/(?[[[:digit: ])/ at - line 2.
+syntax error in (?[...]) in regex; marked by <-- HERE in m/(?[[[:digit: ]) <-- HERE / at - line 2.
########
# NAME qr/(?[ [:digit: ])/
# OPTION fatal
qr/(?[[:digit: ])/
EXPECT
Assuming NOT a POSIX class since no blanks are allowed in one in regex; marked by <-- HERE in m/(?[[:digit: ] <-- HERE )/ at - line 2.
-syntax error in (?[...]) in regex m/(?[[:digit: ])/ at - line 2.
+syntax error in (?[...]) in regex; marked by <-- HERE in m/(?[[:digit: ]) <-- HERE / at - line 2.
########
# NAME [perl #126141]
# OPTION fatal
diff --git a/t/re/reg_mesg.t b/t/re/reg_mesg.t
index d26a7caf37..5194d93751 100644
--- a/t/re/reg_mesg.t
+++ b/t/re/reg_mesg.t
@@ -215,8 +215,9 @@ my @death =
'/\b{gc}/' => "'gc' is an unknown bound type {#} m/\\b{gc{#}}/",
'/\B{gc}/' => "'gc' is an unknown bound type {#} m/\\B{gc{#}}/",
- '/(?[[[::]]])/' => "Syntax error in (?[...]) in regex m/(?[[[::]]])/",
- '/(?[[[:w:]]])/' => "Syntax error in (?[...]) in regex m/(?[[[:w:]]])/",
+
+ '/(?[[[::]]])/' => "Unexpected ']' with no following ')' in (?[... {#} m/(?[[[::]]{#}])/",
+ '/(?[[[:w:]]])/' => "Unexpected ']' with no following ')' in (?[... {#} m/(?[[[:w:]]{#}])/",
'/(?[[:w:]])/' => "",
'/([.].*)[.]/' => "", # [perl #127582]
'/[.].*[.]/' => "", # [perl #127604]
@@ -239,11 +240,12 @@ my @death =
'/(?[ \p{foo} ])/' => 'Can\'t find Unicode property definition "foo" {#} m/(?[ \p{foo}{#} ])/',
'/(?[ \p{ foo = bar } ])/' => 'Can\'t find Unicode property definition "foo = bar" {#} m/(?[ \p{ foo = bar }{#} ])/',
'/(?[ \8 ])/' => 'Unrecognized escape \8 in character class {#} m/(?[ \8{#} ])/',
- '/(?[ \t ]/' => 'Syntax error in (?[...]) in regex m/(?[ \t ]/',
- '/(?[ [ \t ]/' => 'Syntax error in (?[...]) in regex m/(?[ [ \t ]/',
- '/(?[ \t ] ]/' => 'Syntax error in (?[...]) in regex m/(?[ \t ] ]/',
- '/(?[ [ ] ]/' => 'Syntax error in (?[...]) in regex m/(?[ [ ] ]/',
- '/(?[ \t + \e # This was supposed to be a comment ])/' => 'Syntax error in (?[...]) in regex m/(?[ \t + \e # This was supposed to be a comment ])/',
+ '/(?[ \t ]/' => "Unexpected ']' with no following ')' in (?[... {#} m/(?[ \\t ]{#}/",
+ '/(?[ [ \t ]/' => "Syntax error in (?[...]) {#} m/(?[ [ \\t ]{#}/",
+ '/(?[ \t ] ]/' => "Unexpected ']' with no following ')' in (?[... {#} m/(?[ \\t ]{#} ]/",
+ '/(?[ [ ] ]/' => "Syntax error in (?[...]) {#} m/(?[ [ ] ]{#}/",
+ '/(?[ \t + \e # This was supposed to be a comment ])/' =>
+ "Syntax error in (?[...]) {#} m/(?[ \\t + \\e # This was supposed to be a comment ]){#}/",
'/(?[ ])/' => 'Incomplete expression within \'(?[ ])\' {#} m/(?[ {#}])/',
'm/(?[[a-\d]])/' => 'False [] range "a-\d" {#} m/(?[[a-\d{#}]])/',
'm/(?[[\w-x]])/' => 'False [] range "\w-" {#} m/(?[[\w-{#}x]])/',
@@ -431,10 +433,10 @@ my @death_utf8 = mark_as_utf8(
'/ネ\p{}ネ/' => 'Empty \p{} {#} m/ネ\p{{#}}ネ/',
- '/ネ(?[[[:ネ]]])ネ/' => "Syntax error in (?[...]) in regex m/ネ(?[[[:ネ]]])ネ/",
- '/ネ(?[[[:ネ: ])ネ/' => "Syntax error in (?[...]) in regex m/ネ(?[[[:ネ: ])ネ/",
- '/ネ(?[[[::]]])ネ/' => "Syntax error in (?[...]) in regex m/ネ(?[[[::]]])ネ/",
- '/ネ(?[[[:ネ:]]])ネ/' => "Syntax error in (?[...]) in regex m/ネ(?[[[:ネ:]]])ネ/",
+ '/ネ(?[[[:ネ]]])ネ/' => "Unexpected ']' with no following ')' in (?[... {#} m/ネ(?[[[:ネ]]{#}])ネ/",
+ '/ネ(?[[[:ネ: ])ネ/' => "Syntax error in (?[...]) {#} m/ネ(?[[[:ネ: ])ネ{#}/",
+ '/ネ(?[[[::]]])ネ/' => "Unexpected ']' with no following ')' in (?[... {#} m/ネ(?[[[::]]{#}])ネ/",
+ '/ネ(?[[[:ネ:]]])ネ/' => "Unexpected ']' with no following ')' in (?[... {#} m/ネ(?[[[:ネ:]]{#}])ネ/",
'/ネ(?[[:ネ:]])ネ/' => "",
'/ネ(?[ネ])ネ/' => 'Unexpected character {#} m/ネ(?[ネ{#}])ネ/',
'/ネ(?[ + [ネ] ])/' => 'Unexpected binary operator \'+\' with no preceding operand {#} m/ネ(?[ +{#} [ネ] ])/',
@@ -447,8 +449,9 @@ my @death_utf8 = mark_as_utf8(
'/(?[ \x{ネ} ])ネ/' => 'Non-hex character {#} m/(?[ \x{ネ{#}} ])ネ/',
'/(?[ \p{ネ} ])/' => 'Can\'t find Unicode property definition "ネ" {#} m/(?[ \p{ネ}{#} ])/',
'/(?[ \p{ ネ = bar } ])/' => 'Can\'t find Unicode property definition "ネ = bar" {#} m/(?[ \p{ ネ = bar }{#} ])/',
- '/ネ(?[ \t ]/' => 'Syntax error in (?[...]) in regex m/ネ(?[ \t ]/',
- '/(?[ \t + \e # ネ This was supposed to be a comment ])/' => 'Syntax error in (?[...]) in regex m/(?[ \t + \e # ネ This was supposed to be a comment ])/',
+ '/ネ(?[ \t ]/' => "Unexpected ']' with no following ')' in (?[... {#} m/ネ(?[ \\t ]{#}/",
+ '/(?[ \t + \e # ネ This was supposed to be a comment ])/' =>
+ "Syntax error in (?[...]) {#} m/(?[ \\t + \\e # ネ This was supposed to be a comment ]){#}/",
'm/(*ネ)ネ/' => q<Unknown verb pattern 'ネ' {#} m/(*ネ){#}ネ/>,
'/\cネ/' => "Character following \"\\c\" must be printable ASCII",
'/\b{ネ}/' => "'ネ' is an unknown bound type {#} m/\\b{ネ{#}}/",
diff --git a/t/re/regex_sets.t b/t/re/regex_sets.t
index 6a79f9d692..e9644bd4e6 100644
--- a/t/re/regex_sets.t
+++ b/t/re/regex_sets.t
@@ -158,13 +158,13 @@ for my $char ("٠", "٥", "٩") {
eval { $_ = '/(?[(\c]) /'; qr/$_/ };
like($@, qr/^Syntax error/, '/(?[(\c]) / should not panic');
eval { $_ = '(?[\c#]' . "\n])"; qr/$_/ };
- like($@, qr/^Syntax error/, '/(?[(\c]) / should not panic');
+ like($@, qr/^Unexpected/, '/(?[(\c]) / should not panic');
eval { $_ = '(?[(\c])'; qr/$_/ };
like($@, qr/^Syntax error/, '/(?[(\c])/ should be a syntax error');
eval { $_ = '(?[(\c]) ]\b'; qr/$_/ };
- like($@, qr/^Syntax error/, '/(?[(\c]) ]\b/ should be a syntax error');
+ like($@, qr/^Unexpected/, '/(?[(\c]) ]\b/ should be a syntax error');
eval { $_ = '(?[\c[]](])'; qr/$_/ };
- like($@, qr/^Syntax error/, '/(?[\c[]](])/ should be a syntax error');
+ like($@, qr/^Unexpected/, '/(?[\c[]](])/ should be a syntax error');
like("\c#", qr/(?[\c#])/, '\c# should match itself');
like("\c[", qr/(?[\c[])/, '\c[ should match itself');
like("\c\ ", qr/(?[\c\])/, '\c\ should match itself');
--
2.11.0

View File

@ -0,0 +1,44 @@
diff -up perl-5.24.4/Makefile.SH.orig perl-5.24.4/Makefile.SH
--- perl-5.24.4/Makefile.SH.orig 2018-10-02 12:18:23.627226701 +0200
+++ perl-5.24.4/Makefile.SH 2018-10-02 13:35:03.858920366 +0200
@@ -451,6 +451,8 @@ CCCMD = sh $(shellflags) cflags "opti
CCCMDSRC = sh $(shellflags) cflags "optimize='$(OPTIMIZE)'" $<
+DTRACEFLAGS = sh $(shellflags) cflags "optimize='$(OPTIMIZE)'" $@
+
CONFIGPM_FROM_CONFIG_SH = lib/Config.pm lib/Config_heavy.pl
CONFIGPM = $(CONFIGPM_FROM_CONFIG_SH) lib/Config_git.pl
@@ -865,13 +867,13 @@ mydtrace.h: $(DTRACE_H)
define)
$spitshell >>$Makefile <<'!NO!SUBS!'
$(DTRACE_MINI_O): perldtrace.d $(miniperl_objs_nodt)
- $(DTRACE) -G -s perldtrace.d -o $(DTRACE_MINI_O) $(miniperl_objs_nodt)
+ CFLAGS="`$(DTRACEFLAGS)`" $(DTRACE) -G -s perldtrace.d -o $(DTRACE_MINI_O) $(miniperl_objs_nodt)
$(DTRACE_PERLLIB_O): perldtrace.d $(perllib_objs_nodt)
- $(DTRACE) -G -s perldtrace.d -o $(DTRACE_PERLLIB_O) $(perllib_objs_nodt)
+ CFLAGS="`$(DTRACEFLAGS)`" $(DTRACE) -G -s perldtrace.d -o $(DTRACE_PERLLIB_O) $(perllib_objs_nodt)
$(DTRACE_MAIN_O): perldtrace.d perlmain$(OBJ_EXT)
- $(DTRACE) -G -s perldtrace.d -o $(DTRACE_MAIN_O) perlmain$(OBJ_EXT)
+ CFLAGS="`$(DTRACEFLAGS)`" $(DTRACE) -G -s perldtrace.d -o $(DTRACE_MAIN_O) perlmain$(OBJ_EXT)
!NO!SUBS!
;;
diff -up perl-5.24.4/cflags.SH.orig perl-5.24.4/cflags.SH
--- perl-5.24.4/cflags.SH.orig 2018-10-02 14:37:09.368649895 +0200
+++ perl-5.24.4/cflags.SH 2018-10-02 14:39:10.785695193 +0200
@@ -518,7 +518,10 @@ for file do
esac
# Can we perhaps use $ansi2knr here
- echo "$cc -c -DPERL_CORE $ccflags $stdflags $optimize $warn $extra"
+ case "$file" in
+ dtrace_*) echo "$ccflags $stdflags $optimize $warn $extra";;
+ *) echo "$cc -c -DPERL_CORE $ccflags $stdflags $optimize $warn $extra"
+ esac
. $TOP/config.sh

View File

@ -0,0 +1,175 @@
From 34716e2a6ee2af96078d62b065b7785c001194be Mon Sep 17 00:00:00 2001
From: David Mitchell <davem@iabyn.com>
Date: Fri, 29 Jun 2018 13:37:03 +0100
Subject: [PATCH] Perl_my_setenv(); handle integer wrap
RT #133204
Wean this function off int/I32 and onto UV/Size_t.
Also, replace all malloc-ish calls with a wrapper that does
overflow checks,
In particular, it was doing (nlen + vlen + 2) which could wrap when
the combined length of the environment variable name and value
exceeded around 0x7fffffff.
The wrapper check function is probably overkill, but belt and braces...
NB this function has several variant parts, #ifdef'ed by platform
type; I have blindly changed the parts that aren't compiled under linux.
---
util.c | 76 ++++++++++++++++++++++++++++++++++++++++------------------
1 file changed, 53 insertions(+), 23 deletions(-)
diff --git a/util.c b/util.c
index 7282dd9cfe..c5c7becc0f 100644
--- a/util.c
+++ b/util.c
@@ -2162,8 +2162,40 @@ Perl_new_warnings_bitfield(pTHX_ STRLEN *buffer, const char *const bits,
*(s+(nlen+1+vlen)) = '\0'
#ifdef USE_ENVIRON_ARRAY
- /* VMS' my_setenv() is in vms.c */
+
+/* small wrapper for use by Perl_my_setenv that mallocs, or reallocs if
+ * 'current' is non-null, with up to three sizes that are added together.
+ * It handles integer overflow.
+ */
+static char *
+S_env_alloc(void *current, Size_t l1, Size_t l2, Size_t l3, Size_t size)
+{
+ void *p;
+ Size_t sl, l = l1 + l2;
+
+ if (l < l2)
+ goto panic;
+ l += l3;
+ if (l < l3)
+ goto panic;
+ sl = l * size;
+ if (sl < l)
+ goto panic;
+
+ p = current
+ ? safesysrealloc(current, sl)
+ : safesysmalloc(sl);
+ if (p)
+ return (char*)p;
+
+ panic:
+ croak_memory_wrap();
+}
+
+
+/* VMS' my_setenv() is in vms.c */
#if !defined(WIN32) && !defined(NETWARE)
+
void
Perl_my_setenv(pTHX_ const char *nam, const char *val)
{
@@ -2179,28 +2211,27 @@ Perl_my_setenv(pTHX_ const char *nam, const char *val)
#ifndef PERL_USE_SAFE_PUTENV
if (!PL_use_safe_putenv) {
/* most putenv()s leak, so we manipulate environ directly */
- I32 i;
- const I32 len = strlen(nam);
- int nlen, vlen;
+ UV i;
+ Size_t vlen, nlen = strlen(nam);
/* where does it go? */
for (i = 0; environ[i]; i++) {
- if (strnEQ(environ[i],nam,len) && environ[i][len] == '=')
+ if (strnEQ(environ[i], nam, nlen) && environ[i][nlen] == '=')
break;
}
if (environ == PL_origenviron) { /* need we copy environment? */
- I32 j;
- I32 max;
+ UV j, max;
char **tmpenv;
max = i;
while (environ[max])
max++;
- tmpenv = (char**)safesysmalloc((max+2) * sizeof(char*));
+ /* XXX shouldn't that be max+1 rather than max+2 ??? - DAPM */
+ tmpenv = (char**)S_env_alloc(NULL, max, 2, 0, sizeof(char*));
for (j=0; j<max; j++) { /* copy environment */
- const int len = strlen(environ[j]);
- tmpenv[j] = (char*)safesysmalloc((len+1)*sizeof(char));
+ const Size_t len = strlen(environ[j]);
+ tmpenv[j] = S_env_alloc(NULL, len, 1, 0, 1);
Copy(environ[j], tmpenv[j], len+1, char);
}
tmpenv[max] = NULL;
@@ -2219,15 +2250,15 @@ Perl_my_setenv(pTHX_ const char *nam, const char *val)
#endif
}
if (!environ[i]) { /* does not exist yet */
- environ = (char**)safesysrealloc(environ, (i+2) * sizeof(char*));
+ environ = (char**)S_env_alloc(environ, i, 2, 0, sizeof(char*));
environ[i+1] = NULL; /* make sure it's null terminated */
}
else
safesysfree(environ[i]);
- nlen = strlen(nam);
+
vlen = strlen(val);
- environ[i] = (char*)safesysmalloc((nlen+vlen+2) * sizeof(char));
+ environ[i] = S_env_alloc(NULL, nlen, vlen, 2, 1);
/* all that work just for this */
my_setenv_format(environ[i], nam, nlen, val, vlen);
} else {
@@ -2252,22 +2283,21 @@ Perl_my_setenv(pTHX_ const char *nam, const char *val)
if (environ) /* old glibc can crash with null environ */
(void)unsetenv(nam);
} else {
- const int nlen = strlen(nam);
- const int vlen = strlen(val);
- char * const new_env =
- (char*)safesysmalloc((nlen + vlen + 2) * sizeof(char));
+ const Size_t nlen = strlen(nam);
+ const Size_t vlen = strlen(val);
+ char * const new_env = S_env_alloc(NULL, nlen, vlen, 2, 1);
my_setenv_format(new_env, nam, nlen, val, vlen);
(void)putenv(new_env);
}
# else /* ! HAS_UNSETENV */
char *new_env;
- const int nlen = strlen(nam);
- int vlen;
+ const Size_t nlen = strlen(nam);
+ Size_t vlen;
if (!val) {
val = "";
}
vlen = strlen(val);
- new_env = (char*)safesysmalloc((nlen + vlen + 2) * sizeof(char));
+ new_env = S_env_alloc(NULL, nlen, vlen, 2, 1);
/* all that work just for this */
my_setenv_format(new_env, nam, nlen, val, vlen);
(void)putenv(new_env);
@@ -2290,14 +2320,14 @@ Perl_my_setenv(pTHX_ const char *nam, const char *val)
{
dVAR;
char *envstr;
- const int nlen = strlen(nam);
- int vlen;
+ const Size_t nlen = strlen(nam);
+ Size_t vlen;
if (!val) {
val = "";
}
vlen = strlen(val);
- Newx(envstr, nlen+vlen+2, char);
+ envstr = S_env_alloc(NULL, nlen, vlen, 2, 1);
my_setenv_format(envstr, nam, nlen, val, vlen);
(void)PerlEnv_putenv(envstr);
Safefree(envstr);
--
2.17.1

View File

@ -1,4 +1,4 @@
From 892e8b006aa99ac2c880cdc2a81fd16f06c1a0f3 Mon Sep 17 00:00:00 2001 From 0711044bfd02bbd7d2967ba96c6fdcae5b7132d6 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Petr=20P=C3=ADsa=C5=99?= <ppisar@redhat.com> From: =?UTF-8?q?Petr=20P=C3=ADsa=C5=99?= <ppisar@redhat.com>
Date: Mon, 9 Jul 2018 16:18:36 +0200 Date: Mon, 9 Jul 2018 16:18:36 +0200
Subject: [PATCH] Remove ext/GDBM_File/t/fatal.t Subject: [PATCH] Remove ext/GDBM_File/t/fatal.t
@ -23,10 +23,10 @@ Signed-off-by: Petr Písař <ppisar@redhat.com>
delete mode 100644 ext/GDBM_File/t/fatal.t delete mode 100644 ext/GDBM_File/t/fatal.t
diff --git a/MANIFEST b/MANIFEST diff --git a/MANIFEST b/MANIFEST
index 95fa539095..b07fed1f54 100644 index a1a5320..ed5d05f 100644
--- a/MANIFEST --- a/MANIFEST
+++ b/MANIFEST +++ b/MANIFEST
@@ -4100,7 +4100,6 @@ ext/GDBM_File/GDBM_File.pm GDBM extension Perl module @@ -3719,7 +3719,6 @@ ext/GDBM_File/GDBM_File.pm GDBM extension Perl module
ext/GDBM_File/GDBM_File.xs GDBM extension external subroutines ext/GDBM_File/GDBM_File.xs GDBM extension external subroutines
ext/GDBM_File/hints/sco.pl Hint for GDBM_File for named architecture ext/GDBM_File/hints/sco.pl Hint for GDBM_File for named architecture
ext/GDBM_File/Makefile.PL GDBM extension makefile writer ext/GDBM_File/Makefile.PL GDBM extension makefile writer
@ -36,7 +36,7 @@ index 95fa539095..b07fed1f54 100644
ext/Hash-Util/Changes Change history of Hash::Util ext/Hash-Util/Changes Change history of Hash::Util
diff --git a/ext/GDBM_File/t/fatal.t b/ext/GDBM_File/t/fatal.t diff --git a/ext/GDBM_File/t/fatal.t b/ext/GDBM_File/t/fatal.t
deleted file mode 100644 deleted file mode 100644
index 0e426d4dbc..0000000000 index b7045ba..0000000
--- a/ext/GDBM_File/t/fatal.t --- a/ext/GDBM_File/t/fatal.t
+++ /dev/null +++ /dev/null
@@ -1,49 +0,0 @@ @@ -1,49 +0,0 @@
@ -60,7 +60,7 @@ index 0e426d4dbc..0000000000
- -
-unlink <Op_dbmx*>; -unlink <Op_dbmx*>;
- -
-open my $fh, '<', $^X or die "Can't open $^X: $!"; -open my $fh, $^X or die "Can't open $^X: $!";
-my $fileno = fileno $fh; -my $fileno = fileno $fh;
-isnt($fileno, undef, "Can find next available file descriptor"); -isnt($fileno, undef, "Can find next available file descriptor");
-close $fh or die $!; -close $fh or die $!;

View File

@ -1,4 +1,4 @@
From 3e6e57e89f298f450cbe14c61609f08fc01bf233 Mon Sep 17 00:00:00 2001 From bee36f5b5aad82c566311cf8785aa67ba3696155 Mon Sep 17 00:00:00 2001
From: Zefram <zefram@fysh.org> From: Zefram <zefram@fysh.org>
Date: Sat, 16 Dec 2017 05:33:20 +0000 Date: Sat, 16 Dec 2017 05:33:20 +0000
Subject: [PATCH] perform system() arg processing before fork Subject: [PATCH] perform system() arg processing before fork
@ -14,7 +14,7 @@ $$, and in that case it should also happen in the parent process.
Therefore reduce the argument scalars to strings first thing in pp_system. Therefore reduce the argument scalars to strings first thing in pp_system.
Fixes [perl #121105]. Fixes [perl #121105].
Petr Písař: Ported to 5.26.2-RC1 from Petr Písař: Ported to 5.24.4 from
64def2aeaeb63f92dadc6dfa33486c1d7b311963. 64def2aeaeb63f92dadc6dfa33486c1d7b311963.
Signed-off-by: Petr Písař <ppisar@redhat.com> Signed-off-by: Petr Písař <ppisar@redhat.com>
@ -24,10 +24,10 @@ Signed-off-by: Petr Písař <ppisar@redhat.com>
2 files changed, 24 insertions(+), 7 deletions(-) 2 files changed, 24 insertions(+), 7 deletions(-)
diff --git a/pp_sys.c b/pp_sys.c diff --git a/pp_sys.c b/pp_sys.c
index 87961f1..07e552a 100644 index 2fcc219..4ce8540 100644
--- a/pp_sys.c --- a/pp_sys.c
+++ b/pp_sys.c +++ b/pp_sys.c
@@ -4375,14 +4375,18 @@ PP(pp_system) @@ -4343,14 +4343,18 @@ PP(pp_system)
int result; int result;
# endif # endif
@ -53,19 +53,19 @@ index 87961f1..07e552a 100644
} }
PERL_FLUSHALL_FOR_CHILD; PERL_FLUSHALL_FOR_CHILD;
diff --git a/t/op/exec.t b/t/op/exec.t diff --git a/t/op/exec.t b/t/op/exec.t
index 237388b..e29de82 100644 index 726f548..e43dd6e 100644
--- a/t/op/exec.t --- a/t/op/exec.t
+++ b/t/op/exec.t +++ b/t/op/exec.t
@@ -36,7 +36,7 @@ $ENV{LANGUAGE} = 'C'; # Ditto in GNU. @@ -36,7 +36,7 @@ $ENV{LANGUAGE} = 'C'; # Ditto in GNU.
my $Is_VMS = $^O eq 'VMS'; my $Is_VMS = $^O eq 'VMS';
my $Is_Win32 = $^O eq 'MSWin32'; my $Is_Win32 = $^O eq 'MSWin32';
-plan(tests => 34); -plan(tests => 33);
+plan(tests => 37); +plan(tests => 36);
my $Perl = which_perl(); my $Perl = which_perl();
@@ -177,6 +177,19 @@ TODO: { @@ -173,6 +173,19 @@ TODO: {
"exec failure doesn't terminate process"); "exec failure doesn't terminate process");
} }

View File

@ -0,0 +1,65 @@
From cd6b0f4e030d55ff077e9bc8fbcf156ab79dceb1 Mon Sep 17 00:00:00 2001
From: Tony Cook <tony@develop-help.com>
Date: Wed, 7 Sep 2016 16:51:39 +1000
Subject: [PATCH] (perl #129149) avoid a heap buffer overflow with pack "W"...
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Petr Písař: Ported to 5.24.4:
From bf4a926a29374161655548b149d1cb37300bcc05 Mon Sep 17 00:00:00 2001
From: Tony Cook <tony@develop-help.com>
Date: Wed, 7 Sep 2016 16:51:39 +1000
Subject: [PATCH] (perl #129149) avoid a heap buffer overflow with pack "W"...
Signed-off-by: Petr Písař <ppisar@redhat.com>
---
pp_pack.c | 2 +-
t/op/pack.t | 13 ++++++++++++-
2 files changed, 13 insertions(+), 2 deletions(-)
diff --git a/pp_pack.c b/pp_pack.c
index c0de5ab..29fdb01 100644
--- a/pp_pack.c
+++ b/pp_pack.c
@@ -2598,7 +2598,7 @@ S_pack_rec(pTHX_ SV *cat, tempsym_t* symptr, SV **beglist, SV **endlist )
if (in_bytes) auv = auv % 0x100;
if (utf8) {
W_utf8:
- if (cur > end) {
+ if (cur >= end) {
*cur = '\0';
SvCUR_set(cat, cur - start);
diff --git a/t/op/pack.t b/t/op/pack.t
index a480c3a..cf5ae78 100644
--- a/t/op/pack.t
+++ b/t/op/pack.t
@@ -12,7 +12,7 @@ my $no_endianness = $] > 5.009 ? '' :
my $no_signedness = $] > 5.009 ? '' :
"Signed/unsigned pack modifiers not available on this perl";
-plan tests => 14716;
+plan tests => 14717;
use strict;
use warnings qw(FATAL all);
@@ -2066,3 +2066,14 @@ SKIP:
fresh_perl_like('pack "c10f1073741824"', qr/Out of memory during pack/, { stderr => 1 },
"integer overflow calculating allocation (multiply)");
}
+
+{
+ # [perl #129149] the code below would write one past the end of the output
+ # buffer, only detected by ASAN, not by valgrind
+ $Config{ivsize} >= 8
+ or skip "[perl #129149] need 64-bit for this test", 1;
+ fresh_perl_is(<<'EOS', "ok\n", { stderr => 1 }, "pack W overflow");
+print pack("ucW", "0000", 0, 140737488355327) eq "\$,#`P,```\n\0\x{7fffffffffff}"
+ ? "ok\n" : "not ok\n";
+EOS
+}
--
2.14.3

View File

@ -0,0 +1,37 @@
From 308112b17f3d093c11cc25408a421c86364de828 Mon Sep 17 00:00:00 2001
From: Tony Cook <tony@develop-help.com>
Date: Tue, 17 Jan 2017 15:36:31 +1100
Subject: [PATCH] (perl #129149) fix the test so skip has a SKIP: to work with
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Thanks to bulk88 for pointing this out.
Petr Písař: Ported to 5.24.4 from:
From 30be69c851a7fa7e29d85c9b6e070273df82f3e7 Mon Sep 17 00:00:00 2001
From: Tony Cook <tony@develop-help.com>
Date: Tue, 17 Jan 2017 15:36:31 +1100
Subject: [PATCH] (perl #129149) fix the test so skip has a SKIP: to work with
Signed-off-by: Petr Písař <ppisar@redhat.com>
---
t/op/pack.t | 1 +
1 file changed, 1 insertion(+)
diff --git a/t/op/pack.t b/t/op/pack.t
index cf5ae78..e399f7e 100644
--- a/t/op/pack.t
+++ b/t/op/pack.t
@@ -2067,6 +2067,7 @@ SKIP:
"integer overflow calculating allocation (multiply)");
}
+SKIP:
{
# [perl #129149] the code below would write one past the end of the output
# buffer, only detected by ASAN, not by valgrind
--
2.14.3

View File

@ -0,0 +1,56 @@
From f34cc5af94622240abbf730ac82c4f91cc4ffb83 Mon Sep 17 00:00:00 2001
From: Hugo van der Sanden <hv@crypt.org>
Date: Tue, 4 Oct 2016 14:40:11 +0100
Subject: [PATCH] anchored/floating substrings must be utf8 if target is
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Ported to 5.24.4:
commit 2814f4b3549f665a6f9203ac9e890ae1e415e0dc
Author: Hugo van der Sanden <hv@crypt.org>
Date: Tue Oct 4 14:40:11 2016 +0100
[perl #129350] anchored/floating substrings must be utf8 if target is
If the target is utf8 and either the anchored or floating substrings
are not, we need to create utf8 copies to check against. The state
of the two substrings may not be the same, but we were only testing
whichever we planned to check first.
Signed-off-by: Petr Písař <ppisar@redhat.com>
---
regexec.c | 3 ++-
t/re/re_tests | 1 +
2 files changed, 3 insertions(+), 1 deletion(-)
diff --git a/regexec.c b/regexec.c
index ff8e89c..6904546 100644
--- a/regexec.c
+++ b/regexec.c
@@ -703,7 +703,8 @@ Perl_re_intuit_start(pTHX_
reginfo->poscache_maxiter = 0;
if (utf8_target) {
- if (!prog->check_utf8 && prog->check_substr)
+ if ((!prog->anchored_utf8 && prog->anchored_substr)
+ || (!prog->float_utf8 && prog->float_substr))
to_utf8_substr(prog);
check = prog->check_utf8;
} else {
diff --git a/t/re/re_tests b/t/re/re_tests
index ab7ddbb..8b0feaa 100644
--- a/t/re/re_tests
+++ b/t/re/re_tests
@@ -1969,6 +1969,7 @@ ab(?#Comment){2}c abbc y $& abbc
aa$|a(?R)a|a aaa y $& aaa # [perl 128420] recursive matches
(?:\1|a)([bcd])\1(?:(?R)|e)\1 abbaccaddedcb y $& abbaccaddedcb # [perl 128420] recursive match with backreferences
(?il)\x{100}|\x{100}|\x{FF} \xFF y $& \xFF
+\b\z0*\x{100} .\x{100} n - - # [perl #129350] crashed in intuit_start
# Keep these lines at the end of the file
# vim: softtabstop=0 noexpandtab
--
2.14.3

View File

@ -0,0 +1,53 @@
From 7ec44a7b6adbc0221150969fc61134322fd5ed85 Mon Sep 17 00:00:00 2001
From: Hugo van der Sanden <hv@crypt.org>
Date: Mon, 12 Dec 2016 15:15:06 +0000
Subject: [PATCH] Correctly unwind on cache hit
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Petr Pisar: Ported to 5.24.4:
commit d3c48e81594c1d64ba9833495e45d8951b42027c
Author: Hugo van der Sanden <hv@crypt.org>
Date: Mon Dec 12 15:15:06 2016 +0000
[perl #130307] Correctly unwind on cache hit
We've already incremented curlyx.count in the WHILEM branch before
we check for a hit in the super-linear cache, so must reverse that
on the sayNO.
Signed-off-by: Petr Písař <ppisar@redhat.com>
---
regexec.c | 1 +
t/re/re_tests | 1 +
2 files changed, 2 insertions(+)
diff --git a/regexec.c b/regexec.c
index 6904546..25ea3a3 100644
--- a/regexec.c
+++ b/regexec.c
@@ -7334,6 +7334,7 @@ NULL
DEBUG_EXECUTE_r( Perl_re_exec_indentf( aTHX_ "whilem: (cache) already tried at this position...\n",
depth)
);
+ cur_curlyx->u.curlyx.count--;
sayNO; /* cache records failure */
}
ST.cache_offset = offset;
diff --git a/t/re/re_tests b/t/re/re_tests
index 8b0feaa..6717b85 100644
--- a/t/re/re_tests
+++ b/t/re/re_tests
@@ -1970,6 +1970,7 @@ aa$|a(?R)a|a aaa y $& aaa # [perl 128420] recursive matches
(?:\1|a)([bcd])\1(?:(?R)|e)\1 abbaccaddedcb y $& abbaccaddedcb # [perl 128420] recursive match with backreferences
(?il)\x{100}|\x{100}|\x{FF} \xFF y $& \xFF
\b\z0*\x{100} .\x{100} n - - # [perl #129350] crashed in intuit_start
+(X{2,}[-X]{1,4}){3,}X{2,} XXX-XXX-XXX-- n - - # [perl #130307]
# Keep these lines at the end of the file
# vim: softtabstop=0 noexpandtab
--
2.14.3

View File

@ -0,0 +1,44 @@
From bce4a2abeb8652d19e97d3bf07dd2580a3cc2e6c Mon Sep 17 00:00:00 2001
From: Hugo van der Sanden <hv@crypt.org>
Date: Sat, 25 Feb 2017 10:42:17 +0000
Subject: [PATCH] fix VMS test fail
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
d7186add added a runperl() test that breaks command line length limits for
VMS. Switch to fresh_perl() instead, so the prog is put in a file for us.
Signed-off-by: Petr Písař <ppisar@redhat.com>
---
t/comp/parser_run.t | 12 ++++++------
1 file changed, 6 insertions(+), 6 deletions(-)
diff --git a/t/comp/parser_run.t b/t/comp/parser_run.t
index 2543f49..e74644d 100644
--- a/t/comp/parser_run.t
+++ b/t/comp/parser_run.t
@@ -14,14 +14,14 @@ plan(1);
# [perl #130814] can reallocate lineptr while looking ahead for
# "Missing $ on loop variable" diagnostic.
-my $result = runperl(
- prog => " foreach m0\n\$" . ("0" x 0x2000),
- stderr => 1,
+my $result = fresh_perl(
+ " foreach m0\n\$" . ("0" x 0x2000),
+ { stderr => 1 },
);
-is($result, <<EXPECT);
-syntax error at -e line 3, near "foreach m0
+is($result . "\n", <<EXPECT);
+syntax error at - line 3, near "foreach m0
"
-Identifier too long at -e line 3.
+Identifier too long at - line 3.
EXPECT
__END__
--
2.7.4

View File

@ -0,0 +1,55 @@
From d7186addd1b477f6bdcef5e9d24f2125691a9082 Mon Sep 17 00:00:00 2001
From: Hugo van der Sanden <hv@crypt.org>
Date: Sun, 19 Feb 2017 11:15:38 +0000
Subject: [PATCH] [perl #130814] Add testcase, and new testfile
t/comp/parser_run.t
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Sometimes it's useful to have test.pl around, but it seems inappropriate
to pollute the existing t/comp/parser.t with that.
Signed-off-by: Petr Písař <ppisar@redhat.com>
---
t/comp/parser_run.t | 28 ++++++++++++++++++++++++++++
1 file changed, 28 insertions(+)
create mode 100644 t/comp/parser_run.t
diff --git a/t/comp/parser_run.t b/t/comp/parser_run.t
new file mode 100644
index 0000000..2543f49
--- /dev/null
+++ b/t/comp/parser_run.t
@@ -0,0 +1,28 @@
+#!./perl
+
+# Parser tests that want test.pl, eg to use runperl() for tests to show
+# reads through invalid pointers.
+# Note that this should still be runnable under miniperl.
+
+BEGIN {
+ @INC = qw(. ../lib );
+ chdir 't' if -d 't';
+}
+
+require './test.pl';
+plan(1);
+
+# [perl #130814] can reallocate lineptr while looking ahead for
+# "Missing $ on loop variable" diagnostic.
+my $result = runperl(
+ prog => " foreach m0\n\$" . ("0" x 0x2000),
+ stderr => 1,
+);
+is($result, <<EXPECT);
+syntax error at -e line 3, near "foreach m0
+"
+Identifier too long at -e line 3.
+EXPECT
+
+__END__
+# ex: set ts=8 sts=4 sw=4 et:
--
2.7.4

View File

@ -0,0 +1,76 @@
From fc0fe26a7d286480c1bb25f57e469ece575bb68d Mon Sep 17 00:00:00 2001
From: David Mitchell <davem@iabyn.com>
Date: Thu, 7 Jul 2016 17:03:29 +0100
Subject: [PATCH] SEGV in "Subroutine redefined" warning
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
RT #128257
The following SEGVed:
sub P::f{}
undef *P::;
*P::f =sub{};
due to the code which generates the "Subroutine STASH::NAME redefined"
warning assuming that the GV always has a stash. Make it so that if it
hasn't, the message changes to "Subroutine NAME redefined" rather than
just crashing.
Signed-off-by: Petr Písař <ppisar@redhat.com>
---
sv.c | 18 +++++++++++-------
t/lib/warnings/sv | 8 ++++++++
2 files changed, 19 insertions(+), 7 deletions(-)
diff --git a/sv.c b/sv.c
index 1b7a283..0cbe371 100644
--- a/sv.c
+++ b/sv.c
@@ -4074,14 +4074,18 @@ Perl_gv_setref(pTHX_ SV *const dstr, SV *const sstr)
CvCONST((const CV *)sref)
? cv_const_sv((const CV *)sref)
: NULL;
+ HV * const stash = GvSTASH((const GV *)dstr);
report_redefined_cv(
- sv_2mortal(Perl_newSVpvf(aTHX_
- "%"HEKf"::%"HEKf,
- HEKfARG(
- HvNAME_HEK(GvSTASH((const GV *)dstr))
- ),
- HEKfARG(GvENAME_HEK(MUTABLE_GV(dstr)))
- )),
+ sv_2mortal(
+ stash
+ ? Perl_newSVpvf(aTHX_
+ "%"HEKf"::%"HEKf,
+ HEKfARG(HvNAME_HEK(stash)),
+ HEKfARG(GvENAME_HEK(MUTABLE_GV(dstr))))
+ : Perl_newSVpvf(aTHX_
+ "%"HEKf,
+ HEKfARG(GvENAME_HEK(MUTABLE_GV(dstr))))
+ ),
cv,
CvCONST((const CV *)sref) ? &new_const_sv : NULL
);
diff --git a/t/lib/warnings/sv b/t/lib/warnings/sv
index 5ddd4fe..c8e0e62 100644
--- a/t/lib/warnings/sv
+++ b/t/lib/warnings/sv
@@ -413,3 +413,11 @@ Argument "a_c" isn't numeric in preincrement (++) at - line 5.
Argument "(?^:abc)" isn't numeric in preincrement (++) at - line 6.
Argument "123x" isn't numeric in preincrement (++) at - line 7.
Argument "123e" isn't numeric in preincrement (++) at - line 8.
+########
+# RT #128257 This used to SEGV
+use warnings;
+sub Foo::f {}
+undef *Foo::;
+*Foo::f =sub {};
+EXPECT
+Subroutine f redefined at - line 5.
--
2.5.5

View File

@ -0,0 +1,64 @@
From e7acdfe976f01ee0d1ba31b3b1db61454a72d6c9 Mon Sep 17 00:00:00 2001
From: David Mitchell <davem@iabyn.com>
Date: Tue, 21 Jun 2016 17:06:52 +0100
Subject: [PATCH] only treat stash entries with .*:: as sub-stashes
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
RT #128238
%: = 0 would cause an assertion failure in Perl_gv_check(), since when
it searched a stash for substashes, it assumed anything ending in ':' was
a substash, whereas substashes end in '::'. So check for a double colon
before recursing.
Signed-off-by: Petr Písař <ppisar@redhat.com>
---
gv.c | 5 ++++-
t/op/stash.t | 9 ++++++++-
2 files changed, 12 insertions(+), 2 deletions(-)
diff --git a/gv.c b/gv.c
index 4df3bce..2b3bdfa 100644
--- a/gv.c
+++ b/gv.c
@@ -2423,7 +2423,10 @@ Perl_gv_check(pTHX_ HV *stash)
for (entry = HvARRAY(stash)[i]; entry; entry = HeNEXT(entry)) {
GV *gv;
HV *hv;
- if (HeKEY(entry)[HeKLEN(entry)-1] == ':' &&
+ STRLEN keylen = HeKLEN(entry);
+ const char * const key = HeKEY(entry);
+
+ if (keylen >= 2 && key[keylen-2] == ':' && key[keylen-1] == ':' &&
(gv = MUTABLE_GV(HeVAL(entry))) && isGV(gv) && (hv = GvHV(gv)))
{
if (hv != PL_defstash && hv != stash
diff --git a/t/op/stash.t b/t/op/stash.t
index b8e0f34..ec795a9 100644
--- a/t/op/stash.t
+++ b/t/op/stash.t
@@ -7,7 +7,7 @@ BEGIN {
BEGIN { require "./test.pl"; }
-plan( tests => 52 );
+plan( tests => 53 );
# Used to segfault (bug #15479)
fresh_perl_like(
@@ -341,3 +341,10 @@ is runperl(
),
"ok\n",
'[perl #128086] no crash from assigning hash to *:::::: & deleting it';
+
+is runperl(
+ prog => 'BEGIN { %: = 0; $^W=1}; print qq|ok\n|',
+ stderr => 1,
+ ),
+ "ok\n",
+ "[perl #128238] don't treat %: as a stash (needs 2 colons)"
--
2.5.5

View File

@ -0,0 +1,66 @@
From 9e5cda6b852ca831004628051cf32c1576146452 Mon Sep 17 00:00:00 2001
From: Father Chrysostomos <sprout@cpan.org>
Date: Thu, 23 Jun 2016 21:57:09 -0700
Subject: [PATCH] [perl #128238] Crash with non-stash in stash
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
This is a follow-up to e7acdfe976f. Even if the name of the stash
entry ends with ::, it may not itself contain a real stash (though
this only happens with code that assigns directly to stash entries,
which has undefined behaviour according to perlmod), so skip hashes
that are not stashes.
Signed-off-by: Petr Písař <ppisar@redhat.com>
---
gv.c | 4 ++--
t/op/stash.t | 11 +++++++++--
2 files changed, 11 insertions(+), 4 deletions(-)
diff --git a/gv.c b/gv.c
index 2b3bdfa..dff611e 100644
--- a/gv.c
+++ b/gv.c
@@ -2411,10 +2411,10 @@ Perl_gv_check(pTHX_ HV *stash)
PERL_ARGS_ASSERT_GV_CHECK;
- if (!HvARRAY(stash))
+ if (!SvOOK(stash))
return;
- assert(SvOOK(stash));
+ assert(HvARRAY(stash));
for (i = 0; i <= (I32) HvMAX(stash); i++) {
const HE *entry;
diff --git a/t/op/stash.t b/t/op/stash.t
index 1591dbf..fe42700 100644
--- a/t/op/stash.t
+++ b/t/op/stash.t
@@ -7,7 +7,7 @@ BEGIN {
BEGIN { require "./test.pl"; }
-plan( tests => 53 );
+plan( tests => 54 );
# Used to segfault (bug #15479)
fresh_perl_like(
@@ -342,4 +342,11 @@ is runperl(
stderr => 1,
),
"ok\n",
- "[perl #128238] don't treat %: as a stash (needs 2 colons)"
+ "[perl #128238] don't treat %: as a stash (needs 2 colons)";
+
+is runperl(
+ prog => 'BEGIN { $::{q|foo::|}=*ENV; $^W=1}; print qq|ok\n|',
+ stderr => 1,
+ ),
+ "ok\n",
+ "[perl #128238] non-stashes in stashes";
--
2.5.5

View File

@ -0,0 +1,60 @@
From 63aab7ecaa6e826f845c405894bd8c4b6f601b39 Mon Sep 17 00:00:00 2001
From: Father Chrysostomos <sprout@cpan.org>
Date: Sun, 3 Jul 2016 22:23:34 -0700
Subject: [PATCH] [perl #128532] Crash vivifying stub in deleted pkg
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
v5.17.0-515-g186a5ba, which added newSTUB, did not take into account
that a GV may have a null GvSTASH pointer, if its stash has been
freed, so this crashes:
delete $My::{"Foo::"}; \&My::Foo::foo
Signed-off-by: Petr Písař <ppisar@redhat.com>
---
op.c | 2 +-
t/op/ref.t | 6 +++++-
2 files changed, 6 insertions(+), 2 deletions(-)
diff --git a/op.c b/op.c
index 46e76ac..4735d1b 100644
--- a/op.c
+++ b/op.c
@@ -9081,7 +9081,7 @@ Perl_newSTUB(pTHX_ GV *gv, bool fake)
assert(!GvCVu(gv));
GvCV_set(gv, cv);
GvCVGEN(gv) = 0;
- if (!fake && HvENAME_HEK(GvSTASH(gv)))
+ if (!fake && GvSTASH(gv) && HvENAME_HEK(GvSTASH(gv)))
gv_method_changed(gv);
if (SvFAKE(gv)) {
cvgv = gv_fetchsv((SV *)gv, GV_ADDMULTI, SVt_PVCV);
diff --git a/t/op/ref.t b/t/op/ref.t
index 19a44bb..84d9217 100644
--- a/t/op/ref.t
+++ b/t/op/ref.t
@@ -8,7 +8,7 @@ BEGIN {
use strict qw(refs subs);
-plan(235);
+plan(236);
# Test this first before we extend the stack with other operations.
# This caused an asan failure due to a bad write past the end of the stack.
@@ -124,6 +124,10 @@ is (join(':',@{$spring2{"foo"}}), "1:2:3:4");
is ($called, 1);
}
is ref eval {\&{""}}, "CODE", 'reference to &{""} [perl #94476]';
+delete $My::{"Foo::"};
+is ref \&My::Foo::foo, "CODE",
+ 'creating stub with \&deleted_stash::foo [perl #128532]';
+
# Test references to return values of operators (TARGs/PADTMPs)
{
--
2.5.5

View File

@ -0,0 +1,74 @@
From f6203e997f3012b8aab4cd35fe49f58e4d71fb8c Mon Sep 17 00:00:00 2001
From: Karl Williamson <khw@cpan.org>
Date: Sun, 10 Jul 2016 22:06:12 -0600
Subject: [PATCH] t/test.pl: Add fresh_perl() function
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
This will be useful for cases where the results don't readily fall into
fresh_perl_is and fresh_perl_like, such as when a bunch of massaging of
the results is needed before it is convenient to test them.
fresh_perl_like() could be used, but in the case of failure there could
be lines and lines of noise output.
Signed-off-by: Petr Písař <ppisar@redhat.com>
---
t/test.pl | 25 +++++++++++++++++++++----
1 file changed, 21 insertions(+), 4 deletions(-)
diff --git a/t/test.pl b/t/test.pl
index 41b77f4..20d08e9 100644
--- a/t/test.pl
+++ b/t/test.pl
@@ -953,11 +953,16 @@ sub register_tempfile {
return $count;
}
-# This is the temporary file for _fresh_perl
+# This is the temporary file for fresh_perl
my $tmpfile = tempfile();
-sub _fresh_perl {
- my($prog, $action, $expect, $runperl_args, $name) = @_;
+sub fresh_perl {
+ my($prog, $runperl_args) = @_;
+
+ # Run 'runperl' with the complete perl program contained in '$prog', and
+ # arguments in the hash referred to by '$runperl_args'. The results are
+ # returned, with $? set to the exit code. Unless overridden, stderr is
+ # redirected to stdout.
# Given the choice of the mis-parsable {}
# (we want an anon hash, but a borked lexer might think that it's a block)
@@ -975,7 +980,8 @@ sub _fresh_perl {
close TEST or die "Cannot close $tmpfile: $!";
my $results = runperl(%$runperl_args);
- my $status = $?;
+ my $status = $?; # Not necessary to save this, but it makes it clear to
+ # future maintainers.
# Clean up the results into something a bit more predictable.
$results =~ s/\n+$//;
@@ -994,6 +1000,17 @@ sub _fresh_perl {
$results =~ s/\n\n/\n/g;
}
+ $? = $status;
+ return $results;
+}
+
+
+sub _fresh_perl {
+ my($prog, $action, $expect, $runperl_args, $name) = @_;
+
+ my $results = fresh_perl($prog, $runperl_args);
+ my $status = $?;
+
# Use the first line of the program as a name if none was given
unless( $name ) {
($first_line, $name) = $prog =~ /^((.{1,50}).*)/;
--
2.7.4

View File

@ -0,0 +1,74 @@
From 55b6481ff87f84626ba01275708297a42a6537b1 Mon Sep 17 00:00:00 2001
From: David Mitchell <davem@iabyn.com>
Date: Tue, 21 Jun 2016 15:23:20 +0100
Subject: [PATCH] uninit warning from $h{\const} coredumped
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
The code that printed the the name and subscript of a hash element
in an "uninitialized variable" warning assumed that a constant
hash subscript would be SvPOK. Something like \1 is a constant,
but is ROK, not POK. SEGVs ensured.
Signed-off-by: Petr Písař <ppisar@redhat.com>
---
sv.c | 5 ++++-
t/op/hashwarn.t | 19 ++++++++++++++++++-
2 files changed, 22 insertions(+), 2 deletions(-)
diff --git a/sv.c b/sv.c
index 535ee8d..b0fdd15 100644
--- a/sv.c
+++ b/sv.c
@@ -15683,9 +15683,12 @@ Perl_varname(pTHX_ const GV *const gv, const char gvtype, PADOFFSET targ,
if (subscript_type == FUV_SUBSCRIPT_HASH) {
SV * const sv = newSV(0);
+ STRLEN len;
+ const char * const pv = SvPV_nomg_const((SV*)keyname, len);
+
*SvPVX(name) = '$';
Perl_sv_catpvf(aTHX_ name, "{%s}",
- pv_pretty(sv, SvPVX_const(keyname), SvCUR(keyname), 32, NULL, NULL,
+ pv_pretty(sv, pv, len, 32, NULL, NULL,
PERL_PV_PRETTY_DUMP | PERL_PV_ESCAPE_UNI_DETECT ));
SvREFCNT_dec_NN(sv);
}
diff --git a/t/op/hashwarn.t b/t/op/hashwarn.t
index a6a1de9..6d72244 100644
--- a/t/op/hashwarn.t
+++ b/t/op/hashwarn.t
@@ -6,7 +6,7 @@ BEGIN {
}
require './test.pl';
-plan( tests => 16 );
+plan( tests => 18 );
use strict;
use warnings;
@@ -71,3 +71,20 @@ my $fail_not_hr = 'Not a HASH reference at ';
cmp_ok(scalar(@warnings),'==',0,'pseudo-hash 2 count');
cmp_ok(substr($@,0,length($fail_not_hr)),'eq',$fail_not_hr,'pseudo-hash 2 msg');
}
+
+# RT #128189
+# this used to coredump
+
+{
+ @warnings = ();
+ my %h;
+
+ no warnings;
+ use warnings qw(uninitialized);
+
+ my $x = "$h{\1}";
+ is(scalar @warnings, 1, "RT #128189 - 1 warning");
+ like("@warnings",
+ qr/Use of uninitialized value \$h\{"SCALAR\(0x[\da-f]+\)"\}/,
+ "RT #128189 correct warning");
+}
--
2.5.5

View File

@ -0,0 +1,32 @@
From d5ea0ef8623c7d7ba5f42d239787aa71393e2054 Mon Sep 17 00:00:00 2001
From: Yves Orton <demerphq@gmail.com>
Date: Tue, 13 Sep 2016 23:06:58 +0200
Subject: [PATCH 2/5] clean up gv_fetchmethod_pvn_flags: move origname init to
function start
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
so it is more obvious that it is a constant copy of the
original name.
Signed-off-by: Petr Písař <ppisar@redhat.com>
---
gv.c | 1 -
1 file changed, 1 deletion(-)
diff --git a/gv.c b/gv.c
index b0221e0..fe38d44 100644
--- a/gv.c
+++ b/gv.c
@@ -1014,7 +1014,6 @@ Perl_gv_fetchmethod_pvn_flags(pTHX_ HV *stash, const char *name, const STRLEN le
const char *nsplit = NULL;
GV* gv;
HV* ostash = stash;
- const char * const origname = name;
SV *const error_report = MUTABLE_SV(stash);
const U32 autoload = flags & GV_AUTOLOAD;
const U32 do_croak = flags & GV_CROAK;
--
2.7.4

View File

@ -0,0 +1,92 @@
From e2cace1e9e89525afbca257742ddb36630b7fbc3 Mon Sep 17 00:00:00 2001
From: Yves Orton <demerphq@gmail.com>
Date: Tue, 13 Sep 2016 23:10:48 +0200
Subject: [PATCH 3/5] clean up gv_fetchmethod_pvn_flags: rename nsplit to
last_separator
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
nsplit if set points at the first char of the last separator
in name, so rename it so it is more comprehensible what it means.
Signed-off-by: Petr Písař <ppisar@redhat.com>
---
gv.c | 24 ++++++++++++------------
1 file changed, 12 insertions(+), 12 deletions(-)
diff --git a/gv.c b/gv.c
index fe38d44..07709a0 100644
--- a/gv.c
+++ b/gv.c
@@ -1011,7 +1011,7 @@ Perl_gv_fetchmethod_pvn_flags(pTHX_ HV *stash, const char *name, const STRLEN le
const char * const origname = name;
const char * const name_end = name + len;
const char *nend;
- const char *nsplit = NULL;
+ const char *last_separator = NULL;
GV* gv;
HV* ostash = stash;
SV *const error_report = MUTABLE_SV(stash);
@@ -1024,38 +1024,38 @@ Perl_gv_fetchmethod_pvn_flags(pTHX_ HV *stash, const char *name, const STRLEN le
if (SvTYPE(stash) < SVt_PVHV)
stash = NULL;
else {
- /* The only way stash can become NULL later on is if nsplit is set,
+ /* The only way stash can become NULL later on is if last_separator is set,
which in turn means that there is no need for a SVt_PVHV case
the error reporting code. */
}
for (nend = name; *nend || nend != name_end; nend++) {
if (*nend == '\'') {
- nsplit = nend;
+ last_separator = nend;
name = nend + 1;
}
else if (*nend == ':' && *(nend + 1) == ':') {
- nsplit = nend++;
+ last_separator = nend++;
name = nend + 1;
}
}
- if (nsplit) {
- if ((nsplit - origname) == 5 && memEQ(origname, "SUPER", 5)) {
+ if (last_separator) {
+ if ((last_separator - origname) == 5 && memEQ(origname, "SUPER", 5)) {
/* ->SUPER::method should really be looked up in original stash */
stash = CopSTASH(PL_curcop);
flags |= GV_SUPER;
DEBUG_o( Perl_deb(aTHX_ "Treating %s as %s::%s\n",
origname, HvENAME_get(stash), name) );
}
- else if ((nsplit - origname) >= 7 &&
- strnEQ(nsplit - 7, "::SUPER", 7)) {
+ else if ((last_separator - origname) >= 7 &&
+ strnEQ(last_separator - 7, "::SUPER", 7)) {
/* don't autovifify if ->NoSuchStash::SUPER::method */
- stash = gv_stashpvn(origname, nsplit - origname - 7, is_utf8);
+ stash = gv_stashpvn(origname, last_separator - origname - 7, is_utf8);
if (stash) flags |= GV_SUPER;
}
else {
/* don't autovifify if ->NoSuchStash::method */
- stash = gv_stashpvn(origname, nsplit - origname, is_utf8);
+ stash = gv_stashpvn(origname, last_separator - origname, is_utf8);
}
ostash = stash;
}
@@ -1098,8 +1098,8 @@ Perl_gv_fetchmethod_pvn_flags(pTHX_ HV *stash, const char *name, const STRLEN le
else {
SV* packnamesv;
- if (nsplit) {
- packnamesv = newSVpvn_flags(origname, nsplit - origname,
+ if (last_separator) {
+ packnamesv = newSVpvn_flags(origname, last_separator - origname,
SVs_TEMP | is_utf8);
} else {
packnamesv = error_report;
--
2.7.4

View File

@ -0,0 +1,81 @@
From cfb736762c1becf344ce6beaa701ff2e1abd5f9c Mon Sep 17 00:00:00 2001
From: Yves Orton <demerphq@gmail.com>
Date: Tue, 13 Sep 2016 23:14:49 +0200
Subject: [PATCH 4/5] fix #129267: rework gv_fetchmethod_pvn_flags separator
parsing
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
With previous code we could overrun the end of the name when
the last char in the string was a colon. This reworks the code
so it is more clear what is going on, and so it more similar
to other code that also parses out package separaters in gv.c.
This is a rework of the reverted patches:
243ca72 rename "nend" name_cursor in Perl_gv_fetchmethod_pvn_flags
b053c93 fix: [perl #129267] Possible string overrun with invalid len in gv.c
Signed-off-by: Petr Písař <ppisar@redhat.com>
---
gv.c | 36 ++++++++++++++++++++++++++----------
1 file changed, 26 insertions(+), 10 deletions(-)
diff --git a/gv.c b/gv.c
index 07709a0..3237c53 100644
--- a/gv.c
+++ b/gv.c
@@ -1010,7 +1010,6 @@ Perl_gv_fetchmethod_pvn_flags(pTHX_ HV *stash, const char *name, const STRLEN le
{
const char * const origname = name;
const char * const name_end = name + len;
- const char *nend;
const char *last_separator = NULL;
GV* gv;
HV* ostash = stash;
@@ -1029,16 +1028,33 @@ Perl_gv_fetchmethod_pvn_flags(pTHX_ HV *stash, const char *name, const STRLEN le
the error reporting code. */
}
- for (nend = name; *nend || nend != name_end; nend++) {
- if (*nend == '\'') {
- last_separator = nend;
- name = nend + 1;
- }
- else if (*nend == ':' && *(nend + 1) == ':') {
- last_separator = nend++;
- name = nend + 1;
- }
+ {
+ /* check if the method name is fully qualified or
+ * not, and separate the package name from the actual
+ * method name.
+ *
+ * leaves last_separator pointing to the beginning of the
+ * last package separator (either ' or ::) or 0
+ * if none was found.
+ *
+ * leaves name pointing at the beginning of the
+ * method name.
+ */
+ const char *name_cursor = name;
+ const char * const name_em1 = name_end - 1; /* name_end minus 1 */
+ for (name_cursor = name; name_cursor < name_end ; name_cursor++) {
+ if (*name_cursor == '\'') {
+ last_separator = name_cursor;
+ name = name_cursor + 1;
+ }
+ else if (name_cursor < name_em1 && *name_cursor == ':' && name_cursor[1] == ':') {
+ last_separator = name_cursor++;
+ name = name_cursor + 1;
+ }
+ }
}
+
+ /* did we find a separator? */
if (last_separator) {
if ((last_separator - origname) == 5 && memEQ(origname, "SUPER", 5)) {
/* ->SUPER::method should really be looked up in original stash */
--
2.7.4

View File

@ -0,0 +1,44 @@
From 1665b718d8fbd58705dbe6376fa51f8c1a02d887 Mon Sep 17 00:00:00 2001
From: Father Chrysostomos <sprout@cpan.org>
Date: Tue, 13 Sep 2016 22:38:59 -0700
Subject: [PATCH 5/5] [perl #129267] Test for gv_fetchmethod buffer overrun
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Signed-off-by: Petr Písař <ppisar@redhat.com>
---
ext/XS-APItest/APItest.xs | 3 +++
ext/XS-APItest/t/gv_fetchmethod_flags.t | 5 +++++
2 files changed, 8 insertions(+)
diff --git a/ext/XS-APItest/APItest.xs b/ext/XS-APItest/APItest.xs
index 992b6a5..4602cee 100644
--- a/ext/XS-APItest/APItest.xs
+++ b/ext/XS-APItest/APItest.xs
@@ -2571,6 +2571,9 @@ gv_fetchmethod_flags_type(stash, methname, type, flags)
gv = gv_fetchmethod_pvn_flags(stash, name, len, flags | SvUTF8(methname));
break;
}
+ case 4:
+ gv = gv_fetchmethod_pvn_flags(stash, SvPV_nolen(methname),
+ flags, SvUTF8(methname));
}
XPUSHs( gv ? (SV*)gv : &PL_sv_undef);
diff --git a/ext/XS-APItest/t/gv_fetchmethod_flags.t b/ext/XS-APItest/t/gv_fetchmethod_flags.t
index 15d1c41..2da3b70 100644
--- a/ext/XS-APItest/t/gv_fetchmethod_flags.t
+++ b/ext/XS-APItest/t/gv_fetchmethod_flags.t
@@ -49,3 +49,8 @@ is XS::APItest::gv_fetchmethod_flags_type(\%::, "method\0not quite!", 2, 0), "*m
}
}
}
+
+# [perl #129267] Buffer overrun when argument name ends with colon and
+# there is a colon past the end. This used to segv.
+XS::APItest::gv_fetchmethod_flags_type(\%::, "method:::::", 4, 7);
+ # With type 4, 7 is the length
--
2.7.4

View File

@ -0,0 +1,64 @@
From b43665fffa48dd179eba1b5616d4ca35b4def876 Mon Sep 17 00:00:00 2001
From: Father Chrysostomos <sprout@cpan.org>
Date: Sun, 18 Sep 2016 20:17:08 -0700
Subject: [PATCH] [perl #129287] Make UTF8 & append null
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
The & and &. operators were not appending a null byte to the string
in utf8 mode.
(The internal function that they use is the same. I used &. in the
test just because its intent is clearer.)
Signed-off-by: Petr Písař <ppisar@redhat.com>
---
doop.c | 1 +
t/op/bop.t | 14 +++++++++++++-
2 files changed, 14 insertions(+), 1 deletion(-)
diff --git a/doop.c b/doop.c
index ad9172a..234a425 100644
--- a/doop.c
+++ b/doop.c
@@ -1093,6 +1093,7 @@ Perl_do_vop(pTHX_ I32 optype, SV *sv, SV *left, SV *right)
if (sv == left || sv == right)
(void)sv_usepvn(sv, dcorig, needlen);
SvCUR_set(sv, dc - dcorig);
+ *SvEND(sv) = 0;
break;
case OP_BIT_XOR:
while (lulen && rulen) {
diff --git a/t/op/bop.t b/t/op/bop.t
index 2afb8d7..1f96e9b 100644
--- a/t/op/bop.t
+++ b/t/op/bop.t
@@ -19,7 +19,7 @@ BEGIN {
# If you find tests are failing, please try adding names to tests to track
# down where the failure is, and supply your new names as a patch.
# (Just-in-time test naming)
-plan tests => 192 + (10*13*2) + 5 + 29;
+plan tests => 192 + (10*13*2) + 5 + 30;
# numerics
ok ((0xdead & 0xbeef) == 0x9ead);
@@ -664,3 +664,15 @@ is $^A, "123", '~v0 clears vstring magic on retval';
is(-1 >> $w + 1, -1, "IV -1 right shift $w + 1 == -1");
}
}
+
+# [perl #129287] UTF8 & was not providing a trailing null byte.
+# This test is a bit convoluted, as we want to make sure that the string
+# allocated for &s target contains memory initialised to something other
+# than a null byte. Uninitialised memory does not make for a reliable
+# test. So we do &. on a longer non-utf8 string first.
+for (["aaa","aaa"],[substr ("a\x{100}",0,1), "a"]) {
+ use feature "bitwise";
+ no warnings "experimental::bitwise", "pack";
+ $byte = substr unpack("P2", pack "P", $$_[0] &. $$_[1]), -1;
+}
+is $byte, "\0", "utf8 &. appends null byte";
--
2.7.4

View File

@ -0,0 +1,32 @@
From 9ce5bf4c39e28441410672f39b5ee1c4569967f8 Mon Sep 17 00:00:00 2001
From: Hugo van der Sanden <hv@crypt.org>
Date: Fri, 28 Oct 2016 13:27:23 +0100
Subject: [PATCH] [perl #130001] h2xs: avoid infinite loop for enums
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
'typedef enum x { ... } x' causes h2xs to enter a substitution loop while
trying to write the typemap file.
Signed-off-by: Petr Písař <ppisar@redhat.com>
---
utils/h2xs.PL | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/utils/h2xs.PL b/utils/h2xs.PL
index 8fda87b..f9063cb 100644
--- a/utils/h2xs.PL
+++ b/utils/h2xs.PL
@@ -1034,7 +1034,7 @@ if( ! $opt_X ){ # use XS, unless it was disabled
}
}
{ local $" = '|';
- $typedef_rex = qr(\b(?<!struct )(?:@good_td)\b) if @good_td;
+ $typedef_rex = qr(\b(?<!struct )(?<!enum )(?:@good_td)\b) if @good_td;
}
%known_fnames = map @$_[1,3], @$fdecls_parsed; # [1,3] is NAME, FULLTEXT
if ($fmask) {
--
2.7.4

View File

@ -0,0 +1,61 @@
From fecd3be8dbdb747b9cbf4cbb9299ce40faabc8e6 Mon Sep 17 00:00:00 2001
From: John Lightsey <lightsey@debian.org>
Date: Mon, 14 Nov 2016 11:56:15 +0100
Subject: [PATCH] Fix Storable segfaults.
Fix a null pointed dereference segfault in storable when the
retrieve_code logic was unable to read the string that contained
the code.
Also fix several locations where retrieve_other was called with a
null context pointer. This also resulted in a null pointer
dereference.
---
dist/Storable/Storable.xs | 10 +++++++---
1 file changed, 7 insertions(+), 3 deletions(-)
diff --git a/dist/Storable/Storable.xs b/dist/Storable/Storable.xs
index 053951c..caa489c 100644
--- a/dist/Storable/Storable.xs
+++ b/dist/Storable/Storable.xs
@@ -5647,6 +5647,10 @@ static SV *retrieve_code(pTHX_ stcxt_t *cxt, const char *cname)
CROAK(("Unexpected type %d in retrieve_code\n", type));
}
+ if (!text) {
+ CROAK(("Unable to retrieve code\n"));
+ }
+
/*
* prepend "sub " to the source
*/
@@ -5767,7 +5771,7 @@ static SV *old_retrieve_array(pTHX_ stcxt_t *cxt, const char *cname)
continue; /* av_extend() already filled us with undef */
}
if (c != SX_ITEM)
- (void) retrieve_other(aTHX_ (stcxt_t *) 0, 0); /* Will croak out */
+ (void) retrieve_other(aTHX_ cxt, 0); /* Will croak out */
TRACEME(("(#%d) item", i));
sv = retrieve(aTHX_ cxt, 0); /* Retrieve item */
if (!sv)
@@ -5844,7 +5848,7 @@ static SV *old_retrieve_hash(pTHX_ stcxt_t *cxt, const char *cname)
if (!sv)
return (SV *) 0;
} else
- (void) retrieve_other(aTHX_ (stcxt_t *) 0, 0); /* Will croak out */
+ (void) retrieve_other(aTHX_ cxt, 0); /* Will croak out */
/*
* Get key.
@@ -5855,7 +5859,7 @@ static SV *old_retrieve_hash(pTHX_ stcxt_t *cxt, const char *cname)
GETMARK(c);
if (c != SX_KEY)
- (void) retrieve_other(aTHX_ (stcxt_t *) 0, 0); /* Will croak out */
+ (void) retrieve_other(aTHX_ cxt, 0); /* Will croak out */
RLEN(size); /* Get key size */
KBUFCHK((STRLEN)size); /* Grow hash key read pool if needed */
if (size)
--
2.10.2

View File

@ -0,0 +1,124 @@
From 463ddf34c08f2c97199b1bb242da1f17494d4d1a Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Petr=20P=C3=ADsa=C5=99?= <ppisar@redhat.com>
Date: Thu, 24 Nov 2016 16:34:09 +0100
Subject: [PATCH] Fix const correctness in hv_func.h
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Building an XS code with -Wcast-qual yielded warnings about discarding
const qualifiers from pointer targets like:
$ printf '#include "EXTERN.h"\n#include "perl.h"\n' | gcc -Wcast-qual -I/usr/lib64/perl5/CORE -c -x c -
In file included from /usr/lib64/perl5/CORE/hv.h:629:0,
from /usr/lib64/perl5/CORE/perl.h:3740,
from <stdin>:2:
/usr/lib64/perl5/CORE/hv_func.h: In function S_perl_hash_siphash_2_4:
/usr/lib64/perl5/CORE/hv_func.h:213:17: warning: cast discards const qualifier from pointer target type [-Wcast-qual]
U64TYPE k0 = ((U64TYPE*)seed)[0];
^
Signed-off-by: Petr Písař <ppisar@redhat.com>
---
hv_func.h | 22 +++++++++++-----------
1 file changed, 11 insertions(+), 11 deletions(-)
diff --git a/hv_func.h b/hv_func.h
index 8866db9..57b1ed1 100644
--- a/hv_func.h
+++ b/hv_func.h
@@ -118,7 +118,7 @@
#if (BYTEORDER == 0x1234 || BYTEORDER == 0x12345678) && U32SIZE == 4
/* CPU endian matches murmurhash algorithm, so read 32-bit word directly */
- #define U8TO32_LE(ptr) (*((U32*)(ptr)))
+ #define U8TO32_LE(ptr) (*((const U32*)(ptr)))
#elif BYTEORDER == 0x4321 || BYTEORDER == 0x87654321
/* TODO: Add additional cases below where a compiler provided bswap32 is available */
#if defined(__GNUC__) && (__GNUC__>4 || (__GNUC__==4 && __GNUC_MINOR__>=3))
@@ -210,8 +210,8 @@ S_perl_hash_siphash_2_4(const unsigned char * const seed, const unsigned char *i
U64 v3 = UINT64_C(0x7465646279746573);
U64 b;
- U64 k0 = ((U64*)seed)[0];
- U64 k1 = ((U64*)seed)[1];
+ U64 k0 = ((const U64*)seed)[0];
+ U64 k1 = ((const U64*)seed)[1];
U64 m;
const int left = inlen & 7;
const U8 *end = in + inlen - left;
@@ -269,7 +269,7 @@ S_perl_hash_siphash_2_4(const unsigned char * const seed, const unsigned char *i
PERL_STATIC_INLINE U32
S_perl_hash_superfast(const unsigned char * const seed, const unsigned char *str, STRLEN len) {
- U32 hash = *((U32*)seed) + (U32)len;
+ U32 hash = *((const U32*)seed) + (U32)len;
U32 tmp;
int rem= len & 3;
len >>= 2;
@@ -373,7 +373,7 @@ S_perl_hash_superfast(const unsigned char * const seed, const unsigned char *str
/* now we create the hash function */
PERL_STATIC_INLINE U32
S_perl_hash_murmur3(const unsigned char * const seed, const unsigned char *ptr, STRLEN len) {
- U32 h1 = *((U32*)seed);
+ U32 h1 = *((const U32*)seed);
U32 k1;
U32 carry = 0;
@@ -467,7 +467,7 @@ S_perl_hash_murmur3(const unsigned char * const seed, const unsigned char *ptr,
PERL_STATIC_INLINE U32
S_perl_hash_djb2(const unsigned char * const seed, const unsigned char *str, const STRLEN len) {
const unsigned char * const end = (const unsigned char *)str + len;
- U32 hash = *((U32*)seed) + (U32)len;
+ U32 hash = *((const U32*)seed) + (U32)len;
while (str < end) {
hash = ((hash << 5) + hash) + *str++;
}
@@ -477,7 +477,7 @@ S_perl_hash_djb2(const unsigned char * const seed, const unsigned char *str, con
PERL_STATIC_INLINE U32
S_perl_hash_sdbm(const unsigned char * const seed, const unsigned char *str, const STRLEN len) {
const unsigned char * const end = (const unsigned char *)str + len;
- U32 hash = *((U32*)seed) + (U32)len;
+ U32 hash = *((const U32*)seed) + (U32)len;
while (str < end) {
hash = (hash << 6) + (hash << 16) - hash + *str++;
}
@@ -503,7 +503,7 @@ S_perl_hash_sdbm(const unsigned char * const seed, const unsigned char *str, con
PERL_STATIC_INLINE U32
S_perl_hash_one_at_a_time(const unsigned char * const seed, const unsigned char *str, const STRLEN len) {
const unsigned char * const end = (const unsigned char *)str + len;
- U32 hash = *((U32*)seed) + (U32)len;
+ U32 hash = *((const U32*)seed) + (U32)len;
while (str < end) {
hash += *str++;
hash += (hash << 10);
@@ -518,7 +518,7 @@ S_perl_hash_one_at_a_time(const unsigned char * const seed, const unsigned char
PERL_STATIC_INLINE U32
S_perl_hash_one_at_a_time_hard(const unsigned char * const seed, const unsigned char *str, const STRLEN len) {
const unsigned char * const end = (const unsigned char *)str + len;
- U32 hash = *((U32*)seed) + (U32)len;
+ U32 hash = *((const U32*)seed) + (U32)len;
while (str < end) {
hash += (hash << 10);
@@ -553,7 +553,7 @@ S_perl_hash_one_at_a_time_hard(const unsigned char * const seed, const unsigned
PERL_STATIC_INLINE U32
S_perl_hash_old_one_at_a_time(const unsigned char * const seed, const unsigned char *str, const STRLEN len) {
const unsigned char * const end = (const unsigned char *)str + len;
- U32 hash = *((U32*)seed);
+ U32 hash = *((const U32*)seed);
while (str < end) {
hash += *str++;
hash += (hash << 10);
@@ -581,7 +581,7 @@ S_perl_hash_murmur_hash_64a (const unsigned char * const seed, const unsigned ch
{
const U64 m = UINT64_C(0xc6a4a7935bd1e995);
const int r = 47;
- U64 h = *((U64*)seed) ^ len;
+ U64 h = *((const U64*)seed) ^ len;
const U64 * data = (const U64 *)str;
const U64 * end = data + (len/8);
const unsigned char * data2;
--
2.7.4

View File

@ -0,0 +1,38 @@
From bb78386f13c18a1a7dae932b9b36e977056b13c7 Mon Sep 17 00:00:00 2001
From: Yves Orton <demerphq@gmail.com>
Date: Fri, 27 Jan 2017 16:57:40 +0100
Subject: [PATCH] only mess with NEXT_OFF() when we are in PASS2
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
In 31fc93954d1f379c7a49889d91436ce99818e1f6 I added code that would modify
NEXT_OFF() when we were not in PASS2, when we should not do so. Strangly this
did not segfault when I tested, but this fix is required.
Signed-off-by: Petr Písař <ppisar@redhat.com>
---
regcomp.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/regcomp.c b/regcomp.c
index 322d230..d5ce63f 100644
--- a/regcomp.c
+++ b/regcomp.c
@@ -11709,11 +11709,11 @@ S_regpiece(pTHX_ RExC_state_t *pRExC_state, I32 *flagp, U32 depth)
nextchar(pRExC_state);
if (max < min) { /* If can't match, warn and optimize to fail
unconditionally */
+ reginsert(pRExC_state, OPFAIL, orig_emit, depth+1);
if (PASS2) {
ckWARNreg(RExC_parse, "Quantifier {n,m} with n > m can't match");
+ NEXT_OFF(orig_emit)= regarglen[OPFAIL] + NODE_STEP_REGNODE;
}
- reginsert(pRExC_state, OPFAIL, orig_emit, depth+1);
- NEXT_OFF(orig_emit)= regarglen[OPFAIL] + NODE_STEP_REGNODE;
return ret;
}
else if (min == max && *RExC_parse == '?')
--
2.7.4

View File

@ -0,0 +1,69 @@
From 42e9b60980bb8e29e76629e14c6aa945194c0647 Mon Sep 17 00:00:00 2001
From: Hugo van der Sanden <hv@crypt.org>
Date: Wed, 5 Oct 2016 02:20:26 +0100
Subject: [PATCH] [perl #129061] CURLYX nodes can be studied more than once
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
study_chunk() for CURLYX is used to set flags on the linked WHILEM
node to say it is the whilem_c'th of whilem_seen. However it assumes
each CURLYX can be studied only once, which is not the case - there
are various cases such as GOSUB which call study_chunk() recursively
on already-visited parts of the program.
Storing the wrong index can cause the super-linear cache handling in
regmatch() to read/write the byte after the end of poscache.
Also reported in [perl #129281].
Signed-off-by: Petr Písař <ppisar@redhat.com>
---
regcomp.c | 12 +++++++++---
t/re/pat.t | 1 -
2 files changed, 9 insertions(+), 4 deletions(-)
diff --git a/regcomp.c b/regcomp.c
index 850a6c1..48c8d8d 100644
--- a/regcomp.c
+++ b/regcomp.c
@@ -5218,15 +5218,21 @@ S_study_chunk(pTHX_ RExC_state_t *pRExC_state, regnode **scanp,
However, this time it's not a subexpression
we care about, but the expression itself. */
&& (maxcount == REG_INFTY)
- && data && ++data->whilem_c < 16) {
+ && data) {
/* This stays as CURLYX, we can put the count/of pair. */
/* Find WHILEM (as in regexec.c) */
regnode *nxt = oscan + NEXT_OFF(oscan);
if (OP(PREVOPER(nxt)) == NOTHING) /* LONGJMP */
nxt += ARG(nxt);
- PREVOPER(nxt)->flags = (U8)(data->whilem_c
- | (RExC_whilem_seen << 4)); /* On WHILEM */
+ nxt = PREVOPER(nxt);
+ if (nxt->flags & 0xf) {
+ /* we've already set whilem count on this node */
+ } else if (++data->whilem_c < 16) {
+ assert(data->whilem_c <= RExC_whilem_seen);
+ nxt->flags = (U8)(data->whilem_c
+ | (RExC_whilem_seen << 4)); /* On WHILEM */
+ }
}
if (data && fl & (SF_HAS_PAR|SF_IN_PAR))
pars++;
diff --git a/t/re/pat.t b/t/re/pat.t
index ecd3af1..16bfc8e 100644
--- a/t/re/pat.t
+++ b/t/re/pat.t
@@ -1909,7 +1909,6 @@ EOP
}
{
# [perl #129281] buffer write overflow, detected by ASAN, valgrind
- local $::TODO = "whilem_c bumped too much";
fresh_perl_is('/0(?0)|^*0(?0)|^*(^*())0|/', '', {}, "don't bump whilem_c too much");
}
} # End of sub run_tests
--
2.7.4

View File

@ -0,0 +1,34 @@
From 923e23bad0514e1bd29112650fb78aa4ea69e1b7 Mon Sep 17 00:00:00 2001
From: Yves Orton <demerphq@gmail.com>
Date: Sat, 28 Jan 2017 15:13:17 +0100
Subject: [PATCH] silence warnings from tests about impossible quantifiers
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
thanks to Dave M for noticing....
Signed-off-by: Petr Písař <ppisar@redhat.com>
---
t/re/pat_rt_report.t | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/t/re/pat_rt_report.t b/t/re/pat_rt_report.t
index 21aff58..dd740e7 100644
--- a/t/re/pat_rt_report.t
+++ b/t/re/pat_rt_report.t
@@ -1134,9 +1134,10 @@ EOP
{
# rt
fresh_perl_is(
- '"foo"=~/((?1)){8,0}/; print "ok"',
+ 'no warnings "regexp"; "foo"=~/((?1)){8,0}/; print "ok"',
"ok", {}, 'RT #130561 - allowing impossible quantifier should not cause SEGVs');
my $s= "foo";
+ no warnings 'regexp';
ok($s=~/(foo){1,0}|(?1)/,
"RT #130561 - allowing impossible quantifier should not break recursion");
}
--
2.7.4

View File

@ -1,73 +0,0 @@
From 8985b12868f07d9ef501580d600e49fe8f230eb4 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Petr=20P=C3=ADsa=C5=99?= <ppisar@redhat.com>
Date: Tue, 22 Aug 2017 09:49:42 +0200
Subject: [PATCH] Time-HiRes: Fix unreliable t/usleep.t and t/utime.t
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Ported from Time-HiRes-1.9746.
The tests randomly failed on loaded machines because a CPU scheduler
could add unpredictable delays.
CPAN RT#122819
Signed-off-by: Petr Písař <ppisar@redhat.com>
---
dist/Time-HiRes/t/usleep.t | 4 ++--
dist/Time-HiRes/t/utime.t | 9 +++++----
2 files changed, 7 insertions(+), 6 deletions(-)
diff --git a/dist/Time-HiRes/t/usleep.t b/dist/Time-HiRes/t/usleep.t
index 9322458..bb66cbe 100644
--- a/dist/Time-HiRes/t/usleep.t
+++ b/dist/Time-HiRes/t/usleep.t
@@ -32,7 +32,7 @@ SKIP: {
Time::HiRes::usleep(500_000);
my $f2 = Time::HiRes::time();
my $d = $f2 - $f;
- ok $d > 0.4 && $d < 0.9 or print("# slept $d secs $f to $f2\n");
+ ok $d > 0.49 or print("# slept $d secs $f to $f2\n");
}
SKIP: {
@@ -40,7 +40,7 @@ SKIP: {
my $r = [ Time::HiRes::gettimeofday() ];
Time::HiRes::sleep( 0.5 );
my $f = Time::HiRes::tv_interval $r;
- ok $f > 0.4 && $f < 0.9 or print("# slept $f instead of 0.5 secs.\n");
+ ok $f > 0.49 or print("# slept $f instead of 0.5 secs.\n");
}
SKIP: {
diff --git a/dist/Time-HiRes/t/utime.t b/dist/Time-HiRes/t/utime.t
index 22fd48e..c5c7e55 100644
--- a/dist/Time-HiRes/t/utime.t
+++ b/dist/Time-HiRes/t/utime.t
@@ -106,17 +106,18 @@ print "# utime undef sets time to now\n";
my ($fh2, $filename2) = tempfile( "Time-HiRes-utime-XXXXXXXXX", UNLINK => 1 );
my $now = Time::HiRes::time;
+ sleep(1);
is Time::HiRes::utime(undef, undef, $filename1, $fh2), 2, "Two files changed";
{
my ($got_atime, $got_mtime) = ( Time::HiRes::stat($fh1) )[8, 9];
- cmp_ok abs( $got_atime - $now), '<', 0.1, "File 1 atime set correctly";
- cmp_ok abs( $got_mtime - $now), '<', 0.1, "File 1 mtime set correctly";
+ cmp_ok $got_atime, '>=', $now, "File 1 atime set correctly";
+ cmp_ok $got_mtime, '>=', $now, "File 1 mtime set correctly";
}
{
my ($got_atime, $got_mtime) = ( Time::HiRes::stat($filename2) )[8, 9];
- cmp_ok abs( $got_atime - $now), '<', 0.1, "File 2 atime set correctly";
- cmp_ok abs( $got_mtime - $now), '<', 0.1, "File 2 mtime set correctly";
+ cmp_ok $got_atime, '>=', $now, "File 2 atime set correctly";
+ cmp_ok $got_mtime, '>=', $now, "File 2 mtime set correctly";
}
};
--
2.9.5

View File

@ -1,61 +0,0 @@
From cb2fda94b02c5b7e8d16582410034f5a3dae526f Mon Sep 17 00:00:00 2001
From: Tony Cook <tony@develop-help.com>
Date: Tue, 25 Jul 2017 16:21:22 +1000
Subject: [PATCH] (perl #131588) be a little more careful in arybase::_tie_it()
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Original patch by John Leitch <john@autosectools.com>
Petr Pisar: Ported to 5.26.0.
Signed-off-by: Petr Písař <ppisar@redhat.com>
---
ext/arybase/arybase.xs | 10 ++++++----
ext/arybase/t/arybase.t | 4 +++-
2 files changed, 9 insertions(+), 5 deletions(-)
diff --git a/ext/arybase/arybase.xs b/ext/arybase/arybase.xs
index 880bbe3..216442a 100644
--- a/ext/arybase/arybase.xs
+++ b/ext/arybase/arybase.xs
@@ -438,10 +438,12 @@ _tie_it(SV *sv)
INIT:
GV * const gv = (GV *)sv;
CODE:
- if (GvSV(gv))
- /* This is *our* scalar now! */
- sv_unmagic(GvSV(gv), PERL_MAGIC_sv);
- tie(aTHX_ GvSVn(gv), NULL, GvSTASH(CvGV(cv)));
+ if (isGV(gv)) {
+ if (GvSV(gv))
+ /* This is *our* scalar now! */
+ sv_unmagic(GvSV(gv), PERL_MAGIC_sv);
+ tie(aTHX_ GvSVn(gv), NULL, GvSTASH(CvGV(cv)));
+ }
void
FETCH(...)
diff --git a/ext/arybase/t/arybase.t b/ext/arybase/t/arybase.t
index f3d3287..41e90df 100644
--- a/ext/arybase/t/arybase.t
+++ b/ext/arybase/t/arybase.t
@@ -4,7 +4,7 @@
# plus miscellaneous bug fix tests
no warnings 'deprecated';
-use Test::More tests => 7;
+use Test::More tests => 8;
sub outside_base_scope { return "${'['}" }
@@ -34,4 +34,6 @@ is $@, "That use of \$[ is unsupported at $f line $l.\n",
sub foo { my $x; $x = wait } # compilation of this routine used to crash
+ok eval { arybase::_tie_it(1); 1 }, "don't crash on bad call to _tie_it()";
+
1;
--
2.9.4

View File

@ -1,37 +0,0 @@
From 37268580c0cfbf190ff9aa7859a604713cb366ee Mon Sep 17 00:00:00 2001
From: Yves Orton <demerphq@gmail.com>
Date: Tue, 27 Jun 2017 16:36:57 +0200
Subject: [PATCH] t/op/hash.t: fixup intermittently failing test
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Port to 5.26.0:
commit b2ac59d1d0fda74d6612701d8316fe8dfb6a1b90
Author: Yves Orton <demerphq@gmail.com>
Date: Tue Jun 27 16:36:57 2017 +0200
t/op/hash.t: fixup intermittently failing test
Signed-off-by: Petr Písař <ppisar@redhat.com>
---
t/op/hash.t | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/t/op/hash.t b/t/op/hash.t
index a0e79c7..b941c57 100644
--- a/t/op/hash.t
+++ b/t/op/hash.t
@@ -206,7 +206,7 @@ sub torture_hash {
my $keys = pop @groups;
++$h->{$_} foreach @$keys;
my (undef, $total) = validate_hash("$desc " . keys %$h, $h);
- is($total, $total0, "bucket count is constant when rebuilding");
+ ok($total == $total0 || $total == ($total0*2), "bucket count is expected size when rebuilding");
is(scalar %$h, pop @groups, "scalar keys is identical when rebuilding");
++$h1->{$_} foreach @$keys;
validate_hash("$desc copy " . keys %$h1, $h1);
--
2.9.4

View File

@ -1,105 +0,0 @@
From dc1f8f6b581a8e4efbb782398ab3e7c3a52b062f Mon Sep 17 00:00:00 2001
From: Karl Williamson <khw@cpan.org>
Date: Tue, 8 May 2018 12:13:18 -0600
Subject: [PATCH] PATCH: [perl #133185] Infinite loop in qr//
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
This loop was inadvertently introduced as part of patches to fix
(perl #132227 CVE-2018-6797] heap-buffer-overflow". The commit in 5.27
responsible was f8fb8615ddc5a80e3bbd4386a8914497f921b62d.
To be vulnerable, the pattern must start out as /d (hence no use 5.012
or higher), and then there must be something that implicitly forces /u
(which the \pp does in the test case added by this patch), and then
(?aa), and then the code point \xDF. (German Sharp S). The /i must be
in effect by the time the DF is encountered, but it needn't come in the
(?aa) which the test does.
The problem is that the conditional that is testing that we switched
away from /d rules is assuming that this happened during the
construction of the current EXACTFish node. The comments I wrote
indicate this assumption. But this example shows that the switch can
come before this node started getting constructed, and so it loops.
The patch explicitly saves the state at the beginning of this node's
construction, and only retries if it changed during that construction.
Therefore the next time through, it will see that it hasn't changed
since the previous time, and won't loop.
Petr Písař: Ported to 5.26.2 from:
commit 0b9cb33b146b3eb55634853f883a880771dd1413
Author: Karl Williamson <khw@cpan.org>
Date: Tue May 8 12:13:18 2018 -0600
PATCH: [perl #133185] Infinite loop in qr//
Signed-off-by: Petr Písař <ppisar@redhat.com>
---
regcomp.c | 10 +++++++++-
t/re/speed.t | 5 ++++-
2 files changed, 13 insertions(+), 2 deletions(-)
diff --git a/regcomp.c b/regcomp.c
index 845e660..18fa465 100644
--- a/regcomp.c
+++ b/regcomp.c
@@ -13100,6 +13100,10 @@ S_regatom(pTHX_ RExC_state_t *pRExC_state, I32 *flagp, U32 depth)
bool maybe_exactfu = PASS2
&& (node_type == EXACTF || node_type == EXACTFL);
+ /* To see if RExC_uni_semantics changes during parsing of the node.
+ * */
+ bool uni_semantics_at_node_start;
+
/* If a folding node contains only code points that don't
* participate in folds, it can be changed into an EXACT node,
* which allows the optimizer more things to look for */
@@ -13147,6 +13151,8 @@ S_regatom(pTHX_ RExC_state_t *pRExC_state, I32 *flagp, U32 depth)
|| UTF8_IS_INVARIANT(UCHARAT(RExC_parse))
|| UTF8_IS_START(UCHARAT(RExC_parse)));
+ uni_semantics_at_node_start = RExC_uni_semantics;
+
/* Here, we have a literal character. Find the maximal string of
* them in the input that we can fit into a single EXACTish node.
* We quit at the first non-literal or when the node gets full */
@@ -13550,7 +13556,9 @@ S_regatom(pTHX_ RExC_state_t *pRExC_state, I32 *flagp, U32 depth)
* didn't think it needed to reparse. But this
* sharp s now does indicate the need for
* reparsing. */
- if (RExC_uni_semantics) {
+ if ( uni_semantics_at_node_start
+ != RExC_uni_semantics)
+ {
p = oldp;
goto loopdone;
}
diff --git a/t/re/speed.t b/t/re/speed.t
index 4a4830f..9a57de1 100644
--- a/t/re/speed.t
+++ b/t/re/speed.t
@@ -24,7 +24,7 @@ BEGIN {
skip_all('no re module') unless defined &DynaLoader::boot_DynaLoader;
skip_all_without_unicode_tables();
-plan tests => 58; #** update watchdog timeouts proportionally when adding tests
+plan tests => 59; #** update watchdog timeouts proportionally when adding tests
use strict;
use warnings;
@@ -156,6 +156,9 @@ PROG
ok( $elapsed <= 1, "should not COW on long string with substr and m//g");
}
+ # [perl #133185] Infinite loop
+ like("!\xdf", eval 'qr/\pp(?aai)\xdf/',
+ 'Compiling qr/\pp(?aai)\xdf/ doesn\'t loop');
} # End of sub run_tests
--
2.14.3

View File

@ -1,63 +0,0 @@
Subject: [PATCH] Pass CFLAGS to dtrace
Signed-off-by: Petr Písař <ppisar@redhat.com>
---
Makefile.SH | 8 +++++---
cflags.SH | 5 ++++-
2 files changed, 9 insertions(+), 4 deletions(-)
diff --git a/Makefile.SH b/Makefile.SH
index 5fc6d1c..e89ad70 100755
--- a/Makefile.SH
+++ b/Makefile.SH
@@ -457,6 +457,8 @@ CCCMD = sh $(shellflags) cflags "optimize='$(OPTIMIZE)'" $@
CCCMDSRC = sh $(shellflags) cflags "optimize='$(OPTIMIZE)'" $<
+DTRACEFLAGS = sh $(shellflags) cflags "optimize='$(OPTIMIZE)'" $@
+
CONFIGPM_FROM_CONFIG_SH = lib/Config.pm lib/Config_heavy.pl
CONFIGPM = $(CONFIGPM_FROM_CONFIG_SH) lib/Config_git.pl
@@ -890,19 +892,19 @@ $(DTRACE_MINI_O): perldtrace.d $(miniperl_objs_nodt)
-rm -rf mpdtrace
mkdir mpdtrace
cp $(miniperl_objs_nodt) mpdtrace/
- $(DTRACE) -G -s perldtrace.d -o $(DTRACE_MINI_O) $(miniperl_dtrace_objs)
+ CFLAGS="`$(DTRACEFLAGS)`" $(DTRACE) -G -s perldtrace.d -o $(DTRACE_MINI_O) $(miniperl_dtrace_objs)
$(DTRACE_PERLLIB_O): perldtrace.d $(perllib_objs_nodt)
-rm -rf libpdtrace
mkdir libpdtrace
cp $(perllib_objs_nodt) libpdtrace/
- $(DTRACE) -G -s perldtrace.d -o $(DTRACE_PERLLIB_O) $(perllib_dtrace_objs)
+ CFLAGS="`$(DTRACEFLAGS)`" $(DTRACE) -G -s perldtrace.d -o $(DTRACE_PERLLIB_O) $(perllib_dtrace_objs)
$(DTRACE_MAIN_O): perldtrace.d perlmain$(OBJ_EXT)
-rm -rf maindtrace
mkdir maindtrace
cp perlmain$(OBJ_EXT) maindtrace/
- $(DTRACE) -G -s perldtrace.d -o $(DTRACE_MAIN_O) $(perlmain_dtrace_objs) || \
+ CFLAGS="`$(DTRACEFLAGS)`" $(DTRACE) -G -s perldtrace.d -o $(DTRACE_MAIN_O) $(perlmain_dtrace_objs) || \
( $(ECHO) "No probes in perlmain$(OBJ_EXT), generating a dummy $(DTRACE_MAIN_O)" && \
$(ECHO) >dtrace_main.c && \
`$(CCCMD)` $(PLDLFLAGS) dtrace_main.c && \
diff --git a/cflags.SH b/cflags.SH
index 3af1e97..b845127 100755
--- a/cflags.SH
+++ b/cflags.SH
@@ -516,7 +516,10 @@ for file do
esac
# Can we perhaps use $ansi2knr here
- echo "$cc -c -DPERL_CORE $ccflags $stdflags $optimize $warn $extra"
+ case "$file" in
+ dtrace_*) echo "$ccflags $stdflags $optimize $warn $extra";;
+ *) echo "$cc -c -DPERL_CORE $ccflags $stdflags $optimize $warn $extra";;
+ esac
. $TOP/config.sh
--
2.17.1

View File

@ -1,143 +0,0 @@
From 07ebe9c4fb1028d17e61caabe8c15abd0cd48983 Mon Sep 17 00:00:00 2001
From: Yves Orton <demerphq@gmail.com>
Date: Thu, 29 Jun 2017 11:31:14 +0200
Subject: [PATCH] Parse caret vars with subscripts the same as normal vars
inside of ${..} escaping
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
This behavior is discussed in perl #131664, which complains that
"${^CAPTURE}[0]" does not work as expected. Abigail explains the
behavior is by design and Eirik Berg Hanssen expands on that explanation
pointing out that what /should/ work, "${^CAPTURE[0]}" does not,
which Sawyer then ruled was a bug.
So this patch makes "${^CAPTURE[0]}" (and "${^CAPTURE [0]}" [hi
abigial]) work the same as they would if the var was called @foo.
Petr Písař: Ported to 5.26.2-RC1.
Signed-off-by: Petr Písař <ppisar@redhat.com>
---
t/base/lex.t | 28 +++++++++++++++++++++++++++-
toke.c | 46 +++++++++++++++++++++++++---------------------
2 files changed, 52 insertions(+), 22 deletions(-)
diff --git a/t/base/lex.t b/t/base/lex.t
index 99fd3bb..ae17bbd 100644
--- a/t/base/lex.t
+++ b/t/base/lex.t
@@ -1,6 +1,6 @@
#!./perl
-print "1..112\n";
+print "1..119\n";
$x = 'x';
@@ -154,6 +154,32 @@ my $test = 31;
print "not " unless index ($@, 'Can\'t use global $^XYZ in "my"') > -1;
print "ok $test\n"; $test++;
# print "($@)\n" if $@;
+#
+ ${^TEST}= "splat";
+ @{^TEST}= ("foo", "bar");
+ %{^TEST}= ("foo" => "FOO", "bar" => "BAR" );
+
+ print "not " if "${^TEST}" ne "splat";
+ print "ok $test\n"; $test++;
+
+ print "not " if "${^TEST}[0]" ne "splat[0]";
+ print "ok $test\n"; $test++;
+
+ print "not " if "${^TEST[0]}" ne "foo";
+ print "ok $test\n"; $test++;
+
+ print "not " if "${ ^TEST [1] }" ne "bar";
+ print "ok $test\n"; $test++;
+
+ print "not " if "${^TEST}{foo}" ne "splat{foo}";
+ print "ok $test\n"; $test++;
+
+ print "not " if "${^TEST{foo}}" ne "FOO";
+ print "ok $test\n"; $test++;
+
+ print "not " if "${ ^TEST {bar} }" ne "BAR";
+ print "ok $test\n"; $test++;
+
# Now let's make sure that caret variables are all forced into the main package.
package Someother;
diff --git a/toke.c b/toke.c
index ee9c464..aff785b 100644
--- a/toke.c
+++ b/toke.c
@@ -9416,19 +9416,36 @@ S_scan_ident(pTHX_ char *s, char *dest, STRLEN destlen, I32 ck_uni)
bool skip;
char *s2;
/* If we were processing {...} notation then... */
- if (isIDFIRST_lazy_if_safe(d, e, is_utf8)) {
- /* if it starts as a valid identifier, assume that it is one.
- (the later check for } being at the expected point will trap
- cases where this doesn't pan out.) */
- d += is_utf8 ? UTF8SKIP(d) : 1;
- parse_ident(&s, &d, e, 1, is_utf8, TRUE);
- *d = '\0';
+ if (isIDFIRST_lazy_if_safe(d, e, is_utf8)
+ || (!isPRINT(*d) /* isCNTRL(d), plus all non-ASCII */
+ && isWORDCHAR(*s))
+ ) {
+ /* note we have to check for a normal identifier first,
+ * as it handles utf8 symbols, and only after that has
+ * been ruled out can we look at the caret words */
+ if (isIDFIRST_lazy_if_safe(d, e, is_utf8) ) {
+ /* if it starts as a valid identifier, assume that it is one.
+ (the later check for } being at the expected point will trap
+ cases where this doesn't pan out.) */
+ d += is_utf8 ? UTF8SKIP(d) : 1;
+ parse_ident(&s, &d, e, 1, is_utf8, TRUE);
+ *d = '\0';
+ }
+ else { /* caret word: ${^Foo} ${^CAPTURE[0]} */
+ d++;
+ while (isWORDCHAR(*s) && d < e) {
+ *d++ = *s++;
+ }
+ if (d >= e)
+ Perl_croak(aTHX_ "%s", ident_too_long);
+ *d = '\0';
+ }
tmp_copline = CopLINE(PL_curcop);
if (s < PL_bufend && isSPACE(*s)) {
s = skipspace(s);
}
if ((*s == '[' || (*s == '{' && strNE(dest, "sub")))) {
- /* ${foo[0]} and ${foo{bar}} notation. */
+ /* ${foo[0]} and ${foo{bar}} and ${^CAPTURE[0]} notation. */
if (ckWARN(WARN_AMBIGUOUS) && keyword(dest, d - dest, 0)) {
const char * const brack =
(const char *)
@@ -9447,19 +9464,6 @@ S_scan_ident(pTHX_ char *s, char *dest, STRLEN destlen, I32 ck_uni)
return s;
}
}
- /* Handle extended ${^Foo} variables
- * 1999-02-27 mjd-perl-patch@plover.com */
- else if (! isPRINT(*d) /* isCNTRL(d), plus all non-ASCII */
- && isWORDCHAR(*s))
- {
- d++;
- while (isWORDCHAR(*s) && d < e) {
- *d++ = *s++;
- }
- if (d >= e)
- Perl_croak(aTHX_ "%s", ident_too_long);
- *d = '\0';
- }
if ( !tmp_copline )
tmp_copline = CopLINE(PL_curcop);
--
2.14.3

View File

@ -1,45 +0,0 @@
From edea384e57453b0a62de58445eed1fded18c1cca Mon Sep 17 00:00:00 2001
From: Yves Orton <demerphq@gmail.com>
Date: Thu, 29 Jun 2017 13:20:49 +0200
Subject: [PATCH] add an additional test for whitespace tolerance in caret
word-vars
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Petr Písař: Ported to 5.26.2-RC1.
Signed-off-by: Petr Písař <ppisar@redhat.com>
---
t/base/lex.t | 7 +++++--
1 file changed, 5 insertions(+), 2 deletions(-)
diff --git a/t/base/lex.t b/t/base/lex.t
index ae17bbd..414aa1f 100644
--- a/t/base/lex.t
+++ b/t/base/lex.t
@@ -1,6 +1,6 @@
#!./perl
-print "1..119\n";
+print "1..120\n";
$x = 'x';
@@ -158,9 +158,12 @@ my $test = 31;
${^TEST}= "splat";
@{^TEST}= ("foo", "bar");
%{^TEST}= ("foo" => "FOO", "bar" => "BAR" );
-
+
print "not " if "${^TEST}" ne "splat";
print "ok $test\n"; $test++;
+
+ print "not " if "${ ^TEST }" ne "splat";
+ print "ok $test\n"; $test++;
print "not " if "${^TEST}[0]" ne "splat[0]";
print "ok $test\n"; $test++;
--
2.14.3

View File

@ -1,35 +0,0 @@
From 7714b11d11da2bfd0dc11638e9dd6836b6a32e90 Mon Sep 17 00:00:00 2001
From: Karl Williamson <khw@cpan.org>
Date: Mon, 11 Jun 2018 13:26:24 -0600
Subject: [PATCH] perl.h: Add parens around macro arguments
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Arguments used within macros need to be parenthesized in case they are
called with an expression. This commit changes
_CHECK_AND_OUTPUT_WIDE_LOCALE_UTF8_MSG() to do that.
Petr Písař: Ported to 5.26.2 from upstream ff58ca57f844 commit.
Signed-off-by: Petr Písař <ppisar@redhat.com>
---
perl.h | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/perl.h b/perl.h
index 1c613bc..d278c2a 100644
--- a/perl.h
+++ b/perl.h
@@ -5980,7 +5980,7 @@ typedef struct am_table_short AMTS;
# define _CHECK_AND_OUTPUT_WIDE_LOCALE_UTF8_MSG(s, send) \
STMT_START { /* Check if to warn before doing the conversion work */\
if (! PL_in_utf8_CTYPE_locale && ckWARN(WARN_LOCALE)) { \
- UV cp = utf8_to_uvchr_buf((U8 *) s, (U8 *) send, NULL); \
+ UV cp = utf8_to_uvchr_buf((U8 *) (s), (U8 *) (send), NULL); \
Perl_warner(aTHX_ packWARN(WARN_LOCALE), \
"Wide character (U+%" UVXf ") in %s", \
(cp == 0) \
--
2.14.4

View File

@ -1,34 +0,0 @@
From 208dea486fa24081cbc0cf05fa5a15c802e2bc68 Mon Sep 17 00:00:00 2001
From: John Lightsey <jd@cpanel.net>
Date: Wed, 20 Nov 2019 20:02:45 -0600
Subject: [PATCH v528 1/3] regcomp.c: Prevent integer overflow from nested
regex quantifiers.
(CVE-2020-10543) On 32bit systems the size calculations for nested regular
expression quantifiers could overflow causing heap memory corruption.
Fixes: Perl/perl5-security#125
---
regcomp.c | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/regcomp.c b/regcomp.c
index e1da15a77c..dd18add1db 100644
--- a/regcomp.c
+++ b/regcomp.c
@@ -5102,6 +5139,12 @@ S_study_chunk(pTHX_ RExC_state_t *pRExC_state, regnode **scanp,
(void)ReREFCNT_inc(RExC_rx_sv);
}
+ if ( ( minnext > 0 && mincount >= SSize_t_MAX / minnext )
+ || min >= SSize_t_MAX - minnext * mincount )
+ {
+ FAIL("Regexp out of space");
+ }
+
min += minnext * mincount;
is_inf_internal |= deltanext == SSize_t_MAX
|| (maxcount == REG_INFTY && minnext + deltanext > 0);
--
2.20.1

View File

@ -1,148 +0,0 @@
From a3a7598c8ec6efb0eb9c0b786d80c4d2a3751b70 Mon Sep 17 00:00:00 2001
From: Hugo van der Sanden <hv@crypt.org>
Date: Tue, 18 Feb 2020 13:51:16 +0000
Subject: [PATCH v528 2/3] study_chunk: extract rck_elide_nothing
(CVE-2020-10878)
---
embed.fnc | 1 +
embed.h | 1 +
proto.h | 3 +++
regcomp.c | 70 ++++++++++++++++++++++++++++++++++---------------------
4 files changed, 48 insertions(+), 27 deletions(-)
diff --git a/embed.fnc b/embed.fnc
index e762fe1eec..cf89277163 100644
--- a/embed.fnc
+++ b/embed.fnc
@@ -2398,6 +2398,7 @@ Es |SSize_t|study_chunk |NN RExC_state_t *pRExC_state \
|I32 stopparen|U32 recursed_depth \
|NULLOK regnode_ssc *and_withp \
|U32 flags|U32 depth|bool was_mutate_ok
+Es |void |rck_elide_nothing|NN regnode *node
EsRn |U32 |add_data |NN RExC_state_t* const pRExC_state \
|NN const char* const s|const U32 n
rs |void |re_croak2 |bool utf8|NN const char* pat1|NN const char* pat2|...
diff --git a/embed.h b/embed.h
index a5416a1148..886551ce5c 100644
--- a/embed.h
+++ b/embed.h
@@ -1046,6 +1046,7 @@
#define output_or_return_posix_warnings(a,b,c) S_output_or_return_posix_warnings(aTHX_ a,b,c)
#define parse_lparen_question_flags(a) S_parse_lparen_question_flags(aTHX_ a)
#define populate_ANYOF_from_invlist(a,b) S_populate_ANYOF_from_invlist(aTHX_ a,b)
+#define rck_elide_nothing(a) S_rck_elide_nothing(aTHX_ a)
#define reg(a,b,c,d) S_reg(aTHX_ a,b,c,d)
#define reg2Lanode(a,b,c,d) S_reg2Lanode(aTHX_ a,b,c,d)
#define reg_node(a,b) S_reg_node(aTHX_ a,b)
diff --git a/proto.h b/proto.h
index 66bb29b132..d3f8802c1d 100644
--- a/proto.h
+++ b/proto.h
@@ -5150,6 +5150,9 @@ STATIC void S_parse_lparen_question_flags(pTHX_ RExC_state_t *pRExC_state);
STATIC void S_populate_ANYOF_from_invlist(pTHX_ regnode *node, SV** invlist_ptr);
#define PERL_ARGS_ASSERT_POPULATE_ANYOF_FROM_INVLIST \
assert(node); assert(invlist_ptr)
+STATIC void S_rck_elide_nothing(pTHX_ regnode *node);
+#define PERL_ARGS_ASSERT_RCK_ELIDE_NOTHING \
+ assert(node)
PERL_STATIC_NO_RET void S_re_croak2(pTHX_ bool utf8, const char* pat1, const char* pat2, ...)
__attribute__noreturn__;
#define PERL_ARGS_ASSERT_RE_CROAK2 \
diff --git a/regcomp.c b/regcomp.c
index dd18add1db..0a9c6a8085 100644
--- a/regcomp.c
+++ b/regcomp.c
@@ -4094,6 +4094,43 @@ S_unwind_scan_frames(pTHX_ const void *p)
} while (f);
}
+/* Follow the next-chain of the current node and optimize away
+ all the NOTHINGs from it.
+ */
+STATIC void
+S_rck_elide_nothing(pTHX_ regnode *node)
+{
+ dVAR;
+
+ PERL_ARGS_ASSERT_RCK_ELIDE_NOTHING;
+
+ if (OP(node) != CURLYX) {
+ const int max = (reg_off_by_arg[OP(node)]
+ ? I32_MAX
+ /* I32 may be smaller than U16 on CRAYs! */
+ : (I32_MAX < U16_MAX ? I32_MAX : U16_MAX));
+ int off = (reg_off_by_arg[OP(node)] ? ARG(node) : NEXT_OFF(node));
+ int noff;
+ regnode *n = node;
+
+ /* Skip NOTHING and LONGJMP. */
+ while (
+ (n = regnext(n))
+ && (
+ (PL_regkind[OP(n)] == NOTHING && (noff = NEXT_OFF(n)))
+ || ((OP(n) == LONGJMP) && (noff = ARG(n)))
+ )
+ && off + noff < max
+ ) {
+ off += noff;
+ }
+ if (reg_off_by_arg[OP(node)])
+ ARG(node) = off;
+ else
+ NEXT_OFF(node) = off;
+ }
+ return;
+}
STATIC SSize_t
S_study_chunk(pTHX_ RExC_state_t *pRExC_state, regnode **scanp,
@@ -4197,28 +4234,10 @@ S_study_chunk(pTHX_ RExC_state_t *pRExC_state, regnode **scanp,
if (mutate_ok)
JOIN_EXACT(scan,&min_subtract, &unfolded_multi_char, 0);
- /* Follow the next-chain of the current node and optimize
- away all the NOTHINGs from it. */
- if (OP(scan) != CURLYX) {
- const int max = (reg_off_by_arg[OP(scan)]
- ? I32_MAX
- /* I32 may be smaller than U16 on CRAYs! */
- : (I32_MAX < U16_MAX ? I32_MAX : U16_MAX));
- int off = (reg_off_by_arg[OP(scan)] ? ARG(scan) : NEXT_OFF(scan));
- int noff;
- regnode *n = scan;
-
- /* Skip NOTHING and LONGJMP. */
- while ((n = regnext(n))
- && ((PL_regkind[OP(n)] == NOTHING && (noff = NEXT_OFF(n)))
- || ((OP(n) == LONGJMP) && (noff = ARG(n))))
- && off + noff < max)
- off += noff;
- if (reg_off_by_arg[OP(scan)])
- ARG(scan) = off;
- else
- NEXT_OFF(scan) = off;
- }
+ /* Follow the next-chain of the current node and optimize
+ away all the NOTHINGs from it.
+ */
+ rck_elide_nothing(scan);
/* The principal pseudo-switch. Cannot be a switch, since we
look into several different things. */
@@ -5348,11 +5367,7 @@ Perl_re_printf( aTHX_ "LHS=%" UVuf " RHS=%" UVuf "\n",
if (data && (fl & SF_HAS_EVAL))
data->flags |= SF_HAS_EVAL;
optimize_curly_tail:
- if (OP(oscan) != CURLYX) {
- while (PL_regkind[OP(next = regnext(oscan))] == NOTHING
- && NEXT_OFF(next))
- NEXT_OFF(oscan) += NEXT_OFF(next);
- }
+ rck_elide_nothing(oscan);
continue;
default:
--
2.20.1

View File

@ -1,279 +0,0 @@
From c031e3ec7c713077659f5f7dc6638d926c69d7b2 Mon Sep 17 00:00:00 2001
From: Hugo van der Sanden <hv@crypt.org>
Date: Sat, 11 Apr 2020 14:10:24 +0100
Subject: [PATCH v528 3/3] study_chunk: avoid mutating regexp program within
GOSUB
gh16947 and gh17743: studying GOSUB may restudy in an inner call
(via a mix of recursion and enframing) something that an outer call
is in the middle of looking at. Let the outer frame deal with it.
(CVE-2020-12723)
---
embed.fnc | 2 +-
embed.h | 2 +-
proto.h | 2 +-
regcomp.c | 48 ++++++++++++++++++++++++++++++++----------------
t/re/pat.t | 26 +++++++++++++++++++++++++-
5 files changed, 60 insertions(+), 20 deletions(-)
diff --git a/embed.fnc b/embed.fnc
index cf89277163..4b1ba28277 100644
--- a/embed.fnc
+++ b/embed.fnc
@@ -2397,7 +2397,7 @@ Es |SSize_t|study_chunk |NN RExC_state_t *pRExC_state \
|NULLOK struct scan_data_t *data \
|I32 stopparen|U32 recursed_depth \
|NULLOK regnode_ssc *and_withp \
- |U32 flags|U32 depth
+ |U32 flags|U32 depth|bool was_mutate_ok
EsRn |U32 |add_data |NN RExC_state_t* const pRExC_state \
|NN const char* const s|const U32 n
rs |void |re_croak2 |bool utf8|NN const char* pat1|NN const char* pat2|...
diff --git a/embed.h b/embed.h
index 886551ce5c..50fcabc140 100644
--- a/embed.h
+++ b/embed.h
@@ -1075,7 +1075,7 @@
#define ssc_is_cp_posixl_init S_ssc_is_cp_posixl_init
#define ssc_or(a,b,c) S_ssc_or(aTHX_ a,b,c)
#define ssc_union(a,b,c) S_ssc_union(aTHX_ a,b,c)
-#define study_chunk(a,b,c,d,e,f,g,h,i,j,k) S_study_chunk(aTHX_ a,b,c,d,e,f,g,h,i,j,k)
+#define study_chunk(a,b,c,d,e,f,g,h,i,j,k,l) S_study_chunk(aTHX_ a,b,c,d,e,f,g,h,i,j,k,l)
# endif
# if defined(PERL_IN_REGCOMP_C) || defined (PERL_IN_DUMP_C)
#define _invlist_dump(a,b,c,d) Perl__invlist_dump(aTHX_ a,b,c,d)
diff --git a/proto.h b/proto.h
index d3f8802c1d..e276f69bd1 100644
--- a/proto.h
+++ b/proto.h
@@ -5258,7 +5258,7 @@ PERL_STATIC_INLINE void S_ssc_union(pTHX_ regnode_ssc *ssc, SV* const invlist, c
#define PERL_ARGS_ASSERT_SSC_UNION \
assert(ssc); assert(invlist)
#endif
-STATIC SSize_t S_study_chunk(pTHX_ RExC_state_t *pRExC_state, regnode **scanp, SSize_t *minlenp, SSize_t *deltap, regnode *last, struct scan_data_t *data, I32 stopparen, U32 recursed_depth, regnode_ssc *and_withp, U32 flags, U32 depth);
+STATIC SSize_t S_study_chunk(pTHX_ RExC_state_t *pRExC_state, regnode **scanp, SSize_t *minlenp, SSize_t *deltap, regnode *last, struct scan_data_t *data, I32 stopparen, U32 recursed_depth, regnode_ssc *and_withp, U32 flags, U32 depth, bool was_mutate_ok);
#define PERL_ARGS_ASSERT_STUDY_CHUNK \
assert(pRExC_state); assert(scanp); assert(minlenp); assert(deltap); assert(last)
#endif
diff --git a/regcomp.c b/regcomp.c
index 0a9c6a8085..e66032a16a 100644
--- a/regcomp.c
+++ b/regcomp.c
@@ -110,6 +110,7 @@ typedef struct scan_frame {
regnode *next_regnode; /* next node to process when last is reached */
U32 prev_recursed_depth;
I32 stopparen; /* what stopparen do we use */
+ bool in_gosub; /* this or an outer frame is for GOSUB */
U32 is_top_frame; /* what flags do we use? */
struct scan_frame *this_prev_frame; /* this previous frame */
@@ -4102,7 +4103,7 @@ S_study_chunk(pTHX_ RExC_state_t *pRExC_state, regnode **scanp,
I32 stopparen,
U32 recursed_depth,
regnode_ssc *and_withp,
- U32 flags, U32 depth)
+ U32 flags, U32 depth, bool was_mutate_ok)
/* scanp: Start here (read-write). */
/* deltap: Write maxlen-minlen here. */
/* last: Stop before this one. */
@@ -4179,6 +4180,10 @@ S_study_chunk(pTHX_ RExC_state_t *pRExC_state, regnode **scanp,
node length to get a real minimum (because
the folded version may be shorter) */
bool unfolded_multi_char = FALSE;
+ /* avoid mutating ops if we are anywhere within the recursed or
+ * enframed handling for a GOSUB: the outermost level will handle it.
+ */
+ bool mutate_ok = was_mutate_ok && !(frame && frame->in_gosub);
/* Peephole optimizer: */
DEBUG_STUDYDATA("Peep:", data, depth);
DEBUG_PEEP("Peep", scan, depth);
@@ -4189,7 +4194,8 @@ S_study_chunk(pTHX_ RExC_state_t *pRExC_state, regnode **scanp,
* parsing code, as each (?:..) is handled by a different invocation of
* reg() -- Yves
*/
- JOIN_EXACT(scan,&min_subtract, &unfolded_multi_char, 0);
+ if (mutate_ok)
+ JOIN_EXACT(scan,&min_subtract, &unfolded_multi_char, 0);
/* Follow the next-chain of the current node and optimize
away all the NOTHINGs from it. */
@@ -4238,7 +4244,7 @@ S_study_chunk(pTHX_ RExC_state_t *pRExC_state, regnode **scanp,
* NOTE we dont use the return here! */
(void)study_chunk(pRExC_state, &scan, &minlen,
&deltanext, next, &data_fake, stopparen,
- recursed_depth, NULL, f, depth+1);
+ recursed_depth, NULL, f, depth+1, mutate_ok);
scan = next;
} else
@@ -4305,7 +4311,8 @@ S_study_chunk(pTHX_ RExC_state_t *pRExC_state, regnode **scanp,
/* we suppose the run is continuous, last=next...*/
minnext = study_chunk(pRExC_state, &scan, minlenp,
&deltanext, next, &data_fake, stopparen,
- recursed_depth, NULL, f,depth+1);
+ recursed_depth, NULL, f, depth+1,
+ mutate_ok);
if (min1 > minnext)
min1 = minnext;
@@ -4372,9 +4379,10 @@ S_study_chunk(pTHX_ RExC_state_t *pRExC_state, regnode **scanp,
}
}
- if (PERL_ENABLE_TRIE_OPTIMISATION &&
- OP( startbranch ) == BRANCH )
- {
+ if (PERL_ENABLE_TRIE_OPTIMISATION
+ && OP(startbranch) == BRANCH
+ && mutate_ok
+ ) {
/* demq.
Assuming this was/is a branch we are dealing with: 'scan'
@@ -4825,6 +4833,9 @@ S_study_chunk(pTHX_ RExC_state_t *pRExC_state, regnode **scanp,
newframe->stopparen = stopparen;
newframe->prev_recursed_depth = recursed_depth;
newframe->this_prev_frame= frame;
+ newframe->in_gosub = (
+ (frame && frame->in_gosub) || OP(scan) == GOSUB
+ );
DEBUG_STUDYDATA("frame-new:",data,depth);
DEBUG_PEEP("fnew", scan, depth);
@@ -5043,7 +5054,7 @@ S_study_chunk(pTHX_ RExC_state_t *pRExC_state, regnode **scanp,
(mincount == 0
? (f & ~SCF_DO_SUBSTR)
: f)
- ,depth+1);
+ , depth+1, mutate_ok);
if (flags & SCF_DO_STCLASS)
data->start_class = oclass;
@@ -5105,7 +5116,9 @@ S_study_chunk(pTHX_ RExC_state_t *pRExC_state, regnode **scanp,
if ( OP(oscan) == CURLYX && data
&& data->flags & SF_IN_PAR
&& !(data->flags & SF_HAS_EVAL)
- && !deltanext && minnext == 1 ) {
+ && !deltanext && minnext == 1
+ && mutate_ok
+ ) {
/* Try to optimize to CURLYN. */
regnode *nxt = NEXTOPER(oscan) + EXTRA_STEP_2ARGS;
regnode * const nxt1 = nxt;
@@ -5151,10 +5164,10 @@ S_study_chunk(pTHX_ RExC_state_t *pRExC_state, regnode **scanp,
&& !(data->flags & SF_HAS_EVAL)
&& !deltanext /* atom is fixed width */
&& minnext != 0 /* CURLYM can't handle zero width */
-
/* Nor characters whose fold at run-time may be
* multi-character */
&& ! (RExC_seen & REG_UNFOLDED_MULTI_SEEN)
+ && mutate_ok
) {
/* XXXX How to optimize if data == 0? */
/* Optimize to a simpler form. */
@@ -5201,7 +5214,8 @@ S_study_chunk(pTHX_ RExC_state_t *pRExC_state, regnode **scanp,
#endif
/* Optimize again: */
study_chunk(pRExC_state, &nxt1, minlenp, &deltanext, nxt,
- NULL, stopparen, recursed_depth, NULL, 0,depth+1);
+ NULL, stopparen, recursed_depth, NULL, 0,
+ depth+1, mutate_ok);
}
else
oscan->flags = 0;
@@ -5592,7 +5606,8 @@ Perl_re_printf( aTHX_ "LHS=%" UVuf " RHS=%" UVuf "\n",
nscan = NEXTOPER(NEXTOPER(scan));
minnext = study_chunk(pRExC_state, &nscan, minlenp, &deltanext,
last, &data_fake, stopparen,
- recursed_depth, NULL, f, depth+1);
+ recursed_depth, NULL, f, depth+1,
+ mutate_ok);
if (scan->flags) {
if (deltanext) {
FAIL("Variable length lookbehind not implemented");
@@ -5681,7 +5696,7 @@ Perl_re_printf( aTHX_ "LHS=%" UVuf " RHS=%" UVuf "\n",
*minnextp = study_chunk(pRExC_state, &nscan, minnextp,
&deltanext, last, &data_fake,
stopparen, recursed_depth, NULL,
- f,depth+1);
+ f, depth+1, mutate_ok);
if (scan->flags) {
if (deltanext) {
FAIL("Variable length lookbehind not implemented");
@@ -5841,7 +5856,8 @@ Perl_re_printf( aTHX_ "LHS=%" UVuf " RHS=%" UVuf "\n",
branches even though they arent otherwise used. */
minnext = study_chunk(pRExC_state, &scan, minlenp,
&deltanext, (regnode *)nextbranch, &data_fake,
- stopparen, recursed_depth, NULL, f,depth+1);
+ stopparen, recursed_depth, NULL, f, depth+1,
+ mutate_ok);
}
if (nextbranch && PL_regkind[OP(nextbranch)]==BRANCH)
nextbranch= regnext((regnode*)nextbranch);
@@ -7524,7 +7540,7 @@ Perl_re_op_compile(pTHX_ SV ** const patternp, int pat_count,
&data, -1, 0, NULL,
SCF_DO_SUBSTR | SCF_WHILEM_VISITED_POS | stclass_flag
| (restudied ? SCF_TRIE_DOING_RESTUDY : 0),
- 0);
+ 0, TRUE);
CHECK_RESTUDY_GOTO_butfirst(LEAVE_with_name("study_chunk"));
@@ -7670,7 +7686,7 @@ Perl_re_op_compile(pTHX_ SV ** const patternp, int pat_count,
SCF_DO_STCLASS_AND|SCF_WHILEM_VISITED_POS|(restudied
? SCF_TRIE_DOING_RESTUDY
: 0),
- 0);
+ 0, TRUE);
CHECK_RESTUDY_GOTO_butfirst(NOOP);
diff --git a/t/re/pat.t b/t/re/pat.t
index 1d98fe77d7..1488259b02 100644
--- a/t/re/pat.t
+++ b/t/re/pat.t
@@ -23,7 +23,7 @@ BEGIN {
skip_all('no re module') unless defined &DynaLoader::boot_DynaLoader;
skip_all_without_unicode_tables();
-plan tests => 840; # Update this when adding/deleting tests.
+plan tests => 844; # Update this when adding/deleting tests.
run_tests() unless caller;
@@ -1929,6 +1929,30 @@ EOP
fresh_perl_is('"AA" =~ m/AA{1,0}/','',{},"handle OPFAIL insert properly");
}
+ # gh16947: test regexp corruption (GOSUB)
+ {
+ fresh_perl_is(q{
+ 'xy' =~ /x(?0)|x(?|y|y)/ && print 'ok'
+ }, 'ok', {}, 'gh16947: test regexp corruption (GOSUB)');
+ }
+ # gh16947: test fix doesn't break SUSPEND
+ {
+ fresh_perl_is(q{ 'sx' =~ m{ss++}i; print 'ok' },
+ 'ok', {}, "gh16947: test fix doesn't break SUSPEND");
+ }
+
+ # gh17743: more regexp corruption via GOSUB
+ {
+ fresh_perl_is(q{
+ "0" =~ /((0(?0)|000(?|0000|0000)(?0))|)/; print "ok"
+ }, 'ok', {}, 'gh17743: test regexp corruption (1)');
+
+ fresh_perl_is(q{
+ "000000000000" =~ /(0(())(0((?0)())|000(?|\x{ef}\x{bf}\x{bd}|\x{ef}\x{bf}\x{bd}))|)/;
+ print "ok"
+ }, 'ok', {}, 'gh17743: test regexp corruption (2)');
+ }
+
} # End of sub run_tests
1;
--
2.20.1

View File

@ -1,62 +0,0 @@
From 47d2c70bde8c0bdc67e85578133338fc63c33f13 Mon Sep 17 00:00:00 2001
From: Jitka Plesnikova <jplesnik@redhat.com>
Date: Thu, 17 Jun 2021 11:41:48 +0200
Subject: [PATCH 2/2] Fix _resolv return value
in case of the new warnings.
Thanks to @nlv02636
Backported fromn Net-Ping 2.68
---
dist/Net-Ping/lib/Net/Ping.pm | 8 +++++++-
1 file changed, 7 insertions(+), 1 deletion(-)
diff --git a/dist/Net-Ping/lib/Net/Ping.pm b/dist/Net-Ping/lib/Net/Ping.pm
index 9e2497c..87087fc 100644
--- a/dist/Net-Ping/lib/Net/Ping.pm
+++ b/dist/Net-Ping/lib/Net/Ping.pm
@@ -1794,6 +1794,7 @@ sub _resolv {
# Clean up port
if (defined($h{port}) && (($h{port} !~ /^\d{1,5}$/) || ($h{port} < 1) || ($h{port} > 65535))) {
croak("Invalid port `$h{port}' in `$name'");
+ return undef;
}
# END - host:port
@@ -1850,18 +1851,21 @@ sub _resolv {
} else {
(undef, $h{addr_in}, undef, undef) = Socket::unpack_sockaddr_in6 $getaddr[0]->{addr};
}
- return \%h
+ return \%h;
} else {
carp("getnameinfo($getaddr[0]->{addr}) failed - $err");
+ return undef;
}
} else {
warn(sprintf("getaddrinfo($h{host},,%s) failed - $err",
$family == AF_INET ? "AF_INET" : "AF_INET6"));
+ return undef;
}
# old way
} else {
if ($family == $AF_INET6) {
croak("Socket >= 1.94 required for IPv6 - found Socket $Socket::VERSION");
+ return undef;
}
my @gethost = gethostbyname($h{host});
@@ -1872,8 +1876,10 @@ sub _resolv {
return \%h
} else {
carp("gethostbyname($h{host}) failed - $^E");
+ return undef;
}
}
+ return undef;
}
sub _pack_sockaddr_in($$) {
--
2.31.1

View File

@ -1,99 +0,0 @@
From 5a3f94a3f0e21d8e685ede4e851a318578a2151f Mon Sep 17 00:00:00 2001
From: Jitka Plesnikova <jplesnik@redhat.com>
Date: Thu, 17 Jun 2021 11:12:30 +0200
Subject: [PATCH 1/2] carp, not croak on most name lookup failures
See RT #124830, a regression.
Return undef instead.
Backported from Net-Ping 2.67
---
dist/Net-Ping/lib/Net/Ping.pm | 24 ++++++++++++------------
1 file changed, 12 insertions(+), 12 deletions(-)
diff --git a/dist/Net-Ping/lib/Net/Ping.pm b/dist/Net-Ping/lib/Net/Ping.pm
index 13cbe81..9e2497c 100644
--- a/dist/Net-Ping/lib/Net/Ping.pm
+++ b/dist/Net-Ping/lib/Net/Ping.pm
@@ -144,7 +144,7 @@ sub new
if ($self->{'host'}) {
my $host = $self->{'host'};
my $ip = _resolv($host)
- or croak("could not resolve host $host");
+ or carp("could not resolve host $host");
$self->{host} = $ip;
$self->{family} = $ip->{family};
}
@@ -152,7 +152,7 @@ sub new
if ($self->{bind}) {
my $addr = $self->{bind};
my $ip = _resolv($addr)
- or croak("could not resolve local addr $addr");
+ or carp("could not resolve local addr $addr");
$self->{local_addr} = $ip;
} else {
$self->{local_addr} = undef; # Don't bind by default
@@ -323,7 +323,7 @@ sub bind
($self->{proto} eq "udp" || $self->{proto} eq "icmp");
$ip = $self->_resolv($local_addr);
- croak("nonexistent local address $local_addr") unless defined($ip);
+ carp("nonexistent local address $local_addr") unless defined($ip);
$self->{local_addr} = $ip;
if (($self->{proto} ne "udp") &&
@@ -1129,13 +1129,14 @@ sub open
$self->{family_local} = $self->{family};
}
- $ip = $self->_resolv($host);
$timeout = $self->{timeout} unless $timeout;
+ $ip = $self->_resolv($host);
- if($self->{proto} eq "stream") {
- if(defined($self->{fh}->fileno())) {
+ if ($self->{proto} eq "stream") {
+ if (defined($self->{fh}->fileno())) {
croak("socket is already open");
} else {
+ return () unless $ip;
$self->tcp_connect($ip, $timeout);
}
}
@@ -1851,12 +1852,11 @@ sub _resolv {
}
return \%h
} else {
- croak("getnameinfo($getaddr[0]->{addr}) failed - $err");
+ carp("getnameinfo($getaddr[0]->{addr}) failed - $err");
}
} else {
- my $error = sprintf "getaddrinfo($h{host},,%s) failed - $err",
- ($family == AF_INET) ? "AF_INET" : "AF_INET6";
- croak("$error");
+ warn(sprintf("getaddrinfo($h{host},,%s) failed - $err",
+ $family == AF_INET ? "AF_INET" : "AF_INET6"));
}
# old way
} else {
@@ -1871,7 +1871,7 @@ sub _resolv {
$h{family} = AF_INET;
return \%h
} else {
- croak("gethostbyname($h{host}) failed - $^E");
+ carp("gethostbyname($h{host}) failed - $^E");
}
}
}
@@ -1913,7 +1913,7 @@ sub _inet_ntoa {
if (defined($address)) {
$ret = $address;
} else {
- croak("getnameinfo($addr) failed - $err");
+ carp("getnameinfo($addr) failed - $err");
}
} else {
$ret = inet_ntoa($addr)
--
2.31.1

View File

@ -0,0 +1,33 @@
From 2c2da8e7f0f6325fab643997a536072633fa0cf8 Mon Sep 17 00:00:00 2001
From: Yves Orton <demerphq@gmail.com>
Date: Thu, 1 Jun 2017 14:51:44 +0200
Subject: [PATCH] Fix #131190 - UTF8 code improperly casting negative integer
to U8 in comparison
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
This reverts commit b4972372a75776de3c9e6bd234a398d103677316,
effectively restoring commit ca7eb79a236b41b7722c6800527f95cd76843eed,
and commit 85fde2b7c3f5631fd982f5db735b84dc9224bec0.
Signed-off-by: Petr Písař <ppisar@redhat.com>
---
regexec.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/regexec.c b/regexec.c
index 82128a7..35b88d7 100644
--- a/regexec.c
+++ b/regexec.c
@@ -5593,6 +5593,7 @@ S_regmatch(pTHX_ regmatch_info *reginfo, char *startpos, regnode *prog)
if (scan->flags == EXACTL || scan->flags == EXACTFLU8) {
_CHECK_AND_WARN_PROBLEMATIC_LOCALE;
if (utf8_target
+ && nextchr >= 0 /* guard against negative EOS value in nextchr */
&& UTF8_IS_ABOVE_LATIN1(nextchr)
&& scan->flags == EXACTL)
{
--
2.9.4

View File

@ -0,0 +1,135 @@
From bab0f8e933b383b6bef406d79c2da340bbcded33 Mon Sep 17 00:00:00 2001
From: Yves Orton <demerphq@gmail.com>
Date: Sun, 18 Jun 2017 20:45:30 +0200
Subject: [PATCH 1/2] Resolve Perl #131522: Spurious "Assuming NOT a POSIX
class" warning
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Signed-off-by: Petr Písař <ppisar@redhat.com>
---
regcomp.c | 30 ++++++++++++++++++------------
1 file changed, 18 insertions(+), 12 deletions(-)
diff --git a/regcomp.c b/regcomp.c
index 8921eed..0a4ea78 100644
--- a/regcomp.c
+++ b/regcomp.c
@@ -13991,6 +13991,13 @@ S_populate_ANYOF_from_invlist(pTHX_ regnode *node, SV** invlist_ptr)
REPORT_LOCATION_ARGS(p))); \
} \
} STMT_END
+#define CLEAR_POSIX_WARNINGS() \
+ if (posix_warnings && RExC_warn_text) \
+ av_clear(RExC_warn_text)
+
+#define CLEAR_POSIX_WARNINGS_AND_RETURN(ret) \
+ CLEAR_POSIX_WARNINGS(); \
+ return ret
STATIC int
S_handle_possible_posix(pTHX_ RExC_state_t *pRExC_state,
@@ -14063,7 +14070,7 @@ S_handle_possible_posix(pTHX_ RExC_state_t *pRExC_state,
*
* The syntax for a legal posix class is:
*
- * qr/(?xa: \[ : \^? [:lower:]{4,6} : \] )/
+ * qr/(?xa: \[ : \^? [[:lower:]]{4,6} : \] )/
*
* What this routine considers syntactically to be an intended posix class
* is this (the comments indicate some restrictions that the pattern
@@ -14088,7 +14095,7 @@ S_handle_possible_posix(pTHX_ RExC_state_t *pRExC_state,
* # for it to be considered to be
* # an intended posix class.
* \h*
- * [:punct:]? # The closing class character,
+ * [[:punct:]]? # The closing class character,
* # possibly omitted. If not a colon
* # nor semi colon, the class name
* # must be even closer to a valid
@@ -14131,8 +14138,7 @@ S_handle_possible_posix(pTHX_ RExC_state_t *pRExC_state,
PERL_ARGS_ASSERT_HANDLE_POSSIBLE_POSIX;
- if (posix_warnings && RExC_warn_text)
- av_clear(RExC_warn_text);
+ CLEAR_POSIX_WARNINGS();
if (p >= e) {
return NOT_MEANT_TO_BE_A_POSIX_CLASS;
@@ -14224,7 +14230,7 @@ S_handle_possible_posix(pTHX_ RExC_state_t *pRExC_state,
*updated_parse_ptr = (char *) temp_ptr;
}
- return OOB_NAMEDCLASS;
+ CLEAR_POSIX_WARNINGS_AND_RETURN(OOB_NAMEDCLASS);
}
}
@@ -14294,7 +14300,7 @@ S_handle_possible_posix(pTHX_ RExC_state_t *pRExC_state,
/* We consider something like [^:^alnum:]] to not have been intended to
* be a posix class, but XXX maybe we should */
if (complement) {
- return NOT_MEANT_TO_BE_A_POSIX_CLASS;
+ CLEAR_POSIX_WARNINGS_AND_RETURN(NOT_MEANT_TO_BE_A_POSIX_CLASS);
}
complement = 1;
@@ -14321,7 +14327,7 @@ S_handle_possible_posix(pTHX_ RExC_state_t *pRExC_state,
* this leaves this construct looking like [:] or [:^], which almost
* certainly weren't intended to be posix classes */
if (has_opening_bracket) {
- return NOT_MEANT_TO_BE_A_POSIX_CLASS;
+ CLEAR_POSIX_WARNINGS_AND_RETURN(NOT_MEANT_TO_BE_A_POSIX_CLASS);
}
/* But this function can be called when we parse the colon for
@@ -14338,7 +14344,7 @@ S_handle_possible_posix(pTHX_ RExC_state_t *pRExC_state,
/* XXX We are currently very restrictive here, so this code doesn't
* consider the possibility that, say, /[alpha.]]/ was intended to
* be a posix class. */
- return NOT_MEANT_TO_BE_A_POSIX_CLASS;
+ CLEAR_POSIX_WARNINGS_AND_RETURN(NOT_MEANT_TO_BE_A_POSIX_CLASS);
}
/* Here we have something like 'foo:]'. There was no initial colon,
@@ -14508,7 +14514,7 @@ S_handle_possible_posix(pTHX_ RExC_state_t *pRExC_state,
}
/* Otherwise, it can't have meant to have been a class */
- return NOT_MEANT_TO_BE_A_POSIX_CLASS;
+ CLEAR_POSIX_WARNINGS_AND_RETURN(NOT_MEANT_TO_BE_A_POSIX_CLASS);
}
/* If we ran off the end, and the final character was a punctuation
@@ -14558,7 +14564,7 @@ S_handle_possible_posix(pTHX_ RExC_state_t *pRExC_state,
* class name. (We can do this on the first pass, as any second pass
* will yield an even shorter name) */
if (name_len < 3) {
- return NOT_MEANT_TO_BE_A_POSIX_CLASS;
+ CLEAR_POSIX_WARNINGS_AND_RETURN(NOT_MEANT_TO_BE_A_POSIX_CLASS);
}
/* Find which class it is. Initially switch on the length of the name.
@@ -14717,7 +14723,7 @@ S_handle_possible_posix(pTHX_ RExC_state_t *pRExC_state,
}
/* Here neither pass found a close-enough class name */
- return NOT_MEANT_TO_BE_A_POSIX_CLASS;
+ CLEAR_POSIX_WARNINGS_AND_RETURN(NOT_MEANT_TO_BE_A_POSIX_CLASS);
}
probably_meant_to_be:
@@ -14759,7 +14765,7 @@ S_handle_possible_posix(pTHX_ RExC_state_t *pRExC_state,
/* If it is a known class, return the class. The class number
* #defines are structured so each complement is +1 to the normal
* one */
- return class_number + complement;
+ CLEAR_POSIX_WARNINGS_AND_RETURN(class_number + complement);
}
else if (! check_only) {
--
2.9.4

View File

@ -0,0 +1,39 @@
From d730a80128abafff1e47e2506c23a8c1a06cfef4 Mon Sep 17 00:00:00 2001
From: Yves Orton <demerphq@gmail.com>
Date: Sun, 18 Jun 2017 23:44:07 +0200
Subject: [PATCH 2/2] add test for [perl #131522] and fix test for (related)
[perl #127581]
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Signed-off-by: Petr Písař <ppisar@redhat.com>
---
t/re/reg_mesg.t | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/t/re/reg_mesg.t b/t/re/reg_mesg.t
index 090eccb..a0b78c4 100644
--- a/t/re/reg_mesg.t
+++ b/t/re/reg_mesg.t
@@ -221,7 +221,6 @@ my @death =
'/(?[[[::]]])/' => "Syntax error in (?[...]) in regex m/(?[[[::]]])/",
'/(?[[[:w:]]])/' => "Syntax error in (?[...]) in regex m/(?[[[:w:]]])/",
'/(?[[:w:]])/' => "",
- '/[][[:alpha:]]' => "", # [perl #127581]
'/([.].*)[.]/' => "", # [perl #127582]
'/[.].*[.]/' => "", # [perl #127604]
'/(?[a])/' => 'Unexpected character {#} m/(?[a{#}])/',
@@ -587,7 +586,8 @@ my @warning = (
'Assuming NOT a POSIX class since a semi-colon was found instead of a colon {#} m/[foo;{#}punct;]]\x{100}/',
'Assuming NOT a POSIX class since a semi-colon was found instead of a colon {#} m/[foo;punct;]{#}]\x{100}/',
],
-
+ '/[][[:alpha:]]/' => "", # [perl #127581]
+ '/[][[:alpha:]\\@\\\\^_?]/' => "", # [perl #131522]
); # See comments before this for why '\x{100}' is generally needed
# These need the character 'ネ' as a marker for mark_as_utf8()
--
2.9.4

View File

@ -0,0 +1,299 @@
From 99b847695211f825df6299aa9da91f9494f741e2 Mon Sep 17 00:00:00 2001
From: Tony Cook <tony@develop-help.com>
Date: Thu, 1 Jun 2017 15:11:27 +1000
Subject: [PATCH] [perl #131221] improve duplication of :via handles
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Previously duplication (as with open ... ">&...") would fail
unless the user supplied a GETARG, which wasn't documented, and
resulted in an attempt to free and unreferened scalar if supplied.
Cloning on thread creation was simply broken.
We now handle GETARG correctly, and provide a useful default if it
returns nothing.
Cloning on thread creation now duplicates the appropriate parts of the
parent thread's handle.
Signed-off-by: Petr Písař <ppisar@redhat.com>
---
MANIFEST | 1 +
ext/PerlIO-via/t/thread.t | 73 +++++++++++++++++++++++++++++++++++++++++++++++
ext/PerlIO-via/t/via.t | 56 +++++++++++++++++++++++++++++++++++-
ext/PerlIO-via/via.pm | 2 +-
ext/PerlIO-via/via.xs | 55 +++++++++++++++++++++++++++++++----
5 files changed, 179 insertions(+), 8 deletions(-)
create mode 100644 ext/PerlIO-via/t/thread.t
diff --git a/MANIFEST b/MANIFEST
index 8c4950e..d39f992 100644
--- a/MANIFEST
+++ b/MANIFEST
@@ -4056,6 +4056,7 @@ ext/PerlIO-scalar/scalar.xs PerlIO layer for scalars
ext/PerlIO-scalar/t/scalar.t See if PerlIO::scalar works
ext/PerlIO-scalar/t/scalar_ungetc.t Tests for PerlIO layer for scalars
ext/PerlIO-via/hints/aix.pl Hint for PerlIO::via for named architecture
+ext/PerlIO-via/t/thread.t See if PerlIO::via works with threads
ext/PerlIO-via/t/via.t See if PerlIO::via works
ext/PerlIO-via/via.pm PerlIO layer for layers in perl
ext/PerlIO-via/via.xs PerlIO layer for layers in perl
diff --git a/ext/PerlIO-via/t/thread.t b/ext/PerlIO-via/t/thread.t
new file mode 100644
index 0000000..e4358f9
--- /dev/null
+++ b/ext/PerlIO-via/t/thread.t
@@ -0,0 +1,73 @@
+#!perl
+BEGIN {
+ unless (find PerlIO::Layer 'perlio') {
+ print "1..0 # Skip: not perlio\n";
+ exit 0;
+ }
+ require Config;
+ unless ($Config::Config{'usethreads'}) {
+ print "1..0 # Skip -- need threads for this test\n";
+ exit 0;
+ }
+ if (($Config::Config{'extensions'} !~ m!\bPerlIO/via\b!) ){
+ print "1..0 # Skip -- Perl configured without PerlIO::via module\n";
+ exit 0;
+ }
+}
+
+use strict;
+use warnings;
+use threads;
+
+my $tmp = "via$$";
+
+END {
+ 1 while unlink $tmp;
+}
+
+use Test::More tests => 2;
+
+our $push_count = 0;
+
+{
+ open my $fh, ">:via(Test1)", $tmp
+ or die "Cannot open $tmp: $!";
+ $fh->autoflush;
+
+ print $fh "AXAX";
+
+ # previously this would crash
+ threads->create(
+ sub {
+ print $fh "XZXZ";
+ })->join;
+
+ print $fh "BXBX";
+ close $fh;
+
+ open my $in, "<", $tmp;
+ my $line = <$in>;
+ close $in;
+
+ is($line, "AYAYYZYZBYBY", "check thread data delivered");
+
+ is($push_count, 1, "PUSHED not called for dup on thread creation");
+}
+
+package PerlIO::via::Test1;
+
+sub PUSHED {
+ my ($class) = @_;
+ ++$main::push_count;
+ bless {}, $class;
+}
+
+sub WRITE {
+ my ($self, $data, $fh) = @_;
+ $data =~ tr/X/Y/;
+ $fh->autoflush;
+ print $fh $data;
+ return length $data;
+}
+
+
diff --git a/ext/PerlIO-via/t/via.t b/ext/PerlIO-via/t/via.t
index 6787e11..80577df 100644
--- a/ext/PerlIO-via/t/via.t
+++ b/ext/PerlIO-via/t/via.t
@@ -17,7 +17,7 @@ use warnings;
my $tmp = "via$$";
-use Test::More tests => 18;
+use Test::More tests => 26;
my $fh;
my $a = join("", map { chr } 0..255) x 10;
@@ -84,6 +84,60 @@ is( $obj, 'Foo', 'search for package Foo' );
open $fh, '<:via(Bar)', "bar";
is( $obj, 'PerlIO::via::Bar', 'search for package PerlIO::via::Bar' );
+{
+ # [perl #131221]
+ ok(open(my $fh1, ">", $tmp), "open $tmp");
+ ok(binmode($fh1, ":via(XXX)"), "binmode :via(XXX) onto it");
+ ok(open(my $fh2, ">&", $fh1), "dup it");
+ close $fh1;
+ close $fh2;
+
+ # make sure the old workaround still works
+ ok(open($fh1, ">", $tmp), "open $tmp");
+ ok(binmode($fh1, ":via(YYY)"), "binmode :via(YYY) onto it");
+ ok(open($fh2, ">&", $fh1), "dup it");
+ print $fh2 "XZXZ";
+ close $fh1;
+ close $fh2;
+
+ ok(open($fh1, "<", $tmp), "open $tmp for check");
+ { local $/; $b = <$fh1> }
+ close $fh1;
+ is($b, "XZXZ", "check result is from non-filtering class");
+
+ package PerlIO::via::XXX;
+
+ sub PUSHED {
+ my $class = shift;
+ bless {}, $class;
+ }
+
+ sub WRITE {
+ my ($self, $buffer, $handle) = @_;
+
+ print $handle $buffer;
+ return length($buffer);
+ }
+ package PerlIO::via::YYY;
+
+ sub PUSHED {
+ my $class = shift;
+ bless {}, $class;
+ }
+
+ sub WRITE {
+ my ($self, $buffer, $handle) = @_;
+
+ $buffer =~ tr/X/Y/;
+ print $handle $buffer;
+ return length($buffer);
+ }
+
+ sub GETARG {
+ "XXX";
+ }
+}
+
END {
1 while unlink $tmp;
}
diff --git a/ext/PerlIO-via/via.pm b/ext/PerlIO-via/via.pm
index e477dcc..30083fe 100644
--- a/ext/PerlIO-via/via.pm
+++ b/ext/PerlIO-via/via.pm
@@ -1,5 +1,5 @@
package PerlIO::via;
-our $VERSION = '0.16';
+our $VERSION = '0.17';
require XSLoader;
XSLoader::load();
1;
diff --git a/ext/PerlIO-via/via.xs b/ext/PerlIO-via/via.xs
index 8a7f1fc..61953c8 100644
--- a/ext/PerlIO-via/via.xs
+++ b/ext/PerlIO-via/via.xs
@@ -38,6 +38,8 @@ typedef struct
CV *UTF8;
} PerlIOVia;
+static const MGVTBL PerlIOVia_tag = { 0, 0, 0, 0, 0, 0, 0, 0 };
+
#define MYMethod(x) #x,&s->x
static CV *
@@ -131,8 +133,14 @@ PerlIOVia_pushed(pTHX_ PerlIO * f, const char *mode, SV * arg,
PerlIO_funcs * tab)
{
IV code = PerlIOBase_pushed(aTHX_ f, mode, Nullsv, tab);
+
+ if (SvTYPE(arg) >= SVt_PVMG
+ && mg_findext(arg, PERL_MAGIC_ext, &PerlIOVia_tag)) {
+ return code;
+ }
+
if (code == 0) {
- PerlIOVia *s = PerlIOSelf(f, PerlIOVia);
+ PerlIOVia *s = PerlIOSelf(f, PerlIOVia);
if (!arg) {
if (ckWARN(WARN_LAYER))
Perl_warner(aTHX_ packWARN(WARN_LAYER),
@@ -583,20 +591,55 @@ static SV *
PerlIOVia_getarg(pTHX_ PerlIO * f, CLONE_PARAMS * param, int flags)
{
PerlIOVia *s = PerlIOSelf(f, PerlIOVia);
- PERL_UNUSED_ARG(param);
+ SV *arg;
PERL_UNUSED_ARG(flags);
- return PerlIOVia_method(aTHX_ f, MYMethod(GETARG), G_SCALAR, Nullsv);
+
+ /* During cloning, return an undef token object so that _pushed() knows
+ * that it should not call methods and wait for _dup() to actually dup the
+ * object. */
+ if (param) {
+ SV *sv = newSV(0);
+ sv_magicext(sv, NULL, PERL_MAGIC_ext, &PerlIOVia_tag, 0, 0);
+ return sv;
+ }
+
+ arg = PerlIOVia_method(aTHX_ f, MYMethod(GETARG), G_SCALAR, Nullsv);
+ if (arg) {
+ /* arg is a temp, and PerlIOBase_dup() will explicitly free it */
+ SvREFCNT_inc(arg);
+ }
+ else {
+ arg = newSVpvn(HvNAME(s->stash), HvNAMELEN(s->stash));
+ }
+
+ return arg;
}
static PerlIO *
PerlIOVia_dup(pTHX_ PerlIO * f, PerlIO * o, CLONE_PARAMS * param,
int flags)
{
- if ((f = PerlIOBase_dup(aTHX_ f, o, param, flags))) {
- /* Most of the fields will lazily set themselves up as needed
- stash and obj have been set up by the implied push
+ if ((f = PerlIOBase_dup(aTHX_ f, o, param, flags)) && param) {
+ /* For a non-interpreter dup stash and obj have been set up
+ by the implied push.
+
+ But if this is a clone for a new interpreter we need to
+ translate the objects to their dups.
*/
+
+ PerlIOVia *fs = PerlIOSelf(f, PerlIOVia);
+ PerlIOVia *os = PerlIOSelf(o, PerlIOVia);
+
+ fs->obj = sv_dup_inc(os->obj, param);
+ fs->stash = (HV*)sv_dup((SV*)os->stash, param);
+ fs->var = sv_dup_inc(os->var, param);
+ fs->cnt = os->cnt;
+
+ /* fh, io, cached CVs left as NULL, PerlIOVia_method()
+ will reinitialize them if needed */
}
+ /* for a non-threaded dup fs->obj and stash should be set by _pushed() */
+
return f;
}
--
2.9.4

View File

@ -0,0 +1,71 @@
From 7b3443d31f11c15859593e5b710c301795a6de01 Mon Sep 17 00:00:00 2001
From: Tony Cook <tony@develop-help.com>
Date: Thu, 8 Jun 2017 11:06:39 +1000
Subject: [PATCH] [perl #131221] sv_dup/sv_dup_inc are only available under
threads
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Signed-off-by: Petr Písař <ppisar@redhat.com>
---
ext/PerlIO-via/via.xs | 42 +++++++++++++++++++++++-------------------
1 file changed, 23 insertions(+), 19 deletions(-)
diff --git a/ext/PerlIO-via/via.xs b/ext/PerlIO-via/via.xs
index 61953c8..d91c685 100644
--- a/ext/PerlIO-via/via.xs
+++ b/ext/PerlIO-via/via.xs
@@ -619,26 +619,30 @@ static PerlIO *
PerlIOVia_dup(pTHX_ PerlIO * f, PerlIO * o, CLONE_PARAMS * param,
int flags)
{
- if ((f = PerlIOBase_dup(aTHX_ f, o, param, flags)) && param) {
- /* For a non-interpreter dup stash and obj have been set up
- by the implied push.
-
- But if this is a clone for a new interpreter we need to
- translate the objects to their dups.
- */
-
- PerlIOVia *fs = PerlIOSelf(f, PerlIOVia);
- PerlIOVia *os = PerlIOSelf(o, PerlIOVia);
-
- fs->obj = sv_dup_inc(os->obj, param);
- fs->stash = (HV*)sv_dup((SV*)os->stash, param);
- fs->var = sv_dup_inc(os->var, param);
- fs->cnt = os->cnt;
-
- /* fh, io, cached CVs left as NULL, PerlIOVia_method()
- will reinitialize them if needed */
+ if ((f = PerlIOBase_dup(aTHX_ f, o, param, flags))) {
+#ifdef USE_ITHREADS
+ if (param) {
+ /* For a non-interpreter dup stash and obj have been set up
+ by the implied push.
+
+ But if this is a clone for a new interpreter we need to
+ translate the objects to their dups.
+ */
+
+ PerlIOVia *fs = PerlIOSelf(f, PerlIOVia);
+ PerlIOVia *os = PerlIOSelf(o, PerlIOVia);
+
+ fs->obj = sv_dup_inc(os->obj, param);
+ fs->stash = (HV*)sv_dup((SV*)os->stash, param);
+ fs->var = sv_dup_inc(os->var, param);
+ fs->cnt = os->cnt;
+
+ /* fh, io, cached CVs left as NULL, PerlIOVia_method()
+ will reinitialize them if needed */
+ }
+#endif
+ /* for a non-threaded dup fs->obj and stash should be set by _pushed() */
}
- /* for a non-threaded dup fs->obj and stash should be set by _pushed() */
return f;
}
--
2.9.4

View File

@ -0,0 +1,37 @@
From 9604fbf0722bd97ca6031a263c50ad52b6633db7 Mon Sep 17 00:00:00 2001
From: Tony Cook <tony@develop-help.com>
Date: Wed, 14 Jun 2017 09:42:31 +1000
Subject: [PATCH] (perl #131526) don't go beyond the end of the NUL in my_atof2
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Perl_my_atof2() calls GROK_NUMERIC_RADIX() to detect and skip past
a decimal point and then can increment the parse pointer (s) before
checking what it points at, so skipping the terminating NUL if the
decimal point is immediately before the NUL.
Signed-off-by: Petr Písař <ppisar@redhat.com>
---
numeric.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/numeric.c b/numeric.c
index 6ea6968..5771907 100644
--- a/numeric.c
+++ b/numeric.c
@@ -1485,9 +1485,9 @@ Perl_my_atof2(pTHX_ const char* orig, NV* value)
else if (!seen_dp && GROK_NUMERIC_RADIX(&s, send)) {
seen_dp = 1;
if (sig_digits > MAX_SIG_DIGITS) {
- do {
+ while (isDIGIT(*s)) {
++s;
- } while (isDIGIT(*s));
+ }
break;
}
}
--
2.9.4

View File

@ -1,45 +0,0 @@
From b4d257e2d408f0f1c6686dcdc112f3ebfec68f44 Mon Sep 17 00:00:00 2001
From: Yves Orton <demerphq@gmail.com>
Date: Tue, 27 Jun 2017 10:22:23 +0200
Subject: [PATCH] File::Glob - tweak rt131211.t to be less sensitive on wonky
boxes
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
make the test less senstive and avoid divide by zero errors,
also we skip the test if either elapsed_match or elapsed_fail is
true, as we can not rely on the timings then. For the operations
we are doing we should get a non-zero timing from Time::HiRes.
This should mean that running this test on boxes with heavy
load, etc, will no longer result in false positives.
Signed-off-by: Petr Písař <ppisar@redhat.com>
---
ext/File-Glob/t/rt131211.t | 9 +++++++--
1 file changed, 7 insertions(+), 2 deletions(-)
diff --git a/ext/File-Glob/t/rt131211.t b/ext/File-Glob/t/rt131211.t
index c1bcbe0..b29cd04 100644
--- a/ext/File-Glob/t/rt131211.t
+++ b/ext/File-Glob/t/rt131211.t
@@ -49,8 +49,13 @@ while (++$count < 10) {
is $count,10,
"tried all the patterns without bailing out";
-cmp_ok $elapsed_fail/$elapsed_match,"<",2,
- "time to fail less than twice the time to match";
+SKIP: {
+ skip "unstable timing", 1 unless $elapsed_match && $elapsed_fail;
+ ok $elapsed_fail <= 10 * $elapsed_match,
+ "time to fail less than 10x the time to match"
+ or diag("elapsed_match=$elapsed_match elapsed_fail=$elapsed_fail");
+}
+
is "@got_files", catfile($path, $files[0]),
"only got the expected file for xa*..b";
is "@no_files", "", "shouldnt have files for xa*..c";
--
2.9.4

View File

@ -1,226 +0,0 @@
From 5aca16e032861ea3dfcc96ad417ea87e2b1552e5 Mon Sep 17 00:00:00 2001
From: Aaron Crane <arc@cpan.org>
Date: Sat, 4 Mar 2017 12:50:58 +0000
Subject: [PATCH] RT #130907: Fix the Unicode Bug in split " "
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Ported to 5.26.0:
commit 20ae58f7a9bbf84d043d6e90f5988b6e3ca4ee3d
Author: Aaron Crane <arc@cpan.org>
Date: Sat Mar 4 12:50:58 2017 +0000
RT #130907: Fix the Unicode Bug in split " "
Signed-off-by: Petr Písař <ppisar@redhat.com>
---
lib/feature.pm | 5 +++--
pod/perldelta.pod | 9 +++++++++
pod/perlfunc.pod | 8 ++++++++
pod/perlunicode.pod | 11 +++++++++++
pod/perluniintro.pod | 5 +++--
pp.c | 13 +++++++++++++
regen/feature.pl | 5 +++--
t/op/split.t | 20 +++++++++++++++++++-
8 files changed, 69 insertions(+), 7 deletions(-)
diff --git a/lib/feature.pm b/lib/feature.pm
index ed13273..93e020b 100644
--- a/lib/feature.pm
+++ b/lib/feature.pm
@@ -175,8 +175,9 @@ C<use feature 'unicode_strings'> subpragma is B<strongly> recommended.
This feature is available starting with Perl 5.12; was almost fully
implemented in Perl 5.14; and extended in Perl 5.16 to cover C<quotemeta>;
-and extended further in Perl 5.26 to cover L<the range
-operator|perlop/Range Operators>.
+was extended further in Perl 5.26 to cover L<the range
+operator|perlop/Range Operators>; and was extended again in Perl 5.28 to
+cover L<special-cased whitespace splitting|perlfunc/split>.
=head2 The 'unicode_eval' and 'evalbytes' features
#diff --git a/pod/perldelta.pod b/pod/perldelta.pod
#index 06dcd1d..d31335f 100644
#--- a/pod/perldelta.pod
#+++ b/pod/perldelta.pod
#@@ -3206,6 +3206,15 @@ calls.
# Parsing bad POSIX charclasses no longer leaks memory.
# L<[perl #128313]|https://rt.perl.org/Public/Bug/Display.html?id=128313>
#
#+=item *
#+
#+C<split ' '> now correctly handles the argument being split when in the
#+scope of the L<< C<unicode_strings>|feature/"The 'unicode_strings' feature"
#+>> feature. Previously, when a string using the single-byte internal
#+representation contained characters that are whitespace by Unicode rules but
#+not by ASCII rules, it treated those characters as part of fields rather
#+than as field separators. [perl #130907]
#+
# =back
#
# =head1 Known Problems
diff --git a/pod/perlfunc.pod b/pod/perlfunc.pod
index b8dca6e..9abadf4 100644
--- a/pod/perlfunc.pod
+++ b/pod/perlfunc.pod
@@ -7616,6 +7616,14 @@ special case was restricted to the use of a plain S<C<" ">> as the
pattern argument to split; in Perl 5.18.0 and later this special case is
triggered by any expression which evaluates to the simple string S<C<" ">>.
+As of Perl 5.28, this special-cased whitespace splitting works as expected in
+the scope of L<< S<C<"use feature 'unicode_strings">>|feature/The
+'unicode_strings' feature >>. In previous versions, and outside the scope of
+that feature, it exhibits L<perlunicode/The "Unicode Bug">: characters that are
+whitespace according to Unicode rules but not according to ASCII rules can be
+treated as part of fields rather than as field separators, depending on the
+string's internal encoding.
+
If omitted, PATTERN defaults to a single space, S<C<" ">>, triggering
the previously described I<awk> emulation.
diff --git a/pod/perlunicode.pod b/pod/perlunicode.pod
index 9c13c35..2e84e95 100644
--- a/pod/perlunicode.pod
+++ b/pod/perlunicode.pod
@@ -1835,6 +1835,17 @@ outside its scope, it could produce strings whose length in characters
exceeded that of the right-hand side, where the right-hand side took up more
bytes than the correct range endpoint.
+=item *
+
+In L<< C<split>'s special-case whitespace splitting|perlfunc/split >>.
+
+Starting in Perl 5.28.0, the C<split> function with a pattern specified as
+a string containing a single space handles whitespace characters consistently
+within the scope of of C<unicode_strings>. Prior to that, or outside its scope,
+characters that are whitespace according to Unicode rules but not according to
+ASCII rules were treated as field contents rather than field separators when
+they appear in byte-encoded strings.
+
=back
You can see from the above that the effect of C<unicode_strings>
diff --git a/pod/perluniintro.pod b/pod/perluniintro.pod
index d35de34..595ec46 100644
--- a/pod/perluniintro.pod
+++ b/pod/perluniintro.pod
@@ -151,11 +151,12 @@ serious Unicode work. The maintenance release 5.6.1 fixed many of the
problems of the initial Unicode implementation, but for example
regular expressions still do not work with Unicode in 5.6.1.
Perl v5.14.0 is the first release where Unicode support is
-(almost) seamlessly integrable without some gotchas. (There are two
+(almost) seamlessly integrable without some gotchas. (There are a few
exceptions. Firstly, some differences in L<quotemeta|perlfunc/quotemeta>
were fixed starting in Perl 5.16.0. Secondly, some differences in
L<the range operator|perlop/Range Operators> were fixed starting in
-Perl 5.26.0.)
+Perl 5.26.0. Thirdly, some differences in L<split|perlfunc/split> were fixed
+started in Perl 5.28.0.)
To enable this
seamless support, you should C<use feature 'unicode_strings'> (which is
diff --git a/pp.c b/pp.c
index cc4cb59..d9dd005 100644
--- a/pp.c
+++ b/pp.c
@@ -5740,6 +5740,7 @@ PP(pp_split)
STRLEN len;
const char *s = SvPV_const(sv, len);
const bool do_utf8 = DO_UTF8(sv);
+ const bool in_uni_8_bit = IN_UNI_8_BIT;
const char *strend = s + len;
PMOP *pm = cPMOPx(PL_op);
REGEXP *rx;
@@ -5826,6 +5827,10 @@ PP(pp_split)
while (s < strend && isSPACE_LC(*s))
s++;
}
+ else if (in_uni_8_bit) {
+ while (s < strend && isSPACE_L1(*s))
+ s++;
+ }
else {
while (s < strend && isSPACE(*s))
s++;
@@ -5857,6 +5862,10 @@ PP(pp_split)
{
while (m < strend && !isSPACE_LC(*m))
++m;
+ }
+ else if (in_uni_8_bit) {
+ while (m < strend && !isSPACE_L1(*m))
+ ++m;
} else {
while (m < strend && !isSPACE(*m))
++m;
@@ -5891,6 +5900,10 @@ PP(pp_split)
{
while (s < strend && isSPACE_LC(*s))
++s;
+ }
+ else if (in_uni_8_bit) {
+ while (s < strend && isSPACE_L1(*s))
+ ++s;
} else {
while (s < strend && isSPACE(*s))
++s;
diff --git a/regen/feature.pl b/regen/feature.pl
index 579120e..8a4ce63 100755
--- a/regen/feature.pl
+++ b/regen/feature.pl
@@ -485,8 +485,9 @@ C<use feature 'unicode_strings'> subpragma is B<strongly> recommended.
This feature is available starting with Perl 5.12; was almost fully
implemented in Perl 5.14; and extended in Perl 5.16 to cover C<quotemeta>;
-and extended further in Perl 5.26 to cover L<the range
-operator|perlop/Range Operators>.
+was extended further in Perl 5.26 to cover L<the range
+operator|perlop/Range Operators>; and was extended again in Perl 5.28 to
+cover L<special-cased whitespace splitting|perlfunc/split>.
=head2 The 'unicode_eval' and 'evalbytes' features
diff --git a/t/op/split.t b/t/op/split.t
index d60bcaf..038c5d7 100644
--- a/t/op/split.t
+++ b/t/op/split.t
@@ -7,7 +7,7 @@ BEGIN {
set_up_inc('../lib');
}
-plan tests => 163;
+plan tests => 172;
$FS = ':';
@@ -480,6 +480,24 @@ is($cnt, scalar(@ary));
qq{split(\$cond ? qr/ / : " ", "$exp") behaves as expected over repeated similar patterns};
}
+SKIP: {
+ # RT #130907: unicode_strings feature doesn't work with split ' '
+
+ my ($sp) = grep /\s/u, map chr, reverse 128 .. 255 # prefer \xA0 over \x85
+ or skip 'no unicode whitespace found in high-8-bit range', 9;
+
+ for (["$sp$sp. /", "leading unicode whitespace"],
+ [".$sp$sp/", "unicode whitespace separator"],
+ [". /$sp$sp", "trailing unicode whitespace"]) {
+ my ($str, $desc) = @$_;
+ use feature "unicode_strings";
+ my @got = split " ", $str;
+ is @got, 2, "whitespace split: $desc: field count";
+ is $got[0], '.', "whitespace split: $desc: field 0";
+ is $got[1], '/', "whitespace split: $desc: field 1";
+ }
+}
+
{
# 'RT #116086: split "\x20" does not work as documented';
my @results;
--
2.9.4

Some files were not shown because too many files have changed in this diff Show More