Skip to content

Commit 64ba207

Browse files
authored
[CoreFoundation] Replace use of strlcpy/strlcat with our own functions. (#5113)
These can _use_ `strlcpy` and `strlcat` if we have them, but we mustn't go defining `strlcpy` or `strlcat` because (a) those names are reserved, and (b) doing so without explicitly testing for their presence runs the risk of build failures from trying to define them when they already exist. rdar://137567627
1 parent bf7369a commit 64ba207

11 files changed

+64
-58
lines changed

Sources/CoreFoundation/CFBigNumber.c

+1-1
Original file line numberDiff line numberDiff line change
@@ -508,7 +508,7 @@ void _CFBigNumToCString(const _CFBigNum *vp, Boolean leading_zeros, Boolean lead
508508
char *s = tmp;
509509
while (*s == '0') s++;
510510
if (*s == 0) s--; // if tmp is all zeros, copy out at least one zero
511-
strlcpy(buffer, s, buflen);
511+
cf_strlcpy(buffer, s, buflen);
512512
}
513513
}
514514

Sources/CoreFoundation/CFFileUtilities.c

+12-12
Original file line numberDiff line numberDiff line change
@@ -458,9 +458,9 @@ CF_PRIVATE CFMutableArrayRef _CFCreateContentsOfDirectory(CFAllocatorRef alloc,
458458
// Ugh; must stat.
459459
char subdirPath[CFMaxPathLength];
460460
struct statinfo statBuf;
461-
strlcpy(subdirPath, dirPath, sizeof(subdirPath));
462-
strlcat(subdirPath, "/", sizeof(subdirPath));
463-
strlcat(subdirPath, dp->d_name, sizeof(subdirPath));
461+
cf_strlcpy(subdirPath, dirPath, sizeof(subdirPath));
462+
cf_strlcat(subdirPath, "/", sizeof(subdirPath));
463+
cf_strlcat(subdirPath, dp->d_name, sizeof(subdirPath));
464464
if (stat(subdirPath, &statBuf) == 0) {
465465
isDir = ((statBuf.st_mode & S_IFMT) == S_IFDIR);
466466
}
@@ -1040,7 +1040,7 @@ CF_PRIVATE void _CFIterateDirectory(CFStringRef directoryPath, Boolean appendSla
10401040
// Make sure there is room for the additional space we need in the win32 api
10411041
if (strlen(directoryPathBuf) > CFMaxPathSize - 2) return;
10421042

1043-
strlcat(directoryPathBuf, "\\*", CFMaxPathSize);
1043+
cf_strlcat(directoryPathBuf, "\\*", CFMaxPathSize);
10441044

10451045
UniChar wideBuf[CFMaxPathSize];
10461046

@@ -1110,8 +1110,8 @@ CF_PRIVATE void _CFIterateDirectory(CFStringRef directoryPath, Boolean appendSla
11101110
struct stat statBuf;
11111111
char pathToStat[sizeof(dent->d_name)];
11121112
strncpy(pathToStat, directoryPathBuf, sizeof(pathToStat));
1113-
strlcat(pathToStat, "/", sizeof(pathToStat));
1114-
strlcat(pathToStat, dent->d_name, sizeof(pathToStat));
1113+
cf_strlcat(pathToStat, "/", sizeof(pathToStat));
1114+
cf_strlcat(pathToStat, dent->d_name, sizeof(pathToStat));
11151115
if (stat(pathToStat, &statBuf) == 0) {
11161116
if (S_ISDIR(statBuf.st_mode)) {
11171117
dent->d_type = DT_DIR;
@@ -1135,7 +1135,7 @@ CF_PRIVATE void _CFIterateDirectory(CFStringRef directoryPath, Boolean appendSla
11351135
CFStringRef fileName = CFStringCreateWithFileSystemRepresentation(kCFAllocatorSystemDefault, dent->d_name);
11361136

11371137
// 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
1138-
// Be sure to initialize the first character to null, so that strlcat below works correctly
1138+
// Be sure to initialize the first character to null, so that cf_strlcat below works correctly
11391139
#if TARGET_OS_WASI
11401140
// wasi-libc's dirent.d_name is not a fixed-size array but a pointer, so we need to calculate
11411141
// the size of buffer at first.
@@ -1199,8 +1199,8 @@ CF_PRIVATE void _CFIterateDirectory(CFStringRef directoryPath, Boolean appendSla
11991199
struct stat statBuf;
12001200
char pathToStat[sizeof(dent->d_name)];
12011201
strncpy(pathToStat, directoryPathBuf, sizeof(pathToStat));
1202-
strlcat(pathToStat, "/", sizeof(pathToStat));
1203-
strlcat(pathToStat, dent->d_name, sizeof(pathToStat));
1202+
cf_strlcat(pathToStat, "/", sizeof(pathToStat));
1203+
cf_strlcat(pathToStat, dent->d_name, sizeof(pathToStat));
12041204
if (stat(pathToStat, &statBuf) == 0) {
12051205
isDirectory = S_ISDIR(statBuf.st_mode);
12061206
}
@@ -1210,11 +1210,11 @@ CF_PRIVATE void _CFIterateDirectory(CFStringRef directoryPath, Boolean appendSla
12101210

12111211
if (isDirectory) {
12121212
// Append the file name and the trailing /
1213-
strlcat(fullPathToFile, dent->d_name, sizeof(fullPathToFile));
1214-
strlcat(fullPathToFile, "/", sizeof(fullPathToFile));
1213+
cf_strlcat(fullPathToFile, dent->d_name, sizeof(fullPathToFile));
1214+
cf_strlcat(fullPathToFile, "/", sizeof(fullPathToFile));
12151215
} else if (stuffToPrefix) {
12161216
// Append just the file name to our previously-used buffer
1217-
strlcat(fullPathToFile, dent->d_name, sizeof(fullPathToFile));
1217+
cf_strlcat(fullPathToFile, dent->d_name, sizeof(fullPathToFile));
12181218
}
12191219

12201220

Sources/CoreFoundation/CFLocale.c

+11-11
Original file line numberDiff line numberDiff line change
@@ -1830,10 +1830,10 @@ static bool __CFLocaleICUKeywordValueName(const char *locale, const char *value,
18301830
// Need to make a fake locale ID
18311831
char lid[ULOC_FULLNAME_CAPACITY+ULOC_KEYWORD_AND_VALUES_CAPACITY];
18321832
if (strlen(value) < ULOC_KEYWORD_AND_VALUES_CAPACITY) {
1833-
strlcpy(lid, "en_US@", sizeof(lid));
1834-
strlcat(lid, keyword, sizeof(lid));
1835-
strlcat(lid, "=", sizeof(lid));
1836-
strlcat(lid, value, sizeof(lid));
1833+
cf_strlcpy(lid, "en_US@", sizeof(lid));
1834+
cf_strlcat(lid, keyword, sizeof(lid));
1835+
cf_strlcat(lid, "=", sizeof(lid));
1836+
cf_strlcat(lid, value, sizeof(lid));
18371837
size = uloc_getDisplayKeywordValue(lid, keyword, locale, name, kMaxICUNameSize, &icuStatus);
18381838
if (U_SUCCESS(icuStatus) && size > 0 && icuStatus != U_USING_DEFAULT_WARNING) {
18391839
*out = CFStringCreateWithCharacters(kCFAllocatorSystemDefault, (UniChar *)name, size);
@@ -1925,8 +1925,8 @@ static bool __CFLocaleCountryName(const char *locale, const char *value, CFStrin
19251925
// Need to make a fake locale ID
19261926
char lid[ULOC_FULLNAME_CAPACITY];
19271927
if (strlen(value) < sizeof(lid) - 3) {
1928-
strlcpy(lid, "en_", sizeof(lid));
1929-
strlcat(lid, value, sizeof(lid));
1928+
cf_strlcpy(lid, "en_", sizeof(lid));
1929+
cf_strlcat(lid, value, sizeof(lid));
19301930
return __CFLocaleICUName(locale, lid, out, uloc_getDisplayCountry);
19311931
}
19321932
return false;
@@ -1941,9 +1941,9 @@ static bool __CFLocaleScriptName(const char *locale, const char *value, CFString
19411941
// Need to make a fake locale ID
19421942
char lid[ULOC_FULLNAME_CAPACITY];
19431943
if (strlen(value) == 4) {
1944-
strlcpy(lid, "en_", sizeof(lid));
1945-
strlcat(lid, value, sizeof(lid));
1946-
strlcat(lid, "_US", sizeof(lid));
1944+
cf_strlcpy(lid, "en_", sizeof(lid));
1945+
cf_strlcat(lid, value, sizeof(lid));
1946+
cf_strlcat(lid, "_US", sizeof(lid));
19471947
return __CFLocaleICUName(locale, lid, out, uloc_getDisplayScript);
19481948
}
19491949
return false;
@@ -1958,8 +1958,8 @@ static bool __CFLocaleVariantName(const char *locale, const char *value, CFStrin
19581958
// Need to make a fake locale ID
19591959
char lid[ULOC_FULLNAME_CAPACITY+ULOC_KEYWORD_AND_VALUES_CAPACITY];
19601960
if (strlen(value) < sizeof(lid) - 6) {
1961-
strlcpy(lid, "en_US_", sizeof(lid));
1962-
strlcat(lid, value, sizeof(lid));
1961+
cf_strlcpy(lid, "en_US_", sizeof(lid));
1962+
cf_strlcat(lid, value, sizeof(lid));
19631963
return __CFLocaleICUName(locale, lid, out, uloc_getDisplayVariant);
19641964
}
19651965
return false;

Sources/CoreFoundation/CFLocaleIdentifier.c

+6-6
Original file line numberDiff line numberDiff line change
@@ -1779,7 +1779,7 @@ CFStringRef CFLocaleCreateCanonicalLanguageIdentifierFromString(CFAllocatorRef a
17791779
}
17801780
if (foundEntry) {
17811781
// It does match, so replace old string with new
1782-
strlcpy(inLocaleString, foundEntry->result, sizeof(inLocaleString));
1782+
cf_strlcpy(inLocaleString, foundEntry->result, sizeof(inLocaleString));
17831783
varKeyValueString[0] = 0;
17841784
} else {
17851785
char * langRegSubtag = NULL;
@@ -1812,7 +1812,7 @@ CFStringRef CFLocaleCreateCanonicalLanguageIdentifierFromString(CFAllocatorRef a
18121812
sizeof(KeyStringToResultString), _CompareTestEntryToTableEntryKey );
18131813
if (foundEntry) {
18141814
// it does match
1815-
strlcpy(inLocaleString, foundEntry->result, sizeof(inLocaleString));
1815+
cf_strlcpy(inLocaleString, foundEntry->result, sizeof(inLocaleString));
18161816
} else {
18171817
// skip to any region tag or java-type variant
18181818
char * inLocalePtr = inLocaleString;
@@ -1871,7 +1871,7 @@ CFStringRef CFLocaleCreateCanonicalLocaleIdentifierFromString(CFAllocatorRef all
18711871
sizeof(KeyStringToResultString), _CompareTestEntryToTableEntryKey );
18721872
if (foundEntry) {
18731873
// It does match, so replace old string with new // <1.10>
1874-
strlcpy(inLocaleString, foundEntry->result, sizeof(inLocaleString));
1874+
cf_strlcpy(inLocaleString, foundEntry->result, sizeof(inLocaleString));
18751875
varKeyValueString[0] = 0;
18761876
} else {
18771877
char * langRegSubtag = NULL;
@@ -1997,8 +1997,8 @@ Boolean CFLocaleGetLanguageRegionEncodingForLocaleIdentifier(CFStringRef localeI
19971997

19981998
// Append whichever other component we first found
19991999
if (componentLength > 0) {
2000-
strlcat(searchString, "_", sizeof(searchString));
2001-
strlcat(searchString, componentString, sizeof(searchString));
2000+
cf_strlcat(searchString, "_", sizeof(searchString));
2001+
cf_strlcat(searchString, componentString, sizeof(searchString));
20022002
}
20032003

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

21782178
char cLocaleID[2 * ULOC_FULLNAME_CAPACITY + 2 * ULOC_KEYWORD_AND_VALUES_CAPACITY];
2179-
strlcpy(cLocaleID, buf1, sizeof(cLocaleID));
2179+
cf_strlcpy(cLocaleID, buf1, sizeof(cLocaleID));
21802180
free(language);
21812181
free(script);
21822182
free(country);

Sources/CoreFoundation/CFPlatform.c

+2-2
Original file line numberDiff line numberDiff line change
@@ -534,8 +534,8 @@ CFURLRef CFCopyHomeDirectoryURL(void) {
534534
const char *cdrive = __CFgetenv("HOMEDRIVE");
535535
if (cdrive && cpath) {
536536
char fullPath[CFMaxPathSize];
537-
strlcpy(fullPath, cdrive, sizeof(fullPath));
538-
strlcat(fullPath, cpath, sizeof(fullPath));
537+
cf_strlcpy(fullPath, cdrive, sizeof(fullPath));
538+
cf_strlcat(fullPath, cpath, sizeof(fullPath));
539539
str = CFStringCreateWithCString(kCFAllocatorSystemDefault, fullPath, kCFPlatformInterfaceStringEncoding);
540540
retVal = CFURLCreateWithFileSystemPath(kCFAllocatorSystemDefault, str, kCFURLWindowsPathStyle, true);
541541
CFRelease(str);

Sources/CoreFoundation/CFSocketStream.c

+3-3
Original file line numberDiff line numberDiff line change
@@ -135,11 +135,11 @@ static void initializeCFNetworkSupport(void) {
135135
// not loaded yet, try to load from the filesystem
136136
char path[MAX_PATH+1];
137137
if (!CFNetworkSupport.image) {
138-
strlcpy(path, (const char *)_CFDLLPath(), sizeof(path));
138+
cf_strlcpy(path, (const char *)_CFDLLPath(), sizeof(path));
139139
#if _DEBUG
140-
strlcat(path, "\\CFNetwork_debug.dll", sizeof(path));
140+
cf_strlcat(path, "\\CFNetwork_debug.dll", sizeof(path));
141141
#else
142-
strlcat(path, "\\CFNetwork.dll", sizeof(path));
142+
cf_strlcat(path, "\\CFNetwork.dll", sizeof(path));
143143
#endif
144144
CFNetworkSupport.image = LoadLibraryA(path);
145145
}

Sources/CoreFoundation/CFString.c

+3-3
Original file line numberDiff line numberDiff line change
@@ -1896,7 +1896,7 @@ CFStringRef __CFStringMakeConstantString(const char *cStr) {
18961896
CFIndex keySize = strlen(cStr) + 1;
18971897
key = (char *)CFAllocatorAllocate(kCFAllocatorSystemDefault, keySize, 0);
18981898
if (__CFOASafe) __CFSetLastAllocationEventName((void *)key, "CFString (CFSTR key)");
1899-
strlcpy(key, cStr, keySize); // !!! We will leak this, if the string is removed from the table (or table is freed)
1899+
cf_strlcpy(key, cStr, keySize); // !!! We will leak this, if the string is removed from the table (or table is freed)
19001900
}
19011901

19021902
{
@@ -2292,7 +2292,7 @@ Boolean CFStringGetPascalString(CFStringRef str, Str255 buffer, CFIndex bufferSi
22922292

22932293
#if defined(DEBUG)
22942294
if (bufferSize > 0) {
2295-
strlcpy((char *)buffer + 1, CONVERSIONFAILURESTR, bufferSize - 1);
2295+
cf_strlcpy((char *)buffer + 1, CONVERSIONFAILURESTR, bufferSize - 1);
22962296
buffer[0] = (unsigned char)((CFIndex)sizeof(CONVERSIONFAILURESTR) < (bufferSize - 1) ? (CFIndex)sizeof(CONVERSIONFAILURESTR) : (bufferSize - 1));
22972297
}
22982298
#else
@@ -2334,7 +2334,7 @@ Boolean CFStringGetCString(CFStringRef str, char *buffer, CFIndex bufferSize, CF
23342334
return true;
23352335
} else {
23362336
#if defined(DEBUG)
2337-
strlcpy(buffer, CONVERSIONFAILURESTR, bufferSize);
2337+
cf_strlcpy(buffer, CONVERSIONFAILURESTR, bufferSize);
23382338
#else
23392339
if (bufferSize > 0) buffer[0] = 0;
23402340
#endif

Sources/CoreFoundation/CFStringEncodings.c

+6-6
Original file line numberDiff line numberDiff line change
@@ -1147,8 +1147,8 @@ void _CFStringGetUserDefaultEncoding(UInt32 *oScriptValue, UInt32 *oRegionValue)
11471147
path = passwdp->pw_dir;
11481148
}
11491149

1150-
strlcpy(filename, path, sizeof(filename));
1151-
strlcat(filename, __kCFUserEncodingFileName, sizeof(filename));
1150+
cf_strlcpy(filename, path, sizeof(filename));
1151+
cf_strlcat(filename, __kCFUserEncodingFileName, sizeof(filename));
11521152

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

12081208
char filename[MAXPATHLEN + 1];
1209-
strlcpy(filename, path, sizeof(filename));
1210-
strlcat(filename, __kCFUserEncodingFileName, sizeof(filename));
1209+
cf_strlcpy(filename, path, sizeof(filename));
1210+
cf_strlcat(filename, __kCFUserEncodingFileName, sizeof(filename));
12111211

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

12411241
char filename[MAXPATHLEN + 1];
1242-
strlcpy(filename, path, sizeof(filename));
1243-
strlcat(filename, __kCFUserEncodingFileName, sizeof(filename));
1242+
cf_strlcpy(filename, path, sizeof(filename));
1243+
cf_strlcat(filename, __kCFUserEncodingFileName, sizeof(filename));
12441244

12451245
int no_hang_fd = __CFProphylacticAutofsAccess ? open("/dev/autofs_nowait", 0) : -1;
12461246
(void)unlink(filename);

Sources/CoreFoundation/CFSystemDirectories.c

+2-2
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ CFSearchPathEnumerationState __CFGetNextSearchPathEnumeration(CFSearchPathEnumer
4242
if (pathSize < PATH_MAX) {
4343
uint8_t tempPath[PATH_MAX];
4444
result = sysdir_get_next_search_path_enumeration(state, (char *)tempPath);
45-
strlcpy((char *)path, (char *)tempPath, pathSize);
45+
cf_strlcpy((char *)path, (char *)tempPath, pathSize);
4646
} else {
4747
result = sysdir_get_next_search_path_enumeration(state, (char *)path);
4848
}
@@ -75,7 +75,7 @@ CFArrayRef CFCopySearchPathForDirectoriesInDomains(CFSearchPathDirectory directo
7575
}
7676
if (homeLen + strlen(cPath) < CFMaxPathSize) {
7777
home[homeLen] = '\0';
78-
strlcat(home, &cPath[1], sizeof(home));
78+
cf_strlcat(home, &cPath[1], sizeof(home));
7979
url = CFURLCreateFromFileSystemRepresentation(kCFAllocatorSystemDefault, (uint8_t *)home, strlen(home), true);
8080
}
8181
} else {

Sources/CoreFoundation/CFURL.c

+1-1
Original file line numberDiff line numberDiff line change
@@ -844,7 +844,7 @@ static CFStringRef CreateStringFromFileSystemRepresentationByAddingPercentEscape
844844
if ( bufStartPtr != NULL ) {
845845
if ( isAbsolute ) {
846846
// start with the fileURLPrefix
847-
strlcpy((char *)bufStartPtr, (char *)fileURLPrefixPtr, bufferLength);
847+
cf_strlcpy((char *)bufStartPtr, (char *)fileURLPrefixPtr, bufferLength);
848848
bufBytePtr = bufStartPtr + fileURLPrefixLength - 1;
849849
}
850850
else {

Sources/CoreFoundation/internalInclude/CoreFoundation_Prefix.h

+17-11
Original file line numberDiff line numberDiff line change
@@ -109,11 +109,6 @@ typedef char * Class;
109109
#include <pthread.h>
110110
#endif
111111

112-
#if TARGET_OS_WASI
113-
#define HAVE_STRLCPY 1
114-
#define HAVE_STRLCAT 1
115-
#endif
116-
117112
#if TARGET_OS_WIN32
118113
#define BOOL WINDOWS_BOOL
119114

@@ -204,10 +199,20 @@ static dispatch_queue_t __ ## PREFIX ## Queue(void) { \
204199
#endif
205200
#endif
206201

207-
#if !TARGET_OS_MAC
208-
#if !HAVE_STRLCPY
202+
// We know some things (Darwin, WASI, Glibc >= 2.38) have strlcpy/strlcat
203+
#if TARGET_OS_MAC || TARGET_OS_WASI \
204+
|| (defined(__GLIBC__) && \
205+
((__GLIBC_MAJOR__ == 2 && __GLIBC_MINOR__ >= 38) \
206+
|| __GLIBC_MAJOR__ > 2))
207+
#define HAVE_STRLCPY 1
208+
#define HAVE_STRLCAT 1
209+
#endif
210+
211+
#if HAVE_STRLCPY
212+
#define cf_strlcpy strlcpy
213+
#else
209214
CF_INLINE size_t
210-
strlcpy(char * dst, const char * src, size_t maxlen) {
215+
cf_strlcpy(char *dst, const char *src, size_t maxlen) {
211216
const size_t srclen = strlen(src);
212217
if (srclen < maxlen) {
213218
memcpy(dst, src, srclen+1);
@@ -219,9 +224,11 @@ strlcpy(char * dst, const char * src, size_t maxlen) {
219224
}
220225
#endif
221226

222-
#if !HAVE_STRLCAT
227+
#if HAVE_STRLCAT
228+
#define cf_strlcat strlcat
229+
#else
223230
CF_INLINE size_t
224-
strlcat(char * dst, const char * src, size_t maxlen) {
231+
cf_strlcat(char *dst, const char *src, size_t maxlen) {
225232
const size_t srclen = strlen(src);
226233
const size_t dstlen = strnlen(dst, maxlen);
227234
if (dstlen == maxlen) return maxlen+srclen;
@@ -234,7 +241,6 @@ strlcat(char * dst, const char * src, size_t maxlen) {
234241
return dstlen + srclen;
235242
}
236243
#endif
237-
#endif // !TARGET_OS_MAC
238244

239245
#if TARGET_OS_WIN32
240246
// Compatibility with boolean.h

0 commit comments

Comments
 (0)