Skip to content

[3.1] Backport HTTPCookieStorage #963

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
Apr 25, 2017
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
160 changes: 160 additions & 0 deletions CoreFoundation/Base.subproj/CFFileUtilities.c
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
#include <errno.h>
#include <string.h>
#include <stdio.h>
#include <assert.h>

#if DEPLOYMENT_TARGET_WINDOWS
#include <io.h>
Expand Down Expand Up @@ -1166,3 +1167,162 @@ CF_PRIVATE void _CFIterateDirectory(CFStringRef directoryPath, Boolean appendSla
#endif
}

#if DEPLOYMENT_RUNTIME_SWIFT

// https://specifications.freedesktop.org/basedir-spec/basedir-spec-latest.html
// Version 0.8

// This may not be safe to assume
#define _kCFXDGStringEncoding kCFStringEncodingUTF8

// All paths set in these environment variables must be absolute. If an implementation encounters a relative path in any of these variables it should consider the path invalid and ignore it.
static CFStringRef _CFXDGCreateHome(void) {
const char *home = __CFgetenv("HOME");
if (home && strnlen(home, CFMaxPathSize) > 0) {
return CFStringCreateWithCString(kCFAllocatorSystemDefault, home, _kCFXDGStringEncoding);
} else {
return CFRetain(CFSTR(""));
}
}

/// a single base directory relative to which user-specific data files should be written. This directory is defined by the environment variable $XDG_DATA_HOME.
CF_SWIFT_EXPORT
CFStringRef _CFXDGCreateDataHomePath(void) {
// $XDG_DATA_HOME defines the base directory relative to which user specific data files should be stored. If $XDG_DATA_HOME is either not set or empty, a default equal to $HOME/.local/share should be used.
const char *dataHome = __CFgetenv("XDG_DATA_HOME");
if (dataHome && strnlen(dataHome, CFMaxPathSize) > 1 && dataHome[0] == '/') {
return CFStringCreateWithCString(kCFAllocatorSystemDefault, dataHome, _kCFXDGStringEncoding);
} else {
CFStringRef home = _CFXDGCreateHome();
CFStringRef result = CFStringCreateWithFormat(kCFAllocatorSystemDefault, NULL, CFSTR("%@/.local/share"), home);
CFRelease(home);
return result;
}
}

/// a single base directory relative to which user-specific configuration files should be written. This directory is defined by the environment variable $XDG_CONFIG_HOME.
CF_SWIFT_EXPORT
CFStringRef _CFXDGCreateConfigHomePath(void) {
// $XDG_CONFIG_HOME defines the base directory relative to which user specific configuration files should be stored. If $XDG_CONFIG_HOME is either not set or empty, a default equal to $HOME/.config should be used.
const char *configHome = __CFgetenv("XDG_CONFIG_HOME");
if (configHome && strnlen(configHome, CFMaxPathSize) > 1 && configHome[0] == '/') {
return CFStringCreateWithCString(kCFAllocatorSystemDefault, configHome, _kCFXDGStringEncoding);
} else {
CFStringRef home = _CFXDGCreateHome();
CFStringRef result = CFStringCreateWithFormat(kCFAllocatorSystemDefault, NULL, CFSTR("%@/.config"), home);
CFRelease(home);
return result;
}
}

/// a set of preference ordered base directories relative to which data files should be searched. This set of directories is defined by the environment variable $XDG_DATA_DIRS.
CF_SWIFT_EXPORT
CFArrayRef _CFXDGCreateDataDirectoriesPaths(void) {
// $XDG_DATA_DIRS defines the preference-ordered set of base directories to search for data files in addition to the $XDG_DATA_HOME base directory. The directories in $XDG_DATA_DIRS should be seperated with a colon ':'.
// If $XDG_DATA_DIRS is either not set or empty, a value equal to /usr/local/share/:/usr/share/ should be used.
const char *dataDirectoriesPaths = __CFgetenv("XDG_DATA_DIRS");
if ((dataDirectoriesPaths == NULL) || (dataDirectoriesPaths[0] == '\0')) {
// Environmental variable not set. Return default value.
CFStringRef defaultPath[2];
defaultPath[0] = CFSTR("/usr/local/share/");
defaultPath[1] = CFSTR("/usr/share/");
return CFArrayCreate(kCFAllocatorSystemDefault, (const void **)defaultPath, 2, &kCFTypeArrayCallBacks);
}
return _CFCreateCFArrayByTokenizingString(dataDirectoriesPaths, ':');
}


