Versions Compared

Key

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

...

Function

Successful Return

Error Return

aligned_alloc()

Pointer to space

NULL

asctime_s()

0

Nonzero

at_quick_exit()

0

Nonzero

atexit()

0

Nonzero

bsearch()

Pointer to matching element

NULL

bsearch_s()

Pointer to matching element

NULL

btowc()

Converted wide character

WEOF

c16rtomb()

Number of bytes

(size_t)(-1)

c32rtomb()

Number of bytes

(size_t)(-1)

calloc()

Pointer to space

NULL

clock()

Processor time

(clock_t)(-1)

cnd_broadcast()

thrd_success

thrd_error

cnd_init()

thrd_success

thrd_nomem or thrd_error

cnd_signal()

thrd_success

thrd_error

cnd_timedwait()

thrd_success

thrd_timedout or thrd_error

cnd_wait()

thrd_success

thrd_error

ctime_s()

0

Nonzero

fclose()

0

EOF (negative)

fflush()

0

EOF (negative)

fgetc()

Character read

EOF1

fgetpos()

0

Nonzero, errno > 0

fgets()

Pointer to string

NULL

fgetwc()

Wide character read

WEOF1

fopen()

Pointer to stream

NULL

fopen_s()

0

Nonzero

fprintf()

Number of characters (nonnegative)

Negative

fprintf_s()

Number of characters (nonnegative)

Negative

fputc()

Character written

EOF2

fputs()

Nonnegative

EOF (negative)

fputwc()Wide character written WEOF

fputws()

Nonnegative

EOF (negative)

fread()

Elements read

Elements read

freopen()

Pointer to stream

NULL

freopen_s()

0

Nonzero

fscanf()

Number of conversions (nonnegative)

EOF (negative)

fscanf_s()

Number of conversions (nonnegative)

EOF (negative)

fseek()

0

Nonzero

fsetpos()

0

Nonzero, errno > 0

ftell()

File position

−1L, errno > 0

fwprintf()

Number of wide characters (nonnegative)

Negative

fwprintf_s()

Number of wide characters (nonnegative)

Negative

fwrite()

Elements written

Elements written

fwscanf()

Number of conversions (nonnegative)

EOF (negative)

fwscanf_s()

Number of conversions (nonnegative)

EOF (negative)

getc()

Character read

EOF1

getchar()

Character read

EOF1

getenv()

Pointer to string

NULL

getenv_s()

Pointer to string

NULL

gets_s()

Pointer to string

NULL

getwc()

Wide character read

WEOF

getwchar()

Wide character read

WEOF

gmtime()

Pointer to broken-down time

NULL

gmtime_s()

Pointer to broken-down time

NULL

localtime()

Pointer to broken-down time

NULL

localtime_s()

Pointer to broken-down time

NULL

malloc()

Pointer to space

NULL

mblen(), s != NULL

Number of bytes

−1

mbrlen(), s != NULL

Number of bytes or status

(size_t)(-1)

mbrtoc16()

Number of bytes or status

(size_t)(-1), errno == EILSEQ

mbrtoc32()

Number of bytes or status

(size_t)(-1), errno == EILSEQ

mbrtowc(), s != NULL

Number of bytes or status

(size_t)(-1), errno == EILSEQ

mbsrtowcs()

Number of non-null elements

(size_t)(-1), errno == EILSEQ

mbsrtowcs_s()

0

Nonzero

mbstowcs()

Number of non-null elements

(size_t)(-1)

mbstowcs_s()

0

Nonzero

mbtowc(), s != NULL

Number of bytes

−1

memchr()

Pointer to located character

NULL

mktime()

Calendar time

(time_t)(-1)

mtx_init()

thrd_success

thrd_error

mtx_lock()

thrd_success

thrd_error

mtx_timedlock()

thrd_success

thrd_timedout or thrd_error

mtx_trylock()

thrd_success

thrd_busy or thrd_error

mtx_unlock()

thrd_success

thrd_error

printf_s()

Number of characters (nonnegative)

Negative

putc()

Character written

EOF2

putwc()

Wide character written

WEOF

raise()

0

Nonzero

realloc()

Pointer to space

NULL

remove()

0

Nonzero

rename()

0

Nonzero

setlocale()

Pointer to string

NULL

setvbuf()

0

Nonzero

scanf()

Number of conversions (nonnegative)

EOF (negative)

scanf_s()

Number of conversions (nonnegative)

EOF (negative)

signal()

Pointer to previous function

