﻿# V2671\. MISRA\. Pointers returned by the function 'localeconv' / 'getenv' / 'setlocale' / 'strerror' should be used as if they have pointer to const\-qualified type\.

This diagnostic rule is based on the [MISRA](https://misra.org.uk/) \(Motor Industry Software Reliability Association\) software development guidelines\.

This diagnostic rule is relevant only for C\.

Pointers returned by [`localeconv`](https://cppreference.com/w/c/locale/localeconv.html), [`getenv`](https://en.cppreference.com/w/c/program/getenv.html), [`setlocale`](https://en.cppreference.com/w/c/locale/setlocale.html), and [`strerror`](https://en.cppreference.com/w/c/string/byte/strerror.html) functions should be used as pointers to the `const`\-qualified type\.

According to the C standard, behavior is undefined \(C23, Annex J, J\.2, Section [119](https://open-std.org/JTC1/SC22/WG14/www/docs/n3220.pdf#page=607), [121](https://open-std.org/JTC1/SC22/WG14/www/docs/n3220.pdf#page=607), [189](https://open-std.org/JTC1/SC22/WG14/www/docs/n3220.pdf#page=610)\) if a program modifies:

* an object of the [`lconv`](https://cppreference.com/w/c/locale/lconv.html) type via a pointer returned by `localeconv`;
* a string via a pointer returned by `getenv`, `setlocale`, or `strerror`\.

The example:

```cpp
char *GetPath(void)
{
  char *path = getenv("PATH"); // <=
  if (path == NULL)
  {
    return NULL;
  }

  for (size_t i = 0; i < strlen(path); ++i)
  {
    if (path[i] == '\\')
    {
      path[i] = '/';
    }
  }

  return path;
}
```

The value is obtained from the `PATH` environment variable using the `getenv` function\. It returns a pointer to an internal buffer, and the code then replaces every `\` character with `/` directly in that buffer\. The modified buffer is returned from the function via a pointer\. Since standard libraries use an internal buffer, other functions can use it\. Its direct modification leads to undefined behavior\.

A correct implementation involves copying the string into a separate buffer, which is then modified:

```cpp
char *GetPath(void)
{
  const char * const path = getenv("PATH");
  if (path == NULL)
  {
    return NULL;
  }

  size_t len = strlen(path);
  char *buffer = malloc((len + 1) * sizeof(char));
  if (buffer == NULL)
  {
    return NULL;
  }

  buffer[len] = '\0';

  for (size_t i = 0; i < len; ++i)
  {
    if (path[i] == '\\')
    {
      buffer[i] = '/';
    }
    else
    {
      buffer[i] = path[i];
    }
  }

  return buffer;
}
```