/// a set of preference ordered base directories relative to which configuration files should be searched. This set of directories is defined by the environment variable $XDG_CONFIG_DIRS.
CF_SWIFT_EXPORT
CFArrayRef _CFXDGCreateConfigDirectoriesPaths(void) {
// $XDG_CONFIG_DIRS defines the preference-ordered set of base directories to search for configuration files in addition to the $XDG_CONFIG_HOME base directory. The directories in $XDG_CONFIG_DIRS should be seperated with a colon ':'.
// If $XDG_CONFIG_DIRS is either not set or empty, a value equal to /etc/xdg should be used.
const char *configDirectoriesPaths = __CFgetenv("XDG_CONFIG_DIRS");
if ((configDirectoriesPaths == NULL) || (configDirectoriesPaths[0] == '\0')) {
//Environmental variable not set. Return default value.
CFStringRef defaultPath[1];
defaultPath[0] = CFSTR("/etc/xdg");
return CFArrayCreate(kCFAllocatorSystemDefault, (const void **)defaultPath, 1, &kCFTypeArrayCallBacks);
}
return _CFCreateCFArrayByTokenizingString(configDirectoriesPaths, ':');
}

/// a single base directory relative to which user-specific non-essential (cached) data should be written. This directory is defined by the environment variable $XDG_CACHE_HOME.
CF_SWIFT_EXPORT
CFStringRef _CFXDGCreateCacheDirectoryPath(void) {
//$XDG_CACHE_HOME defines the base directory relative to which user specific non-essential data files should be stored. If $XDG_CACHE_HOME is either not set or empty, a default equal to $HOME/.cache should be used.
const char *cacheHome = __CFgetenv("XDG_CACHE_HOME");
const char *path = __CFgetenv("PATH");
if (cacheHome && strnlen(cacheHome, CFMaxPathSize) > 1 && cacheHome[0] == '/') {
return CFStringCreateWithCString(kCFAllocatorSystemDefault, cacheHome, _kCFXDGStringEncoding);
} else {
CFStringRef home = _CFXDGCreateHome();
CFStringRef result = CFStringCreateWithFormat(kCFAllocatorSystemDefault, NULL, CFSTR("%@/.cache"), home);
CFRelease(home);
return result;
}
}

/// a single base directory relative to which user-specific runtime files and other file objects should be placed. This directory is defined by the environment variable $XDG_RUNTIME_DIR.
CF_SWIFT_EXPORT
CFStringRef _CFXDGCreateRuntimeDirectoryPath(void) {
const char *runtimeDir = __CFgetenv("XDG_RUNTIME_DIR");
if (runtimeDir && strnlen(runtimeDir, CFMaxPathSize) > 1 && runtimeDir[0] == '/') {
return CFStringCreateWithCString(kCFAllocatorSystemDefault, runtimeDir, _kCFXDGStringEncoding);
} else {
// If $XDG_RUNTIME_DIR is not set applications should fall back to a replacement directory with similar capabilities and print a warning message.
return CFStringCreateWithCString(kCFAllocatorSystemDefault, "", _kCFXDGStringEncoding);
}
}


