Skip to content

Commit 3781748

Browse files
dcollinsntonycoz
authored andcommitted
[RT #129069] Perl_yylex: Fix two use-after-free bugs
Perl_yylex maintains up to two pointers, `s` and `d`, into the parser buffer at PL_bufptr. It can call skipspace(), which can potentially grow (and realloc) its argument. This can leave the second pointer pointing at the old buffer. Under most cases it isn't visible, because the old buffer isn't reused or zeroed. However, under Valgrind or libdislocator, this memory management error becomes visible. This patch saves the location of the second pointer in two locations, and restores it after the call to skipspace.
1 parent 2b6a5bf commit 3781748

File tree

2 files changed

+19
-2
lines changed

2 files changed

+19
-2
lines changed

t/op/lex.t

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ use warnings;
77

88
BEGIN { chdir 't' if -d 't'; require './test.pl'; }
99

10-
plan(tests => 28);
10+
plan(tests => 30);
1111

1212
{
1313
no warnings 'deprecated';
@@ -227,3 +227,17 @@ fresh_perl_is(
227227

228228
like runperl(prog => 'sub ub(){0} ub ub', stderr=>1), qr/Bareword found/,
229229
'[perl #126482] Assert failure when mentioning a constant twice in a row';
230+
231+
fresh_perl_is(
232+
"do\0"."000000",
233+
"",
234+
{},
235+
'[perl #129069] - no output and valgrind clean'
236+
);
237+
238+
fresh_perl_is(
239+
"00my sub\0",
240+
"Missing name in \"my sub\" at - line 1.\n",
241+
{},
242+
'[perl #129069] - "Missing name" warning and valgrind clean'
243+
);

toke.c

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7509,7 +7509,9 @@ Perl_yylex(pTHX)
75097509
1, &len);
75107510
if (len && (len != 4 || strNE(PL_tokenbuf+1, "CORE"))
75117511
&& !keyword(PL_tokenbuf + 1, len, 0)) {
7512+
SSize_t off = s-SvPVX(PL_linestr);
75127513
d = skipspace(d);
7514+
s = SvPVX(PL_linestr)+off;
75137515
if (*d == '(') {
75147516
force_ident_maybe_lex('&');
75157517
s = d;
@@ -8285,8 +8287,9 @@ Perl_yylex(pTHX)
82858287
const int key = tmp;
82868288
SV *format_name = NULL;
82878289

8288-
d = s;
8290+
SSize_t off = s-SvPVX(PL_linestr);
82898291
s = skipspace(s);
8292+
d = SvPVX(PL_linestr)+off;
82908293

82918294
if (isIDFIRST_lazy_if(s,UTF)
82928295
|| *s == '\''

0 commit comments

Comments
 (0)