Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
Utilities
Ark
Commits
2bb61221
Commit
2bb61221
authored
Feb 20, 2021
by
João Silva
Committed by
Elvis Angelaccio
Apr 05, 2021
Browse files
Support for zip files using backslashes as the path separator.
parent
1e97929e
Changes
2
Hide whitespace changes
Inline
Side-by-side
plugins/libzipplugin/libzipplugin.cpp
View file @
2bb61221
...
...
@@ -55,6 +55,7 @@ LibzipPlugin::LibzipPlugin(QObject *parent, const QVariantList & args)
,
m_overwriteAll
(
false
)
,
m_skipAll
(
false
)
,
m_listAfterAdd
(
false
)
,
m_backslashedZip
(
false
)
{
qCDebug
(
ARK
)
<<
"Initializing libzip plugin"
;
}
...
...
@@ -199,9 +200,9 @@ bool LibzipPlugin::writeEntry(zip_t *archive, const QString &file, const Archive
QByteArray
destFile
;
if
(
destination
)
{
destFile
=
QString
(
destination
->
fullPath
()
+
file
).
toUtf8
();
destFile
=
fromUnixSeparator
(
QString
(
destination
->
fullPath
()
+
file
)
)
.
toUtf8
();
}
else
{
destFile
=
file
.
toUtf8
();
destFile
=
fromUnixSeparator
(
file
)
.
toUtf8
();
}
qlonglong
index
;
...
...
@@ -285,9 +286,10 @@ bool LibzipPlugin::emitEntryForIndex(zip_t *archive, qlonglong index)
}
auto
e
=
new
Archive
::
Entry
();
auto
name
=
toUnixSeparator
(
QString
::
fromUtf8
(
statBuffer
.
name
));
if
(
statBuffer
.
valid
&
ZIP_STAT_NAME
)
{
e
->
setFullPath
(
QString
::
fromUtf8
(
statBuffer
.
name
)
)
;
e
->
setFullPath
(
name
);
}
if
(
e
->
fullPath
(
PathFormat
::
WithTrailingSlash
).
endsWith
(
QDir
::
separator
()))
{
...
...
@@ -366,8 +368,8 @@ bool LibzipPlugin::emitEntryForIndex(zip_t *archive, qlonglong index)
zip_uint8_t
opsys
;
zip_uint32_t
attributes
;
if
(
zip_file_get_external_attributes
(
archive
,
index
,
ZIP_FL_UNCHANGED
,
&
opsys
,
&
attributes
)
==
-
1
)
{
qCCritical
(
ARK
)
<<
"Could not read external attributes for entry:"
<<
QString
::
fromUtf8
(
statBuffer
.
name
)
;
Q_EMIT
error
(
xi18n
(
"Failed to read metadata for entry: %1"
,
QString
::
fromUtf8
(
statBuffer
.
name
))
)
;
qCCritical
(
ARK
)
<<
"Could not read external attributes for entry:"
<<
name
;
Q_EMIT
error
(
xi18n
(
"Failed to read metadata for entry: %1"
,
name
));
return
false
;
}
...
...
@@ -408,7 +410,7 @@ bool LibzipPlugin::deleteFiles(const QVector<Archive::Entry*> &files)
break
;
}
const
qlonglong
index
=
zip_name_locate
(
archive
,
e
->
fullPath
().
toUtf8
().
constData
(),
ZIP_FL_ENC_GUESS
);
const
qlonglong
index
=
zip_name_locate
(
archive
,
fromUnixSeparator
(
e
->
fullPath
()
)
.
toUtf8
().
constData
(),
ZIP_FL_ENC_GUESS
);
if
(
index
==
-
1
)
{
qCCritical
(
ARK
)
<<
"Could not find entry to delete:"
<<
e
->
fullPath
();
Q_EMIT
error
(
xi18n
(
"Failed to delete entry: %1"
,
e
->
fullPath
()));
...
...
@@ -484,8 +486,10 @@ bool LibzipPlugin::testArchive()
// Get statistic for entry. Used to get entry size.
zip_stat_t
statBuffer
;
if
(
zip_stat_index
(
archive
,
i
,
0
,
&
statBuffer
)
!=
0
)
{
qCCritical
(
ARK
)
<<
"Failed to read stat for"
<<
statBuffer
.
name
;
int
stat_index
=
zip_stat_index
(
archive
,
i
,
0
,
&
statBuffer
);
auto
name
=
toUnixSeparator
(
QString
::
fromUtf8
(
statBuffer
.
name
));
if
(
stat_index
!=
0
)
{
qCCritical
(
ARK
)
<<
"Failed to read stat for"
<<
name
;
return
false
;
}
...
...
@@ -493,11 +497,11 @@ bool LibzipPlugin::testArchive()
std
::
unique_ptr
<
uchar
[]
>
buf
(
new
uchar
[
statBuffer
.
size
]);
const
int
len
=
zip_fread
(
zipFile
.
get
(),
buf
.
get
(),
statBuffer
.
size
);
if
(
len
==
-
1
||
uint
(
len
)
!=
statBuffer
.
size
)
{
qCCritical
(
ARK
)
<<
"Failed to read data for"
<<
statBuffer
.
name
;
qCCritical
(
ARK
)
<<
"Failed to read data for"
<<
name
;
return
false
;
}
if
(
statBuffer
.
crc
!=
crc32
(
0
,
&
buf
.
get
()[
0
],
len
))
{
qCCritical
(
ARK
)
<<
"CRC check failed for"
<<
statBuffer
.
name
;
qCCritical
(
ARK
)
<<
"CRC check failed for"
<<
name
;
return
false
;
}
...
...
@@ -552,7 +556,7 @@ bool LibzipPlugin::extractFiles(const QVector<Archive::Entry*> &files, const QSt
break
;
}
if
(
!
extractEntry
(
archive
,
QDir
::
fromNative
Separator
s
(
QString
::
fromUtf8
(
zip_get_name
(
archive
,
i
,
ZIP_FL_ENC_GUESS
))),
toUnix
Separator
(
QString
::
fromUtf8
(
zip_get_name
(
archive
,
i
,
ZIP_FL_ENC_GUESS
))),
QString
(),
destinationDirectory
,
options
.
preservePaths
(),
...
...
@@ -640,7 +644,7 @@ bool LibzipPlugin::extractEntry(zip_t *archive, const QString &entry, const QStr
// Get statistic for entry. Used to get entry size and mtime.
zip_stat_t
statBuffer
;
if
(
zip_stat
(
archive
,
entry
.
toUtf8
().
constData
(),
0
,
&
statBuffer
)
!=
0
)
{
if
(
zip_stat
(
archive
,
fromUnixSeparator
(
entry
)
.
toUtf8
().
constData
(),
0
,
&
statBuffer
)
!=
0
)
{
if
(
isDirectory
&&
zip_error_code_zip
(
zip_get_error
(
archive
))
==
ZIP_ER_NOENT
)
{
qCWarning
(
ARK
)
<<
"Skipping folder without entry:"
<<
entry
;
return
true
;
...
...
@@ -686,7 +690,7 @@ bool LibzipPlugin::extractEntry(zip_t *archive, const QString &entry, const QStr
std
::
unique_ptr
<
zip_file
,
decltype
(
&
zip_fclose
)
>
zipFile
{
nullptr
,
&
zip_fclose
};
bool
firstTry
=
true
;
while
(
!
zipFile
)
{
zipFile
.
reset
(
zip_fopen
(
archive
,
entry
.
toUtf8
().
constData
(),
0
));
zipFile
.
reset
(
zip_fopen
(
archive
,
fromUnixSeparator
(
entry
)
.
toUtf8
().
constData
(),
0
));
if
(
zipFile
)
{
break
;
}
else
if
(
zip_error_code_zip
(
zip_get_error
(
archive
))
==
ZIP_ER_NOPASSWD
||
...
...
@@ -740,7 +744,7 @@ bool LibzipPlugin::extractEntry(zip_t *archive, const QString &entry, const QStr
sum
+=
readBytes
;
}
const
auto
index
=
zip_name_locate
(
archive
,
entry
.
toUtf8
().
constData
(),
ZIP_FL_ENC_GUESS
);
const
auto
index
=
zip_name_locate
(
archive
,
fromUnixSeparator
(
entry
)
.
toUtf8
().
constData
(),
ZIP_FL_ENC_GUESS
);
if
(
index
==
-
1
)
{
qCCritical
(
ARK
)
<<
"Could not locate entry:"
<<
entry
;
Q_EMIT
error
(
xi18n
(
"Failed to locate entry: %1"
,
entry
));
...
...
@@ -968,6 +972,22 @@ QString LibzipPlugin::permissionsToString(mode_t perm)
return
modeval
;
}
QString
LibzipPlugin
::
fromUnixSeparator
(
const
QString
&
path
)
{
if
(
!
m_backslashedZip
)
{
return
path
;
}
return
QString
(
path
).
replace
(
QLatin1Char
(
'/'
),
QLatin1Char
(
'\\'
));
}
QString
LibzipPlugin
::
toUnixSeparator
(
const
QString
&
path
)
{
if
(
!
path
.
contains
(
QLatin1Char
(
'\\'
)))
{
return
path
;
}
m_backslashedZip
=
true
;
return
QString
(
path
).
replace
(
QLatin1Char
(
'\\'
),
QLatin1Char
(
'/'
));
}
bool
LibzipPlugin
::
hasBatchExtractionProgress
()
const
{
...
...
plugins/libzipplugin/libzipplugin.h
View file @
2bb61221
...
...
@@ -59,12 +59,15 @@ private:
bool
emitEntryForIndex
(
zip_t
*
archive
,
qlonglong
index
);
void
emitProgress
(
double
percentage
);
QString
permissionsToString
(
mode_t
perm
);
QString
fromUnixSeparator
(
const
QString
&
path
);
QString
toUnixSeparator
(
const
QString
&
path
);
static
void
progressCallback
(
zip_t
*
,
double
progress
,
void
*
that
);
QVector
<
Archive
::
Entry
*>
m_emittedEntries
;
bool
m_overwriteAll
;
bool
m_skipAll
;
bool
m_listAfterAdd
;
bool
m_backslashedZip
;
};
#endif // LIBZIPPLUGIN_H
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment