Mon Nov 1 02:41:27 2010 UTC ()
Double the array only when really necessary.  Otherwise memory will be
exhausted if user modifies the variable envrion itself repeatedly..


(enami)
diff -r1.26 -r1.27 src/lib/libc/stdlib/getenv.c

cvs diff -r1.26 -r1.27 src/lib/libc/stdlib/getenv.c (expand / switch to unified diff)

--- src/lib/libc/stdlib/getenv.c 2010/10/24 17:53:27 1.26
+++ src/lib/libc/stdlib/getenv.c 2010/11/01 02:41:27 1.27
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: getenv.c,v 1.26 2010/10/24 17:53:27 tron Exp $ */ 1/* $NetBSD: getenv.c,v 1.27 2010/11/01 02:41:27 enami Exp $ */
2 2
3/* 3/*
4 * Copyright (c) 1987, 1993 4 * Copyright (c) 1987, 1993
5 * The Regents of the University of California. All rights reserved. 5 * The Regents of the University of California. All rights reserved.
6 * 6 *
7 * Redistribution and use in source and binary forms, with or without 7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions 8 * modification, are permitted provided that the following conditions
9 * are met: 9 * are met:
10 * 1. Redistributions of source code must retain the above copyright 10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer. 11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright 12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the 13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution. 14 * documentation and/or other materials provided with the distribution.
@@ -24,27 +24,27 @@ @@ -24,27 +24,27 @@
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE. 29 * SUCH DAMAGE.
30 */ 30 */
31 31
32#include <sys/cdefs.h> 32#include <sys/cdefs.h>
33#if defined(LIBC_SCCS) && !defined(lint) 33#if defined(LIBC_SCCS) && !defined(lint)
34#if 0 34#if 0
35static char sccsid[] = "@(#)getenv.c 8.1 (Berkeley) 6/4/93"; 35static char sccsid[] = "@(#)getenv.c 8.1 (Berkeley) 6/4/93";
36#else 36#else
37__RCSID("$NetBSD: getenv.c,v 1.26 2010/10/24 17:53:27 tron Exp $"); 37__RCSID("$NetBSD: getenv.c,v 1.27 2010/11/01 02:41:27 enami Exp $");
38#endif 38#endif
39#endif /* LIBC_SCCS and not lint */ 39#endif /* LIBC_SCCS and not lint */
40 40
41#include "namespace.h" 41#include "namespace.h"
42#include <assert.h> 42#include <assert.h>
43#include <errno.h> 43#include <errno.h>
44#include <stdlib.h> 44#include <stdlib.h>
45#include <string.h> 45#include <string.h>
46#include "reentrant.h" 46#include "reentrant.h"
47#include "local.h" 47#include "local.h"
48 48
49#ifdef _REENTRANT 49#ifdef _REENTRANT
50rwlock_t __environ_lock = RWLOCK_INITIALIZER; 50rwlock_t __environ_lock = RWLOCK_INITIALIZER;
@@ -110,28 +110,27 @@ __allocenv(int offset) @@ -110,28 +110,27 @@ __allocenv(int offset)
110 if (offset == -1 || saveenv != environ) { 110 if (offset == -1 || saveenv != environ) {
111 char **ptr; 111 char **ptr;
112 for (ptr = environ, offset = 0; *ptr != NULL; ptr++) 112 for (ptr = environ, offset = 0; *ptr != NULL; ptr++)
113 offset++; 113 offset++;
114 } 114 }
115 115
116 /* one for potentially new entry one for NULL */ 116 /* one for potentially new entry one for NULL */
117 required_len = offset + 2; 117 required_len = offset + 2;
118 118
119 if (required_len <= environ_malloced_len && saveenv == environ) 119 if (required_len <= environ_malloced_len && saveenv == environ)
120 return 0; 120 return 0;
121 121
122 /* Make sure we at least double the size of the arrays. */ 122 /* Make sure we at least double the size of the arrays. */
123 new_len = (environ_malloced_len >= 16) ? 123 new_len = environ_malloced_len >= 16 ? environ_malloced_len : 16;
124 (environ_malloced_len << 1) : 16; 
125 while (new_len < required_len) 124 while (new_len < required_len)
126 new_len = new_len << 1; 125 new_len = new_len << 1;
127 126
128 if (saveenv == environ) { /* just increase size */ 127 if (saveenv == environ) { /* just increase size */
129 if ((p = realloc(saveenv, new_len * sizeof(*p))) == NULL) 128 if ((p = realloc(saveenv, new_len * sizeof(*p))) == NULL)
130 return -1; 129 return -1;
131 (void)memset(&p[environ_malloced_len], 0, 130 (void)memset(&p[environ_malloced_len], 0,
132 (new_len - environ_malloced_len) * sizeof(*p)); 131 (new_len - environ_malloced_len) * sizeof(*p));
133 saveenv = p; 132 saveenv = p;
134 } else { /* get new space */ 133 } else { /* get new space */
135 free(saveenv); 134 free(saveenv);
136 if ((saveenv = malloc(new_len * sizeof(*saveenv))) == NULL) 135 if ((saveenv = malloc(new_len * sizeof(*saveenv))) == NULL)
137 return -1; 136 return -1;