Skip to content

Commit

Permalink
fix getenv_s for NULL dest
Browse files Browse the repository at this point in the history
still return the length. GH rurban#109. Thanks @ulatekh
Also check if dmax is 0, and fix the error handling.
  • Loading branch information
rurban committed Oct 6, 2022
1 parent e5f0547 commit 153179e
Show file tree
Hide file tree
Showing 2 changed files with 84 additions and 16 deletions.
50 changes: 40 additions & 10 deletions src/os/getenv_s.c
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
*
* September 2017, Reini Urban
* January 2022, Reini Urban
* October 2022, Reini Urban
*
* Copyright (c) 2017,2022 by Reini Urban
* All rights reserved.
Expand Down Expand Up @@ -99,16 +100,42 @@ EXPORT errno_t _getenv_s_chk(size_t *restrict len, char *restrict dest,
const char *buf;
size_t len1;

if (destbos == BOS_UNKNOWN) {
CHK_DMAX_MAX("getenv_s", RSIZE_MAX_STR)
BND_CHK_PTR_BOUNDS(dest, dmax);
} else {
CHK_DEST_OVR("getenv_s", destbos)
if (likely(dest)) {
if (destbos == BOS_UNKNOWN) {
if (unlikely(dmax > RSIZE_MAX_STR)) {
goto err_dmax;
}
BND_CHK_PTR_BOUNDS(dest, dmax);
} else {
if (unlikely(dmax > destbos)) {
err_dmax:
if (len)
*len = 0;
invoke_safe_str_constraint_handler("getenv_s: dmax exceeds max",
(void *)dest, ESLEMAX);
return RCNEGATE(ESLEMAX);
}
}
}
else {
if (dmax != 0) { // with dest == NULL
if (len)
*len = 0;
invoke_safe_str_constraint_handler("getenv_s: dmax must be 0",
NULL, ESNULLP);
return ESNULLP;
}
}
if (unlikely(name == NULL)) {
if (len)
*len = 0;
handle_error(dest, dmax, "getenv_s: name is null", ESNULLP);
if (likely(dest)) {
handle_error(dest, dmax, "getenv_s: name is null", ESNULLP);
}
else {
invoke_safe_str_constraint_handler("getenv_s: name is null",
NULL, ESNULLP);
}
return ESNULLP;
}

Expand All @@ -120,11 +147,13 @@ EXPORT errno_t _getenv_s_chk(size_t *restrict len, char *restrict dest,
#endif

if (buf == NULL) {
if (likely(dest)) {
#ifdef SAFECLIB_STR_NULL_SLACK
memset(dest, 0, dmax);
memset(dest, 0, dmax);
#else
*dest = '\0';
*dest = '\0';
#endif
}
if (len)
*len = 0;
return -1;
Expand All @@ -136,10 +165,11 @@ EXPORT errno_t _getenv_s_chk(size_t *restrict len, char *restrict dest,
*len = 0;
handle_error(dest, dmax, "getenv_s: dmax is too small", ESNOSPC);
return RCNEGATE(ESNOSPC);
} else if (dest) {
} else {
if (len)
*len = len1;
strcpy_s(dest, dmax, buf);
if (dest)
strcpy_s(dest, dmax, buf);
}

return EOK;
Expand Down
50 changes: 44 additions & 6 deletions tests/test_getenv_s.c
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/*------------------------------------------------------------------
* test_getenv_s
* File 'os/getenv_s.c'
* Lines executed:100.00% of 29
* Lines executed:95.24% of 42
*
*------------------------------------------------------------------
*/
Expand Down Expand Up @@ -31,6 +31,8 @@ int test_getenv_s(void) {
const char *name = "PATH";

/*--------------------------------------------------*/
/* Note that native getenv_s with MSVC looks completely broken for
most cases. Maybe we should force our implementation there. */

#ifndef HAVE_CT_BOS_OVR
EXPECT_BOS("empty name")
Expand All @@ -40,22 +42,40 @@ int test_getenv_s(void) {
use_msvcrt = false;
}
ERR_MSVC(ESNULLP, 0);
#endif
ind = len;
if (!use_msvcrt) {
INDCMP(!= 0);
}

rc = getenv_s(&len, NULL, 0, name);
ERR_MSVC(0, EINVAL);
rc = getenv_s(&len, NULL, 0, NULL);
ERR_MSVC(ESNULLP, EINVAL);
ind = len;
if (!use_msvcrt) {
INDCMP(!= 0);
}
#endif

/*--------------------------------------------------*/
/* cases where name exists */

rc = getenv_s(&len, dest, 0, name);
str2 = getenv(name); // for PATH
rc = getenv_s(&len, NULL, 0, name);
ERR_MSVC(0, EINVAL);
ind = strlen(str2);
if (!use_msvcrt) {
INDCMP(!= (int)len);
}

/*--------------------------------------------------*/

#ifndef HAVE_CT_BOS_OVR
EXPECT_BOS("dest overflow")
rc = getenv_s(&len, dest, RSIZE_MAX_STR + 1, name);
ERR_MSVC(ESLEMAX, 0);
ind = len;
if (!use_msvcrt) {
INDCMP(!= 0);
}
#endif

/*--------------------------------------------------*/
Expand All @@ -72,7 +92,6 @@ int test_getenv_s(void) {

rc = getenv_s(&len, dest, LEN, name);
ERR(EOK);
str2 = getenv(name);
EXPSTR(dest, str2);
ind = strlen(str2);
if (!use_msvcrt) {
Expand All @@ -83,7 +102,26 @@ int test_getenv_s(void) {
ERR_MSVC(EOK, EINVAL);
EXPSTR(dest, str2);

rc = getenv_s(&len, dest, LEN, name);
ERR(EOK);
EXPSTR(dest, str2);
ind = strlen(str2);
if (!use_msvcrt) {
INDCMP(!= (int)len);
}

#ifndef HAVE_CT_BOS_OVR
EXPECT_BOS("dest overflow or empty")
rc = getenv_s(&len, NULL, LEN, name);
ERR_MSVC(ESNULLP, EINVAL); // with NULL dmax must be 0
ind = len;
if (!use_msvcrt) {
INDCMP(!= 0);
}
#endif

/*--------------------------------------------------*/
/* cases where name does not exist */

rc = getenv_s(NULL, dest, LEN, "c#hewhc&wehc%erwhc$weh");
ERR_MSVC(-1, EINVAL);
Expand Down

0 comments on commit 153179e

Please sign in to comment.