mirror of
https://github.com/nextcloud/desktop.git
synced 2024-11-22 04:55:48 +03:00
Checksum: Ignore unkown OC-Checksum header when downloading...
And if there are several checksums, pick the "best" one. The case of several checksum was reported in https://github.com/nextcloud/client_theming/issues/213
This commit is contained in:
parent
529bcab009
commit
480932a58a
5 changed files with 42 additions and 24 deletions
|
@ -90,6 +90,21 @@ QByteArray makeChecksumHeader(const QByteArray &checksumType, const QByteArray &
|
|||
return header;
|
||||
}
|
||||
|
||||
QByteArray findBestChecksum(const QByteArray &checksums)
|
||||
{
|
||||
int i = 0;
|
||||
// The order of the searches here defines the preference ordering.
|
||||
if (-1 != (i = checksums.indexOf("SHA1:"))
|
||||
|| -1 != (i = checksums.indexOf("MD5:"))
|
||||
|| -1 != (i = checksums.indexOf("Adler32:"))) {
|
||||
// Now i is the start of the best checksum
|
||||
// Grab it until the next space or end of string.
|
||||
auto checksum = checksums.mid(i);
|
||||
return checksum.mid(0, checksum.indexOf(" "));
|
||||
}
|
||||
return QByteArray();
|
||||
}
|
||||
|
||||
bool parseChecksumHeader(const QByteArray &header, QByteArray *type, QByteArray *checksum)
|
||||
{
|
||||
if (header.isEmpty()) {
|
||||
|
|
|
@ -36,6 +36,16 @@ static const char checkSumAdlerC[] = "Adler32";
|
|||
|
||||
class SyncJournalDb;
|
||||
|
||||
/**
|
||||
* Returns the highest-quality checksum in a 'checksums'
|
||||
* property retrieved from the server.
|
||||
*
|
||||
* Example: "ADLER32:1231 SHA1:ab124124 MD5:2131affa21"
|
||||
* -> "SHA1:ab124124"
|
||||
*/
|
||||
OCSYNC_EXPORT QByteArray findBestChecksum(const QByteArray &checksums);
|
||||
|
||||
|
||||
/// Creates a checksum header from type and value.
|
||||
OCSYNC_EXPORT QByteArray makeChecksumHeader(const QByteArray &checksumType, const QByteArray &checksum);
|
||||
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
#include "account.h"
|
||||
#include "theme.h"
|
||||
#include "common/asserts.h"
|
||||
#include "common/checksums.h"
|
||||
|
||||
#include <csync_private.h>
|
||||
#include <csync_rename.h>
|
||||
|
@ -300,28 +301,6 @@ void DiscoverySingleDirectoryJob::abort()
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the highest-quality checksum in a 'checksums'
|
||||
* property retrieved from the server.
|
||||
*
|
||||
* Example: "ADLER32:1231 SHA1:ab124124 MD5:2131affa21"
|
||||
* -> "SHA1:ab124124"
|
||||
*/
|
||||
static QByteArray findBestChecksum(const QByteArray &checksums)
|
||||
{
|
||||
int i = 0;
|
||||
// The order of the searches here defines the preference ordering.
|
||||
if (-1 != (i = checksums.indexOf("SHA1:"))
|
||||
|| -1 != (i = checksums.indexOf("MD5:"))
|
||||
|| -1 != (i = checksums.indexOf("Adler32:"))) {
|
||||
// Now i is the start of the best checksum
|
||||
// Grab it until the next space or end of string.
|
||||
auto checksum = checksums.mid(i);
|
||||
return checksum.mid(0, checksum.indexOf(" "));
|
||||
}
|
||||
return QByteArray();
|
||||
}
|
||||
|
||||
static std::unique_ptr<csync_file_stat_t> propertyMapToFileStat(const QMap<QString, QString> &map)
|
||||
{
|
||||
std::unique_ptr<csync_file_stat_t> file_stat(new csync_file_stat_t);
|
||||
|
|
|
@ -647,7 +647,7 @@ void PropagateDownloadFile::slotGetFinished()
|
|||
this, &PropagateDownloadFile::transmissionChecksumValidated);
|
||||
connect(validator, &ValidateChecksumHeader::validationFailed,
|
||||
this, &PropagateDownloadFile::slotChecksumFail);
|
||||
auto checksumHeader = job->reply()->rawHeader(checkSumHeaderC);
|
||||
auto checksumHeader = findBestChecksum(job->reply()->rawHeader(checkSumHeaderC));
|
||||
auto contentMd5Header = job->reply()->rawHeader(contentMd5HeaderC);
|
||||
if (checksumHeader.isEmpty() && !contentMd5Header.isEmpty())
|
||||
checksumHeader = "MD5:" + contentMd5Header;
|
||||
|
|
|
@ -510,11 +510,25 @@ private slots:
|
|||
QVERIFY(fakeFolder.syncOnce());
|
||||
QCOMPARE(fakeFolder.currentLocalState(), fakeFolder.currentRemoteState());
|
||||
|
||||
// OC-Checksum has preference
|
||||
// Invalid OC-Checksum is ignored
|
||||
checksumValue = "garbage";
|
||||
// contentMd5Value is still good
|
||||
fakeFolder.remoteModifier().create("A/a6", 16, 'A');
|
||||
QVERIFY(fakeFolder.syncOnce());
|
||||
contentMd5Value = "bad";
|
||||
fakeFolder.remoteModifier().create("A/a7", 16, 'A');
|
||||
QVERIFY(!fakeFolder.syncOnce());
|
||||
contentMd5Value.clear();
|
||||
QVERIFY(fakeFolder.syncOnce());
|
||||
QCOMPARE(fakeFolder.currentLocalState(), fakeFolder.currentRemoteState());
|
||||
|
||||
// OC-Checksum contains Unsupported checksums
|
||||
checksumValue = "Unsupported:XXXX SHA1:invalid Invalid:XxX";
|
||||
fakeFolder.remoteModifier().create("A/a8", 16, 'A');
|
||||
QVERIFY(!fakeFolder.syncOnce()); // Since the supported SHA1 checksum is invalid, no download
|
||||
checksumValue = "Unsupported:XXXX SHA1:19b1928d58a2030d08023f3d7054516dbc186f20 Invalid:XxX";
|
||||
QVERIFY(fakeFolder.syncOnce()); // The supported SHA1 checksum is valid now, so the file are downloaded
|
||||
QCOMPARE(fakeFolder.currentLocalState(), fakeFolder.currentRemoteState());
|
||||
}
|
||||
|
||||
// Tests the behavior of invalid filename detection
|
||||
|
|
Loading…
Reference in a new issue