RetainPtr<CFDataRef> LegacyWebArchive::rawDataRepresentation() { RetainPtr<CFDictionaryRef> propertyList = createPropertyListRepresentation(this); ASSERT(propertyList); if (!propertyList) { LOG(Archives, "LegacyWebArchive - Failed to create property list for archive, returning no data"); return 0; } RetainPtr<CFWriteStreamRef> stream(AdoptCF, CFWriteStreamCreateWithAllocatedBuffers(0, 0)); CFWriteStreamOpen(stream.get()); CFPropertyListWriteToStream(propertyList.get(), stream.get(), kCFPropertyListBinaryFormat_v1_0, 0); RetainPtr<CFDataRef> plistData(AdoptCF, static_cast<CFDataRef>(CFWriteStreamCopyProperty(stream.get(), kCFStreamPropertyDataWritten))); ASSERT(plistData); CFWriteStreamClose(stream.get()); if (!plistData) { LOG(Archives, "LegacyWebArchive - Failed to convert property list into raw data, returning no data"); return 0; } return plistData; }
RefPtr<API::Data> encodeLegacySessionState(const SessionState& sessionState) { auto sessionHistoryDictionary = encodeSessionHistory(sessionState.backForwardListState); auto provisionalURLString = sessionState.provisionalURL.isNull() ? nullptr : sessionState.provisionalURL.string().createCFString(); RetainPtr<CFNumberRef> renderTreeSizeNumber(adoptCF(CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt64Type, &sessionState.renderTreeSize))); RetainPtr<CFDictionaryRef> stateDictionary; if (provisionalURLString) { stateDictionary = createDictionary({ { sessionHistoryKey, sessionHistoryDictionary.get() }, { provisionalURLKey, provisionalURLString.get() }, { renderTreeSizeKey, renderTreeSizeNumber.get() } }); } else { stateDictionary = createDictionary({ { sessionHistoryKey, sessionHistoryDictionary.get() }, { renderTreeSizeKey, renderTreeSizeNumber.get() } }); } auto writeStream = adoptCF(CFWriteStreamCreateWithAllocatedBuffers(kCFAllocatorDefault, nullptr)); if (!writeStream) return nullptr; if (!CFWriteStreamOpen(writeStream.get())) return nullptr; if (!CFPropertyListWrite(stateDictionary.get(), writeStream.get(), kCFPropertyListBinaryFormat_v1_0, 0, nullptr)) return nullptr; auto data = adoptCF(static_cast<CFDataRef>(CFWriteStreamCopyProperty(writeStream.get(), kCFStreamPropertyDataWritten))); CFIndex length = CFDataGetLength(data.get()); size_t bufferSize = length + sizeof(uint32_t); auto buffer = MallocPtr<uint8_t>::malloc(bufferSize); // Put the session state version number at the start of the buffer buffer.get()[0] = (sessionStateDataVersion & 0xff000000) >> 24; buffer.get()[1] = (sessionStateDataVersion & 0x00ff0000) >> 16; buffer.get()[2] = (sessionStateDataVersion & 0x0000ff00) >> 8; buffer.get()[3] = (sessionStateDataVersion & 0x000000ff); // Copy in the actual session state data CFDataGetBytes(data.get(), CFRangeMake(0, length), buffer.get() + sizeof(uint32_t)); return API::Data::createWithoutCopying(buffer.leakPtr(), bufferSize, [] (unsigned char* buffer, const void* context) { fastFree(buffer); }, nullptr); }
sdmmd_return_t SDMMD_ServiceSendStream(SocketConnection handle, CFPropertyListRef data, CFPropertyListFormat format) { CFStringRef errStr; CFWriteStreamRef write = CFWriteStreamCreateWithAllocatedBuffers(kCFAllocatorDefault, kCFAllocatorDefault); CFWriteStreamOpen(write); uint32_t length = CFPropertyListWriteToStream(data, write, format, &errStr); CFDataRef xmlData = CFWriteStreamCopyProperty(write, kCFStreamPropertyDataWritten); sdmmd_return_t result = kAMDInvalidArgumentError; if (length == CFDataGetLength(xmlData)) { result = ((data) ? SDMMD_ServiceSend(handle, xmlData) : kAMDInvalidArgumentError); } if (xmlData) CFRelease(xmlData); CFWriteStreamClose(write); if (write) CFRelease(write); return result; }
CFNetDiagnosticStatus CFNetDiagnosticDiagnoseProblemInteractively(CFNetDiagnosticRef details) { SInt32 retval = 0; mach_port_t port = MACH_PORT_NULL; CFDataRef msgData = NULL; kern_return_t err; //build message CFWriteStreamRef stream = CFWriteStreamCreateWithAllocatedBuffers(kCFAllocatorDefault, kCFAllocatorDefault); CFWriteStreamOpen(stream); CFIndex len = CFPropertyListWriteToStream(details, stream, kCFPropertyListBinaryFormat_v1_0, NULL); CFWriteStreamClose(stream); if(len > 0) { msgData = CFWriteStreamCopyProperty(stream, kCFStreamPropertyDataWritten); } CFRelease(stream); if(msgData) { err = bootstrap_look_up(bootstrap_port, *((name_t*)(&_CFNetDiagnosticMachPortName)), &port); if (err == KERN_SUCCESS) { err = _CFNetDiagnosticClient_passDescriptor( port, _CFNetDiagnosticMachProtocolVersion, (vm_address_t)CFDataGetBytePtr(msgData), CFDataGetLength(msgData)); if (err == KERN_SUCCESS) { //FIXME Yay!!! } } CFRelease(msgData); } return (CFNetDiagnosticStatus)retval; }
// domain should already be locked. static Boolean _writeXMLFile(CFURLRef url, CFMutableDictionaryRef dict, Boolean isWorldReadable, Boolean *tryAgain) { Boolean success = false; CFAllocatorRef alloc = __CFPreferencesAllocator(); *tryAgain = false; if (CFDictionaryGetCount(dict) == 0) { // Destroy the file CFBooleanRef val = (CFBooleanRef) CFURLCreatePropertyFromResource(alloc, url, kCFURLFileExists, NULL); if (val && CFBooleanGetValue(val)) { success = CFURLDestroyResource(url, NULL); } else { success = true; } if (val) CFRelease(val); } else { CFPropertyListFormat desiredFormat = __CFPreferencesShouldWriteXML() ? kCFPropertyListXMLFormat_v1_0 : kCFPropertyListBinaryFormat_v1_0; CFWriteStreamRef binStream = CFWriteStreamCreateWithAllocatedBuffers(alloc, alloc); CFWriteStreamOpen(binStream); CFPropertyListWriteToStream(dict, binStream, desiredFormat, NULL); CFWriteStreamClose(binStream); CFDataRef data = (CFDataRef) CFWriteStreamCopyProperty(binStream, kCFStreamPropertyDataWritten); CFRelease(binStream); if (data) { SInt32 mode; #if DEPLOYMENT_TARGET_MACOSX mode = isWorldReadable ? S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH : S_IRUSR|S_IWUSR; #else mode = 0666; #endif #if DEPLOYMENT_TARGET_MACOSX { // Try quick atomic way first, then fallback to slower ways and error cases CFStringRef scheme = CFURLCopyScheme(url); if (!scheme) { *tryAgain = false; CFRelease(data); return false; } else if (CFStringCompare(scheme, CFSTR("file"), 0) == kCFCompareEqualTo) { SInt32 length = CFDataGetLength(data); const void *bytes = (0 == length) ? (const void *)"" : CFDataGetBytePtr(data); Boolean atomicWriteSuccess = __CFWriteBytesToFileWithAtomicity(url, bytes, length, mode, true); if (atomicWriteSuccess) { CFRelease(scheme); *tryAgain = false; CFRelease(data); return true; } if (!atomicWriteSuccess && thread_errno() == ENOSPC) { CFRelease(scheme); *tryAgain = false; CFRelease(data); return false; } } CFRelease(scheme); } #endif success = CFURLWriteDataAndPropertiesToResource(url, data, URLPropertyDictForPOSIXMode(mode), NULL); URLPropertyDictRelease(); if (success) { CFDataRef readData; if (!CFURLCreateDataAndPropertiesFromResource(alloc, url, &readData, NULL, NULL, NULL) || !CFEqual(readData, data)) { success = false; *tryAgain = true; } if (readData) CFRelease(readData); } else { CFBooleanRef val = (CFBooleanRef) CFURLCreatePropertyFromResource(alloc, url, kCFURLFileExists, NULL); if (!val || !CFBooleanGetValue(val)) { CFURLRef tmpURL = CFURLCreateWithFileSystemPathRelativeToBase(alloc, CFSTR("."), kCFURLPOSIXPathStyle, true, url); // Just "." because url is not a directory URL CFURLRef parentURL = tmpURL ? CFURLCopyAbsoluteURL(tmpURL) : NULL; if (tmpURL) CFRelease(tmpURL); if (val) CFRelease(val); val = (CFBooleanRef) CFURLCreatePropertyFromResource(alloc, parentURL, kCFURLFileExists, NULL); if ((!val || !CFBooleanGetValue(val)) && _createDirectory(parentURL, isWorldReadable)) { // parent directory didn't exist; now it does; try again to write success = CFURLWriteDataAndPropertiesToResource(url, data, URLPropertyDictForPOSIXMode(mode), NULL); URLPropertyDictRelease(); if (success) { CFDataRef rdData; if (!CFURLCreateDataAndPropertiesFromResource(alloc, url, &rdData, NULL, NULL, NULL) || !CFEqual(rdData, data)) { success = false; *tryAgain = true; } if (rdData) CFRelease(rdData); } } if (parentURL) CFRelease(parentURL); } if (val) CFRelease(val); } CFRelease(data); } else { // ??? This should never happen CFLog(__kCFLogAssertion, CFSTR("Could not generate XML data for property list")); success = false; } } return success; }