diff options
author | Dennis Francis <dennis.francis@collabora.com> | 2021-10-22 12:50:19 +0530 |
---|---|---|
committer | Dennis Francis <dennisfrancis.in@gmail.com> | 2021-11-02 15:27:45 +0530 |
commit | ef12112f4a3dfb0193b36be428e8900a05815a8e (patch) | |
tree | 44178f3200a7af50da3c2292b32a8fb7c0dafc12 /wsd | |
parent | Update l10n files for Weblate (diff) | |
download | online-ef12112f4a3dfb0193b36be428e8900a05815a8e.tar.gz online-ef12112f4a3dfb0193b36be428e8900a05815a8e.zip |
clipboard: fix partial content read for text/html
Problem:
In ClientSession::postProcessCopyPayload() the serialized form of
clipboard's text/html is modified to inject meta origin and sent to the
client. When this data is sent back from client to the server(possibly a
different one) to set the core clipboard via "setclipboard", the parser
gets confused because the 'text/html' part/flavour's data length as
originally set by the core the first time does not agree with the actual
length due to the meta origin injection done previously. As a result the
parsed results of 'text/html' is only partial and possibly the parsing
of subsequent flavours are affected.
Fix:
Add a preprocess step for the payload for setclipboard to
remove the meta origin tag from the payload before parsing is done
(in ChildSession).
The original clipboard payload is created in
ChildSession::getClipboard(). Note that here we encode every flavour
core supports ('text/html' is just one of them) where the type and size
of each flavour data is included. The problem is that later on,
ClientSession::postProcessCopyPayload() injects a meta tag(which is
needed in the client) into this multi favour payload without adjusting
the size of the flavour (which messes up any subsequent parsing of the
'text/html' flavour section and those after it). We could adjust/correct
the size in ClientSession::postProcessCopyPayload(), which is one
solution but the way we do it here (string search on the whole payload!)
without proper parsing seems less futuristic (things can go wrong if we
change the format of packing flavour data in the payload). I feel that a
less hacky solution is to remove the meta tag (current patch) to make it
exactly how it was created in ChildSession::getClipboard() so that we
don't have to do any error-prone size adjustments in
ClientSession::postProcessCopyPayload() or when parsing the payload.
Signed-off-by: Dennis Francis <dennis.francis@collabora.com>
Change-Id: I285f133829ea0f2dd1cd07d17e90f794ba9a6caf
Diffstat (limited to 'wsd')
-rw-r--r-- | wsd/ClientSession.cpp | 27 | ||||
-rw-r--r-- | wsd/ClientSession.hpp | 4 |
2 files changed, 31 insertions, 0 deletions
diff --git a/wsd/ClientSession.cpp b/wsd/ClientSession.cpp index b4c9cc9a5e..05931579c8 100644 --- a/wsd/ClientSession.cpp +++ b/wsd/ClientSession.cpp @@ -318,6 +318,7 @@ void ClientSession::handleClipboardRequest(DocumentBroker::ClipboardRequest LOG_TRC("Session [" << getId() << "] sending setclipboard"); if (data.get()) { + preProcessSetClipboardPayload(*data); docBroker->forwardToChild(getId(), "setclipboard\n" + *data); // FIXME: work harder for error detection ? @@ -1379,6 +1380,8 @@ void ClientSession::writeQueuedMessages(std::size_t capacity) } // NB. also see loleaflet/src/map/Clipboard.js that does this in JS for stubs. +// See also ClientSession::preProcessSetClipboardPayload() which removes the +// <meta name="origin"...> tag added here. void ClientSession::postProcessCopyPayload(const std::shared_ptr<Message>& payload) { // Insert our meta origin if we can @@ -2287,4 +2290,28 @@ void ClientSession::traceTileBySend(const TileDesc& tile, bool deduplicated) addTileOnFly(tile); } +// This removes the <meta name="origin" ...> tag which was added in +// ClientSession::postProcessCopyPayload(), else the payload parsing +// in ChildSession::setClipboard() will fail. +// To see why, refer +// 1. ChildSession::getClipboard() where the data for various +// flavours along with flavour-type and length fields are packed into the payload. +// 2. The clipboard payload parsing code in ClipboardData::read(). +void ClientSession::preProcessSetClipboardPayload(std::string& payload) +{ + std::size_t start = payload.find("<meta name=\"origin\" content=\""); + if (start != std::string::npos) + { + std::size_t end = payload.find("\"/>\n", start); + if (end == std::string::npos) + { + LOG_DBG("Found unbalanced <meta name=\"origin\".../> tag in setclipboard payload."); + return; + } + + std::size_t len = end - start + 4; + payload.erase(start, len); + } +} + /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/wsd/ClientSession.hpp b/wsd/ClientSession.hpp index d8f10468b7..f7fef79a7d 100644 --- a/wsd/ClientSession.hpp +++ b/wsd/ClientSession.hpp @@ -241,6 +241,10 @@ private: /// If this session is read-only because of failed lock, try to unlock and make it read-write. bool attemptLock(const std::shared_ptr<DocumentBroker>& docBroker); + /// Removes the <meta name="origin" ...> tag which was added in + /// ClientSession::postProcessCopyPayload(). + static void preProcessSetClipboardPayload(std::string& payload); + private: std::weak_ptr<DocumentBroker> _docBroker; |