Ejemplo n.º 1
0
static zip_int64_t
_zip_checkcons(zip_t *za, zip_cdir_t *cd, zip_error_t *error)
{
    zip_uint64_t i;
    zip_uint64_t min, max, j;
    struct zip_dirent temp;

    _zip_dirent_init(&temp);
    if (cd->nentry) {
	max = cd->entry[0].orig->offset;
	min = cd->entry[0].orig->offset;
    }
    else
	min = max = 0;

    for (i=0; i<cd->nentry; i++) {
	if (cd->entry[i].orig->offset < min)
	    min = cd->entry[i].orig->offset;
	if (min > (zip_uint64_t)cd->offset) {
	    zip_error_set(error, ZIP_ER_NOZIP, 0);
	    return -1;
	}

	j = cd->entry[i].orig->offset + cd->entry[i].orig->comp_size
	    + _zip_string_length(cd->entry[i].orig->filename) + LENTRYSIZE;
	if (j > max)
	    max = j;
	if (max > (zip_uint64_t)cd->offset) {
	    zip_error_set(error, ZIP_ER_NOZIP, 0);
	    return -1;
	}

        if (zip_source_seek(za->src, (zip_int64_t)cd->entry[i].orig->offset, SEEK_SET) < 0) {
            _zip_error_set_from_source(error, za->src);
            return -1;
	}

	if (_zip_dirent_read(&temp, za->src, NULL, true, error) == -1) {
	    _zip_dirent_finalize(&temp);
	    return -1;
	}

	if (_zip_headercomp(cd->entry[i].orig, &temp) != 0) {
	    zip_error_set(error, ZIP_ER_INCONS, 0);
	    _zip_dirent_finalize(&temp);
	    return -1;
	}

	cd->entry[i].orig->extra_fields = _zip_ef_merge(cd->entry[i].orig->extra_fields, temp.extra_fields);
	cd->entry[i].orig->local_extra_fields_read = 1;
	temp.extra_fields = NULL;

	_zip_dirent_finalize(&temp);
    }

    return (max-min) < ZIP_INT64_MAX ? (zip_int64_t)(max-min) : ZIP_INT64_MAX;
}
Ejemplo n.º 2
0
static zip_int64_t
_zip_checkcons(FILE *fp, struct zip_cdir *cd, struct zip_error *error)
{
    zip_uint64_t i;
    zip_uint64_t min, max, j;
    struct zip_dirent temp;

    if (cd->nentry) {
	max = cd->entry[0].orig->offset;
	min = cd->entry[0].orig->offset;
    }
    else
	min = max = 0;

    for (i=0; i<cd->nentry; i++) {
	if (cd->entry[i].orig->offset < min)
	    min = cd->entry[i].orig->offset;
	if (min > (zip_uint64_t)cd->offset) {
	    _zip_error_set(error, ZIP_ER_NOZIP, 0);
	    return -1;
	}

	j = cd->entry[i].orig->offset + cd->entry[i].orig->comp_size
	    + _zip_string_length(cd->entry[i].orig->filename) + LENTRYSIZE;
	if (j > max)
	    max = j;
	if (max > (zip_uint64_t)cd->offset) {
	    _zip_error_set(error, ZIP_ER_NOZIP, 0);
	    return -1;
	}

	if (fseeko(fp, (off_t)cd->entry[i].orig->offset, SEEK_SET) != 0) {
	    _zip_error_set(error, ZIP_ER_SEEK, errno);
	    return -1;
	}

	if (_zip_dirent_read(&temp, fp, NULL, NULL, 1, error) == -1)
	    return -1;

	if (_zip_headercomp(cd->entry[i].orig, &temp) != 0) {
	    _zip_error_set(error, ZIP_ER_INCONS, 0);
	    _zip_dirent_finalize(&temp);
	    return -1;
	}

	cd->entry[i].orig->extra_fields = _zip_ef_merge(cd->entry[i].orig->extra_fields, temp.extra_fields);
	cd->entry[i].orig->local_extra_fields_read = 1;
	temp.extra_fields = NULL;

	_zip_dirent_finalize(&temp);
    }

    return (max-min) < ZIP_INT64_MAX ? (zip_int64_t)(max-min) : ZIP_INT64_MAX;
}
Ejemplo n.º 3
0
int
_zip_read_local_ef(struct zip *za, zip_uint64_t idx)
{
    struct zip_entry *e;
    unsigned char b[4];
    const unsigned char *p;
    zip_uint16_t fname_len, ef_len;

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

    e = za->entry+idx;

    if (e->orig == NULL || e->orig->local_extra_fields_read)
	return 0;


    if (fseeko(za->zp, (off_t)(e->orig->offset + 26), SEEK_SET) < 0) {
	_zip_error_set(&za->error, ZIP_ER_SEEK, errno);
	return -1;
    }

    if (fread(b, sizeof(b), 1, za->zp) != 1) {
	_zip_error_set(&za->error, ZIP_ER_READ, errno);
	return -1;
    }

    p = b;
    fname_len = _zip_read2(&p);
    ef_len = _zip_read2(&p);

    if (ef_len > 0) {
	struct zip_extra_field *ef;
	zip_uint8_t *ef_raw;

	if (fseek(za->zp, fname_len, SEEK_CUR) < 0) {
	    _zip_error_set(&za->error, ZIP_ER_SEEK, errno);
	    return -1;
	}

	ef_raw = _zip_read_data(NULL, za->zp, ef_len, 0, &za->error);

	if (ef_raw == NULL)
	    return -1;

	if ((ef=_zip_ef_parse(ef_raw, ef_len, ZIP_EF_LOCAL, &za->error)) == NULL) {
	    free(ef_raw);
	    return -1;
	}
	free(ef_raw);
	
        ef = _zip_ef_remove_internal(ef);
	e->orig->extra_fields = _zip_ef_merge(e->orig->extra_fields, ef);
    }

    e->orig->local_extra_fields_read = 1;
    
    if (e->changes && e->changes->local_extra_fields_read == 0) {
	e->changes->extra_fields = e->orig->extra_fields;
	e->changes->local_extra_fields_read = 1;
    }

    return 0;
}
Ejemplo n.º 4
0
int
_zip_read_local_ef(zip_t *za, zip_uint64_t idx)
{
    zip_entry_t *e;
    unsigned char b[4];
    zip_buffer_t *buffer;
    zip_uint16_t fname_len, ef_len;

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

    e = za->entry+idx;

    if (e->orig == NULL || e->orig->local_extra_fields_read)
	return 0;

    if (e->orig->offset + 26 > ZIP_INT64_MAX) {
	zip_error_set(&za->error, ZIP_ER_SEEK, EFBIG);
	return -1;
    }	

    if (zip_source_seek(za->src, (zip_int64_t)(e->orig->offset + 26), SEEK_SET) < 0) {
	_zip_error_set_from_source(&za->error, za->src);
	return -1;
    }
    
    if ((buffer = _zip_buffer_new_from_source(za->src, sizeof(b), b, &za->error)) == NULL) {
        return -1;
    }
    
    fname_len = _zip_buffer_get_16(buffer);
    ef_len = _zip_buffer_get_16(buffer);
    
    if (!_zip_buffer_eof(buffer)) {
        _zip_buffer_free(buffer);
        zip_error_set(&za->error, ZIP_ER_INTERNAL, 0);
        return -1;
    }
    
    _zip_buffer_free(buffer);
    
    if (ef_len > 0) {
	zip_extra_field_t *ef;
	zip_uint8_t *ef_raw;

	if (zip_source_seek(za->src, fname_len, SEEK_CUR) < 0) {
	    zip_error_set(&za->error, ZIP_ER_SEEK, errno);
	    return -1;
	}

	ef_raw = _zip_read_data(NULL, za->src, ef_len, 0, &za->error);

	if (ef_raw == NULL)
	    return -1;

	if (!_zip_ef_parse(ef_raw, ef_len, ZIP_EF_LOCAL, &ef, &za->error)) {
	    free(ef_raw);
	    return -1;
	}
	free(ef_raw);

	if (ef) {
	    ef = _zip_ef_remove_internal(ef);
	    e->orig->extra_fields = _zip_ef_merge(e->orig->extra_fields, ef);
	}
    }

    e->orig->local_extra_fields_read = 1;
    
    if (e->changes && e->changes->local_extra_fields_read == 0) {
	e->changes->extra_fields = e->orig->extra_fields;
	e->changes->local_extra_fields_read = 1;
    }

    return 0;
}