fix: clipboard.writeBuffer raw format access (#31116)

* fix: clipboard.writeBuffer raw format access

* test: clipboard.writeBuffer raw format access

* test: clipboard win32 test skip

* fixup spec

* cleanup patch

Co-authored-by: John Kleinschmidt <jkleinsc@electronjs.org>
This commit is contained in:
henrit 2021-11-04 13:19:30 -05:00 коммит произвёл GitHub
Родитель f8df634197
Коммит 3c33d70294
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
4 изменённых файлов: 76 добавлений и 3 удалений

Просмотреть файл

@ -106,6 +106,7 @@ feat_expose_raw_response_headers_from_urlloader.patch
chore_do_not_use_chrome_windows_in_cryptotoken_webrequestsender.patch
process_singleton.patch
fix_expose_decrementcapturercount_in_web_contents_impl.patch
add_ui_scopedcliboardwriter_writeunsaferawdata.patch
feat_add_data_parameter_to_processsingleton.patch
mas_gate_private_enterprise_APIs
load_v8_snapshot_in_browser_process.patch

Просмотреть файл

@ -0,0 +1,45 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Henri Torgemane <henrit@gmail.com>
Date: Thu, 23 Sep 2021 21:30:33 -0500
Subject: add ui::ScopedCliboardWriter::WriteUnsafeRawData
This restores some ability to write to the clipboard using raw formats, which
was removed as part of the Raw Clipboard API scrubbing.
https://bugs.chromium.org/p/chromium/issues/detail?id=1217643
diff --git a/ui/base/clipboard/scoped_clipboard_writer.cc b/ui/base/clipboard/scoped_clipboard_writer.cc
index 153f169d2cdef6f8a726c188283a5bc1b7395fa3..3a5d9ab8dafacafb1025e1cb8c157e8a82078424 100644
--- a/ui/base/clipboard/scoped_clipboard_writer.cc
+++ b/ui/base/clipboard/scoped_clipboard_writer.cc
@@ -212,6 +212,16 @@ void ScopedClipboardWriter::WriteData(const std::u16string& format,
}
}
+void ScopedClipboardWriter::WriteUnsafeRawData(const std::u16string& format,
+ mojo_base::BigBuffer data) {
+ static constexpr int kMaxRegisteredFormats = 100;
+ if (counter_ >= kMaxRegisteredFormats)
+ return;
+ counter_++;
+ platform_representations_.push_back(
+ {base::UTF16ToUTF8(format), std::move(data)});
+}
+
void ScopedClipboardWriter::Reset() {
objects_.clear();
platform_representations_.clear();
diff --git a/ui/base/clipboard/scoped_clipboard_writer.h b/ui/base/clipboard/scoped_clipboard_writer.h
index 879acd4f6f0101a6da3af58d78eeda877ea41a4a..4d4149b6aa34c7073804994cb1c03368830c736d 100644
--- a/ui/base/clipboard/scoped_clipboard_writer.h
+++ b/ui/base/clipboard/scoped_clipboard_writer.h
@@ -80,6 +80,10 @@ class COMPONENT_EXPORT(UI_BASE_CLIPBOARD) ScopedClipboardWriter {
// This is only used to write custom format data.
void WriteData(const std::u16string& format, mojo_base::BigBuffer data);
+ // write raw (non-pickled) data to the clipboard
+ void WriteUnsafeRawData(const std::u16string& format,
+ mojo_base::BigBuffer data);
+
void WriteImage(const SkBitmap& bitmap);
// Mark the data to be written as confidential.

Просмотреть файл

@ -51,7 +51,23 @@ bool Clipboard::Has(const std::string& format_string,
std::string Clipboard::Read(const std::string& format_string) {
ui::Clipboard* clipboard = ui::Clipboard::GetForCurrentThread();
// Prefer raw platform format names
ui::ClipboardFormatType rawFormat(
ui::ClipboardFormatType::CustomPlatformType(format_string));
bool rawFormatAvailable = clipboard->IsFormatAvailable(
rawFormat, ui::ClipboardBuffer::kCopyPaste, /* data_dst = */ nullptr);
#if defined(OS_LINUX)
if (!rawFormatAvailable) {
rawFormatAvailable = clipboard->IsFormatAvailable(
rawFormat, ui::ClipboardBuffer::kSelection, /* data_dst = */ nullptr);
}
#endif
if (rawFormatAvailable) {
std::string data;
clipboard->ReadData(rawFormat, /* data_dst = */ nullptr, &data);
return data;
}
// Otherwise, resolve custom format names
std::map<std::string, std::string> custom_format_names;
custom_format_names =
clipboard->ExtractCustomPlatformNames(ui::ClipboardBuffer::kCopyPaste,
@ -97,8 +113,8 @@ void Clipboard::WriteBuffer(const std::string& format,
base::span<const uint8_t> payload_span(
reinterpret_cast<const uint8_t*>(node::Buffer::Data(buffer)),
node::Buffer::Length(buffer));
writer.WriteData(base::UTF8ToUTF16(format),
mojo_base::BigBuffer(payload_span));
writer.WriteUnsafeRawData(base::UTF8ToUTF16(format),
mojo_base::BigBuffer(payload_span));
}
void Clipboard::Write(const gin_helper::Dictionary& data,

Просмотреть файл

@ -129,5 +129,16 @@ ifdescribe(process.platform !== 'win32' || process.arch !== 'arm64')('clipboard
clipboard.writeBuffer('public/utf8-plain-text', 'hello');
}).to.throw(/buffer must be a node Buffer/);
});
ifit(process.platform !== 'win32')('writes a Buffer using a raw format that is used by native apps', function () {
const message = 'Hello from Electron!';
const buffer = Buffer.from(message);
let rawFormat = 'text/plain';
if (process.platform === 'darwin') {
rawFormat = 'public.utf8-plain-text';
}
clipboard.writeBuffer(rawFormat, buffer);
expect(clipboard.readText()).to.equal(message);
});
});
});