Skip to content
Permalink
Browse files

Fix loss of project when saving to QGZ format and path contains non-a…

…scii chars

Fixes #19567
  • Loading branch information
nyalldawson committed Jan 22, 2019
1 parent d3924ad commit 7d7462c33334a501167813d720fb2589d3c579ec
@@ -67,7 +67,8 @@ bool QgsZipUtils::unzip( const QString &zipFilename, const QString &dir, QString
}

int rc = 0;
struct zip *z = zip_open( zipFilename.toStdString().c_str(), ZIP_CHECKCONS, &rc );
const QByteArray fileNamePtr = zipFilename.toUtf8();
struct zip *z = zip_open( fileNamePtr.constData(), ZIP_CHECKCONS, &rc );

if ( rc == ZIP_ER_OK && z )
{
@@ -92,7 +93,7 @@ bool QgsZipUtils::unzip( const QString &zipFilename, const QString &dir, QString
if ( !newFile.absoluteDir().exists() )
{
if ( !QDir( dir ).mkpath( newFile.absolutePath() ) )
QgsMessageLog::logMessage( QString( "Failed to create a subdirectory %1/%2" ).arg( dir ).arg( fileName ) );
QgsMessageLog::logMessage( QStringLiteral( "Failed to create a subdirectory %1/%2" ).arg( dir ).arg( fileName ) );
}

QFile outFile( newFile.absoluteFilePath() );
@@ -146,7 +147,8 @@ bool QgsZipUtils::zip( const QString &zipFilename, const QStringList &files )
}

int rc = 0;
struct zip *z = zip_open( zipFilename.toStdString().c_str(), ZIP_CREATE, &rc );
const QByteArray fileNamePtr = zipFilename.toUtf8();
struct zip *z = zip_open( fileNamePtr.constData(), ZIP_CREATE, &rc );

if ( rc == ZIP_ER_OK && z )
{
@@ -161,25 +163,27 @@ bool QgsZipUtils::zip( const QString &zipFilename, const QStringList &files )
return false;
}

zip_source *src = zip_source_file( z, file.toStdString().c_str(), 0, 0 );
const QByteArray fileNamePtr = file.toUtf8();
zip_source *src = zip_source_file( z, fileNamePtr.constData(), 0, 0 );
if ( src )
{
const QByteArray fileInfoPtr = fileInfo.fileName().toUtf8();
#if LIBZIP_VERSION_MAJOR < 1
int rc = ( int ) zip_add( z, fileInfo.fileName().toStdString().c_str(), src );
int rc = ( int ) zip_add( z, fileInfoPtr.constData(), src );
#else
int rc = ( int ) zip_file_add( z, fileInfo.fileName().toStdString().c_str(), src, 0 );
int rc = ( int ) zip_file_add( z, fileInfoPtr.constData(), src, 0 );
#endif
if ( rc == -1 )
{
QString err = QObject::tr( "Error adding file: '%1'" ).arg( zip_strerror( z ) );
QString err = QObject::tr( "Error adding file '%1': %2" ).arg( file, zip_strerror( z ) );
QgsMessageLog::logMessage( err, QStringLiteral( "QgsZipUtils" ) );
zip_close( z );
return false;
}
}
else
{
QString err = QObject::tr( "Error creating data source: '%1'" ).arg( zip_strerror( z ) );
QString err = QObject::tr( "Error creating data source '%1': %2" ).arg( file, zip_strerror( z ) );
QgsMessageLog::logMessage( err, QStringLiteral( "QgsZipUtils" ) );
zip_close( z );
return false;
@@ -190,7 +194,7 @@ bool QgsZipUtils::zip( const QString &zipFilename, const QStringList &files )
}
else
{
QString err = QObject::tr( "Error creating zip archive: '%1'" ).arg( zip_strerror( z ) );
QString err = QObject::tr( "Error creating zip archive '%1': %2" ).arg( zipFilename, zip_strerror( z ) );
QgsMessageLog::logMessage( err, QStringLiteral( "QgsZipUtils" ) );
return false;
}
@@ -33,6 +33,8 @@ class TestQgsZipUtils: public QObject

void unzipWithSubdirs();
void unzipWithSubdirs2();
void specialChars();
void testZip();

private:
void genericTest( QString zipName, int expectedEntries, bool includeFolders, const QStringList &testFileNames );
@@ -83,6 +85,38 @@ void TestQgsZipUtils::unzipWithSubdirs2()
genericTest( QString( "diff_structured" ), 3, false, QStringList() << "/subfolder/3.txt" );
}

void TestQgsZipUtils::specialChars()
{
genericTest( "Chars èêæýì", 1, false, QStringList() << "/èêæýì.txt" );
}

void TestQgsZipUtils::testZip()
{
QString txtFile = QString( TEST_DATA_DIR ) + "/zip/aæýì.txt";

QString zipDirPath = QDir::tempPath() + "/test_special_chars æì";
QStringList files;

// Create a root folder otherwise nothing is unzipped
QDir dir( zipDirPath );
if ( dir.exists( zipDirPath ) )
{
dir.remove( zipDirPath );
QFile::remove( zipDirPath + "/special_zip æì.zip" );
QFile::remove( zipDirPath + "/aæýì.txt" );
}
else
{
dir.mkdir( zipDirPath );
}

QVERIFY( QgsZipUtils::zip( zipDirPath + "/special_zip æì.zip", QStringList() << txtFile ) );
QVERIFY( QgsZipUtils::unzip( zipDirPath + "/special_zip æì.zip", zipDirPath, files ) );
QCOMPARE( files.count(), 1 );
QCOMPARE( files.at( 0 ), zipDirPath + "/aæýì.txt" );
QVERIFY( QFile::exists( zipDirPath + "/aæýì.txt" ) );
}

/**
* \brief TestQgsZipUtils::genericTest
* \param zipName File to unzip
@@ -92,11 +126,11 @@ void TestQgsZipUtils::unzipWithSubdirs2()
*/
void TestQgsZipUtils::genericTest( QString zipName, int expectedEntries, bool includeFolders, const QStringList &testFileNames )
{
QFile zipFile( QString( TEST_DATA_DIR ) + QString( "/zip/%1.zip" ).arg( zipName ) );
QFile zipFile( QString( TEST_DATA_DIR ) + QStringLiteral( "/zip/%1.zip" ).arg( zipName ) );
QVERIFY( zipFile.exists() );

QFileInfo fileInfo( zipFile );
QString unzipDirPath = QDir::tempPath() + zipName;
QString unzipDirPath = QDir::tempPath() + '/' + zipName;
QStringList files;

// Create a root folder otherwise nothing is unzipped
Binary file not shown.
No changes.

0 comments on commit 7d7462c

Please sign in to comment.
You can’t perform that action at this time.