Use git apply for applying patch files (issue #1825)

This commit is contained in:
Marshall Greenblatt 2017-04-26 21:59:52 -04:00
parent a2b8c250a8
commit 4fe6ac0d4b
33 changed files with 294 additions and 883 deletions

3
.gitignore vendored
View File

@ -46,7 +46,4 @@ Thumbs.db
/binary_distrib
/docs
# CEF generated files
/include/cef_pack_resources.h
/include/cef_pack_strings.h
/include/cef_version.h
/patch/patch_state.h

View File

@ -1,20 +1,15 @@
There may be instances where CEF requires changes to the Chromium/WebKit code
base that are not desired by the Chromium/WebKit projects as a whole. To address
this situation the CEF project adds a patch capability as part of the CEF GYP
project generation step. The patch capability works as follows:
There may be instances where CEF requires changes to the source code for
Chromium, Blink or third-party projects that are either not desired by those
projects or that have not yet been merged into the source code versions of those
projects used by CEF. To address this situation the CEF project adds a patch
capability as part of cef_create_projects[.bat|sh] build step. This patch
capability works as follows:
1. The CEF developer creates one or more patch files containing all required
changes to the Chromium/WebKit code base and places those patch files in the
"patches" subdirectory.
code changes and places those patch files in the "patches" subdirectory.
2. The CEF developer adds an entry for each patch file in the "patch.cfg" file.
3. CEF applies the patches to the Chromium/WebKit source tree using the
patcher.py tool in the tools directory. If necessary the patcher.py tool
also rewrites the "patch_state.h" file which defines the CEF_PATCHES_APPLIED
preprocessor value.
To disable automatic application of patches to the Chromium/WebKit code base
create an empty "NOPATCH" file in the "patch" directory. Sections of the CEF
code base that otherwise require patches will be disabled using the
CEF_PATCHES_APPLIED preprocessor value defined in the "patch_state.h" file. Be
warned that not applying all required patches may break important CEF
functionality.
3. When building CEF from source code the patch files are applied by the
patcher.py tool via the cef_create_projects[.bat|sh] build step
4. When updating Chromium the patch_updater.py tool is used to update all patch
files. See https://bitbucket.org/chromiumembedded/cef/wiki/ChromiumUpdate.md
for more information about the update process.

View File

@ -1,15 +1,24 @@
# Each map in the list associates a patch file name with a target path and
# optional condition. All paths in the patch file must be relative to the
# target path. Each map should include a comment linking to the code review
# or bug report that the patch relates to. If a condition is provided the
# patch will only be applied if an environment variable with the specified
# name exists.
# Patch configuration file. See the README.txt file in the patch directory for
# information on how this configuration is used.
#
# Each dictionary entry in the "patches" map represents a single patch file.
# Supported key/value pairs are as follows:
#
# - 'name' Required. The name of the patch file without the .patch
# extension that will be read from the patches subdirectory.
# - 'path' Optional. The repository root for the patch file. Defaults to
# the Chromium "src" root. All patch file contents must be
# relative to this repository root.
# - 'condition' Optional. The patch file will only be applied if an environment
# variable with this name exists.
#
# Each entry should also include a comment linking to the code review or bug
# report that the patch relates to.
patches = [
{
# Necessary for grit integration.
'name': 'gritsettings',
'path': '../tools/gritsettings/',
},
{
# Necessary for GN integration.
@ -23,13 +32,11 @@ patches = [
# Write environment.* files with the correct SDK version on Windows.
# https://bugs.chromium.org/p/chromium/issues/detail?id=634788
'name': 'gn_config',
'path': '../',
},
{
# Support loading of password protected zip archives.
# https://bitbucket.org/chromiumembedded/cef/issues/496
'name': 'zlib',
'path': '../third_party/zlib/',
},
{
# Avoid MessageLoop assertion on OS X.
@ -38,18 +45,15 @@ patches = [
# Revert change on Windows that removes MessageLoop::os_modal_loop().
# https://codereview.chromium.org/1992243003
'name': 'message_loop_443_1992243003',
'path': '../base/message_loop/',
},
{
# Enable popups in offscreen rendering on OS X.
'name': 'webkit_popups',
'path': '../third_party/WebKit/',
},
{
# Fix export of UnderlayOpenGLHostingWindow for 64-bit OS X builds.
# https://bitbucket.org/chromiumembedded/cef/issues/1051
'name': 'underlay_1051',
'path': '../ui/base/cocoa/',
},
{
# Allow specification of a parent window handle for Widget creation.
@ -72,7 +76,6 @@ patches = [
# Remove console spam from RenderWidgetHostViewBase::IsInVR.
# https://codereview.chromium.org/2822223002
'name': 'views_widget_180_1481_1565_1677_1749',
'path': '../',
},
{
# Allow specification of a custom WebContentsView.
@ -81,58 +84,49 @@ patches = [
# Support custom RenderWidgetHostViewOSR for BrowserPluginGuest.
# https://bitbucket.org/chromiumembedded/cef/issues/1565
'name': 'web_contents_1257_1565',
'path': '../',
},
{
# Allow creation of a custom SoftwareOutputDevice.
# https://bitbucket.org/chromiumembedded/cef/issues/1368
'name': 'compositor_1368',
'path': '../',
},
{
# Support custom RenderWidgetHostViewOSR for BrowserPluginGuest.
# https://bitbucket.org/chromiumembedded/cef/issues/1565
'name': 'browser_plugin_guest_1565',
'path': '../',
},
{
# Allow customization of the WebView background color.
# https://bitbucket.org/chromiumembedded/cef/issues/1161
# https://codereview.chromium.org/228603007/
'name': 'prefs_content_1161',
'path': '../content/',
},
{
# Fix drag&drop of combined text and URL data on Linux/Aura.
# https://codereview.chromium.org/208313009
'name': 'ui_dragdrop_355390',
'path': '../ui/base/dragdrop/',
},
{
# Windows: Fix AtExitManager assertion on *ServiceFactory destruction during
# multi-threaded message loop shutdown.
# https://bitbucket.org/chromiumembedded/cef/issues/1680
'name': 'service_factory_1680',
'path': '../',
},
{
# Make URLRequest::set_is_pending() public so that it can be called from
# CefRequestInterceptor::MaybeInterceptResponse().
# https://bitbucket.org/chromiumembedded/cef/issues/1327
'name': 'net_urlrequest_1327',
'path': '../net/url_request/',
},
{
# Remove NOTREACHED() that is hit when loading Flash in incognito mode.
# https://bitbucket.org/chromiumembedded/cef/issue/1586
'name': 'content_pepper_flash_1586',
'path': '../content/browser/renderer_host/pepper/',
},
{
# Fix placement of IME window on Windows.
# https://bitbucket.org/chromiumembedded/cef/issue/1610
'name': 'ime_1610',
'path': '../ui/base/ime/',
},
{
# Enable support for print header and footer.
@ -146,7 +140,6 @@ patches = [
#
# Add missing ENABLE_PRINT_PREVIEW checks in chrome/ on Mac.
'name': 'print_header_footer_1478_1565',
'path': '../',
},
{
# Split service_manager::Main into the separate steps required by CEF.
@ -155,52 +148,45 @@ patches = [
# Remove DCHECK on Linux when initialized CEF from a non-main thread.
# https://bitbucket.org/chromiumembedded/cef/issue/1639
'name': 'service_manager_654986',
'path': '../',
},
{
# Fix rendering of the PDF extension with OSR when the device scale factor
# is not 1.
# https://bitbucket.org/chromiumembedded/cef/issues/1687
'name': 'browser_frame_host_guest_1687',
'path': '../content/browser/frame_host/',
},
{
# Fix loading of the PDF extension with proxy BrowserContext.
# https://bitbucket.org/chromiumembedded/cef/issues/1710
'name': 'supports_user_data_1710',
'path': '../base/',
},
{
# Fix background color on Mac.
# https://codereview.chromium.org/1070383005 (reverted)
'name': 'render_widget_host_1070383005',
'path': '../content/browser/renderer_host/',
},
{
# Fix missing check for defined(ENABLE_THEMES) in
# renderer_preferences_util.cc on Linux.
# https://bugs.chromium.org/p/chromium/issues/detail?id=545103
'name': 'renderer_preferences_util_545103',
'path': '../chrome/browser/',
},
{
# Expose the FontFamilyCache UserData key.
# https://bitbucket.org/chromiumembedded/cef/issues/1501
'name': 'font_family_cache_1501',
'path': '../chrome/browser/',
},
{
# Fix crash while printing on Windows by properly initializing V8 in the PDF
# module.
# https://bugs.chromium.org/p/chromium/issues/detail?id=549365#c17
'name': 'pdfium_print_549365',
'path': '../third_party/pdfium/',
'path': 'third_party/pdfium/',
},
{
# Enable support for filtering resource responses.
# https://bitbucket.org/chromiumembedded/cef/issues/515
'name': 'net_filter_515',
'path': '../',
},
{
# Modify views::View to extend SupportsUserData.
@ -219,29 +205,24 @@ patches = [
# Reverts label_button.h changes from
# https://codereview.chromium.org/2793283002
'name': 'views_1749',
'path': '../',
},
{
# Expose RenderViewHostImpl swapped-out state.
# https://bitbucket.org/chromiumembedded/cef/issues/1392
'name': 'render_view_host_impl_1392',
'path': '../content/browser/renderer_host/',
},
{
# Expose ui::Compositor via BrowserCompositorMac for OSR.
'name': 'browser_compositor_mac',
'path': '../',
},
{
# Fix chrome Widevine build on Linux.
'name': 'chrome_widevine',
'path': '../',
},
{
# Make some methods of ProfileManager virtual.
# Allow CEF to intercept GetBrowserContext*InIncognito functions.
'name': 'chrome_profile',
'path': '../',
},
{
# Support StoragePartition proxy by:
@ -258,13 +239,11 @@ patches = [
# initializing the channel from RPHI::ProcessDied.
# https://bitbucket.org/chromiumembedded/cef/issues/2096
'name': 'storage_partition_1973',
'path': '../',
},
{
# Fix plugin placeholder blocked message.
# https://bitbucket.org/chromiumembedded/cef/issues/2020/
'name': 'webview_plugin_2020',
'path': '../',
},
{
# Support WebUI by:
@ -272,25 +251,21 @@ patches = [
# (b) Removing dependency on non-NULL IOThread* object.
# https://bitbucket.org/chromiumembedded/cef/issues/2037
'name': 'webui_2037',
'path': '../',
},
{
# Support an option to enable/disable net security expiration.
# https://bitbucket.org/chromiumembedded/cef/issues/1994
'name': 'net_security_expiration_1994',
'path': '../',
},
{
# Remove DCHECK hit during latency reporting when using OSR.
# https://bitbucket.org/chromiumembedded/cef/issues/2060
'name': 'render_widget_latency_2060',
'path': '../',
},
{
# Implement breakpad/crashpad customization required by CEF.
# https://bitbucket.org/chromiumembedded/cef/issues/1995
'name': 'crashpad_1995',
'path': '../',
},
{
# Support customization of crash report pruning limits.
@ -299,13 +274,11 @@ patches = [
# Implement better rate-limiting/retry logic.
# https://bugs.chromium.org/p/crashpad/issues/detail?id=23
'name': 'crashpad_tp_1995',
'path': '../third_party/crashpad/',
},
{
# Fix white flash during browser creation.
# https://bitbucket.org/chromiumembedded/cef/issues/1984
'name': 'rwh_background_color_1984',
'path': '../',
},
{
# Allow continued use of ContentRendererClient::HandleNavigation.
@ -321,31 +294,26 @@ patches = [
# network error.
# https://groups.google.com/a/chromium.org/d/msg/chromium-dev/6iAQPx_hwh8/gaTR5f1GAQAJ
'name': 'content_1129_2015',
'path': '../',
},
{
# Pass is_main_frame to PluginServiceFilter::IsPluginAvailable.
# https://bitbucket.org/chromiumembedded/cef/issues/2015
'name': 'webkit_plugin_info_2015',
'path': '../third_party/WebKit/',
},
{
# Expose callbacks for mouse/keyboard events that trigger menu switching.
# Add accelerator display support to Label.
# https://bitbucket.org/chromiumembedded/cef/issues/2102
'name': 'views_menu_2102',
'path': '../',
},
{
# Mac: Fix build error when including openssl/opensslconf.h.
# https://bugs.chromium.org/p/chromium/issues/detail?id=711670
'name': 'mac_build_711670',
'path': '../',
},
{
# Linux: Remove DCHECK during GPU feature info detection.
# https://bugs.chromium.org/p/chromium/issues/detail?id=699278
'name': 'gpu_feature_info_699278',
'path': '../',
},
]

View File

@ -1,7 +1,7 @@
diff --git render_widget_host_view_guest.cc render_widget_host_view_guest.cc
diff --git content/browser/frame_host/render_widget_host_view_guest.cc content/browser/frame_host/render_widget_host_view_guest.cc
index fc720a7..1c30365 100644
--- render_widget_host_view_guest.cc
+++ render_widget_host_view_guest.cc
--- content/browser/frame_host/render_widget_host_view_guest.cc
+++ content/browser/frame_host/render_widget_host_view_guest.cc
@@ -247,13 +247,14 @@ void RenderWidgetHostViewGuest::Destroy() {
}

View File

@ -303,7 +303,7 @@ index d237318..3701bd2 100644
content::WebContents* OpenURLFromTab(
content::WebContents* source,
diff --git extensions/browser/guest_view/mime_handler_view/mime_handler_view_guest_delegate.h extensions/browser/guest_view/mime_handler_view/mime_handler_view_guest_delegate.h
index e065104d..ea3f547 100644
index e065104d..e67ae566e 100644
--- extensions/browser/guest_view/mime_handler_view/mime_handler_view_guest_delegate.h
+++ extensions/browser/guest_view/mime_handler_view/mime_handler_view_guest_delegate.h
@@ -6,9 +6,9 @@
@ -317,11 +317,10 @@ index e065104d..ea3f547 100644
struct ContextMenuParams;
} // namespace content
@@ -21,6 +21,14 @@ class MimeHandlerViewGuestDelegate {
public:
@@ -22,6 +22,14 @@ class MimeHandlerViewGuestDelegate {
MimeHandlerViewGuestDelegate() {}
virtual ~MimeHandlerViewGuestDelegate() {}
+
+ // Provides an opportunity to supply a custom view implementation.
+ virtual void OverrideWebContentsCreateParams(
+ content::WebContents::CreateParams* params) {}
@ -329,6 +328,7 @@ index e065104d..ea3f547 100644
+ // Called when a guest is attached or detached.
+ virtual void OnGuestAttached(content::WebContentsView* parent_view) {}
+ virtual void OnGuestDetached(content::WebContentsView* parent_view) {}
+
// Handles context menu, or returns false if unhandled.
virtual bool HandleContextMenu(content::WebContents* web_contents,
const content::ContextMenuParams& params);

View File

@ -1,7 +1,7 @@
diff --git pepper_flash_file_message_filter.cc pepper_flash_file_message_filter.cc
diff --git content/browser/renderer_host/pepper/pepper_flash_file_message_filter.cc content/browser/renderer_host/pepper/pepper_flash_file_message_filter.cc
index 6f03077..c61fed3 100644
--- pepper_flash_file_message_filter.cc
+++ pepper_flash_file_message_filter.cc
--- content/browser/renderer_host/pepper/pepper_flash_file_message_filter.cc
+++ content/browser/renderer_host/pepper/pepper_flash_file_message_filter.cc
@@ -55,7 +55,7 @@ PepperFlashFileMessageFilter::PepperFlashFileMessageFilter(
// will construct a bad path and could provide access to the wrong files.
// In this case, |plugin_data_directory_| will remain unset and

View File

@ -483,7 +483,7 @@ index 3bae07e..12b0a16 100644
+ const char* product_version = "";
+ crash_reporter_client->GetProductNameAndVersion(&product_name,
+ &product_version);
+
+
NSBundle* outer_bundle = base::mac::OuterBundle();
- NSString* product = base::mac::ObjCCast<NSString>([outer_bundle
- objectForInfoDictionaryKey:base::mac::CFToNSCast(kCFBundleNameKey)]);
@ -528,7 +528,7 @@ index 3bae07e..12b0a16 100644
arguments.push_back(
"--reset-own-crash-exception-port-to-system-default");
}
+
+
+ // Since we're using the same subprocess helper exe we must specify the
+ // process type.
+ arguments.push_back(std::string("--type=") + switches::kCrashpadHandler);
@ -581,7 +581,7 @@ index 94a350f..61667a8 100644
- // reinvoke it with --type=crashpad-handler. Otherwise, we use the
- // standalone crashpad_handler.exe (for tests, etc.).
std::vector<std::string> start_arguments;
+
+
+ // Always add --type=crashpad-handler because the value is expected by
+ // CefExecuteProcess.
+ start_arguments.push_back(

View File

@ -1,7 +1,7 @@
diff --git crashpad/client/prune_crash_reports.cc crashpad/client/prune_crash_reports.cc
diff --git third_party/crashpad/crashpad/client/prune_crash_reports.cc third_party/crashpad/crashpad/client/prune_crash_reports.cc
index 3aaaeee..d99fcb4 100644
--- crashpad/client/prune_crash_reports.cc
+++ crashpad/client/prune_crash_reports.cc
--- third_party/crashpad/crashpad/client/prune_crash_reports.cc
+++ third_party/crashpad/crashpad/client/prune_crash_reports.cc
@@ -67,13 +67,19 @@ void PruneCrashReportDatabase(CrashReportDatabase* database,
}
@ -25,10 +25,10 @@ index 3aaaeee..d99fcb4 100644
}
static const time_t kSecondsInDay = 60 * 60 * 24;
diff --git crashpad/client/prune_crash_reports.h crashpad/client/prune_crash_reports.h
diff --git third_party/crashpad/crashpad/client/prune_crash_reports.h third_party/crashpad/crashpad/client/prune_crash_reports.h
index 6dac5f3..34f5ee1 100644
--- crashpad/client/prune_crash_reports.h
+++ crashpad/client/prune_crash_reports.h
--- third_party/crashpad/crashpad/client/prune_crash_reports.h
+++ third_party/crashpad/crashpad/client/prune_crash_reports.h
@@ -57,7 +57,8 @@ class PruneCondition {
//! of 128 MB.
//!
@ -39,10 +39,10 @@ index 6dac5f3..34f5ee1 100644
virtual ~PruneCondition() {}
diff --git crashpad/client/settings.cc crashpad/client/settings.cc
diff --git third_party/crashpad/crashpad/client/settings.cc third_party/crashpad/crashpad/client/settings.cc
index 15d16f2..5e8eadf 100644
--- crashpad/client/settings.cc
+++ crashpad/client/settings.cc
--- third_party/crashpad/crashpad/client/settings.cc
+++ third_party/crashpad/crashpad/client/settings.cc
@@ -38,7 +38,7 @@ void ScopedLockedFileHandleTraits::Free(FileHandle handle) {
struct Settings::Data {
@ -129,10 +129,10 @@ index 15d16f2..5e8eadf 100644
// static
Settings::ScopedLockedFileHandle Settings::MakeScopedLockedFileHandle(
FileHandle file,
diff --git crashpad/client/settings.h crashpad/client/settings.h
diff --git third_party/crashpad/crashpad/client/settings.h third_party/crashpad/crashpad/client/settings.h
index b64f74f..0c3c22e 100644
--- crashpad/client/settings.h
+++ crashpad/client/settings.h
--- third_party/crashpad/crashpad/client/settings.h
+++ third_party/crashpad/crashpad/client/settings.h
@@ -102,6 +102,11 @@ class Settings {
//! error logged.
bool SetLastUploadAttemptTime(time_t time);
@ -145,10 +145,10 @@ index b64f74f..0c3c22e 100644
private:
struct Data;
diff --git crashpad/handler/crash_report_upload_thread.h crashpad/handler/crash_report_upload_thread.h
diff --git third_party/crashpad/crashpad/handler/crash_report_upload_thread.h third_party/crashpad/crashpad/handler/crash_report_upload_thread.h
index 14debac..c25c653 100644
--- crashpad/handler/crash_report_upload_thread.h
+++ crashpad/handler/crash_report_upload_thread.h
--- third_party/crashpad/crashpad/handler/crash_report_upload_thread.h
+++ third_party/crashpad/crashpad/handler/crash_report_upload_thread.h
@@ -78,7 +78,7 @@ class CrashReportUploadThread : public WorkerThread::Delegate {
//! This method may be called from any thread.
void ReportPending();
@ -176,10 +176,10 @@ index 14debac..c25c653 100644
//! \brief Attempts to upload a crash report.
//!
diff --git crashpad/handler/handler_main.cc crashpad/handler/handler_main.cc
diff --git third_party/crashpad/crashpad/handler/handler_main.cc third_party/crashpad/crashpad/handler/handler_main.cc
index 641bf0f..3a86eb3 100644
--- crashpad/handler/handler_main.cc
+++ crashpad/handler/handler_main.cc
--- third_party/crashpad/crashpad/handler/handler_main.cc
+++ third_party/crashpad/crashpad/handler/handler_main.cc
@@ -35,8 +35,10 @@
#include "base/metrics/persistent_histogram_allocator.h"
#include "base/scoped_generic.h"

View File

@ -1,7 +1,7 @@
diff --git font_family_cache.h font_family_cache.h
diff --git chrome/browser/font_family_cache.h chrome/browser/font_family_cache.h
index 743448d..0a9f350 100644
--- font_family_cache.h
+++ font_family_cache.h
--- chrome/browser/font_family_cache.h
+++ chrome/browser/font_family_cache.h
@@ -20,6 +20,8 @@ class Profile;
FORWARD_DECLARE_TEST(FontFamilyCacheTest, Caching);

View File

@ -1,17 +1,16 @@
diff --git resource_ids resource_ids
index 4e3fd2d..447c1f5 100644
--- resource_ids
+++ resource_ids
@@ -361,5 +361,12 @@
# Thinking about appending to the end?
diff --git tools/gritsettings/resource_ids tools/gritsettings/resource_ids
index 4e3fd2d..2cf62da 100644
--- tools/gritsettings/resource_ids
+++ tools/gritsettings/resource_ids
@@ -362,4 +362,11 @@
# Please read the header and find the right section above instead.
# Resource ids starting at 31000 are reserved for projects built on Chromium.
+
+ "cef/libcef/resources/cef_resources.grd": {
+ "includes": [31500],
+ },
+ "cef/libcef/resources/cef_strings.grd": {
+ "messages": [32000],
+ },
+
# Resource ids starting at 31000 are reserved for projects built on Chromium.
}

View File

@ -1,7 +1,7 @@
diff --git input_method_win.cc input_method_win.cc
diff --git ui/base/ime/input_method_win.cc ui/base/ime/input_method_win.cc
index e2bb528..3e851e5 100644
--- input_method_win.cc
+++ input_method_win.cc
--- ui/base/ime/input_method_win.cc
+++ ui/base/ime/input_method_win.cc
@@ -682,8 +682,9 @@ bool InputMethodWin::IsWindowFocused(const TextInputClient* client) const {
// receiving keyboard input as long as it is an active window. This works well
// even when the |attached_window_handle| becomes active but has not received

View File

@ -1,7 +1,7 @@
diff --git message_loop.cc message_loop.cc
diff --git base/message_loop/message_loop.cc base/message_loop/message_loop.cc
index 3d55920..721aca1 100644
--- message_loop.cc
+++ message_loop.cc
--- base/message_loop/message_loop.cc
+++ base/message_loop/message_loop.cc
@@ -96,12 +96,6 @@ MessageLoop::~MessageLoop() {
// may be current.
DCHECK((pump_ && current() == this) || (!pump_ && current() != this));
@ -25,10 +25,10 @@ index 3d55920..721aca1 100644
pump_factory_(pump_factory),
run_loop_(nullptr),
current_pending_task_(nullptr),
diff --git message_loop.h message_loop.h
diff --git base/message_loop/message_loop.h base/message_loop/message_loop.h
index 2ef4537..9c657f8 100644
--- message_loop.h
+++ message_loop.h
--- base/message_loop/message_loop.h
+++ base/message_loop/message_loop.h
@@ -303,6 +303,16 @@ class BASE_EXPORT MessageLoop : public MessagePump::Delegate {
void AddTaskObserver(TaskObserver* task_observer);
void RemoveTaskObserver(TaskObserver* task_observer);
@ -59,10 +59,10 @@ index 2ef4537..9c657f8 100644
// pump_factory_.Run() is called to create a message pump for this loop
// if type_ is TYPE_CUSTOM and pump_ is null.
MessagePumpFactoryCallback pump_factory_;
diff --git message_pump_win.cc message_pump_win.cc
diff --git base/message_loop/message_pump_win.cc base/message_loop/message_pump_win.cc
index d52c785..a43b5b3 100644
--- message_pump_win.cc
+++ message_pump_win.cc
--- base/message_loop/message_pump_win.cc
+++ base/message_loop/message_pump_win.cc
@@ -366,20 +366,28 @@ bool MessagePumpForUI::ProcessMessageHelper(const MSG& msg) {
}

View File

@ -1,7 +1,7 @@
diff --git url_request.h url_request.h
diff --git net/url_request/url_request.h net/url_request/url_request.h
index e1406f3..ed9aa91 100644
--- url_request.h
+++ url_request.h
--- net/url_request/url_request.h
+++ net/url_request/url_request.h
@@ -651,10 +651,11 @@ class NET_EXPORT URLRequest : NON_EXPORTED_BASE(public base::NonThreadSafe),
// Returns the error status of the request.
// Do not use! Going to be protected!

View File

@ -1,7 +1,7 @@
diff --git public/common/common_param_traits_macros.h public/common/common_param_traits_macros.h
diff --git content/public/common/common_param_traits_macros.h content/public/common/common_param_traits_macros.h
index 3dd2e75..9f61aad 100644
--- public/common/common_param_traits_macros.h
+++ public/common/common_param_traits_macros.h
--- content/public/common/common_param_traits_macros.h
+++ content/public/common/common_param_traits_macros.h
@@ -201,6 +201,7 @@ IPC_STRUCT_TRAITS_BEGIN(content::WebPreferences)
IPC_STRUCT_TRAITS_MEMBER(main_frame_resizes_are_orientation_changes)
IPC_STRUCT_TRAITS_MEMBER(initialize_at_minimum_page_scale)
@ -10,10 +10,10 @@ index 3dd2e75..9f61aad 100644
IPC_STRUCT_TRAITS_MEMBER(cookie_enabled)
IPC_STRUCT_TRAITS_MEMBER(navigate_on_drag_drop)
IPC_STRUCT_TRAITS_MEMBER(spatial_navigation_enabled)
diff --git public/common/web_preferences.cc public/common/web_preferences.cc
diff --git content/public/common/web_preferences.cc content/public/common/web_preferences.cc
index 72f7bd8..850e591 100644
--- public/common/web_preferences.cc
+++ public/common/web_preferences.cc
--- content/public/common/web_preferences.cc
+++ content/public/common/web_preferences.cc
@@ -172,6 +172,7 @@ WebPreferences::WebPreferences()
spatial_navigation_enabled(false),
use_solid_color_scrollbars(false),
@ -22,10 +22,10 @@ index 72f7bd8..850e591 100644
v8_cache_options(V8_CACHE_OPTIONS_DEFAULT),
inert_visual_viewport(false),
record_whole_document(false),
diff --git public/common/web_preferences.h public/common/web_preferences.h
diff --git content/public/common/web_preferences.h content/public/common/web_preferences.h
index ae9756c..d0f2f1b 100644
--- public/common/web_preferences.h
+++ public/common/web_preferences.h
--- content/public/common/web_preferences.h
+++ content/public/common/web_preferences.h
@@ -184,6 +184,7 @@ struct CONTENT_EXPORT WebPreferences {
bool spatial_navigation_enabled;
bool use_solid_color_scrollbars;
@ -34,10 +34,10 @@ index ae9756c..d0f2f1b 100644
V8CacheOptions v8_cache_options;
bool inert_visual_viewport;
bool record_whole_document;
diff --git renderer/render_view_impl.cc renderer/render_view_impl.cc
diff --git content/renderer/render_view_impl.cc content/renderer/render_view_impl.cc
index 7d6113c..d600026 100644
--- renderer/render_view_impl.cc
+++ renderer/render_view_impl.cc
--- content/renderer/render_view_impl.cc
+++ content/renderer/render_view_impl.cc
@@ -1383,6 +1383,8 @@ void RenderViewImpl::ApplyWebPreferencesInternal(
blink::WebView* web_view,
CompositorDependencies* compositor_deps) {

View File

@ -1,7 +1,7 @@
diff --git render_view_host_impl.h render_view_host_impl.h
diff --git content/browser/renderer_host/render_view_host_impl.h content/browser/renderer_host/render_view_host_impl.h
index bcc702b..3753c50 100644
--- render_view_host_impl.h
+++ render_view_host_impl.h
--- content/browser/renderer_host/render_view_host_impl.h
+++ content/browser/renderer_host/render_view_host_impl.h
@@ -154,6 +154,7 @@ class CONTENT_EXPORT RenderViewHostImpl : public RenderViewHost,
void set_is_swapped_out(bool is_swapped_out) {
is_swapped_out_ = is_swapped_out;

View File

@ -1,7 +1,7 @@
diff --git render_widget_host_view_mac.mm render_widget_host_view_mac.mm
diff --git content/browser/renderer_host/render_widget_host_view_mac.mm content/browser/renderer_host/render_widget_host_view_mac.mm
index 896170a..4beadf9 100644
--- render_widget_host_view_mac.mm
+++ render_widget_host_view_mac.mm
--- content/browser/renderer_host/render_widget_host_view_mac.mm
+++ content/browser/renderer_host/render_widget_host_view_mac.mm
@@ -453,9 +453,6 @@ RenderWidgetHostViewMac::RenderWidgetHostViewMac(RenderWidgetHost* widget,
// Paint this view host with |background_color_| when there is no content
// ready to draw.

View File

@ -1,7 +1,7 @@
diff --git renderer_preferences_util.cc renderer_preferences_util.cc
diff --git chrome/browser/renderer_preferences_util.cc chrome/browser/renderer_preferences_util.cc
index 7296a04..c702d31 100644
--- renderer_preferences_util.cc
+++ renderer_preferences_util.cc
--- chrome/browser/renderer_preferences_util.cc
+++ chrome/browser/renderer_preferences_util.cc
@@ -32,7 +32,8 @@
#include "ui/base/cocoa/defaults_utils.h"
#endif

View File

@ -1,7 +1,7 @@
diff --git supports_user_data.h supports_user_data.h
diff --git base/supports_user_data.h base/supports_user_data.h
index 233ce38..02e690b 100644
--- supports_user_data.h
+++ supports_user_data.h
--- base/supports_user_data.h
+++ base/supports_user_data.h
@@ -39,10 +39,10 @@ class BASE_EXPORT SupportsUserData {
// delete the object if it is changed or the object is destroyed.
// TODO: remove the raw ptr version of SetUserData once everything uses

View File

@ -1,7 +1,7 @@
diff --git os_exchange_data_provider_aurax11.cc os_exchange_data_provider_aurax11.cc
diff --git ui/base/dragdrop/os_exchange_data_provider_aurax11.cc ui/base/dragdrop/os_exchange_data_provider_aurax11.cc
index 9b93593..fe0f44a 100644
--- os_exchange_data_provider_aurax11.cc
+++ os_exchange_data_provider_aurax11.cc
--- ui/base/dragdrop/os_exchange_data_provider_aurax11.cc
+++ ui/base/dragdrop/os_exchange_data_provider_aurax11.cc
@@ -162,7 +162,8 @@ void OSExchangeDataProviderAuraX11::SetURL(const GURL& url,
mem);

View File

@ -1,7 +1,7 @@
diff --git underlay_opengl_hosting_window.h underlay_opengl_hosting_window.h
diff --git ui/base/cocoa/underlay_opengl_hosting_window.h ui/base/cocoa/underlay_opengl_hosting_window.h
index d673c31..806d134 100644
--- underlay_opengl_hosting_window.h
+++ underlay_opengl_hosting_window.h
--- ui/base/cocoa/underlay_opengl_hosting_window.h
+++ ui/base/cocoa/underlay_opengl_hosting_window.h
@@ -12,7 +12,7 @@
// Common base class for windows that host a OpenGL surface that renders under
// the window. Previously contained methods related to hole punching, now just

View File

@ -258,7 +258,7 @@ index db99e54..7c67a04 100644
// Whether this item should be displayed with the normal text color, even if
// it's disabled.
virtual bool GetShouldUseNormalForegroundColor(int command_id) const;
+
+
+ // Override the text color of a given menu item dependent on the |command_id|
+ // and its |is_hovered| state. |is_minor| will be true for accelerator text.
+ // Returns true if it chooses to override the color.

View File

@ -1,7 +1,7 @@
diff --git Source/core/dom/DOMImplementation.cpp Source/core/dom/DOMImplementation.cpp
diff --git third_party/WebKit/Source/core/dom/DOMImplementation.cpp third_party/WebKit/Source/core/dom/DOMImplementation.cpp
index 8aab9bb..e3286f6 100644
--- Source/core/dom/DOMImplementation.cpp
+++ Source/core/dom/DOMImplementation.cpp
--- third_party/WebKit/Source/core/dom/DOMImplementation.cpp
+++ third_party/WebKit/Source/core/dom/DOMImplementation.cpp
@@ -241,10 +241,11 @@ Document* DOMImplementation::createDocument(const String& type,
// For that reason, the origin must be retrieved directly from init.url().
if (init.GetFrame()->IsMainFrame()) {
@ -16,10 +16,10 @@ index 8aab9bb..e3286f6 100644
->Tree()
.Top()
->GetSecurityContext()
diff --git Source/core/frame/LocalFrame.cpp Source/core/frame/LocalFrame.cpp
diff --git third_party/WebKit/Source/core/frame/LocalFrame.cpp third_party/WebKit/Source/core/frame/LocalFrame.cpp
index b64d75d..869b45d 100644
--- Source/core/frame/LocalFrame.cpp
+++ Source/core/frame/LocalFrame.cpp
--- third_party/WebKit/Source/core/frame/LocalFrame.cpp
+++ third_party/WebKit/Source/core/frame/LocalFrame.cpp
@@ -927,7 +927,7 @@ ContentSettingsClient* LocalFrame::GetContentSettingsClient() {
PluginData* LocalFrame::GetPluginData() const {
if (!Loader().AllowPlugins(kNotAboutToInstantiatePlugin))
@ -29,10 +29,10 @@ index b64d75d..869b45d 100644
Tree().Top()->GetSecurityContext()->GetSecurityOrigin());
}
diff --git Source/core/page/Page.cpp Source/core/page/Page.cpp
diff --git third_party/WebKit/Source/core/page/Page.cpp third_party/WebKit/Source/core/page/Page.cpp
index 941a30c..2c5764c 100644
--- Source/core/page/Page.cpp
+++ Source/core/page/Page.cpp
--- third_party/WebKit/Source/core/page/Page.cpp
+++ third_party/WebKit/Source/core/page/Page.cpp
@@ -289,16 +289,30 @@ void Page::RefreshPlugins() {
for (const Page* page : AllPages()) {
@ -71,10 +71,10 @@ index 941a30c..2c5764c 100644
}
void Page::SetValidationMessageClient(ValidationMessageClient* client) {
diff --git Source/core/page/Page.h Source/core/page/Page.h
diff --git third_party/WebKit/Source/core/page/Page.h third_party/WebKit/Source/core/page/Page.h
index e644faa..2fe0d37 100644
--- Source/core/page/Page.h
+++ Source/core/page/Page.h
--- third_party/WebKit/Source/core/page/Page.h
+++ third_party/WebKit/Source/core/page/Page.h
@@ -132,7 +132,8 @@ class CORE_EXPORT Page final : public GarbageCollectedFinalized<Page>,
ViewportDescription GetViewportDescription() const;
@ -95,10 +95,10 @@ index e644faa..2fe0d37 100644
EditorClient* const editor_client_;
SpellCheckerClient* const spell_checker_client_;
diff --git Source/platform/plugins/PluginData.cpp Source/platform/plugins/PluginData.cpp
diff --git third_party/WebKit/Source/platform/plugins/PluginData.cpp third_party/WebKit/Source/platform/plugins/PluginData.cpp
index 03618f6..5ac59e8 100644
--- Source/platform/plugins/PluginData.cpp
+++ Source/platform/plugins/PluginData.cpp
--- third_party/WebKit/Source/platform/plugins/PluginData.cpp
+++ third_party/WebKit/Source/platform/plugins/PluginData.cpp
@@ -30,11 +30,12 @@
namespace blink {
@ -125,10 +125,10 @@ index 03618f6..5ac59e8 100644
&builder);
}
diff --git Source/platform/plugins/PluginData.h Source/platform/plugins/PluginData.h
diff --git third_party/WebKit/Source/platform/plugins/PluginData.h third_party/WebKit/Source/platform/plugins/PluginData.h
index cdf3381..671f17c 100644
--- Source/platform/plugins/PluginData.h
+++ Source/platform/plugins/PluginData.h
--- third_party/WebKit/Source/platform/plugins/PluginData.h
+++ third_party/WebKit/Source/platform/plugins/PluginData.h
@@ -52,8 +52,9 @@ class PLATFORM_EXPORT PluginData : public RefCounted<PluginData> {
WTF_MAKE_NONCOPYABLE(PluginData);
@ -156,10 +156,10 @@ index cdf3381..671f17c 100644
RefPtr<SecurityOrigin> main_frame_origin_;
};
diff --git public/platform/Platform.h public/platform/Platform.h
diff --git third_party/WebKit/public/platform/Platform.h third_party/WebKit/public/platform/Platform.h
index eab1ca5..6657878 100644
--- public/platform/Platform.h
+++ public/platform/Platform.h
--- third_party/WebKit/public/platform/Platform.h
+++ third_party/WebKit/public/platform/Platform.h
@@ -365,6 +365,7 @@ class BLINK_PLATFORM_EXPORT Platform {
// satisfy this call. mainFrameOrigin is used by the browser process to
// filter plugins from the plugin list based on content settings.

View File

@ -1,7 +1,7 @@
diff --git Source/web/ChromeClientImpl.cpp Source/web/ChromeClientImpl.cpp
diff --git third_party/WebKit/Source/web/ChromeClientImpl.cpp third_party/WebKit/Source/web/ChromeClientImpl.cpp
index ba81ee3..648d7ce 100644
--- Source/web/ChromeClientImpl.cpp
+++ Source/web/ChromeClientImpl.cpp
--- third_party/WebKit/Source/web/ChromeClientImpl.cpp
+++ third_party/WebKit/Source/web/ChromeClientImpl.cpp
@@ -908,7 +908,7 @@ bool ChromeClientImpl::HasOpenedPopup() const {
PopupMenu* ChromeClientImpl::OpenPopupMenu(LocalFrame& frame,
HTMLSelectElement& select) {
@ -11,10 +11,10 @@ index ba81ee3..648d7ce 100644
return new ExternalPopupMenu(frame, select, *web_view_);
DCHECK(RuntimeEnabledFeatures::pagePopupEnabled());
diff --git Source/web/WebViewImpl.cpp Source/web/WebViewImpl.cpp
diff --git third_party/WebKit/Source/web/WebViewImpl.cpp third_party/WebKit/Source/web/WebViewImpl.cpp
index 16ac66b..7053b54 100644
--- Source/web/WebViewImpl.cpp
+++ Source/web/WebViewImpl.cpp
--- third_party/WebKit/Source/web/WebViewImpl.cpp
+++ third_party/WebKit/Source/web/WebViewImpl.cpp
@@ -355,6 +355,7 @@ WebViewImpl::WebViewImpl(WebViewClient* client,
enable_fake_page_scale_animation_for_testing_(false),
fake_page_scale_animation_page_scale_factor_(0),
@ -38,10 +38,10 @@ index 16ac66b..7053b54 100644
}
void WebViewImpl::SetBackgroundColorOverride(WebColor color) {
diff --git Source/web/WebViewImpl.h Source/web/WebViewImpl.h
diff --git third_party/WebKit/Source/web/WebViewImpl.h third_party/WebKit/Source/web/WebViewImpl.h
index a22ef37..33dbab4 100644
--- Source/web/WebViewImpl.h
+++ Source/web/WebViewImpl.h
--- third_party/WebKit/Source/web/WebViewImpl.h
+++ third_party/WebKit/Source/web/WebViewImpl.h
@@ -362,7 +362,8 @@ class WEB_EXPORT WebViewImpl final
// Returns true if popup menus should be rendered by the browser, false if
@ -61,10 +61,10 @@ index a22ef37..33dbab4 100644
float compositor_device_scale_factor_override_;
TransformationMatrix device_emulation_transform_;
diff --git public/web/WebView.h public/web/WebView.h
diff --git third_party/WebKit/public/web/WebView.h third_party/WebKit/public/web/WebView.h
index e811392..d6d5bf8 100644
--- public/web/WebView.h
+++ public/web/WebView.h
--- third_party/WebKit/public/web/WebView.h
+++ third_party/WebKit/public/web/WebView.h
@@ -403,6 +403,7 @@ class WebView : protected WebWidget {
// Sets whether select popup menus should be rendered by the browser.

View File

@ -1,7 +1,7 @@
diff --git contrib/minizip/unzip.c contrib/minizip/unzip.c
diff --git third_party/zlib/contrib/minizip/unzip.c third_party/zlib/contrib/minizip/unzip.c
index 199b472..be42478 100644
--- contrib/minizip/unzip.c
+++ contrib/minizip/unzip.c
--- third_party/zlib/contrib/minizip/unzip.c
+++ third_party/zlib/contrib/minizip/unzip.c
@@ -69,7 +69,7 @@
#include <string.h>

View File

@ -5,21 +5,20 @@
from subprocess import Popen, PIPE
import sys
def exec_cmd(cmd, path, input_file=None):
def exec_cmd(cmd, path, input_string=None):
""" Execute the specified command and return the result. """
out = ''
err = ''
parts = cmd.split()
try:
if not input_file:
if input_string is None:
process = Popen(parts, cwd=path, stdout=PIPE, stderr=PIPE,
shell=(sys.platform == 'win32'))
out, err = process.communicate()
else:
with open(input_file, 'rb') as f:
process = Popen(parts, cwd=path, stdout=PIPE, stderr=PIPE,
stdin=f,
shell=(sys.platform == 'win32'))
out, err = process.communicate()
process = Popen(parts, cwd=path, stdin=PIPE, stdout=PIPE, stderr=PIPE,
shell=(sys.platform == 'win32'))
out, err = process.communicate(input=input_string)
except IOError, (errno, strerror):
raise
except:

View File

@ -35,8 +35,7 @@ cmd = [ 'python', 'tools/make_version_header.py',
RunAction(cef_dir, cmd)
print "\nPatching build configuration and source files for CEF..."
cmd = [ 'python', 'tools/patcher.py',
'--patch-config', 'patch/patch.cfg' ]
cmd = [ 'python', 'tools/patcher.py' ]
RunAction(cef_dir, cmd)
print "\nGenerating CEF project files..."

View File

@ -4,14 +4,21 @@
from exec_util import exec_cmd
import os
import sys
if sys.platform == 'win32':
# Force use of the git version bundled with depot_tools.
git_exe = 'git.bat'
else:
git_exe = 'git'
def is_checkout(path):
""" Returns true if the path represents a git checkout. """
return os.path.exists(os.path.join(path, '.git'))
return os.path.isdir(os.path.join(path, '.git'))
def get_hash(path = '.', branch = 'HEAD'):
""" Returns the git hash for the specified branch/tag/hash. """
cmd = "git rev-parse %s" % branch
cmd = "%s rev-parse %s" % (git_exe, branch)
result = exec_cmd(cmd, path)
if result['out'] != '':
return result['out'].strip()
@ -19,7 +26,7 @@ def get_hash(path = '.', branch = 'HEAD'):
def get_url(path = '.'):
""" Returns the origin url for the specified path. """
cmd = "git config --get remote.origin.url"
cmd = "%s config --get remote.origin.url" % git_exe
result = exec_cmd(cmd, path)
if result['out'] != '':
return result['out'].strip()
@ -27,7 +34,7 @@ def get_url(path = '.'):
def get_commit_number(path = '.', branch = 'HEAD'):
""" Returns the number of commits in the specified branch/tag/hash. """
cmd = "git rev-list --count %s" % branch
cmd = "%s rev-list --count %s" % (git_exe, branch)
result = exec_cmd(cmd, path)
if result['out'] != '':
return result['out'].strip()
@ -37,3 +44,64 @@ def get_changed_files(path = '.'):
""" Retrieves the list of changed files. """
# not implemented
return []
def write_indented_output(output):
""" Apply a fixed amount of intent to lines before printing. """
if output == '':
return
for line in output.split('\n'):
line = line.strip()
if len(line) == 0:
continue
sys.stdout.write('\t%s\n' % line)
def git_apply_patch_file(patch_path, patch_dir):
""" Apply |patch_path| to files in |patch_dir|. """
patch_name = os.path.basename(patch_path)
sys.stdout.write('\nApply %s in %s\n' % (patch_name, patch_dir))
if not os.path.isfile(patch_path):
sys.stdout.write('... patch file does not exist.\n')
return 'fail'
patch_string = open(patch_path, 'rb').read()
if sys.platform == 'win32':
# Convert the patch to Unix line endings. This is necessary to avoid
# whitespace errors with git apply.
patch_string = patch_string.replace('\r\n', '\n')
# Git apply fails silently if not run relative to a respository root.
if not is_checkout(patch_dir):
sys.stdout.write('... patch directory is not a repository root.\n')
return 'fail'
# Output patch contents.
cmd = '%s apply -p0 --numstat' % git_exe
result = exec_cmd(cmd, patch_dir, patch_string)
write_indented_output(result['out'].replace('<stdin>', patch_name))
# Reverse check to see if the patch has already been applied.
cmd = '%s apply -p0 --reverse --check' % git_exe
result = exec_cmd(cmd, patch_dir, patch_string)
if result['err'].find('error:') < 0:
sys.stdout.write('... already applied (skipping).\n')
return 'skip'
# Normal check to see if the patch can be applied cleanly.
cmd = '%s apply -p0 --check' % git_exe
result = exec_cmd(cmd, patch_dir, patch_string)
if result['err'].find('error:') >= 0:
sys.stdout.write('... failed to apply:\n')
write_indented_output(result['err'].replace('<stdin>', patch_name))
return 'fail'
# Apply the patch file. This should always succeed because the previous
# command succeeded.
cmd = '%s apply -p0' % git_exe
result = exec_cmd(cmd, patch_dir, patch_string)
if result['err'] == '':
sys.stdout.write('... successfully applied.\n')
else:
sys.stdout.write('... successfully applied (with warnings):\n')
write_indented_output(result['err'].replace('<stdin>', patch_name))
return 'apply'

View File

@ -1,2 +1,2 @@
@echo off
python.bat tools\patcher.py --patch-config patch/patch.cfg
python.bat tools\patcher.py

View File

@ -1,2 +1,2 @@
#!/bin/sh
python tools/patcher.py --patch-config patch/patch.cfg
python tools/patcher.py

View File

@ -75,7 +75,7 @@ if options.resave and options.revert:
# The CEF root directory is the parent directory of _this_ script.
cef_dir = os.path.abspath(os.path.join(os.path.dirname(__file__), os.pardir))
src_dir = os.path.join(cef_dir, os.pardir)
src_dir = os.path.abspath(os.path.join(cef_dir, os.pardir))
# Determine the type of Chromium checkout.
if not git.is_checkout(src_dir):
@ -104,8 +104,10 @@ for patch in patches:
if os.path.isfile(patch_file):
msg('Reading patch file %s' % patch_file)
patch_root = patch['path']
patch_root_abs = os.path.abspath(os.path.join(cef_dir, patch_root))
if 'path' in patch:
patch_root_abs = os.path.abspath(os.path.join(src_dir, patch['path']))
else:
patch_root_abs = src_dir
# Retrieve the list of paths modified by the patch file.
patch_paths = extract_paths(patch_file)
@ -136,7 +138,8 @@ for patch in patches:
if not options.revert:
# Apply the patch file.
msg('Applying patch to %s' % patch_root_abs)
result = exec_cmd('patch -p0', patch_root_abs, patch_file)
patch_string = open(patch_file, 'rb').read()
result = exec_cmd('patch -p0', patch_root_abs, patch_string)
if result['err'] != '':
raise Exception('Failed to apply patch file: %s' % result['err'])
sys.stdout.write(result['out'])

View File

@ -1,615 +0,0 @@
""" Patch utility to apply unified diffs """
""" Brute-force line-by-line parsing
Project home: http://code.google.com/p/python-patch/
This file is subject to the MIT license available here:
http://www.opensource.org/licenses/mit-license.php
CEF Changes
-----------
2016/10/27
- Create folders for new files created by a patch if needed
- Adding support for patches created with git diff on non svn platforms
(git diff on OSX creates source/target as /dev/null
for new/deleted files)
2015/04/22
- Write to stdout instead of using warning() for messages
2013/01/03
- Add support for patches containing new files
2009/07/22
- Add a 'root_directory' argument to PatchInfo::apply
- Fix a Python 2.4 compile error in PatchInfo::parse_stream
"""
__author__ = "techtonik.rainforce.org"
__version__ = "8.12-1"
import copy
import logging
import os
import re
from stat import *
# cStringIO doesn't support unicode in 2.5
from StringIO import StringIO
from logging import debug, info
from os.path import exists, isfile
from os import unlink
debugmode = False
def from_file(filename):
""" read and parse patch file
return PatchInfo() object
"""
info("reading patch from file %s" % filename)
fp = open(filename, "rb")
patch = PatchInfo(fp)
fp.close()
return patch
def from_string(s):
""" parse text string and return PatchInfo() object """
return PatchInfo(
StringIO.StringIO(s)
)
def msg(message):
""" Output a message. """
sys.stdout.write('--> ' + message + "\n")
class HunkInfo(object):
""" parsed hunk data (hunk starts with @@ -R +R @@) """
def __init__(self):
# define HunkInfo data members
self.startsrc=None
self.linessrc=None
self.starttgt=None
self.linestgt=None
self.invalid=False
self.text=[]
def copy(self):
return copy.copy(self)
# def apply(self, estream):
# """ write hunk data into enumerable stream
# return strings one by one until hunk is
# over
#
# enumerable stream are tuples (lineno, line)
# where lineno starts with 0
# """
# pass
class PatchInfo(object):
""" patch information container """
def __init__(self, stream=None):
""" parse incoming stream """
# define PatchInfo data members
# table with a row for every source file
#: list of source filenames
self.source=None
self.target=None
#: list of lists of hunks
self.hunks=None
#: file endings statistics for every hunk
self.hunkends=None
if stream:
self.parse_stream(stream)
def copy(self):
return copy.copy(self)
def parse_stream(self, stream):
""" parse unified diff """
self.source = []
self.target = []
self.hunks = []
self.hunkends = []
# define possible file regions that will direct the parser flow
header = False # comments before the patch body
filenames = False # lines starting with --- and +++
hunkhead = False # @@ -R +R @@ sequence
hunkbody = False #
hunkskip = False # skipping invalid hunk mode
header = True
lineends = dict(lf=0, crlf=0, cr=0)
nextfileno = 0
nexthunkno = 0 #: even if index starts with 0 user messages number hunks from 1
# hunkinfo holds parsed values, hunkactual - calculated
hunkinfo = HunkInfo()
hunkactual = dict(linessrc=None, linestgt=None)
fe = enumerate(stream)
for lineno, line in fe:
# analyze state
if header and line.startswith("--- "):
header = False
# switch to filenames state
filenames = True
#: skip hunkskip and hunkbody code until you read definition of hunkhead
if hunkbody:
# process line first
if re.match(r"^[- \+\\]", line):
# gather stats about line endings
if line.endswith("\r\n"):
self.hunkends[nextfileno-1]["crlf"] += 1
elif line.endswith("\n"):
self.hunkends[nextfileno-1]["lf"] += 1
elif line.endswith("\r"):
self.hunkends[nextfileno-1]["cr"] += 1
if line.startswith("-"):
hunkactual["linessrc"] += 1
elif line.startswith("+"):
hunkactual["linestgt"] += 1
elif not line.startswith("\\"):
hunkactual["linessrc"] += 1
hunkactual["linestgt"] += 1
hunkinfo.text.append(line)
# todo: handle \ No newline cases
else:
msg("invalid hunk no.%d at %d for target file %s" % (nexthunkno, lineno+1, self.target[nextfileno-1]))
# add hunk status node
self.hunks[nextfileno-1].append(hunkinfo.copy())
self.hunks[nextfileno-1][nexthunkno-1]["invalid"] = True
# switch to hunkskip state
hunkbody = False
hunkskip = True
# check exit conditions
if hunkactual["linessrc"] > hunkinfo.linessrc or hunkactual["linestgt"] > hunkinfo.linestgt:
msg("extra hunk no.%d lines at %d for target %s" % (nexthunkno, lineno+1, self.target[nextfileno-1]))
# add hunk status node
self.hunks[nextfileno-1].append(hunkinfo.copy())
self.hunks[nextfileno-1][nexthunkno-1]["invalid"] = True
# switch to hunkskip state
hunkbody = False
hunkskip = True
elif hunkinfo.linessrc == hunkactual["linessrc"] and hunkinfo.linestgt == hunkactual["linestgt"]:
self.hunks[nextfileno-1].append(hunkinfo.copy())
# switch to hunkskip state
hunkbody = False
hunkskip = True
# detect mixed window/unix line ends
ends = self.hunkends[nextfileno-1]
if ((ends["cr"]!=0) + (ends["crlf"]!=0) + (ends["lf"]!=0)) > 1:
msg("inconsistent line ends in patch hunks for %s" % self.source[nextfileno-1])
if debugmode:
debuglines = dict(ends)
debuglines.update(file=self.target[nextfileno-1], hunk=nexthunkno)
debug("crlf: %(crlf)d lf: %(lf)d cr: %(cr)d\t - file: %(file)s hunk: %(hunk)d" % debuglines)
if hunkskip:
match = re.match("^@@ -(\d+)(,(\d+))? \+(\d+)(,(\d+))?", line)
if match:
# switch to hunkhead state
hunkskip = False
hunkhead = True
elif line.startswith("--- "):
# switch to filenames state
hunkskip = False
filenames = True
if debugmode and len(self.source) > 0:
debug("- %2d hunks for %s" % (len(self.hunks[nextfileno-1]), self.source[nextfileno-1]))
if filenames:
if line.startswith("--- "):
if nextfileno in self.source:
msg("skipping invalid patch for %s" % self.source[nextfileno])
del self.source[nextfileno]
# double source filename line is encountered
# attempt to restart from this second line
re_filename = "^--- ([^\t]+)"
match = re.match(re_filename, line)
if not match:
msg("skipping invalid filename at line %d" % lineno)
# switch back to header state
filenames = False
header = True
else:
self.source.append(match.group(1).strip())
elif not line.startswith("+++ "):
if nextfileno in self.source:
msg("skipping invalid patch with no target for %s" % self.source[nextfileno])
del self.source[nextfileno]
else:
# this should be unreachable
msg("skipping invalid target patch")
filenames = False
header = True
else:
if nextfileno in self.target:
msg("skipping invalid patch - double target at line %d" % lineno)
del self.source[nextfileno]
del self.target[nextfileno]
nextfileno -= 1
# double target filename line is encountered
# switch back to header state
filenames = False
header = True
else:
re_filename = "^\+\+\+ ([^\t]+)"
match = re.match(re_filename, line)
if not match:
msg("skipping invalid patch - no target filename at line %d" % lineno)
# switch back to header state
filenames = False
header = True
else:
self.target.append(match.group(1).strip())
nextfileno += 1
# switch to hunkhead state
filenames = False
hunkhead = True
nexthunkno = 0
self.hunks.append([])
self.hunkends.append(lineends.copy())
continue
if hunkhead:
match = re.match("^@@ -(\d+)(,(\d+))? \+(\d+)(,(\d+))?", line)
if not match:
if nextfileno-1 not in self.hunks:
msg("skipping invalid patch with no hunks for file %s" % self.target[nextfileno-1])
# switch to header state
hunkhead = False
header = True
continue
else:
# switch to header state
hunkhead = False
header = True
else:
hunkinfo.startsrc = int(match.group(1))
if match.group(3):
hunkinfo.linessrc = int(match.group(3))
else:
hunkinfo.linessrc = 1
hunkinfo.starttgt = int(match.group(4))
if match.group(6):
hunkinfo.linestgt = int(match.group(6))
else:
hunkinfo.linestgt = 1
hunkinfo.invalid = False
hunkinfo.text = []
hunkactual["linessrc"] = hunkactual["linestgt"] = 0
# switch to hunkbody state
hunkhead = False
hunkbody = True
nexthunkno += 1
continue
else:
if not hunkskip:
msg("patch file incomplete - %s" % filename)
# sys.exit(?)
else:
# duplicated message when an eof is reached
if debugmode and len(self.source) > 0:
debug("- %2d hunks for %s" % (len(self.hunks[nextfileno-1]), self.source[nextfileno-1]))
info("total files: %d total hunks: %d" % (len(self.source), sum(len(hset) for hset in self.hunks)))
def apply(self, root_directory = None):
""" apply parsed patch """
total = len(self.source)
for fileno, filename in enumerate(self.source):
# git diff on OSX creates source/target as /dev/null for new/deleted files
if filename != '/dev/null':
f2patch = filename
else:
f2patch = self.target[fileno]
if not root_directory is None:
f2patch = root_directory + f2patch
if not exists(f2patch):
# if the patch contains a single hunk at position 0 consider it a new file
if len(self.hunks[fileno]) == 1 and self.hunks[fileno][0].startsrc == 0:
hunklines = [x[1:].rstrip("\r\n") for x in self.hunks[fileno][0].text if x[0] in " +"]
if len(hunklines) > 0:
f2patchfolder = os.path.dirname(os.path.abspath(f2patch))
if not os.path.exists(f2patchfolder):
msg("creating folder %s" % (f2patchfolder))
os.makedirs(f2patchfolder)
msg("creating file %s" % (f2patch))
f = open(f2patch, "wb")
for line in hunklines:
f.write(line + "\n")
f.close()
continue
f2patch = self.target[fileno]
if not exists(f2patch):
msg("source/target file does not exist\n--- %s\n+++ %s" % (filename, f2patch))
continue
if not isfile(f2patch):
msg("not a file - %s" % f2patch)
continue
filename = f2patch
info("processing %d/%d:\t %s" % (fileno+1, total, filename))
# validate before patching
f2fp = open(filename)
hunkno = 0
hunk = self.hunks[fileno][hunkno]
hunkfind = []
hunkreplace = []
validhunks = 0
canpatch = False
for lineno, line in enumerate(f2fp):
if lineno+1 < hunk.startsrc:
continue
elif lineno+1 == hunk.startsrc:
hunkfind = [x[1:].rstrip("\r\n") for x in hunk.text if x[0] in " -"]
hunkreplace = [x[1:].rstrip("\r\n") for x in hunk.text if x[0] in " +"]
#pprint(hunkreplace)
hunklineno = 0
# todo \ No newline at end of file
# check hunks in source file
if lineno+1 < hunk.startsrc+len(hunkfind)-1:
if line.rstrip("\r\n") == hunkfind[hunklineno]:
hunklineno+=1
else:
debug("hunk no.%d doesn't match source file %s" % (hunkno+1, filename))
# file may be already patched, but we will check other hunks anyway
hunkno += 1
if hunkno < len(self.hunks[fileno]):
hunk = self.hunks[fileno][hunkno]
continue
else:
break
# check if processed line is the last line
if lineno+1 == hunk.startsrc+len(hunkfind)-1:
debug("file %s hunk no.%d -- is ready to be patched" % (filename, hunkno+1))
hunkno+=1
validhunks+=1
if hunkno < len(self.hunks[fileno]):
hunk = self.hunks[fileno][hunkno]
else:
if validhunks == len(self.hunks[fileno]):
# patch file
canpatch = True
break
else:
if hunkno < len(self.hunks[fileno]) and \
(len(self.hunks[fileno]) != 1 or self.hunks[fileno][0].startsrc != 0):
msg("premature end of source file %s at hunk %d" % (filename, hunkno+1))
f2fp.close()
if validhunks < len(self.hunks[fileno]):
if check_patched(filename, self.hunks[fileno]):
msg("already patched %s" % filename)
else:
msg("source file is different - %s" % filename)
if canpatch:
backupname = filename+".orig"
if exists(backupname):
msg("can't backup original file to %s - aborting" % backupname)
else:
import shutil
shutil.move(filename, backupname)
if patch_hunks(backupname, filename, self.hunks[fileno]):
msg("successfully patched %s" % filename)
unlink(backupname)
else:
msg("error patching file %s" % filename)
shutil.copy(filename, filename+".invalid")
msg("invalid version is saved to %s" % filename+".invalid")
# todo: proper rejects
shutil.move(backupname, filename)
# todo: check for premature eof
def check_patched(filename, hunks):
matched = True
fp = open(filename)
class NoMatch(Exception):
pass
# special case for new files
try:
if len(hunks) == 1 and hunks[0].startsrc == 0:
hunklines = [x[1:].rstrip("\r\n") for x in hunks[0].text if x[0] in " +"]
if len(hunklines) > 0:
for line in hunklines:
srcline = fp.readline()
if not len(srcline) or srcline.rstrip("\r\n") != line:
raise NoMatch
srcline = fp.readline()
if len(srcline):
raise NoMatch
fp.close()
return True
except NoMatch:
fp.close()
fp = open(filename)
lineno = 1
line = fp.readline()
hno = None
try:
if not len(line):
raise NoMatch
for hno, h in enumerate(hunks):
# skip to line just before hunk starts
while lineno < h.starttgt-1:
line = fp.readline()
lineno += 1
if not len(line):
raise NoMatch
for hline in h.text:
# todo: \ No newline at the end of file
if not hline.startswith("-") and not hline.startswith("\\"):
line = fp.readline()
lineno += 1
if not len(line):
raise NoMatch
if line.rstrip("\r\n") != hline[1:].rstrip("\r\n"):
msg("file is not patched - failed hunk: %d" % (hno+1))
raise NoMatch
except NoMatch:
matched = False
# todo: display failed hunk, i.e. expected/found
fp.close()
return matched
def patch_stream(instream, hunks):
""" given a source stream and hunks iterable, yield patched stream
converts lineends in hunk lines to the best suitable format
autodetected from input
"""
# todo: At the moment substituted lineends may not be the same
# at the start and at the end of patching. Also issue a
# warning/throw about mixed lineends (is it really needed?)
hunks = iter(hunks)
srclineno = 1
lineends = {'\n':0, '\r\n':0, '\r':0}
def get_line():
"""
local utility function - return line from source stream
collecting line end statistics on the way
"""
line = instream.readline()
# 'U' mode works only with text files
if line.endswith("\r\n"):
lineends["\r\n"] += 1
elif line.endswith("\n"):
lineends["\n"] += 1
elif line.endswith("\r"):
lineends["\r"] += 1
return line
for hno, h in enumerate(hunks):
debug("hunk %d" % (hno+1))
# skip to line just before hunk starts
while srclineno < h.startsrc:
yield get_line()
srclineno += 1
for hline in h.text:
# todo: check \ No newline at the end of file
if hline.startswith("-") or hline.startswith("\\"):
get_line()
srclineno += 1
continue
else:
if not hline.startswith("+"):
get_line()
srclineno += 1
line2write = hline[1:]
# detect if line ends are consistent in source file
if sum([bool(lineends[x]) for x in lineends]) == 1:
newline = [x for x in lineends if lineends[x] != 0][0]
yield line2write.rstrip("\r\n")+newline
else: # newlines are mixed
yield line2write
for line in instream:
yield line
def patch_hunks(srcname, tgtname, hunks):
# get the current file mode
mode = os.stat(srcname)[ST_MODE]
src = open(srcname, "rb")
tgt = open(tgtname, "wb")
debug("processing target file %s" % tgtname)
tgt.writelines(patch_stream(src, hunks))
tgt.close()
src.close()
# restore the file mode
os.chmod(tgtname, mode)
return True
from optparse import OptionParser
from os.path import exists
import sys
if __name__ == "__main__":
opt = OptionParser(usage="%prog [options] unipatch-file", version="python-patch %s" % __version__)
opt.add_option("-d", action="store_true", dest="debugmode", help="debug mode")
(options, args) = opt.parse_args()
if not args:
opt.print_version()
print("")
opt.print_help()
sys.exit()
debugmode = options.debugmode
patchfile = args[0]
if not exists(patchfile) or not isfile(patchfile):
sys.exit("patch file does not exist - %s" % patchfile)
if debugmode:
logging.basicConfig(level=logging.DEBUG, format="%(levelname)8s %(message)s")
else:
logging.basicConfig(level=logging.INFO, format="%(message)s")
patch = from_file(patchfile)
#pprint(patch)
patch.apply()
# todo: document and test line ends handling logic - patch.py detects proper line-endings
# for inserted hunks and issues a warning if patched file has incosistent line ends

View File

@ -1,32 +1,18 @@
Chromium Embedded Framework (CEF) Patch Application Tool -- patcher.py
-------------------------------------------------------------------------------
Document Last Updated: July 23, 2009
Document Last Updated: April 26, 2017
OVERVIEW
--------
The CEF patch application tool is used by the patch project to apply patches
to the Chromium and WebKit code bases. Currently only unified diff format is
supported. See the README.txt file in the patch directory for information on
how the patch project uses this tool.
The CEF patch application tool is used to apply patches to the Chromium, Blink
and third-party code bases. Currently only unified diff format is supported.
See the README.txt file in the patch directory for information on how this tool
is used.
The 'patcher.bat' file can be used to run the patch application tool with
The patch.[bat|sh] file can be used to run the patch application tool with
command-line arguments that match the default CEF directory structure and
output options. Run 'patcher.py -h' for a complete list of available command-
line arguments.
CREDITS
-------
Thanks go to techtonik for developing the python-patch script. The
patch_util.py file is a slightly modified version of the original script which
can be found here: http://code.google.com/p/python-patch/
WORK REMAINING
--------------
o Add support for the GIT patch format.

View File

@ -7,36 +7,44 @@ from optparse import OptionParser
import os
import sys
from file_util import *
from patch_util import *
from git_util import git_apply_patch_file
# Cannot be loaded as a module.
if __name__ != "__main__":
sys.stdout.write('This file cannot be loaded as a module!')
sys.exit()
# The CEF root directory is the parent directory of _this_ script.
cef_dir = os.path.abspath(os.path.join(os.path.dirname(__file__), os.pardir))
cef_patch_dir = os.path.join(cef_dir, 'patch')
src_dir = os.path.abspath(os.path.join(cef_dir, os.pardir))
def normalize_dir(dir):
''' Normalize the directory value. '''
dir = dir.replace('\\', '/')
if dir[-1] != '/':
dir += '/'
return dir
def write_note(type, note):
separator = '-' * 79 + '\n'
sys.stdout.write(separator)
sys.stdout.write('!!!! %s: %s\n' % (type, note))
sys.stdout.write(separator)
def patch_file(patch_file, patch_dir):
''' Apply a single patch file in a single directory. '''
if not os.path.isfile(patch_file):
raise Exception('Patch file %s does not exist.' % patch_file)
def apply_patch_file(patch_file, patch_dir):
''' Apply a specific patch file in optional patch directory. '''
patch_path = os.path.join(cef_patch_dir, 'patches', patch_file + '.patch')
sys.stdout.write('Reading patch file %s\n' % patch_file)
patchObj = from_file(patch_file)
patchObj.apply(normalize_dir(patch_dir))
if patch_dir is None or len(patch_dir) == 0:
patch_dir = src_dir
else:
if not os.path.isabs(patch_dir):
# Apply patch relative to the Chromium 'src' directory.
patch_dir = os.path.join(src_dir, patch_dir)
patch_dir = os.path.abspath(patch_dir)
def patch_config(config_file):
result = git_apply_patch_file(patch_path, patch_dir)
if result == 'fail':
write_note('ERROR', 'This patch failed to apply. Your build will not be correct.')
return result
def apply_patch_config():
''' Apply patch files based on a configuration file. '''
# Normalize the patch directory value.
patchdir = normalize_dir(os.path.dirname(os.path.abspath(config_file)))
config_file = os.path.join(cef_patch_dir, 'patch.cfg')
if not os.path.isfile(config_file):
raise Exception('Patch config file %s does not exist.' % config_file)
@ -45,24 +53,33 @@ def patch_config(config_file):
execfile(config_file, scope)
patches = scope["patches"]
results = {'apply': 0, 'skip': 0, 'fail': 0}
for patch in patches:
file = patchdir+'patches/'+patch['name']+'.patch'
patch_file = patch['name']
dopatch = True
if 'condition' in patch:
# Check that the environment variable is set.
if patch['condition'] not in os.environ:
sys.stdout.write('Skipping patch file %s\n' % file)
sys.stdout.write('\nSkipping patch file %s\n' % patch_file)
dopatch = False
if dopatch:
patch_file(file, patch['path'])
if 'note' in patch:
separator = '-' * 79 + '\n'
sys.stdout.write(separator)
sys.stdout.write('NOTE: %s\n' % patch['note'])
sys.stdout.write(separator)
result = apply_patch_file(patch_file, patch['path'] if 'path' in patch else None)
results[result] += 1
if 'note' in patch:
write_note('NOTE', patch['note'])
else:
results['skip'] += 1
sys.stdout.write('\n%d patches total (%d applied, %d skipped, %d failed)\n' % \
(len(patches), results['apply'], results['skip'], results['fail']))
if results['fail'] > 0:
sys.stdout.write('\n')
write_note('ERROR', '%d patches failed to apply. Your build will not be correct.' % results['fail'])
# Parse command-line options.
disc = """
@ -70,18 +87,13 @@ This utility applies patch files.
"""
parser = OptionParser(description=disc)
parser.add_option('--patch-config', dest='patchconfig', metavar='DIR',
help='patch configuration file')
parser.add_option('--patch-file', dest='patchfile', metavar='FILE',
help='patch source file')
parser.add_option('--patch-dir', dest='patchdir', metavar='DIR',
help='patch target directory')
(options, args) = parser.parse_args()
if not options.patchconfig is None:
patch_config(options.patchconfig)
elif not options.patchfile is None and not options.patchdir is None:
patch_file(options.patchfile, options.patchdir)
if not options.patchfile is None:
apply_patch_file(options.patchfile, options.patchdir)
else:
parser.print_help(sys.stdout)
sys.exit()
apply_patch_config()