summaryrefslogtreecommitdiffstats
path: root/wsd
diff options
context:
space:
mode:
authorDennis Francis <dennis.francis@collabora.com>2021-10-22 12:50:19 +0530
committerDennis Francis <dennisfrancis.in@gmail.com>2021-11-02 15:27:45 +0530
commitef12112f4a3dfb0193b36be428e8900a05815a8e (patch)
tree44178f3200a7af50da3c2292b32a8fb7c0dafc12 /wsd
parentUpdate l10n files for Weblate (diff)
downloadonline-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.cpp27
-rw-r--r--wsd/ClientSession.hpp4
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;