X-Git-Url: http://git.draconx.ca/gitweb/upkg.git/blobdiff_plain/bb9c28745ae254b832805e5d41f2a5e6c3cb8f40..95f7a657a099c844a644b8736bd18e08afd50661:/src/libupkg.c diff --git a/src/libupkg.c b/src/libupkg.c index 178e235..307e1be 100644 --- a/src/libupkg.c +++ b/src/libupkg.c @@ -110,12 +110,11 @@ 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) { - size_t i = 0; - *val = 0; - while (i < MIN(n, 5)) { + + for (size_t i = 0; i < MIN(n, 5); i++) { /* * Least significant bytes are first, so we need to do this * nonsense. @@ -127,18 +126,14 @@ size_t upkg_decode_index(long *val, unsigned char *bytes, size_t n) *val += tmp; if (!(bytes[i] & (i == 0 ? 0x40 : 0x80))) { - i++; - break; + if (bytes[0] & 0x80) + *val = -*val; + return i+1; } - - i++; } - if (i > MIN(n, 5) || n == 0) - return 0; - if (bytes[0] & 0x80) - *val = -*val; - return i; + /* Error */ + return 0; } static struct upkg_priv *init_upkg(unsigned char hdr[static UPKG_HDR_SIZE]) @@ -281,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. */ @@ -301,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; @@ -493,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;