Add encoding support to zip_{get,set}_{file,archive}_comment,
and handle interaction in zip_{get,set}_name.
Set general purpose bit flag 11 when writing out UTF-8 names.
Add new error type ZIP_ER_ENCMISMATCH for the case where the
encoding of file name and file comment don't match.
Document changes and workaround for ZIP_ER_ENCMISMATCH.
Update copyright years.
--HG--
branch : HEAD
diff --git a/lib/zip_get_file_comment.c b/lib/zip_get_file_comment.c
index aef0a7a..fc8c1ae 100644
--- a/lib/zip_get_file_comment.c
+++ b/lib/zip_get_file_comment.c
@@ -1,6 +1,6 @@
/*
zip_get_file_comment.c -- get file comment
- Copyright (C) 2006-2007 Dieter Baron and Thomas Klausner
+ Copyright (C) 2006-2012 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <libzip@nih.at>
@@ -33,6 +33,8 @@
+#include <string.h>
+
#include "zipint.h"
@@ -40,12 +42,18 @@
ZIP_EXTERN const char *
zip_get_file_comment(struct zip *za, zip_uint64_t idx, int *lenp, int flags)
{
+ const char *ret;
+
if (idx >= za->nentry) {
_zip_error_set(&za->error, ZIP_ER_INVAL, 0);
return NULL;
}
if ((flags & ZIP_FL_UNCHANGED) || (za->entry[idx].changes.valid & ZIP_DIRENT_COMMENT) == 0) {
+ if (za->cdir == NULL) {
+ _zip_error_set(&za->error, ZIP_ER_NOENT, 0);
+ return NULL;
+ }
if (idx >= za->cdir->nentry) {
_zip_error_set(&za->error, ZIP_ER_INVAL, 0);
return NULL;
@@ -53,9 +61,32 @@
if (lenp != NULL)
*lenp = za->cdir->entry[idx].settable.comment_len;
- return za->cdir->entry[idx].settable.comment;
+ ret = za->cdir->entry[idx].settable.comment;
+
+ if (flags & ZIP_FL_NAME_RAW)
+ return ret;
+
+ /* file comment already is UTF-8? */
+ if (za->cdir->entry[idx].bitflags & ZIP_GPBF_ENCODING_UTF_8)
+ return ret;
+
+ /* undeclared, start guessing */
+ if (za->cdir->entry[idx].fc_type == ZIP_ENCODING_UNKNOWN)
+ za->cdir->entry[idx].fc_type = _zip_guess_encoding(ret, za->cdir->entry[idx].settable.comment_len);
+
+ if (((flags & ZIP_FL_NAME_STRICT) && (za->cdir->entry[idx].fc_type != ZIP_ENCODING_ASCII))
+ || (za->cdir->entry[idx].fc_type == ZIP_ENCODING_CP437)) {
+ if (za->cdir->entry[idx].comment_converted == NULL)
+ za->cdir->entry[idx].comment_converted = _zip_cp437_to_utf8(ret, za->cdir->entry[idx].settable.comment_len, &za->error);
+ ret = za->cdir->entry[idx].comment_converted;
+ if (lenp != NULL)
+ *lenp = strlen(ret);
+ }
+
+ return ret;
}
+ /* already UTF-8, no conversion necessary */
if (lenp != NULL)
*lenp = za->entry[idx].changes.comment_len;
return za->entry[idx].changes.comment;