YouTip LogoYouTip

C Safe Func

In C language, to improve code security, especially to prevent common security issues such as buffer overflows, the C11 standard introduced some **secure functions**, also known as **Annex K** standard library functions. These secure functions are enhanced versions of standard string and memory operation functions, providing better error detection and handling by adding parameters (such as buffer size). **Characteristics of Secure Functions:** * **Buffer Size Check**: All secure functions require passing the size parameter of the target buffer to prevent buffer overflow. * **Return Value Check**: Most functions return an error code of type `errno_t`, allowing checking whether the function executed successfully. * **Better Error Handling**: When the buffer size is insufficient or other problems occur, these functions return error codes and attempt to clear or initialize the output buffer. Secure functions are well supported in compilers like Visual Studio, but may not be available in some older versions of compilers, so attention to compatibility is needed. Below are common secure functions in C and their comparison with traditional functions: ### 1、String Operation Secure Functions strcpy_s: Secure version of strcpy, copies string and checks target buffer size. errno_t strcpy_s(char *dest, rsize_t destsz, const char *src); strcat_s: Secure version of strcat, appends source string to end of target string and checks buffer size. errno_t strcat_s(char *dest, rsize_t destsz, const char *src); strncpy_s: Secure version of strncpy, copies up to n characters and checks buffer size. errno_t strncpy_s(char *dest, rsize_t destsz, const char *src, rsize_t count); strncat_s: Secure version of strncat, appends up to n characters to end of target string and checks buffer size. errno_t strncat_s(char *dest, rsize_t destsz, const char *src, rsize_t count); strtok_s: Secure version of strtok, introduces context parameter to solve thread safety issues. char *strtok_s(char *str, const char *delim, char **context); ### 2、Formatted Output Secure Functions sprintf_s: Secure version of sprintf, checks buffer size when formatting output to string. int sprintf_s(char *buffer, rsize_t buffer_size, const char *format, ...); snprintf_s: Secure version of snprintf, limits character count during formatting and checks buffer size. int snprintf_s(char *buffer, rsize_t buffer_size, const char *format, ...); vsprintf_s: Secure version of vsprintf, accepts va_list parameter list and checks buffer size. int vsprintf_s(char *buffer, rsize_t buffer_size, const char *format, va_list argptr); ### 3、Memory Operation Secure Functions memcpy_s: Secure version of memcpy, checks target buffer size when copying memory regions. errno_t memcpy_s(void *dest, rsize_t destsz, const void *src, rsize_t count); memmove_s: Secure version of memmove, copies memory regions, allows overlapping, and checks target buffer size. errno_t memmove_s(void *dest, rsize_t destsz, const void *src, rsize_t count); memset_s: Secure version of memset, fills specified characters into memory block and checks buffer size. errno_t memset_s(void *dest, rsize_t destsz, int ch, rsize_t count); ### 4、Other Common Secure Functions _itoa_s and _ultoa_s: Secure versions of integer conversion functions, check target buffer size when converting integers to strings. errno_t _itoa_s(int value, char *buffer, size_t buffer_size, int radix);errno_t _ultoa_s(unsigned long value, char *buffer, size_t buffer_size, int radix); _strlwr_s and _strupr_s: Secure versions that convert strings to lowercase or uppercase. errno_t _strlwr_s(char *str, size_t numberOfElements);errno_t _strupr_s(char *str, size_t numberOfElements); * * * ## Example The following are examples of using C secure functions for string operations and memory operations, demonstrating how they avoid common buffer overflow issues and provide a safer programming approach. ### Example 1: strcpy_s and strcat_s ## Example #include #include int main(){ char dest;// Target buffer size is 20 const char*src ="Hello, World!"; // Use strcpy_s to copy src to dest if(strcpy_s(dest,sizeof(dest), src)!=0){ printf("strcpy_s failed!n"); return 1;// Return error code }else{ printf("After strcpy_s: %sn", dest); } // Use strcat_s to append " C Language" to dest const char*appendStr =" C Language"; if(strcat_s(dest,sizeof(dest), appendStr)!=0){ printf("strcat_s failed!n"); return 1;// Return error code }else{ printf("After strcat_s: %sn", dest); } return 0; } Output: After strcpy_s: Hello, World! strcat_s failed! In the above code, strcpy_s successfully copied the string "Hello, World!" to dest, but since the size of dest is 20, it is not enough to hold "Hello, World! C Language", so strcat_s will detect insufficient buffer and return an error code. ### Example 2: memcpy_s ## Example #include #include int main(){ char src[]="Sensitive Data"; char dest;// Target buffer size is 15 // Use memcpy_s to copy data to dest if(memcpy_s(dest,sizeof(dest), src,strlen(src)+1)!=0){ printf("memcpy_s failed!n"); return 1;// Return error code }else{ printf("After memcpy_s: %sn", dest); } return 0; } Output: After memcpy_s: Sensitive Data In this example, memcpy_s checks whether the target buffer dest is large enough to hold the data from src, including the null character at the end of the string. If destsz is less than strlen(src) + 1, the function will return an error and not perform the memory copy. ### Example 3: strtok_s ## Example #include #include int main(){ char str[]="apple,orange,banana"; char*token; char*context = NULL; // Use strtok_s to split string token = strtok_s(str,",",&context); while(token != NULL){ printf("Token: %sn", token); token = strtok_s(NULL,",",&context); } return 0; } Output: Token: apple Token: orange Token: banana In this example, when strtok_s splits the string, it uses the context parameter to save context information, thereby avoiding the thread-unsafe problem of strtok. ### Example 4: sprintf_s ## Example #include int main(){ char buffer; int num =42; const char*str ="Hello"; // Use sprintf_s to format string and check buffer size if(sprintf_s(buffer,sizeof(buffer),"Number: %d, String: %s", num, str)<0){ printf("sprintf_s failed!n"); return 1;// Return error code }else{ printf("Formatted String: %sn", buffer); } return 0; } Output: Formatted String: Number: 42, String: Hello Here, when sprintf_s formats the string, it accepts the buffer size as a parameter. If the formatted string exceeds the size of the buffer, the function will return an error, thus avoiding buffer overflow. The above examples demonstrate the use of C secure functions for string copying, concatenation, memory copying, string splitting, and formatted output. These functions provide buffer size checking, significantly improving code security. * * * ## Reference Manual Secure functions are mainly designed to prevent buffer overflow, a type of vulnerability that usually originates from functions not checking the size of the target buffer. Currently, the mainstream secure function standards mainly come from the C11 standard's Annex K (Bounds-checking interfaces), as well as enhanced versions provided by various operating systems (such as Windows' MSVC CRT). The following table shows the reference table for C secure functions. ### 1、String Processing This is the most prone to overflow area, and secure functions usually require passing the size of the target buffer. | Original Function (Insecure) | Secure Alternative | Main Improvements | | --- | --- | --- | | `strcpy` | `strcpy_s` | Adds target buffer size parameter; if source string is too long, calls constraint handler. | | `strcat` | `strcat_s` | Adds target buffer remaining space parameter to prevent out-of-bounds during concatenation. | | `strncpy` | `str
← Nodejs Build AppHtml5 Web Api Indexeddb β†’