Fix memory leaks

This commit is contained in:
schmidt9
2017-07-17 17:14:43 +03:00
committed by Howard Hinnant
parent a828109809
commit 496497d16e

99
ios.mm
View File

@@ -36,7 +36,8 @@
# define TAR_DEBUG 0 # define TAR_DEBUG 0
#endif #endif
#define INTERNAL_DIR "Library/tzdata" #define INTERNAL_DIR "Library"
#define TZDATA_DIR "tzdata"
#define TARGZ_EXTENSION "tar.gz" #define TARGZ_EXTENSION "tar.gz"
#define TAR_BLOCK_SIZE 512 #define TAR_BLOCK_SIZE 512
@@ -60,7 +61,7 @@ struct TarInfo
bool success; bool success;
}; };
char* convertCFStringRefPathToCStringPath(CFStringRef ref); std::string convertCFStringRefPathToCStringPath(CFStringRef ref);
bool extractTzdata(CFURLRef homeUrl, CFURLRef archiveUrl, std::string destPath); bool extractTzdata(CFURLRef homeUrl, CFURLRef archiveUrl, std::string destPath);
TarInfo getTarObjectInfo(CFReadStreamRef readStream, int64_t location); TarInfo getTarObjectInfo(CFReadStreamRef readStream, int64_t location);
std::string getTarObject(CFReadStreamRef readStream, int64_t size); std::string getTarObject(CFReadStreamRef readStream, int64_t size);
@@ -68,19 +69,43 @@ bool writeFile(CFURLRef tzdataUrl, std::string fileName, std::string data,
int64_t realContentSize); int64_t realContentSize);
std::string std::string
date::iOSUtils::get_tzdata_path() get_current_timezone()
{ {
CFURLRef ref = CFCopyHomeDirectoryURL(); CFTimeZoneRef tzRef = CFTimeZoneCopySystem();
CFStringRef homePath = CFURLCopyPath(CFCopyHomeDirectoryURL()); CFStringRef tzNameRef = CFTimeZoneGetName(tzRef);
std::string tzdata_path(std::string(convertCFStringRefPathToCStringPath(homePath)) + CFIndex bufferSize = CFStringGetLength(tzNameRef) + 1;
char buffer[bufferSize];
if (CFStringGetCString(tzNameRef, buffer, bufferSize, kCFStringEncodingUTF8))
{
CFRelease(tzRef);
return std::string(buffer);
}
CFRelease(tzRef);
return "";
}
std::string
get_tzdata_path()
{
CFURLRef homeUrlRef = CFCopyHomeDirectoryURL();
CFStringRef homePath = CFURLCopyPath(homeUrlRef);
std::string path(std::string(convertCFStringRefPathToCStringPath(homePath)) +
INTERNAL_DIR + "/" + TZDATA_DIR);
std::string result_path(std::string(convertCFStringRefPathToCStringPath(homePath)) +
INTERNAL_DIR); INTERNAL_DIR);
if (access(tzdata_path.c_str(), F_OK) == 0) if (access(path.c_str(), F_OK) == 0)
{ {
#if TAR_DEBUG #if TAR_DEBUG
printf("tzdata exists\n"); printf("tzdata dir exists\n");
#endif #endif
return tzdata_path; CFRelease(homeUrlRef);
CFRelease(homePath);
return result_path;
} }
CFBundleRef mainBundle = CFBundleGetMainBundle(); CFBundleRef mainBundle = CFBundleGetMainBundle();
@@ -94,19 +119,28 @@ date::iOSUtils::get_tzdata_path()
CFStringRef archiveName = CFURLCopyPath(archiveUrl); CFStringRef archiveName = CFURLCopyPath(archiveUrl);
archiveUrl = CFBundleCopyResourceURL(mainBundle, archiveName, NULL, NULL); archiveUrl = CFBundleCopyResourceURL(mainBundle, archiveName, NULL, NULL);
extractTzdata(CFCopyHomeDirectoryURL(), archiveUrl, tzdata_path); extractTzdata(homeUrlRef, archiveUrl, path);
CFRelease(archiveUrl);
CFRelease(archiveName);
} }
return tzdata_path; CFRelease(homeUrlRef);
CFRelease(homePath);
CFRelease(paths);
return result_path;
} }
char* std::string
convertCFStringRefPathToCStringPath(CFStringRef ref) convertCFStringRefPathToCStringPath(CFStringRef ref)
{ {
CFIndex bufferSize = CFStringGetMaximumSizeOfFileSystemRepresentation(ref); CFIndex bufferSize = CFStringGetMaximumSizeOfFileSystemRepresentation(ref);
char *buffer = new char[bufferSize]; char *buffer = new char[bufferSize];
CFStringGetFileSystemRepresentation(ref, buffer, bufferSize); CFStringGetFileSystemRepresentation(ref, buffer, bufferSize);
return buffer; auto result = std::string(buffer);
delete[] buffer;
return result;
} }
bool extractTzdata(CFURLRef homeUrl, CFURLRef archiveUrl, std::string destPath) bool extractTzdata(CFURLRef homeUrl, CFURLRef archiveUrl, std::string destPath)
@@ -114,28 +148,29 @@ bool extractTzdata(CFURLRef homeUrl, CFURLRef archiveUrl, std::string destPath)
const char *TAR_TMP_PATH = "/tmp.tar"; const char *TAR_TMP_PATH = "/tmp.tar";
// create Library path // create Library path
CFStringRef libraryStr = CFStringCreateWithCString(NULL, "Library", CFStringRef libraryStr = CFStringCreateWithCString(NULL, INTERNAL_DIR,
CFStringGetSystemEncoding()); CFStringGetSystemEncoding());
CFURLRef libraryUrl = CFURLCreateCopyAppendingPathComponent(kCFAllocatorDefault, CFURLRef libraryUrl = CFURLCreateCopyAppendingPathComponent(kCFAllocatorDefault,
homeUrl, libraryStr, homeUrl, libraryStr,
false); false);
// create tzdata path // create tzdata path
CFStringRef tzdataPathRef = CFStringCreateWithCString(NULL, INTERNAL_DIR, CFStringRef tzdataPathRef = CFStringCreateWithCString(NULL, std::string(std::string(INTERNAL_DIR) + "/" + TZDATA_DIR).c_str(),
CFStringGetSystemEncoding()); CFStringGetSystemEncoding());
CFURLRef tzdataPathUrl = CFURLCreateCopyAppendingPathComponent(NULL, homeUrl, CFURLRef tzdataPathUrl = CFURLCreateCopyAppendingPathComponent(NULL, homeUrl,
tzdataPathRef, false); tzdataPathRef, false);
// create src archive path // create src archive path
CFStringRef archivePath = CFURLCopyPath(archiveUrl); CFStringRef archivePath = CFURLCopyPath(archiveUrl);
gzFile tarFile = gzopen(convertCFStringRefPathToCStringPath(archivePath), "rb"); gzFile tarFile = gzopen(convertCFStringRefPathToCStringPath(archivePath).c_str(), "rb");
// create tar unpacking path // create tar unpacking path
CFStringRef tarName = CFStringCreateWithCString(NULL, TAR_TMP_PATH, CFStringRef tarName = CFStringCreateWithCString(NULL, TAR_TMP_PATH,
CFStringGetSystemEncoding()); CFStringGetSystemEncoding());
CFURLRef tarUrl = CFURLCreateCopyAppendingPathComponent(NULL, libraryUrl, tarName, CFURLRef tarUrl = CFURLCreateCopyAppendingPathComponent(NULL, libraryUrl, tarName,
false); false);
const char *tarPath = convertCFStringRefPathToCStringPath(CFURLCopyPath(tarUrl)); CFStringRef tarPathRef = CFURLCopyPath(tarUrl);
auto tarPath = convertCFStringRefPathToCStringPath(tarPathRef);
// create tzdata directory // create tzdata directory
mkdir(destPath.c_str(), S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH); mkdir(destPath.c_str(), S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH);
@@ -144,6 +179,13 @@ bool extractTzdata(CFURLRef homeUrl, CFURLRef archiveUrl, std::string destPath)
CFWriteStreamRef writeStream = CFWriteStreamCreateWithFile(NULL, tarUrl); CFWriteStreamRef writeStream = CFWriteStreamCreateWithFile(NULL, tarUrl);
bool success = true; bool success = true;
CFRelease(libraryStr);
CFRelease(libraryUrl);
CFRelease(tzdataPathRef);
CFRelease(archivePath);
CFRelease(tarName);
CFRelease(tarPathRef);
if (!CFWriteStreamOpen(writeStream)) if (!CFWriteStreamOpen(writeStream))
{ {
CFStreamError err = CFWriteStreamGetError(writeStream); CFStreamError err = CFWriteStreamGetError(writeStream);
@@ -162,7 +204,8 @@ bool extractTzdata(CFURLRef homeUrl, CFURLRef archiveUrl, std::string destPath)
if (!success) if (!success)
{ {
remove(tarPath); CFRelease(tzdataPathUrl);
CFRelease(writeStream);
return false; return false;
} }
@@ -213,7 +256,7 @@ bool extractTzdata(CFURLRef homeUrl, CFURLRef archiveUrl, std::string destPath)
if (!success) if (!success)
{ {
remove(tarPath); CFRelease(tzdataPathUrl);
return false; return false;
} }
@@ -223,17 +266,18 @@ bool extractTzdata(CFURLRef homeUrl, CFURLRef archiveUrl, std::string destPath)
// get file size // get file size
struct stat stat_buf; struct stat stat_buf;
int res = stat(tarPath, &stat_buf); int res = stat(tarPath.c_str(), &stat_buf);
if (res != 0) if (res != 0)
{ {
printf("error file size\n"); printf("error file size\n");
remove(tarPath); CFRelease(tzdataPathUrl);
return false; return false;
} }
int64_t tarSize = stat_buf.st_size; int64_t tarSize = stat_buf.st_size;
// create read stream // create read stream
CFReadStreamRef readStream = CFReadStreamCreateWithFile(kCFAllocatorDefault, tarUrl); CFReadStreamRef readStream = CFReadStreamCreateWithFile(kCFAllocatorDefault, tarUrl);
CFRelease(tarUrl);
if (!CFReadStreamOpen(readStream)) if (!CFReadStreamOpen(readStream))
{ {
@@ -253,14 +297,11 @@ bool extractTzdata(CFURLRef homeUrl, CFURLRef archiveUrl, std::string destPath)
if (!success) if (!success)
{ {
CFRelease(tzdataPathUrl);
CFRelease(readStream); CFRelease(readStream);
remove(tarPath);
return false; return false;
} }
int count = 0;
long size = 0;
// process files // process files
while (location < tarSize) while (location < tarSize)
{ {
@@ -290,11 +331,10 @@ bool extractTzdata(CFURLRef homeUrl, CFURLRef archiveUrl, std::string destPath)
} }
} }
CFRelease(tzdataPathUrl);
CFReadStreamClose(readStream); CFReadStreamClose(readStream);
CFRelease(readStream); CFRelease(readStream);
remove(tarPath);
return true; return true;
} }
@@ -309,8 +349,6 @@ getTarObjectInfo(CFReadStreamRef readStream, int64_t location)
char sizeBuf[TAR_SIZE_SIZE + 1]; char sizeBuf[TAR_SIZE_SIZE + 1];
CFIndex bytesRead; CFIndex bytesRead;
bool avail = CFReadStreamHasBytesAvailable(readStream);
bytesRead = CFReadStreamRead(readStream, buffer, length); bytesRead = CFReadStreamRead(readStream, buffer, length);
if (bytesRead < 0) if (bytesRead < 0)
@@ -360,6 +398,9 @@ writeFile(CFURLRef tzdataUrl, std::string fileName, std::string data,
false); false);
CFWriteStreamRef writeStream = CFWriteStreamCreateWithFile(NULL, url); CFWriteStreamRef writeStream = CFWriteStreamCreateWithFile(NULL, url);
CFRelease(fileNameRef);
CFRelease(url);
// open stream // open stream
if (!CFWriteStreamOpen(writeStream)) if (!CFWriteStreamOpen(writeStream))
{ {