@@ -2061,8 +2061,40 @@ Perl_new_warnings_bitfield(pTHX_ STRLEN *buffer, const char *const bits,
2061
2061
*(s+(nlen+1+vlen)) = '\0'
2062
2062
2063
2063
#ifdef USE_ENVIRON_ARRAY
2064
- /* VMS' my_setenv() is in vms.c */
2064
+
2065
+ /* small wrapper for use by Perl_my_setenv that mallocs, or reallocs if
2066
+ * 'current' is non-null, with up to three sizes that are added together.
2067
+ * It handles integer overflow.
2068
+ */
2069
+ static char *
2070
+ S_env_alloc (void * current , Size_t l1 , Size_t l2 , Size_t l3 , Size_t size )
2071
+ {
2072
+ void * p ;
2073
+ Size_t sl , l = l1 + l2 ;
2074
+
2075
+ if (l < l2 )
2076
+ goto panic ;
2077
+ l += l3 ;
2078
+ if (l < l3 )
2079
+ goto panic ;
2080
+ sl = l * size ;
2081
+ if (sl < l )
2082
+ goto panic ;
2083
+
2084
+ p = current
2085
+ ? safesysrealloc (current , sl )
2086
+ : safesysmalloc (sl );
2087
+ if (p )
2088
+ return (char * )p ;
2089
+
2090
+ panic :
2091
+ croak_memory_wrap ();
2092
+ }
2093
+
2094
+
2095
+ /* VMS' my_setenv() is in vms.c */
2065
2096
#if !defined(WIN32 ) && !defined(NETWARE )
2097
+
2066
2098
void
2067
2099
Perl_my_setenv (pTHX_ const char * nam , const char * val )
2068
2100
{
@@ -2078,28 +2110,27 @@ Perl_my_setenv(pTHX_ const char *nam, const char *val)
2078
2110
#ifndef PERL_USE_SAFE_PUTENV
2079
2111
if (!PL_use_safe_putenv ) {
2080
2112
/* most putenv()s leak, so we manipulate environ directly */
2081
- I32 i ;
2082
- const I32 len = strlen (nam );
2083
- int nlen , vlen ;
2113
+ UV i ;
2114
+ Size_t vlen , nlen = strlen (nam );
2084
2115
2085
2116
/* where does it go? */
2086
2117
for (i = 0 ; environ [i ]; i ++ ) {
2087
- if (strnEQ (environ [i ],nam ,len ) && environ [i ][len ] == '=' )
2118
+ if (strnEQ (environ [i ], nam , nlen ) && environ [i ][nlen ] == '=' )
2088
2119
break ;
2089
2120
}
2090
2121
2091
2122
if (environ == PL_origenviron ) { /* need we copy environment? */
2092
- I32 j ;
2093
- I32 max ;
2123
+ UV j , max ;
2094
2124
char * * tmpenv ;
2095
2125
2096
2126
max = i ;
2097
2127
while (environ [max ])
2098
2128
max ++ ;
2099
- tmpenv = (char * * )safesysmalloc ((max + 2 ) * sizeof (char * ));
2129
+ /* XXX shouldn't that be max+1 rather than max+2 ??? - DAPM */
2130
+ tmpenv = (char * * )S_env_alloc (NULL , max , 2 , 0 , sizeof (char * ));
2100
2131
for (j = 0 ; j < max ; j ++ ) { /* copy environment */
2101
- const int len = strlen (environ [j ]);
2102
- tmpenv [j ] = ( char * ) safesysmalloc (( len + 1 ) * sizeof ( char ) );
2132
+ const Size_t len = strlen (environ [j ]);
2133
+ tmpenv [j ] = S_env_alloc ( NULL , len , 1 , 0 , 1 );
2103
2134
Copy (environ [j ], tmpenv [j ], len + 1 , char );
2104
2135
}
2105
2136
tmpenv [max ] = NULL ;
@@ -2118,15 +2149,15 @@ Perl_my_setenv(pTHX_ const char *nam, const char *val)
2118
2149
#endif
2119
2150
}
2120
2151
if (!environ [i ]) { /* does not exist yet */
2121
- environ = (char * * )safesysrealloc (environ , ( i + 2 ) * sizeof (char * ));
2152
+ environ = (char * * )S_env_alloc (environ , i , 2 , 0 , sizeof (char * ));
2122
2153
environ [i + 1 ] = NULL ; /* make sure it's null terminated */
2123
2154
}
2124
2155
else
2125
2156
safesysfree (environ [i ]);
2126
- nlen = strlen ( nam );
2157
+
2127
2158
vlen = strlen (val );
2128
2159
2129
- environ [i ] = ( char * ) safesysmalloc (( nlen + vlen + 2 ) * sizeof ( char ) );
2160
+ environ [i ] = S_env_alloc ( NULL , nlen , vlen , 2 , 1 );
2130
2161
/* all that work just for this */
2131
2162
my_setenv_format (environ [i ], nam , nlen , val , vlen );
2132
2163
} else {
@@ -2150,22 +2181,21 @@ Perl_my_setenv(pTHX_ const char *nam, const char *val)
2150
2181
if (environ ) /* old glibc can crash with null environ */
2151
2182
(void )unsetenv (nam );
2152
2183
} else {
2153
- const int nlen = strlen (nam );
2154
- const int vlen = strlen (val );
2155
- char * const new_env =
2156
- (char * )safesysmalloc ((nlen + vlen + 2 ) * sizeof (char ));
2184
+ const Size_t nlen = strlen (nam );
2185
+ const Size_t vlen = strlen (val );
2186
+ char * const new_env = S_env_alloc (NULL , nlen , vlen , 2 , 1 );
2157
2187
my_setenv_format (new_env , nam , nlen , val , vlen );
2158
2188
(void )putenv (new_env );
2159
2189
}
2160
2190
# else /* ! HAS_UNSETENV */
2161
2191
char * new_env ;
2162
- const int nlen = strlen (nam );
2163
- int vlen ;
2192
+ const Size_t nlen = strlen (nam );
2193
+ Size_t vlen ;
2164
2194
if (!val ) {
2165
2195
val = "" ;
2166
2196
}
2167
2197
vlen = strlen (val );
2168
- new_env = ( char * ) safesysmalloc (( nlen + vlen + 2 ) * sizeof ( char ) );
2198
+ new_env = S_env_alloc ( NULL , nlen , vlen , 2 , 1 );
2169
2199
/* all that work just for this */
2170
2200
my_setenv_format (new_env , nam , nlen , val , vlen );
2171
2201
(void )putenv (new_env );
@@ -2187,14 +2217,14 @@ Perl_my_setenv(pTHX_ const char *nam, const char *val)
2187
2217
{
2188
2218
dVAR ;
2189
2219
char * envstr ;
2190
- const int nlen = strlen (nam );
2191
- int vlen ;
2220
+ const Size_t nlen = strlen (nam );
2221
+ Size_t vlen ;
2192
2222
2193
2223
if (!val ) {
2194
2224
val = "" ;
2195
2225
}
2196
2226
vlen = strlen (val );
2197
- Newx ( envstr , nlen + vlen + 2 , char );
2227
+ envstr = S_env_alloc ( NULL , nlen , vlen , 2 , 1 );
2198
2228
my_setenv_format (envstr , nam , nlen , val , vlen );
2199
2229
(void )PerlEnv_putenv (envstr );
2200
2230
Safefree (envstr );
0 commit comments