SIG_ERR, errno > 0

snprintf()

Number of characters that would be written (nonnegative)

Negative

snprintf_s()

Number of characters that would be written (nonnegative)

Negative

sprintf()

Number of non-null characters written

Negative

sprintf_s()

Number of non-null characters written

Negative

sscanf()

Number of conversions (nonnegative)

EOF (negative)

sscanf_s()

Number of conversions (nonnegative)

EOF (negative)

strchr()

Pointer to located character

NULL

strerror_s()

0

Nonzero

strftime()

Number of non-null characters

0

strpbrk()

Pointer to located character

NULL

strrchr()

Pointer to located character

NULL

strstr()

Pointer to located string

NULL

strtod()

Converted value

0, errno == ERANGE

strtof()

Converted value

0, errno == ERANGE

strtoimax()

Converted value

INTMAX_MAX or INTMAX_MIN, errno == ERANGE

strtok()

Pointer to first character of a token

NULL

strtok_s()

Pointer to first character of a token

NULL

strtol()

Converted value

LONG_MAX or LONG_MIN, errno == ERANGE

strtold()

Converted value

0, errno == ERANGE

strtoll()

Converted value

LLONG_MAX or LLONG_MIN, errno == ERANGE

strtoumax()

Converted value

UINTMAX_MAX, errno == ERANGE

strtoul()

Converted value

ULONG_MAX, errno == ERANGE

strtoull()

Converted value

ULLONG_MAX, errno == ERANGE

strxfrm()

Length of transformed string

>= n

swprintf()

Number of non-null wide characters

Negative

swprintf_s()

Number of non-null wide characters

Negative

swscanf()

Number of conversions (nonnegative)

EOF (negative)

swscanf_s()

Number of conversions (nonnegative)

EOF (negative)

thrd_create()

thrd_success

thrd_nomem or thrd_error

thrd_detach()

thrd_success

thrd_error

thrd_join()

thrd_success

thrd_error

thrd_sleep()

0

negative

time()

Calendar time

(time_t)(-1)

timespec_get()

Base

0

tmpfile()

Pointer to stream

NULL

tmpfile_s()

0

Nonzero

tmpnam()

Non-null pointer

NULL

tmpnam_s()

0

Nonzero

tss_create()

thrd_success

thrd_error

tss_get()

Value of thread-specific storage

0

tss_set()

thrd_success

thrd_error

ungetc()

Character pushed back

EOF (see below)

ungetwc()

Character pushed back

WEOF

vfprintf()

Number of characters (nonnegative)

Negative

vfprintf_s()

Number of characters (nonnegative)

Negative

vfscanf()

Number of conversions (nonnegative)

EOF (negative)

vfscanf_s()

Number of conversions (nonnegative)

EOF (negative)

vfwprintf()

Number of wide characters (nonnegative)

Negative

vfwprintf_s()

Number of wide characters (nonnegative)

Negative

vfwscanf()

Number of conversions (nonnegative)

EOF (negative)

vfwscanf_s()

Number of conversions (nonnegative)

EOF (negative)

vprintf_s()

Number of characters (nonnegative)

Negative

vscanf()

Number of conversions (nonnegative)

EOF (negative)

vscanf_s()

Number of conversions (nonnegative)

EOF (negative)

vsnprintf()

Number of characters that would be written (nonnegative)

Negative

vsnprintf_s()

Number of characters that would be written (nonnegative)

Negative

vsprintf()

Number of non-null characters (nonnegative)

Negative

vsprintf_s()

Number of non-null characters (nonnegative)

Negative

vsscanf()

Number of conversions (nonnegative)

EOF (negative)

vsscanf_s()

Number of conversions (nonnegative)

EOF (negative)

vswprintf()

Number of non-null wide characters

Negative

vswprintf_s()

Number of non-null wide characters

Negative

vswscanf()

Number of conversions (nonnegative)

EOF (negative)

vswscanf_s()

Number of conversions (nonnegative)

EOF (negative)

vwprintf_s()

Number of wide characters (nonnegative)

Negative

vwscanf()

Number of conversions (nonnegative)

EOF (negative)

vwscanf_s()

Number of conversions (nonnegative)

EOF (negative)

wcrtomb()

Number of bytes stored

(size_t)(-1)

wcschr()

Pointer to located wide character

NULL

wcsftime()

Number of non-null wide characters

0

wcspbrk()

Pointer to located wide character

NULL

wcsrchr()

Pointer to located wide character

NULL

