Skip to content

Commit

Permalink
fix: clipboard.writeBuffer raw format access (#31720)
Browse files Browse the repository at this point in the history
* 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>

* fixup .patches file

Co-authored-by: henrit <henrit@gmail.com>
Co-authored-by: John Kleinschmidt <jkleinsc@electronjs.org>
  • Loading branch information
3 people committed Nov 8, 2021
1 parent 3e0a2ed commit 5426d2c
Show file tree
Hide file tree
Showing 4 changed files with 76 additions and 3 deletions.
1 change: 1 addition & 0 deletions patches/chromium/.patches
Expand Up @@ -106,6 +106,7 @@ feat_expose_raw_response_headers_from_urlloader.patch
fix_media_key_usage_with_globalshortcuts.patch
cherry-pick-ec42dfd3545f.patch
cherry-pick-39090918efac.patch
add_ui_scopedcliboardwriter_writeunsaferawdata.patch
mas_gate_private_enterprise_APIs
cherry-pick-8af66de55aad.patch
cherry-pick-c69dddfe1cde.patch
Expand Down
@@ -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.
22 changes: 19 additions & 3 deletions shell/common/api/electron_api_clipboard.cc
Expand Up @@ -50,7 +50,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,
Expand Down Expand Up @@ -96,8 +112,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,
Expand Down
11 changes: 11 additions & 0 deletions spec/api-clipboard-spec.js
Expand Up @@ -123,5 +123,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);
});
});
});

0 comments on commit 5426d2c

Please sign in to comment.