Provide fallback strnlen implementation
authorDagfinn Ilmari Mannsåker <ilmari@ilmari.org>
Sat, 21 Oct 2017 19:05:17 +0000 (20:05 +0100)
committerDagfinn Ilmari Mannsåker <ilmari@ilmari.org>
Sat, 21 Oct 2017 19:05:17 +0000 (20:05 +0100)
embed.fnc
metaconfig.h
perl.h
proto.h
util.c

index 71b3087..16b678c 100644 (file)
--- 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
index 2bc226a..eea0073 100644 (file)
@@ -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 (file)
--- 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 (file)
--- 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 (file)
--- 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<strnlen> if available, or a Perl implementation of it.
+
+C<my_strnlen()> computes the length of the string, up to C<maxlen>
+characters.  It will will never attempt to address more than C<maxlen>
+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. */