@@ -177,7 +177,7 @@ QJsonObject getArchiveEntryInformation(archive_entry* entry, bool bExcluded) {
177177#if (QT_VERSION >= QT_VERSION_CHECK(5, 8, 0))
178178 QDateTime::fromSecsSinceEpoch (lastAccessT)
179179#else
180- QDateTime::fromTime_t (lastAccessT)
180+ QDateTime::fromTime_t (lastAccessT)
181181#endif
182182 )
183183 .toString (Qt::ISODate)));
@@ -759,32 +759,33 @@ short ExtractorPrivate::extract() {
759759 return ArchiveWriteError;
760760 }
761761 }
762- for (;;) {
763- if (m_CurrentArchiveEntry) {
764- err = writeData (m_CurrentArchiveEntry);
765- if (err == OperationPaused) {
766- return err;
767- }
768- if (err) { // NoError = 0
769- m_ArchiveRead.clear ();
770- m_ArchiveWrite.clear ();
771- return err;
772- }
773- ++n_ProcessedEntries;
774-
775- // Report final progress signal after extracting the file fully.
776- if (n_BytesTotal > 0 && n_TotalEntries > 0 ) {
777- emit progress (archive_entry_pathname (m_CurrentArchiveEntry),
778- n_ProcessedEntries, n_TotalEntries, n_BytesProcessed,
779- n_BytesTotal);
780- } else {
781- emit progress (archive_entry_pathname (m_CurrentArchiveEntry), 1 , 1 , 1 ,
782- 1 );
783- }
784762
785- archive_entry_clear (m_CurrentArchiveEntry);
786- m_CurrentArchiveEntry = nullptr ;
763+ if (m_CurrentArchiveEntry) {
764+ err = writeData (m_CurrentArchiveEntry);
765+ if (err == OperationPaused) {
766+ return err;
767+ }
768+ if (err) { // NoError = 0
769+ m_ArchiveRead.clear ();
770+ m_ArchiveWrite.clear ();
771+ return err;
772+ }
773+ ++n_ProcessedEntries;
774+
775+ // Report final progress signal after extracting the file fully.
776+ if (n_BytesTotal > 0 && n_TotalEntries > 0 ) {
777+ emit progress (archive_entry_pathname (m_CurrentArchiveEntry),
778+ n_ProcessedEntries, n_TotalEntries, n_BytesProcessed,
779+ n_BytesTotal);
780+ } else {
781+ emit progress (archive_entry_pathname (m_CurrentArchiveEntry), 1 , 1 , 1 , 1 );
787782 }
783+
784+ archive_entry_clear (m_CurrentArchiveEntry);
785+ m_CurrentArchiveEntry = nullptr ;
786+ }
787+
788+ for (;;) {
788789 ret = archive_read_next_header (m_ArchiveRead.data (), &entry);
789790 if (ret == ARCHIVE_EOF) {
790791 break ;
@@ -853,14 +854,14 @@ short ExtractorPrivate::writeData(struct archive_entry* entry) {
853854
854855 if (!b_MemoryMode && b_RawMode && !m_RawOutputFilename.isEmpty ()) {
855856 const auto & path = (QFileInfo (archive_entry_pathname (entry)).path () +
856- QString::fromLatin1 (" /" ) + m_RawOutputFilename)
857+ QString::fromUtf8 (" /" ) + m_RawOutputFilename)
857858 .toStdWString ();
858859 archive_entry_copy_pathname_w (entry, path.c_str ());
859860 }
860861 if (b_hasBasePath) {
861862 const auto & relativePath =
862863 m_basePath
863- .relativeFilePath (QString::fromLatin1 (" /" ) +
864+ .relativeFilePath (QString::fromUtf8 (" /" ) +
864865 archive_entry_pathname (entry))
865866 .toStdWString ();
866867 if (relativePath == L" ." ) { // Root directory
@@ -885,6 +886,23 @@ short ExtractorPrivate::writeData(struct archive_entry* entry) {
885886#endif
886887 if (m_CurrentArchiveEntry != entry) {
887888 if (!b_MemoryMode) {
889+ // UTF-8 in archive entry messes up when extracting under Windows
890+ // when UTF-8 is not set, to fix this we first get the archive
891+ // entry pathname in raw bytes then convert it to wide characters
892+ // and set it has the new pathname which should make libarchive
893+ // handle it better.
894+
895+ // Get current pathname
896+ auto ptname_cstr = archive_entry_pathname (entry);
897+
898+ // Check if UTF-8
899+ if (isUTF8 (ptname_cstr)) {
900+ auto ptname = QString::fromUtf8 (ptname_cstr);
901+
902+ auto wstr = ptname.toStdWString ();
903+ archive_entry_copy_pathname_w (entry, wstr.c_str ());
904+ }
905+
888906 ret = archive_write_header (m_ArchiveWrite.data (), entry);
889907 } else {
890908 currentNode.setFileInformation (getArchiveEntryInformation (entry, false ));
0 commit comments