summaryrefslogtreecommitdiff
path: root/sv.c
diff options
context:
space:
mode:
authorMarcus Holland-Moritz <mhx-perl@gmx.net>2003-06-14 14:51:31 +0200
committerJarkko Hietaniemi <jhi@iki.fi>2003-06-14 13:13:34 +0000
commitbc3e8b6e7257ce0b7af7dcd5f3c2ff55a3b60ae3 (patch)
tree5fcb6c5655f637740f077e15dbbb38d4ce7521e9 /sv.c
parent6e37fd2a54b1a286397ea047abb89aad1f47cd8d (diff)
downloadperl-bc3e8b6e7257ce0b7af7dcd5f3c2ff55a3b60ae3.tar.gz
strchr() running amok in sv_vcatpvfn()
From: "Marcus Holland-Moritz" <mhx-perl@gmx.net> Message-ID: <041901c33262$eac8ae30$f248eed9@R2D2> (choosing the safe alternative) p4raw-id: //depot/perl@19779
Diffstat (limited to 'sv.c')
-rw-r--r--sv.c24
1 files changed, 23 insertions, 1 deletions
diff --git a/sv.c b/sv.c
index d1324fc60f..ed37411e5d 100644
--- a/sv.c
+++ b/sv.c
@@ -8431,6 +8431,24 @@ Perl_sv_vsetpvfn(pTHX_ SV *sv, const char *pat, STRLEN patlen, va_list *args, SV
sv_vcatpvfn(sv, pat, patlen, args, svargs, svmax, maybe_tainted);
}
+/* strnchr(): private function for use in sv_vcatpvfn()
+ *
+ * Like strchr(), but allows to use strings that are not null-terminated.
+ * The string length must be given instead and it _must_ be correct, as
+ * the function does not stop searching when a '\0' is discovered.
+ * This would also allow to explicitly search for '\0' characters.
+ */
+
+static const char *
+strnchr(const char* s, int c, size_t n)
+{
+ if (s)
+ for (; n > 0; n--, s++)
+ if ((int)*s == c)
+ return s;
+ return NULL;
+}
+
/* private function for use in sv_vcatpvfn via the EXPECT_NUMBER macro */
STATIC I32
@@ -9329,7 +9347,11 @@ Perl_sv_vcatpvfn(pTHX_ SV *sv, const char *pat, STRLEN patlen, va_list *args, SV
p = SvEND(sv);
*p = '\0';
}
- if (left && ckWARN(WARN_PRINTF) && strchr(eptr, '\n') &&
+ /* Don't use strchr() here, because eptr does not necessarily point */
+ /* to a null-terminated string. E.g. with the format "%-10c", eptr */
+ /* points to c (a single char on the stack), which makes strchr() */
+ /* run amok over the stack until it eventually hits '\n' or '\0'. */
+ if (left && ckWARN(WARN_PRINTF) && strnchr(eptr, '\n', elen) &&
(PL_op->op_type == OP_PRTF || PL_op->op_type == OP_SPRINTF))
Perl_warner(aTHX_ packWARN(WARN_PRINTF),
"Newline in left-justified string for %sprintf",