SplitTestInitializer.cpp [plain text]
#include "config.h"
#include "SplitTestInitializer.h"
#if !PLATFORM(IOS) && OS(DARWIN) && USE(APPLE_INTERNAL_SDK)
#include <dlfcn.h>
#include <mutex>
#include <WebCore/SoftLinking.h>
#include <wtf/ASCIICType.h>
#include <wtf/Optional.h>
#include <wtf/SplitTest.h>
SOFT_LINK_PRIVATE_FRAMEWORK(CrashReporterSupport);
SOFT_LINK(CrashReporterSupport, CRGetUserUUID, CFStringRef, (void), ());
namespace {
struct UUID {
uint64_t lo;
uint64_t hi;
};
std::optional<UUID> getUUID()
{
static constexpr const size_t maxBytes = 37;
static bool failed = true;
static UUID uuid = { 0, 0 };
static std::once_flag once;
std::call_once(once, [] {
char userUUID[maxBytes] = { '\0' };
CFStringRef (*softLinkCRGetUserUUID)(void) = (CFStringRef (*)(void)) dlsym(CrashReporterSupportLibrary(), "CRGetUserUUID");
if (!softLinkCRGetUserUUID)
return;
CFStringRef userUUIDString = CRGetUserUUID();
CFIndex length = CFStringGetLength(userUUIDString);
CFRange range = CFRangeMake(0, length);
CFIndex numConvertedCharacters = CFStringGetBytes(userUUIDString, range, kCFStringEncodingASCII, 0, false, reinterpret_cast<UInt8*>(userUUID), maxBytes - 1, nullptr);
if (numConvertedCharacters <= 0 || static_cast<size_t>(numConvertedCharacters) >= maxBytes)
return;
size_t nibblesDecoded = 0;
for (size_t position = 0; position < maxBytes; ++position) {
uint64_t nibble;
int c = toASCIILowerUnchecked(userUUID[position]);
if (c >= 'a' && c <= 'f')
nibble = c - 'a' + 10;
else if (c >= '0' && c <= '9')
nibble = c - '0';
else
continue;
if (nibblesDecoded < 64 / 4) {
uuid.lo <<= 4;
uuid.lo |= nibble;
} else {
uuid.hi <<= 4;
uuid.hi |= nibble;
}
++nibblesDecoded;
}
failed = false;
});
return failed ? std::optional<UUID>() : uuid;
}
}
void initSplitTest()
{
std::optional<UUID> uuid = getUUID();
if (!uuid)
return;
SplitTest::singleton().initializeSingleton(uuid->lo, uuid->hi);
}
#else
void initSplitTest()
{
}
#endif