pkg: fix indexing of multi-part apks

cute-signatures
Timo Teras 2009-07-21 17:37:44 +03:00
parent 75802cb07d
commit 812483515a
3 changed files with 32 additions and 26 deletions

View File

@ -225,10 +225,10 @@ int apk_tar_parse(struct apk_istream *is, apk_archive_entry_parser parser,
} }
/* Check that there was no partial record */ /* Check that there was no partial record */
if (r != 0) if (r > 0)
return -1; r = -1;
return 0; return r;
err: err:
EVP_MD_CTX_cleanup(&teis.mdctx); EVP_MD_CTX_cleanup(&teis.mdctx);

View File

@ -21,7 +21,7 @@ struct apk_gzip_istream {
struct apk_istream is; struct apk_istream is;
struct apk_bstream *bs; struct apk_bstream *bs;
z_stream zs; z_stream zs;
int z_err; int err;
apk_multipart_cb cb; apk_multipart_cb cb;
void *cbctx; void *cbctx;
@ -34,10 +34,11 @@ static size_t gzi_read(void *stream, void *ptr, size_t size)
container_of(stream, struct apk_gzip_istream, is); container_of(stream, struct apk_gzip_istream, is);
int r; int r;
if (gis->z_err == Z_DATA_ERROR || gis->z_err == Z_ERRNO) if (gis->err != 0) {
return -1; if (gis->err > 0)
if (gis->z_err == Z_STREAM_END)
return 0; return 0;
return gis->err;
}
if (ptr == NULL) if (ptr == NULL)
return apk_istream_skip(&gis->is, size); return apk_istream_skip(&gis->is, size);
@ -45,7 +46,7 @@ static size_t gzi_read(void *stream, void *ptr, size_t size)
gis->zs.avail_out = size; gis->zs.avail_out = size;
gis->zs.next_out = ptr; gis->zs.next_out = ptr;
while (gis->zs.avail_out != 0 && gis->z_err == Z_OK) { while (gis->zs.avail_out != 0 && gis->err == 0) {
if (gis->zs.avail_in == 0) { if (gis->zs.avail_in == 0) {
apk_blob_t blob; apk_blob_t blob;
@ -59,48 +60,54 @@ static size_t gzi_read(void *stream, void *ptr, size_t size)
gis->zs.avail_in = blob.len; gis->zs.avail_in = blob.len;
gis->zs.next_in = (void *) gis->cbprev; gis->zs.next_in = (void *) gis->cbprev;
if (gis->zs.avail_in < 0) { if (gis->zs.avail_in < 0) {
gis->z_err = Z_DATA_ERROR; gis->err = -1;
return size - gis->zs.avail_out; goto ret;
} else if (gis->zs.avail_in == 0) { } else if (gis->zs.avail_in == 0) {
if (gis->cb != NULL) { if (gis->cb != NULL) {
r = gis->cb(gis->cbctx, APK_MPART_END, r = gis->cb(gis->cbctx, APK_MPART_END,
APK_BLOB_NULL); APK_BLOB_NULL);
if (r != 0) { if (r != 0) {
gis->z_err = Z_STREAM_END;
if (r > 0) if (r > 0)
r = -1; r = -1;
return r; gis->err = r;
} }
} } else
gis->z_err = Z_STREAM_END; gis->err = 1;
return size - gis->zs.avail_out; goto ret;
} }
} }
gis->z_err = inflate(&gis->zs, Z_NO_FLUSH); r = inflate(&gis->zs, Z_NO_FLUSH);
if (gis->z_err == Z_STREAM_END) { switch (r) {
case Z_STREAM_END:
/* Digest the inflated bytes */ /* Digest the inflated bytes */
if (gis->cb != NULL) { if (gis->cb != NULL) {
r = gis->cb(gis->cbctx, APK_MPART_BOUNDARY, r = gis->cb(gis->cbctx, APK_MPART_BOUNDARY,
APK_BLOB_PTR_LEN(gis->cbprev, APK_BLOB_PTR_LEN(gis->cbprev,
(void *)gis->zs.next_in - gis->cbprev)); (void *)gis->zs.next_in - gis->cbprev));
if (r != 0) { if (r != 0) {
gis->z_err = Z_DATA_ERROR;
if (r > 0) if (r > 0)
r = -1; r = -1;
return r; gis->err = r;
goto ret;
} }
gis->cbprev = gis->zs.next_in; gis->cbprev = gis->zs.next_in;
} }
inflateEnd(&gis->zs); inflateEnd(&gis->zs);
if (inflateInit2(&gis->zs, 15+32) != Z_OK) if (inflateInit2(&gis->zs, 15+32) != Z_OK)
return -1; return -1;
gis->z_err = Z_OK; break;
case Z_OK:
break;
default:
gis->err = -1;
break;
} }
} }
if (gis->z_err != Z_OK && gis->z_err != Z_STREAM_END) ret:
return -1; if (size - gis->zs.avail_out == 0)
return gis->err;
return size - gis->zs.avail_out; return size - gis->zs.avail_out;
} }
@ -131,7 +138,6 @@ struct apk_istream *apk_bstream_gunzip_mpart(struct apk_bstream *bs,
.is.read = gzi_read, .is.read = gzi_read,
.is.close = gzi_close, .is.close = gzi_close,
.bs = bs, .bs = bs,
.z_err = 0,
.cb = cb, .cb = cb,
.cbctx = ctx, .cbctx = ctx,
}; };

View File

@ -447,7 +447,7 @@ int apk_sign_ctx_mpart_cb(void *ctx, int part, apk_blob_t data)
/* Package identity is checksum of control block */ /* Package identity is checksum of control block */
sctx->identity.type = EVP_MD_CTX_size(&sctx->mdctx); sctx->identity.type = EVP_MD_CTX_size(&sctx->mdctx);
EVP_DigestFinal_ex(&sctx->mdctx, sctx->identity.data, NULL); EVP_DigestFinal_ex(&sctx->mdctx, sctx->identity.data, NULL);
return 1; return -1000;
} else { } else {
/* Reset digest for hashing data */ /* Reset digest for hashing data */
EVP_DigestFinal_ex(&sctx->mdctx, calculated, NULL); EVP_DigestFinal_ex(&sctx->mdctx, calculated, NULL);
@ -702,7 +702,7 @@ struct apk_package *apk_pkg_read(struct apk_database *db, const char *file,
tar = apk_bstream_gunzip_mpart(bs, apk_sign_ctx_mpart_cb, sctx); tar = apk_bstream_gunzip_mpart(bs, apk_sign_ctx_mpart_cb, sctx);
r = apk_tar_parse(tar, read_info_entry, &ctx); r = apk_tar_parse(tar, read_info_entry, &ctx);
tar->close(tar); tar->close(tar);
if (r < 0) if (r < 0 && r != -1000)
goto err; goto err;
if (ctx.pkg->name == NULL) if (ctx.pkg->name == NULL)
goto err; goto err;