Skip to content

[CoreFoundation] Replace use of strlcpy/strlcat with our own functions. #5113

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Oct 18, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Sources/CoreFoundation/CFBigNumber.c
Original file line number Diff line number Diff line change
Expand Up @@ -508,7 +508,7 @@ void _CFBigNumToCString(const _CFBigNum *vp, Boolean leading_zeros, Boolean lead
char *s = tmp;
while (*s == '0') s++;
if (*s == 0) s--; // if tmp is all zeros, copy out at least one zero
strlcpy(buffer, s, buflen);
cf_strlcpy(buffer, s, buflen);
}
}

Expand Down
24 changes: 12 additions & 12 deletions Sources/CoreFoundation/CFFileUtilities.c
Original file line number Diff line number Diff line change
Expand Up @@ -458,9 +458,9 @@ CF_PRIVATE CFMutableArrayRef _CFCreateContentsOfDirectory(CFAllocatorRef alloc,
// Ugh; must stat.
char subdirPath[CFMaxPathLength];
struct statinfo statBuf;
strlcpy(subdirPath, dirPath, sizeof(subdirPath));
strlcat(subdirPath, "/", sizeof(subdirPath));
strlcat(subdirPath, dp->d_name, sizeof(subdirPath));
cf_strlcpy(subdirPath, dirPath, sizeof(subdirPath));
cf_strlcat(subdirPath, "/", sizeof(subdirPath));
cf_strlcat(subdirPath, dp->d_name, sizeof(subdirPath));
if (stat(subdirPath, &statBuf) == 0) {
isDir = ((statBuf.st_mode & S_IFMT) == S_IFDIR);
}
Expand Down Expand Up @@ -1040,7 +1040,7 @@ CF_PRIVATE void _CFIterateDirectory(CFStringRef directoryPath, Boolean appendSla
// Make sure there is room for the additional space we need in the win32 api
if (strlen(directoryPathBuf) > CFMaxPathSize - 2) return;

strlcat(directoryPathBuf, "\\*", CFMaxPathSize);
cf_strlcat(directoryPathBuf, "\\*", CFMaxPathSize);

UniChar wideBuf[CFMaxPathSize];

Expand Down Expand Up @@ -1110,8 +1110,8 @@ CF_PRIVATE void _CFIterateDirectory(CFStringRef directoryPath, Boolean appendSla
struct stat statBuf;
char pathToStat[sizeof(dent->d_name)];
strncpy(pathToStat, directoryPathBuf, sizeof(pathToStat));
strlcat(pathToStat, "/", sizeof(pathToStat));
strlcat(pathToStat, dent->d_name, sizeof(pathToStat));
cf_strlcat(pathToStat, "/", sizeof(pathToStat));
cf_strlcat(pathToStat, dent->d_name, sizeof(pathToStat));
if (stat(pathToStat, &statBuf) == 0) {
if (S_ISDIR(statBuf.st_mode)) {
dent->d_type = DT_DIR;
Expand All @@ -1135,7 +1135,7 @@ CF_PRIVATE void _CFIterateDirectory(CFStringRef directoryPath, Boolean appendSla
CFStringRef fileName = CFStringCreateWithFileSystemRepresentation(kCFAllocatorSystemDefault, dent->d_name);

// This buffer has to be 1 bigger than the size of the one in the dirent so we can hold the extra '/' if it's required
// Be sure to initialize the first character to null, so that strlcat below works correctly
// Be sure to initialize the first character to null, so that cf_strlcat below works correctly
#if TARGET_OS_WASI
// wasi-libc's dirent.d_name is not a fixed-size array but a pointer, so we need to calculate
// the size of buffer at first.
Expand Down Expand Up @@ -1199,8 +1199,8 @@ CF_PRIVATE void _CFIterateDirectory(CFStringRef directoryPath, Boolean appendSla
struct stat statBuf;
char pathToStat[sizeof(dent->d_name)];
strncpy(pathToStat, directoryPathBuf, sizeof(pathToStat));
strlcat(pathToStat, "/", sizeof(pathToStat));
strlcat(pathToStat, dent->d_name, sizeof(pathToStat));
cf_strlcat(pathToStat, "/", sizeof(pathToStat));
cf_strlcat(pathToStat, dent->d_name, sizeof(pathToStat));
if (stat(pathToStat, &statBuf) == 0) {
isDirectory = S_ISDIR(statBuf.st_mode);
}
Expand All @@ -1210,11 +1210,11 @@ CF_PRIVATE void _CFIterateDirectory(CFStringRef directoryPath, Boolean appendSla

if (isDirectory) {
// Append the file name and the trailing /
strlcat(fullPathToFile, dent->d_name, sizeof(fullPathToFile));
strlcat(fullPathToFile, "/", sizeof(fullPathToFile));
cf_strlcat(fullPathToFile, dent->d_name, sizeof(fullPathToFile));
cf_strlcat(fullPathToFile, "/", sizeof(fullPathToFile));
} else if (stuffToPrefix) {
// Append just the file name to our previously-used buffer
strlcat(fullPathToFile, dent->d_name, sizeof(fullPathToFile));
cf_strlcat(fullPathToFile, dent->d_name, sizeof(fullPathToFile));
}


Expand Down
22 changes: 11 additions & 11 deletions Sources/CoreFoundation/CFLocale.c
Original file line number Diff line number Diff line change
Expand Up @@ -1830,10 +1830,10 @@ static bool __CFLocaleICUKeywordValueName(const char *locale, const char *value,
// Need to make a fake locale ID
char lid[ULOC_FULLNAME_CAPACITY+ULOC_KEYWORD_AND_VALUES_CAPACITY];
if (strlen(value) < ULOC_KEYWORD_AND_VALUES_CAPACITY) {
strlcpy(lid, "en_US@", sizeof(lid));
strlcat(lid, keyword, sizeof(lid));
strlcat(lid, "=", sizeof(lid));
strlcat(lid, value, sizeof(lid));
cf_strlcpy(lid, "en_US@", sizeof(lid));
cf_strlcat(lid, keyword, sizeof(lid));
cf_strlcat(lid, "=", sizeof(lid));
cf_strlcat(lid, value, sizeof(lid));
size = uloc_getDisplayKeywordValue(lid, keyword, locale, name, kMaxICUNameSize, &icuStatus);
if (U_SUCCESS(icuStatus) && size > 0 && icuStatus != U_USING_DEFAULT_WARNING) {
*out = CFStringCreateWithCharacters(kCFAllocatorSystemDefault, (UniChar *)name, size);
Expand Down Expand Up @@ -1925,8 +1925,8 @@ static bool __CFLocaleCountryName(const char *locale, const char *value, CFStrin
// Need to make a fake locale ID
char lid[ULOC_FULLNAME_CAPACITY];
if (strlen(value) < sizeof(lid) - 3) {
strlcpy(lid, "en_", sizeof(lid));
strlcat(lid, value, sizeof(lid));
cf_strlcpy(lid, "en_", sizeof(lid));
cf_strlcat(lid, value, sizeof(lid));
return __CFLocaleICUName(locale, lid, out, uloc_getDisplayCountry);
}
return false;
Expand All @@ -1941,9 +1941,9 @@ static bool __CFLocaleScriptName(const char *locale, const char *value, CFString
// Need to make a fake locale ID
char lid[ULOC_FULLNAME_CAPACITY];
if (strlen(value) == 4) {
strlcpy(lid, "en_", sizeof(lid));
strlcat(lid, value, sizeof(lid));
strlcat(lid, "_US", sizeof(lid));
cf_strlcpy(lid, "en_", sizeof(lid));
cf_strlcat(lid, value, sizeof(lid));
cf_strlcat(lid, "_US", sizeof(lid));
return __CFLocaleICUName(locale, lid, out, uloc_getDisplayScript);
}
return false;
Expand All @@ -1958,8 +1958,8 @@ static bool __CFLocaleVariantName(const char *locale, const char *value, CFStrin
// Need to make a fake locale ID
char lid[ULOC_FULLNAME_CAPACITY+ULOC_KEYWORD_AND_VALUES_CAPACITY];
if (strlen(value) < sizeof(lid) - 6) {
strlcpy(lid, "en_US_", sizeof(lid));
strlcat(lid, value, sizeof(lid));
cf_strlcpy(lid, "en_US_", sizeof(lid));
cf_strlcat(lid, value, sizeof(lid));
return __CFLocaleICUName(locale, lid, out, uloc_getDisplayVariant);
}
return false;
Expand Down
12 changes: 6 additions & 6 deletions Sources/CoreFoundation/CFLocaleIdentifier.c
Original file line number Diff line number Diff line change
Expand Up @@ -1779,7 +1779,7 @@ CFStringRef CFLocaleCreateCanonicalLanguageIdentifierFromString(CFAllocatorRef a
}
if (foundEntry) {
// It does match, so replace old string with new
strlcpy(inLocaleString, foundEntry->result, sizeof(inLocaleString));
cf_strlcpy(inLocaleString, foundEntry->result, sizeof(inLocaleString));
varKeyValueString[0] = 0;
} else {
char * langRegSubtag = NULL;
Expand Down Expand Up @@ -1812,7 +1812,7 @@ CFStringRef CFLocaleCreateCanonicalLanguageIdentifierFromString(CFAllocatorRef a
sizeof(KeyStringToResultString), _CompareTestEntryToTableEntryKey );
if (foundEntry) {
// it does match
strlcpy(inLocaleString, foundEntry->result, sizeof(inLocaleString));
cf_strlcpy(inLocaleString, foundEntry->result, sizeof(inLocaleString));
} else {
// skip to any region tag or java-type variant
char * inLocalePtr = inLocaleString;
Expand Down Expand Up @@ -1871,7 +1871,7 @@ CFStringRef CFLocaleCreateCanonicalLocaleIdentifierFromString(CFAllocatorRef all
sizeof(KeyStringToResultString), _CompareTestEntryToTableEntryKey );
if (foundEntry) {
// It does match, so replace old string with new // <1.10>
strlcpy(inLocaleString, foundEntry->result, sizeof(inLocaleString));
cf_strlcpy(inLocaleString, foundEntry->result, sizeof(inLocaleString));
varKeyValueString[0] = 0;
} else {
char * langRegSubtag = NULL;
Expand Down Expand Up @@ -1997,8 +1997,8 @@ Boolean CFLocaleGetLanguageRegionEncodingForLocaleIdentifier(CFStringRef localeI

// Append whichever other component we first found
if (componentLength > 0) {
strlcat(searchString, "_", sizeof(searchString));
strlcat(searchString, componentString, sizeof(searchString));
cf_strlcat(searchString, "_", sizeof(searchString));
cf_strlcat(searchString, componentString, sizeof(searchString));
}

// Search
Expand Down Expand Up @@ -2176,7 +2176,7 @@ CFStringRef CFLocaleCreateLocaleIdentifierFromComponents(CFAllocatorRef allocato
asprintf(&buf1, "%s%s%s%s%s%s%s", language ? language : "", script ? "_" : "", script ? script : "", (country || variant ? "_" : ""), country ? country : "", variant ? "_" : "", variant ? variant : "");

char cLocaleID[2 * ULOC_FULLNAME_CAPACITY + 2 * ULOC_KEYWORD_AND_VALUES_CAPACITY];
strlcpy(cLocaleID, buf1, sizeof(cLocaleID));
cf_strlcpy(cLocaleID, buf1, sizeof(cLocaleID));
free(language);
free(script);
free(country);
Expand Down
4 changes: 2 additions & 2 deletions Sources/CoreFoundation/CFPlatform.c
Original file line number Diff line number Diff line change
Expand Up @@ -534,8 +534,8 @@ CFURLRef CFCopyHomeDirectoryURL(void) {
const char *cdrive = __CFgetenv("HOMEDRIVE");
if (cdrive && cpath) {
char fullPath[CFMaxPathSize];
strlcpy(fullPath, cdrive, sizeof(fullPath));
strlcat(fullPath, cpath, sizeof(fullPath));
cf_strlcpy(fullPath, cdrive, sizeof(fullPath));
cf_strlcat(fullPath, cpath, sizeof(fullPath));
str = CFStringCreateWithCString(kCFAllocatorSystemDefault, fullPath, kCFPlatformInterfaceStringEncoding);
retVal = CFURLCreateWithFileSystemPath(kCFAllocatorSystemDefault, str, kCFURLWindowsPathStyle, true);
CFRelease(str);
Expand Down
6 changes: 3 additions & 3 deletions Sources/CoreFoundation/CFSocketStream.c
Original file line number Diff line number Diff line change
Expand Up @@ -135,11 +135,11 @@ static void initializeCFNetworkSupport(void) {
// not loaded yet, try to load from the filesystem
char path[MAX_PATH+1];
if (!CFNetworkSupport.image) {
strlcpy(path, (const char *)_CFDLLPath(), sizeof(path));
cf_strlcpy(path, (const char *)_CFDLLPath(), sizeof(path));
#if _DEBUG
strlcat(path, "\\CFNetwork_debug.dll", sizeof(path));
cf_strlcat(path, "\\CFNetwork_debug.dll", sizeof(path));
#else
strlcat(path, "\\CFNetwork.dll", sizeof(path));
cf_strlcat(path, "\\CFNetwork.dll", sizeof(path));
#endif
CFNetworkSupport.image = LoadLibraryA(path);
}
Expand Down
6 changes: 3 additions & 3 deletions Sources/CoreFoundation/CFString.c
Original file line number Diff line number Diff line change
Expand Up @@ -1896,7 +1896,7 @@ CFStringRef __CFStringMakeConstantString(const char *cStr) {
CFIndex keySize = strlen(cStr) + 1;
key = (char *)CFAllocatorAllocate(kCFAllocatorSystemDefault, keySize, 0);
if (__CFOASafe) __CFSetLastAllocationEventName((void *)key, "CFString (CFSTR key)");
strlcpy(key, cStr, keySize); // !!! We will leak this, if the string is removed from the table (or table is freed)
cf_strlcpy(key, cStr, keySize); // !!! We will leak this, if the string is removed from the table (or table is freed)
}

{
Expand Down Expand Up @@ -2292,7 +2292,7 @@ Boolean CFStringGetPascalString(CFStringRef str, Str255 buffer, CFIndex bufferSi

#if defined(DEBUG)
if (bufferSize > 0) {
strlcpy((char *)buffer + 1, CONVERSIONFAILURESTR, bufferSize - 1);
cf_strlcpy((char *)buffer + 1, CONVERSIONFAILURESTR, bufferSize - 1);
buffer[0] = (unsigned char)((CFIndex)sizeof(CONVERSIONFAILURESTR) < (bufferSize - 1) ? (CFIndex)sizeof(CONVERSIONFAILURESTR) : (bufferSize - 1));
}
#else
Expand Down Expand Up @@ -2334,7 +2334,7 @@ Boolean CFStringGetCString(CFStringRef str, char *buffer, CFIndex bufferSize, CF
return true;
} else {
#if defined(DEBUG)
strlcpy(buffer, CONVERSIONFAILURESTR, bufferSize);
cf_strlcpy(buffer, CONVERSIONFAILURESTR, bufferSize);
#else
if (bufferSize > 0) buffer[0] = 0;
#endif
Expand Down
12 changes: 6 additions & 6 deletions Sources/CoreFoundation/CFStringEncodings.c
Original file line number Diff line number Diff line change
Expand Up @@ -1147,8 +1147,8 @@ void _CFStringGetUserDefaultEncoding(UInt32 *oScriptValue, UInt32 *oRegionValue)
path = passwdp->pw_dir;
}

strlcpy(filename, path, sizeof(filename));
strlcat(filename, __kCFUserEncodingFileName, sizeof(filename));
cf_strlcpy(filename, path, sizeof(filename));
cf_strlcat(filename, __kCFUserEncodingFileName, sizeof(filename));

int no_hang_fd = __CFProphylacticAutofsAccess ? open("/dev/autofs_nowait", 0) : -1;
int fd = open(filename, O_RDONLY, 0);
Expand Down Expand Up @@ -1206,8 +1206,8 @@ void _CFStringGetInstallationEncodingAndRegion(uint32_t *encoding, uint32_t *reg
const char *path = passwdp->pw_dir;

char filename[MAXPATHLEN + 1];
strlcpy(filename, path, sizeof(filename));
strlcat(filename, __kCFUserEncodingFileName, sizeof(filename));
cf_strlcpy(filename, path, sizeof(filename));
cf_strlcat(filename, __kCFUserEncodingFileName, sizeof(filename));

int no_hang_fd = __CFProphylacticAutofsAccess ? open("/dev/autofs_nowait", 0) : -1;
int fd = open(filename, O_RDONLY, 0);
Expand Down Expand Up @@ -1239,8 +1239,8 @@ Boolean _CFStringSaveUserDefaultEncoding(UInt32 iScriptValue, UInt32 iRegionValu
}

char filename[MAXPATHLEN + 1];
strlcpy(filename, path, sizeof(filename));
strlcat(filename, __kCFUserEncodingFileName, sizeof(filename));
cf_strlcpy(filename, path, sizeof(filename));
cf_strlcat(filename, __kCFUserEncodingFileName, sizeof(filename));

int no_hang_fd = __CFProphylacticAutofsAccess ? open("/dev/autofs_nowait", 0) : -1;
(void)unlink(filename);
Expand Down
4 changes: 2 additions & 2 deletions Sources/CoreFoundation/CFSystemDirectories.c
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ CFSearchPathEnumerationState __CFGetNextSearchPathEnumeration(CFSearchPathEnumer
if (pathSize < PATH_MAX) {
uint8_t tempPath[PATH_MAX];
result = sysdir_get_next_search_path_enumeration(state, (char *)tempPath);
strlcpy((char *)path, (char *)tempPath, pathSize);
cf_strlcpy((char *)path, (char *)tempPath, pathSize);
} else {
result = sysdir_get_next_search_path_enumeration(state, (char *)path);
}
Expand Down Expand Up @@ -75,7 +75,7 @@ CFArrayRef CFCopySearchPathForDirectoriesInDomains(CFSearchPathDirectory directo
}
if (homeLen + strlen(cPath) < CFMaxPathSize) {
home[homeLen] = '\0';
strlcat(home, &cPath[1], sizeof(home));
cf_strlcat(home, &cPath[1], sizeof(home));
url = CFURLCreateFromFileSystemRepresentation(kCFAllocatorSystemDefault, (uint8_t *)home, strlen(home), true);
}
} else {
Expand Down
2 changes: 1 addition & 1 deletion Sources/CoreFoundation/CFURL.c
Original file line number Diff line number Diff line change
Expand Up @@ -844,7 +844,7 @@ static CFStringRef CreateStringFromFileSystemRepresentationByAddingPercentEscape
if ( bufStartPtr != NULL ) {
if ( isAbsolute ) {
// start with the fileURLPrefix
strlcpy((char *)bufStartPtr, (char *)fileURLPrefixPtr, bufferLength);
cf_strlcpy((char *)bufStartPtr, (char *)fileURLPrefixPtr, bufferLength);
bufBytePtr = bufStartPtr + fileURLPrefixLength - 1;
}
else {
Expand Down
28 changes: 17 additions & 11 deletions Sources/CoreFoundation/internalInclude/CoreFoundation_Prefix.h
Original file line number Diff line number Diff line change
Expand Up @@ -109,11 +109,6 @@ typedef char * Class;
#include <pthread.h>
#endif

#if TARGET_OS_WASI
#define HAVE_STRLCPY 1
#define HAVE_STRLCAT 1
#endif

#if TARGET_OS_WIN32
#define BOOL WINDOWS_BOOL

Expand Down Expand Up @@ -204,10 +199,20 @@ static dispatch_queue_t __ ## PREFIX ## Queue(void) { \
#endif
#endif

#if !TARGET_OS_MAC
#if !HAVE_STRLCPY
// We know some things (Darwin, WASI, Glibc >= 2.38) have strlcpy/strlcat
#if TARGET_OS_MAC || TARGET_OS_WASI \
|| (defined(__GLIBC__) && \
((__GLIBC_MAJOR__ == 2 && __GLIBC_MINOR__ >= 38) \
|| __GLIBC_MAJOR__ > 2))
#define HAVE_STRLCPY 1
#define HAVE_STRLCAT 1
#endif

#if HAVE_STRLCPY
#define cf_strlcpy strlcpy
#else
CF_INLINE size_t
strlcpy(char * dst, const char * src, size_t maxlen) {
cf_strlcpy(char *dst, const char *src, size_t maxlen) {
const size_t srclen = strlen(src);
if (srclen < maxlen) {
memcpy(dst, src, srclen+1);
Expand All @@ -219,9 +224,11 @@ strlcpy(char * dst, const char * src, size_t maxlen) {
}
#endif

#if !HAVE_STRLCAT
#if HAVE_STRLCAT
#define cf_strlcat strlcat
#else
CF_INLINE size_t
strlcat(char * dst, const char * src, size_t maxlen) {
cf_strlcat(char *dst, const char *src, size_t maxlen) {
const size_t srclen = strlen(src);
const size_t dstlen = strnlen(dst, maxlen);
if (dstlen == maxlen) return maxlen+srclen;
Expand All @@ -234,7 +241,6 @@ strlcat(char * dst, const char * src, size_t maxlen) {
return dstlen + srclen;
}
#endif
#endif // !TARGET_OS_MAC

#if TARGET_OS_WIN32
// Compatibility with boolean.h
Expand Down