
Related functions, such as those that make up a library, should provide consistent and usable interfaces. Ralph Waldo Emerson might have said, "A foolish consistency is the hobgoblin of little minds," but inconsistencies in functional interfaces or behavior can lead to erroneous use so we understand this to be a "wise consistency". One aspect of providing a consistent interface is to provide a consistent and usable error checking mechanism API04-C. Provide a consistent and usable error checking mechanism.
Noncompliant Code Example (interface)
It is not necessary to go beyond the standard C library to find examples of inconsistent interfaces. This is because the standard library is a fusion of multiple different libraries with various styles and various levels of rigor.
For example, the fputs()
defined in §7.19.7 is closely related to the fprintf()
defined in §7.19.6. However, the fputs()
has the file handle at the end and fprintf()
at the beginning as shown by their function declarations.
int fputs(const char * restrict s, FILE * restrict stream); int fprintf(FILE * restrict stream, const char * restrict format, ...);
The argument order can be easily rearranged using macros, for example:
#include <stdio.h> #define fputs(X,Y) fputs(Y,X)
However, according to clause 7.1.3 of C99, the behavior of a program that defines a symbol, including a macro, with the same name as that of a standard library function, type, macro, or other reserved identifier, is undefined.
Doing so without running afoul of the C requirement mentioned above makes the code difficult to read, for example, by causing confusion when moving between code that follows this convention and code that does not. In effect, it becomes impossible to modify an interface once that interface has been broadly adopted. Consequently, it is important to get the interface design right the first time.
Compliant Solution (interface)
The POSIX ® threads library [[Butenhof 97]] defines an interface that is both consistent and fits in with established conventions from the rest of the POSIX library. For example, all initialization functions follow the same consistent pattern of the first argument being a pointer to the object to initialize with the subsequent arguments, if any, optionally providing additional attributes for the initialization:
/* initialization of Pthread attribute objects */ int pthread_condattr_init(pthread_condattr_t *); int pthread_mutexattr_init(pthread_mutexattr_t *); int pthread_rwlockattr_init(pthread_rwlockattr_t *); ... /* initialization of Pthread objects using attributes */ int pthread_cond_init(pthread_cond_t * restrict, const pthread_condattr_t * restrict); int pthread_mutex_init(pthread_mutex_t * restrict, const pthread_mutexattr_t * restrict); int pthread_rwlock_init(pthread_rwlock_t * restrict, const pthread_rwlockattr_t * restrict); ...
Function arguments that refer to objects that aren't modified are declared const
. Because the object pointed to by the first argument is modified by the function, it is not const
. For functions that implement a data abstraction (see DCL12-C. Implement abstract data types using opaque types), it is reasonable to define the handle for the data abstraction as the initial parameter. Finally, initialization functions that accept a pointer to an attribute object allow it to be NULL
as an indication that a reasonable default be used.
Noncompliant Code Example (behavior)
The shared folder and file copy functions in the VMware virtual infrastructure (VIX) API are inconsistent in the set of characters they allow in folder names. As a result, you can create a shared folder that you subsequently can't use in a file copy function such as VixVM_CopyFileFromHostToGuest()
.
Compliant Solution (behavior)
Try to be consistent in the behavior of related functions that perform operations on common objects, so that an object created or modified by one function can be successfully processed by a downstream invocation of a related function.
Risk Assessment
Failure to do so can result in type errors in the program.
Rule |
Severity |
Likelihood |
Remediation Cost |
Priority |
Level |
---|---|---|---|---|---|
API04-C |
medium |
unlikely |
medium |
P2 |
L3 |
Related Vulnerabilities
Search for vulnerabilities resulting from the violation of this rule on the CERT website.
Other Languages
This rule appears in the C++ Secure Coding Standard as cplusplus:API04-CPP. Provide a consistent and usable error checking mechanism.
References
VMware 07 VIX API Version 1.1.1 (for Workstation 6.0.1) Release Notes. 16-August-2007
[[Burch 06]]
[[CERT 06c]]
[[ISO/IEC 9945:2003]]
[[ISO/IEC 9899:1999]] Section 7.21, "String handling <string.h
>"
[[ISO/IEC 23360-1:2006]]
[[ISO/IEC TR 24731-1:2007]]
[[ISO/IEC PDTR 24731-2]]
[[Miller 99]]
[[MISRA 04]] Rule 20.4
[[Seacord 05a]] Chapter 2, "Strings"
13. Application Programming Interfaces (API) API04-C. Provide a consistent and usable error checking mechanism