[libgsf] zip: Fix zip directory record problem. [#614968]
- From: Morten Welinder <mortenw src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [libgsf] zip: Fix zip directory record problem. [#614968]
- Date: Tue, 6 Apr 2010 18:13:21 +0000 (UTC)
commit 0a2e93f6b302e1836c727f1b13ec62cc0ae7efa2
Author: Morten Welinder <terra gnome org>
Date: Tue Apr 6 14:10:55 2010 -0400
zip: Fix zip directory record problem. [#614968]
ChangeLog | 9 +++++++++
NEWS | 3 +++
gsf/gsf-infile-zip.c | 4 +++-
gsf/gsf-outfile-zip.c | 17 ++++++++++++-----
gsf/gsf-zip-impl.h | 1 +
5 files changed, 28 insertions(+), 6 deletions(-)
---
diff --git a/ChangeLog b/ChangeLog
index 5c7d471..ac555ae 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,12 @@
+2010-04-06 Morten Welinder <terra gnome org>
+
+ * gsf/gsf-outfile-zip.c (zip_header_write, zip_dirent_write): Use
+ dirent->flags for consistency. Fixes #614968.
+ (zip_dirent_update_flags): New function.
+ (zip_dirent_new_out): Deduce dirent->flags.
+
+ * gsf/gsf-infile-zip.c (zip_dirent_new_in): Read dirent->flags.
+
2010-04-05 Morten Welinder <terra gnome org>
* gsf/gsf-libxml.c (gsf_xml_out_add_cstr): Fix win32 warning about
diff --git a/NEWS b/NEWS
index f0f0138..5b08b49 100644
--- a/NEWS
+++ b/NEWS
@@ -1,5 +1,8 @@
libgsf 1.14.18
+Morten:
+ * Fix zip directory record problem. [#614968]
+
--------------------------------------------------------------------------
libgsf 1.14.17
diff --git a/gsf/gsf-infile-zip.c b/gsf/gsf-infile-zip.c
index e11a152..cba7247 100644
--- a/gsf/gsf-infile-zip.c
+++ b/gsf/gsf-infile-zip.c
@@ -191,7 +191,7 @@ zip_dirent_new_in (GsfInfileZip *zip, gsf_off_t *offset)
{ 'P', 'K', 0x01, 0x02 };
GsfZipDirent *dirent;
guint8 const *data;
- guint16 name_len, extras_len, comment_len, compr_method;
+ guint16 name_len, extras_len, comment_len, compr_method, flags;
guint32 crc32, csize, usize, off;
gchar *name;
@@ -206,6 +206,7 @@ zip_dirent_new_in (GsfInfileZip *zip, gsf_off_t *offset)
extras_len = GSF_LE_GET_GUINT16 (data + ZIP_DIRENT_EXTRAS_SIZE);
comment_len = GSF_LE_GET_GUINT16 (data + ZIP_DIRENT_COMMENT_SIZE);
+ flags = GSF_LE_GET_GUINT32 (data + ZIP_DIRENT_FLAGS);
compr_method = GSF_LE_GET_GUINT16 (data + ZIP_DIRENT_COMPR_METHOD);
crc32 = GSF_LE_GET_GUINT32 (data + ZIP_DIRENT_CRC32);
csize = GSF_LE_GET_GUINT32 (data + ZIP_DIRENT_CSIZE);
@@ -222,6 +223,7 @@ zip_dirent_new_in (GsfInfileZip *zip, gsf_off_t *offset)
dirent = gsf_zip_dirent_new ();
dirent->name = name;
+ dirent->flags = flags;
dirent->compr_method = compr_method;
dirent->crc32 = crc32;
dirent->csize = csize;
diff --git a/gsf/gsf-outfile-zip.c b/gsf/gsf-outfile-zip.c
index c7e1767..f94e262 100644
--- a/gsf/gsf-outfile-zip.c
+++ b/gsf/gsf-outfile-zip.c
@@ -157,7 +157,7 @@ zip_dirent_write (GsfOutput *sink, GsfZipDirent *dirent)
memcpy (buf, dirent_signature, sizeof dirent_signature);
GSF_LE_SET_GUINT16 (buf + ZIP_DIRENT_ENCODER, 0x317); /* Unix */
GSF_LE_SET_GUINT16 (buf + ZIP_DIRENT_EXTRACT, 0x14);
- GSF_LE_SET_GUINT16 (buf + ZIP_DIRENT_FLAGS, 0x08);
+ GSF_LE_SET_GUINT16 (buf + ZIP_DIRENT_FLAGS, dirent->flags);
GSF_LE_SET_GUINT16 (buf + ZIP_DIRENT_COMPR_METHOD,
dirent->compr_method);
GSF_LE_SET_GUINT32 (buf + ZIP_DIRENT_DOSTIME, dirent->dostime);
@@ -275,6 +275,15 @@ zip_time_make (time_t t)
return ztime;
}
+static void
+zip_dirent_update_flags (GsfZipDirent *dirent)
+{
+ if (dirent->compr_method == GSF_ZIP_STORED)
+ dirent->flags &= ~8;
+ else
+ dirent->flags |= 8;
+}
+
static GsfZipDirent*
zip_dirent_new_out (GsfOutfileZip *zip)
{
@@ -282,6 +291,7 @@ zip_dirent_new_out (GsfOutfileZip *zip)
dirent->name = stream_name_build (zip);
dirent->compr_method = zip->compression_method;
dirent->dostime = zip_time_make (time (NULL));
+ zip_dirent_update_flags (dirent);
return dirent;
}
@@ -292,7 +302,6 @@ zip_header_write (GsfOutfileZip *zip)
{ 'P', 'K', 0x03, 0x04 };
guint8 hbuf[ZIP_HEADER_SIZE];
GsfZipDirent *dirent = zip->vdir->dirent;
- guint16 flags = 0;
char *name = dirent->name;
int nlen = strlen (name);
gboolean ret;
@@ -300,9 +309,7 @@ zip_header_write (GsfOutfileZip *zip)
memset (hbuf, 0, sizeof hbuf);
memcpy (hbuf, header_signature, sizeof header_signature);
GSF_LE_SET_GUINT16 (hbuf + ZIP_HEADER_VERSION, 0x14);
- if (dirent->compr_method == GSF_ZIP_DEFLATED)
- flags = 0x08;
- GSF_LE_SET_GUINT16 (hbuf + ZIP_HEADER_FLAGS, flags);
+ GSF_LE_SET_GUINT16 (hbuf + ZIP_HEADER_FLAGS, dirent->flags);
GSF_LE_SET_GUINT16 (hbuf + ZIP_HEADER_COMP_METHOD,
dirent->compr_method);
GSF_LE_SET_GUINT32 (hbuf + ZIP_HEADER_TIME, dirent->dostime);
diff --git a/gsf/gsf-zip-impl.h b/gsf/gsf-zip-impl.h
index 5e89f47..d36daa8 100644
--- a/gsf/gsf-zip-impl.h
+++ b/gsf/gsf-zip-impl.h
@@ -88,6 +88,7 @@ G_BEGIN_DECLS
typedef struct {
char *name;
+ guint16 flags;
GsfZipCompressionMethod compr_method;
guint32 crc32;
size_t csize;
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]