don't allow duplicate names in archive
--HG--
branch : HEAD
diff --git a/ChangeLog b/ChangeLog
index d9255b5..5896ccd 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,14 @@
+2004-11-30 Dieter Baron <dillo@danbala.tuwien.ac.at>
+
+ * lib/zip_name_locate.c (_zip_name_locate): new function.
+ (zip_name_locate): move actual name lookup to _zip_name_locate.
+ * lib/zip_set_name.c (_zip_set_name): don't allow duplicate names
+ in archive; return error if name is NULL.
+ * lib/zip_replace.c (_zip_replace): don't call _zip_set_name when
+ name is NULL.
+ * lib/zip_get_name.c (zip_get_name): fix when called with
+ partially initialized entry.
+
2004-11-30 Thomas Klausner <wiz@danbala.tuwien.ac.at>
* zipint.h: Include zip.h; add zlib.h.
diff --git a/TODO b/TODO
index 6352a01..6bf93b3 100644
--- a/TODO
+++ b/TODO
@@ -11,18 +11,16 @@
* zipcmp.c: In function `compare_zip':
* zipcmp.c:189: warning: passing arg 3 of `compare_list' from incompatible pointer type
* what is ZIP_CMD_CLOSE good for; check callers
-* man page cleanup: zf/za -> archive; "global variable zip_err"
-* zipint.h should include zip.h?
-* sort zipint.h contents
+* man page cleanup: "global variable zip_err"
* documentation:
zip_error_sys_type zip_file_get_error zip_get_error
-* don't allow the same filename twice in a zip (when adding/replacing)
* regression tests
* code review
* README
* update code for new API
* fix XXX in man/
* fix XXX in lib?
+* fix XXX in ChangeLog!
------------------------------------------------ others
* zip_commit
* zip_replace_zip: allow rewinding
diff --git a/lib/zip_get_name.c b/lib/zip_get_name.c
index 34f5f3a..293eb3e 100644
--- a/lib/zip_get_name.c
+++ b/lib/zip_get_name.c
@@ -1,5 +1,5 @@
/*
- $NiH: zip_get_name.c,v 1.9 2004/11/17 21:55:11 wiz Exp $
+ $NiH: zip_get_name.c,v 1.10 2004/11/18 17:11:21 wiz Exp $
zip_get_name.c -- get filename for a file in zip file
Copyright (C) 1999, 2003, 2004 Dieter Baron and Thomas Klausner
@@ -51,5 +51,9 @@
if (za->entry[idx].ch_filename)
return za->entry[idx].ch_filename;
+ /* newly added (partially filled) entry */
+ if (za->cdir == NULL || idx >= za->cdir->nentry)
+ return NULL;
+
return za->cdir->entry[idx].filename;
}
diff --git a/lib/zip_name_locate.c b/lib/zip_name_locate.c
index 7dc8318..cc8bbc3 100644
--- a/lib/zip_name_locate.c
+++ b/lib/zip_name_locate.c
@@ -1,5 +1,5 @@
/*
- $NiH: zip_name_locate.c,v 1.14 2004/11/17 21:55:12 wiz Exp $
+ $NiH: zip_name_locate.c,v 1.15 2004/11/18 15:04:05 wiz Exp $
zip_name_locate.c -- get index by name
Copyright (C) 1999, 2003, 2004 Dieter Baron and Thomas Klausner
@@ -45,15 +45,30 @@
int
zip_name_locate(struct zip *za, const char *fname, int flags)
{
- int (*cmp)(const char *, const char *);
- const char *fn, *p, *q;
- int i, n;
-
+ int i;
+
if (fname == NULL) {
_zip_error_set(&za->error, ZIP_ER_INVAL, 0);
return -1;
}
+ i = _zip_name_locate(za, fname, flags);
+
+ if (i == -1)
+ _zip_error_set(&za->error, ZIP_ER_NOENT, 0);
+
+ return i;
+}
+
+
+
+int
+_zip_name_locate(struct zip *za, const char *fname, int flags)
+{
+ int (*cmp)(const char *, const char *);
+ const char *fn, *p, *q;
+ int i, n;
+
cmp = (flags & ZIP_FL_NOCASE) ? strcasecmp : strcmp;
n = (flags & ZIP_FL_UNCHANGED) ? za->cdir->nentry : za->nentry;
@@ -62,6 +77,10 @@
fn = za->cdir->entry[i].filename;
else
fn = zip_get_name(za, i);
+
+ /* newly added (partially filled) entry */
+ if (fn == NULL)
+ continue;
if (flags & ZIP_FL_NODIR) {
/* XXX: is this correct? */
@@ -79,6 +98,5 @@
return i;
}
- _zip_error_set(&za->error, ZIP_ER_NOENT, 0);
return -1;
}
diff --git a/lib/zip_rename.c b/lib/zip_rename.c
index ab6b669..7e75d2b 100644
--- a/lib/zip_rename.c
+++ b/lib/zip_rename.c
@@ -1,5 +1,5 @@
/*
- $NiH: zip_rename.c,v 1.13 2004/11/17 21:55:12 wiz Exp $
+ $NiH: zip_rename.c,v 1.14 2004/11/18 17:11:22 wiz Exp $
zip_rename.c -- rename file in zip archive
Copyright (C) 1999, 2003, 2004 Dieter Baron and Thomas Klausner
@@ -48,11 +48,5 @@
return -1;
}
- /* XXX: move this to _zip_set_name */
- if (za->entry[idx].state == ZIP_ST_UNCHANGED)
- za->entry[idx].state = ZIP_ST_RENAMED;
-
- _zip_set_name(za, idx, name);
-
- return 0;
+ return _zip_set_name(za, idx, name);
}
diff --git a/lib/zip_replace.c b/lib/zip_replace.c
index 595271d..92929aa 100644
--- a/lib/zip_replace.c
+++ b/lib/zip_replace.c
@@ -1,5 +1,5 @@
/*
- $NiH: zip_replace.c,v 1.17 2004/11/18 15:04:05 wiz Exp $
+ $NiH: zip_replace.c,v 1.18 2004/11/30 21:42:23 wiz Exp $
zip_replace.c -- replace file via callback function
Copyright (C) 1999, 2003, 2004 Dieter Baron and Thomas Klausner
@@ -67,7 +67,7 @@
_zip_unchange_data(za->entry+idx);
- if (_zip_set_name(za, idx, name) != 0)
+ if (name && _zip_set_name(za, idx, name) != 0)
return -1;
za->entry[idx].state = ((za->cdir == NULL || idx >= za->cdir->nentry)
diff --git a/lib/zip_set_name.c b/lib/zip_set_name.c
index ac5f930..d0bf1a5 100644
--- a/lib/zip_set_name.c
+++ b/lib/zip_set_name.c
@@ -1,5 +1,5 @@
/*
- $NiH: zip_set_name.c,v 1.13 2004/11/17 21:55:13 wiz Exp $
+ $NiH: zip_set_name.c,v 1.14 2004/11/18 17:11:22 wiz Exp $
zip_set_name.c -- rename helper function
Copyright (C) 1999, 2003, 2004 Dieter Baron and Thomas Klausner
@@ -47,20 +47,26 @@
{
char *s;
- if (idx < 0 || idx >= za->nentry) {
+ if (idx < 0 || idx >= za->nentry || name == NULL) {
_zip_error_set(&za->error, ZIP_ER_INVAL, 0);
return -1;
}
- if (name != NULL) {
- if ((s=strdup(name)) == NULL) {
- _zip_error_set(&za->error, ZIP_ER_MEMORY, 0);
- return -1;
- }
-
- free(za->entry[idx].ch_filename);
- za->entry[idx].ch_filename = s;
+ if (_zip_name_locate(za, name, 0) != -1) {
+ _zip_error_set(&za->error, ZIP_ER_EXISTS, 0);
+ return -1;
}
+ if ((s=strdup(name)) == NULL) {
+ _zip_error_set(&za->error, ZIP_ER_MEMORY, 0);
+ return -1;
+ }
+
+ if (za->entry[idx].state == ZIP_ST_UNCHANGED)
+ za->entry[idx].state = ZIP_ST_RENAMED;
+
+ free(za->entry[idx].ch_filename);
+ za->entry[idx].ch_filename = s;
+
return 0;
}
diff --git a/lib/zipint.h b/lib/zipint.h
index 0dcc044..79efc00 100644
--- a/lib/zipint.h
+++ b/lib/zipint.h
@@ -2,7 +2,7 @@
#define _HAD_ZIPINT_H
/*
- $NiH: zipint.h,v 1.32 2004/11/30 21:42:24 wiz Exp $
+ $NiH: zipint.h,v 1.33 2004/11/30 21:51:30 wiz Exp $
zipint.h -- internal declarations.
Copyright (C) 1999, 2003, 2004 Dieter Baron and Thomas Klausner
@@ -199,6 +199,7 @@
void _zip_free(struct zip *);
int _zip_local_header_read(struct zip *, int);
void *_zip_memdup(const void *, int);
+int _zip_name_locate(struct zip *, const char *, int);
struct zip *_zip_new(struct zip_error *);
unsigned short _zip_read2(unsigned char **);
unsigned int _zip_read4(unsigned char **);