mirror of
https://github.com/nextcloud/desktop.git
synced 2024-11-26 23:28:14 +03:00
Handle Encoding Problems
TestSyncEngine now passes
This commit is contained in:
parent
501da58b10
commit
92ddc60900
3 changed files with 30 additions and 42 deletions
|
@ -148,21 +148,6 @@ static int _csync_detect_update(CSYNC *ctx, std::unique_ptr<csync_file_stat_t> f
|
|||
}
|
||||
}
|
||||
|
||||
auto localCodec = QTextCodec::codecForLocale();
|
||||
if (ctx->current == REMOTE_REPLICA && localCodec->mibEnum() != 106) {
|
||||
/* If the locale codec is not UTF-8, we must check that the filename from the server can
|
||||
* be encoded in the local file system.
|
||||
*
|
||||
* We cannot use QTextCodec::canEncode() since that can incorrectly return true, see
|
||||
* https://bugreports.qt.io/browse/QTBUG-6925.
|
||||
*/
|
||||
QTextEncoder encoder(localCodec, QTextCodec::ConvertInvalidToNull);
|
||||
if (encoder.fromUnicode(QString::fromUtf8(fs->path)).contains('\0')) {
|
||||
qCInfo(lcUpdate, "cannot encode %s to local encoding %d",
|
||||
fs->path.constData(), localCodec->mibEnum());
|
||||
excluded = CSYNC_FILE_EXCLUDE_CANNOT_ENCODE;
|
||||
}
|
||||
}
|
||||
|
||||
if (fs->type == ItemTypeFile ) {
|
||||
if (fs->modtime == 0) {
|
||||
|
|
|
@ -19,10 +19,12 @@
|
|||
#include <algorithm>
|
||||
#include <set>
|
||||
#include <QDirIterator>
|
||||
#include <QTextCodec>
|
||||
#include "vio/csync_vio_local.h"
|
||||
#include "common/checksums.h"
|
||||
#include "csync_exclude.h"
|
||||
|
||||
|
||||
namespace OCC {
|
||||
|
||||
Q_LOGGING_CATEGORY(lcDisco, "sync.discovery", QtInfoMsg)
|
||||
|
@ -97,7 +99,20 @@ void ProcessDirectoryJob::start()
|
|||
}
|
||||
while (auto dirent = csync_vio_local_readdir(dh)) {
|
||||
LocalInfo i;
|
||||
i.name = QString::fromUtf8(dirent->path); // FIXME! conversion errors
|
||||
static QTextCodec *codec = QTextCodec::codecForName("UTF-8");
|
||||
ASSERT(codec);
|
||||
QTextCodec::ConverterState state;
|
||||
i.name = codec->toUnicode(dirent->path, dirent->path.size(), &state);
|
||||
if (state.invalidChars > 0 || state.remainingChars > 0) {
|
||||
_childIgnored = true;
|
||||
auto item = SyncFileItemPtr::create();
|
||||
item->_file = _currentFolder + i.name;
|
||||
item->_instruction = CSYNC_INSTRUCTION_IGNORE;
|
||||
item->_status = SyncFileItem::NormalError;
|
||||
item->_errorString = tr("Filename encoding is not valid");
|
||||
emit itemDiscovered(item);
|
||||
continue;
|
||||
}
|
||||
i.modtime = dirent->modtime;
|
||||
i.size = dirent->size;
|
||||
i.inode = dirent->inode;
|
||||
|
@ -194,6 +209,20 @@ bool ProcessDirectoryJob::handleExcluded(const QString &path, bool isDirectory,
|
|||
excluded = CSYNC_FILE_EXCLUDE_HIDDEN;
|
||||
}
|
||||
|
||||
auto localCodec = QTextCodec::codecForLocale();
|
||||
if (localCodec->mibEnum() != 106) {
|
||||
// If the locale codec is not UTF-8, we must check that the filename from the server can
|
||||
// be encoded in the local file system.
|
||||
//
|
||||
// We cannot use QTextCodec::canEncode() since that can incorrectly return true, see
|
||||
// https://bugreports.qt.io/browse/QTBUG-6925.
|
||||
QTextEncoder encoder(localCodec, QTextCodec::ConvertInvalidToNull);
|
||||
if (encoder.fromUnicode(path).contains('\0')) {
|
||||
qCWarning(lcDisco) << "Cannot encode " << path << " to local encoding " << localCodec->name();
|
||||
excluded = CSYNC_FILE_EXCLUDE_CANNOT_ENCODE;
|
||||
}
|
||||
}
|
||||
|
||||
if (excluded == CSYNC_NOT_EXCLUDED /* FIXME && item->_type != ItemTypeSoftLink */) {
|
||||
return false;
|
||||
} else if (excluded == CSYNC_FILE_SILENTLY_EXCLUDED || excluded == CSYNC_FILE_EXCLUDE_AND_REMOVE) {
|
||||
|
|
|
@ -387,28 +387,7 @@ int SyncEngine::treewalkFile(csync_file_stat_t * /*file*/, csync_file_stat_t * /
|
|||
// Decode utf8 path and rename_path QByteArrays to QStrings
|
||||
QString fileUtf8;
|
||||
QString renameTarget;
|
||||
bool utf8DecodeError = false;
|
||||
{
|
||||
const auto toUnicode = [](QByteArray utf8, QString *result) {
|
||||
static QTextCodec *codec = QTextCodec::codecForName("UTF-8");
|
||||
ASSERT(codec);
|
||||
|
||||
QTextCodec::ConverterState state;
|
||||
*result = codec->toUnicode(utf8, utf8.size(), &state);
|
||||
return !(state.invalidChars > 0 || state.remainingChars > 0);
|
||||
};
|
||||
|
||||
if (!toUnicode(file->path, &fileUtf8)) {
|
||||
qCWarning(lcEngine) << "File ignored because of invalid utf-8 sequence: " << file->path;
|
||||
instruction = CSYNC_INSTRUCTION_IGNORE;
|
||||
utf8DecodeError = true;
|
||||
}
|
||||
if (!toUnicode(file->rename_path, &renameTarget)) {
|
||||
qCWarning(lcEngine) << "File ignored because of invalid utf-8 sequence in the rename_path: " << file->path << file->rename_path;
|
||||
instruction = CSYNC_INSTRUCTION_IGNORE;
|
||||
utf8DecodeError = true;
|
||||
}
|
||||
}
|
||||
|
||||
// key is the handle that the SyncFileItem will have in the map.
|
||||
QString key = fileUtf8;
|
||||
|
@ -513,11 +492,6 @@ int SyncEngine::treewalkFile(csync_file_stat_t * /*file*/, csync_file_stat_t * /
|
|||
}
|
||||
|
||||
|
||||
if (item->_instruction == CSYNC_INSTRUCTION_IGNORE && utf8DecodeError) {
|
||||
item->_status = SyncFileItem::NormalError;
|
||||
//item->_instruction = CSYNC_INSTRUCTION_ERROR;
|
||||
item->_errorString = tr("Filename encoding is not valid");
|
||||
}
|
||||
|
||||
bool isDirectory = file->type == ItemTypeDirectory;
|
||||
|
||||
|
|
Loading…
Reference in a new issue