This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
t/lib/open.t: Generalize for EBCDIC platforms
[perl5.git] / util.c
diff --git a/util.c b/util.c
index 4289451..28be5ca 100644 (file)
--- a/util.c
+++ b/util.c
@@ -128,7 +128,12 @@ Perl_safesysmalloc(MEM_SIZE size)
     dTHX;
 #endif
     Malloc_t ptr;
+
+#ifdef USE_MDH
+    if (size + PERL_MEMORY_DEBUG_HEADER_SIZE < size)
+        goto out_of_memory;
     size += PERL_MEMORY_DEBUG_HEADER_SIZE;
+#endif
 #ifdef DEBUGGING
     if ((SSize_t)size < 0)
        Perl_croak_nocontext("panic: malloc, size=%"UVuf, (UV) size);
@@ -175,13 +180,18 @@ Perl_safesysmalloc(MEM_SIZE size)
 
     }
     else {
+#ifdef USE_MDH
+      out_of_memory:
+#endif
+        {
 #ifndef ALWAYS_NEED_THX
-       dTHX;
+            dTHX;
 #endif
-       if (PL_nomemok)
-           ptr =  NULL;
-       else
-           croak_no_mem();
+            if (PL_nomemok)
+                ptr =  NULL;
+            else
+                croak_no_mem();
+        }
     }
     return ptr;
 }
@@ -214,6 +224,8 @@ Perl_safesysrealloc(Malloc_t where,MEM_SIZE size)
     else {
 #ifdef USE_MDH
        where = (Malloc_t)((char*)where-PERL_MEMORY_DEBUG_HEADER_SIZE);
+        if (size + PERL_MEMORY_DEBUG_HEADER_SIZE < size)
+            goto out_of_memory;
        size += PERL_MEMORY_DEBUG_HEADER_SIZE;
        {
            struct perl_memory_debug_header *const header
@@ -292,13 +304,18 @@ Perl_safesysrealloc(Malloc_t where,MEM_SIZE size)
        DEBUG_m(PerlIO_printf(Perl_debug_log, "0x%"UVxf": (%05ld) realloc %ld bytes\n",PTR2UV(ptr),(long)PL_an++,(long)size));
 
        if (ptr == NULL) {
+#ifdef USE_MDH
+          out_of_memory:
+#endif
+            {
 #ifndef ALWAYS_NEED_THX
-           dTHX;
+                dTHX;
 #endif
-           if (PL_nomemok)
-               ptr = NULL;
-           else
-               croak_no_mem();
+                if (PL_nomemok)
+                    ptr = NULL;
+                else
+                    croak_no_mem();
+            }
        }
     }
     return ptr;
@@ -539,10 +556,6 @@ Perl_instr(const char *big, const char *little)
 
     PERL_ARGS_ASSERT_INSTR;
 
-    /* libc prior to 4.6.27 (late 1994) did not work properly on a NULL
-     * 'little' */
-    if (!little)
-       return (char*)big;
     return strstr((char*)big, (char*)little);
 }
 