CF_PRIVATE CFArrayRef _CFCreateCFArrayByTokenizingString(const char *values, char delimiter) {
size_t pathCount = 0;
char* tmpDirectoriesPaths = (char*)values;
char* last_colon = 0;
// Count how many paths will be extracted.
while (*tmpDirectoriesPaths)
{
if (*tmpDirectoriesPaths == delimiter)
{
pathCount++;
last_colon = tmpDirectoriesPaths;
}
tmpDirectoriesPaths++;
}
// Add count for trailing path unless ending with colon.
pathCount += last_colon < (values + strlen(values) - 1);
if (pathCount > 0)
{
size_t validPathCount = 0;
CFStringRef pathList[pathCount];
char* copyDirPath = strdup(values);
char delimiterStr[2];
delimiterStr[0] = delimiter;
delimiterStr[1] = '\0';
char* path = strtok(copyDirPath, delimiterStr);
while (path)
{
assert(validPathCount < pathCount);
char* pathString = strdup(path);
CFStringRef dirPath = CFStringCreateWithCString(kCFAllocatorSystemDefault, pathString, _kCFXDGStringEncoding);
CFStringRef slash = CFSTR("/");
CFStringRef tilde = CFSTR("~");
// Check for absolutePath, if not ignore.
if (CFStringHasPrefix(dirPath, slash) || CFStringHasPrefix(dirPath, tilde) ) {
pathList[validPathCount++] = dirPath;
}
path = strtok(NULL, delimiterStr);
free(pathString);
}
free(copyDirPath);
CFArrayRef pathArray = CFArrayCreate(kCFAllocatorSystemDefault, (const void **)pathList , validPathCount, &kCFTypeArrayCallBacks);
for(int i = 0; i < pathCount; i ++) {
CFRelease(pathList[i]);
}
return pathArray;
}
return CFArrayCreate(kCFAllocatorSystemDefault, NULL, 0, &kCFTypeArrayCallBacks);
}

#endif
1 change: 1 addition & 0 deletions CoreFoundation/Base.subproj/CFInternal.h
Original file line number Diff line number Diff line change
Expand Up @@ -609,6 +609,7 @@ CF_PRIVATE CFIndex _CFLengthAfterDeletingPathExtension2(CFStringRef path);
CF_EXPORT CFIndex _CFStartOfPathExtension(UniChar *unichars, CFIndex length);
CF_PRIVATE CFIndex _CFStartOfPathExtension2(CFStringRef path);
CF_EXPORT CFIndex _CFLengthAfterDeletingPathExtension(UniChar *unichars, CFIndex length);
CF_PRIVATE CFArrayRef _CFCreateCFArrayByTokenizingString(const char *values, char delimiter);

#if __BLOCKS__
#if DEPLOYMENT_TARGET_WINDOWS
Expand Down
9 changes: 9 additions & 0 deletions CoreFoundation/Base.subproj/CFRuntime.c
Original file line number Diff line number Diff line change
Expand Up @@ -907,6 +907,15 @@ static struct {
{"CFNumberDisableCache", NULL},
{"__CFPREFERENCES_AVOID_DAEMON", NULL},
{"APPLE_FRAMEWORKS_ROOT", NULL},
#if DEPLOYMENT_RUNTIME_SWIFT
{"HOME", NULL},
{"XDG_DATA_HOME", NULL},
{"XDG_CONFIG_HOME", NULL},
{"XDG_DATA_DIRS", NULL},
{"XDG_CONFIG_DIRS", NULL},
{"XDG_CACHE_HOME", NULL},
{"XDG_RUNTIME_DIR", NULL},
#endif
{NULL, NULL}, // the last one is for optional "COMMAND_MODE" "legacy", do not use this slot, insert before
};

Expand Down
23 changes: 23 additions & 0 deletions CoreFoundation/Base.subproj/ForSwiftFoundationOnly.h
Original file line number Diff line number Diff line change
Expand Up @@ -308,6 +308,29 @@ CF_EXPORT _Nullable CFErrorRef _CFReadStreamCopyError(CFReadStreamRef stream);

CF_EXPORT _Nullable CFErrorRef _CFWriteStreamCopyError(CFWriteStreamRef stream);

// https://specifications.freedesktop.org/basedir-spec/basedir-spec-latest.html
// Version 0.8

// note: All paths set in these environment variables must be absolute.

/// a single base directory relative to which user-specific data files should be written. This directory is defined by the environment variable $XDG_DATA_HOME.
CF_EXPORT CFStringRef _CFXDGCreateDataHomePath(void);

/// a single base directory relative to which user-specific configuration files should be written. This directory is defined by the environment variable $XDG_CONFIG_HOME.
CF_EXPORT CFStringRef _CFXDGCreateConfigHomePath(void);

