From aefb3fa072c057c13029faf2c7044bca8e0cc344 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Dagfinn=20Ilmari=20Manns=C3=A5ker?= Date: Sat, 21 Oct 2017 20:05:17 +0100 Subject: [PATCH] Provide fallback strnlen implementation --- embed.fnc | 4 ++++ metaconfig.h | 1 - perl.h | 6 ++++++ proto.h | 5 +++++ util.c | 30 ++++++++++++++++++++++++++++++ 5 files changed, 45 insertions(+), 1 deletion(-) diff --git a/embed.fnc b/embed.fnc index 71b3087..16b678c 100644 --- a/embed.fnc +++ b/embed.fnc @@ -3038,6 +3038,10 @@ Apnod |Size_t |my_strlcat |NULLOK char *dst|NULLOK const char *src|Size_t size Apnod |Size_t |my_strlcpy |NULLOK char *dst|NULLOK const char *src|Size_t size #endif +#ifndef HAS_STRNLEN +Apnod |Size_t |my_strnlen |NN const char *str|Size_t maxlen +#endif + #ifndef HAS_MKSTEMP pno |int |my_mkstemp |NN char *templte #endif diff --git a/metaconfig.h b/metaconfig.h index 2bc226a..eea0073 100644 --- a/metaconfig.h +++ b/metaconfig.h @@ -22,7 +22,6 @@ * HAS_MBRTOWC * HAS_MEMRCHR * HAS_NANOSLEEP - * HAS_STRNLEN * HAS_STRTOLD_L * I_WCHAR */ diff --git a/perl.h b/perl.h index 2063175..f9b1ec3 100644 --- a/perl.h +++ b/perl.h @@ -1479,6 +1479,12 @@ EXTERN_C char *crypt(const char *, const char *); # define my_strlcpy Perl_my_strlcpy #endif +#ifdef HAS_STRNLEN +# define my_strnlen strnlen +#else +# define my_strnlen Perl_my_strnlen +#endif + /* The IV type is supposed to be long enough to hold any integral value or a pointer. diff --git a/proto.h b/proto.h index 70c1a63..4459d10 100644 --- a/proto.h +++ b/proto.h @@ -3858,6 +3858,11 @@ PERL_CALLCONV Size_t Perl_my_strlcat(char *dst, const char *src, Size_t size); #if !defined(HAS_STRLCPY) PERL_CALLCONV Size_t Perl_my_strlcpy(char *dst, const char *src, Size_t size); #endif +#if !defined(HAS_STRNLEN) +PERL_CALLCONV Size_t Perl_my_strnlen(const char *str, Size_t maxlen); +#define PERL_ARGS_ASSERT_MY_STRNLEN \ + assert(str) +#endif #if !defined(HAS_TRUNCATE) && !defined(HAS_CHSIZE) && defined(F_FREESP) PERL_CALLCONV I32 Perl_my_chsize(pTHX_ int fd, Off_t length) __attribute__warn_unused_result__; diff --git a/util.c b/util.c index 087c918..244d936 100644 --- a/util.c +++ b/util.c @@ -5480,6 +5480,36 @@ Perl_my_strlcpy(char *dst, const char *src, Size_t size) } #endif +/* +=for apidoc my_strnlen + +The C library C if available, or a Perl implementation of it. + +C computes the length of the string, up to C +characters. It will will never attempt to address more than C +characters, making it suitable for use with strings that are not +guaranteed to be NUL-terminated. + +=cut + +Description stolen from http://man.openbsd.org/strnlen.3, +implementation stolen from PostgreSQL. +*/ +#ifndef HAS_STRNLEN +Size_t +Perl_my_strnlen(const char *str, Size_t maxlen) +{ + const char *p = str; + + PERL_ARGS_ASSERT_MY_STRNLEN; + + while(maxlen-- && *p) + p++; + + return p - str; +} +#endif + #if defined(_MSC_VER) && (_MSC_VER >= 1300) && (_MSC_VER < 1400) && (WINVER < 0x0500) /* VC7 or 7.1, building with pre-VC7 runtime libraries. */ long _ftol( double ); /* Defined by VC6 C libs. */ -- 1.8.3.1