Module Name: src Committed By: njoly Date: Sat Oct 16 11:23:42 UTC 2010
Modified Files: src/lib/libc/stdlib: getenv.3 setenv.c src/tests/lib/libc/stdlib: t_environment.c Log Message: Make setenv(3) follow the standard, by rejecting invalid strings. It now fails with EINVAL errno when variable is NULL, empty or contains an `=' character; or value is NULL. Adjust the man page accordingly, and exercize them in the existing environment testcase. To generate a diff of this commit: cvs rdiff -u -r1.22 -r1.23 src/lib/libc/stdlib/getenv.3 cvs rdiff -u -r1.40 -r1.41 src/lib/libc/stdlib/setenv.c cvs rdiff -u -r1.2 -r1.3 src/tests/lib/libc/stdlib/t_environment.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/lib/libc/stdlib/getenv.3 diff -u src/lib/libc/stdlib/getenv.3:1.22 src/lib/libc/stdlib/getenv.3:1.23 --- src/lib/libc/stdlib/getenv.3:1.22 Fri Oct 1 20:57:50 2010 +++ src/lib/libc/stdlib/getenv.3 Sat Oct 16 11:23:41 2010 @@ -1,4 +1,4 @@ -.\" $NetBSD: getenv.3,v 1.22 2010/10/01 20:57:50 wiz Exp $ +.\" $NetBSD: getenv.3,v 1.23 2010/10/16 11:23:41 njoly Exp $ .\" .\" Copyright (c) 1988, 1991, 1993 .\" The Regents of the University of California. All rights reserved. @@ -33,7 +33,7 @@ .\" .\" from: @(#)getenv.3 8.2 (Berkeley) 12/11/93 .\" -.Dd October 1, 2010 +.Dd October 16, 2010 .Dt GETENV 3 .Os .Sh NAME @@ -62,16 +62,14 @@ host .Em environment list . For compatibility with differing environment conventions, -the given arguments +the +.Fn getenv +or +.Fn getenv_r +given argument .Ar name -and -.Ar value -may be appended and prepended, -respectively, -with an equal sign -.Dq Li \&= , -except for -.Fn unsetenv . +may be appended with an equal sign +.Dq Li \&= . .Pp The .Fn getenv @@ -160,11 +158,18 @@ The .Fa name argument to +.Fn setenv +or .Fn unsetenv is a null pointer, points to an empty string, or points to a string containing an .Dq Li \&= character. +The +.Fa value +argument to +.Fn setenv +is a null pointer. .It Bq Er ENOMEM The function .Fn setenv Index: src/lib/libc/stdlib/setenv.c diff -u src/lib/libc/stdlib/setenv.c:1.40 src/lib/libc/stdlib/setenv.c:1.41 --- src/lib/libc/stdlib/setenv.c:1.40 Sat Oct 2 16:56:03 2010 +++ src/lib/libc/stdlib/setenv.c Sat Oct 16 11:23:41 2010 @@ -1,4 +1,4 @@ -/* $NetBSD: setenv.c,v 1.40 2010/10/02 16:56:03 tron Exp $ */ +/* $NetBSD: setenv.c,v 1.41 2010/10/16 11:23:41 njoly Exp $ */ /* * Copyright (c) 1987, 1993 @@ -34,7 +34,7 @@ #if 0 static char sccsid[] = "@(#)setenv.c 8.1 (Berkeley) 6/4/93"; #else -__RCSID("$NetBSD: setenv.c,v 1.40 2010/10/02 16:56:03 tron Exp $"); +__RCSID("$NetBSD: setenv.c,v 1.41 2010/10/16 11:23:41 njoly Exp $"); #endif #endif /* LIBC_SCCS and not lint */ @@ -60,13 +60,23 @@ setenv(const char *name, const char *value, int rewrite) { char *c; - const char *cc; size_t l_value, size; int offset; _DIAGASSERT(name != NULL); _DIAGASSERT(value != NULL); + if (name == NULL || value == NULL) { + errno = EINVAL; + return -1; + } + + size = strcspn(name, "="); + if (size == 0 || name[size] != '\0') { + errno = EINVAL; + return -1; + } + if (rwlock_wrlock(&__environ_lock) != 0) return -1; @@ -76,8 +86,6 @@ if (__allocenv(offset) == -1) goto bad; - if (*value == '=') /* no `=' in value */ - ++value; l_value = strlen(value); if (c != NULL) { @@ -93,9 +101,6 @@ goto copy; } } - for (cc = name; *cc && *cc != '='; ++cc) /* no `=' in name */ - continue; - size = cc - name; /* name + `=' + value */ if ((c = malloc(size + l_value + 2)) == NULL) goto bad; Index: src/tests/lib/libc/stdlib/t_environment.c diff -u src/tests/lib/libc/stdlib/t_environment.c:1.2 src/tests/lib/libc/stdlib/t_environment.c:1.3 --- src/tests/lib/libc/stdlib/t_environment.c:1.2 Fri Oct 1 20:12:20 2010 +++ src/tests/lib/libc/stdlib/t_environment.c Sat Oct 16 11:23:41 2010 @@ -1,4 +1,4 @@ -/* $NetBSD: t_environment.c,v 1.2 2010/10/01 20:12:20 christos Exp $ */ +/* $NetBSD: t_environment.c,v 1.3 2010/10/16 11:23:41 njoly Exp $ */ /*- * Copyright (c) 2010 The NetBSD Foundation, Inc. * All rights reserved. @@ -32,9 +32,10 @@ */ #include <sys/cdefs.h> -__RCSID("$NetBSD: t_environment.c,v 1.2 2010/10/01 20:12:20 christos Exp $"); +__RCSID("$NetBSD: t_environment.c,v 1.3 2010/10/16 11:23:41 njoly Exp $"); #include <atf-c.h> +#include <errno.h> #include <stdio.h> #include <stdlib.h> #include <string.h> @@ -71,6 +72,14 @@ unsetenv(name); ATF_CHECK(getenv(name) == NULL); } + + ATF_CHECK_ERRNO(EINVAL, setenv(NULL, "val", 1) == -1); + ATF_CHECK_ERRNO(EINVAL, setenv("", "val", 1) == -1); + ATF_CHECK_ERRNO(EINVAL, setenv("v=r", "val", 1) == -1); + ATF_CHECK_ERRNO(EINVAL, setenv("var", NULL, 1) == -1); + + ATF_CHECK(setenv("var", "=val", 1) == 0); + ATF_CHECK_STREQ(getenv("var"), "=val"); } ATF_TC_BODY(t_putenv, tc)