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