Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.
Comment: Added explanatory text. Also, eliminated errors from examples because it is better not to have obvious errors in compliant solutions even when demonstrating error handling code.

...

  1. A pointer to a character string describing the runtime-constraint violation.
  2. A null pointer or a pointer to an implementation defined object.
  3. If the function calling the handler has a return type declared as errno_t, the return value of the function is passed. Otherwise, a positive value of type
    errno_t is passed.

The implementation has a default constraint handler that is used if no calls to the set_constraint_handler_s() function have been made or the handler argument to set_constraint_handler_s() is a null pointer. The behavior of the default handler is implementation-defined, and it may cause the program to exit or abort.

...

In this non-compliant example no set_constraint_handler, the strcpy_s() has been called so function is called, but no runtime-constraint handler has been explicitly registered. As a result, the implementation defined default handler will be called on a run-time error. This will result in inconsistent behavior across implementations and possible termination of the program instead of a graceful exit.

Code Block
bgColor#FFCCCC
errno_t function(char* dst1, size_t size){
  char src1[100] = "hello";

  if (strcpy_s( dst1, sizeof(dst1)size, src1) != 0) {
    return -1;
  }
  /* ... */
  return 0;
}

This will result in inconsistent behavior across implementations and possible termination of the program instead of a graceful exit. The implementation defined default handler performs a default action consistent with a particular implementation. However, this may not be the desired action, and because the behavior is implementation-defined, it is not guaranteed to be the same on all implementations.

As a result, in is generally prudent to explicitly install a run-time constraint handler to ensure consistent behavior across implementations.

Compliant Code Example (TR24731-1)

This compliant solution explicitly installs a runtime-constraint handler by invoking the set_constraint_handler() function. This would typically be performed during system initialization, and before any functions that used the mechanism were invoked.

Code Block
bgColor#ccccff
constraint_handler_t handle_errors() {
  /* define what to do whenhandle runtime-constraint error occurs */
}

/*...*/

set_constraint_handler(handle_errors);

/*...*/

/* Returns zero on success */
errno_t function(char* dst1, size_t size){
  char src1[100] = "hello";

  if (strcpy_s( dst1, sizeof(dst1)size, src1) != 0) {
    return -1;
  }
  /* ... */
  return 0;
}

Compliant Code Example (Visual Studio2008Studio 2008/.NET Framework 3.5)

Unfortunately, although the ISO/IEC TR 24731-1 functions were created by Microsoft, currently available versions of Microsoft Visual Studio do not support the same interface defined by the TR for installing run-time constraint handlers. Visual Studio calls these functions "invalid parameter handlers" and they are installed by calling the _set_invalid_parameter_handler() function. The signature of the handler is also significantly different.

Code Block
bgColor#ccccff
_invalid_parameter_handler handle_errors(
   const wchar_t* expression,
   const wchar_t* function,
   const wchar_t* file,
   unsigned int line,
   uintptr_t pReserved
)
 {
  /*define whathandle to do when error occursinvalid parameter */
}

/*...*/

_set_invalid_parameter_handler(handle_errors)

/*...*/

errno_t function(char *dst1, size_t size) {
  char src1[100] = "hello";

  if (strcpy_s( dst1, sizeof(dst1)size, src1) != 0) {
    return -1;
  }
  /* ...  */
  return 0;
}

...

The TR24731-1 standard indicates that if no constraint handler is set, a default one executes when errors arise. The default handler is implementation-defined and "may cause the program to exit or abort". Therefore using constraint handlers prevents a program from immediately crashingIt is important to understand the behavior of the default handler for all implementations being used, and replace it if the behavior is inappropriate for the application.

Recommendation

Severity

Likelihood

Remediation Cost

Priority

Level

ERR03-A

low

unlikely

low

P3

L3

...