/// a set of preference ordered base directories relative to which data files should be searched. This set of directories is defined by the environment variable $XDG_DATA_DIRS.
CF_EXPORT CFArrayRef _CFXDGCreateDataDirectoriesPaths(void);

/// a set of preference ordered base directories relative to which configuration files should be searched. This set of directories is defined by the environment variable $XDG_CONFIG_DIRS.
CF_EXPORT CFArrayRef _CFXDGCreateConfigDirectoriesPaths(void);

/// a single base directory relative to which user-specific non-essential (cached) data should be written. This directory is defined by the environment variable $XDG_CACHE_HOME.
CF_EXPORT CFStringRef _CFXDGCreateCacheDirectoryPath(void);

/// a single base directory relative to which user-specific runtime files and other file objects should be placed. This directory is defined by the environment variable $XDG_RUNTIME_DIR.
CF_EXPORT CFStringRef _CFXDGCreateRuntimeDirectoryPath(void);

_CF_EXPORT_SCOPE_END

#endif /* __COREFOUNDATION_FORSWIFTFOUNDATIONONLY__ */
4 changes: 4 additions & 0 deletions Foundation.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
/* Begin PBXBuildFile section */
0383A1751D2E558A0052E5D1 /* TestNSStream.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0383A1741D2E558A0052E5D1 /* TestNSStream.swift */; };
1520469B1D8AEABE00D02E36 /* HTTPServer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1520469A1D8AEABE00D02E36 /* HTTPServer.swift */; };
159884921DCC877700E3314C /* TestNSHTTPCookieStorage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 159884911DCC877700E3314C /* TestNSHTTPCookieStorage.swift */; };
231503DB1D8AEE5D0061694D /* TestNSDecimal.swift in Sources */ = {isa = PBXBuildFile; fileRef = 231503DA1D8AEE5D0061694D /* TestNSDecimal.swift */; };
294E3C1D1CC5E19300E4F44C /* TestNSAttributedString.swift in Sources */ = {isa = PBXBuildFile; fileRef = 294E3C1C1CC5E19300E4F44C /* TestNSAttributedString.swift */; };
2EBE67A51C77BF0E006583D5 /* TestNSDateFormatter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2EBE67A31C77BF05006583D5 /* TestNSDateFormatter.swift */; };
Expand Down Expand Up @@ -464,6 +465,7 @@
/* Begin PBXFileReference section */
0383A1741D2E558A0052E5D1 /* TestNSStream.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TestNSStream.swift; sourceTree = "<group>"; };
1520469A1D8AEABE00D02E36 /* HTTPServer.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = HTTPServer.swift; sourceTree = "<group>"; };
159884911DCC877700E3314C /* TestNSHTTPCookieStorage.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TestNSHTTPCookieStorage.swift; sourceTree = "<group>"; };
22B9C1E01C165D7A00DECFF9 /* TestNSDate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TestNSDate.swift; sourceTree = "<group>"; };
231503DA1D8AEE5D0061694D /* TestNSDecimal.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TestNSDecimal.swift; sourceTree = "<group>"; };
294E3C1C1CC5E19300E4F44C /* TestNSAttributedString.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TestNSAttributedString.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -1334,6 +1336,7 @@
EA66F65A1BF1976100136161 /* Tests */ = {
isa = PBXGroup;
children = (
159884911DCC877700E3314C /* TestNSHTTPCookieStorage.swift */,
D4FE895A1D703D1100DA7986 /* TestURLRequest.swift */,
C93559281C12C49F009FD6A9 /* TestNSAffineTransform.swift */,
EA66F63C1BF1619600136161 /* TestNSArray.swift */,
Expand Down Expand Up @@ -2228,6 +2231,7 @@
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
159884921DCC877700E3314C /* TestNSHTTPCookieStorage.swift in Sources */,
5FE52C951D147D1C00F7D270 /* TestNSTextCheckingResult.swift in Sources */,
5B13B3451C582D4C00651CE2 /* TestNSString.swift in Sources */,
1520469B1D8AEABE00D02E36 /* HTTPServer.swift in Sources */,
Expand Down
Loading