@@ -1304,7 +1317,7 @@ Perl_closest_cop(pTHX_ const COP *cop, const OP *o, const OP *curop,
 
     if (o->op_flags & OPf_KIDS) {
        const OP *kid;
-       for (kid = cUNOPo->op_first; kid; kid = OP_SIBLING(kid)) {
+       for (kid = cUNOPo->op_first; kid; kid = OpSIBLING(kid)) {
            const COP *new_cop;
 
            /* If the OP_NEXTSTATE has been optimised away we can still use it
@@ -1358,11 +1371,13 @@ Perl_mess_sv(pTHX_ SV *basemsg, bool consume)
 #if defined(USE_C_BACKTRACE) && defined(USE_C_BACKTRACE_ON_ERROR)
     {
         char *ws;
-        int wi;
+        UV wi;
         /* The PERL_C_BACKTRACE_ON_WARN must be an integer of one or more. */
-        if ((ws = PerlEnv_getenv("PERL_C_BACKTRACE_ON_ERROR")) &&
-            (wi = grok_atou(ws, NULL)) > 0) {
-            Perl_dump_c_backtrace(aTHX_ Perl_debug_log, wi, 1);
+        if ((ws = PerlEnv_getenv("PERL_C_BACKTRACE_ON_ERROR"))
+            && grok_atoUV(ws, &wi, NULL)
+            && wi <= PERL_INT_MAX
+        ) {
+            Perl_dump_c_backtrace(aTHX_ Perl_debug_log, (int)wi, 1);
         }
     }
 #endif
@@ -1397,7 +1412,7 @@ Perl_mess_sv(pTHX_ SV *basemsg, bool consume)
         */
 
        const COP *cop =
-           closest_cop(PL_curcop, OP_SIBLING(PL_curcop), PL_op, FALSE);
+           closest_cop(PL_curcop, OpSIBLING(PL_curcop), PL_op, FALSE);
        if (!cop)
            cop = PL_curcop;
 
@@ -2966,7 +2981,7 @@ Perl_wait4pid(pTHX_ Pid_t pid, int *statusp, int flags)
                *statusp = SvIVX(sv);
                /* The hash iterator is currently on this entry, so simply
                   calling hv_delete would trigger the lazy delete, which on
-                  aggregate does more work, beacuse next call to hv_iterinit()
+                  aggregate does more work, because next call to hv_iterinit()
                   would spot the flag, and have to call the delete routine,
                   while in the meantime any new entries can't re-use that
                   memory.  */
@@ -3936,7 +3951,7 @@ Fill the sv with current working directory
 /* Originally written in Perl by John Bazik; rewritten in C by Ben Sugars.
  * rewritten again by dougm, optimized for use with xs TARG, and to prefer
  * getcwd(3) if available
- * Comments from the orignal:
+ * Comments from the original:
  *     This is a faster version of getcwd.  It's also more dangerous
  *     because you might chdir out of a directory that you can't chdir
  *     back into. */
@@ -4403,15 +4418,20 @@ Perl_parse_unicode_opts(pTHX_ const char **popt)
   if (*p) {
        if (isDIGIT(*p)) {
             const char* endptr;
-            opt = (U32) grok_atou(p, &endptr);
-           p = endptr;
-           if (*p && *p != '\n' && *p != '\r') {
-            if(isSPACE(*p)) goto the_end_of_the_opts_parser;
-            else
-                Perl_croak(aTHX_ "Unknown Unicode option letter '%c'", *p);
-           }
-       }
-       else {
+            UV uv;
+            if (grok_atoUV(p, &uv, &endptr)
+                && uv <= U32_MAX
+                && (p = endptr)
+                && *p && *p != '\n' && *p != '\r'
+            ) {
+                opt = (U32)uv;
+                if (isSPACE(*p))
+                    goto the_end_of_the_opts_parser;
+                else
+                    Perl_croak(aTHX_ "Unknown Unicode option letter '%c'", *p);
+            }
+        }
+        else {
            for (; *p; p++) {
                 switch (*p) {
                 case PERL_UNICODE_STDIN:
@@ -4712,14 +4732,14 @@ Perl_free_global_struct(pTHX_ struct perl_vars *plvarsp)
 
 #ifdef PERL_MEM_LOG
 
-/* -DPERL_MEM_LOG: the Perl_mem_log_..() is compiled, including the
+/* -DPERL_MEM_LOG: the Perl_mem_log_..() is compiled, including
  * the default implementation, unless -DPERL_MEM_LOG_NOIMPL is also
  * given, and you supply your own implementation.
  *
  * The default implementation reads a single env var, PERL_MEM_LOG,
  * expecting one or more of the following:
  *
- *    \d+ - fd         fd to write to          : must be 1st (grok_atou)
+ *    \d+ - fd         fd to write to          : must be 1st (grok_atoUV)
  *    'm' - memlog     was PERL_MEM_LOG=1
  *    's' - svlog      was PERL_SV_LOG=1
  *    't' - timestamp  was PERL_MEM_LOG_TIMESTAMP=1
@@ -4788,9 +4808,15 @@ S_mem_log_common(enum mem_log_type mlt, const UV n,
        {
            STRLEN len;
             const char* endptr;
-           int fd = grok_atou(pmlenv, &endptr); /* Ignore endptr. */
-           if (!fd)
+           int fd;
+            UV uv;
+            if (grok_atoUV(pmlenv, &uv, &endptr) /* Ignore endptr. */
+                && uv && uv <= PERL_INT_MAX
+            ) {
+                fd = (int)uv;
+            } else {
                fd = PERL_MEM_LOG_FD;
+            }
 
            if (strchr(pmlenv, 't')) {
                len = my_snprintf(buf, sizeof(buf),
@@ -5343,28 +5369,42 @@ Perl_my_cxt_init(pTHX_ const char *my_cxt_key, size_t size)
 #endif /* PERL_IMPLICIT_CONTEXT */
 
 
-/* The meaning of the varargs is determined U32 key arg. This is not a format
-   string. The U32 key is assembled with HS_KEY.
-
-   v_my_perl arg is "PerlInterpreter * my_perl" if PERL_IMPLICIT_CONTEXT and
-   otherwise "CV * cv" (boot xsub's CV *). v_my_perl will catch where a threaded
-   future perl526.dll calling IO.dll for example, and IO.dll was linked with
-   threaded perl524.dll, and both perl526.dll and perl524.dll are in %PATH and
-   the Win32 DLL loader sucessfully can load IO.dll into the process but
-   simultaniously it loaded a interp of a different version into the process,
-   and XS code will naturally pass SV*s created by perl524.dll for perl526.dll
-   to use through perl526.dll's my_perl->Istack_base.
-
-   v_my_perl (v=void) can not be the first arg since then key will be out of
-   place in a threaded vs non-threaded mixup and analyzing the key number's
-   bitfields won't reveal the problem since it will be a valid key
-   (unthreaded perl) on interp side, but croak reports the XS mod's key as
-   gibberish (it is really my_perl ptr) (threaded XS mod), or if threaded perl
-   and unthreaded XS module, threaded perl will look at uninit C stack or uninit
-   register to get var key (remember it assumes 1st arg is interp cxt).
-
-Perl_xs_handshake(U32 key, void * v_my_perl, const char * file,
-[U32 items, U32 ax], [char * api_version], [char * xs_version]) */
+/* Perl_xs_handshake():
+   implement the various XS_*_BOOTCHECK macros, which are added to .c
+   files by ExtUtils::ParseXS, to check that the perl the module was built
+   with is binary compatible with the running perl.
+
+   usage:
+       Perl_xs_handshake(U32 key, void * v_my_perl, const char * file,
+            [U32 items, U32 ax], [char * api_version], [char * xs_version])
+
+   The meaning of the varargs is determined the U32 key arg (which is not
+   a format string). The fields of key are assembled by using HS_KEY().
+
+   Under PERL_IMPLICIT_CONTEX, the v_my_perl arg is of type
+   "PerlInterpreter *" and represents the callers context; otherwise it is
+   of type "CV *", and is the boot xsub's CV.
+
+   v_my_perl will catch where a threaded future perl526.dll calling IO.dll
+   for example, and IO.dll was linked with threaded perl524.dll, and both
+   perl526.dll and perl524.dll are in %PATH and the Win32 DLL loader
+   successfully can load IO.dll into the process but simultaneously it
+   loaded an interpreter of a different version into the process, and XS
+   code will naturally pass SV*s created by perl524.dll for perl526.dll to
+   use through perl526.dll's my_perl->Istack_base.
+
+   v_my_perl cannot be the first arg, since then 'key' will be out of
+   place in a threaded vs non-threaded mixup; and analyzing the key
+   number's bitfields won't reveal the problem, since it will be a valid
+   key (unthreaded perl) on interp side, but croak will report the XS mod's
+   key as gibberish (it is really a my_perl ptr) (threaded XS mod); or if
+   it's a threaded perl and an unthreaded XS module, threaded perl will
+   look at an uninit C stack or an uninit register to get 'key'
+   (remember that it assumes that the 1st arg is the interp cxt).
+
+   'file' is the source filename of the caller.
+*/
+
 I32
 Perl_xs_handshake(const U32 key, void * v_my_perl, const char * file, ...)
 {
@@ -5411,8 +5451,8 @@ Perl_xs_handshake(const U32 key, void * v_my_perl, const char * file, ...)
     if(UNLIKELY(got != need)) {
        bad_handshake:/* recycle branch and string from above */
        if(got != (void *)HSf_NOCHK)
-           noperl_die("%s: Invalid handshake key got %p"
-               " needed %p, binaries are mismatched",
+           noperl_die("%s: loadable library and perl binaries are mismatched"
+                       " (got handshake key %p, needed %p)\n",
                file, got, need);
     }
 
@@ -5451,15 +5491,16 @@ Perl_xs_handshake(const U32 key, void * v_my_perl, const char * file, ...)
        U32 xsverlen;
        assert(HS_GETXSVERLEN(key) <= UCHAR_MAX && HS_GETXSVERLEN(key) <= HS_APIVERLEN_MAX);
        if((xsverlen = HS_GETXSVERLEN(key)))
-           Perl_xs_version_bootcheck(aTHX_
+           S_xs_version_bootcheck(aTHX_
                items, ax, va_arg(args, char*), xsverlen);
     }
     va_end(args);
     return ax;
 }
 
-void
-Perl_xs_version_bootcheck(pTHX_ U32 items, U32 ax, const char *xs_p,
+
+STATIC void
+S_xs_version_bootcheck(pTHX_ U32 items, U32 ax, const char *xs_p,
                          STRLEN xs_len)
 {
     SV *sv;
@@ -5661,7 +5702,7 @@ Perl_my_dirfd(DIR * dir) {
     return dir->dd_fd;
 #else
     Perl_croak_nocontext(PL_no_func, "dirfd");
-    NOT_REACHED; /* NOT REACHED */
+    NOT_REACHED; /* NOTREACHED */
     return 0;
 #endif 
 }
@@ -5805,6 +5846,9 @@ static void bfd_update(bfd_context* ctx, Dl_info* dl_info)
     /* BFD open and scan only if the filename changed. */
     if (ctx->fname_prev == NULL ||
         strNE(dl_info->dli_fname, ctx->fname_prev)) {
+        if (ctx->abfd) {
+            bfd_close(ctx->abfd);
+        }
         ctx->abfd = bfd_openr(dl_info->dli_fname, 0);
         if (ctx->abfd) {
             if (bfd_check_format(ctx->abfd, bfd_object)) {
@@ -5973,6 +6017,8 @@ static const char* atos_parse(const char* p,
     const char* source_name_end;
     const char* source_line_end;
     const char* close_paren;
+    UV uv;
+
     /* Skip trailing whitespace. */
     while (p > start && isspace(*p)) p--;
     /* Now we should be at the close paren. */
@@ -5999,10 +6045,14 @@ static const char* atos_parse(const char* p,
         return NULL;
     p++;
     *source_name_size = source_name_end - p;
-    *source_line = grok_atou(source_number_start, &source_line_end);
-    if (source_line_end != close_paren)
-        return NULL;
-    return p;
+    if (grok_atoUV(source_number_start, &uv,  &source_line_end)
+        && source_line_end == close_paren
+        && uv <= MAX_STRLEN
+    ) {
+        *source_line = (STRLEN)uv;
+        return p;
+    }
+    return NULL;
 }
 
 /* Given a raw frame, read a pipe from the symbolicator (that's the
@@ -6301,6 +6351,9 @@ Perl_get_c_backtrace(pTHX_ int depth, int skip)
     }
 #ifdef USE_BFD
     Safefree(symbol_names);
+    if (bfd_ctx.abfd) {
+        bfd_close(bfd_ctx.abfd);
+    }
 #endif
     Safefree(source_lines);
     Safefree(source_name_sizes);