wcsrtombs()

Number of non-null bytes

(size_t)(-1), errno == EILSEQ

wcsrtombs_s()

0

Nonzero

wcsstr()

Pointer to located wide string

NULL

wcstod()

Converted value

0, errno == ERANGE

wcstof()

Converted value

0, errno == ERANGE

wcstoimax()

Converted value

INTMAX_MAX or INTMAX_MIN, errno == ERANGE

wcstok()

Pointer to first wide character of a token

NULL

wcstok_s()

Pointer to first wide character of a token

NULL

wcstol()

Converted value

LONG_MAX or LONG_MIN, errno == ERANGE

wcstold()

Converted value

0, errno == ERANGE

wcstoll()

Converted value

LLONG_MAX or LLONG_MIN, errno == ERANGE

wcstombs()

Number of non-null bytes

(size_t)(-1)

wcstombs_s()

0

Nonzero

wcstoumax()

Converted value

UINTMAX_MAX, errno == ERANGE

wcstoul()

Converted value

ULONG_MAX, errno == ERANGE

wcstoull()

Converted value

ULLONG_MAX, errno == ERANGE

wcsxfrm()

Length of transformed wide string

>= n

wctob()

Converted character

EOF

wctomb(), s != NULL

Number of bytes stored

−1

wctomb_s(), s != NULL

Number of bytes stored

−1

wctrans()

Valid argument to towctrans

0

wctype()

Valid argument to iswctype

0

wmemchr()

Pointer to located wide character

NULL

wprintf_s()

Number of wide characters (nonnegative)

Negative

wscanf()

Number of conversions (nonnegative)

EOF (negative)

wscanf_s()

Number of conversions (nonnegative)

EOF (negative)

When FIO35-C. Use feof() and ferror() to detect end-of-file and file errors when sizeof(int) == sizeof(char) applies, callers shall determine the success or failure of the functions in this table as follows:

...

Code Block
bgColor#ccccFF
langc
#include <locale.h>
#include <stdlib.h>
 
int utf8_to_wcs(wchar_t *wcs, size_t n, const char *utf8,
                size_t *size) {
  if (NULL == size) {
    return -1;
  }
  const char *save = setlocale(LC_CTYPE, "en_US.UTF-8");
  if (NULL == save) {
    return -1;
  }

  *size = mbstowcs(wcs, utf8, n);
  if (NULL == setlocale(LC_CTYPE, save)) {
    return -1;
  }
  return 0;
}

Noncompliant Code Example (

...

In this noncompliant example, the function signal() is invoked to install a handler for the SIGINT signal. The signal() function returns a pointer to the previously installed handler on success and the value SIG_ERR on failure. However, because the caller fails to check for errors, when signal() fails, the function may proceed with the lengthy computation without the ability to interrupt it.

Code Block
bgColor#FFcccc
langc
#include <signal.h>
 
volatile sig_atomic_t interrupted;

void handle_interrupt(int signo) {
  interrupted = 1;
}

int f(void) {
  int result = 0;

  signal(SIGINT, handle_interrupt);

  while (0 == result && 0 == interrupted) {
    /* Perform a lengthy computation */
  }

  /* Indicate success or failure */
  return interrupted ? -1 : result;
}

Compliant Solution (signal())

This compliant solution checks the value returned by the signal() function and avoids performing the lengthy computation when signal() fails. The calling function also takes care to restore the disposition for the SIGINT signal to its initial setting before returning control to the caller.

Code Block
bgColor#ccccFF
langc
#include <signal.h>
 
volatile sig_atomic_t interrupted;

void handle_interrupt(int signo) {
  interrupted = 1;
}

int f(void) {
  int result = 0;
  void (*saved_handler)(int);
  saved_handler = signal(SIGINT, handle_interrupt);

  if (SIG_ERR == (int)saved_handler) {
    /* Indicate failure */
    return -1;
  }

  while (0 == result && 0 == interrupted) {
    /* Perform a lengthy computation */
  }

  if (SIG_ERR == signal(SIGINT, saved_handler)) {
    return -1;
  }

  /* Indicate success or failure */
  return interrupted ? -1 : result;
}

Noncompliant Code Example (calloc())

In this noncompliant code example, temp_num, tmp2, and num_of_records are derived from a tainted source. Consequently, an attacker can easily cause calloc() to fail by providing a large value for num_of_records

...

This code example does comply with MEM04-C. Do not perform zero-length allocations.

Compliant Solution (realloc())

...

...