};
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];
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)) {
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;
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];
}
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);
}
}
+ free(pkg->priv->imports);
free(pkg->priv->exports);
free(pkg->priv->names);
free(pkg->priv);