mirror of
https://github.com/shadow-maint/shadow.git
synced 2026-01-27 22:34:17 +00:00
Always start a sentence with lowercase letter after 'Note:', 'Warning:', etc. This unifies all occurrences. No functional change. Signed-off-by: Tobias Stoeckmann <tobias@stoeckmann.org>
General guidelines:
===================
- If there's an upper-case macro that wraps a function, use the macro
if possible. These use macro magic to add safety.
- If there's a *_a() macro that wraps an API, use the macro if
possible. These use countof() to add bounds safety.
- x*() functions wrap a function of the same name without the 'x'.
These wrappers exit on error instead of returning NULL.
They simplify program code. Avoid them in library code.
- strn*() functions are forbidden for use with strings. Consider strn
a mnemonic for [[gnu::nonstring]]. We use them with utmp(5) members
(almost) exclusively.
Don't use some libc functions without Really Good Reasons:
==========================================================
<stdio.h>
asprintf(3)
Use aprintf() instead.
It is difficult to handle errors after asprintf(3).
Also, it makes it more difficult for static analyzers to check
that memory is later free(3)d appropriately.
<string.h>
snprintf(3)
Use stprintf() or seprintf() instead.
It is difficult to check for truncation after snprintf(3).
strcmp(3)
Use streq() instead.
The return value of strcmp(3) is confusing.
strcmp(3) would be legitimate for sorting strings.
strncmp(3)
Use strneq_a(), or strpfx(), or else,
depending on what you want.
The return value of strncmp(3) is confusing,
and it is unclear the purpose of its use when you read it.
strcasecmp(3)
Use strcaseeq() instead.
strncat(3)
Use strndup(3) or strndupa(3) instead.
strncat(3) is legitimate for catenating a prefix of a string
after an existing string.
strlcpy(3)
Use strtcpy() instead.
strlcpy(3) is vulnerable to DoS.
Also, it is difficult to check for truncation after strlcpy(3).
strlcat(3)
Use strtcat() or stpecpy() instead.
strlcat(3) is vulnerable to DoS.
Also, it is difficult to check for truncation after strlcat(3).
Specific guidelines:
====================
Under lib/string/ we provide a set of functions to manipulate
strings, separated in subdirectories by utility type. In this
section, we provide a broad overview.
ctype/ - Character classification and conversion functions
strchrisascii/
The functions defined under this directory
return true
if the string has any characters that
belong to the category specified in the function name.
strisascii/
The functions defined under this directory
return true
if all of the characters of the string
belong to the category specified in the function name
and the string is not an empty string.
strtoascii/
The functions defined under this directory
translate all characters in a string.
memset/ - Memory zeroing
memzero()
Synonym of explicit_bzero(3).
memzero_a()
Like memzero(), but takes an array.
strzero()
Like memzero(), but takes a string.
strchr/ - Character search and counting
strchrcnt()
Count the number of occurrences of a given character in a string.
strchrscnt()
Count the number of occurrences of several characters.
strnul()
Return a pointer to the terminating null byte. (s + strlen(s))
strstr/ - String search
s/
stppfx() // Current name: strprefix()
Return a pointer to the end of the prefix,
or NULL if not found.
stpsfx() // Unimplemented
Return a pointer to the beginning of the suffix,
or NULL if not found.
strcmp/ - String comparison
s/
streq()
Return true if the strings are equal.
strpfx() // Unimplemented
Return true if the string starts with a prefix.
strsfx() // Unimplemented
Return true if the string ends with a suffix.
strcaseeq()
Like streq(), but ignore upper-/lower-case.
strcasepfx() // Unimplemented
Like strpfx(), but ignore upper-/lower-case.
strcasesfx() // Unimplemented
Like strsfx(), but ignore upper-/lower-case.
n/
strneq()
Return true if a [[gnu::nonstring]] is equal to a string.
strneq_a()
Like strneq(), but takes an array.
strnpfx() // Unimplemented
Return true if a [[gnu::nonstring]] starts with a prefix.
STRNPFX() // Unimplemented
Like strnpfx(), but takes an array.
strdup/ - Memory duplication
s/
strndupa(3)
Create a new string (in stack) from a [[gnu::nonstring]].
strndupa_a()
Like strndupa(3), but takes an array.
strndup_a()
Like strndup(3), but takes an array.
m/
memdup()
Duplicate an object. Returns a pointer to the dup.
MEMDUP()
Like memdup(), but with type-safety checks.
strcpy/ - String copying
n/
strncpy_a()
Like strncpy(3), but takes an array.
Use it *exclusively* for copying from a string into a utmp(5)
member.
strncpytail()
Like strncpy(), but when truncating, the tail of the string is
kept instead of the beginning. This is useful for ut_id.
STRNCPYTAIL()
Like strncpytail, but takes an array.
strncat_a() // To be removed
Do NOT use. I'll remove it soon.
s/
strtcpy()
Copy from a string into another string with truncation.
This is what the Linux kernel calls strscpy().
If you need more than one call to form a string,
use stpecpy() instead.
strtcpy_a()
Like strtcpy(), but takes an array.
strtcat() // Unimplemented
Catenate a string after an existing string, with truncation.
Rarely useful. Consider using stpecpy() instead.
STRTCAT() // Unimplemented
Like strtcat(), but takes an array.
stpecpy()
Similar to strtcpy(), but takes a pointer to the end instead of
a size. This makes it safer for chaining several calls.
m/
MEMCPY()
Like memcpy(3), but takes two arrays.
sprintf/ - Formatted string creation
aprintf()
sprintf(3) variant that allocates.
It has better interface than asprintf(3).
stprintf() // Current name: snprintf_()
snprintf(3) wrapper that reports truncation with -1.
If you need more than one call to form a string,
use seprintf() instead.
stprintf_a()
Like stprintf(), but takes an array.
seprintf() // Current name: stpeprintf())
Similar to stprintf(), but takes a pointer to the end instead of
a size. This makes it safer for chaining several calls.
strspn/ - String span searching
Naming conventions:
- 'r': reverse (search from the end).
- 'c': complement (negate the second argument).
- 'stp': return a pointer instead of a length.
stpspn()
Like strspn(3), but return a pointer instead of an offset.
It is useful for skipping leading white space.
strrspn()
Use stprspn() instead.
Return the offset of a suffix segment consisting only of
characters in 'accept'.
stprspn()
Like strrspn(), but return a pointer instead of an offset.
It is useful for removing trailing white space.
strrcspn()
Use stprcspn() instead.
Return the offset of a suffix segment consisting only of
characters not in 'reject'.
stprcspn()
Like strrcspn(), but return a pointer instead of an offset.
This is rarely useful. It was useful for implementing
basename().
strsep/ - String separation
stpsep()
Similar to strsep(3), but swap the input pointer with the return
value. It writes a null byte at the first delimiter found, and
returns a pointer to one past that null byte. If no delimiters
are found, it returns NULL.
It is very useful after fgets(3), for removing the '\n', while
checking for its presence. In some cases, it's also useful as
a replacement for strsep(3) with a more convenient calling
convention, but this depends on the surrounding code.
strsep2arr()
Loop around strsep(3) to fill an array of buffers with all
the delimited strings that have been split.
Useful when the number of delimiter-separated fields is known.
strsep2arr_a()
Like strsep2arr(), but take an array, and simplify error checks.
strsep2ls()
Similar to strsep2arr(), but terminate the list with a null
pointer.
Useful when the number of delimiter-separated fields is unknown.
strsep2ls_a()
Like strsep2ls(), but take an array.
astrsep2ls()
Variant of strsep2ls() that allocates the array of strings.
(But the strings themselves are not duplicated.)
strftime.h
strftime_a()
Like strftime(3), but takes an array.