Diff
Modified: trunk/Source/WebKit2/ChangeLog (102496 => 102497)
--- trunk/Source/WebKit2/ChangeLog 2011-12-10 01:18:20 UTC (rev 102496)
+++ trunk/Source/WebKit2/ChangeLog 2011-12-10 01:25:29 UTC (rev 102497)
@@ -1,3 +1,34 @@
+2011-12-07 Mark Rowe <[email protected]>
+
+ <http://webkit.org/b/74061> WebProcess and PluginProcess should inherit environment
+ variables provided in LC_DYLD_ENVIRONMENT of main executable binary.
+
+ Reviewed by Darin Adler.
+
+ * UIProcess/Launcher/mac/DynamicLinkerEnvironmentExtractor.h: Added.
+ * UIProcess/Launcher/mac/DynamicLinkerEnvironmentExtractor.mm: Added.
+ (WebKit::DynamicLinkerEnvironmentExtractor::DynamicLinkerEnvironmentExtractor):
+ (WebKit::DynamicLinkerEnvironmentExtractor::processEnvironmentVariable): Parse out the name
+ and value from the environment string and add an entry to our variable map if the variable
+ is one that dyld would respect in LC_DYLD_ENVIRONMENT.
+ (WebKit::DynamicLinkerEnvironmentExtractor::processLoadCommand): Look for a LC_DYLD_ENVIRONMENT
+ load command and extract any environment string that we find within.
+ (WebKit::DynamicLinkerEnvironmentExtractor::processLoadCommands): Iterate over each
+ load command in the Mach-O file.
+ (WebKit::DynamicLinkerEnvironmentExtractor::processSingleArchitecture): Determine whether
+ the Mach-O file is of the correct architecture, and if so then process the load commands
+ found within.
+ (WebKit::DynamicLinkerEnvironmentExtractor::processFatFile): Process each architecture of the
+ Mach-O file in turn.
+ (WebKit::DynamicLinkerEnvironmentExtractor::getExtractedEnvironmentVariables): Add our
+ extracted variables to the passed-in EnvironmentVariables object. We skip adding any
+ variables that already exist so as to allow variables passed in the environment to override
+ those that we extract from the executable file.
+ * UIProcess/Launcher/mac/ProcessLauncherMac.mm:
+ (WebKit::ProcessLauncher::launchProcess): Extract the environment variables from the
+ main binary and add them to the launch environment of our subprocess.
+ * WebKit2.xcodeproj/project.pbxproj:
+
2011-12-09 Sam Weinig <[email protected]>
Add WKView implementation for quickLookPreviewItemsAtWindowLocation.
Added: trunk/Source/WebKit2/UIProcess/Launcher/mac/DynamicLinkerEnvironmentExtractor.h (0 => 102497)
--- trunk/Source/WebKit2/UIProcess/Launcher/mac/DynamicLinkerEnvironmentExtractor.h (rev 0)
+++ trunk/Source/WebKit2/UIProcess/Launcher/mac/DynamicLinkerEnvironmentExtractor.h 2011-12-10 01:25:29 UTC (rev 102497)
@@ -0,0 +1,62 @@
+/*
+ * Copyright (C) 2011 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef DynamicLinkerEnvironmentExtractor_h
+#define DynamicLinkerEnvironmentExtractor_h
+
+#include <mach/machine.h>
+#include <wtf/Noncopyable.h>
+#include <wtf/RetainPtr.h>
+#include <wtf/Vector.h>
+#include <wtf/text/CString.h>
+
+namespace WebKit {
+
+class EnvironmentVariables;
+
+class DynamicLinkerEnvironmentExtractor {
+ WTF_MAKE_NONCOPYABLE(DynamicLinkerEnvironmentExtractor);
+
+public:
+ DynamicLinkerEnvironmentExtractor(NSString *executablePath, cpu_type_t architecture);
+
+ void getExtractedEnvironmentVariables(EnvironmentVariables&) const;
+
+private:
+ void processSingleArchitecture(const void* data, size_t length);
+ void processFatFile(const void* data, size_t length);
+ void processLoadCommands(const void* data, size_t length, int32_t numberOfCommands, bool shouldByteSwap);
+ size_t processLoadCommand(const void* data, size_t length, bool shouldByteSwap);
+ void processEnvironmentVariable(const char* environmentString);
+
+ RetainPtr<NSString> m_executablePath;
+ cpu_type_t m_architecture;
+
+ Vector<std::pair<CString, CString> > m_extractedVariables;
+};
+
+} // namespace WebKit
+
+#endif // DynamicLinkerEnvironmentExtractor_h
Added: trunk/Source/WebKit2/UIProcess/Launcher/mac/DynamicLinkerEnvironmentExtractor.mm (0 => 102497)
--- trunk/Source/WebKit2/UIProcess/Launcher/mac/DynamicLinkerEnvironmentExtractor.mm (rev 0)
+++ trunk/Source/WebKit2/UIProcess/Launcher/mac/DynamicLinkerEnvironmentExtractor.mm 2011-12-10 01:25:29 UTC (rev 102497)
@@ -0,0 +1,200 @@
+/*
+ * Copyright (C) 2011 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "DynamicLinkerEnvironmentExtractor.h"
+
+#include "EnvironmentVariables.h"
+#include <mach-o/loader.h>
+#include <mach-o/swap.h>
+#include <wtf/OwnPtr.h>
+#include <wtf/PassOwnPtr.h>
+#include <wtf/text/WTFString.h>
+
+namespace WebKit {
+
+DynamicLinkerEnvironmentExtractor::DynamicLinkerEnvironmentExtractor(NSString *executablePath, cpu_type_t architecture)
+ : m_executablePath(executablePath)
+ , m_architecture(architecture)
+{
+ NSData *mainExecutableData = [NSData dataWithContentsOfFile:m_executablePath.get() options:NSDataReadingMappedIfSafe error:0];
+ if (!mainExecutableData)
+ return;
+
+ const void* mainExecutableBytes = [mainExecutableData bytes];
+ size_t length = [mainExecutableData length];
+ if (length < sizeof(uint32_t))
+ return;
+
+ uint32_t magicValue = *static_cast<const uint32_t*>(mainExecutableBytes);
+ if (magicValue == FAT_MAGIC || magicValue == FAT_CIGAM) {
+ processFatFile(mainExecutableBytes, length);
+ return;
+ }
+
+ processSingleArchitecture(mainExecutableBytes, length);
+}
+
+#define DEFINE_BYTE_SWAPPER(type) inline type byteSwapIfNeeded(const type& data, bool shouldByteSwap) \
+{ \
+ type swapped = data; \
+ if (shouldByteSwap) \
+ swap_##type(&swapped, NX_UnknownByteOrder); \
+ return swapped; \
+}
+
+DEFINE_BYTE_SWAPPER(load_command)
+DEFINE_BYTE_SWAPPER(dylinker_command)
+DEFINE_BYTE_SWAPPER(mach_header)
+DEFINE_BYTE_SWAPPER(mach_header_64)
+
+#undef DEFINE_BYTE_SWAPPER
+
+void DynamicLinkerEnvironmentExtractor::processEnvironmentVariable(const char* environmentString)
+{
+ const char* equalsLocation = strchr(environmentString, '=');
+ if (!equalsLocation)
+ return;
+
+ size_t nameLength = equalsLocation - environmentString;
+ String name(environmentString, nameLength);
+
+ // LC_DYLD_ENVIRONMENT only respects DYLD_*_PATH variables.
+ if (!name.startsWith("DYLD_") || !name.endsWith("_PATH"))
+ return;
+
+ CString value(equalsLocation + 1);
+ m_extractedVariables.append(make_pair(name.latin1(), value));
+}
+
+size_t DynamicLinkerEnvironmentExtractor::processLoadCommand(const void* data, size_t length, bool shouldByteSwap)
+{
+ if (length < sizeof(load_command))
+ return 0;
+
+ const load_command* rawLoadCommand = static_cast<const load_command*>(data);
+ load_command loadCommand = byteSwapIfNeeded(*rawLoadCommand, shouldByteSwap);
+
+ if (length < loadCommand.cmdsize)
+ return 0;
+
+ if (loadCommand.cmd == LC_DYLD_ENVIRONMENT) {
+ if (length < sizeof(dylinker_command))
+ return 0;
+
+ dylinker_command environmentCommand = byteSwapIfNeeded(*reinterpret_cast<const dylinker_command*>(rawLoadCommand), shouldByteSwap);
+ if (loadCommand.cmdsize < environmentCommand.name.offset)
+ return 0;
+
+ size_t environmentStringLength = loadCommand.cmdsize - environmentCommand.name.offset;
+ Vector<char, 256> environmentString;
+ environmentString.reserveCapacity(environmentStringLength + 1);
+ environmentString.append(reinterpret_cast<const char*>(rawLoadCommand) + environmentCommand.name.offset, environmentStringLength);
+ environmentString.append(0);
+
+ processEnvironmentVariable(environmentString.data());
+ }
+
+ return loadCommand.cmdsize;
+}
+
+void DynamicLinkerEnvironmentExtractor::processLoadCommands(const void* data, size_t length, int32_t numberOfCommands, bool shouldByteSwap)
+{
+ const void* dataRemaining = data;
+ size_t lengthRemaining = length;
+ for (int i = 0; i < numberOfCommands; i++) {
+ size_t commandLength = processLoadCommand(dataRemaining, lengthRemaining, shouldByteSwap);
+ if (!commandLength || lengthRemaining < commandLength)
+ return;
+
+ dataRemaining = static_cast<const char*>(dataRemaining) + commandLength;
+ lengthRemaining -= commandLength;
+ }
+}
+
+void DynamicLinkerEnvironmentExtractor::processSingleArchitecture(const void* data, size_t length)
+{
+ if (length < sizeof(mach_header))
+ return;
+
+ const mach_header* header = static_cast<const mach_header*>(data);
+ if (header->magic == MH_MAGIC || header->magic == MH_CIGAM) {
+ bool shouldByteSwap = header->magic == MH_CIGAM;
+ mach_header swappedHeader = byteSwapIfNeeded(*header, shouldByteSwap);
+ if (swappedHeader.cputype == m_architecture)
+ processLoadCommands(static_cast<const char*>(data) + sizeof(*header), length - sizeof(*header), swappedHeader.ncmds, shouldByteSwap);
+ return;
+ }
+
+ if (length < sizeof(mach_header_64))
+ return;
+
+ const mach_header_64* header64 = static_cast<const mach_header_64*>(data);
+ bool shouldByteSwap = header->magic == MH_CIGAM_64;
+ mach_header_64 swappedHeader64 = byteSwapIfNeeded(*header64, shouldByteSwap);
+ if (swappedHeader64.cputype == m_architecture)
+ processLoadCommands(static_cast<const char*>(data) + sizeof(*header64), length - sizeof(*header64), swappedHeader64.ncmds, shouldByteSwap);
+}
+
+void DynamicLinkerEnvironmentExtractor::processFatFile(const void* data, size_t length)
+{
+ if (length < sizeof(fat_header))
+ return;
+
+ const fat_header* header = static_cast<const fat_header*>(data);
+
+ size_t numberOfArchitectures = OSSwapBigToHostInt32(header->nfat_arch);
+
+ // Ensure that we have enough data remaining for numberOfArchitectures fat_arch structs.
+ if ((length - sizeof(fat_header)) / sizeof(fat_arch) < numberOfArchitectures)
+ return;
+
+ const fat_arch* archs = reinterpret_cast<const fat_arch*>(reinterpret_cast<const char*>(data) + sizeof(*header));
+ for (uint32_t i = 0; i < numberOfArchitectures; i++) {
+ uint32_t architectureOffset = OSSwapBigToHostInt32(archs[i].offset);
+ uint32_t architectureSize = OSSwapBigToHostInt32(archs[i].size);
+ if (length < architectureOffset + architectureSize)
+ return;
+
+ processSingleArchitecture(static_cast<const char*>(data) + architectureOffset, architectureSize);
+ }
+}
+
+void DynamicLinkerEnvironmentExtractor::getExtractedEnvironmentVariables(EnvironmentVariables& environmentVariables) const
+{
+ size_t extractedVariableCount = m_extractedVariables.size();
+ for (size_t i = 0; i < extractedVariableCount; ++i) {
+ const CString& name = m_extractedVariables[i].first;
+
+ // Preserve any existing environment variable by this name so that it will take
+ // precedence over what we extracted from the executable file.
+ if (environmentVariables.get(name.data()))
+ continue;
+
+ environmentVariables.set(name.data(), m_extractedVariables[i].second.data());
+ }
+}
+
+} // namespace WebKit
Modified: trunk/Source/WebKit2/UIProcess/Launcher/mac/ProcessLauncherMac.mm (102496 => 102497)
--- trunk/Source/WebKit2/UIProcess/Launcher/mac/ProcessLauncherMac.mm 2011-12-10 01:18:20 UTC (rev 102496)
+++ trunk/Source/WebKit2/UIProcess/Launcher/mac/ProcessLauncherMac.mm 2011-12-10 01:25:29 UTC (rev 102497)
@@ -26,6 +26,7 @@
#import "config.h"
#import "ProcessLauncher.h"
+#import "DynamicLinkerEnvironmentExtractor.h"
#import "EnvironmentVariables.h"
#import "RunLoop.h"
#import "WebProcess.h"
@@ -117,7 +118,7 @@
if (architecture == LaunchOptions::MatchCurrentArchitecture)
architecture = _NSGetMachExecuteHeader()->cputype;
- cpu_type_t cpuTypes[] = { architecture };
+ cpu_type_t cpuTypes[] = { architecture };
size_t outCount = 0;
posix_spawnattr_setbinpref_np(&attr, 1, cpuTypes, &outCount);
@@ -136,6 +137,9 @@
EnvironmentVariables environmentVariables;
+ DynamicLinkerEnvironmentExtractor environmentExtractor([[NSBundle mainBundle] executablePath], architecture);
+ environmentExtractor.getExtractedEnvironmentVariables(environmentVariables);
+
// To make engineering builds work, if the path is outside of /System set up
// DYLD_FRAMEWORK_PATH to pick up other frameworks, but don't do it for the
// production configuration because it involves extra file system access.
Modified: trunk/Source/WebKit2/WebKit2.xcodeproj/project.pbxproj (102496 => 102497)
--- trunk/Source/WebKit2/WebKit2.xcodeproj/project.pbxproj 2011-12-10 01:18:20 UTC (rev 102496)
+++ trunk/Source/WebKit2/WebKit2.xcodeproj/project.pbxproj 2011-12-10 01:25:29 UTC (rev 102497)
@@ -424,6 +424,8 @@
5272B28B1406985D0096A5D0 /* StatisticsData.h in Headers */ = {isa = PBXBuildFile; fileRef = 5272B2891406985D0096A5D0 /* StatisticsData.h */; };
5D51845513BCF9CC00C7FF4A /* APIClientTraits.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5D51845313BCF9CC00C7FF4A /* APIClientTraits.cpp */; };
5D51845613BCF9CC00C7FF4A /* APIClientTraits.h in Headers */ = {isa = PBXBuildFile; fileRef = 5D51845413BCF9CC00C7FF4A /* APIClientTraits.h */; };
+ 5DA6ED0A1490606900B41D12 /* DynamicLinkerEnvironmentExtractor.h in Headers */ = {isa = PBXBuildFile; fileRef = 5DA6ED081490606900B41D12 /* DynamicLinkerEnvironmentExtractor.h */; };
+ 5DA6ED0B1490606900B41D12 /* DynamicLinkerEnvironmentExtractor.mm in Sources */ = {isa = PBXBuildFile; fileRef = 5DA6ED091490606900B41D12 /* DynamicLinkerEnvironmentExtractor.mm */; };
6501BD1A12F1243400E9F248 /* WKBundleInspector.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 65B86F1712F11D7B00B7DD8A /* WKBundleInspector.cpp */; };
659C551E130006410025C0C2 /* InjectedBundlePageResourceLoadClient.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6546A82913000164000CEB1C /* InjectedBundlePageResourceLoadClient.cpp */; };
65B86F1E12F11DE300B7DD8A /* WKBundleInspector.h in Headers */ = {isa = PBXBuildFile; fileRef = 65B86F1812F11D7B00B7DD8A /* WKBundleInspector.h */; settings = {ATTRIBUTES = (Private, ); }; };
@@ -1428,6 +1430,8 @@
5272B2891406985D0096A5D0 /* StatisticsData.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = StatisticsData.h; sourceTree = "<group>"; };
5D51845313BCF9CC00C7FF4A /* APIClientTraits.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = APIClientTraits.cpp; sourceTree = "<group>"; };
5D51845413BCF9CC00C7FF4A /* APIClientTraits.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = APIClientTraits.h; sourceTree = "<group>"; };
+ 5DA6ED081490606900B41D12 /* DynamicLinkerEnvironmentExtractor.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DynamicLinkerEnvironmentExtractor.h; sourceTree = "<group>"; };
+ 5DA6ED091490606900B41D12 /* DynamicLinkerEnvironmentExtractor.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = DynamicLinkerEnvironmentExtractor.mm; sourceTree = "<group>"; };
5DAD7294116FF70B00EE5396 /* WebProcess.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = WebProcess.xcconfig; sourceTree = "<group>"; };
5DAD73F1116FF90C00EE5396 /* BaseTarget.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = BaseTarget.xcconfig; sourceTree = "<group>"; };
6546A82913000164000CEB1C /* InjectedBundlePageResourceLoadClient.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = InjectedBundlePageResourceLoadClient.cpp; sourceTree = "<group>"; };
@@ -3065,6 +3069,8 @@
BC111B19112F5FC500337BAB /* mac */ = {
isa = PBXGroup;
children = (
+ 5DA6ED081490606900B41D12 /* DynamicLinkerEnvironmentExtractor.h */,
+ 5DA6ED091490606900B41D12 /* DynamicLinkerEnvironmentExtractor.mm */,
1A7C6CD81378950800B9C04D /* EnvironmentVariables.cpp */,
1A7C6CD91378950800B9C04D /* EnvironmentVariables.h */,
BC111B1B112F5FE600337BAB /* ProcessLauncherMac.mm */,
@@ -4111,6 +4117,7 @@
31A2EC74148D59CA00810D71 /* WKNotificationPermissionRequest.h in Headers */,
3131261F148FF82C00BA2A39 /* NotificationPermissionRequestManager.h in Headers */,
31312621148FF82C00BA2A39 /* WebNotificationManager.h in Headers */,
+ 5DA6ED0A1490606900B41D12 /* DynamicLinkerEnvironmentExtractor.h in Headers */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -4829,6 +4836,7 @@
31A2EC77148D662E00810D71 /* WKNotificationPermissionRequest.cpp in Sources */,
3131261E148FF82C00BA2A39 /* NotificationPermissionRequestManager.cpp in Sources */,
31312620148FF82C00BA2A39 /* WebNotificationManager.cpp in Sources */,
+ 5DA6ED0B1490606900B41D12 /* DynamicLinkerEnvironmentExtractor.mm in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};