summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTobias Markmann <tm@ayena.de>2016-02-10 19:25:21 (GMT)
committerKevin Smith <kevin.smith@isode.com>2016-02-15 12:31:10 (GMT)
commitca226e7bb019308db4bfc818d7e04422d9d28106 (patch)
tree9f7ef065f20db3e04eb08560674eed16d10e95e5 /Swift/QtUI
parent431eb62386101dc8fc1e7d346c49bd0d81fda70e (diff)
downloadswift-ca226e7bb019308db4bfc818d7e04422d9d28106.zip
swift-ca226e7bb019308db4bfc818d7e04422d9d28106.tar.bz2
Fix crash when saving a received file to non-writable location
WriteBytestream::write(…) now returns a boolean indicating its success state (false in case of an error). Adjusted FileWriteBytestream accordingly. The QtWebKitChatView will test if the file path selected by the user is writable before accepting it and starting the transfer. If it is not writable a red warning message will be added to the file-transfer element in the chat view. Test-Information: Added an integration test that tests the new behavior for the FileWriteBytestream class. Tested two file transfers on OS X 10.11.3, one to a write protected location and another to /tmp. The first is not accepted by the UI, and without the UI sanity check it results in a file-transfer error. The second succeeds as expected. Change-Id: I5aa0c617423073feb371365a23a294c149c88036
Diffstat (limited to 'Swift/QtUI')
-rw-r--r--Swift/QtUI/QtWebKitChatView.cpp53
-rw-r--r--Swift/QtUI/QtWebKitChatView.h4
2 files changed, 54 insertions, 3 deletions
diff --git a/Swift/QtUI/QtWebKitChatView.cpp b/Swift/QtUI/QtWebKitChatView.cpp
index 260da8a..b543e34 100644
--- a/Swift/QtUI/QtWebKitChatView.cpp
+++ b/Swift/QtUI/QtWebKitChatView.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2010-2015 Isode Limited.
+ * Copyright (c) 2010-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
@@ -11,6 +11,7 @@
#include <QEventLoop>
#include <QFile>
#include <QFileDialog>
+#include <QFileInfo>
#include <QInputDialog>
#include <QKeyEvent>
#include <QMessageBox>
@@ -747,6 +748,50 @@ void QtWebKitChatView::setWhiteboardSessionStatus(const std::string& id, const C
setWhiteboardSessionStatus(P2QSTRING(id), state);
}
+static bool isFilePathWritable(const QString& path) {
+ QFileInfo fileInfo = QFileInfo(path);
+ if (fileInfo.exists()) {
+ return fileInfo.isWritable();
+ }
+ else {
+ bool writable = false;
+ QFile writeTestFile(path);
+ if (writeTestFile.open(QIODevice::ReadWrite)) {
+ writeTestFile.write("test");
+ if (writeTestFile.error() == QFileDevice::NoError) {
+ writable = true;
+ }
+ }
+ writeTestFile.close();
+ writeTestFile.remove();
+ return writable;
+ }
+}
+
+void QtWebKitChatView::setFileTransferWarning(QString id, QString warningText) {
+ QWebElement ftElement = findElementWithID(document_, "div", id);
+ if (ftElement.isNull()) {
+ SWIFT_LOG(debug) << "Tried to access FT UI via invalid id! id = " << Q2PSTRING(id) << std::endl;
+ return;
+ }
+
+ removeFileTransferWarning(id);
+ ftElement.appendInside(QString("<div class='ft_warning' style='color: red;'><br/>%1</div>").arg(QtUtilities::htmlEscape(warningText)));
+}
+
+void QtWebKitChatView::removeFileTransferWarning(QString id) {
+ QWebElement ftElement = findElementWithID(document_, "div", id);
+ if (ftElement.isNull()) {
+ SWIFT_LOG(debug) << "Tried to access FT UI via invalid id! id = " << Q2PSTRING(id) << std::endl;
+ return;
+ }
+
+ QWebElement warningElement = ftElement.findFirst(".ft_warning");
+ if (!warningElement.isNull()) {
+ warningElement.removeFromDocument();
+ }
+}
+
void QtWebKitChatView::handleHTMLButtonClicked(QString id, QString encodedArgument1, QString encodedArgument2, QString encodedArgument3, QString encodedArgument4, QString encodedArgument5) {
QString arg1 = decodeButtonArgument(encodedArgument1);
QString arg2 = decodeButtonArgument(encodedArgument2);
@@ -777,9 +822,13 @@ void QtWebKitChatView::handleHTMLButtonClicked(QString id, QString encodedArgume
QString filename = arg2;
QString path = QFileDialog::getSaveFileName(this, tr("Save File"), filename);
- if (!path.isEmpty()) {
+ if (!path.isEmpty() && isFilePathWritable(path)) {
filePaths_[ft_id] = path;
window_->onFileTransferAccept(Q2PSTRING(ft_id), Q2PSTRING(path));
+ removeFileTransferWarning(ft_id);
+ }
+ else {
+ setFileTransferWarning(ft_id, tr("The chosen save location is not writable! Click the 'Accept' button to select a different save location."));
}
}
else if (id.startsWith(ButtonFileTransferOpenFile)) {
diff --git a/Swift/QtUI/QtWebKitChatView.h b/Swift/QtUI/QtWebKitChatView.h
index 99375f7..173a05b 100644
--- a/Swift/QtUI/QtWebKitChatView.h
+++ b/Swift/QtUI/QtWebKitChatView.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2010-2015 Isode Limited.
+ * Copyright (c) 2010-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
@@ -95,6 +95,8 @@ namespace Swift {
void addToJSEnvironment(const QString&, QObject*);
void setFileTransferProgress(QString id, const int percentageDone);
void setFileTransferStatus(QString id, const ChatWindow::FileTransferState state, const QString& msg);
+ void setFileTransferWarning(QString id, QString warningText);
+ void removeFileTransferWarning(QString id);
void setWhiteboardSessionStatus(QString id, const ChatWindow::WhiteboardSessionState state);
void setMUCInvitationJoined(QString id);
void askDesktopToOpenFile(const QString& filename);