commit - a6b158cc8110b488f51e265bea16ed17a0079e0a
commit + 0e22967e43602d4c52a8d102e30107f8c4da765a
blob - 47d76d27b6b0d7cb999126ff93c9be462456dd24
blob + 41af9356c9c8a63448df12b4f5c977e9eb233dc5
--- lib/delta.c
+++ lib/delta.c
#endif
struct got_delta *
-got_delta_open(const char *path_packfile, int type, off_t offset,
- size_t size)
+got_delta_open(const char *path_packfile, off_t offset, size_t tslen,
+ int type, size_t size)
{
struct got_delta *delta;
}
delta->type = type;
delta->offset = offset;
+ delta->tslen = tslen;
delta->size = size;
return delta;
}
}
const struct got_error *
-got_delta_apply(FILE *base_compressed, const uint8_t *delta_buf,
+got_delta_apply(FILE *base_file, const uint8_t *delta_buf,
size_t delta_len, FILE *outfile)
{
const struct got_error *err = NULL;
- FILE *base_file = NULL;
uint64_t base_size, result_size;
size_t remain, outsize = 0;
const uint8_t *p;
err = parse_opcode(&offset, &len, &p, &remain);
if (err)
break;
- if (base_file == NULL) {
- size_t inflated_size;
- base_file = got_opentemp();
- if (base_file == NULL) {
- err = got_error_from_errno();
- break;
- }
- err = got_inflate_to_file(&inflated_size,
- base_compressed, base_file);
- if (err)
- break;
- if (inflated_size != base_size) {
- err = got_error(GOT_ERR_BAD_DELTA);
- break;
- }
- }
err = copy_from_base(base_file, offset, len, outfile);
if (err == NULL)
outsize += len;
if (outsize != result_size)
err = got_error(GOT_ERR_BAD_DELTA);
- if (base_file)
- fclose(base_file);
if (err == NULL)
rewind(outfile);
return err;
blob - 84193ca76b0e39db46ace39f37ccb3854f6fed91
blob + 159057631e643f4fad94371f41acbd2023aa9529
--- lib/delta.h
+++ lib/delta.h
SIMPLEQ_ENTRY(got_delta) entry;
char *path_packfile;
off_t offset;
+ size_t tslen;
int type;
size_t size;
};
SIMPLEQ_HEAD(, got_delta) entries;
};
-struct got_delta *got_delta_open(const char *, int, off_t, size_t);
+struct got_delta *got_delta_open(const char *, off_t, size_t, int, size_t);
void got_delta_close(struct got_delta *);
const struct got_error *got_delta_chain_get_base_type(int *,
struct got_delta_chain *);
blob - 695e3dc57b3f6950442c696698ebf4591a41da82
blob + dd64e4ac004ebf28028927affaa8a9d342b5f944
--- lib/pack.c
+++ lib/pack.c
return NULL;
}
-static const struct got_error *resolve_delta_chain(struct got_delta_chain *,
- struct got_repository *repo, FILE *, const char *, int, off_t, size_t);
+static const struct got_error *
+resolve_delta_chain(struct got_delta_chain *, struct got_repository *,
+ FILE *, const char *, off_t, size_t, int, size_t);
static const struct got_error *
resolve_offset_delta(struct got_delta_chain *deltas,
return err;
return resolve_delta_chain(deltas, repo, packfile, path_packfile,
- base_type, base_offset + base_tslen, base_size);
+ base_offset, base_tslen, base_type, base_size);
}
static const struct got_error *
goto done;
err = resolve_delta_chain(deltas, repo, base_packfile,
- path_base_packfile, base_type, base_offset + base_tslen, base_size);
+ path_base_packfile, base_offset, base_tslen, base_type,
+ base_size);
done:
free(path_base_packfile);
if (base_packfile && fclose(base_packfile) == -1 && err == 0)
static const struct got_error *
resolve_delta_chain(struct got_delta_chain *deltas, struct got_repository *repo,
- FILE *packfile, const char *path_packfile, int delta_type,
- off_t delta_offset, size_t delta_size)
+ FILE *packfile, const char *path_packfile, off_t delta_offset, size_t tslen,
+ int delta_type, size_t delta_size)
{
const struct got_error *err = NULL;
struct got_delta *delta;
- delta = got_delta_open(path_packfile, delta_type, delta_offset,
- delta_size);
+ delta = got_delta_open(path_packfile, delta_offset, tslen,
+ delta_type, delta_size);
if (delta == NULL)
return got_error(GOT_ERR_NO_MEM);
deltas->nentries++;
(*obj)->flags |= GOT_OBJ_FLAG_DELTIFIED;
err = resolve_delta_chain(&(*obj)->deltas, repo, packfile,
- path_packfile, delta_type, offset, delta_size);
+ path_packfile, offset, tslen, delta_type, delta_size);
if (err)
goto done;
goto done;
}
- if (fseeko(delta_file, delta->offset, SEEK_SET) != 0) {
+ if (fseeko(delta_file, delta->offset + delta->tslen,
+ SEEK_SET) != 0) {
fclose(delta_file);
err = got_error_from_errno();
goto done;
continue;
}
+ if (delta->type == GOT_OBJ_TYPE_REF_DELTA &&
+ fseeko(delta_file, SHA1_DIGEST_LENGTH, SEEK_CUR) != 0) {
+ fclose(delta_file);
+ err = got_error_from_errno();
+ goto done;
+ }
+
/* Delta streams should always fit in memory. */
err = got_inflate_to_mem(&delta_buf, &delta_len, delta_file);
fclose(delta_file);