diff options
author | Tony Cook <tony@develop-help.com> | 2023-01-12 11:35:25 +1100 |
---|---|---|
committer | Tony Cook <tony@develop-help.com> | 2023-01-17 10:04:58 +1100 |
commit | 92ef216deffb274d2e40a3516632fb089187b008 (patch) | |
tree | 6706f79a84a6fca05638e219a7087bce16ba0d50 /pp_hot.c | |
parent | 2ef20824b530076c9c3387ca64f1b373438a75b2 (diff) | |
download | perl-92ef216deffb274d2e40a3516632fb089187b008.tar.gz |
pp_multiconcat: don't set svpv_p to an invalid pointer
When svpv_base == svpv_buf, svpv_p would be set to point before the
buffer, which is undefined.
This appears to be what gcc 13 is complaining about in #20678,
despite that report including what appears to be a completely valid
address, on a line where the value of svpv_p is now within the range
of svpv_buf.
An intermediate approach to this used:
temp = svpv_p;
if (svpv_p++ == svpv_end)
break
but this is also incorrect, since svpv_p would end up as an invalid
pointer, though gcc UBSAN didn't pick that up.
Fixes #20678.
Diffstat (limited to 'pp_hot.c')
-rw-r--r-- | pp_hot.c | 5 |
1 files changed, 3 insertions, 2 deletions
@@ -957,7 +957,7 @@ PP(pp_multiconcat) /* Note that we iterate the loop nargs+1 times: to append nargs * arguments and nargs+1 constant strings. For example, "-$a-$b-" */ - svpv_p = svpv_base - 1; + svpv_p = svpv_base; for (;;) { SSize_t len = (const_lens++)->ssize; @@ -969,7 +969,7 @@ PP(pp_multiconcat) const_pv += len; } - if (++svpv_p == svpv_end) + if (svpv_p == svpv_end) break; /* append next arg */ @@ -997,6 +997,7 @@ PP(pp_multiconcat) targ_pv += len; } + ++svpv_p; } } |