#endif
-/* copy a string up to some (non-backslashed) delimiter, if any */
+/* copy a string up to some (non-backslashed) delimiter, if any.
+ * With allow_escape, converts \<delimiter> to <delimiter>, while leaves
+ * \<non-delimiter> as-is.
+ * Returns the position in the src string of the closing delimiter, if
+ * any, or returns fromend otherwise.
+ * This is the internal implementation for Perl_delimcpy and
+ * Perl_delimcpy_no_escape.
+ */
static char *
-S_delimcpy(char *to, const char *toend, const char *from,
+S_delimcpy_intern(char *to, const char *toend, const char *from,
const char *fromend, int delim, I32 *retlen,
const bool allow_escape)
{
PERL_ARGS_ASSERT_DELIMCPY;
for (tolen = 0; from < fromend; from++, tolen++) {
- if (allow_escape && *from == '\\') {
+ if (allow_escape && *from == '\\' && from + 1 < fromend) {
if (from[1] != delim) {
if (to < toend)
*to++ = *from;
{
PERL_ARGS_ASSERT_DELIMCPY;
- return S_delimcpy(to, toend, from, fromend, delim, retlen, 1);
+ return S_delimcpy_intern(to, toend, from, fromend, delim, retlen, 1);
}
char *
{
PERL_ARGS_ASSERT_DELIMCPY_NO_ESCAPE;
- return S_delimcpy(to, toend, from, fromend, delim, retlen, 0);
+ return S_delimcpy_intern(to, toend, from, fromend, delim, retlen, 0);
}
/*