summaryrefslogtreecommitdiff
path: root/pp_hot.c
diff options
context:
space:
mode:
authorTony Cook <tony@develop-help.com>2023-01-12 11:35:25 +1100
committerTony Cook <tony@develop-help.com>2023-01-17 10:04:58 +1100
commit92ef216deffb274d2e40a3516632fb089187b008 (patch)
tree6706f79a84a6fca05638e219a7087bce16ba0d50 /pp_hot.c
parent2ef20824b530076c9c3387ca64f1b373438a75b2 (diff)
downloadperl-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.c5
1 files changed, 3 insertions, 2 deletions
diff --git a/pp_hot.c b/pp_hot.c
index c56d7976e9..1d6e002fb1 100644
--- a/pp_hot.c
+++ b/pp_hot.c
@@ -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;
}
}