Example #1
0
void
_zip_error_set_from_source(struct zip_error *err, struct zip_source *src)
{
    int ze, se;
    
    zip_source_error(src, &ze, &se);
    _zip_error_set(err, ze, se);
}
Example #2
0
zip_source_error(struct zip_source *src, int *ze, int *se)
{
    int e[2] = { 0, 0 };

    if (src->src == NULL) {
    }
    else {
	switch (src->error_source) {
	case ZIP_LES_NONE:
	    if (src->src == NULL) {
		if (src->cb.f(src->ud, e, sizeof(e), ZIP_SOURCE_ERROR) < 0) {
		    e[0] = ZIP_ER_INTERNAL;
		    e[1] = 0;
		}
	    }
	    else
		e[0] = e[1] = 0;
	    break;

	case ZIP_LES_INVAL:
	    e[0] = ZIP_ER_INVAL;
	    e[1] = 0;
	    break;

	case ZIP_LES_LOWER:
	    zip_source_error(src->src, ze, se);
	    return;

	case ZIP_LES_UPPER:
	    if (src->cb.l(src->src, src->ud, e, sizeof(e),
			  ZIP_SOURCE_ERROR) < 0) {
		e[0] = ZIP_ER_INTERNAL;
		e[1] = 0;
	    }
	    break;

	default:
	    e[0] = ZIP_ER_INTERNAL;
	    e[1] = 0;
	}
    }

    if (ze)
	*ze = e[0];
    if (se)
	*se = e[1];
}
Example #3
0
/*
 * tests for file existence
 */
static exists_t
_zip_file_exists(zip_source_t *src, zip_error_t *error)
{
    struct zip_stat st;

    zip_stat_init(&st);
    if (zip_source_stat(src, &st) != 0) {
        zip_error_t *src_error = zip_source_error(src);
        if (zip_error_code_zip(src_error) == ZIP_ER_READ && zip_error_code_system(src_error) == ENOENT) {
	    return EXISTS_NOT;
	}
	_zip_error_copy(error, src_error);
	return EXISTS_ERROR;
    }

    return (st.valid & ZIP_STAT_SIZE) && st.size == 0 ? EXISTS_EMPTY : EXISTS_NONEMPTY;
}
Example #4
0
static zip_cdir_t *
_zip_find_central_dir(zip_t *za, zip_uint64_t len)
{
    zip_cdir_t *cdir, *cdirnew;
    zip_uint8_t *match;
    zip_int64_t buf_offset;
    zip_uint64_t buflen;
    zip_int64_t a;
    zip_int64_t best;
    zip_error_t error;
    zip_buffer_t *buffer;

    if (len < EOCDLEN) {
	zip_error_set(&za->error, ZIP_ER_NOZIP, 0);
        return NULL;
    }

    buflen = (len < CDBUFSIZE ? len : CDBUFSIZE);
    if (zip_source_seek(za->src, -(zip_int64_t)buflen, SEEK_END) < 0) {
	zip_error_t *src_error = zip_source_error(za->src);
	if (zip_error_code_zip(src_error) != ZIP_ER_SEEK || zip_error_code_system(src_error) != EFBIG) {
	    /* seek before start of file on my machine */
	    _zip_error_copy(&za->error, src_error);
	    return NULL;
	}
    }
    if ((buf_offset = zip_source_tell(za->src)) < 0) {
        _zip_error_set_from_source(&za->error, za->src);
        return NULL;
    }

    if ((buffer = _zip_buffer_new_from_source(za->src, buflen, NULL, &za->error)) == NULL) {
        return NULL;
    }

    best = -1;
    cdir = NULL;
    if (buflen >= CDBUFSIZE) {
        /* EOCD64 locator is before EOCD, so leave place for it */
        _zip_buffer_set_offset(buffer, EOCD64LOCLEN);
    }
    zip_error_set(&error, ZIP_ER_NOZIP, 0);

    match = _zip_buffer_get(buffer, 0);
    while ((match=_zip_memmem(match, _zip_buffer_left(buffer)-(EOCDLEN-4), (const unsigned char *)EOCD_MAGIC, 4)) != NULL) {
        _zip_buffer_set_offset(buffer, (zip_uint64_t)(match - _zip_buffer_data(buffer)));
        if ((cdirnew = _zip_read_cdir(za, buffer, (zip_uint64_t)buf_offset, &error)) != NULL) {
            if (cdir) {
                if (best <= 0) {
                    best = _zip_checkcons(za, cdir, &error);
                }

                a = _zip_checkcons(za, cdirnew, &error);
                if (best < a) {
                    _zip_cdir_free(cdir);
                    cdir = cdirnew;
                    best = a;
                }
                else {
                    _zip_cdir_free(cdirnew);
                }
            }
            else {
                cdir = cdirnew;
                if (za->open_flags & ZIP_CHECKCONS)
                    best = _zip_checkcons(za, cdir, &error);
                else {
                    best = 0;
                }
            }
            cdirnew = NULL;
        }

        match++;
        _zip_buffer_set_offset(buffer, (zip_uint64_t)(match - _zip_buffer_data(buffer)));
    }

    _zip_buffer_free(buffer);

    if (best < 0) {
        _zip_error_copy(&za->error, &error);
        _zip_cdir_free(cdir);
        return NULL;
    }

    return cdir;
}
Example #5
0
static zip_int64_t
compress_read(struct zip_source *src, struct deflate *ctx,
	      void *data, zip_uint64_t len)
{
    int end, ret;
    zip_int64_t n;

    if (ctx->e[0] != 0)
	return -1;
    
    if (len == 0)
	return 0;
	
    ctx->zstr.next_out = (Bytef *)data;
    ctx->zstr.avail_out = (uInt)len; /* TODO: check for overflow */

    end = 0;
    while (!end) {
	ret = deflate(&ctx->zstr, ctx->eof ? Z_FINISH : 0);

	switch (ret) {
	case Z_OK:
	case Z_STREAM_END:
	    /* all ok */

	    if (ctx->zstr.avail_out == 0
		|| (ctx->eof && ctx->zstr.avail_in == 0))
		end = 1;
	    break;

	case Z_BUF_ERROR:
	    if (ctx->zstr.avail_in == 0) {
		if (ctx->eof) {
		    end = 1;
		    break;
		}

		if ((n=zip_source_read(src, ctx->buffer, sizeof(ctx->buffer))) < 0) {
		    zip_source_error(src, ctx->e, ctx->e+1);
		    end = 1;
		    break;
		}
		else if (n == 0) {
		    ctx->eof = 1;
		    ctx->size = ctx->zstr.total_in;
		    /* TODO: check against stat of src? */
		}
		else {
		    ctx->zstr.next_in = (Bytef *)ctx->buffer;
		    ctx->zstr.avail_in = (uInt)n;
		}
		continue;
	    }
	    /* fallthrough */
	case Z_NEED_DICT:
	case Z_DATA_ERROR:
	case Z_STREAM_ERROR:
	case Z_MEM_ERROR:
	    ctx->e[0] = ZIP_ER_ZLIB;
	    ctx->e[1] = ret;

	    end = 1;
	    break;
	}
    }

    if (ctx->zstr.avail_out < len)
	return (zip_int64_t)(len - ctx->zstr.avail_out);

    return (ctx->e[0] == 0) ? 0 : -1;
}
Example #6
0
bool
_zip_source_had_error(zip_source_t *src)
{
    return zip_source_error(src)->zip_err != ZIP_ER_OK;
}
Example #7
0
void
_zip_error_set_from_source(zip_error_t *err, zip_source_t *src)
{
    _zip_error_copy(err, zip_source_error(src));
}