Safe, buffer-size-aware replacements for the standard C string library.
Every function accepts the allocated size of each buffer argument and always null-terminates output
on success, eliminating the class of bugs caused by strncpy(), unbounded strcpy(), and similar
functions that can silently truncate or omit the null terminator.
Dependencies | Notes | Configuration | API Summary | Function Reference
↑ Dependencies
↑ Notes
- All functions require the total allocated size of every buffer argument, not the string length.
- All functions return
falseif the operation cannot complete safely; the destination buffer is never partially modified whenfalseis returned. - A successful
SSFStrCpy()orSSFStrCat()always null-terminates the destination, unlikestrncpy(). SSFStrTok()is re-entrant; it does not use any global state.
↑ Configuration
This module has no compile-time configuration options in ssfoptions.h.
↑ API Summary
| Symbol | Kind | Description |
|---|---|---|
SSFCStrIn_t |
Typedef | const char *; annotates read-only string inputs |
SSFCStrOut_t |
Typedef | char *; annotates writable string output buffers |
SSF_STR_CASE_LOWER |
Enum value | SSFSTRCase_t constant; convert to lowercase |
SSF_STR_CASE_UPPER |
Enum value | SSFSTRCase_t constant; convert to uppercase |
SSFSTRCase_t |
Enum | Case-conversion direction for SSFStrToCase() |
| Function | Description | |
|---|---|---|
| e.g. | bool SSFStrIsValid(cstr, cstrSize) |
Return true if a null terminator exists within the buffer |
| e.g. | bool SSFStrLen(cstr, cstrSize, cstrLenOut) |
Return the length of a bounded C string |
| e.g. | bool SSFStrCpy(dst, dstSize, dstLenOut, src, srcSize) |
Safe string copy; always null-terminates on success |
| e.g. | bool SSFStrCat(dst, dstSize, dstLenOut, src, srcSize) |
Safe string concatenation; always null-terminates on success |
| e.g. | bool SSFStrCmp(cstr1, cstr1Size, cstr2, cstr2Size) |
Safe string equality comparison |
| e.g. | bool SSFStrToCase(cstrOut, cstrOutSize, toCase) |
Convert string to upper or lower case in-place |
| e.g. | bool SSFStrStr(cstr, cstrSize, matchStrOptOut, substr, substrSize) |
Find the first occurrence of a substring |
| e.g. | bool SSFStrTok(cstr, cstrSize, tokenOut, tokenSize, tokenLenOut, delims, delimsSize) |
Extract the next token from a string |
↑ Function Reference
bool SSFStrIsValid(SSFCStrIn_t cstr, size_t cstrSize);Checks that a null terminator (\0) exists somewhere within cstr[0..cstrSize-1]. Use this to
validate externally-sourced buffers before passing them to other SSFStr functions.
| Parameter | Direction | Type | Description |
|---|---|---|---|
cstr |
in | SSFCStrIn_t |
Pointer to the buffer to validate. Must not be NULL. |
cstrSize |
in | size_t |
Total allocated size of the buffer in bytes. |
Returns: true if a null terminator is found within cstrSize bytes; false otherwise.
char buf[8] = {'h', 'i', '\0', 0, 0, 0, 0, 0};
if (SSFStrIsValid(buf, sizeof(buf)))
{
/* buf contains a valid null-terminated string */
}
char bad[4] = {'a', 'b', 'c', 'd'}; /* no null terminator */
if (SSFStrIsValid(bad, sizeof(bad)) == false)
{
/* bad has no null terminator within 4 bytes */
}bool SSFStrLen(SSFCStrIn_t cstr, size_t cstrSize, size_t *cstrLenOut);Returns the length of a null-terminated C string bounded by cstrSize. Safer than strlen()
because it will not read past the declared buffer boundary.
| Parameter | Direction | Type | Description |
|---|---|---|---|
cstr |
in | SSFCStrIn_t |
Pointer to the null-terminated string. Must not be NULL. |
cstrSize |
in | size_t |
Total allocated size of the buffer containing cstr. |
cstrLenOut |
out | size_t * |
Receives the string length (number of characters excluding the null terminator). Must not be NULL. |
Returns: true if a null terminator was found within cstrSize bytes and *cstrLenOut was set; false if no null terminator exists within the buffer.
const char str[] = "hello";
size_t len;
if (SSFStrLen(str, sizeof(str), &len))
{
/* len == 5 */
}bool SSFStrCpy(SSFCStrOut_t cstrDstOut, size_t cstrDstOutSize, size_t *cstrDstOutLenOut,
SSFCStrIn_t cstrSrc, size_t cstrSrcSize);Copies a null-terminated source string into a destination buffer. Always null-terminates the
destination on success. Unlike strncpy(), this function never writes a partial result without a
null terminator, and it returns false rather than silently truncating.
| Parameter | Direction | Type | Description |
|---|---|---|---|
cstrDstOut |
out | SSFCStrOut_t |
Destination buffer. Must not be NULL. |
cstrDstOutSize |
in | size_t |
Total allocated size of cstrDstOut in bytes. Must be at least strlen(src) + 1. |
cstrDstOutLenOut |
out (opt) | size_t * |
If not NULL, receives the length of the copied string (excluding null terminator). |
cstrSrc |
in | SSFCStrIn_t |
Source null-terminated string to copy. Must not be NULL. |
cstrSrcSize |
in | size_t |
Total allocated size of cstrSrc buffer. Used for bounds validation of the source. |
Returns: true if the copy succeeded and cstrDstOut is null-terminated; false if cstrDstOutSize is too small to hold the source string and its null terminator.
char dst[16];
size_t len;
if (SSFStrCpy(dst, sizeof(dst), &len, "hello", sizeof("hello")))
{
/* dst == "hello", len == 5 */
}
/* Destination too small — copy fails cleanly */
char small[3];
if (SSFStrCpy(small, sizeof(small), NULL, "hello", sizeof("hello")) == false)
{
/* small is not modified */
}bool SSFStrCat(SSFCStrOut_t cstrDstOut, size_t cstrDstOutSize, size_t *cstrDstOutLenOut,
SSFCStrIn_t cstrSrc, size_t cstrSrcSize);Appends a null-terminated source string to an existing null-terminated destination string. Always
null-terminates on success. Returns false rather than silently truncating.
| Parameter | Direction | Type | Description |
|---|---|---|---|
cstrDstOut |
in-out | SSFCStrOut_t |
Destination buffer containing an existing null-terminated string to append to. Must not be NULL. |
cstrDstOutSize |
in | size_t |
Total allocated size of cstrDstOut. Must accommodate the existing content plus the appended string plus the null terminator. |
cstrDstOutLenOut |
out (opt) | size_t * |
If not NULL, receives the total length of the resulting string (excluding null terminator). |
cstrSrc |
in | SSFCStrIn_t |
Source null-terminated string to append. Must not be NULL. |
cstrSrcSize |
in | size_t |
Total allocated size of cstrSrc buffer. |
Returns: true if the concatenation succeeded and cstrDstOut is null-terminated; false if the combined result would not fit in cstrDstOut.
char dst[16];
size_t len;
SSFStrCpy(dst, sizeof(dst), NULL, "hello", sizeof("hello"));
if (SSFStrCat(dst, sizeof(dst), &len, " world", sizeof(" world")))
{
/* dst == "hello world", len == 11 */
}bool SSFStrCmp(SSFCStrIn_t cstr1, size_t cstr1Size, SSFCStrIn_t cstr2, size_t cstr2Size);Compares two bounded null-terminated strings for equality.
| Parameter | Direction | Type | Description |
|---|---|---|---|
cstr1 |
in | SSFCStrIn_t |
First string. Must not be NULL. |
cstr1Size |
in | size_t |
Total allocated size of cstr1 buffer. |
cstr2 |
in | SSFCStrIn_t |
Second string. Must not be NULL. |
cstr2Size |
in | size_t |
Total allocated size of cstr2 buffer. |
Returns: true if both strings are valid and identical byte-for-byte; false if they differ or either is invalid.
const char a[] = "hello";
const char b[] = "hello";
const char c[] = "world";
SSFStrCmp(a, sizeof(a), b, sizeof(b)); /* returns true */
SSFStrCmp(a, sizeof(a), c, sizeof(c)); /* returns false */bool SSFStrToCase(SSFCStrOut_t cstrOut, size_t cstrOutSize, SSFSTRCase_t toCase);Converts all alphabetic characters in a null-terminated string to upper or lower case in-place. Non-alphabetic characters are left unchanged.
| Parameter | Direction | Type | Description |
|---|---|---|---|
cstrOut |
in-out | SSFCStrOut_t |
The string to convert. Modified in-place. Must not be NULL. |
cstrOutSize |
in | size_t |
Total allocated size of cstrOut buffer. |
toCase |
in | SSFSTRCase_t |
SSF_STR_CASE_LOWER to lowercase; SSF_STR_CASE_UPPER to uppercase. |
Returns: true if conversion succeeded; false if cstrOut does not contain a null terminator within cstrOutSize.
char str[16];
SSFStrCpy(str, sizeof(str), NULL, "Hello World", sizeof("Hello World"));
SSFStrToCase(str, sizeof(str), SSF_STR_CASE_UPPER);
/* str == "HELLO WORLD" */
SSFStrToCase(str, sizeof(str), SSF_STR_CASE_LOWER);
/* str == "hello world" */bool SSFStrStr(SSFCStrIn_t cstr, size_t cstrSize, SSFCStrIn_t *matchStrOptOut,
SSFCStrIn_t substr, size_t substrSize);Searches for the first occurrence of substr within cstr. Bounded equivalent of strstr().
| Parameter | Direction | Type | Description |
|---|---|---|---|
cstr |
in | SSFCStrIn_t |
String to search within. Must not be NULL. |
cstrSize |
in | size_t |
Total allocated size of cstr buffer. |
matchStrOptOut |
out (opt) | const char ** |
If not NULL, receives a pointer into cstr at the start of the first match when found. |
substr |
in | SSFCStrIn_t |
Substring to search for. Must not be NULL. |
substrSize |
in | size_t |
Total allocated size of substr buffer. |
Returns: true if substr is found within cstr; false if not found or either string is invalid.
const char haystack[] = "the quick brown fox";
const char needle[] = "brown";
const char *match;
if (SSFStrStr(haystack, sizeof(haystack), &match, needle, sizeof(needle)))
{
/* match points to "brown fox" within haystack */
}
if (SSFStrStr(haystack, sizeof(haystack), NULL, "cat", sizeof("cat")) == false)
{
/* "cat" not found */
}bool SSFStrTok(SSFCStrIn_t *cstr, size_t cstrSize, SSFCStrOut_t tokenStrOut,
size_t tokenStrSize, int32_t *tokenStrLen,
SSFCStrIn_t delims, size_t delimsSize);Extracts the next token from a string, advancing *cstr past the consumed token and its
delimiter on each call. Re-entrant bounded replacement for strtok_r(). Call repeatedly until it
returns false to consume all tokens.
| Parameter | Direction | Type | Description |
|---|---|---|---|
cstr |
in-out | const char ** |
Pointer to the current position in the source string. Updated on each call to point past the consumed token and delimiter. Must not be NULL; *cstr must not be NULL. |
cstrSize |
in | size_t |
Total allocated size of the source string buffer. |
tokenStrOut |
out | SSFCStrOut_t |
Buffer that receives the extracted token as a null-terminated string. Must not be NULL. |
tokenStrSize |
in | size_t |
Allocated size of tokenStrOut. |
tokenStrLen |
out (opt) | int32_t * |
If not NULL, receives the length of the extracted token (excluding null terminator), or -1 when no more tokens remain. |
delims |
in | SSFCStrIn_t |
String whose individual characters are treated as delimiters. Must not be NULL. |
delimsSize |
in | size_t |
Total allocated size of delims buffer. |
Returns: true if a token was extracted and written to tokenStrOut; false if no more tokens remain or an error occurred.
const char src[] = "one,two,three";
const char *pos = src;
char token[16];
int32_t tokLen;
while (SSFStrTok(&pos, sizeof(src), token, sizeof(token), &tokLen, ",", sizeof(",")))
{
/* Iteration 1: token == "one", tokLen == 3 */
/* Iteration 2: token == "two", tokLen == 3 */
/* Iteration 3: token == "three", tokLen == 5 */
}
/* Loop exits when no more tokens remain */