From 05e3500b16aa61732a22ffafe1b3edb3933d1897 Mon Sep 17 00:00:00 2001 From: Nick Bowler Date: Fri, 5 Jun 2009 21:20:50 -0400 Subject: [PATCH] Implement import table parsing. --- libupkg.c | 89 ++++++++++++++++++++++++++++++++++++++++++++++++++----- upkg.c | 1 + 2 files changed, 83 insertions(+), 7 deletions(-) diff --git a/libupkg.c b/libupkg.c index a269698..85767a2 100644 --- a/libupkg.c +++ b/libupkg.c @@ -13,16 +13,24 @@ struct upkg_name { }; struct upkg_export { - long class, super, name; - unsigned long package, flags; + const char *name; + + long package, class, super; + unsigned long flags; unsigned long size, offset; }; +struct upkg_import { + const char *class_package, *class_name, *object_name; + long package; +}; + struct upkg_private { FILE *f; struct upkg_name *names; struct upkg_export *exports; + struct upkg_import *imports; unsigned long name_offset, export_offset, import_offset; unsigned char guid[16]; @@ -159,6 +167,7 @@ static int pkg_init_exports(struct upkg *pkg) while (index < pkg->export_count) { struct upkg_export *export = &pkg->priv->exports[index]; + long tmp; /* Read some data into buffer. */ if (!feof(pkg->priv->f)) { @@ -181,8 +190,9 @@ static int pkg_init_exports(struct upkg *pkg) export->package = unpack_32_le(buf+len); len += 4; - rc = decode_index(&export->name, buf+len, nbuf-len); - if (rc == 0) goto err; + rc = decode_index(&tmp, buf+len, nbuf-len); + if (rc == 0 || tmp < 0 || tmp >= pkg->name_count) goto err; + export->name = pkg->priv->names[tmp].name; len += rc; if (nbuf-len < 4) goto err; @@ -210,6 +220,62 @@ err: return -1; } +static int pkg_init_imports(struct upkg *pkg) +{ + size_t rc, len, nbuf = 0; + unsigned long index = 0; + char buf[512]; + + if (fseek(pkg->priv->f, pkg->priv->import_offset, SEEK_SET) != 0) + return -1; + + pkg->priv->imports = malloc(pkg->import_count * sizeof *pkg->priv->imports); + if (!pkg->priv->imports) + return -1; + + while (index < pkg->import_count) { + struct upkg_import *import = &pkg->priv->imports[index]; + long tmp; + + /* Read some data into buffer. */ + if (!feof(pkg->priv->f)) { + rc = fread(buf+nbuf, 1, sizeof buf-nbuf, pkg->priv->f); + if (rc == 0) + goto err; + nbuf += rc; + } + + len = 0; + rc = decode_index(&tmp, buf+len, nbuf-len); + if (rc == 0 || len < 0 || len >= pkg->name_count) goto err; + import->class_package = pkg->priv->names[tmp].name; + len += rc; + + rc = decode_index(&tmp, buf+len, nbuf-len); + if (rc == 0 || len < 0 || len >= pkg->name_count) goto err; + import->class_name = pkg->priv->names[tmp].name; + len += rc; + + if (nbuf-len < 4) goto err; + import->package = unpack_32_le(buf+len); + len += 4; + + rc = decode_index(&tmp, buf+len, nbuf-len); + if (rc == 0 || len < 0 || len >= pkg->name_count) goto err; + import->object_name = pkg->priv->names[tmp].name; + len += rc; + + nbuf -= len; + memmove(buf, buf+len, nbuf); + index++; + } + + return 0; +err: + free(pkg->priv->imports); + return -1; +} + struct upkg *upkg_fopen(const char *path) { unsigned char hdr_buf[UPKG_HDR_SIZE]; @@ -233,17 +299,25 @@ struct upkg *upkg_fopen(const char *path) } pkg->priv->f = f; - if (pkg_init_exports(pkg) != 0) { + if (pkg_init_names(pkg) != 0) { goto err2; } - if (pkg_init_names(pkg) != 0) { + if (pkg_init_exports(pkg) != 0) { goto err3; } + if (pkg_init_imports(pkg) != 0) { + goto err4; + } + return pkg; -err3: +err4: free(pkg->priv->exports); +err3: + for (unsigned i = 0; i < pkg->name_count; i++) + free(pkg->priv->names[i].name); + free(pkg->priv->names); err2: free(pkg->priv); free(pkg); @@ -264,6 +338,7 @@ int upkg_close(struct upkg *pkg) } } + free(pkg->priv->imports); free(pkg->priv->exports); free(pkg->priv->names); free(pkg->priv); diff --git a/upkg.c b/upkg.c index 2694f5b..660819c 100644 --- a/upkg.c +++ b/upkg.c @@ -46,6 +46,7 @@ int main(int argc, char **argv) } printf("Exports: %lu\n", pkg->export_count); + printf("Imports: %lu\n", pkg->import_count); upkg_close(pkg); return 0; -- 2.43.2