X-Git-Url: https://git.draconx.ca/gitweb/upkg.git/blobdiff_plain/5fca0fe6cdbe90d31cce2ef17c1d76a8cfe0f921..195935b16f1a2966e50007309f0e68275dc8f2b5:/src/libupkg.c diff --git a/src/libupkg.c b/src/libupkg.c index 3ecce7f..a648bb4 100644 --- a/src/libupkg.c +++ b/src/libupkg.c @@ -110,7 +110,7 @@ const struct upkg_file_ops upkg_default_fops = { * Stores the result in *val and returns the number of input bytes read (or 0 * if the input is invalid, in which case *val is undefined). */ -size_t upkg_decode_index(long *val, unsigned char *bytes, size_t n) +size_t upkg_decode_index(long *val, const unsigned char *bytes, size_t n) { *val = 0; @@ -276,6 +276,7 @@ static int pkg_init_exports(struct upkg_priv *pkg) while (index < pkg->pub.export_count) { struct upkg_export_priv *export = &pkg->exports[index]; + unsigned long parent_index; long tmp; /* Read some data into buffer. */ @@ -296,9 +297,17 @@ static int pkg_init_exports(struct upkg_priv *pkg) len += rc; if (nbuf-len < 4) goto err; - export->pub.package = unpack_s32_le(buf+len); + parent_index = unpack_32_le(buf+len); len += 4; + export->pub.parent = NULL; + if (parent_index > 0) { + parent_index--; + if (parent_index >= pkg->pub.export_count) + goto err; + export->pub.parent = &pkg->exports[parent_index].pub; + } + rc = upkg_decode_index(&tmp, buf+len, nbuf-len); if (rc == 0 || tmp < 0 || tmp >= pkg->pub.name_count) goto err; export->pub.name = pkg->names[tmp].name; @@ -488,22 +497,22 @@ const char *upkg_get_name(struct upkg *pub, unsigned long idx) return pkg->names[idx].name; } -long upkg_export_find(struct upkg *pub, long parent, const char *name) +long upkg_export_find(struct upkg *pub, long parent_index, const char *name) { struct upkg_priv *pkg = (struct upkg_priv *)pub; + struct upkg_export *parent = NULL; - /* This only makes sense if the assertion below is not violated. */ - long package = parent < 0 ? 0 : parent + 1; + if (parent_index >= 0) { + if (parent_index >= pkg->pub.export_count) + return -1; + parent = &pkg->exports[parent_index].pub; + } for (unsigned long i = 0; i < pkg->pub.export_count; i++) { struct upkg_export_priv *e = &pkg->exports[i]; - /* Assertion: an object's package is an export. */ - format_assert(e->pub.package >= 0, continue); - if (e->pub.package == package - && strcmp(e->pub.name, name) == 0) { + if (e->pub.parent == parent && !strcmp(e->pub.name, name)) return i; - } } return -1; @@ -579,7 +588,7 @@ struct upkg_file *upkg_export_open(struct upkg *pub, unsigned long idx) return NULL; *f = (struct upkg_file) { - .pkg = pkg, + .pkg = pub, .base = pkg->exports[idx].offset, .len = pkg->exports[idx].size, .name = pkg->exports[idx].pub.name, @@ -590,8 +599,10 @@ struct upkg_file *upkg_export_open(struct upkg *pub, unsigned long idx) void upkg_export_close(struct upkg_file *f) { - if (f->pkg->last_file == f) - f->pkg->last_file = NULL; + struct upkg_priv *pkg = (struct upkg_priv *)f->pkg; + + if (pkg->last_file == f) + pkg->last_file = NULL; free(f); } @@ -602,7 +613,8 @@ long upkg_export_tell(struct upkg_file *f) int upkg_export_seek(struct upkg_file *f, long offset, int whence) { - const struct upkg_file_ops *fops = f->pkg->fops; + struct upkg_priv *pkg = (struct upkg_priv *)f->pkg; + const struct upkg_file_ops *fops = pkg->fops; int rc = EOF; switch (whence) { @@ -611,23 +623,23 @@ int upkg_export_seek(struct upkg_file *f, long offset, int whence) case SEEK_SET: if (offset < 0 || offset > f->len) return EOF; - rc = fops->seek(f->pkg->f, f->base + offset, SEEK_SET); + rc = fops->seek(pkg->f, f->base + offset, SEEK_SET); break; case SEEK_END: offset = -offset; if (offset < 0 || offset > f->len) return EOF; offset = f->len - offset; - rc = fops->seek(f->pkg->f, f->base + offset, SEEK_SET); + rc = fops->seek(pkg->f, f->base + offset, SEEK_SET); break; } if (rc == 0) { - f->pkg->last_file = f; + pkg->last_file = f; f->offset = offset; f->eof = 0; - } else if (f->pkg->last_file == f) { - f->pkg->last_file = NULL; + } else if (pkg->last_file == f) { + pkg->last_file = NULL; } return rc; @@ -635,7 +647,8 @@ int upkg_export_seek(struct upkg_file *f, long offset, int whence) size_t upkg_export_read(struct upkg_file *f, void *buf, size_t n) { - const struct upkg_file_ops *fops = f->pkg->fops; + struct upkg_priv *pkg = (struct upkg_priv *)f->pkg; + const struct upkg_file_ops *fops = pkg->fops; size_t want = MIN(n, f->len - f->offset); size_t rc; @@ -643,15 +656,15 @@ size_t upkg_export_read(struct upkg_file *f, void *buf, size_t n) return 0; } - if (f != f->pkg->last_file) { - if (fops->seek(f->pkg->f, f->base + f->offset, SEEK_SET)) + if (f != pkg->last_file) { + if (fops->seek(pkg->f, f->base + f->offset, SEEK_SET)) return 0; } - rc = fops->read(buf, want, f->pkg->f); + rc = fops->read(buf, want, pkg->f); f->offset += rc; - if (want < n || (rc < want && fops->eof(f->pkg->f))) + if (want < n || (rc < want && fops->eof(pkg->f))) f->eof = 1; return rc; }