Exemple #1
0
void
zip_discard(zip_t *za)
{
    zip_uint64_t i;

    if (za == NULL)
	return;

    if (za->src) {
	zip_source_close(za->src);
	zip_source_free(za->src);
    }

    free(za->default_password);
    _zip_string_free(za->comment_orig);
    _zip_string_free(za->comment_changes);

    if (za->entry) {
	for (i=0; i<za->nentry; i++)
	    _zip_entry_finalize(za->entry+i);
	free(za->entry);
    }

    for (i=0; i<za->nopen_source; i++) {
	_zip_source_invalidate(za->open_source[i]);
    }
    free(za->open_source);

    zip_error_fini(&za->error);
    
    free(za);

    return;
}
ZIP_EXTERN int
zip_set_archive_comment(struct zip *za, const char *comment, zip_uint16_t len)
{
    struct zip_string *cstr;

    if (ZIP_IS_RDONLY(za)) {
	_zip_error_set(&za->error, ZIP_ER_RDONLY, 0);
	return -1;
    }

    if (len < 0 || len > MAXCOMLEN
	|| (len > 0 && comment == NULL)) {
	_zip_error_set(&za->error, ZIP_ER_INVAL, 0);
	return -1;
    }

    if (len > 0) {
	if ((cstr=_zip_string_new((const zip_uint8_t *)comment, len, ZIP_FL_ENC_GUESS, &za->error)) == NULL)
	    return -1;

	if (_zip_guess_encoding(cstr, ZIP_ENCODING_UNKNOWN) == ZIP_ENCODING_CP437) {
	    _zip_string_free(cstr);
	    _zip_error_set(&za->error, ZIP_ER_INVAL, 0);
	    return -1;
	}
    }
    else
	cstr = NULL;

    _zip_string_free(za->comment_changes);
    za->comment_changes = NULL;

    if (((za->comment_orig && _zip_string_equal(za->comment_orig, cstr))
	 || (za->comment_orig == NULL && cstr == NULL))) {
	_zip_string_free(cstr);
	za->comment_changed = 0;
    }
    else {
	za->comment_changes = cstr;
	za->comment_changed = 1;
    }
    
    return 0;
}
Exemple #3
0
zip_string_t *
_zip_string_new(const zip_uint8_t *raw, zip_uint16_t length, zip_flags_t flags, zip_error_t *error)
{
    zip_string_t *s;
    zip_encoding_type_t expected_encoding;
    
    if (length == 0)
	return NULL;

    switch (flags & ZIP_FL_ENCODING_ALL) {
    case ZIP_FL_ENC_GUESS:
	expected_encoding = ZIP_ENCODING_UNKNOWN;
	break;
    case ZIP_FL_ENC_UTF_8:
	expected_encoding = ZIP_ENCODING_UTF8_KNOWN;
	break;
    case ZIP_FL_ENC_CP437:
	expected_encoding = ZIP_ENCODING_CP437;
	break;
    default:
	zip_error_set(error, ZIP_ER_INVAL, 0);
	return NULL;
    }
	
    if ((s=(zip_string_t *)malloc(sizeof(*s))) == NULL) {
	zip_error_set(error, ZIP_ER_MEMORY, 0);
	return NULL;
    }

    if ((s->raw=(zip_uint8_t *)malloc((size_t)(length+1))) == NULL) {
	free(s);
	return NULL;
    }

    memcpy(s->raw, raw, length);
    s->raw[length] = '\0';
    s->length = length;
    s->encoding = ZIP_ENCODING_UNKNOWN;
    s->converted = NULL;
    s->converted_length = 0;

    if (expected_encoding != ZIP_ENCODING_UNKNOWN) {
	if (_zip_guess_encoding(s, expected_encoding) == ZIP_ENCODING_ERROR) {
	    _zip_string_free(s);
	    zip_error_set(error, ZIP_ER_INVAL, 0);
	    return NULL;
	}
    }
    
    return s;
}
Exemple #4
0
void
zip_discard(struct zip *za)
{
    zip_uint64_t i;

    if (za == NULL)
	return;

    if (za->zn)
	free(za->zn);

    if (za->zp)
	fclose(za->zp);

    free(za->default_password);
    _zip_string_free(za->comment_orig);
    _zip_string_free(za->comment_changes);

    if (za->entry) {
	for (i=0; i<za->nentry; i++)
	    _zip_entry_finalize(za->entry+i);
	free(za->entry);
    }

    for (i=0; i<za->nfile; i++) {
	if (za->file[i]->error.zip_err == ZIP_ER_OK) {
	    _zip_error_set(&za->file[i]->error, ZIP_ER_ZIPCLOSED, 0);
	    za->file[i]->za = NULL;
	}
    }

    _zip_error_fini(&za->error);
    free(za->file);
    
    free(za);

    return;
}
Exemple #5
0
int
_zip_set_name(struct zip *za, zip_uint64_t idx, const char *name, zip_flags_t flags)
{
    struct zip_entry *e;
    struct zip_string *str;
    int changed;
    zip_int64_t i;

    if (idx >= za->nentry) {
        _zip_error_set(&za->error, ZIP_ER_INVAL, 0);
        return -1;
    }

    if (ZIP_IS_RDONLY(za)) {
        _zip_error_set(&za->error, ZIP_ER_RDONLY, 0);
        return -1;
    }

    if (name && strlen(name) > 0) {
        /* XXX: check for string too long */
        if ((str=_zip_string_new((const zip_uint8_t *)name, (zip_uint16_t)strlen(name), flags, &za->error)) == NULL)
            return -1;
        if ((flags & ZIP_FL_ENCODING_ALL) == ZIP_FL_ENC_GUESS && _zip_guess_encoding(str, ZIP_ENCODING_UNKNOWN) == ZIP_ENCODING_UTF8_GUESSED)
            str->encoding = ZIP_ENCODING_UTF8_KNOWN;
    }
    else
        str = NULL;

    /* XXX: encoding flags needed for CP437? */
    if ((i=_zip_name_locate(za, name, 0, NULL)) >= 0 && (zip_uint64_t)i != idx) {
        _zip_string_free(str);
        _zip_error_set(&za->error, ZIP_ER_EXISTS, 0);
        return -1;
    }

    /* no effective name change */
    if (i>=0 && (zip_uint64_t)i == idx) {
        _zip_string_free(str);
        return 0;
    }

    e = za->entry+idx;

    if (e->changes) {
        _zip_string_free(e->changes->filename);
        e->changes->filename = NULL;
        e->changes->changed &= ~ZIP_DIRENT_FILENAME;
    }

    if (e->orig)
        changed = !_zip_string_equal(e->orig->filename, str);
    else
        changed = 1;

    if (changed) {
        if (e->changes == NULL) {
            if ((e->changes=_zip_dirent_clone(e->orig)) == NULL) {
                _zip_error_set(&za->error, ZIP_ER_MEMORY, 0);
                return -1;
            }
        }
        e->changes->filename = str;
        e->changes->changed |= ZIP_DIRENT_FILENAME;
    }
    else {
        _zip_string_free(str);
        if (e->changes && e->changes->changed == 0) {
            _zip_dirent_free(e->changes);
            e->changes = NULL;
        }
    }

    return 0;
}
ZIP_EXTERN int
zip_file_set_comment(struct zip *za, zip_uint64_t idx,
		     const char *comment, zip_uint16_t len, zip_flags_t flags)
{
    struct zip_entry *e;
    struct zip_string *cstr;
    struct zip_dirent *de;
    int changed;

    if ((de=_zip_get_dirent(za, idx, 0, NULL)) == NULL)
	return -1;

    if (ZIP_IS_RDONLY(za)) {
	_zip_error_set(&za->error, ZIP_ER_RDONLY, 0);
	return -1;
    }

    if (len > 0 && comment == NULL) {
	_zip_error_set(&za->error, ZIP_ER_INVAL, 0);
	return -1;
    }

    if (len > 0) {
	if ((cstr=_zip_string_new((const zip_uint8_t *)comment, len, flags, &za->error)) == NULL)
	    return -1;
	if ((flags & ZIP_FL_ENCODING_ALL) == ZIP_FL_ENC_GUESS && _zip_guess_encoding(cstr, ZIP_ENCODING_UNKNOWN) == ZIP_ENCODING_UTF8_GUESSED)
	    cstr->encoding = ZIP_ENCODING_UTF8_KNOWN;
    }
    else
	cstr = NULL;

    e = za->entry+idx;

    if (e->changes) {
	_zip_string_free(e->changes->comment);
	e->changes->comment = NULL;
	e->changes->changed &= ~ZIP_DIRENT_COMMENT;
    }

    if (e->orig && e->orig->comment)
	changed = !_zip_string_equal(e->orig->comment, cstr);
    else
	changed = (cstr != NULL);
	
    if (changed) {
        if (e->changes == NULL) {
            if ((e->changes=_zip_dirent_clone(e->orig)) == NULL) {
                _zip_error_set(&za->error, ZIP_ER_MEMORY, 0);
                return -1;
            }
        }
        e->changes->comment = cstr;
        e->changes->changed |= ZIP_DIRENT_COMMENT;
    }
    else {
	_zip_string_free(cstr);
	if (e->changes && e->changes->changed == 0) {
	    _zip_dirent_free(e->changes);
	    e->changes = NULL;
	}
    }

    return 0;
}
Exemple #7
0
int
_zip_set_name(zip_t *za, zip_uint64_t idx, const char *name, zip_flags_t flags)
{
    zip_entry_t *e;
    zip_string_t *str;
    bool same_as_orig;
    zip_int64_t i;
    const zip_uint8_t *old_name, *new_name;
    zip_string_t *old_str;

    if (idx >= za->nentry) {
	zip_error_set(&za->error, ZIP_ER_INVAL, 0);
	return -1;
    }

    if (ZIP_IS_RDONLY(za)) {
	zip_error_set(&za->error, ZIP_ER_RDONLY, 0);
	return -1;
    }

    if (name && name[0] != '\0') {
        /* TODO: check for string too long */
	if ((str=_zip_string_new((const zip_uint8_t *)name, (zip_uint16_t)strlen(name), flags, &za->error)) == NULL)
	    return -1;
	if ((flags & ZIP_FL_ENCODING_ALL) == ZIP_FL_ENC_GUESS && _zip_guess_encoding(str, ZIP_ENCODING_UNKNOWN) == ZIP_ENCODING_UTF8_GUESSED)
	    str->encoding = ZIP_ENCODING_UTF8_KNOWN;
    }
    else
	str = NULL;

    /* TODO: encoding flags needed for CP437? */
    if ((i=_zip_name_locate(za, name, 0, NULL)) >= 0 && (zip_uint64_t)i != idx) {
	_zip_string_free(str);
	zip_error_set(&za->error, ZIP_ER_EXISTS, 0);
	return -1;
    }

    /* no effective name change */
    if (i>=0 && (zip_uint64_t)i == idx) {
	_zip_string_free(str);
	return 0;
    }

    e = za->entry+idx;

    if (e->orig)
	same_as_orig = _zip_string_equal(e->orig->filename, str);
    else
	same_as_orig = false;

    if (!same_as_orig && e->changes == NULL) {
	if ((e->changes=_zip_dirent_clone(e->orig)) == NULL) {
	    zip_error_set(&za->error, ZIP_ER_MEMORY, 0);
	    _zip_string_free(str);
	    return -1;
	}
    }

    if ((new_name = _zip_string_get(same_as_orig ? e->orig->filename : str, NULL, 0, &za->error)) == NULL) {
	_zip_string_free(str);
	return -1;
    }

    if (e->changes) {
	old_str = e->changes->filename;
    }
    else if (e->orig) {
	old_str = e->orig->filename;
    }
    else {
	old_str = NULL;
    }
    
    if (old_str) {
	if ((old_name = _zip_string_get(old_str, NULL, 0, &za->error)) == NULL) {
	    _zip_string_free(str);
	    return -1;
	}
    }
    else {
	old_name = NULL;
    }

    if (_zip_hash_add(za->names, new_name, idx, 0, &za->error) == false) {
	_zip_string_free(str);
	return -1;
    }
    if (old_name) {
	_zip_hash_delete(za->names, old_name, NULL);
    }

    if (same_as_orig) {
	if (e->changes) {
	    if (e->changes->changed & ZIP_DIRENT_FILENAME) {
		_zip_string_free(e->changes->filename);
		e->changes->changed &= ~ZIP_DIRENT_FILENAME;
		if (e->changes->changed == 0) {
		    _zip_dirent_free(e->changes);
		    e->changes = NULL;
		}
		else {
		    /* TODO: what if not cloned? can that happen? */
		    e->changes->filename = e->orig->filename;
		}
	    }
	}
	_zip_string_free(str);
    }
    else {
	if (e->changes->changed & ZIP_DIRENT_FILENAME) {
	    _zip_string_free(e->changes->filename);
	}
	e->changes->changed |= ZIP_DIRENT_FILENAME;
	e->changes->filename = str;
    }

    return 0;
}