Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

The getenv function returns a pointer to a string associated with the matched list member. The string pointed to shall not be modified by the program , but may be overwritten by a subsequent call to the getenv function.

Consequently, it is best not to store this pointer, as it may be overwritten by a subsequent call to the getenv() function or invalidated as a result of changes made to the environment list through calls to putenv(), setenv(), or other means. Storing the pointer for later use can result in a dangling pointer or a pointer to incorrect data. This string should be referenced immediately and discarded, or ; if later use is anticipated, the string should be copied so that the copy may can be referenced safely at a later timesafetly referenced as needed.

The getenv() function is not thread-safe. Make sure to address any possible race conditions resulting from the use of this function.

...

This noncompliant code example compares the value of the TMP and TEMP environment variables to determine if they are the same. This code example is noncompliant because the string referenced by tmpvar may be overwritten as a result of the second call to the getenv() function. As a result, it is possible that both tmpvar and tempvar will compare equal even if the two environment variables have different values.

Code Block
bgColor#FFcccc
constchar *tmpvar;
char *tempvar;

tmpvar = getenv("TMP");
if (!tmpvar) return -1;
const char *tempvar = getenv("TEMP");
if (!tempvar) return -1;

if (strcmp(tmpvar, tempvar) == 0) {
  if (puts("TMP and TEMP are the same.\n") == EOF) {
    /* Handle Errorerror */
  }
}
else {
  if (puts("TMP and TEMP are NOT the same.\n") == EOF) {
    /* Handle Errorerror */
  }
}

This code example is noncompliant because the string referenced by tmpvar may be overwritten as a result of the second call to the getenv() function. As a result, it is possible that both tmpvar and tempvar will compare equal even if the two environment variables have different values.

Compliant Solution (Windows)

...

Code Block
bgColor#ccccff
char *tmpvar;
char *tempvar;
size_t requiredSize;

getenv_s(&requiredSize, NULL, 0, "TMP");
tmpvar = (char *)malloc(requiredSize * sizeof(char));
if (!tmpvar) {
   /* Handle error */
}
getenv_s(&requiredSize, tmpvar, requiredSize, "TMP" );

getenv_s(&requiredSize, NULL, 0, "TEMP");
tempvar = (char *)malloc(requiredSize * sizeof(char));
if (!tempvar) {
   free(tmpvar);
   tmpvar = NULL;
   /* Handle error */
}
getenv_s(&requiredSize, tempvar, requiredSize, "TEMP" );

if (strcmp(tmpvar, tempvar) == 0) {
  if (puts("TMP and TEMP are the same.\n") == EOF) {
    /* Handle Errorerror */
  }
}
else {
  if (puts("TMP and TEMP are NOT the same.\n") == EOF) {
    /* Handle Error */
  }
}
free(tmpvar);
tmpvar = NULL;
free(tempvar);
tempvar = NULL;

...

Code Block
bgColor#ccccff
char *tmpvar;
char *tempvar;
size_t len;

errno_t err = _dupenv_s(&tmpvar, &len, "TMP");
if (err) return -1;
errno_t err = _dupenv_s(&tempvar, &len, "TEMP");
if (err) {
  free(tmpvar);
  tmpvar = NULL;
  return -1;
}

if (strcmp(tmpvar, tempvar) == 0) {
  if (puts("TMP and TEMP are the same.\n") == EOF) {
    /* Handle Errorerror */
  }
}
else {
  if (puts("TMP and TEMP are NOT the same.\n") == EOF) {
    /* Handle Errorerror */
  }
}
free(tmpvar);
tmpvar = NULL;
free(tempvar);
tempvar = NULL;

...

Wiki Markup
POSIX provides the [{{strdup()}}|http://www.opengroup.org/onlinepubs/009695399/functions/strdup.html] function, which can make a copy of the environment variable string \[[Open Group 04|AA. C References#Open Group 04]\].  The {{strdup()}} function is also included in ISO/IEC PDTR 24731-2 \[[ISO/IEC PDTR 24731-2|AA. C References#ISO/IEC ISO/IEC PDTR 24731-2]\].

Code Block
bgColor#ccccff
char *tmpvar;
char *tempvar;

const char *temp = getenv("TMP");
if (temp != NULL) {
  tmpvar = strdup(temp);
  if (tmpvar == NULL) {
    /* Handle Errorerror */
  }
}
else {
  return -1;
}

temp = getenv("TEMP");
if (temp != NULL) {
  tempvar = strdup(temp);
  if (tempvar == NULL) {
    free(tmpvar);
    tmpvar = NULL;
    /* Handle Errorerror */
  }
}
else {
  free(tmpvar);
  tmpvar = NULL;
  return -1;
}

if (strcmp(tmpvar, tempvar) == 0) {
  if (puts("TMP and TEMP are the same.\n") == EOF) {
    /* Handle Errorerror */
  }
}
else {
  if (puts("TMP and TEMP are NOT the same.\n") == EOF) {
    /* Handle Errorerror */
  }
}
free(tmpvar);
tmpvar = NULL;
free(tempvar);
tempvar = NULL;

...

Code Block
bgColor#ccccff
char *tmpvar;
char *tempvar;

const char *temp = getenv("TMP");
if (temp != NULL) {
  tmpvar = (char *)malloc(strlen(temp)+1);
  if (tmpvar != NULL) {
    strcpy(tmpvar, temp);
  }
  else {
    /* Handle Errorerror */
  }
}
else {
  return -1;
}

temp = getenv("TEMP");
if (temp != NULL) {
  tempvar = (char *)malloc(strlen(temp)+1);
  if (tempvar != NULL) {
    strcpy(tempvar, temp);
  }
  else {
    free(tmpvar);
    tmpvar = NULL;
    /* Handle Errorerror */
  }
}
else {
  free(tmpvar);
  tmpvar = NULL;
  return -1;
}

if (strcmp(tmpvar, tempvar) == 0) {
  if (puts("TMP and TEMP are the same.\n") == EOF) {
    /* Handle Errorerror */
  }
}
else {
  if (puts("TMP and TEMP are NOT the same.\n") == EOF) {
    /* Handle Errorerror */
  }
}
free(tmpvar);
tmpvar = NULL;
free(tempvar);
tempvar = NULL;

...

Wiki Markup
\[[ISO/IEC 9899:1999|AA. C References#ISO/IEC 9899-1999]\] Section 7.20.4, "Communication with the environment"
\[[ISO/IEC PDTR 24731-2|AA. C References#ISO/IEC PDTR 24731-2-2007]\]
\[[MSDN|AA. C References#MSDN]\] [{{\_dupenv_s()}} and {{\_wdupenv_s()}}|http://msdn.microsoft.com/en-us/library/ms175774.aspx], [{{getenv_s()}}, {{\_wgetenv_s()}}|http://msdn.microsoft.com/en-us/library/tb2sfw2z(VS.80).aspx]
\[[Open Group 04|AA. C References#Open Group 04]\] Chapter 8, and "Environment Variables", [{{strdup}}|http://www.opengroup.org/onlinepubs/009695399/functions/strdup.html]
\[[Viega 03|AA. C References#Viega 03]\] Section 3.6, "Using Environment Variables Securely"

...